ft@0: #!/usr/bin/python ft@0: ft@0: # ------------------------------------------------------------ ft@0: # opensecurity package file ft@0: # ft@0: # Autor: X-Net Services GmbH ft@0: # ft@0: # Copyright 2013-2014 X-Net and AIT Austrian Institute of Technology ft@0: # ft@0: # ft@0: # X-Net Technologies GmbH ft@0: # Elisabethstrasse 1 ft@0: # 4020 Linz ft@0: # AUSTRIA ft@0: # https://www.x-net.at ft@0: # ft@0: # AIT Austrian Institute of Technology ft@0: # Donau City Strasse 1 ft@0: # 1220 Wien ft@0: # AUSTRIA ft@0: # http://www.ait.ac.at ft@0: # ft@0: # ft@0: # Licensed under the Apache License, Version 2.0 (the "License"); ft@0: # you may not use this file except in compliance with the License. ft@0: # You may obtain a copy of the License at ft@0: # ft@0: # http://www.apache.org/licenses/LICENSE-2.0 ft@0: # ft@0: # Unless required by applicable law or agreed to in writing, software ft@0: # distributed under the License is distributed on an "AS IS" BASIS, ft@0: # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ft@0: # See the License for the specific language governing permissions and ft@0: # limitations under the License. ft@0: # ------------------------------------------------------------ ft@0: ft@0: ft@0: import subprocess ft@0: import web ft@0: import netifaces ft@0: import os ft@0: import sys ft@0: import base64 ft@0: #import logging ft@0: ft@0: opensecurity_urls = ( ft@0: '/password', 'os_password', ft@0: '/init', 'os_init' ft@0: ) ft@0: ft@0: #__LOG = logging.getLogger("passwordreceiver") ft@0: ft@0: class os_password: ft@0: ft@0: # delete the key file in a secure way (will not working on ssd's :/ ,but ram only vm -> should be ok) ft@0: def deleteKeyfile(self, keyfilepath): ft@0: filesize = os.path.getsize(keyfilepath) ft@0: keyfile = open (keyfilepath, "w+") ft@0: for i in range (0, 10): ft@0: keyfile.seek(0) ft@0: keyfile.write(os.urandom(filesize)) ft@0: keyfile.flush() ft@0: keyfile.close() ft@0: os.remove(keyfilepath) ft@0: ft@0: ft@0: def GET(self, settings): ft@0: return self.POST(settings) ft@0: ft@0: def POST(self, settings): ft@0: ft@0: # pick the arguments ft@0: args = web.input() ft@0: ft@0: if not "password" in args: ft@0: raise web.badrequest() ft@0: ft@0: if "keyfile" in args: ft@0: keyfile = open (settings["keyfilepath"], "w+") ft@0: keyfile.write(base64.b64decode(args["keyfile"])) ft@0: keyfile.close() ft@0: command = [settings["script"], settings["device"], settings["mountpoint"], args["password"], settings["keyfilepath"]] ft@0: else: ft@0: command = [settings["script"], settings["device"], settings["mountpoint"], args["password"]] ft@0: ft@0: process = subprocess.Popen( command, stdout=subprocess.PIPE, stderr=subprocess.PIPE ) ft@0: retval = process.wait() ft@0: ( stdout, stderr ) = process.communicate() ft@0: ft@0: if "keyfile" in args: ft@0: self.deleteKeyfile(settings["keyfilepath"]) ft@0: ft@0: if (retval != 0): ft@0: raise web.badrequest(stderr) ft@0: ft@0: return "Success: Encrypted Stick is mounted" ft@0: ft@0: class os_init: ft@0: # delete the key file in a secure way (will not working on ssd's :/ ,but ram only vm -> should be ok) ft@0: def deleteKeyfile(self, keyfilepath): ft@0: filesize = os.path.getsize(keyfilepath) ft@0: keyfile = open (keyfilepath, "w+") ft@0: for i in range (0, 10): ft@0: keyfile.seek(0) ft@0: keyfile.write(os.urandom(filesize)) ft@0: keyfile.flush() ft@0: keyfile.close() ft@0: os.remove(keyfilepath) ft@0: ft@0: def runPreInitScript(self, preinitscript, device): ft@0: #__LOG.debug("Start preinit Script") ft@0: ft@0: command = [preinitscript, device] ft@0: process = subprocess.Popen( command, stdout=subprocess.PIPE, stderr=subprocess.PIPE ) ft@0: retval = process.wait() ft@0: ( stdout, stderr ) = process.communicate() ft@0: ft@0: #__LOG.debug("preinit done result: %s" %(retval,)) ft@0: ft@0: if (retval != 0): ft@0: raise web.badrequest(stderr) ft@0: ft@0: def runPostInitScript(self, postinitscript): ft@0: #__LOG.debug("Start postinit Script") ft@0: ft@0: command = [postinitscript] ft@0: process = subprocess.Popen( command, stdout=subprocess.PIPE, stderr=subprocess.PIPE ) ft@0: retval = process.wait() ft@0: ( stdout, stderr ) = process.communicate() ft@0: ft@0: #__LOG.debug("postinit done result: %s" %(retval,)) ft@0: ft@0: if (retval != 0): ft@0: raise web.badrequest(stderr) ft@0: ft@0: def GET(self, settings): ft@0: return self.POST(settings) ft@0: ft@0: def POST(self, settings): ft@0: ft@0: # pick the arguments ft@0: args = web.input() ft@0: ft@0: if not "password" in args: ft@0: raise web.badrequest() ft@0: ft@0: # Do the preinit stuff ft@0: self.runPreInitScript(settings["preinitscript"], settings["device"]) ft@0: ft@0: if "keyfile" in args: ft@0: keyfile = open (settings["keyfilepath"], "w+") ft@0: keyfile.write(base64.b64decode(args["keyfile"])) ft@0: keyfile.close() ft@0: command = [settings["script"], settings["device"], settings["mountpoint"], args["password"], settings["keyfilepath"]] ft@0: else: ft@0: command = [settings["script"], settings["device"], settings["mountpoint"], args["password"]] ft@0: ft@0: #__LOG.debug("Start init script") ft@0: ft@0: process = subprocess.Popen( command, stdout=subprocess.PIPE, stderr=subprocess.PIPE ) ft@0: retval = process.wait() ft@0: ( stdout, stderr ) = process.communicate() ft@0: ft@0: if "keyfile" in args: ft@0: self.deleteKeyfile(settings["keyfilepath"]) ft@0: ft@0: #__LOG.debug("init done result: %s" %(retval,)) ft@0: ft@0: if (retval != 0): ft@0: raise web.badrequest(stderr) ft@0: ft@0: # Do the postinit stuff ft@0: self.runPostInitScript(settings["postinitscript"]) ft@0: ft@0: return "Success: Stick is initialized and mounted" ft@0: ft@0: class MyRestListener(web.application): ft@0: def __init__(self, mapping=(), fvars={}, autoreload=None, script=None, device=None, mountpoint=None, tries=None, keyfilepath=None, preinitscript=None, postinitscript=None): ft@0: web.application.__init__(self, mapping, fvars, autoreload) ft@0: self.device = device ft@0: self.mountpoint = mountpoint ft@0: self.script = script ft@0: self.tries = tries ft@0: self.keyfilepath = keyfilepath ft@0: self.preinitscript = preinitscript ft@0: self.postinitscript = postinitscript ft@0: ft@0: def run(self, interface, port, *middleware): ft@0: func = self.wsgifunc(*middleware) ft@0: ifaceip = netifaces.ifaddresses(interface)[2][0]["addr"] ft@0: return web.httpserver.runsimple(func, (ifaceip, port)) ft@0: ft@0: def handle(self): ft@0: fn, args = self._match(self.mapping, web.ctx.path) ft@0: args.append({"script": self.script, "device": self.device, "mountpoint": self.mountpoint, "tries": self.tries, "keyfilepath": self.keyfilepath, "preinitscript": self.preinitscript, "postinitscript": self.postinitscript}) ft@0: return self._delegate(fn, self.fvars, args)