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 LangDir = ../lang
# path to documentation files # path to documentation files
#DocDir = /usr/share/doc/cryptobox/html #DocDir = /usr/share/doc/cryptobox/www-data
DocDir = ../doc/html DocDir = ../doc/html
# path to the plugin directory # 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 Section: admin
Priority: extra Priority: extra
Maintainer: Lars Kruse <devel@sumpfralle.de> 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 Standards-Version: 3.7.2
Package: cryptobox Package: cryptobox

View File

@ -7,5 +7,15 @@
# set to "0" to enable the startup of the cryptobox - otherwise "1" # set to "0" to enable the startup of the cryptobox - otherwise "1"
NO_START=1 NO_START=1
# the use that should execute the cryptobox # the user that should execute the cryptobox
RUNAS=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 # 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} NO_START=${NO_START:-0}
RUNAS=${RUNAS:-cryptobox} 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" ] # quit if NO_START is 1 (see /etc/default/cryptobox)
then [ $# -eq 0 ] && exit 0 [ "$NO_START" = "1" ] && 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
DAEMON=/usr/bin/CryptoBoxWebserver
PIDFILE=/var/run/cryptobox/webserver.pid PIDFILE=/var/run/cryptobox/webserver.pid
DAEMON=/usr/bin/python2.4
DAEMON_OPTS=$CBXPATH/$CBXSERVER
NAME=cryptoboxd
DESC="CryptoBox Daemon (webinterface)" DESC="CryptoBox Daemon (webinterface)"
OPTIONS="-B --pidfile=$PIDFILE --config=$CONF_FILE $SERVER_OPTS"
# check if the package is installed # 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 # include some useful functions to unify our output format
. /lib/lsb/init-functions . /lib/lsb/init-functions
@ -57,24 +49,28 @@ case "$1" in
# TODO: create certificate # TODO: create certificate
# TODO: run stunnel # TODO: run stunnel
# the lines above should go into the live-cd scripts # 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 ..." ## create the directory of the pid file if necessary
log_daemon_msg "Starting cryptobox webserver" "$DESC" 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 \ if start-stop-daemon \
--chdir "$CBXPATH" --chuid "$RUNAS" --quiet --start \ --chuid $RUNAS: --quiet --start \
-oknodo --user "$RUNAS" --pidfile "$PIDFILE" \ --oknodo --user $RUNAS --pidfile "$PIDFILE" \
--exec "$DAEMON" -- $DAEMON_OPTS --exec /usr/bin/python --startas "$DAEMON" -- $OPTIONS
then log_end_msg 0 then log_end_msg 0
else log_end_msg 1 else log_end_msg 1
exit 1 exit 1
fi fi
;; ;;
stop ) 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" 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" then rm "$PIDFILE"
log_end_msg 0 log_end_msg 0
else log_end_msg 1 else log_end_msg 1
@ -86,8 +82,22 @@ case "$1" in
sleep 1 sleep 1
"$0" start "$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 exit 1
;; ;;
esac esac

2
debian/postinst vendored
View File

@ -35,7 +35,7 @@ create_add_super_permission()
## do nothing, if there is already a CryptoBox line ## do nothing, if there is already a CryptoBox line
grep -q "CRYPTOBOX_MARKER" "$SUPER_FILE" && return 0 grep -q "CRYPTOBOX_MARKER" "$SUPER_FILE" && return 0
echo >>"$SUPER_FILE" "## CRYPTOBOX_MARKER - please do not remove!" 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() create_pid_dir()

5
debian/rules vendored
View File

@ -51,9 +51,10 @@ install: build
dh_testroot dh_testroot
dh_clean -k dh_clean -k
dh_installdirs 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/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. # 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" ] pluginCapabilities = [ "system" ]
pluginVisibility = [ "preferences" ] 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" ] pluginCapabilities = [ "system" ]
pluginVisibility = [ "menu" ] 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" ] pluginCapabilities = [ "system" ]
pluginVisibility = [ "menu" ] 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" ] pluginCapabilities = [ "system" ]
pluginVisibility = [ "menu", "preferences" ] pluginVisibility = [ "menu", "preferences" ]

