src/passwordreceiver.py
author ft
Tue, 04 Nov 2014 14:23:14 +0100
changeset 27 a8c8d86b8501
parent 24 597ff293cbdf
child 28 07be57baf1f9
permissions -rw-r--r--
Added licence things
ft@1
     1
#!/usr/bin/python
ft@1
     2
ft@27
     3
# ------------------------------------------------------------
ft@27
     4
# opensecurity package file
ft@27
     5
#
ft@27
     6
# Autor: X-Net Services GmbH <office@x-net.at>
ft@27
     7
#
ft@27
     8
# Copyright 2013-2014 X-Net and AIT Austrian Institute of Technology
ft@27
     9
#
ft@27
    10
#
ft@27
    11
#     X-Net Technologies GmbH
ft@27
    12
#     Elisabethstrasse 1
ft@27
    13
#     4020 Linz
ft@27
    14
#     AUSTRIA
ft@27
    15
#     https://www.x-net.at
ft@27
    16
#
ft@27
    17
#     AIT Austrian Institute of Technology
ft@27
    18
#     Donau City Strasse 1
ft@27
    19
#     1220 Wien
ft@27
    20
#     AUSTRIA
ft@27
    21
#     http://www.ait.ac.at
ft@27
    22
#
ft@27
    23
#
ft@27
    24
# Licensed under the Apache License, Version 2.0 (the "License");
ft@27
    25
# you may not use this file except in compliance with the License.
ft@27
    26
# You may obtain a copy of the License at
ft@27
    27
#
ft@27
    28
#    http://www.apache.org/licenses/LICENSE-2.0
ft@27
    29
#
ft@27
    30
# Unless required by applicable law or agreed to in writing, software
ft@27
    31
# distributed under the License is distributed on an "AS IS" BASIS,
ft@27
    32
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
ft@27
    33
# See the License for the specific language governing permissions and
ft@27
    34
# limitations under the License.
ft@27
    35
# ------------------------------------------------------------
ft@27
    36
ft@27
    37
ft@1
    38
import subprocess
ft@1
    39
import web
ft@1
    40
import netifaces
ft@1
    41
import os
ft@1
    42
import sys
ft@24
    43
import base64
ft@20
    44
#import logging
ft@1
    45
ft@1
    46
opensecurity_urls = (
ft@7
    47
    '/password',                'os_password',
ft@7
    48
    '/init',                    'os_init'
ft@1
    49
)
ft@1
    50
ft@20
    51
#__LOG = logging.getLogger("passwordreceiver")
ft@17
    52
ft@1
    53
class os_password:
ft@1
    54
    
ft@1
    55
    # delete the key file in a secure way (will not working on ssd's :/ ,but ram only vm -> should be ok)
ft@1
    56
    def deleteKeyfile(self, keyfilepath):
ft@1
    57
        filesize = os.path.getsize(keyfilepath)
ft@7
    58
        keyfile = open (keyfilepath, "w+")
ft@1
    59
        for i in range (0, 10):
ft@1
    60
            keyfile.seek(0)
ft@1
    61
            keyfile.write(os.urandom(filesize))
ft@1
    62
            keyfile.flush()
ft@1
    63
        keyfile.close()
ft@1
    64
        os.remove(keyfilepath)
ft@1
    65
    
ft@1
    66
    
ft@1
    67
    def GET(self, settings):
ft@6
    68
        return self.POST(settings)
ft@1
    69
    
ft@1
    70
    def POST(self, settings):
ft@1
    71
        
ft@1
    72
        # pick the arguments
ft@1
    73
        args = web.input()
ft@1
    74
                      
ft@1
    75
        if not "password" in args:
ft@1
    76
            raise web.badrequest()
ft@1
    77
ft@1
    78
        if "keyfile" in args:
ft@7
    79
            keyfile = open (settings["keyfilepath"], "w+")
ft@24
    80
            keyfile.write(base64.b64decode(args["keyfile"]))
ft@1
    81
            keyfile.close()
ft@1
    82
            command = [settings["script"], settings["device"], settings["mountpoint"], args["password"], settings["keyfilepath"]]
ft@1
    83
        else:
ft@1
    84
            command = [settings["script"], settings["device"], settings["mountpoint"], args["password"]]
ft@1
    85
            
ft@1
    86
        process = subprocess.Popen( command, stdout=subprocess.PIPE, stderr=subprocess.PIPE )
ft@1
    87
        retval = process.wait()
ft@1
    88
        ( stdout, stderr ) = process.communicate()
ft@1
    89
        
ft@1
    90
        if "keyfile" in args:
ft@1
    91
            self.deleteKeyfile(settings["keyfilepath"])
ft@1
    92
        
ft@1
    93
        if (retval != 0):
ft@1
    94
            raise web.badrequest(stderr)
ft@1
    95
        
ft@1
    96
        return "Success: Encrypted Stick is mounted"
ft@1
    97
ft@7
    98
class os_init:
ft@7
    99
    # delete the key file in a secure way (will not working on ssd's :/ ,but ram only vm -> should be ok)
ft@7
   100
    def deleteKeyfile(self, keyfilepath):
ft@7
   101
        filesize = os.path.getsize(keyfilepath)
ft@7
   102
        keyfile = open (keyfilepath, "w+")
ft@7
   103
        for i in range (0, 10):
