1.1 --- a/OpenSecurity/bin/opensecurityd.pyw Fri May 23 15:04:52 2014 +0100
1.2 +++ b/OpenSecurity/bin/opensecurityd.pyw Mon Jun 02 17:08:11 2014 +0100
1.3 @@ -329,7 +329,7 @@
1.4 class os_setup:
1.5 """OpenSecurity '/setup' handler
1.6
1.7 - - GET: Give user some info how to setup the OpenSecurity envvironment
1.8 + - GET: Give user some info how to setup the OpenSecurity environment
1.9 """
1.10
1.11 def GET(self):
2.1 --- a/OpenSecurity/bin/vmmanager.pyw Fri May 23 15:04:52 2014 +0100
2.2 +++ b/OpenSecurity/bin/vmmanager.pyw Mon Jun 02 17:08:11 2014 +0100
2.3 @@ -38,24 +38,28 @@
2.4 return repr(self.value)
2.5
2.6 class USBFilter:
2.7 + uuid = ""
2.8 vendorid = ""
2.9 productid = ""
2.10 revision = ""
2.11 + serial = ""
2.12
2.13 - def __init__(self, vendorid, productid, revision):
2.14 + def __init__(self, uuid, vendorid, productid, revision, serial):
2.15 + self.uuid = uuid
2.16 self.vendorid = vendorid.lower()
2.17 self.productid = productid.lower()
2.18 self.revision = revision.lower()
2.19 + self.serial = serial
2.20 return
2.21
2.22 def __eq__(self, other):
2.23 - return self.vendorid == other.vendorid and self.productid == other.productid and self.revision == other.revision
2.24 + return self.uuid == other.uuid #self.vendorid == other.vendorid and self.productid == other.productid and self.revision == other.revision
2.25
2.26 def __hash__(self):
2.27 - return hash(self.vendorid) ^ hash(self.productid) ^ hash(self.revision)
2.28 + return hash(self.uuid) ^ hash(self.vendorid) ^ hash(self.productid) ^ hash(self.revision) ^ hash(self.serial)
2.29
2.30 def __repr__(self):
2.31 - return "VendorId = \'" + str(self.vendorid) + "\' ProductId = \'" + str(self.productid) + "\' Revision = \'" + str(self.revision) + "\'"
2.32 + return "UUID:" + str(self.uuid) + " VendorId = \'" + str(self.vendorid) + "\' ProductId = \'" + str(self.productid) + "\'" + "\' Revision = \'" + str(self.revision) + "\' SerialNumber = \'" + str(self.serial)
2.33
2.34 #def __getitem__(self, item):
2.35 # return self.coords[item]
2.36 @@ -221,7 +225,7 @@
2.37
2.38 # return the RSDs connected to the host
2.39 @staticmethod
2.40 - def getConnectedRSDS():
2.41 + def getExistingRSDs():
2.42 results = Cygwin.checkResult(Cygwin.vboxExecute('list usbhost'))[1]
2.43 results = results.split('Host USB Devices:')[1].strip()
2.44
2.45 @@ -229,31 +233,64 @@
2.46 rsds = dict()
2.47 for item in items:
2.48 props = dict()
2.49 - for line in item.splitlines():
2.50 + for line in item.splitlines():
2.51 if line != "":
2.52 k,v = line[:line.index(':')].strip(), line[line.index(':')+1:].strip()
2.53 props[k] = v
2.54
2.55 - #if 'Product' in props.keys() and props['Product'] == 'Mass Storage':
2.56 -
2.57 - usb_filter = USBFilter( re.search(r"\((?P<vid>[0-9A-Fa-f]+)\)", props['VendorId']).groupdict()['vid'],
2.58 - re.search(r"\((?P<pid>[0-9A-Fa-f]+)\)", props['ProductId']).groupdict()['pid'],
2.59 - re.search(r"\((?P<rev>[0-9A-Fa-f]+)\)", props['Revision']).groupdict()['rev'] )
2.60 + uuid = re.search(r"(?P<uuid>[0-9A-Fa-f\-]+)", props['UUID']).groupdict()['uuid']
2.61 + vid = re.search(r"\((?P<vid>[0-9A-Fa-f]+)\)", props['VendorId']).groupdict()['vid']
2.62 + pid = re.search(r"\((?P<pid>[0-9A-Fa-f]+)\)", props['ProductId']).groupdict()['pid']
2.63 + rev = re.search(r"\((?P<rev>[0-9A-Fa-f]+)\)", props['Revision']).groupdict()['rev']
2.64 + serial = None
2.65 + if 'SerialNumber' in props.keys():
2.66 + serial = re.search(r"(?P<ser>[0-9A-Fa-f]+)", props['SerialNumber']).groupdict()['ser']
2.67 + usb_filter = USBFilter( uuid, vid, pid, rev, serial)
2.68 if VMManager.isMassStorageDevice(usb_filter):
2.69 - rsds[props['UUID']] = usb_filter;
2.70 + rsds[uuid] = usb_filter
2.71 logger.debug(usb_filter)
2.72 return rsds
2.73
2.74 +
2.75 + #def getAttachedRSD(self, vm_name):
2.76 + # props = self.getVMInfo(vm_name)
2.77 + # keys = set(['USBFilterVendorId1', 'USBFilterProductId1', 'USBFilterRevision1', 'USBFilterSerialNumber1'])
2.78 + # keyset = set(props.keys())
2.79 + # usb_filter = None
2.80 + # if keyset.issuperset(keys):
2.81 + # usb_filter = USBFilter(props['USBFilterVendorId1'], props['USBFilterProductId1'], props['USBFilterRevision1'])
2.82 + # return usb_filter
2.83 +
2.84 + # return the attached USB device as usb descriptor for an existing VM
2.85 + def getAttachedRSD(self, vm_name):
2.86 + props = self.getVMInfo(vm_name)
2.87 + keys = set(['USBAttachedUUID1', 'USBAttachedVendorId1', 'USBAttachedProductId1', 'USBAttachedRevision1', 'USBAttachedSerialNumber1'])
2.88 + keyset = set(props.keys())
2.89 + usb_filter = None
2.90 + if keyset.issuperset(keys):
2.91 + usb_filter = USBFilter(props['USBAttachedUUID1'], props['USBAttachedVendorId1'], props['USBAttachedProductId1'], props['USBAttachedRevision1'], props['USBAttachedSerialNumber1'])
2.92 + return usb_filter
2.93 +
2.94 # return the RSDs attached to all existing SDVMs
2.95 def getAttachedRSDs(self):
2.96 vms = self.listSDVM()
2.97 attached_devices = dict()
2.98 for vm in vms:
2.99 - rsd_filter = self.getUSBFilter(vm)
2.100 + rsd_filter = self.getAttachedRSD(vm)
2.101 if rsd_filter != None:
2.102 attached_devices[vm] = rsd_filter
2.103 return attached_devices
2.104
2.105 + # attach removable storage device to VM by provision of filter
2.106 + def attachRSD(self, vm_name, rsd_filter):
2.107 + #return Cygwin.checkResult(Cygwin.vboxExecute('usbfilter add 0 --target ' + vm_name + ' --name OpenSecurityRSD --vendorid ' + rsd_filter.vendorid + ' --productid ' + rsd_filter.productid + ' --revision ' + rsd_filter.revision + ' --serialnumber ' + rsd_filter.serial))
2.108 + return Cygwin.checkResult(Cygwin.vboxExecute('controlvm ' + vm_name + ' usbattach ' + rsd_filter.uuid ))
2.109 +
2.110 + # detach removable storage from VM by
2.111 + def detachRSD(self, vm_name, rsd_filter):
2.112 + #return Cygwin.checkResult(Cygwin.vboxExecute('usbfilter remove 0 --target ' + vm_name))
2.113 + return Cygwin.checkResult(Cygwin.vboxExecute('controlvm ' + vm_name + ' usbdetach ' + rsd_filter.uuid ))
2.114 +
2.115 # configures hostonly networking and DHCP server. requires admin rights
2.116 def configureHostNetworking(self):
2.117 #cmd = 'vboxmanage list hostonlyifs'
2.118 @@ -461,14 +498,6 @@
2.119 if result.startswith('No value set!'):
2.120 return None
2.121 return result[result.index(':')+1:].strip()
2.122 -
2.123 - # attach removable storage device to VM by provision of filter
2.124 - def attachRSD(self, vm_name, rsd_filter):
2.125 - return Cygwin.checkResult(Cygwin.vboxExecute('usbfilter add 0 --target ' + vm_name + ' --name OpenSecurityRSD --vendorid ' + rsd_filter.vendorid + ' --productid ' + rsd_filter.productid + ' --revision ' + rsd_filter.revision))
2.126 -
2.127 - # detach removable storage from VM by
2.128 - def detachRSD(self, vm_name):
2.129 - return Cygwin.checkResult(Cygwin.vboxExecute('usbfilter remove 0 --target ' + vm_name))
2.130
2.131 # return the description set for an existing VM
2.132 def getVMInfo(self, vm_name):
2.133 @@ -476,16 +505,6 @@
2.134 props = dict((k.strip().strip('"'),v.strip().strip('"')) for k,v in (line.split('=', 1) for line in results.splitlines()))
2.135 return props
2.136
2.137 - # return the configured USB filter for an existing VM
2.138 - def getUSBFilter(self, vm_name):
2.139 - props = self.getVMInfo(vm_name)
2.140 - keys = set(['USBFilterVendorId1', 'USBFilterProductId1', 'USBFilterRevision1'])
2.141 - keyset = set(props.keys())
2.142 - usb_filter = None
2.143 - if keyset.issuperset(keys):
2.144 - usb_filter = USBFilter(props['USBFilterVendorId1'], props['USBFilterProductId1'], props['USBFilterRevision1'])
2.145 - return usb_filter
2.146 -
2.147 #generates ISO containing authorized_keys for use with guest VM
2.148 def genCertificateISO(self, vm_name):
2.149 machineFolder = Cygwin.cygPath(self.machineFolder)
2.150 @@ -772,8 +791,8 @@
2.151
2.152 class DeviceHandler(threading.Thread):
2.153 vmm = None
2.154 + existingRSDs = None
2.155 attachedRSDs = None
2.156 - connectedRSDs = None
2.157 running = True
2.158 def __init__(self, vmmanger):
2.159 threading.Thread.__init__(self)
2.160 @@ -783,51 +802,63 @@
2.161 self.running = False
2.162
2.163 def run(self):
2.164 - self.connectedRSDs = dict()
2.165 + self.existingRSDs = self.vmm.getExistingRSDs()
2.166 + self.attachedRSDs = self.vmm.getAttachedRSDs()
2.167
2.168 while self.running:
2.169 - tmp_rsds = self.vmm.getConnectedRSDS()
2.170 -
2.171 - self.attachedRSDs = self.vmm.getAttachedRSDs()
2.172 + tmp_rsds = self.vmm.getExistingRSDs()
2.173 for vm_name in self.attachedRSDs.keys():
2.174 if self.attachedRSDs[vm_name] not in tmp_rsds.values():
2.175 drive = self.vmm.getNetworkDrive(vm_name)
2.176 - if drive == None:
2.177 - logger.error("Error getting SDVM's network drive letter.")
2.178 - continue
2.179 try:
2.180 - result = urllib2.urlopen('http://127.0.0.1:8090/netumount?'+'drive_letter='+drive).readline()
2.181 + if drive != None:
2.182 + result = urllib2.urlopen('http://127.0.0.1:8090/netumount?'+'drive_letter='+drive).readline()
2.183 + else:
2.184 + logger.error("Error getting SDVM's network drive letter.")
2.185 except urllib2.URLError:
2.186 logger.error("Network drive disconnect failed. OpenSecurity Tray client not running.")
2.187 continue
2.188 - self.vmm.detachRSD(vm_name)
2.189 +
2.190 + # detach not necessary as already removed from vm description upon disconnect
2.191 + #self.vmm.detachRSD(vm_name, self.attachedRSDs[vm_name])
2.192 + del self.attachedRSDs[vm_name]
2.193 self.vmm.poweroffVM(vm_name)
2.194 self.vmm.removeVM(vm_name)
2.195 break
2.196
2.197 -
2.198 - if tmp_rsds.keys() == self.connectedRSDs.keys():
2.199 + if tmp_rsds.keys() == self.existingRSDs.keys():
2.200 logger.debug("Nothing's changed. sleep(3)")
2.201 time.sleep(3)
2.202 continue
2.203
2.204 logger.info("Something's changed")
2.205 - self.connectedRSDs = tmp_rsds
2.206 + self.existingRSDs = tmp_rsds
2.207
2.208 #create new vm for attached device if any
2.209 - self.attachedRSDs = self.vmm.getAttachedRSDs()
2.210 - self.connectedRSDs = self.vmm.getConnectedRSDS()
2.211 + #self.attachedRSDs = self.vmm.getAttachedRSDs()
2.212 + #self.connectedRSDs = self.vmm.getExistingRSDs()
2.213
2.214 new_ip = None
2.215 - for connected_device in self.connectedRSDs.values():
2.216 - if (self.attachedRSDs and False) or (connected_device not in self.attachedRSDs.values()):
2.217 + for new_device in self.existingRSDs.values():
2.218 + if (self.attachedRSDs and False) or (new_device not in self.attachedRSDs.values()):
2.219 new_sdvm = self.vmm.newSDVM()
2.220 self.vmm.storageAttach(new_sdvm)
2.221 - self.vmm.attachRSD(new_sdvm, connected_device)
2.222 self.vmm.startVM(new_sdvm)
2.223 new_ip = self.vmm.waitStartup(new_sdvm)
2.224 if new_ip == None:
2.225 - logger.error("Error getting IP address of SDVM.")
2.226 + logger.error("Error getting IP address of SDVM. Cleaning up.")
2.227 + self.vmm.poweroffVM(new_sdvm)
2.228 + self.vmm.removeVM(new_sdvm)
2.229 + continue
2.230 + else:
2.231 + logger.info("Got IP address for " + new_sdvm + ' ' + new_ip)
2.232 + try:
2.233 + self.vmm.attachRSD(new_sdvm, new_device)
2.234 + self.attachedRSDs[new_sdvm] = new_device
2.235 + except:
2.236 + logger.info("RSD prematurely removed. Cleaning up.")
2.237 + self.vmm.poweroffVM(new_sdvm)
2.238 + self.vmm.removeVM(new_sdvm)
2.239 continue
2.240 drive = self.vmm.genNetworkDrive()
2.241 if drive == None:
2.242 @@ -837,7 +868,9 @@
2.243 net_resource = '\\\\' + new_ip + '\\USB'
2.244 result = urllib2.urlopen('http://127.0.0.1:8090/netmount?'+'drive_letter='+drive+'&net_resource='+net_resource).readline()
2.245 except urllib2.URLError:
2.246 - logger.error("Network drive connect failed. OpenSecurity Tray client not running.")
2.247 + logger.error("Network drive connect failed (tray client not accessible). Cleaning up.")
2.248 + self.vmm.poweroffVM(new_sdvm)
2.249 + self.vmm.removeVM(new_sdvm)
2.250 continue
2.251
2.252