Lars' poland path #2

This commit is contained in:
age 2006-08-27 08:38:48 +00:00
parent 175cb831ad
commit f450e116a7
8 changed files with 173 additions and 220 deletions

View file

@ -21,6 +21,7 @@ import os
import unittest import unittest
import logging import logging
import subprocess import subprocess
from CryptoBoxExceptions import *
CONF_LOCATIONS = [ CONF_LOCATIONS = [
"./cryptobox.conf", "./cryptobox.conf",
@ -34,11 +35,6 @@ class CryptoBox:
put things like logging, conf and oter stuff in here, put things like logging, conf and oter stuff in here,
that might be used by more classes, it will be passed on to them''' that might be used by more classes, it will be passed on to them'''
def __init__(self, config_file=None): def __init__(self, config_file=None):
# choose an exit function
if __name__ == "__main__":
self.errorExit = self.errorExitProg
else:
self.errorExit = self.errorExitMod
self.__initLogging() self.__initLogging()
self.__initPreferences(config_file) self.__initPreferences(config_file)
self.__runTests() self.__runTests()
@ -65,14 +61,14 @@ class CryptoBox:
self.log.info("loggingsystem is up'n running") self.log.info("loggingsystem is up'n running")
## from now on everything can be logged via self.log... ## from now on everything can be logged via self.log...
except: except:
self.errorExit("SystemError","Couldn't initialise the loggingsystem. I give up.") raise CBEnvironmentError("couldn't initialise the loggingsystem. I give up.")
def __initPreferences(self, config_file): def __initPreferences(self, config_file):
try: try:
import configobj ## needed for reading and writing of the config file import configobj ## needed for reading and writing of the config file
except: except:
self.errorExit("SystemError", "Couldn't import 'configobj'! Try 'apt-get install python-configobj'.") raise CBEnvironmentError("couldn't import 'configobj'! Try 'apt-get install python-configobj'.")
# search for the configuration file # search for the configuration file
if config_file is None: if config_file is None:
# no config file was specified - we will look for it in the ususal locations # no config file was specified - we will look for it in the ususal locations
@ -81,31 +77,29 @@ class CryptoBox:
if os.path.exists(os.path.expanduser(f))] if os.path.exists(os.path.expanduser(f))]
if not conf_file_list: if not conf_file_list:
# no possible config file found in the usual locations # no possible config file found in the usual locations
self.errorExit("ConfigError", "No configuration file found - sorry!") raise CBConfigUnavailableError()
config_file = conf_file_list[0] config_file = conf_file_list[0]
else: else:
# a config file was specified (e.g. via command line) # a config file was specified (e.g. via command line)
if type(config_file) != types.StringType: if type(config_file) != types.StringType:
self.errorExit("ConfigError","Invalid config file specified: %s" % config_file) raise CBConfigUnavailableError("invalid config file specified: %s" % config_file)
if not os.path.exists(config_file): if not os.path.exists(config_file):
self.errorExit("ConfigError","Could not find the specified configuration file (%s)" % config_file) raise CBConfigUnavailableError("could not find the specified configuration file (%s)" % config_file)
try: try:
self.cbxPrefs = configobj.ConfigObj(config_file) self.cbxPrefs = configobj.ConfigObj(config_file)
if self.cbxPrefs: if self.cbxPrefs:
self.log.info("found config: %s" % self.cbxPrefs.items()) self.log.info("found config: %s" % self.cbxPrefs.items())
else: else:
self.errorExit("ConfigError","failed to load the config file: %s" % config_file) raise CBConfigUnavailableError("failed to load the config file: %s" % config_file)
except IOError: except IOError:
self.errorExit("ConfigError","unable to open the config file: %s" % config_file) raise CBConfigUnavailableError("unable to open the config file: %s" % config_file)
try: try:
try: try:
nameDB_file = os.path.join( nameDB_file = self.cbxPrefs["Locations"]["NameDatabase"]
self.cbxPrefs["Main"]["DataDir"],
self.cbxPrefs["Main"]["NameDatabase"])
except KeyError: except KeyError:
self.errorExit("ConfigError","could not find one of these configuration settings: [Main]->DataDir and [Main]->NameDatabase - please check your config file(%s)" % config_file) raise CBConfigUndefinedError("Locations", "NameDatabase")
except SyntaxError: except SyntaxError:
self.errorExit("ConfigError","Error during parsing of name database file (%s).\n" % (nameDB_file, )) raise CBConfigInvalidValueError("Locations", "NameDatabase", nameDB_file, "failed to interprete the filename of the name database correctly")
## create nameDB is necessary ## create nameDB is necessary
if os.path.exists(nameDB_file): if os.path.exists(nameDB_file):
self.nameDB = configobj.ConfigObj(nameDB_file) self.nameDB = configobj.ConfigObj(nameDB_file)
@ -113,54 +107,78 @@ class CryptoBox:
self.nameDB = configobj.ConfigObj(nameDB_file, create_empty=True) self.nameDB = configobj.ConfigObj(nameDB_file, create_empty=True)
## check if nameDB file was created successfully? ## check if nameDB file was created successfully?
if not os.path.exists(nameDB_file): if not os.path.exists(nameDB_file):
self.errorExit("ConfigError","failed to create name database (%s)" % nameDB_file) raise CBEnvironmentError("failed to create name database (%s)" % nameDB_file)
# get the loglevel # get the loglevel
try: try:
log_level = self.cbxPrefs["Log"]["Level"].upper() log_level = self.cbxPrefs["Log"]["Level"].upper()
log_level_avail = ["DEBUG", "INFO", "WARN", "ERROR"] log_level_avail = ["DEBUG", "INFO", "WARN", "ERROR"]
if not log_level in log_level_avail: if not log_level in log_level_avail:
self.errorExit("ConfigError","invalid log level: %s is not in %s" % (self.cbxPrefs["Log"]["Level"], log_level_avail)) raise TypeError
except KeyError: except KeyError:
self.errorExit("ConfigError","could not find the configuration setting [Log]->Level in the config file (%s)" % config_file) raise CBConfigUndefinedError("Log", "Level")
except TypeError: except TypeError:
self.errorExit("ConfigError","invalid log level: %s" % self.cbxPrefs["Log"]["Level"]) raise CBConfigInvalidValueError("Log", "Level", log_level, "invalid log level: only %s are allowed" % log_level_avail)
try: try:
try: try:
new_handler = logging.FileHandler(self.cbxPrefs["Log"]["Details"]) new_handler = logging.FileHandler(self.cbxPrefs["Log"]["Details"])
except KeyError: except KeyError:
self.errorExit("ConfigError","could not find a configuration setting: [Log]->Details - please check your config file(%s)" % config_file) raise CBConfigUndefinedError("Log", "Details")
except IOError:
raise CBEnvironmentError("could not create the log file (%s)" % self.cbxPrefs["Log"]["Details"])
new_handler.setFormatter(logging.Formatter('%(asctime)s %(module)s %(levelname)s: %(message)s')) new_handler.setFormatter(logging.Formatter('%(asctime)s %(module)s %(levelname)s: %(message)s'))
self.log.addHandler(new_handler) self.log.addHandler(new_handler)
## do not call parent's handlers ## do not call parent's handlers
self.log.propagate = False self.log.propagate = False
## use 'getattr' as 'log_level' is a string ## 'log_level' is a string -> use 'getattr'
self.log.setLevel(getattr(logging,log_level)) self.log.setLevel(getattr(logging,log_level))
except IOError:
self.errorExit("ConfigError","could not open logfile: %s" % self.cbxPrefs["Log"]["Details"])
# do some initial checks # do some initial checks
def __runTests(self): def __runTests(self):
## try to run 'super' with 'CryptoBoxRootActions' self.__runTestRootPriv()
self.__runTestLocations()
def __runTestLocations(self):
"""check if all configured locations exist"""
try:
conf_locations = self.cbxPrefs["Locations"]
except KeyError:
raise CBConfigUndefinedError("Locations")
try:
for key in ["MountParentDir", "NameDatabase", "TemplateDir", "LangDir", "DocDir"]:
value = self.cbxPrefs["Locations"][key]
#if not (os.path.exists(value) and os.access(value, os.R_OK)):
if not os.access(value, os.R_OK):
raise CBConfigInvalidValueError("Locations", key, value, "could not access")
except KeyError:
raise CBConfigUndefinedError("Locations", key)
def __runTestRootPriv(self):
"""try to run 'super' with 'CryptoBoxRootActions'"""
try: try:
devnull = open(os.devnull, "w") devnull = open(os.devnull, "w")
except IOError: except IOError:
self.errorExit("SystemError","Could not open %s for writing!" % os.devnull) raise CBEnvironmentError("could not open %s for writing!" % os.devnull)
try:
prog_super = self.cbxPrefs["Programs"]["super"]
except KeyError:
raise CBConfigUndefinedError("Programs", "super")
try:
prog_rootactions = self.cbxPrefs["Programs"]["CryptoBoxRootActions"]
except KeyError:
raise CBConfigUndefinedError("Programs", "CryptoBoxRootActions")
try: try:
proc = subprocess.Popen( proc = subprocess.Popen(
shell = False, shell = False,
stdout = devnull, stdout = devnull,
stderr = devnull, stderr = devnull,
args = [ self.cbxPrefs["Programs"]["super"], args = [prog_super, prog_rootactions, "check"])
self.cbxPrefs["Programs"]["CryptoBoxRootActions"],
"check"])
except OSError: except OSError:
self.errorExit("ConfigError","could not find: %s" % self.cbxPrefs["Programs"]["super"]) raise CBEnvironmentError("failed to execute 'super' (%s)" % self.cbxPrefs["Programs"]["super"])
except KeyError:
self.errorExit("ConfigError","could not find one of these configurations settings: [Programs]->super or [Programs]->CryptoBoxRootActions in the config file")
proc.wait() proc.wait()
if proc.returncode != 0: if proc.returncode != 0:
self.errorExit("ConfigError","Could not call CryptoBoxRootActions by 'super' - maybe you did not add the appropriate line to /etc/super.tab?") raise CBEnvironmentError("failed to call CryptoBoxRootActions (%s) via 'super' - maybe you did not add the appropriate line to /etc/super.tab?" % prog_rootactions)
# this method just demonstrates inheritance effects - may be removed # this method just demonstrates inheritance effects - may be removed
@ -168,27 +186,6 @@ class CryptoBox:
self.log.info(string) self.log.info(string)
def errorExitMod(self, title, msg, code=1):
"""output an error message and quit by raising an exception
this function should be used if this class was used as a module instead
of as a standalone program
"""
self.log.error(msg)
raise title, msg
def errorExitProg(self, title, msg, code=1):
"""output an error message and quit by calling sys.exit
this function should be used if this class was used as a standalone
program
"""
self.log.error(msg)
sys.exit(code)
# RFC: why should CryptoBoxProps inherit CryptoBox? [l] # RFC: why should CryptoBoxProps inherit CryptoBox? [l]
# RFC: shouldn't we move all useful functions of CryptoBoxProps to CryptoBox? [l] # RFC: shouldn't we move all useful functions of CryptoBoxProps to CryptoBox? [l]
@ -230,13 +227,12 @@ class CryptoBoxProps(CryptoBox):
the maximum number and size of these entries can be limited by 'lines' and 'maxSize' the maximum number and size of these entries can be limited by 'lines' and 'maxSize'
""" """
# return nothing if the currently selected log output is not a file # return nothing if the currently selected log output is not a file
empty = [""]
try: try:
if self.cbxPrefs["Log"]["Destination"].upper() != "FILE": return empty if self.cbxPrefs["Log"]["Destination"].upper() != "FILE": return []
log_file = self.cbxPrefs["Log"]["Details"] log_file = self.cbxPrefs["Log"]["Details"]
except KeyError: except KeyError:
self.log.error("could not evaluate one of the following config settings: [Log]->Destination or [Log]->Details") self.log.error("could not evaluate one of the following config settings: [Log]->Destination or [Log]->Details")
return empty return []
try: try:
fd = open(log_file, "r") fd = open(log_file, "r")
if maxSize: content = fd.readlines(maxSize) if maxSize: content = fd.readlines(maxSize)
@ -244,7 +240,7 @@ class CryptoBoxProps(CryptoBox):
fd.close() fd.close()
except IOError: except IOError:
self.log.warn("failed to read the log file (%s)" % log_file) self.log.warn("failed to read the log file (%s)" % log_file)
return empty return []
if lines: content = content[-lines:] if lines: content = content[-lines:]
return content return content

