OpenSecurity/bin/opensecurity_client_restful_server.py
changeset 29 3f564e1673bb
parent 16 e16d64b5e008
child 31 d95fe93d7a83
     1.1 --- a/OpenSecurity/bin/opensecurity_client_restful_server.py	Fri Dec 06 12:24:24 2013 +0100
     1.2 +++ b/OpenSecurity/bin/opensecurity_client_restful_server.py	Mon Dec 09 14:44:41 2013 +0100
     1.3 @@ -36,10 +36,13 @@
     1.4  import os.path
     1.5  import subprocess
     1.6  import sys
     1.7 +import urllib
     1.8 +import urllib2
     1.9  import web
    1.10  
    1.11  # local
    1.12  from environment import Environment
    1.13 +from notification import Notification
    1.14  import opensecurity_server
    1.15  
    1.16  
    1.17 @@ -54,6 +57,7 @@
    1.18  opensecurity_urls = (
    1.19      '/application',             'os_application',
    1.20      '/credentials',             'os_credentials',
    1.21 +    '/notification',            'os_notification',
    1.22      '/password',                'os_password',
    1.23      '/',                        'os_root'
    1.24  )
    1.25 @@ -78,11 +82,11 @@
    1.26          
    1.27          # we _need_ a vm
    1.28          if not "vm" in args:
    1.29 -            raise web.badrequest()
    1.30 +            raise web.badrequest('no vm given')
    1.31          
    1.32          # we _need_ a app
    1.33          if not "app" in args:
    1.34 -            raise web.badrequest()
    1.35 +            raise web.badrequest('no app given')
    1.36          
    1.37          apps = opensecurity_server.query_apps()
    1.38          vms = opensecurity_server.query_vms()
    1.39 @@ -125,13 +129,13 @@
    1.40          # pick the arguments
    1.41          args = web.input()
    1.42          
    1.43 -        # we _need_ a device id
    1.44 +        # we _need_ a text
    1.45          if not "text" in args:
    1.46 -            raise web.badrequest()
    1.47 +            raise web.badrequest('no text given')
    1.48          
    1.49          # invoke the user dialog as a subprocess
    1.50 -        dlg_credentials_image = os.path.join(sys.path[0], 'opensecurity_dialog.py')
    1.51 -        process_command = [sys.executable, dlg_credentials_image, 'credentials', args.text]
    1.52 +        dlg_image = os.path.join(sys.path[0], 'opensecurity_dialog.py')
    1.53 +        process_command = [sys.executable, dlg_image, 'credentials', args.text]
    1.54          process = subprocess.Popen(process_command, shell = False, stdout = subprocess.PIPE)
    1.55          result = process.communicate()[0]
    1.56          if process.returncode != 0:
    1.57 @@ -140,6 +144,36 @@
    1.58          return result
    1.59  
    1.60  
    1.61 +class os_notification:
    1.62 +    """OpenSecurity '/notification' handler.
    1.63 +    
    1.64 +    This is called on GET /notification?msgtype=TYPE&text=TEXT.
    1.65 +    This will pop up an OpenSecurity notifcation window
    1.66 +    """
    1.67 +    
    1.68 +    def GET(self):
    1.69 +        
    1.70 +        # pick the arguments
    1.71 +        args = web.input()
    1.72 +        
    1.73 +        # we _need_ a type
    1.74 +        if not "msgtype" in args:
    1.75 +            raise web.badrequest('no msgtype given')
    1.76 +            
    1.77 +        if not args.msgtype in Notification.TYPES:
    1.78 +            raise web.badrequest('Unknown value for msgtype')
    1.79 +            
    1.80 +        # we _need_ a text
    1.81 +        if not "text" in args:
    1.82 +            raise web.badrequest('no text given')
    1.83 +            
    1.84 +        # invoke the user dialog as a subprocess
    1.85 +        dlg_image = os.path.join(sys.path[0], 'opensecurity_dialog.py')
    1.86 +        process_command = [sys.executable, dlg_image, 'notification-' + args.msgtype, args.text]
    1.87 +        process = subprocess.Popen(process_command, shell = False, stdout = subprocess.PIPE)
    1.88 +        return "Ok"
    1.89 +
    1.90 +
    1.91  class os_password:
    1.92      """OpenSecurity '/password' handler.
    1.93      
    1.94 @@ -153,19 +187,45 @@
    1.95          # pick the arguments
    1.96          args = web.input()
    1.97          
    1.98 -        # we _need_ a device id
    1.99 +        # we _need_ a text
   1.100          if not "text" in args:
   1.101 -            raise web.badrequest()
   1.102 +            raise web.badrequest('no text given')
   1.103              
   1.104 +        # remember remote ip
   1.105 +        remote_ip = web.ctx.environ['REMOTE_ADDR']
   1.106 +        
   1.107          # invoke the user dialog as a subprocess
   1.108 -        dlg_credentials_image = os.path.join(sys.path[0], 'opensecurity_dialog.py')
   1.109 -        process_command = [sys.executable, dlg_credentials_image, 'password', args.text]
   1.110 +        dlg_image = os.path.join(sys.path[0], 'opensecurity_dialog.py')
   1.111 +        process_command = [sys.executable, dlg_image, 'password', args.text]
   1.112          process = subprocess.Popen(process_command, shell = False, stdout = subprocess.PIPE)
   1.113          result = process.communicate()[0]
   1.114          if process.returncode != 0:
   1.115              return 'password request has been aborted.'
   1.116          
   1.117 -        return result
   1.118 +        # all ok, tell send request back appropriate destination
   1.119 +        
   1.120 +        # the returned value of the dialog is a jason object like
   1.121 +        # "{ 'password': 'THE_PASSWORD' }"
   1.122 +        # so we _could_ call eval(...) on this.
   1.123 +        #
   1.124 +        # However, anyone malicious enough _could_ encode a certain
   1.125 +        # "password" making some nasty things within that eval code. :(
   1.126 +        #
   1.127 +        # So this is plain old-school string hacking then ...
   1.128 +        try:
   1.129 +            password = result.split(':')[1].split("'")[1]
   1.130 +        except:
   1.131 +            raise web.internalerror('error in password parsing')
   1.132 +        
   1.133 +        url_addr = 'http://' + remote_ip + ':58080/password'
   1.134 +        url_data = urllib.urlencode({ 'password': password})
   1.135 +        req = urllib2.Request(url = url_addr + '?' + url_data)
   1.136 +        try:
   1.137 +            res = urllib2.urlopen(req)
   1.138 +        except:
   1.139 +            raise web.internalerror('failed to contact: ' + url_addr)
   1.140 +        
   1.141 +        return 'password told'
   1.142  
   1.143  
   1.144  class os_root: