def test_connect_wrong_input(self, stdout_mock, input_mock): key_io = StringIO("""-----BEGIN OPENSSH PRIVATE KEY----- b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW QyNTUxOQAAACB69SvZKJh/9VgSL0G27b5xVYa8nethH3IERbi0YqJDXwAAAKhjwAdrY8AH awAAAAtzc2gtZWQyNTUxOQAAACB69SvZKJh/9VgSL0G27b5xVYa8nethH3IERbi0YqJDXw AAAEA9tGQi2IrprbOSbDCF+RmAHd6meNSXBUQ2ekKXm4/8xnr1K9komH/1WBIvQbbtvnFV hryd62EfcgRFuLRiokNfAAAAI2FsZXhfZ2F5bm9yQEFsZXhzLU1hY0Jvb2stQWlyLmxvY2 FsAQI= -----END OPENSSH PRIVATE KEY-----""") key = paramiko.Ed25519Key.from_private_key(key_io) hostname = "0.0.0.0" key_type = key.get_name().replace("ssh-", "").upper() inputs = ["asd", "yes", "yoo", "no"] input_mock.side_effect = inputs ssh_connection = SSHConnection(hostname=hostname, known_hosts_file=self.known_hosts_file) ssh_connection._socket = paramiko.SSHClient() with self.assertLogs("gvm.connections", level="INFO") as cm: hostkeys = paramiko.HostKeys(filename=self.known_hosts_file) ssh_connection._ssh_authentication_input_loop(hostkeys=hostkeys, key=key) ret = stdout_mock.getvalue() self.assertEqual( cm.output, [ "INFO:gvm.connections:Warning: " f"Host '{hostname}' ({key_type}) not added to " "the list of known hosts." ], ) self.assertEqual( ret, f"The authenticity of host '{hostname}' can't be established.\n" f"{key_type} key fingerprint is " "J6VESFdD3xSChn8y9PzWzeF+1tl892mOy2TqkMLO4ow.\n" "Are you sure you want to continue connecting (yes/no)? " "Please type 'yes' or 'no': " "Do you want to add 0.0.0.0 to known_hosts (yes/no)? " "Please type 'yes' or 'no': ", )
def test_connect_adding_and_dont_save_hostkey(self, input_mock): key_io = StringIO("""-----BEGIN OPENSSH PRIVATE KEY----- b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW QyNTUxOQAAACB69SvZKJh/9VgSL0G27b5xVYa8nethH3IERbi0YqJDXwAAAKhjwAdrY8AH awAAAAtzc2gtZWQyNTUxOQAAACB69SvZKJh/9VgSL0G27b5xVYa8nethH3IERbi0YqJDXw AAAEA9tGQi2IrprbOSbDCF+RmAHd6meNSXBUQ2ekKXm4/8xnr1K9komH/1WBIvQbbtvnFV hryd62EfcgRFuLRiokNfAAAAI2FsZXhfZ2F5bm9yQEFsZXhzLU1hY0Jvb2stQWlyLmxvY2 FsAQI= -----END OPENSSH PRIVATE KEY-----""") key = paramiko.Ed25519Key.from_private_key(key_io) key_type = key.get_name().replace("ssh-", "").upper() hostname = "0.0.0.0" input_mock.side_effect = ["yes", "no"] ssh_connection = SSHConnection(hostname=hostname, known_hosts_file=self.known_hosts_file) ssh_connection._socket = paramiko.SSHClient() keys = self.known_hosts_file.read_text(encoding="utf-8") self.assertEqual( keys, "127.0.0.1 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBOZWi" "fs+DoMqIa5Nr0wiVrzQNpMbUwaLzuSTN6rNrYA\n", ) with self.assertLogs("gvm.connections", level="INFO") as cm: hostkeys = paramiko.HostKeys(filename=self.known_hosts_file) ssh_connection._ssh_authentication_input_loop(hostkeys=hostkeys, key=key) keys = self.known_hosts_file.read_text(encoding="utf-8") self.assertEqual( cm.output, [ "INFO:gvm.connections:Warning: " f"Host '{hostname}' ({key_type}) not added to " "the list of known hosts." ], ) self.assertEqual( keys, "127.0.0.1 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBOZWi" "fs+DoMqIa5Nr0wiVrzQNpMbUwaLzuSTN6rNrYA\n", )
def test_user_denies_auth(self, input_mock): key_io = StringIO("""-----BEGIN OPENSSH PRIVATE KEY----- b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW QyNTUxOQAAACB69SvZKJh/9VgSL0G27b5xVYa8nethH3IERbi0YqJDXwAAAKhjwAdrY8AH awAAAAtzc2gtZWQyNTUxOQAAACB69SvZKJh/9VgSL0G27b5xVYa8nethH3IERbi0YqJDXw AAAEA9tGQi2IrprbOSbDCF+RmAHd6meNSXBUQ2ekKXm4/8xnr1K9komH/1WBIvQbbtvnFV hryd62EfcgRFuLRiokNfAAAAI2FsZXhfZ2F5bm9yQEFsZXhzLU1hY0Jvb2stQWlyLmxvY2 FsAQI= -----END OPENSSH PRIVATE KEY-----""") key = paramiko.Ed25519Key.from_private_key(key_io) hostname = "0.0.0.0" input_mock.return_value = "no" ssh_connection = SSHConnection(hostname=hostname, known_hosts_file=self.known_hosts_file) ssh_connection._socket = paramiko.SSHClient() with self.assertRaises( SystemExit, msg="User denied key. Host key verification failed."): hostkeys = paramiko.HostKeys(filename=self.known_hosts_file) ssh_connection._ssh_authentication_input_loop(hostkeys=hostkeys, key=key)
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()