From 7443b4684e3a57337e59de80714e427de3d1f47b Mon Sep 17 00:00:00 2001 From: lars Date: Wed, 16 Aug 2006 18:17:16 +0000 Subject: [PATCH] class CryptoBoxContainer finished --- pythonrewrite/bin2/CryptoBox.py | 217 ++++++--- pythonrewrite/bin2/CryptoBoxContainer.py | 569 ++++++++++++++++++++++- pythonrewrite/bin2/cbox.log | 4 + pythonrewrite/bin2/cbx.conf | 8 +- pythonrewrite/bin2/classes.txt | 12 - 5 files changed, 735 insertions(+), 75 deletions(-) diff --git a/pythonrewrite/bin2/CryptoBox.py b/pythonrewrite/bin2/CryptoBox.py index 913e1e3..9f30c52 100644 --- a/pythonrewrite/bin2/CryptoBox.py +++ b/pythonrewrite/bin2/CryptoBox.py @@ -1,17 +1,19 @@ #!/usr/bin/env python ''' This is a secure fileserver with encrypted filesystem and webinterface. - + It was originally written in bash/perl. Now a complete rewrite is in progress. So things might be confusing here. Hopefully not for long. :) ''' -import re + import CryptoBoxLogger import CryptoBoxContainer import CryptoBoxPreferences +import re +import os -CONFIG_FILE="cbx.conf" +CONFIG_FILE = "cbx.conf" class CryptoBoxProps: '''Get and set the properties of a CryptoBox @@ -20,43 +22,116 @@ class CryptoBoxProps: be used further. ''' + def __init__(self): '''read config and fill class variables''' print CONFIG_FILE self.cbxPrefs = CryptoBoxPreferences.Preferences(CONFIG_FILE) self.debug = CryptoBoxLogger.CryptoBoxLogger( - self.cbxPrefs["debuglevel"], - self.cbxPrefs["debugfacility"], - self.cbxPrefs["logfile"] ) - self.alloweddevices = self.__csv2list(self.cbxPrefs["allowed_devices"]) + self.cbxPrefs["debuglevel"], + self.cbxPrefs["debugfacility"], + self.cbxPrefs["logfile"] ) + "TODO: move this to config file" + self.config = {} + self.config["ContainerNameDatabase"] = { + "4edc83f1-9ecd-4182-820f-b7815725a957":"Alpha", + "7dee9ef8-d69a-400b-8b74-33d828d8bea6":"Beta"} + self.containers = [] + for device in self.__getAvailablePartitions(): + if self.isDeviceAllowed(device): + self.containers.append(CryptoBoxContainer.CryptoBoxContainer(device, self, self.debug)) - def __csv2list(self, csvstring): - '''transform a csv preferences string into a list''' - commalist = csvstring.split(",") # split the csv by "," - list = [] - for element in commalist: - list.append(element.strip()) # remove whitespaces - return list - def __deviceIsReallyAllowed(self, device): - '''return "true" if the given device is white-listed for being used as cryptobox container''' - for a in self.alloweddevices: - if re.search('^' + a, device): - return True + def debugMessage(self, level, text): + "print a debug message to the previously choosen debugging facility" + self.debug.printMessage(level,text) - def __allAvailablePartitions(self): - '''retrieve a list of all available containers - - TODO: if the code is not like a poem, write prosadocumentation ;) - ''' + + def isDeviceAllowed(self, devicename): + "check if a device is white-listed for being used as cryptobox containers" + "TODO: broken!" + for a_dev in self.cbxPrefs["allowed_devices"]: + if a_dev and re.search('^' + a_dev, devicename): return True + return False + + + def getConfigValue(self, name): + "returns the value of a config setting" + try: + "TODO: return copy instead of original" + return self.cbxPrefs[name] + except KeyError: + return None + + + def setConfigValue(self, name, value): + "set the value of a config setting" + if not name: return False + try: + self.cbxPrefs[name] = value + except AttributeError: + self.cbxPrefs = {} + self.cbxPrefs[name] = value + + + def getContainerList(self, filterType=None, filterName=None): + "retrieve the list of all containers of this cryptobox" + try: + result = self.containers[:] + if filterType != None: + if filterType in range(len(CryptoBoxContainer.Types)): + return [e for e in self.containers if e.getType() == filterType] + else: + self.logger.debugMessage( + CryptoBoxLogger.DebugLevels["info"], + "invalid filterType (%d)" % filterType) + result.clear() + if filterName != None: + result = [e for e in self.containers if e.getName() == filterName] + return result + except AttributeError: + return [] + + + def setNameForUUID(self, uuid, name): + "assign a name to a uuid in the ContainerNameDatabase" + used_uuid = self.getUUIDForName(name) + "first remove potential conflicting uuid/name combination" + if used_uuid: del self.config["ContainerNameDatabase"][used_uuid] + self.config["ContainerNameDatabase"][uuid] = name + + + def getNameForUUID(self, uuid): + "get the name belonging to a specified key (usually the UUID of a fs)" + try: + return self.config["ContainerNameDatabase"][uuid] + except KeyError: + return None + + + def getUUIDForName(self, name): + """ get the key belonging to a value in the ContainerNameDatabase + this is the reverse action of 'getNameForUUID' """ + for key in self.config["ContainerNameDatabase"].keys(): + if self.config["ContainerNameDatabase"][key] == name: return key + "the uuid was not found" + return None + + + """ ************ internal stuff starts here *********** """ + + def __getAvailablePartitions(self): + "retrieve a list of all available containers" ret_list = [] try: + "the following reads all lines of /proc/partitions and adds the mentioned devices" fpart = open("/proc/partitions", "r") try: line = fpart.readline() while line: p_details = line.split() if (len(p_details) == 4): + "the following code prevents double entries like /dev/hda and /dev/hda1" (p_major, p_minor, p_size, p_device) = p_details if re.search('^[0-9]*$', p_major) and re.search('^[0-9]*$', p_minor): p_parent = re.sub('[1-9]?[0-9]$', '', p_device) @@ -74,44 +149,80 @@ class CryptoBoxProps: line = fpart.readline() finally: fpart.close() - return ["/dev/" + e for e in ret_list] + return [self.__getAbsoluteDeviceName(e) for e in ret_list] except IOError: self.debugMessage( "Could not read /proc/partitions", CryptoBoxLogger.DebugLevels["warn"]) return [] - def debugMessage(self, level, text): - '''print a debug message to the previously choosen debugging facility''' - self.debug.printMessage(level,text) - def getContainerList(self): - '''return a list of all actual available containers of this cryptobox''' - self.containers = [] - for device in self.__allAvailablePartitions(): - if self.__deviceIsReallyAllowed(device): - self.containers.append(CryptoBoxContainer.CryptoBoxContainer(device)) + def __getAbsoluteDeviceName(self, shortname): + """ returns the absolute file name of a device (e.g.: "hda1" -> "/dev/hda1") + this does also work for device mapper devices + if the result is non-unique, one arbitrary value is returned""" + if re.search('^/', shortname): return shortname + default = os.path.join("/dev", shortname) + if os.path.exists(default): return default + result = self.__findMajorMinorOfDevice(shortname) + "if no valid major/minor was found -> exit" + if not result: return default + (major, minor) = result + "for device-mapper devices (major == 254) ..." + if major == 254: + result = self.__findMajorMinorDeviceName("/dev/mapper", major, minor) + if result: return result[0] + "now check all files in /dev" + result = self.__findMajorMinorDeviceName("/dev", major, minor) + if result: return result[0] + return default + + + def __findMajorMinorOfDevice(self, device): + "return the major/minor numbers of a block device by querying /sys/block/?/dev" + if not os.path.exists(os.path.join("/sys/block", device)): return None + blockdev_info_file = os.path.join(os.path.join("/sys/block", device), "dev") try: - return self.containers[:] - except AttributeError: - return None + f_blockdev_info = open(blockdev_info_file, "r") + blockdev_info = f_blockdev_info.read() + f_blockdev_info.close() + (str_major, str_minor) = blockdev_info.split(":") + "numeric conversion" + try: + major = int(str_major) + minor = int(str_minor) + return (major, minor) + except ValueError: + "unknown device numbers -> stop guessing" + return None + except IOError: + pass - def getConfigValue(self, key): - '''return a tuple of key+value from the configfile''' - return (key, self.cbxPrefs[key]) - def setConfigValue(self, key, value): - '''save the strings key+value in configfile''' - self.cbxPrefs[key]=value + def __findMajorMinorDeviceName(self, dir, major, minor): + "returns the names of devices with the specified major and minor number" + collected = [] + try: + subdirs = [os.path.join(dir, e) for e in os.listdir(dir) if (not os.path.islink(os.path.join(dir, e))) and os.path.isdir(os.path.join(dir, e))] + "do a recursive call to parse the directory tree" + for dirs in subdirs: + collected.extend(self.__findMajorMinorDeviceName(dirs, major, minor)) + "filter all device inodes in this directory" + collected.extend([os.path.realpath(os.path.join(dir, e)) for e in os.listdir(dir) if (os.major(os.stat(os.path.join(dir, e)).st_rdev) == major) and (os.minor(os.stat(os.path.join(dir, e)).st_rdev) == minor)]) + result = [] + for e in collected: + if e not in result: result.append(e) + return collected + except OSError: + return [] + + + def __csv2list(self, csvstring): + '''transform a csv preferences string into a list''' + commalist = csvstring.split(",") # split the csv by "," + list = [] + for element in commalist: + list.append(element.strip()) # remove whitespaces + return list -if __name__ == "__main__": - ''' - Start the Cryptobox with: `python CryptoBox.py` - ''' - cbprops = CryptoBoxProps() - #print "Allowed_Devices: %s" % (cb.getConfigValue("allowed_devices"), ) - #print "non-existing: %s" % (cb.getConfigValue("alowed_devices"), ) - print [e.device for e in cbprops.getContainerList()] - print "Config %s" % str(cbprops.getConfigValue("logfile")) - #cbprops.setConfigValue("foo","bar") diff --git a/pythonrewrite/bin2/CryptoBoxContainer.py b/pythonrewrite/bin2/CryptoBoxContainer.py index f71fe9f..e3e3d6e 100644 --- a/pythonrewrite/bin2/CryptoBoxContainer.py +++ b/pythonrewrite/bin2/CryptoBoxContainer.py @@ -1,13 +1,568 @@ -''' -TODO -''' +from CryptoBoxLogger import CryptoBoxLogger +import subprocess +import os +import re + +"""exceptions: + VolumeIsActive + InvalidName + NameActivelyUsed + InvalidPassword + InvalidType + MountError + ChangePasswordError + """ + class CryptoBoxContainer: - ''' - TODO - ''' - def __init__(self, device): + 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, + "luks":2, + "swap":3} + + + __fsTypes = { + "plain":["ext3", "ext2", "vfat", "reiser"], + "swap":["swap"]} + "TODO: mehr Dateisystemtypen? / 'reiser' pruefen" + + __dmDir = "/dev/mapper" + + + def __init__(self, device, cbox, logger): self.device = device + self.logger = logger + self.cbox = cbox + self.__resetObject() + def getName(self): + return self.name + + + def setName(self, new_name): + "TODO: den Test-Code pruefen" + if new_name == self.name: return + if self.isMounted(): + raise "VolumeIsActive", "the container must be inactive during renaming" + if not re.search(r'^[a-zA-Z0-9_\.\- ]$', new_name): + raise "InvalidName", "the supplied new name contains illegal characters" + "check for active partitions with the same name" + prev_name_owner = self.cbox.getContainerList(filterName=new_name) + if prev_name_owner: + for a in prev_name_owner: + if a.isMounted(): + raise "NameActivelyUsed", "the supplied new name is already in use for an active partition" + self.cbox.setNameForUUID(self.uuid, new_name) + self.name = new_name + + + def getDevice(self): + return self.device + + + def getType(self): + return self.type + + + def isMounted(self): + return os.path.ismount(self.__getMountPoint()) + + + def create(self, type, password=None): + if type == self.Types["luks"]: + self.__createLuks(password) + self.__resetObject() + return + if type == self.Types["plain"]: + self.__createPlain() + self.__resetObject() + return + raise "InvalidType", "invalid container type (%d) supplied" % (type, ) + + + def changePassword(self, oldpw, newpw): + if self.type != self.Types["luks"]: + raise "InvalidType", \ + "changing of password is possible only for luks containers" + if not oldpw: + raise "InvalidPassword", "no old password supplied for password change" + if not newpw: + raise "InvalidPassword", "no new password supplied for password change" + "return if new and old passwords are the same" + if oldpw == newpw: return + if self.isMounted(): + raise "VolumeIsActive", "this container is currently active" + devnull = None + try: + devnull = open(os.devnull, "w") + except IOError: + self.logger.printMessage( + CryptoBoxLogger.DebugLevels["warn"], + "Could not open %s" % (os.devnull, )) + "remove any potential open luks mapping" + self.__umountLuks() + "create the luks header" + proc = subprocess.Popen( + shell = False, + stdin = subprocess.PIPE, + stdout = subprocess.PIPE, + stderr = subprocess.PIPE, + args = [ + self.Progs["cryptsetup"], + "--batch-mode", + "luksAddKey", + self.device]) + proc.stdin.write("%s\n%s" % (oldpw, newpw)) + (output, errout) = proc.communicate() + if proc.returncode != 0: + errorMsg = "Could not add a new luks key: %s - %s" % (output.strip(), errout.strip(), ) + self.logger.printMessage( + CryptoBoxLogger.DebugLevels["error"], + errorMsg) + raise "ChangePasswordError", errorMsg + keys_found = re.search(r'key slot (\d{1,3}) unlocked', output).groups() + if keys_found: + keyslot = int(keys_found[0]) + else: + raise "ChangePasswordError", "could not get the old key slot" + "remove the old key" + proc = subprocess.Popen( + shell = False, + stdin = None, + stdout = devnull, + stderr = subprocess.PIPE, + args = [ + self.Progs["cryptsetup"], + "--batch-mode", + "luksDelKey", + self.device, + "%d" % (keyslot, )]) + proc.wait() + if proc.returncode != 0: + errorMsg = "Could not remove the old luks key: %s" % (proc.stderr.read().strip(), ) + self.logger.printMessage( + CryptoBoxLogger.DebugLevels["error"], + errorMsg) + raise "ChangePasswordError", errorMsg + + + + " ****************** internal stuff ********************* " + + def __resetObject(self): + """ recheck the information about this container + this is especially useful after changing the type via 'create' """ + self.uuid = self.__getUUID() + self.type = self.__getTypeOfPartition() + self.name = self.__getNameOfContainer() + if self.type == self.Types["luks"]: + self.mount = self.__mountLuks + self.umount = self.__umountLuks + if self.type == self.Types["plain"]: + self.mount = self.__mountPlain + self.umount = self.__umountPlain + + + def __getNameOfContainer(self): + "retrieve the name of the container by querying the database" + def_name = self.cbox.getNameForUUID(self.uuid) + if def_name: return def_name + "there is no name defined for this uuid - we will propose a good one" + prefix = self.cbox.getConfigValue("DefaultNamePrefix") + unused_found = False + counter = 1 + while not unused_found: + guess = prefix + str(counter) + if self.cbox.getUUIDForName(guess): + counter += 1 + else: + unused_found = True + self.cbox.setNameForUUID(self.uuid, guess) + return guess + + + def __getUUID(self): + """return UUID for luks partitions, ext2/3 and vfat filesystems""" + devnull = None + try: + devnull = open(os.devnull, "w") + except IOError: + self.logger.printMessage( + CryptoBoxLogger.DebugLevels["warn"], + "Could not open %s" % (os.devnull, )) + proc = subprocess.Popen( + shell=False, + stdin=None, + stdout=subprocess.PIPE, + stderr=devnull, + args=[self.Progs["blkid"], + "-s", "UUID", + "-o", "value", + "-c", os.devnull, + "-w", os.devnull, + self.device]) + proc.wait() + if proc.returncode != 0: + self.logger.printMessage( + CryptoBoxLogger.DebugLevels["warn"], + "retrieving of partition type via 'blkid' failed: %s" % (proc.stderr.read().strip(), )) + return None + result = proc.stdout.read().strip() + devnull.close() + if result: return result + return self.device.replace(os.path.sep, "_") + + + def __getTypeOfPartition(self): + "retrieve the type of the given partition (see CryptoBoxContainer.Types)" + if self.__isLuksPartition(): return self.Types["luks"] + typeOfPartition = self.__getTypeIdOfPartition() + if typeOfPartition in self.__fsTypes["plain"]: + return self.Types["plain"] + if typeOfPartition in self.__fsTypes["swap"]: + return self.Types["swap"] + return self.Types["unused"] + + + def __getTypeIdOfPartition(self): + "returns the type of the partition (see 'man blkid')" + devnull = None + try: + devnull = open(os.devnull, "w") + except IOError: + self.logger.printMessage( + CryptoBoxLogger.DebugLevels["warn"], + "Could not open %s" % (os.devnull, )) + proc = subprocess.Popen( + shell=False, + stdin=None, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + args=[self.Progs["blkid"], + "-s", "TYPE", + "-o", "value", + "-c", os.devnull, + "-w", os.devnull, + self.device]) + proc.wait() + if proc.returncode != 0: + self.logger.printMessage( + CryptoBoxLogger.DebugLevels["warn"], + "retrieving of partition type via 'blkid' failed: %s" % (proc.stderr.read().strip(), )) + return None + output = proc.stdout.read().strip() + devnull.close() + return output + + + def __isLuksPartition(self): + "check if the given device is a luks partition" + devnull = None + try: + devnull = open(os.devnull, "w") + except IOError: + self.logger.printMessage( + CryptoBoxLogger.DebugLevels["warn"], + "Could not open %s" % (os.devnull, )) + proc = subprocess.Popen( + shell = False, + stdin = None, + stdout = devnull, + stderr = devnull, + args = [ + self.Progs["cryptsetup"], + "--batch-mode", + "isLuks", + self.device]) + proc.wait() + devnull.close() + return proc.returncode == 0 + + + def __getMountPoint(self): + "return the name of the mountpoint of this volume" + return os.path.join(self.cbox.getConfigValue("MountParent"), self.name) + + + def __mountLuks(self, password): + "mount a luks partition" + if not password: + raise "InvalidPassword", "no password supplied for luksOpen" + if self.isMounted(): raise "VolumeIsActive", "this container is already active" + self.__umountLuks() + try: + devnull = open(os.devnull, "w") + except IOError: + self.logger.printMessage( + CryptoBoxLogger.DebugLevels["warn"], + "Could not open %s" % (os.devnull, )) + proc = subprocess.Popen( + shell = False, + stdin = subprocess.PIPE, + stdout = devnull, + stderr = subprocess.PIPE, + args = [ + self.Progs["cryptsetup"], + "luksOpen", + "--batch-mode", + self.device, + self.name]) + proc.stdin.write(password) + (output, errout) = proc.communicate() + if proc.returncode != 0: + errorMsg = "Could not open the luks mapping: %s" % (errout.strip(), ) + self.logger.printMessage( + CryptoBoxLogger.DebugLevels["warn"], + errorMsg) + raise "MountError", errorMsg + proc = subprocess.Popen( + shell = False, + stdin = None, + stdout = devnull, + stderr = devnull, + args = [ + self.Progs["mount"], + os.path.join(self.__dmDir, self.name), + self.__getMountPoint()]) + proc.wait() + if proc.returncode != 0: + errorMsg = "Could not mount the filesystem: %s" % (proc.stderr.read().strip(), ) + self.logger.printMessage( + CryptoBoxLogger.DebugLevels["warn"], + errorMsg) + raise "MountError", errorMsg + devnull.close() + + + def __umountLuks(self): + "umount a luks partition" + devnull = None + try: + devnull = open(os.devnull, "w") + except IOError: + self.logger.printMessage( + CryptoBoxLogger.DebugLevels["warn"], + "Could not open %s" % (os.devnull, )) + if self.isMounted(): + proc = subprocess.Popen( + shell = False, + stdin = None, + stdout = devnull, + stderr = devnull, + args = [self.Progs["umount"], "-l", self.__getMountPoint()]) + proc.wait() + if proc.returncode != 0: + errorMsg = "Could not umount the filesystem: %s" % (proc.stderr.read().strip(), ) + self.logger.printMessage( + CryptoBoxLogger.DebugLevels["warn"], + errorMsg) + raise "MountError", errorMsg + if os.path.exists(os.path.join(self.__dmDir, self.name)): + proc = subprocess.Popen( + shell = False, + stdin = None, + stdout = devnull, + stderr = subprocess.PIPE, + args = [ + self.Progs["cryptsetup"], + "--batch-mode", + "luksClose", + self.name]) + proc.wait() + if proc.returncode != 0: + errorMsg = "Could not remove the luks mapping: %s" % (proc.stderr.read().strip(), ) + self.logger.printMessage( + CryptoBoxLogger.DebugLevels["warn"], + errorMsg) + raise "MountError", errorMsg + devnull.close() + + + def __mountPlain(self): + "mount a plaintext partition" + devnull = None + try: + devnull = open(os.devnull, "w") + except IOError: + self.logger.printMessage( + CryptoBoxLogger.DebugLevels["warn"], + "Could not open %s" % (os.devnull, )) + self.__cleanMountDirs() + if not os.path.exists(self.__getMountPoint()): + os.mkdir(self.__getMountPoint()) + proc = subprocess.Popen( + shell = False, + stdin = None, + stdout = devnull, + stderr = subprocess.PIPE, + args = [ + self.Progs["mount"], + self.device, + self.__getMountPoint()]) + proc.wait() + if proc.returncode != 0: + errorMsg = "Could not mount the filesystem: %s" % (proc.stderr.read().strip(), ) + self.logger.printMessage( + CryptoBoxLogger.DebugLevels["warn"], + errorMsg) + raise "MountError", errorMsg + devnull.close() + + + def __umountPlain(self): + "umount a plaintext partition" + devnull = None + try: + devnull = open(os.devnull, "w") + except IOError: + self.logger.printMessage( + CryptoBoxLogger.DebugLevels["warn"], + "Could not open %s" % (os.devnull, )) + proc = subprocess.Popen( + shell = False, + stdin = None, + stdout = devnull, + stderr = subprocess.PIPE, + args = [ + self.Progs["umount"], + "-l", + self.__getMountPoint()]) + proc.wait() + if proc.returncode != 0: + errorMsg = "Could not umount the filesystem: %s" % (proc.stderr.read().strip(), ) + self.logger.printMessage( + CryptoBoxLogger.DebugLevels["warn"], + errorMsg) + raise "MountError", errorMsg + devnull.close() + + + def __createPlain(self): + "make a plaintext partition" + if self.isMounted(): + raise "VolumeIsActive", \ + "deactivate the partition before filesystem initialization" + devnull = None + try: + devnull = open(os.devnull, "w") + except IOError: + self.logger.printMessage( + CryptoBoxLogger.DebugLevels["warn"], + "Could not open %s" % (os.devnull, )) + proc = subprocess.Popen( + shell = False, + stdin = None, + stdout = devnull, + stderr = subprocess.PIPE, + args = [ + self.Progs["mkfs-data"], + self.device]) + proc.wait() + if proc.returncode != 0: + errorMsg = "Could not create the filesystem: %s" % (proc.stderr.read().strip(), ) + self.logger.printMessage( + CryptoBoxLogger.DebugLevels["error"], + errorMsg) + raise "CreateError", errorMsg + devnull.close() + + + def __createLuks(self, password): + "make a luks partition" + if not password: + raise "InvalidPassword", "no password supplied for new luks mapping" + if self.isMounted(): + raise "VolumeIsActive", \ + "deactivate the partition before filesystem initialization" + devnull = None + try: + devnull = open(os.devnull, "w") + except IOError: + self.logger.printMessage( + CryptoBoxLogger.DebugLevels["warn"], + "Could not open %s" % (os.devnull, )) + "remove any potential open luks mapping" + self.__umountLuks() + "create the luks header" + proc = subprocess.Popen( + shell = False, + stdin = subprocess.PIPE, + stdout = devnull, + stderr = subprocess.PIPE, + args = [ + self.Progs["cryptsetup"], + "--batch-mode", + "--cipher", self.cbox.getConfigValue("DefaultCipher"), + "--iter-time", "2000", + "luksFormat", + self.device]) + proc.stdin.write(password) + (output, errout) = proc.communicate() + if proc.returncode != 0: + errorMsg = "Could not create the luks header: %s" % (errout.strip(), ) + self.logger.printMessage( + CryptoBoxLogger.DebugLevels["error"], + errorMsg) + raise "CreateError", errorMsg + "open the luks container for mkfs" + proc = subprocess.Popen( + shell = False, + stdin = subprocess.PIPE, + stdout = devnull, + stderr = subprocess.PIPE, + args = [ + self.Progs["cryptsetup"], + "--batch-mode", + "luksOpen", + self.device, + self.name]) + proc.stdin.write(password) + (output, errout) = proc.communicate() + if proc.returncode != 0: + errorMsg = "Could not open the new luks mapping: %s" % (errout.strip(), ) + self.logger.printMessage( + CryptoBoxLogger.DebugLevels["error"], + errorMsg) + raise "CreateError", errorMsg + "make the filesystem" + proc = subprocess.Popen( + shell = False, + stdin = None, + stdout = devnull, + stderr = devnull, + args = [ + self.Progs["mkfs-data"], + os.path.join(self.__dmDir, self.name)]) + proc.wait() + "remove the mapping - for every exit status" + self.__umountLuks() + if proc.returncode != 0: + errorMsg = "Could not create the filesystem: %s" % (proc.stderr.read().strip(), ) + self.logger.printMessage( + CryptoBoxLogger.DebugLevels["error"], + errorMsg) + "remove the luks mapping" + raise "CreateError", errorMsg + devnull.close() + + + def __cleanMountDirs(self): + """ remove all unnecessary subdirs of the mount parent directory + this should be called for every (u)mount """ + subdirs = os.listdir(self.cbox.getConfigValue("MountParent")) + for dir in subdirs: + abs_dir = os.path.join(self.cbox.getConfigValue("MountParent"), 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) + diff --git a/pythonrewrite/bin2/cbox.log b/pythonrewrite/bin2/cbox.log index e69de29..8546490 100644 --- a/pythonrewrite/bin2/cbox.log +++ b/pythonrewrite/bin2/cbox.log @@ -0,0 +1,4 @@ +[CryptoBox] - 6 +[CryptoBox] - 6 +[CryptoBox] - 6 +[CryptoBox] - 6 diff --git a/pythonrewrite/bin2/cbx.conf b/pythonrewrite/bin2/cbx.conf index 9dd94c9..9541290 100644 --- a/pythonrewrite/bin2/cbx.conf +++ b/pythonrewrite/bin2/cbx.conf @@ -1,7 +1,9 @@ [Main] -logfile = cbox.log -allowed_devices = /dev/sda1, /dev/hda1, /dev/hda3, asf +allowed_devices = /dev/loop +defaultcipher = aes-cbc-essiv:sha256 +defaultnameprefix = "Data " +mountparent = /var/cache/cryptobox/mnt debugfacility = 0 debuglevel = 0 -foo = bar +logfile = cbox.log diff --git a/pythonrewrite/bin2/classes.txt b/pythonrewrite/bin2/classes.txt index ceca63b..255e0ec 100644 --- a/pythonrewrite/bin2/classes.txt +++ b/pythonrewrite/bin2/classes.txt @@ -2,17 +2,5 @@ this is the future plan for the cbx python classes, you can find the actual clas Classes and Methods: CryptoBoxContainer - getName - getDevice - getUUID - isMounted getCapacity - mount - umount - create(type, opt: pw...) - getType - CryptoBoxContainerPlain (CryptoBoxContainer) - CryptoBoxContainerLuks (CryptoBoxContainer) - getCipher - changePassword