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