changed the interface of CryptoBoxRootActions: "allowedProgs" are now prefixed with the parameter "program"

added allowedProg "pvdisplay" to CryptoBoxRootActions to allow LVM detection
improved blockdevice handling: caching and detection of lvm, luks and raid
This commit is contained in:
lars 2007-08-16 16:13:04 +00:00
parent 53e09ff825
commit b72310097c
5 changed files with 470 additions and 85 deletions

View file

@ -1,6 +1,6 @@
#!/usr/bin/env python #!/usr/bin/env python
# #
# Copyright 2006 sense.lab e.V. # Copyright 2007 sense.lab e.V.
# #
# This file is part of the CryptoBox. # This file is part of the CryptoBox.
# #
@ -20,13 +20,23 @@
# #
"""module for executing the programs, that need root privileges """module for executing some programs or scripts that need root privileges
Syntax: Syntax:
- TODO check
- return exitcode zero if basic checks succeeded
this script will always return with an exitcode 0 (true), program PROGRAM_NAME [ARGS]
if "check" is the only argument - call the program (must be defined in "allowedProgs" below)
event EVENT_SCRIPT [ARGS]
- call an event script
plugin PLUGIN_NAME [ARGS]
- call a root_action script of a plugin
For more detailed information take a look at the manpage:
"man CryptoBoxRootActions"
""" """
__revision__ = "$Id" __revision__ = "$Id"
@ -44,6 +54,7 @@ allowedProgs = {
"mount": "/bin/mount", "mount": "/bin/mount",
"umount": "/bin/umount", "umount": "/bin/umount",
"blkid": "/sbin/blkid", "blkid": "/sbin/blkid",
"pvdisplay": "/sbin/pvdisplay",
} }
## this line is necessary for running unittests or playing around with a local ## this line is necessary for running unittests or playing around with a local
@ -387,6 +398,19 @@ def run_umount(args):
return proc.returncode == 0 return proc.returncode == 0
def run_pvdisplay(args):
"""execute pvdisplay to check for physical LVM devices
"""
if len(args) > 0:
raise "WrongArguments", "no arguments may be supplied for 'pvdisplay'"
## call pvdisplay with the parameter "--colon"
proc = subprocess.Popen(
shell = False,
args = [ allowedProgs["pvdisplay"], "--colon" ])
proc.wait()
return proc.returncode == 0
def getCallingUserInfo(): def getCallingUserInfo():
"""return information about the user that was calling this program via "super" """return information about the user that was calling this program via "super"
@ -456,6 +480,7 @@ if __name__ == "__main__":
# exit silently # exit silently
sys.exit(0) sys.exit(0)
## call a plugin root_action script
if args[0].lower() == "plugin": if args[0].lower() == "plugin":
del args[0] del args[0]
try: try:
@ -468,6 +493,7 @@ if __name__ == "__main__":
else: else:
sys.exit(1) sys.exit(1)
## call an event script
if args[0].lower() == "event": if args[0].lower() == "event":
del args[0] del args[0]
try: try:
@ -480,11 +506,13 @@ if __name__ == "__main__":
else: else:
sys.exit(1) sys.exit(1)
# check parameters count ## call one of the allowed programs
if len(args) < 2: if args[0].lower() == "program":
sys.stderr.write("Not enough arguments supplied (%s)!\n" % " ".join(args)) del args[0]
sys.exit(100)
if len(args) < 1:
sys.stderr.write("No program specified for execution\n")
sys.exit(100)
progRequest = args[0] progRequest = args[0]
del args[0] del args[0]
@ -495,6 +523,7 @@ if __name__ == "__main__":
if progRequest == "cryptsetup": runner = run_cryptsetup if progRequest == "cryptsetup": runner = run_cryptsetup
elif progRequest == "mount": runner = run_mount elif progRequest == "mount": runner = run_mount
elif progRequest == "umount": runner = run_umount elif progRequest == "umount": runner = run_umount
elif progRequest == "pvdisplay": runner = run_pvdisplay
else: else:
sys.stderr.write("The interface for this program (%s) is " \ sys.stderr.write("The interface for this program (%s) is " \
+ "not yet implemented!\n" % progRequest) + "not yet implemented!\n" % progRequest)

View file