View file

@ -293,7 +293,7 @@ class CryptoBoxContainer:
def __getMountPoint(self): def __getMountPoint(self):
"return the name of the mountpoint of this volume" "return the name of the mountpoint of this volume"
return os.path.join(self.cbox.cbxPrefs["System"]["MountParentDir"], self.name) return os.path.join(self.cbox.cbxPrefs["Locations"]["MountParentDir"], self.name)
def __mountLuks(self, password): def __mountLuks(self, password):
@ -559,9 +559,9 @@ class CryptoBoxContainer:
def __cleanMountDirs(self): def __cleanMountDirs(self):
""" remove all unnecessary subdirs of the mount parent directory """ remove all unnecessary subdirs of the mount parent directory
this should be called for every (u)mount """ this should be called for every (u)mount """
subdirs = os.listdir(self.cbox.cbxPrefs["System"]["MountParentDir"]) subdirs = os.listdir(self.cbox.cbxPrefs["Locations"]["MountParentDir"])
for dir in subdirs: for dir in subdirs:
abs_dir = os.path.join(self.cbox.cbxPrefs["System"]["MountParentDir"], dir) abs_dir = os.path.join(self.cbox.cbxPrefs["Locations"]["MountParentDir"], dir)
if (not os.path.islink(abs_dir)) and os.path.isdir(abs_dir) and (not os.path.ismount(abs_dir)): if (not os.path.islink(abs_dir)) and os.path.isdir(abs_dir) and (not os.path.ismount(abs_dir)):
os.rmdir(abs_dir) os.rmdir(abs_dir)

