OpenSecurity/bin/opensecurity_client_restful_server.py
author Oliver Maurhart <oliver.maurhart@ait.ac.at>
Thu, 24 Apr 2014 12:19:30 +0200
changeset 130 f770f1b2abf7
parent 112 9cd4654c040b
child 134 f1c1c06c947d
permissions -rwxr-xr-x
more info on http://localhost:8080 for V0.2.5
     1 #!/bin/env python
     2 # -*- coding: utf-8 -*-
     3 
     4 # ------------------------------------------------------------
     5 # opensecurity_client_restful_server
     6 # 
     7 # the OpenSecurity client RESTful server
     8 #
     9 # Autor: Oliver Maurhart, <oliver.maurhart@ait.ac.at>
    10 #
    11 # Copyright (C) 2013 AIT Austrian Institute of Technology
    12 # AIT Austrian Institute of Technology GmbH
    13 # Donau-City-Strasse 1 | 1220 Vienna | Austria
    14 # http://www.ait.ac.at
    15 #
    16 # This program is free software; you can redistribute it and/or
    17 # modify it under the terms of the GNU General Public License
    18 # as published by the Free Software Foundation version 2.
    19 # 
    20 # This program is distributed in the hope that it will be useful,
    21 # but WITHOUT ANY WARRANTY; without even the implied warranty of
    22 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    23 # GNU General Public License for more details.
    24 # 
    25 # You should have received a copy of the GNU General Public License
    26 # along with this program; if not, write to the Free Software
    27 # Foundation, Inc., 51 Franklin Street, Fifth Floor, 
    28 # Boston, MA  02110-1301, USA.
    29 # ------------------------------------------------------------
    30 
    31 
    32 # ------------------------------------------------------------
    33 # imports
    34 
    35 import os
    36 import os.path
    37 import subprocess
    38 import sys
    39 import urllib
    40 import urllib2
    41 import web
    42 import threading
    43 import time
    44 
    45 # local
    46 from environment import Environment
    47 from notification import Notification
    48 
    49 
    50 # ------------------------------------------------------------
    51 # const
    52 
    53 
    54 __version__ = "0.2.5"
    55 
    56 
    57 """All the URLs we know mapping to class handler"""
    58 opensecurity_urls = (
    59     #'/application',             'os_application',
    60     '/credentials',             'os_credentials',
    61     '/notification',            'os_notification',
    62     '/password',                'os_password',
    63     '/',                        'os_root'
    64 )
    65 
    66 
    67 # ------------------------------------------------------------
    68 # code
    69 
    70 
    71 # class os_application:
    72 #
    73 # PRESUMLY DEAD CODE
    74 #
    75     # """OpenSecurity '/application' handler.
    76     
    77     # This is called on GET /application?vm=VM-ID&app=APP-ID
    78     # This tries to access the vm identified with the label VM-ID
    79     # and launched the application identified APP-ID
    80     # """
    81     
    82     # def GET(self):
    83         
    84         # # pick the arguments
    85         # args = web.input()
    86         
    87         # # we _need_ a vm
    88         # if not "vm" in args:
    89             # raise web.badrequest('no vm given')
    90         
    91         # # we _need_ a app
    92         # if not "command" in args:
    93             # raise web.badrequest('no app given')
    94         
    95         # # check if we do have valid vm
    96         # v = [v for v in vms if v['name'] == args.vm]
    97         # if len(v) == 0:
    98             # raise web.notfound('vm not found')
    99         # v = v[0]
   100         
   101         # # check if we do have a valid app
   102         # a = [a for a in apps if a['name'] == args.app]
   103         # if len(a) == 0:
   104             # raise web.notfound('app not found')
   105         # a = a[0]
   106         
   107         # # invoke launch with 
   108         # res = "starting: launch " + v['user'] + " " + v['ip'] + " " + a['command']
   109 
   110         # launch_image = os.path.join(sys.path[0], 'launch.py')
   111         # process_command = [sys.executable, launch_image, v['user'], v['ip'], a['command']]
   112         # process = subprocess.Popen(process_command, shell = False, stdout = subprocess.PIPE)
   113         # result = process.communicate()[0]
   114         # if process.returncode != 0:
   115             # return 'Launch of application aborted.'
   116         
   117         # return result
   118         
   119 
   120 class os_credentials:
   121     """OpenSecurity '/credentials' handler.
   122     
   123     This is called on GET /credentials?text=TEXT.
   124     Ideally this should pop up a user dialog to insert his
   125     credentials based the given TEXT.
   126     """
   127     
   128     def GET(self):
   129         
   130         # pick the arguments
   131         args = web.input()
   132         
   133         # we _need_ a text
   134         if not "text" in args:
   135             raise web.badrequest('no text given')
   136         
   137         # invoke the user dialog as a subprocess
   138         dlg_image = os.path.join(sys.path[0], 'opensecurity_dialog.py')
   139         process_command = [sys.executable, dlg_image, 'credentials', args.text]
   140         process = subprocess.Popen(process_command, shell = False, stdout = subprocess.PIPE)
   141         result = process.communicate()[0]
   142         if process.returncode != 0:
   143             return 'Credentials request has been aborted.'
   144         
   145         return result
   146 
   147 
   148 class os_notification:
   149     """OpenSecurity '/notification' handler.
   150     
   151     This is called on GET /notification?msgtype=TYPE&text=TEXT.
   152     This will pop up an OpenSecurity notifcation window
   153     """
   154     
   155     def GET(self):
   156         
   157         # pick the arguments
   158         args = web.input()
   159         
   160         if "message" in args:
   161             print args.message
   162         
   163         # we _need_ a type
   164         if not "msgtype" in args:
   165             raise web.badrequest('no msgtype given')
   166             
   167         if not args.msgtype in Notification.TYPES:
   168             raise web.badrequest('Unknown value for msgtype')
   169             
   170         # we _need_ a text
   171         if not "text" in args:
   172             raise web.badrequest('no text given')
   173             
   174         # invoke the user dialog as a subprocess
   175         dlg_image = os.path.join(sys.path[0], 'opensecurity_dialog.py')
   176         process_command = [sys.executable, dlg_image, 'notification-' + args.msgtype, args.text]
   177         process = subprocess.Popen(process_command, shell = False, stdout = subprocess.PIPE)
   178         return "Ok"
   179 
   180 class PasswordSender(threading.Thread):
   181     remote_ip = None
   182     args = None
   183     def __init__(self, remote_ip, args): 
   184         threading.Thread.__init__(self)
   185         self.args = args
   186         self.remote_ip = remote_ip
   187  
   188     def stop(self):
   189         self.running = False
   190         
   191     def run(self):
   192         # invoke the user dialog as a subprocess
   193         dlg_image = os.path.join(sys.path[0], 'opensecurity_dialog.py')
   194         process_command = [sys.executable, dlg_image, 'password', self.args.text]
   195         process = subprocess.Popen(process_command, shell = False, stdout = subprocess.PIPE)
   196         result = process.communicate()[0]
   197         if process.returncode != 0:
   198             print 'password request has been aborted.'
   199             return
   200         
   201         # all ok, tell send request back appropriate destination
   202         try:
   203             password = result.split(':')[1].split("'")[1]
   204         except:
   205             print 'error in password parsing'
   206             return
   207         
   208         url_addr = 'http://' + self.remote_ip + ':58080/password'
   209         url_data = urllib.urlencode({ 'password': password})
   210         url = url_addr + '?' + url_data
   211         req = urllib2.Request(url)
   212         try:
   213             res = urllib2.urlopen(req)
   214         except:
   215             print 'failed to contact: ' + url_addr
   216             return 
   217 
   218 class os_password:
   219     """OpenSecurity '/password' handler.
   220     
   221     This is called on GET /password?text=TEXT.
   222     Ideally this should pop up a user dialog to insert his
   223     password based device name.
   224     """
   225     
   226     def GET(self):
   227         
   228         # pick the arguments
   229         args = web.input()
   230         
   231         # we _need_ a text
   232         if not "text" in args:
   233             raise web.badrequest('no text given')
   234             
   235         # remember remote ip
   236         remote_ip = web.ctx.environ['REMOTE_ADDR']
   237         
   238         sender = PasswordSender(remote_ip, args)
   239         sender.start()
   240         
   241         return 'password told'
   242 
   243 
   244 class os_root:
   245     """OpenSecurity '/' handler"""
   246     
   247     def GET(self):
   248     
   249         res = "OpenSecurity-Client RESTFul Server { \"version\": \"%s\" }" % __version__
   250         
   251         # add some sample links
   252         res = res + """
   253         
   254 USAGE EXAMPLES:
   255         
   256 Request a password: 
   257     (copy paste this into your browser's address field after the host:port)
   258     
   259     /password?text=Give+me+a+password+for+device+%22My+USB+Drive%22+(ID%3A+32090-AAA-X0)
   260     
   261     (eg.: http://127.0.0.1:8090/password?text=Give+me+a+password+for+device+%22My+USB+Drive%22+(ID%3A+32090-AAA-X0))
   262     NOTE: check yout taskbar, the dialog window may not pop up in front of your browser window.
   263     
   264     
   265 Request a combination of user and password:
   266     (copy paste this into your browser's address field after the host:port)
   267     
   268     /credentials?text=Tell+the+NSA+which+credentials+to+use+in+order+to+avoid+hacking+noise+on+wire.
   269     
   270     (eg.: http://127.0.0.1:8090/credentials?text=Tell+the+NSA+which+credentials+to+use+in+order+to+avoid+hacking+noise+on+wire.)
   271     NOTE: check yout taskbar, the dialog window may not pop up in front of your browser window.
   272     
   273 
   274 Start a Browser:
   275     (copy paste this into your browser's address field after the host:port)
   276 
   277     /application?vm=Debian+7&app=Browser
   278 
   279     (e.g. http://127.0.0.1:8090/application?vm=Debian+7&app=Browser)
   280         """
   281     
   282         return res
   283 
   284 
   285 # start
   286 if __name__ == "__main__":
   287     server = web.application(opensecurity_urls, globals())
   288     server.run()