merge
authormb
Tue, 18 Mar 2014 16:31:47 +0100
changeset 96630b62946c9e
parent 95 cdebb7e0ba10
parent 94 fa16c1c12393
child 97 f274426bdbb4
merge
OpenSecurity/bin/cygwin.py
OpenSecurity/bin/opensecurity_tray.pyw
OpenSecurity/bin/vmmanager.pyw
     1.1 --- a/.hgignore	Tue Mar 18 16:28:15 2014 +0100
     1.2 +++ b/.hgignore	Tue Mar 18 16:31:47 2014 +0100
     1.3 @@ -24,6 +24,7 @@
     1.4  OpenSecurity/python27/DLLs
     1.5  OpenSecurity/python27/Lib
     1.6  OpenSecurity/python27/libs
     1.7 +OpenSecurity/python27/Scripts
     1.8  OpenSecurity/python27/python.exe
     1.9  OpenSecurity/python27/python27.dll
    1.10  OpenSecurity/python27/pythoncom27.dll
     2.1 --- a/OpenSecurity.iss	Tue Mar 18 16:28:15 2014 +0100
     2.2 +++ b/OpenSecurity.iss	Tue Mar 18 16:31:47 2014 +0100
     2.3 @@ -8,12 +8,12 @@
     2.4  AppContact=AIT Austrian Institute of Technology
     2.5  AppPublisher=AIT Austrian Institute of Technology
     2.6  AppPublisherURL=http://www.ait.ac.at/
     2.7 -AppVersion=0.2
     2.8 +AppVersion=0.2.2
     2.9  ArchitecturesInstallIn64BitMode=x64
    2.10  DefaultDirName={pf}\OpenSecurity
    2.11  DefaultGroupName=OpenSecurity
    2.12  OutputDir="."
    2.13 -OutputBaseFilename="OpenSecurity Setup V0.2"
    2.14 +OutputBaseFilename="OpenSecurity Setup V0.2.2"
    2.15  OutputManifestFile=OpenSecurity-Setup-Manifest.txt
    2.16  SetupIconFile=OpenSecurity\gfx\OpenSecurity.ico
    2.17  SolidCompression=yes
    2.18 @@ -28,8 +28,8 @@
    2.19  Source: "OpenSecurity\python27\*"; DestDir: "{app}\python27"; Flags: recursesubdirs createallsubdirs;
    2.20  
    2.21  [Dirs]
    2.22 -Name: "{app}\log"; 
    2.23 -Name: "{app}\vm";
    2.24 +Name: "{app}\cygwin64\var\log\xwin"; Permissions: everyone-modify
    2.25 +Name: "{app}\log"; Permissions: everyone-modify
    2.26  
    2.27  [Registry]
    2.28  ; Registry entries to set
    2.29 @@ -37,23 +37,24 @@
    2.30  
    2.31  [Icons]
    2.32  ; Program Icons in start menu
    2.33 -Name: "{group}\OpenSecurity Initial VM"; Filename: "{app}\python27\pythonw.exe"; Parameters: """{app}\bin\download-image.pyw"""; WorkingDir: "{app}"; Comment: "Download and install the initial OpenSecurity VM image"; IconFilename: "{app}\gfx\OpenSecurity.ico"
    2.34  Name: "{group}\OpenSecurity Tray Icon"; Filename: "{app}\python27\pythonw.exe"; Parameters: """{app}\bin\opensecurity_tray.pyw"""; WorkingDir: "{userappdata}"; Comment: "The OpenSecurity Tray Icon"; IconFilename: "{app}\gfx\OpenSecurity.ico"
    2.35 -Name: "{group}\Initial VM import"; Filename: "{app}\cygwin64\bin\bash.exe"; Parameters: "-i -l /OpenSecurity/install/initial_vm.sh"; WorkingDir: "{app}"; Comment: "Import the initial OpenSecurity VM"; IconFilename: "{app}\gfx\OpenSecurity.ico"
    2.36  Name: "{group}\Uninstall OpenSecurity"; Filename: "{uninstallexe}"
    2.37  
    2.38  [Run]
    2.39  ; Run after installment
    2.40  Filename: "{app}\cygwin64\bin\dash.exe"; Parameters: "/bin/rebaseall"; Description: "Rebasing background system"; WorkingDir: "{app}"; StatusMsg: "Rebasing background system..."; Flags: runascurrentuser
    2.41 -Filename: "{app}\install\fix_cygwin_paths.bat"; Description: "Fixing Cygwin paths"; WorkingDir: "{app}\install"; StatusMsg: "Fixing Cygwin Paths..";
    2.42 +Filename: "{app}\install\fix_cygwin_paths.bat"; Description: "Fixing Cygwin paths"; WorkingDir: "{app}\install"; StatusMsg: "Fixing Cygwin Paths...";
    2.43 +Filename: "{app}\cygwin64\bin\bash.exe"; Parameters: "-l -i -c echo -n"; Description: "Enforcing login environment for shells"; WorkingDir: "{app}"; StatusMsg: "Enforcing login environment for shells...";
    2.44 +Filename: "{app}\python27\pythonw.exe"; Parameters: """{app}python27\Scripts\pywin32_postinstall.py"" --install"; Description: "Registering Python Win32 Extensions"; WorkingDir: "{app}"; StatusMsg: "Registering Python Win32 Extensions"; Flags: runascurrentuser
    2.45  Filename: "{app}\python27\pythonw.exe"; Parameters: """{app}\bin\opensecurity_service.pyw"" --startup auto install"; Description: "Installing the OpenSecurity Service"; WorkingDir: "{app}"; StatusMsg: "Installing the OpenSecurity Service"; Flags: runascurrentuser
    2.46 -Filename: "{app}\python27\pythonw.exe"; Parameters: """{app}\bin\download-image.pyw"""; WorkingDir: "{app}"; Description: "Download and install the initial OpenSecurity VM image"; Flags: postinstall runascurrentuser
    2.47 -Filename: "{app}\cygwin64\bin\bash.exe"; Parameters: "-i -l /OpenSecurity/install/initial_vm.sh"; WorkingDir: "{app}"; Description: "Import the initial OpenSecurity VM"; Flags: postinstall runascurrentuser
    2.48 -                
    2.49 +Filename: "{app}\python27\pythonw.exe"; Parameters: """{app}\bin\opensecurity_service.pyw"" start"; Description: "Starting OpenSecurity Service"; WorkingDir: "{app}"; StatusMsg: "Starting OpenSecurity Service"; Flags: runascurrentuser
    2.50 +Filename: "{app}\python27\pythonw.exe"; Parameters: """{app}\bin\opensecurity_tray.pyw"""; WorkingDir: "{userappdata}"; Description: "Launching OpenSecurity Tray Icon"; Flags: nowait
    2.51 +
    2.52  [UninstallRun]
    2.53  ; When uninstalling run this command prior
    2.54  Filename: "{app}\python27\pythonw.exe"; Parameters: """{app}\bin\opensecurity_service.pyw"" stop"; WorkingDir: "{app}"; StatusMsg: "Stopping the OpenSecurity Service"; Flags: runascurrentuser
    2.55  Filename: "{app}\python27\pythonw.exe"; Parameters: """{app}\bin\opensecurity_service.pyw"" remove"; WorkingDir: "{app}"; StatusMsg: "Removing the OpenSecurity Service"; Flags: runascurrentuser
    2.56 +Filename: "{app}\python27\pythonw.exe"; Parameters: """{app}python27\Scripts\pywin32_postinstall.py"" --uninstall"; WorkingDir: "{app}"; StatusMsg: "Unregistering Python Win32 Extensions"; Flags: runascurrentuser
    2.57  
    2.58  [UninstallDelete]
    2.59  Type: filesandordirs; Name: "{app}"
     3.1 --- a/OpenSecurity/bin/about.py	Tue Mar 18 16:28:15 2014 +0100
     3.2 +++ b/OpenSecurity/bin/about.py	Tue Mar 18 16:31:47 2014 +0100
     3.3 @@ -111,7 +111,7 @@
     3.4          super(About, self).__init__(parent, flags)
     3.5          
     3.6          # setup image search path
     3.7 -        QtCore.QDir.setSearchPaths("image", QtCore.QStringList(os.path.join(Environment('opensecurity').data_path, '..', 'gfx')));
     3.8 +        QtCore.QDir.setSearchPaths("image", QtCore.QStringList(os.path.join(Environment('opensecurity').data_path, 'gfx')));
     3.9          
    3.10          self.setWindowTitle('About OpenSecurity ...')
    3.11          self.setup_ui()
     4.1 --- a/OpenSecurity/bin/cygwin.py	Tue Mar 18 16:28:15 2014 +0100
     4.2 +++ b/OpenSecurity/bin/cygwin.py	Tue Mar 18 16:31:47 2014 +0100
     4.3 @@ -1,226 +1,235 @@
     4.4 -#!/bin/env python
     4.5 -# -*- coding: utf-8 -*-
     4.6 -
     4.7 -# ------------------------------------------------------------
     4.8 -# cygwin command
     4.9 -# 
    4.10 -# executes a cygwin command inside the opensecurity project
    4.11 -#
    4.12 -# Autor: Mihai Bartha, <mihai.bartha@ait.ac.at>
    4.13 -#        Oliver Maurhart, <oliver.maurhart@ait.ac.at>
    4.14 -#
    4.15 -# Copyright (C) 2013 AIT Austrian Institute of Technology
    4.16 -# AIT Austrian Institute of Technology GmbH
    4.17 -# Donau-City-Strasse 1 | 1220 Vienna | Austria
    4.18 -# http://www.ait.ac.at
    4.19 -#
    4.20 -# This program is free software; you can redistribute it and/or
    4.21 -# modify it under the terms of the GNU General Public License
    4.22 -# as published by the Free Software Foundation version 2.
    4.23 -# 
    4.24 -# This program is distributed in the hope that it will be useful,
    4.25 -# but WITHOUT ANY WARRANTY; without even the implied warranty of
    4.26 -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    4.27 -# GNU General Public License for more details.
    4.28 -# 
    4.29 -# You should have received a copy of the GNU General Public License
    4.30 -# along with this program; if not, write to the Free Software
    4.31 -# Foundation, Inc., 51 Franklin Street, Fifth Floor, 
    4.32 -# Boston, MA  02110-1301, USA.
    4.33 -# ------------------------------------------------------------
    4.34 -
    4.35 -
    4.36 -# ------------------------------------------------------------
    4.37 -# imports
    4.38 -
    4.39 -import os
    4.40 -import subprocess
    4.41 -import sys
    4.42 -import _winreg
    4.43 -from subprocess import Popen, PIPE, call, STARTUPINFO, _subprocess
    4.44 -import threading
    4.45 -# local
    4.46 -from environment import Environment
    4.47 -from opensecurity_util import logger, setupLogger, OpenSecurityException
    4.48 -
    4.49 -# ------------------------------------------------------------
    4.50 -# code
    4.51 -
    4.52 -def once(theClass):
    4.53 -    """get the path to our local cygwin installment"""
    4.54 -    home_drive = os.path.expandvars("%HOMEDRIVE%") + os.sep
    4.55 -    path_hint = [ 
    4.56 -        os.path.abspath(os.path.join(Environment('OpenSecurity').prefix_path, '..', 'cygwin')), 
    4.57 -        os.path.abspath(os.path.join(Environment('OpenSecurity').prefix_path, '..', 'cygwin64')), 
    4.58 -        os.path.abspath(os.path.join(home_drive, 'cygwin')),
    4.59 -        os.path.abspath(os.path.join(home_drive, 'cygwin64'))
    4.60 -    ]
    4.61 -    path_valid = [ p for p in path_hint if os.path.exists(p) ]
    4.62 -        
    4.63 -    theClass.cygwin_root = path_valid[0]
    4.64 -    theClass.cygwin_bin = os.path.join(theClass.cygwin_root, 'bin') + os.path.sep
    4.65 -    theClass.cygwin_bash = os.path.join(theClass.cygwin_bin, 'bash.exe')
    4.66 -    theClass.cygwin_ssh = os.path.join(theClass.cygwin_bin, 'ssh.exe')
    4.67 -    theClass.cygwin_x11 = os.path.join(theClass.cygwin_bin, 'XWin.exe')
    4.68 -    theClass.win_cmd = os.environ.get("COMSPEC", "cmd.exe") 
    4.69 -    """get the path to the VirtualBox installation on this system"""
    4.70 -    theClass.vbox_root = theClass.getRegEntry('SOFTWARE\Oracle\VirtualBox', 'InstallDir')[0]
    4.71 -    theClass.vbox_man = os.path.join(theClass.vbox_root, 'VBoxManage.exe')
    4.72 -    
    4.73 -    return theClass
    4.74 -
    4.75 -@once
    4.76 -class Cygwin(object):
    4.77 -    cygwin_root = ''
    4.78 -    cygwin_bin = ''
    4.79 -    cygwin_bash = ''
    4.80 -    cygwin_ssh = ''
    4.81 -    cygwin_x11 = ''
    4.82 -    vbox_root = ''
    4.83 -    vbox_man = ''
    4.84 -    win_cmd = ''
    4.85 -    """Some nifty methods working with Cygwin"""
    4.86 -    
    4.87 -    def __call__(self, command, arguments, wait_return=True, window = False):
    4.88 -        """make an instance of this object act as a function"""
    4.89 -        return self.execute(command, arguments, wait_return, window)
    4.90 -
    4.91 -    @staticmethod
    4.92 -    def getRegEntry(key, value):
    4.93 -        try:
    4.94 -            k = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, key)
    4.95 -            value = _winreg.QueryValueEx(k, value)
    4.96 -            _winreg.CloseKey(k)
    4.97 -            return value
    4.98 -        except:
    4.99 -            pass
   4.100 -            
   4.101 -    @staticmethod
   4.102 -    def root():
   4.103 -        return Cygwin.cygwin_root
   4.104 -
   4.105 -    @staticmethod
   4.106 -    def bin():
   4.107 -        return Cygwin.cygwin_bin
   4.108 -    
   4.109 -    @staticmethod
   4.110 -    def bash():
   4.111 -        return Cygwin.cygwin_bash
   4.112 -    
   4.113 -    @staticmethod    
   4.114 -    def ssh():
   4.115 -        return Cygwin.cygwin_ssh
   4.116 -
   4.117 -    @staticmethod    
   4.118 -    def x11():
   4.119 -        return Cygwin.cygwin_x11
   4.120 -    
   4.121 -    @staticmethod
   4.122 -    def vboxman():
   4.123 -        return Cygwin.vbox_man
   4.124 -    
   4.125 -    @staticmethod
   4.126 -    def cmd():
   4.127 -        return Cygwin.win_cmd
   4.128 -    
   4.129 -    executeLock = threading.Lock()
   4.130 -    #executes command on host system
   4.131 -    @staticmethod
   4.132 -    def execute(program, arguments, wait_return=True, window = False):
   4.133 -        _startupinfo = STARTUPINFO()
   4.134 -        if not window:
   4.135 -            _startupinfo.dwFlags |= _subprocess.STARTF_USESHOWWINDOW
   4.136 -            _startupinfo.wShowWindow = _subprocess.SW_HIDE
   4.137 -
   4.138 -            #logger.debug('trying to launch: ' + program + ' ' + ''.join(arguments))
   4.139 -        res_stderr = None
   4.140 -        try:
   4.141 -            process = Popen(executable=program, args=' ' + arguments, startupinfo = _startupinfo, stdin=PIPE, stdout=PIPE, stderr=PIPE, shell = False)
   4.142 -            logger.debug('Launched: ' + program + ' ' + ''.join(arguments))
   4.143 -            if not wait_return:
   4.144 -                return [0, 'working in background', '']
   4.145 -            result = process.wait()
   4.146 -            res_stdout = process.stdout.read();
   4.147 -            res_stderr = process.stderr.read();
   4.148 -
   4.149 -        except Exception as ex:
   4.150 -            res_stderr.join(ex.args)
   4.151 -            result = 1 
   4.152 -            
   4.153 -        return result, res_stdout, res_stderr
   4.154 -    
   4.155 -    @staticmethod
   4.156 -    def vboxExecute(command, wait_return=True, window = False, bash_opts=''):
   4.157 -        retry = 0
   4.158 -        result = None
   4.159 -        while retry < 3:
   4.160 -            if Cygwin.executeLock.acquire(True):
   4.161 -                result = Cygwin.execute(Cygwin.vbox_man, command, wait_return, window)
   4.162 -                Cygwin.executeLock.release()
   4.163 -                if result[0] == 0:
   4.164 -                    return result
   4.165 -                retry+=1
   4.166 -        return result
   4.167 -        
   4.168 -    
   4.169 -    @staticmethod
   4.170 -    def bashExecute(command, wait_return=True, window = False, bash_opts=''):
   4.171 -        command = bash_opts + ' -l -c '  + command
   4.172 -        return Cygwin.execute(Cygwin.cygwin_bash, command, wait_return, window)
   4.173 -    
   4.174 -    @staticmethod
   4.175 -    def cmdExecute(command, wait_return=True, window = False, bash_opts=''):
   4.176 -        command = ' /c ' + command 
   4.177 -        return Cygwin.execute(Cygwin.win_cmd, command, wait_return, window)
   4.178 -
   4.179 -    # executes command over ssh on guest vm
   4.180 -    @staticmethod
   4.181 -    def sshExecute(command, address, user_name, certificate, wait_return=True, window = False):
   4.182 -        command = ' -v -i "' + certificate + '" ' + user_name + '@' + address + ' ' + command        
   4.183 -        return Cygwin.execute(Cygwin.cygwin_ssh, command, wait_return, window)     
   4.184 -    
   4.185 -    #machineFolder + '/' + vm_name + '/dvm_key
   4.186 -    #address = self.getHostOnlyIP(vm_name)
   4.187 -    #machineFolder = self.getDefaultMachineFolder()
   4.188 -    #machineFolder = Cygwin.cygwinPath(machineFolder)
   4.189 -    
   4.190 -    # executes command over ssh on guest vm with X forwarding
   4.191 -    @staticmethod
   4.192 -    def sshExecuteX11(command, address, user_name, certificate, wait_return=True):
   4.193 -        return Cygwin.bashExecute('"DISPLAY=:0.0 /usr/bin/ssh -v -Y -i \\"' + certificate +'\\" ' + user_name + '@' + address + ' ' + command + '\"')
   4.194 -
   4.195 -    @staticmethod
   4.196 -    def is_X11_running():
   4.197 -        """check if we can connect to a X11 running instance"""
   4.198 -        p = Cygwin.bashExecute('"DISPLAY=:0 /usr/bin/xset -q"')
   4.199 -        return p[0] == 0
   4.200 -        
   4.201 -        
   4.202 -    @staticmethod
   4.203 -    def start_X11():
   4.204 -        """start X11 in the background (if not already running) on DISPLAY=:0"""
   4.205 -        # do not start if already running
   4.206 -        if Cygwin.is_X11_running():
   4.207 -            return           
   4.208 -        # launch X11 (forget output and return immediately)
   4.209 -        return Cygwin.execute(Cygwin.cygwin_x11, ':0 -multiwindow', wait_return = False, window = False)
   4.210 -        #return 0, None, None
   4.211 -    
   4.212 -    @staticmethod    
   4.213 -    def cygPath(path):
   4.214 -        return Cygwin.bashExecute('"/usr/bin/cygpath -u \\"' + path + '\\""')[1].rstrip('\n')
   4.215 -    
   4.216 -# start
   4.217 -if __name__ == "__main__":
   4.218 -    logger = setupLogger('Cygwin')
   4.219 -    c = Cygwin()
   4.220 -    logger.info(c.root())
   4.221 -    logger.info(c.bin())
   4.222 -    logger.info(c.bash())
   4.223 -    logger.info(c.ssh())
   4.224 -    
   4.225 -    c.cygPath('C:')
   4.226 +#!/bin/env python
   4.227 +# -*- coding: utf-8 -*-
   4.228 +
   4.229 +# ------------------------------------------------------------
   4.230 +# cygwin command
   4.231 +# 
   4.232 +# executes a cygwin command inside the opensecurity project
   4.233 +#
   4.234 +# Autor: Mihai Bartha, <mihai.bartha@ait.ac.at>
   4.235 +#        Oliver Maurhart, <oliver.maurhart@ait.ac.at>
   4.236 +#
   4.237 +# Copyright (C) 2013 AIT Austrian Institute of Technology
   4.238 +# AIT Austrian Institute of Technology GmbH
   4.239 +# Donau-City-Strasse 1 | 1220 Vienna | Austria
   4.240 +# http://www.ait.ac.at
   4.241 +#
   4.242 +# This program is free software; you can redistribute it and/or
   4.243 +# modify it under the terms of the GNU General Public License
   4.244 +# as published by the Free Software Foundation version 2.
   4.245 +# 
   4.246 +# This program is distributed in the hope that it will be useful,
   4.247 +# but WITHOUT ANY WARRANTY; without even the implied warranty of
   4.248 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   4.249 +# GNU General Public License for more details.
   4.250 +# 
   4.251 +# You should have received a copy of the GNU General Public License
   4.252 +# along with this program; if not, write to the Free Software
   4.253 +# Foundation, Inc., 51 Franklin Street, Fifth Floor, 
   4.254 +# Boston, MA  02110-1301, USA.
   4.255 +# ------------------------------------------------------------
   4.256 +
   4.257 +
   4.258 +# ------------------------------------------------------------
   4.259 +# imports
   4.260 +
   4.261 +import os
   4.262 +import subprocess
   4.263 +import sys
   4.264 +import _winreg
   4.265 +from subprocess import Popen, PIPE, call, STARTUPINFO, _subprocess
   4.266 +import threading
   4.267 +# local
   4.268 +from environment import Environment
   4.269 +from opensecurity_util import logger, setupLogger, OpenSecurityException
   4.270 +
   4.271 +# ------------------------------------------------------------
   4.272 +# code
   4.273 +
   4.274 +def once(theClass):
   4.275 +    """get the path to our local cygwin installment"""
   4.276 +    home_drive = os.path.expandvars("%HOMEDRIVE%") + os.sep
   4.277 +    path_hint = [ 
   4.278 +        os.path.abspath(os.path.join(Environment('OpenSecurity').prefix_path, 'cygwin')), 
   4.279 +        os.path.abspath(os.path.join(Environment('OpenSecurity').prefix_path, 'cygwin64')), 
   4.280 +        os.path.abspath(os.path.join(home_drive, 'cygwin')),
   4.281 +        os.path.abspath(os.path.join(home_drive, 'cygwin64'))
   4.282 +    ]
   4.283 +    path_valid = [ p for p in path_hint if os.path.exists(p) ]
   4.284 +        
   4.285 +    theClass.cygwin_root = path_valid[0]
   4.286 +    theClass.cygwin_bin = os.path.join(theClass.cygwin_root, 'bin') + os.path.sep
   4.287 +    theClass.cygwin_bash = os.path.join(theClass.cygwin_bin, 'bash.exe')
   4.288 +    theClass.cygwin_ssh = os.path.join(theClass.cygwin_bin, 'ssh.exe')
   4.289 +    theClass.cygwin_x11 = os.path.join(theClass.cygwin_bin, 'XWin.exe')
   4.290 +    theClass.win_cmd = os.environ.get("COMSPEC", "cmd.exe") 
   4.291 +    """get the path to the VirtualBox installation on this system"""
   4.292 +    theClass.vbox_root = theClass.getRegEntry('SOFTWARE\Oracle\VirtualBox', 'InstallDir')[0]  
   4.293 +    theClass.vbox_man = os.path.join(theClass.vbox_root, 'VBoxManage.exe')
   4.294 +    
   4.295 +    return theClass
   4.296 +
   4.297 +@once
   4.298 +class Cygwin(object):
   4.299 +    cygwin_root = ''
   4.300 +    cygwin_bin = ''
   4.301 +    cygwin_bash = ''
   4.302 +    cygwin_ssh = ''
   4.303 +    cygwin_x11 = ''
   4.304 +    vbox_root = ''
   4.305 +    vbox_man = ''
   4.306 +    win_cmd = ''
   4.307 +    """Some nifty methods working with Cygwin"""
   4.308 +    
   4.309 +    def __call__(self, command, arguments, wait_return=True, window = False):
   4.310 +        """make an instance of this object act as a function"""
   4.311 +        return self.execute(command, arguments, wait_return, window)
   4.312 +
   4.313 +    @staticmethod
   4.314 +    def getRegEntry(key, value):
   4.315 +        try:
   4.316 +            k = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, key)
   4.317 +            value = _winreg.QueryValueEx(k, value)
   4.318 +            _winreg.CloseKey(k)
   4.319 +            return value
   4.320 +        except:
   4.321 +            pass
   4.322 +    
   4.323 +            
   4.324 +    @staticmethod
   4.325 +    def root():
   4.326 +        return Cygwin.cygwin_root
   4.327 +
   4.328 +    @staticmethod
   4.329 +    def bin():
   4.330 +        return Cygwin.cygwin_bin
   4.331 +    
   4.332 +    @staticmethod
   4.333 +    def bash():
   4.334 +        return Cygwin.cygwin_bash
   4.335 +    
   4.336 +    @staticmethod    
   4.337 +    def ssh():
   4.338 +        return Cygwin.cygwin_ssh
   4.339 +
   4.340 +    @staticmethod    
   4.341 +    def x11():
   4.342 +        return Cygwin.cygwin_x11
   4.343 +    
   4.344 +    @staticmethod
   4.345 +    def vboxman():
   4.346 +        return Cygwin.vbox_man
   4.347 +    
   4.348 +    @staticmethod
   4.349 +    def cmd():
   4.350 +        return Cygwin.win_cmd
   4.351 +    
   4.352 +    executeLock = threading.Lock()
   4.353 +    #executes command on host system
   4.354 +    @staticmethod
   4.355 +    def execute(program, arguments, wait_return=True, window = False, stdin = PIPE, stdout = PIPE, stderr = PIPE):
   4.356 +        _startupinfo = STARTUPINFO()
   4.357 +        if not window:
   4.358 +            _startupinfo.dwFlags |= _subprocess.STARTF_USESHOWWINDOW
   4.359 +            _startupinfo.wShowWindow = _subprocess.SW_HIDE
   4.360 +
   4.361 +            #logger.debug('trying to launch: ' + program + ' ' + ''.join(arguments))
   4.362 +        res_stderr = None
   4.363 +        try:
   4.364 +            # quote the executable otherwise we run into troubles
   4.365 +            # when the path contains spaces and additonal arguments
   4.366 +            # are presented as well.
   4.367 +            # special: invoking bash as login shell here with
   4.368 +            # an unquoted command does not execute /etc/profile
   4.369 +            args = '"' + program + '" ' + arguments
   4.370 +            process = Popen(args, startupinfo = _startupinfo, stdin = stdin, stdout = stdout, stderr = stderr, shell = False)
   4.371 +            logger.debug('Launched: ' + program + ' ' + ''.join(arguments))
   4.372 +            if not wait_return:
   4.373 +                return [0, 'working in background', '']
   4.374 +            result = process.wait()
   4.375 +            res_stdout = process.stdout.read();
   4.376 +            res_stderr = process.stderr.read();
   4.377 +
   4.378 +        except Exception as ex:
   4.379 +            res_stderr = ''.join(str(ex.args))
   4.380 +            result = 1 
   4.381 +            
   4.382 +        return result, res_stdout, res_stderr
   4.383 +    
   4.384 +    @staticmethod
   4.385 +    def vboxExecute(command, wait_return=True, window = False, bash_opts=''):
   4.386 +        retry = 0
   4.387 +        result = None
   4.388 +        while retry < 3:
   4.389 +            if Cygwin.executeLock.acquire(True):
   4.390 +                result = Cygwin.execute(Cygwin.vbox_man, command, wait_return, window)
   4.391 +                Cygwin.executeLock.release()
   4.392 +                if result[0] == 0:
   4.393 +                    return result
   4.394 +                retry+=1
   4.395 +        return result
   4.396 +
   4.397 +
   4.398 +    @staticmethod
   4.399 +    def bashExecute(command, wait_return=True, window = False, bash_opts='', stdin = PIPE, stdout = PIPE, stderr = PIPE):
   4.400 +        # for some reason, the '-l' is ignored when started via python
   4.401 +        # so the same behavior is triggered by calling /etc/profile 
   4.402 +        # directly
   4.403 +        command = bash_opts + ' -l -c "'  + command + '"'
   4.404 +        return Cygwin.execute(Cygwin.cygwin_bash, command, wait_return, window, stdin = stdin, stdout = stdout, stderr = stderr)
   4.405 +    
   4.406 +    @staticmethod
   4.407 +    def cmdExecute(command, wait_return=True, window = False, bash_opts=''):
   4.408 +        command = ' /c ' + command 
   4.409 +        return Cygwin.execute(Cygwin.win_cmd, command, wait_return, window)
   4.410 +
   4.411 +    # executes command over ssh on guest vm
   4.412 +    @staticmethod
   4.413 +    def sshExecute(command, address, user_name, certificate, wait_return=True, window = False):
   4.414 +        command = ' -v -i "' + certificate + '" ' + user_name + '@' + address + ' ' + command        
   4.415 +        return Cygwin.execute(Cygwin.cygwin_ssh, command, wait_return, window)     
   4.416 +    
   4.417 +    #machineFolder + '/' + vm_name + '/dvm_key
   4.418 +    #address = self.getHostOnlyIP(vm_name)
   4.419 +    #machineFolder = self.getDefaultMachineFolder()
   4.420 +    #machineFolder = Cygwin.cygwinPath(machineFolder)
   4.421 +    
   4.422 +    # executes command over ssh on guest vm with X forwarding
   4.423 +    @staticmethod
   4.424 +    def sshExecuteX11(command, address, user_name, certificate, wait_return=True):
   4.425 +        return Cygwin.bashExecute('"DISPLAY=:0.0 /usr/bin/ssh -v -Y -i \\"' + certificate +'\\" ' + user_name + '@' + address + ' ' + command + '\"')
   4.426 +
   4.427 +    @staticmethod
   4.428 +    def is_X11_running():
   4.429 +        """check if we can connect to a X11 running instance"""
   4.430 +        p = Cygwin.bashExecute('DISPLAY=:0 /usr/bin/xset -q')
   4.431 +        return p[0] == 0
   4.432 +        
   4.433 +        
   4.434 +    @staticmethod
   4.435 +    def start_X11():
   4.436 +        """start X11 in the background (if not already running) on DISPLAY=:0"""
   4.437 +        # do not start if already running
   4.438 +        if Cygwin.is_X11_running():
   4.439 +            return           
   4.440 +        # launch X11 (forget output and return immediately)
   4.441 +        return Cygwin.execute(Cygwin.cygwin_x11, ':0 -multiwindow', wait_return = False, window = False)
   4.442 +    
   4.443 +    @staticmethod    
   4.444 +    def cygPath(path):
   4.445 +        cmd = 'cygpath -u \'' + path + '\''
   4.446 +        return Cygwin.bashExecute(cmd)[1].rstrip('\n')
   4.447 +    
   4.448 +# start
   4.449 +if __name__ == "__main__":
   4.450 +    logger = setupLogger('Cygwin')
   4.451 +    c = Cygwin()
   4.452 +    logger.info(c.root())
   4.453 +    logger.info(c.bin())
   4.454 +    logger.info(c.bash())
   4.455 +    logger.info(c.ssh())
   4.456 +    
   4.457 +    print(c.bashExecute('echo $PATH')[1])
   4.458 +    print(c.cygPath('C:'))
   4.459 +    print('C:\\Program Files\\OpenSecurity: ' + c.cygPath('C:\\Program Files\\OpenSecurity'))
   4.460      c.start_X11()
   4.461 -    logger.info('X11 started')
   4.462 -    logger.info("X11 running: " + str(c.is_X11_running()))
   4.463 -    
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/OpenSecurity/bin/download_initial_image.sh	Tue Mar 18 16:31:47 2014 +0100
     5.3 @@ -0,0 +1,47 @@
     5.4 +#!/bin/bash
     5.5 +
     5.6 +# ------------------------------------------------------------
     5.7 +# download initial VM for
     5.8 +#
     5.9 +#       OpenSecurity V0.2
    5.10 +#
    5.11 +# (C)opyright 2014, AIT Austrian Instiitute of Technology
    5.12 +# ------------------------------------------------------------
    5.13 +
    5.14 +# ------------------------------------------------------------
    5.15 +# code
    5.16 +
    5.17 +
    5.18 +# download the ionitial OsecVM.ova from the X-Net servers
    5.19 +# and place the file in the folder specified by ${1}
    5.20 +
    5.21 +
    5.22 +# ------------------------------
    5.23 +# main ...
    5.24 +#
    5.25 +
    5.26 +# check if we do have elevated rights
    5.27 +# that is "Run as Administrator" invocation
    5.28 +id -G | grep 544 &> /dev/null
    5.29 +if [ "${?}" != 0 ]; then
    5.30 +    echo "Insufficient privileges."
    5.31 +    echo "Is this script executed with 'Run As Administrator'?"
    5.32 +    exit 1
    5.33 +fi
    5.34 +
    5.35 +TARGET_FOLDER="${1}"
    5.36 +echo "fetching OpenSecurity initial VM at " $(date)
    5.37 +echo "target folder: ${TARGET_FOLDER}"
    5.38 +
    5.39 +# sanity check
    5.40 +mkdir -p "${TARGET_FOLDER}" 
    5.41 +if [ ! -d "${TARGET_FOLDER}" ]; then
    5.42 +    echo "failed to access target folder."
    5.43 +    exit 1
    5.44 +fi
    5.45 +
    5.46 +# start download
    5.47 +URL="http://service.x-net.at/opensecurity/OsecVM_latest.ova"
    5.48 +wget --progress=dot:mega ${URL} -O "${TARGET_FOLDER}"/OsecVM.ova
    5.49 +
    5.50 +
     6.1 --- a/OpenSecurity/bin/environment.py	Tue Mar 18 16:28:15 2014 +0100
     6.2 +++ b/OpenSecurity/bin/environment.py	Tue Mar 18 16:31:47 2014 +0100
     6.3 @@ -64,7 +64,7 @@
     6.4          if sys.platform == 'linux2':
     6.5              self._prefix_path = os.path.split(sys.path[0])[0]
     6.6          elif sys.platform == 'win32' or sys.platform == 'cygwin':
     6.7 -            self._prefix_path = sys.path[0]
     6.8 +            self._prefix_path = os.path.normpath(os.path.join(sys.path[0], '..'))
     6.9              
    6.10          # the data path where all data files are stored
    6.11          if sys.platform == 'linux2':
    6.12 @@ -118,7 +118,7 @@
    6.13              # somewhere like C:\Program Files\OpenSecurity\log
    6.14              # having this script residing in 
    6.15              # C:\Progam Files\OpenSecurity\bin
    6.16 -            ideal_log_path = os.path.normpath(os.path.join(self.prefix_path, '..', 'log'))
    6.17 +            ideal_log_path = os.path.normpath(os.path.join(self.prefix_path, 'log'))
    6.18  
    6.19              # check ideal path first
    6.20              if not os.path.exists(ideal_log_path):
    6.21 @@ -147,3 +147,4 @@
    6.22  # test the module			
    6.23  if __name__ == '__main__':
    6.24      test()
    6.25 +
     7.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.2 +++ b/OpenSecurity/bin/initial_vm.sh	Tue Mar 18 16:31:47 2014 +0100
     7.3 @@ -0,0 +1,165 @@
     7.4 +#!/bin/bash
     7.5 +
     7.6 +# ------------------------------------------------------------
     7.7 +# install the initial VM for 
     7.8 +#
     7.9 +#       OpenSecurity V0.2
    7.10 +#
    7.11 +# This has been originally a Windows only BAT file.
    7.12 +#
    7.13 +# ... but coding this makes your head hurt and
    7.14 +# supporting this "technology" any further by adding
    7.15 +# software to the world relying on CMD.exe is an act
    7.16 +# against humanity and should be punished by jail.
    7.17 +#
    7.18 +# (C)opyright 2014, AIT Austrian Instiitute of Technology
    7.19 +# ------------------------------------------------------------
    7.20 +
    7.21 +
    7.22 +# ------------------------------------------------------------
    7.23 +# code
    7.24 +
    7.25 +# install the initial VM given by ${1}
    7.26 +
    7.27 +
    7.28 +# ------------------------------
    7.29 +# turns a windows path into a cygwin path
    7.30 +#
    7.31 +#   $1  ...     windows path
    7.32 +#   stdout      the value found
    7.33 +#
    7.34 +function sanitize_path() {
    7.35 +    test -z "${1}" && return
    7.36 +    echo $(cygpath -u "${1}") 
    7.37 +}
    7.38 +
    7.39 +
    7.40 +# ------------------------------
    7.41 +# main ...
    7.42 +#
    7.43 +
    7.44 +# check if we do have elevated rights
    7.45 +# that is "Run as Administrator" invocation
    7.46 +echo 'checking privileges...'
    7.47 +id -G | grep 544 &> /dev/null
    7.48 +if [ "${?}" != 0 ]; then
    7.49 +    echo "Insufficient privileges."
    7.50 +    echo "Is this script executed with 'Run As Administrator'?"
    7.51 +    exit 1
    7.52 +echo 'privileges sufficient.'
    7.53 +fi
    7.54 +
    7.55 +# check OpenSecurity Initial VM Image
    7.56 +#
    7.57 +echo "looking for VM image: ${1}..."
    7.58 +OSECVM_IMAGE=$(cygpath -u "${1}")
    7.59 +echo "looking for VM image: ${1}"
    7.60 +if [ ! -f "${OSECVM_IMAGE}" ]; then
    7.61 +    echo "Warning: no OpenSecurity Initial Image found."
    7.62 +    echo "Please download using the OpenSecurity download tool."
    7.63 +    exit 1
    7.64 +fi
    7.65 +echo "initial VM image: ${1} found"
    7.66 +
    7.67 +# look up VirtulBox installation
    7.68 +#
    7.69 +echo "looking up VirtualBox installation..."
    7.70 +VBOX_MANAGER="$(cat /proc/registry/HKEY_LOCAL_MACHINE/SOFTWARE/Oracle/VirtualBox/InstallDir)/VBoxManage.exe"
    7.71 +VBOX_MANAGER=$(sanitize_path "${VBOX_MANAGER}")
    7.72 +if [ ! -x "${VBOX_MANAGER}" ]; then
    7.73 +    echo "can't execute VBoxManage.exe - is VirtualBox installed?"
    7.74 +    echo "looked at: "$(cygpath -w ${VBOX_MANAGER})""
    7.75 +    exit 1
    7.76 +fi
    7.77 +echo "VirtualBox found at: ${VBOX_MANAGER}"
    7.78 +
    7.79 +# enforce VirtualBox to "feel good" by calling a function
    7.80 +# (that is to "warm up" VirtualBox DCOM server ...)
    7.81 +#
    7.82 +echo "grabing VBox machine folder..."
    7.83 +MACHINE_FOLDER=$("${VBOX_MANAGER}" list systemproperties | grep '^Default machine folder:' | sed 's/^Default machine folder: *//')
    7.84 +MACHINE_FOLDER=$(cygpath -u "${MACHINE_FOLDER}")
    7.85 +echo "machine folder: ${MACHINE_FOLDER}"
    7.86 +
    7.87 +# we have to stop the OpenSecurity service now
    7.88 +# the VMManger does lock the SecurityDVMs so we can't
    7.89 +# change them when he's on
    7.90 +echo "stopping OpenSecurity service..."
    7.91 +net stop "OpenSecurity Service"
    7.92 +echo "OpenSecurity service stopped."
    7.93 +
    7.94 +echo -n "After stopping we'll wait 5 secs to let VirtualBox calm itself"
    7.95 +for i in {1..5}; do
    7.96 +    echo -n .
    7.97 +    sleep 1
    7.98 +done
    7.99 +echo
   7.100 +
   7.101 +# do all stuff relativ to the given machinefolder
   7.102 +pushd "${MACHINE_FOLDER}" &> /dev/null
   7.103 +if [ "$?" != "0" ]; then
   7.104 +    echo "Failed to switch into machine folder."
   7.105 +    exit 1
   7.106 +fi    
   7.107 +
   7.108 +# the Security VM disk image
   7.109 +VDISK_IMAGE="SecurityDVM/SecurityDVM.vmdk"
   7.110 +
   7.111 +# import VM 
   7.112 +#
   7.113 +"${VBOX_MANAGER}" list vms | grep SecurityDVM &> /dev/null
   7.114 +if [ ! "${?}" = "0" ]; then
   7.115 +    echo "importing VM: ${OSECVM_IMAGE}"
   7.116 +    "${VBOX_MANAGER}" import "$(cygpath -w "${OSECVM_IMAGE}")" --vsys 0 --vmname SecurityDVM --unit 12 --disk "${VDISK_IMAGE}"
   7.117 +else
   7.118 +    echo "found SecurityDVM already present in VBox reusing it."
   7.119 +    echo "if you want a complete new import please remove the VM first."
   7.120 +    echo "starting OpenSecurity service..."
   7.121 +    net start "OpenSecurity Service"
   7.122 +    echo "OpenSecurity service started"
   7.123 +    exit 1
   7.124 +fi
   7.125 +
   7.126 +# grab VM storage controller and port 
   7.127 +#
   7.128 +VDISK_SETUP=$("${VBOX_MANAGER}" showvminfo SecurityDVM | grep SecurityDVM.vmdk | cut -d ':' -f 1 | tr '(),' '   ')
   7.129 +VDISK_CONTROLLER=$(echo ${VDISK_SETUP} | gawk '{print $1;}')
   7.130 +VDISK_PORT=$(echo ${VDISK_SETUP} | gawk '{print $2;}')
   7.131 +VDISK_DEVICE=$(echo ${VDISK_SETUP} | gawk '{print $3;}')
   7.132 +if [ -z "${VDISK_CONTROLLER}" ]; then
   7.133 +    echo "unable to grab virtual disk controller in VM."
   7.134 +    echo "this shouldn't happen. It's a bug."
   7.135 +    echo "starting OpenSecurity service..."
   7.136 +    net start "OpenSecurity Service"
   7.137 +    echo "OpenSecurity service started"
   7.138 +    exit 1
   7.139 +fi
   7.140 +
   7.141 +# detach disk image
   7.142 +#
   7.143 +echo "detaching disk image ..."
   7.144 +"${VBOX_MANAGER}" storageattach SecurityDVM --storagectl ${VDISK_CONTROLLER} --port ${VDISK_PORT} --medium none
   7.145 +
   7.146 +# turn disk image into writethrough
   7.147 +#
   7.148 +echo "turning disk image into writetrough ..."
   7.149 +"${VBOX_MANAGER}" storageattach SecurityDVM --storagectl ${VDISK_CONTROLLER} --port ${VDISK_PORT} --device ${VDISK_DEVICE} --type hdd --mtype writethrough --medium "${VDISK_IMAGE}" 
   7.150 +
   7.151 +# detach disk image
   7.152 +#
   7.153 +echo "detaching disk image ..."
   7.154 +"${VBOX_MANAGER}" storageattach SecurityDVM --storagectl ${VDISK_CONTROLLER} --port ${VDISK_PORT} --medium none
   7.155 +
   7.156 +# immutablize disk
   7.157 +#
   7.158 +echo "reattach immutable disk image ..."
   7.159 +"${VBOX_MANAGER}" storageattach SecurityDVM --storagectl ${VDISK_CONTROLLER} --port ${VDISK_PORT} --device ${VDISK_DEVICE} --type hdd --mtype immutable --medium "${VDISK_IMAGE}"
   7.160 +
   7.161 +echo "imported initial OsecVM.ova image"
   7.162 +
   7.163 +"${VBOX_MANAGER}" list vms
   7.164 +
   7.165 +echo "starting OpenSecurity service..."
   7.166 +net start "OpenSecurity Service"
   7.167 +echo "OpenSecurity service started"
   7.168 +
     8.1 --- a/OpenSecurity/bin/launch.pyw	Tue Mar 18 16:28:15 2014 +0100
     8.2 +++ b/OpenSecurity/bin/launch.pyw	Tue Mar 18 16:31:47 2014 +0100
     8.3 @@ -195,7 +195,7 @@
     8.4      """ask the user for VM and app to start"""
     8.5      
     8.6      # prebuild the pixmap cache: fetch all jpg, png and jpeg images and load them
     8.7 -    image_path = os.path.join(Environment("OpenSecurity").data_path, '..', 'gfx')
     8.8 +    image_path = os.path.join(Environment("OpenSecurity").data_path, 'gfx')
     8.9      for file in os.listdir(image_path):
    8.10          if file.lower().rpartition('.')[2] in ('jpg', 'png', 'jpeg'):
    8.11              QtGui.QPixmapCache.insert(file.lower().rpartition('.')[0], QtGui.QPixmap(os.path.join(image_path, file)))
     9.1 --- a/OpenSecurity/bin/opensecurity_dialog.py	Tue Mar 18 16:28:15 2014 +0100
     9.2 +++ b/OpenSecurity/bin/opensecurity_dialog.py	Tue Mar 18 16:31:47 2014 +0100
     9.3 @@ -62,7 +62,7 @@
     9.4      
     9.5      # prebuild the pixmap cache: fetch all jpg, png and jpeg images and load them
     9.6      data_path = Environment("OpenSecurity").data_path
     9.7 -    image_path = os.path.join(data_path, '..', 'gfx')
     9.8 +    image_path = os.path.join(data_path, 'gfx')
     9.9      for file in os.listdir(image_path):
    9.10          if file.lower().rpartition('.')[2] in ('jpg', 'png', 'jpeg'):
    9.11              QtGui.QPixmapCache.insert(file.lower().rpartition('.')[0], QtGui.QPixmap(os.path.join(image_path, file)))
    10.1 --- a/OpenSecurity/bin/opensecurity_service.pyw	Tue Mar 18 16:28:15 2014 +0100
    10.2 +++ b/OpenSecurity/bin/opensecurity_service.pyw	Tue Mar 18 16:31:47 2014 +0100
    10.3 @@ -82,7 +82,10 @@
    10.4          # the REST server from a distance ...
    10.5          #
    10.6          # TODO: find a better secure way to do that
    10.7 -        r = urllib2.urlopen('http://localhost:8080/terminate', timeout=1)
    10.8 +        try:
    10.9 +            r = urllib2.urlopen('http://localhost:8080/terminate', timeout=1)
   10.10 +        except:
   10.11 +            pass
   10.12  
   10.13          win32event.SetEvent(self.hWaitStop)
   10.14          self.log('OpenSecurity Service stopped...\n') 
    11.1 --- a/OpenSecurity/bin/opensecurity_tray.pyw	Tue Mar 18 16:28:15 2014 +0100
    11.2 +++ b/OpenSecurity/bin/opensecurity_tray.pyw	Tue Mar 18 16:31:47 2014 +0100
    11.3 @@ -161,7 +161,7 @@
    11.4      app = QtGui.QApplication(sys.argv)
    11.5  
    11.6      # prebuild the pixmap cache: fetch all jpg, png and jpeg images and load them
    11.7 -    image_path = os.path.join(Environment("OpenSecurity").data_path, '..', 'gfx')
    11.8 +    image_path = os.path.join(Environment("OpenSecurity").data_path, 'gfx')
    11.9      for file in os.listdir(image_path):
   11.10          if file.lower().rpartition('.')[2] in ('jpg', 'png', 'jpeg'):
   11.11              QtGui.QPixmapCache.insert(file.lower().rpartition('.')[0], QtGui.QPixmap(os.path.join(image_path, file)))
    12.1 --- a/OpenSecurity/bin/opensecurityd.pyw	Tue Mar 18 16:28:15 2014 +0100
    12.2 +++ b/OpenSecurity/bin/opensecurityd.pyw	Tue Mar 18 16:31:47 2014 +0100
    12.3 @@ -36,12 +36,13 @@
    12.4  import os.path
    12.5  import subprocess
    12.6  import sys
    12.7 +import tempfile
    12.8  import web
    12.9 -from cygwin import Cygwin
   12.10  
   12.11  import vmmanager
   12.12  
   12.13  # local
   12.14 +from cygwin import Cygwin
   12.15  from environment import Environment
   12.16  from opensecurity_util import logger
   12.17  
   12.18 @@ -55,12 +56,15 @@
   12.19  """All the URLs we know mapping to class handler"""
   12.20  opensecurity_urls = (
   12.21      '/browsing',                        'os_browsing',          # http://localhost:8080/browsing                                GET
   12.22 +    '/fetch_initial_image',             'os_fetch_image',       # http://localhost:8080/fetch_initial_image                     GET
   12.23 +    '/init',                            'os_init',              # http://localhost:8080/init                                    GET
   12.24      '/sdvms',                           'os_sdvms',             # http://localhost:8080/sdvms                                   GET, PUT
   12.25      '/sdvms/(.*)/application/(.*)',     'os_sdvm_application',  # http://localhost:8080/sdvms/[VMNAME]/application/[COMMAND]    GET
   12.26      '/sdvms/(.*)/ip',                   'os_sdvm_ip',           # http://localhost:8080/sdvms/[VMNAME]/ip                       GET
   12.27      '/sdvms/(.*)/start',                'os_sdvm_start',        # http://localhost:8080/sdvms/[VMNAME]/start                    GET
   12.28      '/sdvms/(.*)/stop',                 'os_sdvm_stop',         # http://localhost:8080/sdvms/[VMNAME]/stop                     GET
   12.29      '/sdvms/(.*)',                      'os_sdvm',              # http://localhost:8080/sdvms/[VMNAME]                          GET, DELETE
   12.30 +    '/setup',                           'os_setup',             # http://localhost:8080/setup                                   GET
   12.31      '/vms',                             'os_vms',               # http://localhost:8080/vms                                     GET
   12.32      '/vms/(.*)',                        'os_vm',                # http://localhost:8080/vms/[VMNAME]                            GET
   12.33      '/update_template',                 'os_update_template',   # http://localhost:8080/update_template                         GET
   12.34 @@ -96,6 +100,70 @@
   12.35              raise web.internalerror()
   12.36  
   12.37         
   12.38 +class os_fetch_image:
   12.39 +    """OpenSecurity '/fetch_initial_image' handler
   12.40 +    
   12.41 +    - GET: fetch the initial image from the X-Net Servers
   12.42 +            The initial image is stored in the
   12.43 +            Virtual Box default machine path.
   12.44 +            The result to this call is a temprary file
   12.45 +            which shows the progress (or error state)
   12.46 +            of this call.
   12.47 +    """
   12.48 +    
   12.49 +    def GET(self):
   12.50 +        
   12.51 +        log_call(web.ctx.environ)
   12.52 +        global gvm_mgr
   12.53 +
   12.54 +        trace_file_name = os.path.join(tempfile.gettempdir(), 'OpenSecurity_fetch_image.log')
   12.55 +        trace_file = open(trace_file_name, 'w+')
   12.56 +
   12.57 +        machine_folder = Cygwin.cygPath(gvm_mgr.getMachineFolder()) 
   12.58 +        download_initial_image_script = '/OpenSecurity/bin/download_initial_image.sh \'' + machine_folder + '\''
   12.59 +        Cygwin.bashExecute(download_initial_image_script, wait_return = False, stdout = trace_file, stderr = trace_file) 
   12.60 +
   12.61 +        page = """
   12.62 +        <html>
   12.63 +        <head></head>
   12.64 +        <body>
   12.65 +        Fetch OpenSecurity image log ({0}):<br/>
   12.66 +        <iframe src="file://{0}" width="100%" height="100%"></iframe>
   12.67 +        </body>
   12.68 +        </head>
   12.69 +        """
   12.70 +        return page.format(trace_file_name)
   12.71 +
   12.72 +
   12.73 +class os_init:
   12.74 +    """OpenSecurity '/init' handler
   12.75 +    
   12.76 +    - GET: Do initial import of OsecVM.ova
   12.77 +    """
   12.78 +    
   12.79 +    def GET(self):
   12.80 +        log_call(web.ctx.environ)
   12.81 +        global gvm_mgr
   12.82 +
   12.83 +        trace_file_name = os.path.join(tempfile.gettempdir(), 'OpenSecurity_initial_import.log')
   12.84 +        trace_file = open(trace_file_name, 'w+')
   12.85 +
   12.86 +        vm_image = Cygwin.cygPath(gvm_mgr.getMachineFolder()) + '/OsecVM.ova'
   12.87 +        initial_import_script = '/OpenSecurity/bin/initial_vm.sh \'' + vm_image + '\''
   12.88 +        Cygwin.bashExecute(initial_import_script, wait_return = False, stdout = trace_file, stderr = trace_file) 
   12.89 +
   12.90 +        page = """
   12.91 +        <html>
   12.92 +        <head></head>
   12.93 +        <body>
   12.94 +        Import initial OpenSecurity image log ({0}):<br/>
   12.95 +        <iframe src="file://{0}" width="100%" height="100%"></iframe>
   12.96 +        </body>
   12.97 +        </head>
   12.98 +        """
   12.99 +        return page.format(trace_file_name)
  12.100 +
  12.101 +
  12.102  class os_root:
  12.103      """OpenSecurity '/' handler
  12.104      
  12.105 @@ -107,7 +175,8 @@
  12.106          global gvm_mgr
  12.107          res = "'os_server': { "
  12.108          res += "'version': '" + __version__ + "', "
  12.109 -        res += "'machine_folder': '" + gvm_mgr.machineFolder + "' "
  12.110 +        res += "'virtual box systemproperties': '" + str(gvm_mgr.systemProperties) + "', "
  12.111 +        res += "'current temporary folder': '" + tempfile.gettempdir() + "' "
  12.112          res += "}"
  12.113          return res
  12.114  
  12.115 @@ -141,7 +210,8 @@
  12.116          global gvm_mgr
  12.117          command = '/' + command
  12.118          result = Cygwin.sshExecuteX11(command, gvm_mgr.getHostOnlyIP(name), 'osecuser', Cygwin.cygPath(gvm_mgr.getMachineFolder()) + '/' + name + '/dvm_key'  )
  12.119 -        return result
  12.120 +        self.poweroffVM(name)
  12.121 +        return gvm_mgr.removeVM(name)
  12.122      
  12.123  
  12.124  class os_sdvm_ip:
  12.125 @@ -208,6 +278,31 @@
  12.126          return name
  12.127              
  12.128  
  12.129 +class os_setup:
  12.130 +    """OpenSecurity '/setup' handler
  12.131 +    
  12.132 +    - GET: Give user some info how to setup the OpenSecurity envvironment
  12.133 +    """
  12.134 +    
  12.135 +    def GET(self):
  12.136 +
  12.137 +        log_call(web.ctx.environ)
  12.138 +
  12.139 +        page = """
  12.140 +        <html>
  12.141 +        <body>
  12.142 +        <h1>Setup OpenSecurity</h1>
  12.143 +        In order to setup OpenSecurity an inital VM image has to be downloaded and imported:<br/>
  12.144 +        <ul>
  12.145 +            <li>Download initial VM image: <a href="/fetch_initial_image">fetch_initial_image</a>
  12.146 +            <li>Import initial VM: <a href="/init">init</a>
  12.147 +        </ul>
  12.148 +        </body>
  12.149 +        </html>
  12.150 +        """
  12.151 +        return page
  12.152 +
  12.153 +
  12.154  class os_terminate:
  12.155      """OpenSecurity '/terminate' handler
  12.156      
  12.157 @@ -229,6 +324,7 @@
  12.158      def GET(self):
  12.159          log_call(web.ctx.environ)
  12.160          global gvm_mgr
  12.161 +        gvm_mgr.stop()
  12.162          gvm_mgr.cleanup()
  12.163          sys.exit(0)
  12.164          return None
    13.1 --- a/OpenSecurity/bin/vmmanager.pyw	Tue Mar 18 16:28:15 2014 +0100
    13.2 +++ b/OpenSecurity/bin/vmmanager.pyw	Tue Mar 18 16:31:47 2014 +0100
    13.3 @@ -1,3 +1,4 @@
    13.4 +<<<<<<< local
    13.5  '''
    13.6  Created on Nov 19, 2013
    13.7  
    13.8 @@ -679,3 +680,686 @@
    13.9      
   13.10      #cmd = "c:\\cygwin64\\bin\\bash.exe --login -c \"/bin/ls\""
   13.11      #man.execute(cmd)
   13.12 +=======
   13.13 +'''
   13.14 +Created on Nov 19, 2013
   13.15 +
   13.16 +@author: BarthaM
   13.17 +'''
   13.18 +import os
   13.19 +import os.path
   13.20 +from subprocess import Popen, PIPE, call, STARTUPINFO, _subprocess
   13.21 +import sys
   13.22 +import re
   13.23 +
   13.24 +from cygwin import Cygwin
   13.25 +from environment import Environment
   13.26 +import threading
   13.27 +import time
   13.28 +import string
   13.29 +
   13.30 +import shutil
   13.31 +import stat
   13.32 +import tempfile
   13.33 +from opensecurity_util import logger, setupLogger, OpenSecurityException
   13.34 +import ctypes
   13.35 +import itertools
   13.36 +import _winreg
   13.37 +DEBUG = True
   13.38 +
   13.39 +class VMManagerException(Exception):
   13.40 +    def __init__(self, value):
   13.41 +        self.value = value
   13.42 +    def __str__(self):
   13.43 +        return repr(self.value)
   13.44 +
   13.45 +class USBFilter:
   13.46 +    vendorid = ""
   13.47 +    productid = ""
   13.48 +    revision = ""
   13.49 +    
   13.50 +    def __init__(self, vendorid, productid, revision):
   13.51 +        self.vendorid = vendorid.lower()
   13.52 +        self.productid = productid.lower()
   13.53 +        self.revision = revision.lower()
   13.54 +        return
   13.55 +    
   13.56 +    def __eq__(self, other):
   13.57 +        return self.vendorid == other.vendorid and self.productid == other.productid and self.revision == other.revision
   13.58 +    
   13.59 +    def __hash__(self):
   13.60 +        return hash(self.vendorid) ^ hash(self.productid) ^ hash(self.revision)
   13.61 +    
   13.62 +    def __repr__(self):
   13.63 +        return "VendorId = \'" + str(self.vendorid) + "\' ProductId = \'" + str(self.productid) + "\' Revision = \'" + str(self.revision) + "\'"
   13.64 +    
   13.65 +    #def __getitem__(self, item):
   13.66 +    #    return self.coords[item]
   13.67 + 
   13.68 +class VMManager(object):
   13.69 +    vmRootName = "SecurityDVM"
   13.70 +    systemProperties = None
   13.71 +    _instance = None
   13.72 +    machineFolder = ''
   13.73 +    rsdHandler = None
   13.74 +    _running = True
   13.75 +    
   13.76 +    def __init__(self):
   13.77 +        self._running = True
   13.78 +        self.systemProperties = self.getSystemProperties()
   13.79 +        self.machineFolder = self.systemProperties["Default machine folder"]
   13.80 +        self.cleanup()
   13.81 +        self.rsdHandler = DeviceHandler(self)
   13.82 +        self.rsdHandler.start()
   13.83 +        return
   13.84 +    
   13.85 +    @staticmethod
   13.86 +    def getInstance():
   13.87 +        if VMManager._instance == None:
   13.88 +            VMManager._instance = VMManager()
   13.89 +        return VMManager._instance
   13.90 +    
   13.91 +    def cleanup(self):
   13.92 +        if self.rsdHandler != None:
   13.93 +            self.rsdHandler.stop()
   13.94 +            self.rsdHandler.join()
   13.95 +        drives = self.getNetworkDrives()
   13.96 +        for drive in drives.keys():
   13.97 +            self.unmapNetworkDrive(drive)
   13.98 +        for vm in self.listSDVM():
   13.99 +            self.poweroffVM(vm)
  13.100 +            self.removeVM(vm)
  13.101 +        
  13.102 +    # return hosty system properties
  13.103 +    def getSystemProperties(self):
  13.104 +        result = checkResult(Cygwin.vboxExecute('list systemproperties'))
  13.105 +        if result[1]=='':
  13.106 +            return None
  13.107 +        props = dict((k.strip(),v.strip().strip('"')) for k,v in (line.split(':', 1) for line in result[1].strip().splitlines()))
  13.108 +        return props
  13.109 +    
  13.110 +    # return the folder containing the guest VMs     
  13.111 +    def getMachineFolder(self):
  13.112 +        return self.machineFolder
  13.113 +
  13.114 +    # list all existing VMs registered with VBox
  13.115 +    def listVM(self):
  13.116 +        result = checkResult(Cygwin.vboxExecute('list vms'))[1]
  13.117 +        vms = list(k.strip().strip('"') for k,_ in (line.split(' ') for line in result.splitlines()))
  13.118 +        return vms
  13.119 +    
  13.120 +    # list running VMs
  13.121 +    def listRunningVMS(self):
  13.122 +        result = checkResult(Cygwin.vboxExecute('list runningvms'))[1]
  13.123 +        vms = list(k.strip().strip('"') for k,_ in (line.split(' ') for line in result.splitlines()))
  13.124 +        return vms
  13.125 +    
  13.126 +    # list existing SDVMs
  13.127 +    def listSDVM(self):
  13.128 +        vms = self.listVM()
  13.129 +        svdms = []
  13.130 +        for vm in vms:
  13.131 +            if vm.startswith(self.vmRootName) and vm != self.vmRootName:
  13.132 +                svdms.append(vm)
  13.133 +        return svdms
  13.134 +    
  13.135 +    # generate valid (not already existing SDVM name). necessary for creating a new VM
  13.136 +    def generateSDVMName(self):
  13.137 +        vms = self.listVM()
  13.138 +        for i in range(0,999):
  13.139 +            if(not self.vmRootName+str(i) in vms):
  13.140 +                return self.vmRootName+str(i)
  13.141 +        return ''
  13.142 +    
  13.143 +    # check if the device is mass storage type
  13.144 +    @staticmethod
  13.145 +    def isMassStorageDevice(device):
  13.146 +        keyname = 'SYSTEM\CurrentControlSet\Enum\USB' + '\VID_' + device.vendorid+'&'+'PID_'+ device.productid
  13.147 +        key = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, keyname)
  13.148 +        #subkeys = _winreg.QueryInfoKey(key)[0]
  13.149 +        #for i in range(0, subkeys):
  13.150 +        #    print _winreg.EnumKey(key, i)     
  13.151 +        devinfokeyname = _winreg.EnumKey(key, 0)
  13.152 +        _winreg.CloseKey(key)
  13.153 +
  13.154 +        devinfokey = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, keyname+'\\'+devinfokeyname)
  13.155 +        value = _winreg.QueryValueEx(devinfokey, 'SERVICE')[0]
  13.156 +        _winreg.CloseKey(devinfokey)
  13.157 +        
  13.158 +        return 'USBSTOR' in value
  13.159 +    
  13.160 +    # return the RSDs connected to the host
  13.161 +    @staticmethod
  13.162 +    def getConnectedRSDS():
  13.163 +        results = checkResult(Cygwin.vboxExecute('list usbhost'))[1]
  13.164 +        results = results.split('Host USB Devices:')[1].strip()
  13.165 +        
  13.166 +        items = list( "UUID:"+result for result in results.split('UUID:') if result != '')
  13.167 +        rsds = dict()   
  13.168 +        for item in items:
  13.169 +            props = dict()
  13.170 +            for line in item.splitlines():
  13.171 +                if line != "":         
  13.172 +                    k,v = line[:line.index(':')].strip(), line[line.index(':')+1:].strip()
  13.173 +                    props[k] = v
  13.174 +            
  13.175 +            #if 'Product' in props.keys() and props['Product'] == 'Mass Storage':
  13.176 +            
  13.177 +            usb_filter = USBFilter( re.search(r"\((?P<vid>[0-9A-Fa-f]+)\)", props['VendorId']).groupdict()['vid'], 
  13.178 +                                    re.search(r"\((?P<pid>[0-9A-Fa-f]+)\)", props['ProductId']).groupdict()['pid'],
  13.179 +                                    re.search(r"\((?P<rev>[0-9A-Fa-f]+)\)", props['Revision']).groupdict()['rev'] )
  13.180 +            if VMManager.isMassStorageDevice(usb_filter):
  13.181 +                rsds[props['UUID']] = usb_filter;
  13.182 +                logger.debug(usb_filter)
  13.183 +        return rsds
  13.184 +    
  13.185 +    # return the RSDs attached to all existing SDVMs
  13.186 +    def getAttachedRSDs(self):
  13.187 +        vms = self.listSDVM()
  13.188 +        attached_devices = dict()
  13.189 +        for vm in vms:
  13.190 +            rsd_filter = self.getUSBFilter(vm)
  13.191 +            if rsd_filter != None:
  13.192 +                attached_devices[vm] = rsd_filter
  13.193 +        return attached_devices
  13.194 +    
  13.195 +    # configures hostonly networking and DHCP server. requires admin rights
  13.196 +    def configureHostNetworking(self):
  13.197 +        #cmd = 'vboxmanage list hostonlyifs'
  13.198 +        #Cygwin.vboxExecute(cmd)
  13.199 +        #cmd = 'vboxmanage hostonlyif remove \"VirtualBox Host-Only Ethernet Adapter\"'
  13.200 +        #Cygwin.vboxExecute(cmd)
  13.201 +        #cmd = 'vboxmanage hostonlyif create'
  13.202 +        #Cygwin.vboxExecute(cmd)
  13.203 +        checkResult(Cygwin.vboxExecute('hostonlyif ipconfig \"VirtualBox Host-Only Ethernet Adapter\" --ip 192.168.56.1 --netmask 255.255.255.0'))
  13.204 +        #cmd = 'vboxmanage dhcpserver add'
  13.205 +        #Cygwin.vboxExecute(cmd)
  13.206 +        checkResult(Cygwin.vboxExecute('dhcpserver modify --ifname \"VirtualBox Host-Only Ethernet Adapter\" --ip 192.168.56.100 --netmask 255.255.255.0 --lowerip 192.168.56.101 --upperip 192.168.56.200'))
  13.207 +    
  13.208 +    #create new virtual machine instance based on template vm named SecurityDVM (\SecurityDVM\SecurityDVM.vmdk)
  13.209 +    def createVM(self, vm_name):
  13.210 +        hostonly_if = self.getHostOnlyIFs()
  13.211 +        checkResult(Cygwin.vboxExecute('createvm --name ' + vm_name + ' --ostype Debian --register'))
  13.212 +        checkResult(Cygwin.vboxExecute('modifyvm ' + vm_name + ' --memory 512 --vram 10 --cpus 1 --usb on --usbehci on --nic1 hostonly --hostonlyadapter1 \"' + hostonly_if['Name'] + '\" --nic2 nat'))
  13.213 +        checkResult(Cygwin.vboxExecute('storagectl ' + vm_name + ' --name SATA --add sata --portcount 2'))
  13.214 +        return
  13.215 +    
  13.216 +    # attach storage image to controller
  13.217 +    def storageAttach(self, vm_name):
  13.218 +        if self.isStorageAttached(vm_name):
  13.219 +            self.storageDetach(vm_name)
  13.220 +        checkResult(Cygwin.vboxExecute('storageattach ' + vm_name + ' --storagectl SATA --port 0 --device 0 --type hdd --medium \"'+ self.machineFolder + '\SecurityDVM\SecurityDVM.vmdk\"'))
  13.221 +    
  13.222 +    # return true if storage is attached 
  13.223 +    def isStorageAttached(self, vm_name):
  13.224 +        info = self.getVMInfo(vm_name)
  13.225 +        return (info['SATA-0-0']!='none')
  13.226 +    
  13.227 +    # detach storage from controller
  13.228 +    def storageDetach(self, vm_name):
  13.229 +        if self.isStorageAttached(vm_name):
  13.230 +            checkResult(Cygwin.vboxExecute('storageattach ' + vm_name + ' --storagectl SATA --port 0 --device 0 --type hdd --medium none'))
  13.231 +    
  13.232 +    def changeStorageType(self, filename, storage_type):
  13.233 +        checkResult(Cygwin.vboxExecute('modifyhd \"' + filename + '\" --type ' + storage_type))
  13.234 +    
  13.235 +    # list storage snaphots for VM
  13.236 +    def updateTemplate(self):
  13.237 +        self.cleanup()
  13.238 +        self.poweroffVM('SecurityDVM')
  13.239 +        self.waitShutdown('SecurityDVM')
  13.240 +        
  13.241 +        # check for updates
  13.242 +        self.genCertificateISO('SecurityDVM')
  13.243 +        self.attachCertificateISO('SecurityDVM')
  13.244 +        
  13.245 +        self.storageDetach('SecurityDVM')
  13.246 +        results = checkResult(Cygwin.vboxExecute('list hdds'))[1]
  13.247 +        results = results.replace('Parent UUID', 'Parent')
  13.248 +        items = list( "UUID:"+result for result in results.split('UUID:') if result != '')
  13.249 +        
  13.250 +        snaps = dict()   
  13.251 +        for item in items:
  13.252 +            props = dict()
  13.253 +            for line in item.splitlines():
  13.254 +                if line != "":         
  13.255 +                    k,v = line[:line.index(':')].strip(), line[line.index(':')+1:].strip()
  13.256 +                    props[k] = v;
  13.257 +            snaps[props['UUID']] = props
  13.258 +        
  13.259 +        
  13.260 +        template_storage = self.machineFolder + '\SecurityDVM\SecurityDVM.vmdk'
  13.261 +        
  13.262 +        # find template uuid
  13.263 +        template_uuid = ''
  13.264 +        for hdd in snaps.values():
  13.265 +            if hdd['Location'] == template_storage:
  13.266 +                template_uuid = hdd['UUID']
  13.267 +        logger.debug('found parent uuid ' + template_uuid)
  13.268 +        
  13.269 +        # remove snapshots 
  13.270 +        for hdd in snaps.values():
  13.271 +            if hdd['Parent'] == template_uuid:
  13.272 +                #template_uuid = hdd['UUID']
  13.273 +                logger.debug('removing snapshot ' + hdd['UUID'])
  13.274 +                checkResult(Cygwin.vboxExecute('closemedium disk {' + hdd['UUID'] + '} --delete'))#[1]
  13.275 +                # parse result 0%...10%...20%...30%...40%...50%...60%...70%...80%...90%...100%
  13.276 +        
  13.277 +        self.changeStorageType(template_storage,'normal')
  13.278 +        self.storageAttach('SecurityDVM')
  13.279 +        self.startVM('SecurityDVM')
  13.280 +        self.waitStartup('SecurityDVM')
  13.281 +        checkResult(Cygwin.sshExecute('"sudo apt-get -y update"', VMManager.getHostOnlyIP('SecurityDVM'), 'osecuser', Cygwin.cygPath(self.machineFolder) + '/' + 'SecurityDVM' + '/dvm_key'))
  13.282 +        checkResult(Cygwin.sshExecute('"sudo apt-get -y upgrade"', VMManager.getHostOnlyIP('SecurityDVM'), 'osecuser', Cygwin.cygPath(self.machineFolder) + '/' + 'SecurityDVM' + '/dvm_key'))
  13.283 +        #self.stopVM('SecurityDVM')
  13.284 +        self.hibernateVM('SecurityDVM')
  13.285 +        self.waitShutdown('SecurityDVM')
  13.286 +        self.storageDetach('SecurityDVM')
  13.287 +        self.changeStorageType(template_storage,'immutable')
  13.288 +        self.storageAttach('SecurityDVM')
  13.289 +        self.rsdHandler = DeviceHandler(self)
  13.290 +        self.rsdHandler.start()
  13.291 +    
  13.292 +    #remove VM from the system. should be used on VMs returned by listSDVMs    
  13.293 +    def removeVM(self, vm_name):
  13.294 +        logger.info('Removing ' + vm_name)
  13.295 +        checkResult(Cygwin.vboxExecute('unregistervm ' + vm_name + ' --delete'))
  13.296 +        vm_file = Cygwin.cygPath(self.machineFolder + '\\' + vm_name)
  13.297 +        checkResult(Cygwin.bashExecute('rm -rf \'' + vm_file + '\''))
  13.298 +    
  13.299 +    # start VM
  13.300 +    def startVM(self, vm_name):
  13.301 +        logger.info('Starting ' +  vm_name)
  13.302 +        result = checkResult(Cygwin.vboxExecute('startvm ' + vm_name + ' --type headless' ))
  13.303 +        while 'successfully started' not in result[1] and _running:
  13.304 +            logger.error("Failed to start SDVM: " + vm_name + " retrying")
  13.305 +            time.sleep(1)
  13.306 +            result = checkResult(Cygwin.vboxExecute('startvm ' + vm_name + ' --type headless'))
  13.307 +        return result[0]
  13.308 +    
  13.309 +    # return wether VM is running or not
  13.310 +    def isVMRunning(self, vm_name):
  13.311 +        return vm_name in self.listRunningVMS()    
  13.312 +    
  13.313 +    # stop VM
  13.314 +    def stopVM(self, vm_name):
  13.315 +        logger.info('Sending shutdown signal to ' + vm_name)
  13.316 +        checkResult(Cygwin.sshExecute( '"sudo shutdown -h now"', VMManager.getHostOnlyIP(vm_name), 'osecuser', Cygwin.cygPath(self.machineFolder) + '/' + vm_name + '/dvm_key' ))
  13.317 +    
  13.318 +    # stop VM
  13.319 +    def hibernateVM(self, vm_name):
  13.320 +        logger.info('Sending shutdown signal to ' + vm_name)
  13.321 +        checkResult(Cygwin.sshExecute( '"sudo hibernate-disk&"', VMManager.getHostOnlyIP(vm_name), 'osecuser', Cygwin.cygPath(self.machineFolder) + '/' + vm_name + '/dvm_key', wait_return=False))
  13.322 +            
  13.323 +    # poweroff VM
  13.324 +    def poweroffVM(self, vm_name):
  13.325 +        if not self.isVMRunning(vm_name):
  13.326 +            return
  13.327 +        logger.info('Powering off ' + vm_name)
  13.328 +        return checkResult(Cygwin.vboxExecute('controlvm ' + vm_name + ' poweroff'))
  13.329 +    
  13.330 +    #list the hostonly IFs exposed by the VBox host
  13.331 +    @staticmethod    
  13.332 +    def getHostOnlyIFs():
  13.333 +        result = Cygwin.vboxExecute('list hostonlyifs')[1]
  13.334 +        if result=='':
  13.335 +            return None
  13.336 +        props = dict((k.strip(),v.strip().strip('"')) for k,v in (line.split(':', 1) for line in result.strip().splitlines()))
  13.337 +        return props
  13.338 +    
  13.339 +    # return the hostOnly IP for a running guest or the host
  13.340 +    @staticmethod    
  13.341 +    def getHostOnlyIP(vm_name):
  13.342 +        if vm_name == None:
  13.343 +            logger.info('Gettting hostOnly IP address for Host')
  13.344 +            return VMManager.getHostOnlyIFs()['IPAddress']
  13.345 +        else:
  13.346 +            logger.info('Gettting hostOnly IP address ' + vm_name)
  13.347 +            result = checkResult(Cygwin.vboxExecute('guestproperty get ' + vm_name + ' /VirtualBox/GuestInfo/Net/0/V4/IP'))
  13.348 +            if result=='':
  13.349 +                return None
  13.350 +            result = result[1]
  13.351 +            if result.startswith('No value set!'):
  13.352 +                return None
  13.353 +            return result[result.index(':')+1:].strip()
  13.354 +            
  13.355 +    # attach removable storage device to VM by provision of filter
  13.356 +    def attachRSD(self, vm_name, rsd_filter):
  13.357 +        return checkResult(Cygwin.vboxExecute('usbfilter add 0 --target ' + vm_name + ' --name OpenSecurityRSD --vendorid ' + rsd_filter.vendorid + ' --productid ' + rsd_filter.productid + ' --revision ' + rsd_filter.revision))
  13.358 +    
  13.359 +    # detach removable storage from VM by 
  13.360 +    def detachRSD(self, vm_name):
  13.361 +        return checkResult(Cygwin.vboxExecute('usbfilter remove 0 --target ' + vm_name))
  13.362 +        
  13.363 +    # return the description set for an existing VM
  13.364 +    def getVMInfo(self, vm_name):
  13.365 +        results = checkResult(Cygwin.vboxExecute('showvminfo ' + vm_name + ' --machinereadable'))[1]
  13.366 +        props = dict((k.strip().strip('"'),v.strip().strip('"')) for k,v in (line.split('=', 1) for line in results.splitlines()))
  13.367 +        return props
  13.368 +    
  13.369 +    # return the configured USB filter for an existing VM 
  13.370 +    def getUSBFilter(self, vm_name):
  13.371 +        props = self.getVMInfo(vm_name)
  13.372 +        keys = set(['USBFilterVendorId1', 'USBFilterProductId1', 'USBFilterRevision1'])
  13.373 +        keyset = set(props.keys())
  13.374 +        usb_filter = None
  13.375 +        if keyset.issuperset(keys):
  13.376 +            usb_filter = USBFilter(props['USBFilterVendorId1'], props['USBFilterProductId1'], props['USBFilterRevision1'])
  13.377 +        return usb_filter
  13.378 +    
  13.379 +    #generates ISO containing authorized_keys for use with guest VM
  13.380 +    def genCertificateISO(self, vm_name):
  13.381 +        machineFolder = Cygwin.cygPath(self.machineFolder)
  13.382 +        # remove .ssh folder if exists
  13.383 +        checkResult(Cygwin.bashExecute('\"/usr/bin/rm -rf \\\"' + machineFolder + '/' + vm_name + '/.ssh\\\"\"'))
  13.384 +        # remove .ssh folder if exists
  13.385 +        checkResult(Cygwin.bashExecute('\"/usr/bin/rm -rf \\\"' + machineFolder + '/' + vm_name + '/dvm_key\\\"\"'))
  13.386 +        # create .ssh folder in vm_name
  13.387 +        checkResult(Cygwin.bashExecute('\"/usr/bin/mkdir -p \\\"' + machineFolder + '/' + vm_name + '/.ssh\\\"\"'))
  13.388 +        # generate dvm_key pair in vm_name / .ssh     
  13.389 +        checkResult(Cygwin.bashExecute('\"/usr/bin/ssh-keygen -q -t rsa -N \\"\\" -C \\\"' + vm_name + '\\\" -f \\\"' + machineFolder + '/' + vm_name + '/.ssh/dvm_key\\\"\"'))
  13.390 +        # move out private key
  13.391 +        checkResult(Cygwin.bashExecute('\"/usr/bin/mv \\\"' + machineFolder + '/' + vm_name + '/.ssh/dvm_key\\\" \\\"' + machineFolder + '/' + vm_name + '\\\"'))
  13.392 +        # set permissions for private key
  13.393 +        checkResult(Cygwin.bashExecute('\"/usr/bin/chmod 500 \\\"' + machineFolder + '/' + vm_name + '/dvm_key\\\"\"'))
  13.394 +        # rename public key to authorized_keys
  13.395 +        checkResult(Cygwin.bashExecute('\"/usr/bin/mv \\\"' + machineFolder + '/' + vm_name + '/.ssh/dvm_key.pub\\\" \\\"' + machineFolder + '/' + vm_name + '/.ssh/authorized_keys\\\"'))
  13.396 +        # set permissions for authorized_keys
  13.397 +        checkResult(Cygwin.bashExecute('\"/usr/bin/chmod 500 \\\"' + machineFolder + '/' + vm_name + '/.ssh/authorized_keys\\\"\"'))
  13.398 +        # generate iso image with .ssh/authorized keys
  13.399 +        checkResult(Cygwin.bashExecute('\"/usr/bin/genisoimage -J -R -o \\\"' + machineFolder + '/' + vm_name + '/'+ vm_name + '.iso\\\" \\\"' + machineFolder + '/' + vm_name + '/.ssh\\\"\"'))
  13.400 +    
  13.401 +    # attaches generated ssh public cert to guest vm
  13.402 +    def attachCertificateISO(self, vm_name):
  13.403 +        result = checkResult(Cygwin.vboxExecute('storageattach ' + vm_name + ' --storagectl SATA --port 1 --device 0 --type dvddrive --mtype readonly --medium \"' + self.machineFolder + '\\' + vm_name + '\\'+ vm_name + '.iso\"'))
  13.404 +        return result
  13.405 +    
  13.406 +    # wait for machine to come up
  13.407 +    def waitStartup(self, vm_name, timeout_ms = 30000):
  13.408 +        checkResult(Cygwin.vboxExecute('guestproperty wait ' + vm_name + ' SDVMStarted --timeout ' + str(timeout_ms) + ' --fail-on-timeout'))
  13.409 +        return VMManager.getHostOnlyIP(vm_name)
  13.410 +    
  13.411 +    # wait for machine to shutdown
  13.412 +    def waitShutdown(self, vm_name):
  13.413 +        while vm_name in self.listRunningVMS() and _running:
  13.414 +            time.sleep(1)
  13.415 +        return
  13.416 +        
  13.417 +    # handles browsing request    
  13.418 +    def handleBrowsingRequest(self):
  13.419 +        handler = BrowsingHandler(self)
  13.420 +        handler.start()
  13.421 +        return 'ok'
  13.422 +    
  13.423 +    #Small function to check the availability of network resource.
  13.424 +    #def isAvailable(self, path):
  13.425 +        #return os.path.exists(path)
  13.426 +        #result = Cygwin.cmdExecute('IF EXIST "' + path + '" echo YES')
  13.427 +        #return string.find(result[1], 'YES',)
  13.428 +    
  13.429 +    #Small function to check if the mention location is a directory
  13.430 +    def isDirectory(self, path):
  13.431 +        result = checkResult(Cygwin.cmdExecute('dir ' + path + ' | FIND ".."'))
  13.432 +        return string.find(result[1], 'DIR',)
  13.433 +
  13.434 +    def mapNetworkDrive(self, drive, networkPath, user, password):
  13.435 +        self.unmapNetworkDrive(drive)
  13.436 +        #Check for drive availability
  13.437 +        if os.path.exists(drive):
  13.438 +            logger.error("Drive letter is already in use: " + drive)
  13.439 +            return -1
  13.440 +        #Check for network resource availability
  13.441 +        retry = 5
  13.442 +        while not os.path.exists(networkPath):
  13.443 +            time.sleep(1)
  13.444 +            if retry == 0:
  13.445 +                return -1
  13.446 +            logger.info("Path not accessible: " + networkPath + " retrying")
  13.447 +            retry-=1
  13.448 +            #return -1
  13.449 +    
  13.450 +        command = 'USE ' + drive + ' ' + networkPath + ' /PERSISTENT:NO'
  13.451 +        if user != None:
  13.452 +            command += ' ' + password + ' /User' + user
  13.453 +    
  13.454 +        #TODO: Execute 'NET USE' command with authentication
  13.455 +        result = checkResult(Cygwin.execute('C:\\Windows\\system32\\net.exe', command))
  13.456 +        if string.find(result[1], 'successfully',) == -1:
  13.457 +            logger.error("Failed: NET " + command)
  13.458 +            return -1
  13.459 +        return 1
  13.460 +    
  13.461 +    def unmapNetworkDrive(self, drive):
  13.462 +        drives = self.getNetworkDrives()
  13.463 +        if drive not in drives.keys():
  13.464 +            return 1 
  13.465 +        result = checkResult(Cygwin.execute('C:\\Windows\\system32\\net.exe', 'USE ' + drive + ' /DELETE /YES'))
  13.466 +        if string.find(str(result[1]), 'successfully',) == -1:
  13.467 +            logger.error(result[2])
  13.468 +            return -1
  13.469 +        return 1
  13.470 +    
  13.471 +    def getNetworkDrives(self):
  13.472 +        ip = VMManager.getHostOnlyIP(None)
  13.473 +        ip = ip[:ip.rindex('.')]
  13.474 +        drives = dict()    
  13.475 +        result = checkResult(Cygwin.execute('C:\\Windows\\system32\\net.exe', 'USE'))
  13.476 +        for line in result[1].splitlines():
  13.477 +            if ip in line:
  13.478 +                parts = line.split()
  13.479 +                drives[parts[1]] = parts[2]
  13.480 +        return drives
  13.481 +            
  13.482 +    def genNetworkDrive(self):
  13.483 +        network_drives = self.getNetworkDrives()
  13.484 +        logical_drives = VMManager.getLogicalDrives()
  13.485 +        drives = list(map(chr, range(68, 91)))  
  13.486 +        for drive in drives:
  13.487 +            if drive+':' not in network_drives and drive not in logical_drives:
  13.488 +                return drive+':'
  13.489 +
  13.490 +    def getNetworkDrive(self, vm_name):
  13.491 +        ip = self.getHostOnlyIP(vm_name)
  13.492 +        result = checkResult(Cygwin.execute('C:\\Windows\\system32\\net.exe', 'USE'))
  13.493 +        for line in result[1].splitlines():
  13.494 +            if line != None and ip in line:
  13.495 +                parts = line.split()
  13.496 +                return parts[0]
  13.497 +    @staticmethod
  13.498 +    def getLogicalDrives():
  13.499 +        drive_bitmask = ctypes.cdll.kernel32.GetLogicalDrives()
  13.500 +        return list(itertools.compress(string.ascii_uppercase,  map(lambda x:ord(x) - ord('0'), bin(drive_bitmask)[:1:-1])))
  13.501 +    
  13.502 +    @staticmethod
  13.503 +    def getDriveType(drive):
  13.504 +        return ctypes.cdll.kernel32.GetDriveTypeW(u"%s:\\"%drive)
  13.505 +    
  13.506 +    @staticmethod
  13.507 +    def getVolumeInfo(drive):
  13.508 +        volumeNameBuffer = ctypes.create_unicode_buffer(1024)
  13.509 +        fileSystemNameBuffer = ctypes.create_unicode_buffer(1024)
  13.510 +        serial_number = None
  13.511 +        max_component_length = None
  13.512 +        file_system_flags = None
  13.513 +        
  13.514 +        rc = ctypes.cdll.kernel32.GetVolumeInformationW(
  13.515 +            #ctypes.c_wchar_p("F:\\"),
  13.516 +            u"%s:\\"%drive,
  13.517 +            volumeNameBuffer,
  13.518 +            ctypes.sizeof(volumeNameBuffer),
  13.519 +            serial_number,
  13.520 +            max_component_length,
  13.521 +            file_system_flags,
  13.522 +            fileSystemNameBuffer,
  13.523 +            ctypes.sizeof(fileSystemNameBuffer)
  13.524 +        )
  13.525 +        
  13.526 +        return volumeNameBuffer.value, fileSystemNameBuffer.value
  13.527 +
  13.528 +    @staticmethod
  13.529 +    def stop():
  13.530 +        """stop all running infinite loops now --> needed for gracefull shutdown"""
  13.531 +        _running = False
  13.532 +
  13.533 +
  13.534 +
  13.535 +def checkResult(result):
  13.536 +    if result[0] != 0:
  13.537 +        logger.error('Command failed:' + ''.join(result[2]))
  13.538 +        raise OpenSecurityException('Command failed:' + ''.join(result[2]))
  13.539 +    return result
  13.540 +
  13.541 +# handles browsing request                    
  13.542 +class BrowsingHandler(threading.Thread):
  13.543 +    vmm = None
  13.544 +    def __init__(self, vmmanager):
  13.545 +        threading.Thread.__init__(self)
  13.546 +        self.vmm = vmmanager
  13.547 +     
  13.548 +    def run(self):
  13.549 +        try:
  13.550 +            new_sdvm = self.vmm.generateSDVMName()
  13.551 +            self.vmm.createVM(new_sdvm)
  13.552 +            self.vmm.storageAttach(new_sdvm)
  13.553 +            self.vmm.genCertificateISO(new_sdvm)
  13.554 +            self.vmm.attachCertificateISO(new_sdvm)
  13.555 +            self.vmm.startVM(new_sdvm)
  13.556 +            new_ip = self.vmm.waitStartup(new_sdvm)
  13.557 +            drive = self.vmm.genNetworkDrive()
  13.558 +            if new_ip != None:
  13.559 +                self.vmm.mapNetworkDrive(drive, '\\\\' + new_ip + '\\Download', None, None)
  13.560 +            result = checkResult(Cygwin.sshExecuteX11('/usr/bin/iceweasel', new_ip, 'osecuser', Cygwin.cygPath(self.vmm.getMachineFolder()) + '/' + new_sdvm + '/dvm_key'))
  13.561 +        except:
  13.562 +            logger.error("BrowsingHandler failed. Cleaning up")
  13.563 +            
  13.564 +        self.vmm.unmapNetworkDrive(drive)
  13.565 +        self.vmm.poweroffVM(new_sdvm)
  13.566 +        self.vmm.removeVM(new_sdvm)
  13.567 +                
  13.568 +class DeviceHandler(threading.Thread): 
  13.569 +    vmm = None
  13.570 +    #handleDeviceChangeLock = threading.Lock()
  13.571 +    attachedRSDs = None  
  13.572 +    connectedRSDs = None
  13.573 +    running = True
  13.574 +    def __init__(self, vmmanger): 
  13.575 +        threading.Thread.__init__(self)
  13.576 +        self.vmm = vmmanger
  13.577 + 
  13.578 +    def stop(self):
  13.579 +        self.running = False
  13.580 +        
  13.581 +    def run(self):
  13.582 +        self.connectedRSDs = dict()
  13.583 +        self.attachedRSDs = self.vmm.getAttachedRSDs()
  13.584 +        while self.running:
  13.585 +            tmp_rsds = self.vmm.getConnectedRSDS()
  13.586 +            if tmp_rsds.keys() == self.connectedRSDs.keys():
  13.587 +                logger.debug("Nothing's changed. sleep(3)")
  13.588 +                time.sleep(3)
  13.589 +                continue
  13.590 +            
  13.591 +            logger.info("Something's changed")          
  13.592 +            self.connectedRSDs = tmp_rsds
  13.593 +            self.attachedRSDs = self.vmm.getAttachedRSDs()
  13.594 +            
  13.595 +            for vm_name in self.attachedRSDs.keys():
  13.596 +                if self.attachedRSDs[vm_name] not in self.connectedRSDs.values():
  13.597 +                    drive = self.vmm.getNetworkDrive(vm_name)
  13.598 +                    self.vmm.unmapNetworkDrive(drive)
  13.599 +                    #self.stopVM(vm_name)
  13.600 +                    self.vmm.detachRSD(vm_name)
  13.601 +                    self.vmm.poweroffVM(vm_name)
  13.602 +                    self.vmm.removeVM(vm_name)
  13.603 +            #create new vm for attached device if any
  13.604 +            self.attachedRSDs = self.vmm.getAttachedRSDs()
  13.605 +            self.connectedRSDs = self.vmm.getConnectedRSDS()
  13.606 +            
  13.607 +            new_ip = None
  13.608 +            for connected_device in self.connectedRSDs.values():
  13.609 +                if (self.attachedRSDs and False) or (connected_device not in self.attachedRSDs.values()):
  13.610 +                    new_sdvm = self.vmm.generateSDVMName()
  13.611 +                    self.vmm.createVM(new_sdvm)
  13.612 +                    self.vmm.storageAttach(new_sdvm)
  13.613 +                    self.vmm.attachRSD(new_sdvm, connected_device)
  13.614 +                    self.vmm.startVM(new_sdvm)
  13.615 +                    new_ip = self.vmm.waitStartup(new_sdvm)
  13.616 +                    drive = self.vmm.genNetworkDrive()
  13.617 +                    if new_ip != None:
  13.618 +                        self.vmm.mapNetworkDrive(drive, '\\\\' + new_ip + '\\USB', None, None)
  13.619 +
  13.620 +if __name__ == '__main__':
  13.621 +    #man = VMManager.getInstance()
  13.622 +    #man.listVM()
  13.623 +    #print man.getConnectedRSDs()
  13.624 +    #print man.getNetworkDrives()
  13.625 +    #man.genNetworkDrive()
  13.626 +    #drive_bitmask = ctypes.cdll.kernel32.GetLogicalDrives()
  13.627 +    #print list(itertools.compress(string.ascii_uppercase,  map(lambda x:ord(x) - ord('0'), bin(drive_bitmask)[:1:-1])))
  13.628 +    #print list(map(chr, range(68, 91))) 
  13.629 +    #print Cygwin.getRegEntry('SYSTEM\CurrentControlSet\Enum\USB', 'VID_1058&PID_0704')[0]
  13.630 +    #devices = VMManager.getConnectedRSDS()
  13.631 +    #print devices
  13.632 +    
  13.633 +    drives = VMManager.getLogicalDrives()
  13.634 +    print drives
  13.635 +    print VMManager.getDriveType("E")
  13.636 +    print VMManager.getVolumeInfo("E")
  13.637 +    #for device in devices.values():
  13.638 +    #    #print device
  13.639 +    #    if VMManager.isMassStorageDevice(device):
  13.640 +    #        print device
  13.641 +        
  13.642 +    
  13.643 +    
  13.644 +    #time.sleep(-1)
  13.645 +    #man.listVM()
  13.646 +    #man.listVM()
  13.647 +    #man.listVM()
  13.648 +    #man.listVM()
  13.649 +    #man.genCertificateISO('SecurityDVM0')
  13.650 +    #man.guestExecute('SecurityDVM0', '/bin/ls -la')
  13.651 +    #logger = setupLogger('VMManager')
  13.652 +    #c = Cygwin()
  13.653 +    
  13.654 +    #man.sshExecute('/bin/ls -la', 'SecurityDVM0')
  13.655 +    #man.sshExecuteX11('/usr/bin/iceweasel', 'SecurityDVM0')
  13.656 +    #man.removeVM('SecurityDVM0')
  13.657 +    #man.netUse('192.168.56.134', 'USB\\')
  13.658 +    #ip = '192.168.56.139'
  13.659 +    
  13.660 +    #man.cygwin_path = 'c:\\cygwin64\\bin\\'
  13.661 +    #man.handleDeviceChange()
  13.662 +    #print man.listSDVM()
  13.663 +    #man.configureHostNetworking()
  13.664 +    #new_vm = man.generateSDVMName()
  13.665 +    #man.createVM(new_vm)
  13.666 +    
  13.667 +    #print Cygwin.cmd()
  13.668 +    #man.isAvailable('c:')
  13.669 +    #ip = man.getHostOnlyIP('SecurityDVM0')
  13.670 +    #man.mapNetworkDrive('h:', '\\\\' + ip + '\Download', None, None)
  13.671 +    
  13.672 +    #man.genCertificateISO(new_vm)
  13.673 +    #man.attachCertificateISO(new_vm)
  13.674 +    
  13.675 +    #man.attachCertificateISO(vm_name)
  13.676 +    #man.guestExecute(vm_name, "ls")
  13.677 +    #man.sshGuestX11Execute('SecurityDVM1', '/usr/bin/iceweasel')
  13.678 +    #time.sleep(60)
  13.679 +    #print man.cygwinPath("C:\Users\BarthaM\VirtualBox VMs\SecurityDVM\.ssh\*")
  13.680 +    #man.genCertificateISO('SecurityDVM')
  13.681 +    #man.attachCertificateISO('SecurityDVM')
  13.682 +    #man.isStorageAttached('SecurityDVM')
  13.683 +    #man.guestExecute('SecurityDVM', 'sudo apt-get -y update')
  13.684 +    #man.guestExecute('SecurityDVM', 'sudo apt-get -y upgrade' )
  13.685 +    
  13.686 +    #man.stopVM('SecurityDVM')
  13.687 +    #man.storageDetach('SecurityDVM')
  13.688 +    #man.changeStorageType('C:\Users\BarthaM\VirtualBox VMs\SecurityDVM\SecurityDVM.vmdk','immutable')
  13.689 +    #man.storageAttach('SecurityDVM')
  13.690 +    
  13.691 +    
  13.692 +    #cmd = "c:\\cygwin64\\bin\\bash.exe --login -c \"/bin/ls\""
  13.693 +    #man.execute(cmd)
  13.694 +>>>>>>> other