OpenSecurity/bin/opensecurityd.pyw
author mb
Fri, 07 Mar 2014 14:32:12 +0100
changeset 90 bfd41c38d156
parent 89 7a925dd96e2d
child 91 a26757850ea9
permissions -rwxr-xr-x
new version. many bugfixes and new functionality
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
mb@63
    39
import web
mb@63
    40
from cygwin import Cygwin
mb@63
    41
oliver@87
    42
import vmmanager
mb@63
    43
mb@63
    44
# local
mb@63
    45
from environment import Environment
oliver@74
    46
from opensecurity_util import logger
mb@63
    47
mb@63
    48
mb@63
    49
# ------------------------------------------------------------
mb@63
    50
# const
mb@63
    51
mb@63
    52
__version__ = "0.2"
mb@63
    53
mb@63
    54
mb@63
    55
"""All the URLs we know mapping to class handler"""
mb@63
    56
opensecurity_urls = (
mb@63
    57
    '/browsing',                        'os_browsing',          # http://localhost:8080/browsing                                GET
mb@63
    58
    '/sdvms',                           'os_sdvms',             # http://localhost:8080/sdvms                                   GET, PUT
mb@63
    59
    '/sdvms/(.*)/application/(.*)',     'os_sdvm_application',  # http://localhost:8080/sdvms/[VMNAME]/application/[COMMAND]    GET
mb@63
    60
    '/sdvms/(.*)/ip',                   'os_sdvm_ip',           # http://localhost:8080/sdvms/[VMNAME]/ip                       GET
mb@63
    61
    '/sdvms/(.*)/start',                'os_sdvm_start',        # http://localhost:8080/sdvms/[VMNAME]/start                    GET
mb@63
    62
    '/sdvms/(.*)/stop',                 'os_sdvm_stop',         # http://localhost:8080/sdvms/[VMNAME]/stop                     GET
mb@63
    63
    '/sdvms/(.*)',                      'os_sdvm',              # http://localhost:8080/sdvms/[VMNAME]                          GET, DELETE
mb@63
    64
    '/vms',                             'os_vms',               # http://localhost:8080/vms                                     GET
mb@63
    65
    '/vms/(.*)',                        'os_vm',                # http://localhost:8080/vms/[VMNAME]                            GET
oliver@87
    66
    '/update_template',                 'os_update_template',   # http://localhost:8080/update_template                         GET
oliver@87
    67
    '/terminate',                       'os_terminate',         # http://localhost:8080/terminate                               GET
oliver@87
    68
    '/',                                'os_root'               # http://localhost:8080/                                        GET
mb@63
    69
)
mb@63
    70
oliver@87
    71
mb@66
    72
# ------------------------------------------------------------
mb@63
    73
# vars
mb@63
    74
mb@63
    75
# Global VMManager instance
oliver@86
    76
gvm_mgr = None
oliver@86
    77
mb@63
    78
mb@63
    79
# ------------------------------------------------------------
mb@63
    80
# code
mb@63
    81
mb@63
    82
mb@63
    83
class os_browsing:
mb@63
    84
    """OpenSecurity '/browsing' handler
mb@63
    85
    
mb@63
    86
    - GET: Start and prepare a new SecurityVM for Internet Browsing. Return the name of the VM.
mb@63
    87
    """
mb@63
    88
    
mb@63
    89
    def GET(self):
oliver@74
    90
        log_call(web.ctx.environ)
oliver@87
    91
        global gvm_mgr
mb@63
    92
        try:
mb@90
    93
            result = gvm_mgr.handleBrowsingRequest()
mb@90
    94
            return result
mb@63
    95
        except:
mb@63
    96
            raise web.internalerror()
mb@63
    97
oliver@87
    98
       
oliver@87
    99
class os_root:
oliver@87
   100
    """OpenSecurity '/' handler
oliver@87
   101
    
oliver@87
   102
    - GET: give information about current installation.
oliver@87
   103
    """
oliver@87
   104
    
oliver@87
   105
    def GET(self):
oliver@87
   106
        log_call(web.ctx.environ)
oliver@87
   107
        global gvm_mgr
oliver@87
   108
        res = "'os_server': { "
oliver@87
   109
        res += "'version': '" + __version__ + "', "
oliver@88
   110
        res += "'machine_folder': '" + gvm_mgr.machineFolder + "' "
oliver@87
   111
        res += "}"
oliver@87
   112
        return res
oliver@87
   113
oliver@87
   114
mb@63
   115
class os_sdvm:
mb@63
   116
    """OpenSecurity '/sdvms/[VM]' handler
mb@63
   117
    
mb@63
   118
    - GET: Information about a specific SecurityVM
mb@63
   119
    - DELETE: Remove a specific
mb@63
   120
    """
mb@63
   121
    
mb@63
   122
    def GET(self, name):
oliver@74
   123
        log_call(web.ctx.environ)
oliver@87
   124
        global gvm_mgr
oliver@87
   125
        return gvm_mgr.getVMInfo(name)
mb@63
   126
mb@63
   127
    def DELETE(self, name):
oliver@74
   128
        log_call(web.ctx.environ)
oliver@87
   129
        global gvm_mgr
oliver@87
   130
        return gvm_mgr.removeVM(name)
mb@63
   131
            
mb@63
   132
mb@63
   133
class os_sdvm_application:
mb@63
   134
    """OpenSecurity '/sdvms/[VM]/application/[CMD]' handler
mb@63
   135
    
mb@63
   136
    - GET: start application with given command in the VM.
mb@63
   137
    """
mb@63
   138
    
mb@63
   139
    def GET(self, name, command):
oliver@74
   140
        log_call(web.ctx.environ)
oliver@87
   141
        global gvm_mgr
mb@63
   142
        command = '/' + command
oliver@87
   143
        result = Cygwin.sshExecuteX11(command, gvm_mgr.getHostOnlyIP(name), 'osecuser', Cygwin.cygPath(gvm_mgr.getMachineFolder()) + '/' + name + '/dvm_key'  )
mb@90
   144
        return result
mb@63
   145
    
mb@63
   146
mb@63
   147
class os_sdvm_ip:
mb@63
   148
    """OpenSecurity '/sdvms/[VM]/ip' handler
mb@63
   149
    
mb@63
   150
    - GET: give IP of SecurityVM.
mb@63
   151
    """
mb@63
   152
    
mb@63
   153
    def GET(self, name):
oliver@74
   154
        log_call(web.ctx.environ)
oliver@87
   155
        global gvm_mgr
oliver@87
   156
        return gvm_mgr.getHostOnlyIP(name)
mb@63
   157
            
mb@63
   158
mb@63
   159
class os_sdvm_start:
mb@63
   160
    """OpenSecurity '/sdvms/[VM]/start' handler
mb@63
   161
    
mb@63
   162
    - GET: Start specific SecuirtyVM.
mb@63
   163
    """
mb@63
   164
    
mb@63
   165
    def GET(self, name):
oliver@74
   166
        log_call(web.ctx.environ)
oliver@87
   167
        global gvm_mgr
oliver@87
   168
        return gvm_mgr.startVM(name)
mb@63
   169
            
mb@63
   170
mb@63
   171
class os_sdvm_stop:
mb@63
   172
    """OpenSecurity '/sdvms/[VM]/stop' handler
mb@63
   173
    
mb@63
   174
    - GET: stop specific Secuirty VM.
mb@63
   175
    """
mb@63
   176
    
mb@63
   177
    def GET(self, name):
oliver@74
   178
        log_call(web.ctx.environ)
oliver@87
   179
        global gvm_mgr
oliver@87
   180
        return gvm_mgr.stopVM(name)
mb@63
   181
            
mb@63
   182
mb@63
   183
class os_sdvms:
mb@63
   184
    """OpenSecurity '/sdvms' handler
mb@63
   185
    
mb@63
   186
    - GET: list all available secuirty VMs.
mb@63
   187
    - POST: create new security vm.
mb@63
   188
    """
mb@63
   189
    
mb@63
   190
    def GET(self):
mb@63
   191
        """get the list of SDVMs"""
oliver@74
   192
        log_call(web.ctx.environ)
oliver@87
   193
        global gvm_mgr
oliver@87
   194
        return gvm_mgr.listSDVM() 
mb@63
   195
            
mb@63
   196
    def POST(self):
mb@63
   197
        """create a new SDVM"""
oliver@74
   198
        log_call(web.ctx.environ)
oliver@87
   199
        global gvm_mgr
oliver@74
   200
        
mb@63
   201
        # get a new vm-name
oliver@87
   202
        name = gvm_mgr.generateSDVMName()
mb@63
   203
        try:
oliver@87
   204
            gvm_mgr.createVM(name)
mb@63
   205
        except:
mb@63
   206
            raise web.internalerror()
mb@63
   207
            
mb@63
   208
        return name
mb@63
   209
            
oliver@87
   210
oliver@87
   211