View file

@ -44,20 +44,9 @@ def isWriteable(device, force_dev_type=None):
if dev_type != force_dev_type: return False if dev_type != force_dev_type: return False
# retrieve the information for the real user id # retrieve the information for the real user id
(trustUserName, trustUID, groupsOfTrustUser) = getUserInfo(os.getuid()) (trustUserName, trustUID, groupsOfTrustUser) = getUserInfo(os.getuid())
trustGIDs = []
try:
"if 'allowedGroups' are defined, then ignore the previously aquired groups"
"TODO: for now only group ids (no names) are allowed"
trustGIDs.extend(allowedGroups)
except NameError:
"'allowedGroups' was not defined - we use the default ones of the user"
trustGIDs.extend(groupsOfTrustUser)
except TypeError:
"if it fails, then 'allowedGroups' was really not well defined"
trustGIDs.append(allowedGID)
# set the default groups of the caller for the check (restore them later) # set the default groups of the caller for the check (restore them later)
savedGroups = os.getgroups() savedGroups = os.getgroups()
os.setgroups(trustGIDs) os.setgroups(groupsOfTrustUser)
# check permissions # check permissions
result = os.access(device, os.W_OK) and os.access(device, os.R_OK) result = os.access(device, os.W_OK) and os.access(device, os.R_OK)
# reset the groups of this process # reset the groups of this process

