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: