def test_connect_unknown_host(self):
     ssh_connection = SSHConnection(hostname="0.0.0.1",
                                    known_hosts_file=self.known_hosts_file)
     with self.assertRaises(
             GvmError,
             msg=("Could'nt establish a connection to fetch the remote "
                  "server key: [Errno 65] No route to host"),
     ):
         ssh_connection.connect()
    def test_connect_denied_known_hosts_file(self):
        if os.path.exists(self.known_hosts_file):
            os.chmod(self.known_hosts_file, 0000)

        ssh_connection = SSHConnection(hostname="0.0.0.1",
                                       known_hosts_file=self.known_hosts_file)
        with self.assertRaises(
                GvmError,
                msg=("Could'nt establish a connection to fetch the remote "
                     "server key: [Errno 65] No route to host"),
        ):
            ssh_connection.connect()
    def test_connect(self):
        with patch("paramiko.SSHClient") as SSHClientMock:
            client_mock = SSHClientMock.return_value
            client_mock.exec_command.return_value = ["a", "b", "c"]
            ssh_connection = SSHConnection(
                known_hosts_file=self.known_hosts_file)

            ssh_connection.connect()
            self.assertEqual(ssh_connection._stdin, "a")
            self.assertEqual(ssh_connection._stdout, "b")
            self.assertEqual(ssh_connection._stderr, "c")
            ssh_connection.disconnect()
    def test_read(self):
        with patch("paramiko.SSHClient") as SSHClientMock:
            client_mock = SSHClientMock.return_value
            stdout = Mock()
            stdout.channel.recv.return_value = b"foo bar baz"
            client_mock.exec_command.return_value = [None, stdout, None]
            ssh_connection = SSHConnection(
                known_hosts_file=self.known_hosts_file)

            ssh_connection.connect()
            recved = ssh_connection._read()
            self.assertEqual(recved, b"foo bar baz")
            ssh_connection.disconnect()
    def test_send(self):
        with patch("paramiko.SSHClient") as SSHClientMock:
            client_mock = SSHClientMock.return_value
            stdin = Mock()
            stdin.channel.send.return_value = 4
            client_mock.exec_command.return_value = [stdin, None, None]
            ssh_connection = SSHConnection(
                known_hosts_file=self.known_hosts_file)

            ssh_connection.connect()
            req = ssh_connection.send("blah")
            self.assertEqual(req, 4)
            ssh_connection.disconnect()
    def test_send_error(self):
        with patch("paramiko.SSHClient") as SSHClientMock:
            client_mock = SSHClientMock.return_value
            stdin = Mock()
            stdin.channel.send.return_value = None
            client_mock.exec_command.return_value = [stdin, None, None]
            ssh_connection = SSHConnection(
                known_hosts_file=self.known_hosts_file)

            ssh_connection.connect()
            with self.assertRaises(GvmError,
                                   msg="Remote closed the connection"):
                ssh_connection.send("blah")
            ssh_connection.disconnect()
    def test_disconnect_os_error(self):
        with patch("paramiko.SSHClient") as SSHClientMock:
            client_mock = SSHClientMock.return_value
            client_mock.exec_command.return_value = ["a", "b", "c"]
            client_mock.close.side_effect = OSError

            ssh_connection = SSHConnection(
                known_hosts_file=self.known_hosts_file)
            ssh_connection.connect()

            with self.assertRaises(OSError):
                with self.assertLogs("gvm.connections", level="INFO") as cm:
                    ssh_connection.disconnect()
                    self.assertEqual(cm.output, ["Connection closing error: "])
    def test_send_and_slice(self):
        with patch("paramiko.SSHClient") as SSHClientMock:
            client_mock = SSHClientMock.return_value
            stdin = Mock()
            stdin.channel.send.side_effect = [2, 2]
            client_mock.exec_command.return_value = [stdin, None, None]
            ssh_connection = SSHConnection(
                known_hosts_file=self.known_hosts_file)

            ssh_connection.connect()
            req = ssh_connection.send("blah")
            self.assertEqual(req, 4)

            stdin.channel.send.assert_called()
            with self.assertRaises(AssertionError):
                stdin.channel.send.assert_called_once()
            ssh_connection.disconnect()
    def test_disconnect(self):
        with patch("paramiko.SSHClient") as SSHClientMock:
            client_mock = SSHClientMock.return_value
            client_mock.exec_command.return_value = ["a", "b", "c"]
            ssh_connection = SSHConnection(
                known_hosts_file=self.known_hosts_file)

            ssh_connection.connect()
            self.assertEqual(ssh_connection._stdin, "a")
            self.assertEqual(ssh_connection._stdout, "b")
            self.assertEqual(ssh_connection._stderr, "c")

            ssh_connection.disconnect()
            # make sure the attributes have been deleted
            with self.assertRaises(AttributeError):
                type(ssh_connection._stdin)
            with self.assertRaises(AttributeError):
                type(ssh_connection._stdout)
            with self.assertRaises(AttributeError):
                type(ssh_connection._stderr)
            with self.assertRaises(AttributeError):
                type(ssh_connection._socket)

            with self.assertRaises(AttributeError):
                with self.assertLogs("gvm.connections", level="INFO") as cm:
                    # disconnect twice should not work ...
                    ssh_connection.disconnect()
                    self.assertEqual(
                        cm.output,
                        [
                            "Connection might already be"
                            " closed. No socket found.",
                        ],
                    )

            ssh_connection._socket = None
            ssh_connection.disconnect()
    def test_connect_error(self):
        print(self.known_hosts_file.read_text(encoding="utf-8"))

        ssh_connection = SSHConnection(known_hosts_file=self.known_hosts_file)
        with self.assertRaises(GvmError, msg="SSH Connection failed"):
            ssh_connection.connect()