# HG changeset patch # User BarthaM@N3SIM1218.D03.arc.local # Date 1412251689 -3600 # Node ID 216da9017f8f91bd281c8db95db51a7d477bcf00 # Parent bab44ef66a3cabf313f1747457b382eace684855 - changed opensecurity to always hold at least 2 SDVM sessions to be ready when needed - added automatic wpad proxy detection diff -r bab44ef66a3c -r 216da9017f8f OpenSecurity/bin/opensecurity_tray.pyw --- a/OpenSecurity/bin/opensecurity_tray.pyw Thu Oct 02 13:20:37 2014 +0200 +++ b/OpenSecurity/bin/opensecurity_tray.pyw Thu Oct 02 13:08:09 2014 +0100 @@ -39,8 +39,6 @@ import urllib import urllib2 import webbrowser -import _winreg -import re from PyQt4 import QtCore from PyQt4 import QtGui @@ -52,11 +50,11 @@ from cygwin import Cygwin import opensecurity_client_restful_server +import proxy_getter from ui import AboutDialog from ui import ConfigureDialog from ui import opensecurity_rc - # ------------------------------------------------------------ # code @@ -106,32 +104,6 @@ """clicked about""" d = AboutDialog() d.exec_() - - def getProxySettings(self): - aReg = _winreg.ConnectRegistry(None,_winreg.HKEY_CURRENT_USER) - aKey = _winreg.OpenKey(aReg, r"Software\Microsoft\Windows\CurrentVersion\Internet Settings") - subCount, valueCount, lastModified = _winreg.QueryInfoKey(aKey) - reg_entries = dict() - for i in range(valueCount): - try: - n,v,t = _winreg.EnumValue(aKey,i) - reg_entries[n] = v - except EnvironmentError: - break - _winreg.CloseKey(aKey) - - if 'AutoConfigURL' in reg_entries.keys(): - return {'ProxyAutoConfigURL': reg_entries['AutoConfigURL']} - - if 'ProxyEnable' in reg_entries.keys() and reg_entries['ProxyEnable'] == 1: - proxy_search = re.search(r"(?<=http=)(?P.*?)(?=;)", reg_entries['ProxyServer']) - if proxy_search: - proxies = proxy_search.groupdict() - if 'ProxyServer' in proxies.keys(): # found http proxy - return {'ProxyServer': proxies['ProxyServer']} - return {'ProxyServer': reg_entries['ProxyServer']} - - return None def clicked_browser(self): """wish for safe internet browsing""" @@ -150,7 +122,7 @@ urllib2.install_opener(opener) req_data = "" - proxy = self.getProxySettings() + proxy = proxy_getter.getProxySettings() if proxy: req_data = '?' + urllib.urlencode(proxy) req = 'http://127.0.0.1:8080/browsing'+ req_data @@ -187,14 +159,11 @@ return try: - # get a proper browsing VM Cygwin.start_X11() - # TODO: HARDCODED ADDRESS OF OPENSECURITYD url = 'http://127.0.0.1:8080/sdvms/' + j['vm'] + '/application' + j['application'] result = urllib2.urlopen(url).readline() - except: pass diff -r bab44ef66a3c -r 216da9017f8f OpenSecurity/bin/proxy_getter.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/OpenSecurity/bin/proxy_getter.py Thu Oct 02 13:08:09 2014 +0100 @@ -0,0 +1,105 @@ +import socket +import os +import httplib +import sys +import _winreg +import re + +DNS_WPAD_FILENAME = "wpad.dat" + +def check_for_wpad_file(server, path): + + wpad_url = "http://%s/%s"%(server, path) + print "checking", wpad_url + try: + conn = httplib.HTTPConnection(server) + conn.request("HEAD", "/%s"%path) + r = conn.getresponse() + if r.status == 200: + return wpad_url + except Exception, e: + return None + + return None + +def get_wpad_server_searchlist(): + #get fully-qualified hostname + fqhn = socket.getfqdn().split(" ")[0] + + #do we really have a fully-qualified name? + #if not, linux offers a second possibility + if fqhn.count(".") == 0 and os.name == 'posix': + #weird method to get own ip address and fqhn + s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) + s.connect(('', 0)) + my_ip = s.getsockname()[0] + s.close() + fqhn = socket.gethostbyaddr(my_ip)[0] + + parts = fqhn.split(".") + if len(parts) < 3: + return [] + + servers = [] + parts[0] = "wpad" + servers.append(".".join(parts)) + parts = parts[0:1]+parts[2:] + #not correct for some suffixes, but everyone does it that way, see wikipedia for details + while len(parts) >= 3: + servers.append(".".join(parts)) + parts = parts[0:1]+parts[2:] + + return servers + +def search_for_wpad_url(): + #TODO: According to RFC we should check DHCP first, but it isn't used often + #check most common case first + wpad_server = "wpad" + wpad_url = check_for_wpad_file(wpad_server, DNS_WPAD_FILENAME) + if wpad_url: + return wpad_url + + #wpad DNS search procedure + possible_wpad_servers = get_wpad_server_searchlist() + for server in possible_wpad_servers: + wpad_url = check_for_wpad_file(server, DNS_WPAD_FILENAME) + if wpad_url: + return wpad_url + + #no wpad url found + return None + +def getProxySettings(): + # try to autodetect domain wpad file + wpad_url = search_for_wpad_url() + if wpad_url: + return {'ProxyAutoConfigURL': wpad_url} + + # get Proxy settings from registry + aReg = _winreg.ConnectRegistry(None,_winreg.HKEY_CURRENT_USER) + aKey = _winreg.OpenKey(aReg, r"Software\Microsoft\Windows\CurrentVersion\Internet Settings") + _, valueCount, _ = _winreg.QueryInfoKey(aKey) + reg_entries = dict() + for i in range(valueCount): + try: + n,v,_ = _winreg.EnumValue(aKey,i) + reg_entries[n] = v + except EnvironmentError: + break + _winreg.CloseKey(aKey) + + # return configured WPAD url + if 'AutoConfigURL' in reg_entries.keys(): + return {'ProxyAutoConfigURL': reg_entries['AutoConfigURL']} + + # return manually configured proxy + if 'ProxyEnable' in reg_entries.keys() and reg_entries['ProxyEnable'] == 1: + proxy_search = re.search(r"(?<=http=)(?P.*?)(?=;)", reg_entries['ProxyServer']) + if proxy_search: + proxies = proxy_search.groupdict() + if 'ProxyServer' in proxies.keys(): # found http proxy + return {'ProxyServer': proxies['ProxyServer']} + return {'ProxyServer': reg_entries['ProxyServer']} + + return None \ No newline at end of file diff -r bab44ef66a3c -r 216da9017f8f OpenSecurity/bin/test_vmmanager.pyw --- a/OpenSecurity/bin/test_vmmanager.pyw Thu Oct 02 13:20:37 2014 +0200 +++ b/OpenSecurity/bin/test_vmmanager.pyw Thu Oct 02 13:08:09 2014 +0100 @@ -41,6 +41,7 @@ import cygwin import vmmanager import _winreg +import time gvm_mgr = None class TestVMManager(unittest.TestCase): @@ -54,6 +55,11 @@ gvm_mgr = vmmanager.VMManager.getInstance() pass + #@classmethod + #def tearOffClass(self): + # gvm_mgr.stop() + # gvm_mgr.cleanup() + @unittest.skip("skipping") def testGetTemplateUUID(self): template = vmmanager.VMManager.getVDiskUUID(gvm_mgr.templateImage) @@ -97,12 +103,9 @@ print re.search(r"(?<=http=)(?P.*?)(?=;)", text).groupdict() print re.search(r"(?<=http=)(.*?)(?=;)", text) - #@classmethod - #def tearOffClass(self): - # gvm_mgr.stop() - # gvm_mgr.cleanup() + @unittest.skip("skipping") def testImportTemplate(self): gvm_mgr.cleanup() if 'SecurityDVM' in gvm_mgr.listVMS(): @@ -115,16 +118,8 @@ gvm_mgr.removeVMFolder('SecurityDVM') gvm_mgr.importTemplate('C:\Windows\System32\config\systemprofile\VirtualBox VMs\OsecVM.ova') gvm_mgr.updateTemplate() - #VBoxManage list hostonlyifs - #VBoxManage list dhcpservers - #VBoxManage dhcpserver remove --netname "HostInterfaceNetworking-VirtualBox Host-Only Ethernet Adapter" - #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 - #VBoxManage dhcpserver modify --ifname "VirtualBox Host-Only Ethernet Adapter" --enable - #VBoxManage hostonlyif ipconfig "VirtualBox Host-Only Ethernet Adapter" --dhcp - #VBoxManage hostonlyif ipconfig "VirtualBox Host-Only Ethernet Adapter" --ip 192.168.56.1 --netmask 255.255.255.0 - - - + + @unittest.skip("skipping") def testHostOnlyDHCP(self): #list hostonlyifs #Cygwin.vboxExecute("list hostonlyifs") @@ -135,12 +130,25 @@ dhcpservers = gvm_mgr.getDHCPServers() print dhcpservers + def testBrowsingRequest(self): + gvm_mgr.start() + gvm_mgr.handleBrowsingRequest() + time.sleep(3000) + pass + if __name__ == '__main__': TestVMManager.setUpClass() suite = unittest.TestLoader().loadTestsFromTestCase(TestVMManager) unittest.TextTestRunner().run(suite) + #VBoxManage list hostonlyifs + #VBoxManage list dhcpservers + #VBoxManage dhcpserver remove --netname "HostInterfaceNetworking-VirtualBox Host-Only Ethernet Adapter" + #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 + #VBoxManage dhcpserver modify --ifname "VirtualBox Host-Only Ethernet Adapter" --enable + #VBoxManage hostonlyif ipconfig "VirtualBox Host-Only Ethernet Adapter" --dhcp + #VBoxManage hostonlyif ipconfig "VirtualBox Host-Only Ethernet Adapter" --ip 192.168.56.1 --netmask 255.255.255.0 # logger = setupLogger('Cygwin') # c = Cygwin() # unittest.main() diff -r bab44ef66a3c -r 216da9017f8f OpenSecurity/bin/vmmanager.pyw --- a/OpenSecurity/bin/vmmanager.pyw Thu Oct 02 13:20:37 2014 +0200 +++ b/OpenSecurity/bin/vmmanager.pyw Thu Oct 02 13:08:09 2014 +0100 @@ -108,14 +108,17 @@ systemProperties = None _instance = None machineFolder = '' - rsdHandler = None hostonlyIF = None - browsingManager = None + blacklistedRSD = None status_message = 'Starting up...' templateImage = None importHandler = None updateHandler = None + deviceHandler = None + sdvmFactory = None + vms = dict() + def __init__(self): # only proceed if we have a working background environment @@ -145,9 +148,6 @@ props = dict((k.strip(),v.strip().strip('"')) for k,v in (line.split(':', 1) for line in item.strip().splitlines())) ifs[props["Name"]] = props return ifs - - #props = dict((k.strip(),v.strip().strip('"')) for k,v in (line.split(':', 1) for line in result.strip().splitlines())) - #return props #list the hostonly IFs exposed by the VBox host @staticmethod @@ -239,19 +239,6 @@ self.status_message = 'All is ok.' return True - def stop(self): - Cygwin.denyExec() - if self.rsdHandler != None: - self.rsdHandler.stop() - self.rsdHandler.join() - self.rsdHandler = None - - if self.browsingManager != None: - self.browsingManager.stop() - self.browsingManager.join() - self.browsingManager = None - Cygwin.allowExec() - def start(self, force = False): if not force: if self.importHandler and self.importHandler.isAlive(): @@ -265,11 +252,23 @@ self.stop() Cygwin.allowExec() if self.backend_ok() and self.template_installed(): - self.browsingManager = BrowsingManager(self) - self.browsingManager.start() - self.rsdHandler = DeviceHandler(self) - self.rsdHandler.start() + self.sdvmFactory = SDVMFactory(self) + self.sdvmFactory.start() + self.deviceHandler = DeviceHandler(self) + self.deviceHandler.start() + + def stop(self): + Cygwin.denyExec() + if self.sdvmFactory != None: + self.sdvmFactory.stop() + self.sdvmFactory.join() + self.sdvmFactory = None + if self.deviceHandler != None: + self.deviceHandler.stop() + self.deviceHandler.join() + self.deviceHandler = None + Cygwin.allowExec() def cleanup(self): self.stop() @@ -740,7 +739,7 @@ return network_drives # handles browsing request - def handleBrowsingRequest(self, proxy, wpad): + def handleBrowsingRequest(self, proxy = None, wpad = None): showTrayMessage('Starting Secure Browsing...', 7000) handler = BrowsingHandler(self, proxy, wpad) handler.start() @@ -774,17 +773,6 @@ #value, type = win32api.RegQueryValueEx(key, "ProfileImagePath") #print value - def backupFile(self, src, dest): - certificate = Cygwin.cygPath(self.getMachineFolder()) + '/' + self.browsingManager.vm_name + '/dvm_key' - command = '-r -o StrictHostKeyChecking=no -i "' + certificate + '" "osecuser@' + self.browsingManager.ip_addr + ':' + src + '" "' + dest + '"' - return Cygwin.execute(Cygwin.cygwin_scp, command, wait_return=True, window=False) - - def restoreFile(self, src, dest): - certificate = Cygwin.cygPath(self.getMachineFolder()) + '/' + self.browsingManager.vm_name + '/dvm_key' - #command = '-r -v -o StrictHostKeyChecking=no -i \"' + certificate + '\" \"' + src + '\" \"osecuser@' + self.browsingManager.ip_addr + ':' + dest + '\"' - command = '-r -o StrictHostKeyChecking=no -i "' + certificate + '" "' + src + '" "osecuser@' + self.browsingManager.ip_addr + ':' + dest + '"' - return Cygwin.execute(Cygwin.cygwin_scp, command, wait_return=True, window=False) - #import initial template def importTemplate(self, image_path): import_logger.info('Stopping Opensecurity...') @@ -926,6 +914,251 @@ self.updateHandler = UpdateHandler(self) self.updateHandler.start() import_logger.info("Initial import started.") + + def createSession(self): + new_sdvm = self.newSDVM() + self.attachVDisk(new_sdvm, 'SATA', '0', '0', self.templateImage) + self.genCertificate(new_sdvm) + self.attachCertificate(new_sdvm) + self.startVM(new_sdvm) + new_ip = self.waitStartup(new_sdvm) + if new_ip == None: + logger.error("Error getting IP address of SDVM. Cleaning up.") + self.poweroffVM(new_sdvm) + self.removeVM(new_sdvm) + return None + else: + logger.info("Got IP address for " + new_sdvm + ' ' + new_ip) + self.vms[new_sdvm] = {'vm_name' : new_sdvm, 'ip_addr' : new_ip, 'used' : False, 'running' : True} + return self.vms[new_sdvm] + + def releaseSession(self, vm_name): + del self.vms[vm_name] + self.poweroffVM(vm_name) + self.removeVM(vm_name) + self.sdvmFactory.trigger() + + def getSession(self): + # return first found unused SDVM + for vm in self.vms.values(): + if vm['used'] == False: + vm['used'] = True + self.sdvmFactory.trigger() + return vm + return self.createSession() + +class SDVMFactory(threading.Thread): + vmm = None + running = True + triggerEv = None + + def __init__(self, vmmanager): + threading.Thread.__init__(self) + self.vmm = vmmanager + self.triggerEv = threading.Event() + + def run(self): + while self.running: + self.triggerEv.clear() + + if len(self.vmm.vms) < 2: + self.vmm.createSession() + continue + unused = 0 + for vm in self.vmm.vms.values(): + if vm['used'] == False: + unused+=1 + if unused == 0: + self.vmm.createSession() + self.triggerEv.wait() + + def trigger(self): + self.triggerEv.set() + + def stop(self): + self.running = False + self.triggerEv.set() + +#handles browsing session creation +class BrowsingHandler(threading.Thread): + vmm = None + proxy = None + wpad = None + net_resource = None + ip_addr = None + vm_name = None + + def __init__(self, vmmanager, proxy, wpad): + threading.Thread.__init__(self) + self.vmm = vmmanager + self.proxy = proxy + self.wpad = wpad + + def run(self): + session = None + try: + appDataDir = self.getAppDataDir() + + session = self.vmm.getSession() + if not session: + raise OpenSecurityException("Could not get new SDVM session.") + + self.ip_addr = session['ip_addr'] + self.vm_name = session['vm_name'] + + self.net_resource = '\\\\' + self.ip_addr + '\\Download' + urllib2.urlopen('http://127.0.0.1:8090/netmount?'+'net_resource='+self.net_resource).readline() + + logger.info("Restoring browser settings in AppData dir " + appDataDir) + # create OpenSecurity settings dir on local machine user home /AppData/Roaming + Cygwin.bashExecute('/usr/bin/mkdir -p \\\"' + appDataDir + '/OpenSecurity\\\"') + # create chromium settings dir on local machine if not existing + Cygwin.bashExecute('/usr/bin/mkdir -p \\\"' + appDataDir + '/OpenSecurity/chromium\\\"') + # create chromium settings dir on remote machine if not existing + Cygwin.sshExecute('"mkdir -p \\\"/home/osecuser/.config\\\""', self.ip_addr, 'osecuser', Cygwin.cygPath(self.vmm.getMachineFolder()) + '/' + self.vm_name + '/dvm_key') + #restore settings on vm + self.restoreFile(appDataDir + '/OpenSecurity/chromium', '/home/osecuser/.config/') + + if self.wpad: + browser = '\\\"/usr/bin/chromium --proxy-pac-url=\\\"'+self.wpad+'\\\"\\\"' + elif self.proxy: + browser = '\\\"export http_proxy='+self.proxy+'; /usr/bin/chromium\\\"' + else: + browser = '\\\"/usr/bin/chromium\\\"' + + Cygwin.sshExecuteX11(browser, self.ip_addr, 'osecuser', Cygwin.cygPath(self.vmm.getMachineFolder()) + '/' + self.vm_name + '/dvm_key') + self.backupFile('/home/osecuser/.config/chromium', appDataDir + '/OpenSecurity/') + + except urllib2.URLError: + logger.error("Network drive connect failed. OpenSecurity Tray client not running.") + self.net_resource = None + + except: + logger.info("BrowsingHandler failed. See log for details") + + if session: + if self.net_resource == None: + logger.info("Missing browsing SDVM's network share. Skipping disconnect") + else: + try: + urllib2.urlopen('http://127.0.0.1:8090/netumount?'+'net_resource='+self.net_resource).readline() + self.net_resource = None + except urllib2.URLError: + logger.error("Network share disconnect failed. OpenSecurity Tray client not running.") + if self.vm_name: + self.vmm.releaseSession(self.vm_name) + + self.vmm.sdvmFactory.trigger() + + def backupFile(self, src, dest): + certificate = Cygwin.cygPath(self.vmm.getMachineFolder()) + '/' + self.vm_name + '/dvm_key' + command = '-r -o StrictHostKeyChecking=no -i "' + certificate + '" "osecuser@' + self.ip_addr + ':' + src + '" "' + dest + '"' + return Cygwin.execute(Cygwin.cygwin_scp, command, wait_return=True, window=False) + + def restoreFile(self, src, dest): + certificate = Cygwin.cygPath(self.vmm.getMachineFolder()) + '/' + self.vm_name + '/dvm_key' + command = '-r -o StrictHostKeyChecking=no -i "' + certificate + '" "' + src + '" "osecuser@' + self.ip_addr + ':' + dest + '"' + return Cygwin.execute(Cygwin.cygwin_scp, command, wait_return=True, window=False) + + def getAppDataDir(self): + user = self.vmm.getActiveUserName() + if user == None: + logger.error("Cannot get active user name") + raise OpenSecurityException("Cannot get active user name") + else: + logger.info('Got active user name ' + user) + sid = self.vmm.getUserSID(user) + if sid == None: + logger.error("Cannot get SID for active user") + raise OpenSecurityException("Cannot get SID for active user") + else: + logger.info("Got active user SID " + sid + " for user " + user) + + path = self.vmm.getAppDataDir(sid) + if path == None: + logger.error("Cannot get AppDataDir for active user") + raise OpenSecurityException("Cannot get AppDataDir for active user") + else: + logger.info("Got AppData dir for user " + user + ': ' + path) + + return Cygwin.cygPath(path) + + +class DeviceHandler(threading.Thread): + vmm = None + existingRSDs = None + attachedRSDs = None + running = True + def __init__(self, vmmanger): + threading.Thread.__init__(self) + self.vmm = vmmanger + + def stop(self): + self.running = False + + def run(self): + self.existingRSDs = dict() + self.attachedRSDs = self.vmm.getAttachedRSDs() + + while self.running: + tmp_rsds = self.vmm.getExistingRSDs() + if tmp_rsds.keys() == self.existingRSDs.keys(): + logger.debug("Nothing's changed. sleep(3)") + time.sleep(3) + continue + + showTrayMessage('System changed.\nEvaluating...', 7000) + logger.info("Something's changed") + + tmp_attached = self.attachedRSDs + for vm_name in tmp_attached.keys(): + if tmp_attached[vm_name] not in tmp_rsds.values(): + ip = self.vmm.getHostOnlyIP(vm_name) + if ip == None: + logger.error("Failed getting hostonly IP for " + vm_name) + continue + + try: + net_resource = '\\\\' + ip + '\\USB' + result = urllib2.urlopen('http://127.0.0.1:8090/netumount?'+'net_resource='+net_resource).readline() + except urllib2.URLError: + logger.error("Network drive disconnect failed. OpenSecurity Tray client not running.") + continue + + # detach not necessary as already removed from vm description upon disconnect + del self.attachedRSDs[vm_name] + self.vmm.releaseSession(vm_name) + + #create new vms for new devices if any + new_ip = None + for new_device in tmp_rsds.values(): + showTrayMessage('Mounting device...', 7000) + if (self.attachedRSDs and False) or (new_device not in self.attachedRSDs.values()): + + session = self.vmm.getSession() + if not session: + logger.info("Could not get new SDVM session.") + continue + #raise OpenSecurityException("Could not get new SDVM session.") + new_sdvm = session['vm_name'] + new_ip = session['ip_addr'] + try: + self.vmm.attachRSD(new_sdvm, new_device) + self.attachedRSDs[new_sdvm] = new_device + except: + logger.info("RSD prematurely removed. Cleaning up.") + self.vmm.releaseSession(new_sdvm) + continue + + try: + net_resource = '\\\\' + new_ip + '\\USB' + result = urllib2.urlopen('http://127.0.0.1:8090/netmount?'+'net_resource='+net_resource).readline() + except urllib2.URLError: + logger.error("Network drive connect failed (tray client not accessible). Cleaning up.") + self.vmm.releaseSession(new_sdvm) + continue + + self.existingRSDs = tmp_rsds class UpdateHandler(threading.Thread): vmm = None @@ -952,219 +1185,4 @@ self.vmm.updateTemplate() except: import_logger.info("Initial import failed. Refer to service log for details.") - self.vmm.start(force=True) - -#handles browsing session creation -class BrowsingHandler(threading.Thread): - vmm = None - proxy = None - wpad = None - def __init__(self, vmmanager, proxy, wpad): - threading.Thread.__init__(self) - self.vmm = vmmanager - self.proxy = proxy - self.wpad = wpad - - def run(self): - #browser = '\\\"/usr/bin/chromium; pidof dbus-launch | xargs kill\\\"' - #browser = '\\\"/usr/bin/chromium\\\"' - - try: - if self.wpad: - browser = '\\\"/usr/bin/chromium --proxy-pac-url=\\\"'+self.wpad+'\\\"\\\"' - elif self.proxy: - browser = '\\\"export http_proxy='+self.proxy+'; /usr/bin/chromium\\\"' - else: - browser = '\\\"/usr/bin/chromium\\\"' - - self.vmm.browsingManager.started.wait() - result = Cygwin.sshExecuteX11(browser, self.vmm.browsingManager.ip_addr, 'osecuser', Cygwin.cygPath(self.vmm.getMachineFolder()) + '/' + self.vmm.browsingManager.vm_name + '/dvm_key') - self.vmm.backupFile('/home/osecuser/.config/chromium', self.vmm.browsingManager.appDataDir + '/OpenSecurity/') - except: - logger.info("BrowsingHandler closing. Restarting browsing SDVM.") - - self.vmm.browsingManager.restart.set() - - -# handles browsing Vm creation and destruction -class BrowsingManager(threading.Thread): - vmm = None - running = True - restart = None - ip_addr = None - vm_name = None - net_resource = None - appDataDir = None - - def __init__(self, vmmanager): - threading.Thread.__init__(self) - self.vmm = vmmanager - self.restart = threading.Event() - self.started = threading.Event() - - def stop(self): - self.running = False - self.restart.set() - - def run(self): - while self.running: - self.restart.clear() - self.started.clear() - - if self.net_resource == None: - logger.info("Missing browsing SDVM's network share. Skipping disconnect") - else: - try: - browsing_vm = urllib2.urlopen('http://127.0.0.1:8090/netumount?'+'net_resource='+self.net_resource).readline() - self.net_resource = None - except urllib2.URLError: - logger.error("Network share disconnect failed. OpenSecurity Tray client not running.") - continue - - self.ip_addr = None - - if self.vm_name != None: - self.vmm.poweroffVM(self.vm_name) - self.vmm.removeVM(self.vm_name) - - try: - self.vm_name = self.vmm.newSDVM() - self.vmm.attachVDisk(self.vm_name, 'SATA', '0', '0', self.vmm.templateImage) - self.vmm.genCertificate(self.vm_name) - self.vmm.attachCertificate(self.vm_name) - - self.vmm.startVM(self.vm_name) - - self.ip_addr = self.vmm.waitStartup(self.vm_name) - if self.ip_addr == None: - logger.error("Failed to get ip address") - continue - else: - logger.info("Got IP address for " + self.vm_name + ' ' + self.ip_addr) - - try: - self.net_resource = '\\\\' + self.ip_addr + '\\Download' - result = urllib2.urlopen('http://127.0.0.1:8090/netmount?'+'net_resource='+self.net_resource).readline() - except urllib2.URLError: - logger.error("Network drive connect failed. OpenSecurity Tray client not running.") - self.net_resource = None - continue - - user = self.vmm.getActiveUserName() - if user == None: - logger.error("Cannot get active user name") - continue - else: - logger.info('Got active user name ' + user) - sid = self.vmm.getUserSID(user) - if sid == None: - logger.error("Cannot get SID for active user") - continue - else: - logger.info("Got active user SID " + sid + " for user " + user) - - path = self.vmm.getAppDataDir(sid) - if path == None: - logger.error("Cannot get AppDataDir for active user") - continue - else: - logger.info("Got AppData dir for user " + user + ': ' + path) - - self.appDataDir = Cygwin.cygPath(path) - logger.info("Restoring browser settings in AppData dir " + self.appDataDir) - # create OpenSecurity settings dir on local machine user home /AppData/Roaming - Cygwin.bashExecute('/usr/bin/mkdir -p \\\"' + self.appDataDir + '/OpenSecurity\\\"') - # create chromium settings dir on local machine if not existing - Cygwin.bashExecute('/usr/bin/mkdir -p \\\"' + self.appDataDir + '/OpenSecurity/chromium\\\"') - # create chromium settings dir on remote machine if not existing - Cygwin.sshExecute('"mkdir -p \\\"/home/osecuser/.config\\\""', self.ip_addr, 'osecuser', Cygwin.cygPath(self.vmm.getMachineFolder()) + '/' + self.vm_name + '/dvm_key') - #restore settings on vm - self.vmm.restoreFile(self.appDataDir + '/OpenSecurity/chromium', '/home/osecuser/.config/') - self.started.set() - logger.info("Browsing SDVM running.") - self.restart.wait() - except Exception as e: - logger.error("Unexpected error: ".join(e)) - logger.error("BrowsingHandler failed. Cleaning up") - #self.running= False - -class DeviceHandler(threading.Thread): - vmm = None - existingRSDs = None - attachedRSDs = None - running = True - def __init__(self, vmmanger): - threading.Thread.__init__(self) - self.vmm = vmmanger - - def stop(self): - self.running = False - - def run(self): - self.existingRSDs = dict() - self.attachedRSDs = self.vmm.getAttachedRSDs() - - while self.running: - tmp_rsds = self.vmm.getExistingRSDs() - if tmp_rsds.keys() == self.existingRSDs.keys(): - logger.debug("Nothing's changed. sleep(3)") - time.sleep(3) - continue - - showTrayMessage('System changed.\nEvaluating...', 7000) - logger.info("Something's changed") - tmp_attached = self.attachedRSDs - for vm_name in tmp_attached.keys(): - if tmp_attached[vm_name] not in tmp_rsds.values(): - ip = self.vmm.getHostOnlyIP(vm_name) - if ip == None: - logger.error("Failed getting hostonly IP for " + vm_name) - continue - try: - net_resource = '\\\\' + ip + '\\USB' - result = urllib2.urlopen('http://127.0.0.1:8090/netumount?'+'net_resource='+net_resource).readline() - except urllib2.URLError: - logger.error("Network drive disconnect failed. OpenSecurity Tray client not running.") - continue - - # detach not necessary as already removed from vm description upon disconnect - #self.vmm.detachRSD(vm_name, self.attachedRSDs[vm_name]) - del self.attachedRSDs[vm_name] - self.vmm.poweroffVM(vm_name) - self.vmm.removeVM(vm_name) - #break - - #create new vms for new devices if any - new_ip = None - for new_device in tmp_rsds.values(): - showTrayMessage('Mounting device...', 7000) - if (self.attachedRSDs and False) or (new_device not in self.attachedRSDs.values()): - new_sdvm = self.vmm.newSDVM() - self.vmm.attachVDisk(new_sdvm, 'SATA', '0', '0', self.vmm.templateImage) - self.vmm.startVM(new_sdvm) - new_ip = self.vmm.waitStartup(new_sdvm) - if new_ip == None: - logger.error("Error getting IP address of SDVM. Cleaning up.") - self.vmm.poweroffVM(new_sdvm) - self.vmm.removeVM(new_sdvm) - continue - else: - logger.info("Got IP address for " + new_sdvm + ' ' + new_ip) - try: - self.vmm.attachRSD(new_sdvm, new_device) - self.attachedRSDs[new_sdvm] = new_device - except: - logger.info("RSD prematurely removed. Cleaning up.") - self.vmm.poweroffVM(new_sdvm) - self.vmm.removeVM(new_sdvm) - continue - try: - net_resource = '\\\\' + new_ip + '\\USB' - result = urllib2.urlopen('http://127.0.0.1:8090/netmount?'+'net_resource='+net_resource).readline() - except urllib2.URLError: - logger.error("Network drive connect failed (tray client not accessible). Cleaning up.") - self.vmm.poweroffVM(new_sdvm) - self.vmm.removeVM(new_sdvm) - continue - - self.existingRSDs = tmp_rsds + self.vmm.start(force=True) \ No newline at end of file