added setup.py to use distutils for packaging

moved python modules to separate packages below src/
renamed "hook" to "event" to avoid confusion
This commit is contained in:
lars 2006-11-23 19:13:08 +00:00
parent a66e5d3512
commit 112979b3af
55 changed files with 470 additions and 422 deletions

0
CHANGELOG Normal file
View File

8
MANIFEST.in Normal file
View File

@ -0,0 +1,8 @@
include README
graft www-data
#graft www-data/screenshots
graft templates
graft lang
graft plugins
prune commit.log
prune package.exclude

173
bin/CryptoBoxWebserver Executable file
View File

@ -0,0 +1,173 @@
#!/usr/bin/python2.4
import os, sys
import cryptobox.web.sites
from cryptobox.core.exceptions import *
from optparse import OptionParser
try:
import cherrypy
except:
print "Could not import the cherrypy module! Try 'apt-get install python-cherrypy'."
sys.exit(1)
# TODO: change this for the release version
SERVER_ENVIRONMENT = "development"
class CryptoBoxWebserver:
'''this class starts the cherryp webserver and serves the single sites'''
def __init__(self, opts):
## check conffile
if not os.access(opts.conffile, os.R_OK) or not os.path.isfile(opts.conffile):
sys.stderr.write("Error: could not read configuration file (%s)\n" % opts.conffile)
sys.exit(1)
## store the absolute path as we will chdir later (for daemons)
self.conffile = os.path.realpath(opts.conffile)
## initialize site class
try:
cherrypy.root = cryptobox.web.sites.WebInterfaceSites(self.conffile)
except (CBConfigError,CBEnvironmentError), errMsg:
sys.stderr.write("Error: the CryptoBox is misconfigured - please fix it!\n")
sys.stderr.write("%s\n" % str(errMsg))
sys.exit(1)
#expose static content:
#I currently have no idea how to cleanly extract the stylesheet path from
#the config object without an extra cryptobox.core.main.CryptoBoxProps instance.
#perhaps put config handling into a separate class in CryptoBox.py?
#
# the following manual mapping is necessary, as we may not use relative
# paths in the config file
cherrypy.config.update({
"global": {
"server.socket_port" : int(opts.port),
"server.socket_host" : opts.host,
"server.log_to_screen" : not opts.background and opts.verbose,
"server.log_tracebacks" : opts.verbose,
"server.environment": SERVER_ENVIRONMENT,
"server.log_file" : opts.logfile },
"/cryptobox-misc": {
"staticFilter.on" : True,
"staticFilter.dir": os.path.realpath(opts.datadir)}
})
def start(self):
cherrypy.server.start()
def fork_to_background():
## this is just copy'n'pasted from http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/278731
## check the original for exhaustive comments
try:
pid = os.fork()
except OSError, errMsg:
sys.stderr.write("Error: failed to fork cryptobox daemon process!\n")
sys.stderr.write("%s\n" % errMsg)
sys.exit(1)
if pid == 0: # the first child
os.setsid()
try:
pid = os.fork()
except OSError, errMsg:
sys.stderr.write("Error: failed to fork second cryptobox daemon process!\n")
sys.stderr.write("%s\n" % errMsg)
sys.exit(1)
if pid == 0: # the second child
## we do not change the directory - otherwise there seems to be a race condition with the python interpreter loading this script file
#os.chdir(os.path.sep)
os.umask(0)
else:
os._exit(0)
else:
os._exit(0)
def close_open_files():
"""this is only necessary if we want to go into background"""
import resource # Resource usage information.
maxfd = resource.getrlimit(resource.RLIMIT_NOFILE)[1]
if (maxfd == resource.RLIM_INFINITY):
maxfd = 1024
for fd in range(0, maxfd):
try:
os.close(fd)
except OSError: # ERROR, fd wasn't open to begin with (ignored)
pass
os.open(os.devnull, os.O_RDWR) # standard input (0)
os.dup2(0, 1) # standard output (1)
os.dup2(0, 2) # standard error (2)
def write_pid_file(pid_file):
try:
pidf = open(pid_file,"w")
pidf.write(str(os.getpid()))
pidf.close()
except (IOError, OSError), errMsg:
sys.stderr.write("Warning: failed to write pid file (%s): %s\n" % (pid_file, errMsg))
## it is just a warning - no need to break
def parseOptions():
version = "%prog" + cryptobox.core.main.VERSION
parser = OptionParser(version=version)
parser.set_defaults(conffile="/etc/cryptobox/webserver.conf",
pidfile="/var/run/cryptobox/webserver.pid",
background=False,
datadir="/usr/share/cryptobox/html",
logfile="/var/log/cryptobox/webserver.log",
port="8080",
host="",
verbose=True)
parser.add_option("-c", "--config", dest="conffile",
help="read configuration from FILE", metavar="FILE")
parser.add_option("","--pidfile", dest="pidfile",
help="write process id to FILE", metavar="FILE")
parser.add_option("-B","", dest="background", action="store_true",
help="run webserver in background (as daemon)")
parser.add_option("-q","", dest="verbose", action="store_false",
help="output only errors")
parser.add_option("","--datadir", dest="datadir", metavar="DIR",
help="set data directory to DIR")
parser.add_option("-p","--port", dest="port", metavar="PORT",
help="listen on PORT")
parser.add_option("-l","--logfile", dest="logfile", metavar="FILE",
help="write webserver log to FILE")
parser.add_option("","--host", dest="host", metavar="HOST",
help="attach to HOST")
(options, args) = parser.parse_args()
## we do not expect any remaining arguments
if len(args) != 0:
parser.error("unknown argument: %s" % str(args[0]))
if not os.path.isdir(options.datadir) or not os.access(options.datadir,os.X_OK):
parser.error("could not access the data directory (%s)" % options.datadir)
try:
if (int(options.port) < 0) or (int(options.port) > 65535):
parser.error("invalid port number: %s" % str(options.port))
except ValueError:
parser.error("invalid port specified (%s) - it must be a number" % (options.port))
return options
if __name__ == "__main__":
## process arguments
options = parseOptions()
## initialize the webserver class (before forking to get some error messages)
cbw = CryptoBoxWebserver(options)
## run the webserver as a daemon process
if options.background: fork_to_background()
## write pid file
write_pid_file(options.pidfile)
## close open files to allow background execution
if options.background: close_open_files()
## start the webserver
try:
cbw.start()
except CBError, errMsg:
sys.stderr.write("Failed to start the CryptoBox webserver!\n")
sys.stderr.write("%s\n" % str(errMsg))
sys.stderr.write("Check the log file for details.\n")
sys.exit(1)
sys.exit(0)

View File

