Esempio n. 1
0
    def _send_all(self, data):
        while data:
            sent = self._stdin.channel.send(data)

            if not sent:
                # Connection was closed by server
                raise GvmError("Remote closed the connection")

            data = data[sent:]
Esempio n. 2
0
 def _feed_xml(self, data):
     try:
         self._parser.feed(data)
     except etree.ParseError as e:
         raise GvmError(
             "Cannot parse XML response. Response data "
             "read {0}".format(data),
             e,
         )
Esempio n. 3
0
 def connect(self):
     """Connect to the UNIX socket
     """
     self._socket = socketlib.socket(socketlib.AF_UNIX,
                                     socketlib.SOCK_STREAM)
     self._socket.settimeout(self._timeout)
     try:
         self._socket.connect(self.path)
     except FileNotFoundError:
         raise GvmError('Socket {path} does not exist'.format(
             path=self.path)) from None
Esempio n. 4
0
    def read(self) -> str:
        """Read data from the remote server

        Returns:
            str: data as utf-8 encoded string
        """
        response = ""

        self._start_xml()

        if self._timeout is not None:
            now = time.time()

            break_timeout = now + self._timeout

        while True:
            data = self._read()

            if not data:
                # Connection was closed by server
                raise GvmError("Remote closed the connection")

            clean_data = data.decode("utf-8", errors="ignore")
            clean_data = clean_data.replace('&#', '')
            self._parser.feed(clean_data.encode())
            #self._feed_xml(data)

            response += data.decode("utf-8", errors="ignore")

            if self._is_end_xml():
                break

            if self._timeout is not None:
                now = time.time()

                if now > break_timeout:
                    raise GvmError("Timeout while reading the response")

        return response
Esempio n. 5
0
def _check_command_status(root: etree.Element):
    status = root.get("status")

    if status is None:
        raise GvmServerError("No status in response.", root)

    if status[0] == "4":
        raise GvmResponseError(status=status, message=root.get("status_text"))
    elif status[0] == "5":
        raise GvmServerError(status=status, message=root.get("status_text"))
    elif status[0] != "2":
        raise GvmError(
            "Error in response. {0}".format(root.get("status_text")), root)
Esempio n. 6
0
    def determine_remote_gmp_version(self) -> str:
        """Determine the supported GMP version of the remote daemon"""
        self.connect()
        resp = self._send_xml_command(XmlCommand("get_version"))
        self.disconnect()

        version_el = resp.find('version')
        if version_el is None:
            raise GvmError(
                'Invalid response from manager daemon while requesting the '
                'version information.')

        return version_el.text
Esempio n. 7
0
def validate_xml_string(xml_string):
    """Checks if the passed string contains valid XML

    Raises a GvmError if the XML is invalid. Otherwise the function just
    returns.

    Raises:
        GvmError: The xml string did contain invalid XML

    """
    try:
        secET.fromstring(xml_string)
    except (DefusedXmlException, etree.LxmlError) as e:
        raise GvmError('Invalid XML', e) from e
Esempio n. 8
0
    def send(self, data: Union[bytes, str]):
        """Send data to the connected remote server

        Arguments:
            data: Data to be send to the server. Either utf-8 encoded string or
                bytes.
        """
        if self._socket is None:
            raise GvmError("Socket is not connected")

        if isinstance(data, str):
            self._socket.sendall(data.encode())
        else:
            self._socket.sendall(data)
Esempio n. 9
0
    def _get_remote_host_key(self):
        """Get the remote host key for ssh connection"""
        try:
            tmp_socket = socketlib.socket()
            tmp_socket.connect((self.hostname, self.port))
        except OSError as e:
            raise GvmError("Couldn't establish a connection to fetch the"
                           f" remote server key: {e}") from None

        trans = paramiko.transport.Transport(tmp_socket)
        try:
            trans.start_client()
        except paramiko.SSHException as e:
            raise GvmError(
                f"Couldn't fetch the remote server key: {e}") from None
        key = trans.get_remote_server_key()
        try:
            trans.close()
        except paramiko.SSHException as e:
            raise GvmError(
                f"Couldn't close the connection to the remote server key: {e}"
            ) from None
        return key
Esempio n. 10
0
    def _read(self):
        """Read a command response from gvmd

        Returns:
            str: Response from server.
        """
        response = self._connection.read()

        logger.debug('read() %i Bytes response: %s', len(response), response)

        if response is None or len(str(response)) == 0:
            raise GvmError('Connection was closed by remote server')

        return response
Esempio n. 11
0
    def _send_all(self, data) -> int:
        """Returns the sum of sent bytes if success"""
        sent_sum = 0
        while data:
            sent = self._stdin.channel.send(data)

            if not sent:
                # Connection was closed by server
                raise GvmError("Remote closed the connection")

            sent_sum += sent

            data = data[sent:]
        return sent_sum
