OpenSecurity/bin/vmmanager.pyw
changeset 234 216da9017f8f
parent 223 a4fb6694e6fe
child 235 8fd7b197735c
     1.1 --- a/OpenSecurity/bin/vmmanager.pyw	Wed Sep 24 16:40:43 2014 +0100
     1.2 +++ b/OpenSecurity/bin/vmmanager.pyw	Thu Oct 02 13:08:09 2014 +0100
     1.3 @@ -108,14 +108,17 @@
     1.4      systemProperties = None
     1.5      _instance = None
     1.6      machineFolder = ''
     1.7 -    rsdHandler = None
     1.8      hostonlyIF = None
     1.9 -    browsingManager = None
    1.10 +    
    1.11      blacklistedRSD = None
    1.12      status_message = 'Starting up...'
    1.13      templateImage = None
    1.14      importHandler = None
    1.15      updateHandler = None
    1.16 +    deviceHandler = None
    1.17 +    sdvmFactory = None
    1.18 +    vms = dict()
    1.19 +    
    1.20   
    1.21      def __init__(self):
    1.22          # only proceed if we have a working background environment
    1.23 @@ -145,9 +148,6 @@
    1.24                  props = dict((k.strip(),v.strip().strip('"')) for k,v in (line.split(':', 1) for line in item.strip().splitlines()))
    1.25                  ifs[props["Name"]] = props
    1.26          return ifs
    1.27 -                    
    1.28 -        #props = dict((k.strip(),v.strip().strip('"')) for k,v in (line.split(':', 1) for line in result.strip().splitlines()))
    1.29 -        #return props
    1.30      
    1.31      #list the hostonly IFs exposed by the VBox host
    1.32      @staticmethod    
    1.33 @@ -239,19 +239,6 @@
    1.34          self.status_message = 'All is ok.'
    1.35          return True
    1.36      
    1.37 -    def stop(self):
    1.38 -        Cygwin.denyExec()
    1.39 -        if self.rsdHandler != None:
    1.40 -            self.rsdHandler.stop()
    1.41 -            self.rsdHandler.join()
    1.42 -            self.rsdHandler = None
    1.43 -            
    1.44 -        if self.browsingManager != None:
    1.45 -            self.browsingManager.stop()
    1.46 -            self.browsingManager.join()
    1.47 -            self.browsingManager = None
    1.48 -        Cygwin.allowExec()
    1.49 -    
    1.50      def start(self, force = False):
    1.51          if not force:
    1.52              if self.importHandler and self.importHandler.isAlive():
    1.53 @@ -265,11 +252,23 @@
    1.54          self.stop()
    1.55          Cygwin.allowExec()
    1.56          if self.backend_ok() and self.template_installed():
    1.57 -            self.browsingManager = BrowsingManager(self)
    1.58 -            self.browsingManager.start()
    1.59 -            self.rsdHandler = DeviceHandler(self)
    1.60 -            self.rsdHandler.start()
    1.61 +            self.sdvmFactory = SDVMFactory(self)
    1.62 +            self.sdvmFactory.start()
    1.63 +            self.deviceHandler = DeviceHandler(self)
    1.64 +            self.deviceHandler.start()
    1.65 +    
    1.66 +    def stop(self):
    1.67 +        Cygwin.denyExec()
    1.68 +        if self.sdvmFactory != None:
    1.69 +            self.sdvmFactory.stop()
    1.70 +            self.sdvmFactory.join()
    1.71 +            self.sdvmFactory = None
    1.72 +        if self.deviceHandler != None:
    1.73 +            self.deviceHandler.stop()
    1.74 +            self.deviceHandler.join()
    1.75 +            self.deviceHandler = None
    1.76          
    1.77 +        Cygwin.allowExec()
    1.78  
    1.79      def cleanup(self):
    1.80          self.stop()
    1.81 @@ -740,7 +739,7 @@
    1.82          return network_drives
    1.83      
    1.84      # handles browsing request    
    1.85 -    def handleBrowsingRequest(self, proxy, wpad):
    1.86 +    def handleBrowsingRequest(self, proxy = None, wpad = None):
    1.87          showTrayMessage('Starting Secure Browsing...', 7000)
    1.88          handler = BrowsingHandler(self, proxy, wpad)
    1.89          handler.start()
    1.90 @@ -774,17 +773,6 @@
    1.91          #value, type = win32api.RegQueryValueEx(key, "ProfileImagePath")
    1.92          #print value
    1.93      
    1.94 -    def backupFile(self, src, dest):
    1.95 -        certificate = Cygwin.cygPath(self.getMachineFolder()) + '/' + self.browsingManager.vm_name + '/dvm_key'
    1.96 -        command = '-r -o StrictHostKeyChecking=no -i "' + certificate + '" "osecuser@' + self.browsingManager.ip_addr + ':' + src + '" "' + dest + '"'
    1.97 -        return Cygwin.execute(Cygwin.cygwin_scp, command, wait_return=True, window=False)
    1.98 -    
    1.99 -    def restoreFile(self, src, dest):
   1.100 -        certificate = Cygwin.cygPath(self.getMachineFolder()) + '/' + self.browsingManager.vm_name + '/dvm_key'
   1.101 -        #command = '-r -v -o StrictHostKeyChecking=no -i \"' + certificate + '\" \"' + src + '\" \"osecuser@' + self.browsingManager.ip_addr + ':' + dest + '\"'
   1.102 -        command = '-r -o StrictHostKeyChecking=no -i "' + certificate + '" "' + src + '" "osecuser@' + self.browsingManager.ip_addr + ':' + dest + '"'
   1.103 -        return Cygwin.execute(Cygwin.cygwin_scp, command, wait_return=True, window=False)
   1.104 -    
   1.105      #import initial template
   1.106      def importTemplate(self, image_path):
   1.107          import_logger.info('Stopping Opensecurity...')
   1.108 @@ -926,6 +914,251 @@
   1.109          self.updateHandler = UpdateHandler(self)
   1.110          self.updateHandler.start()
   1.111          import_logger.info("Initial import started.")
   1.112 +        
   1.113 +    def createSession(self):
   1.114 +        new_sdvm = self.newSDVM()
   1.115 +        self.attachVDisk(new_sdvm, 'SATA', '0', '0', self.templateImage)
   1.116 +        self.genCertificate(new_sdvm)
   1.117 +        self.attachCertificate(new_sdvm)
   1.118 +        self.startVM(new_sdvm)
   1.119 +        new_ip = self.waitStartup(new_sdvm)
   1.120 +        if new_ip == None:
   1.121 +            logger.error("Error getting IP address of SDVM. Cleaning up.")
   1.122 +            self.poweroffVM(new_sdvm)
   1.123 +            self.removeVM(new_sdvm)
   1.124 +            return None
   1.125 +        else:
   1.126 +            logger.info("Got IP address for " + new_sdvm + ' ' + new_ip)
   1.127 +            self.vms[new_sdvm] = {'vm_name' : new_sdvm, 'ip_addr' : new_ip, 'used' : False, 'running' : True}
   1.128 +            return self.vms[new_sdvm]
   1.129 +            
   1.130 +    def releaseSession(self, vm_name):
   1.131 +        del self.vms[vm_name]
   1.132 +        self.poweroffVM(vm_name)
   1.133 +        self.removeVM(vm_name)
   1.134 +        self.sdvmFactory.trigger()
   1.135 +        
   1.136 +    def getSession(self):
   1.137 +        # return first found unused SDVM
   1.138 +        for vm in self.vms.values():
   1.139 +            if vm['used'] == False:
   1.140 +                vm['used'] = True
   1.141 +                self.sdvmFactory.trigger()
   1.142 +                return vm
   1.143 +        return self.createSession()
   1.144 +        
   1.145 +class SDVMFactory(threading.Thread):
   1.146 +    vmm = None
   1.147 +    running = True
   1.148 +    triggerEv = None
   1.149 +    
   1.150 +    def __init__(self, vmmanager):
   1.151 +        threading.Thread.__init__(self)
   1.152 +        self.vmm = vmmanager
   1.153 +        self.triggerEv = threading.Event()
   1.154 +        
   1.155 +    def run(self):
   1.156 +        while self.running:
   1.157 +            self.triggerEv.clear()            
   1.158 +
   1.159 +            if len(self.vmm.vms) < 2:
   1.160 +                self.vmm.createSession()
   1.161 +                continue
   1.162 +            unused = 0
   1.163 +            for vm in self.vmm.vms.values():
   1.164 +                if vm['used'] == False:
   1.165 +                    unused+=1
   1.166 +            if unused == 0:
   1.167 +                self.vmm.createSession()
   1.168 +            self.triggerEv.wait()
   1.169 +    
   1.170 +    def trigger(self):
   1.171 +        self.triggerEv.set()
   1.172 +        
   1.173 +    def stop(self):
   1.174 +        self.running = False
   1.175 +        self.triggerEv.set()
   1.176 +        
   1.177 +#handles browsing session creation 
   1.178 +class BrowsingHandler(threading.Thread):
   1.179 +    vmm = None
   1.180 +    proxy = None
   1.181 +    wpad = None
   1.182 +    net_resource = None
   1.183 +    ip_addr = None
   1.184 +    vm_name = None
   1.185 +    
   1.186 +    def __init__(self, vmmanager, proxy, wpad):
   1.187 +        threading.Thread.__init__(self)
   1.188 +        self.vmm = vmmanager
   1.189 +        self.proxy = proxy
   1.190 +        self.wpad = wpad
   1.191 +        
   1.192 +    def run(self):
   1.193 +        session = None
   1.194 +        try:
   1.195 +            appDataDir = self.getAppDataDir()
   1.196 +
   1.197 +            session = self.vmm.getSession()
   1.198 +            if not session:
   1.199 +                raise OpenSecurityException("Could not get new SDVM session.")
   1.200 +            
   1.201 +            self.ip_addr = session['ip_addr']
   1.202 +            self.vm_name = session['vm_name']
   1.203 +            
   1.204 +            self.net_resource = '\\\\' + self.ip_addr + '\\Download'
   1.205 +            urllib2.urlopen('http://127.0.0.1:8090/netmount?'+'net_resource='+self.net_resource).readline()
   1.206 +            
   1.207 +            logger.info("Restoring browser settings in AppData dir " + appDataDir)
   1.208 +            # create OpenSecurity settings dir on local machine user home /AppData/Roaming 
   1.209 +            Cygwin.bashExecute('/usr/bin/mkdir -p \\\"' + appDataDir + '/OpenSecurity\\\"')
   1.210 +            # create chromium settings dir on local machine if not existing
   1.211 +            Cygwin.bashExecute('/usr/bin/mkdir -p \\\"' + appDataDir + '/OpenSecurity/chromium\\\"')
   1.212 +            # create chromium settings dir on remote machine if not existing
   1.213 +            Cygwin.sshExecute('"mkdir -p \\\"/home/osecuser/.config\\\""', self.ip_addr, 'osecuser', Cygwin.cygPath(self.vmm.getMachineFolder()) + '/' + self.vm_name + '/dvm_key')
   1.214 +            #restore settings on vm
   1.215 +            self.restoreFile(appDataDir + '/OpenSecurity/chromium', '/home/osecuser/.config/')
   1.216 +                    
   1.217 +            if self.wpad:
   1.218 +                browser = '\\\"/usr/bin/chromium --proxy-pac-url=\\\"'+self.wpad+'\\\"\\\"'
   1.219 +            elif self.proxy:
   1.220 +                browser = '\\\"export http_proxy='+self.proxy+'; /usr/bin/chromium\\\"'
   1.221 +            else:
   1.222 +                browser = '\\\"/usr/bin/chromium\\\"'
   1.223 +                
   1.224 +            Cygwin.sshExecuteX11(browser, self.ip_addr, 'osecuser', Cygwin.cygPath(self.vmm.getMachineFolder()) + '/' + self.vm_name + '/dvm_key')
   1.225 +            self.backupFile('/home/osecuser/.config/chromium', appDataDir + '/OpenSecurity/')
   1.226 +        
   1.227 +        except urllib2.URLError:
   1.228 +            logger.error("Network drive connect failed. OpenSecurity Tray client not running.")
   1.229 +            self.net_resource = None
   1.230 +
   1.231 +        except:
   1.232 +            logger.info("BrowsingHandler failed. See log for details")
   1.233 +        
   1.234 +        if session:
   1.235 +            if self.net_resource == None:
   1.236 +                logger.info("Missing browsing SDVM's network share. Skipping disconnect")
   1.237 +            else:
   1.238 +                try:
   1.239 +                    urllib2.urlopen('http://127.0.0.1:8090/netumount?'+'net_resource='+self.net_resource).readline()
   1.240 +                    self.net_resource = None
   1.241 +                except urllib2.URLError:
   1.242 +                    logger.error("Network share disconnect failed. OpenSecurity Tray client not running.")
   1.243 +        if self.vm_name:
   1.244 +            self.vmm.releaseSession(self.vm_name)
   1.245 +        
   1.246 +        self.vmm.sdvmFactory.trigger()
   1.247 +
   1.248 +    def backupFile(self, src, dest):
   1.249 +        certificate = Cygwin.cygPath(self.vmm.getMachineFolder()) + '/' + self.vm_name + '/dvm_key'
   1.250 +        command = '-r -o StrictHostKeyChecking=no -i "' + certificate + '" "osecuser@' + self.ip_addr + ':' + src + '" "' + dest + '"'
   1.251 +        return Cygwin.execute(Cygwin.cygwin_scp, command, wait_return=True, window=False)
   1.252 +    
   1.253 +    def restoreFile(self, src, dest):
   1.254 +        certificate = Cygwin.cygPath(self.vmm.getMachineFolder()) + '/' + self.vm_name + '/dvm_key'
   1.255 +        command = '-r -o StrictHostKeyChecking=no -i "' + certificate + '" "' + src + '" "osecuser@' + self.ip_addr + ':' + dest + '"'
   1.256 +        return Cygwin.execute(Cygwin.cygwin_scp, command, wait_return=True, window=False)
   1.257 +                
   1.258 +    def getAppDataDir(self):
   1.259 +        user = self.vmm.getActiveUserName()
   1.260 +        if user == None:
   1.261 +            logger.error("Cannot get active user name")
   1.262 +            raise OpenSecurityException("Cannot get active user name")
   1.263 +        else:
   1.264 +            logger.info('Got active user name ' + user)
   1.265 +        sid = self.vmm.getUserSID(user)
   1.266 +        if sid == None:
   1.267 +            logger.error("Cannot get SID for active user")
   1.268 +            raise OpenSecurityException("Cannot get SID for active user")
   1.269 +        else:
   1.270 +            logger.info("Got active user SID " + sid + " for user " + user)
   1.271 +            
   1.272 +        path = self.vmm.getAppDataDir(sid)
   1.273 +        if path == None:
   1.274 +            logger.error("Cannot get AppDataDir for active user")
   1.275 +            raise OpenSecurityException("Cannot get AppDataDir for active user")
   1.276 +        else:
   1.277 +            logger.info("Got AppData dir for user " + user + ': ' + path)
   1.278 +        
   1.279 +        return Cygwin.cygPath(path)
   1.280 +            
   1.281 +                
   1.282 +class DeviceHandler(threading.Thread): 
   1.283 +    vmm = None
   1.284 +    existingRSDs = None
   1.285 +    attachedRSDs = None  
   1.286 +    running = True
   1.287 +    def __init__(self, vmmanger): 
   1.288 +        threading.Thread.__init__(self)
   1.289 +        self.vmm = vmmanger
   1.290 + 
   1.291 +    def stop(self):
   1.292 +        self.running = False
   1.293 +        
   1.294 +    def run(self):
   1.295 +        self.existingRSDs = dict()
   1.296 +        self.attachedRSDs = self.vmm.getAttachedRSDs()
   1.297 +        
   1.298 +        while self.running:
   1.299 +            tmp_rsds = self.vmm.getExistingRSDs()
   1.300 +            if tmp_rsds.keys() == self.existingRSDs.keys():
   1.301 +                logger.debug("Nothing's changed. sleep(3)")
   1.302 +                time.sleep(3)
   1.303 +                continue
   1.304 +            
   1.305 +            showTrayMessage('System changed.\nEvaluating...', 7000)
   1.306 +            logger.info("Something's changed")
   1.307 +            
   1.308 +            tmp_attached = self.attachedRSDs     
   1.309 +            for vm_name in tmp_attached.keys():
   1.310 +                if tmp_attached[vm_name] not in tmp_rsds.values():
   1.311 +                    ip = self.vmm.getHostOnlyIP(vm_name)
   1.312 +                    if ip == None:
   1.313 +                        logger.error("Failed getting hostonly IP for " + vm_name)
   1.314 +                        continue
   1.315 +                    
   1.316 +                    try:
   1.317 +                        net_resource = '\\\\' + ip + '\\USB'
   1.318 +                        result = urllib2.urlopen('http://127.0.0.1:8090/netumount?'+'net_resource='+net_resource).readline()
   1.319 +                    except urllib2.URLError:
   1.320 +                        logger.error("Network drive disconnect failed. OpenSecurity Tray client not running.")
   1.321 +                        continue
   1.322 +                    
   1.323 +                    # detach not necessary as already removed from vm description upon disconnect
   1.324 +                    del self.attachedRSDs[vm_name]
   1.325 +                    self.vmm.releaseSession(vm_name)
   1.326 +                    
   1.327 +            #create new vms for new devices if any
   1.328 +            new_ip = None
   1.329 +            for new_device in tmp_rsds.values():
   1.330 +                showTrayMessage('Mounting device...', 7000)
   1.331 +                if (self.attachedRSDs and False) or (new_device not in self.attachedRSDs.values()):
   1.332 +                   
   1.333 +                    session = self.vmm.getSession()
   1.334 +                    if not session:
   1.335 +                        logger.info("Could not get new SDVM session.")
   1.336 +                        continue
   1.337 +                        #raise OpenSecurityException("Could not get new SDVM session.")
   1.338 +                    new_sdvm = session['vm_name']
   1.339 +                    new_ip = session['ip_addr']
   1.340 +                    try:
   1.341 +                        self.vmm.attachRSD(new_sdvm, new_device)
   1.342 +                        self.attachedRSDs[new_sdvm] = new_device
   1.343 +                    except:
   1.344 +                        logger.info("RSD prematurely removed. Cleaning up.")
   1.345 +                        self.vmm.releaseSession(new_sdvm)
   1.346 +                        continue
   1.347 +                    
   1.348 +                    try:
   1.349 +                        net_resource = '\\\\' + new_ip + '\\USB'
   1.350 +                        result = urllib2.urlopen('http://127.0.0.1:8090/netmount?'+'net_resource='+net_resource).readline()
   1.351 +                    except urllib2.URLError:
   1.352 +                        logger.error("Network drive connect failed (tray client not accessible). Cleaning up.")
   1.353 +                        self.vmm.releaseSession(new_sdvm)
   1.354 +                        continue
   1.355 +                    
   1.356 +            self.existingRSDs = tmp_rsds
   1.357  
   1.358  class UpdateHandler(threading.Thread):
   1.359      vmm = None    
   1.360 @@ -952,219 +1185,4 @@
   1.361              self.vmm.updateTemplate()
   1.362          except:
   1.363              import_logger.info("Initial import failed. Refer to service log for details.")
   1.364 -        self.vmm.start(force=True)
   1.365 -            
   1.366 -#handles browsing session creation 
   1.367 -class BrowsingHandler(threading.Thread):
   1.368 -    vmm = None
   1.369 -    proxy = None
   1.370 -    wpad = None
   1.371 -    def __init__(self, vmmanager, proxy, wpad):
   1.372 -        threading.Thread.__init__(self)
   1.373 -        self.vmm = vmmanager
   1.374 -        self.proxy = proxy
   1.375 -        self.wpad = wpad
   1.376 -        
   1.377 -    def run(self):
   1.378 -        #browser = '\\\"/usr/bin/chromium; pidof dbus-launch | xargs kill\\\"'
   1.379 -        #browser = '\\\"/usr/bin/chromium\\\"'
   1.380 -        
   1.381 -        try:
   1.382 -            if self.wpad:
   1.383 -                browser = '\\\"/usr/bin/chromium --proxy-pac-url=\\\"'+self.wpad+'\\\"\\\"'
   1.384 -            elif self.proxy:
   1.385 -                browser = '\\\"export http_proxy='+self.proxy+'; /usr/bin/chromium\\\"'
   1.386 -            else:
   1.387 -                browser = '\\\"/usr/bin/chromium\\\"'
   1.388 -                
   1.389 -            self.vmm.browsingManager.started.wait() 
   1.390 -            result = Cygwin.sshExecuteX11(browser, self.vmm.browsingManager.ip_addr, 'osecuser', Cygwin.cygPath(self.vmm.getMachineFolder()) + '/' + self.vmm.browsingManager.vm_name + '/dvm_key')
   1.391 -            self.vmm.backupFile('/home/osecuser/.config/chromium', self.vmm.browsingManager.appDataDir + '/OpenSecurity/')
   1.392 -        except:
   1.393 -            logger.info("BrowsingHandler closing. Restarting browsing SDVM.")
   1.394 -
   1.395 -        self.vmm.browsingManager.restart.set()
   1.396 -        
   1.397 -            
   1.398 -# handles browsing Vm creation and destruction                    
   1.399 -class BrowsingManager(threading.Thread):   
   1.400 -    vmm = None
   1.401 -    running = True
   1.402 -    restart = None
   1.403 -    ip_addr = None
   1.404 -    vm_name = None
   1.405 -    net_resource = None
   1.406 -    appDataDir = None
   1.407 -    
   1.408 -    def __init__(self, vmmanager):
   1.409 -        threading.Thread.__init__(self)
   1.410 -        self.vmm = vmmanager
   1.411 -        self.restart = threading.Event()
   1.412 -        self.started = threading.Event()
   1.413 -    
   1.414 -    def stop(self):
   1.415 -        self.running = False
   1.416 -        self.restart.set()   
   1.417 -     
   1.418 -    def run(self):
   1.419 -        while self.running:
   1.420 -            self.restart.clear()
   1.421 -            self.started.clear()
   1.422 -            
   1.423 -            if self.net_resource == None:
   1.424 -                logger.info("Missing browsing SDVM's network share. Skipping disconnect")
   1.425 -            else:
   1.426 -                try:
   1.427 -                    browsing_vm = urllib2.urlopen('http://127.0.0.1:8090/netumount?'+'net_resource='+self.net_resource).readline()
   1.428 -                    self.net_resource = None
   1.429 -                except urllib2.URLError:
   1.430 -                    logger.error("Network share disconnect failed. OpenSecurity Tray client not running.")
   1.431 -                    continue
   1.432 -            
   1.433 -            self.ip_addr = None
   1.434 -
   1.435 -            if self.vm_name != None:
   1.436 -                self.vmm.poweroffVM(self.vm_name)
   1.437 -                self.vmm.removeVM(self.vm_name)
   1.438 -            
   1.439 -            try:
   1.440 -                self.vm_name = self.vmm.newSDVM()
   1.441 -                self.vmm.attachVDisk(self.vm_name, 'SATA', '0', '0', self.vmm.templateImage)
   1.442 -                self.vmm.genCertificate(self.vm_name)
   1.443 -                self.vmm.attachCertificate(self.vm_name)
   1.444 -                
   1.445 -                self.vmm.startVM(self.vm_name)
   1.446 -                
   1.447 -                self.ip_addr = self.vmm.waitStartup(self.vm_name)
   1.448 -                if self.ip_addr == None:
   1.449 -                    logger.error("Failed to get ip address")
   1.450 -                    continue
   1.451 -                else:
   1.452 -                    logger.info("Got IP address for " + self.vm_name + ' ' + self.ip_addr)
   1.453 -                
   1.454 -                try:
   1.455 -                    self.net_resource = '\\\\' + self.ip_addr + '\\Download'
   1.456 -                    result = urllib2.urlopen('http://127.0.0.1:8090/netmount?'+'net_resource='+self.net_resource).readline()
   1.457 -                except urllib2.URLError:
   1.458 -                    logger.error("Network drive connect failed. OpenSecurity Tray client not running.")
   1.459 -                    self.net_resource = None
   1.460 -                    continue
   1.461 -                
   1.462 -                user = self.vmm.getActiveUserName()
   1.463 -                if user == None:
   1.464 -                    logger.error("Cannot get active user name")
   1.465 -                    continue
   1.466 -                else:
   1.467 -                    logger.info('Got active user name ' + user)
   1.468 -                sid = self.vmm.getUserSID(user)
   1.469 -                if sid == None:
   1.470 -                    logger.error("Cannot get SID for active user")
   1.471 -                    continue
   1.472 -                else:
   1.473 -                    logger.info("Got active user SID " + sid + " for user " + user)
   1.474 -                    
   1.475 -                path = self.vmm.getAppDataDir(sid)
   1.476 -                if path == None:
   1.477 -                    logger.error("Cannot get AppDataDir for active user")
   1.478 -                    continue
   1.479 -                else:
   1.480 -                    logger.info("Got AppData dir for user " + user + ': ' + path)
   1.481 -                
   1.482 -                self.appDataDir = Cygwin.cygPath(path)
   1.483 -                logger.info("Restoring browser settings in AppData dir " + self.appDataDir)
   1.484 -                # create OpenSecurity settings dir on local machine user home /AppData/Roaming 
   1.485 -                Cygwin.bashExecute('/usr/bin/mkdir -p \\\"' + self.appDataDir + '/OpenSecurity\\\"')
   1.486 -                # create chromium settings dir on local machine if not existing
   1.487 -                Cygwin.bashExecute('/usr/bin/mkdir -p \\\"' + self.appDataDir + '/OpenSecurity/chromium\\\"')
   1.488 -                # create chromium settings dir on remote machine if not existing
   1.489 -                Cygwin.sshExecute('"mkdir -p \\\"/home/osecuser/.config\\\""', self.ip_addr, 'osecuser', Cygwin.cygPath(self.vmm.getMachineFolder()) + '/' + self.vm_name + '/dvm_key')
   1.490 -                #restore settings on vm
   1.491 -                self.vmm.restoreFile(self.appDataDir + '/OpenSecurity/chromium', '/home/osecuser/.config/')
   1.492 -                self.started.set()
   1.493 -                logger.info("Browsing SDVM running.")
   1.494 -                self.restart.wait()
   1.495 -            except Exception as e:
   1.496 -                logger.error("Unexpected error: ".join(e))
   1.497 -                logger.error("BrowsingHandler failed. Cleaning up")
   1.498 -                #self.running= False
   1.499 -                
   1.500 -class DeviceHandler(threading.Thread): 
   1.501 -    vmm = None
   1.502 -    existingRSDs = None
   1.503 -    attachedRSDs = None  
   1.504 -    running = True
   1.505 -    def __init__(self, vmmanger): 
   1.506 -        threading.Thread.__init__(self)
   1.507 -        self.vmm = vmmanger
   1.508 - 
   1.509 -    def stop(self):
   1.510 -        self.running = False
   1.511 -        
   1.512 -    def run(self):
   1.513 -        self.existingRSDs = dict()
   1.514 -        self.attachedRSDs = self.vmm.getAttachedRSDs()
   1.515 -        
   1.516 -        while self.running:
   1.517 -            tmp_rsds = self.vmm.getExistingRSDs()
   1.518 -            if tmp_rsds.keys() == self.existingRSDs.keys():
   1.519 -                logger.debug("Nothing's changed. sleep(3)")
   1.520 -                time.sleep(3)
   1.521 -                continue
   1.522 -            
   1.523 -            showTrayMessage('System changed.\nEvaluating...', 7000)
   1.524 -            logger.info("Something's changed")
   1.525 -            tmp_attached = self.attachedRSDs     
   1.526 -            for vm_name in tmp_attached.keys():
   1.527 -                if tmp_attached[vm_name] not in tmp_rsds.values():
   1.528 -                    ip = self.vmm.getHostOnlyIP(vm_name)
   1.529 -                    if ip == None:
   1.530 -                        logger.error("Failed getting hostonly IP for " + vm_name)
   1.531 -                        continue
   1.532 -                    try:
   1.533 -                        net_resource = '\\\\' + ip + '\\USB'
   1.534 -                        result = urllib2.urlopen('http://127.0.0.1:8090/netumount?'+'net_resource='+net_resource).readline()
   1.535 -                    except urllib2.URLError:
   1.536 -                        logger.error("Network drive disconnect failed. OpenSecurity Tray client not running.")
   1.537 -                        continue
   1.538 -                    
   1.539 -                    # detach not necessary as already removed from vm description upon disconnect
   1.540 -                    #self.vmm.detachRSD(vm_name, self.attachedRSDs[vm_name])
   1.541 -                    del self.attachedRSDs[vm_name]
   1.542 -                    self.vmm.poweroffVM(vm_name)
   1.543 -                    self.vmm.removeVM(vm_name)
   1.544 -                    #break
   1.545 -                    
   1.546 -            #create new vms for new devices if any
   1.547 -            new_ip = None
   1.548 -            for new_device in tmp_rsds.values():
   1.549 -                showTrayMessage('Mounting device...', 7000)
   1.550 -                if (self.attachedRSDs and False) or (new_device not in self.attachedRSDs.values()):
   1.551 -                    new_sdvm = self.vmm.newSDVM()
   1.552 -                    self.vmm.attachVDisk(new_sdvm, 'SATA', '0', '0', self.vmm.templateImage)
   1.553 -                    self.vmm.startVM(new_sdvm)
   1.554 -                    new_ip = self.vmm.waitStartup(new_sdvm)
   1.555 -                    if new_ip == None:
   1.556 -                        logger.error("Error getting IP address of SDVM. Cleaning up.")
   1.557 -                        self.vmm.poweroffVM(new_sdvm)
   1.558 -                        self.vmm.removeVM(new_sdvm)
   1.559 -                        continue
   1.560 -                    else:
   1.561 -                        logger.info("Got IP address for " + new_sdvm + ' ' + new_ip)
   1.562 -                    try:
   1.563 -                        self.vmm.attachRSD(new_sdvm, new_device)
   1.564 -                        self.attachedRSDs[new_sdvm] = new_device
   1.565 -                    except:
   1.566 -                        logger.info("RSD prematurely removed. Cleaning up.")
   1.567 -                        self.vmm.poweroffVM(new_sdvm)
   1.568 -                        self.vmm.removeVM(new_sdvm)
   1.569 -                        continue
   1.570 -                    try:
   1.571 -                        net_resource = '\\\\' + new_ip + '\\USB'
   1.572 -                        result = urllib2.urlopen('http://127.0.0.1:8090/netmount?'+'net_resource='+net_resource).readline()
   1.573 -                    except urllib2.URLError:
   1.574 -                        logger.error("Network drive connect failed (tray client not accessible). Cleaning up.")
   1.575 -                        self.vmm.poweroffVM(new_sdvm)
   1.576 -                        self.vmm.removeVM(new_sdvm)
   1.577 -                        continue
   1.578 -                    
   1.579 -            self.existingRSDs = tmp_rsds
   1.580 +        self.vmm.start(force=True)
   1.581 \ No newline at end of file