@ -1,110 +0,0 @@
#!/usr/bin/python2.4
import os
import WebInterfaceSites
from CryptoBoxExceptions import *
import sys
try:
import cherrypy
except:
print "Could not import the cherrypy module! Try 'apt-get install python-cherrypy'."
sys.exit(1)
## TODO: it should be possible to override this via commandline arguments
PID_FILE = '/var/run/cryptobox/webserver.pid'
class CryptoBoxWebserver:
'''this class starts the cherryp webserver and serves the single sites'''
def __init__(self):
try:
cherrypy.root = WebInterfaceSites.WebInterfaceSites()
except (CBConfigError,CBEnvironmentError), errMsg:
sys.stderr.write("The CryptoBox is misconfigured - please fix it!\n")
sys.stderr.write("%s\n" % str(errMsg))
sys.exit(1)
#expose static content:
#I currently have no idea how to cleanly extract the stylesheet path from
#the config object without an extra CryptoBox.CryptoBoxProps instance.
#perhaps put config handling into a separate class in CryptoBox.py?
#
# the following manual mapping is necessary, as we may not use relative
# paths in the config file
cherrypy.config.configMap.update({
"/cryptobox-misc": {
"staticFilter.on" : True,
"staticFilter.dir": os.path.abspath("/usr/share/cryptobox/html" )}
})
def start(self):
# just use this config, when we're started directly
cherrypy.config.update(file = "/etc/cryptobox/cryptoboxwebserver.conf")
cherrypy.server.start()
def fork_to_background():
## this is just copy'n'pasted from http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/278731
## check the original for exhaustive comments
try:
pid = os.fork()
except OSError, errMsg:
sys.stderr.write("Failed to fork cryptobox daemon process!\n")
sys.stderr.write("%s\n" % errMsg)
sys.exit(1)
if pid == 0: # the first child
os.setsid()
try:
pid = os.fork()
except OSError, errMsg:
sys.stderr.write("Failed to fork second cryptobox daemon process!\n")
sys.stderr.write("%s\n" % errMsg)
sys.exit(1)
if pid == 0: # the second child
os.chdir(os.path.sep)
os.umask(0)
else:
os._exit(0)
else:
os._exit(0)
import resource # Resource usage information.
maxfd = resource.getrlimit(resource.RLIMIT_NOFILE)[1]
if (maxfd == resource.RLIM_INFINITY):
maxfd = 1024
for fd in range(0, maxfd):
try:
os.close(fd)
except OSError: # ERROR, fd wasn't open to begin with (ignored)
pass
os.open(os.devnull, os.O_RDWR) # standard input (0)
os.dup2(0, 1) # standard output (1)
os.dup2(0, 2) # standard error (2)
def write_pid_file(pid_file):
try:
pidf = open(pid_file,"w")
pidf.write(str(os.getpid()))
pidf.close()
except (IOError, OSError), errMsg:
sys.stderr.write("Failed to write pid file (%s): %s\n" % (pid_file, errMsg))
## it is just a warning - no need to break
if __name__ == "__main__":
## TODO: add some argument checking: configFile, daemonMode, ...
cbw = CryptoBoxWebserver()
## run the webserver as a daemon process
fork_to_background()
## write pid file
write_pid_file(PID_FILE)
try:
cbw.start()
except Exceptions, errMsg:
sys.stderr.write("Failed to start the CryptoBox webserver!\n")
sys.stderr.write("%s\n" % str(errMsg))
sys.stderr.write("Check the log file for details.\n")
sys.exit(1)
sys.exit(0)

View File

@ -38,7 +38,7 @@ TemplateDir = ../templates
LangDir = ../lang
# path to documentation files
#DocDir = /usr/share/doc/cryptobox/html
#DocDir = /usr/share/doc/cryptobox/www-data
DocDir = ../doc/html
# path to the plugin directory

15
bin/run_webserver.sh Executable file
View File

@ -0,0 +1,15 @@
#!/bin/sh
#
# example start script to run a local cryptobox webserver
#
# we set some en
#
BIN_DIR=$(dirname "$0")
## add the local python directory to the search path
export PYTHONPATH="$BIN_DIR/../src"
## run the webserver
"$BIN_DIR/CryptoBoxWebserver" --config="$BIN_DIR/cryptobox.conf" --pidfile=/tmp/cryptoboxwebserver.pid --logfile=/tmp/cryptoboxwebser.log --port=8080 --datadir="$BIN_DIR/../www-data" "$@"

View File

@ -1,116 +0,0 @@
#!/usr/bin/env python2.4
"""
BEWARE: this script may overwrite the data of one of your loop devices. You
should restrict the AllowedDevices directive in cryptobox.conf to exclude
your precious black devices from being used by this script.
the following script runs a number of tests for different parts
"""
from CryptoBox import CryptoBoxProps
from CryptoBoxContainer import CryptoBoxContainer
import sys
def main():
cb = CryptoBoxProps()
print "Confguration:"
print "\tConfig file:\t\t%s" % (cb.prefs.prefs.filename, )
print "\tAllowed devices:\t%s" % (cb.prefs["Main"]["AllowedDevices"], )
"""for e in cb.getContainerList(filterType=CryptoBoxContainer.Types["luks"]):"""
for e in cb.getContainerList():
print "\t\t%d\t\t%s - %s - %d" % (cb.getContainerList().index(e), e.getDevice(), e.getName(), e.getType())
if not cb.getContainerList() or len(cb.getContainerList()) < 1:
print "no loop devices found for testing"
sys.exit(1)
if len(cb.getContainerList()) > 1:
print "I found more than one available loop device - I will stop now to avoid risking data loss."
print "Please change the 'AllowedDevices' setting in 'cryptobox.conf' to reduce the number of allowed devices to only one."
sys.exit(1)
testElement = cb.getContainerList()[0]
print "\nRunning some tests now ..."
if not plain_tests(testElement):
print "some previous tests failed - we should stop now"
sys.exit(1)
luks_tests(testElement)
" ***************** some functions ******************** "
def luks_tests(e):
# umount if necessary
try:
e.umount()
except "MountError":
pass
e.create(e.Types["luks"], "alt")
print "\tluks create:\tok"
e.changePassword("alt","neu")
print "\tluks changepw:\tok"
e.setName("lalla")
print "\tluks setName:\tok"
try:
e.mount("neu")
except "MountError":
pass
if e.isMounted(): print "\tluks mount:\tok"
else: print "\tluks mount:\tfailed"
print "\tCapacity (size, free, used) [MB]:\t%s" % (e.getCapacity(), )
try:
e.umount()
except "MountError":
pass
if e.isMounted(): print "\tluks umount:\tfailed"
else: print "\tluks umount:\tok"
if e.isMounted(): return False
else: return True
def plain_tests(e):
# umount if necessary
try:
e.umount()
except "MountError":
pass
e.create(e.Types["plain"])
print "\tplain create:\tok"
e.setName("plain-lili")
print "\tplain setName:\tok"
try:
e.mount()
except "MountError":
pass
if e.isMounted(): print "\tplain mount:\tok"
else: print "\tplain mount:\tfailed"
print "\tCapacity (size, free, used) [MB]:\t%s" % (e.getCapacity(), )
try:
e.umount()
except "MountError":
pass
if e.isMounted(): print "\tplain umount:\tfailed"
else: print "\tplain umount:\tok"
if e.isMounted(): return False
else: return True
# ************ main ****************
main()

3
debian/control vendored
View File

@ -2,7 +2,8 @@ Source: cryptobox
Section: admin
Priority: extra
Maintainer: Lars Kruse <devel@sumpfralle.de>
Build-Depends: debhelper (>= 5.0.37.2), dpatch, python-all-dev (>= 2.4)
Build-Depends: debhelper (>= 5.0.37.2), dpatch, python-all-dev (>= 2.4), python-central (>= 0.5.6)
XS-Python-Version: 2.4
Standards-Version: 3.7.2
Package: cryptobox

View File

@ -7,5 +7,15 @@
# set to "0" to enable the startup of the cryptobox - otherwise "1"
NO_START=1
# the use that should execute the cryptobox
# the user that should execute the cryptobox
RUNAS=cryptobox
# listening port
PORT=8080
# log file of the webserver
LOGFILE=/var/log/cryptobox/webserver.log
# some more server options (rarely necessary)
#SERVER_OPTS="--host localhost --datadir=/usr/share/cryptobox/html"

72
debian/cryptobox.init vendored
View File

