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