encryptionprovider.py
author ft
Wed, 03 Dec 2014 11:35:21 +0100
changeset 4 9c3105aa50e0
permissions -rwxr-xr-x
chnaged init sucess message so the user has to click away the message
ft@0
     1
#!/usr/bin/python
ft@0
     2
ft@0
     3
# ------------------------------------------------------------
ft@0
     4
# opensecurity package file
ft@0
     5
#
ft@0
     6
# Autor: X-Net Services GmbH <office@x-net.at>
ft@0
     7
#
ft@0
     8
# Copyright 2013-2014 X-Net and AIT Austrian Institute of Technology
ft@0
     9
#
ft@0
    10
#
ft@0
    11
#     X-Net Technologies GmbH
ft@0
    12
#     Elisabethstrasse 1
ft@0
    13
#     4020 Linz
ft@0
    14
#     AUSTRIA
ft@0
    15
#     https://www.x-net.at
ft@0
    16
#
ft@0
    17
#     AIT Austrian Institute of Technology
ft@0
    18
#     Donau City Strasse 1
ft@0
    19
#     1220 Wien
ft@0
    20
#     AUSTRIA
ft@0
    21
#     http://www.ait.ac.at
ft@0
    22
#
ft@0
    23
#
ft@0
    24
# Licensed under the Apache License, Version 2.0 (the "License");
ft@0
    25
# you may not use this file except in compliance with the License.
ft@0
    26
# You may obtain a copy of the License at
ft@0
    27
#
ft@0
    28
#    http://www.apache.org/licenses/LICENSE-2.0
ft@0
    29
#
ft@0
    30
# Unless required by applicable law or agreed to in writing, software
ft@0
    31
# distributed under the License is distributed on an "AS IS" BASIS,
ft@0
    32
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
ft@0
    33
# See the License for the specific language governing permissions and
ft@0
    34
# limitations under the License.
ft@0
    35
# ------------------------------------------------------------
ft@0
    36
ft@0
    37
import subprocess
ft@0
    38
import web
ft@0
    39
import netifaces
ft@0
    40
import argparse
ft@0
    41
import thread
ft@0
    42
import time
ft@0
    43
import os
ft@0
    44
import sys
ft@0
    45
import ConfigParser
ft@0
    46
import logging
ft@0
    47
from passwordreceiver import *
ft@0
    48
ft@0
    49
MINOPTS = { "Main" : ["LogFile", "LogLevel", "MountScript", "UmountScript", "InitScript", "GetDevicesScript", "Keyfile"]}
ft@0
    50
ft@0
    51
CONFIG_FILE="/etc/encryptionprovider/encryptionprovider.cfg"
ft@0
    52
CONFIG_NOT_READABLE = "Configfile is not readable"
ft@0
    53
CONFIG_WRONG = "Something is wrong with the config"
ft@0
    54
CONFIG_MISSING = "Section: \"%s\" Option: \"%s\" in configfile is missing"
ft@0
    55
ft@0
    56
def checkMinimumOptions (config):
ft@0
    57
    for section, options in MINOPTS.iteritems ():
ft@0
    58
        for option in options:
ft@0
    59
            if (config.has_option(section, option) == False):
ft@0
    60
                print (CONFIG_MISSING % (section, option))
ft@0
    61
                exit (129)
ft@0
    62
    
ft@0
    63
    
ft@0
    64
def loadConfig ():
ft@0
    65
    configfile = CONFIG_FILE
ft@0
    66
    config = ConfigParser.SafeConfigParser ()
ft@0
    67
ft@0
    68
    if ((os.path.exists (configfile) == False) or (os.path.isfile (configfile) == False) or (os.access (configfile, os.R_OK) == False)):
ft@0
    69
        print (CONFIG_NOT_READABLE)
ft@0
    70
        exit (1)
ft@0
    71
ft@0
    72
    try:
ft@0
    73
        config.read (CONFIG_FILE)
ft@0
    74
    except Exception, e:
ft@0
    75
        print (CONFIG_WRONG)
ft@0
    76
        print ("Error: %s" % (e))
ft@0
    77
        exit (1)
ft@0
    78
ft@0
    79
    checkMinimumOptions (config)
ft@0
    80
    return config
ft@0
    81
ft@0
    82