@ -1,4 +1,4 @@
.TH CryptoBoxRootActions 8 "March 02007" "CryptoBox" "CryptoBox-Server manual" .TH CryptoBoxRootActions 8 "August 02007" "CryptoBox" "CryptoBox-Server manual"
.SH NAME .SH NAME
CryptoBoxRootActions \- The CryptoBoxWebserver calls this script in order to CryptoBoxRootActions \- The CryptoBoxWebserver calls this script in order to
execute various programs which require root privileges. execute various programs which require root privileges.
@ -13,7 +13,7 @@ plugin \fIFEATURE_SCRIPT\fR [\fIARGS\fR]
hook \fIEVENT_SCRIPT\fR [\fIARGS\fR] hook \fIEVENT_SCRIPT\fR [\fIARGS\fR]
.br .br
.B CryptoBoxRootActions .B CryptoBoxRootActions
\fIPROG\fR [\fIARGS\fR] program \fIPROG\fR [\fIARGS\fR]
.SH DESCRIPTION .SH DESCRIPTION
CryptoBoxRootActions is a script that is called by the CryptoBoxRootActions is a script that is called by the
\fBCryptoBox\fR-Server to execute programs which require root privileges. You \fBCryptoBox\fR-Server to execute programs which require root privileges. You
@ -30,7 +30,8 @@ CryptoBoxRootActions /usr/sbin/CryptoBoxRootActions cryptobox
.PP .PP
We assume that the CryptoBoxRootActions script is located at We assume that the CryptoBoxRootActions script is located at
\fI/usr/sbin/CryptoBoxRootActions\fR. Furthermore the user running the \fI/usr/sbin/CryptoBoxRootActions\fR. Furthermore the user running the
CryptoBox-Server is assumed to be \fIcryptobox\fR. CryptoBox-Server is assumed to be \fIcryptobox\fR. Otherwise you must change the
above line accordingly.
.SH CONFIGURATION CHECK .SH CONFIGURATION CHECK
Call the CryptoBoxRootActions script with the argument \fIcheck\fR to test if Call the CryptoBoxRootActions script with the argument \fIcheck\fR to test if
\fBsuper\fR is configured properly. Just type the following: \fBsuper\fR is configured properly. Just type the following:

View file

