diff -r 000000000000 -r 28b7682d5476 encryptionprovider.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/encryptionprovider.py Tue Nov 04 18:26:39 2014 +0100 @@ -0,0 +1,220 @@ +#!/usr/bin/python + +# ------------------------------------------------------------ +# opensecurity package file +# +# Autor: X-Net Services GmbH +# +# Copyright 2013-2014 X-Net and AIT Austrian Institute of Technology +# +# +# X-Net Technologies GmbH +# Elisabethstrasse 1 +# 4020 Linz +# AUSTRIA +# https://www.x-net.at +# +# AIT Austrian Institute of Technology +# Donau City Strasse 1 +# 1220 Wien +# AUSTRIA +# http://www.ait.ac.at +# +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ------------------------------------------------------------ + +import subprocess +import web +import netifaces +import argparse +import thread +import time +import os +import sys +import ConfigParser +import logging +from passwordreceiver import * + +MINOPTS = { "Main" : ["LogFile", "LogLevel", "MountScript", "UmountScript", "InitScript", "GetDevicesScript", "Keyfile"]} + +CONFIG_FILE="/etc/encryptionprovider/encryptionprovider.cfg" +CONFIG_NOT_READABLE = "Configfile is not readable" +CONFIG_WRONG = "Something is wrong with the config" +CONFIG_MISSING = "Section: \"%s\" Option: \"%s\" in configfile is missing" + +def checkMinimumOptions (config): + for section, options in MINOPTS.iteritems (): + for option in options: + if (config.has_option(section, option) == False): + print (CONFIG_MISSING % (section, option)) + exit (129) + + +def loadConfig (): + configfile = CONFIG_FILE + config = ConfigParser.SafeConfigParser () + + if ((os.path.exists (configfile) == False) or (os.path.isfile (configfile) == False) or (os.access (configfile, os.R_OK) == False)): + print (CONFIG_NOT_READABLE) + exit (1) + + try: + config.read (CONFIG_FILE) + except Exception, e: + print (CONFIG_WRONG) + print ("Error: %s" % (e)) + exit (1) + + checkMinimumOptions (config) + return config + +def initLog (config): + global LOG + logfile = config.get("Main", "LogFile") + + numeric_level = getattr(logging, config.get("Main", "LogLevel").upper(), None) + if not isinstance(numeric_level, int): + raise ValueError('Invalid log level: %s' % loglevel) + + # ToDo move log level and maybe other things to config file + logging.basicConfig( + level = numeric_level, + format = "%(asctime)s %(name)-12s %(funcName)-15s %(levelname)-8s %(message)s", + datefmt = "%Y-%m-%d %H:%M:%S", + filename = logfile, + filemode = "a+", + ) + LOG = logging.getLogger("encryptionprovicer") + + + + +def runExternalScripts (command): + LOG.debug ("Run external Script: %s" %(command,)) + + if (os.path.isfile (command[0]) == False): + LOG.error ("File does not exist: %s" %((command[0]),)) + sys.stderr.write("File does not exist: %s\n" %((command[0]),)) + exit (1) + + process = subprocess.Popen( command, stdout=subprocess.PIPE, stderr=subprocess.PIPE ) + retcode = process.wait() + ( stdout, stderr ) = process.communicate() + + return { "retcode" : retcode, "stdout" : stdout, "stderr" : stderr } + + +def getDevices (script): + command = [script]; + result = runExternalScripts (command); + + if (result["retcode"] != 0): + LOG.error ("Retcode: %s" %(result["retcode"],)) + LOG.error ("stdout: %s" %(result["stdout"],)) + LOG.error ("stderr: %s" %(result["stderr"],)) + sys.stderr.write("%s" %(result["stderr"],)) + exit (1) + + #print ("%s" %(result["stdout"],)) + # don't use print here, because of the extra newline + sys.stdout.write ("%s" %(result["stdout"],)) + + +def umountDevice (script, device): + command = [script, device]; + result = runExternalScripts (command); + + if (result["retcode"] != 0): + LOG.error ("Retcode: %s" %(result["retcode"],)) + LOG.error ("stdout: %s" %(result["stdout"],)) + LOG.error ("stderr: %s" %(result["stderr"],)) + sys.stderr.write("%s" %(result["stderr"],)) + exit (1) + + #print ("%s" %(result["stdout"],)) + # don't use print here, because of the extra newline + sys.stdout.write ("%s" %(result["stdout"],)) + + +def mountDevice (script, interface, port, device, mountpoint, keyfilepath): + listener = MyRestListener (opensecurity_urls, globals(), script = script, device = device, mountpoint = mountpoint, tries = 3, keyfilepath = keyfilepath) + thread.start_new_thread(listener.run, (interface, port,)) + + close = False + while (close == False): + time.sleep(1) + if (os.path.ismount(mountpoint) == True): + close = True + LOG.info ("Stick \"%s\" was mounted sucessfully to \"%s\"" %(device, mountpoint,)) + sys.exit(0) + + if (os.path.exists(device) == False): + close = True + LOG.error ("Stick \"%s\" removed -> exit" %(device,)) + sys.exit(1) + +def isDeviceMountedAtMountpoint (device, mountpoint): + command = ("/bin/df %s | /usr/bin/tail -1 | awk '{print $1}'" %(mountpoint,)) + pipe = os.popen(command) + result = pipe.read().rstrip() + + if (pipe.close() != None): + LOG.error ("error: %s" %(result,)) + exit (1) + + if (result == device): + LOG.debug ("Device: %s ### Result: %s ### Return: True" %(device, result,)) + return True + else: + LOG.debug ("Device: %s ### Result: %s ### Return: False" %(device, result,)) + return False + + +def initDevice (script, interface, port, device, mountpoint, keyfilepath, preinitscript, postinitscript): + listener = MyRestListener (opensecurity_urls, globals(), script = script, device = device, mountpoint = mountpoint, tries = 3, keyfilepath = keyfilepath, preinitscript = preinitscript, postinitscript = postinitscript) + thread.start_new_thread(listener.run, (interface, port,)) + + close = False + while (close == False): + time.sleep(1) + if (os.path.exists(device) == False): + close = True + LOG.info ("Stick \"%s\" removed -> exit" %(device,)) + sys.exit(1) + +if __name__ == "__main__": + + parser = argparse.ArgumentParser(epilog='--mount, --umount and --initialize are mutually exclusive') + group = parser.add_mutually_exclusive_group(required=True) + group.add_argument('-m', '--mount', action='store', nargs=4, dest='mount', help='Mounts an encrypted device.', metavar=("interface", "port", "device", "mountpoint")) + group.add_argument('-u', '--umount', action='store', nargs=1, dest='umount', help='Unmounts an encrypted device', metavar="device") + group.add_argument('-i', '--initialize', action='store', nargs=4, dest='initialize', help='Initialize an device.', metavar=("interface", "port", "device", "mountpoint")) + group.add_argument('-g', '--getdevices', action='store_true', dest="getdevices", help='Returns a list of all mounted encrypted devices') + arguments = parser.parse_args() + + + config = loadConfig () + initLog (config) + + if (arguments.getdevices): + getDevices (config.get ("Main", "GetDevicesScript")) + + if (arguments.umount): + umountDevice (config.get ("Main", "UmountScript"), arguments.umount[0]) + + if (arguments.mount): + mountDevice (config.get ("Main", "MountScript"), arguments.mount[0], int(arguments.mount[1]), arguments.mount[2], arguments.mount[3], config.get ("Main", "Keyfile")) + + if (arguments.initialize): + initDevice (config.get ("Main", "InitScript"), arguments.initialize[0], int(arguments.initialize[1]), arguments.initialize[2], arguments.initialize[3], config.get ("Main", "Keyfile"), config.get("Main", "PreInitScript"), config.get("Main", "PostInitScript"))