passwordreceiver.py
author ft
Wed, 03 Dec 2014 11:35:21 +0100
changeset 4 9c3105aa50e0
parent 0 28b7682d5476
permissions -rw-r--r--
chnaged init sucess message so the user has to click away the message
     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 
    38 import subprocess
    39 import web
    40 import netifaces
    41 import os
    42 import sys
    43 import base64
    44 import thread
    45 import urllib3
    46 import netaddr
    47 
    48 opensecurity_urls = (
    49     '/password',                'os_password',
    50     '/init',                    'os_init'
    51 )
    52 
    53 STATUS_CODE_OK = 200
    54 
    55 
    56 def sendDataToRest (urlpath, data):
    57     netifaces.ifaddresses("eth0")[2][0]["addr"]
    58     
    59     # Get first address in network (0 = network ip -> 192.168.0.0)
    60     remote_ip = netaddr.IPNetwork("%s/%s" %(netifaces.ifaddresses("eth0")[2][0]["addr"], netifaces.ifaddresses("eth0")[2][0]["netmask"]))[1]
    61     
    62     url = ("http://%s:8090//%s" %(remote_ip, urlpath))
    63     
    64     try:
    65         response = httpPool.request_encode_body("POST", url, fields=data, retries=0)
    66     except Exception, e:
    67         return
    68     
    69     if response.status == STATUS_CODE_OK:
    70         return True
    71     else:
    72         return False
    73     
    74 
    75 def sendNotification (type, message):
    76     data = {"msgtype" : type, "text" : message}
    77     
    78     if (type == "information"):
    79         sendDataToRest ("message", data)
    80     else:
    81         sendDataToRest ("notification", data)
    82 
    83 def sendInitialisationFailedError():
    84     sendNotification("critical", "Initialisation of the stick failed.")
    85 
    86 
    87 
    88 
    89 
    90 
    91 
    92 class os_password:
    93     
    94     # delete the key file in a secure way (will not working on ssd's :/ ,but ram only vm -> should be ok)
    95     def deleteKeyfile(self, keyfilepath):
    96         filesize = os.path.getsize(keyfilepath)
    97         keyfile = open (keyfilepath, "w+")
    98         for i in range (0, 10):
    99             keyfile.seek(0)
   100             keyfile.write(os.urandom(filesize))
   101             keyfile.flush()
   102         keyfile.close()
   103         os.remove(keyfilepath)
   104     
   105     
   106     def GET(self, settings):
   107         return self.POST(settings)
   108     
   109     def POST(self, settings):
   110         
   111         # pick the arguments
   112         args = web.input()
   113                       
   114         if not "password" in args:
   115             raise web.badrequest()
   116 
   117         if "keyfile" in args:
   118             keyfile = open (settings["keyfilepath"], "w+")
   119             keyfile.write(base64.b64decode(args["keyfile"]))
   120             keyfile.close()
   121             command = [settings["script"], settings["device"], settings["mountpoint"], args["password"], settings["keyfilepath"]]
   122         else:
   123             command = [settings["script"], settings["device"], settings["mountpoint"], args["password"]]
   124             
   125         process = subprocess.Popen( command, stdout=subprocess.PIPE, stderr=subprocess.PIPE )
   126         retval = process.wait()
   127         ( stdout, stderr ) = process.communicate()
   128         
   129         if "keyfile" in args:
   130             self.deleteKeyfile(settings["keyfilepath"])
   131         
   132         if (retval != 0):
   133             raise web.badrequest(stderr)
   134         
   135         return "Success: Encrypted Stick is mounted"
   136 
   137 class os_init:
   138     # delete the key file in a secure way (will not working on ssd's :/ ,but ram only vm -> should be ok)
   139     def deleteKeyfile(self, keyfilepath):
   140         filesize = os.path.getsize(keyfilepath)
   141         keyfile = open (keyfilepath, "w+")
   142         for i in range (0, 10):
   143             keyfile.seek(0)
   144             keyfile.write(os.urandom(filesize))
   145             keyfile.flush()
   146         keyfile.close()
   147         os.remove(keyfilepath)
   148     
   149     def runPreInitScript(self, preinitscript, device):
   150         
   151         command = [preinitscript, device]
   152         process = subprocess.Popen( command, stdout=subprocess.PIPE, stderr=subprocess.PIPE )
   153         retval = process.wait()
   154         ( stdout, stderr ) = process.communicate()
   155         
   156         if (retval != 0):
   157             raise web.badrequest(stderr)
   158     
   159     def runPostInitScript(self, postinitscript):
   160         command = [postinitscript]
   161         process = subprocess.Popen( command, stdout=subprocess.PIPE, stderr=subprocess.PIPE )
   162         retval = process.wait()
   163         ( stdout, stderr ) = process.communicate()
   164         
   165         if (retval != 0):
   166             return False
   167         else:
   168             return True
   169     
   170     def GET(self, settings):
   171         return self.POST(settings)
   172     
   173     def POST(self, settings):
   174         
   175         # pick the arguments
   176         args = web.input()
   177                       
   178         if not "password" in args:
   179             raise web.badrequest()
   180         
   181         # Do the preinit stuff
   182         self.runPreInitScript(settings["preinitscript"], settings["device"])
   183 
   184         if "keyfile" in args:
   185             keyfile = open (settings["keyfilepath"], "w+")
   186             keyfile.write(base64.b64decode(args["keyfile"]))
   187             keyfile.close()
   188             command = [settings["script"], settings["device"], settings["mountpoint"], args["password"], settings["keyfilepath"]]
   189         else:
   190             command = [settings["script"], settings["device"], settings["mountpoint"], args["password"]]
   191         
   192         thread.start_new_thread(self.initStick, (command,settings,args,))
   193         
   194         return "Success: Init started"
   195 
   196     def initStick(self, command, settings, args):
   197         process = subprocess.Popen( command, stdout=subprocess.PIPE, stderr=subprocess.PIPE )
   198         retval = process.wait()
   199         ( stdout, stderr ) = process.communicate()
   200         
   201         if "keyfile" in args:
   202             self.deleteKeyfile(settings["keyfilepath"])
   203         
   204         if (retval != 0):
   205             sendInitialisationFailedError();
   206         
   207         # Do the postinit stuff
   208         if (self.runPostInitScript(settings["postinitscript"]) != True):
   209             sendInitialisationFailedError();
   210 
   211 class MyRestListener(web.application):
   212     def __init__(self, mapping=(), fvars={}, autoreload=None, script=None, device=None, mountpoint=None, tries=None, keyfilepath=None, preinitscript=None, postinitscript=None):
   213         web.application.__init__(self, mapping, fvars, autoreload)
   214         self.device = device
   215         self.mountpoint = mountpoint
   216         self.script = script
   217         self.tries = tries
   218         self.keyfilepath = keyfilepath
   219         self.preinitscript = preinitscript
   220         self.postinitscript = postinitscript
   221         
   222     def run(self, interface, port, *middleware):
   223         func = self.wsgifunc(*middleware)
   224         ifaceip = netifaces.ifaddresses(interface)[2][0]["addr"]
   225         return web.httpserver.runsimple(func, (ifaceip, port))
   226     
   227     def handle(self):
   228         fn, args = self._match(self.mapping, web.ctx.path)
   229         args.append({"script": self.script, "device": self.device, "mountpoint": self.mountpoint, "tries": self.tries, "keyfilepath": self.keyfilepath, "preinitscript": self.preinitscript, "postinitscript": self.postinitscript})
   230         return self._delegate(fn, self.fvars, args)