@ -18,35 +18,27 @@
# read the default setting file, if it exists
[ -e /etc/default/cryptobox ] && source /etc/default/cryptobox
[ -r /etc/default/cryptobox ] && source /etc/default/cryptobox
# startup switch defaults to zero (enabled)
# set default values (if not defined in /etc/default/cryptobox)
NO_START=${NO_START:-0}
RUNAS=${RUNAS:-cryptobox}
PORT=${PORT:-8080}
HOST=${HOST:-}
LOGFILE=${LOGFILE:-/var/log/cryptobox/webserver.log}
SERVER_OPTS=${SERVER_OPTS:-}
CONF_FILE=/etc/cryptobox/cryptobox.conf
if [ "$NO_START" = "1" ]
then [ $# -eq 0 ] && exit 0
[ "$1" = "status" ] && exit 1
[ "$1" = "stop" ] && exit 0
echo "CryptoBox is disabled by default (check /etc/default/cryptobox)"
exit 0
fi
CBXSERVER=CryptoBoxWebserver.py
if test -e "./$CBXSERVER"
then CBXPATH=$(pwd)
else CBXPATH=/usr/lib/cryptobox
fi
# quit if NO_START is 1 (see /etc/default/cryptobox)
[ "$NO_START" = "1" ] && exit 0
DAEMON=/usr/bin/CryptoBoxWebserver
PIDFILE=/var/run/cryptobox/webserver.pid
DAEMON=/usr/bin/python2.4
DAEMON_OPTS=$CBXPATH/$CBXSERVER
NAME=cryptoboxd
DESC="CryptoBox Daemon (webinterface)"
OPTIONS="-B --pidfile=$PIDFILE --config=$CONF_FILE $SERVER_OPTS"
# check if the package is installed
test -e "$CBXPATH/$CBXSERVER" || exit 0
test -e "$DAEMON" || exit 0
# include some useful functions to unify our output format
. /lib/lsb/init-functions
@ -57,24 +49,28 @@ case "$1" in
# TODO: create certificate
# TODO: run stunnel
# the lines above should go into the live-cd scripts
test -e "$PIDFILE" && log_warning_msg "CryptoBox seems to running already (pid file exists) - we will try to start it anyway ..."
log_daemon_msg "Starting cryptobox webserver" "$DESC"
## create the directory of the pid file if necessary
PIDDIR=$(dirname "$PIDFILE")
if [ -d "$PIDDIR" ]
then mkdir -p "$PIDDIR"
chown $RUNAS:root "$PIDDIR"
chmod 755 "$PIDDIR"
fi
log_daemon_msg "Starting $DESC"
if start-stop-daemon \
--chdir "$CBXPATH" --chuid "$RUNAS" --quiet --start \
-oknodo --user "$RUNAS" --pidfile "$PIDFILE" \
--exec "$DAEMON" -- $DAEMON_OPTS
--chuid $RUNAS: --quiet --start \
--oknodo --user $RUNAS --pidfile "$PIDFILE" \
--exec /usr/bin/python --startas "$DAEMON" -- $OPTIONS
then log_end_msg 0
else log_end_msg 1
exit 1
fi
;;
stop )
if test ! -e "$PIDFILE"
then log_warning_msg "CryptoBox is not running (no pid file found)"
exit 0
fi
log_daemon_msg "Stopping cryptobox webserver" "$DESC"
if start-stop-daemon --quiet --stop --pidfile "$PIDFILE"
if start-stop-daemon --oknodo --quiet --stop \
--pidfile "$PIDFILE" \
--user "$RUNAS"
then rm "$PIDFILE"
log_end_msg 0
else log_end_msg 1
@ -86,8 +82,22 @@ case "$1" in
sleep 1
"$0" start
;;
status )
echo -n "$DESC "
if start-stop-daemon --stop --signal 0 --quiet \
--pidfile "$PIDFILE" -user "$RUNAS"
then echo "running"
exit 0
else if [ -e "$PIDFILE" ]
then echo "failed"
exit 1
else echo "not running"
exit 0
fi
fi
;;
* )
echo "Usage: $0 {start|stop|restart|reload|force-reload}" >&2
echo "Usage: $0 {start|stop|restart|force-reload|status}" >&2
exit 1
;;
esac

2
debian/postinst vendored
View File

@ -35,7 +35,7 @@ create_add_super_permission()
## do nothing, if there is already a CryptoBox line
grep -q "CRYPTOBOX_MARKER" "$SUPER_FILE" && return 0
echo >>"$SUPER_FILE" "## CRYPTOBOX_MARKER - please do not remove!"
echo >>"$SUPER_FILE" "CryptoBoxRootActions /usr/lib/cryptobox/CryptoBoxRootActions.py $CRYPTOBOX_USER"
echo >>"$SUPER_FILE" "CryptoBoxRootActions /usr/bin/CryptoBoxRootActions $CRYPTOBOX_USER"
}
create_pid_dir()

5
debian/rules vendored
View File

@ -51,9 +51,10 @@ install: build
dh_testroot
dh_clean -k
dh_installdirs
$(MAKE) install PREFIX=$(DEB_BUILD_DIR)/usr
dh_pycentral
python setup.py install --root=debian/cryptobox
install -c -m 644 conf-examples/cryptobox.conf-dist $(DEB_BUILD_DIR)/etc/cryptobox/cryptobox.conf
install -c -m 644 conf-examples/cryptoboxwebserver.conf-dist $(DEB_BUILD_DIR)/etc/cryptobox/cryptoboxwebserver.conf
install -c -m 644 conf-examples/cryptoboxwebserver.conf-dist $(DEB_BUILD_DIR)/etc/cryptobox/webserver.conf
# Build architecture-independent files here.

View File

@ -1,7 +1,7 @@
import CryptoBoxPlugin
import cryptobox.plugins.base
class date(CryptoBoxPlugin.CryptoBoxPlugin):
class date(cryptobox.plugins.base.CryptoBoxPlugin):
pluginCapabilities = [ "system" ]
pluginVisibility = [ "preferences" ]

View File

@ -1,6 +1,6 @@
import CryptoBoxPlugin
import cryptobox.plugins.base
class disks(CryptoBoxPlugin.CryptoBoxPlugin):
class disks(cryptobox.plugins.base.CryptoBoxPlugin):
pluginCapabilities = [ "system" ]
pluginVisibility = [ "menu" ]

View File

@ -1,6 +1,6 @@
import CryptoBoxPlugin
import cryptobox.plugins.base
class help(CryptoBoxPlugin.CryptoBoxPlugin):
class help(cryptobox.plugins.base.CryptoBoxPlugin):
pluginCapabilities = [ "system" ]
pluginVisibility = [ "menu" ]

View File

@ -1,7 +1,7 @@
import CryptoBoxPlugin
import cryptobox.plugins.base
class language_selection(CryptoBoxPlugin.CryptoBoxPlugin):
class language_selection(cryptobox.plugins.base.CryptoBoxPlugin):
pluginCapabilities = [ "system" ]
pluginVisibility = [ "menu", "preferences" ]

View File

@ -1,7 +1,7 @@
import CryptoBoxPlugin
import cryptobox.plugins.base
import os
class logs(CryptoBoxPlugin.CryptoBoxPlugin):
class logs(cryptobox.plugins.base.CryptoBoxPlugin):
pluginCapabilities = [ "system" ]
pluginVisibility = [ "preferences" ]

View File

@ -1,13 +1,13 @@
import subprocess
import os
import CryptoBoxPlugin
import cryptobox.plugins.base
## specify (in seconds), how long we should wait before redirecting and ip change
REDIRECT_DELAY=20
CHANGE_IP_DELAY=1
class network(CryptoBoxPlugin.CryptoBoxPlugin):
class network(cryptobox.plugins.base.CryptoBoxPlugin):
pluginCapabilities = [ "system" ]
pluginVisibility = [ "preferences" ]

View File