ft@7
   104
            keyfile.seek(0)
ft@7
   105
            keyfile.write(os.urandom(filesize))
ft@7
   106
            keyfile.flush()
ft@7
   107
        keyfile.close()
ft@7
   108
        os.remove(keyfilepath)
ft@7
   109
    
ft@19
   110
    def runPreInitScript(self, preinitscript, device):
ft@20
   111
        #__LOG.debug("Start preinit Script")
ft@17
   112
        
ft@17
   113
        command = [preinitscript, device]
ft@17
   114
        process = subprocess.Popen( command, stdout=subprocess.PIPE, stderr=subprocess.PIPE )
ft@17
   115
        retval = process.wait()
ft@17
   116
        ( stdout, stderr ) = process.communicate()
ft@17
   117
        
ft@23
   118
        #__LOG.debug("preinit done result: %s" %(retval,))
ft@17
   119
        
ft@17
   120
        if (retval != 0):
ft@17
   121
            raise web.badrequest(stderr)
ft@17
   122
    
ft@17
   123
    def runPostInitScript(self, postinitscript):
ft@20
   124
        #__LOG.debug("Start postinit Script")
ft@17
   125
        
ft@20
   126
        command = [postinitscript]
ft@17
   127
        process = subprocess.Popen( command, stdout=subprocess.PIPE, stderr=subprocess.PIPE )
ft@17
   128
        retval = process.wait()
ft@17
   129
        ( stdout, stderr ) = process.communicate()
ft@17
   130
        
ft@23
   131
        #__LOG.debug("postinit done result: %s" %(retval,))
ft@17
   132
        
ft@17
   133
        if (retval != 0):
ft@17
   134
            raise web.badrequest(stderr)
ft@7
   135
    
ft@7
   136
    def GET(self, settings):
ft@7
   137
        return self.POST(settings)
ft@7
   138
    
ft@7
   139
    def POST(self, settings):
ft@7
   140
        
ft@7
   141
        # pick the arguments
ft@7
   142
        args = web.input()
ft@7
   143
                      
ft@7
   144
        if not "password" in args:
ft@7
   145
            raise web.badrequest()
ft@17
   146
        
ft@17
   147
        # Do the preinit stuff
ft@19
   148
        self.runPreInitScript(settings["preinitscript"], settings["device"])
ft@7
   149
ft@7
   150
        if "keyfile" in args:
ft@7
   151
            keyfile = open (settings["keyfilepath"], "w+")
ft@24
   152
            keyfile.write(base64.b64decode(args["keyfile"]))
ft@7
   153
            keyfile.close()
ft@7
   154
            command = [settings["script"], settings["device"], settings["mountpoint"], args["password"], settings["keyfilepath"]]
ft@7
   155
        else:
ft@7
   156
            command = [settings["script"], settings["device"], settings["mountpoint"], args["password"]]
ft@7
   157
            
ft@20
   158
        #__LOG.debug("Start init script")
ft@17
   159
        
ft@7
   160
        process = subprocess.Popen( command, stdout=subprocess.PIPE, stderr=subprocess.PIPE )
ft@7
   161
        retval = process.wait()
ft@7
   162
        ( stdout, stderr ) = process.communicate()
ft@7
   163
        
ft@7
   164
        if "keyfile" in args:
ft@7
   165
            self.deleteKeyfile(settings["keyfilepath"])
ft@7
   166
        
ft@23
   167
        #__LOG.debug("init done result: %s" %(retval,))
ft@17
   168
        
ft@7
   169
        if (retval != 0):
ft@7
   170
            raise web.badrequest(stderr)
ft@7
   171
        
ft@17
   172
        # Do the postinit stuff
ft@22
   173
        self.runPostInitScript(settings["postinitscript"])
ft@17
   174
        
ft@7
   175
        return "Success: Stick is initialized and mounted"
ft@7
   176
ft@1
   177
class MyRestListener(web.application):
ft@17
   178
    def __init__(self, mapping=(), fvars={}, autoreload=None, script=None, device=None, mountpoint=None, tries=None, keyfilepath=None, preinitscript=None, postinitscript=None):
ft@1
   179
        web.application.__init__(self, mapping, fvars, autoreload)
ft@1
   180
        self.device = device
ft@1
   181
        self.mountpoint = mountpoint
ft@1
   182
        self.script = script
ft@1
   183
        self.tries = tries
ft@1
   184
        self.keyfilepath = keyfilepath
ft@17
   185
        self.preinitscript = preinitscript
ft@17
   186
        self.postinitscript = postinitscript
ft@1
   187
        
ft@1
   188
    def run(self, interface, port, *middleware):
ft@1
   189
        func = self.wsgifunc(*middleware)
ft@1
   190
        ifaceip = netifaces.ifaddresses(interface)[2][0]["addr"]
ft@1
   191
        return web.httpserver.runsimple(func, (ifaceip, port))
ft@1
   192
    
ft@1
   193
    def handle(self):
ft@1
   194
        fn, args = self._match(self.mapping, web.ctx.path)
ft@17
   195
        args.append({"script": self.script, "device": self.device, "mountpoint": self.mountpoint, "tries": self.tries, "keyfilepath": self.keyfilepath, "preinitscript": self.preinitscript, "postinitscript": self.postinitscript})
ft@1
   196
        return self._delegate(fn, self.fvars, args)