OpenSecurity/bin/vmmanager.pyw
author mb
Tue, 18 Feb 2014 14:38:24 +0100
changeset 66 d768c98d1e48
parent 63 c354ec779b61
child 78 23551f635ca9
permissions -rw-r--r--
removed headless comment
     1 '''
     2 Created on Nov 19, 2013
     3 
     4 @author: BarthaM
     5 '''
     6 import os
     7 import os.path
     8 from subprocess import Popen, PIPE, call, STARTUPINFO, _subprocess
     9 import subprocess
    10 import sys
    11 import re
    12 
    13 from cygwin import Cygwin
    14 from environment import Environment
    15 import threading
    16 import time
    17 import string
    18 
    19 import shutil
    20 import stat
    21 import tempfile
    22 from opensecurity_util import logger, setupLogger, OpenSecurityException
    23 
    24 DEBUG = True
    25 
    26 class VMManagerException(Exception):
    27     def __init__(self, value):
    28         self.value = value
    29     def __str__(self):
    30         return repr(self.value)
    31 
    32 class USBFilter:
    33     vendorid = ""
    34     productid = ""
    35     revision = ""
    36     
    37     def __init__(self, vendorid, productid, revision):
    38         self.vendorid = vendorid.lower()
    39         self.productid = productid.lower()
    40         self.revision = revision.lower()
    41         return
    42     
    43     def __eq__(self, other):
    44         return self.vendorid == other.vendorid and self.productid == other.productid and self.revision == other.revision
    45     
    46     def __hash__(self):
    47         return hash(self.vendorid) ^ hash(self.productid) ^ hash(self.revision)
    48     
    49     def __repr__(self):
    50         return "VendorId = \'" + str(self.vendorid) + "\' ProductId = \'" + str(self.productid) + "\' Revision = \'" + str(self.revision) + "\'"
    51  
    52 class VMManager(object):
    53     vmRootName = "SecurityDVM"
    54     systemProperties = None
    55     startNotifications = list()
    56     _instance = None
    57     machineFolder = ''
    58     
    59     def __init__(self):
    60         self.systemProperties = self.getSystemProperties()
    61         self.machineFolder = self.systemProperties["Default machine folder"]
    62         self.cleanup()
    63         return
    64     
    65     @staticmethod
    66     def getInstance():
    67         if VMManager._instance == None:
    68             VMManager._instance = VMManager()
    69         return VMManager._instance
    70     
    71     def cleanup(self):
    72         self.unmapNetworkDrive('G:')
    73         self.unmapNetworkDrive('H:')
    74         for vm in self.listSDVM():
    75             self.poweroffVM(vm)
    76             self.removeVM(vm)
    77         
    78     def putStartNotification(self, ip):
    79         self.startNotifications.append(ip)
    80     
    81     def isSDVMStarted(self, ip):
    82         return self.startNotifications.contains(ip)
    83     
    84     # return hosty system properties
    85     def getSystemProperties(self):
    86         result = Cygwin.vboxExecute('list systemproperties')
    87         if result[1]=='':
    88             return None
    89         props = dict((k.strip(),v.strip().strip('"')) for k,v in (line.split(':', 1) for line in result[1].strip().splitlines()))
    90         logger.debug(props)
    91         return props
    92     
    93     # return the folder containing the guest VMs     
    94     def getMachineFolder(self):
    95         return self.machineFolder
    96     
    97     #list the hostonly IFs exposed by the VBox host
    98     def getHostOnlyIFs(self):
    99         result = Cygwin.vboxExecute('list hostonlyifs')[1]
   100         if result=='':
   101             return None
   102         props = dict((k.strip(),v.strip().strip('"')) for k,v in (line.split(':', 1) for line in result.strip().splitlines()))
   103         return props
   104         
   105     def listRSDS(self):
   106         results = Cygwin.vboxExecute('list usbhost')[1]
   107         results = results.split('Host USB Devices:')[1].strip()
   108         
   109         items = list( "UUID:"+result for result in results.split('UUID:') if result != '')
   110         rsds = dict()   
   111         for item in items:
   112             props = dict()
   113             for line in item.splitlines():
   114                 if line != "":         
   115                     k,v = line[:line.index(':')].strip(), line[line.index(':')+1:].strip()
   116                     props[k] = v
   117             
   118             if 'Product' in props.keys() and props['Product'] == 'Mass Storage':
   119                 usb_filter = USBFilter( re.search(r"\((?P<vid>[0-9A-Fa-f]+)\)", props['VendorId']).groupdict()['vid'], 
   120                                         re.search(r"\((?P<pid>[0-9A-Fa-f]+)\)", props['ProductId']).groupdict()['pid'],
   121                                         re.search(r"\((?P<rev>[0-9A-Fa-f]+)\)", props['Revision']).groupdict()['rev'] )
   122                 rsds[props['UUID']] = usb_filter;
   123                 logger.debug(usb_filter)
   124         return rsds
   125 
   126     # list all existing VMs registered with VBox
   127     def listVM(self):
   128         result = Cygwin.vboxExecute('list vms')[1]
   129         vms = list(k.strip().strip('"') for k,_ in (line.split(' ') for line in result.splitlines()))
   130         return vms
   131     
   132     # list running VMs
   133     def listRunningVMS(self):
   134         result = Cygwin.vboxExecute('list runningvms')[1]
   135         vms = list(k.strip().strip('"') for k,_ in (line.split(' ') for line in result.splitlines()))
   136         return vms
   137     
   138     # list existing SDVMs
   139     def listSDVM(self):
   140         vms = self.listVM()
   141         svdms = []
   142         for vm in vms:
   143             if vm.startswith(self.vmRootName) and vm != self.vmRootName:
   144                 svdms.append(vm)
   145         return svdms
   146     
   147     # generate valid (not already existing SDVM name). necessary for creating a new VM
   148     def generateSDVMName(self):
   149         vms = self.listVM()
   150         for i in range(0,999):
   151             if(not self.vmRootName+str(i) in vms):
   152                 return self.vmRootName+str(i)
   153         return ''
   154     
   155     # return the RSDs attached to all existing SDVMs
   156     def getAttachedRSDs(self):
   157         vms = self.listSDVM()
   158         attached_devices = dict()
   159         for vm in vms:
   160             rsd_filter = self.getUSBFilter(vm)
   161             if rsd_filter != None:
   162                 attached_devices[vm] = rsd_filter
   163         return attached_devices
   164     
   165     # configures hostonly networking and DHCP server. requires admin rights
   166     def configureHostNetworking(self):
   167         #cmd = 'vboxmanage list hostonlyifs'
   168         #Cygwin.vboxExecute(cmd)
   169         #cmd = 'vboxmanage hostonlyif remove \"VirtualBox Host-Only Ethernet Adapter\"'
   170         #Cygwin.vboxExecute(cmd)
   171         #cmd = 'vboxmanage hostonlyif create'
   172         #Cygwin.vboxExecute(cmd)
   173         Cygwin.vboxExecute('hostonlyif ipconfig \"VirtualBox Host-Only Ethernet Adapter\" --ip 192.168.56.1 --netmask 255.255.255.0')
   174         #cmd = 'vboxmanage dhcpserver add'
   175         #Cygwin.vboxExecute(cmd)
   176         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')
   177     
   178     #create new virtual machine instance based on template vm named SecurityDVM (\SecurityDVM\SecurityDVM.vmdk)
   179     def createVM(self, vm_name):
   180         hostonly_if = self.getHostOnlyIFs()
   181         Cygwin.vboxExecute('createvm --name ' + vm_name + ' --ostype Debian --register')
   182         Cygwin.vboxExecute('modifyvm ' + vm_name + ' --memory 512 --vram 10 --cpus 1 --usb on --usbehci on --nic1 hostonly --hostonlyadapter1 \"' + hostonly_if['Name'] + '\" --nic2 nat')
   183         Cygwin.vboxExecute('storagectl ' + vm_name + ' --name SATA --add sata --portcount 2')
   184         return
   185     
   186     # attach storage image to controller
   187     def storageAttach(self, vm_name):
   188         if self.isStorageAttached(vm_name):
   189             self.storageDetach(vm_name)
   190         Cygwin.vboxExecute('storageattach ' + vm_name + ' --storagectl SATA --port 0 --device 0 --type hdd --medium \"'+ self.machineFolder + '\SecurityDVM\SecurityDVM.vmdk\"')
   191         return
   192     
   193     # return true if storage is attached 
   194     def isStorageAttached(self, vm_name):
   195         info = self.getVMInfo(vm_name)
   196         return (info['SATA-0-0']!='none')
   197     
   198     # detach storage from controller
   199     def storageDetach(self, vm_name):
   200         if self.isStorageAttached(vm_name):
   201             Cygwin.vboxExecute('storageattach ' + vm_name + ' --storagectl SATA --port 0 --device 0 --type hdd --medium none')
   202         return
   203     
   204     def changeStorageType(self, filename, storage_type):
   205         Cygwin.vboxExecute('modifyhd \"' + filename + '\" --type ' + storage_type)
   206         return
   207     
   208     # list storage snaphots for VM
   209     def updateTemplate(self):
   210         self.poweroffVM('SecurityDVM')
   211         self.waitShutdown('SecurityDVM')
   212         
   213         # check for updates
   214         self.genCertificateISO('SecurityDVM')
   215         self.attachCertificateISO('SecurityDVM')
   216         
   217         self.storageDetach('SecurityDVM')
   218         results = Cygwin.vboxExecute('list hdds')[1]
   219         results = results.replace('Parent UUID', 'Parent')
   220         items = list( "UUID:"+result for result in results.split('UUID:') if result != '')
   221         
   222         snaps = dict()   
   223         for item in items:
   224             props = dict()
   225             for line in item.splitlines():
   226                 if line != "":         
   227                     k,v = line[:line.index(':')].strip(), line[line.index(':')+1:].strip()
   228                     props[k] = v;
   229             snaps[props['UUID']] = props
   230         
   231         
   232         template_storage = self.machineFolder + '\SecurityDVM\SecurityDVM.vmdk'
   233         
   234         # find template uuid
   235         template_uuid = ''
   236         for hdd in snaps.values():
   237             if hdd['Location'] == template_storage:
   238                 template_uuid = hdd['UUID']
   239         logger.debug('found parent uuid ' + template_uuid)
   240         
   241         # remove snapshots 
   242         for hdd in snaps.values():
   243             if hdd['Parent'] == template_uuid:
   244                 #template_uuid = hdd['UUID']
   245                 logger.debug('removing snapshot ' + hdd['UUID'])
   246                 results = Cygwin.vboxExecute('closemedium disk {' + hdd['UUID'] + '} --delete')[1]
   247                 # parse result 0%...10%...20%...30%...40%...50%...60%...70%...80%...90%...100%
   248         
   249         self.changeStorageType(template_storage,'normal')
   250         self.storageAttach('SecurityDVM')
   251         self.startVM('SecurityDVM')
   252         self.waitStartup('SecurityDVM')
   253         Cygwin.sshExecute('sudo apt-get -y update', VMManager.getHostOnlyIP('SecurityDVM'), 'osecuser', Cygwin.cygPath(self.machineFolder) + '/' + 'SecurityDVM' + '/dvm_key'  )
   254         Cygwin.sshExecute('sudo apt-get -y upgrade', VMManager.getHostOnlyIP('SecurityDVM'), 'osecuser', Cygwin.cygPath(self.machineFolder) + '/' + 'SecurityDVM' + '/dvm_key'  )
   255         self.stopVM('SecurityDVM')
   256         self.waitShutdown('SecurityDVM')
   257         self.storageDetach('SecurityDVM')
   258         self.changeStorageType(template_storage,'immutable')
   259         self.storageAttach('SecurityDVM')
   260     
   261     #remove VM from the system. should be used on VMs returned by listSDVMs    
   262     def removeVM(self, vm_name):
   263         logger.info('Removing ' + vm_name)
   264         Cygwin.vboxExecute('unregistervm ' + vm_name + ' --delete')
   265         machineFolder = Cygwin.cygPath(self.machineFolder)
   266         Cygwin.bashExecute('"/usr/bin/rm -rf ' + machineFolder + '/' + vm_name + '"')
   267     
   268     # start VM
   269     def startVM(self, vm_name):
   270         logger.info('Starting ' +  vm_name)
   271         result = Cygwin.vboxExecute('startvm ' + vm_name + ' --type headless' )
   272         while not string.find(str(result), 'successfully started',):
   273             logger.error("Failed to start SDVM: " + vm_name + " retrying")
   274             time.sleep(1)
   275             result = Cygwin.vboxExecute('startvm ' + vm_name + ' --type headless')
   276         return result[0]
   277     
   278     # return wether VM is running or not
   279     def isVMRunning(self, vm_name):
   280         return vm_name in self.listRunningVMS()    
   281     
   282     # stop VM
   283     def stopVM(self, vm_name):
   284         logger.info('Sending shutdown signal to ' + vm_name)
   285         Cygwin.sshExecute( 'sudo shutdown -h now', VMManager.getHostOnlyIP(vm_name), 'osecuser', Cygwin.cygPath(self.machineFolder) + '/' + vm_name + '/dvm_key' )
   286             
   287     # poweroff VM
   288     def poweroffVM(self, vm_name):
   289         if not self.isVMRunning(vm_name):
   290             return
   291         logger.info('Powering off ' + vm_name)
   292         return Cygwin.vboxExecute('controlvm ' + vm_name + ' poweroff')
   293     
   294     # return the hostOnly IP for a running guest
   295     @staticmethod    
   296     def getHostOnlyIP(vm_name):
   297         logger.info('Gettting hostOnly IP address ' + vm_name)
   298         result = Cygwin.vboxExecute('guestproperty get ' + vm_name + ' /VirtualBox/GuestInfo/Net/0/V4/IP')
   299         if result=='':
   300             return None
   301         result = result[1]
   302         if result.startswith('No value set!'):
   303             return None
   304         return result[result.index(':')+1:].strip()
   305     
   306     # attach removable storage device to VM by provision of filter
   307     def attachRSD(self, vm_name, rsd_filter):
   308         return Cygwin.vboxExecute('usbfilter add 0 --target ' + vm_name + ' --name OpenSecurityRSD --vendorid ' + rsd_filter.vendorid + ' --productid ' + rsd_filter.productid + ' --revision ' + rsd_filter.revision)
   309     
   310     # detach removable storage from VM by 
   311     def detachRSD(self, vm_name):
   312         return Cygwin.vboxExecute('usbfilter remove 0 --target ' + vm_name )
   313         
   314     
   315     # return the description set for an existing VM
   316     def getVMInfo(self, vm_name):
   317         results = Cygwin.vboxExecute('showvminfo ' + vm_name + ' --machinereadable')[1]
   318         props = dict((k.strip().strip('"'),v.strip().strip('"')) for k,v in (line.split('=', 1) for line in results.splitlines()))
   319         logger.debug(props)
   320         return props
   321     
   322     # return the configured USB filter for an existing VM 
   323     def getUSBFilter(self, vm_name):
   324         props = self.getVMInfo(vm_name)
   325         keys = set(['USBFilterVendorId1', 'USBFilterProductId1', 'USBFilterRevision1'])
   326         keyset = set(props.keys())
   327         usb_filter = None
   328         if keyset.issuperset(keys):
   329             usb_filter = USBFilter(props['USBFilterVendorId1'], props['USBFilterProductId1'], props['USBFilterRevision1'])
   330         return usb_filter
   331     
   332     #generates ISO containing authorized_keys for use with guest VM
   333     def genCertificateISO(self, vm_name):
   334         machineFolder = Cygwin.cygPath(self.machineFolder)
   335         # remove .ssh folder if exists
   336         cmd = '\"/usr/bin/rm -rf \\\"' + machineFolder + '/' + vm_name + '/.ssh\\\"\"'
   337         Cygwin.bashExecute(cmd)
   338         # remove .ssh folder if exists
   339         Cygwin.bashExecute('\"/usr/bin/rm -rf \\\"' + machineFolder + '/' + vm_name + '/dvm_key\\\"\"')
   340         # create .ssh folder in vm_name
   341         Cygwin.bashExecute('\"/usr/bin/mkdir -p \\\"' + machineFolder + '/' + vm_name + '/.ssh\\\"\"')
   342         # generate dvm_key pair in vm_name / .ssh     
   343         Cygwin.bashExecute('\"/usr/bin/ssh-keygen -q -t rsa -N \\"\\" -C \\\"' + vm_name + '\\\" -f \\\"' + machineFolder + '/' + vm_name + '/.ssh/dvm_key\\\"\"')
   344         # move out private key
   345         Cygwin.bashExecute('\"/usr/bin/mv \\\"' + machineFolder + '/' + vm_name + '/.ssh/dvm_key\\\" \\\"' + machineFolder + '/' + vm_name + '\\\"')
   346         # set permissions for private key
   347         Cygwin.bashExecute('\"/usr/bin/chmod 500 \\\"' + machineFolder + '/' + vm_name + '/dvm_key\\\"\"')
   348         # rename public key to authorized_keys
   349         Cygwin.bashExecute('\"/usr/bin/mv \\\"' + machineFolder + '/' + vm_name + '/.ssh/dvm_key.pub\\\" \\\"' + machineFolder + '/' + vm_name + '/.ssh/authorized_keys\\\"')
   350         # set permissions for authorized_keys
   351         Cygwin.bashExecute('\"/usr/bin/chmod 500 \\\"' + machineFolder + '/' + vm_name + '/.ssh/authorized_keys\\\"\"')
   352         # generate iso image with .ssh/authorized keys
   353         Cygwin.bashExecute('\"/usr/bin/genisoimage -J -R -o \\\"' + machineFolder + '/' + vm_name + '/'+ vm_name + '.iso\\\" \\\"' + machineFolder + '/' + vm_name + '/.ssh\\\"\"')
   354     
   355     # attaches generated ssh public cert to guest vm
   356     def attachCertificateISO(self, vm_name):
   357         result = Cygwin.vboxExecute('storageattach ' + vm_name + ' --storagectl SATA --port 1 --device 0 --type dvddrive --mtype readonly --medium \"' + self.machineFolder + '\\' + vm_name + '\\'+ vm_name + '.iso\"')
   358         return result
   359     
   360     handleDeviceChangeLock = threading.Lock()
   361     
   362     # handles device change events
   363     def handleDeviceChange(self):
   364         if VMManager.handleDeviceChangeLock.acquire(True):
   365             #destroy unused vms
   366             new_ip = None
   367             attached_devices = self.getAttachedRSDs()
   368             connected_devices = self.listRSDS()
   369             for vm_name in attached_devices.keys():
   370                 if attached_devices[vm_name] not in connected_devices.values():
   371                     self.unmapNetworkDrive('h:')
   372                     #self.stopVM(vm_name)
   373                     self.detachRSD(vm_name)
   374                     self.poweroffVM(vm_name)
   375                     self.removeVM(vm_name)
   376             #create new vm for attached device if any
   377             attached_devices = self.getAttachedRSDs()
   378             connected_devices = self.listRSDS()
   379             for connected_device in connected_devices.values():
   380                 if (attached_devices and False) or (connected_device not in attached_devices.values()):
   381                     new_sdvm = self.generateSDVMName()
   382                     self.createVM(new_sdvm)
   383                     self.storageAttach(new_sdvm)
   384                     self.attachRSD(new_sdvm, connected_device)
   385                     self.startVM(new_sdvm)
   386                     new_ip = self.waitStartup(new_sdvm)
   387                     if new_ip != None:
   388                         self.mapNetworkDrive('h:', '\\\\' + new_ip + '\\USB', None, None)
   389                     #TODO: cleanup notifications somwhere else (eg. machine shutdown)
   390                     self.startNotifications.remove(new_ip)
   391             VMManager.handleDeviceChangeLock.release()
   392             return new_ip
   393     
   394     # wait for machine to come up
   395     def waitStartup(self, vm_name): 
   396         new_ip = None
   397         while new_ip == None:
   398             time.sleep(1)
   399             new_ip = VMManager.getHostOnlyIP(vm_name)
   400         while new_ip not in self.startNotifications:
   401             time.sleep(1)
   402         return new_ip
   403     
   404     # wait for machine to shutdown
   405     def waitShutdown(self, vm_name):
   406         while vm_name in self.listRunningVMS():
   407             time.sleep(1)
   408         return
   409         
   410     # handles browsing request    
   411     def handleBrowsingRequest(self):
   412         if VMManager.handleDeviceChangeLock.acquire(True):
   413             new_sdvm = self.generateSDVMName()
   414             self.createVM(new_sdvm)
   415             self.storageAttach(new_sdvm)
   416             self.genCertificateISO(new_sdvm)
   417             self.attachCertificateISO(new_sdvm)
   418             self.startVM(new_sdvm)
   419             new_ip = self.waitStartup(new_sdvm)
   420             if new_ip != None:
   421                 self.mapNetworkDrive('g:', '\\\\' + new_ip + '\\Download', None, None)
   422             #TODO: cleanup notifications somwhere else (eg. machine shutdown)
   423             self.startNotifications.remove(new_ip)
   424             VMManager.handleDeviceChangeLock.release()
   425         return new_sdvm
   426     
   427     #Small function to check the availability of network resource.
   428     def isAvailable(self, path):
   429         result = Cygwin.cmdExecute('IF EXIST "' + path + '" echo YES')
   430         return string.find(result[1], 'YES',)
   431     
   432     #Small function to check if the mention location is a directory
   433     def isDirectory(self, path):
   434         result = Cygwin.cmdExecute('dir ' + path + ' | FIND ".."')
   435         return string.find(result[1], 'DIR',)
   436 
   437     def mapNetworkDrive(self, drive, networkPath, user, password):
   438         self.unmapNetworkDrive(drive)
   439         #Check for drive availability
   440         if self.isAvailable(drive) > -1:
   441             logger.error("Drive letter is already in use: " + drive)
   442             return -1
   443         #Check for network resource availability
   444         while self.isAvailable(networkPath) == -1:
   445             time.sleep(1)
   446             logger.info("Path not accessible: " + networkPath + " retrying")
   447             #return -1
   448     
   449         command = 'USE ' + drive + ' ' + networkPath
   450         if user != None:
   451             command += ' ' + password + ' /User' + user
   452     
   453         #TODO: Execute 'NET USE' command with authentication
   454         result = Cygwin.execute('C:\\Windows\\system32\\net.exe', command)
   455         if string.find(result[1], 'successfully',) == -1:
   456             logger.error("Failed: NET " + command)
   457             return -1
   458         return 1
   459     
   460     def unmapNetworkDrive(self, drive):
   461         if self.isAvailable(drive) == -1:
   462             return -1
   463         result = Cygwin.execute('C:\\Windows\\system32\\net.exe', 'USE ' + drive + ' /DELETE /YES')
   464         if string.find(str(result), 'successfully',) == -1:
   465             return -1
   466         return 1
   467 
   468 
   469 if __name__ == '__main__':
   470     man = VMManager.getInstance()
   471     #man.listVM()
   472     print man.listRSDS()
   473     
   474     #man.listVM()
   475     #man.listVM()
   476     #man.listVM()
   477     #man.listVM()
   478     #man.genCertificateISO('SecurityDVM0')
   479     #man.guestExecute('SecurityDVM0', '/bin/ls -la')
   480     #logger = setupLogger('VMManager')
   481     c = Cygwin()
   482     
   483     #man.sshExecute('/bin/ls -la', 'SecurityDVM0')
   484     #man.sshExecuteX11('/usr/bin/iceweasel', 'SecurityDVM0')
   485     #man.removeVM('SecurityDVM0')
   486     #man.netUse('192.168.56.134', 'USB\\')
   487     #ip = '192.168.56.139'
   488     
   489     #man.cygwin_path = 'c:\\cygwin64\\bin\\'
   490     #man.handleDeviceChange()
   491     #print man.listSDVM()
   492     #man.configureHostNetworking()
   493     #new_vm = man.generateSDVMName()
   494     #man.createVM(new_vm)
   495     
   496     #print Cygwin.cmd()
   497     #man.isAvailable('c:')
   498     #ip = man.getHostOnlyIP('SecurityDVM0')
   499     #man.mapNetworkDrive('h:', '\\\\' + ip + '\Download', None, None)
   500     
   501     #man.genCertificateISO(new_vm)
   502     #man.attachCertificateISO(new_vm)
   503     
   504     #man.attachCertificateISO(vm_name)
   505     #man.guestExecute(vm_name, "ls")
   506     #man.sshGuestX11Execute('SecurityDVM1', '/usr/bin/iceweasel')
   507     #time.sleep(60)
   508     #print man.cygwinPath("C:\Users\BarthaM\VirtualBox VMs\SecurityDVM\.ssh\*")
   509     #man.genCertificateISO('SecurityDVM')
   510     #man.attachCertificateISO('SecurityDVM')
   511     #man.isStorageAttached('SecurityDVM')
   512     #man.guestExecute('SecurityDVM', 'sudo apt-get -y update')
   513     #man.guestExecute('SecurityDVM', 'sudo apt-get -y upgrade' )
   514     
   515     #man.stopVM('SecurityDVM')
   516     #man.storageDetach('SecurityDVM')
   517     #man.changeStorageType('C:\Users\BarthaM\VirtualBox VMs\SecurityDVM\SecurityDVM.vmdk','immutable')
   518     #man.storageAttach('SecurityDVM')
   519     
   520     
   521     #cmd = "c:\\cygwin64\\bin\\bash.exe --login -c \"/bin/ls\""
   522     #man.execute(cmd)
   523