View File

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

View File

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

View File

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

View File

@ -1,8 +1,8 @@
import CryptoBoxPlugin import cryptobox.plugins.base
import Plugins import cryptobox.plugins.manage
class plugin_manager(CryptoBoxPlugin.CryptoBoxPlugin): class plugin_manager(cryptobox.plugins.base.CryptoBoxPlugin):
pluginCapabilities = [ "system" ] pluginCapabilities = [ "system" ]
pluginVisibility = [ "preferences" ] pluginVisibility = [ "preferences" ]
@ -14,7 +14,7 @@ class plugin_manager(CryptoBoxPlugin.CryptoBoxPlugin):
if plugin_name: if plugin_name:
## check for invalid characters ## check for invalid characters
if re.search(u'\W', plugin_name): return "plugin_list" 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) plugin = pluginList.getPlugin(plugin_name)
if not plugin: return "plugin_list" if not plugin: return "plugin_list"
## take only plugins, that are of the same type as the choosen one ## 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 REDIRECT_DELAY = 180
class shutdown(CryptoBoxPlugin.CryptoBoxPlugin): class shutdown(cryptobox.plugins.base.CryptoBoxPlugin):
pluginCapabilities = [ "system" ] pluginCapabilities = [ "system" ]
pluginVisibility = [ "preferences", "menu" ] 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" ] pluginCapabilities = [ "system" ]
pluginVisibility = [ "menu" ] pluginVisibility = [ "menu" ]

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