def initLog (config):
ft@0
    83
    global LOG
ft@0
    84
    logfile = config.get("Main", "LogFile")
ft@0
    85
    
ft@0
    86
    numeric_level = getattr(logging, config.get("Main", "LogLevel").upper(), None)
ft@0
    87
    if not isinstance(numeric_level, int):
ft@0
    88
        raise ValueError('Invalid log level: %s' % loglevel)
ft@0
    89
ft@0
    90
    # ToDo move log level and maybe other things to config file
ft@0
    91
    logging.basicConfig(
ft@0
    92
                        level = numeric_level,
ft@0
    93
                        format = "%(asctime)s %(name)-12s %(funcName)-15s %(levelname)-8s %(message)s",
ft@0
    94
                        datefmt = "%Y-%m-%d %H:%M:%S",
ft@0
    95
                        filename = logfile,
ft@0
    96
                        filemode = "a+",
ft@0
    97
    )
ft@0
    98
    LOG = logging.getLogger("encryptionprovicer")
ft@0
    99
    
ft@0
   100
    
ft@0
   101
    
ft@0
   102
    
ft@0
   103
def runExternalScripts (command):
ft@0
   104
    LOG.debug ("Run external Script: %s" %(command,))
ft@0
   105
    
ft@0
   106
    if (os.path.isfile (command[0]) == False):
ft@0
   107
        LOG.error ("File does not exist: %s" %((command[0]),))
ft@0
   108
        sys.stderr.write("File does not exist: %s\n" %((command[0]),))
ft@0
   109
        exit (1)
ft@0
   110
    
ft@0
   111
    process = subprocess.Popen( command, stdout=subprocess.PIPE, stderr=subprocess.PIPE )
ft@0
   112
    retcode = process.wait()
ft@0
   113
    ( stdout, stderr ) = process.communicate()
ft@0
   114
    
ft@0
   115
    return { "retcode" : retcode, "stdout" : stdout, "stderr" : stderr }
ft@0
   116
    
ft@0
   117
    
ft@0
   118
def getDevices (script):
ft@0
   119
    command = [script];
ft@0
   120
    result = runExternalScripts (command);
ft@0
   121
    
ft@0
   122
    if (result["retcode"] != 0):
ft@0
   123
        LOG.error ("Retcode: %s" %(result["retcode"],))
ft@0
   124
        LOG.error ("stdout: %s" %(result["stdout"],))
ft@0
   125
        LOG.error ("stderr: %s" %(result["stderr"],))
ft@0
   126
        sys.stderr.write("%s" %(result["stderr"],))
ft@0
   127
        exit (1)
ft@0
   128
    
ft@0
   129
    #print ("%s" %(result["stdout"],))
ft@0
   130
    # don't use print here, because of the extra newline
ft@0
   131
    sys.stdout.write ("%s" %(result["stdout"],))
ft@0
   132
ft@0
   133
ft@0
   134
def umountDevice (script, device):
ft@0
   135
    command = [script, device];
ft@0
   136
    result = runExternalScripts (command);
ft@0
   137
    
ft@0
   138
    if (result["retcode"] != 0):
ft@0
   139
        LOG.error ("Retcode: %s" %(result["retcode"],))
ft@0
   140
        LOG.error ("stdout: %s" %(result["stdout"],))
ft@0
   141
        LOG.error ("stderr: %s" %(result["stderr"],))
ft@0
   142
        sys.stderr.write("%s" %(result["stderr"],))
ft@0
   143
        exit (1)
ft@0
   144
        
ft@0
   145
    #print ("%s" %(result["stdout"],))
ft@0
   146
    # don't use print here, because of the extra newline
ft@0
   147
    sys.stdout.write ("%s" %(result["stdout"],))
ft@0
   148
    
ft@0
   149
ft@0
   150
def mountDevice (script, interface, port, device, mountpoint, keyfilepath):    
ft@0
   151
    listener = MyRestListener (opensecurity_urls, globals(), script = script, device = device, mountpoint = mountpoint, tries = 3, keyfilepath = keyfilepath)
ft@0
   152
    thread.start_new_thread(listener.run, (interface, port,))
ft@0
   153
    
ft@0
   154
    close = False
ft@0
   155
    while (close == False):
ft@0
   156
        time.sleep(1)