@ -25,26 +25,44 @@ These classes detect and filter available blockdevices.
__revision__ = "$Id$" __revision__ = "$Id$"
""" #TODO: use logger to report interesting behaviour
TODO:
- implement some caching
- find the devnodes for each device (e.g. /dev/hda)
- detect luks devices
- detect LVM
"""
import os import os
import subprocess
import time
import cryptobox.core.settings
DEFAULT_SYSBLOCK_DIR = '/sys/block'
DEFAULT_DEVNODE_DIR = '/dev'
MINIMUM_STORAGE_SIZE = 20
MAJOR_DEVNUM_RAM = 1
MAJOR_DEVNUM_LOOP = 7
MAJOR_DEVNUM_MD_RAID = 9
USE_CACHE = True
CACHE_EXPIRE_SECONDS = 60
#TODO: remove this after profiling
IS_VISIBLE = True
## caching is quite important for the following implementation
CACHED_VALUES = {}
class Blockdevices: class Blockdevices:
"""handle all blockdevices of this system
"""
def __init__(self, sysblock_dir='/sys/block', devnode_dir='/dev'): def __init__(self,
sysblock_dir=DEFAULT_SYSBLOCK_DIR,
devnode_dir=DEFAULT_DEVNODE_DIR):
self.sysblock_dir = sysblock_dir self.sysblock_dir = sysblock_dir
self.devnode_dir = devnode_dir self.devnode_dir = devnode_dir
self.devices = [] self.devices = []
for devdir in find_blockdevices(self.sysblock_dir): for devdir in find_blockdevices(self.sysblock_dir):
blockdevice = Blockdevice(devdir, self.devnode_dir) blockdevice = get_blockdevice(devdir,
if not blockdevice is None: self.sysblock_dir, self.devnode_dir)
if (not blockdevice is None) and blockdevice.is_valid():
self.devices.append(blockdevice) self.devices.append(blockdevice)
@ -55,60 +73,197 @@ class Blockdevices:
class Blockdevice: class Blockdevice:
def __init__(self, dev, devnode_dir='/dev', sysblock_dir='/sys/block'): def __init__(self, dev,
sysblock_dir=DEFAULT_SYSBLOCK_DIR,
devnode_dir=DEFAULT_DEVNODE_DIR):
"""initialize the blockdevice
"""
self.devdir = dev
self.devnode_dir = devnode_dir self.devnode_dir = devnode_dir
self.sysblock_dir = sysblock_dir self.sysblock_dir = sysblock_dir
if os.path.isabs(dev):
self.devdir = dev
else:
self.devdir = self.__find_relative_device(dev)
if self.devdir is None:
self = None
return
self.name = os.path.basename(self.devdir) self.name = os.path.basename(self.devdir)
self.devnum = self.__get_major_minor() self.devnum = self.__get_major_minor()
## check valid devnum
try:
major, minor = self.devnum
except TypeError:
self = None
return
self.size = self.__get_size() self.size = self.__get_size()
self.range = self.__get_device_range() self.range = self.__get_device_range()
self.slaves = self.__get_dev_related("slaves") self.slaves = self.__get_dev_related("slaves")
self.holders = self.__get_dev_related("holders") self.holders = self.__get_dev_related("holders")
self.children = self.__get_children() self.children = self.__get_children()
self.devnodes = self.__get_device_nodes()
def isstorage(self): def is_valid(self):
if self.range > 1: """ check if the device is usable and valid
## partitionable blockdevice """
if not self.devnodes:
return False return False
if self.size < 20: ## check valid devnum
## extended partition, unused loop device try:
return False major, minor = self.devnum
if self.devnum[0] == 1: if (major == 0) and (minor == 0):
## ram device return False
return False ## ram devices are ignored
if self.children: if major == MAJOR_DEVNUM_RAM:
## a parent blockdevice return False
## loop devices are ignored
if major == MAJOR_DEVNUM_LOOP:
return False
except TypeError:
return False return False
return True return True
def ispartitionable(self): def is_storage(self):
"""return if this device can be used as a storage
"""
## check the cache first
cache_link = ["blockdevice_info", self.name, "is_storage"]
cached = _get_cached_value(cache_link)
if not cached is None:
return cached
if self.range > 1:
## partitionable blockdevice
_set_cached_value(cache_link, False)
return False
if self.size < MINIMUM_STORAGE_SIZE:
## extended partition, unused loop device
_set_cached_value(cache_link, False)
return False
if self.devnum[0] == MAJOR_DEVNUM_RAM:
## ram device
_set_cached_value(cache_link, False)
return False
## are we the device mapper of a luks device?
for slave in self.slaves:
if get_blockdevice(slave, self.sysblock_dir,
self.devnode_dir).is_luks():
_set_cached_value(cache_link, False)
return False
## if we are a luks device with exactly one child, then
## we are a storage
if (len(self.children) == 1) and self.is_luks():
_set_cached_value(cache_link, True)
return True
if self.children:
## a parent blockdevice
_set_cached_value(cache_link, False)
return False
_set_cached_value(cache_link, True)
return True
def is_partitionable(self):
"""is the device partitionable
"""
if self.range > 1: if self.range > 1:
return True return True
else:
return False
def __find_relative_device(self, devname): def is_lvm_pv(self):
for devdir in find_blockdevices(self.sysblock_dir): """return if the device is a physical volume of a LVM
if os.path.basename(devdir) == devname: """
return devdir ## check the cache first
return None cache_link = ["blockdevice_info", self.name, "is_lvm_pv"]
cached = _get_cached_value(cache_link)
if not cached is None:
return cached
## is one of the devnodes of the device a physical volume?
for one_lvm_pv in find_lvm_pv():
if one_lvm_pv in self.devnodes:
_set_cached_value(cache_link, True)
return True
_set_cached_value(cache_link, False)
return False
def is_lvm_lv(self):
"""return if the device is a logical volume of a LVM
"""
## check the cache first
cache_link = ["blockdevice_info", self.name, "is_lvm_lv"]
cached = _get_cached_value(cache_link)
if not cached is None:
return cached
## is one of the devnodes of the device a physical volume?
## logical LVM volumes always depend on their physical volumes
if not self.slaves:
_set_cached_value(cache_link, False)
return False
## is one of the LVM physical volumes a device node of our slave(s)?
for one_lvm_pv in find_lvm_pv():
for one_slave in self.slaves:
if one_lvm_pv in get_blockdevice(one_slave,
self.sysblock_dir, self.devnode_dir).devnodes:
_set_cached_value(cache_link, True)
return True
_set_cached_value(cache_link, False)
return False
def is_md_raid(self):
"""check if the device is the base of a md raid device
"""
## check the cache first
cache_link = ["blockdevice_info", self.name, "is_md_raid"]
cached = _get_cached_value(cache_link)
if not cached is None:
return cached
if self.range > 1:
result = False
elif self.size < MINIMUM_STORAGE_SIZE:
result = False
else:
for hold in self.holders:
if get_blockdevice(hold, self.sysblock_dir,
self.devnode_dir).devnum[0] == MAJOR_DEVNUM_MD_RAID:
result = True
break
else:
result = False
## store result and return
_set_cached_value(cache_link, result)
return result
def is_luks(self):
"""check if the device is a luks container
"""
## check the cache first
cache_link = ["blockdevice_info", self.name, "is_luks"]
cached = _get_cached_value(cache_link)
if not cached is None:
return cached
if self.range > 1:
result = False
elif self.size < MINIMUM_STORAGE_SIZE:
result = False
elif self.is_lvm_pv():
result = False
elif self.is_md_raid():
result = False
else:
## is the device a luks volume?
prefs = _load_preferences()
proc = subprocess.Popen(
shell = False,
stdout = subprocess.PIPE,
stderr = subprocess.PIPE,
args = [ prefs["Programs"]["cryptsetup"],
"--batch-mode", "isLuks", self.devnodes[0]])
proc.wait()
result = proc.returncode == 0
## store result and return
_set_cached_value(cache_link, result)
return result
def __get_dev_related(self, subdir): def __get_dev_related(self, subdir):
@ -121,6 +276,8 @@ class Blockdevice:
def __get_size(self): def __get_size(self):
"""return the size (in kB) of the blockdevice
"""
default = 0 default = 0
try: try:
return int(file(os.path.join(self.devdir, 'size')).read()) return int(file(os.path.join(self.devdir, 'size')).read())
@ -132,12 +289,15 @@ class Blockdevice:
def __get_major_minor(self): def __get_major_minor(self):
"""return the major and minor of the device""" """return the major and minor of the device"""
default = (0 ,0) default = (0, 0)
try: try:
content = file(os.path.join(self.devdir, "dev")).read() content = file(os.path.join(self.devdir, "dev")).read()
except IOError: except IOError:
return default return default
major, minor = content.split(":", 2) try:
major, minor = content.split(":", 1)
except TypeError:
return default
try: try:
return int(major), int(minor) return int(major), int(minor)
except ValueError: except ValueError:
@ -165,20 +325,48 @@ class Blockdevice:
all holders, subdevices and children of subdevices all holders, subdevices and children of subdevices
""" """
direct_children = [Blockdevice(child).name direct_children = [
get_blockdevice(child, self.sysblock_dir, self.devnode_dir).name
for child in find_blockdevices(self.devdir)] for child in find_blockdevices(self.devdir)]
direct_children.extend(self.holders[:]) direct_children.extend(self.holders[:])
children = direct_children[:] children = direct_children[:]
for dchild in direct_children: for dchild in direct_children:
children.extend(Blockdevice(dchild).children) children.extend(get_blockdevice(dchild, self.sysblock_dir,
self.devnode_dir).children)
return children return children
def __get_device_nodes(self):
"""get all device nodes with the major/minor combination of the device
"""
result = []
major, minor = self.devnum
def find_major_minor(arg, dirname, fnames):
for fname in fnames:
try:
stat = os.stat(os.path.join(dirname, fname))
## check if it is a blockdevice and compare major/minor
if (stat.st_mode & 060000 == 060000) \
and (os.major(stat.st_rdev) == major) \
and (os.minor(stat.st_rdev) == minor):
result.append(os.path.join(dirname, fname))
except OSError:
pass
os.path.walk(self.devnode_dir, find_major_minor, None)
return result
def __str__(self): def __str__(self):
"""display the name of the device
"""
return self.name return self.name
def info(self): def info(self):
"""display some information about the device
"""
output = "%s:\n" % self.name output = "%s:\n" % self.name
output += "\t%s:\t%s\n" % ("blockdir", self.devdir) output += "\t%s:\t%s\n" % ("blockdir", self.devdir)
output += "\t%s:\t%s\n" % ("major/minor", self.devnum) output += "\t%s:\t%s\n" % ("major/minor", self.devnum)
@ -187,12 +375,45 @@ class Blockdevice:
output += "\t%s:\t\t%s\n" % ("slaves", self.slaves) output += "\t%s:\t\t%s\n" % ("slaves", self.slaves)
output += "\t%s:\t%s\n" % ("holders", self.holders) output += "\t%s:\t%s\n" % ("holders", self.holders)
output += "\t%s:\t%s\n" % ("children", self.children) output += "\t%s:\t%s\n" % ("children", self.children)
output += "\t%s:\t%s\n" % ("device nodes", self.devnodes)
output += "\tflags:\t\t"
for funcname in [ "storage", "md_raid", "partitionable", "luks",
"lvm_pv", "lvm_lv"]:
if getattr(self, "is_%s" % funcname)():
output += "%s " % funcname
output += "\n"
return output return output
def get_blockdevice(dev,
sysblock_dir=DEFAULT_SYSBLOCK_DIR,
devnode_dir=DEFAULT_DEVNODE_DIR):
if os.path.isabs(dev):
if os.path.isfile(os.path.join(dev, "dev")):
devdir = dev
else:
return None
else:
for one_devdir in find_blockdevices(sysblock_dir):
if os.path.basename(one_devdir) == dev:
devdir = one_devdir
break
else:
return None
devname = os.path.basename(devdir)
dev = _get_cached_value(["blockdevices", devname])
if dev is None:
dev = Blockdevice(devdir, sysblock_dir, devnode_dir)
_set_cached_value(["blockdevices", devname], dev)
return dev
def find_blockdevices(top_dir): def find_blockdevices(top_dir):
cached = _get_cached_value(["blockdevice_dirs", top_dir])
if not cached is None:
return cached[:]
dev_dirs = [] dev_dirs = []
def look4dev_dirs(arg, dirname, fnames): def look4dev_dirs(arg, dirname, fnames):
@ -210,21 +431,141 @@ def find_blockdevices(top_dir):
fnames.remove(fname) fnames.remove(fname)
os.path.walk(top_dir, look4dev_dirs, 'dev') os.path.walk(top_dir, look4dev_dirs, 'dev')
return dev_dirs _set_cached_value(["blockdevice_dirs", top_dir], dev_dirs)
return dev_dirs[:]
def find_lvm_pv():
"""return the blockdevice names of all physical LVM volumes
"""
cached = _get_cached_value(["lvm", "pv"])
if not cached is None:
return cached[:]
#TODO: should we check, if LVM is supported at all?
# e.g. by checking the existence of pvdisplay?
prefs = _load_preferences()
result = None
try:
proc = subprocess.Popen(
shell = False,
stdout = subprocess.PIPE,
args = [ prefs["Programs"]["super"],
prefs["Programs"]["CryptoBoxRootActions"],
"program", "pvdisplay" ])
proc.wait()
except OSError, err_msg:
# TODO: add a logging warning
result = []
if proc.returncode != 0:
# TODO: add a logging warning
result = []
if result is None:
result = []
for line in proc.stdout.readlines():
result.append(line.split(":", 1)[0].strip())
_set_cached_value(["lvm", "pv"], result)
return result[:]
def _get_cached_value(link):
"""return a cached value
"link" is an array of the hierachie of the accessed item
e.g. link = ["blockdevices", "hda"]
return None if the value is not in the cache or if USE_CACHE is False
"""
if not USE_CACHE:
return None
if "expires" in CACHED_VALUES:
if CACHED_VALUES["expires"] < int(time.time()):
reset_cache()
else:
__reset_cache_timer()
ref = CACHED_VALUES
for element in link:
if element in ref:
ref = ref[element]
else:
return None
return ref
def reset_cache():
## refresh the cache
for item in CACHED_VALUES:
CACHED_VALUES[item] = {}
__reset_cache_timer()
def __reset_cache_timer():
CACHED_VALUES["expires"] = int(time.time()) + CACHE_EXPIRE_SECONDS
def _set_cached_value(link, item):
"""store an item in the cache
"link" is an array of the hierachie of the accessed item
e.g. link = ["blockdevices", "hda"]
"""
if not USE_CACHE:
return
ref = CACHED_VALUES
for element in link[:-1]:
if not element in ref:
## create a non-existing sub element
ref[element] = {}
ref = ref[element]
## store the item
ref[link[-1]] = item
def _load_preferences():
prefs = cryptobox.core.settings.get_current_settings()
if not prefs is None:
## now the preferences are loaded
return prefs
## we have to load an emergency fallback for proper function
## this is mainly useful for local testing
root_dir = os.path.realpath(os.path.join(globals()["cryptobox"].__path__[0],
os.path.pardir, os.path.pardir))
config_file = os.path.join(root_dir, "bin", "cryptobox.conf")
## we have to chdir to the 'bin' directory - otherwise the paths in
## cryptobox.conf do not work
os.chdir(os.path.dirname(config_file))
return cryptobox.core.settings.CryptoBoxSettings(config_file)
if __name__ == '__main__': if __name__ == '__main__':
blocks = Blockdevices() ## list the properties of all available devices
for dev in blocks.get_devices(): ## this is just for testing purposes
print dev.info() blocks = Blockdevices().get_devices()
print
print "Usable storage devices:" ## do we want to show the result?
for dev in blocks.get_devices(): def show(text=""):
if dev.isstorage(): if IS_VISIBLE:
print dev print text
print
print "Partitionable devices:" if len(blocks) > 0:
for dev in blocks.get_devices(): ## show all devices and their properties
if dev.ispartitionable(): show("Properties of all devices:")
print dev for device in blocks:
show(device.info())
## discover all self-check methods
example = blocks[0]
flag_checker = [ method for method in dir(example)
if callable(getattr(example, method))
and method.startswith("is_")]
## list all checks and the respective devices
for check in flag_checker:
show("List of '%s' devices:" % check[3:])
for device in blocks:
if getattr(device, check)():
show("\t%s" % device)
show()

