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