ft@0
   157
        if (os.path.ismount(mountpoint) == True):
ft@0
   158
            close = True
ft@0
   159
            LOG.info ("Stick \"%s\" was mounted sucessfully to \"%s\"" %(device, mountpoint,))
ft@0
   160
            sys.exit(0)
ft@0
   161
            
ft@0
   162
        if (os.path.exists(device) == False):
ft@0
   163
            close = True
ft@0
   164
            LOG.error ("Stick \"%s\" removed -> exit" %(device,))
ft@0
   165
            sys.exit(1)
ft@0
   166
ft@0
   167
def isDeviceMountedAtMountpoint (device, mountpoint):
ft@0
   168
    command = ("/bin/df %s | /usr/bin/tail -1 | awk '{print $1}'" %(mountpoint,))
ft@0
   169
    pipe = os.popen(command)
ft@0
   170
    result = pipe.read().rstrip()
ft@0
   171
    
ft@0
   172
    if (pipe.close() != None):
ft@0
   173
        LOG.error ("error: %s" %(result,))
ft@0
   174
        exit (1)
ft@0
   175
    
ft@0
   176
    if (result == device):
ft@0
   177
        LOG.debug ("Device: %s ### Result: %s ### Return: True" %(device, result,))
ft@0
   178
        return True
ft@0
   179
    else:
ft@0
   180
        LOG.debug ("Device: %s ### Result: %s ### Return: False" %(device, result,))
ft@0
   181
        return False
ft@0
   182
    
ft@0
   183
ft@0
   184
def initDevice (script, interface, port, device, mountpoint, keyfilepath, preinitscript, postinitscript):    
ft@0
   185
    listener = MyRestListener (opensecurity_urls, globals(), script = script, device = device, mountpoint = mountpoint, tries = 3, keyfilepath = keyfilepath, preinitscript = preinitscript, postinitscript = postinitscript)
ft@0
   186
    thread.start_new_thread(listener.run, (interface, port,))
ft@0
   187
    
ft@0
   188
    close = False
ft@0
   189
    while (close == False):
ft@0
   190
        time.sleep(1)
ft@0
   191
        if (os.path.exists(device) == False):
ft@0
   192
            close = True
ft@0
   193
            LOG.info ("Stick \"%s\" removed -> exit" %(device,))
ft@0
   194
            sys.exit(1)
ft@0
   195
ft@0
   196
if __name__ == "__main__":
ft@0
   197
    
ft@0
   198
    parser = argparse.ArgumentParser(epilog='--mount, --umount and --initialize are mutually exclusive')
ft@0
   199
    group = parser.add_mutually_exclusive_group(required=True)
ft@0
   200
    group.add_argument('-m', '--mount', action='store', nargs=4, dest='mount', help='Mounts an encrypted device.', metavar=("interface", "port", "device", "mountpoint"))
ft@0
   201
    group.add_argument('-u', '--umount', action='store', nargs=1, dest='umount', help='Unmounts an encrypted device', metavar="device")
ft@0
   202
    group.add_argument('-i', '--initialize', action='store', nargs=4, dest='initialize', help='Initialize an device.', metavar=("interface", "port", "device", "mountpoint"))
ft@0
   203
    group.add_argument('-g', '--getdevices', action='store_true', dest="getdevices", help='Returns a list of all mounted encrypted devices')
ft@0
   204
    arguments = parser.parse_args()
ft@0
   205
    
ft@0
   206
    
ft@0
   207
    config = loadConfig ()
ft@0
   208
    initLog (config)
ft@0
   209
    
ft@0
   210
    if (arguments.getdevices):
ft@0
   211
        getDevices (config.get ("Main", "GetDevicesScript"))
ft@0
   212
        
ft@0
   213
    if (arguments.umount):
ft@0
   214
        umountDevice (config.get ("Main", "UmountScript"), arguments.umount[0])
ft@0
   215
    
ft@0
   216
    if (arguments.mount):
ft@0
   217
        mountDevice (config.get ("Main", "MountScript"), arguments.mount[0], int(arguments.mount[1]), arguments.mount[2], arguments.mount[3], config.get ("Main", "Keyfile"))
ft@0
   218
    
ft@0
   219
    if (arguments.initialize):
ft@0
   220
        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"))