def test_leading_stuff(self): orig = RSAKey.from_private_key(StringIO(RSA_PRIVATE_OUT)) skey = RSAKey.from_private_key( StringIO("\n\n" + RSA_PRIVATE_OUT + "\n\n")) self.assertEqual(orig.get_fingerprint(), skey.get_fingerprint()) comment = "Bag Attributes\n localKeyID: 32 CB FA 64 B9 D8 C5 D3 BC 4B 20 04 3D EC 38 6B 32 2D C4 9A \nKey Attributes: <No Attributes>\n" # noqa: E501 ckey = RSAKey.from_private_key(StringIO(comment + RSA_PRIVATE_OUT)) self.assertEqual(orig.get_fingerprint(), ckey.get_fingerprint())
def test_host_config_test_proxycommand(self): test_config_file = """ Host proxy-with-equal-divisor-and-space ProxyCommand = foo=bar Host proxy-with-equal-divisor-and-no-space ProxyCommand=foo=bar Host proxy-without-equal-divisor ProxyCommand foo=bar:%h-%p """ for host, values in { 'proxy-with-equal-divisor-and-space': { 'hostname': 'proxy-with-equal-divisor-and-space', 'proxycommand': 'foo=bar' }, 'proxy-with-equal-divisor-and-no-space': { 'hostname': 'proxy-with-equal-divisor-and-no-space', 'proxycommand': 'foo=bar' }, 'proxy-without-equal-divisor': { 'hostname': 'proxy-without-equal-divisor', 'proxycommand': 'foo=bar:proxy-without-equal-divisor-22' } }.items(): f = StringIO(test_config_file) config = paramiko.util.parse_ssh_config(f) self.assertEqual( paramiko.util.lookup_ssh_host_config(host, config), values)
def test_proxycommand_interpolation(self): """ ProxyCommand should perform interpolation on the value """ config = paramiko.util.parse_ssh_config(StringIO(textwrap.dedent("""\ Host specific Port 37 ProxyCommand host %h port %p lol %%r-tricky%% Host portonly Port 155 Host * Port 25 ProxyCommand host %h port %p """))) for host, val in ( ('foo.com', "host foo.com port 25"), ('specific', "host specific port 37 lol %r-tricky%"), ('portonly', "host portonly port 155"), ): self.assertEqual( host_config(host, config)['proxycommand'], val )
def test_host_config_test_proxycommand(self): test_config_file = """ Host proxy-with-equal-divisor-and-space ProxyCommand = foo=bar Host proxy-with-equal-divisor-and-no-space ProxyCommand=foo=bar Host proxy-without-equal-divisor ProxyCommand foo=bar:%h-%p """ for host, values in { "proxy-with-equal-divisor-and-space": { "hostname": "proxy-with-equal-divisor-and-space", "proxycommand": "foo=bar", }, "proxy-with-equal-divisor-and-no-space": { "hostname": "proxy-with-equal-divisor-and-no-space", "proxycommand": "foo=bar", }, "proxy-without-equal-divisor": { "hostname": "proxy-without-equal-divisor", "proxycommand": "foo=bar:proxy-without-equal-divisor-22", }, }.items(): f = StringIO(test_config_file) config = paramiko.util.parse_ssh_config(f) self.assertEqual( paramiko.util.lookup_ssh_host_config(host, config), values)
def test_host_config(self): global test_config_file f = StringIO(test_config_file) config = paramiko.util.parse_ssh_config(f) for host, values in { "irc.danger.com": { "crazy": "something dumb", "hostname": "irc.danger.com", "user": "******", }, "irc.example.com": { "crazy": "something dumb", "hostname": "irc.example.com", "user": "******", "port": "3333", }, "spoo.example.com": { "crazy": "something dumb", "hostname": "spoo.example.com", "user": "******", "port": "3333", }, }.items(): values = dict( values, hostname=host, identityfile=[os.path.expanduser("~/.ssh/id_rsa")], ) self.assertEqual( paramiko.util.lookup_ssh_host_config(host, config), values)
def test_host_config_test_proxycommand(self): test_config_file = """ Host proxy-with-equal-divisor-and-space ProxyCommand = foo=bar Host proxy-with-equal-divisor-and-no-space ProxyCommand=foo=bar Host proxy-without-equal-divisor ProxyCommand foo=bar:%h-%p """ for host, proxycmd in [ ('proxy-with-equal-divisor-and-space', 'foo=bar'), ('proxy-with-equal-divisor-and-no-space', 'foo=bar'), ('proxy-without-equal-divisor', 'foo=bar:proxy-without-equal-divisor-22'), ]: f = StringIO(test_config_file) config = paramiko.util.parse_ssh_config(f) self.assertEqual( paramiko.util.lookup_ssh_host_config(host, config), { 'hostname': host, 'proxycommand': proxycmd }, )
def test_host_config_test_identityfile(self): test_config_file = """ IdentityFile id_dsa0 Host * IdentityFile id_dsa1 Host dsa2 IdentityFile id_dsa2 Host dsa2* IdentityFile id_dsa22 """ for host, values in { "foo": { "hostname": "foo", "identityfile": ["id_dsa0", "id_dsa1"] }, "dsa2": { "hostname": "dsa2", "identityfile": ["id_dsa0", "id_dsa1", "id_dsa2", "id_dsa22"], }, "dsa22": { "hostname": "dsa22", "identityfile": ["id_dsa0", "id_dsa1", "id_dsa22"], }, }.items(): f = StringIO(test_config_file) config = paramiko.util.parse_ssh_config(f) self.assertEqual( 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.assertEqual( paramiko.util.lookup_ssh_host_config(host, config), values )
def test_parse_config(self): global test_config_file f = StringIO(test_config_file) config = paramiko.util.parse_ssh_config(f) self.assertEqual(config._config, [{ 'host': ['*'], 'config': {} }, { 'host': ['*'], 'config': { 'identityfile': ['~/.ssh/id_rsa'], 'user': '******' } }, { 'host': ['*.example.com'], 'config': { 'user': '******', 'port': '3333' } }, { 'host': ['*'], 'config': { 'crazy': 'something dumb' } }, { 'host': ['spoo.example.com'], 'config': { 'crazy': 'something else' } }])
def test_proxycommand_none_masking(self): # Re: https://github.com/paramiko/paramiko/issues/670 source_config = """ Host specific-host ProxyCommand none Host other-host ProxyCommand other-proxy Host * ProxyCommand default-proxy """ config = paramiko.SSHConfig() config.parse(StringIO(source_config)) # When bug is present, the full stripping-out of specific-host's # ProxyCommand means it actually appears to pick up the default # ProxyCommand value instead, due to cascading. It should (for # backwards compatibility reasons in 1.x/2.x) appear completely blank, # as if the host had no ProxyCommand whatsoever. # Threw another unrelated host in there just for sanity reasons. self.assertFalse("proxycommand" in config.lookup("specific-host")) self.assertEqual( config.lookup("other-host")["proxycommand"], "other-proxy") self.assertEqual( config.lookup("some-random-host")["proxycommand"], "default-proxy")
def test_host_config_test_identityfile(self): test_config_file = """ IdentityFile id_dsa0 Host * IdentityFile id_dsa1 Host dsa2 IdentityFile id_dsa2 Host dsa2* IdentityFile id_dsa22 """ for host, values in { 'foo': { 'hostname': 'foo', 'identityfile': ['id_dsa0', 'id_dsa1'] }, 'dsa2': { 'hostname': 'dsa2', 'identityfile': ['id_dsa0', 'id_dsa1', 'id_dsa2', 'id_dsa22'] }, 'dsa22': { 'hostname': 'dsa22', 'identityfile': ['id_dsa0', 'id_dsa1', 'id_dsa22'] } }.items(): f = StringIO(test_config_file) config = paramiko.util.parse_ssh_config(f) self.assertEqual( paramiko.util.lookup_ssh_host_config(host, config), values)
def test_host_config(self): global test_config_file f = StringIO(test_config_file) config = paramiko.util.parse_ssh_config(f) for host, values in { 'irc.danger.com': { 'crazy': 'something dumb', 'hostname': 'irc.danger.com', 'user': '******' }, 'irc.example.com': { 'crazy': 'something dumb', 'hostname': 'irc.example.com', 'user': '******', 'port': '3333' }, 'spoo.example.com': { 'crazy': 'something dumb', 'hostname': 'spoo.example.com', 'user': '******', 'port': '3333' } }.items(): values = dict(values, hostname=host, identityfile=[os.path.expanduser("~/.ssh/id_rsa")]) self.assertEqual( paramiko.util.lookup_ssh_host_config(host, config), values)
def test_config_addressfamily_and_lazy_fqdn(self): """ Ensure the code path honoring non-'all' AddressFamily doesn't asplode """ test_config = """ AddressFamily inet IdentityFile something_%l_using_fqdn """ config = paramiko.util.parse_ssh_config(StringIO(test_config)) assert config.lookup('meh') # will die during lookup() if bug regresses
def test_sftp_key_connect(self): server_interface = MyTServerInterface() pub_key_str = ( "AAAAB3NzaC1yc2EAAAADAQABAAAAgQCzvWE391K1pyBvePGpwDWMboSLIp" "5L5sMq+bXPPeJPSLOm9dnm8XexZOpeg14UpsYcmrkzVPeooaqz5PqtaHO46CdK11dS" "cs2a8PLnavGkJRf25/PDXxlHkiZXXbAfW+6t5aVJxSJ4Jt4FV0aDqMaaYxy4ikw6da" "BCkvug2OZQqQ==" ) priv_key_str = """-----BEGIN RSA PRIVATE KEY----- MIICXgIBAAKBgQCzvWE391K1pyBvePGpwDWMboSLIp5L5sMq+bXPPeJPSLOm9dnm 8XexZOpeg14UpsYcmrkzVPeooaqz5PqtaHO46CdK11dScs2a8PLnavGkJRf25/PD XxlHkiZXXbAfW+6t5aVJxSJ4Jt4FV0aDqMaaYxy4ikw6daBCkvug2OZQqQIDAQAB AoGASpK9XlIQD+wqafWdFpf3368O8QdI9CbnPNJkG3sKhWidmR0R7l6rEX/UOah5 hUn4km+jfWe4ZU/GGmNbmkznDdOWspDKs7eeYl7saeRzuX2CdTVvrdU7qmD5+JLk mXlWWd6rgRIfrFYXYeDVd8p6/kPR4SJe7dTTHuEKKIt9njECQQDhMqjyoNxftpl4 +mwQu0ZDLCZ4afDCGcsf73W3oSmqLyf401vQ6KAp/PmfxqGXY0ewGMzUJn9LFOyP WOGcDFglAkEAzFL/DI3SYmsvLMt6/vK4qwEwSiJU8byUBj3CL3eL0xjn895GXPzb 9CUMu0fz60Tn7UhbohynPLmQ2w6npbZ9NQJBAN+uujGFpl9LuFV6KCzWV4wRJoUk dYfWpvQpnfuvkPsBq+pzxhdTeQM7y5bwbUE509MOTyXKt1WUiwQ3fKDLgiECQQCb Z4zhSYT4ojlRQrqb6pSWS+Mkn5QoAJw9Wv+1BqHsvwa8rxSpaREKUpuqXgGhsdkM 2noHhO+V+jW4xx6vpWr5AkEAgHoSbQUR5uY8ib3N3mNowVi9NhvBN1FkwGStM9W8 QKHf8Ha+rOx3B7Dbljc+Xdpcn9VyRmDlSqzX9aCkr18mNg== -----END RSA PRIVATE KEY-----""" private_key = RSAKey.from_private_key(file_obj=StringIO(priv_key_str)) # Fail if public key not registered self.assertEqual( server_interface.check_auth_publickey(self.username, private_key), AUTH_FAILED ) SFTPPublicKey.objects.create( user = self.user, name = "TestKey", key_type = "ssh-rsa", public_key = pub_key_str ) # Succeed if public key is registered self.assertEqual( server_interface.check_auth_publickey(self.username, private_key), AUTH_SUCCESSFUL ) # Should fail if user is inactive self.user.is_active = False self.user.save() self.assertEqual( server_interface.check_auth_publickey(self.username, private_key), AUTH_FAILED ) self.user.is_active = True self.user.save()
def test_load_rsa(self): key = RSAKey.from_private_key_file(_support('test_rsa.key')) self.assert_key_values(key, 'ssh-rsa', 1024, PUB_RSA, FINGER_RSA.split()[1], FINGER_SHA256_RSA) s = StringIO() key.write_private_key(s) self.assertEqual(RSA_PRIVATE_OUT, s.getvalue()) s.seek(0) key2 = RSAKey.from_private_key(s) self.assertEqual(key, key2)
def test_SSHConfig_host_dicts_are_SSHConfigDict_instances(): test_config_file = """ Host *.example.com Port 2222 Host * Port 3333 """ f = StringIO(test_config_file) config = parse_ssh_config(f) assert config.lookup("foo.example.com").as_int("port") == 2222
def test_SSHConfig_wildcard_host_dicts_are_SSHConfigDict_instances(): test_config_file = """\ Host *.example.com Port 2222 Host * Port 3333 """ f = StringIO(test_config_file) config = parse_ssh_config(f) assert config.lookup("anything-else").as_int("port") == 3333
def test_load_dss(self): key = DSSKey.from_private_key_file(_support('test_dss.key')) self.assert_key_values(key, 'ssh-dss', 1024, PUB_DSS, FINGER_DSS.split()[1], FINGER_SHA256_DSS) s = StringIO() key.write_private_key(s) self.assertEqual(DSS_PRIVATE_OUT, s.getvalue()) s.seek(0) key2 = DSSKey.from_private_key(s) self.assertEqual(key, key2)
def test_load_ecdsa_384(self): key = ECDSAKey.from_private_key_file(_support('test_ecdsa_384.key')) self.assert_key_values(key, 'ecdsa-sha2-nistp384', 384, PUB_ECDSA_384, FINGER_ECDSA_384.split()[1], FINGER_SHA256_ECDSA_384) s = StringIO() key.write_private_key(s) self.assertEqual(ECDSA_PRIVATE_OUT_384, s.getvalue()) s.seek(0) key2 = ECDSAKey.from_private_key(s) self.assertEqual(key, key2)
def test_putfo_empty_file(self, sftp): """ Send an empty file and confirm it is sent. """ target = sftp.FOLDER + '/empty file.txt' stream = StringIO() try: attrs = sftp.putfo(stream, target) # the returned attributes should not be null assert attrs is not None finally: sftp.remove(target)
def test_proxycommand_tilde_expansion(self): """ Tilde (~) should be expanded inside ProxyCommand """ config = paramiko.util.parse_ssh_config(StringIO(""" Host test ProxyCommand ssh -F ~/.ssh/test_config bastion nc %h %p """)) self.assertEqual( 'ssh -F %s/.ssh/test_config bastion nc test 22' % os.path.expanduser('~'), host_config('test', config)['proxycommand'] )
def test_load_rsa(self): key = RSAKey.from_private_key_file(_support("test_rsa.key")) self.assertEqual("ssh-rsa", key.get_name()) self.assert_key_fingerprints(key, FINGER_RSA) self.assertEqual(PUB_RSA.split()[1], key.get_base64()) self.assertEqual(1024, key.get_bits()) s = StringIO() key.write_private_key(s) self.assertEqual(RSA_PRIVATE_OUT, s.getvalue()) s.seek(0) key2 = RSAKey.from_private_key(s) self.assertEqual(key, key2)
def test_load_ecdsa_384(self): key = ECDSAKey.from_private_key_file(_support("test_ecdsa_384.key")) self.assertEqual("ecdsa-sha2-nistp384", key.get_name()) self.assert_key_fingerprints(key, FINGER_ECDSA_384) self.assertEqual(PUB_ECDSA_384.split()[1], key.get_base64()) self.assertEqual(384, key.get_bits()) s = StringIO() key.write_private_key(s) self.assertEqual(ECDSA_PRIVATE_OUT_384, s.getvalue()) s.seek(0) key2 = ECDSAKey.from_private_key(s) self.assertEqual(key, key2)
def test_load_dss(self): key = DSSKey.from_private_key_file(_support("test_dss.key")) self.assertEqual("ssh-dss", key.get_name()) self.assert_key_fingerprints(key, FINGER_DSS) self.assertEqual(PUB_DSS.split()[1], key.get_base64()) self.assertEqual(1024, key.get_bits()) s = StringIO() key.write_private_key(s) self.assertEqual(DSS_PRIVATE_OUT, s.getvalue()) s.seek(0) key2 = DSSKey.from_private_key(s) self.assertEqual(key, key2)
def test_sign_ecdsa_key(): """ Round trip a certificate through the parser and signer. It should result in the same sequence of bytes after the signing. """ ca_buf = StringIO(TEST_RSA_CA) ca_key = RSAKey.from_private_key(ca_buf) crt_data = base64.b64decode(TEST_ECDSA_KEY_RSA_CA) crt = SSHCertificate(data=crt_data) assert crt.signature_key == ca_key.asbytes() crt._bytes = None assert crt._bytes != crt_data crt.sign(ca_key, crt.nonce) assert crt._bytes == crt_data
def test_14_load_ecdsa_384(self): key = ECDSAKey.from_private_key_file(_support("test_ecdsa_384.key")) self.assertEqual("ecdsa-sha2-nistp384", key.get_name()) exp_ecdsa = b(FINGER_ECDSA_384.split()[1].replace(":", "")) my_ecdsa = hexlify(key.get_fingerprint()) self.assertEqual(exp_ecdsa, my_ecdsa) self.assertEqual(PUB_ECDSA_384.split()[1], key.get_base64()) self.assertEqual(384, key.get_bits()) s = StringIO() key.write_private_key(s) self.assertEqual(ECDSA_PRIVATE_OUT_384, s.getvalue()) s.seek(0) key2 = ECDSAKey.from_private_key(s) self.assertEqual(key, key2)
def test_4_load_dss(self): key = DSSKey.from_private_key_file(_support("test_dss.key")) self.assertEqual("ssh-dss", key.get_name()) exp_dss = b(FINGER_DSS.split()[1].replace(":", "")) my_dss = hexlify(key.get_fingerprint()) self.assertEqual(exp_dss, my_dss) self.assertEqual(PUB_DSS.split()[1], key.get_base64()) self.assertEqual(1024, key.get_bits()) s = StringIO() key.write_private_key(s) self.assertEqual(DSS_PRIVATE_OUT, s.getvalue()) s.seek(0) key2 = DSSKey.from_private_key(s) self.assertEqual(key, key2)
def test_2_load_rsa(self): key = RSAKey.from_private_key_file(_support("test_rsa.key")) self.assertEqual("ssh-rsa", key.get_name()) exp_rsa = b(FINGER_RSA.split()[1].replace(":", "")) my_rsa = hexlify(key.get_fingerprint()) self.assertEqual(exp_rsa, my_rsa) self.assertEqual(PUB_RSA.split()[1], key.get_base64()) self.assertEqual(1024, key.get_bits()) s = StringIO() key.write_private_key(s) self.assertEqual(RSA_PRIVATE_OUT, s.getvalue()) s.seek(0) key2 = RSAKey.from_private_key(s) self.assertEqual(key, key2)
def test_10_load_ecdsa_256(self): key = ECDSAKey.from_private_key_file(test_path('test_ecdsa_256.key')) self.assertEqual('ecdsa-sha2-nistp256', key.get_name()) exp_ecdsa = b(FINGER_ECDSA_256.split()[1].replace(':', '')) my_ecdsa = hexlify(key.get_fingerprint()) self.assertEqual(exp_ecdsa, my_ecdsa) self.assertEqual(PUB_ECDSA_256.split()[1], key.get_base64()) self.assertEqual(256, key.get_bits()) s = StringIO() key.write_private_key(s) self.assertEqual(ECDSA_PRIVATE_OUT_256, s.getvalue()) s.seek(0) key2 = ECDSAKey.from_private_key(s) self.assertEqual(key, key2)
def test_load_ecdsa_521(self): key = ECDSAKey.from_private_key_file(_support('test_ecdsa_521.key')) self.assert_key_values(key, 'ecdsa-sha2-nistp521', 521, PUB_ECDSA_521, FINGER_ECDSA_521.split()[1], FINGER_SHA256_ECDSA_521) s = StringIO() key.write_private_key(s) # Different versions of OpenSSL (SSLeay versions 0x1000100f and # 0x1000207f for instance) use different apparently valid (as far as # ssh-keygen is concerned) padding. So we can't check the actual value # of the pem encoded key. s.seek(0) key2 = ECDSAKey.from_private_key(s) self.assertEqual(key, key2)