OpenSecurity/bin/vmmanager.pyw
changeset 63 c354ec779b61
child 66 d768c98d1e48
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/OpenSecurity/bin/vmmanager.pyw	Tue Feb 18 10:36:55 2014 +0100
     1.3 @@ -0,0 +1,523 @@
     1.4 +'''
     1.5 +Created on Nov 19, 2013
     1.6 +
     1.7 +@author: BarthaM
     1.8 +'''
     1.9 +import os
    1.10 +import os.path
    1.11 +from subprocess import Popen, PIPE, call, STARTUPINFO, _subprocess
    1.12 +import subprocess
    1.13 +import sys
    1.14 +import re
    1.15 +
    1.16 +from cygwin import Cygwin
    1.17 +from environment import Environment
    1.18 +import threading
    1.19 +import time
    1.20 +import string
    1.21 +
    1.22 +import shutil
    1.23 +import stat
    1.24 +import tempfile
    1.25 +from opensecurity_util import logger, setupLogger, OpenSecurityException
    1.26 +
    1.27 +DEBUG = True
    1.28 +
    1.29 +class VMManagerException(Exception):
    1.30 +    def __init__(self, value):
    1.31 +        self.value = value
    1.32 +    def __str__(self):
    1.33 +        return repr(self.value)
    1.34 +
    1.35 +class USBFilter:
    1.36 +    vendorid = ""
    1.37 +    productid = ""
    1.38 +    revision = ""
    1.39 +    
    1.40 +    def __init__(self, vendorid, productid, revision):
    1.41 +        self.vendorid = vendorid.lower()
    1.42 +        self.productid = productid.lower()
    1.43 +        self.revision = revision.lower()
    1.44 +        return
    1.45 +    
    1.46 +    def __eq__(self, other):
    1.47 +        return self.vendorid == other.vendorid and self.productid == other.productid and self.revision == other.revision
    1.48 +    
    1.49 +    def __hash__(self):
    1.50 +        return hash(self.vendorid) ^ hash(self.productid) ^ hash(self.revision)
    1.51 +    
    1.52 +    def __repr__(self):
    1.53 +        return "VendorId = \'" + str(self.vendorid) + "\' ProductId = \'" + str(self.productid) + "\' Revision = \'" + str(self.revision) + "\'"
    1.54 + 
    1.55 +class VMManager(object):
    1.56 +    vmRootName = "SecurityDVM"
    1.57 +    systemProperties = None
    1.58 +    startNotifications = list()
    1.59 +    _instance = None
    1.60 +    machineFolder = ''
    1.61 +    
    1.62 +    def __init__(self):
    1.63 +        self.systemProperties = self.getSystemProperties()
    1.64 +        self.machineFolder = self.systemProperties["Default machine folder"]
    1.65 +        self.cleanup()
    1.66 +        return
    1.67 +    
    1.68 +    @staticmethod
    1.69 +    def getInstance():
    1.70 +        if VMManager._instance == None:
    1.71 +            VMManager._instance = VMManager()
    1.72 +        return VMManager._instance
    1.73 +    
    1.74 +    def cleanup(self):
    1.75 +        self.unmapNetworkDrive('G:')
    1.76 +        self.unmapNetworkDrive('H:')
    1.77 +        for vm in self.listSDVM():
    1.78 +            self.poweroffVM(vm)
    1.79 +            self.removeVM(vm)
    1.80 +        
    1.81 +    def putStartNotification(self, ip):
    1.82 +        self.startNotifications.append(ip)
    1.83 +    
    1.84 +    def isSDVMStarted(self, ip):
    1.85 +        return self.startNotifications.contains(ip)
    1.86 +    
    1.87 +    # return hosty system properties
    1.88 +    def getSystemProperties(self):
    1.89 +        result = Cygwin.vboxExecute('list systemproperties')
    1.90 +        if result[1]=='':
    1.91 +            return None
    1.92 +        props = dict((k.strip(),v.strip().strip('"')) for k,v in (line.split(':', 1) for line in result[1].strip().splitlines()))
    1.93 +        logger.debug(props)
    1.94 +        return props
    1.95 +    
    1.96 +    # return the folder containing the guest VMs     
    1.97 +    def getMachineFolder(self):
    1.98 +        return self.machineFolder
    1.99 +    
   1.100 +    #list the hostonly IFs exposed by the VBox host
   1.101 +    def getHostOnlyIFs(self):
   1.102 +        result = Cygwin.vboxExecute('list hostonlyifs')[1]
   1.103 +        if result=='':
   1.104 +            return None
   1.105 +        props = dict((k.strip(),v.strip().strip('"')) for k,v in (line.split(':', 1) for line in result.strip().splitlines()))
   1.106 +        return props
   1.107 +        
   1.108 +    def listRSDS(self):
   1.109 +        results = Cygwin.vboxExecute('list usbhost')[1]
   1.110 +        results = results.split('Host USB Devices:')[1].strip()
   1.111 +        
   1.112 +        items = list( "UUID:"+result for result in results.split('UUID:') if result != '')
   1.113 +        rsds = dict()   
   1.114 +        for item in items:
   1.115 +            props = dict()
   1.116 +            for line in item.splitlines():
   1.117 +                if line != "":         
   1.118 +                    k,v = line[:line.index(':')].strip(), line[line.index(':')+1:].strip()
   1.119 +                    props[k] = v
   1.120 +            
   1.121 +            if 'Product' in props.keys() and props['Product'] == 'Mass Storage':
   1.122 +                usb_filter = USBFilter( re.search(r"\((?P<vid>[0-9A-Fa-f]+)\)", props['VendorId']).groupdict()['vid'], 
   1.123 +                                        re.search(r"\((?P<pid>[0-9A-Fa-f]+)\)", props['ProductId']).groupdict()['pid'],
   1.124 +                                        re.search(r"\((?P<rev>[0-9A-Fa-f]+)\)", props['Revision']).groupdict()['rev'] )
   1.125 +                rsds[props['UUID']] = usb_filter;
   1.126 +                logger.debug(usb_filter)
   1.127 +        return rsds
   1.128 +
   1.129 +    # list all existing VMs registered with VBox
   1.130 +    def listVM(self):
   1.131 +        result = Cygwin.vboxExecute('list vms')[1]
   1.132 +        vms = list(k.strip().strip('"') for k,_ in (line.split(' ') for line in result.splitlines()))
   1.133 +        return vms
   1.134 +    
   1.135 +    # list running VMs
   1.136 +    def listRunningVMS(self):
   1.137 +        result = Cygwin.vboxExecute('list runningvms')[1]
   1.138 +        vms = list(k.strip().strip('"') for k,_ in (line.split(' ') for line in result.splitlines()))
   1.139 +        return vms
   1.140 +    
   1.141 +    # list existing SDVMs
   1.142 +    def listSDVM(self):
   1.143 +        vms = self.listVM()
   1.144 +        svdms = []
   1.145 +        for vm in vms:
   1.146 +            if vm.startswith(self.vmRootName) and vm != self.vmRootName:
   1.147 +                svdms.append(vm)
   1.148 +        return svdms
   1.149 +    
   1.150 +    # generate valid (not already existing SDVM name). necessary for creating a new VM
   1.151 +    def generateSDVMName(self):
   1.152 +        vms = self.listVM()
   1.153 +        for i in range(0,999):
   1.154 +            if(not self.vmRootName+str(i) in vms):
   1.155 +                return self.vmRootName+str(i)
   1.156 +        return ''
   1.157 +    
   1.158 +    # return the RSDs attached to all existing SDVMs
   1.159 +    def getAttachedRSDs(self):
   1.160 +        vms = self.listSDVM()
   1.161 +        attached_devices = dict()
   1.162 +        for vm in vms:
   1.163 +            rsd_filter = self.getUSBFilter(vm)
   1.164 +            if rsd_filter != None:
   1.165 +                attached_devices[vm] = rsd_filter
   1.166 +        return attached_devices
   1.167 +    
   1.168 +    # configures hostonly networking and DHCP server. requires admin rights
   1.169 +    def configureHostNetworking(self):
   1.170 +        #cmd = 'vboxmanage list hostonlyifs'
   1.171 +        #Cygwin.vboxExecute(cmd)
   1.172 +        #cmd = 'vboxmanage hostonlyif remove \"VirtualBox Host-Only Ethernet Adapter\"'
   1.173 +        #Cygwin.vboxExecute(cmd)
   1.174 +        #cmd = 'vboxmanage hostonlyif create'
   1.175 +        #Cygwin.vboxExecute(cmd)
   1.176 +        Cygwin.vboxExecute('hostonlyif ipconfig \"VirtualBox Host-Only Ethernet Adapter\" --ip 192.168.56.1 --netmask 255.255.255.0')
   1.177 +        #cmd = 'vboxmanage dhcpserver add'
   1.178 +        #Cygwin.vboxExecute(cmd)
   1.179 +        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.180 +    
   1.181 +    #create new virtual machine instance based on template vm named SecurityDVM (\SecurityDVM\SecurityDVM.vmdk)
   1.182 +    def createVM(self, vm_name):
   1.183 +        hostonly_if = self.getHostOnlyIFs()
   1.184 +        Cygwin.vboxExecute('createvm --name ' + vm_name + ' --ostype Debian --register')
   1.185 +        Cygwin.vboxExecute('modifyvm ' + vm_name + ' --memory 512 --vram 10 --cpus 1 --usb on --usbehci on --nic1 hostonly --hostonlyadapter1 \"' + hostonly_if['Name'] + '\" --nic2 nat')
   1.186 +        Cygwin.vboxExecute('storagectl ' + vm_name + ' --name SATA --add sata --portcount 2')
   1.187 +        return
   1.188 +    
   1.189 +    # attach storage image to controller
   1.190 +    def storageAttach(self, vm_name):
   1.191 +        if self.isStorageAttached(vm_name):
   1.192 +            self.storageDetach(vm_name)
   1.193 +        Cygwin.vboxExecute('storageattach ' + vm_name + ' --storagectl SATA --port 0 --device 0 --type hdd --medium \"'+ self.machineFolder + '\SecurityDVM\SecurityDVM.vmdk\"')
   1.194 +        return
   1.195 +    
   1.196 +    # return true if storage is attached 
   1.197 +    def isStorageAttached(self, vm_name):
   1.198 +        info = self.getVMInfo(vm_name)
   1.199 +        return (info['SATA-0-0']!='none')
   1.200 +    
   1.201 +    # detach storage from controller
   1.202 +    def storageDetach(self, vm_name):
   1.203 +        if self.isStorageAttached(vm_name):
   1.204 +            Cygwin.vboxExecute('storageattach ' + vm_name + ' --storagectl SATA --port 0 --device 0 --type hdd --medium none')
   1.205 +        return
   1.206 +    
   1.207 +    def changeStorageType(self, filename, storage_type):
   1.208 +        Cygwin.vboxExecute('modifyhd \"' + filename + '\" --type ' + storage_type)
   1.209 +        return
   1.210 +    
   1.211 +    # list storage snaphots for VM
   1.212 +    def updateTemplate(self):
   1.213 +        self.poweroffVM('SecurityDVM')
   1.214 +        self.waitShutdown('SecurityDVM')
   1.215 +        
   1.216 +        # check for updates
   1.217 +        self.genCertificateISO('SecurityDVM')
   1.218 +        self.attachCertificateISO('SecurityDVM')
   1.219 +        
   1.220 +        self.storageDetach('SecurityDVM')
   1.221 +        results = Cygwin.vboxExecute('list hdds')[1]
   1.222 +        results = results.replace('Parent UUID', 'Parent')
   1.223 +        items = list( "UUID:"+result for result in results.split('UUID:') if result != '')
   1.224 +        
   1.225 +        snaps = dict()   
   1.226 +        for item in items:
   1.227 +            props = dict()
   1.228 +            for line in item.splitlines():
   1.229 +                if line != "":         
   1.230 +                    k,v = line[:line.index(':')].strip(), line[line.index(':')+1:].strip()
   1.231 +                    props[k] = v;
   1.232 +            snaps[props['UUID']] = props
   1.233 +        
   1.234 +        
   1.235 +        template_storage = self.machineFolder + '\SecurityDVM\SecurityDVM.vmdk'
   1.236 +        
   1.237 +        # find template uuid
   1.238 +        template_uuid = ''
   1.239 +        for hdd in snaps.values():
   1.240 +            if hdd['Location'] == template_storage:
   1.241 +                template_uuid = hdd['UUID']
   1.242 +        logger.debug('found parent uuid ' + template_uuid)
   1.243 +        
   1.244 +        # remove snapshots 
   1.245 +        for hdd in snaps.values():
   1.246 +            if hdd['Parent'] == template_uuid:
   1.247 +                #template_uuid = hdd['UUID']
   1.248 +                logger.debug('removing snapshot ' + hdd['UUID'])
   1.249 +                results = Cygwin.vboxExecute('closemedium disk {' + hdd['UUID'] + '} --delete')[1]
   1.250 +                # parse result 0%...10%...20%...30%...40%...50%...60%...70%...80%...90%...100%
   1.251 +        
   1.252 +        self.changeStorageType(template_storage,'normal')
   1.253 +        self.storageAttach('SecurityDVM')
   1.254 +        self.startVM('SecurityDVM')
   1.255 +        self.waitStartup('SecurityDVM')
   1.256 +        Cygwin.sshExecute('sudo apt-get -y update', VMManager.getHostOnlyIP('SecurityDVM'), 'osecuser', Cygwin.cygPath(self.machineFolder) + '/' + 'SecurityDVM' + '/dvm_key'  )
   1.257 +        Cygwin.sshExecute('sudo apt-get -y upgrade', VMManager.getHostOnlyIP('SecurityDVM'), 'osecuser', Cygwin.cygPath(self.machineFolder) + '/' + 'SecurityDVM' + '/dvm_key'  )
   1.258 +        self.stopVM('SecurityDVM')
   1.259 +        self.waitShutdown('SecurityDVM')
   1.260 +        self.storageDetach('SecurityDVM')
   1.261 +        self.changeStorageType(template_storage,'immutable')
   1.262 +        self.storageAttach('SecurityDVM')
   1.263 +    
   1.264 +    #remove VM from the system. should be used on VMs returned by listSDVMs    
   1.265 +    def removeVM(self, vm_name):
   1.266 +        logger.info('Removing ' + vm_name)
   1.267 +        Cygwin.vboxExecute('unregistervm ' + vm_name + ' --delete')
   1.268 +        machineFolder = Cygwin.cygPath(self.machineFolder)
   1.269 +        Cygwin.bashExecute('"/usr/bin/rm -rf ' + machineFolder + '/' + vm_name + '"')
   1.270 +    
   1.271 +    # start VM
   1.272 +    def startVM(self, vm_name):
   1.273 +        logger.info('Starting ' +  vm_name)
   1.274 +        result = Cygwin.vboxExecute('startvm ' + vm_name )#+ ' --type headless' )
   1.275 +        while not string.find(str(result), 'successfully started',):
   1.276 +            logger.error("Failed to start SDVM: " + vm_name + " retrying")
   1.277 +            time.sleep(1)
   1.278 +            result = Cygwin.vboxExecute('startvm ' + vm_name + ' --type headless')
   1.279 +        return result[0]
   1.280 +    
   1.281 +    # return wether VM is running or not
   1.282 +    def isVMRunning(self, vm_name):
   1.283 +        return vm_name in self.listRunningVMS()    
   1.284 +    
   1.285 +    # stop VM
   1.286 +    def stopVM(self, vm_name):
   1.287 +        logger.info('Sending shutdown signal to ' + vm_name)
   1.288 +        Cygwin.sshExecute( 'sudo shutdown -h now', VMManager.getHostOnlyIP(vm_name), 'osecuser', Cygwin.cygPath(self.machineFolder) + '/' + vm_name + '/dvm_key' )
   1.289 +            
   1.290 +    # poweroff VM
   1.291 +    def poweroffVM(self, vm_name):
   1.292 +        if not self.isVMRunning(vm_name):
   1.293 +            return
   1.294 +        logger.info('Powering off ' + vm_name)
   1.295 +        return Cygwin.vboxExecute('controlvm ' + vm_name + ' poweroff')
   1.296 +    
   1.297 +    # return the hostOnly IP for a running guest
   1.298 +    @staticmethod    
   1.299 +    def getHostOnlyIP(vm_name):
   1.300 +        logger.info('Gettting hostOnly IP address ' + vm_name)
   1.301 +        result = Cygwin.vboxExecute('guestproperty get ' + vm_name + ' /VirtualBox/GuestInfo/Net/0/V4/IP')
   1.302 +        if result=='':
   1.303 +            return None
   1.304 +        result = result[1]
   1.305 +        if result.startswith('No value set!'):
   1.306 +            return None
   1.307 +        return result[result.index(':')+1:].strip()
   1.308 +    
   1.309 +    # attach removable storage device to VM by provision of filter
   1.310 +    def attachRSD(self, vm_name, rsd_filter):
   1.311 +        return Cygwin.vboxExecute('usbfilter add 0 --target ' + vm_name + ' --name OpenSecurityRSD --vendorid ' + rsd_filter.vendorid + ' --productid ' + rsd_filter.productid + ' --revision ' + rsd_filter.revision)
   1.312 +    
   1.313 +    # detach removable storage from VM by 
   1.314 +    def detachRSD(self, vm_name):
   1.315 +        return Cygwin.vboxExecute('usbfilter remove 0 --target ' + vm_name )
   1.316 +        
   1.317 +    
   1.318 +    # return the description set for an existing VM
   1.319 +    def getVMInfo(self, vm_name):
   1.320 +        results = Cygwin.vboxExecute('showvminfo ' + vm_name + ' --machinereadable')[1]
   1.321 +        props = dict((k.strip().strip('"'),v.strip().strip('"')) for k,v in (line.split('=', 1) for line in results.splitlines()))
   1.322 +        logger.debug(props)
   1.323 +        return props
   1.324 +    
   1.325 +    # return the configured USB filter for an existing VM 
   1.326 +    def getUSBFilter(self, vm_name):
   1.327 +        props = self.getVMInfo(vm_name)
   1.328 +        keys = set(['USBFilterVendorId1', 'USBFilterProductId1', 'USBFilterRevision1'])
   1.329 +        keyset = set(props.keys())
   1.330 +        usb_filter = None
   1.331 +        if keyset.issuperset(keys):
   1.332 +            usb_filter = USBFilter(props['USBFilterVendorId1'], props['USBFilterProductId1'], props['USBFilterRevision1'])
   1.333 +        return usb_filter
   1.334 +    
   1.335 +    #generates ISO containing authorized_keys for use with guest VM
   1.336 +    def genCertificateISO(self, vm_name):
   1.337 +        machineFolder = Cygwin.cygPath(self.machineFolder)
   1.338 +        # remove .ssh folder if exists
   1.339 +        cmd = '\"/usr/bin/rm -rf \\\"' + machineFolder + '/' + vm_name + '/.ssh\\\"\"'
   1.340 +        Cygwin.bashExecute(cmd)
   1.341 +        # remove .ssh folder if exists
   1.342 +        Cygwin.bashExecute('\"/usr/bin/rm -rf \\\"' + machineFolder + '/' + vm_name + '/dvm_key\\\"\"')
   1.343 +        # create .ssh folder in vm_name
   1.344 +        Cygwin.bashExecute('\"/usr/bin/mkdir -p \\\"' + machineFolder + '/' + vm_name + '/.ssh\\\"\"')
   1.345 +        # generate dvm_key pair in vm_name / .ssh     
   1.346 +        Cygwin.bashExecute('\"/usr/bin/ssh-keygen -q -t rsa -N \\"\\" -C \\\"' + vm_name + '\\\" -f \\\"' + machineFolder + '/' + vm_name + '/.ssh/dvm_key\\\"\"')
   1.347 +        # move out private key
   1.348 +        Cygwin.bashExecute('\"/usr/bin/mv \\\"' + machineFolder + '/' + vm_name + '/.ssh/dvm_key\\\" \\\"' + machineFolder + '/' + vm_name + '\\\"')
   1.349 +        # set permissions for private key
   1.350 +        Cygwin.bashExecute('\"/usr/bin/chmod 500 \\\"' + machineFolder + '/' + vm_name + '/dvm_key\\\"\"')
   1.351 +        # rename public key to authorized_keys
   1.352 +        Cygwin.bashExecute('\"/usr/bin/mv \\\"' + machineFolder + '/' + vm_name + '/.ssh/dvm_key.pub\\\" \\\"' + machineFolder + '/' + vm_name + '/.ssh/authorized_keys\\\"')
   1.353 +        # set permissions for authorized_keys
   1.354 +        Cygwin.bashExecute('\"/usr/bin/chmod 500 \\\"' + machineFolder + '/' + vm_name + '/.ssh/authorized_keys\\\"\"')
   1.355 +        # generate iso image with .ssh/authorized keys
   1.356 +        Cygwin.bashExecute('\"/usr/bin/genisoimage -J -R -o \\\"' + machineFolder + '/' + vm_name + '/'+ vm_name + '.iso\\\" \\\"' + machineFolder + '/' + vm_name + '/.ssh\\\"\"')
   1.357 +    
   1.358 +    # attaches generated ssh public cert to guest vm
   1.359 +    def attachCertificateISO(self, vm_name):
   1.360 +        result = Cygwin.vboxExecute('storageattach ' + vm_name + ' --storagectl SATA --port 1 --device 0 --type dvddrive --mtype readonly --medium \"' + self.machineFolder + '\\' + vm_name + '\\'+ vm_name + '.iso\"')
   1.361 +        return result
   1.362 +    
   1.363 +    handleDeviceChangeLock = threading.Lock()
   1.364 +    
   1.365 +    # handles device change events
   1.366 +    def handleDeviceChange(self):
   1.367 +        if VMManager.handleDeviceChangeLock.acquire(True):
   1.368 +            #destroy unused vms
   1.369 +            new_ip = None
   1.370 +            attached_devices = self.getAttachedRSDs()
   1.371 +            connected_devices = self.listRSDS()
   1.372 +            for vm_name in attached_devices.keys():
   1.373 +                if attached_devices[vm_name] not in connected_devices.values():
   1.374 +                    self.unmapNetworkDrive('h:')
   1.375 +                    #self.stopVM(vm_name)
   1.376 +                    self.detachRSD(vm_name)
   1.377 +                    self.poweroffVM(vm_name)
   1.378 +                    self.removeVM(vm_name)
   1.379 +            #create new vm for attached device if any
   1.380 +            attached_devices = self.getAttachedRSDs()
   1.381 +            connected_devices = self.listRSDS()
   1.382 +            for connected_device in connected_devices.values():
   1.383 +                if (attached_devices and False) or (connected_device not in attached_devices.values()):
   1.384 +                    new_sdvm = self.generateSDVMName()
   1.385 +                    self.createVM(new_sdvm)
   1.386 +                    self.storageAttach(new_sdvm)
   1.387 +                    self.attachRSD(new_sdvm, connected_device)
   1.388 +                    self.startVM(new_sdvm)
   1.389 +                    new_ip = self.waitStartup(new_sdvm)
   1.390 +                    if new_ip != None:
   1.391 +                        self.mapNetworkDrive('h:', '\\\\' + new_ip + '\\USB', None, None)
   1.392 +                    #TODO: cleanup notifications somwhere else (eg. machine shutdown)
   1.393 +                    self.startNotifications.remove(new_ip)
   1.394 +            VMManager.handleDeviceChangeLock.release()
   1.395 +            return new_ip
   1.396 +    
   1.397 +    # wait for machine to come up
   1.398 +    def waitStartup(self, vm_name): 
   1.399 +        new_ip = None
   1.400 +        while new_ip == None:
   1.401 +            time.sleep(1)
   1.402 +            new_ip = VMManager.getHostOnlyIP(vm_name)
   1.403 +        while new_ip not in self.startNotifications:
   1.404 +            time.sleep(1)
   1.405 +        return new_ip
   1.406 +    
   1.407 +    # wait for machine to shutdown
   1.408 +    def waitShutdown(self, vm_name):
   1.409 +        while vm_name in self.listRunningVMS():
   1.410 +            time.sleep(1)
   1.411 +        return
   1.412 +        
   1.413 +    # handles browsing request    
   1.414 +    def handleBrowsingRequest(self):
   1.415 +        if VMManager.handleDeviceChangeLock.acquire(True):
   1.416 +            new_sdvm = self.generateSDVMName()
   1.417 +            self.createVM(new_sdvm)
   1.418 +            self.storageAttach(new_sdvm)
   1.419 +            self.genCertificateISO(new_sdvm)
   1.420 +            self.attachCertificateISO(new_sdvm)
   1.421 +            self.startVM(new_sdvm)
   1.422 +            new_ip = self.waitStartup(new_sdvm)
   1.423 +            if new_ip != None:
   1.424 +                self.mapNetworkDrive('g:', '\\\\' + new_ip + '\\Download', None, None)
   1.425 +            #TODO: cleanup notifications somwhere else (eg. machine shutdown)
   1.426 +            self.startNotifications.remove(new_ip)
   1.427 +            VMManager.handleDeviceChangeLock.release()
   1.428 +        return new_sdvm
   1.429 +    
   1.430 +    #Small function to check the availability of network resource.
   1.431 +    def isAvailable(self, path):
   1.432 +        result = Cygwin.cmdExecute('IF EXIST "' + path + '" echo YES')
   1.433 +        return string.find(result[1], 'YES',)
   1.434 +    
   1.435 +    #Small function to check if the mention location is a directory
   1.436 +    def isDirectory(self, path):
   1.437 +        result = Cygwin.cmdExecute('dir ' + path + ' | FIND ".."')
   1.438 +        return string.find(result[1], 'DIR',)
   1.439 +
   1.440 +    def mapNetworkDrive(self, drive, networkPath, user, password):
   1.441 +        self.unmapNetworkDrive(drive)
   1.442 +        #Check for drive availability
   1.443 +        if self.isAvailable(drive) > -1:
   1.444 +            logger.error("Drive letter is already in use: " + drive)
   1.445 +            return -1
   1.446 +        #Check for network resource availability
   1.447 +        while self.isAvailable(networkPath) == -1:
   1.448 +            time.sleep(1)
   1.449 +            logger.info("Path not accessible: " + networkPath + " retrying")
   1.450 +            #return -1
   1.451 +    
   1.452 +        command = 'USE ' + drive + ' ' + networkPath
   1.453 +        if user != None:
   1.454 +            command += ' ' + password + ' /User' + user
   1.455 +    
   1.456 +        #TODO: Execute 'NET USE' command with authentication
   1.457 +        result = Cygwin.execute('C:\\Windows\\system32\\net.exe', command)
   1.458 +        if string.find(result[1], 'successfully',) == -1:
   1.459 +            logger.error("Failed: NET " + command)
   1.460 +            return -1
   1.461 +        return 1
   1.462 +    
   1.463 +    def unmapNetworkDrive(self, drive):
   1.464 +        if self.isAvailable(drive) == -1:
   1.465 +            return -1
   1.466 +        result = Cygwin.execute('C:\\Windows\\system32\\net.exe', 'USE ' + drive + ' /DELETE /YES')
   1.467 +        if string.find(str(result), 'successfully',) == -1:
   1.468 +            return -1
   1.469 +        return 1
   1.470 +
   1.471 +
   1.472 +if __name__ == '__main__':
   1.473 +    man = VMManager.getInstance()
   1.474 +    #man.listVM()
   1.475 +    print man.listRSDS()
   1.476 +    
   1.477 +    #man.listVM()
   1.478 +    #man.listVM()
   1.479 +    #man.listVM()
   1.480 +    #man.listVM()
   1.481 +    #man.genCertificateISO('SecurityDVM0')
   1.482 +    #man.guestExecute('SecurityDVM0', '/bin/ls -la')
   1.483 +    #logger = setupLogger('VMManager')
   1.484 +    c = Cygwin()
   1.485 +    
   1.486 +    #man.sshExecute('/bin/ls -la', 'SecurityDVM0')
   1.487 +    #man.sshExecuteX11('/usr/bin/iceweasel', 'SecurityDVM0')
   1.488 +    #man.removeVM('SecurityDVM0')
   1.489 +    #man.netUse('192.168.56.134', 'USB\\')
   1.490 +    #ip = '192.168.56.139'
   1.491 +    
   1.492 +    #man.cygwin_path = 'c:\\cygwin64\\bin\\'
   1.493 +    #man.handleDeviceChange()
   1.494 +    #print man.listSDVM()
   1.495 +    #man.configureHostNetworking()
   1.496 +    #new_vm = man.generateSDVMName()
   1.497 +    #man.createVM(new_vm)
   1.498 +    
   1.499 +    #print Cygwin.cmd()
   1.500 +    #man.isAvailable('c:')
   1.501 +    #ip = man.getHostOnlyIP('SecurityDVM0')
   1.502 +    #man.mapNetworkDrive('h:', '\\\\' + ip + '\Download', None, None)
   1.503 +    
   1.504 +    #man.genCertificateISO(new_vm)
   1.505 +    #man.attachCertificateISO(new_vm)
   1.506 +    
   1.507 +    #man.attachCertificateISO(vm_name)
   1.508 +    #man.guestExecute(vm_name, "ls")
   1.509 +    #man.sshGuestX11Execute('SecurityDVM1', '/usr/bin/iceweasel')
   1.510 +    #time.sleep(60)
   1.511 +    #print man.cygwinPath("C:\Users\BarthaM\VirtualBox VMs\SecurityDVM\.ssh\*")
   1.512 +    #man.genCertificateISO('SecurityDVM')
   1.513 +    #man.attachCertificateISO('SecurityDVM')
   1.514 +    #man.isStorageAttached('SecurityDVM')
   1.515 +    #man.guestExecute('SecurityDVM', 'sudo apt-get -y update')
   1.516 +    #man.guestExecute('SecurityDVM', 'sudo apt-get -y upgrade' )
   1.517 +    
   1.518 +    #man.stopVM('SecurityDVM')
   1.519 +    #man.storageDetach('SecurityDVM')
   1.520 +    #man.changeStorageType('C:\Users\BarthaM\VirtualBox VMs\SecurityDVM\SecurityDVM.vmdk','immutable')
   1.521 +    #man.storageAttach('SecurityDVM')
   1.522 +    
   1.523 +    
   1.524 +    #cmd = "c:\\cygwin64\\bin\\bash.exe --login -c \"/bin/ls\""
   1.525 +    #man.execute(cmd)
   1.526 +