class os_terminate:
oliver@87
   212
    """OpenSecurity '/terminate' handler
oliver@87
   213
    
oliver@87
   214
    - GET: terminate the opensecurityd.
oliver@87
   215
oliver@87
   216
    YES: this here is bonkers. But the web.py http
oliver@87
   217
    server runs infinite until a SystemExit exception
oliver@87
   218
    or KeyboardInterrupt exception is raised.
oliver@87
   219
oliver@87
   220
    see: site-packages/web/httpserver.py - line 157ff
oliver@87
   221
    see: site-packages/web/wsgiserver/__init__.py - line 1682ff
oliver@87
   222
oliver@87
   223
    So, we invoke a sys.exit(0) here to trigger server.stop().
oliver@87
   224
oliver@87
   225
    TODO: need to find a better way doing this, and not via the
oliver@87
   226
          REST api. Maybe hack web.py server code?
oliver@87
   227
    """
oliver@87
   228
    
oliver@87
   229
    def GET(self):
oliver@87
   230
        log_call(web.ctx.environ)
oliver@87
   231
        global gvm_mgr
oliver@88
   232
        gvm_mgr.cleanup()
oliver@87
   233
        sys.exit(0)
oliver@87
   234
        return None
oliver@87
   235
oliver@87
   236
oliver@87
   237
class os_update_template:
oliver@87
   238
    """OpenSecurity '/update_template' handler
oliver@87
   239
    
oliver@87
   240
    - GET: update template vm
oliver@87
   241
    """
oliver@87
   242
    
oliver@87
   243
    def GET(self):
oliver@87
   244
        #return gvm_mgr.guestExecute('SecurityDVM', 'sudo apt-get -y update')
oliver@87
   245
        global gvm_mgr
oliver@87
   246
        log_call(web.ctx.environ)
oliver@87
   247
        return gvm_mgr.updateTemplate()
oliver@87
   248
oliver@87
   249
mb@63
   250
class os_vm:
mb@63
   251
    """OpenSecurity '/vms/[VM]' handler
mb@63
   252
    
mb@63
   253
    - GET: list information of arbitrary VM.
mb@63
   254
    """
mb@63
   255
    
mb@63
   256
    def GET(self, name):
oliver@74
   257
        log_call(web.ctx.environ)
oliver@87
   258
        global gvm_mgr
oliver@87
   259
        return gvm_mgr.getVMInfo(name)
mb@63
   260
            
mb@63
   261
mb@63
   262
class os_vms:
mb@63
   263
    """OpenSecurity '/vms' handler
mb@63
   264
    
mb@63
   265
    - GET: list all (also non Security) VMs.
mb@63
   266
    """
mb@63
   267
    
mb@63
   268
    def GET(self):
oliver@74
   269
        log_call(web.ctx.environ)
oliver@87
   270
        global gvm_mgr
oliver@87
   271
        return gvm_mgr.listVM() 
mb@63
   272
            
mb@63
   273
oliver@74
   274
def log_call(web_environ):
oliver@74
   275
    """log the incoming call to the REST api"""
oliver@74
   276
    try:
oliver@74
   277
        call = 'REST ' +  web_environ['REQUEST_METHOD'] + ' ' + web_environ['REQUEST_URI'] + ' from ' + web_environ['REMOTE_ADDR'] + ':' + web_environ['REMOTE_PORT']
oliver@74
   278
        logger.debug(call)
oliver@74
   279
    except:
oliver@74
   280
        pass
oliver@74
   281
oliver@86
   282
oliver@86
   283
def main():
oliver@86
   284
    """main startup for the opensecuirityd"""
oliver@87
   285
oliver@87
   286
    logger.debug('Starting OpenSecurity REST server')
oliver@87
   287
oliver@87
   288
    # ensure a VMManger is yet loaded
oliver@87
   289
    global gvm_mgr
oliver@87
   290
    gvm_mgr = vmmanager.VMManager.getInstance()
oliver@87
   291
    
oliver@87
   292
    server = web.application(opensecurity_urls, globals(), autoreload = False)
mb@63
   293
    server.run()
oliver@87
   294
    
oliver@87
   295
    logger.debug('Stopped OpenSecurity REST server')
oliver@86
   296
oliver@86
   297
oliver@88
   298
def stop():
oliver@88
   299
    """stop the opensecuirityd"""
oliver@88
   300
oliver@88
   301
    # calling sys.exit() raises a SystemExit exception
oliver@88
   302
    # of the WSGI Server to let it wind down
oliver@89
   303
    # gracefully
oliver@88
   304
    sys.exit(0)
oliver@88
   305
oliver@88
   306
oliver@88
   307
oliver@86
   308
# start
oliver@86
   309
if __name__ == "__main__":
oliver@86
   310
    main()
oliver@86
   311