encryptionprovider.py
changeset 0 28b7682d5476
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/encryptionprovider.py	Tue Nov 04 18:26:39 2014 +0100
     1.3 @@ -0,0 +1,220 @@
     1.4 +#!/usr/bin/python
     1.5 +
     1.6 +# ------------------------------------------------------------
     1.7 +# opensecurity package file
     1.8 +#
     1.9 +# Autor: X-Net Services GmbH <office@x-net.at>
    1.10 +#
    1.11 +# Copyright 2013-2014 X-Net and AIT Austrian Institute of Technology
    1.12 +#
    1.13 +#
    1.14 +#     X-Net Technologies GmbH
    1.15 +#     Elisabethstrasse 1
    1.16 +#     4020 Linz
    1.17 +#     AUSTRIA
    1.18 +#     https://www.x-net.at
    1.19 +#
    1.20 +#     AIT Austrian Institute of Technology
    1.21 +#     Donau City Strasse 1
    1.22 +#     1220 Wien
    1.23 +#     AUSTRIA
    1.24 +#     http://www.ait.ac.at
    1.25 +#
    1.26 +#
    1.27 +# Licensed under the Apache License, Version 2.0 (the "License");
    1.28 +# you may not use this file except in compliance with the License.
    1.29 +# You may obtain a copy of the License at
    1.30 +#
    1.31 +#    http://www.apache.org/licenses/LICENSE-2.0
    1.32 +#
    1.33 +# Unless required by applicable law or agreed to in writing, software
    1.34 +# distributed under the License is distributed on an "AS IS" BASIS,
    1.35 +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    1.36 +# See the License for the specific language governing permissions and
    1.37 +# limitations under the License.
    1.38 +# ------------------------------------------------------------
    1.39 +
    1.40 +import subprocess
    1.41 +import web
    1.42 +import netifaces
    1.43 +import argparse
    1.44 +import thread
    1.45 +import time
    1.46 +import os
    1.47 +import sys
    1.48 +import ConfigParser
    1.49 +import logging
    1.50 +from passwordreceiver import *
    1.51 +
    1.52 +MINOPTS = { "Main" : ["LogFile", "LogLevel", "MountScript", "UmountScript", "InitScript", "GetDevicesScript", "Keyfile"]}
    1.53 +
    1.54 +CONFIG_FILE="/etc/encryptionprovider/encryptionprovider.cfg"
    1.55 +CONFIG_NOT_READABLE = "Configfile is not readable"
    1.56 +CONFIG_WRONG = "Something is wrong with the config"
    1.57 +CONFIG_MISSING = "Section: \"%s\" Option: \"%s\" in configfile is missing"
    1.58 +
    1.59 +def checkMinimumOptions (config):
    1.60 +    for section, options in MINOPTS.iteritems ():
    1.61 +        for option in options:
    1.62 +            if (config.has_option(section, option) == False):
    1.63 +                print (CONFIG_MISSING % (section, option))
    1.64 +                exit (129)
    1.65 +    
    1.66 +    
    1.67 +def loadConfig ():
    1.68 +    configfile = CONFIG_FILE
    1.69 +    config = ConfigParser.SafeConfigParser ()
    1.70 +
    1.71 +    if ((os.path.exists (configfile) == False) or (os.path.isfile (configfile) == False) or (os.access (configfile, os.R_OK) == False)):
    1.72 +        print (CONFIG_NOT_READABLE)
    1.73 +        exit (1)
    1.74 +
    1.75 +    try:
    1.76 +        config.read (CONFIG_FILE)
    1.77 +    except Exception, e:
    1.78 +        print (CONFIG_WRONG)
    1.79 +        print ("Error: %s" % (e))
    1.80 +        exit (1)
    1.81 +
    1.82 +    checkMinimumOptions (config)
    1.83 +    return config
    1.84 +
    1.85 +def initLog (config):
    1.86 +    global LOG
    1.87 +    logfile = config.get("Main", "LogFile")
    1.88 +    
    1.89 +    numeric_level = getattr(logging, config.get("Main", "LogLevel").upper(), None)
    1.90 +    if not isinstance(numeric_level, int):
    1.91 +        raise ValueError('Invalid log level: %s' % loglevel)
    1.92 +
    1.93 +    # ToDo move log level and maybe other things to config file
    1.94 +    logging.basicConfig(
    1.95 +                        level = numeric_level,
    1.96 +                        format = "%(asctime)s %(name)-12s %(funcName)-15s %(levelname)-8s %(message)s",
    1.97 +                        datefmt = "%Y-%m-%d %H:%M:%S",
    1.98 +                        filename = logfile,
    1.99 +                        filemode = "a+",
   1.100 +    )
   1.101 +    LOG = logging.getLogger("encryptionprovicer")
   1.102 +    
   1.103 +    
   1.104 +    
   1.105 +    
   1.106 +def runExternalScripts (command):
   1.107 +    LOG.debug ("Run external Script: %s" %(command,))
   1.108 +    
   1.109 +    if (os.path.isfile (command[0]) == False):
   1.110 +        LOG.error ("File does not exist: %s" %((command[0]),))
   1.111 +        sys.stderr.write("File does not exist: %s\n" %((command[0]),))
   1.112 +        exit (1)
   1.113 +    
   1.114 +    process = subprocess.Popen( command, stdout=subprocess.PIPE, stderr=subprocess.PIPE )
   1.115 +    retcode = process.wait()
   1.116 +    ( stdout, stderr ) = process.communicate()
   1.117 +    
   1.118 +    return { "retcode" : retcode, "stdout" : stdout, "stderr" : stderr }
   1.119 +    
   1.120 +    
   1.121 +def getDevices (script):
   1.122 +    command = [script];
   1.123 +    result = runExternalScripts (command);
   1.124 +    
   1.125 +    if (result["retcode"] != 0):
   1.126 +        LOG.error ("Retcode: %s" %(result["retcode"],))
   1.127 +        LOG.error ("stdout: %s" %(result["stdout"],))
   1.128 +        LOG.error ("stderr: %s" %(result["stderr"],))
   1.129 +        sys.stderr.write("%s" %(result["stderr"],))
   1.130 +        exit (1)
   1.131 +    
   1.132 +    #print ("%s" %(result["stdout"],))
   1.133 +    # don't use print here, because of the extra newline
   1.134 +    sys.stdout.write ("%s" %(result["stdout"],))
   1.135 +
   1.136 +
   1.137 +def umountDevice (script, device):
   1.138 +    command = [script, device];
   1.139 +    result = runExternalScripts (command);
   1.140 +    
   1.141 +    if (result["retcode"] != 0):
   1.142 +        LOG.error ("Retcode: %s" %(result["retcode"],))
   1.143 +        LOG.error ("stdout: %s" %(result["stdout"],))
   1.144 +        LOG.error ("stderr: %s" %(result["stderr"],))
   1.145 +        sys.stderr.write("%s" %(result["stderr"],))
   1.146 +        exit (1)
   1.147 +        
   1.148 +    #print ("%s" %(result["stdout"],))
   1.149 +    # don't use print here, because of the extra newline
   1.150 +    sys.stdout.write ("%s" %(result["stdout"],))
   1.151 +    
   1.152 +
   1.153 +def mountDevice (script, interface, port, device, mountpoint, keyfilepath):    
   1.154 +    listener = MyRestListener (opensecurity_urls, globals(), script = script, device = device, mountpoint = mountpoint, tries = 3, keyfilepath = keyfilepath)
   1.155 +    thread.start_new_thread(listener.run, (interface, port,))
   1.156 +    
   1.157 +    close = False
   1.158 +    while (close == False):
   1.159 +        time.sleep(1)
   1.160 +        if (os.path.ismount(mountpoint) == True):
   1.161 +            close = True
   1.162 +            LOG.info ("Stick \"%s\" was mounted sucessfully to \"%s\"" %(device, mountpoint,))
   1.163 +            sys.exit(0)
   1.164 +            
   1.165 +        if (os.path.exists(device) == False):
   1.166 +            close = True
   1.167 +            LOG.error ("Stick \"%s\" removed -> exit" %(device,))
   1.168 +            sys.exit(1)
   1.169 +
   1.170 +def isDeviceMountedAtMountpoint (device, mountpoint):
   1.171 +    command = ("/bin/df %s | /usr/bin/tail -1 | awk '{print $1}'" %(mountpoint,))
   1.172 +    pipe = os.popen(command)
   1.173 +    result = pipe.read().rstrip()
   1.174 +    
   1.175 +    if (pipe.close() != None):
   1.176 +        LOG.error ("error: %s" %(result,))
   1.177 +        exit (1)
   1.178 +    
   1.179 +    if (result == device):
   1.180 +        LOG.debug ("Device: %s ### Result: %s ### Return: True" %(device, result,))
   1.181 +        return True
   1.182 +    else:
   1.183 +        LOG.debug ("Device: %s ### Result: %s ### Return: False" %(device, result,))
   1.184 +        return False
   1.185 +    
   1.186 +
   1.187 +def initDevice (script, interface, port, device, mountpoint, keyfilepath, preinitscript, postinitscript):    
   1.188 +    listener = MyRestListener (opensecurity_urls, globals(), script = script, device = device, mountpoint = mountpoint, tries = 3, keyfilepath = keyfilepath, preinitscript = preinitscript, postinitscript = postinitscript)
   1.189 +    thread.start_new_thread(listener.run, (interface, port,))
   1.190 +    
   1.191 +    close = False
   1.192 +    while (close == False):
   1.193 +        time.sleep(1)
   1.194 +        if (os.path.exists(device) == False):
   1.195 +            close = True
   1.196 +            LOG.info ("Stick \"%s\" removed -> exit" %(device,))
   1.197 +            sys.exit(1)
   1.198 +
   1.199 +if __name__ == "__main__":
   1.200 +    
   1.201 +    parser = argparse.ArgumentParser(epilog='--mount, --umount and --initialize are mutually exclusive')
   1.202 +    group = parser.add_mutually_exclusive_group(required=True)
   1.203 +    group.add_argument('-m', '--mount', action='store', nargs=4, dest='mount', help='Mounts an encrypted device.', metavar=("interface", "port", "device", "mountpoint"))
   1.204 +    group.add_argument('-u', '--umount', action='store', nargs=1, dest='umount', help='Unmounts an encrypted device', metavar="device")
   1.205 +    group.add_argument('-i', '--initialize', action='store', nargs=4, dest='initialize', help='Initialize an device.', metavar=("interface", "port", "device", "mountpoint"))
   1.206 +    group.add_argument('-g', '--getdevices', action='store_true', dest="getdevices", help='Returns a list of all mounted encrypted devices')
   1.207 +    arguments = parser.parse_args()
   1.208 +    
   1.209 +    
   1.210 +    config = loadConfig ()
   1.211 +    initLog (config)
   1.212 +    
   1.213 +    if (arguments.getdevices):
   1.214 +        getDevices (config.get ("Main", "GetDevicesScript"))
   1.215 +        
   1.216 +    if (arguments.umount):
   1.217 +        umountDevice (config.get ("Main", "UmountScript"), arguments.umount[0])
   1.218 +    
   1.219 +    if (arguments.mount):
   1.220 +        mountDevice (config.get ("Main", "MountScript"), arguments.mount[0], int(arguments.mount[1]), arguments.mount[2], arguments.mount[3], config.get ("Main", "Keyfile"))
   1.221 +    
   1.222 +    if (arguments.initialize):
   1.223 +        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"))