diff options
Diffstat (limited to 'tests/test_util.py')
-rw-r--r-- | tests/test_util.py | 234 |
1 files changed, 189 insertions, 45 deletions
diff --git a/tests/test_util.py b/tests/test_util.py index 12677a9b..bfdc525e 100644 --- a/tests/test_util.py +++ b/tests/test_util.py @@ -21,15 +21,14 @@ Some unit tests for utility functions. """ from binascii import hexlify -import cStringIO import errno import os +from hashlib import sha1 import unittest -from Crypto.Hash import SHA -import paramiko.util -from paramiko.util import lookup_ssh_host_config as host_config -from util import ParamikoTest +import paramiko.util +from paramiko.util import lookup_ssh_host_config as host_config, safe_string +from paramiko.py3compat import StringIO, byte_ord, b test_config_file = """\ Host * @@ -41,7 +40,12 @@ Host *.example.com \tUser bjork Port=3333 Host * - \t \t Crazy something dumb +""" + +dont_strip_whitespace_please = "\t \t Crazy something dumb " + +test_config_file += dont_strip_whitespace_please +test_config_file += """ Host spoo.example.com Crazy something else """ @@ -60,12 +64,12 @@ BGQ3GQ/Fc7SX6gkpXkwcZryoi4kNFhHu5LvHcZPdxXV1D+uTMfGS1eyd2Yz/DoNWXNAl8TI0cAsW\ from paramiko import * -class UtilTest(ParamikoTest): +class UtilTest(unittest.TestCase): def test_1_import(self): """ verify that all the classes can be imported from paramiko. """ - symbols = globals().keys() + symbols = list(globals().keys()) self.assertTrue('Transport' in symbols) self.assertTrue('SSHClient' in symbols) self.assertTrue('MissingHostKeyPolicy' in symbols) @@ -101,9 +105,9 @@ class UtilTest(ParamikoTest): def test_2_parse_config(self): global test_config_file - f = cStringIO.StringIO(test_config_file) + f = StringIO(test_config_file) config = paramiko.util.parse_ssh_config(f) - self.assertEquals(config._config, + self.assertEqual(config._config, [{'host': ['*'], 'config': {}}, {'host': ['*'], 'config': {'identityfile': ['~/.ssh/id_rsa'], 'user': 'robey'}}, {'host': ['*.example.com'], 'config': {'user': 'bjork', 'port': '3333'}}, {'host': ['*'], 'config': {'crazy': 'something dumb '}}, @@ -111,7 +115,7 @@ class UtilTest(ParamikoTest): def test_3_host_config(self): global test_config_file - f = cStringIO.StringIO(test_config_file) + f = StringIO(test_config_file) config = paramiko.util.parse_ssh_config(f) for host, values in { @@ -131,36 +135,29 @@ class UtilTest(ParamikoTest): hostname=host, identityfile=[os.path.expanduser("~/.ssh/id_rsa")] ) - self.assertEquals( + self.assertEqual( paramiko.util.lookup_ssh_host_config(host, config), values ) def test_4_generate_key_bytes(self): - x = paramiko.util.generate_key_bytes(SHA, 'ABCDEFGH', 'This is my secret passphrase.', 64) - hex = ''.join(['%02x' % ord(c) for c in x]) - self.assertEquals(hex, '9110e2f6793b69363e58173e9436b13a5a4b339005741d5c680e505f57d871347b4239f14fb5c46e857d5e100424873ba849ac699cea98d729e57b3e84378e8b') + x = paramiko.util.generate_key_bytes(sha1, b'ABCDEFGH', 'This is my secret passphrase.', 64) + hex = ''.join(['%02x' % byte_ord(c) for c in x]) + self.assertEqual(hex, '9110e2f6793b69363e58173e9436b13a5a4b339005741d5c680e505f57d871347b4239f14fb5c46e857d5e100424873ba849ac699cea98d729e57b3e84378e8b') def test_5_host_keys(self): - f = open('hostfile.temp', 'w') - f.write(test_hosts_file) - f.close() + with open('hostfile.temp', 'w') as f: + f.write(test_hosts_file) try: hostdict = paramiko.util.load_host_keys('hostfile.temp') - self.assertEquals(2, len(hostdict)) - self.assertEquals(1, len(hostdict.values()[0])) - self.assertEquals(1, len(hostdict.values()[1])) + self.assertEqual(2, len(hostdict)) + self.assertEqual(1, len(list(hostdict.values())[0])) + self.assertEqual(1, len(list(hostdict.values())[1])) fp = hexlify(hostdict['secure.example.com']['ssh-rsa'].get_fingerprint()).upper() - self.assertEquals('E6684DB30E109B67B70FF1DC5C7F1363', fp) + self.assertEqual(b'E6684DB30E109B67B70FF1DC5C7F1363', fp) finally: os.unlink('hostfile.temp') - def test_6_random(self): - from paramiko.common import rng - # just verify that we can pull out 32 bytes and not get an exception. - x = rng.read(32) - self.assertEquals(len(x), 32) - def test_7_host_config_expose_issue_33(self): test_config_file = """ Host www13.* @@ -172,16 +169,16 @@ Host *.example.com Host * Port 3333 """ - f = cStringIO.StringIO(test_config_file) + f = StringIO(test_config_file) config = paramiko.util.parse_ssh_config(f) host = 'www13.example.com' - self.assertEquals( + self.assertEqual( paramiko.util.lookup_ssh_host_config(host, config), {'hostname': host, 'port': '22'} ) def test_8_eintr_retry(self): - self.assertEquals('foo', paramiko.util.retry_on_signal(lambda: 'foo')) + self.assertEqual('foo', paramiko.util.retry_on_signal(lambda: 'foo')) # Variables that are set by raises_intr intr_errors_remaining = [3] @@ -192,8 +189,8 @@ Host * intr_errors_remaining[0] -= 1 raise IOError(errno.EINTR, 'file', 'interrupted system call') self.assertTrue(paramiko.util.retry_on_signal(raises_intr) is None) - self.assertEquals(0, intr_errors_remaining[0]) - self.assertEquals(4, call_count[0]) + self.assertEqual(0, intr_errors_remaining[0]) + self.assertEqual(4, call_count[0]) def raises_ioerror_not_eintr(): raise IOError(errno.ENOENT, 'file', 'file not found') @@ -216,10 +213,10 @@ Host space-delimited Host equals-delimited ProxyCommand=foo bar=biz baz """ - f = cStringIO.StringIO(conf) + f = StringIO(conf) config = paramiko.util.parse_ssh_config(f) for host in ('space-delimited', 'equals-delimited'): - self.assertEquals( + self.assertEqual( host_config(host, config)['proxycommand'], 'foo bar=biz baz' ) @@ -228,7 +225,7 @@ Host equals-delimited """ ProxyCommand should perform interpolation on the value """ - config = paramiko.util.parse_ssh_config(cStringIO.StringIO(""" + config = paramiko.util.parse_ssh_config(StringIO(""" Host specific Port 37 ProxyCommand host %h port %p lol @@ -245,7 +242,7 @@ Host * ('specific', "host specific port 37 lol"), ('portonly', "host portonly port 155"), ): - self.assertEquals( + self.assertEqual( host_config(host, config)['proxycommand'], val ) @@ -264,10 +261,10 @@ Host www13.* Host * Port 3333 """ - f = cStringIO.StringIO(test_config_file) + f = StringIO(test_config_file) config = paramiko.util.parse_ssh_config(f) host = 'www13.example.com' - self.assertEquals( + self.assertEqual( paramiko.util.lookup_ssh_host_config(host, config), {'hostname': host, 'port': '8080'} ) @@ -293,9 +290,9 @@ ProxyCommand foo=bar:%h-%p 'foo=bar:proxy-without-equal-divisor-22'} }.items(): - f = cStringIO.StringIO(test_config_file) + f = StringIO(test_config_file) config = paramiko.util.parse_ssh_config(f) - self.assertEquals( + self.assertEqual( paramiko.util.lookup_ssh_host_config(host, config), values ) @@ -323,9 +320,9 @@ IdentityFile id_dsa22 'identityfile': ['id_dsa0', 'id_dsa1', 'id_dsa22']} }.items(): - f = cStringIO.StringIO(test_config_file) + f = StringIO(test_config_file) config = paramiko.util.parse_ssh_config(f) - self.assertEquals( + self.assertEqual( paramiko.util.lookup_ssh_host_config(host, config), values ) @@ -338,5 +335,152 @@ IdentityFile id_dsa22 AddressFamily inet IdentityFile something_%l_using_fqdn """ - config = paramiko.util.parse_ssh_config(cStringIO.StringIO(test_config)) - assert config.lookup('meh') # will die during lookup() if bug regresses + config = paramiko.util.parse_ssh_config(StringIO(test_config)) + assert config.lookup('meh') # will die during lookup() if bug regresses + + def test_clamp_value(self): + self.assertEqual(32768, paramiko.util.clamp_value(32767, 32768, 32769)) + self.assertEqual(32767, paramiko.util.clamp_value(32767, 32765, 32769)) + self.assertEqual(32769, paramiko.util.clamp_value(32767, 32770, 32769)) + + def test_13_config_dos_crlf_succeeds(self): + config_file = StringIO("host abcqwerty\r\nHostName 127.0.0.1\r\n") + config = paramiko.SSHConfig() + config.parse(config_file) + self.assertEqual(config.lookup("abcqwerty")["hostname"], "127.0.0.1") + + def test_14_get_hostnames(self): + f = StringIO(test_config_file) + config = paramiko.util.parse_ssh_config(f) + self.assertEqual(config.get_hostnames(), set(['*', '*.example.com', 'spoo.example.com'])) + + def test_quoted_host_names(self): + test_config_file = """\ +Host "param pam" param "pam" + Port 1111 + +Host "param2" + Port 2222 + +Host param3 parara + Port 3333 + +Host param4 "p a r" "p" "par" para + Port 4444 +""" + res = { + 'param pam': {'hostname': 'param pam', 'port': '1111'}, + 'param': {'hostname': 'param', 'port': '1111'}, + 'pam': {'hostname': 'pam', 'port': '1111'}, + + 'param2': {'hostname': 'param2', 'port': '2222'}, + + 'param3': {'hostname': 'param3', 'port': '3333'}, + 'parara': {'hostname': 'parara', 'port': '3333'}, + + 'param4': {'hostname': 'param4', 'port': '4444'}, + 'p a r': {'hostname': 'p a r', 'port': '4444'}, + 'p': {'hostname': 'p', 'port': '4444'}, + 'par': {'hostname': 'par', 'port': '4444'}, + 'para': {'hostname': 'para', 'port': '4444'}, + } + f = StringIO(test_config_file) + config = paramiko.util.parse_ssh_config(f) + for host, values in res.items(): + self.assertEquals( + paramiko.util.lookup_ssh_host_config(host, config), + values + ) + + def test_quoted_params_in_config(self): + test_config_file = """\ +Host "param pam" param "pam" + IdentityFile id_rsa + +Host "param2" + IdentityFile "test rsa key" + +Host param3 parara + IdentityFile id_rsa + IdentityFile "test rsa key" +""" + res = { + 'param pam': {'hostname': 'param pam', 'identityfile': ['id_rsa']}, + 'param': {'hostname': 'param', 'identityfile': ['id_rsa']}, + 'pam': {'hostname': 'pam', 'identityfile': ['id_rsa']}, + + 'param2': {'hostname': 'param2', 'identityfile': ['test rsa key']}, + + 'param3': {'hostname': 'param3', 'identityfile': ['id_rsa', 'test rsa key']}, + 'parara': {'hostname': 'parara', 'identityfile': ['id_rsa', 'test rsa key']}, + } + f = StringIO(test_config_file) + config = paramiko.util.parse_ssh_config(f) + for host, values in res.items(): + self.assertEquals( + paramiko.util.lookup_ssh_host_config(host, config), + values + ) + + def test_quoted_host_in_config(self): + conf = SSHConfig() + correct_data = { + 'param': ['param'], + '"param"': ['param'], + + 'param pam': ['param', 'pam'], + '"param" "pam"': ['param', 'pam'], + '"param" pam': ['param', 'pam'], + 'param "pam"': ['param', 'pam'], + + 'param "pam" p': ['param', 'pam', 'p'], + '"param" pam "p"': ['param', 'pam', 'p'], + + '"pa ram"': ['pa ram'], + '"pa ram" pam': ['pa ram', 'pam'], + 'param "p a m"': ['param', 'p a m'], + } + incorrect_data = [ + 'param"', + '"param', + 'param "pam', + 'param "pam" "p a', + ] + for host, values in correct_data.items(): + self.assertEquals( + conf._get_hosts(host), + values + ) + for host in incorrect_data: + self.assertRaises(Exception, conf._get_hosts, host) + + def test_safe_string(self): + vanilla = b("vanilla") + has_bytes = b("has \7\3 bytes") + safe_vanilla = safe_string(vanilla) + safe_has_bytes = safe_string(has_bytes) + expected_bytes = b("has %07%03 bytes") + err = "{0!r} != {1!r}" + assert safe_vanilla == vanilla, err.format(safe_vanilla, vanilla) + assert safe_has_bytes == expected_bytes, \ + err.format(safe_has_bytes, expected_bytes) + + def test_proxycommand_none_issue_418(self): + test_config_file = """ +Host proxycommand-standard-none + ProxyCommand None + +Host proxycommand-with-equals-none + ProxyCommand=None + """ + for host, values in { + 'proxycommand-standard-none': {'hostname': 'proxycommand-standard-none'}, + 'proxycommand-with-equals-none': {'hostname': 'proxycommand-with-equals-none'} + }.items(): + + f = StringIO(test_config_file) + config = paramiko.util.parse_ssh_config(f) + self.assertEqual( + paramiko.util.lookup_ssh_host_config(host, config), + values + ) |