hibernate, wait_startup, and other changes
authormb
Wed, 26 Feb 2014 17:27:07 +0100
changeset 79617009c32da0
parent 78 23551f635ca9
child 80 f6c0b8f48ca8
hibernate, wait_startup, and other changes
OpenSecurity/bin/cygwin.py
OpenSecurity/bin/opensecurityd.pyw
OpenSecurity/bin/vmmanager.pyw
server/windows/USBEventSvc/OpenSecUSBEventSvc/OpenSecUSBEventSvc.cpp
server/windows/USBEventSvc/USBEventSvc.sdf
server/windows/USBEventSvc/USBEventSvc.v12.suo
server/windows/USBEventSvc/Win32/Debug/OpenSecUSBEventSvc.ilk
server/windows/USBEventSvc/Win32/Debug/OpenSecUSBEventSvc.pdb
server/windows/USBEventSvc/Win32/Debug/OpenSecUSBEventSvcLog.ilk
server/windows/USBEventSvc/Win32/Debug/OpenSecUSBEventSvcLog.pdb
server/windows/USBEventSvc/Win32/Release/OpenSecUSBEventSvc.pdb
server/windows/USBEventSvc/Win32/Release/OpenSecUSBEventSvcLog.pdb
server/windows/USBEventSvc/x64/Debug/OpenSecUSBEventSvcLog.ilk
server/windows/USBEventSvc/x64/Debug/OpenSecUSBEventSvcLog.pdb
server/windows/USBEventSvc/x64/Release/OpenSecUSBEventSvc.exe
server/windows/USBEventSvc/x64/Release/OpenSecUSBEventSvc.pdb
server/windows/USBEventSvc/x64/Release/OpenSecUSBEventSvcLog.dll
server/windows/USBEventSvc/x64/Release/OpenSecUSBEventSvcLog.pdb
     1.1 --- a/OpenSecurity/bin/cygwin.py	Fri Feb 21 11:04:04 2014 +0100
     1.2 +++ b/OpenSecurity/bin/cygwin.py	Wed Feb 26 17:27:07 2014 +0100
     1.3 @@ -123,35 +123,47 @@
     1.4      #executes command on host system
     1.5      @staticmethod
     1.6      def execute(program, arguments, wait_return=True, window = False):
     1.7 -        if Cygwin.executeLock.acquire(True):
     1.8 -            _startupinfo = STARTUPINFO()
     1.9 -            if not window:
    1.10 -                _startupinfo.dwFlags |= _subprocess.STARTF_USESHOWWINDOW
    1.11 -                _startupinfo.wShowWindow = _subprocess.SW_HIDE
    1.12 +        _startupinfo = STARTUPINFO()
    1.13 +        if not window:
    1.14 +            _startupinfo.dwFlags |= _subprocess.STARTF_USESHOWWINDOW
    1.15 +            _startupinfo.wShowWindow = _subprocess.SW_HIDE
    1.16  
    1.17 -                #logger.debug('trying to launch: ' + program + ' ' + ''.join(arguments))
    1.18 -            try:
    1.19 -                process = Popen(executable=program, args=' ' + arguments, startupinfo = _startupinfo, stdin=PIPE, stdout=PIPE, stderr=PIPE, shell = False)
    1.20 -                logger.debug('Launched: ' + program + ' ' + ''.join(arguments))
    1.21 -                if not wait_return:
    1.22 -                    return [0, 'working in background', '']
    1.23 -                result = process.wait()
    1.24 -                res_stdout = process.stdout.read();
    1.25 -                res_stderr = process.stderr.read();
    1.26 -                #if res_stdout != "":
    1.27 -                #    logger.debug(res_stdout)
    1.28 -                #if res_stderr != "":
    1.29 -                #    logger.debug(res_stderr)
    1.30 -            except:
    1.31 -                logger.error('Failed to execute cygwin command.\n\tcommand=' + program + ' ' + ''.join(arguments) + '\n')
    1.32 -                #TODO: throw exception
    1.33 -                
    1.34 -            Cygwin.executeLock.release()
    1.35 +            #logger.debug('trying to launch: ' + program + ' ' + ''.join(arguments))
    1.36 +        res_stderr = None
    1.37 +        try:
    1.38 +            process = Popen(executable=program, args=' ' + arguments, startupinfo = _startupinfo, stdin=PIPE, stdout=PIPE, stderr=PIPE, shell = False)
    1.39 +            logger.debug('Launched: ' + program + ' ' + ''.join(arguments))
    1.40 +            if not wait_return:
    1.41 +                return [0, 'working in background', '']
    1.42 +            result = process.wait()
    1.43 +            res_stdout = process.stdout.read();
    1.44 +            res_stderr = process.stderr.read();
    1.45 +
    1.46 +        except Exception as ex:
    1.47 +            res_stderr = ''.join(ex.args)
    1.48 +            result = -1 
    1.49 +        
    1.50 +        if result != 0:
    1.51 +            logger.error('Failed to execute cygwin command.\n\tcommand=' + program + ' ' + ''.join(arguments) + '\n' + res_stderr)
    1.52 +            raise OpenSecurityException('Failed to execute cygwin command.\n\tcommand=' + program + ' ' + ''.join(arguments) + '\n' + res_stderr)
    1.53 +            
    1.54          return result, res_stdout, res_stderr
    1.55      
    1.56      @staticmethod
    1.57      def vboxExecute(command, wait_return=True, window = False, bash_opts=''):
    1.58 -        return Cygwin.execute(Cygwin.vbox_man, command, wait_return, window)
    1.59 +        if Cygwin.executeLock.acquire(True):
    1.60 +            retry = 0
    1.61 +            while retry < 3:
    1.62 +                try:
    1.63 +                    result = Cygwin.execute(Cygwin.vbox_man, command, wait_return, window)
    1.64 +                    Cygwin.executeLock.release()
    1.65 +                    return result
    1.66 +                except OpenSecurityException as inst:
    1.67 +                    retry+=1
    1.68 +            Cygwin.executeLock.release()
    1.69 +            raise inst
    1.70 +        return result
    1.71 +        
    1.72      
    1.73      @staticmethod
    1.74      def bashExecute(command, wait_return=True, window = False, bash_opts=''):
     2.1 --- a/OpenSecurity/bin/opensecurityd.pyw	Fri Feb 21 11:04:04 2014 +0100
     2.2 +++ b/OpenSecurity/bin/opensecurityd.pyw	Wed Feb 26 17:27:07 2014 +0100
     2.3 @@ -54,8 +54,8 @@
     2.4  
     2.5  """All the URLs we know mapping to class handler"""
     2.6  opensecurity_urls = (
     2.7 -    '/device_change',                   'os_device_change',     # http://localhost:8080/device_change                           GET
     2.8 -    '/sdvm_started',                    'os_sdvm_started',      # http://localhost:8080/sdvm_started                            GET
     2.9 +    #'/device_change',                   'os_device_change',     # http://localhost:8080/device_change                           GET
    2.10 +    #'/sdvm_started',                    'os_sdvm_started',      # http://localhost:8080/sdvm_started                            GET
    2.11      '/browsing',                        'os_browsing',          # http://localhost:8080/browsing                                GET
    2.12      '/sdvms',                           'os_sdvms',             # http://localhost:8080/sdvms                                   GET, PUT
    2.13      '/sdvms/(.*)/application/(.*)',     'os_sdvm_application',  # http://localhost:8080/sdvms/[VMNAME]/application/[COMMAND]    GET
    2.14 @@ -79,16 +79,16 @@
    2.15  # code
    2.16  
    2.17  
    2.18 -class os_device_change:
    2.19 -    """OpenSecurity '/device_change' handler"""
    2.20 -    
    2.21 -    def GET(self):
    2.22 -        log_call(web.ctx.environ)
    2.23 -        try:
    2.24 -            new_ip = gvm_mgr.handleDeviceChange()
    2.25 -            return new_ip
    2.26 -        except:
    2.27 -            raise web.internalerror()
    2.28 +#class os_device_change:
    2.29 +#    """OpenSecurity '/device_change' handler"""
    2.30 +#    
    2.31 +#    def GET(self):
    2.32 +#        log_call(web.ctx.environ)
    2.33 +#        try:
    2.34 +#            new_ip = gvm_mgr.handleDeviceChange()
    2.35 +#            return new_ip
    2.36 +#        except:
    2.37 +#            raise web.internalerror()
    2.38  
    2.39          
    2.40  class os_browsing:
    2.41 @@ -105,14 +105,14 @@
    2.42          except:
    2.43              raise web.internalerror()
    2.44  
    2.45 -class os_sdvm_started:
    2.46 -    """OpenSecurity '/sdvm_started' handler"""
    2.47 -    
    2.48 -    def GET(self):
    2.49 -        log_call(web.ctx.environ)
    2.50 -        remote_ip = web.ctx.environ['REMOTE_ADDR']
    2.51 -        gvm_mgr.putStartNotification(remote_ip)
    2.52 -        return "os_sdvm_started"
    2.53 +#class os_sdvm_started:
    2.54 +#    """OpenSecurity '/sdvm_started' handler"""
    2.55 +#    
    2.56 +#    def GET(self):
    2.57 +#        log_call(web.ctx.environ)
    2.58 +#        remote_ip = web.ctx.environ['REMOTE_ADDR']
    2.59 +#        gvm_mgr.putStartNotification(remote_ip)
    2.60 +#        return "os_sdvm_started"
    2.61          
    2.62  class os_sdvm:
    2.63      """OpenSecurity '/sdvms/[VM]' handler
     3.1 --- a/OpenSecurity/bin/vmmanager.pyw	Fri Feb 21 11:04:04 2014 +0100
     3.2 +++ b/OpenSecurity/bin/vmmanager.pyw	Wed Feb 26 17:27:07 2014 +0100
     3.3 @@ -6,7 +6,6 @@
     3.4  import os
     3.5  import os.path
     3.6  from subprocess import Popen, PIPE, call, STARTUPINFO, _subprocess
     3.7 -import subprocess
     3.8  import sys
     3.9  import re
    3.10  
    3.11 @@ -20,7 +19,8 @@
    3.12  import stat
    3.13  import tempfile
    3.14  from opensecurity_util import logger, setupLogger, OpenSecurityException
    3.15 -
    3.16 +import ctypes
    3.17 +import itertools
    3.18  DEBUG = True
    3.19  
    3.20  class VMManagerException(Exception):
    3.21 @@ -55,15 +55,14 @@
    3.22      startNotifications = list()
    3.23      _instance = None
    3.24      machineFolder = ''
    3.25 -    attachedRSDs = None  
    3.26 -    connectedRSDs = None
    3.27 +    rsdHandler = None
    3.28      
    3.29      def __init__(self):
    3.30          self.systemProperties = self.getSystemProperties()
    3.31          self.machineFolder = self.systemProperties["Default machine folder"]
    3.32          self.cleanup()
    3.33 -        self.attachedRSDs = self.getAttachedRSDs()
    3.34 -        self.connectedRSDs = self.getConnectedRSDS()
    3.35 +        self.rsdHandler = DeviceHandler(self)
    3.36 +        self.rsdHandler.start()
    3.37          return
    3.38      
    3.39      @staticmethod
    3.40 @@ -73,8 +72,12 @@
    3.41          return VMManager._instance
    3.42      
    3.43      def cleanup(self):
    3.44 -        self.unmapNetworkDrive('G:')
    3.45 -        self.unmapNetworkDrive('H:')
    3.46 +        if self.rsdHandler != None:
    3.47 +            self.rsdHandler.stop()
    3.48 +            self.rsdHandler.join()
    3.49 +        drives = self.getNetworkDrives()
    3.50 +        for drive in drives.keys():
    3.51 +            self.unmapNetworkDrive(drive)
    3.52          for vm in self.listSDVM():
    3.53              self.poweroffVM(vm)
    3.54              self.removeVM(vm)
    3.55 @@ -83,7 +86,7 @@
    3.56          self.startNotifications.append(ip)
    3.57      
    3.58      def isSDVMStarted(self, ip):
    3.59 -        return self.startNotifications.contains(ip)
    3.60 +        return ip in self.startNotifications
    3.61      
    3.62      # return hosty system properties
    3.63      def getSystemProperties(self):
    3.64 @@ -97,14 +100,6 @@
    3.65      # return the folder containing the guest VMs     
    3.66      def getMachineFolder(self):
    3.67          return self.machineFolder
    3.68 -    
    3.69 -    #list the hostonly IFs exposed by the VBox host
    3.70 -    def getHostOnlyIFs(self):
    3.71 -        result = Cygwin.vboxExecute('list hostonlyifs')[1]
    3.72 -        if result=='':
    3.73 -            return None
    3.74 -        props = dict((k.strip(),v.strip().strip('"')) for k,v in (line.split(':', 1) for line in result.strip().splitlines()))
    3.75 -        return props
    3.76  
    3.77      # list all existing VMs registered with VBox
    3.78      def listVM(self):
    3.79 @@ -258,13 +253,14 @@
    3.80          self.waitStartup('SecurityDVM')
    3.81          Cygwin.sshExecute('"sudo apt-get -y update"', VMManager.getHostOnlyIP('SecurityDVM'), 'osecuser', Cygwin.cygPath(self.machineFolder) + '/' + 'SecurityDVM' + '/dvm_key'  )
    3.82          Cygwin.sshExecute('"sudo apt-get -y upgrade"', VMManager.getHostOnlyIP('SecurityDVM'), 'osecuser', Cygwin.cygPath(self.machineFolder) + '/' + 'SecurityDVM' + '/dvm_key'  )
    3.83 -        self.stopVM('SecurityDVM')
    3.84 -        #self.hibernateVM('SecurityDVM')
    3.85 +        #self.stopVM('SecurityDVM')
    3.86 +        self.hibernateVM('SecurityDVM')
    3.87          self.waitShutdown('SecurityDVM')
    3.88          self.storageDetach('SecurityDVM')
    3.89          self.changeStorageType(template_storage,'immutable')
    3.90          self.storageAttach('SecurityDVM')
    3.91 -        self.handleDeviceChange()
    3.92 +        self.rsdHandler = DeviceHandler(self)
    3.93 +        self.rsdHandler.start()
    3.94      
    3.95      #remove VM from the system. should be used on VMs returned by listSDVMs    
    3.96      def removeVM(self, vm_name):
    3.97 @@ -295,7 +291,7 @@
    3.98      # stop VM
    3.99      def hibernateVM(self, vm_name):
   3.100          logger.info('Sending shutdown signal to ' + vm_name)
   3.101 -        Cygwin.sshExecute( '"sudo hibernate-disk"', VMManager.getHostOnlyIP(vm_name), 'osecuser', Cygwin.cygPath(self.machineFolder) + '/' + vm_name + '/dvm_key' )
   3.102 +        Cygwin.sshExecute( '"sudo hibernate-disk&"', VMManager.getHostOnlyIP(vm_name), 'osecuser', Cygwin.cygPath(self.machineFolder) + '/' + vm_name + '/dvm_key', wait_return=False )
   3.103              
   3.104      # poweroff VM
   3.105      def poweroffVM(self, vm_name):
   3.106 @@ -304,18 +300,31 @@
   3.107          logger.info('Powering off ' + vm_name)
   3.108          return Cygwin.vboxExecute('controlvm ' + vm_name + ' poweroff')
   3.109      
   3.110 -    # return the hostOnly IP for a running guest
   3.111 +    #list the hostonly IFs exposed by the VBox host
   3.112 +    @staticmethod    
   3.113 +    def getHostOnlyIFs():
   3.114 +        result = Cygwin.vboxExecute('list hostonlyifs')[1]
   3.115 +        if result=='':
   3.116 +            return None
   3.117 +        props = dict((k.strip(),v.strip().strip('"')) for k,v in (line.split(':', 1) for line in result.strip().splitlines()))
   3.118 +        return props
   3.119 +    
   3.120 +    # return the hostOnly IP for a running guest or the host
   3.121      @staticmethod    
   3.122      def getHostOnlyIP(vm_name):
   3.123 -        logger.info('Gettting hostOnly IP address ' + vm_name)
   3.124 -        result = Cygwin.vboxExecute('guestproperty get ' + vm_name + ' /VirtualBox/GuestInfo/Net/0/V4/IP')
   3.125 -        if result=='':
   3.126 -            return None
   3.127 -        result = result[1]
   3.128 -        if result.startswith('No value set!'):
   3.129 -            return None
   3.130 -        return result[result.index(':')+1:].strip()
   3.131 -    
   3.132 +        if vm_name == None:
   3.133 +            logger.info('Gettting hostOnly IP address for Host')
   3.134 +            return VMManager.getHostOnlyIFs()['IPAddress']
   3.135 +        else:
   3.136 +            logger.info('Gettting hostOnly IP address ' + vm_name)
   3.137 +            result = Cygwin.vboxExecute('guestproperty get ' + vm_name + ' /VirtualBox/GuestInfo/Net/0/V4/IP')
   3.138 +            if result=='':
   3.139 +                return None
   3.140 +            result = result[1]
   3.141 +            if result.startswith('No value set!'):
   3.142 +                return None
   3.143 +            return result[result.index(':')+1:].strip()
   3.144 +            
   3.145      # attach removable storage device to VM by provision of filter
   3.146      def attachRSD(self, vm_name, rsd_filter):
   3.147          return Cygwin.vboxExecute('usbfilter add 0 --target ' + vm_name + ' --name OpenSecurityRSD --vendorid ' + rsd_filter.vendorid + ' --productid ' + rsd_filter.productid + ' --revision ' + rsd_filter.revision)
   3.148 @@ -370,72 +379,18 @@
   3.149          result = Cygwin.vboxExecute('storageattach ' + vm_name + ' --storagectl SATA --port 1 --device 0 --type dvddrive --mtype readonly --medium \"' + self.machineFolder + '\\' + vm_name + '\\'+ vm_name + '.iso\"')
   3.150          return result
   3.151      
   3.152 -    
   3.153 -    handleDeviceChangeLock = threading.Lock()
   3.154 -    trigger = False
   3.155 -    # handles device change events
   3.156 -    def handleDeviceChange(self):
   3.157 -        if VMManager.handleDeviceChangeLock.acquire(True):
   3.158 -            #logger.debug("triggered")
   3.159 -            #VMManager.handleDeviceChangeLock.release()
   3.160 -            #return
   3.161 -            #destroy unused vms
   3.162 -            #diff = DictDiffer(self.connectedRSDs, tmp_conn)
   3.163 -            retry = 0
   3.164 -            while retry < 30:
   3.165 -                if self.getConnectedRSDS().keys() == self.connectedRSDs.keys():
   3.166 -                    logger.info("Nothing's changed. Waiting for VBox USB sub-system to update...")
   3.167 -                else:
   3.168 -                    self.connectedRSDs = self.getConnectedRSDS()
   3.169 -                    break
   3.170 -                time.sleep(1)
   3.171 -                retry+=1
   3.172 -            
   3.173 -            if retry == 30:
   3.174 -                VMManager.handleDeviceChangeLock.release()
   3.175 -                return None
   3.176 -
   3.177 -            logger.info("Something's changed")
   3.178 -            
   3.179 -            self.attachedRSDs = self.getAttachedRSDs()
   3.180 -            
   3.181 -            for vm_name in self.attachedRSDs.keys():
   3.182 -                if self.attachedRSDs[vm_name] not in self.connectedRSDs.values():
   3.183 -                    self.unmapNetworkDrive('h:')
   3.184 -                    #self.stopVM(vm_name)
   3.185 -                    self.detachRSD(vm_name)
   3.186 -                    self.poweroffVM(vm_name)
   3.187 -                    self.removeVM(vm_name)
   3.188 -            #create new vm for attached device if any
   3.189 -            self.attachedRSDs = self.getAttachedRSDs()
   3.190 -            self.connectedRSDs = self.getConnectedRSDS()
   3.191 -            
   3.192 -            new_ip = None
   3.193 -            for connected_device in self.connectedRSDs.values():
   3.194 -                if (self.attachedRSDs and False) or (connected_device not in self.attachedRSDs.values()):
   3.195 -                    new_sdvm = self.generateSDVMName()
   3.196 -                    self.createVM(new_sdvm)
   3.197 -                    self.storageAttach(new_sdvm)
   3.198 -                    self.attachRSD(new_sdvm, connected_device)
   3.199 -                    self.startVM(new_sdvm)
   3.200 -                    new_ip = self.waitStartup(new_sdvm)
   3.201 -                    
   3.202 -                    if new_ip != None:
   3.203 -                        self.mapNetworkDrive('h:', '\\\\' + new_ip + '\\USB', None, None)
   3.204 -                    #TODO: cleanup notifications somwhere else (eg. machine shutdown)
   3.205 -                    self.startNotifications.remove(new_ip)
   3.206 -            VMManager.handleDeviceChangeLock.release()
   3.207 -            return new_ip
   3.208 -    
   3.209      # wait for machine to come up
   3.210 -    def waitStartup(self, vm_name): 
   3.211 -        new_ip = None
   3.212 -        while new_ip == None:
   3.213 -            time.sleep(1)
   3.214 -            new_ip = VMManager.getHostOnlyIP(vm_name)
   3.215 -        while new_ip not in self.startNotifications:
   3.216 -            time.sleep(1)
   3.217 -        return new_ip
   3.218 +    def waitStartup(self, vm_name, timeout_ms = 30000):
   3.219 +        #result = Cygwin.vboxExecute('guestproperty wait ' + vm_name + ' /VirtualBox/GuestInfo/Net/0/V4/IP --timeout ' + str(timeout_ms) + ' --fail-on-timeout')
   3.220 +        
   3.221 +        result = Cygwin.vboxExecute('guestproperty wait ' + vm_name + ' SDVMStarted --timeout ' + str(timeout_ms) + ' --fail-on-timeout')
   3.222 +        #new_ip = VMManager.getHostOnlyIP(vm_name)
   3.223 +        #while new_ip == None:
   3.224 +        #    time.sleep(1)
   3.225 +        #    new_ip = VMManager.getHostOnlyIP(vm_name)
   3.226 +        #while not self.isSDVMStarted(new_ip):
   3.227 +        #    time.sleep(1)
   3.228 +        return VMManager.getHostOnlyIP(vm_name)
   3.229      
   3.230      # wait for machine to shutdown
   3.231      def waitShutdown(self, vm_name):
   3.232 @@ -483,7 +438,7 @@
   3.233              logger.info("Path not accessible: " + networkPath + " retrying")
   3.234              #return -1
   3.235      
   3.236 -        command = 'USE ' + drive + ' ' + networkPath
   3.237 +        command = 'USE ' + drive + ' ' + networkPath + ' /PERSISTENT:NO'
   3.238          if user != None:
   3.239              command += ' ' + password + ' /User' + user
   3.240      
   3.241 @@ -495,35 +450,119 @@
   3.242          return 1
   3.243      
   3.244      def unmapNetworkDrive(self, drive):
   3.245 -        if not os.path.exists(drive):
   3.246 -            return -1
   3.247 +        drives = self.getNetworkDrives()
   3.248 +        if drive not in drives.keys():
   3.249 +            return 1 
   3.250          result = Cygwin.execute('C:\\Windows\\system32\\net.exe', 'USE ' + drive + ' /DELETE /YES')
   3.251 -        if string.find(str(result), 'successfully',) == -1:
   3.252 +        if string.find(str(result[1]), 'successfully',) == -1:
   3.253              logger.error(result[2])
   3.254              return -1
   3.255          return 1
   3.256 +    
   3.257 +    def getNetworkDrives(self):
   3.258 +        ip = VMManager.getHostOnlyIP(None)
   3.259 +        ip = ip[:ip.rindex('.')]
   3.260 +        drives = dict()    
   3.261 +        result = Cygwin.execute('C:\\Windows\\system32\\net.exe', 'USE')
   3.262 +        for line in result[1].splitlines():
   3.263 +            if ip in line:
   3.264 +                parts = line.split()
   3.265 +                drives[parts[1]] = parts[2]
   3.266 +        return drives
   3.267 +            
   3.268 +    def genNetworkDrive(self):
   3.269 +        network_drives = self.getNetworkDrives()
   3.270 +        logical_drives = self.getLogicalDrives()
   3.271 +        drives = list(map(chr, range(68, 91)))  
   3.272 +        for drive in drives:
   3.273 +            if drive+':' not in network_drives and drive not in logical_drives:
   3.274 +                return drive+':'
   3.275  
   3.276 +    def getNetworkDrive(self, vm_name):
   3.277 +        ip = self.getHostOnlyIP(vm_name)
   3.278 +        result = Cygwin.execute('C:\\Windows\\system32\\net.exe', 'USE')
   3.279 +        for line in result[1].splitlines():
   3.280 +            if ip in line:
   3.281 +                parts = line.split()
   3.282 +                return parts[0]
   3.283 +    
   3.284 +    def getLogicalDrives(self):
   3.285 +        drive_bitmask = ctypes.cdll.kernel32.GetLogicalDrives()
   3.286 +        return list(itertools.compress(string.ascii_uppercase,  map(lambda x:ord(x) - ord('0'), bin(drive_bitmask)[:1:-1])))
   3.287 +                    
   3.288 +        #vms = self.listSDVM()
   3.289 +        #for vm in vms:
   3.290 +        #    ip = self.getHostOnlyIP(vm)
   3.291 +        
   3.292  class DeviceHandler(threading.Thread): 
   3.293      vmm = None
   3.294 -    triggered = False
   3.295 -    def __init__(self, zahl): 
   3.296 -        threading.Thread.__init__(self) 
   3.297 -        self.vmm = None 
   3.298 +    #handleDeviceChangeLock = threading.Lock()
   3.299 +    attachedRSDs = None  
   3.300 +    connectedRSDs = None
   3.301 +    running = True
   3.302 +    def __init__(self, vmmanger): 
   3.303 +        threading.Thread.__init__(self)
   3.304 +        self.vmm = vmmanger
   3.305   
   3.306 +    def stop(self):
   3.307 +        self.running = False
   3.308 +        
   3.309      def run(self):
   3.310 -        while True:
   3.311 -            if self.triggered:
   3.312 -                logger.debug("triggered")
   3.313 -                triggered = False
   3.314 -            else:
   3.315 -                time.sleep(1)
   3.316 +        self.connectedRSDs = dict()#self.vmm.getConnectedRSDS()
   3.317 +        self.attachedRSDs = self.vmm.getAttachedRSDs()
   3.318 +        while self.running:
   3.319 +            tmp_rsds = self.vmm.getConnectedRSDS()
   3.320 +            if tmp_rsds.keys() == self.connectedRSDs.keys():
   3.321 +                logger.debug("Nothing's changed. sleep(3)")
   3.322 +                time.sleep(3)
   3.323 +                continue
   3.324 +            
   3.325 +            logger.info("Something's changed")          
   3.326 +            
   3.327 +            self.connectedRSDs = tmp_rsds
   3.328 +            self.attachedRSDs = self.vmm.getAttachedRSDs()
   3.329 +            
   3.330 +            
   3.331 +            for vm_name in self.attachedRSDs.keys():
   3.332 +                if self.attachedRSDs[vm_name] not in self.connectedRSDs.values():
   3.333 +                    drive = self.vmm.getNetworkDrive(vm_name)
   3.334 +                    self.vmm.unmapNetworkDrive(drive)
   3.335 +                    #self.stopVM(vm_name)
   3.336 +                    self.vmm.detachRSD(vm_name)
   3.337 +                    self.vmm.poweroffVM(vm_name)
   3.338 +                    self.vmm.removeVM(vm_name)
   3.339 +            #create new vm for attached device if any
   3.340 +            self.attachedRSDs = self.vmm.getAttachedRSDs()
   3.341 +            self.connectedRSDs = self.vmm.getConnectedRSDS()
   3.342 +            
   3.343 +            new_ip = None
   3.344 +            for connected_device in self.connectedRSDs.values():
   3.345 +                if (self.attachedRSDs and False) or (connected_device not in self.attachedRSDs.values()):
   3.346 +                    new_sdvm = self.vmm.generateSDVMName()
   3.347 +                    self.vmm.createVM(new_sdvm)
   3.348 +                    self.vmm.storageAttach(new_sdvm)
   3.349 +                    self.vmm.attachRSD(new_sdvm, connected_device)
   3.350 +                    self.vmm.startVM(new_sdvm)
   3.351 +                    new_ip = self.vmm.waitStartup(new_sdvm)
   3.352 +                    drive = self.vmm.genNetworkDrive()
   3.353 +                    if new_ip != None:
   3.354 +                        self.vmm.mapNetworkDrive(drive, '\\\\' + new_ip + '\\USB', None, None)
   3.355 +                    #TODO: cleanup notifications somwhere else (eg. machine shutdown)
   3.356 +                    self.vmm.startNotifications.remove(new_ip)
   3.357 +            #self.handleDeviceChangeLock.release()
   3.358                  
   3.359  
   3.360  if __name__ == '__main__':
   3.361 -    man = VMManager.getInstance()
   3.362 +    #man = VMManager.getInstance()
   3.363      #man.listVM()
   3.364 -    print man.getConnectedRSDs()
   3.365 +    #print man.getConnectedRSDs()
   3.366 +    #print man.getNetworkDrives()
   3.367 +    #man.genNetworkDrive()
   3.368 +    drive_bitmask = ctypes.cdll.kernel32.GetLogicalDrives()
   3.369 +    print list(itertools.compress(string.ascii_uppercase,  map(lambda x:ord(x) - ord('0'), bin(drive_bitmask)[:1:-1])))
   3.370 +    #print list(map(chr, range(68, 91))) 
   3.371      
   3.372 +    #time.sleep(-1)
   3.373      #man.listVM()
   3.374      #man.listVM()
   3.375      #man.listVM()
   3.376 @@ -531,7 +570,7 @@
   3.377      #man.genCertificateISO('SecurityDVM0')
   3.378      #man.guestExecute('SecurityDVM0', '/bin/ls -la')
   3.379      #logger = setupLogger('VMManager')
   3.380 -    c = Cygwin()
   3.381 +    #c = Cygwin()
   3.382      
   3.383      #man.sshExecute('/bin/ls -la', 'SecurityDVM0')
   3.384      #man.sshExecuteX11('/usr/bin/iceweasel', 'SecurityDVM0')
     4.1 --- a/server/windows/USBEventSvc/OpenSecUSBEventSvc/OpenSecUSBEventSvc.cpp	Fri Feb 21 11:04:04 2014 +0100
     4.2 +++ b/server/windows/USBEventSvc/OpenSecUSBEventSvc/OpenSecUSBEventSvc.cpp	Wed Feb 26 17:27:07 2014 +0100
     4.3 @@ -32,6 +32,45 @@
     4.4  VOID SvcInit(DWORD, LPTSTR *);
     4.5  VOID SvcReportEvent(WORD, LPTSTR);
     4.6  
     4.7 +// Purpose: 
     4.8 +//   Called by SCM whenever a control code is sent to the service
     4.9 +//   using the ControlService function.
    4.10 +//
    4.11 +// Parameters:
    4.12 +//   dwCtrl - control code
    4.13 +// 
    4.14 +// Return value:
    4.15 +//   None
    4.16 +//
    4.17 +VOID WINAPI SvcCtrlHandlerEx(DWORD dwCtrl, DWORD dwEventType, LPVOID lpEventData, LPVOID lpContext) {
    4.18 +	// Handle the requested control code. 
    4.19 +	switch (dwCtrl) {
    4.20 +		case SERVICE_CONTROL_STOP:
    4.21 +			UnregisterDeviceNotification(ghDeviceNotify);
    4.22 +			ReportSvcStatus(SERVICE_STOP_PENDING, NO_ERROR, 0);
    4.23 +			// Signal the service to stop.
    4.24 +			SetEvent(ghSvcStopEvent);
    4.25 +			ReportSvcStatus(gSvcStatus.dwCurrentState, NO_ERROR, 0);
    4.26 +			return;
    4.27 +
    4.28 +		case SERVICE_CONTROL_INTERROGATE:
    4.29 +			break;
    4.30 +
    4.31 +		case SERVICE_CONTROL_DEVICEEVENT:
    4.32 +			SvcReportEvent(EVENTLOG_INFORMATION_TYPE, TEXT("Received SERVICE_CONTROL_DEVICEEVENT"));
    4.33 +			//NotifyOpenSecManager();
    4.34 +			break;
    4.35 +		case SERVICE_CONTROL_HARDWAREPROFILECHANGE:
    4.36 +			SvcReportEvent(EVENTLOG_INFORMATION_TYPE, TEXT("Received SERVICE_CONTROL_HARDWAREPROFILECHANGE"));
    4.37 +			break;
    4.38 +		case SERVICE_CONTROL_POWEREVENT:
    4.39 +			SvcReportEvent(EVENTLOG_INFORMATION_TYPE, TEXT("Received SERVICE_CONTROL_POWEREVENT"));
    4.40 +			break;
    4.41 +		default:
    4.42 +			SvcReportEvent(EVENTLOG_INFORMATION_TYPE, TEXT("Received WM_event %d", dwCtrl));
    4.43 +			break;
    4.44 +	}
    4.45 +}
    4.46  
    4.47  // DoRegisterDeviceInterfaceToHwnd
    4.48  //     Registers an HWND for notification of changes in the device interfaces
    4.49 @@ -50,25 +89,50 @@
    4.50  //     so a similar wrapper function to this one supporting that scenario
    4.51  //     could be made from this template.
    4.52  
    4.53 +GUID guid =
    4.54 +GUID_DEVINTERFACE_USB_DEVICE; //{ 0xa5dcbf10, 0x6530, 0x11d2, 0x90, 0x1f, 0x00, 0xc0, 0x4f, 0xb9, 0x51, 0xed };  // USB Raw Device Interface Class GUID
    4.55 +//GUID_USB_WMI_STD_NOTIFICATION;
    4.56 +//GUID_USB_WMI_STD_DATA;
    4.57 +//GUID_DEVINTERFACE_USB_HOST_CONTROLLER;
    4.58 +//GUID_DEVINTERFACE_USB_HUB;
    4.59 +//GUID_DEVCLASS_USB;
    4.60 +//{ 0x25dbce51, 0x6c8f, 0x4a72, 0x8a, 0x6d, 0xb5, 0x4c, 0x2b, 0x4f, 0xc8, 0x35 }; // This GUID is for all USB serial host PnP drivers
    4.61 +//{ 0x88bae032, 0x5a81, 0x49f0, 0xbc, 0x3d, 0xa4, 0xff, 0x13, 0x82, 0x16, 0xd6 };
    4.62 +//{ 0x36fc9e60, 0xc465, 0x11cf, 0x80, 0x56, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00 };
    4.63 +
    4.64  BOOL DoRegisterDeviceInterfaceToHwnd(void) {
    4.65 -	DEV_BROADCAST_DEVICEINTERFACE notificationFilter;
    4.66 -	ZeroMemory(&notificationFilter, sizeof (notificationFilter));
    4.67 -	notificationFilter.dbcc_size = sizeof (DEV_BROADCAST_DEVICEINTERFACE);
    4.68 -	notificationFilter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
    4.69 -	notificationFilter.dbcc_reserved = 0;
    4.70 -	notificationFilter.dbcc_classguid = 
    4.71 -		//GUID_DEVINTERFACE_USB_DEVICE;
    4.72 -		//{ 0x25dbce51, 0x6c8f, 0x4a72, 0x8a, 0x6d, 0xb5, 0x4c, 0x2b, 0x4f, 0xc8, 0x35 }; // This GUID is for all USB serial host PnP drivers
    4.73 -		//{ 0x53f56307, 0xb6bf, 0x11d0, 0x94, 0xf2, 0x00, 0xa0, 0xc9, 0x1e, 0xfb, 0x8b }; // Disk Device Interface Class GUID
    4.74 -		//{ 0xa5dcbf10, 0x6530, 0x11d2, 0x90, 0x1f, 0x00, 0xc0, 0x4f, 0xb9, 0x51, 0xed };  // USB Raw Device Interface Class GUID
    4.75 -		//{ 0x88bae032, 0x5a81, 0x49f0, 0xbc, 0x3d, 0xa4, 0xff, 0x13, 0x82, 0x16, 0xd6 };
    4.76 -		GUID_DEVCLASS_USB;
    4.77 +	DEV_BROADCAST_DEVICEINTERFACE filter;
    4.78 +	ZeroMemory(&filter, sizeof (filter));
    4.79 +	filter.dbcc_size = sizeof (filter);
    4.80 +	filter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
    4.81 +	filter.dbcc_reserved = 0;
    4.82 +	filter.dbcc_classguid = guid;
    4.83 +	CopyMemory(&filter.dbcc_classguid,
    4.84 +		&GUID_DEVINTERFACE_USB_DEVICE,
    4.85 +		sizeof(GUID));
    4.86 +
    4.87 +	/*DEV_BROADCAST_DEVICEINTERFACE filter;
    4.88 +	ZeroMemory(&filter, sizeof (filter));
    4.89 +	filter.dbcc_size = sizeof (filter);
    4.90 +	filter.dbcc_devicetype = DBT_DEVTYP_HANDLE;
    4.91 +	filter.dbcc_reserved = 0;
    4.92 +	filter.dbcc_classguid = guid;*/
    4.93 +
    4.94  	
    4.95 -	//memcpy(&(notificationFilter.dbcc_classguid), &(GUID_DEVINTERFACE_USB_DEVICE), sizeof(struct _GUID));
    4.96 +	/*CopyMemory(	&filter.dbcc_classguid,
    4.97 +				&guid, 
    4.98 +				sizeof(GUID));*/
    4.99 +	
   4.100 +	/*DEV_BROADCAST_DEVNODE filter;
   4.101 +	ZeroMemory(&filter, sizeof (filter));
   4.102 +	filter.dbcd_size = sizeof (DEV_BROADCAST_DEVNODE);
   4.103 +	filter.dbcd_devicetype = DBT_DEVTYP_DEVNODE;
   4.104 +	filter.dbcd_reserved = 0;
   4.105 +	//filter.dbcd_devnode*/
   4.106  
   4.107  	ghDeviceNotify = RegisterDeviceNotification(	gSvcStatusHandle, 
   4.108 -													&notificationFilter,
   4.109 -													DEVICE_NOTIFY_SERVICE_HANDLE /*| DEVICE_NOTIFY_ALL_INTERFACE_CLASSES*/);
   4.110 +													&filter,
   4.111 +													DEVICE_NOTIFY_SERVICE_HANDLE | DEVICE_NOTIFY_ALL_INTERFACE_CLASSES);
   4.112  	if (NULL == ghDeviceNotify) {
   4.113  		SvcReportEvent(EVENTLOG_ERROR_TYPE, _T("RegisterDeviceNotification failed!"));
   4.114  		return FALSE;
   4.115 @@ -175,7 +239,7 @@
   4.116  //
   4.117  VOID WINAPI SvcMain(DWORD dwArgc, LPTSTR *lpszArgv) {
   4.118  	// Register the handler function for the service
   4.119 -	gSvcStatusHandle = RegisterServiceCtrlHandlerEx(SVCNAME, (LPHANDLER_FUNCTION_EX)SvcCtrlHandler, 0);
   4.120 +	gSvcStatusHandle = RegisterServiceCtrlHandlerEx(SVCNAME, (LPHANDLER_FUNCTION_EX)SvcCtrlHandlerEx, 0);
   4.121  	if (!gSvcStatusHandle) {
   4.122  		SvcReportEvent(EVENTLOG_ERROR_TYPE, TEXT("RegisterServiceCtrlHandler"));
   4.123  		return;
   4.124 @@ -305,40 +369,6 @@
   4.125  	SetServiceStatus(gSvcStatusHandle, &gSvcStatus);
   4.126  }
   4.127  
   4.128 -// Purpose: 
   4.129 -//   Called by SCM whenever a control code is sent to the service
   4.130 -//   using the ControlService function.
   4.131 -//
   4.132 -// Parameters:
   4.133 -//   dwCtrl - control code
   4.134 -// 
   4.135 -// Return value:
   4.136 -//   None
   4.137 -//
   4.138 -VOID WINAPI SvcCtrlHandler(DWORD dwCtrl) {
   4.139 -	// Handle the requested control code. 
   4.140 -	switch (dwCtrl) {
   4.141 -		case SERVICE_CONTROL_STOP:
   4.142 -			UnregisterDeviceNotification(ghDeviceNotify);
   4.143 -			ReportSvcStatus(SERVICE_STOP_PENDING, NO_ERROR, 0);
   4.144 -			// Signal the service to stop.
   4.145 -			SetEvent(ghSvcStopEvent);
   4.146 -			ReportSvcStatus(gSvcStatus.dwCurrentState, NO_ERROR, 0);
   4.147 -			return;
   4.148 -
   4.149 -		case SERVICE_CONTROL_INTERROGATE:
   4.150 -			break;
   4.151 -
   4.152 -		case SERVICE_CONTROL_DEVICEEVENT:
   4.153 -			SvcReportEvent(EVENTLOG_INFORMATION_TYPE, TEXT("Received SERVICE_CONTROL_DEVICEEVENT"));
   4.154 -			//NotifyOpenSecManager();
   4.155 -			break;
   4.156 -
   4.157 -		default:
   4.158 -			break;
   4.159 -	}
   4.160 -}
   4.161 -
   4.162  //
   4.163  // Purpose: 
   4.164  //   Logs messages to the event log
     5.1 Binary file server/windows/USBEventSvc/USBEventSvc.sdf has changed
     6.1 Binary file server/windows/USBEventSvc/USBEventSvc.v12.suo has changed
     7.1 Binary file server/windows/USBEventSvc/Win32/Debug/OpenSecUSBEventSvc.ilk has changed
     8.1 Binary file server/windows/USBEventSvc/Win32/Debug/OpenSecUSBEventSvc.pdb has changed
     9.1 Binary file server/windows/USBEventSvc/Win32/Debug/OpenSecUSBEventSvcLog.ilk has changed
    10.1 Binary file server/windows/USBEventSvc/Win32/Debug/OpenSecUSBEventSvcLog.pdb has changed
    11.1 Binary file server/windows/USBEventSvc/Win32/Release/OpenSecUSBEventSvc.pdb has changed
    12.1 Binary file server/windows/USBEventSvc/Win32/Release/OpenSecUSBEventSvcLog.pdb has changed
    13.1 Binary file server/windows/USBEventSvc/x64/Debug/OpenSecUSBEventSvcLog.ilk has changed
    14.1 Binary file server/windows/USBEventSvc/x64/Debug/OpenSecUSBEventSvcLog.pdb has changed
    15.1 Binary file server/windows/USBEventSvc/x64/Release/OpenSecUSBEventSvc.exe has changed
    16.1 Binary file server/windows/USBEventSvc/x64/Release/OpenSecUSBEventSvc.pdb has changed
    17.1 Binary file server/windows/USBEventSvc/x64/Release/OpenSecUSBEventSvcLog.dll has changed
    18.1 Binary file server/windows/USBEventSvc/x64/Release/OpenSecUSBEventSvcLog.pdb has changed