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