2 # -*- coding: utf-8 -*-
4 # ------------------------------------------------------------
7 # the opensecurityd as RESTful server
9 # Autor: Oliver Maurhart, <oliver.maurhart@ait.ac.at>
11 # Copyright (C) 2013 AIT Austrian Institute of Technology
12 # AIT Austrian Institute of Technology GmbH
13 # Donau-City-Strasse 1 | 1220 Vienna | Austria
14 # http://www.ait.ac.at
16 # This program is free software; you can redistribute it and/or
17 # modify it under the terms of the GNU General Public License
18 # as published by the Free Software Foundation version 2.
20 # This program is distributed in the hope that it will be useful,
21 # but WITHOUT ANY WARRANTY; without even the implied warranty of
22 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 # GNU General Public License for more details.
25 # You should have received a copy of the GNU General Public License
26 # along with this program; if not, write to the Free Software
27 # Foundation, Inc., 51 Franklin Street, Fifth Floor,
28 # Boston, MA 02110-1301, USA.
29 # ------------------------------------------------------------
32 # ------------------------------------------------------------
46 import __init__ as opensecurity
47 from cygwin import Cygwin
48 from opensecurity_util import logger
51 # ------------------------------------------------------------
54 """All the URLs we know mapping to class handler"""
56 '/browsing', 'os_browsing', # http://localhost:8080/browsing GET
57 '/fetch_initial_image', 'os_fetch_image', # http://localhost:8080/fetch_initial_image GET
58 '/init', 'os_init', # http://localhost:8080/init GET
59 '/initial_image', 'os_initial_image', # http://localhost:8080/initial_image GET
60 '/sdvms', 'os_sdvms', # http://localhost:8080/sdvms GET, PUT
61 '/sdvms/(.*)/application/(.*)', 'os_sdvm_application', # http://localhost:8080/sdvms/[VMNAME]/application/[COMMAND] GET
62 '/sdvms/(.*)/ip', 'os_sdvm_ip', # http://localhost:8080/sdvms/[VMNAME]/ip GET
63 '/sdvms/(.*)/start', 'os_sdvm_start', # http://localhost:8080/sdvms/[VMNAME]/start GET
64 '/sdvms/(.*)/stop', 'os_sdvm_stop', # http://localhost:8080/sdvms/[VMNAME]/stop GET
65 '/sdvms/(.*)', 'os_sdvm', # http://localhost:8080/sdvms/[VMNAME] GET, DELETE
66 '/setup', 'os_setup', # http://localhost:8080/setup GET
67 '/vms', 'os_vms', # http://localhost:8080/vms GET
68 '/vms/(.*)', 'os_vm', # http://localhost:8080/vms/[VMNAME] GET
69 '/update_template', 'os_update_template', # http://localhost:8080/update_template GET
70 '/terminate', 'os_terminate', # http://localhost:8080/terminate GET
71 '/', 'os_root' # http://localhost:8080/ GET
75 # ------------------------------------------------------------
78 # Global VMManager instance
85 # ------------------------------------------------------------
90 """OpenSecurity '/browsing' handler
92 - GET: Start and prepare a new SecurityVM for Internet Browsing. Return the name of the VM.
96 log_call(web.ctx.environ)
99 result = gvm_mgr.handleBrowsingRequest()
102 raise web.internalerror()
105 class os_fetch_image:
106 """OpenSecurity '/fetch_initial_image' handler
108 - GET: fetch the initial image from the X-Net Servers
109 The initial image is stored in the
110 Virtual Box default machine path.
111 The result to this call is a temprary file
112 which shows the progress (or error state)
118 log_call(web.ctx.environ)
121 trace_file_name = os.path.join(tempfile.gettempdir(), 'OpenSecurity_fetch_image.log')
122 trace_file = open(trace_file_name, 'w+')
124 machine_folder = Cygwin.cygPath(gvm_mgr.getMachineFolder())
125 download_initial_image_script = '/OpenSecurity/bin/download_initial_image.sh \'' + machine_folder + '\''
126 Cygwin.bashExecute(download_initial_image_script, wait_return = False, stdout = trace_file, stderr = trace_file)
128 res = '{ "fetch_log": "' + trace_file_name.replace('\\', '\\\\') + '" }'
132 """OpenSecurity '/init' handler
134 - GET: Do initial import of OsecVM.ova
138 log_call(web.ctx.environ)
141 trace_file_name = os.path.join(tempfile.gettempdir(), 'OpenSecurity_initial_import.log')
142 trace_file = open(trace_file_name, 'w+')
144 vm_image = Cygwin.cygPath(gvm_mgr.getMachineFolder()) + '/OsecVM.ova'
145 initial_import_script = '/OpenSecurity/bin/initial_vm.sh \'' + vm_image + '\''
146 Cygwin.bashExecute(initial_import_script, wait_return = False, stdout = trace_file, stderr = trace_file)
148 res = '{ "init_log": "' + trace_file_name.replace('\\', '\\\\') + '" }'
152 class os_initial_image:
153 """OpenSecurity '/initial_image' handler
155 - GET: Return what we have as initial image.
159 log_call(web.ctx.environ)
161 t = os.path.join(gvm_mgr.systemProperties['Default machine folder'], 'OsecVM.ova')
163 if os.path.isfile(t):
164 res = '{"initial_template": { '
165 res += '"name": "OsecVM.ova", '
166 res += '"path": "' + t.replace('\\', '\\\\') + '", '
167 res += '"size": ' + str(os.path.getsize(t)) + ', '
168 res += '"date": ' + str(os.path.getmtime(t)) + ''
174 """OpenSecurity '/' handler
176 - GET: give information about current installation.
180 log_call(web.ctx.environ)
183 # create a json string and pretty print it
184 res = '{"os_server": { '
185 res += '"version": "' + opensecurity.__version__ + '" '
186 res += ', "virtual box systemproperties": ' + str(gvm_mgr.systemProperties).replace("'", '"')
187 res += ', "current temporary folder": "' + tempfile.gettempdir().replace('\\', '\\\\') + '"'
190 res += ', "whoami": "' + Cygwin.bashExecute('whoami')[1].strip() + '"'
192 res += ', "whoami": "FAILED"'
195 res += ', "mount": ' + str(Cygwin.bashExecute('mount')[1].split('\n')[:-1]).replace("'", '"')
197 res += ', "mount": "FAILED"'
200 res += ', "cygpath --windows ~": "' + Cygwin.bashExecute('cygpath --windows ~')[1].strip().replace('\\', '\\\\') + '"'
202 res += ', "cygpath --windows ~": "FAILED"'
205 res += ', "status message": "' + gvm_mgr.status_message.replace('"', "'") + '"'
209 # loading it into json and print it again ensures
210 # we really do have a valid RFC conform json string
211 # created (as long as the python json module is RFC conform)
212 return json.dumps(json.loads(res), indent = 4)
216 """OpenSecurity '/sdvms/[VM]' handler
218 - GET: Information about a specific SecurityVM
219 - DELETE: Remove a specific
223 log_call(web.ctx.environ)
225 return gvm_mgr.getVMInfo(name)
227 def DELETE(self, name):
228 log_call(web.ctx.environ)
230 return gvm_mgr.removeVM(name)
233 class os_sdvm_application:
234 """OpenSecurity '/sdvms/[VM]/application/[CMD]' handler
236 - GET: start application with given command in the VM.
239 def GET(self, name, command):
240 log_call(web.ctx.environ)
242 command = '/' + command
243 result = Cygwin.sshExecuteX11(command, gvm_mgr.getHostOnlyIP(name), 'osecuser', Cygwin.cygPath(gvm_mgr.getMachineFolder()) + '/' + name + '/dvm_key' )
244 self.poweroffVM(name)
245 return gvm_mgr.removeVM(name)
249 """OpenSecurity '/sdvms/[VM]/ip' handler
251 - GET: give IP of SecurityVM.
255 log_call(web.ctx.environ)
257 return gvm_mgr.getHostOnlyIP(name)
261 """OpenSecurity '/sdvms/[VM]/start' handler
263 - GET: Start specific SecuirtyVM.
267 log_call(web.ctx.environ)
269 return gvm_mgr.startVM(name)
273 """OpenSecurity '/sdvms/[VM]/stop' handler
275 - GET: stop specific Secuirty VM.
279 log_call(web.ctx.environ)
281 return gvm_mgr.stopVM(name)
285 """OpenSecurity '/sdvms' handler
287 - GET: list all available secuirty VMs.
288 - POST: create new security vm.
292 """get the list of SDVMs"""
293 log_call(web.ctx.environ)
295 return gvm_mgr.listSDVM()
298 """create a new SDVM"""
299 log_call(web.ctx.environ)
303 name = gvm_mgr.generateSDVMName()
305 gvm_mgr.createVM(name)
307 raise web.internalerror()
313 """OpenSecurity '/setup' handler
315 - GET: Give user some info how to setup the OpenSecurity envvironment
320 log_call(web.ctx.environ)
325 <h1>Setup OpenSecurity</h1>
326 In order to setup OpenSecurity an inital VM image has to be downloaded and imported:<br/>
328 <li>Download initial VM image: <a href="/fetch_initial_image">fetch_initial_image</a>
329 <li>Import initial VM: <a href="/init">init</a>
338 """OpenSecurity '/terminate' handler
340 - GET: terminate the opensecurityd.
342 TODO: need to find a better way doing this, and not via the
343 REST api. Maybe hack web.py server code?
347 log_call(web.ctx.environ)
355 class os_update_template:
356 """OpenSecurity '/update_template' handler
358 - GET: update template vm
362 #return gvm_mgr.guestExecute('SecurityDVM', 'sudo apt-get -y update')
364 log_call(web.ctx.environ)
365 return gvm_mgr.updateTemplate()
369 """OpenSecurity '/vms/[VM]' handler
371 - GET: list information of arbitrary VM.
375 log_call(web.ctx.environ)
377 return gvm_mgr.getVMInfo(name)
381 """OpenSecurity '/vms' handler
383 - GET: list all (also non Security) VMs.
387 log_call(web.ctx.environ)
389 return str(gvm_mgr.listVM()).replace("'",'"')
392 def log_call(web_environ):
393 """log the incoming call to the REST api"""
395 call = 'REST ' + web_environ['REQUEST_METHOD'] + ' ' + web_environ['REQUEST_URI'] + ' from ' + web_environ['REMOTE_ADDR'] + ':' + web_environ['REMOTE_PORT']
402 """main startup for the opensecuirityd"""
407 logger.debug('Starting OpenSecurity REST server')
409 # ensure a VMManger is yet loaded
410 gvm_mgr = vmmanager.VMManager.getInstance()
412 # tweak sys.argv to control wep.py server start behavior
413 sys.argv = [__file__, "8080"]
414 server = web.application(opensecurity_urls, globals(), autoreload = False)
417 logger.debug('Stopped OpenSecurity REST server')
421 """stop the opensecuirityd"""
423 # calling sys.exit() raises a SystemExit exception
424 # of the WSGI Server to let it wind down
431 if __name__ == "__main__":