OpenSecurity/bin/opensecurityd.pyw
author Oliver Maurhart <oliver.maurhart@ait.ac.at>
Mon, 10 Mar 2014 13:01:08 +0100
changeset 91 a26757850ea9
parent 90 bfd41c38d156
child 93 8fe521017397
permissions -rwxr-xr-x
download and initial import from within service working
     1 #!/bin/env python
     2 # -*- coding: utf-8 -*-
     3 
     4 # ------------------------------------------------------------
     5 # opensecurityd
     6 # 
     7 # the opensecurityd as RESTful server
     8 #
     9 # Autor: Oliver Maurhart, <oliver.maurhart@ait.ac.at>
    10 #
    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
    15 #
    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.
    19 # 
    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.
    24 # 
    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 # ------------------------------------------------------------
    30 
    31 
    32 # ------------------------------------------------------------
    33 # imports
    34 
    35 import os
    36 import os.path
    37 import subprocess
    38 import sys
    39 import tempfile
    40 import web
    41 
    42 import vmmanager
    43 
    44 # local
    45 from cygwin import Cygwin
    46 from environment import Environment
    47 from opensecurity_util import logger
    48 
    49 
    50 # ------------------------------------------------------------
    51 # const
    52 
    53 __version__ = "0.2"
    54 
    55 
    56 """All the URLs we know mapping to class handler"""
    57 opensecurity_urls = (
    58     '/browsing',                        'os_browsing',          # http://localhost:8080/browsing                                GET
    59     '/fetch_initial_image',             'os_fetch_image',       # http://localhost:8080/fetch_initial_image                     GET
    60     '/init',                            'os_init',              # http://localhost:8080/init                                    GET
    61     '/sdvms',                           'os_sdvms',             # http://localhost:8080/sdvms                                   GET, PUT
    62     '/sdvms/(.*)/application/(.*)',     'os_sdvm_application',  # http://localhost:8080/sdvms/[VMNAME]/application/[COMMAND]    GET
    63     '/sdvms/(.*)/ip',                   'os_sdvm_ip',           # http://localhost:8080/sdvms/[VMNAME]/ip                       GET
    64     '/sdvms/(.*)/start',                'os_sdvm_start',        # http://localhost:8080/sdvms/[VMNAME]/start                    GET
    65     '/sdvms/(.*)/stop',                 'os_sdvm_stop',         # http://localhost:8080/sdvms/[VMNAME]/stop                     GET
    66     '/sdvms/(.*)',                      'os_sdvm',              # http://localhost:8080/sdvms/[VMNAME]                          GET, DELETE
    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
    72 )
    73 
    74 
    75 # ------------------------------------------------------------
    76 # vars
    77 
    78 # Global VMManager instance
    79 gvm_mgr = None
    80 
    81 
    82 # ------------------------------------------------------------
    83 # code
    84 
    85 
    86 class os_browsing:
    87     """OpenSecurity '/browsing' handler
    88     
    89     - GET: Start and prepare a new SecurityVM for Internet Browsing. Return the name of the VM.
    90     """
    91     
    92     def GET(self):
    93         log_call(web.ctx.environ)
    94         global gvm_mgr
    95         try:
    96             result = gvm_mgr.handleBrowsingRequest()
    97             return result
    98         except:
    99             raise web.internalerror()
   100 
   101        
   102 class os_fetch_image:
   103     """OpenSecurity '/fetch_initial_image' handler
   104     
   105     - GET: fetch the initial image from the X-Net Servers
   106             The initial image is stored in the
   107             Virtual Box default machine path.
   108             The result to this call is a temprary file
   109             which shows the progress (or error state)
   110             of this call.
   111     """
   112     
   113     def GET(self):
   114         
   115         log_call(web.ctx.environ)
   116         global gvm_mgr
   117 
   118         trace_file_name = os.path.join(tempfile.gettempdir(), 'OpenSecurity_fetch_image.log')
   119         trace_file = open(trace_file_name, 'w+')
   120 
   121         machine_folder = Cygwin.cygPath(gvm_mgr.getMachineFolder()) 
   122         download_initial_image_script = '/OpenSecurity/bin/download_initial_image.sh \'' + machine_folder + '\''
   123         Cygwin.bashExecute(download_initial_image_script, wait_return = False, stdout = trace_file, stderr = trace_file) 
   124 
   125         return trace_file_name
   126 
   127 
   128 class os_init:
   129     """OpenSecurity '/init' handler
   130     
   131     - GET: Do initial import of OsecVM.ova
   132     """
   133     
   134     def GET(self):
   135         log_call(web.ctx.environ)
   136         global gvm_mgr
   137 
   138         trace_file_name = os.path.join(tempfile.gettempdir(), 'OpenSecurity_initial_import.log')
   139         trace_file = open(trace_file_name, 'w+')
   140 
   141         vm_image = Cygwin.cygPath(gvm_mgr.getMachineFolder()) + '/OsecVM.ova'
   142         initial_import_script = '/OpenSecurity/bin/initial_vm.sh \'' + vm_image + '\''
   143         Cygwin.bashExecute(initial_import_script, wait_return = False, stdout = trace_file, stderr = trace_file) 
   144 
   145         return trace_file_name
   146 
   147 
   148 class os_root:
   149     """OpenSecurity '/' handler
   150     
   151     - GET: give information about current installation.
   152     """
   153     
   154     def GET(self):
   155         log_call(web.ctx.environ)
   156         global gvm_mgr
   157         res = "'os_server': { "
   158         res += "'version': '" + __version__ + "', "
   159         res += "'virtual box systemproperties': '" + str(gvm_mgr.systemProperties) + "', "
   160         res += "'current temporary folder': '" + tempfile.gettempdir() + "' "
   161         res += "}"
   162         return res
   163 
   164 
   165 class os_sdvm:
   166     """OpenSecurity '/sdvms/[VM]' handler
   167     
   168     - GET: Information about a specific SecurityVM
   169     - DELETE: Remove a specific
   170     """
   171     
   172     def GET(self, name):
   173         log_call(web.ctx.environ)
   174         global gvm_mgr
   175         return gvm_mgr.getVMInfo(name)
   176 
   177     def DELETE(self, name):
   178         log_call(web.ctx.environ)
   179         global gvm_mgr
   180         return gvm_mgr.removeVM(name)
   181             
   182 
   183 class os_sdvm_application:
   184     """OpenSecurity '/sdvms/[VM]/application/[CMD]' handler
   185     
   186     - GET: start application with given command in the VM.
   187     """
   188     
   189     def GET(self, name, command):
   190         log_call(web.ctx.environ)
   191         global gvm_mgr
   192         command = '/' + command
   193         result = Cygwin.sshExecuteX11(command, gvm_mgr.getHostOnlyIP(name), 'osecuser', Cygwin.cygPath(gvm_mgr.getMachineFolder()) + '/' + name + '/dvm_key'  )
   194         self.poweroffVM(name)
   195         return gvm_mgr.removeVM(name)
   196     
   197 
   198 class os_sdvm_ip:
   199     """OpenSecurity '/sdvms/[VM]/ip' handler
   200     
   201     - GET: give IP of SecurityVM.
   202     """
   203     
   204     def GET(self, name):
   205         log_call(web.ctx.environ)
   206         global gvm_mgr
   207         return gvm_mgr.getHostOnlyIP(name)
   208             
   209 
   210 class os_sdvm_start:
   211     """OpenSecurity '/sdvms/[VM]/start' handler
   212     
   213     - GET: Start specific SecuirtyVM.
   214     """
   215     
   216     def GET(self, name):
   217         log_call(web.ctx.environ)
   218         global gvm_mgr
   219         return gvm_mgr.startVM(name)
   220             
   221 
   222 class os_sdvm_stop:
   223     """OpenSecurity '/sdvms/[VM]/stop' handler
   224     
   225     - GET: stop specific Secuirty VM.
   226     """
   227     
   228     def GET(self, name):
   229         log_call(web.ctx.environ)
   230         global gvm_mgr
   231         return gvm_mgr.stopVM(name)
   232             
   233 
   234 class os_sdvms:
   235     """OpenSecurity '/sdvms' handler
   236     
   237     - GET: list all available secuirty VMs.
   238     - POST: create new security vm.
   239     """
   240     
   241     def GET(self):
   242         """get the list of SDVMs"""
   243         log_call(web.ctx.environ)
   244         global gvm_mgr
   245         return gvm_mgr.listSDVM() 
   246             
   247     def POST(self):
   248         """create a new SDVM"""
   249         log_call(web.ctx.environ)
   250         global gvm_mgr
   251         
   252         # get a new vm-name
   253         name = gvm_mgr.generateSDVMName()
   254         try:
   255             gvm_mgr.createVM(name)
   256         except:
   257             raise web.internalerror()
   258             
   259         return name
   260             
   261 
   262 class os_terminate:
   263     """OpenSecurity '/terminate' handler
   264     
   265     - GET: terminate the opensecurityd.
   266 
   267     YES: this here is bonkers. But the web.py http
   268     server runs infinite until a SystemExit exception
   269     or KeyboardInterrupt exception is raised.
   270 
   271     see: site-packages/web/httpserver.py - line 157ff
   272     see: site-packages/web/wsgiserver/__init__.py - line 1682ff
   273 
   274     So, we invoke a sys.exit(0) here to trigger server.stop().
   275 
   276     TODO: need to find a better way doing this, and not via the
   277           REST api. Maybe hack web.py server code?
   278     """
   279     
   280     def GET(self):
   281         log_call(web.ctx.environ)
   282         global gvm_mgr
   283         gvm_mgr.stop()
   284         gvm_mgr.cleanup()
   285         sys.exit(0)
   286         return None
   287 
   288 
   289 class os_update_template:
   290     """OpenSecurity '/update_template' handler
   291     
   292     - GET: update template vm
   293     """
   294     
   295     def GET(self):
   296         #return gvm_mgr.guestExecute('SecurityDVM', 'sudo apt-get -y update')
   297         global gvm_mgr
   298         log_call(web.ctx.environ)
   299         return gvm_mgr.updateTemplate()
   300 
   301 
   302 class os_vm:
   303     """OpenSecurity '/vms/[VM]' handler
   304     
   305     - GET: list information of arbitrary VM.
   306     """
   307     
   308     def GET(self, name):
   309         log_call(web.ctx.environ)
   310         global gvm_mgr
   311         return gvm_mgr.getVMInfo(name)
   312             
   313 
   314 class os_vms:
   315     """OpenSecurity '/vms' handler
   316     
   317     - GET: list all (also non Security) VMs.
   318     """
   319     
   320     def GET(self):
   321         log_call(web.ctx.environ)
   322         global gvm_mgr
   323         return gvm_mgr.listVM() 
   324             
   325 
   326 def log_call(web_environ):
   327     """log the incoming call to the REST api"""
   328     try:
   329         call = 'REST ' +  web_environ['REQUEST_METHOD'] + ' ' + web_environ['REQUEST_URI'] + ' from ' + web_environ['REMOTE_ADDR'] + ':' + web_environ['REMOTE_PORT']
   330         logger.debug(call)
   331     except:
   332         pass
   333 
   334 
   335 def main():
   336     """main startup for the opensecuirityd"""
   337 
   338     logger.debug('Starting OpenSecurity REST server')
   339 
   340     # ensure a VMManger is yet loaded
   341     global gvm_mgr
   342     gvm_mgr = vmmanager.VMManager.getInstance()
   343     
   344     server = web.application(opensecurity_urls, globals(), autoreload = False)
   345     server.run()
   346     
   347     logger.debug('Stopped OpenSecurity REST server')
   348 
   349 
   350 def stop():
   351     """stop the opensecuirityd"""
   352 
   353     # calling sys.exit() raises a SystemExit exception
   354     # of the WSGI Server to let it wind down
   355     # gracefully
   356     sys.exit(0)
   357 
   358 
   359 
   360 # start
   361 if __name__ == "__main__":
   362     main()
   363