Esempio n. 1
0
    def stop(self, label):
        """Stops a virtual machine. Kill them all.
        @param label: virtual machine name.
        @raise CuckooMachineError: if unable to stop virtual machine.
        """
        log.debug("Stopping machine %s", label)

        if self._status(label) == self.POWEROFF:
            raise CuckooMachineError(
                "Trying to stop an already stopped machine {0}".format(label))

        # Force virtual machine shutdown.
        conn = self._connect()
        try:
            if not self.vms[label].isActive():
                log.debug("Trying to stop an already stopped machine %s. Skip",
                          label)
            else:
                self.vms[label].destroy()  # Machete's way!
        except libvirt.libvirtError as e:
            raise CuckooMachineError(
                "Error stopping virtual machine {0}: {1}".format(label, e))
        finally:
            self._disconnect(conn)
        # Check state.
        self._wait_status(label, self.POWEROFF)
Esempio n. 2
0
    def start(self, label):
        """Start a virtual machine.
        @param label: virtual machine identifier: path to vmx file and current snapshot name.
        @raise CuckooMachineError: if unable to start.
        """
        host, snapshot = self._parse_label(label)

        # Preventive check
        if self._is_running(host):
            raise CuckooMachineError("Machine %s is already running" % host)

        self._revert(host, snapshot)

        time.sleep(3)

        log.debug("Starting vm %s" % host)
        try:
            proc = subprocess.Popen([
                self.options.vmware.path, "start", host,
                self.options.vmware.mode
            ],
                                    stdout=subprocess.PIPE,
                                    stderr=subprocess.PIPE)
            if self.options.vmware.mode.lower() == "gui":
                output, error = proc.communicate()
                if output:
                    raise CuckooMachineError("Unable to start machine %s: %s" %
                                             (host, output))
        except OSError as e:
            raise CuckooMachineError(
                "Unable to start machine %s in %s mode: %s" %
                (host, self.options.vmware.mode.upper(), e))
Esempio n. 3
0
    def stop(self, label):
        """Stops a virtual machine.
        @param label: virtual machine name.
        @raise CuckooMachineError: if unable to stop.
        """
        log.debug("Stopping vm %s" % label)

        if self._status(label) in [self.POWEROFF, self.ABORTED]:
            raise CuckooMachineError("Trying to stop an already stopped vm %s" % label)

        try:
            proc = subprocess.Popen([self.options.virtualbox.path, "controlvm", label, "poweroff"],
                               stdout=subprocess.PIPE,
                               stderr=subprocess.PIPE)
            # Sometimes VBoxManage stucks when stopping vm so we needed
            # to add a timeout and kill it after that.
            stop_me = 0
            while proc.poll() is None:
                if stop_me < int(self.options_globals.timeouts.vm_state):
                    time.sleep(1)
                    stop_me += 1
                else:
                    log.debug("Stopping vm %s timeouted. Killing" % label)
                    proc.terminate()

            if proc.returncode != 0 and stop_me < int(self.options_globals.timeouts.vm_state):
                log.debug("VBoxManage exited with error powering off the machine")
        except OSError as e:
            raise CuckooMachineError("VBoxManage failed powering off the machine: %s" % e)
        self._wait_status(label, [self.POWEROFF, self.ABORTED, self.SAVED])
Esempio n. 4
0
    def start(self, label):
        """Start a virtual machine.
        @param label: virtual machine name.
        @raise CuckooMachineError: if unable to start.
        """
        log.debug("Starting vm %s" % label)

        if self._status(label) == self.RUNNING:
            raise CuckooMachineError("Trying to start an already started vm %s" % label)

        try:
            if subprocess.call([self.options.virtualbox.path, "snapshot", label, "restorecurrent"],
                               stdout=subprocess.PIPE,
                               stderr=subprocess.PIPE):
                raise CuckooMachineError("VBoxManage exited with error restoring the machine's snapshot")
        except OSError as e:
            raise CuckooMachineError("VBoxManage failed restoring the machine: %s" % e)
        self._wait_status(label, self.SAVED)

        try:
            subprocess.call([self.options.virtualbox.path,
                              "startvm",
                              label,
                              "--type",
                              self.options.virtualbox.mode],
                             stdout=subprocess.PIPE,
                             stderr=subprocess.PIPE)
        except OSError as e:
            raise CuckooMachineError("VBoxManage failed starting the machine in %s mode: %s"
                                     % (mode.upper(), e))
        self._wait_status(label, self.RUNNING)