Esempio n. 12
0
    def read(self):
        """Read data from the remote server

        Returns:
            str: data as utf-8 encoded string
        """
        response = ''

        self._start_xml()

        if self._timeout is not None:
            now = time.time()

            break_timeout = now + self._timeout

        while True:
            data = self._read()

            if not data:
                # Connection was closed by server
                raise GvmError('Remote closed the connection')

            self._feed_xml(data)

            response += data.decode('utf-8', errors='ignore')

            if self._is_end_xml():
                break

            if self._timeout is not None:
                now = time.time()

                if now > break_timeout:
                    raise GvmError('Timeout while reading the response')

        return response
Esempio n. 13
0
    def determine_supported_gmp(self) -> SUPPORTED_GMP_VERSIONS:
        """Determine supported GMP version of the remote daemon and return a
        corresponding Gmp class instance
        """
        version = self.determine_remote_gmp_version()
        major_version = int(version.split('.')[0])
        if major_version == 20:
            gmp_class = Gmpv208
        elif major_version == 21:
            gmp_class = Gmpv214
        else:
            raise GvmError(
                'Remote manager daemon uses an unsupported version of GMP. '
                'The GMP version was {}.'.format(version))

        return gmp_class(self._connection, transform=self._gmp_transform)
Esempio n. 14
0
def validate_xml_string(xml_string: str):
    """Checks if the passed string contains valid XML

    Raises a GvmError if the XML is invalid. Otherwise the function just
    returns.

    Arguments:
        xml_string: XML string to validate

    Raises:
        GvmError: The xml string did contain invalid XML

    """
    try:
        secET.fromstring(xml_string)
    except (DefusedXmlException, LxmlError) as e:
        raise GvmError("Invalid XML", e) from e
Esempio n. 15
0
    def determine_supported_gmp(self) -> SUPPORTED_GMP_VERSIONS:
        """Determine supported GMP version of the remote daemon and return a
        corresponding Gmp class instance
        """
        version_str = self.determine_remote_gmp_version().split(".", 1)
        major_version = int(version_str[0])
        minor_version = int(version_str[1])
        if major_version == 20:
            gmp_class = Gmpv208
        elif major_version == 21 and minor_version == 4:
            gmp_class = Gmpv214
        elif major_version == 22 and minor_version == 4:
            gmp_class = Gmpv224
        else:
            raise GvmError(
                "Remote manager daemon uses an unsupported version of GMP. "
                f"The GMP version was {major_version}.{minor_version}")

        return gmp_class(self._connection, transform=self._gmp_transform)
Esempio n. 16
0
    def determine_supported_gmp(self) -> SupportedGmpVersion:
        """ Determine supported GMP version of the remote deamon and return a
            corresponding Gmp class instance
        """
        version = self.determine_remote_gmp_version()
        major_version = int(version[0])
        if major_version == 7:
            gmp_class = Gmpv7
        elif major_version == 8:
            gmp_class = Gmpv8
        elif major_version >= 9:
            gmp_class = Gmpv9
        else:
            raise GvmError(
                'Remote manager daemon uses an unsupported version of GMP. '
                'The GMP version was {}.'.format(version)
            )

        return gmp_class(self._connection, transform=self._gmp_transform)
Esempio n. 17
0
    def _ssh_authentication(self) -> None:
        """Search/add/save the servers key for the SSH authentication process"""

        # set to reject policy (avoid MITM attacks)
        self._socket.set_missing_host_key_policy(paramiko.RejectPolicy())
        # openssh is posix, so this might only a posix approach
        # https://stackoverflow.com/q/32945533
        try:
            # load the keys into paramiko and check if remote is in the list
            self._socket.load_host_keys(filename=self.known_hosts_file)
        except OSError as e:
            if e.errno != errno.ENOENT:
                raise GvmError("Something went wrong with reading "
                               f"the known_hosts file: {e}") from None
        hostkeys = self._socket.get_host_keys()
        if not hostkeys.lookup(self.hostname):
            # Key not found, so connect to remote and fetch the key
            # with the paramiko Transport protocol
            key = self._get_remote_host_key()

            self._ssh_authentication_input_loop(hostkeys=hostkeys, key=key)
Esempio n. 18
0
    def connect(self):
        """
        Connect to the SSH server and authenticate to it
        """
        self._socket = paramiko.SSHClient()
        self._socket.set_missing_host_key_policy(paramiko.AutoAddPolicy())

        try:
            self._socket.connect(hostname=self.hostname,
                                 username=self.username,
                                 password=self.password,
                                 timeout=self._timeout,
                                 port=int(self.port),
                                 allow_agent=False,
                                 look_for_keys=False)
            self._stdin, self._stdout, self._stderr = self._socket.exec_command(
                "", get_pty=False)

        except (
                paramiko.BadHostKeyException,
                paramiko.AuthenticationException,
                paramiko.SSHException,
        ) as e:
            raise GvmError('SSH Connection failed', e)
Esempio n. 19
0
 def my_authenticate(username, password):
     raise GvmError('foo')