From 3bb46c9cb414ca82afab715d2d0cc00ed71cfb6d Mon Sep 17 00:00:00 2001 From: "Jeremy T. Bouse" Date: Fri, 14 Feb 2014 21:29:58 -0500 Subject: Imported Upstream version 1.12.2 --- tests/loop.py | 2 +- tests/stub_sftp.py | 2 +- tests/test_auth.py | 2 +- tests/test_buffered_pipe.py | 2 +- tests/test_client.py | 33 ++++++++++++++++++++-- tests/test_ecdsa.key | 5 ++++ tests/test_ecdsa_password.key | 8 ++++++ tests/test_file.py | 2 +- tests/test_hostkeys.py | 2 +- tests/test_kex.py | 2 +- tests/test_message.py | 2 +- tests/test_packetizer.py | 2 +- tests/test_pkey.py | 66 +++++++++++++++++++++++++++++++++++++++++-- tests/test_sftp.py | 2 +- tests/test_sftp_big.py | 2 +- tests/test_transport.py | 2 +- tests/test_util.py | 13 ++++++++- 17 files changed, 131 insertions(+), 18 deletions(-) create mode 100644 tests/test_ecdsa.key create mode 100644 tests/test_ecdsa_password.key (limited to 'tests') diff --git a/tests/loop.py b/tests/loop.py index ffa8e3c..91c216d 100644 --- a/tests/loop.py +++ b/tests/loop.py @@ -7,7 +7,7 @@ # Software Foundation; either version 2.1 of the License, or (at your option) # any later version. # -# Paramiko is distrubuted in the hope that it will be useful, but WITHOUT ANY +# Paramiko is distributed in the hope that it will be useful, but WITHOUT ANY # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR # A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more # details. diff --git a/tests/stub_sftp.py b/tests/stub_sftp.py index 7f1ecc7..3021d81 100644 --- a/tests/stub_sftp.py +++ b/tests/stub_sftp.py @@ -7,7 +7,7 @@ # Software Foundation; either version 2.1 of the License, or (at your option) # any later version. # -# Paramiko is distrubuted in the hope that it will be useful, but WITHOUT ANY +# Paramiko is distributed in the hope that it will be useful, but WITHOUT ANY # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR # A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more # details. diff --git a/tests/test_auth.py b/tests/test_auth.py index 816e978..61fe63f 100644 --- a/tests/test_auth.py +++ b/tests/test_auth.py @@ -7,7 +7,7 @@ # Software Foundation; either version 2.1 of the License, or (at your option) # any later version. # -# Paramiko is distrubuted in the hope that it will be useful, but WITHOUT ANY +# Paramiko is distributed in the hope that it will be useful, but WITHOUT ANY # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR # A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more # details. diff --git a/tests/test_buffered_pipe.py b/tests/test_buffered_pipe.py index b9d91f6..47ece93 100644 --- a/tests/test_buffered_pipe.py +++ b/tests/test_buffered_pipe.py @@ -7,7 +7,7 @@ # Software Foundation; either version 2.1 of the License, or (at your option) # any later version. # -# Paramiko is distrubuted in the hope that it will be useful, but WITHOUT ANY +# Paramiko is distributed in the hope that it will be useful, but WITHOUT ANY # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR # A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more # details. diff --git a/tests/test_client.py b/tests/test_client.py index 08ef1f9..fae1d32 100644 --- a/tests/test_client.py +++ b/tests/test_client.py @@ -7,7 +7,7 @@ # Software Foundation; either version 2.1 of the License, or (at your option) # any later version. # -# Paramiko is distrubuted in the hope that it will be useful, but WITHOUT ANY +# Paramiko is distributed in the hope that it will be useful, but WITHOUT ANY # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR # A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more # details. @@ -20,11 +20,14 @@ Some unit tests for SSHClient. """ +from __future__ import with_statement # Python 2.5 support import socket import threading import time import unittest import weakref +import warnings +import os from binascii import hexlify import paramiko @@ -184,7 +187,33 @@ class SSHClientTest (unittest.TestCase): self.assertEquals(1, len(self.tc.get_host_keys())) self.assertEquals(public_host_key, self.tc.get_host_keys()['[%s]:%d' % (self.addr, self.port)]['ssh-rsa']) - def test_5_cleanup(self): + def test_5_save_host_keys(self): + """ + verify that SSHClient correctly saves a known_hosts file. + """ + warnings.filterwarnings('ignore', 'tempnam.*') + + host_key = paramiko.RSAKey.from_private_key_file('tests/test_rsa.key') + public_host_key = paramiko.RSAKey(data=str(host_key)) + localname = os.tempnam() + + client = paramiko.SSHClient() + self.assertEquals(0, len(client.get_host_keys())) + + host_id = '[%s]:%d' % (self.addr, self.port) + + client.get_host_keys().add(host_id, 'ssh-rsa', public_host_key) + self.assertEquals(1, len(client.get_host_keys())) + self.assertEquals(public_host_key, client.get_host_keys()[host_id]['ssh-rsa']) + + client.save_host_keys(localname) + + with open(localname) as fd: + assert host_id in fd.read() + + os.unlink(localname) + + def test_6_cleanup(self): """ verify that when an SSHClient is collected, its transport (and the transport's packetizer) is closed. diff --git a/tests/test_ecdsa.key b/tests/test_ecdsa.key new file mode 100644 index 0000000..42d4473 --- /dev/null +++ b/tests/test_ecdsa.key @@ -0,0 +1,5 @@ +-----BEGIN EC PRIVATE KEY----- +MHcCAQEEIKB6ty3yVyKEnfF/zprx0qwC76MsMlHY4HXCnqho2eKioAoGCCqGSM49 +AwEHoUQDQgAElI9mbdlaS+T9nHxY/59lFnn80EEecZDBHq4gLpccY8Mge5ZTMiMD +ADRvOqQ5R98Sxst765CAqXmRtz8vwoD96g== +-----END EC PRIVATE KEY----- diff --git a/tests/test_ecdsa_password.key b/tests/test_ecdsa_password.key new file mode 100644 index 0000000..eb7910e --- /dev/null +++ b/tests/test_ecdsa_password.key @@ -0,0 +1,8 @@ +-----BEGIN EC PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: AES-128-CBC,EEB56BC745EDB2DE04FC3FE1F8DA387E + +wdt7QTCa6ahTJLaEPH7NhHyBcxhzrzf93d4UwQOuAhkM6//jKD4lF9fErHBW0f3B +ExberCU3UxfEF3xX2thXiLw47JgeOCeQUlqRFx92p36k6YmfNGX6W8CsZ3d+XodF +Z+pb6m285CiSX+W95NenFMexXFsIpntiCvTifTKJ8os= +-----END EC PRIVATE KEY----- diff --git a/tests/test_file.py b/tests/test_file.py index c539b22..6cb3507 100755 --- a/tests/test_file.py +++ b/tests/test_file.py @@ -7,7 +7,7 @@ # Software Foundation; either version 2.1 of the License, or (at your option) # any later version. # -# Paramiko is distrubuted in the hope that it will be useful, but WITHOUT ANY +# Paramiko is distributed in the hope that it will be useful, but WITHOUT ANY # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR # A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more # details. diff --git a/tests/test_hostkeys.py b/tests/test_hostkeys.py index e28a41d..44070cb 100644 --- a/tests/test_hostkeys.py +++ b/tests/test_hostkeys.py @@ -7,7 +7,7 @@ # Software Foundation; either version 2.1 of the License, or (at your option) # any later version. # -# Paramiko is distrubuted in the hope that it will be useful, but WITHOUT ANY +# Paramiko is distributed in the hope that it will be useful, but WITHOUT ANY # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR # A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more # details. diff --git a/tests/test_kex.py b/tests/test_kex.py index f6e6996..39d2e17 100644 --- a/tests/test_kex.py +++ b/tests/test_kex.py @@ -7,7 +7,7 @@ # Software Foundation; either version 2.1 of the License, or (at your option) # any later version. # -# Paramiko is distrubuted in the hope that it will be useful, but WITHOUT ANY +# Paramiko is distributed in the hope that it will be useful, but WITHOUT ANY # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR # A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more # details. diff --git a/tests/test_message.py b/tests/test_message.py index 7bfd44d..ad622a2 100644 --- a/tests/test_message.py +++ b/tests/test_message.py @@ -7,7 +7,7 @@ # Software Foundation; either version 2.1 of the License, or (at your option) # any later version. # -# Paramiko is distrubuted in the hope that it will be useful, but WITHOUT ANY +# Paramiko is distributed in the hope that it will be useful, but WITHOUT ANY # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR # A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more # details. diff --git a/tests/test_packetizer.py b/tests/test_packetizer.py index d1eb584..1f5bec0 100644 --- a/tests/test_packetizer.py +++ b/tests/test_packetizer.py @@ -7,7 +7,7 @@ # Software Foundation; either version 2.1 of the License, or (at your option) # any later version. # -# Paramiko is distrubuted in the hope that it will be useful, but WITHOUT ANY +# Paramiko is distributed in the hope that it will be useful, but WITHOUT ANY # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR # A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more # details. diff --git a/tests/test_pkey.py b/tests/test_pkey.py index 89d5580..8e8c4aa 100644 --- a/tests/test_pkey.py +++ b/tests/test_pkey.py @@ -7,7 +7,7 @@ # Software Foundation; either version 2.1 of the License, or (at your option) # any later version. # -# Paramiko is distrubuted in the hope that it will be useful, but WITHOUT ANY +# Paramiko is distributed in the hope that it will be useful, but WITHOUT ANY # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR # A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more # details. @@ -23,14 +23,17 @@ Some unit tests for public/private key objects. from binascii import hexlify, unhexlify import StringIO import unittest -from paramiko import RSAKey, DSSKey, Message, util +from paramiko import RSAKey, DSSKey, ECDSAKey, Message, util from paramiko.common import rng # from openssh's ssh-keygen PUB_RSA = 'ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAIEA049W6geFpmsljTwfvI1UmKWWJPNFI74+vNKTk4dmzkQY2yAMs6FhlvhlI8ysU4oj71ZsRYMecHbBbxdN79+JRFVYTKaLqjwGENeTd+yv4q+V2PvZv3fLnzApI3l7EJCqhWwJUHJ1jAkZzqDx0tyOL4uoZpww3nmE0kb3y21tH4c=' PUB_DSS = 'ssh-dss AAAAB3NzaC1kc3MAAACBAOeBpgNnfRzr/twmAQRu2XwWAp3CFtrVnug6s6fgwj/oLjYbVtjAy6pl/h0EKCWx2rf1IetyNsTxWrniA9I6HeDj65X1FyDkg6g8tvCnaNB8Xp/UUhuzHuGsMIipRxBxw9LF608EqZcj1E3ytktoW5B5OcjrkEoz3xG7C+rpIjYvAAAAFQDwz4UnmsGiSNu5iqjn3uTzwUpshwAAAIEAkxfFeY8P2wZpDjX0MimZl5wkoFQDL25cPzGBuB4OnB8NoUk/yjAHIIpEShw8V+LzouMK5CTJQo5+Ngw3qIch/WgRmMHy4kBq1SsXMjQCte1So6HBMvBPIW5SiMTmjCfZZiw4AYHK+B/JaOwaG9yRg2Ejg4Ok10+XFDxlqZo8Y+wAAACARmR7CCPjodxASvRbIyzaVpZoJ/Z6x7dAumV+ysrV1BVYd0lYukmnjO1kKBWApqpH1ve9XDQYN8zgxM4b16L21kpoWQnZtXrY3GZ4/it9kUgyB7+NwacIBlXa8cMDL7Q/69o0d54U0X/NeX5QxuYR6OMJlrkQB7oiW/P/1mwjQgE=' +PUB_ECDSA = 'ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBJSPZm3ZWkvk/Zx8WP+fZRZ5/NBBHnGQwR6uIC6XHGPDIHuWUzIjAwA0bzqkOUffEsbLe+uQgKl5kbc/L8KA/eo=' + FINGER_RSA = '1024 60:73:38:44:cb:51:86:65:7f:de:da:a2:2b:5a:57:d5' FINGER_DSS = '1024 44:78:f0:b9:a2:3c:c5:18:20:09:ff:75:5b:c1:d2:6c' +FINGER_ECDSA = '256 25:19:eb:55:e6:a1:47:ff:4f:38:d2:75:6f:a5:d5:60' SIGNED_RSA = '20:d7:8a:31:21:cb:f7:92:12:f2:a4:89:37:f5:78:af:e6:16:b6:25:b9:97:3d:a2:cd:5f:ca:20:21:73:4c:ad:34:73:8f:20:77:28:e2:94:15:08:d8:91:40:7a:85:83:bf:18:37:95:dc:54:1a:9b:88:29:6c:73:ca:38:b4:04:f1:56:b9:f2:42:9d:52:1b:29:29:b4:4f:fd:c9:2d:af:47:d2:40:76:30:f3:63:45:0c:d9:1d:43:86:0f:1c:70:e2:93:12:34:f3:ac:c5:0a:2f:14:50:66:59:f1:88:ee:c1:4a:e9:d1:9c:4e:46:f0:0e:47:6f:38:74:f1:44:a8' RSA_PRIVATE_OUT = """\ @@ -66,6 +69,13 @@ QPSch9pT9XHqn+1rZ4bK+QGA -----END DSA PRIVATE KEY----- """ +ECDSA_PRIVATE_OUT = """\ +-----BEGIN EC PRIVATE KEY----- +MHcCAQEEIKB6ty3yVyKEnfF/zprx0qwC76MsMlHY4HXCnqho2eKioAoGCCqGSM49 +AwEHoUQDQgAElI9mbdlaS+T9nHxY/59lFnn80EEecZDBHq4gLpccY8Mge5ZTMiMD +ADRvOqQ5R98Sxst765CAqXmRtz8vwoD96g== +-----END EC PRIVATE KEY----- +""" class KeyTest (unittest.TestCase): @@ -176,7 +186,7 @@ class KeyTest (unittest.TestCase): msg.rewind() pub = DSSKey(data=str(key)) self.assert_(pub.verify_ssh_sig('ice weasels', msg)) - + def test_A_generate_rsa(self): key = RSAKey.generate(1024) msg = key.sign_ssh_data(rng, 'jerri blank') @@ -188,3 +198,53 @@ class KeyTest (unittest.TestCase): msg = key.sign_ssh_data(rng, 'jerri blank') msg.rewind() self.assert_(key.verify_ssh_sig('jerri blank', msg)) + + def test_10_load_ecdsa(self): + key = ECDSAKey.from_private_key_file('tests/test_ecdsa.key') + self.assertEquals('ecdsa-sha2-nistp256', key.get_name()) + exp_ecdsa = FINGER_ECDSA.split()[1].replace(':', '') + my_ecdsa = hexlify(key.get_fingerprint()) + self.assertEquals(exp_ecdsa, my_ecdsa) + self.assertEquals(PUB_ECDSA.split()[1], key.get_base64()) + self.assertEquals(256, key.get_bits()) + + s = StringIO.StringIO() + key.write_private_key(s) + self.assertEquals(ECDSA_PRIVATE_OUT, s.getvalue()) + s.seek(0) + key2 = ECDSAKey.from_private_key(s) + self.assertEquals(key, key2) + + def test_11_load_ecdsa_password(self): + key = ECDSAKey.from_private_key_file('tests/test_ecdsa_password.key', 'television') + self.assertEquals('ecdsa-sha2-nistp256', key.get_name()) + exp_ecdsa = FINGER_ECDSA.split()[1].replace(':', '') + my_ecdsa = hexlify(key.get_fingerprint()) + self.assertEquals(exp_ecdsa, my_ecdsa) + self.assertEquals(PUB_ECDSA.split()[1], key.get_base64()) + self.assertEquals(256, key.get_bits()) + + def test_12_compare_ecdsa(self): + # verify that the private & public keys compare equal + key = ECDSAKey.from_private_key_file('tests/test_ecdsa.key') + self.assertEquals(key, key) + pub = ECDSAKey(data=str(key)) + self.assert_(key.can_sign()) + self.assert_(not pub.can_sign()) + self.assertEquals(key, pub) + + def test_13_sign_ecdsa(self): + # verify that the rsa private key can sign and verify + key = ECDSAKey.from_private_key_file('tests/test_ecdsa.key') + msg = key.sign_ssh_data(rng, 'ice weasels') + self.assert_(type(msg) is Message) + msg.rewind() + self.assertEquals('ecdsa-sha2-nistp256', msg.get_string()) + # ECDSA signatures, like DSS signatures, tend to be different + # each time, so we can't compare against a "known correct" + # signature. + # Even the length of the signature can change. + + msg.rewind() + pub = ECDSAKey(data=str(key)) + self.assert_(pub.verify_ssh_sig('ice weasels', msg)) diff --git a/tests/test_sftp.py b/tests/test_sftp.py index b1697ea..cc512c1 100755 --- a/tests/test_sftp.py +++ b/tests/test_sftp.py @@ -7,7 +7,7 @@ # Software Foundation; either version 2.1 of the License, or (at your option) # any later version. # -# Paramiko is distrubuted in the hope that it will be useful, but WITHOUT ANY +# Paramiko is distributed in the hope that it will be useful, but WITHOUT ANY # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR # A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more # details. diff --git a/tests/test_sftp_big.py b/tests/test_sftp_big.py index a32a700..04b15b0 100644 --- a/tests/test_sftp_big.py +++ b/tests/test_sftp_big.py @@ -7,7 +7,7 @@ # Software Foundation; either version 2.1 of the License, or (at your option) # any later version. # -# Paramiko is distrubuted in the hope that it will be useful, but WITHOUT ANY +# Paramiko is distributed in the hope that it will be useful, but WITHOUT ANY # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR # A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more # details. diff --git a/tests/test_transport.py b/tests/test_transport.py index 1c57d18..e8f7f36 100644 --- a/tests/test_transport.py +++ b/tests/test_transport.py @@ -7,7 +7,7 @@ # Software Foundation; either version 2.1 of the License, or (at your option) # any later version. # -# Paramiko is distrubuted in the hope that it will be useful, but WITHOUT ANY +# Paramiko is distributed in the hope that it will be useful, but WITHOUT ANY # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR # A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more # details. diff --git a/tests/test_util.py b/tests/test_util.py index efda9b2..12677a9 100644 --- a/tests/test_util.py +++ b/tests/test_util.py @@ -7,7 +7,7 @@ # Software Foundation; either version 2.1 of the License, or (at your option) # any later version. # -# Paramiko is distrubuted in the hope that it will be useful, but WITHOUT ANY +# Paramiko is distributed in the hope that it will be useful, but WITHOUT ANY # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR # A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more # details. @@ -329,3 +329,14 @@ IdentityFile id_dsa22 paramiko.util.lookup_ssh_host_config(host, config), values ) + + def test_12_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(cStringIO.StringIO(test_config)) + assert config.lookup('meh') # will die during lookup() if bug regresses -- cgit v1.2.3