1.1 --- a/OpenSecurity/bin/environment.py Fri May 16 10:04:11 2014 +0200
1.2 +++ b/OpenSecurity/bin/environment.py Mon May 19 13:13:30 2014 +0200
1.3 @@ -44,6 +44,8 @@
1.4 class Environment(object):
1.5
1.6 """Hold some nifty environment stuff in a dedicated class."""
1.7 +
1.8 + _log_warning_shown = False
1.9
1.10 def __init__(self, application = None):
1.11
1.12 @@ -103,7 +105,9 @@
1.13 if os.access('/var/log', os.W_OK):
1.14 return '/var/log'
1.15
1.16 - print('no permissions to write log files in /var/log, switching to ~/.log')
1.17 + if not Environment._log_warning_shown:
1.18 + print('no permissions to write log files in /var/log, switching to ~/.log')
1.19 + Environment._log_warning_shown = True
1.20
1.21 if not os.path.exists(user_log_path):
1.22 os.mkdir(user_log_path)
2.1 --- a/OpenSecurity/bin/opensecurity_client_restful_server.py Fri May 16 10:04:11 2014 +0200
2.2 +++ b/OpenSecurity/bin/opensecurity_client_restful_server.py Mon May 19 13:13:30 2014 +0200
2.3 @@ -33,19 +33,20 @@
2.4 # imports
2.5
2.6 import getpass
2.7 +import glob
2.8 import json
2.9 import os
2.10 import os.path
2.11 +import pickle
2.12 import platform
2.13 import socket
2.14 import subprocess
2.15 import sys
2.16 +import threading
2.17 +import time
2.18 import urllib
2.19 import urllib2
2.20 import web
2.21 -import threading
2.22 -import time
2.23 -import string
2.24
2.25 from opensecurity_util import logger, setupLogger, OpenSecurityException
2.26 if sys.platform == 'win32' or sys.platform == 'cygwin':
2.27 @@ -53,6 +54,7 @@
2.28
2.29 # local
2.30 import __init__ as opensecurity
2.31 +from environment import Environment
2.32
2.33
2.34 # ------------------------------------------------------------
2.35 @@ -76,6 +78,13 @@
2.36 # vars
2.37
2.38
2.39 +"""lock for read/write log file"""
2.40 +log_file_lock = threading.Lock()
2.41 +
2.42 +"""timer for the log file bouncer"""
2.43 +log_file_bouncer = None
2.44 +
2.45 +
2.46 """The REST server object"""
2.47 server = None
2.48
2.49 @@ -170,19 +179,13 @@
2.50 args['user'] = getpass.getuser()
2.51 args['system'] = platform.node() + " " + platform.system() + " " + platform.release()
2.52
2.53 - # bounce log data
2.54 - url_addr = 'http://GIMME-SERVER-TO-LOG-TO/log'
2.55 + # add these to new data to log
2.56 + global log_file_lock
2.57 + log_file_name = os.path.join(Environment('OpenSecurity').log_path, 'vm_new.log')
2.58 + log_file_lock.acquire()
2.59 + pickle.dump(args, open(log_file_name, 'ab'))
2.60 + log_file_lock.release()
2.61
2.62 - # by provided a 'data' we turn this into a POST statement
2.63 - d = urllib.urlencode(args)
2.64 - req = urllib2.Request(url_addr, d)
2.65 - try:
2.66 - res = urllib2.urlopen(req)
2.67 - except:
2.68 - print('failed to contact: ' + url_addr)
2.69 - print('log data: ' + d)
2.70 - return "Failed"
2.71 -
2.72 return "Ok"
2.73
2.74
2.75 @@ -488,12 +491,88 @@
2.76 return True
2.77
2.78
2.79 +def _bounce_vm_logs():
2.80 +
2.81 + """grab all logs from the VMs and push them to the log servers"""
2.82 +
2.83 + global log_file_lock
2.84 +
2.85 + # pick the highest current number
2.86 + cur = 0
2.87 + for f in glob.iglob(os.path.join(Environment('OpenSecurity').log_path, 'vm_cur.log.*')):
2.88 + try:
2.89 + n = f.split('.')[-1:][0]
2.90 + if cur < int(n):
2.91 + cur = int(n)
2.92 + except:
2.93 + pass
2.94 +
2.95 + cur = cur + 1
2.96 +
2.97 + # first add new vm logs to our existing one: rename the log file
2.98 + log_file_name_new = os.path.join(Environment('OpenSecurity').log_path, 'vm_new.log')
2.99 + log_file_name_cur = os.path.join(Environment('OpenSecurity').log_path, 'vm_cur.log.' + str(cur))
2.100 + log_file_lock.acquire()
2.101 + try:
2.102 + os.rename(log_file_name_new, log_file_name_cur)
2.103 + print('new log file: ' + log_file_name_cur)
2.104 + except:
2.105 + pass
2.106 + log_file_lock.release()
2.107 +
2.108 + # now we have a list of next log files to dump
2.109 + log_files = glob.glob(os.path.join(Environment('OpenSecurity').log_path, 'vm_cur.log.*'))
2.110 + log_files.sort()
2.111 + for log_file in log_files:
2.112 +
2.113 + try:
2.114 + f = open(log_file, 'rb')
2.115 + while True:
2.116 + l = pickle.load(f)
2.117 + _push_log(l)
2.118 +
2.119 + except EOFError:
2.120 +
2.121 + try:
2.122 + os.remove(log_file)
2.123 + except:
2.124 + logger.warning('tried to delete log file (pushed to EOF) "' + log_file + '" but failed')
2.125 +
2.126 + except:
2.127 + logger.warning('encountered error while pushing log file "' + log_file + '"')
2.128 +
2.129 + # start bouncer again ...
2.130 + global log_file_bouncer
2.131 + log_file_bouncer = threading.Timer(5.0, _bounce_vm_logs)
2.132 + log_file_bouncer.start()
2.133 +
2.134 +
2.135 +def _push_log(log):
2.136 + """POST a single log to log server
2.137 +
2.138 + @param log the log POST param
2.139 + """
2.140 +
2.141 + url_addr = 'http://GIMME-SERVER-TO-LOG-TO/log'
2.142 +
2.143 + # by provided a 'data' we turn this into a POST statement
2.144 + d = urllib.urlencode(log)
2.145 + req = urllib2.Request(url_addr, d)
2.146 + urllib2.urlopen(req)
2.147 + logger.debug('pushed log to server: ' + str(log))
2.148 +
2.149 +
2.150 def _serve(port):
2.151
2.152 """Start the REST server"""
2.153
2.154 global server
2.155
2.156 + # start the VM-log bouncer timer
2.157 + global log_file_bouncer
2.158 + log_file_bouncer = threading.Timer(5.0, _bounce_vm_logs)
2.159 + log_file_bouncer.start()
2.160 +
2.161 # trick the web.py server
2.162 sys.argv = [__file__, str(port)]
2.163 server = web.application(opensecurity_urls, globals())
2.164 @@ -521,9 +600,12 @@
2.165 if server is None:
2.166 return
2.167
2.168 + global log_file_bouncer
2.169 + if log_file_bouncer is not None:
2.170 + log_file_bouncer.cancel()
2.171 +
2.172 server.stop()
2.173
2.174 -
2.175 # start
2.176 if __name__ == "__main__":
2.177 serve()