View file

@ -19,12 +19,12 @@ class CryptoBoxWebserverRender:
website.log.info("rendering site: "+website.settings["Data.Action"]) website.log.info("rendering site: "+website.settings["Data.Action"])
cs_path = website.cbxPrefs["Settings"]["TemplateDir"]+"/main.cs" cs_path = website.cbxPrefs["Locations"]["TemplateDir"]+"/main.cs"
if not os.access(cs_path, os.R_OK): if not os.access(cs_path, os.R_OK):
website.log.error("Couldn't read cs file: %s" % cs_path) website.log.error("Couldn't read cs file: %s" % cs_path)
return "Couldn't read cs file: %s" % cs_path return "Couldn't read cs file: %s" % cs_path
hdf_path = website.cbxPrefs["Settings"]["LangDir"]+"/"+website.cbxPrefs["Settings"]["Language"]+".hdf" hdf_path = website.cbxPrefs["Locations"]["LangDir"]+"/"+website.cbxPrefs["Settings"]["Language"]+".hdf"
if not os.access(hdf_path, os.R_OK): if not os.access(hdf_path, os.R_OK):
website.log.error("Couldn't read hdf file: %s" % hdf_path) website.log.error("Couldn't read hdf file: %s" % hdf_path)
return "Couldn't read hdf file: %s" % hdf_path return "Couldn't read hdf file: %s" % hdf_path

View file

