1.1 --- a/OpenSecurity/bin/opensecurity_client_restful_server.py Mon May 19 17:19:47 2014 +0100
1.2 +++ b/OpenSecurity/bin/opensecurity_client_restful_server.py Tue May 20 11:21:48 2014 +0200
1.3 @@ -33,19 +33,25 @@
1.4 # imports
1.5
1.6 import getpass
1.7 +import glob
1.8 import json
1.9 import os
1.10 import os.path
1.11 +import pickle
1.12 import platform
1.13 import socket
1.14 import subprocess
1.15 import sys
1.16 +import threading
1.17 +import time
1.18 import urllib
1.19 import urllib2
1.20 import web
1.21 import threading
1.22 import time
1.23 import string
1.24 +import win32api
1.25 +import win32con
1.26
1.27 from opensecurity_util import logger, setupLogger, OpenSecurityException
1.28 if sys.platform == 'win32' or sys.platform == 'cygwin':
1.29 @@ -53,6 +59,7 @@
1.30
1.31 # local
1.32 import __init__ as opensecurity
1.33 +from environment import Environment
1.34
1.35
1.36 # ------------------------------------------------------------
1.37 @@ -76,6 +83,13 @@
1.38 # vars
1.39
1.40
1.41 +"""lock for read/write log file"""
1.42 +log_file_lock = threading.Lock()
1.43 +
1.44 +"""timer for the log file bouncer"""
1.45 +log_file_bouncer = None
1.46 +
1.47 +
1.48 """The REST server object"""
1.49 server = None
1.50
1.51 @@ -170,19 +184,13 @@
1.52 args['user'] = getpass.getuser()
1.53 args['system'] = platform.node() + " " + platform.system() + " " + platform.release()
1.54
1.55 - # bounce log data
1.56 - url_addr = 'http://GIMME-SERVER-TO-LOG-TO/log'
1.57 + # add these to new data to log
1.58 + global log_file_lock
1.59 + log_file_name = os.path.join(Environment('OpenSecurity').log_path, 'vm_new.log')
1.60 + log_file_lock.acquire()
1.61 + pickle.dump(args, open(log_file_name, 'ab'))
1.62 + log_file_lock.release()
1.63
1.64 - # by provided a 'data' we turn this into a POST statement
1.65 - d = urllib.urlencode(args)
1.66 - req = urllib2.Request(url_addr, d)
1.67 - try:
1.68 - res = urllib2.urlopen(req)
1.69 - except:
1.70 - print('failed to contact: ' + url_addr)
1.71 - print('log data: ' + d)
1.72 - return "Failed"
1.73 -
1.74 return "Ok"
1.75
1.76
1.77 @@ -301,7 +309,6 @@
1.78
1.79 driveHandler = MountNetworkDriveHandler(args['drive_letter'], args['net_resource'])
1.80 driveHandler.start()
1.81 - driveHandler.join(None)
1.82 return 'Ok'
1.83
1.84
1.85 @@ -350,7 +357,6 @@
1.86
1.87 driveHandler = UmountNetworkDriveHandler(args['drive_letter'])
1.88 driveHandler.start()
1.89 - driveHandler.join(None)
1.90 return 'Ok'
1.91
1.92
1.93 @@ -442,11 +448,8 @@
1.94 print 'error in password parsing'
1.95 return
1.96
1.97 - # TODO: it would be WAY easier and secure if we just
1.98 - # add the result json to a HTTP-POST here.
1.99 + # by provided a 'data' we turn this into a POST statement
1.100 url_addr = 'http://' + self._remote_ip + ':58080' + self._resource
1.101 -
1.102 - # by provided a 'data' we turn this into a POST statement
1.103 req = urllib2.Request(url_addr, urllib.urlencode(j))
1.104 try:
1.105 res = urllib2.urlopen(req)
1.106 @@ -490,12 +493,95 @@
1.107 return True
1.108
1.109
1.110 +def _bounce_vm_logs():
1.111 +
1.112 + """grab all logs from the VMs and push them to the log servers"""
1.113 +
1.114 + global log_file_lock
1.115 +
1.116 + # pick the highest current number
1.117 + cur = 0
1.118 + for f in glob.iglob(os.path.join(Environment('OpenSecurity').log_path, 'vm_cur.log.*')):
1.119 + try:
1.120 + n = f.split('.')[-1:][0]
1.121 + if cur < int(n):
1.122 + cur = int(n)
1.123 + except:
1.124 + pass
1.125 +
1.126 + cur = cur + 1
1.127 +
1.128 + # first add new vm logs to our existing one: rename the log file
1.129 + log_file_name_new = os.path.join(Environment('OpenSecurity').log_path, 'vm_new.log')
1.130 + log_file_name_cur = os.path.join(Environment('OpenSecurity').log_path, 'vm_cur.log.' + str(cur))
1.131 + log_file_lock.acquire()
1.132 + try:
1.133 + os.rename(log_file_name_new, log_file_name_cur)
1.134 + print('new log file: ' + log_file_name_cur)
1.135 + except:
1.136 + pass
1.137 + log_file_lock.release()
1.138 +
1.139 + # now we have a list of next log files to dump
1.140 + log_files = glob.glob(os.path.join(Environment('OpenSecurity').log_path, 'vm_cur.log.*'))
1.141 + log_files.sort()
1.142 + for log_file in log_files:
1.143 +
1.144 + try:
1.145 + f = open(log_file, 'rb')
1.146 + while True:
1.147 + l = pickle.load(f)
1.148 + _push_log(l)
1.149 +
1.150 + except EOFError:
1.151 +
1.152 + try:
1.153 + os.remove(log_file)
1.154 + except:
1.155 + logger.warning('tried to delete log file (pushed to EOF) "' + log_file + '" but failed')
1.156 +
1.157 + except:
1.158 + logger.warning('encountered error while pushing log file "' + log_file + '"')
1.159 + break
1.160 +
1.161 + # start bouncer again ...
1.162 + global log_file_bouncer
1.163 + log_file_bouncer = threading.Timer(5.0, _bounce_vm_logs)
1.164 + log_file_bouncer.start()
1.165 +
1.166 +
1.167 +def _push_log(log):
1.168 + """POST a single log to log server
1.169 +
1.170 + @param log the log POST param
1.171 + """
1.172 +
1.173 + try:
1.174 + key = win32api.RegOpenKey(win32con.HKEY_LOCAL_MACHINE, 'SOFTWARE\OpenSecurity')
1.175 + log_server_url = str(win32api.RegQueryValueEx(key, 'LogServerURL')[0])
1.176 + win32api.RegCloseKey(key)
1.177 + except:
1.178 + logger.critical('Cannot open Registry HKEY_LOCAL_MACHINE\SOFTWARE\OpenSecurity and get LogServerURL value')
1.179 + raise
1.180 +
1.181 + # by provided a 'data' we turn this into a POST statement
1.182 + d = urllib.urlencode(log)
1.183 + req = urllib2.Request(log_server_url, d)
1.184 + urllib2.urlopen(req)
1.185 + logger.debug('pushed log to server: ' + str(log_server_url))
1.186 +
1.187 +
1.188 def _serve(port):
1.189
1.190 """Start the REST server"""
1.191
1.192 global server
1.193
1.194 + # start the VM-log bouncer timer
1.195 + global log_file_bouncer
1.196 + log_file_bouncer = threading.Timer(5.0, _bounce_vm_logs)
1.197 + log_file_bouncer.start()
1.198 +
1.199 # trick the web.py server
1.200 sys.argv = [__file__, str(port)]
1.201 server = web.application(opensecurity_urls, globals())
1.202 @@ -523,9 +609,12 @@
1.203 if server is None:
1.204 return
1.205
1.206 + global log_file_bouncer
1.207 + if log_file_bouncer is not None:
1.208 + log_file_bouncer.cancel()
1.209 +
1.210 server.stop()
1.211
1.212 -
1.213 # start
1.214 if __name__ == "__main__":
1.215 serve()
2.1 --- a/OpenSecurity/bin/opensecurityd.pyw Mon May 19 17:19:47 2014 +0100
2.2 +++ b/OpenSecurity/bin/opensecurityd.pyw Tue May 20 11:21:48 2014 +0200
2.3 @@ -123,8 +123,8 @@
2.4 trace_file = open(trace_file_name, 'w+')
2.5
2.6 machine_folder = Cygwin.cygPath(gvm_mgr.getMachineFolder())
2.7 - download_initial_image_script = '/OpenSecurity/bin/download_initial_image.sh \'' + machine_folder + '\''
2.8 - Cygwin.bashExecute(download_initial_image_script, wait_return = False, stdout = trace_file, stderr = trace_file)
2.9 + download_initial_image_script = Cygwin.cygPath(os.path.abspath(os.path.join(os.path.split(__file__)[0], 'download_initial_image.sh')))
2.10 + Cygwin.bashExecute(download_initial_image_script + ' \'' + machine_folder + '\'', wait_return = False, stdout = trace_file, stderr = trace_file)
2.11
2.12 res = '{ "fetch_log": "' + trace_file_name.replace('\\', '\\\\') + '" }'
2.13 return res
2.14 @@ -144,8 +144,8 @@
2.15 trace_file = open(trace_file_name, 'w+')
2.16
2.17 vm_image = Cygwin.cygPath(gvm_mgr.getMachineFolder()) + '/OsecVM.ova'
2.18 - initial_import_script = '/OpenSecurity/bin/initial_vm.sh \'' + vm_image + '\''
2.19 - Cygwin.bashExecute(initial_import_script, wait_return = False, stdout = trace_file, stderr = trace_file)
2.20 + initial_import_script = Cygwin.cygPath(os.path.abspath(os.path.join(os.path.split(__file__)[0], 'initial_vm.sh')))
2.21 + Cygwin.bashExecute(initial_import_script + ' \'' + vm_image + '\'', wait_return = False, stdout = trace_file, stderr = trace_file)
2.22
2.23 res = '{ "init_log": "' + trace_file_name.replace('\\', '\\\\') + '" }'
2.24 return res