Esempio n. 5
0
 def _check_vmx(self, host):
     """Checks a vmx file
     @param host: file path
     @raise CuckooMachineError: if file not found or not ending with .vmx
     """
     if not host.endswith(".vmx"):
         raise CuckooMachineError(
             "Wrong configuration: vm path not ending with .vmx: %s)" %
             host)
     if not os.path.exists(self.options.vmware.path):
         raise CuckooMachineError("Vm file %s not found" % host)
Esempio n. 6
0
    def _connect(self):
        """Connects to libvirt subsystem.
        @raise CuckooMachineError: if cannot connect to libvirt or missing connection string.
        """
        # Check if a connection string is available.
        if not self.dsn:
            raise CuckooMachineError(
                "You must provide a proper connection string")

        try:
            return libvirt.open(self.dsn)
        except libvirt.libvirtError:
            raise CuckooMachineError("Cannot connect to libvirt")
Esempio n. 7
0
    def _wait_status(self, label, state):
        """Waits for a vm status.
        @param label: virtual machine name.
        @param state: virtual machine status, accepts more than one states in a list.
        @raise CuckooMachineError: if default waiting timeout expire.
        """
        # This block was originally suggested by Loic Jaquemet.
        waitme = 0
        try:
            current = self._status(label)
        except NameError:
            return

        if isinstance(state, str):
            state = [state]
        while current not in state:
            log.debug(
                "Waiting %i cuckooseconds for machine %s to switch to status %s",
                waitme, label, state)
            if waitme > int(self.options_globals.timeouts.vm_state):
                raise CuckooMachineError(
                    "Timeout hit while for machine {0} to change status".
                    format(label))
            time.sleep(1)
            waitme += 1
            current = self._status(label)
Esempio n. 8
0
 def _disconnect(self, conn):
     """Disconnects to libvirt subsystem.
     @raise CuckooMachineError: if cannot disconnect from libvirt.
     """
     try:
         conn.close()
     except libvirt.libvirtError:
         raise CuckooMachineError("Cannot disconnect from libvirt")
Esempio n. 9
0
 def _revert(self, host, snapshot):
     """Revets machine to snapshot.
     @param host: file path
     @param snapshot: snapshot name
     @raise CuckooMachineError: if unable to revert
     """
     log.debug("Revert snapshot for vm %s" % host)
     try:
         if subprocess.call(
             [self.options.vmware.path, "revertToSnapshot", host, snapshot],
                 stdout=subprocess.PIPE,
                 stderr=subprocess.PIPE):
             raise CuckooMachineError(
                 "Unable to revert snapshot for machine %s: vmrun exited with error"
                 % host)
     except OSError as e:
         raise CuckooMachineError(
             "Unable to revert snapshot for machine %s: %s" % (host, e))
Esempio n. 10
0
 def _initialize_check(self):
     """Check for configuration file and vmware setup.
     @raise CuckooMachineError: if configuration is missing or wrong.
     """
     if not self.options.vmware.path:
         raise CuckooMachineError(
             "VMware vmrun path missing, please add it to vmware.conf")
     if not os.path.exists(self.options.vmware.path):
         raise CuckooMachineError(
             "VMware vmrun not found in specified path %s" %
             self.options.vmware.path)
     # Consistency checks.
     for machine in self.machines():
         host, snapshot = self._parse_label(machine.label)
         self._check_vmx(host)
         self._check_snapshot(host, snapshot)
     # Base checks.
     super(VMware, self)._initialize_check()
Esempio n. 11
0
    def _status(self, label):
        """Gets current status of a vm.
        @param label: virtual machine name.
        @return: status string.
        """
        log.debug("Getting status for %s", label)

        # Stetes mapping of python-libvirt.
        # virDomainState
        # VIR_DOMAIN_NOSTATE = 0
        # VIR_DOMAIN_RUNNING = 1
        # VIR_DOMAIN_BLOCKED = 2
        # VIR_DOMAIN_PAUSED = 3
        # VIR_DOMAIN_SHUTDOWN = 4
        # VIR_DOMAIN_SHUTOFF = 5
        # VIR_DOMAIN_CRASHED = 6
        # VIR_DOMAIN_PMSUSPENDED = 7

        conn = self._connect()
        try:
            state = self.vms[label].state(flags=0)
        except libvirt.libvirtError as e:
            raise CuckooMachineError(
                "Error getting status for virtual machine {0}: {1}".format(
                    label, e))
        finally:
            self._disconnect(conn)

        if state:
            if state[0] == 1 or state[0] == 3:
                status = self.RUNNING
            elif state[0] == 4 or state[0] == 5:
                status = self.POWEROFF
            else:
                status = self.ERROR

        # Report back status.
        if status:
            self.set_status(label, status)
            return status
        else:
            raise CuckooMachineError(
                "Unable to get status for {0}".format(label))
