- changed opensecurity to always hold at least 2 SDVM sessions to be ready when needed
authorBarthaM@N3SIM1218.D03.arc.local
Thu, 02 Oct 2014 13:08:09 +0100
changeset 234216da9017f8f
parent 233 bab44ef66a3c
child 235 8fd7b197735c
- changed opensecurity to always hold at least 2 SDVM sessions to be ready when needed
- added automatic wpad proxy detection
OpenSecurity/bin/opensecurity_tray.pyw
OpenSecurity/bin/proxy_getter.py
OpenSecurity/bin/test_vmmanager.pyw
OpenSecurity/bin/vmmanager.pyw
     1.1 --- a/OpenSecurity/bin/opensecurity_tray.pyw	Thu Oct 02 13:20:37 2014 +0200
     1.2 +++ b/OpenSecurity/bin/opensecurity_tray.pyw	Thu Oct 02 13:08:09 2014 +0100
     1.3 @@ -39,8 +39,6 @@
     1.4  import urllib
     1.5  import urllib2
     1.6  import webbrowser
     1.7 -import _winreg
     1.8 -import re
     1.9  
    1.10  from PyQt4 import QtCore
    1.11  from PyQt4 import QtGui
    1.12 @@ -52,11 +50,11 @@
    1.13      from cygwin import Cygwin
    1.14  
    1.15  import opensecurity_client_restful_server 
    1.16 +import proxy_getter
    1.17  from ui import AboutDialog
    1.18  from ui import ConfigureDialog
    1.19  from ui import opensecurity_rc
    1.20  
    1.21 -
    1.22  # ------------------------------------------------------------
    1.23  # code
    1.24  
    1.25 @@ -106,32 +104,6 @@
    1.26          """clicked about"""
    1.27          d = AboutDialog()
    1.28          d.exec_()
    1.29 -    
    1.30 -    def getProxySettings(self):        
    1.31 -        aReg = _winreg.ConnectRegistry(None,_winreg.HKEY_CURRENT_USER)
    1.32 -        aKey = _winreg.OpenKey(aReg, r"Software\Microsoft\Windows\CurrentVersion\Internet Settings")
    1.33 -        subCount, valueCount, lastModified = _winreg.QueryInfoKey(aKey)
    1.34 -        reg_entries = dict()
    1.35 -        for i in range(valueCount):                                           
    1.36 -            try:
    1.37 -                n,v,t = _winreg.EnumValue(aKey,i)
    1.38 -                reg_entries[n] = v
    1.39 -            except EnvironmentError:                                               
    1.40 -                break
    1.41 -        _winreg.CloseKey(aKey)
    1.42 -        
    1.43 -        if 'AutoConfigURL' in reg_entries.keys():
    1.44 -            return {'ProxyAutoConfigURL': reg_entries['AutoConfigURL']}
    1.45 -
    1.46 -        if 'ProxyEnable' in reg_entries.keys() and reg_entries['ProxyEnable'] == 1:
    1.47 -            proxy_search = re.search(r"(?<=http=)(?P<ProxyServer>.*?)(?=;)", reg_entries['ProxyServer'])
    1.48 -            if proxy_search:
    1.49 -                proxies = proxy_search.groupdict()
    1.50 -                if 'ProxyServer' in proxies.keys(): # found http proxy
    1.51 -                    return {'ProxyServer': proxies['ProxyServer']}  
    1.52 -            return {'ProxyServer': reg_entries['ProxyServer']}
    1.53 -            
    1.54 -        return None
    1.55  
    1.56      def clicked_browser(self):
    1.57          """wish for safe internet browsing"""
    1.58 @@ -150,7 +122,7 @@
    1.59              urllib2.install_opener(opener)
    1.60  
    1.61              req_data = ""
    1.62 -            proxy = self.getProxySettings()
    1.63 +            proxy = proxy_getter.getProxySettings()
    1.64              if proxy:
    1.65                  req_data = '?' + urllib.urlencode(proxy) 
    1.66              req = 'http://127.0.0.1:8080/browsing'+ req_data
    1.67 @@ -187,14 +159,11 @@
    1.68              return
    1.69  
    1.70          try:
    1.71 -        
    1.72              # get a proper browsing VM
    1.73              Cygwin.start_X11()
    1.74 -
    1.75              # TODO: HARDCODED ADDRESS OF OPENSECURITYD
    1.76              url = 'http://127.0.0.1:8080/sdvms/' + j['vm'] + '/application' + j['application']
    1.77              result = urllib2.urlopen(url).readline()
    1.78 -            
    1.79          except:
    1.80              pass 
    1.81              
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/OpenSecurity/bin/proxy_getter.py	Thu Oct 02 13:08:09 2014 +0100
     2.3 @@ -0,0 +1,105 @@
     2.4 +import socket
     2.5 +import os
     2.6 +import httplib
     2.7 +import sys
     2.8 +import _winreg
     2.9 +import re
    2.10 +
    2.11 +DNS_WPAD_FILENAME = "wpad.dat"
    2.12 +
    2.13 +def check_for_wpad_file(server, path):
    2.14 +
    2.15 +    wpad_url = "http://%s/%s"%(server, path)
    2.16 +    print "checking", wpad_url
    2.17 +    try:
    2.18 +        conn = httplib.HTTPConnection(server)
    2.19 +        conn.request("HEAD", "/%s"%path)
    2.20 +        r = conn.getresponse()
    2.21 +        if r.status == 200:
    2.22 +            return wpad_url
    2.23 +    except Exception, e:
    2.24 +        return None
    2.25 +
    2.26 +    return None
    2.27 +
    2.28 +def get_wpad_server_searchlist():
    2.29 +    #get fully-qualified hostname
    2.30 +    fqhn = socket.getfqdn().split(" ")[0]
    2.31 +    
    2.32 +    #do we really have a fully-qualified name?
    2.33 +    #if not, linux offers a second possibility
    2.34 +    if fqhn.count(".") == 0 and os.name == 'posix':
    2.35 +        #weird method to get own ip address and fqhn 
    2.36 +        s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    2.37 +        s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
    2.38 +        s.connect(('<broadcast>', 0))
    2.39 +        my_ip = s.getsockname()[0]
    2.40 +        s.close()
    2.41 +        fqhn = socket.gethostbyaddr(my_ip)[0]
    2.42 +
    2.43 +    parts = fqhn.split(".")
    2.44 +    if len(parts) < 3:
    2.45 +        return []
    2.46 +
    2.47 +    servers = []
    2.48 +    parts[0] = "wpad"
    2.49 +    servers.append(".".join(parts))
    2.50 +    parts = parts[0:1]+parts[2:]
    2.51 +    #not correct for some suffixes, but everyone does it that way, see wikipedia for details
    2.52 +    while len(parts) >= 3:
    2.53 +        servers.append(".".join(parts))
    2.54 +        parts = parts[0:1]+parts[2:]
    2.55 +
    2.56 +    return servers
    2.57 +
    2.58 +def search_for_wpad_url():
    2.59 +    #TODO: According to RFC we should check DHCP first, but it isn't used often
    2.60 +    #check most common case first
    2.61 +    wpad_server = "wpad"
    2.62 +    wpad_url = check_for_wpad_file(wpad_server, DNS_WPAD_FILENAME)
    2.63 +    if wpad_url:
    2.64 +        return wpad_url
    2.65 +
    2.66 +    #wpad DNS search procedure
    2.67 +    possible_wpad_servers = get_wpad_server_searchlist()
    2.68 +    for server in possible_wpad_servers:
    2.69 +        wpad_url = check_for_wpad_file(server, DNS_WPAD_FILENAME)
    2.70 +        if wpad_url:
    2.71 +            return wpad_url
    2.72 +        
    2.73 +    #no wpad url found
    2.74 +    return None
    2.75 +    
    2.76 +def getProxySettings():
    2.77 +    # try to autodetect domain wpad file
    2.78 +    wpad_url = search_for_wpad_url()
    2.79 +    if wpad_url:
    2.80 +        return {'ProxyAutoConfigURL': wpad_url}
    2.81 +    
    2.82 +    # get Proxy settings from registry      
    2.83 +    aReg = _winreg.ConnectRegistry(None,_winreg.HKEY_CURRENT_USER)
    2.84 +    aKey = _winreg.OpenKey(aReg, r"Software\Microsoft\Windows\CurrentVersion\Internet Settings")
    2.85 +    _, valueCount, _ = _winreg.QueryInfoKey(aKey)
    2.86 +    reg_entries = dict()
    2.87 +    for i in range(valueCount):                                           
    2.88 +        try:
    2.89 +            n,v,_ = _winreg.EnumValue(aKey,i)
    2.90 +            reg_entries[n] = v
    2.91 +        except EnvironmentError:                                               
    2.92 +            break
    2.93 +    _winreg.CloseKey(aKey)
    2.94 +    
    2.95 +    # return configured WPAD url
    2.96 +    if 'AutoConfigURL' in reg_entries.keys():
    2.97 +        return {'ProxyAutoConfigURL': reg_entries['AutoConfigURL']}
    2.98 +
    2.99 +    # return manually configured proxy
   2.100 +    if 'ProxyEnable' in reg_entries.keys() and reg_entries['ProxyEnable'] == 1:
   2.101 +        proxy_search = re.search(r"(?<=http=)(?P<ProxyServer>.*?)(?=;)", reg_entries['ProxyServer'])
   2.102 +        if proxy_search:
   2.103 +            proxies = proxy_search.groupdict()
   2.104 +            if 'ProxyServer' in proxies.keys(): # found http proxy
   2.105 +                return {'ProxyServer': proxies['ProxyServer']}  
   2.106 +        return {'ProxyServer': reg_entries['ProxyServer']}
   2.107 +        
   2.108 +    return None
   2.109 \ No newline at end of file
     3.1 --- a/OpenSecurity/bin/test_vmmanager.pyw	Thu Oct 02 13:20:37 2014 +0200
     3.2 +++ b/OpenSecurity/bin/test_vmmanager.pyw	Thu Oct 02 13:08:09 2014 +0100
     3.3 @@ -41,6 +41,7 @@
     3.4  import cygwin
     3.5  import vmmanager
     3.6  import _winreg
     3.7 +import time
     3.8  gvm_mgr = None
     3.9  
    3.10  class TestVMManager(unittest.TestCase):
    3.11 @@ -54,6 +55,11 @@
    3.12          gvm_mgr = vmmanager.VMManager.getInstance()
    3.13          pass
    3.14      
    3.15 +    #@classmethod
    3.16 +    #def tearOffClass(self):
    3.17 +    #    gvm_mgr.stop()
    3.18 +    #    gvm_mgr.cleanup()
    3.19 +    
    3.20      @unittest.skip("skipping")
    3.21      def testGetTemplateUUID(self):
    3.22          template = vmmanager.VMManager.getVDiskUUID(gvm_mgr.templateImage)
    3.23 @@ -97,12 +103,9 @@
    3.24          print re.search(r"(?<=http=)(?P<HttpProxy>.*?)(?=;)", text).groupdict()
    3.25          print re.search(r"(?<=http=)(.*?)(?=;)", text)
    3.26          
    3.27 -    #@classmethod
    3.28 -    #def tearOffClass(self):
    3.29 -    #    gvm_mgr.stop()
    3.30 -    #    gvm_mgr.cleanup()
    3.31      
    3.32      
    3.33 +    @unittest.skip("skipping")
    3.34      def testImportTemplate(self):
    3.35          gvm_mgr.cleanup()
    3.36          if 'SecurityDVM' in gvm_mgr.listVMS():
    3.37 @@ -115,16 +118,8 @@
    3.38          gvm_mgr.removeVMFolder('SecurityDVM')
    3.39          gvm_mgr.importTemplate('C:\Windows\System32\config\systemprofile\VirtualBox VMs\OsecVM.ova')
    3.40          gvm_mgr.updateTemplate()
    3.41 -    #VBoxManage list hostonlyifs
    3.42 -    #VBoxManage list dhcpservers
    3.43 -    #VBoxManage dhcpserver remove --netname "HostInterfaceNetworking-VirtualBox Host-Only Ethernet Adapter"
    3.44 -    #VBoxManage dhcpserver add --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.254 --enable
    3.45 -    #VBoxManage dhcpserver modify --ifname "VirtualBox Host-Only Ethernet Adapter" --enable
    3.46 -    #VBoxManage hostonlyif ipconfig "VirtualBox Host-Only Ethernet Adapter" --dhcp
    3.47 -    #VBoxManage hostonlyif ipconfig "VirtualBox Host-Only Ethernet Adapter" --ip 192.168.56.1 --netmask 255.255.255.0
    3.48 -
    3.49 -    
    3.50 -    
    3.51 +   
    3.52 +    @unittest.skip("skipping")   
    3.53      def testHostOnlyDHCP(self):
    3.54          #list hostonlyifs
    3.55          #Cygwin.vboxExecute("list hostonlyifs")
    3.56 @@ -135,12 +130,25 @@
    3.57          dhcpservers = gvm_mgr.getDHCPServers()
    3.58          print dhcpservers
    3.59          
    3.60 +    def testBrowsingRequest(self):
    3.61 +        gvm_mgr.start()
    3.62 +        gvm_mgr.handleBrowsingRequest()
    3.63 +        time.sleep(3000)
    3.64 +        pass
    3.65 +        
    3.66  if __name__ == '__main__':
    3.67      TestVMManager.setUpClass()
    3.68      
    3.69      suite = unittest.TestLoader().loadTestsFromTestCase(TestVMManager)
    3.70      unittest.TextTestRunner().run(suite)
    3.71      
    3.72 +    #VBoxManage list hostonlyifs
    3.73 +    #VBoxManage list dhcpservers
    3.74 +    #VBoxManage dhcpserver remove --netname "HostInterfaceNetworking-VirtualBox Host-Only Ethernet Adapter"
    3.75 +    #VBoxManage dhcpserver add --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.254 --enable
    3.76 +    #VBoxManage dhcpserver modify --ifname "VirtualBox Host-Only Ethernet Adapter" --enable
    3.77 +    #VBoxManage hostonlyif ipconfig "VirtualBox Host-Only Ethernet Adapter" --dhcp
    3.78 +    #VBoxManage hostonlyif ipconfig "VirtualBox Host-Only Ethernet Adapter" --ip 192.168.56.1 --netmask 255.255.255.0    
    3.79  #    logger = setupLogger('Cygwin')
    3.80  #    c = Cygwin()
    3.81  #    unittest.main()
     4.1 --- a/OpenSecurity/bin/vmmanager.pyw	Thu Oct 02 13:20:37 2014 +0200
     4.2 +++ b/OpenSecurity/bin/vmmanager.pyw	Thu Oct 02 13:08:09 2014 +0100
     4.3 @@ -108,14 +108,17 @@
     4.4      systemProperties = None
     4.5      _instance = None
     4.6      machineFolder = ''
     4.7 -    rsdHandler = None
     4.8      hostonlyIF = None
     4.9 -    browsingManager = None
    4.10 +    
    4.11      blacklistedRSD = None
    4.12      status_message = 'Starting up...'
    4.13      templateImage = None
    4.14      importHandler = None
    4.15      updateHandler = None
    4.16 +    deviceHandler = None
    4.17 +    sdvmFactory = None
    4.18 +    vms = dict()
    4.19 +    
    4.20   
    4.21      def __init__(self):
    4.22          # only proceed if we have a working background environment
    4.23 @@ -145,9 +148,6 @@
    4.24                  props = dict((k.strip(),v.strip().strip('"')) for k,v in (line.split(':', 1) for line in item.strip().splitlines()))
    4.25                  ifs[props["Name"]] = props
    4.26          return ifs
    4.27 -                    
    4.28 -        #props = dict((k.strip(),v.strip().strip('"')) for k,v in (line.split(':', 1) for line in result.strip().splitlines()))
    4.29 -        #return props
    4.30      
    4.31      #list the hostonly IFs exposed by the VBox host
    4.32      @staticmethod    
    4.33 @@ -239,19 +239,6 @@
    4.34          self.status_message = 'All is ok.'
    4.35          return True
    4.36      
    4.37 -    def stop(self):
    4.38 -        Cygwin.denyExec()
    4.39 -        if self.rsdHandler != None:
    4.40 -            self.rsdHandler.stop()
    4.41 -            self.rsdHandler.join()
    4.42 -            self.rsdHandler = None
    4.43 -            
    4.44 -        if self.browsingManager != None:
    4.45 -            self.browsingManager.stop()
    4.46 -            self.browsingManager.join()
    4.47 -            self.browsingManager = None
    4.48 -        Cygwin.allowExec()
    4.49 -    
    4.50      def start(self, force = False):
    4.51          if not force:
    4.52              if self.importHandler and self.importHandler.isAlive():
    4.53 @@ -265,11 +252,23 @@
    4.54          self.stop()
    4.55          Cygwin.allowExec()
    4.56          if self.backend_ok() and self.template_installed():
    4.57 -            self.browsingManager = BrowsingManager(self)
    4.58 -            self.browsingManager.start()
    4.59 -            self.rsdHandler = DeviceHandler(self)
    4.60 -            self.rsdHandler.start()
    4.61 +            self.sdvmFactory = SDVMFactory(self)
    4.62 +            self.sdvmFactory.start()
    4.63 +            self.deviceHandler = DeviceHandler(self)
    4.64 +            self.deviceHandler.start()
    4.65 +    
    4.66 +    def stop(self):
    4.67 +        Cygwin.denyExec()
    4.68 +        if self.sdvmFactory != None:
    4.69 +            self.sdvmFactory.stop()
    4.70 +            self.sdvmFactory.join()
    4.71 +            self.sdvmFactory = None
    4.72 +        if self.deviceHandler != None:
    4.73 +            self.deviceHandler.stop()
    4.74 +            self.deviceHandler.join()
    4.75 +            self.deviceHandler = None
    4.76          
    4.77 +        Cygwin.allowExec()
    4.78  
    4.79      def cleanup(self):
    4.80          self.stop()
    4.81 @@ -740,7 +739,7 @@
    4.82          return network_drives
    4.83      
    4.84      # handles browsing request    
    4.85 -    def handleBrowsingRequest(self, proxy, wpad):
    4.86 +    def handleBrowsingRequest(self, proxy = None, wpad = None):
    4.87          showTrayMessage('Starting Secure Browsing...', 7000)
    4.88          handler = BrowsingHandler(self, proxy, wpad)
    4.89          handler.start()
    4.90 @@ -774,17 +773,6 @@
    4.91          #value, type = win32api.RegQueryValueEx(key, "ProfileImagePath")
    4.92          #print value
    4.93      
    4.94 -    def backupFile(self, src, dest):
    4.95 -        certificate = Cygwin.cygPath(self.getMachineFolder()) + '/' + self.browsingManager.vm_name + '/dvm_key'
    4.96 -        command = '-r -o StrictHostKeyChecking=no -i "' + certificate + '" "osecuser@' + self.browsingManager.ip_addr + ':' + src + '" "' + dest + '"'
    4.97 -        return Cygwin.execute(Cygwin.cygwin_scp, command, wait_return=True, window=False)
    4.98 -    
    4.99 -    def restoreFile(self, src, dest):
   4.100 -        certificate = Cygwin.cygPath(self.getMachineFolder()) + '/' + self.browsingManager.vm_name + '/dvm_key'
   4.101 -        #command = '-r -v -o StrictHostKeyChecking=no -i \"' + certificate + '\" \"' + src + '\" \"osecuser@' + self.browsingManager.ip_addr + ':' + dest + '\"'
   4.102 -        command = '-r -o StrictHostKeyChecking=no -i "' + certificate + '" "' + src + '" "osecuser@' + self.browsingManager.ip_addr + ':' + dest + '"'
   4.103 -        return Cygwin.execute(Cygwin.cygwin_scp, command, wait_return=True, window=False)
   4.104 -    
   4.105      #import initial template
   4.106      def importTemplate(self, image_path):
   4.107          import_logger.info('Stopping Opensecurity...')
   4.108 @@ -926,6 +914,251 @@
   4.109          self.updateHandler = UpdateHandler(self)
   4.110          self.updateHandler.start()
   4.111          import_logger.info("Initial import started.")
   4.112 +        
   4.113 +    def createSession(self):
   4.114 +        new_sdvm = self.newSDVM()
   4.115 +        self.attachVDisk(new_sdvm, 'SATA', '0', '0', self.templateImage)
   4.116 +        self.genCertificate(new_sdvm)
   4.117 +        self.attachCertificate(new_sdvm)
   4.118 +        self.startVM(new_sdvm)
   4.119 +        new_ip = self.waitStartup(new_sdvm)
   4.120 +        if new_ip == None:
   4.121 +            logger.error("Error getting IP address of SDVM. Cleaning up.")
   4.122 +            self.poweroffVM(new_sdvm)
   4.123 +            self.removeVM(new_sdvm)
   4.124 +            return None
   4.125 +        else:
   4.126 +            logger.info("Got IP address for " + new_sdvm + ' ' + new_ip)
   4.127 +            self.vms[new_sdvm] = {'vm_name' : new_sdvm, 'ip_addr' : new_ip, 'used' : False, 'running' : True}
   4.128 +            return self.vms[new_sdvm]
   4.129 +            
   4.130 +    def releaseSession(self, vm_name):
   4.131 +        del self.vms[vm_name]
   4.132 +        self.poweroffVM(vm_name)
   4.133 +        self.removeVM(vm_name)
   4.134 +        self.sdvmFactory.trigger()
   4.135 +        
   4.136 +    def getSession(self):
   4.137 +        # return first found unused SDVM
   4.138 +        for vm in self.vms.values():
   4.139 +            if vm['used'] == False:
   4.140 +                vm['used'] = True
   4.141 +                self.sdvmFactory.trigger()
   4.142 +                return vm
   4.143 +        return self.createSession()
   4.144 +        
   4.145 +class SDVMFactory(threading.Thread):
   4.146 +    vmm = None
   4.147 +    running = True
   4.148 +    triggerEv = None
   4.149 +    
   4.150 +    def __init__(self, vmmanager):
   4.151 +        threading.Thread.__init__(self)
   4.152 +        self.vmm = vmmanager
   4.153 +        self.triggerEv = threading.Event()
   4.154 +        
   4.155 +    def run(self):
   4.156 +        while self.running:
   4.157 +            self.triggerEv.clear()            
   4.158 +
   4.159 +            if len(self.vmm.vms) < 2:
   4.160 +                self.vmm.createSession()
   4.161 +                continue
   4.162 +            unused = 0
   4.163 +            for vm in self.vmm.vms.values():
   4.164 +                if vm['used'] == False:
   4.165 +                    unused+=1
   4.166 +            if unused == 0:
   4.167 +                self.vmm.createSession()
   4.168 +            self.triggerEv.wait()
   4.169 +    
   4.170 +    def trigger(self):
   4.171 +        self.triggerEv.set()
   4.172 +        
   4.173 +    def stop(self):
   4.174 +        self.running = False
   4.175 +        self.triggerEv.set()
   4.176 +        
   4.177 +#handles browsing session creation 
   4.178 +class BrowsingHandler(threading.Thread):
   4.179 +    vmm = None
   4.180 +    proxy = None
   4.181 +    wpad = None
   4.182 +    net_resource = None
   4.183 +    ip_addr = None
   4.184 +    vm_name = None
   4.185 +    
   4.186 +    def __init__(self, vmmanager, proxy, wpad):
   4.187 +        threading.Thread.__init__(self)
   4.188 +        self.vmm = vmmanager
   4.189 +        self.proxy = proxy
   4.190 +        self.wpad = wpad
   4.191 +        
   4.192 +    def run(self):
   4.193 +        session = None
   4.194 +        try:
   4.195 +            appDataDir = self.getAppDataDir()
   4.196 +
   4.197 +            session = self.vmm.getSession()
   4.198 +            if not session:
   4.199 +                raise OpenSecurityException("Could not get new SDVM session.")
   4.200 +            
   4.201 +            self.ip_addr = session['ip_addr']
   4.202 +            self.vm_name = session['vm_name']
   4.203 +            
   4.204 +            self.net_resource = '\\\\' + self.ip_addr + '\\Download'
   4.205 +            urllib2.urlopen('http://127.0.0.1:8090/netmount?'+'net_resource='+self.net_resource).readline()
   4.206 +            
   4.207 +            logger.info("Restoring browser settings in AppData dir " + appDataDir)
   4.208 +            # create OpenSecurity settings dir on local machine user home /AppData/Roaming 
   4.209 +            Cygwin.bashExecute('/usr/bin/mkdir -p \\\"' + appDataDir + '/OpenSecurity\\\"')
   4.210 +            # create chromium settings dir on local machine if not existing
   4.211 +            Cygwin.bashExecute('/usr/bin/mkdir -p \\\"' + appDataDir + '/OpenSecurity/chromium\\\"')
   4.212 +            # create chromium settings dir on remote machine if not existing
   4.213 +            Cygwin.sshExecute('"mkdir -p \\\"/home/osecuser/.config\\\""', self.ip_addr, 'osecuser', Cygwin.cygPath(self.vmm.getMachineFolder()) + '/' + self.vm_name + '/dvm_key')
   4.214 +            #restore settings on vm
   4.215 +            self.restoreFile(appDataDir + '/OpenSecurity/chromium', '/home/osecuser/.config/')
   4.216 +                    
   4.217 +            if self.wpad:
   4.218 +                browser = '\\\"/usr/bin/chromium --proxy-pac-url=\\\"'+self.wpad+'\\\"\\\"'
   4.219 +            elif self.proxy:
   4.220 +                browser = '\\\"export http_proxy='+self.proxy+'; /usr/bin/chromium\\\"'
   4.221 +            else:
   4.222 +                browser = '\\\"/usr/bin/chromium\\\"'
   4.223 +                
   4.224 +            Cygwin.sshExecuteX11(browser, self.ip_addr, 'osecuser', Cygwin.cygPath(self.vmm.getMachineFolder()) + '/' + self.vm_name + '/dvm_key')
   4.225 +            self.backupFile('/home/osecuser/.config/chromium', appDataDir + '/OpenSecurity/')
   4.226 +        
   4.227 +        except urllib2.URLError:
   4.228 +            logger.error("Network drive connect failed. OpenSecurity Tray client not running.")
   4.229 +            self.net_resource = None
   4.230 +
   4.231 +        except:
   4.232 +            logger.info("BrowsingHandler failed. See log for details")
   4.233 +        
   4.234 +        if session:
   4.235 +            if self.net_resource == None:
   4.236 +                logger.info("Missing browsing SDVM's network share. Skipping disconnect")
   4.237 +            else:
   4.238 +                try:
   4.239 +                    urllib2.urlopen('http://127.0.0.1:8090/netumount?'+'net_resource='+self.net_resource).readline()
   4.240 +                    self.net_resource = None
   4.241 +                except urllib2.URLError:
   4.242 +                    logger.error("Network share disconnect failed. OpenSecurity Tray client not running.")
   4.243 +        if self.vm_name:
   4.244 +            self.vmm.releaseSession(self.vm_name)
   4.245 +        
   4.246 +        self.vmm.sdvmFactory.trigger()
   4.247 +
   4.248 +    def backupFile(self, src, dest):
   4.249 +        certificate = Cygwin.cygPath(self.vmm.getMachineFolder()) + '/' + self.vm_name + '/dvm_key'
   4.250 +        command = '-r -o StrictHostKeyChecking=no -i "' + certificate + '" "osecuser@' + self.ip_addr + ':' + src + '" "' + dest + '"'
   4.251 +        return Cygwin.execute(Cygwin.cygwin_scp, command, wait_return=True, window=False)
   4.252 +    
   4.253 +    def restoreFile(self, src, dest):
   4.254 +        certificate = Cygwin.cygPath(self.vmm.getMachineFolder()) + '/' + self.vm_name + '/dvm_key'
   4.255 +        command = '-r -o StrictHostKeyChecking=no -i "' + certificate + '" "' + src + '" "osecuser@' + self.ip_addr + ':' + dest + '"'
   4.256 +        return Cygwin.execute(Cygwin.cygwin_scp, command, wait_return=True, window=False)
   4.257 +                
   4.258 +    def getAppDataDir(self):
   4.259 +        user = self.vmm.getActiveUserName()
   4.260 +        if user == None:
   4.261 +            logger.error("Cannot get active user name")
   4.262 +            raise OpenSecurityException("Cannot get active user name")
   4.263 +        else:
   4.264 +            logger.info('Got active user name ' + user)
   4.265 +        sid = self.vmm.getUserSID(user)
   4.266 +        if sid == None:
   4.267 +            logger.error("Cannot get SID for active user")
   4.268 +            raise OpenSecurityException("Cannot get SID for active user")
   4.269 +        else:
   4.270 +            logger.info("Got active user SID " + sid + " for user " + user)
   4.271 +            
   4.272 +        path = self.vmm.getAppDataDir(sid)
   4.273 +        if path == None:
   4.274 +            logger.error("Cannot get AppDataDir for active user")
   4.275 +            raise OpenSecurityException("Cannot get AppDataDir for active user")
   4.276 +        else:
   4.277 +            logger.info("Got AppData dir for user " + user + ': ' + path)
   4.278 +        
   4.279 +        return Cygwin.cygPath(path)
   4.280 +            
   4.281 +                
   4.282 +class DeviceHandler(threading.Thread): 
   4.283 +    vmm = None
   4.284 +    existingRSDs = None
   4.285 +    attachedRSDs = None  
   4.286 +    running = True
   4.287 +    def __init__(self, vmmanger): 
   4.288 +        threading.Thread.__init__(self)
   4.289 +        self.vmm = vmmanger
   4.290 + 
   4.291 +    def stop(self):
   4.292 +        self.running = False
   4.293 +        
   4.294 +    def run(self):
   4.295 +        self.existingRSDs = dict()
   4.296 +        self.attachedRSDs = self.vmm.getAttachedRSDs()
   4.297 +        
   4.298 +        while self.running:
   4.299 +            tmp_rsds = self.vmm.getExistingRSDs()
   4.300 +            if tmp_rsds.keys() == self.existingRSDs.keys():
   4.301 +                logger.debug("Nothing's changed. sleep(3)")
   4.302 +                time.sleep(3)
   4.303 +                continue
   4.304 +            
   4.305 +            showTrayMessage('System changed.\nEvaluating...', 7000)
   4.306 +            logger.info("Something's changed")
   4.307 +            
   4.308 +            tmp_attached = self.attachedRSDs     
   4.309 +            for vm_name in tmp_attached.keys():
   4.310 +                if tmp_attached[vm_name] not in tmp_rsds.values():
   4.311 +                    ip = self.vmm.getHostOnlyIP(vm_name)
   4.312 +                    if ip == None:
   4.313 +                        logger.error("Failed getting hostonly IP for " + vm_name)
   4.314 +                        continue
   4.315 +                    
   4.316 +                    try:
   4.317 +                        net_resource = '\\\\' + ip + '\\USB'
   4.318 +                        result = urllib2.urlopen('http://127.0.0.1:8090/netumount?'+'net_resource='+net_resource).readline()
   4.319 +                    except urllib2.URLError:
   4.320 +                        logger.error("Network drive disconnect failed. OpenSecurity Tray client not running.")
   4.321 +                        continue
   4.322 +                    
   4.323 +                    # detach not necessary as already removed from vm description upon disconnect
   4.324 +                    del self.attachedRSDs[vm_name]
   4.325 +                    self.vmm.releaseSession(vm_name)
   4.326 +                    
   4.327 +            #create new vms for new devices if any
   4.328 +            new_ip = None
   4.329 +            for new_device in tmp_rsds.values():
   4.330 +                showTrayMessage('Mounting device...', 7000)
   4.331 +                if (self.attachedRSDs and False) or (new_device not in self.attachedRSDs.values()):
   4.332 +                   
   4.333 +                    session = self.vmm.getSession()
   4.334 +                    if not session:
   4.335 +                        logger.info("Could not get new SDVM session.")
   4.336 +                        continue
   4.337 +                        #raise OpenSecurityException("Could not get new SDVM session.")
   4.338 +                    new_sdvm = session['vm_name']
   4.339 +                    new_ip = session['ip_addr']
   4.340 +                    try:
   4.341 +                        self.vmm.attachRSD(new_sdvm, new_device)
   4.342 +                        self.attachedRSDs[new_sdvm] = new_device
   4.343 +                    except:
   4.344 +                        logger.info("RSD prematurely removed. Cleaning up.")
   4.345 +                        self.vmm.releaseSession(new_sdvm)
   4.346 +                        continue
   4.347 +                    
   4.348 +                    try:
   4.349 +                        net_resource = '\\\\' + new_ip + '\\USB'
   4.350 +                        result = urllib2.urlopen('http://127.0.0.1:8090/netmount?'+'net_resource='+net_resource).readline()
   4.351 +                    except urllib2.URLError:
   4.352 +                        logger.error("Network drive connect failed (tray client not accessible). Cleaning up.")
   4.353 +                        self.vmm.releaseSession(new_sdvm)
   4.354 +                        continue
   4.355 +                    
   4.356 +            self.existingRSDs = tmp_rsds
   4.357  
   4.358  class UpdateHandler(threading.Thread):
   4.359      vmm = None    
   4.360 @@ -952,219 +1185,4 @@
   4.361              self.vmm.updateTemplate()
   4.362          except:
   4.363              import_logger.info("Initial import failed. Refer to service log for details.")
   4.364 -        self.vmm.start(force=True)
   4.365 -            
   4.366 -#handles browsing session creation 
   4.367 -class BrowsingHandler(threading.Thread):
   4.368 -    vmm = None
   4.369 -    proxy = None
   4.370 -    wpad = None
   4.371 -    def __init__(self, vmmanager, proxy, wpad):
   4.372 -        threading.Thread.__init__(self)
   4.373 -        self.vmm = vmmanager
   4.374 -        self.proxy = proxy
   4.375 -        self.wpad = wpad
   4.376 -        
   4.377 -    def run(self):
   4.378 -        #browser = '\\\"/usr/bin/chromium; pidof dbus-launch | xargs kill\\\"'
   4.379 -        #browser = '\\\"/usr/bin/chromium\\\"'
   4.380 -        
   4.381 -        try:
   4.382 -            if self.wpad:
   4.383 -                browser = '\\\"/usr/bin/chromium --proxy-pac-url=\\\"'+self.wpad+'\\\"\\\"'
   4.384 -            elif self.proxy:
   4.385 -                browser = '\\\"export http_proxy='+self.proxy+'; /usr/bin/chromium\\\"'
   4.386 -            else:
   4.387 -                browser = '\\\"/usr/bin/chromium\\\"'
   4.388 -                
   4.389 -            self.vmm.browsingManager.started.wait() 
   4.390 -            result = Cygwin.sshExecuteX11(browser, self.vmm.browsingManager.ip_addr, 'osecuser', Cygwin.cygPath(self.vmm.getMachineFolder()) + '/' + self.vmm.browsingManager.vm_name + '/dvm_key')
   4.391 -            self.vmm.backupFile('/home/osecuser/.config/chromium', self.vmm.browsingManager.appDataDir + '/OpenSecurity/')
   4.392 -        except:
   4.393 -            logger.info("BrowsingHandler closing. Restarting browsing SDVM.")
   4.394 -
   4.395 -        self.vmm.browsingManager.restart.set()
   4.396 -        
   4.397 -            
   4.398 -# handles browsing Vm creation and destruction                    
   4.399 -class BrowsingManager(threading.Thread):   
   4.400 -    vmm = None
   4.401 -    running = True
   4.402 -    restart = None
   4.403 -    ip_addr = None
   4.404 -    vm_name = None
   4.405 -    net_resource = None
   4.406 -    appDataDir = None
   4.407 -    
   4.408 -    def __init__(self, vmmanager):
   4.409 -        threading.Thread.__init__(self)
   4.410 -        self.vmm = vmmanager
   4.411 -        self.restart = threading.Event()
   4.412 -        self.started = threading.Event()
   4.413 -    
   4.414 -    def stop(self):
   4.415 -        self.running = False
   4.416 -        self.restart.set()   
   4.417 -     
   4.418 -    def run(self):
   4.419 -        while self.running:
   4.420 -            self.restart.clear()
   4.421 -            self.started.clear()
   4.422 -            
   4.423 -            if self.net_resource == None:
   4.424 -                logger.info("Missing browsing SDVM's network share. Skipping disconnect")
   4.425 -            else:
   4.426 -                try:
   4.427 -                    browsing_vm = urllib2.urlopen('http://127.0.0.1:8090/netumount?'+'net_resource='+self.net_resource).readline()
   4.428 -                    self.net_resource = None
   4.429 -                except urllib2.URLError:
   4.430 -                    logger.error("Network share disconnect failed. OpenSecurity Tray client not running.")
   4.431 -                    continue
   4.432 -            
   4.433 -            self.ip_addr = None
   4.434 -
   4.435 -            if self.vm_name != None:
   4.436 -                self.vmm.poweroffVM(self.vm_name)
   4.437 -                self.vmm.removeVM(self.vm_name)
   4.438 -            
   4.439 -            try:
   4.440 -                self.vm_name = self.vmm.newSDVM()
   4.441 -                self.vmm.attachVDisk(self.vm_name, 'SATA', '0', '0', self.vmm.templateImage)
   4.442 -                self.vmm.genCertificate(self.vm_name)
   4.443 -                self.vmm.attachCertificate(self.vm_name)
   4.444 -                
   4.445 -                self.vmm.startVM(self.vm_name)
   4.446 -                
   4.447 -                self.ip_addr = self.vmm.waitStartup(self.vm_name)
   4.448 -                if self.ip_addr == None:
   4.449 -                    logger.error("Failed to get ip address")
   4.450 -                    continue
   4.451 -                else:
   4.452 -                    logger.info("Got IP address for " + self.vm_name + ' ' + self.ip_addr)
   4.453 -                
   4.454 -                try:
   4.455 -                    self.net_resource = '\\\\' + self.ip_addr + '\\Download'
   4.456 -                    result = urllib2.urlopen('http://127.0.0.1:8090/netmount?'+'net_resource='+self.net_resource).readline()
   4.457 -                except urllib2.URLError:
   4.458 -                    logger.error("Network drive connect failed. OpenSecurity Tray client not running.")
   4.459 -                    self.net_resource = None
   4.460 -                    continue
   4.461 -                
   4.462 -                user = self.vmm.getActiveUserName()
   4.463 -                if user == None:
   4.464 -                    logger.error("Cannot get active user name")
   4.465 -                    continue
   4.466 -                else:
   4.467 -                    logger.info('Got active user name ' + user)
   4.468 -                sid = self.vmm.getUserSID(user)
   4.469 -                if sid == None:
   4.470 -                    logger.error("Cannot get SID for active user")
   4.471 -                    continue
   4.472 -                else:
   4.473 -                    logger.info("Got active user SID " + sid + " for user " + user)
   4.474 -                    
   4.475 -                path = self.vmm.getAppDataDir(sid)
   4.476 -                if path == None:
   4.477 -                    logger.error("Cannot get AppDataDir for active user")
   4.478 -                    continue
   4.479 -                else:
   4.480 -                    logger.info("Got AppData dir for user " + user + ': ' + path)
   4.481 -                
   4.482 -                self.appDataDir = Cygwin.cygPath(path)
   4.483 -                logger.info("Restoring browser settings in AppData dir " + self.appDataDir)
   4.484 -                # create OpenSecurity settings dir on local machine user home /AppData/Roaming 
   4.485 -                Cygwin.bashExecute('/usr/bin/mkdir -p \\\"' + self.appDataDir + '/OpenSecurity\\\"')
   4.486 -                # create chromium settings dir on local machine if not existing
   4.487 -                Cygwin.bashExecute('/usr/bin/mkdir -p \\\"' + self.appDataDir + '/OpenSecurity/chromium\\\"')
   4.488 -                # create chromium settings dir on remote machine if not existing
   4.489 -                Cygwin.sshExecute('"mkdir -p \\\"/home/osecuser/.config\\\""', self.ip_addr, 'osecuser', Cygwin.cygPath(self.vmm.getMachineFolder()) + '/' + self.vm_name + '/dvm_key')
   4.490 -                #restore settings on vm
   4.491 -                self.vmm.restoreFile(self.appDataDir + '/OpenSecurity/chromium', '/home/osecuser/.config/')
   4.492 -                self.started.set()
   4.493 -                logger.info("Browsing SDVM running.")
   4.494 -                self.restart.wait()
   4.495 -            except Exception as e:
   4.496 -                logger.error("Unexpected error: ".join(e))
   4.497 -                logger.error("BrowsingHandler failed. Cleaning up")
   4.498 -                #self.running= False
   4.499 -                
   4.500 -class DeviceHandler(threading.Thread): 
   4.501 -    vmm = None
   4.502 -    existingRSDs = None
   4.503 -    attachedRSDs = None  
   4.504 -    running = True
   4.505 -    def __init__(self, vmmanger): 
   4.506 -        threading.Thread.__init__(self)
   4.507 -        self.vmm = vmmanger
   4.508 - 
   4.509 -    def stop(self):
   4.510 -        self.running = False
   4.511 -        
   4.512 -    def run(self):
   4.513 -        self.existingRSDs = dict()
   4.514 -        self.attachedRSDs = self.vmm.getAttachedRSDs()
   4.515 -        
   4.516 -        while self.running:
   4.517 -            tmp_rsds = self.vmm.getExistingRSDs()
   4.518 -            if tmp_rsds.keys() == self.existingRSDs.keys():
   4.519 -                logger.debug("Nothing's changed. sleep(3)")
   4.520 -                time.sleep(3)
   4.521 -                continue
   4.522 -            
   4.523 -            showTrayMessage('System changed.\nEvaluating...', 7000)
   4.524 -            logger.info("Something's changed")
   4.525 -            tmp_attached = self.attachedRSDs     
   4.526 -            for vm_name in tmp_attached.keys():
   4.527 -                if tmp_attached[vm_name] not in tmp_rsds.values():
   4.528 -                    ip = self.vmm.getHostOnlyIP(vm_name)
   4.529 -                    if ip == None:
   4.530 -                        logger.error("Failed getting hostonly IP for " + vm_name)
   4.531 -                        continue
   4.532 -                    try:
   4.533 -                        net_resource = '\\\\' + ip + '\\USB'
   4.534 -                        result = urllib2.urlopen('http://127.0.0.1:8090/netumount?'+'net_resource='+net_resource).readline()
   4.535 -                    except urllib2.URLError:
   4.536 -                        logger.error("Network drive disconnect failed. OpenSecurity Tray client not running.")
   4.537 -                        continue
   4.538 -                    
   4.539 -                    # detach not necessary as already removed from vm description upon disconnect
   4.540 -                    #self.vmm.detachRSD(vm_name, self.attachedRSDs[vm_name])
   4.541 -                    del self.attachedRSDs[vm_name]
   4.542 -                    self.vmm.poweroffVM(vm_name)
   4.543 -                    self.vmm.removeVM(vm_name)
   4.544 -                    #break
   4.545 -                    
   4.546 -            #create new vms for new devices if any
   4.547 -            new_ip = None
   4.548 -            for new_device in tmp_rsds.values():
   4.549 -                showTrayMessage('Mounting device...', 7000)
   4.550 -                if (self.attachedRSDs and False) or (new_device not in self.attachedRSDs.values()):
   4.551 -                    new_sdvm = self.vmm.newSDVM()
   4.552 -                    self.vmm.attachVDisk(new_sdvm, 'SATA', '0', '0', self.vmm.templateImage)
   4.553 -                    self.vmm.startVM(new_sdvm)
   4.554 -                    new_ip = self.vmm.waitStartup(new_sdvm)
   4.555 -                    if new_ip == None:
   4.556 -                        logger.error("Error getting IP address of SDVM. Cleaning up.")
   4.557 -                        self.vmm.poweroffVM(new_sdvm)
   4.558 -                        self.vmm.removeVM(new_sdvm)
   4.559 -                        continue
   4.560 -                    else:
   4.561 -                        logger.info("Got IP address for " + new_sdvm + ' ' + new_ip)
   4.562 -                    try:
   4.563 -                        self.vmm.attachRSD(new_sdvm, new_device)
   4.564 -                        self.attachedRSDs[new_sdvm] = new_device
   4.565 -                    except:
   4.566 -                        logger.info("RSD prematurely removed. Cleaning up.")
   4.567 -                        self.vmm.poweroffVM(new_sdvm)
   4.568 -                        self.vmm.removeVM(new_sdvm)
   4.569 -                        continue
   4.570 -                    try:
   4.571 -                        net_resource = '\\\\' + new_ip + '\\USB'
   4.572 -                        result = urllib2.urlopen('http://127.0.0.1:8090/netmount?'+'net_resource='+net_resource).readline()
   4.573 -                    except urllib2.URLError:
   4.574 -                        logger.error("Network drive connect failed (tray client not accessible). Cleaning up.")
   4.575 -                        self.vmm.poweroffVM(new_sdvm)
   4.576 -                        self.vmm.removeVM(new_sdvm)
   4.577 -                        continue
   4.578 -                    
   4.579 -            self.existingRSDs = tmp_rsds
   4.580 +        self.vmm.start(force=True)
   4.581 \ No newline at end of file