- changed opensecurity to always hold at least 2 SDVM sessions to be ready when needed
- added automatic wpad proxy detection
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