src/encryptionprovider.py
author ft
Tue, 09 Sep 2014 09:19:17 +0200
changeset 25 25581dcb9e62
parent 12 ee0ff4b21221
child 27 a8c8d86b8501
permissions -rwxr-xr-x
changed information notifications (no popup anymore)
ft@0
     1
#!/usr/bin/python
ft@0
     2
ft@0
     3
import subprocess
ft@0
     4
import web
ft@0
     5
import netifaces
ft@0
     6
import argparse
ft@0
     7
import thread
ft@0
     8
import time
ft@0
     9
import os
ft@0
    10
import sys
ft@0
    11
import ConfigParser
ft@0
    12
import logging
ft@1
    13
from passwordreceiver import *
ft@0
    14
ft@1
    15
MINOPTS = { "Main" : ["LogFile", "LogLevel", "MountScript", "UmountScript", "InitScript", "GetDevicesScript", "Keyfile"]}
ft@0
    16
ft@6
    17
CONFIG_FILE="/etc/encryptionprovider/encryptionprovider.cfg"
ft@0
    18
CONFIG_NOT_READABLE = "Configfile is not readable"
ft@0
    19
CONFIG_WRONG = "Something is wrong with the config"
ft@0
    20
CONFIG_MISSING = "Section: \"%s\" Option: \"%s\" in configfile is missing"
ft@0
    21
ft@0
    22
def checkMinimumOptions (config):
ft@0
    23
    for section, options in MINOPTS.iteritems ():
ft@0
    24
        for option in options:
ft@0
    25
            if (config.has_option(section, option) == False):
ft@0
    26
                print (CONFIG_MISSING % (section, option))
ft@0
    27
                exit (129)
ft@0
    28
    
ft@0
    29
    
ft@0
    30
def loadConfig ():
ft@0
    31
    configfile = CONFIG_FILE
ft@0
    32
    config = ConfigParser.SafeConfigParser ()
ft@0
    33
ft@0
    34
    if ((os.path.exists (configfile) == False) or (os.path.isfile (configfile) == False) or (os.access (configfile, os.R_OK) == False)):
ft@0
    35
        print (CONFIG_NOT_READABLE)
ft@0
    36
        exit (1)
ft@0
    37
ft@0
    38
    try:
ft@0
    39
        config.read (CONFIG_FILE)
ft@0
    40
    except Exception, e:
ft@0
    41
        print (CONFIG_WRONG)
ft@0
    42
        print ("Error: %s" % (e))
ft@0
    43
        exit (1)
ft@0
    44
ft@0
    45
    checkMinimumOptions (config)
ft@0
    46
    return config
ft@0
    47
ft@0
    48
def initLog (config):
ft@0
    49
    global LOG
ft@0
    50
    logfile = config.get("Main", "LogFile")
ft@0
    51
    
ft@0
    52
    numeric_level = getattr(logging, config.get("Main", "LogLevel").upper(), None)
ft@0
    53
    if not isinstance(numeric_level, int):
ft@0
    54
        raise ValueError('Invalid log level: %s' % loglevel)
ft@0
    55
ft@0
    56
    # ToDo move log level and maybe other things to config file
ft@0
    57
    logging.basicConfig(
ft@0
    58
                        level = numeric_level,
ft@0
    59
                        format = "%(asctime)s %(name)-12s %(funcName)-15s %(levelname)-8s %(message)s",
ft@0
    60
                        datefmt = "%Y-%m-%d %H:%M:%S",
ft@0
    61
                        filename = logfile,
ft@0
    62
                        filemode = "a+",
ft@0
    63
    )
ft@17
    64
    LOG = logging.getLogger("encryptionprovicer")
ft@0
    65
    
ft@0
    66
    
ft@0
    67
    
ft@0
    68
    
ft@1
    69
def runExternalScripts (command):
ft@1
    70
    LOG.debug ("Run external Script: %s" %(command,))
ft@0
    71
    
ft@1
    72
    if (os.path.isfile (command[0]) == False):
ft@1
    73
        LOG.error ("File does not exist: %s" %((command[0]),))
ft@1
    74
        sys.stderr.write("File does not exist: %s\n" %((command[0]),))
ft@1
    75
        exit (1)
ft@0
    76
    
ft@1
    77
    process = subprocess.Popen( command, stdout=subprocess.PIPE, stderr=subprocess.PIPE )
ft@1
    78
    retcode = process.wait()
ft@1
    79
    ( stdout, stderr ) = process.communicate()
ft@0
    80
    
ft@1
    81
    return { "retcode" : retcode, "stdout" : stdout, "stderr" : stderr }
ft@1
    82
    
ft@1
    83
    
ft@1
    84
def getDevices (script):
ft@1
    85
    command = [script];
ft@1
    86
    result = runExternalScripts (command);
ft@1
    87
    
ft@1
    88
    if (result["retcode"] != 0):
ft@1
    89
        LOG.error ("Retcode: %s" %(result["retcode"],))
ft@1
    90
        LOG.error ("stdout: %s" %(result["stdout"],))
ft@1
    91
        LOG.error ("stderr: %s" %(result["stderr"],))
ft@1
    92
        sys.stderr.write("%s" %(result["stderr"],))
ft@1
    93
        exit (1)
ft@1
    94
    
ft@1
    95
    #print ("%s" %(result["stdout"],))
ft@1
    96
    # don't use print here, because of the extra newline
ft@1
    97
    sys.stdout.write ("%s" %(result["stdout"],))
ft@1
    98
ft@1
    99
ft@1
   100
def umountDevice (script, device):
ft@1
   101
    command = [script, device];
