privilege dropping replaced by a separate python script for root actions
syslog support added moved program locations to config file removed obsolete CryptoBoxPreferences added some requests for comments (RFC)
This commit is contained in:
parent
975b2bb14a
commit
b951efdd9c
7 changed files with 156 additions and 269 deletions
|
@ -15,27 +15,35 @@ import os
|
|||
import sys
|
||||
import unittest
|
||||
|
||||
CONF_LOCATIONS = [ "./cryptobox.conf", "~/.cryptobox.conf", "/etc/cryptobox/cryptobox.conf"]
|
||||
CONF_LOCATIONS = [
|
||||
"./cryptobox.conf",
|
||||
"~/.cryptobox.conf",
|
||||
"/etc/cryptobox/cryptobox.conf"]
|
||||
|
||||
|
||||
class CryptoBox:
|
||||
'''this class rules them all!
|
||||
|
||||
put things like logging, conf and oter stuff in here,
|
||||
that might be used by more classes, it will be passed on to them'''
|
||||
def __init__(self):
|
||||
def __init__(self, config_file=None):
|
||||
self.__initLogging()
|
||||
self.__initPreferences()
|
||||
self.__initPreferences(config_file)
|
||||
|
||||
|
||||
def __initLogging(self):
|
||||
import logging
|
||||
# RFC: this import should be at the top of the file - or at least (for clarity) be there in a comment line [l]
|
||||
'''initialises the logging system
|
||||
|
||||
use it with: 'self.log.[debug|info|warning|error|critical](logmessage)'
|
||||
from all classes the inherited from CryptoBox
|
||||
|
||||
TODO: read the logfile from the config - this is a hen-egg problem
|
||||
TODO/RFC: read the logfile from the config - this is a hen-egg problem
|
||||
i would prefer start logging to stdout, read the config and redirect
|
||||
logging to the logfile found in the config [a] '''
|
||||
logging to the logfile found in the config [a]
|
||||
|
||||
[l]: ok'''
|
||||
## basicConfig(...) needs python >= 2.4
|
||||
try:
|
||||
logging.basicConfig(level=logging.DEBUG,
|
||||
|
@ -49,22 +57,35 @@ class CryptoBox:
|
|||
sys.stderr.write("Something with the loggingsystem went wrong. I give up.")
|
||||
sys.exit(1)
|
||||
|
||||
def __initPreferences(self):
|
||||
try:
|
||||
import configobj ## needed for reading and writing the config file
|
||||
except:
|
||||
self.log.error("Could't import 'configobj'! Try apt-get install python-configobj.")
|
||||
sys.exit(1)
|
||||
|
||||
for f in CONF_LOCATIONS:
|
||||
if os.path.exists(os.path.expanduser(f)):
|
||||
conf_file = os.path.expanduser(f)
|
||||
break
|
||||
def __initPreferences(self, config_file):
|
||||
# RFC: this try-except should happen at the top of the script - or? [l]
|
||||
try:
|
||||
import configobj ## needed for reading and writing of the config file
|
||||
except:
|
||||
self.log.error("Could't import 'configobj'! Try 'apt-get install python-configobj'.")
|
||||
sys.exit(1)
|
||||
# search for the configuration file
|
||||
if config_file is None:
|
||||
# no config file was specified - we will look for it in the ususal locations
|
||||
conf_file_list = [os.path.expanduser(f)
|
||||
for f in CONF_LOCATIONS
|
||||
if os.path.exists(os.path.expanduser(f))]
|
||||
if not conf_file_list:
|
||||
# no possible config file found in the usual locations
|
||||
self.log.error("No configuration file found - sorry!")
|
||||
sys.exit(1)
|
||||
config_file = conf_file_list[0]
|
||||
else:
|
||||
# a config file was specified (e.g. via command line)
|
||||
if not os.path.exists(config_file):
|
||||
self.log.error("Could not find the specified configuration file (%s)" % config_file)
|
||||
sys.exit(1)
|
||||
try:
|
||||
self.cbxPrefs = configobj.ConfigObj(conf_file)
|
||||
self.log.debug("found config: %s" % self.cbxPrefs.items())
|
||||
except:
|
||||
self.log.error("Could not read configuration file. I give up.\n")
|
||||
self.log.error("Could not read configuration file. I give up.")
|
||||
sys.exit(1)
|
||||
try:
|
||||
nameDB_file = os.path.join(
|
||||
|
@ -77,11 +98,16 @@ class CryptoBox:
|
|||
except SyntaxError:
|
||||
self.log.error("Error during parsing of name database file (%s).\n" % (nameDB_file, ))
|
||||
sys.exit(1)
|
||||
# TODO: check if nameDB file was created successfully?
|
||||
|
||||
|
||||
# RFC: what is this method useful for?
|
||||
def cbx_inheritance_test(self):
|
||||
print "you lucky widow"
|
||||
|
||||
|
||||
# RFC: why should CryptoBoxProps inherit CryptoBox? [l]
|
||||
# RFC: shouldn't we move all useful functions of CryptoBoxProps to CryptoBox? [l]
|
||||
class CryptoBoxProps(CryptoBox):
|
||||
'''Get and set the properties of a CryptoBox
|
||||
|
||||
|
@ -91,23 +117,16 @@ class CryptoBoxProps(CryptoBox):
|
|||
|
||||
def __init__(self):
|
||||
'''read config and fill class variables'''
|
||||
"enable it again - or remove the priv-dropping"
|
||||
#if os.geteuid() != 0:
|
||||
# sys.stderr.write("You need to be root to run this program!\n")
|
||||
# sys.exit(1)
|
||||
CryptoBox.__init__(self)
|
||||
|
||||
#self.cbx_inheritance_test()
|
||||
#print self.cbxPrefs.items()
|
||||
####
|
||||
|
||||
self.__cboxUID = int(self.cbxPrefs["System"]["User"])
|
||||
self.__cboxGID = int(self.cbxPrefs["System"]["Group"])
|
||||
self.debug = CryptoBoxLogger.CryptoBoxLogger(
|
||||
self.cbxPrefs["Log"]["Level"],
|
||||
self.cbxPrefs["Log"]["Facility"],
|
||||
self.cbxPrefs["Log"]["Destination"])
|
||||
self.dropPrivileges()
|
||||
self.debugMessage = self.debug.printMessage
|
||||
self.containers = []
|
||||
for device in self.__getAvailablePartitions():
|
||||
|
@ -116,7 +135,6 @@ class CryptoBoxProps(CryptoBox):
|
|||
|
||||
def isDeviceAllowed(self, devicename):
|
||||
"check if a device is white-listed for being used as cryptobox containers"
|
||||
"TODO: broken!"
|
||||
allowed = self.cbxPrefs["Main"]["AllowedDevices"]
|
||||
if type(allowed) == types.StringType: allowed = [allowed]
|
||||
for a_dev in allowed:
|
||||
|
@ -170,24 +188,6 @@ class CryptoBoxProps(CryptoBox):
|
|||
return None
|
||||
|
||||
|
||||
def dropPrivileges(self):
|
||||
"change the effective uid to 'User' specified in section 'System'"
|
||||
"enable it again - or remove the priv-dropping"
|
||||
#if os.getuid() != os.geteuid():
|
||||
# raise "PrivilegeManager", "we already dropped privileges"
|
||||
os.seteuid(self.__cboxUID)
|
||||
os.setegid(self.__cboxGID)
|
||||
|
||||
|
||||
def risePrivileges(self):
|
||||
"regain superuser privileges temporarily - call dropPrivileges afterwards!"
|
||||
"enable it again - or remove the priv-dropping"
|
||||
#if os.getuid() == os.geteuid():
|
||||
# raise "PrivilegeManager", "we already have superuser privileges"
|
||||
os.seteuid(os.getuid())
|
||||
os.setegid(os.getgid())
|
||||
|
||||
|
||||
""" ************ internal stuff starts here *********** """
|
||||
|
||||
def __getAvailablePartitions(self):
|
||||
|
@ -310,6 +310,9 @@ DefaultCipher = aes-cbc-essiv:sha256
|
|||
Level = debug
|
||||
Facility = file
|
||||
Destination = /tmp/cryptobox.log
|
||||
[Programs]
|
||||
blkid = /sbin/blkid
|
||||
cryptsetup = /sbin/cryptsetup
|
||||
"""
|
||||
|
||||
def setUp(self):
|
||||
|
@ -318,19 +321,21 @@ Destination = /tmp/cryptobox.log
|
|||
|
||||
|
||||
def tearDown(self):
|
||||
if os.path.exists(self.tmpdir): os.rmdir(self.tmpdir)
|
||||
if os.path.exists(self.configFile): os.remove(self.configFile)
|
||||
if os.path.exists(self.logFile): os.remove(self.logFile)
|
||||
if os.path.exists(self.nameDBFile): os.remove(self.nameDBFile)
|
||||
if os.path.exists(self.tmpdir): os.rmdir(self.tmpdir)
|
||||
|
||||
|
||||
def testConfigFile(self):
|
||||
# RFC: which 'age' did a commit with a broken unittest? [l]
|
||||
CryptoBoxProps()
|
||||
self.assertTrue(os.path.exists(self.nameDBFile))
|
||||
self.assertTrue(os.path.exists(self.logFile))
|
||||
|
||||
|
||||
def testDeviceCheck(self):
|
||||
# RFC: dito [l]
|
||||
cb = CryptoBoxProps()
|
||||
self.assertTrue(cb.isDeviceAllowed("/dev/loop"))
|
||||
self.assertTrue(cb.isDeviceAllowed("/dev/loop1"))
|
||||
|
@ -340,9 +345,9 @@ Destination = /tmp/cryptobox.log
|
|||
self.assertTrue(cb.isDeviceAllowed("/dev/usb/../loop1"))
|
||||
self.assertFalse(cb.isDeviceAllowed("/"))
|
||||
|
||||
"a lot of tests are still missing - how can we provide a prepared environment?"
|
||||
"a lot of tests are still missing - how can we provide a prepared environment?"
|
||||
|
||||
# ********************* run unittest ****************************
|
||||
# ********************* run unittest ****************************
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
|
|
@ -19,15 +19,6 @@ import re
|
|||
|
||||
class CryptoBoxContainer:
|
||||
|
||||
Progs = {
|
||||
"cryptsetup":"/sbin/cryptsetup",
|
||||
"mkfs-data":"/sbin/mkfs.ext3",
|
||||
"mkfs-config":"/sbin/mkfs.ext2",
|
||||
"blkid":"/sbin/blkid",
|
||||
"mount":"/bin/mount",
|
||||
"umount":"/bin/umount"}
|
||||
|
||||
|
||||
Types = {
|
||||
"unused":0,
|
||||
"plain":1,
|
||||
|
@ -47,8 +38,7 @@ class CryptoBoxContainer:
|
|||
self.device = device
|
||||
self.cbox = cbox
|
||||
self.debugMessage = self.cbox.debugMessage
|
||||
self.__dropPrivileges = self.cbox.dropPrivileges
|
||||
self.__risePrivileges = self.cbox.risePrivileges
|
||||
self.Progs = self.cbox.cbxPrefs["Programs"]
|
||||
self.__resetObject()
|
||||
|
||||
|
||||
|
@ -119,7 +109,6 @@ class CryptoBoxContainer:
|
|||
"remove any potential open luks mapping"
|
||||
self.__umountLuks()
|
||||
"create the luks header"
|
||||
self.__risePrivileges()
|
||||
proc = subprocess.Popen(
|
||||
shell = False,
|
||||
stdin = subprocess.PIPE,
|
||||
|
@ -131,7 +120,6 @@ class CryptoBoxContainer:
|
|||
"luksAddKey",
|
||||
self.device])
|
||||
proc.stdin.write("%s\n%s" % (oldpw, newpw))
|
||||
self.__dropPrivileges()
|
||||
(output, errout) = proc.communicate()
|
||||
if proc.returncode != 0:
|
||||
errorMsg = "Could not add a new luks key: %s - %s" % (output.strip(), errout.strip(), )
|
||||
|
@ -143,7 +131,6 @@ class CryptoBoxContainer:
|
|||
else:
|
||||
raise "ChangePasswordError", "could not get the old key slot"
|
||||
"remove the old key"
|
||||
self.__risePrivileges()
|
||||
proc = subprocess.Popen(
|
||||
shell = False,
|
||||
stdin = None,
|
||||
|
@ -156,7 +143,6 @@ class CryptoBoxContainer:
|
|||
self.device,
|
||||
"%d" % (keyslot, )])
|
||||
proc.wait()
|
||||
self.__dropPrivileges()
|
||||
if proc.returncode != 0:
|
||||
errorMsg = "Could not remove the old luks key: %s" % (proc.stderr.read().strip(), )
|
||||
self.debugMessage(CryptoBoxLogger.DebugLevels["error"], errorMsg)
|
||||
|
@ -207,7 +193,6 @@ class CryptoBoxContainer:
|
|||
self.debugMessage(
|
||||
CryptoBoxLogger.DebugLevels["warn"],
|
||||
"Could not open %s" % (os.devnull, ))
|
||||
self.__risePrivileges()
|
||||
proc = subprocess.Popen(
|
||||
shell=False,
|
||||
stdin=None,
|
||||
|
@ -221,7 +206,6 @@ class CryptoBoxContainer:
|
|||
self.device])
|
||||
proc.wait()
|
||||
result = proc.stdout.read().strip()
|
||||
self.__dropPrivileges()
|
||||
if proc.returncode != 0:
|
||||
self.debugMessage(
|
||||
CryptoBoxLogger.DebugLevels["warn"],
|
||||
|
@ -252,7 +236,6 @@ class CryptoBoxContainer:
|
|||
self.debugMessage(
|
||||
CryptoBoxLogger.DebugLevels["warn"],
|
||||
"Could not open %s" % (os.devnull, ))
|
||||
self.__risePrivileges()
|
||||
proc = subprocess.Popen(
|
||||
shell=False,
|
||||
stdin=None,
|
||||
|
@ -266,7 +249,6 @@ class CryptoBoxContainer:
|
|||
self.device])
|
||||
proc.wait()
|
||||
output = proc.stdout.read().strip()
|
||||
self.__dropPrivileges()
|
||||
if proc.returncode != 0:
|
||||
self.debugMessage(
|
||||
CryptoBoxLogger.DebugLevels["warn"],
|
||||
|
@ -285,7 +267,6 @@ class CryptoBoxContainer:
|
|||
self.debugMessage(
|
||||
CryptoBoxLogger.DebugLevels["warn"],
|
||||
"Could not open %s" % (os.devnull, ))
|
||||
self.__risePrivileges()
|
||||
proc = subprocess.Popen(
|
||||
shell = False,
|
||||
stdin = None,
|
||||
|
@ -297,7 +278,6 @@ class CryptoBoxContainer:
|
|||
"isLuks",
|
||||
self.device])
|
||||
proc.wait()
|
||||
self.__dropPrivileges()
|
||||
devnull.close()
|
||||
return proc.returncode == 0
|
||||
|
||||
|
@ -326,7 +306,6 @@ class CryptoBoxContainer:
|
|||
errorMsg = "Could not create mountpoint (%s)" % (self.__getMountPoint(), )
|
||||
self.debugMessage("error", errorMsg)
|
||||
raise "MountError", errorMsg
|
||||
self.__risePrivileges()
|
||||
proc = subprocess.Popen(
|
||||
shell = False,
|
||||
stdin = subprocess.PIPE,
|
||||
|
@ -340,12 +319,10 @@ class CryptoBoxContainer:
|
|||
self.name])
|
||||
proc.stdin.write(password)
|
||||
(output, errout) = proc.communicate()
|
||||
self.__dropPrivileges()
|
||||
if proc.returncode != 0:
|
||||
errorMsg = "Could not open the luks mapping: %s" % (errout.strip(), )
|
||||
self.debugMessage(CryptoBoxLogger.DebugLevels["warn"], errorMsg)
|
||||
raise "MountError", errorMsg
|
||||
self.__risePrivileges()
|
||||
proc = subprocess.Popen(
|
||||
shell = False,
|
||||
stdin = None,
|
||||
|
@ -356,7 +333,6 @@ class CryptoBoxContainer:
|
|||
os.path.join(self.__dmDir, self.name),
|
||||
self.__getMountPoint()])
|
||||
proc.wait()
|
||||
self.__dropPrivileges()
|
||||
if proc.returncode != 0:
|
||||
errorMsg = "Could not mount the filesystem: %s" % (proc.stderr.read().strip(), )
|
||||
self.debugMessage(CryptoBoxLogger.DebugLevels["warn"], errorMsg)
|
||||
|
@ -374,7 +350,6 @@ class CryptoBoxContainer:
|
|||
CryptoBoxLogger.DebugLevels["warn"],
|
||||
"Could not open %s" % (os.devnull, ))
|
||||
if self.isMounted():
|
||||
self.__risePrivileges()
|
||||
proc = subprocess.Popen(
|
||||
shell = False,
|
||||
stdin = None,
|
||||
|
@ -382,13 +357,11 @@ class CryptoBoxContainer:
|
|||
stderr = subprocess.PIPE,
|
||||
args = [self.Progs["umount"], "-l", self.__getMountPoint()])
|
||||
proc.wait()
|
||||
self.__dropPrivileges()
|
||||
if proc.returncode != 0:
|
||||
errorMsg = "Could not umount the filesystem: %s" % (proc.stderr.read().strip(), )
|
||||
self.debugMessage(CryptoBoxLogger.DebugLevels["warn"], errorMsg)
|
||||
raise "MountError", errorMsg
|
||||
if os.path.exists(os.path.join(self.__dmDir, self.name)):
|
||||
self.__risePrivileges()
|
||||
proc = subprocess.Popen(
|
||||
shell = False,
|
||||
stdin = None,
|
||||
|
@ -400,7 +373,6 @@ class CryptoBoxContainer:
|
|||
"luksClose",
|
||||
self.name])
|
||||
proc.wait()
|
||||
self.__dropPrivileges()
|
||||
if proc.returncode != 0:
|
||||
errorMsg = "Could not remove the luks mapping: %s" % (proc.stderr.read().strip(), )
|
||||
self.debugMessage(CryptoBoxLogger.DebugLevels["warn"], errorMsg)
|
||||
|
@ -425,7 +397,6 @@ class CryptoBoxContainer:
|
|||
errorMsg = "Could not create mountpoint (%s)" % (self.__getMountPoint(), )
|
||||
self.debugMessage("error", errorMsg)
|
||||
raise "MountError", errorMsg
|
||||
self.__risePrivileges()
|
||||
proc = subprocess.Popen(
|
||||
shell = False,
|
||||
stdin = None,
|
||||
|
@ -436,7 +407,6 @@ class CryptoBoxContainer:
|
|||
self.device,
|
||||
self.__getMountPoint()])
|
||||
proc.wait()
|
||||
self.__dropPrivileges()
|
||||
if proc.returncode != 0:
|
||||
errorMsg = "Could not mount the filesystem: %s" % (proc.stderr.read().strip(), )
|
||||
self.debugMessage(CryptoBoxLogger.DebugLevels["warn"], errorMsg)
|
||||
|
@ -454,7 +424,6 @@ class CryptoBoxContainer:
|
|||
CryptoBoxLogger.DebugLevels["warn"],
|
||||
"Could not open %s" % (os.devnull, ))
|
||||
if self.isMounted():
|
||||
self.__risePrivileges()
|
||||
proc = subprocess.Popen(
|
||||
shell = False,
|
||||
stdin = None,
|
||||
|
@ -465,7 +434,6 @@ class CryptoBoxContainer:
|
|||
"-l",
|
||||
self.__getMountPoint()])
|
||||
proc.wait()
|
||||
self.__dropPrivileges()
|
||||
if proc.returncode != 0:
|
||||
errorMsg = "Could not umount the filesystem: %s" % (proc.stderr.read().strip(), )
|
||||
self.debugMessage(CryptoBoxLogger.DebugLevels["warn"], errorMsg)
|
||||
|
@ -485,7 +453,6 @@ class CryptoBoxContainer:
|
|||
self.debugMessage(
|
||||
CryptoBoxLogger.DebugLevels["warn"],
|
||||
"Could not open %s" % (os.devnull, ))
|
||||
self.__risePrivileges()
|
||||
proc = subprocess.Popen(
|
||||
shell = False,
|
||||
stdin = None,
|
||||
|
@ -495,7 +462,6 @@ class CryptoBoxContainer:
|
|||
self.Progs["mkfs-data"],
|
||||
self.device])
|
||||
proc.wait()
|
||||
self.__dropPrivileges()
|
||||
if proc.returncode != 0:
|
||||
errorMsg = "Could not create the filesystem: %s" % (proc.stderr.read().strip(), )
|
||||
self.debugMessage(CryptoBoxLogger.DebugLevels["error"], errorMsg)
|
||||
|
@ -520,7 +486,6 @@ class CryptoBoxContainer:
|
|||
"remove any potential open luks mapping"
|
||||
self.__umountLuks()
|
||||
"create the luks header"
|
||||
self.__risePrivileges()
|
||||
proc = subprocess.Popen(
|
||||
shell = False,
|
||||
stdin = subprocess.PIPE,
|
||||
|
@ -535,13 +500,11 @@ class CryptoBoxContainer:
|
|||
self.device])
|
||||
proc.stdin.write(password)
|
||||
(output, errout) = proc.communicate()
|
||||
self.__dropPrivileges()
|
||||
if proc.returncode != 0:
|
||||
errorMsg = "Could not create the luks header: %s" % (errout.strip(), )
|
||||
self.debugMessage("error", errorMsg)
|
||||
raise "CreateError", errorMsg
|
||||
"open the luks container for mkfs"
|
||||
self.__risePrivileges()
|
||||
proc = subprocess.Popen(
|
||||
shell = False,
|
||||
stdin = subprocess.PIPE,
|
||||
|
@ -555,13 +518,11 @@ class CryptoBoxContainer:
|
|||
self.name])
|
||||
proc.stdin.write(password)
|
||||
(output, errout) = proc.communicate()
|
||||
self.__dropPrivileges()
|
||||
if proc.returncode != 0:
|
||||
errorMsg = "Could not open the new luks mapping: %s" % (errout.strip(), )
|
||||
self.debugMessage(CryptoBoxLogger.DebugLevels["error"], errorMsg)
|
||||
raise "CreateError", errorMsg
|
||||
"make the filesystem"
|
||||
self.__risePrivileges()
|
||||
proc = subprocess.Popen(
|
||||
shell = False,
|
||||
stdin = None,
|
||||
|
@ -571,7 +532,6 @@ class CryptoBoxContainer:
|
|||
self.Progs["mkfs-data"],
|
||||
os.path.join(self.__dmDir, self.name)])
|
||||
proc.wait()
|
||||
self.__dropPrivileges()
|
||||
"remove the mapping - for every exit status"
|
||||
self.__umountLuks()
|
||||
if proc.returncode != 0:
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
'''
|
||||
manages logging events of the CryptoBox
|
||||
'''
|
||||
|
||||
import sys
|
||||
import os
|
||||
import syslog
|
||||
import unittest
|
||||
|
||||
class CryptoBoxLogger:
|
||||
|
@ -10,28 +12,35 @@ class CryptoBoxLogger:
|
|||
handles logging events and prints them e.g. to a logfile
|
||||
'''
|
||||
|
||||
DebugLevels = {"debug":0, "info":3, "warn":6, "error":9}
|
||||
DebugFacilities = {"file":0}
|
||||
DebugLevels = {
|
||||
"debug": syslog.LOG_DEBUG,
|
||||
"info": syslog.LOG_INFO,
|
||||
"notice": syslog.LOG_NOTICE,
|
||||
"warn": syslog.LOG_WARNING,
|
||||
"error": syslog.LOG_ERR,
|
||||
"crit": syslog.LOG_CRIT,
|
||||
"alert": syslog.LOG_ALERT,
|
||||
"emerg": syslog.LOG_EMERG}
|
||||
DebugDestinations = {"file":0, "syslog":1}
|
||||
|
||||
def __init__(self, level, facility, destination=None):
|
||||
"""create a CryptoBoxLogger object and connect it to an output facility
|
||||
|
||||
level: an integer (0..9) or string ('debug', 'info', 'warn' or 'error')
|
||||
facility: for now only 'file'
|
||||
destination: e.g. the name of the logfile or syslog facility
|
||||
def __init__(self, level, destination, args=None):
|
||||
"""create a CryptoBoxLogger object and connect it to an output destination
|
||||
|
||||
level: string (debug/info/notice/warn/error/crit/alert/emerg) or syslog level
|
||||
destination: the string "file" or "syslog"
|
||||
args: e.g. the name of the logfile or syslog facility
|
||||
"""
|
||||
try:
|
||||
try:
|
||||
facility = int(facility)
|
||||
destination = int(destination)
|
||||
except Exception:
|
||||
try:
|
||||
facility = self.DebugFacilities[facility]
|
||||
destination = self.DebugDestinations[destination]
|
||||
except KeyError:
|
||||
raise "LoggerError"
|
||||
if (facility != 0): raise "LoggerError"
|
||||
if not destination in self.DebugDestinations.values(): raise "LoggerError"
|
||||
except "LoggerError":
|
||||
errorMsg = "Invalid debug facility: %s" % facility
|
||||
errorMsg = "Invalid debug destination: %s" % destination
|
||||
sys.stderr.write(errorMsg + "\n")
|
||||
raise "LoggerError", errorMsg
|
||||
try:
|
||||
|
@ -42,16 +51,16 @@ class CryptoBoxLogger:
|
|||
level = self.DebugLevels[level]
|
||||
except KeyError:
|
||||
raise "LoggerError"
|
||||
if (level < 0) or (level > 9): raise "LoggerError"
|
||||
if not level in self.DebugLevels.values(): raise "LoggerError"
|
||||
except "LoggerError":
|
||||
errorMsg = "Invalid debug level: %s" % level
|
||||
sys.stderr.write(errorMsg + "\n")
|
||||
raise "LoggerError", errorMsg
|
||||
self.debug_level = level
|
||||
if facility == self.DebugFacilities["file"]:
|
||||
if destination == self.DebugDestinations["file"]:
|
||||
self.logFunc = self.message2file
|
||||
if destination is not None:
|
||||
self.logFile = destination
|
||||
if args is not None:
|
||||
self.logFile = args
|
||||
else:
|
||||
self.logFile = '/var/log/cryptobox.log'
|
||||
try:
|
||||
|
@ -61,7 +70,12 @@ class CryptoBoxLogger:
|
|||
errorMsg ="Unable to open logfile (%s) for writing." % (self.logFile,)
|
||||
sys.stderr.write(errorMsg + "\n")
|
||||
raise "LoggerError", errorMsg
|
||||
|
||||
elif destination == self.DebugDestinations["syslog"]:
|
||||
self.logFunc = self.message2syslog
|
||||
if args is None:
|
||||
syslog.openlog("CryptoBox", 0, syslog.LOG_USER)
|
||||
else:
|
||||
syslog.openlog("CryptoBox", 0, args)
|
||||
else:
|
||||
errorMsg = "Invalid logging facility: %d." % (facility, )
|
||||
sys.stderr.write(errorMsg + "\n")
|
||||
|
@ -80,7 +94,7 @@ class CryptoBoxLogger:
|
|||
errorMsg = "Invalid debug level: %s" % msg_level
|
||||
sys.stderr.write(errorMsg + "\n")
|
||||
raise "LoggerError", errorMsg
|
||||
if (msg_level < 0) or (msg_level > 9):
|
||||
if not msg_level in self.DebugLevels.values():
|
||||
errorMsg = "Invalid debug level: %s" % msg_level
|
||||
sys.stderr.write(errorMsg + "\n")
|
||||
raise "LoggerError", errorMsg
|
||||
|
@ -88,15 +102,16 @@ class CryptoBoxLogger:
|
|||
errorMsg = "Empty debug message - this is not allowed"
|
||||
sys.stderr.write(errorMsg + "\n")
|
||||
raise "LoggerError", errorMsg
|
||||
if msg_level >= self.debug_level:
|
||||
self.logFunc("[CryptoBox] - %s\n" % (text, ))
|
||||
if msg_level <= self.debug_level:
|
||||
self.logFunc(text, msg_level)
|
||||
|
||||
|
||||
def message2file(self, text):
|
||||
def message2file(self, text, level):
|
||||
# "level" gets ignored (but syslog needs it)
|
||||
try:
|
||||
log_sock = open(self.logFile, "a")
|
||||
try:
|
||||
log_sock.writelines(text)
|
||||
log_sock.writelines("[CryptoBox] - %s\n" % (text, ))
|
||||
log_sock.close()
|
||||
return
|
||||
except IOError:
|
||||
|
@ -105,10 +120,18 @@ class CryptoBoxLogger:
|
|||
raise "LoggerError", errorMsg
|
||||
except IOError:
|
||||
errorMsg = "Unable to open logfile (%s) for writing." % (self.logFile, )
|
||||
sys.stderr.write(errorMsg + "\n")
|
||||
sys.stderr.write("[CryptoBox] - %s\n" % (errorMsg, ))
|
||||
raise "LoggerError", errorMsg
|
||||
|
||||
|
||||
def message2syslog(self, text, level):
|
||||
syslog_level = [self.DebugLevels[e]
|
||||
for e in self.DebugLevels.keys()
|
||||
if self.DebugLevels[e] == level
|
||||
][0]
|
||||
syslog.syslog(syslog_level, text)
|
||||
|
||||
|
||||
# ********************* test class **********************
|
||||
|
||||
class CryptoBoxLoggerTest(unittest.TestCase):
|
||||
|
@ -118,47 +141,60 @@ class CryptoBoxLoggerTest(unittest.TestCase):
|
|||
def setUp(self):
|
||||
if os.path.exists(self.logFile): os.remove(self.logFile)
|
||||
|
||||
|
||||
def tearDown(self):
|
||||
if os.path.exists(self.logFile): os.remove(self.logFile)
|
||||
|
||||
|
||||
def testInit(self):
|
||||
"""Initialization should fail for invalid parameters"""
|
||||
try:
|
||||
CryptoBoxLogger(0, 0)
|
||||
CryptoBoxLogger(syslog.LOG_ERR, 0)
|
||||
except "LoggerError":
|
||||
CryptoBoxLogger(0, 0, self.logFile)
|
||||
CryptoBoxLogger(syslog.LOG_ERR, 0, self.logFile)
|
||||
os.remove(self.logFile)
|
||||
CryptoBoxLogger("info", "file", self.logFile)
|
||||
self.assertRaises("LoggerError", CryptoBoxLogger, "invalid", 0, self.logFile)
|
||||
self.assertRaises("LoggerError", CryptoBoxLogger, 0, "invalid", self.logFile)
|
||||
self.assertRaises("LoggerError", CryptoBoxLogger, 10, 0, self.logFile)
|
||||
self.assertRaises("LoggerError", CryptoBoxLogger, syslog.LOG_ERR, "invalid", self.logFile)
|
||||
self.assertRaises("LoggerError", CryptoBoxLogger, 3353, 0, self.logFile)
|
||||
self.assertRaises("LoggerError", CryptoBoxLogger, -1, 0, self.logFile)
|
||||
self.assertRaises("LoggerError", CryptoBoxLogger, 0, 10, self.logFile)
|
||||
self.assertRaises("LoggerError", CryptoBoxLogger, 0, -1, self.logFile)
|
||||
self.assertRaises("LoggerError", CryptoBoxLogger, syslog.LOG_INFO, self.logFile)
|
||||
self.assertRaises("LoggerError", CryptoBoxLogger, syslog.LOG_CRIT, -1, self.logFile)
|
||||
self.assertRaises("LoggerError", CryptoBoxLogger, None, 0, self.logFile)
|
||||
self.assertRaises("LoggerError", CryptoBoxLogger, 0, None, self.logFile)
|
||||
self.assertRaises("LoggerError", CryptoBoxLogger, 0, 0, "/no/existing/path")
|
||||
os.remove(self.logFile)
|
||||
self.assertRaises("LoggerError", CryptoBoxLogger, syslog.LOG_WARNING, None, self.logFile)
|
||||
self.assertRaises("LoggerError", CryptoBoxLogger, syslog.LOG_EMERG, 0, "/no/existing/path")
|
||||
|
||||
def testMessage(self):
|
||||
cb = CryptoBoxLogger(3, 0, self.logFile)
|
||||
|
||||
def testOutputParams(self):
|
||||
"""Output should fail for invalid parameters"""
|
||||
cb = CryptoBoxLogger(syslog.LOG_ERR, 0, self.logFile)
|
||||
self.assertRaises("LoggerError", cb.printMessage, 3353, "Ausgabe")
|
||||
self.assertRaises("LoggerError", cb.printMessage, -1, "Ausgabe")
|
||||
self.assertRaises("LoggerError", cb.printMessage, "invalid", "Ausgabe")
|
||||
self.assertRaises("LoggerError", cb.printMessage, syslog.LOG_DEBUG, None)
|
||||
|
||||
def testFile(self):
|
||||
"""Do not write messages below specified priority to a file"""
|
||||
cb = CryptoBoxLogger(syslog.LOG_ERR, 0, self.logFile)
|
||||
content1 = self.readFile()
|
||||
self.assertEquals(content1, "")
|
||||
cb.printMessage(3, "Ausgabe")
|
||||
cb.printMessage(syslog.LOG_ERR, "Ausgabe")
|
||||
content2 = self.readFile()
|
||||
self.assertNotEqual(content1, content2)
|
||||
self.assertRaises("LoggerError", cb.printMessage, 10, "Ausgabe")
|
||||
cb.printMessage(syslog.LOG_DEBUG, "Ausgabe")
|
||||
self.assertEquals(content2, self.readFile())
|
||||
self.assertRaises("LoggerError", cb.printMessage, -1, "Ausgabe")
|
||||
self.assertEquals(content2, self.readFile())
|
||||
self.assertRaises("LoggerError", cb.printMessage, "invalid", "Ausgabe")
|
||||
self.assertEquals(content2, self.readFile())
|
||||
self.assertRaises("LoggerError", cb.printMessage, 3, None)
|
||||
self.assertEquals(content2, self.readFile())
|
||||
cb.printMessage(2, "Ausgabe")
|
||||
self.assertEquals(content2, self.readFile())
|
||||
cb.printMessage(4, "Ausgabe")
|
||||
cb.printMessage(syslog.LOG_CRIT, "Ausgabe")
|
||||
self.assertNotEqual(content2, self.readFile())
|
||||
os.remove(self.logFile)
|
||||
|
||||
|
||||
def testSyslog(self):
|
||||
"""Check syslog output"""
|
||||
cb = CryptoBoxLogger(syslog.LOG_DEBUG, "syslog")
|
||||
cb.printMessage(syslog.LOG_DEBUG, "just a verification check")
|
||||
"""sorry - we do not have a way to check, if something was written somewhere
|
||||
so we cannot do other checks beside initialization and writing"""
|
||||
|
||||
|
||||
|
||||
def readFile(self):
|
||||
fd = None
|
||||
|
|
|
@ -1,131 +0,0 @@
|
|||
#!/usr/bin/env python
|
||||
'''
|
||||
read and write configuration
|
||||
|
||||
This Class is derived mainly from 'gimini' project.
|
||||
Thanx to Dutoit! <dutoitc(at)hotmail.com>
|
||||
'''
|
||||
|
||||
from ConfigParser import *
|
||||
import sys, os
|
||||
|
||||
### Set the Preferences filename
|
||||
|
||||
|
||||
class Preferences:
|
||||
"""
|
||||
This class handles preferences and stores them into given configfile
|
||||
|
||||
To use it :
|
||||
- instanciate a Preferences object :
|
||||
myPP=Preferences()
|
||||
- to get a preference :
|
||||
mypref=myPP["ma_preference"]
|
||||
- to set a preference :
|
||||
myPP["ma_preference"]=xxx
|
||||
|
||||
The preferences are automatically loaded on the first instanciation of this
|
||||
class and are saved when a value is added or changed automatically, too.
|
||||
"""
|
||||
def __init__(self, filename):
|
||||
"""
|
||||
Constructor
|
||||
|
||||
@author C.Dutoit <dutoitc@hotmail.com>
|
||||
"""
|
||||
self.prefsfilename = filename
|
||||
self._config = None
|
||||
self.__loadConfig()
|
||||
|
||||
#>--------------------------------------------------------------------------
|
||||
|
||||
def __getitem__(self, name):
|
||||
"""
|
||||
Return the preferences for the given item
|
||||
|
||||
@param String name : Name of the item for which we return a value
|
||||
@return String : value of the pref, or None if inexistant
|
||||
@since 1.1.2.7
|
||||
@author C.Dutoit <dutoitc@hotmail.com>
|
||||
"""
|
||||
if not self._config.has_section("Main"):
|
||||
print "No section: \"[Main]\""
|
||||
return None
|
||||
|
||||
try:
|
||||
return self._config.get("Main", name)
|
||||
except NoOptionError:
|
||||
print "No such option: \"" + name +"\""
|
||||
return None
|
||||
|
||||
#>--------------------------------------------------------------------------
|
||||
|
||||
def __setitem__(self, name, value):
|
||||
"""
|
||||
Return the preferences for the given item
|
||||
|
||||
@param String name : Name of the item WITHOUT SPACES
|
||||
@param String Value : Value for the given name
|
||||
@raises TypeError : if the name contains spaces
|
||||
@since 1.1.2.7
|
||||
@author C.Dutoit <dutoitc@hotmail.com>
|
||||
"""
|
||||
# Add 'Main' section ?
|
||||
if not self._config.has_section("Main"):
|
||||
self._config.add_section("Main")
|
||||
|
||||
if " " in list(name):
|
||||
raise TypeError, "Name cannot contain a space"
|
||||
|
||||
# Save
|
||||
self._config.set("Main", name, str(value))
|
||||
self.__saveConfig()
|
||||
|
||||
#>--------------------------------------------------------------------------
|
||||
|
||||
def __saveConfig(self):
|
||||
"""
|
||||
Save datas to config file
|
||||
|
||||
@since 1.1.2.5
|
||||
@author C.Dutoit <dutoitc@hotmail.com>
|
||||
"""
|
||||
f=open(self.prefsfilename, "w")
|
||||
self._config.write(f)
|
||||
f.close()
|
||||
|
||||
#>--------------------------------------------------------------------------
|
||||
|
||||
def __loadConfig(self):
|
||||
"""
|
||||
Load datas from config file
|
||||
|
||||
@since 1.1.2.5
|
||||
@author C.Dutoit <dutoitc@hotmail.com>
|
||||
"""
|
||||
# Make sure that the configuration file exist
|
||||
try:
|
||||
f = open(self.prefsfilename, "r")
|
||||
f.close()
|
||||
except:
|
||||
try:
|
||||
f = open(self.prefsfilename, "w")
|
||||
f.write("")
|
||||
f.close()
|
||||
except:
|
||||
print "Can't make %s for saving preferences !" % self.prefsfilename
|
||||
return
|
||||
|
||||
|
||||
# Read datas
|
||||
self._config=ConfigParser()
|
||||
self._config.read(self.prefsfilename)
|
||||
|
||||
#>--------------------------------------------------------------------------
|
||||
|
||||
if __name__ == "__main__":
|
||||
myPP=Preferences()
|
||||
mypref=myPP["ma_preference"]
|
||||
myPP["ma_preference"]="xxx"
|
||||
|
||||
|
|
@ -46,7 +46,7 @@ Facility = file
|
|||
# file: $FILENAME
|
||||
# syslog: $LOG_FACILITY
|
||||
# The log file will get created as root and then handed over to the
|
||||
# cryptobox user 8see above)
|
||||
# cryptobox user (see above)
|
||||
#Destination = /var/log/cryptobox.log
|
||||
Destination = ./cryptobox.log
|
||||
|
||||
|
@ -63,3 +63,12 @@ Language = de
|
|||
DocDir = ../doc/html
|
||||
#default language for documentation
|
||||
DocLang = en
|
||||
|
||||
[Programs]
|
||||
cryptsetup = /sbin/cryptsetup
|
||||
mkfs-data = /sbin/mkfs.ext3
|
||||
mkfs-config = /sbin/mkfs.ext2
|
||||
blkid = /sbin/blkid
|
||||
mount = /bin/mount
|
||||
umount = /bin/umount
|
||||
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
import os,tempfile,dircache,string,commands
|
||||
"""I suppose this stuff should be inside some class?"""
|
||||
|
||||
# RFC: which of these methods do we need more than once?
|
||||
# or: these actions are too short for methods - or not? [l]
|
||||
|
||||
def read_file(filename):
|
||||
"""
|
||||
read from the file whose name is given
|
||||
|
|
|
@ -33,15 +33,15 @@ def main():
|
|||
|
||||
testElement = cb.getContainerList()[0]
|
||||
print "\nRunning some tests now ..."
|
||||
if not luke_tests(testElement):
|
||||
if not plain_tests(testElement):
|
||||
print "some previous tests failed - we should stop now"
|
||||
sys.exit(1)
|
||||
plain_tests(testElement)
|
||||
luks_tests(testElement)
|
||||
|
||||
|
||||
" ***************** some functions ******************** "
|
||||
|
||||
def luke_tests(e):
|
||||
def luks_tests(e):
|
||||
e.create(e.Types["luks"], "alt")
|
||||
print "\tluks create:\tok"
|
||||
|
||||
|
@ -90,4 +90,9 @@ def plain_tests(e):
|
|||
if e.isMounted(): print "\tplain umount:\tfailed"
|
||||
else: print "\tplain umount:\tok"
|
||||
|
||||
if e.isMounted(): return False
|
||||
else: return True
|
||||
|
||||
# ************ main ****************
|
||||
|
||||
main()
|
||||
|
|
Loading…
Reference in a new issue