reverted to last revision but before
authorOliver Maurhart <oliver.maurhart@ait.ac.at>
Tue, 20 May 2014 11:21:48 +0200
changeset 164b6b9dc0ed2ac
parent 163 e7fbdaabd0bc
child 165 a1b7a5a48a1e
reverted to last revision but before
OpenSecurity/bin/opensecurity_client_restful_server.py
OpenSecurity/bin/opensecurityd.pyw
     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