@ -36,20 +36,21 @@ class CryptoBoxWebserverSites(CryptoBox.CryptoBoxProps, CryptoBoxWebserverSettin
sanitizing input automatically for all sites. sanitizing input automatically for all sites.
# RFC: why shouldn't it be called in __init__? [l] # RFC: why shouldn't it be called in __init__? [l]
''' '''
#TODO: generate languages from existing hdf files niceparams = { 'weblang': tuple(self.__getAvailableLanguages()),
niceparams = { 'weblang': ('', 'de', 'en'),
'loglevel': ('','info', 'warn', 'debug', 'error'), 'loglevel': ('','info', 'warn', 'debug', 'error'),
'type': ('reboot', 'poweroff') 'type': ('reboot', 'poweroff')
} }
for evilkey in evilparams.keys(): for evilkey in evilparams.keys():
## if the param isn't in the niceparams list, ignore it ## if the param isn't in the niceparams list, ignore it
if not niceparams.get(evilkey): if not niceparams.get(evilkey):
self.log.warn("ignoring \"%s\"" % evilkey) self.log.warn('ignoring "%s"' % evilkey)
# RFC: why "return False"? - just ignoring is sufficient
return False return False
#TODO: until now only a warning message is printed #TODO: until now only a warning message is printed
## if the param has no such value, set it to a default (the first in the list) ## if the param has no such value, set it to a default (the first in the list)
if evilparams.get(evilkey) not in niceparams.get(evilkey): if evilparams.get(evilkey) not in niceparams.get(evilkey):
self.log.warn("\"%s\" not in weblang %s"% (evilkey, niceparams.get(evilkey))) self.log.warn('"%s" not in weblang %s' % (evilkey, niceparams.get(evilkey)))
# RFC: why "weblang"?
#TODO: set it to: niceparams.get(evilkey)[0])) #TODO: set it to: niceparams.get(evilkey)[0]))
return return
@ -63,6 +64,44 @@ class CryptoBoxWebserverSites(CryptoBox.CryptoBoxProps, CryptoBoxWebserverSettin
#TODO #TODO
pass pass
def __getAvailableLanguages(self):
import re, os
regpat = re.compile(r"^\w+\.hdf$")
try:
lang_dir = self.cbxPrefs["Locations"]["LangDir"]
except KeyError:
self.log.error("Could not find a configuration setting: [Locations]->LangDir - please check the config file")
return []
if not os.path.exists(lang_dir):
self.log.error("The configured language directory (%s) does not exist" % (lang_dir, ))
return []
try:
return [ e[:-4] for e in os.listdir(lang_dir) if regpat.search(e)]
except OSError:
self.log.error("Could not access the language directory (%s)" % (lang_dir,))
return []
def __getAvailableDocLanguages(self):
import re, os
regpat = re.compile(r"^\w+$")
try:
doc_dir = self.cbxPrefs["Locations"]["DocDir"]
except KeyError:
self.log.error("Could not find a configuration setting: [Locations]->DocDir - please check the config file")
return []
if not os.path.exists(doc_dir):
self.log.error("The configured documentation directory (%s) does not exist" % (doc_dir, ))
return []
try:
return [ e for e in os.listdir(doc_dir)
if regpat.search(e) and os.path.isdir(os.path.join(doc_dir, e))]
except OSError:
self.log.error("Could not access the documentations directory (%s)" % (doc_dir,))
return []
###################################################################### ######################################################################
## put real sites down here and don't forget to expose them at the end ## put real sites down here and don't forget to expose them at the end
@ -78,10 +117,7 @@ class CryptoBoxWebserverSites(CryptoBox.CryptoBoxProps, CryptoBoxWebserverSettin
''' '''
self.__sanitize_input({"loglevel":loglevel}) self.__sanitize_input({"loglevel":loglevel})
self.__prepare("show_log") self.__prepare("show_log")
import filehandling
self.settings["Data.Log"] = "<br/>".join(self.getLogData(lines=30, maxSize=2000)) self.settings["Data.Log"] = "<br/>".join(self.getLogData(lines=30, maxSize=2000))
#TODO: give the logs a nice format for displaying as html
# sed s/$/<\/br>/
return website.render(self) return website.render(self)
def status(self, weblang=""): def status(self, weblang=""):
@ -117,11 +153,13 @@ class CryptoBoxWebserverSites(CryptoBox.CryptoBoxProps, CryptoBoxWebserverSettin
self.__prepare("show_doc") self.__prepare("show_doc")
if page: if page:
self.settings["Data.Doc.Page"] = page self.settings["Data.Doc.Page"] = page
if page == "": else:
self.settings["Data.Doc.Page"] ="CryptoBoxUser" self.settings["Data.Doc.Page"] ="CryptoBoxUser"
if not weblang == "": if weblang:
# TODO: check if there is a 'weblang' translation available for the docs if weblang in self.__getAvailableDocLanguages():
self.settings["Settings.DocLang"] = weblang self.settings["Settings.DocLang"] = weblang
else:
self.log.warn("invalid documentation language selected: %s", % (weblang, ))
return website.render(self) return website.render(self)
@ -163,8 +201,8 @@ class CryptoBoxWebserverSites(CryptoBox.CryptoBoxProps, CryptoBoxWebserverSettin
#-------------------------------------------------------# #-------------------------------------------------------#
################ umount_do ####################### ################ umount_do #######################
elif action == "unmount_do": elif action == "unmount_do":
if device == "": if not device:
#TODO: debug message: "invalid device: "+ device self.log.debug("invalid device chosen: %s" device
settings["Data.Warning"] = "InvalidDevice" settings["Data.Warning"] = "InvalidDevice"
settings["Data.Action"] = "empty" settings["Data.Action"] = "empty"
elif not True: #TODO: replace True with check_config() elif not True: #TODO: replace True with check_config()
@ -187,10 +225,10 @@ class CryptoBoxWebserverSites(CryptoBox.CryptoBoxProps, CryptoBoxWebserverSettin
settings["Data.Action"] = "show_volume" settings["Data.Action"] = "show_volume"
################ mount_do ######################## ################ mount_do ########################
elif action == "mount_do": elif action == "mount_do":
if device != "": if device:
pass #TODO: is_encrypted = check_device_encryption(device) pass #TODO: is_encrypted = check_device_encryption(device)
if device == "": else:
#TODO: debug_msg(DEBUG_INFO, "invalid device: " + device) self.log.debug("invalid device chosen: %s" device
settings["Data.Warning"] = "InvalidDevice" settings["Data.Warning"] = "InvalidDevice"
settings["Data.Action"] = "empty" settings["Data.Action"] = "empty"
elif not True: #TODO: replace True with check_config() elif not True: #TODO: replace True with check_config()
@ -208,3 +246,4 @@ class CryptoBoxWebserverSites(CryptoBox.CryptoBoxProps, CryptoBoxWebserverSettin
system.exposed = True system.exposed = True
status.exposed = True status.exposed = True

View file

@ -4,36 +4,38 @@
# beware: .e.g "/dev/hd" grants access to _all_ harddisks # beware: .e.g "/dev/hd" grants access to _all_ harddisks
AllowedDevices = /dev/loop AllowedDevices = /dev/loop
# the default prefix of not yet named containers # the default name prefix of not unnamed containers
DefaultVolumePrefix = "Data " DefaultVolumePrefix = "Data "
# where should we put the local configuration and the mountpoints?
# this directory must be accessible by the cryptobox user (see below)
#DataDir = /var/cache/cryptobox
DataDir = .
# the name-database file - inside of DataDir
NameDatabase = cryptobox_names.db
[System]
# most actions of the cryptobox are not executed as root - choose a limited
# user and group here - for now only numeric ids are allowed
User = 1000
Group = 1000
# where should we mount volumes?
# this directory must be writeable by the cryptobox user (see above)
MountParentDir = /var/cache/cryptobox/mnt
# which cipher should cryptsetup-luks use? # which cipher should cryptsetup-luks use?
DefaultCipher = aes-cbc-essiv:sha256 DefaultCipher = aes-cbc-essiv:sha256
[Locations]
# where should we mount volumes?
# this directory must be writeable by the cryptobox user (see above)
MountParentDir = /var/cache/cryptobox/mnt
# the name-database file - inside of DataDir
#NameDatabase = /var/cache/cryptobox/cryptobox_names.db
NameDatabase = cryptobox_names.db
# where are the clearsilver templates?
#TemplateDir = /usr/share/cryptobox/templates
TemplateDir = ../templates
# path to language files
#LangDir = /usr/share/cryptobox/lang
LangDir = ../lang
# path to documentation files
#DocDir = /usr/share/doc/cryptobox/html
DocDir = ../doc/html
[Log] [Log]
# possible values are "debug", "info", "warn" and "error" or numbers from # possible values are "debug", "info", "warn" and "error" or numbers from
# 0 (debug) to 9 (error) # 0 (debug) to 7 (error)
Level = debug Level = debug
# where to write the log messages to? # where to write the log messages to?
@ -48,20 +50,18 @@ Destination = file
#Details = /var/log/cryptobox.log #Details = /var/log/cryptobox.log
Details = ./cryptobox.log Details = ./cryptobox.log
[Settings]
#default stylesheet [WebSettings]
# URL of default stylesheet
Stylesheet = cryptobox.css Stylesheet = cryptobox.css
#where are the clearsilver templates?
TemplateDir = ../templates
#path to language files
LangDir = ../lang
# default language # default language
Language = de Language = de
#path to documentation files
DocDir = ../doc/html
# default language for documentation # default language for documentation
DocLang = de DocLang = de
[Programs] [Programs]
cryptsetup = /sbin/cryptsetup cryptsetup = /sbin/cryptsetup
mkfs-data = /sbin/mkfs.ext3 mkfs-data = /sbin/mkfs.ext3
@ -70,6 +70,6 @@ blkid = /sbin/blkid
mount = /bin/mount mount = /bin/mount
umount = /bin/umount umount = /bin/umount
super = /usr/bin/super super = /usr/bin/super
# this is the "program" name as defined in the /etc/super.tab # this is the "program" name as defined in /etc/super.tab
CryptoBoxRootActions = CryptoBoxRootActions CryptoBoxRootActions = CryptoBoxRootActions

View file

@ -1,71 +0,0 @@
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
@param filename String : name of file to read from
@return String: content of given file or None
"""
try:
f = open(filename,"r")
filecontent = f.read()
f.close()
except:
#TODO:if debug >=1:
print "(EE)[%s]: \"%s\" is not readable!"%(__name__, filename)
return ""
return filecontent
def is_dir_readable(path):
"""
Gets the name of a directory.
returns True if dir is readable, else False.
"""
return os.access(path,os.R_OK)
def write_file(filename,content):
"""
Write content to the given filename.
gets: filename,content.
"""
try:
f = open(filename,"w")#oeffnen und schliessen =>
f.close() #datei ist jetzt genullt
f = open(filename,"a") #anhaengend oeffnen
f.write(content)
f.close()
return ""
except:
#TODO: debug
#if self.debug >=1:
print "(EE)[%s]: \"%s\" is not writeable!"%(__name__, filename)
return filename
def basename(filename):
return os.path.basename(filename)
def gen_temp_dir(prefix='cryptobox--'):
'''returns the name of a secure temporary directory
with optional prefix as parameter'''
dirname=tempfile.mkdtemp("",prefix)
dirname+="/"
return dirname
def gen_temp_file(suffix="--cryptobox"):
"""
returns the name of a generated temporay file.
optionally gets a suffix for the filename.
"""
return tempfile.mkstemp(suffix)[1]

View file

@ -2,6 +2,7 @@
import unittest import unittest
import sys import sys
from CryptoBox import *
class CryptoBoxPropsDeviceTests(unittest.TestCase): class CryptoBoxPropsDeviceTests(unittest.TestCase):
import CryptoBox import CryptoBox
@ -38,13 +39,13 @@ class CryptoBoxPropsConfigTests(unittest.TestCase):
[Main] [Main]
AllowedDevices = /dev/loop AllowedDevices = /dev/loop
DefaultVolumePrefix = "Data " DefaultVolumePrefix = "Data "
DataDir = %s
NameDatabase = cryptobox_names.db
[System]
User = 1000
Group = 1000
MountParentDir = %s/mnt
DefaultCipher = aes-cbc-essiv:sha256 DefaultCipher = aes-cbc-essiv:sha256
[Locations]
NameDatabase = %s/cryptobox_names.db
MountParentDir = %s
TemplateDir = ../templates
LangDir = ../lang
DocDir = ../doc/html
[Log] [Log]
Level = debug Level = debug
Destination = file Destination = file
@ -82,29 +83,28 @@ CryptoBoxRootActions = CryptoBoxRootActions
def testConfigInit(self): def testConfigInit(self):
'''Check various branches of config file loading''' '''Check various branches of config file loading'''
import os import os
self.assertRaises("ConfigError", self.CryptoBox.CryptoBoxProps,"/invalid/path/to/config/file") self.assertRaises(CBConfigUnavailableError, self.CryptoBox.CryptoBoxProps,"/invalid/path/to/config/file")
self.assertRaises("ConfigError", self.CryptoBox.CryptoBoxProps,"/etc/shadow") self.assertRaises(CBConfigUnavailableError, self.CryptoBox.CryptoBoxProps,"/etc/shadow")
for a in self.CryptoBox.CONF_LOCATIONS: for a in self.CryptoBox.CONF_LOCATIONS:
if os.path.exists(a): self.CryptoBox.CryptoBoxProps() if os.path.exists(a): self.CryptoBox.CryptoBoxProps()
else: self.assertRaises("ConfigError", self.CryptoBox.CryptoBoxProps) else: self.assertRaises(CBConfigUnavailableError, self.CryptoBox.CryptoBoxProps)
self.CryptoBox.CryptoBoxProps(self.filenames["configFileOK"]) self.CryptoBox.CryptoBoxProps(self.filenames["configFileOK"])
self.assertRaises("ConfigError", self.CryptoBox.CryptoBoxProps,[]) self.assertRaises(CBConfigUnavailableError, self.CryptoBox.CryptoBoxProps,[])
def testBrokenConfigs(self): def testBrokenConfigs(self):
"""Check various broken configurations""" """Check various broken configurations"""
self.writeConfig("NameDatabase", "#out", filename=self.filenames["configFileBroken"]) self.writeConfig("NameDatabase", "#out", filename=self.filenames["configFileBroken"])
self.assertRaises("ConfigError", self.CryptoBox.CryptoBoxProps,self.filenames["configFileBroken"]) self.assertRaises(CBConfigUndefinedError, self.CryptoBox.CryptoBoxProps,self.filenames["configFileBroken"])
self.writeConfig("Level", "#out", filename=self.filenames["configFileBroken"]) self.writeConfig("Level", "#out", filename=self.filenames["configFileBroken"])
self.assertRaises("ConfigError", self.CryptoBox.CryptoBoxProps,self.filenames["configFileBroken"]) self.assertRaises(CBConfigUndefinedError, self.CryptoBox.CryptoBoxProps,self.filenames["configFileBroken"])
self.writeConfig("Details", "#out", filename=self.filenames["configFileBroken"]) self.writeConfig("Details", "#out", filename=self.filenames["configFileBroken"])
self.assertRaises("ConfigError", self.CryptoBox.CryptoBoxProps,self.filenames["configFileBroken"]) self.assertRaises(CBConfigUndefinedError, self.CryptoBox.CryptoBoxProps,self.filenames["configFileBroken"])
self.writeConfig("super", "super=/bin/invalid/no", filename=self.filenames["configFileBroken"]) self.writeConfig("super", "super=/bin/invalid/no", filename=self.filenames["configFileBroken"])
self.assertRaises("ConfigError", self.CryptoBox.CryptoBoxProps,self.filenames["configFileBroken"]) self.assertRaises(CBEnvironmentError, self.CryptoBox.CryptoBoxProps,self.filenames["configFileBroken"])
self.writeConfig("CryptoBoxRootActions", "#not here", filename=self.filenames["configFileBroken"]) self.writeConfig("CryptoBoxRootActions", "#not here", filename=self.filenames["configFileBroken"])
self.assertRaises("ConfigError", self.CryptoBox.CryptoBoxProps,self.filenames["configFileBroken"]) self.assertRaises(CBConfigUndefinedError, self.CryptoBox.CryptoBoxProps,self.filenames["configFileBroken"])
self.writeConfig("CryptoBoxRootActions", "CryptoBoxRootActions = /bin/false", filename=self.filenames["configFileBroken"]) self.writeConfig("CryptoBoxRootActions", "CryptoBoxRootActions = /bin/false", filename=self.filenames["configFileBroken"])
self.assertRaises("ConfigError", self.CryptoBox.CryptoBoxProps,self.filenames["configFileBroken"]) self.assertRaises(CBEnvironmentError, self.CryptoBox.CryptoBoxProps,self.filenames["configFileBroken"])
# TODO: check details of different ConfigError-exceptions
def writeConfig(self, replace=None, newline=None, filename=None): def writeConfig(self, replace=None, newline=None, filename=None):