Esempio n. 12
0
 def _parse_label(self, label):
     """Parse configuration file label.
     @param label: configuration option from config file
     @return: tuple of host file path and snapshot name
     """
     opts = label.strip().split(",")
     if len(opts) != 2:
         raise CuckooMachineError(
             "Wrong label syntax for %s in vmware.conf: %s" % label)
     label = opts[0].strip()
     snapshot = opts[1].strip()
     return label, snapshot
Esempio n. 13
0
 def _list(self):
     """List available virtual machines.
     @raise CuckooMachineError: if unable to list virtual machines.
     """
     conn = self._connect()
     try:
         names = conn.listDefinedDomains()
     except libvirt.libvirtError:
         raise CuckooMachineError("Cannot list domains")
     finally:
         self._disconnect(conn)
     return names
Esempio n. 14
0
    def stop(self, label):
        """Stops a virtual machine.
        @param label: virtual machine identifier: path to vmx file and current snapshot name.
        @raise CuckooMachineError: if unable to stop.
        """
        host, snapshot = self._parse_label(label)

        log.debug("Stopping vm %s" % host)
        if self._is_running(host):
            try:
                if subprocess.call(
                    [self.options.vmware.path, "stop", host, "hard"
                     ],  # Machete never wait.
                        stdout=subprocess.PIPE,
                        stderr=subprocess.PIPE):
                    raise CuckooMachineError("Error shutting down machine %s" %
                                             host)
            except OSError as e:
                raise CuckooMachineError("Error shutting down machine %s: %s" %
                                         (host, e))
        else:
            log.warning("Trying to stop an already stopped machine: %s" % host)
Esempio n. 15
0
    def start(self, label):
        """Starts a virtual machine.
        @param label: virtual machine name.
        @raise CuckooMachineError: if unable to start virtual machine.
        """
        log.debug("Staring machine %s", label)

        if self._status(label) == self.RUNNING:
            raise CuckooMachineError(
                "Trying to start an already started machine {0}".format(label))

        # Get current snapshot.
        conn = self._connect()

        try:
            snap = self.vms[label].hasCurrentSnapshot(flags=0)
        except libvirt.libvirtError:
            self._disconnect(conn)
            raise CuckooMachineError(
                "Unable to get current snapshot for virtual machine {0}".
                format(label))

        # Revert to latest snapshot.
        if snap:
            try:
                current = self.vms[label].snapshotCurrent(flags=0)
                self.vms[label].revertToSnapshot(current, flags=0)
            except libvirt.libvirtError:
                raise CuckooMachineError(
                    "Unable to restore snapshot on virtual machine {0}".format(
                        label))
            finally:
                self._disconnect(conn)
        else:
            self._disconnect(conn)
            raise CuckooMachineError(
                "No snapshot found for virtual machine {0}".format(label))
        # Check state.
        self._wait_status(label, self.RUNNING)
Esempio n. 16
0
 def _initialize_check(self):
     """Runs all checks when a machine manager is initialized.
     @raise CuckooMachineError: if libvirt version is not supported.
     """
     # Version checks.
     if not self._version_check():
         raise CuckooMachineError(
             "Libvirt version is not supported, please get an updated version"
         )
     # Preload VMs
     self.vms = self._fetch_machines()
     # Base checks.
     super(LibVirtMachineManager, self)._initialize_check()
Esempio n. 17
0
 def _lookup(self, label):
     """Search for a virtual machine.
     @param conn: libvirt connection handle.
     @param label: virtual machine name.
     @raise CuckooMachineError: if virtual machine is not found.
     """
     conn = self._connect()
     try:
         vm = conn.lookupByName(label)
     except libvirt.libvirtError:
         raise CuckooMachineError("Cannot found machine {0}".format(label))
     finally:
         self._disconnect(conn)
     return vm
Esempio n. 18
0
 def _is_running(self, host):
     """Checks if host is running.
     @param host: file path
     @return: running status
     """
     try:
         output, error = subprocess.Popen(
             [self.options.vmware.path, "list"],
             stdout=subprocess.PIPE,
             stderr=subprocess.PIPE).communicate()
         if output:
             if host in output:
                 return True
             else:
                 return False
         else:
             raise CuckooMachineError(
                 "Unable to check running status for %s. No output from `vmrun list`"
                 % host)
     except OSError as e:
         raise CuckooMachineError(
             "Unable to check running status for %s. Reason: %s" %
             (host, e))
Esempio n. 19
0
 def _check_snapshot(self, host, snapshot):
     """Checks snapshot existance.
     @param host: file path
     @param snapshot: snapshot name
     @raise CuckooMachineError: if snapshot not found
     """
     try:
         output, error = subprocess.Popen(
             [self.options.vmware.path, "listSnapshots", host],
             stdout=subprocess.PIPE,
             stderr=subprocess.PIPE).communicate()
         if output:
             if snapshot in output:
                 return True
             else:
                 return False
         else:
             raise CuckooMachineError(
                 "Unable to get snapshot list for %s. No output from `vmrun listSnapshots`"
                 % host)
     except OSError as e:
         raise CuckooMachineError(
             "Unable to get snapshot list for %s. Reason: %s" % (host, e))
Esempio n. 20
0
    def dump_memory(self, label, path):
        """Takes a memory dump.
        @param path: path to where to store the memory dump.
        """
        log.debug("Dumping memory for machine %s", label)

        conn = self._connect()
        try:
            self.vms[label].coreDump(path, flags=libvirt.VIR_DUMP_MEMORY_ONLY)
        except libvirt.libvirtError as e:
            raise CuckooMachineError(
                "Error dumping memory virtual machine {0}: {1}".format(
                    label, e))
        finally:
            self._disconnect(conn)
Esempio n. 21
0
 def dump_memory(self, label, path):
     """Takes a memory dump.
     @param path: path to where to store the memory dump.
     """
     try:
         subprocess.call([self.options.virtualbox.path,
                          "debugvm",
                          label,
                          "dumpguestcore",
                          "--filename",
                          path],
                          stdout=subprocess.PIPE,
                          stderr=subprocess.PIPE)
         log.info("Successfully generated memory dump for virtual machine with label %s to path %s"
                  % (label, path))
     except OSError as e:
         raise CuckooMachineError("VBoxManage failed to take a memory dump of the machine with label %s: %s"
                                  % (label, e))
Esempio n. 22
0
    def _status(self, label):
        """Gets current status of a vm.
        @param label: virtual machine name.
        @return: status string.
        """
        log.debug("Getting status for %s"% label)
        status = None
        try:
            proc = subprocess.Popen([self.options.virtualbox.path,
                                     "showvminfo",
                                     label,
                                     "--machinereadable"],
                                     stdout=subprocess.PIPE,
                                     stderr=subprocess.PIPE)
            output, err = proc.communicate()

            if proc.returncode != 0:
                # It's quite common for virtualbox crap utility to exit with:
                # VBoxManage: error: Details: code E_ACCESSDENIED (0x80070005)
                # So we just log to debug this.
                log.debug("VBoxManage returns error checking status for machine %s: %s"
                                       % (label, err))
                status = self.ERROR
        except OSError as e:
            log.warning("VBoxManage failed to check status for machine %s: %s"
                                     % (label, e))
            status = self.ERROR
        if not status:
            for line in output.split("\n"):
                state = re.match(r"VMState=\"(\w+)\"", line, re.M|re.I)
                if state:
                    status = state.group(1)
                    log.debug("Machine %s status %s" % (label, status))
                    status = status.lower()
        # Report back status.
        if status:
            self.set_status(label, status)
            return status
        else:
            raise CuckooMachineError("Unable to get status for %s" % label)
Esempio n. 23
0
    def _list(self):
        """Lists virtual machines installed.
        @return: virtual machine names list.
        """
        try:
            proc = subprocess.Popen([self.options.virtualbox.path, "list", "vms"],
                                    stdout=subprocess.PIPE,
                                    stderr=subprocess.PIPE)
            output = proc.communicate()
        except OSError as e:
            raise CuckooMachineError("VBoxManage error listing installed machines: %s" % e)

        machines = []
        for line in output[0].split("\n"):
            try:
                label = line.split('"')[1]
                if label == "<inaccessible>":
                    log.warning("Found an inaccessible vitual machine: please check his state")
                else:
                    machines.append(label)
            except IndexError:
                continue

        return machines