@ -1,10 +1,10 @@
import subprocess
import os
import logging
import CryptoBoxTools
import CryptoBoxPlugin
import cryptobox.core.tools as cbxTools
import cryptobox.plugins.base
class partition(CryptoBoxPlugin.CryptoBoxPlugin):
class partition(cryptobox.plugins.base.CryptoBoxPlugin):
pluginCapabilities = [ "system" ]
pluginVisibility = [ "preferences" ]
@ -80,7 +80,7 @@ class partition(CryptoBoxPlugin.CryptoBoxPlugin):
return False
if not self.cbox.isDeviceAllowed(device):
return False
if not device in CryptoBoxTools.getParentBlockDevices():
if not device in cbxTools.getParentBlockDevices():
return False
return True
@ -96,14 +96,13 @@ class partition(CryptoBoxPlugin.CryptoBoxPlugin):
def __actionSelectDevice(self, args):
import CryptoBoxTools
block_devices = [e
for e in CryptoBoxTools.getParentBlockDevices()
for e in cbxTools.getParentBlockDevices()
if self.cbox.isDeviceAllowed(e)]
counter = 0
for a in block_devices:
self.hdf[self.hdf_prefix + "BlockDevices.%d.name" % counter] = a
self.hdf[self.hdf_prefix + "BlockDevices.%d.size" % counter] = CryptoBoxTools.getBlockDeviceSizeHumanly(a)
self.hdf[self.hdf_prefix + "BlockDevices.%d.size" % counter] = cbxTools.getBlockDeviceSizeHumanly(a)
self.cbox.log.debug("found a suitable block device: %s" % a)
counter += 1
if self.withConfigPartition:
@ -143,7 +142,7 @@ class partition(CryptoBoxPlugin.CryptoBoxPlugin):
parts = self.__getPartitionsFromArgs(args)
if parts:
self.__setPartitionData(parts)
if CryptoBoxTools.isPartOfBlockDevice(self.device, self.cbox.prefs.getActivePartition()):
if cbxTools.isPartOfBlockDevice(self.device, self.cbox.prefs.getActivePartition()):
self.cbox.prefs.umountPartition()
if not self.__runFDisk(parts):
self.hdf["Data.Warning"] = "Plugins.partition.PartitioningFailed"
@ -189,7 +188,7 @@ class partition(CryptoBoxPlugin.CryptoBoxPlugin):
## we do not have to take special care for a possible config partition
parts = [ { "size": self.deviceSize, "type": "windows" } ]
## umount partition if necessary
if CryptoBoxTools.isPartOfBlockDevice(self.device, self.cbox.prefs.getActivePartition()):
if cbxTools.isPartOfBlockDevice(self.device, self.cbox.prefs.getActivePartition()):
self.cbox.prefs.umountPartition()
## partition it
if not self.__runFDisk(parts):
@ -229,10 +228,10 @@ class partition(CryptoBoxPlugin.CryptoBoxPlugin):
for t in self.PartTypes.keys():
self.hdf[self.hdf_prefix + "Types.%s" % t] = t
## store the currently existing partitions of the choosen block device
current_containers = [ e for e in self.cbox.getContainerList() if CryptoBoxTools.isPartOfBlockDevice(self.device, e.getDevice()) ]
current_containers = [ e for e in self.cbox.getContainerList() if cbxTools.isPartOfBlockDevice(self.device, e.getDevice()) ]
for (index, t) in enumerate(current_containers):
self.hdf[self.hdf_prefix + "ExistingContainers.%d.name" % index] = t.getName()
self.hdf[self.hdf_prefix + "ExistingContainers.%d.size" % index] = CryptoBoxTools.getBlockDeviceSizeHumanly(t.getDevice())
self.hdf[self.hdf_prefix + "ExistingContainers.%d.size" % index] = cbxTools.getBlockDeviceSizeHumanly(t.getDevice())
def __getPartitionsFromArgs(self, args):
@ -264,8 +263,7 @@ class partition(CryptoBoxPlugin.CryptoBoxPlugin):
def __getAvailableDeviceSize(self, device):
"""calculate the available size (MB) of the device
also consider a (possible) configuration partition"""
import CryptoBoxTools
deviceSize = CryptoBoxTools.getBlockDeviceSize(device)
deviceSize = cbxTools.getBlockDeviceSize(device)
if deviceSize < 0: return 0
if self.withConfigPartition:
deviceSize -= self.ConfigPartition["size"]
@ -279,7 +277,7 @@ class partition(CryptoBoxPlugin.CryptoBoxPlugin):
## we need a partition, if there is no active one
if not active: return True
## check if the active one is part of the current device
return CryptoBoxTools.isPartOfBlockDevice(self.device, active)
return cbxTools.isPartOfBlockDevice(self.device, active)
return False

View File

@ -1,8 +1,8 @@
import CryptoBoxPlugin
import Plugins
import cryptobox.plugins.base
import cryptobox.plugins.manage
class plugin_manager(CryptoBoxPlugin.CryptoBoxPlugin):
class plugin_manager(cryptobox.plugins.base.CryptoBoxPlugin):
pluginCapabilities = [ "system" ]
pluginVisibility = [ "preferences" ]
@ -14,7 +14,7 @@ class plugin_manager(CryptoBoxPlugin.CryptoBoxPlugin):
if plugin_name:
## check for invalid characters
if re.search(u'\W', plugin_name): return "plugin_list"
pluginList = Plugins.PluginManager(self.cbox, self.cbox.prefs["Locations"]["PluginDir"])
pluginList = cryptobox.plugins.manage.PluginManager(self.cbox, self.cbox.prefs["Locations"]["PluginDir"])
plugin = pluginList.getPlugin(plugin_name)
if not plugin: return "plugin_list"
## take only plugins, that are of the same type as the choosen one

View File

@ -1,8 +1,8 @@
import CryptoBoxPlugin
import cryptobox.plugins.base
REDIRECT_DELAY = 180
class shutdown(CryptoBoxPlugin.CryptoBoxPlugin):
class shutdown(cryptobox.plugins.base.CryptoBoxPlugin):
pluginCapabilities = [ "system" ]
pluginVisibility = [ "preferences", "menu" ]

View File

@ -1,6 +1,6 @@
import CryptoBoxPlugin
import cryptobox.plugins.base
class system_preferences(CryptoBoxPlugin.CryptoBoxPlugin):
class system_preferences(cryptobox.plugins.base.CryptoBoxPlugin):
pluginCapabilities = [ "system" ]
pluginVisibility = [ "menu" ]

View File

@ -1,8 +1,8 @@
import CryptoBoxPlugin
import cryptobox.plugins.base
RESERVED_USERS = [ "admin" ]
class user_manager(CryptoBoxPlugin.CryptoBoxPlugin):
class user_manager(cryptobox.plugins.base.CryptoBoxPlugin):
pluginCapabilities = [ "system" ]
pluginVisibility = [ "preferences" ]

View File

@ -1,8 +1,8 @@
import CryptoBoxPlugin
from CryptoBoxExceptions import *
import cryptobox.plugins.base
from cryptobox.core.exceptions import *
class volume_automount(CryptoBoxPlugin.CryptoBoxPlugin):
class volume_automount(cryptobox.plugins.base.CryptoBoxPlugin):
pluginCapabilities = [ "volume" ]
pluginVisibility = [ "properties" ]

View File

@ -1,8 +1,8 @@
import CryptoBoxPlugin
from CryptoBoxExceptions import *
import cryptobox.plugins.base
from cryptobox.core.exceptions import *
class volume_chpasswd(CryptoBoxPlugin.CryptoBoxPlugin):
class volume_chpasswd(cryptobox.plugins.base.CryptoBoxPlugin):
pluginCapabilities = [ "volume" ]
pluginVisibility = [ "properties" ]

View File

@ -1,7 +1,7 @@
import CryptoBoxPlugin
import cryptobox.plugins.base
class volume_details(CryptoBoxPlugin.CryptoBoxPlugin):
class volume_details(cryptobox.plugins.base.CryptoBoxPlugin):
pluginCapabilities = [ "volume" ]
pluginVisibility = [ "volume" ]

View File

@ -1,7 +1,7 @@
import CryptoBoxPlugin
from CryptoBoxExceptions import *
import cryptobox.plugins.base
from cryptobox.core.exceptions import *
class format_fs(CryptoBoxPlugin.CryptoBoxPlugin):
class format_fs(cryptobox.plugins.base.CryptoBoxPlugin):
pluginCapabilities = [ "volume" ]
pluginVisibility = [ "volume" ]

