1.1 --- a/OpenSecurity/bin/vmmanager.pyw Tue Mar 18 16:28:15 2014 +0100
1.2 +++ b/OpenSecurity/bin/vmmanager.pyw Tue Mar 18 16:31:47 2014 +0100
1.3 @@ -1,3 +1,4 @@
1.4 +<<<<<<< local
1.5 '''
1.6 Created on Nov 19, 2013
1.7
1.8 @@ -679,3 +680,686 @@
1.9
1.10 #cmd = "c:\\cygwin64\\bin\\bash.exe --login -c \"/bin/ls\""
1.11 #man.execute(cmd)
1.12 +=======
1.13 +'''
1.14 +Created on Nov 19, 2013
1.15 +
1.16 +@author: BarthaM
1.17 +'''
1.18 +import os
1.19 +import os.path
1.20 +from subprocess import Popen, PIPE, call, STARTUPINFO, _subprocess
1.21 +import sys
1.22 +import re
1.23 +
1.24 +from cygwin import Cygwin
1.25 +from environment import Environment
1.26 +import threading
1.27 +import time
1.28 +import string
1.29 +
1.30 +import shutil
1.31 +import stat
1.32 +import tempfile
1.33 +from opensecurity_util import logger, setupLogger, OpenSecurityException
1.34 +import ctypes
1.35 +import itertools
1.36 +import _winreg
1.37 +DEBUG = True
1.38 +
1.39 +class VMManagerException(Exception):
1.40 + def __init__(self, value):
1.41 + self.value = value
1.42 + def __str__(self):
1.43 + return repr(self.value)
1.44 +
1.45 +class USBFilter:
1.46 + vendorid = ""
1.47 + productid = ""
1.48 + revision = ""
1.49 +
1.50 + def __init__(self, vendorid, productid, revision):
1.51 + self.vendorid = vendorid.lower()
1.52 + self.productid = productid.lower()
1.53 + self.revision = revision.lower()
1.54 + return
1.55 +
1.56 + def __eq__(self, other):
1.57 + return self.vendorid == other.vendorid and self.productid == other.productid and self.revision == other.revision
1.58 +
1.59 + def __hash__(self):
1.60 + return hash(self.vendorid) ^ hash(self.productid) ^ hash(self.revision)
1.61 +
1.62 + def __repr__(self):
1.63 + return "VendorId = \'" + str(self.vendorid) + "\' ProductId = \'" + str(self.productid) + "\' Revision = \'" + str(self.revision) + "\'"
1.64 +
1.65 + #def __getitem__(self, item):
1.66 + # return self.coords[item]
1.67 +
1.68 +class VMManager(object):
1.69 + vmRootName = "SecurityDVM"
1.70 + systemProperties = None
1.71 + _instance = None
1.72 + machineFolder = ''
1.73 + rsdHandler = None
1.74 + _running = True
1.75 +
1.76 + def __init__(self):
1.77 + self._running = True
1.78 + self.systemProperties = self.getSystemProperties()
1.79 + self.machineFolder = self.systemProperties["Default machine folder"]
1.80 + self.cleanup()
1.81 + self.rsdHandler = DeviceHandler(self)
1.82 + self.rsdHandler.start()
1.83 + return
1.84 +
1.85 + @staticmethod
1.86 + def getInstance():
1.87 + if VMManager._instance == None:
1.88 + VMManager._instance = VMManager()
1.89 + return VMManager._instance
1.90 +
1.91 + def cleanup(self):
1.92 + if self.rsdHandler != None:
1.93 + self.rsdHandler.stop()
1.94 + self.rsdHandler.join()
1.95 + drives = self.getNetworkDrives()
1.96 + for drive in drives.keys():
1.97 + self.unmapNetworkDrive(drive)
1.98 + for vm in self.listSDVM():
1.99 + self.poweroffVM(vm)
1.100 + self.removeVM(vm)
1.101 +
1.102 + # return hosty system properties
1.103 + def getSystemProperties(self):
1.104 + result = checkResult(Cygwin.vboxExecute('list systemproperties'))
1.105 + if result[1]=='':
1.106 + return None
1.107 + props = dict((k.strip(),v.strip().strip('"')) for k,v in (line.split(':', 1) for line in result[1].strip().splitlines()))
1.108 + return props
1.109 +
1.110 + # return the folder containing the guest VMs
1.111 + def getMachineFolder(self):
1.112 + return self.machineFolder
1.113 +
1.114 + # list all existing VMs registered with VBox
1.115 + def listVM(self):
1.116 + result = checkResult(Cygwin.vboxExecute('list vms'))[1]
1.117 + vms = list(k.strip().strip('"') for k,_ in (line.split(' ') for line in result.splitlines()))
1.118 + return vms
1.119 +
1.120 + # list running VMs
1.121 + def listRunningVMS(self):
1.122 + result = checkResult(Cygwin.vboxExecute('list runningvms'))[1]
1.123 + vms = list(k.strip().strip('"') for k,_ in (line.split(' ') for line in result.splitlines()))
1.124 + return vms
1.125 +
1.126 + # list existing SDVMs
1.127 + def listSDVM(self):
1.128 + vms = self.listVM()
1.129 + svdms = []
1.130 + for vm in vms:
1.131 + if vm.startswith(self.vmRootName) and vm != self.vmRootName:
1.132 + svdms.append(vm)
1.133 + return svdms
1.134 +
1.135 + # generate valid (not already existing SDVM name). necessary for creating a new VM
1.136 + def generateSDVMName(self):
1.137 + vms = self.listVM()
1.138 + for i in range(0,999):
1.139 + if(not self.vmRootName+str(i) in vms):
1.140 + return self.vmRootName+str(i)
1.141 + return ''
1.142 +
1.143 + # check if the device is mass storage type
1.144 + @staticmethod
1.145 + def isMassStorageDevice(device):
1.146 + keyname = 'SYSTEM\CurrentControlSet\Enum\USB' + '\VID_' + device.vendorid+'&'+'PID_'+ device.productid
1.147 + key = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, keyname)
1.148 + #subkeys = _winreg.QueryInfoKey(key)[0]
1.149 + #for i in range(0, subkeys):
1.150 + # print _winreg.EnumKey(key, i)
1.151 + devinfokeyname = _winreg.EnumKey(key, 0)
1.152 + _winreg.CloseKey(key)
1.153 +
1.154 + devinfokey = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, keyname+'\\'+devinfokeyname)
1.155 + value = _winreg.QueryValueEx(devinfokey, 'SERVICE')[0]
1.156 + _winreg.CloseKey(devinfokey)
1.157 +
1.158 + return 'USBSTOR' in value
1.159 +
1.160 + # return the RSDs connected to the host
1.161 + @staticmethod
1.162 + def getConnectedRSDS():
1.163 + results = checkResult(Cygwin.vboxExecute('list usbhost'))[1]
1.164 + results = results.split('Host USB Devices:')[1].strip()
1.165 +
1.166 + items = list( "UUID:"+result for result in results.split('UUID:') if result != '')
1.167 + rsds = dict()
1.168 + for item in items:
1.169 + props = dict()
1.170 + for line in item.splitlines():
1.171 + if line != "":
1.172 + k,v = line[:line.index(':')].strip(), line[line.index(':')+1:].strip()
1.173 + props[k] = v
1.174 +
1.175 + #if 'Product' in props.keys() and props['Product'] == 'Mass Storage':
1.176 +
1.177 + usb_filter = USBFilter( re.search(r"\((?P<vid>[0-9A-Fa-f]+)\)", props['VendorId']).groupdict()['vid'],
1.178 + re.search(r"\((?P<pid>[0-9A-Fa-f]+)\)", props['ProductId']).groupdict()['pid'],
1.179 + re.search(r"\((?P<rev>[0-9A-Fa-f]+)\)", props['Revision']).groupdict()['rev'] )
1.180 + if VMManager.isMassStorageDevice(usb_filter):
1.181 + rsds[props['UUID']] = usb_filter;
1.182 + logger.debug(usb_filter)
1.183 + return rsds
1.184 +
1.185 + # return the RSDs attached to all existing SDVMs
1.186 + def getAttachedRSDs(self):
1.187 + vms = self.listSDVM()
1.188 + attached_devices = dict()
1.189 + for vm in vms:
1.190 + rsd_filter = self.getUSBFilter(vm)
1.191 + if rsd_filter != None:
1.192 + attached_devices[vm] = rsd_filter
1.193 + return attached_devices
1.194 +
1.195 + # configures hostonly networking and DHCP server. requires admin rights
1.196 + def configureHostNetworking(self):
1.197 + #cmd = 'vboxmanage list hostonlyifs'
1.198 + #Cygwin.vboxExecute(cmd)
1.199 + #cmd = 'vboxmanage hostonlyif remove \"VirtualBox Host-Only Ethernet Adapter\"'
1.200 + #Cygwin.vboxExecute(cmd)
1.201 + #cmd = 'vboxmanage hostonlyif create'
1.202 + #Cygwin.vboxExecute(cmd)
1.203 + checkResult(Cygwin.vboxExecute('hostonlyif ipconfig \"VirtualBox Host-Only Ethernet Adapter\" --ip 192.168.56.1 --netmask 255.255.255.0'))
1.204 + #cmd = 'vboxmanage dhcpserver add'
1.205 + #Cygwin.vboxExecute(cmd)
1.206 + checkResult(Cygwin.vboxExecute('dhcpserver modify --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.200'))
1.207 +
1.208 + #create new virtual machine instance based on template vm named SecurityDVM (\SecurityDVM\SecurityDVM.vmdk)
1.209 + def createVM(self, vm_name):
1.210 + hostonly_if = self.getHostOnlyIFs()
1.211 + checkResult(Cygwin.vboxExecute('createvm --name ' + vm_name + ' --ostype Debian --register'))
1.212 + checkResult(Cygwin.vboxExecute('modifyvm ' + vm_name + ' --memory 512 --vram 10 --cpus 1 --usb on --usbehci on --nic1 hostonly --hostonlyadapter1 \"' + hostonly_if['Name'] + '\" --nic2 nat'))
1.213 + checkResult(Cygwin.vboxExecute('storagectl ' + vm_name + ' --name SATA --add sata --portcount 2'))
1.214 + return
1.215 +
1.216 + # attach storage image to controller
1.217 + def storageAttach(self, vm_name):
1.218 + if self.isStorageAttached(vm_name):
1.219 + self.storageDetach(vm_name)
1.220 + checkResult(Cygwin.vboxExecute('storageattach ' + vm_name + ' --storagectl SATA --port 0 --device 0 --type hdd --medium \"'+ self.machineFolder + '\SecurityDVM\SecurityDVM.vmdk\"'))
1.221 +
1.222 + # return true if storage is attached
1.223 + def isStorageAttached(self, vm_name):
1.224 + info = self.getVMInfo(vm_name)
1.225 + return (info['SATA-0-0']!='none')
1.226 +
1.227 + # detach storage from controller
1.228 + def storageDetach(self, vm_name):
1.229 + if self.isStorageAttached(vm_name):
1.230 + checkResult(Cygwin.vboxExecute('storageattach ' + vm_name + ' --storagectl SATA --port 0 --device 0 --type hdd --medium none'))
1.231 +
1.232 + def changeStorageType(self, filename, storage_type):
1.233 + checkResult(Cygwin.vboxExecute('modifyhd \"' + filename + '\" --type ' + storage_type))
1.234 +
1.235 + # list storage snaphots for VM
1.236 + def updateTemplate(self):
1.237 + self.cleanup()
1.238 + self.poweroffVM('SecurityDVM')
1.239 + self.waitShutdown('SecurityDVM')
1.240 +
1.241 + # check for updates
1.242 + self.genCertificateISO('SecurityDVM')
1.243 + self.attachCertificateISO('SecurityDVM')
1.244 +
1.245 + self.storageDetach('SecurityDVM')
1.246 + results = checkResult(Cygwin.vboxExecute('list hdds'))[1]
1.247 + results = results.replace('Parent UUID', 'Parent')
1.248 + items = list( "UUID:"+result for result in results.split('UUID:') if result != '')
1.249 +
1.250 + snaps = dict()
1.251 + for item in items:
1.252 + props = dict()
1.253 + for line in item.splitlines():
1.254 + if line != "":
1.255 + k,v = line[:line.index(':')].strip(), line[line.index(':')+1:].strip()
1.256 + props[k] = v;
1.257 + snaps[props['UUID']] = props
1.258 +
1.259 +
1.260 + template_storage = self.machineFolder + '\SecurityDVM\SecurityDVM.vmdk'
1.261 +
1.262 + # find template uuid
1.263 + template_uuid = ''
1.264 + for hdd in snaps.values():
1.265 + if hdd['Location'] == template_storage:
1.266 + template_uuid = hdd['UUID']
1.267 + logger.debug('found parent uuid ' + template_uuid)
1.268 +
1.269 + # remove snapshots
1.270 + for hdd in snaps.values():
1.271 + if hdd['Parent'] == template_uuid:
1.272 + #template_uuid = hdd['UUID']
1.273 + logger.debug('removing snapshot ' + hdd['UUID'])
1.274 + checkResult(Cygwin.vboxExecute('closemedium disk {' + hdd['UUID'] + '} --delete'))#[1]
1.275 + # parse result 0%...10%...20%...30%...40%...50%...60%...70%...80%...90%...100%
1.276 +
1.277 + self.changeStorageType(template_storage,'normal')
1.278 + self.storageAttach('SecurityDVM')
1.279 + self.startVM('SecurityDVM')
1.280 + self.waitStartup('SecurityDVM')
1.281 + checkResult(Cygwin.sshExecute('"sudo apt-get -y update"', VMManager.getHostOnlyIP('SecurityDVM'), 'osecuser', Cygwin.cygPath(self.machineFolder) + '/' + 'SecurityDVM' + '/dvm_key'))
1.282 + checkResult(Cygwin.sshExecute('"sudo apt-get -y upgrade"', VMManager.getHostOnlyIP('SecurityDVM'), 'osecuser', Cygwin.cygPath(self.machineFolder) + '/' + 'SecurityDVM' + '/dvm_key'))
1.283 + #self.stopVM('SecurityDVM')
1.284 + self.hibernateVM('SecurityDVM')
1.285 + self.waitShutdown('SecurityDVM')
1.286 + self.storageDetach('SecurityDVM')
1.287 + self.changeStorageType(template_storage,'immutable')
1.288 + self.storageAttach('SecurityDVM')
1.289 + self.rsdHandler = DeviceHandler(self)
1.290 + self.rsdHandler.start()
1.291 +
1.292 + #remove VM from the system. should be used on VMs returned by listSDVMs
1.293 + def removeVM(self, vm_name):
1.294 + logger.info('Removing ' + vm_name)
1.295 + checkResult(Cygwin.vboxExecute('unregistervm ' + vm_name + ' --delete'))
1.296 + vm_file = Cygwin.cygPath(self.machineFolder + '\\' + vm_name)
1.297 + checkResult(Cygwin.bashExecute('rm -rf \'' + vm_file + '\''))
1.298 +
1.299 + # start VM
1.300 + def startVM(self, vm_name):
1.301 + logger.info('Starting ' + vm_name)
1.302 + result = checkResult(Cygwin.vboxExecute('startvm ' + vm_name + ' --type headless' ))
1.303 + while 'successfully started' not in result[1] and _running:
1.304 + logger.error("Failed to start SDVM: " + vm_name + " retrying")
1.305 + time.sleep(1)
1.306 + result = checkResult(Cygwin.vboxExecute('startvm ' + vm_name + ' --type headless'))
1.307 + return result[0]
1.308 +
1.309 + # return wether VM is running or not
1.310 + def isVMRunning(self, vm_name):
1.311 + return vm_name in self.listRunningVMS()
1.312 +
1.313 + # stop VM
1.314 + def stopVM(self, vm_name):
1.315 + logger.info('Sending shutdown signal to ' + vm_name)
1.316 + checkResult(Cygwin.sshExecute( '"sudo shutdown -h now"', VMManager.getHostOnlyIP(vm_name), 'osecuser', Cygwin.cygPath(self.machineFolder) + '/' + vm_name + '/dvm_key' ))
1.317 +
1.318 + # stop VM
1.319 + def hibernateVM(self, vm_name):
1.320 + logger.info('Sending shutdown signal to ' + vm_name)
1.321 + checkResult(Cygwin.sshExecute( '"sudo hibernate-disk&"', VMManager.getHostOnlyIP(vm_name), 'osecuser', Cygwin.cygPath(self.machineFolder) + '/' + vm_name + '/dvm_key', wait_return=False))
1.322 +
1.323 + # poweroff VM
1.324 + def poweroffVM(self, vm_name):
1.325 + if not self.isVMRunning(vm_name):
1.326 + return
1.327 + logger.info('Powering off ' + vm_name)
1.328 + return checkResult(Cygwin.vboxExecute('controlvm ' + vm_name + ' poweroff'))
1.329 +
1.330 + #list the hostonly IFs exposed by the VBox host
1.331 + @staticmethod
1.332 + def getHostOnlyIFs():
1.333 + result = Cygwin.vboxExecute('list hostonlyifs')[1]
1.334 + if result=='':
1.335 + return None
1.336 + props = dict((k.strip(),v.strip().strip('"')) for k,v in (line.split(':', 1) for line in result.strip().splitlines()))
1.337 + return props
1.338 +
1.339 + # return the hostOnly IP for a running guest or the host
1.340 + @staticmethod
1.341 + def getHostOnlyIP(vm_name):
1.342 + if vm_name == None:
1.343 + logger.info('Gettting hostOnly IP address for Host')
1.344 + return VMManager.getHostOnlyIFs()['IPAddress']
1.345 + else:
1.346 + logger.info('Gettting hostOnly IP address ' + vm_name)
1.347 + result = checkResult(Cygwin.vboxExecute('guestproperty get ' + vm_name + ' /VirtualBox/GuestInfo/Net/0/V4/IP'))
1.348 + if result=='':
1.349 + return None
1.350 + result = result[1]
1.351 + if result.startswith('No value set!'):
1.352 + return None
1.353 + return result[result.index(':')+1:].strip()
1.354 +
1.355 + # attach removable storage device to VM by provision of filter
1.356 + def attachRSD(self, vm_name, rsd_filter):
1.357 + return checkResult(Cygwin.vboxExecute('usbfilter add 0 --target ' + vm_name + ' --name OpenSecurityRSD --vendorid ' + rsd_filter.vendorid + ' --productid ' + rsd_filter.productid + ' --revision ' + rsd_filter.revision))
1.358 +
1.359 + # detach removable storage from VM by
1.360 + def detachRSD(self, vm_name):
1.361 + return checkResult(Cygwin.vboxExecute('usbfilter remove 0 --target ' + vm_name))
1.362 +
1.363 + # return the description set for an existing VM
1.364 + def getVMInfo(self, vm_name):
1.365 + results = checkResult(Cygwin.vboxExecute('showvminfo ' + vm_name + ' --machinereadable'))[1]
1.366 + props = dict((k.strip().strip('"'),v.strip().strip('"')) for k,v in (line.split('=', 1) for line in results.splitlines()))
1.367 + return props
1.368 +
1.369 + # return the configured USB filter for an existing VM
1.370 + def getUSBFilter(self, vm_name):
1.371 + props = self.getVMInfo(vm_name)
1.372 + keys = set(['USBFilterVendorId1', 'USBFilterProductId1', 'USBFilterRevision1'])
1.373 + keyset = set(props.keys())
1.374 + usb_filter = None
1.375 + if keyset.issuperset(keys):
1.376 + usb_filter = USBFilter(props['USBFilterVendorId1'], props['USBFilterProductId1'], props['USBFilterRevision1'])
1.377 + return usb_filter
1.378 +
1.379 + #generates ISO containing authorized_keys for use with guest VM
1.380 + def genCertificateISO(self, vm_name):
1.381 + machineFolder = Cygwin.cygPath(self.machineFolder)
1.382 + # remove .ssh folder if exists
1.383 + checkResult(Cygwin.bashExecute('\"/usr/bin/rm -rf \\\"' + machineFolder + '/' + vm_name + '/.ssh\\\"\"'))
1.384 + # remove .ssh folder if exists
1.385 + checkResult(Cygwin.bashExecute('\"/usr/bin/rm -rf \\\"' + machineFolder + '/' + vm_name + '/dvm_key\\\"\"'))
1.386 + # create .ssh folder in vm_name
1.387 + checkResult(Cygwin.bashExecute('\"/usr/bin/mkdir -p \\\"' + machineFolder + '/' + vm_name + '/.ssh\\\"\"'))
1.388 + # generate dvm_key pair in vm_name / .ssh
1.389 + checkResult(Cygwin.bashExecute('\"/usr/bin/ssh-keygen -q -t rsa -N \\"\\" -C \\\"' + vm_name + '\\\" -f \\\"' + machineFolder + '/' + vm_name + '/.ssh/dvm_key\\\"\"'))
1.390 + # move out private key
1.391 + checkResult(Cygwin.bashExecute('\"/usr/bin/mv \\\"' + machineFolder + '/' + vm_name + '/.ssh/dvm_key\\\" \\\"' + machineFolder + '/' + vm_name + '\\\"'))
1.392 + # set permissions for private key
1.393 + checkResult(Cygwin.bashExecute('\"/usr/bin/chmod 500 \\\"' + machineFolder + '/' + vm_name + '/dvm_key\\\"\"'))
1.394 + # rename public key to authorized_keys
1.395 + checkResult(Cygwin.bashExecute('\"/usr/bin/mv \\\"' + machineFolder + '/' + vm_name + '/.ssh/dvm_key.pub\\\" \\\"' + machineFolder + '/' + vm_name + '/.ssh/authorized_keys\\\"'))
1.396 + # set permissions for authorized_keys
1.397 + checkResult(Cygwin.bashExecute('\"/usr/bin/chmod 500 \\\"' + machineFolder + '/' + vm_name + '/.ssh/authorized_keys\\\"\"'))
1.398 + # generate iso image with .ssh/authorized keys
1.399 + checkResult(Cygwin.bashExecute('\"/usr/bin/genisoimage -J -R -o \\\"' + machineFolder + '/' + vm_name + '/'+ vm_name + '.iso\\\" \\\"' + machineFolder + '/' + vm_name + '/.ssh\\\"\"'))
1.400 +
1.401 + # attaches generated ssh public cert to guest vm
1.402 + def attachCertificateISO(self, vm_name):
1.403 + result = checkResult(Cygwin.vboxExecute('storageattach ' + vm_name + ' --storagectl SATA --port 1 --device 0 --type dvddrive --mtype readonly --medium \"' + self.machineFolder + '\\' + vm_name + '\\'+ vm_name + '.iso\"'))
1.404 + return result
1.405 +
1.406 + # wait for machine to come up
1.407 + def waitStartup(self, vm_name, timeout_ms = 30000):
1.408 + checkResult(Cygwin.vboxExecute('guestproperty wait ' + vm_name + ' SDVMStarted --timeout ' + str(timeout_ms) + ' --fail-on-timeout'))
1.409 + return VMManager.getHostOnlyIP(vm_name)
1.410 +
1.411 + # wait for machine to shutdown
1.412 + def waitShutdown(self, vm_name):
1.413 + while vm_name in self.listRunningVMS() and _running:
1.414 + time.sleep(1)
1.415 + return
1.416 +
1.417 + # handles browsing request
1.418 + def handleBrowsingRequest(self):
1.419 + handler = BrowsingHandler(self)
1.420 + handler.start()
1.421 + return 'ok'
1.422 +
1.423 + #Small function to check the availability of network resource.
1.424 + #def isAvailable(self, path):
1.425 + #return os.path.exists(path)
1.426 + #result = Cygwin.cmdExecute('IF EXIST "' + path + '" echo YES')
1.427 + #return string.find(result[1], 'YES',)
1.428 +
1.429 + #Small function to check if the mention location is a directory
1.430 + def isDirectory(self, path):
1.431 + result = checkResult(Cygwin.cmdExecute('dir ' + path + ' | FIND ".."'))
1.432 + return string.find(result[1], 'DIR',)
1.433 +
1.434 + def mapNetworkDrive(self, drive, networkPath, user, password):
1.435 + self.unmapNetworkDrive(drive)
1.436 + #Check for drive availability
1.437 + if os.path.exists(drive):
1.438 + logger.error("Drive letter is already in use: " + drive)
1.439 + return -1
1.440 + #Check for network resource availability
1.441 + retry = 5
1.442 + while not os.path.exists(networkPath):
1.443 + time.sleep(1)
1.444 + if retry == 0:
1.445 + return -1
1.446 + logger.info("Path not accessible: " + networkPath + " retrying")
1.447 + retry-=1
1.448 + #return -1
1.449 +
1.450 + command = 'USE ' + drive + ' ' + networkPath + ' /PERSISTENT:NO'
1.451 + if user != None:
1.452 + command += ' ' + password + ' /User' + user
1.453 +
1.454 + #TODO: Execute 'NET USE' command with authentication
1.455 + result = checkResult(Cygwin.execute('C:\\Windows\\system32\\net.exe', command))
1.456 + if string.find(result[1], 'successfully',) == -1:
1.457 + logger.error("Failed: NET " + command)
1.458 + return -1
1.459 + return 1
1.460 +
1.461 + def unmapNetworkDrive(self, drive):
1.462 + drives = self.getNetworkDrives()
1.463 + if drive not in drives.keys():
1.464 + return 1
1.465 + result = checkResult(Cygwin.execute('C:\\Windows\\system32\\net.exe', 'USE ' + drive + ' /DELETE /YES'))
1.466 + if string.find(str(result[1]), 'successfully',) == -1:
1.467 + logger.error(result[2])
1.468 + return -1
1.469 + return 1
1.470 +
1.471 + def getNetworkDrives(self):
1.472 + ip = VMManager.getHostOnlyIP(None)
1.473 + ip = ip[:ip.rindex('.')]
1.474 + drives = dict()
1.475 + result = checkResult(Cygwin.execute('C:\\Windows\\system32\\net.exe', 'USE'))
1.476 + for line in result[1].splitlines():
1.477 + if ip in line:
1.478 + parts = line.split()
1.479 + drives[parts[1]] = parts[2]
1.480 + return drives
1.481 +
1.482 + def genNetworkDrive(self):
1.483 + network_drives = self.getNetworkDrives()
1.484 + logical_drives = VMManager.getLogicalDrives()
1.485 + drives = list(map(chr, range(68, 91)))
1.486 + for drive in drives:
1.487 + if drive+':' not in network_drives and drive not in logical_drives:
1.488 + return drive+':'
1.489 +
1.490 + def getNetworkDrive(self, vm_name):
1.491 + ip = self.getHostOnlyIP(vm_name)
1.492 + result = checkResult(Cygwin.execute('C:\\Windows\\system32\\net.exe', 'USE'))
1.493 + for line in result[1].splitlines():
1.494 + if line != None and ip in line:
1.495 + parts = line.split()
1.496 + return parts[0]
1.497 + @staticmethod
1.498 + def getLogicalDrives():
1.499 + drive_bitmask = ctypes.cdll.kernel32.GetLogicalDrives()
1.500 + return list(itertools.compress(string.ascii_uppercase, map(lambda x:ord(x) - ord('0'), bin(drive_bitmask)[:1:-1])))
1.501 +
1.502 + @staticmethod
1.503 + def getDriveType(drive):
1.504 + return ctypes.cdll.kernel32.GetDriveTypeW(u"%s:\\"%drive)
1.505 +
1.506 + @staticmethod
1.507 + def getVolumeInfo(drive):
1.508 + volumeNameBuffer = ctypes.create_unicode_buffer(1024)
1.509 + fileSystemNameBuffer = ctypes.create_unicode_buffer(1024)
1.510 + serial_number = None
1.511 + max_component_length = None
1.512 + file_system_flags = None
1.513 +
1.514 + rc = ctypes.cdll.kernel32.GetVolumeInformationW(
1.515 + #ctypes.c_wchar_p("F:\\"),
1.516 + u"%s:\\"%drive,
1.517 + volumeNameBuffer,
1.518 + ctypes.sizeof(volumeNameBuffer),
1.519 + serial_number,
1.520 + max_component_length,
1.521 + file_system_flags,
1.522 + fileSystemNameBuffer,
1.523 + ctypes.sizeof(fileSystemNameBuffer)
1.524 + )
1.525 +
1.526 + return volumeNameBuffer.value, fileSystemNameBuffer.value
1.527 +
1.528 + @staticmethod
1.529 + def stop():
1.530 + """stop all running infinite loops now --> needed for gracefull shutdown"""
1.531 + _running = False
1.532 +
1.533 +
1.534 +
1.535 +def checkResult(result):
1.536 + if result[0] != 0:
1.537 + logger.error('Command failed:' + ''.join(result[2]))
1.538 + raise OpenSecurityException('Command failed:' + ''.join(result[2]))
1.539 + return result
1.540 +
1.541 +# handles browsing request
1.542 +class BrowsingHandler(threading.Thread):
1.543 + vmm = None
1.544 + def __init__(self, vmmanager):
1.545 + threading.Thread.__init__(self)
1.546 + self.vmm = vmmanager
1.547 +
1.548 + def run(self):
1.549 + try:
1.550 + new_sdvm = self.vmm.generateSDVMName()
1.551 + self.vmm.createVM(new_sdvm)
1.552 + self.vmm.storageAttach(new_sdvm)
1.553 + self.vmm.genCertificateISO(new_sdvm)
1.554 + self.vmm.attachCertificateISO(new_sdvm)
1.555 + self.vmm.startVM(new_sdvm)
1.556 + new_ip = self.vmm.waitStartup(new_sdvm)
1.557 + drive = self.vmm.genNetworkDrive()
1.558 + if new_ip != None:
1.559 + self.vmm.mapNetworkDrive(drive, '\\\\' + new_ip + '\\Download', None, None)
1.560 + result = checkResult(Cygwin.sshExecuteX11('/usr/bin/iceweasel', new_ip, 'osecuser', Cygwin.cygPath(self.vmm.getMachineFolder()) + '/' + new_sdvm + '/dvm_key'))
1.561 + except:
1.562 + logger.error("BrowsingHandler failed. Cleaning up")
1.563 +
1.564 + self.vmm.unmapNetworkDrive(drive)
1.565 + self.vmm.poweroffVM(new_sdvm)
1.566 + self.vmm.removeVM(new_sdvm)
1.567 +
1.568 +class DeviceHandler(threading.Thread):
1.569 + vmm = None
1.570 + #handleDeviceChangeLock = threading.Lock()
1.571 + attachedRSDs = None
1.572 + connectedRSDs = None
1.573 + running = True
1.574 + def __init__(self, vmmanger):
1.575 + threading.Thread.__init__(self)
1.576 + self.vmm = vmmanger
1.577 +
1.578 + def stop(self):
1.579 + self.running = False
1.580 +
1.581 + def run(self):
1.582 + self.connectedRSDs = dict()
1.583 + self.attachedRSDs = self.vmm.getAttachedRSDs()
1.584 + while self.running:
1.585 + tmp_rsds = self.vmm.getConnectedRSDS()
1.586 + if tmp_rsds.keys() == self.connectedRSDs.keys():
1.587 + logger.debug("Nothing's changed. sleep(3)")
1.588 + time.sleep(3)
1.589 + continue
1.590 +
1.591 + logger.info("Something's changed")
1.592 + self.connectedRSDs = tmp_rsds
1.593 + self.attachedRSDs = self.vmm.getAttachedRSDs()
1.594 +
1.595 + for vm_name in self.attachedRSDs.keys():
1.596 + if self.attachedRSDs[vm_name] not in self.connectedRSDs.values():
1.597 + drive = self.vmm.getNetworkDrive(vm_name)
1.598 + self.vmm.unmapNetworkDrive(drive)
1.599 + #self.stopVM(vm_name)
1.600 + self.vmm.detachRSD(vm_name)
1.601 + self.vmm.poweroffVM(vm_name)
1.602 + self.vmm.removeVM(vm_name)
1.603 + #create new vm for attached device if any
1.604 + self.attachedRSDs = self.vmm.getAttachedRSDs()
1.605 + self.connectedRSDs = self.vmm.getConnectedRSDS()
1.606 +
1.607 + new_ip = None
1.608 + for connected_device in self.connectedRSDs.values():
1.609 + if (self.attachedRSDs and False) or (connected_device not in self.attachedRSDs.values()):
1.610 + new_sdvm = self.vmm.generateSDVMName()
1.611 + self.vmm.createVM(new_sdvm)
1.612 + self.vmm.storageAttach(new_sdvm)
1.613 + self.vmm.attachRSD(new_sdvm, connected_device)
1.614 + self.vmm.startVM(new_sdvm)
1.615 + new_ip = self.vmm.waitStartup(new_sdvm)
1.616 + drive = self.vmm.genNetworkDrive()
1.617 + if new_ip != None:
1.618 + self.vmm.mapNetworkDrive(drive, '\\\\' + new_ip + '\\USB', None, None)
1.619 +
1.620 +if __name__ == '__main__':
1.621 + #man = VMManager.getInstance()
1.622 + #man.listVM()
1.623 + #print man.getConnectedRSDs()
1.624 + #print man.getNetworkDrives()
1.625 + #man.genNetworkDrive()
1.626 + #drive_bitmask = ctypes.cdll.kernel32.GetLogicalDrives()
1.627 + #print list(itertools.compress(string.ascii_uppercase, map(lambda x:ord(x) - ord('0'), bin(drive_bitmask)[:1:-1])))
1.628 + #print list(map(chr, range(68, 91)))
1.629 + #print Cygwin.getRegEntry('SYSTEM\CurrentControlSet\Enum\USB', 'VID_1058&PID_0704')[0]
1.630 + #devices = VMManager.getConnectedRSDS()
1.631 + #print devices
1.632 +
1.633 + drives = VMManager.getLogicalDrives()
1.634 + print drives
1.635 + print VMManager.getDriveType("E")
1.636 + print VMManager.getVolumeInfo("E")
1.637 + #for device in devices.values():
1.638 + # #print device
1.639 + # if VMManager.isMassStorageDevice(device):
1.640 + # print device
1.641 +
1.642 +
1.643 +
1.644 + #time.sleep(-1)
1.645 + #man.listVM()
1.646 + #man.listVM()
1.647 + #man.listVM()
1.648 + #man.listVM()
1.649 + #man.genCertificateISO('SecurityDVM0')
1.650 + #man.guestExecute('SecurityDVM0', '/bin/ls -la')
1.651 + #logger = setupLogger('VMManager')
1.652 + #c = Cygwin()
1.653 +
1.654 + #man.sshExecute('/bin/ls -la', 'SecurityDVM0')
1.655 + #man.sshExecuteX11('/usr/bin/iceweasel', 'SecurityDVM0')
1.656 + #man.removeVM('SecurityDVM0')
1.657 + #man.netUse('192.168.56.134', 'USB\\')
1.658 + #ip = '192.168.56.139'
1.659 +
1.660 + #man.cygwin_path = 'c:\\cygwin64\\bin\\'
1.661 + #man.handleDeviceChange()
1.662 + #print man.listSDVM()
1.663 + #man.configureHostNetworking()
1.664 + #new_vm = man.generateSDVMName()
1.665 + #man.createVM(new_vm)
1.666 +
1.667 + #print Cygwin.cmd()
1.668 + #man.isAvailable('c:')
1.669 + #ip = man.getHostOnlyIP('SecurityDVM0')
1.670 + #man.mapNetworkDrive('h:', '\\\\' + ip + '\Download', None, None)
1.671 +
1.672 + #man.genCertificateISO(new_vm)
1.673 + #man.attachCertificateISO(new_vm)
1.674 +
1.675 + #man.attachCertificateISO(vm_name)
1.676 + #man.guestExecute(vm_name, "ls")
1.677 + #man.sshGuestX11Execute('SecurityDVM1', '/usr/bin/iceweasel')
1.678 + #time.sleep(60)
1.679 + #print man.cygwinPath("C:\Users\BarthaM\VirtualBox VMs\SecurityDVM\.ssh\*")
1.680 + #man.genCertificateISO('SecurityDVM')
1.681 + #man.attachCertificateISO('SecurityDVM')
1.682 + #man.isStorageAttached('SecurityDVM')
1.683 + #man.guestExecute('SecurityDVM', 'sudo apt-get -y update')
1.684 + #man.guestExecute('SecurityDVM', 'sudo apt-get -y upgrade' )
1.685 +
1.686 + #man.stopVM('SecurityDVM')
1.687 + #man.storageDetach('SecurityDVM')
1.688 + #man.changeStorageType('C:\Users\BarthaM\VirtualBox VMs\SecurityDVM\SecurityDVM.vmdk','immutable')
1.689 + #man.storageAttach('SecurityDVM')
1.690 +
1.691 +
1.692 + #cmd = "c:\\cygwin64\\bin\\bash.exe --login -c \"/bin/ls\""
1.693 + #man.execute(cmd)
1.694 +>>>>>>> other