ft@1
   102
    result = runExternalScripts (command);
ft@1
   103
    
ft@1
   104
    if (result["retcode"] != 0):
ft@1
   105
        LOG.error ("Retcode: %s" %(result["retcode"],))
ft@1
   106
        LOG.error ("stdout: %s" %(result["stdout"],))
ft@1
   107
        LOG.error ("stderr: %s" %(result["stderr"],))
ft@1
   108
        sys.stderr.write("%s" %(result["stderr"],))
ft@1
   109
        exit (1)
ft@1
   110
        
ft@1
   111
    #print ("%s" %(result["stdout"],))
ft@1
   112
    # don't use print here, because of the extra newline
ft@1
   113
    sys.stdout.write ("%s" %(result["stdout"],))
ft@1
   114
    
ft@1
   115
ft@1
   116
def mountDevice (script, interface, port, device, mountpoint, keyfilepath):    
ft@1
   117
    listener = MyRestListener (opensecurity_urls, globals(), script = script, device = device, mountpoint = mountpoint, tries = 3, keyfilepath = keyfilepath)
ft@1
   118
    thread.start_new_thread(listener.run, (interface, port,))
ft@1
   119
    
ft@1
   120
    close = False
ft@1
   121
    while (close == False):
ft@1
   122
        time.sleep(1)
ft@1
   123
        if (os.path.ismount(mountpoint) == True):
ft@1
   124
            close = True
ft@1
   125
            LOG.info ("Stick \"%s\" was mounted sucessfully to \"%s\"" %(device, mountpoint,))
ft@1
   126
            sys.exit(0)
ft@1
   127
            
ft@1
   128
        if (os.path.exists(device) == False):
ft@1
   129
            close = True
ft@1
   130
            LOG.error ("Stick \"%s\" removed -> exit" %(device,))
ft@1
   131
            sys.exit(1)
ft@1
   132
ft@9
   133
def isDeviceMountedAtMountpoint (device, mountpoint):
ft@10
   134
    command = ("/bin/df %s | /usr/bin/tail -1 | awk '{print $1}'" %(mountpoint,))
ft@11
   135
    pipe = os.popen(command)
ft@12
   136
    result = pipe.read().rstrip()
ft@10
   137
    
ft@11
   138
    if (pipe.close() != None):
ft@11
   139
        LOG.error ("error: %s" %(result,))
ft@9
   140
        exit (1)
ft@9
   141
    
ft@11
   142
    if (result == device):
ft@12
   143
        LOG.debug ("Device: %s ### Result: %s ### Return: True" %(device, result,))
ft@9
   144
        return True
ft@9
   145
    else:
ft@12
   146
        LOG.debug ("Device: %s ### Result: %s ### Return: False" %(device, result,))
ft@9
   147
        return False
ft@9
   148
    
ft@9
   149
ft@17
   150
def initDevice (script, interface, port, device, mountpoint, keyfilepath, preinitscript, postinitscript):    
ft@17
   151
    listener = MyRestListener (opensecurity_urls, globals(), script = script, device = device, mountpoint = mountpoint, tries = 3, keyfilepath = keyfilepath, preinitscript = preinitscript, postinitscript = postinitscript)
ft@7
   152
    thread.start_new_thread(listener.run, (interface, port,))
ft@7
   153
    
ft@7
   154
    close = False
ft@7
   155
    while (close == False):
ft@7
   156
        time.sleep(1)
ft@7
   157
        if (os.path.exists(device) == False):
ft@7
   158
            close = True
ft@8
   159
            LOG.info ("Stick \"%s\" removed -> exit" %(device,))
ft@9
   160
            sys.exit(1)
ft@7
   161
ft@0
   162
if __name__ == "__main__":
ft@0
   163
    
ft@0
   164
    parser = argparse.ArgumentParser(epilog='--mount, --umount and --initialize are mutually exclusive')
ft@0
   165
    group = parser.add_mutually_exclusive_group(required=True)
ft@7
   166
    group.add_argument('-m', '--mount', action='store', nargs=4, dest='mount', help='Mounts an encrypted device.', metavar=("interface", "port", "device", "mountpoint"))
ft@7
   167
    group.add_argument('-u', '--umount', action='store', nargs=1, dest='umount', help='Unmounts an encrypted device', metavar="device")
ft@7
   168
    group.add_argument('-i', '--initialize', action='store', nargs=4, dest='initialize', help='Initialize an device.', metavar=("interface", "port", "device", "mountpoint"))
ft@1
   169
    group.add_argument('-g', '--getdevices', action='store_true', dest="getdevices", help='Returns a list of all mounted encrypted devices')
ft@0
   170
    arguments = parser.parse_args()
ft@0
   171
    
ft@0
   172
    
ft@0
   173
    config = loadConfig ()
ft@0
   174
    initLog (config)
ft@0
   175
    
ft@0
   176
    if (arguments.getdevices):
ft@1
   177
        getDevices (config.get ("Main", "GetDevicesScript"))
ft@0
   178
        
ft@0
   179
    if (arguments.umount):
ft@1
   180
        umountDevice (config.get ("Main", "UmountScript"), arguments.umount[0])
ft@0
   181
    
ft@0
   182
    if (arguments.mount):
ft@1
   183
        mountDevice (config.get ("Main", "MountScript"), arguments.mount[0], int(arguments.mount[1]), arguments.mount[2], arguments.mount[3], config.get ("Main", "Keyfile"))
ft@0
   184
    
ft@0
   185
    if (arguments.initialize):
ft@17
   186
        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"))