49
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 ## check python version
import sys import sys
(ver_major, ver_minor, ver_sub, ver_desc, ver_subsub) = sys.version_info (ver_major, ver_minor, ver_sub, ver_desc, ver_subsub) = sys.version_info
@ -11,7 +9,7 @@ import subprocess
import os import os
import re import re
import logging import logging
from CryptoBoxExceptions import * from cryptobox.core.exceptions import *
"""exceptions: """exceptions:
CBVolumeIsActive CBVolumeIsActive
@ -24,14 +22,15 @@ from CryptoBoxExceptions import *
CBChangePasswordError CBChangePasswordError
""" """
class CryptoBoxContainer: ContainerTypes = {
"unused":0,
"plain":1,
"luks":2,
"swap":3,
}
Types = {
"unused":0, class CryptoBoxContainer:
"plain":1,
"luks":2,
"swap":3}
__fsTypes = { __fsTypes = {
"plain":["ext3", "ext2", "vfat", "reiser"], "plain":["ext3", "ext2", "vfat", "reiser"],
@ -126,8 +125,8 @@ class CryptoBoxContainer:
the result is a value in megabyte the result is a value in megabyte
an error is indicated by "-1" an error is indicated by "-1"
""" """
import CryptoBoxTools import cryptobox.core.tools as cbxtools
return CryptoBoxTools.getBlockDeviceSize(self.device) return cbxtools.getBlockDeviceSize(self.device)
def resetObject(self): def resetObject(self):
@ -137,19 +136,19 @@ class CryptoBoxContainer:
self.type = self.__getTypeOfPartition() self.type = self.__getTypeOfPartition()
self.name = self.__getNameOfContainer() self.name = self.__getNameOfContainer()
self.__setAttributes() self.__setAttributes()
if self.type == self.Types["luks"]: if self.type == ContainerTypes["luks"]:
self.mount = self.__mountLuks self.mount = self.__mountLuks
self.umount = self.__umountLuks self.umount = self.__umountLuks
elif self.type == self.Types["plain"]: elif self.type == ContainerTypes["plain"]:
self.mount = self.__mountPlain self.mount = self.__mountPlain
self.umount = self.__umountPlain self.umount = self.__umountPlain
def create(self, type, password=None): def create(self, type, password=None):
old_name = self.getName() old_name = self.getName()
if type == self.Types["luks"]: if type == ContainerTypes["luks"]:
self.__createLuks(password) self.__createLuks(password)
elif type == self.Types["plain"]: elif type == ContainerTypes["plain"]:
self.__createPlain() self.__createPlain()
else: else:
raise CBInvalidType("invalid container type (%d) supplied" % (type, )) raise CBInvalidType("invalid container type (%d) supplied" % (type, ))
@ -161,7 +160,7 @@ class CryptoBoxContainer:
def changePassword(self, oldpw, newpw): 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") raise CBInvalidType("changing of password is possible only for luks containers")
if not oldpw: if not oldpw:
raise CBInvalidPassword("no old password supplied for password change") raise CBInvalidPassword("no old password supplied for password change")
@ -247,7 +246,7 @@ class CryptoBoxContainer:
def __getUUID(self): def __getUUID(self):
if self.__getTypeOfPartition() == self.Types["luks"]: if self.__getTypeOfPartition() == ContainerTypes["luks"]:
guess = self.__getLuksUUID() guess = self.__getLuksUUID()
else: else:
guess = self.__getNonLuksUUID() guess = self.__getNonLuksUUID()
@ -302,14 +301,14 @@ class CryptoBoxContainer:
def __getTypeOfPartition(self): def __getTypeOfPartition(self):
"retrieve the type of the given partition (see CryptoBoxContainer.Types)" "retrieve the type of the given partition (see cryptobox.core.container.ContainerTypes)"
if self.__isLuksPartition(): return self.Types["luks"] if self.__isLuksPartition(): return ContainerTypes["luks"]
typeOfPartition = self.__getTypeIdOfPartition() typeOfPartition = self.__getTypeIdOfPartition()
if typeOfPartition in self.__fsTypes["plain"]: if typeOfPartition in self.__fsTypes["plain"]:
return self.Types["plain"] return ContainerTypes["plain"]
if typeOfPartition in self.__fsTypes["swap"]: if typeOfPartition in self.__fsTypes["swap"]:
return self.Types["swap"] return ContainerTypes["swap"]
return self.Types["unused"] return ContainerTypes["unused"]
def __getTypeIdOfPartition(self): def __getTypeIdOfPartition(self):
@ -645,8 +644,8 @@ class CryptoBoxContainer:
def __getEventArgs(self): 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""" 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()] 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""" """base class for exceptions of the cryptobox"""
pass pass
class CBConfigError(CryptoBoxError): class CBConfigError(CBError):
"""any kind of error related to the configuration of a cryptobox""" """any kind of error related to the configuration of a cryptobox"""
pass pass
@ -57,7 +57,7 @@ class CBConfigInvalidValueError(CBConfigError):
return "invalid configuration setting [%s]->%s (%s): %s" % (self.section, self.name, self.value, self.reason) 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 """some part of the environment of the cryptobox is broken
e.g. the wrong version of a required program e.g. the wrong version of a required program
""" """
@ -69,7 +69,7 @@ class CBEnvironmentError(CryptoBoxError):
return "misconfiguration detected: %s" % self.desc return "misconfiguration detected: %s" % self.desc
class CBContainerError(CryptoBoxError): class CBContainerError(CBError):
"""any error raised while manipulating a cryptobox container""" """any error raised while manipulating a cryptobox container"""
def __init__(self, desc): 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. 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.stderr.write("You need a python version >= 2.4\nCurrent version is:\n %s\n" % sys.version)
sys.exit(1) sys.exit(1)
import CryptoBoxContainer import cryptobox.core.container as cbxContainer
from CryptoBoxExceptions import * from cryptobox.core.exceptions import *
import re import re
import os import os
import CryptoBoxTools import cryptobox.core.tools as cbxTools
import subprocess import subprocess
VERSION = "0.3~1"
class CryptoBox: class CryptoBox:
'''this class rules them all! '''this class rules them all!
@ -29,12 +29,11 @@ class CryptoBox:
put things like logging, conf and oter stuff in here, put things like logging, conf and oter stuff in here,
that might be used by more classes, it will be passed on to them''' that might be used by more classes, it will be passed on to them'''
VERSION = "0.3~1"
def __init__(self, config_file=None): def __init__(self, config_file=None):
import CryptoBoxSettings import cryptobox.core.settings as cbxSettings
self.log = self.__getStartupLogger() self.log = self.__getStartupLogger()
self.prefs = CryptoBoxSettings.CryptoBoxSettings(config_file) self.prefs = cbxSettings.CryptoBoxSettings(config_file)
self.__runTests() self.__runTests()
@ -124,9 +123,9 @@ class CryptoBoxProps(CryptoBox):
def reReadContainerList(self): def reReadContainerList(self):
self.log.debug("rereading container list") self.log.debug("rereading container list")
self.containers = [] self.containers = []
for device in CryptoBoxTools.getAvailablePartitions(): for device in cbxTools.getAvailablePartitions():
if self.isDeviceAllowed(device) and not self.isConfigPartition(device): 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 ## sort by container name
self.containers.sort(cmp = lambda x,y: x.getName() < y.getName() and -1 or 1) self.containers.sort(cmp = lambda x,y: x.getName() < y.getName() and -1 or 1)
@ -187,7 +186,7 @@ class CryptoBoxProps(CryptoBox):
try: try:
result = self.containers[:] result = self.containers[:]
if filterType != None: 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] return [e for e in self.containers if e.getType() == filterType]
else: else:
self.log.info("invalid filterType (%d)" % filterType) self.log.info("invalid filterType (%d)" % filterType)
@ -221,14 +220,14 @@ class CryptoBoxProps(CryptoBox):
def sendEventNotification(self, event, event_infos): def sendEventNotification(self, event, event_infos):
"""call all available scripts in the hook directory with some event information""" """call all available scripts in the event directory with some event information"""
hook_dir = self.prefs["Locations"]["HookDir"] event_dir = self.prefs["Locations"]["EventDir"]
for fname in os.listdir(hook_dir): for fname in os.listdir(event_dir):
real_fname = os.path.join(hook_dir, fname) real_fname = os.path.join(event_dir, fname)
if os.path.isfile(real_fname) and os.access(real_fname, os.X_OK): if os.path.isfile(real_fname) and os.access(real_fname, os.X_OK):
cmd_args = [ self.prefs["Programs"]["super"], cmd_args = [ self.prefs["Programs"]["super"],
self.prefs["Programs"]["CryptoBoxRootActions"], self.prefs["Programs"]["CryptoBoxRootActions"],
"hook", real_fname, event] "event", real_fname, event]
cmd_args.extend(event_infos) cmd_args.extend(event_infos)
proc = subprocess.Popen( proc = subprocess.Popen(
shell = False, shell = False,
@ -237,7 +236,7 @@ class CryptoBoxProps(CryptoBox):
args = cmd_args) args = cmd_args)
(stdout, stderr) = proc.communicate() (stdout, stderr) = proc.communicate()
if proc.returncode != 0: 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: else:
self.log.info("event handler (%s) finished successfully: %s" % (real_fname, event)) 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 import logging
try: try:
import validate import validate
except: 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 os
import CryptoBoxExceptions
import subprocess import subprocess
try: try:
import configobj ## needed for reading and writing of the config file import configobj ## needed for reading and writing of the config file
except: except:
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: if prefs:
self.log.info("found config: %s" % prefs.items()) self.log.info("found config: %s" % prefs.items())
else: 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: 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 return prefs
@ -190,7 +190,7 @@ class CryptoBoxSettings:
else: else:
errorMsg = "invalid configuration value (%s) in section '%s': %s" % (key, section_name, text) errorMsg = "invalid configuration value (%s) in section '%s': %s" % (key, section_name, text)
errorMsgs.append(errorMsg) errorMsgs.append(errorMsg)
raise CryptoBoxExceptions.CBConfigError, "\n".join(errorMsgs) raise CBConfigError, "\n".join(errorMsgs)
def __checkUnknownPreferences(self): def __checkUnknownPreferences(self):
@ -228,9 +228,9 @@ class CryptoBoxSettings:
try: try:
pluginConf_file = os.path.join(self.prefs["Locations"]["SettingsDir"], self.PLUGINCONF_FILE) pluginConf_file = os.path.join(self.prefs["Locations"]["SettingsDir"], self.PLUGINCONF_FILE)
except KeyError: except KeyError:
raise CryptoBoxExceptions.CBConfigUndefinedError("Locations", "SettingsDir") raise CBConfigUndefinedError("Locations", "SettingsDir")
except SyntaxError: 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 ## create pluginConf_file if necessary
if os.path.exists(pluginConf_file): if os.path.exists(pluginConf_file):
pluginConf = configobj.ConfigObj(pluginConf_file, configspec=plugin_rules) pluginConf = configobj.ConfigObj(pluginConf_file, configspec=plugin_rules)
@ -240,7 +240,7 @@ class CryptoBoxSettings:
pluginConf.validate(validate.Validator()) pluginConf.validate(validate.Validator())
## check if pluginConf_file file was created successfully? ## check if pluginConf_file file was created successfully?
if not os.path.exists(pluginConf_file): 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 return pluginConf
@ -249,9 +249,9 @@ class CryptoBoxSettings:
try: try:
conf_file = os.path.join(self.prefs["Locations"]["SettingsDir"], self.VOLUMESDB_FILE) conf_file = os.path.join(self.prefs["Locations"]["SettingsDir"], self.VOLUMESDB_FILE)
except KeyError: except KeyError:
raise CryptoBoxExceptions.CBConfigUndefinedError("Locations", "SettingsDir") raise CBConfigUndefinedError("Locations", "SettingsDir")
except SyntaxError: 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 ## create conf_file if necessary
if os.path.exists(conf_file): if os.path.exists(conf_file):
conf = configobj.ConfigObj(conf_file) conf = configobj.ConfigObj(conf_file)
@ -259,7 +259,7 @@ class CryptoBoxSettings:
conf = configobj.ConfigObj(conf_file, create_empty=True) conf = configobj.ConfigObj(conf_file, create_empty=True)
## check if conf_file file was created successfully? ## check if conf_file file was created successfully?
if not os.path.exists(conf_file): 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 return conf
@ -270,9 +270,9 @@ class CryptoBoxSettings:
try: try:
userDB_file = os.path.join(self.prefs["Locations"]["SettingsDir"], self.USERDB_FILE) userDB_file = os.path.join(self.prefs["Locations"]["SettingsDir"], self.USERDB_FILE)
except KeyError: except KeyError:
raise CryptoBoxExceptions.CBConfigUndefinedError("Locations", "SettingsDir") raise CBConfigUndefinedError("Locations", "SettingsDir")
except SyntaxError: 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 ## create userDB_file if necessary
if os.path.exists(userDB_file): if os.path.exists(userDB_file):
userDB = configobj.ConfigObj(userDB_file, configspec=userDB_rules) userDB = configobj.ConfigObj(userDB_file, configspec=userDB_rules)
@ -282,7 +282,7 @@ class CryptoBoxSettings:
userDB.validate(validate.Validator()) userDB.validate(validate.Validator())
## check if userDB file was created successfully? ## check if userDB file was created successfully?
if not os.path.exists(userDB_file): 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 ## define password hash function - never use "sha" directly - SPOT
userDB.getDigest = lambda password: sha.new(password).hexdigest() userDB.getDigest = lambda password: sha.new(password).hexdigest()
return userDB return userDB
@ -307,14 +307,14 @@ class CryptoBoxSettings:
if os.path.exists(os.path.expanduser(f))] if os.path.exists(os.path.expanduser(f))]
if not conf_file_list: if not conf_file_list:
# no possible config file found in the usual locations # no possible config file found in the usual locations
raise CryptoBoxExceptions.CBConfigUnavailableError() raise CBConfigUnavailableError()
config_file = conf_file_list[0] config_file = conf_file_list[0]
else: else:
# a config file was specified (e.g. via command line) # a config file was specified (e.g. via command line)
if type(config_file) != types.StringType: if type(config_file) != types.StringType:
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): 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 return config_file
@ -325,16 +325,16 @@ class CryptoBoxSettings:
if not log_level in log_level_avail: if not log_level in log_level_avail:
raise TypeError raise TypeError
except KeyError: except KeyError:
raise CryptoBoxExceptions.CBConfigUndefinedError("Log", "Level") raise CBConfigUndefinedError("Log", "Level")
except TypeError: 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:
try: try:
log_handler = logging.FileHandler(self.prefs["Log"]["Details"]) log_handler = logging.FileHandler(self.prefs["Log"]["Details"])
except KeyError: except KeyError:
raise CryptoBoxExceptions.CBConfigUndefinedError("Log", "Details") raise CBConfigUndefinedError("Log", "Details")
except IOError: 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')) log_handler.setFormatter(logging.Formatter('%(asctime)s CryptoBox %(levelname)s: %(message)s'))
cbox_log = logging.getLogger("CryptoBox") cbox_log = logging.getLogger("CryptoBox")
## remove previous handlers ## remove previous handlers
@ -362,9 +362,9 @@ MountParentDir = directoryExists(default="/var/cache/cryptobox/mnt")
SettingsDir = directoryExists(default="/var/cache/cryptobox/settings") SettingsDir = directoryExists(default="/var/cache/cryptobox/settings")
TemplateDir = directoryExists(default="/usr/share/cryptobox/template") TemplateDir = directoryExists(default="/usr/share/cryptobox/template")
LangDir = directoryExists(default="/usr/share/cryptobox/lang") 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") PluginDir = directoryExists(default="/usr/share/cryptobox/plugins")
HookDir = directoryExists(default="/etc/cryptobox/hooks") EventDir = directoryExists(default="/etc/cryptobox/events.d")
[Log] [Log]
Level = option("debug", "info", "warn", "error", default="warn") 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 LangDir = ../lang
DocDir = ../doc/html DocDir = ../doc/html
PluginDir = ../plugins PluginDir = ../plugins
HookDir = ../hook-scripts EventDir = ../event-scripts
[Log] [Log]
Level = debug Level = debug
Destination = file Destination = file

View File

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

View File

@ -7,11 +7,11 @@ from twill.errors import *
from mechanize import BrowserStateError, LinkNotFoundError from mechanize import BrowserStateError, LinkNotFoundError
## import the module of the common super class of all web interface test classes ## 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): def test_is_server_running(self):
'''the server should run under given name and port''' '''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 ## 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): def test_goto_index(self):

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

View File

@ -1,9 +1,8 @@
import os import os
import CryptoBoxContainer from cryptobox.core.exceptions import *
import CryptoBoxTools 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): class WebInterfaceDataset(dict):
"""this class contains all data that should be available for the clearsilver """this class contains all data that should be available for the clearsilver
@ -22,7 +21,8 @@ class WebInterfaceDataset(dict):
def setCryptoBoxState(self): def setCryptoBoxState(self):
import cherrypy import cherrypy
self["Data.Version"] = self.cbox.VERSION import cryptobox.core.main
self["Data.Version"] = cryptobox.core.main.VERSION
langs = self.cbox.getAvailableLanguages() langs = self.cbox.getAvailableLanguages()
langs.sort() langs.sort()
for (index, lang) in enumerate(langs): for (index, lang) in enumerate(langs):
@ -60,15 +60,15 @@ class WebInterfaceDataset(dict):
def setCurrentDiskState(self, device): def setCurrentDiskState(self, device):
for container in self.cbox.getContainerList(): for container in self.cbox.getContainerList():
if container.getDevice() == device: if container.getDevice() == device:
isEncrypted = (container.getType() == CONT_TYPES["luks"]) and 1 or 0 isEncrypted = (container.getType() == cbxContainer.ContainerTypes["luks"]) and 1 or 0
isPlain = (container.getType() == CONT_TYPES["plain"]) and 1 or 0 isPlain = (container.getType() == cbxContainer.ContainerTypes["plain"]) and 1 or 0
isMounted = container.isMounted() and 1 or 0 isMounted = container.isMounted() and 1 or 0
self["Data.CurrentDisk.device"] = container.getDevice() self["Data.CurrentDisk.device"] = container.getDevice()
self["Data.CurrentDisk.name"] = container.getName() self["Data.CurrentDisk.name"] = container.getName()
self["Data.CurrentDisk.encryption"] = isEncrypted self["Data.CurrentDisk.encryption"] = isEncrypted
self["Data.CurrentDisk.plaintext"] = isPlain self["Data.CurrentDisk.plaintext"] = isPlain
self["Data.CurrentDisk.active"] = isMounted self["Data.CurrentDisk.active"] = isMounted
self["Data.CurrentDisk.size"] = CryptoBoxTools.getBlockDeviceSizeHumanly(container.getDevice()) self["Data.CurrentDisk.size"] = cbxTools.getBlockDeviceSizeHumanly(container.getDevice())
if isMounted: if isMounted:
(size, avail, used) = container.getCapacity() (size, avail, used) = container.getCapacity()
percent = used / size percent = used / size
@ -85,15 +85,15 @@ class WebInterfaceDataset(dict):
for container in self.cbox.getContainerList(): for container in self.cbox.getContainerList():
## useful if the container was changed during an action ## useful if the container was changed during an action
container.resetObject() container.resetObject()
isEncrypted = (container.getType() == CONT_TYPES["luks"]) and 1 or 0 isEncrypted = (container.getType() == cbxContainer.ContainerTypes["luks"]) and 1 or 0
isPlain = (container.getType() == CONT_TYPES["plain"]) and 1 or 0 isPlain = (container.getType() == cbxContainer.ContainerTypes["plain"]) and 1 or 0
isMounted = container.isMounted() and 1 or 0 isMounted = container.isMounted() and 1 or 0
self["Data.Disks.%d.device" % avail_counter] = container.getDevice() self["Data.Disks.%d.device" % avail_counter] = container.getDevice()
self["Data.Disks.%d.name" % avail_counter] = container.getName() self["Data.Disks.%d.name" % avail_counter] = container.getName()
self["Data.Disks.%d.encryption" % avail_counter] = isEncrypted self["Data.Disks.%d.encryption" % avail_counter] = isEncrypted
self["Data.Disks.%d.plaintext" % avail_counter] = isPlain self["Data.Disks.%d.plaintext" % avail_counter] = isPlain
self["Data.Disks.%d.active" % avail_counter] = isMounted 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 if isMounted: active_counter += 1
avail_counter += 1 avail_counter += 1
self["Data.activeDisksCount"] = active_counter self["Data.activeDisksCount"] = active_counter
@ -131,7 +131,7 @@ class WebInterfaceDataset(dict):
try: try:
import neo_cgi, neo_util, neo_cs import neo_cgi, neo_util, neo_cs
except: 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_path = os.path.join(self.prefs["Locations"]["LangDir"], lang + ".hdf")
hdf = neo_util.HDF() hdf = neo_util.HDF()
hdf.readFile(hdf_path) 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 cryptobox.core.main
import WebInterfaceDataset import cryptobox.web.dataset
import cryptobox.plugins.manage
from cryptobox.core.exceptions import *
import re import re
import Plugins
from CryptoBoxExceptions import *
import cherrypy import cherrypy
import types import types
import os import os
@ -36,9 +36,9 @@ class WebInterfaceSites:
defaultTemplate = "empty" defaultTemplate = "empty"
def __init__(self): def __init__(self, conf_file=None):
import logging,sys import logging,sys
self.cbox = CryptoBox.CryptoBoxProps() self.cbox = cryptobox.core.main.CryptoBoxProps(conf_file)
self.log = logging.getLogger("CryptoBox") self.log = logging.getLogger("CryptoBox")
self.prefs = self.cbox.prefs self.prefs = self.cbox.prefs
self.__resetDataset() self.__resetDataset()
@ -51,7 +51,7 @@ class WebInterfaceSites:
also take care for the plugins, as they also contain datasets also take care for the plugins, as they also contain datasets
""" """
self.__loadPlugins() 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 ## publish plugin icons
self.icons = PluginIconHandler(self.pluginList) self.icons = PluginIconHandler(self.pluginList)
self.icons.exposed = True self.icons.exposed = True
@ -60,7 +60,7 @@ class WebInterfaceSites:
def __loadPlugins(self): 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(): for plugin in self.pluginList.getPlugins():
if not plugin: continue if not plugin: continue
plname = plugin.getName() plname = plugin.getName()

View File

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