diff options
author | Jeff Forcier <jeff@bitprophet.org> | 2022-04-25 08:15:42 -0400 |
---|---|---|
committer | Jeff Forcier <jeff@bitprophet.org> | 2022-04-25 08:15:42 -0400 |
commit | d9eb35c69ab29a1ad7a9e3dd5325d4cab9dd2bc0 (patch) | |
tree | bfa73aede87b442db84627cbe9075d3082a1601f | |
parent | 9151b5a5ef6634142cc810193a59630c863549c3 (diff) | |
parent | 47529be4385cffba6851f10e505f5683290d116e (diff) |
Merge branch '2.10'
-rw-r--r-- | paramiko/pkey.py | 2 | ||||
-rw-r--r-- | paramiko/transport.py | 10 | ||||
-rw-r--r-- | sites/www/changelog.rst | 10 | ||||
-rw-r--r-- | tests/test_pkey.py | 5 | ||||
-rw-r--r-- | tests/test_transport.py | 8 |
5 files changed, 32 insertions, 3 deletions
diff --git a/paramiko/pkey.py b/paramiko/pkey.py index 3c975630..585cb74a 100644 --- a/paramiko/pkey.py +++ b/paramiko/pkey.py @@ -140,7 +140,7 @@ class PKey(object): return cmp(self.asbytes(), other.asbytes()) # noqa def __eq__(self, other): - return self._fields == other._fields + return isinstance(other, PKey) and self._fields == other._fields def __hash__(self): return hash(self._fields) diff --git a/paramiko/transport.py b/paramiko/transport.py index 36ff237d..2168032f 100644 --- a/paramiko/transport.py +++ b/paramiko/transport.py @@ -549,7 +549,15 @@ class Transport(threading.Thread, ClosingContextManager): @property def preferred_keys(self): - return self._filter_algorithm("keys") + # Interleave cert variants here; resistant to various background + # overwriting of _preferred_keys, and necessary as hostkeys can't use + # the logic pubkey auth does re: injecting/checking for certs at + # runtime + filtered = self._filter_algorithm("keys") + return tuple( + filtered + + tuple("{}-cert-v01@openssh.com".format(x) for x in filtered) + ) @property def preferred_pubkeys(self): diff --git a/sites/www/changelog.rst b/sites/www/changelog.rst index 4c033ab3..eda7d1e5 100644 --- a/sites/www/changelog.rst +++ b/sites/www/changelog.rst @@ -2,10 +2,20 @@ Changelog ========= +- :bug:`1964` (via :issue:`2024` as also reported in :issue:`2023`) + `~paramiko.pkey.PKey` instances' ``__eq__`` did not have the usual safety + guard in place to ensure they were being compared to another ``PKey`` object, + causing occasional spurious ``BadHostKeyException`` (among other things). + This has been fixed. Thanks to Shengdun Hua for the original report/patch and + to Christopher Papke for the final version of the fix. - :support:`2004` (via :issue:`2011`) Apply unittest ``skipIf`` to tests currently using SHA1 in their critical path, to avoid failures on systems starting to disable SHA1 outright in their crypto backends (eg RHEL 9). Report & patch via Paul Howarth. +- :bug:`2035` Servers offering certificate variants of hostkey algorithms (eg + ``ssh-rsa-cert-v01@openssh.com``) could not have their host keys verified by + Paramiko clients, as it only ever considered non-cert key types for that part + of connection handshaking. This has been fixed. - :release:`2.10.3 <2022-03-18>` - :release:`2.9.3 <2022-03-18>` - :bug:`1963` (via :issue:`1977`) Certificate-based pubkey auth was diff --git a/tests/test_pkey.py b/tests/test_pkey.py index 44ab688f..738e8cf0 100644 --- a/tests/test_pkey.py +++ b/tests/test_pkey.py @@ -626,6 +626,11 @@ class KeyTest(unittest.TestCase): for key1, key2 in self.keys(): assert key1 == key2 + def test_keys_are_not_equal_to_other(self): + for value in [None, True, ""]: + for key1, _ in self.keys(): + assert key1 != value + def test_keys_are_hashable(self): # NOTE: this isn't a great test due to hashseed randomization under # Python 3 preventing use of static values, but it does still prove diff --git a/tests/test_transport.py b/tests/test_transport.py index 52a49b0e..8e5f8cd7 100644 --- a/tests/test_transport.py +++ b/tests/test_transport.py @@ -1121,7 +1121,12 @@ class AlgorithmDisablingTests(unittest.TestCase): t = Transport(sock=Mock()) assert t.preferred_ciphers == t._preferred_ciphers assert t.preferred_macs == t._preferred_macs - assert t.preferred_keys == t._preferred_keys + assert t.preferred_keys == tuple( + t._preferred_keys + + tuple( + "{}-cert-v01@openssh.com".format(x) for x in t._preferred_keys + ) + ) assert t.preferred_kex == t._preferred_kex def test_preferred_lists_filter_disabled_algorithms(self): @@ -1140,6 +1145,7 @@ class AlgorithmDisablingTests(unittest.TestCase): assert "hmac-md5" not in t.preferred_macs assert "ssh-dss" in t._preferred_keys assert "ssh-dss" not in t.preferred_keys + assert "ssh-dss-cert-v01@openssh.com" not in t.preferred_keys assert "diffie-hellman-group14-sha256" in t._preferred_kex assert "diffie-hellman-group14-sha256" not in t.preferred_kex |