def test_create_with_password(self): """ Initialize object with password. Just to have better coverage, initialize the object with the 'password' value instead of the 'key'. """ conn_params = { 'hostname': 'dummy.host.org', 'username': '******', 'password': '******' } mock = ParamikoSSHClient(**conn_params) mock.connect() expected_conn = { 'username': '******', 'password': '******', 'allow_agent': False, 'hostname': 'dummy.host.org', 'look_for_keys': False, 'port': 22 } mock.client.connect.assert_called_once_with(**expected_conn) self.assertLogMsg('Connecting to server')
def test_password_protected_key_no_password_provided_1(self): path = os.path.join(os.path.dirname(__file__), 'fixtures', 'misc', 'test_rsa_2048b_pass_foobar.key') # Supplied as key_material with open(path, 'r') as fp: private_key = fp.read() conn_params = { 'hostname': 'dummy.host.org', 'username': '******', 'key_material': private_key } mock = ParamikoSSHClient(**conn_params) expected_msg = 'private key file is encrypted' assertRaisesRegex(self, paramiko.ssh_exception.PasswordRequiredException, expected_msg, mock.connect) conn_params = { 'hostname': 'dummy.host.org', 'username': '******', 'key_files': path } mock = ParamikoSSHClient(**conn_params) expected_msg = 'private key file is encrypted' assertRaisesRegex(self, paramiko.ssh_exception.PasswordRequiredException, expected_msg, mock.connect)
def test_key_material_argument(self): path = os.path.join(os.path.dirname(__file__), 'fixtures', 'misc', 'test_rsa.key') with open(path, 'r') as fp: private_key = fp.read() conn_params = { 'hostname': 'dummy.host.org', 'username': '******', 'key_material': private_key } mock = ParamikoSSHClient(**conn_params) mock.connect() pkey = paramiko.RSAKey.from_private_key(StringIO(private_key)) expected_conn = { 'username': '******', 'allow_agent': False, 'hostname': 'dummy.host.org', 'look_for_keys': False, 'pkey': pkey, 'port': 22 } mock.client.connect.assert_called_once_with(**expected_conn) self.assertLogMsg('Connecting to server')
def test_key_material_argument(self): path = os.path.join(os.path.dirname(__file__), "fixtures", "misc", "test_rsa.key") with open(path, "r") as fp: private_key = fp.read() conn_params = { "hostname": "dummy.host.org", "username": "******", "key_material": private_key, } mock = ParamikoSSHClient(**conn_params) mock.connect() pkey = paramiko.RSAKey.from_private_key(StringIO(private_key)) expected_conn = { "username": "******", "allow_agent": False, "hostname": "dummy.host.org", "look_for_keys": False, "pkey": pkey, "port": 22, } mock.client.connect.assert_called_once_with(**expected_conn) self.assertLogMsg("Connecting to server")
def test_putfo_relative_path(self): conn_params = {"hostname": "dummy.host.org", "username": "******"} client = ParamikoSSHClient(**conn_params) mock_client = Mock() mock_sftp_client = Mock() mock_transport = Mock() mock_client.get_transport.return_value = mock_transport mock_sftp_client.getcwd.return_value = "/mock/cwd" client.client = mock_client client.sftp_client = mock_sftp_client mock_fo = StringIO("mock stream data 2") result = client.putfo(path="path2.txt", fo=mock_fo, chmod=466) self.assertEqual(result, "/mock/cwd/path2.txt") calls = [call(".")] mock_sftp_client.chdir.assert_has_calls(calls, any_order=False) mock_sftp_client.putfo.assert_called_once_with(mock_fo, "path2.txt") calls = [call("path2.txt"), call().chmod(466), call().close()] mock_sftp_client.file.assert_has_calls(calls, any_order=False)
def test_put_relative_path(self): conn_params = {"hostname": "dummy.host.org", "username": "******"} client = ParamikoSSHClient(**conn_params) mock_client = Mock() mock_sftp_client = Mock() mock_transport = Mock() mock_client.get_transport.return_value = mock_transport mock_sftp_client.getcwd.return_value = "/mock/cwd" client.client = mock_client client.sftp_client = mock_sftp_client result = client.put(path="path2.txt", contents="foo bar 2", chmod=466, mode="a") self.assertEqual(result, "/mock/cwd/path2.txt") calls = [call(".")] mock_sftp_client.chdir.assert_has_calls(calls, any_order=False) calls = [ call("path2.txt", mode="a"), call().write("foo bar 2"), call().chmod(466), call().close(), ] mock_sftp_client.file.assert_has_calls(calls, any_order=False)
def test_put_relative_path(self): conn_params = {'hostname': 'dummy.host.org', 'username': '******'} client = ParamikoSSHClient(**conn_params) mock_client = Mock() mock_sftp_client = Mock() mock_transport = Mock() mock_client.get_transport.return_value = mock_transport mock_sftp_client.getcwd.return_value = '/mock/cwd' client.client = mock_client client.sftp_client = mock_sftp_client result = client.put(path='path2.txt', contents='foo bar 2', chmod=466, mode='a') self.assertEqual(result, '/mock/cwd/path2.txt') calls = [call('.')] mock_sftp_client.chdir.assert_has_calls(calls, any_order=False) calls = [ call('path2.txt', mode='a'), call().write('foo bar 2'), call().chmod(466), call().close() ] mock_sftp_client.file.assert_has_calls(calls, any_order=False)
def test_putfo_relative_path(self): conn_params = {'hostname': 'dummy.host.org', 'username': '******'} client = ParamikoSSHClient(**conn_params) mock_client = Mock() mock_sftp_client = Mock() mock_transport = Mock() mock_client.get_transport.return_value = mock_transport mock_sftp_client.getcwd.return_value = '/mock/cwd' client.client = mock_client client.sftp_client = mock_sftp_client mock_fo = StringIO('mock stream data 2') result = client.putfo(path='path2.txt', fo=mock_fo, chmod=466) self.assertEqual(result, '/mock/cwd/path2.txt') calls = [call('.')] mock_sftp_client.chdir.assert_has_calls(calls, any_order=False) mock_sftp_client.putfo.assert_called_once_with(mock_fo, "path2.txt") calls = [call('path2.txt'), call().chmod(466), call().close()] mock_sftp_client.file.assert_has_calls(calls, any_order=False)
def test_consume_stderr_chunk_contains_non_utf8_character(self): conn_params = {'hostname': 'dummy.host.org', 'username': '******'} client = ParamikoSSHClient(**conn_params) client.CHUNK_SIZE = 1 chan = Mock() chan.recv_stderr_ready.side_effect = [True, True, True, False] chan.recv_stderr.side_effect = ['🤦'.encode('utf-32'), 'a', 'b'] stderr = client._consume_stderr(chan).getvalue() self.assertEqual('\x00\x00&\x01\x00ab', stderr) self.assertEqual(len(stderr), 7)
def test_consume_stderr_chunk_contains_non_utf8_character(self): conn_params = {"hostname": "dummy.host.org", "username": "******"} client = ParamikoSSHClient(**conn_params) client.CHUNK_SIZE = 1 chan = Mock() chan.recv_stderr_ready.side_effect = [True, True, True, False] chan.recv_stderr.side_effect = ["🤦".encode("utf-32"), "a", "b"] stderr = client._consume_stderr(chan).getvalue() self.assertEqual("\x00\x00&\x01\x00ab", stderr) self.assertEqual(len(stderr), 7)
def test_consume_stderr_chunk_contains_part_of_multi_byte_utf8_character( self): conn_params = {"hostname": "dummy.host.org", "username": "******"} client = ParamikoSSHClient(**conn_params) client.CHUNK_SIZE = 1 chan = Mock() chan.recv_stderr_ready.side_effect = [True, True, True, True, False] chan.recv_stderr.side_effect = ["\xF0", "\x90", "\x8D", "\x88"] stderr = client._consume_stderr(chan).getvalue() self.assertEqual("ð\x90\x8d\x88", stderr) self.assertEqual(len(stderr), 4)
def test_consume_stderr_chunk_contains_part_of_multi_byte_utf8_character( self): conn_params = {'hostname': 'dummy.host.org', 'username': '******'} client = ParamikoSSHClient(**conn_params) client.CHUNK_SIZE = 1 chan = Mock() chan.recv_stderr_ready.side_effect = [True, True, True, True, False] chan.recv_stderr.side_effect = ['\xF0', '\x90', '\x8D', '\x88'] stderr = client._consume_stderr(chan).getvalue() self.assertEqual('\xf0\x90\x8d\x88', stderr.encode('utf-8')) self.assertTrue(len(stderr) in [1, 2])
def test_key_material_valid_pem_keys_invalid_header_auto_conversion(self): # Test a scenario where valid PEM keys with invalid headers which is # not recognized by paramiko are automatically converted in a format # which is recognized by paramiko conn_params = {"hostname": "dummy.host.org", "username": "******"} client = ParamikoSSHClient(**conn_params) # 1. RSA key type with header which is not supported by paramiko path = os.path.join( os.path.dirname(__file__), "fixtures", "misc", "test_rsa_non_paramiko_recognized_header.key", ) with open(path, "r") as fp: private_key = fp.read() pkey = client._get_pkey_object(key=private_key) self.assertTrue(pkey) self.assertTrue(isinstance(pkey, paramiko.RSAKey)) # 2. DSA key type with header which is not supported by paramiko path = os.path.join( os.path.dirname(__file__), "fixtures", "misc", "test_dsa_non_paramiko_recognized_header.key", ) with open(path, "r") as fp: private_key = fp.read() pkey = client._get_pkey_object(key=private_key) self.assertTrue(pkey) self.assertTrue(isinstance(pkey, paramiko.DSSKey)) # 3. ECDSA key type with header which is not supported by paramiko path = os.path.join( os.path.dirname(__file__), "fixtures", "misc", "test_ecdsa_non_paramiko_recognized_header.key", ) with open(path, "r") as fp: private_key = fp.read() pkey = client._get_pkey_object(key=private_key) self.assertTrue(pkey) self.assertTrue(isinstance(pkey, paramiko.ECDSAKey))
def test_consume_stderr(self): conn_params = {'hostname': 'dummy.host.org', 'username': '******'} client = ParamikoSSHClient(**conn_params) client.CHUNK_SIZE = 1024 chan = Mock() chan.recv_stderr_ready.side_effect = [True, True, False] chan.recv_stderr.side_effect = ['123', '456'] stderr = client._consume_stderr(chan).getvalue() self.assertEqual(u('123456'), stderr) self.assertEqual(len(stderr), 6) conn_params = {'hostname': 'dummy.host.org', 'username': '******'} client = ParamikoSSHClient(**conn_params) client.CHUNK_SIZE = 1024 chan = Mock() chan.recv_stderr_ready.side_effect = [True, True, False] chan.recv_stderr.side_effect = ['987', '6543210'] stderr = client._consume_stderr(chan).getvalue() self.assertEqual(u('9876543210'), stderr) self.assertEqual(len(stderr), 10)
def test_create_with_password(self): conn_params = {'hostname': 'dummy.host.org', 'username': '******', 'password': '******'} mock = ParamikoSSHClient(**conn_params) mock.connect() expected_conn = {'username': '******', 'password': '******', 'allow_agent': False, 'hostname': 'dummy.host.org', 'look_for_keys': False, 'port': 22} mock.client.connect.assert_called_once_with(**expected_conn) self.assertLogMsg('Connecting to server')
def test_deprecated_key_argument(self): conn_params = {'hostname': 'dummy.host.org', 'username': '******', 'key': 'id_rsa'} mock = ParamikoSSHClient(**conn_params) mock.connect() expected_conn = {'username': '******', 'allow_agent': False, 'hostname': 'dummy.host.org', 'look_for_keys': False, 'key_filename': 'id_rsa', 'port': 22} mock.client.connect.assert_called_once_with(**expected_conn) self.assertLogMsg('Connecting to server')
def test_ed25519_key_type(self): path = os.path.join(os.path.dirname(__file__), "fixtures", "misc", "test_ed25519.key") # Supplied as key_material with open(path, "r") as fp: private_key = fp.read() conn_params = { "hostname": "dummy.host.org", "username": "******", "key_material": private_key, } mock = ParamikoSSHClient(**conn_params) self.assertTrue(mock.connect())
def test_ed25519_key_type(self): path = os.path.join(os.path.dirname(__file__), 'fixtures', 'misc', 'test_ed25519.key') # Supplied as key_material with open(path, 'r') as fp: private_key = fp.read() conn_params = { 'hostname': 'dummy.host.org', 'username': '******', 'key_material': private_key } mock = ParamikoSSHClient(**conn_params) self.assertTrue(mock.connect())
def test_create_without_credentials(self): """ Initialize object with no credentials. Just to have better coverage, initialize the object without 'password' neither 'key'. """ conn_params = {'hostname': 'dummy.host.org', 'username': '******'} mock = ParamikoSSHClient(**conn_params) mock.connect() expected_conn = {'username': '******', 'hostname': 'dummy.host.org', 'allow_agent': True, 'look_for_keys': True, 'port': 22} mock.client.connect.assert_called_once_with(**expected_conn)
def test_create_without_credentials(self): """ Initialize object with no credentials. Just to have better coverage, initialize the object without 'password' neither 'key'. """ conn_params = {"hostname": "dummy.host.org", "username": "******"} mock = ParamikoSSHClient(**conn_params) mock.connect() expected_conn = { "username": "******", "hostname": "dummy.host.org", "allow_agent": True, "look_for_keys": True, "port": 22, } mock.client.connect.assert_called_once_with(**expected_conn)
def test_password_protected_key_no_password_provided_1(self): path = os.path.join( os.path.dirname(__file__), "fixtures", "misc", "test_rsa_2048b_pass_foobar.key", ) # Supplied as key_material with open(path, "r") as fp: private_key = fp.read() conn_params = { "hostname": "dummy.host.org", "username": "******", "key_material": private_key, } mock = ParamikoSSHClient(**conn_params) expected_msg = "private key file is encrypted" assertRaisesRegex( self, paramiko.ssh_exception.PasswordRequiredException, expected_msg, mock.connect, ) conn_params = { "hostname": "dummy.host.org", "username": "******", "key_files": path, } mock = ParamikoSSHClient(**conn_params) expected_msg = "private key file is encrypted" assertRaisesRegex( self, paramiko.ssh_exception.PasswordRequiredException, expected_msg, mock.connect, )
def test_deprecated_key_argument(self): conn_params = { "hostname": "dummy.host.org", "username": "******", "key": "id_rsa", } mock = ParamikoSSHClient(**conn_params) mock.connect() expected_conn = { "username": "******", "allow_agent": False, "hostname": "dummy.host.org", "look_for_keys": False, "key_filename": "id_rsa", "port": 22, } mock.client.connect.assert_called_once_with(**expected_conn) self.assertLogMsg("Connecting to server")
def test_key_material_argument_invalid_key(self): conn_params = {'hostname': 'dummy.host.org', 'username': '******', 'key_material': 'id_rsa'} mock = ParamikoSSHClient(**conn_params) expected_msg = 'Invalid or unsupported key type' self.assertRaisesRegexp(paramiko.ssh_exception.SSHException, expected_msg, mock.connect)
def test_create_with_password(self): """ Initialize object with password. Just to have better coverage, initialize the object with the 'password' value instead of the 'key'. """ conn_params = {'hostname': 'dummy.host.org', 'username': '******', 'password': '******'} mock = ParamikoSSHClient(**conn_params) mock.connect() expected_conn = {'username': '******', 'password': '******', 'allow_agent': False, 'hostname': 'dummy.host.org', 'look_for_keys': False, 'port': 22} mock.client.connect.assert_called_once_with(**expected_conn)
def test_put_absolute_path_windows(self): conn_params = {'hostname': 'dummy.host.org', 'username': '******'} client = ParamikoSSHClient(**conn_params) mock_client = Mock() mock_sftp_client = Mock() mock_transport = Mock() mock_client.get_transport.return_value = mock_transport mock_sftp_client.getcwd.return_value = 'C:\\Administrator' client.client = mock_client client.sftp_client = mock_sftp_client result = client.put(path='C:\\users\\user1\\1.txt', contents='foo bar', chmod=455, mode='w') self.assertEqual(result, 'C:\\users\\user1\\1.txt') result = client.put(path='\\users\\user1\\1.txt', contents='foo bar', chmod=455, mode='w') self.assertEqual(result, '\\users\\user1\\1.txt') result = client.put(path='1.txt', contents='foo bar', chmod=455, mode='w') self.assertEqual(result, 'C:\\Administrator\\1.txt') mock_client.get_transport.return_value = mock_transport mock_sftp_client.getcwd.return_value = '/C:\\User1' client.client = mock_client client.sftp_client = mock_sftp_client result = client.put(path='1.txt', contents='foo bar', chmod=455, mode='w') self.assertEqual(result, 'C:\\User1\\1.txt')
def test_put_absolute_path_windows(self): conn_params = {"hostname": "dummy.host.org", "username": "******"} client = ParamikoSSHClient(**conn_params) mock_client = Mock() mock_sftp_client = Mock() mock_transport = Mock() mock_client.get_transport.return_value = mock_transport mock_sftp_client.getcwd.return_value = "C:\\Administrator" client.client = mock_client client.sftp_client = mock_sftp_client result = client.put(path="C:\\users\\user1\\1.txt", contents="foo bar", chmod=455, mode="w") self.assertEqual(result, "C:\\users\\user1\\1.txt") result = client.put(path="\\users\\user1\\1.txt", contents="foo bar", chmod=455, mode="w") self.assertEqual(result, "\\users\\user1\\1.txt") result = client.put(path="1.txt", contents="foo bar", chmod=455, mode="w") self.assertEqual(result, "C:\\Administrator\\1.txt") mock_client.get_transport.return_value = mock_transport mock_sftp_client.getcwd.return_value = "/C:\\User1" client.client = mock_client client.sftp_client = mock_sftp_client result = client.put(path="1.txt", contents="foo bar", chmod=455, mode="w") self.assertEqual(result, "C:\\User1\\1.txt")
def setUp(self): """ Creates the object patching the actual connection. """ conn_params = { 'hostname': 'dummy.host.org', 'port': 8822, 'username': '******', 'key': '~/.ssh/ubuntu_ssh', 'timeout': '600' } self.ssh_cli = ParamikoSSHClient(**conn_params)
def test_key_material_argument_invalid_key(self): conn_params = { "hostname": "dummy.host.org", "username": "******", "key_material": "id_rsa", } mock = ParamikoSSHClient(**conn_params) expected_msg = "Invalid or unsupported key type" assertRaisesRegex(self, paramiko.ssh_exception.SSHException, expected_msg, mock.connect)
def test_keep_alive_and_compression(self): conn_params = {'hostname': 'dummy.host.org', 'username': '******'} client = ParamikoSSHClient(**conn_params) mock_transport = Mock() client.client.get_transport = Mock(return_value=mock_transport) transport = client._get_transport() self.assertEqual(transport.set_keepalive.call_count, 0) self.assertEqual(transport.use_compression.call_count, 0) conn_params = { 'hostname': 'dummy.host.org', 'username': '******', 'keep_alive': 15, 'use_compression': True } client = ParamikoSSHClient(**conn_params) mock_transport = Mock() client.client.get_transport = Mock(return_value=mock_transport) transport = client._get_transport() self.assertEqual(transport.set_keepalive.call_count, 1) self.assertEqual(transport.use_compression.call_count, 1)
def test_password_protected_key_valid_password_provided(self): path = os.path.join( os.path.dirname(__file__), "fixtures", "misc", "test_rsa_2048b_pass_foobar.key", ) # Supplied as key_material with open(path, "r") as fp: private_key = fp.read() conn_params = { "hostname": "dummy.host.org", "username": "******", "key_material": private_key, "password": "******", } mock = ParamikoSSHClient(**conn_params) self.assertTrue(mock.connect()) conn_params = { "hostname": "dummy.host.org", "username": "******", "key_files": path, "password": "******", } mock = ParamikoSSHClient(**conn_params) self.assertTrue(mock.connect())
def test_keep_alive_and_compression(self): conn_params = {"hostname": "dummy.host.org", "username": "******"} client = ParamikoSSHClient(**conn_params) mock_transport = Mock() client.client.get_transport = Mock(return_value=mock_transport) transport = client._get_transport() self.assertEqual(transport.set_keepalive.call_count, 0) self.assertEqual(transport.use_compression.call_count, 0) conn_params = { "hostname": "dummy.host.org", "username": "******", "keep_alive": 15, "use_compression": True, } client = ParamikoSSHClient(**conn_params) mock_transport = Mock() client.client.get_transport = Mock(return_value=mock_transport) transport = client._get_transport() self.assertEqual(transport.set_keepalive.call_count, 1) self.assertEqual(transport.use_compression.call_count, 1)
def test_key_material_argument(self): path = os.path.join(os.path.dirname(__file__), 'fixtures', 'misc', 'dummy_rsa') with open(path, 'r') as fp: private_key = fp.read() conn_params = {'hostname': 'dummy.host.org', 'username': '******', 'key_material': private_key} mock = ParamikoSSHClient(**conn_params) mock.connect() pkey = paramiko.RSAKey.from_private_key(StringIO(private_key)) expected_conn = {'username': '******', 'allow_agent': False, 'hostname': 'dummy.host.org', 'look_for_keys': False, 'pkey': pkey, 'port': 22} mock.client.connect.assert_called_once_with(**expected_conn) self.assertLogMsg('Connecting to server')