View File

@ -1,7 +1,7 @@
import CryptoBoxPlugin
from CryptoBoxExceptions import *
import cryptobox.plugins.base
from cryptobox.core.exceptions import *
class volume_format_fs(CryptoBoxPlugin.CryptoBoxPlugin):
class volume_format_fs(cryptobox.plugins.base.CryptoBoxPlugin):
pluginCapabilities = [ "volume" ]
pluginVisibility = [ "volume" ]

View File

@ -1,8 +1,8 @@
import CryptoBoxPlugin
from CryptoBoxExceptions import *
import cryptobox.plugins.base
from cryptobox.core.exceptions import *
class volume_mount(CryptoBoxPlugin.CryptoBoxPlugin):
class volume_mount(cryptobox.plugins.base.CryptoBoxPlugin):
pluginCapabilities = [ "volume" ]
pluginVisibility = [ "volume" ]

View File

@ -1,9 +1,9 @@
import CryptoBoxPlugin
import Plugins
from CryptoBoxExceptions import *
import cryptobox.plugins.base
import cryptobox.plugins.manage
from cryptobox.core.exceptions import *
class volume_props(CryptoBoxPlugin.CryptoBoxPlugin):
class volume_props(cryptobox.plugins.base.CryptoBoxPlugin):
pluginCapabilities = [ "volume" ]
pluginVisibility = [ "volume" ]
@ -13,7 +13,7 @@ class volume_props(CryptoBoxPlugin.CryptoBoxPlugin):
def doAction(self, **args):
import os
self.props_plugins = [e for e in Plugins.PluginManager(self.cbox, self.cbox.prefs["Locations"]["PluginDir"]).getPlugins() if "properties" in e.getVisibility()]
self.props_plugins = [e for e in cryptobox.plugins.manage.PluginManager(self.cbox, self.cbox.prefs["Locations"]["PluginDir"]).getPlugins() if "properties" in e.getVisibility()]
## sort plugins by rank
self.props_plugins.sort(cmp = self.__cmpPluginsRank)
## set the name of the templates for every plugin
@ -42,7 +42,7 @@ class volume_props(CryptoBoxPlugin.CryptoBoxPlugin):
for p in self.props_plugins:
p.loadDataSet(hdf)
## call our parent's method
CryptoBoxPlugin.CryptoBoxPlugin.loadDataSet(self, hdf)
cryptobox.plugins.base.CryptoBoxPlugin.loadDataSet(self, hdf)
def __cmpPluginsRank(self, p1, p2):

View File

@ -1,8 +1,8 @@
import CryptoBoxPlugin
from CryptoBoxExceptions import *
import cryptobox.plugins.base
from cryptobox.core.exceptions import *
class volume_rename(CryptoBoxPlugin.CryptoBoxPlugin):
class volume_rename(cryptobox.plugins.base.CryptoBoxPlugin):
pluginCapabilities = [ "volume" ]
pluginVisibility = [ "properties" ]

59
setup.py Normal file
View File

@ -0,0 +1,59 @@
#!/usr/bin/env python
from distutils.core import setup
import distutils.sysconfig
import os
## define some strings (not patterns) to exclude specific files or directories
IGNORE_FILES = [ '.svn' ]
## define the data destination directory (below the python directory - we will fix this for debian in the rules file)
datadir = distutils.sysconfig.get_python_lib()
## remove installation prefix to get relative path
datadir = datadir.replace(distutils.sysconfig.get_config_var("prefix") + os.path.sep, '')
datadir = os.path.join(datadir, 'cryptobox','share')
def getdatafiles(dirs):
filelist = []
def listfiles(srcdir):
## add the files of this directory
result = [(os.path.join(datadir,srcdir), [ os.path.join(srcdir, f) for f in os.listdir(srcdir) if os.path.isfile(os.path.join(srcdir, f)) and not f in IGNORE_FILES ])]
## add the files in subdirectories
for d in os.listdir(os.path.join(srcdir)):
if os.path.isdir(os.path.join(srcdir,d)) and not d in IGNORE_FILES:
result.extend(listfiles(os.path.join(srcdir,d)))
return result
for d in dirs:
filelist.extend(listfiles(d))
return filelist
setup(
name = 'cryptobox',
version = '0.3.0',
description = 'webinterface for handling encrypted disks',
author = 'Lars Kruse',
author_email = 'devel@sumpfralle.de',
maintainer = 'Lars Kruse',
maintainer_email = 'devel@sumpfralle.de',
license = 'GPL',
url = 'http://cryptobox.org',
packages = [ 'cryptobox', 'cryptobox.core', 'cryptobox.web', 'cryptobox.plugins', 'cryptobox.tests' ],
data_files = getdatafiles(['templates','www-data','lang','plugins','event-scripts','conf-examples']) + [
(datadir, ['README']),
(datadir, ['CHANGELOG']),
(datadir, ['LICENSE'])],
package_dir = { 'cryptobox': 'src' },
scripts = [ 'bin/CryptoBoxWebserver', 'bin/CryptoBoxRootActions' ],
classifiers = [
'Development Status :: 2 - Beta',
'Environment :: Web Environment',
'Intended Audience :: End Users/Desktop',
'Intended Audience :: System Administrators',
'License :: OSI Approved :: GNU General Public License (GPL)',
'Topic :: System :: Systems Administration',
'Operating System :: POSIX',
'Operating System :: Unix',
'Programming Language :: Python'],
)

1
src/__init__.py Normal file
View File

@ -0,0 +1 @@
__all__ = ['core','web','plugins','tests']

0
src/core/__init__.py Normal file
View File

43
bin/CryptoBoxContainer.py → src/core/container.py Executable file → Normal file
View File

@ -1,5 +1,3 @@
#!/usr/bin/env python2.4
## check python version
import sys
(ver_major, ver_minor, ver_sub, ver_desc, ver_subsub) = sys.version_info
@ -11,7 +9,7 @@ import subprocess
import os
import re
import logging
from CryptoBoxExceptions import *
from cryptobox.core.exceptions import *
"""exceptions:
CBVolumeIsActive
@ -24,15 +22,16 @@ from CryptoBoxExceptions import *
CBChangePasswordError
"""
class CryptoBoxContainer:
Types = {
ContainerTypes = {
"unused":0,
"plain":1,
"luks":2,
"swap":3}
"swap":3,
}
class CryptoBoxContainer:
__fsTypes = {
"plain":["ext3", "ext2", "vfat", "reiser"],
"swap":["swap"]}
@ -126,8 +125,8 @@ class CryptoBoxContainer:
the result is a value in megabyte
an error is indicated by "-1"
"""
import CryptoBoxTools
return CryptoBoxTools.getBlockDeviceSize(self.device)
import cryptobox.core.tools as cbxtools
return cbxtools.getBlockDeviceSize(self.device)
def resetObject(self):
@ -137,19 +136,19 @@ class CryptoBoxContainer:
self.type = self.__getTypeOfPartition()
self.name = self.__getNameOfContainer()
self.__setAttributes()
if self.type == self.Types["luks"]:
if self.type == ContainerTypes["luks"]:
self.mount = self.__mountLuks
self.umount = self.__umountLuks
elif self.type == self.Types["plain"]:
elif self.type == ContainerTypes["plain"]:
self.mount = self.__mountPlain
self.umount = self.__umountPlain
def create(self, type, password=None):
old_name = self.getName()
if type == self.Types["luks"]:
if type == ContainerTypes["luks"]:
self.__createLuks(password)
elif type == self.Types["plain"]:
elif type == ContainerTypes["plain"]:
self.__createPlain()
else:
raise CBInvalidType("invalid container type (%d) supplied" % (type, ))
@ -161,7 +160,7 @@ class CryptoBoxContainer:
def changePassword(self, oldpw, newpw):
if self.type != self.Types["luks"]:
if self.type != ContainerTypes["luks"]:
raise CBInvalidType("changing of password is possible only for luks containers")
if not oldpw:
raise CBInvalidPassword("no old password supplied for password change")
@ -247,7 +246,7 @@ class CryptoBoxContainer:
def __getUUID(self):
if self.__getTypeOfPartition() == self.Types["luks"]:
if self.__getTypeOfPartition() == ContainerTypes["luks"]:
guess = self.__getLuksUUID()
else:
guess = self.__getNonLuksUUID()
@ -302,14 +301,14 @@ class CryptoBoxContainer:
def __getTypeOfPartition(self):
"retrieve the type of the given partition (see CryptoBoxContainer.Types)"
if self.__isLuksPartition(): return self.Types["luks"]
"retrieve the type of the given partition (see cryptobox.core.container.ContainerTypes)"
if self.__isLuksPartition(): return ContainerTypes["luks"]
typeOfPartition = self.__getTypeIdOfPartition()
if typeOfPartition in self.__fsTypes["plain"]:
return self.Types["plain"]
return ContainerTypes["plain"]
if typeOfPartition in self.__fsTypes["swap"]:
return self.Types["swap"]
return self.Types["unused"]
return ContainerTypes["swap"]
return ContainerTypes["unused"]
def __getTypeIdOfPartition(self):
@ -645,8 +644,8 @@ class CryptoBoxContainer:
def __getEventArgs(self):
"""return an array of arguments for hook scripts handling pre/post-mount/umount
"""return an array of arguments for event scripts handling pre/post-mount/umount
events"""
typeText = [e for e in self.Types.keys() if self.Types[e] == self.getType()][0]
typeText = [e for e in ContainerTypes.keys() if ContainerTypes[e] == self.getType()][0]
return [self.getDevice(), self.getName(), typeText, self.__getMountPoint()]

View File

@ -3,12 +3,12 @@ exceptions of the cryptobox package
"""
class CryptoBoxError(Exception):
class CBError(Exception):
"""base class for exceptions of the cryptobox"""
pass
class CBConfigError(CryptoBoxError):
class CBConfigError(CBError):
"""any kind of error related to the configuration of a cryptobox"""
pass
@ -57,7 +57,7 @@ class CBConfigInvalidValueError(CBConfigError):
return "invalid configuration setting [%s]->%s (%s): %s" % (self.section, self.name, self.value, self.reason)
class CBEnvironmentError(CryptoBoxError):
class CBEnvironmentError(CBError):
"""some part of the environment of the cryptobox is broken
e.g. the wrong version of a required program
"""
@ -69,7 +69,7 @@ class CBEnvironmentError(CryptoBoxError):
return "misconfiguration detected: %s" % self.desc
class CBContainerError(CryptoBoxError):
class CBContainerError(CBError):
"""any error raised while manipulating a cryptobox container"""
def __init__(self, desc):

31
bin/CryptoBox.py → src/core/main.py Executable file → Normal file
View File

@ -1,4 +1,3 @@
#!/usr/bin/env python2.4
'''
This is the web interface for a fileserver managing encrypted filesystems.
@ -14,14 +13,15 @@ if (ver_major < 2) or ((ver_major == 2) and (ver_minor < 4)):
sys.stderr.write("You need a python version >= 2.4\nCurrent version is:\n %s\n" % sys.version)
sys.exit(1)
import CryptoBoxContainer
from CryptoBoxExceptions import *
import cryptobox.core.container as cbxContainer
from cryptobox.core.exceptions import *
import re
import os
import CryptoBoxTools
import cryptobox.core.tools as cbxTools
import subprocess
VERSION = "0.3~1"
class CryptoBox:
'''this class rules them all!
@ -29,12 +29,11 @@ class CryptoBox:
put things like logging, conf and oter stuff in here,
that might be used by more classes, it will be passed on to them'''
VERSION = "0.3~1"
def __init__(self, config_file=None):
import CryptoBoxSettings
import cryptobox.core.settings as cbxSettings
self.log = self.__getStartupLogger()
self.prefs = CryptoBoxSettings.CryptoBoxSettings(config_file)
self.prefs = cbxSettings.CryptoBoxSettings(config_file)
self.__runTests()
@ -124,9 +123,9 @@ class CryptoBoxProps(CryptoBox):
def reReadContainerList(self):
self.log.debug("rereading container list")
self.containers = []
for device in CryptoBoxTools.getAvailablePartitions():
for device in cbxTools.getAvailablePartitions():
if self.isDeviceAllowed(device) and not self.isConfigPartition(device):
self.containers.append(CryptoBoxContainer.CryptoBoxContainer(device, self))
self.containers.append(cbxContainer.CryptoBoxContainer(device, self))
## sort by container name
self.containers.sort(cmp = lambda x,y: x.getName() < y.getName() and -1 or 1)
@ -187,7 +186,7 @@ class CryptoBoxProps(CryptoBox):
try:
result = self.containers[:]
if filterType != None:
if filterType in range(len(CryptoBoxContainer.Types)):
if filterType in range(len(cbxContainer.Types)):
return [e for e in self.containers if e.getType() == filterType]
else:
self.log.info("invalid filterType (%d)" % filterType)
@ -221,14 +220,14 @@ class CryptoBoxProps(CryptoBox):
def sendEventNotification(self, event, event_infos):
"""call all available scripts in the hook directory with some event information"""
hook_dir = self.prefs["Locations"]["HookDir"]
for fname in os.listdir(hook_dir):
real_fname = os.path.join(hook_dir, fname)
"""call all available scripts in the event directory with some event information"""
event_dir = self.prefs["Locations"]["EventDir"]
for fname in os.listdir(event_dir):
real_fname = os.path.join(event_dir, fname)
if os.path.isfile(real_fname) and os.access(real_fname, os.X_OK):
cmd_args = [ self.prefs["Programs"]["super"],
self.prefs["Programs"]["CryptoBoxRootActions"],
"hook", real_fname, event]
"event", real_fname, event]
cmd_args.extend(event_infos)
proc = subprocess.Popen(
shell = False,
@ -237,7 +236,7 @@ class CryptoBoxProps(CryptoBox):
args = cmd_args)
(stdout, stderr) = proc.communicate()
if proc.returncode != 0:
self.log.warn("a hook script (%s) failed (exitcode=%d) to handle an event (%s): %s" % (real_fname, proc.returncode, event, stderr.strip()))
self.log.warn("an event script (%s) failed (exitcode=%d) to handle an event (%s): %s" % (real_fname, proc.returncode, event, stderr.strip()))
else:
self.log.info("event handler (%s) finished successfully: %s" % (real_fname, event))

View File

@ -1,15 +1,15 @@
from cryptobox.core.exceptions import *
import logging
try:
import validate
except:
raise CryptoBoxExceptions.CBEnvironmentError("couldn't import 'validate'! Try 'apt-get install python-formencode'.")
raise CBEnvironmentError("couldn't import 'validate'! Try 'apt-get install python-formencode'.")
import os
import CryptoBoxExceptions
import subprocess
try:
import configobj ## needed for reading and writing of the config file
except:
raise CryptoBoxExceptions.CBEnvironmentError("couldn't import 'configobj'! Try 'apt-get install python-configobj'.")
raise CBEnvironmentError("couldn't import 'configobj'! Try 'apt-get install python-configobj'.")
@ -172,9 +172,9 @@ class CryptoBoxSettings:
if prefs:
self.log.info("found config: %s" % prefs.items())
else:
raise CryptoBoxExceptions.CBConfigUnavailableError("failed to load the config file: %s" % config_file)
raise CBConfigUnavailableError("failed to load the config file: %s" % config_file)
except IOError:
raise CryptoBoxExceptions.CBConfigUnavailableError("unable to open the config file: %s" % config_file)
raise CBConfigUnavailableError("unable to open the config file: %s" % config_file)
return prefs
@ -190,7 +190,7 @@ class CryptoBoxSettings:
else:
errorMsg = "invalid configuration value (%s) in section '%s': %s" % (key, section_name, text)
errorMsgs.append(errorMsg)
raise CryptoBoxExceptions.CBConfigError, "\n".join(errorMsgs)
raise CBConfigError, "\n".join(errorMsgs)
def __checkUnknownPreferences(self):
@ -228,9 +228,9 @@ class CryptoBoxSettings:
try:
pluginConf_file = os.path.join(self.prefs["Locations"]["SettingsDir"], self.PLUGINCONF_FILE)
except KeyError:
raise CryptoBoxExceptions.CBConfigUndefinedError("Locations", "SettingsDir")
raise CBConfigUndefinedError("Locations", "SettingsDir")
except SyntaxError:
raise CryptoBoxExceptions.CBConfigInvalidValueError("Locations", "SettingsDir", pluginConf_file, "failed to interprete the filename of the plugin config file correctly (%s)" % pluginConf_file)
raise CBConfigInvalidValueError("Locations", "SettingsDir", pluginConf_file, "failed to interprete the filename of the plugin config file correctly (%s)" % pluginConf_file)
## create pluginConf_file if necessary
if os.path.exists(pluginConf_file):
pluginConf = configobj.ConfigObj(pluginConf_file, configspec=plugin_rules)
@ -240,7 +240,7 @@ class CryptoBoxSettings:
pluginConf.validate(validate.Validator())
## check if pluginConf_file file was created successfully?
if not os.path.exists(pluginConf_file):
raise CryptoBoxExceptions.CBEnvironmentError("failed to create plugin configuration file (%s)" % pluginConf_file)
raise CBEnvironmentError("failed to create plugin configuration file (%s)" % pluginConf_file)
return pluginConf
@ -249,9 +249,9 @@ class CryptoBoxSettings:
try:
conf_file = os.path.join(self.prefs["Locations"]["SettingsDir"], self.VOLUMESDB_FILE)
except KeyError:
raise CryptoBoxExceptions.CBConfigUndefinedError("Locations", "SettingsDir")
raise CBConfigUndefinedError("Locations", "SettingsDir")
except SyntaxError:
raise CryptoBoxExceptions.CBConfigInvalidValueError("Locations", "SettingsDir", conf_file, "failed to interprete the filename of the volume database correctly (%s)" % conf_file)
raise CBConfigInvalidValueError("Locations", "SettingsDir", conf_file, "failed to interprete the filename of the volume database correctly (%s)" % conf_file)
## create conf_file if necessary
if os.path.exists(conf_file):
conf = configobj.ConfigObj(conf_file)
@ -259,7 +259,7 @@ class CryptoBoxSettings:
conf = configobj.ConfigObj(conf_file, create_empty=True)
## check if conf_file file was created successfully?
if not os.path.exists(conf_file):
raise CryptoBoxExceptions.CBEnvironmentError("failed to create volume database file (%s)" % conf_file)
raise CBEnvironmentError("failed to create volume database file (%s)" % conf_file)
return conf
@ -270,9 +270,9 @@ class CryptoBoxSettings:
try:
userDB_file = os.path.join(self.prefs["Locations"]["SettingsDir"], self.USERDB_FILE)
except KeyError:
raise CryptoBoxExceptions.CBConfigUndefinedError("Locations", "SettingsDir")
raise CBConfigUndefinedError("Locations", "SettingsDir")
except SyntaxError:
raise CryptoBoxExceptions.CBConfigInvalidValueError("Locations", "SettingsDir", userDB_file, "failed to interprete the filename of the users database file correctly (%s)" % userDB_file)
raise CBConfigInvalidValueError("Locations", "SettingsDir", userDB_file, "failed to interprete the filename of the users database file correctly (%s)" % userDB_file)
## create userDB_file if necessary
if os.path.exists(userDB_file):
userDB = configobj.ConfigObj(userDB_file, configspec=userDB_rules)
@ -282,7 +282,7 @@ class CryptoBoxSettings:
userDB.validate(validate.Validator())
## check if userDB file was created successfully?
if not os.path.exists(userDB_file):
raise CryptoBoxExceptions.CBEnvironmentError("failed to create user database file (%s)" % userDB_file)
raise CBEnvironmentError("failed to create user database file (%s)" % userDB_file)
## define password hash function - never use "sha" directly - SPOT
userDB.getDigest = lambda password: sha.new(password).hexdigest()
return userDB
@ -307,14 +307,14 @@ class CryptoBoxSettings:
if os.path.exists(os.path.expanduser(f))]
if not conf_file_list:
# no possible config file found in the usual locations
raise CryptoBoxExceptions.CBConfigUnavailableError()
raise CBConfigUnavailableError()
config_file = conf_file_list[0]
else:
# a config file was specified (e.g. via command line)
if type(config_file) != types.StringType:
raise CryptoBoxExceptions.CBConfigUnavailableError("invalid config file specified: %s" % config_file)
raise CBConfigUnavailableError("invalid config file specified: %s" % config_file)
if not os.path.exists(config_file):
raise CryptoBoxExceptions.CBConfigUnavailableError("could not find the specified configuration file (%s)" % config_file)
raise CBConfigUnavailableError("could not find the specified configuration file (%s)" % config_file)
return config_file
@ -325,16 +325,16 @@ class CryptoBoxSettings:
if not log_level in log_level_avail:
raise TypeError
except KeyError:
raise CryptoBoxExceptions.CBConfigUndefinedError("Log", "Level")
raise CBConfigUndefinedError("Log", "Level")
except TypeError:
raise CryptoBoxExceptions.CBConfigInvalidValueError("Log", "Level", log_level, "invalid log level: only %s are allowed" % log_level_avail)
raise CBConfigInvalidValueError("Log", "Level", log_level, "invalid log level: only %s are allowed" % log_level_avail)
try:
try:
log_handler = logging.FileHandler(self.prefs["Log"]["Details"])
except KeyError:
raise CryptoBoxExceptions.CBConfigUndefinedError("Log", "Details")
raise CBConfigUndefinedError("Log", "Details")
except IOError:
raise CryptoBoxExceptions.CBEnvironmentError("could not create the log file (%s)" % self.prefs["Log"]["Details"])
raise CBEnvironmentError("could not create the log file (%s)" % self.prefs["Log"]["Details"])
log_handler.setFormatter(logging.Formatter('%(asctime)s CryptoBox %(levelname)s: %(message)s'))
cbox_log = logging.getLogger("CryptoBox")
## remove previous handlers
@ -362,9 +362,9 @@ MountParentDir = directoryExists(default="/var/cache/cryptobox/mnt")
SettingsDir = directoryExists(default="/var/cache/cryptobox/settings")
TemplateDir = directoryExists(default="/usr/share/cryptobox/template")
LangDir = directoryExists(default="/usr/share/cryptobox/lang")
DocDir = directoryExists(default="/usr/share/doc/cryptobox/html")
DocDir = directoryExists(default="/usr/share/doc/cryptobox/www-data")
PluginDir = directoryExists(default="/usr/share/cryptobox/plugins")
HookDir = directoryExists(default="/etc/cryptobox/hooks")
EventDir = directoryExists(default="/etc/cryptobox/events.d")
[Log]
Level = option("debug", "info", "warn", "error", default="warn")

0
src/plugins/__init__.py Normal file
View File

0
src/tests/__init__.py Normal file
View File

View File

@ -51,7 +51,7 @@ TemplateDir = ../templates
LangDir = ../lang
DocDir = ../doc/html
PluginDir = ../plugins
HookDir = ../hook-scripts
EventDir = ../event-scripts
[Log]
Level = debug
Destination = file

View File

@ -1,7 +1,7 @@
#!/usr/bin/python2.4
import unittest
import Plugins
import cryptobox.plugins.manage
class CheckForUndefinedTestCases(unittest.TestCase):
"""here we will add failing test functions for every non-existing testcase"""
@ -9,7 +9,7 @@ class CheckForUndefinedTestCases(unittest.TestCase):
def create_testcases():
plugins = Plugins.PluginManager(None, "../plugins").getPlugins()
plugins = cryptobox.plugins.manage.PluginManager(None, "../plugins").getPlugins()
glob_dict = globals()
loc_dict = locals()
for pl in plugins:

View File

@ -7,11 +7,11 @@ from twill.errors import *
from mechanize import BrowserStateError, LinkNotFoundError
## import the module of the common super class of all web interface test classes
import WebInterfaceTestClass
import cryptobox.web.testclass
class WebServer(WebInterfaceTestClass.WebInterfaceTestClass):
class WebServer(cryptobox.web.testclass.WebInterfaceTestClass):
def test_is_server_running(self):
'''the server should run under given name and port'''
@ -19,7 +19,7 @@ class WebServer(WebInterfaceTestClass.WebInterfaceTestClass):
## other URLs must not be checked, as we do not know, if they are valid
class BuiltinPages(WebInterfaceTestClass.WebInterfaceTestClass):
class BuiltinPages(cryptobox.web.testclass.WebInterfaceTestClass):
def test_goto_index(self):

0
src/web/__init__.py Normal file
View File

View File

@ -1,9 +1,8 @@
import os
import CryptoBoxContainer
import CryptoBoxTools
from cryptobox.core.exceptions import *
import cryptobox.core.container as cbxContainer
import cryptobox.core.tools as cbxTools
## useful constant for some functions
CONT_TYPES = CryptoBoxContainer.CryptoBoxContainer.Types
class WebInterfaceDataset(dict):
"""this class contains all data that should be available for the clearsilver
@ -22,7 +21,8 @@ class WebInterfaceDataset(dict):
def setCryptoBoxState(self):
import cherrypy
self["Data.Version"] = self.cbox.VERSION
import cryptobox.core.main
self["Data.Version"] = cryptobox.core.main.VERSION
langs = self.cbox.getAvailableLanguages()
langs.sort()
for (index, lang) in enumerate(langs):
@ -60,15 +60,15 @@ class WebInterfaceDataset(dict):
def setCurrentDiskState(self, device):
for container in self.cbox.getContainerList():
if container.getDevice() == device:
isEncrypted = (container.getType() == CONT_TYPES["luks"]) and 1 or 0
isPlain = (container.getType() == CONT_TYPES["plain"]) and 1 or 0
isEncrypted = (container.getType() == cbxContainer.ContainerTypes["luks"]) and 1 or 0
isPlain = (container.getType() == cbxContainer.ContainerTypes["plain"]) and 1 or 0
isMounted = container.isMounted() and 1 or 0
self["Data.CurrentDisk.device"] = container.getDevice()
self["Data.CurrentDisk.name"] = container.getName()
self["Data.CurrentDisk.encryption"] = isEncrypted
self["Data.CurrentDisk.plaintext"] = isPlain
self["Data.CurrentDisk.active"] = isMounted
self["Data.CurrentDisk.size"] = CryptoBoxTools.getBlockDeviceSizeHumanly(container.getDevice())
self["Data.CurrentDisk.size"] = cbxTools.getBlockDeviceSizeHumanly(container.getDevice())
if isMounted:
(size, avail, used) = container.getCapacity()
percent = used / size
@ -85,15 +85,15 @@ class WebInterfaceDataset(dict):
for container in self.cbox.getContainerList():
## useful if the container was changed during an action
container.resetObject()
isEncrypted = (container.getType() == CONT_TYPES["luks"]) and 1 or 0
isPlain = (container.getType() == CONT_TYPES["plain"]) and 1 or 0
isEncrypted = (container.getType() == cbxContainer.ContainerTypes["luks"]) and 1 or 0
isPlain = (container.getType() == cbxContainer.ContainerTypes["plain"]) and 1 or 0
isMounted = container.isMounted() and 1 or 0
self["Data.Disks.%d.device" % avail_counter] = container.getDevice()
self["Data.Disks.%d.name" % avail_counter] = container.getName()
self["Data.Disks.%d.encryption" % avail_counter] = isEncrypted
self["Data.Disks.%d.plaintext" % avail_counter] = isPlain
self["Data.Disks.%d.active" % avail_counter] = isMounted
self["Data.Disks.%d.size" % avail_counter] = CryptoBoxTools.getBlockDeviceSizeHumanly(container.getDevice())
self["Data.Disks.%d.size" % avail_counter] = cbxTools.getBlockDeviceSizeHumanly(container.getDevice())
if isMounted: active_counter += 1
avail_counter += 1
self["Data.activeDisksCount"] = active_counter
@ -131,7 +131,7 @@ class WebInterfaceDataset(dict):
try:
import neo_cgi, neo_util, neo_cs
except:
raise CryptoBoxExceptions.CBEnvironmentError("couldn't import 'neo_*'! Try 'apt-get install python-clearsilver'.")
raise CBEnvironmentError("couldn't import 'neo_*'! Try 'apt-get install python-clearsilver'.")
hdf_path = os.path.join(self.prefs["Locations"]["LangDir"], lang + ".hdf")
hdf = neo_util.HDF()
hdf.readFile(hdf_path)

16
bin/WebInterfaceSites.py → src/web/sites.py Executable file → Normal file
View File

@ -1,8 +1,8 @@
import CryptoBox
import WebInterfaceDataset
import cryptobox.core.main
import cryptobox.web.dataset
import cryptobox.plugins.manage
from cryptobox.core.exceptions import *
import re
import Plugins
from CryptoBoxExceptions import *
import cherrypy
import types
import os
@ -36,9 +36,9 @@ class WebInterfaceSites:
defaultTemplate = "empty"
def __init__(self):
def __init__(self, conf_file=None):
import logging,sys
self.cbox = CryptoBox.CryptoBoxProps()
self.cbox = cryptobox.core.main.CryptoBoxProps(conf_file)
self.log = logging.getLogger("CryptoBox")
self.prefs = self.cbox.prefs
self.__resetDataset()
@ -51,7 +51,7 @@ class WebInterfaceSites:
also take care for the plugins, as they also contain datasets
"""
self.__loadPlugins()
self.dataset = WebInterfaceDataset.WebInterfaceDataset(self.cbox, self.prefs, self.pluginList.getPlugins())
self.dataset = cryptobox.web.dataset.WebInterfaceDataset(self.cbox, self.prefs, self.pluginList.getPlugins())
## publish plugin icons
self.icons = PluginIconHandler(self.pluginList)
self.icons.exposed = True
@ -60,7 +60,7 @@ class WebInterfaceSites:
def __loadPlugins(self):
self.pluginList = Plugins.PluginManager(self.cbox, self.prefs["Locations"]["PluginDir"])
self.pluginList = cryptobox.plugins.manage.PluginManager(self.cbox, self.prefs["Locations"]["PluginDir"])
for plugin in self.pluginList.getPlugins():
if not plugin: continue
plname = plugin.getName()

View File

@ -7,7 +7,7 @@ just inherit this class and add some test functions
import unittest
import twill
import cherrypy
import WebInterfaceSites
import cryptobox.web.dataset
## we do the following, for easy surfing
## e.g. use: cbx.go(your_url)
@ -42,7 +42,7 @@ class WebInterfaceTestClass(unittest.TestCase):
'server.threadPool': 1,
'server.environment': 'production',
})
cherrypy.root = WebInterfaceSites.WebInterfaceSites()
cherrypy.root = cryptobox.web.dataset.WebInterfaceSites()
cherrypy.server.start(initOnly=True, serverClass=None)
from cherrypy._cpwsgi import wsgiApp