View file

@ -275,7 +275,7 @@ class CryptoBoxContainer:
args = [ args = [
self.cbox.prefs["Programs"]["super"], self.cbox.prefs["Programs"]["super"],
self.cbox.prefs["Programs"]["CryptoBoxRootActions"], self.cbox.prefs["Programs"]["CryptoBoxRootActions"],
"cryptsetup", "program", "cryptsetup",
"luksAddKey", "luksAddKey",
self.device, self.device,
"--batch-mode"]) "--batch-mode"])
@ -523,7 +523,7 @@ class CryptoBoxContainer:
args = [ args = [
self.cbox.prefs["Programs"]["super"], self.cbox.prefs["Programs"]["super"],
self.cbox.prefs["Programs"]["CryptoBoxRootActions"], self.cbox.prefs["Programs"]["CryptoBoxRootActions"],
"cryptsetup", "program", "cryptsetup",
"luksOpen", "luksOpen",
self.device, self.device,
self.name, self.name,
@ -542,7 +542,7 @@ class CryptoBoxContainer:
args = [ args = [
self.cbox.prefs["Programs"]["super"], self.cbox.prefs["Programs"]["super"],
self.cbox.prefs["Programs"]["CryptoBoxRootActions"], self.cbox.prefs["Programs"]["CryptoBoxRootActions"],
"mount", "program", "mount",
os.path.join(self.__dmDir, self.name), os.path.join(self.__dmDir, self.name),
self.__get_mount_point()]) self.__get_mount_point()])
proc.wait() proc.wait()
@ -572,7 +572,7 @@ class CryptoBoxContainer:
args = [ args = [
self.cbox.prefs["Programs"]["super"], self.cbox.prefs["Programs"]["super"],
self.cbox.prefs["Programs"]["CryptoBoxRootActions"], self.cbox.prefs["Programs"]["CryptoBoxRootActions"],
"umount", "program", "umount",
self.__get_mount_point()]) self.__get_mount_point()])
proc.wait() proc.wait()
if proc.returncode != 0: if proc.returncode != 0:
@ -588,7 +588,7 @@ class CryptoBoxContainer:
args = [ args = [
self.cbox.prefs["Programs"]["super"], self.cbox.prefs["Programs"]["super"],
self.cbox.prefs["Programs"]["CryptoBoxRootActions"], self.cbox.prefs["Programs"]["CryptoBoxRootActions"],
"cryptsetup", "program", "cryptsetup",
"luksClose", "luksClose",
self.name, self.name,
"--batch-mode"]) "--batch-mode"])
@ -620,7 +620,7 @@ class CryptoBoxContainer:
args = [ args = [
self.cbox.prefs["Programs"]["super"], self.cbox.prefs["Programs"]["super"],
self.cbox.prefs["Programs"]["CryptoBoxRootActions"], self.cbox.prefs["Programs"]["CryptoBoxRootActions"],
"mount", "program", "mount",
self.device, self.device,
self.__get_mount_point()]) self.__get_mount_point()])
proc.wait() proc.wait()
@ -653,7 +653,7 @@ class CryptoBoxContainer:
args = [ args = [
self.cbox.prefs["Programs"]["super"], self.cbox.prefs["Programs"]["super"],
self.cbox.prefs["Programs"]["CryptoBoxRootActions"], self.cbox.prefs["Programs"]["CryptoBoxRootActions"],
"umount", "program", "umount",
self.__get_mount_point()]) self.__get_mount_point()])
proc.wait() proc.wait()
if proc.returncode != 0: if proc.returncode != 0:
@ -734,7 +734,7 @@ class CryptoBoxContainer:
args = [ args = [
self.cbox.prefs["Programs"]["super"], self.cbox.prefs["Programs"]["super"],
self.cbox.prefs["Programs"]["CryptoBoxRootActions"], self.cbox.prefs["Programs"]["CryptoBoxRootActions"],
"cryptsetup", "program", "cryptsetup",
"luksFormat", "luksFormat",
self.device, self.device,
"--batch-mode", "--batch-mode",
@ -755,7 +755,7 @@ class CryptoBoxContainer:
args = [ args = [
self.cbox.prefs["Programs"]["super"], self.cbox.prefs["Programs"]["super"],
self.cbox.prefs["Programs"]["CryptoBoxRootActions"], self.cbox.prefs["Programs"]["CryptoBoxRootActions"],
"cryptsetup", "program", "cryptsetup",
"luksOpen", "luksOpen",
self.device, self.device,
self.name, self.name,

View file

@ -40,6 +40,19 @@ VOLUMESDB_FILE = "cryptobox_volumes.db"
PLUGINCONF_FILE = "cryptobox_plugins.conf" PLUGINCONF_FILE = "cryptobox_plugins.conf"
USERDB_FILE = "cryptobox_users.db" USERDB_FILE = "cryptobox_users.db"
## allow to retrieve the most recently created setting object
CURRENT_SETTING = []
def get_current_settings():
"""return the most recently created setting object
"""
if not CURRENT_SETTING:
return None
else:
return CURRENT_SETTING[0]
class CryptoBoxSettings: class CryptoBoxSettings:
"""Manage the various configuration files of the CryptoBox """Manage the various configuration files of the CryptoBox
@ -63,6 +76,7 @@ class CryptoBoxSettings:
self.misc_files = [] self.misc_files = []
self.reload_misc_files() self.reload_misc_files()
self.__is_initialized = True self.__is_initialized = True
CURRENT_SETTING.insert(0, self)
def reload_misc_files(self): def reload_misc_files(self):
@ -190,7 +204,7 @@ class CryptoBoxSettings:
args = [ args = [
self.prefs["Programs"]["super"], self.prefs["Programs"]["super"],
self.prefs["Programs"]["CryptoBoxRootActions"], self.prefs["Programs"]["CryptoBoxRootActions"],
"mount", "program", "mount",
"_tmpfs_", "_tmpfs_",
mount_dir ]) mount_dir ])
(stdout, stderr) = proc.communicate() (stdout, stderr) = proc.communicate()
@ -211,7 +225,7 @@ class CryptoBoxSettings:
args = [ args = [
self.prefs["Programs"]["super"], self.prefs["Programs"]["super"],
self.prefs["Programs"]["CryptoBoxRootActions"], self.prefs["Programs"]["CryptoBoxRootActions"],
"mount", "program", "mount",
partition, partition,
mount_dir ]) mount_dir ])
(stdout, stderr) = proc.communicate() (stdout, stderr) = proc.communicate()
@ -241,7 +255,7 @@ class CryptoBoxSettings:
args = [ args = [
self.prefs["Programs"]["super"], self.prefs["Programs"]["super"],
self.prefs["Programs"]["CryptoBoxRootActions"], self.prefs["Programs"]["CryptoBoxRootActions"],
"umount", "program", "umount",
mount_dir ]) mount_dir ])
(stdout, stderr) = proc.communicate() (stdout, stderr) = proc.communicate()
if proc.returncode != 0: if proc.returncode != 0: