commit 7d00d48994bf3baba764a00758816559b798982e Author: Adrian Schröter Date: Mon Jul 15 12:55:11 2024 +0200 Sync from SUSE:ALP:Source:Standard:1.0 saltbundlepy-paramiko revision 2dc0449bc49935c75549a214d3bf92a8 diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..fecc750 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,23 @@ +## Default LFS +*.7z filter=lfs diff=lfs merge=lfs -text +*.bsp filter=lfs diff=lfs merge=lfs -text +*.bz2 filter=lfs diff=lfs merge=lfs -text +*.gem filter=lfs diff=lfs merge=lfs -text +*.gz filter=lfs diff=lfs merge=lfs -text +*.jar filter=lfs diff=lfs merge=lfs -text +*.lz filter=lfs diff=lfs merge=lfs -text +*.lzma filter=lfs diff=lfs merge=lfs -text +*.obscpio filter=lfs diff=lfs merge=lfs -text +*.oxt filter=lfs diff=lfs merge=lfs -text +*.pdf filter=lfs diff=lfs merge=lfs -text +*.png filter=lfs diff=lfs merge=lfs -text +*.rpm filter=lfs diff=lfs merge=lfs -text +*.tbz filter=lfs diff=lfs merge=lfs -text +*.tbz2 filter=lfs diff=lfs merge=lfs -text +*.tgz filter=lfs diff=lfs merge=lfs -text +*.ttf filter=lfs diff=lfs merge=lfs -text +*.txz filter=lfs diff=lfs merge=lfs -text +*.whl filter=lfs diff=lfs merge=lfs -text +*.xz filter=lfs diff=lfs merge=lfs -text +*.zip filter=lfs diff=lfs merge=lfs -text +*.zst filter=lfs diff=lfs merge=lfs -text diff --git a/CVE-2022-24302-race-condition.patch b/CVE-2022-24302-race-condition.patch new file mode 100644 index 0000000..9ee45d4 --- /dev/null +++ b/CVE-2022-24302-race-condition.patch @@ -0,0 +1,102 @@ +Index: paramiko-2.4.2/paramiko/pkey.py +=================================================================== +--- paramiko-2.4.2.orig/paramiko/pkey.py ++++ paramiko-2.4.2/paramiko/pkey.py +@@ -519,7 +519,18 @@ class PKey(object): + + :raises: ``IOError`` -- if there was an error writing the file. + """ +- with open(filename, "w") as f: ++ # Ensure that we create new key files directly with a user-only mode, ++ # instead of opening, writing, then chmodding, which leaves us open to ++ # CVE-2022-24302. ++ # NOTE: O_TRUNC is a noop on new files, and O_CREAT is a noop on ++ # existing files, so using all 3 in both cases is fine. Ditto the use ++ # of the 'mode' argument; it should be safe to give even for existing ++ # files (though it will not act like a chmod in that case). ++ # TODO 3.0: turn into kwargs again ++ args = [os.O_WRONLY | os.O_TRUNC | os.O_CREAT, o600] ++ # NOTE: yea, you still gotta inform the FLO that it is in "write" mode ++ with os.fdopen(os.open(filename, *args), "w") as f: ++ # TODO 3.0: remove the now redundant chmod + os.chmod(filename, o600) + self._write_private_key(f, key, format, password=password) + +Index: paramiko-2.4.2/tests/test_pkey.py +=================================================================== +--- paramiko-2.4.2.orig/tests/test_pkey.py ++++ paramiko-2.4.2/tests/test_pkey.py +@@ -23,11 +23,15 @@ Some unit tests for public/private key o + + import unittest + import os ++import stat + from binascii import hexlify + from hashlib import md5 + + from paramiko import RSAKey, DSSKey, ECDSAKey, Ed25519Key, Message, util + from paramiko.py3compat import StringIO, byte_chr, b, bytes, PY2 ++from paramiko.common import o600 ++ ++from mock import patch, Mock + + from .util import _support + +@@ -567,3 +571,57 @@ class KeyTest(unittest.TestCase): + key1.load_certificate, + _support("test_rsa.key-cert.pub"), + ) ++ ++ @patch("paramiko.pkey.os") ++ def _test_keyfile_race(self, os_, exists): ++ # Re: CVE-2022-24302 ++ password = "television" ++ newpassword = "radio" ++ source = _support("test_ecdsa_384.key") ++ new = source + ".new" ++ # Mock setup ++ os_.path.exists.return_value = exists ++ # Attach os flag values to mock ++ for attr, value in vars(os).items(): ++ if attr.startswith("O_"): ++ setattr(os_, attr, value) ++ # Load fixture key ++ key = ECDSAKey(filename=source, password=password) ++ key._write_private_key = Mock() ++ # Write out in new location ++ key.write_private_key_file(new, password=newpassword) ++ # Expected open via os module ++ os_.open.assert_called_once_with(new, os.O_WRONLY | os.O_CREAT | os.O_TRUNC, o600) ++ os_.fdopen.assert_called_once_with(os_.open.return_value, "w") ++ # Old chmod still around for backwards compat ++ os_.chmod.assert_called_once_with(new, o600) ++ assert ( ++ key._write_private_key.call_args[0][0] ++ == os_.fdopen.return_value.__enter__.return_value ++ ) ++ ++ def test_new_keyfiles_avoid_file_descriptor_race_on_chmod(self): ++ self._test_keyfile_race(exists=False) ++ ++ def test_existing_keyfiles_still_work_ok(self): ++ self._test_keyfile_race(exists=True) ++ ++ def test_new_keyfiles_avoid_descriptor_race_integration(self): ++ # Integration-style version of above ++ password = "television" ++ newpassword = "radio" ++ source = _support("test_ecdsa_384.key") ++ new = source + ".new" ++ # Load fixture key ++ key = ECDSAKey(filename=source, password=password) ++ try: ++ # Write out in new location ++ key.write_private_key_file(new, password=newpassword) ++ # Test mode ++ assert stat.S_IMODE(os.stat(new).st_mode) == o600 ++ # Prove can open with new password ++ reloaded = ECDSAKey(filename=new, password=newpassword) ++ assert reloaded == key ++ finally: ++ if os.path.exists(new): ++ os.unlink(new) diff --git a/add-support-for-new-OpenSSH-private-key-format.patch b/add-support-for-new-OpenSSH-private-key-format.patch new file mode 100644 index 0000000..add3696 --- /dev/null +++ b/add-support-for-new-OpenSSH-private-key-format.patch @@ -0,0 +1,485 @@ +From eff204faf5624c51b7ac96b9b93e4ce9622f853a Mon Sep 17 00:00:00 2001 +From: Jared Hobbs +Date: Tue, 27 Nov 2018 17:22:59 -0700 +Subject: [PATCH] add support for new OpenSSH private key format + +This work is based off the work done in https://github.com/paramiko/paramiko/pull/618 +--- + paramiko/dsskey.py | 15 +++- + paramiko/ecdsakey.py | 22 +++-- + paramiko/ed25519key.py | 4 +- + paramiko/pkey.py | 191 +++++++++++++++++++++++++++++++++++++--- + paramiko/rsakey.py | 30 +++++-- + tests/test_dss_1k_o.key | 22 +++++ + tests/test_pkey.py | 25 +++++- + tests/test_rsa_2k_o.key | 28 ++++++ + 9 files changed, 307 insertions(+), 31 deletions(-) + create mode 100644 tests/test_dss_1k_o.key + create mode 100644 tests/test_rsa_2k_o.key + +diff --git a/paramiko/dsskey.py b/paramiko/dsskey.py +index ec358ee2..a1adf818 100644 +--- a/paramiko/dsskey.py ++++ b/paramiko/dsskey.py +@@ -229,12 +229,19 @@ class DSSKey(PKey): + self._decode_key(data) + + def _decode_key(self, data): ++ pkformat, data = data + # private key file contains: + # DSAPrivateKey = { version = 0, p, q, g, y, x } +- try: +- keylist = BER(data).decode() +- except BERException as e: +- raise SSHException("Unable to parse key file: " + str(e)) ++ if pkformat == self.PRIVATE_KEY_FORMAT_ORIGINAL: ++ try: ++ keylist = BER(data).decode() ++ except BERException as e: ++ raise SSHException("Unable to parse key file: " + str(e)) ++ elif pkformat == self.PRIVATE_KEY_FORMAT_OPENSSH: ++ keylist = self._uint32_cstruct_unpack(data, 'iiiii') ++ keylist = [0] + list(keylist) ++ else: ++ raise SSHException('private key format.') + if type(keylist) is not list or len(keylist) < 6 or keylist[0] != 0: + raise SSHException( + "not a valid DSA private key file (bad ber encoding)" +diff --git a/paramiko/ecdsakey.py b/paramiko/ecdsakey.py +index b73a969e..c3ef8e4d 100644 +--- a/paramiko/ecdsakey.py ++++ b/paramiko/ecdsakey.py +@@ -283,12 +283,22 @@ class ECDSAKey(PKey): + self._decode_key(data) + + def _decode_key(self, data): +- try: +- key = serialization.load_der_private_key( +- data, password=None, backend=default_backend() +- ) +- except (ValueError, AssertionError) as e: +- raise SSHException(str(e)) ++ pkformat, data = data ++ if pkformat == self.PRIVATE_KEY_FORMAT_ORIGINAL: ++ try: ++ key = serialization.load_der_private_key( ++ data, password=None, backend=default_backend() ++ ) ++ except (ValueError, AssertionError) as e: ++ raise SSHException(str(e)) ++ elif pkformat == self.PRIVATE_KEY_FORMAT_OPENSSH: ++ curve, verkey, sigkey = self._uint32_cstruct_unpack(data, 'sss') ++ try: ++ key = ec.derive_private_key(sigkey, curve, default_backend()) ++ except TypeError as e: ++ raise SSHException(str(e)) ++ else: ++ raise SSHException('unknown private key format.') + + self.signing_key = key + self.verifying_key = key.public_key() +diff --git a/paramiko/ed25519key.py b/paramiko/ed25519key.py +index 68ada224..3bd0ff10 100644 +--- a/paramiko/ed25519key.py ++++ b/paramiko/ed25519key.py +@@ -73,9 +73,9 @@ class Ed25519Key(PKey): + verifying_key = nacl.signing.VerifyKey(msg.get_binary()) + elif filename is not None: + with open(filename, "r") as f: +- data = self._read_private_key("OPENSSH", f) ++ pkformat, data = self._read_private_key("OPENSSH", f) + elif file_obj is not None: +- data = self._read_private_key("OPENSSH", file_obj) ++ pkformat, data = self._read_private_key("OPENSSH", file_obj) + + if filename or file_obj: + signing_key = self._parse_signing_key_data(data, password) +diff -ur paramiko-2.4.3.orig/paramiko/pkey.py paramiko-2.4.3/paramiko/pkey.py +--- paramiko-2.4.3.orig/paramiko/pkey.py 2019-06-24 00:45:29.000000000 +0200 ++++ paramiko-2.4.3/paramiko/pkey.py 2022-09-02 15:45:18.345029737 +0200 +@@ -24,6 +24,10 @@ + from binascii import unhexlify + import os + from hashlib import md5 ++import re ++import struct ++ ++import bcrypt + + from cryptography.hazmat.backends import default_backend + from cryptography.hazmat.primitives import serialization +@@ -31,7 +35,8 @@ + + from paramiko import util + from paramiko.common import o600 +-from paramiko.py3compat import u, encodebytes, decodebytes, b, string_types ++from paramiko.py3compat import u, encodebytes, decodebytes, b, string_types,\ ++ byte_ord + from paramiko.ssh_exception import SSHException, PasswordRequiredException + from paramiko.message import Message + +@@ -62,6 +67,12 @@ + "mode": modes.CBC, + }, + } ++ PRIVATE_KEY_FORMAT_ORIGINAL = 1 ++ PRIVATE_KEY_FORMAT_OPENSSH = 2 ++ BEGIN_TAG = re.compile( ++ '^-{5}BEGIN (RSA|DSA|EC|OPENSSH) PRIVATE KEY-{5}\s*$' ++ ) ++ END_TAG = re.compile('^-{5}END (RSA|DSA|EC|OPENSSH) PRIVATE KEY-{5}\s*$') + + def __init__(self, msg=None, data=None): + """ +@@ -281,12 +292,47 @@ + + def _read_private_key(self, tag, f, password=None): + lines = f.readlines() ++ ++ # find the BEGIN tag + start = 0 +- beginning_of_key = "-----BEGIN " + tag + " PRIVATE KEY-----" +- while start < len(lines) and lines[start].strip() != beginning_of_key: ++ m = self.BEGIN_TAG.match(lines[start]) ++ line_range = len(lines) - 1 ++ while start < line_range and not m: + start += 1 ++ m = self.BEGIN_TAG.match(lines[start]) ++ start += 1 ++ keytype = m.group(1) + if start >= len(lines): + raise SSHException("not a valid " + tag + " private key file") ++ ++ # find the END tag ++ end = start ++ m = self.END_TAG.match(lines[end]) ++ while end < line_range and not m: ++ end += 1 ++ m = self.END_TAG.match(lines[end]) ++ ++ if keytype == tag: ++ data = self._read_private_key_old_format( ++ lines, ++ password, ++ ) ++ pkformat = self.PRIVATE_KEY_FORMAT_ORIGINAL ++ elif keytype == 'OPENSSH': ++ data = self._read_private_key_new_format( ++ lines[start:end], ++ password, ++ ) ++ pkformat = self.PRIVATE_KEY_FORMAT_OPENSSH ++ else: ++ raise SSHException( ++ 'encountered {} key, expected {} key'.format(keytype, tag) ++ ) ++ ++ return pkformat, data ++ ++ def _read_private_key_old_format(self, lines, password): ++ start = 0 + # parse any headers first + headers = {} + start += 1 +@@ -296,14 +342,9 @@ + break + headers[line[0].lower()] = line[1].strip() + start += 1 +- # find end +- end = start +- ending_of_key = "-----END " + tag + " PRIVATE KEY-----" +- while end < len(lines) and lines[end].strip() != ending_of_key: +- end += 1 + # if we trudged to the end of the file, just try to cope. + try: +- data = decodebytes(b("".join(lines[start:end]))) ++ data = decodebytes(b(''.join(lines[start:]))) + except base64.binascii.Error as e: + raise SSHException("base64 decoding error: " + str(e)) + if "proc-type" not in headers: +@@ -337,6 +378,132 @@ + ).decryptor() + return decryptor.update(data) + decryptor.finalize() + ++ def _read_private_key_new_format(self, lines, password): ++ """ ++ Read the new OpenSSH SSH2 private key format available ++ since OpenSSH version 6.5 ++ Reference: ++ https://github.com/openssh/openssh-portable/blob/master/PROTOCOL.key ++ """ ++ try: ++ data = decodebytes(b(''.join(lines))) ++ except base64.binascii.Error as e: ++ raise SSHException('base64 decoding error: ' + str(e)) ++ ++ # read data struct ++ auth_magic = data[:14] ++ if auth_magic != b('openssh-key-v1'): ++ raise SSHException('unexpected OpenSSH key header encountered') ++ ++ cstruct = self._uint32_cstruct_unpack(data[15:], 'sssur') ++ cipher, kdfname, kdf_options, num_pubkeys, remainder = cstruct ++ # For now, just support 1 key. ++ if num_pubkeys > 1: ++ raise SSHException( ++ 'unsupported: private keyfile has multiple keys' ++ ) ++ pubkey, privkey_blob = self._uint32_cstruct_unpack(remainder, 'ss') ++ ++ if kdfname == b('bcrypt'): ++ if cipher == b('aes256-cbc'): ++ mode = modes.CBC ++ elif cipher == b('aes256-ctr'): ++ mode = modes.CTR ++ else: ++ raise SSHException( ++ 'unknown cipher `{}` used in private key file'.format( ++ cipher.decode('utf-8') ++ ) ++ ) ++ # Encrypted private key. ++ # If no password was passed in, raise an exception pointing ++ # out that we need one ++ if password is None: ++ raise PasswordRequiredException( ++ 'private key file is encrypted' ++ ) ++ ++ # Unpack salt and rounds from kdfoptions ++ salt, rounds = self._uint32_cstruct_unpack(kdf_options, 'su') ++ ++ # run bcrypt kdf to derive key and iv/nonce (32 + 16 bytes) ++ key_iv = bcrypt.kdf(b(password), b(salt), 48, rounds) ++ key = key_iv[:32] ++ iv = key_iv[32:] ++ ++ # decrypt private key blob ++ decryptor = Cipher( ++ algorithms.AES(key), mode(iv), default_backend() ++ ).decryptor() ++ decrypted_privkey = decryptor.update(privkey_blob) ++ decrypted_privkey += decryptor.finalize() ++ elif cipher == b('none') and kdfname == b('none'): ++ # Unencrypted private key ++ decrypted_privkey = privkey_blob ++ else: ++ raise SSHException( ++ 'unknown cipher or kdf used in private key file' ++ ) ++ ++ # Unpack private key and verify checkints ++ cstruct = self._uint32_cstruct_unpack(decrypted_privkey, 'uusr') ++ checkint1, checkint2, keytype, keydata = cstruct ++ ++ if checkint1 != checkint2: ++ raise SSHException( ++ 'OpenSSH private key file checkints do not match' ++ ) ++ ++ # Remove padding ++ padlen = byte_ord(keydata[len(keydata) - 1]) ++ return keydata[:len(keydata) - padlen] ++ ++ def _uint32_cstruct_unpack(self, data, strformat): ++ """ ++ Used to read new OpenSSH private key format. ++ Unpacks a c data structure containing a mix of 32-bit uints and ++ variable length strings prefixed by 32-bit uint size field, ++ according to the specified format. Returns the unpacked vars ++ in a tuple. ++ Format strings: ++ s - denotes a string ++ i - denotes a long integer, encoded as a byte string ++ u - denotes a 32-bit unsigned integer ++ r - the remainder of the input string, returned as a string ++ """ ++ arr = [] ++ idx = 0 ++ try: ++ for f in strformat: ++ if f == 's': ++ # string ++ s_size = struct.unpack('>L', data[idx:idx + 4])[0] ++ idx += 4 ++ s = data[idx:idx + s_size] ++ idx += s_size ++ arr.append(s) ++ if f == 'i': ++ # long integer ++ s_size = struct.unpack('>L', data[idx:idx + 4])[0] ++ idx += 4 ++ s = data[idx:idx + s_size] ++ idx += s_size ++ i = util.inflate_long(s, True) ++ arr.append(i) ++ elif f == 'u': ++ # 32-bit unsigned int ++ u = struct.unpack('>L', data[idx:idx + 4])[0] ++ idx += 4 ++ arr.append(u) ++ elif f == 'r': ++ # remainder as string ++ s = data[idx:] ++ arr.append(s) ++ break ++ except Exception as e: ++ raise SSHException(str(e)) ++ return tuple(arr) ++ + def _write_private_key_file(self, filename, key, format, password=None): + """ + Write an SSH2-format private key file in a form that can be read by +diff --git a/paramiko/rsakey.py b/paramiko/rsakey.py +index 442bfe1f..3ff601ec 100644 +--- a/paramiko/rsakey.py ++++ b/paramiko/rsakey.py +@@ -180,12 +180,30 @@ class RSAKey(PKey): + self._decode_key(data) + + def _decode_key(self, data): +- try: +- key = serialization.load_der_private_key( +- data, password=None, backend=default_backend() ++ pkformat, data = data ++ if pkformat == self.PRIVATE_KEY_FORMAT_ORIGINAL: ++ try: ++ key = serialization.load_der_private_key( ++ data, password=None, backend=default_backend() ++ ) ++ except ValueError as e: ++ raise SSHException(str(e)) ++ elif pkformat == self.PRIVATE_KEY_FORMAT_OPENSSH: ++ n, e, d, iqmp, q, p = self._uint32_cstruct_unpack(data, 'iiiiii') ++ public_numbers = rsa.RSAPublicNumbers( ++ e=e, ++ n=n, + ) +- except ValueError as e: +- raise SSHException(str(e)) +- ++ key = rsa.RSAPrivateNumbers( ++ p=p, ++ q=q, ++ d=d, ++ dmp1=d % (p - 1), ++ dmq1=d % (q - 1), ++ iqmp=iqmp, ++ public_numbers=public_numbers, ++ ).private_key(default_backend()) ++ else: ++ raise SSHException('unknown private key format.') + assert isinstance(key, rsa.RSAPrivateKey) + self.key = key +diff --git a/tests/test_dss_1k_o.key b/tests/test_dss_1k_o.key +new file mode 100644 +index 00000000..2a9f8922 +--- /dev/null ++++ b/tests/test_dss_1k_o.key +@@ -0,0 +1,22 @@ ++-----BEGIN OPENSSH PRIVATE KEY----- ++b3BlbnNzaC1rZXktdjEAAAAACmFlczI1Ni1jdHIAAAAGYmNyeXB0AAAAGAAAABAsyq4pxL ++R5sOprPDHGpvzxAAAAEAAAAAEAAAGxAAAAB3NzaC1kc3MAAACBAL8XEx7F9xuwBNles+vW ++pNF+YcofrBhjX1r5QhpBe0eoYWLHRcroN6lxwCdGYRfgOoRjTncBiixQX/uUxAY96zDh3i ++r492s2BcJt4ihvNn/AY0I0OTuX/2IwGk9CGzafjaeZNVYxMa8lcVt0hSOTjkPQ7gVuk6bJ ++zMInvie+VWKLAAAAFQDUgYdY+rhR0SkKbC09BS/SIHcB+wAAAIB44+4zpCNcd0CGvZlowH ++99zyPX8uxQtmTLQFuR2O8O0FgVVuCdDgD0D9W8CLOp32oatpM0jyyN89EdvSWzjHzZJ+L6 ++H1FtZps7uhpDFWHdva1R25vyGecLMUuXjo5t/D7oCDih+HwHoSAxoi0QvsPd8/qqHQVznN ++JKtR6thUpXEwAAAIAG4DCBjbgTTgpBw0egRkJwBSz0oTt+1IcapNU2jA6N8urMSk9YXHEQ ++HKN68BAF3YJ59q2Ujv3LOXmBqGd1T+kzwUszfMlgzq8MMu19Yfzse6AIK1Agn1Vj6F7YXL ++sXDN+T4KszX5+FJa7t/Zsp3nALWy6l0f4WKivEF5Y2QpEFcQAAAgCH6XUl1hYWB6kgCSHV ++a4C+vQHrgFNgNwEQnE074LXHXlAhxC+Dm8XTGqVPX1KRPWzadq9/+v6pqLFqiRueB86uRb ++J5WtAbUs3WwxAaC5Mi+mn42MBfL9PIwWPWCvstrAq9Nyj3EBMeX3XFLxN3RuGXIQnY/5rF ++f5hriUVxhWDQGIVbBKhkpn7Geqg6nLpn7iqQhzFmFGjPmAdrllgdVGJRLyIN6BRsaltDdy ++vxufkvGzKudvQ85QvsaoFJQ6K1d0S7907pexvxmWpcO7zchXb6i09BITWOAKIcHpVkbNQw +++8pzSdpggsAwCRbfk/Jkezz8sXVUCfmmJ23NFUw04/0ZbilCADRsUaPfafgVPeDznBnuCm ++tfXa4JSrVUvPdwoex3SKZmYsFXwsuOEQnFkhUGHfWwTbmOmxzy6dtC24KYhnWG5OGFVJXh ++3B8jQJGGs2ANfusI/Z0o15tAnQy5fqsLf9TT3RX7RG2ujIiDBsU+A1g//IXmSxxkUOQMZs ++v+cMI8KfODAXmQtB30+yAgoV03Zb/bdptv+HqPT4eeecstJUxzEGYADt1mDq3uV7fQbNmo ++80bppU52JjztrJb7hBmXsXHPRRK6spQ1FCatqvu1ggZeXZpEifNsHeqCljt87ueXsQsORY ++pvhLzjTbTKZmjLDPuB+GxUNLEKh1ZNyAqKng== ++-----END OPENSSH PRIVATE KEY----- +diff -u paramiko-2.4.3.orig/tests/test_pkey.py paramiko-2.4.3/tests/test_pkey.py +--- paramiko-2.4.3.orig/tests/test_pkey.py 2019-06-24 00:45:29.000000000 +0200 ++++ paramiko-2.4.3/tests/test_pkey.py 2022-09-02 15:47:02.217412268 +0200 +@@ -38,6 +38,8 @@ + PUB_ECDSA_256 = "ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBJSPZm3ZWkvk/Zx8WP+fZRZ5/NBBHnGQwR6uIC6XHGPDIHuWUzIjAwA0bzqkOUffEsbLe+uQgKl5kbc/L8KA/eo=" # noqa + PUB_ECDSA_384 = "ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBBbGibQLW9AAZiGN2hEQxWYYoFaWKwN3PKSaDJSMqmIn1Z9sgRUuw8Y/w502OGvXL/wFk0i2z50l3pWZjD7gfMH7gX5TUiCzwrQkS+Hn1U2S9aF5WJp0NcIzYxXw2r4M2A==" # noqa + PUB_ECDSA_521 = "ecdsa-sha2-nistp521 AAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlzdHA1MjEAAACFBACaOaFLZGuxa5AW16qj6VLypFbLrEWrt9AZUloCMefxO8bNLjK/O5g0rAVasar1TnyHE9qj4NwzANZASWjQNbc4MAG8vzqezFwLIn/kNyNTsXNfqEko9OgHZknlj2Z79dwTJcRAL4QLcT5aND0EHZLB2fAUDXiWIb2j4rg1mwPlBMiBXA==" # noqa ++PUB_RSA_2K_OPENSSH = 'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDF+Dpr54DX0WdeTDpNAMdkCWEkl3OXtNgf58qlN1gX572OLBqLf0zT4bHstUEpU3piazph/rSWcUMuBoD46tZ6jiH7H9b9Pem2eYQWaELDDkM+v9BMbEy5rMbFRLol5OtEvPFqneyEAanPOgvd8t3yyhSev9QVusakzJ8j8LGgrA8huYZ+Srnw0shEWLG70KUKCh3rG0QIvA8nfhtUOisr2Gp+F0YxMGb5gwBlQYAYE5l6u1SjZ7hNjyNosjK+wRBFgFFBYVpkZKJgWoK9w4ijFyzMZTucnZMqKOKAjIJvHfKBf2/cEfYxSq1EndqTqjYsd9T7/s2vcn1OH5a0wkER' ++PUB_DSS_1K_OPENSSH = 'ssh-dss AAAAB3NzaC1kc3MAAACBAL8XEx7F9xuwBNles+vWpNF+YcofrBhjX1r5QhpBe0eoYWLHRcroN6lxwCdGYRfgOoRjTncBiixQX/uUxAY96zDh3ir492s2BcJt4ihvNn/AY0I0OTuX/2IwGk9CGzafjaeZNVYxMa8lcVt0hSOTjkPQ7gVuk6bJzMInvie+VWKLAAAAFQDUgYdY+rhR0SkKbC09BS/SIHcB+wAAAIB44+4zpCNcd0CGvZlowH99zyPX8uxQtmTLQFuR2O8O0FgVVuCdDgD0D9W8CLOp32oatpM0jyyN89EdvSWzjHzZJ+L6H1FtZps7uhpDFWHdva1R25vyGecLMUuXjo5t/D7oCDih+HwHoSAxoi0QvsPd8/qqHQVznNJKtR6thUpXEwAAAIAG4DCBjbgTTgpBw0egRkJwBSz0oTt+1IcapNU2jA6N8urMSk9YXHEQHKN68BAF3YJ59q2Ujv3LOXmBqGd1T+kzwUszfMlgzq8MMu19Yfzse6AIK1Agn1Vj6F7YXLsXDN+T4KszX5+FJa7t/Zsp3nALWy6l0f4WKivEF5Y2QpEFcQ==' + + 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" +@@ -45,6 +47,8 @@ + FINGER_ECDSA_384 = "384 c1:8d:a0:59:09:47:41:8e:a8:a6:07:01:29:23:b4:65" + FINGER_ECDSA_521 = "521 44:58:22:52:12:33:16:0e:ce:0e:be:2c:7c:7e:cc:1e" + 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" # noqa ++FINGER_RSA_2K_OPENSSH = '2048 68:d1:72:01:bf:c0:0c:66:97:78:df:ce:75:74:46:d6' ++FINGER_DSS_1K_OPENSSH = '1024 cf:1d:eb:d7:61:d3:12:94:c6:c0:c6:54:35:35:b0:82' + + RSA_PRIVATE_OUT = """\ + -----BEGIN RSA PRIVATE KEY----- +@@ -437,6 +441,26 @@ + pub = ECDSAKey(data=key.asbytes()) + self.assertTrue(pub.verify_ssh_sig(b"ice weasels", msg)) + ++ def test_22_load_RSA_key_new_format(self): ++ key = RSAKey.from_private_key_file( ++ _support('test_rsa_2k_o.key'), b'television') ++ self.assertEqual('ssh-rsa', key.get_name()) ++ self.assertEqual(PUB_RSA_2K_OPENSSH.split()[1], key.get_base64()) ++ self.assertEqual(2048, key.get_bits()) ++ exp_rsa = b(FINGER_RSA_2K_OPENSSH.split()[1].replace(':', '')) ++ my_rsa = hexlify(key.get_fingerprint()) ++ self.assertEqual(exp_rsa, my_rsa) ++ ++ def test_23_load_DSS_key_new_format(self): ++ key = DSSKey.from_private_key_file( ++ _support('test_dss_1k_o.key'), b'television') ++ self.assertEqual('ssh-dss', key.get_name()) ++ self.assertEqual(PUB_DSS_1K_OPENSSH.split()[1], key.get_base64()) ++ self.assertEqual(1024, key.get_bits()) ++ exp_rsa = b(FINGER_DSS_1K_OPENSSH.split()[1].replace(':', '')) ++ my_rsa = hexlify(key.get_fingerprint()) ++ self.assertEqual(exp_rsa, my_rsa) ++ + def test_salt_size(self): + # Read an existing encrypted private key + file_ = _support("test_rsa_password.key") +diff --git a/tests/test_rsa_2k_o.key b/tests/test_rsa_2k_o.key +new file mode 100644 +index 00000000..afc15f1c +--- /dev/null ++++ b/tests/test_rsa_2k_o.key +@@ -0,0 +1,28 @@ ++-----BEGIN OPENSSH PRIVATE KEY----- ++ b3BlbnNzaC1rZXktdjEAAAAACmFlczI1Ni1jYmMAAAAGYmNyeXB0AAAAGAAAABD0R3hOFS ++ FMb2SJeo5h8QPNAAAAEAAAAAEAAAEXAAAAB3NzaC1yc2EAAAADAQABAAABAQDF+Dpr54DX ++ 0WdeTDpNAMdkCWEkl3OXtNgf58qlN1gX572OLBqLf0zT4bHstUEpU3piazph/rSWcUMuBo ++ D46tZ6jiH7H9b9Pem2eYQWaELDDkM+v9BMbEy5rMbFRLol5OtEvPFqneyEAanPOgvd8t3y ++ yhSev9QVusakzJ8j8LGgrA8huYZ+Srnw0shEWLG70KUKCh3rG0QIvA8nfhtUOisr2Gp+F0 ++ YxMGb5gwBlQYAYE5l6u1SjZ7hNjyNosjK+wRBFgFFBYVpkZKJgWoK9w4ijFyzMZTucnZMq ++ KOKAjIJvHfKBf2/cEfYxSq1EndqTqjYsd9T7/s2vcn1OH5a0wkERAAAD0JnzCJYfDeiUQ6 ++ 9LOAb6/NnhKvFjCdBYal60MfLcLBHvzHLJvTneQ4f1Vknq8xEVmRba7SDSfwaEybP/1FsP ++ SGH6FNKA5gKllemgmcaUVr3wtNPtjX4WgsyHcwCRgHmOiyNrUj0OZR5wbZabHIIyirl4wa ++ LBz8Jb3GalKEagtyWsBKDCKHCFNzh8xmsT1SWhnC7baRyC8e3krQm9hGbNhpj6Q5AtN3ql ++ wBVamUp0eKxkt70mKBKI4v3DR8KqrEndeK6d0cegVEkE67fqa99a5J3uSDC8mglKrHiKEs ++ dU1dh/bOF/H3aFpINlRwvlZ95Opby7rG0BHgbZONq0+VUnABVzNTM5Xd5UKjjCF28CrQBf ++ XS6WeHeUx2zHtOmL1xdePk+Bii+SSUl3pLa4SDwX4nV95cSPx8vMm8dJEruxad6+MPoSuy ++ Oyho89jqUTSgC/RPejuTgrnB3WbzE5SJb+V3zMata0J1wxbNfYKG9U+VucUZhP4+jzfNqH ++ B/v8JqtuxnqR8NjPsK2+8wJxebL2KVNjKOm//6P3KSDsavpscGpVWOM06zUlwWCB26W3pP ++ X/+xO9aR5wiBteFKoJG1waziIjqhOJSmvq+I/texUKEUd/eEFNt10Ubc0zy0sRYVN8rIRJ ++ masQzCYuUylDzCa4ar1s4qngBZzWL2PRkPuXuhoHuT0J5no174GR6+6EAYZZhnq0tkYrhZ ++ Ar0tQ4CDlI235a3MPHzvABuwYuWys1tBuLAb+6Gc6CmCiQ+mhojfQUBYG5T65iRFA5UQsH ++ O1RLEC3yasxGcBI6d0J/fwOP/YLktNu3AeUumr0N9Xgf02DlBNwd+4GOI0LcQvl/3J8ppo ++ bamTppKPEZ2d32VNEO+Z6Zx5DlIVm5gDeMvIvdwap445VnhL3ZZH2NCkAcXM9+0WH+Quas ++ JCAMgPYiP9FzF+8Onmj2OmhgIVj/9eanhS3/GLrRC4xCvER2V7PwgB0I5qY110BPEttDyo ++ IvYE51kvtdW447SK7HZywJnkyw2RNm+29dvWJJwSQckUHuZkXEtmEPk0ePL3yf2NH5XYJc ++ pXX6Zac0KemCPIHr8l7GogE4Rb2BBTqddkegb9piz6QTAPcQnn+GuMFG06IBhUrgcMEQ8x ++ UOXYUUrT5HvSxWUcgaYH1nfC3bTWmDaodw8/HQKyF6c44rujO2s2NLFOCAyQMUNdhh3lfD ++ yHYLO7xYkP6xzzkpk+2lwBoeYdQdAwlKN/XqC8ZhBfwTdem/1hh1BpQJFbbFftWxU8gxxi ++ iuI+vmlsuIsxKoGCq8YXuophx62lo= ++ -----END OPENSSH PRIVATE KEY----- +-- +2.25.1 diff --git a/cert_support.tar.gz b/cert_support.tar.gz new file mode 100644 index 0000000..9df7ad3 --- /dev/null +++ b/cert_support.tar.gz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:12795b0b9f5ec2fd1c4458564823df4c089018e56e9c3f911d7a1eff6652993c +size 4970 diff --git a/disable-gssapi.patch b/disable-gssapi.patch new file mode 100644 index 0000000..a0a4c8b --- /dev/null +++ b/disable-gssapi.patch @@ -0,0 +1,13 @@ +Index: paramiko-2.4.2/paramiko/ssh_gss.py +=================================================================== +--- paramiko-2.4.2.orig/paramiko/ssh_gss.py ++++ paramiko-2.4.2/paramiko/ssh_gss.py +@@ -53,7 +53,7 @@ try: + import gssapi + + GSS_EXCEPTIONS = (gssapi.GSSException,) +-except (ImportError, OSError): ++except (ImportError, OSError, AttributeError): + try: + import pywintypes + import sspicon diff --git a/paramiko-2.4.3.tar.gz b/paramiko-2.4.3.tar.gz new file mode 100644 index 0000000..28c7bed --- /dev/null +++ b/paramiko-2.4.3.tar.gz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f56f723ab4148b6797de1280fe7017aad5423eee17a6a85d21cc917cb8741818 +size 290310 diff --git a/paramiko-fix-1169489.patch b/paramiko-fix-1169489.patch new file mode 100644 index 0000000..e02407d --- /dev/null +++ b/paramiko-fix-1169489.patch @@ -0,0 +1,21 @@ +commit 8d57be27ddeda68cbc0f97ee857871aadb5c5170 +Author: Jared Hobbs +Date: Wed Mar 20 10:08:12 2019 -0600 + + handle exception that can occur if no regex match + +diff --git a/paramiko/pkey.py b/paramiko/pkey.py +index f2447e15..0464795a 100644 +--- a/paramiko/pkey.py ++++ b/paramiko/pkey.py +@@ -307,8 +307,8 @@ class PKey(object): + start += 1 + m = self.BEGIN_TAG.match(lines[start]) + start += 1 +- keytype = m.group(1) +- if start >= len(lines): ++ keytype = m.group(1) if m else None ++ if start >= len(lines) or keytype is None: + raise SSHException("not a valid " + tag + " private key file") + + # find the END tag diff --git a/paramiko-test_extend_timeout.patch b/paramiko-test_extend_timeout.patch new file mode 100644 index 0000000..9b7d0ac --- /dev/null +++ b/paramiko-test_extend_timeout.patch @@ -0,0 +1,11 @@ +--- paramiko-2.4.3.orig/tests/test_buffered_pipe.py 2019-06-24 00:45:29.000000000 +0200 ++++ paramiko-2.4.3/tests/test_buffered_pipe.py 2022-09-02 15:38:37.067697674 +0200 +@@ -68,7 +68,7 @@ + self.assertTrue(False) + except PipeTimeout: + pass +- self.assertEqual(b"b", p.read(1, 1.0)) ++ self.assertEqual(b"b", p.read(1, 3.0)) + self.assertEqual(b"", p.read(1)) + + def test_close_while_reading(self): diff --git a/rsa-key-loading-fix.patch b/rsa-key-loading-fix.patch new file mode 100644 index 0000000..2c28b56 --- /dev/null +++ b/rsa-key-loading-fix.patch @@ -0,0 +1,23 @@ +From 81064206bf3cec2ca4372257ff138481e1227b91 Mon Sep 17 00:00:00 2001 +From: Alex Gaynor +Date: Sat, 18 Jul 2020 14:18:07 -0400 +Subject: [PATCH] fix RSA key loading: p and q were being swapped + +This currently works, because OpenSSL simply re-computes iqmp when it doesn't match the p & q values. However a future pyca/cryptography patch enforces this. +--- + paramiko/rsakey.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +Index: paramiko-2.4.3/paramiko/rsakey.py +=================================================================== +--- paramiko-2.4.3.orig/paramiko/rsakey.py ++++ paramiko-2.4.3/paramiko/rsakey.py +@@ -189,7 +189,7 @@ class RSAKey(PKey): + except ValueError as e: + raise SSHException(str(e)) + elif pkformat == self.PRIVATE_KEY_FORMAT_OPENSSH: +- n, e, d, iqmp, q, p = self._uint32_cstruct_unpack(data, 'iiiiii') ++ n, e, d, iqmp, p, q = self._uint32_cstruct_unpack(data, 'iiiiii') + public_numbers = rsa.RSAPublicNumbers( + e=e, + n=n, diff --git a/saltbundlepy-paramiko.changes b/saltbundlepy-paramiko.changes new file mode 100644 index 0000000..c370d7d --- /dev/null +++ b/saltbundlepy-paramiko.changes @@ -0,0 +1,711 @@ +------------------------------------------------------------------- +Wed Mar 29 10:50:40 UTC 2023 - Pablo Suárez Hernández + +- Add rsa-key-loading-fix.patch (bsc#1205132) fixing loading RSA + key. + +- update to 2.4.3 + * Fix Ed25519 key handling so certain key comment lengths don't cause + SSHException("Invalid key") (bsc#1200603) + * Add support for the modern (as of Python 3.3) import location of + MutableMapping (used in host key management) to avoid the old location + becoming deprecated in Python 3.8. + * refresh add-support-for-new-OpenSSH-private-key-format.patch + * refresh paramiko-test_extend_timeout.patch + * refresh support-cryptography-25-and-above.patch + +- Add CVE-2022-24302-race-condition.patch: + * Fix a race condition between creation and chmod when writing private + keys. (bsc#1197279) + +- Removed: + * Use-args-not-kwargs-to-retain-py2-compat-for-now.patch + * Fix-CVE-re-PKey.write_private_key-chmod-race.patch + * use-MutableMapping-from-collections.abc.patch + +------------------------------------------------------------------- +Mon Apr 4 11:43:53 UTC 2022 - Victor Zhestkov + +- Strictly require Python 3.10 with saltbundlepy requrement +- Fix using deprecated and removed class from collections + +- Added: + * use-MutableMapping-from-collections.abc.patch + +------------------------------------------------------------------- +Thu Mar 31 08:49:54 UTC 2022 - Victor Zhestkov + +- Add patches to ensure that we create new key files directly + with a user-only mode, instead of opening, writing, then chmodding. + (bsc#1197279) (CVE-2022-24302) + +- Added: + * Fix-CVE-re-PKey.write_private_key-chmod-race.patch + * Use-args-not-kwargs-to-retain-py2-compat-for-now.patch + +------------------------------------------------------------------- +Thu Apr 12 05:33:09 UTC 2021 - Steve Kowalik + +- Add support-cryptography-25-and-above.patch: + * Since SLE15 SP1 and above have cryptography 2.8, stop using deprecated + methods, and update the required version. (bsc#1178341) + +------------------------------------------------------------------- +Wed Apr 22 15:58:55 UTC 2020 - Marcus Meissner + +- paramiko-fix-1169489.patch: fixed fallout from last patch (bsc#1169489) + +------------------------------------------------------------------- +Tue Mar 24 10:29:55 UTC 2020 - Ali Abdallah + +- add-support-for-new-OpenSSH-private-key-format.patch: + Add support for new OpenSSH >= 7.8p1 private key format (bsc#1166758) + +------------------------------------------------------------------- +Tue Nov 13 11:47:43 UTC 2018 - Ondřej Súkup + +- add disable-gssapi.patch - workaround for boo#1115769 + +------------------------------------------------------------------- +Fri Oct 5 08:26:46 UTC 2018 - Ondřej Súkup + +- update to 2.4.2 +- refresh paramiko-test_extend_timeout.patch + * Fix exploit (CVE pending) in Paramiko's server mode (not client mode) + where hostile clients could trick the server into thinking they were + authenticated without actually submitting valid authentication. + * Modify protocol message handling such that Transport does not respond + to MSG_UNIMPLEMENTED with its own MSG_UNIMPLEMENTED + * Updated SSHConfig.lookup so it returns + a new, type-casting-friendly dict subclass (~paramiko.config.SSHConfigDict) + in lieu of dict literals. + +------------------------------------------------------------------- +Thu Mar 15 18:38:22 CET 2018 - ro@suse.de + +- add paramiko-test_extend_timeout.patch (bsc#1085529) + extend timeout in testsuite to pass on ppc64le + +------------------------------------------------------------------- +Thu Mar 15 07:10:09 UTC 2018 - tbechtold@suse.com + +update to version 2.4.1 (bsc#1085276, CVE-2018-7750): + * changelog: update for #1039 / #1051 + * Screen off dev version of Python from test matrix + * ensure ed25519 password is bytes + * Cut 2.0.8 + * Cut 2.3.2 + * Initial tests proving CVE-2018-7750 / #1175 + * Guess something else added this prior to the merge + * Fixes CVE-2018-7750 / #1175 + * Uncaught typo in test suite + * Initial tests proving CVE-2018-7750 / #XXX + * Test proving #1039 / efficacy of #1051 + * Changelog closes #1175 + * Cut 2.1.5 + * Allow overriding test client connect kwargs in Transport test suite + * Cut 2.4.1 + * Fixes CVE-2018-7750 / #XXX + * Cut 2.2.3 + * flake8 + +------------------------------------------------------------------- +Thu Nov 16 09:36:24 UTC 2017 - mimi.vx@gmail.com + +- update to 2.4.0 + + new pytest based testsuite + * dd a new passphrase kwarg to SSHClient.connect so users may disambiguate + key-decryption passphrases from password-auth passwords. + * Drop Python 2.6 and Python 3.3 support + +------------------------------------------------------------------- +Thu Oct 5 11:12:50 UTC 2017 - mimi.vx@gmail.com + +- update to 2.3.1 + + cert_support.tar.gz - missing test certificates for testsuite + * Certificate support broke the no-certificate case for Ed25519 keys + (symptom is an AttributeError about public_blob.) This went uncaught + due to cert autoload behavior (i.e. our test suite never actually ran + the no-cert case, because the cert existed!) Both issues have been fixed. + * Implement basic client-side certificate authentication + (as per the OpenSSH vendor extension.) + * Added pre-authentication banner support for the server interface + (ServerInterface.get_banner plus related support in Transport/AuthHandler.) + * Update Ed25519Key so its constructor offers the same file_obj parameter + as its sibling key classes. + * Add a gss_trust_dns option to Client and Transport to allow explicitly + setting whether or not DNS canonicalization should occur when using GSSAPI. + * Paramiko originally defaulted to zlib compression level 9 + (when one connects with compression=True; it defaults to off.) This has been + found to be quite wasteful and tends to cause much longer transfers in most + cases, than is necessar + * Enhance documentation around the new SFTP.posix_rename method + so it’s referenced in the ‘standard’ rename method for increased visibility. + * Modify logic around explicit disconnect messages, and unknown-channel situations, + so that they rely on centralized shutdown code instead of running their own. + This is at worst removing some unnecessary code, and may help with some + situations where Paramiko hangs at the end of a session. + * Display exception type and message when logging auth-rejection messages + (ones reading Auth rejected: unsupported or mangled public key); previously + this error case had a bare except and did not display exactly why the key + failed. + * Ed25519 keys never got proper API documentation support; this has been fixed. + * Update how we use Cryptography‘s signature/verification methods + so we aren’t relying on a deprecated API. + +------------------------------------------------------------------- +Thu Oct 5 10:33:48 UTC 2017 - mimi.vx@gmail.com + +- update to 2.2.2: + * SSHClient now requests the type of host key it has (e.g. from known_hosts) + and does not consider a different type to be a “Missing” host key. + This fixes a common case where an ECDSA key is in known_hosts and the server + also has an RSA host key. + * Fix up host-key checking in our GSSAPI support, which was previously + using an incorrect API call + * Fix key exchange (kex) algorithm list for GSSAPI authentication; + reviously, the list used solely out-of-date algorithms, and now contains + newer ones listed preferentially before the old + * Clean up GSSAPI authentication procedures so they do not prevent normal + fallback to other authentication methods on failure. + * Add rekeying support to GSSAPI connections, which was erroneously missing. + +------------------------------------------------------------------- +Thu Aug 10 08:11:25 UTC 2017 - tbechtold@suse.com + +- update to 2.2.1: + * Missed a spot + * Update .travis.yml + * Whitespace + * Having this in a mini-toctree made the nav look funny and is also just unintuitive + * Changelog re #471, re #65 + * these are bytes + * changelog: update for #990 and #993 + * ecdh kex support + * flake8/whitespace + * Trailing comma + * Add test for posix-rename@openssh.com extension for SFTP client + * Changelog re #921 + * Add a note about new Python-level deps to changelog re: Ed25519 support + * Add method for "posix-rename@openssh.com" extension for SFTP client. + * Add IOError in posix-rename@openssh.com test for python 2 support. + * this isnt bytes + * Added a auth_timeout to handle situations where SSH server stops responding during auth. + * small cleanups + * More changelog flimflammery + * Added changelog entry + * python 3 compatibility + * Incorrect comparison, should be <= + * DDD re #857 + * Improve __hash__ functions + * Hrm that should always have been an h1 + * No idea how this got past all the earlier flake8 work... + * comments + * Fixed test to support python 2.6 + * Note ecdh-sha2 preferred-kex placement in changelog entry for #951, re #983 + * Changelog language tweaks + * Reorder cipher and key preferences to make more sense + * Added a test to check that the auth_timeout argument is passed through and applied. + * Changelog tweak + * Cut 2.2.1 + * transport: change order of preferred kex and hmac algorithms + * need bcrypt >= 3.1.3 for kdf() ignore_few_rounds kwarg + * Changelog re #972, re #325, closes #325 + * cleanup/simplify auth_timeout tests + * Missed a merge conflict lolol + * flake8 + * Changelog re #951 + * Perplexed at why flake8 did not report this earlier + * Add Python 3.6 to classifiers + * Add support for posix-rename@openssh.com for the SFTP server side and fix tests accordingly. + * sphinx nitpick fixes + * Fixed encoding/decoding of the public key on the wire + * Added test for authentication timeout from a non-responsive server + * refactor files + * fixed comment + consistency + * Changelog re #857 + * Cut 2.2.0 + * integration test, with ourselves + * TODO + * That was easy. Closes #857 + * Add sanity note to changelog re #869 + * Unit tests + * Fixes #325 -- add support for Ed25519 keys + * Happy New Year + * implement __hash__() method for Ed25519Key + * pep8 + * Increased auth_timeout to 30 seconds + * py3k + * fixed long line + * Link to the spec + * set a minimum version + * Support decrypting keys + * Failing test proving need for #857 +- move demos/ to extra -doc package + +------------------------------------------------------------------- +Sun Jun 11 16:32:09 UTC 2017 - mimi.vx@gmail.com + +- update to 2.1.3 +* Make util.log_to_file append instead of replace. +* SSHClient and Transport could cause a memory leak if there’s a connection + problem or protocol error, even if Transport.close() is called. +* Prior support for ecdsa-sha2-nistp(384|521) algorithms didn’t fully extend + to covering host keys, preventing connection to hosts which only offer + these key types and no others. This is now fixed. +* Prefer newer ecdsa-sha2-nistp keys over RSA and DSA keys during host key + selection. This improves compatibility with OpenSSH, both in terms of general + behavior, and also re: ability to properly leverage OpenSSH-modified + known_hosts files. +* The RC4/arcfour family of ciphers has been broken since version 2.0; but since + the algorithm is now known to be completely insecure, we are opting + to remove support outright instead of fixing it. +* Move sha1 above the now-arguably-broken md5 in the list of preferred MAC + algorithms, as an incremental security improvement for users whose target + systems offer both. +* Writing encrypted/password-protected private key files was silently broken + since 2.0 due to an incorrect API call + Includes a directly related fix, namely adding the ability to read AES-256-CBC + ciphered private keys (which is now what we tend to write out as it is + Cryptography’s default private key cipher.) +* Allow any type implementing the buffer API to be used with BufferedFile, + Channel, and SFTPFile. This resolves a regression introduced in 1.13 + with the Python 3 porting changes, when using types such as memoryview. +* Enhance default cipher preference order such that aes(192|256)-cbc are preferred + over blowfish-cbc. +* SSHClient now requests the type of host key it has (e.g. from known_hosts) + and does not consider a different type to be a “Missing” host key. This fixes + a common case where an ECDSA key is in known_hosts and the server also has + an RSA host key. +* Overhaul the codebase to be PEP-8 + +------------------------------------------------------------------- +Wed Apr 19 17:24:58 UTC 2017 - toddrme2178@gmail.com + +- Implement single-spec version. + +------------------------------------------------------------------- +Fri Mar 17 20:25:35 UTC 2017 - rjschwei@suse.com + +- Fix version setting for cryptography for build + +------------------------------------------------------------------- +Thu Mar 16 22:23:45 UTC 2017 - rjschwei@suse.com + +- Add python-pyasn1 as Buildrequires for testing + +------------------------------------------------------------------- +Fri Feb 24 16:27:00 UTC 2017 - mimi.vx@gmail.com + +- update to 2.1.2 +* Fix a bug in server-mode concerning multiple interactive auth steps +* SSHClient now gives its internal Transport a handle on itself, preventing + garbage collection of the client until the session is closed. Without this, + some code which returns stream or transport objects without the client that + generated them, would result in premature session closure + when the client was GCd +* Avoid test suite exceptions on platforms lacking errno.ETIME +* weak how RSAKey.__str__ behaves so it doesn’t cause TypeError under Python 3. + +------------------------------------------------------------------- +Tue Dec 13 11:50:39 UTC 2016 - mimi.vx@gmail.com + +- update to 2.1.1 +* A tweak to the original patch implementing gh#398 was not fully applied, + causing calls to ~paramiko.client.SSHClient.invoke_shell to fail with + AttributeError. This has been fixed. +* Fix the implementation of PKey.write_private_key_file (this method is only + publicly defined on subclasses; the fix was in the private real + implementation) so it passes the correct params to open() +* Add an optional timeout parameter to Transport.start_clienti + (and feed it the value of the + configured connection timeout when used within SSHClient + .) +* Catch AssertionError thrown by Cryptography when attempting to load bad + ECDSA keys, turning it into an SSHException. +* Add a missing .closed attribute (plus ._closed because reasons) to + ProxyCommand +* Make the subprocess import in proxy.py lazy so users on platforms without + it (such as Google App Engine) can import Paramiko successfully +* Fix incorrect docstring/param-list for Transport.auth_gssapi_keyex + so it matches + the real signature. +* Add an environment dict argument to Client.exec_command + +------------------------------------------------------------------- +Fri Oct 7 09:13:06 UTC 2016 - tbechtold@suse.com + +- Fix Requires for python-cryptography +- Add missing Requires for python-pyasn1 + +------------------------------------------------------------------- +Sun Jul 31 12:15:25 UTC 2016 - michael@stroeder.com + +- update to 2.0.2 + * [Bug] #758: Apply type definitions to _winapi module from + jaraco.windows 3.6.1. This should address issues on Windows platforms + that often result in errors like ArgumentError: [...] int too long to + convert. Thanks to @swohlerLL for the report and Jason R. Coombs for the + patch. + * [Bug] #774: Add a _closed private attribute to Channel objects so that + they continue functioning when used as proxy sockets under Python 3 (e.g. + as direct-tcpip gateways for other Paramiko connections.) + * [Bug] #673: (via #681) Fix protocol banner read errors (SSHException) + which would occasionally pop up when using ProxyCommand gatewaying. + Thanks to @Depado for the initial report and Paul Kapp for the fix. + +------------------------------------------------------------------- +Sat Jul 23 14:20:34 UTC 2016 - michael@stroeder.com + +- updated homepage URL +- update to 2.0.1: + * [Bug] #537: Fix a bug in BufferedPipe.set_event which could cause + deadlocks/hangs when one uses select.select against Channel objects (or + otherwise calls Channel.fileno after the channel has closed). + * [Bug] #520: (Partial fix) Fix at least one instance of race condition + driven threading hangs at end of the Python interpreter session. + (Includes a docs update as well - always make sure to .close() your + clients!) + +------------------------------------------------------------------- +Fri Jul 8 08:50:08 UTC 2016 - dmueller@suse.com + +- fix build + +------------------------------------------------------------------- +Mon Jun 6 11:32:04 UTC 2016 - dmueller@suse.com + +- fix source url + +------------------------------------------------------------------- +Sun May 8 21:11:31 UTC 2016 - hpj@urpla.net + +- update to 2.0.0: + * Add support for 384- and 512-bit elliptic curve groups in ECDSA + key types (aka ecdsa-sha2-nistp384 / ecdsa-sha2-nistp521). + * Due to an earlier bugfix, less-specific Host blocks' ProxyCommand + values were overriding ProxyCommand none in more-specific Host + blocks. This has been fixed in a backwards compatible manner (i.e. + ProxyCommand none continues to appear as a total lack of any + proxycommand key in parsed config structures). + * Fix a backwards incompatibility issue that cropped up in + SFTPFile.prefetch <~paramiko.sftp_file.prefetch> re: the + erroneously non-optional file_size parameter. Should only affect + users who manually call prefetch. + * Replace PyCrypto with the Python Cryptographic Authority (PyCA) + 'Cryptography' library suite. This improves security, + installability, and performance; adds PyPy support; and much more. + * Fix stalled/hung SFTP downloads by cleaning up some threading lock + issues. + * Fix a Python 3 compatibility issue when handling two-factor + authentication. + * Clean up setup.py to always use setuptools, not doing so was a + historical artifact from bygone days. + * Update the module in charge of handling SSH moduli so it's + consistent with OpenSSH behavior re: prime number selection. + * Fix up ~paramiko.ssh_exception.NoValidConnectionsError so it + pickles correctly, and fix a related Python 3 compatibility issue. + * Update to jaraco.windows 3.4.1 to fix some errors related to + ctypes on Windows platforms. + * Annotate some public attributes on ~paramiko.channel.Channel such + as .closed. + * Fix logic bug in the SFTP client's callback-calling functionality; + previously there was a chance the given callback would fire twice + at the end of a transfer. + * Identify & work around a race condition in the test for handshake + timeouts, which was causing frequent test failures for a subset of + contributors as well as Travis-CI (usually, but not always, + limited to Python 3.5). + * Remove whitespace in our setup.py's install_requires as it + triggers occasional bugs in some versions of setuptools. + * Strip trailing/leading whitespace from lines when parsing SSH + config files - this brings things in line with OpenSSH behavior. + * Fix behavior of gssapi-with-mic auth requests so they fail + gracefully (allowing followup via other auth methods) instead of + raising an exception. + * Add missing file-like object methods for ~paramiko.file.BufferedFile + and ~paramiko.sftp_file.SFTPFile. + * Clean up and enhance the README (and rename it to README.rst from + just README). + +------------------------------------------------------------------- +Mon Feb 1 11:26:44 UTC 2016 - toddrme2178@gmail.com + +- Add --no-transport to fix a known issue with the tests + https://github.com/paramiko/paramiko/issues/574 + Check if still failing on next release. + The tests is currently failing on Python 3.5, but it is not + actually Python 3.5 specific, it is just more likely to be + encountered on Python 3.5 +- update to version 1.16.0: + * Streamline use of stat when downloading SFTP files via + SFTPClient.get ; this avoids + triggering bugs in some off-spec SFTP servers such as IBM + Sterling. Thanks to @muraleee for the initial report and to Torkil + Gustavsen for the patch. + * Fully enable two-factor authentication (e.g. when a server + requires AuthenticationMethods + pubkey,keyboard-interactive). Thanks to @perryjrandall for the + patch and to @nevins-b and Matt Robenolt for additional support. + * Fix 'exec' requests in server mode to use get_string instead of + get_text to avoid UnicodeDecodeError on non-UTF-8 input. Thanks to + Anselm Kruis for the patch & discussion. + * Fix line number reporting in log output regarding invalid + known_hosts line entries. Thanks to Dylan Thacker-Smith for catch + & patch. + * Update the vendored Windows API addon to a more recent + edition. Also fixes :issue:`193`, :issue:`488`, + :issue:`498`. Thanks to Jason Coombs. + +------------------------------------------------------------------- +Thu Feb 26 11:00:52 UTC 2015 - tbechtold@suse.com + +- update to version 1.15.2 (bsc#962291) + * [Bug] #320: Update our win_pageant module to be Python 3 compatible + * [Bug] #429: Server-level debug message logging was overlooked during the + Python 3 compatibility update; Python 3 clients attempting to log SSH + debug packets encountered type errors. This is now fixed + * [Bug] #459: Tighten up agent connection closure behavior to avoid + spurious ResourceWarning display in some situations + * [Bug] #266: Change numbering of Transport channels to start at 0 + instead of 1 for better compatibility with OpenSSH & certain server + implementations which break on 1-indexed channels + * [Support] #419: Modernize a bunch of the codebase internals to + leverage decorators. Props to @beckjake for realizing we’re no longer + on Python 2.2 :D + * [Support] #421: Modernize threading calls to user newer API + * [Support] #422: Clean up some unused imports + * [Support] #431: Replace handrolled ssh_config parsing code with + use of the shlex module + * [Bug] #415: Fix ssh_config parsing to correctly interpret ProxyCommand + none as the lack of a proxy command, instead of as a literal command + string of "none" + * [Bug] #428: Fix an issue in BufferedFile (primarily used in the SFTP + modules) concerning incorrect behavior by readlines on files whose + size exceeds the buffer size + * [Bug] #455: Tweak packet size handling to conform better to the + OpenSSH RFCs; this helps address issues with interactive program cursors + * [Bug] #413: (also #414, #420, #454) Be significantly smarter about polling + & timing behavior when running proxy commands, to avoid unnecessary + (often 100%!) CPU usage + +------------------------------------------------------------------- +Thu Oct 2 16:33:24 UTC 2014 - andrea@opensuse.org + +- new upsteam version 1.15.1 + * fixed from previous version: Bug] #399: SSH agent forwarding + would hang due to incorrect values passed into the new window + size arguments for Transport + * detailed changelog available on pramiko website: + http://paramiko-www.readthedocs.org/en/latest/changelog.html + +------------------------------------------------------------------- +Sat May 31 11:35:11 UTC 2014 - dmueller@suse.com + +- update to 1.13.1: +* :support:`256 backported` Convert API documentation to Sphinx, yielding a new + API docs website to replace the old Epydoc one. +* :bug:`-` Use constant-time hash comparison operations where possible, to + protect against `timing-based attacks + `_. Thanks to Alex Gaynor + for the patch. +* :feature:`58` Allow client code to access the stored SSH server banner via + `Transport.get_banner `. Thanks to + ``@Jhoanor`` for the patch. +* :bug:`252` (`Fabric #1020 `_) + Enhanced the implementation of ``ProxyCommand`` to avoid a deadlock/hang + condition that frequently occurs at ``Transport`` shutdown time. Thanks to + Mateusz Kobos, Matthijs van der Vleuten and Guillaume Zitta for the original + reports and to Marius Gedminas for helping test nontrivial use cases. +* :bug:`268` Fix some missed renames of ``ProxyCommand`` related error classes. + Thanks to Marius Gedminas for catch & patch. +* :bug:`34` (PR :issue:`35`) Fix SFTP prefetching incompatibility with some + SFTP servers regarding request/response ordering. Thanks to Richard + Kettlewell. +* :bug:`193` (and its attentant PRs :issue:`230` & :issue:`253`) Fix SSH agent + problems present on Windows. Thanks to David Hobbs for initial report and to + Aarni Koskela & Olle Lundberg for the patches. +* :bug:`225 (1.12+)` Note ecdsa requirement in README. Thanks to Amaury + Rodriguez for the catch. +* :bug:`176` Fix AttributeError bugs in known_hosts file (re)loading. Thanks + to Nathan Scowcroft for the patch & Martin Blumenstingl for the initial test + case. + +------------------------------------------------------------------- +Fri Apr 18 15:10:24 UTC 2014 - rschweikert@suse.com + +- include in SLE 12 (FATE #315990) + +------------------------------------------------------------------- +Mon Nov 25 23:01:56 UTC 2013 - p.drouand@gmail.com + +- Update to version 1.12 + * #152: Add tentative support for ECDSA keys. *This adds the ecdsa + module as a new dependency of Paramiko.* The module is available at + [warner/python-ecdsa on Github](https://github.com/warner/python-ecdsa) and + [ecdsa on PyPI](https://pypi.python.org/pypi/ecdsa). + * Note that you might still run into problems with key negotiation -- + Paramiko picks the first key that the server offers, which might not be + what you have in your known_hosts file. + * Mega thanks to Ethan Glasser-Camp for the patch. + * #136: Add server-side support for the SSH protocol's 'env' command +- Use local source instead of service +- Add python-ecdsa requirement; new dependency + +------------------------------------------------------------------- +Sun Oct 27 17:50:34 UTC 2013 - lukas@wunner.de + +- update to 1.11.2: + * #156: Fix potential deadlock condition when using Channel objects as + sockets (e.g. when using SSH gatewaying). Thanks to Steven Noonan and + Frank Arnold for catch & patch. + * #179: Fix a missing variable causing errors when an ssh_config file + has a non-default AddressFamily set. Thanks to Ed Marshall & Tomaz + Muraus for catch & patch. + * #200: Fix an exception-causing typo in `demo_simple.py`. Thanks to + Alex Buchanan for catch & Dave Foster for patch. + * #199: Typo fix in the license header cross-project. Thanks to Armin + Ronacher for catch & patch. + * #162: Clean up HMAC module import to avoid deadlocks in certain uses + of SSHClient. Thanks to Gernot Hillier for the catch & suggested fix. + * #36: Fix the port-forwarding demo to avoid file descriptor errors. + Thanks to Jonathan Halcrow for catch & patch. + * #168: Update config handling to properly handle multiple 'localforward' + and 'remoteforward' keys. Thanks to Emre Yilmaz for the patch. + +------------------------------------------------------------------- +Tue Sep 3 08:06:53 UTC 2013 - dmueller@suse.com + +- update to 1.11.0: + * #98: On Windows, when interacting with the PuTTY PAgeant, Paramiko now + creates the shared memory map with explicit Security Attributes of the user, + which is the same technique employed by the canonical PuTTY library to avoid + permissions issues when Paramiko is running under a different UAC context + than the PuTTY Ageant process. Thanks to Jason R. Coombs for the patch. + * #100: Remove use of PyWin32 in `win_pageant` module. Module was already + dependent on ctypes for constructing appropriate structures and had ctypes + implementations of all functionality. Thanks to Jason R. Coombs for the + patch. + * #87: Ensure updates to `known_hosts` files account for any updates to said + files after Paramiko initially read them. (Includes related fix to guard + against duplicate entries during subsequent `known_hosts` loads.) Thanks to + `@sunweaver` for the contribution. + +------------------------------------------------------------------- +Mon Apr 29 12:52:27 UTC 2013 - dmueller@suse.com + +- update to 1.10.1: + * SFTP put of empty file will still return the attributes + of the put file. Thanks to Jason R. Coombs for the patch. + * Forwarded SSH agent connections left stale local pipes + lying around, which could cause local (and sometimes remote or network + resource starvation when running many agent-using remote commands. Thanks to + * Batch SFTP writes to help speed up file transfers + * Fix handling of window-change events to be on-spec + * Overhaul SSH config parsing to be in line with `man ssh_config` + * Forego random padding for packets when running under `*-ctr` ciphers + * Add `SFTPClient.putfo` and `.getfo` methods to allow direct + uploading/downloading of file-like objects + * Add `timeout` parameter to `SSHClient.exec_command` for easier setting + of the command's internal channel object's timeout + * Expose the internal "is closed" property of the file transfer class + BufferedFile` as `.closed`, better conforming to Python's file interface + +------------------------------------------------------------------- +Sat Dec 1 15:12:44 UTC 2012 - saschpe@suse.de + +- Update to version 1.9.0: + + #97 (with a little #93): Improve config parsing of ProxyCommand directives + and provide a wrapper class to allow subprocess-driven proxy commands to be + used as sock= arguments for SSHClient.connect. + + #77: Allow SSHClient.connect() to take an explicit sock parameter + overriding creation of an internal, implicit socket object. +- Changes from version 1.8.1: + + #90: Ensure that callbacks handed to SFTPClient.get() always fire at least + once, even for zero-length files downloaded. Thanks to Github user @enB for + the catch. + + #85: Paramiko's test suite overrides + unittest.TestCase.assertTrue/assertFalse to provide these modern assertions + to Python 2.2/2.3, which lacked them. However on newer Pythons such as 2.7, + this now causes deprecation warnings. The overrides have been patched to only + execute when necessary. Thanks to @Arfrever for catch & patch. +- Changes from version 1.8.0: + + #17 ('ssh' 28): Fix spurious NoneType has no attribute 'error' and similar + exceptions that crop up on interpreter exit. + + 'ssh' 32: Raise a more useful error explaining which known_hosts key line was + problematic, when encountering binascii issues decoding known host keys. + Thanks to @thomasvs for catch & patch. + + 'ssh' 33: Bring ssh_config parsing more in line with OpenSSH spec, re: order of + setting overrides by Host specifiers. Specifically, the overrides now go by + file order instead of automatically sorting by Host value length. In + addition, the first value found per config key (e.g. Port, User etc) + wins, instead of the last. Thanks to Jan Brauer for the contribution. + + 'ssh' 36: Support new server two-factor authentication option + (RequiredAuthentications2), at least re: combining key-based & password + auth. Thanks to Github user bninja. + + 'ssh' 11: When raising an exception for hosts not listed in + known_hosts (when RejectPolicy is in effect) the exception message was + confusing/vague. This has been improved somewhat. Thanks to Cal Leeming for + highlighting the issue. + + 'ssh' 40: Fixed up & expanded EINTR signal handling. Thanks to Douglas Turk. + + 'ssh' 15: Implemented parameter substitution in SSHConfig, matching the + implementation of ssh_config(5). Thanks to Olle Lundberg for the patch. + + 'ssh' 24: Switch some internal type checking to use isinstance to help prevent + problems with client libraries using subclasses of builtin types. Thanks to + Alex Morega for the patch. + + Fabric #562: Agent forwarding would error out (with Authentication response + too long) or freeze, when more than one remote connection to the local agent + was active at the same time. This has been fixed. Thanks to Steven McDonald + for assisting in troubleshooting/patching, and to GitHub user @lynxis for + providing the final version of the patch. + + 'ssh' 5: Moved a fcntl import closer to where it's used to help avoid + ImportError problems on Windows platforms. Thanks to Jason Coombs for the + catch + suggested fix. + + 'ssh' 4: Updated implementation of WinPageant integration to work on 64-bit + Windows. Thanks again to Jason Coombs for the patch. + + Added an IO loop sleep() call to avoid needless CPU usage when agent + forwarding is in use. + + Handful of internal tweaks to version number storage. + + Updated setup.py with ==dev install URL for pip users. + + Updated setup.py to account for packaging problems in PyCrypto 2.4.0 + + Added an extra atfork() call to help prevent spurious RNG errors when + running under high parallel (multiprocess) load. + + Merge PR #28: https://github.com/paramiko/paramiko/pull/28 which adds a + ssh-keygen like demo module. (Sofian Brabez) + +------------------------------------------------------------------- +Sun Jun 24 20:04:03 UTC 2012 - os-dev@jacraig.com + +- Update to 1.7.7.2: + * Merge pull request #63: https://github.com/paramiko/paramiko/pull/63 which + fixes exceptions that occur when re-keying over fast connections. +- Add unit tests to build + +------------------------------------------------------------------- +Mon Mar 12 21:05:53 UTC 2012 - saschpe@gmx.de + +- Simplified macro usage + +------------------------------------------------------------------- +Tue Sep 20 14:30:25 UTC 2011 - saschpe@suse.de + +- Update to version 0.7.7: + * Various bug fixes (upstream provides no further changes) + +------------------------------------------------------------------- +Tue Oct 5 08:20:00 UTC 2010 - nix@opensuse.org + +- Require newer python-crypto + +------------------------------------------------------------------- +Thu Sep 16 07:58:41 UTC 2010 - coolo@novell.com + +- updte to 1.7.6 "Fanny" + various bug fixes, "Ernest" brought ARC4 & CTR support and IP6 support + +------------------------------------------------------------------- +Wed Sep 24 11:44:21 CEST 2008 - kssingvo@suse.de + +- initial version 1.7.4 required from bzr + based on python-paramiko from openSUSE BuildService: + devel:languages:python/openSUSE_Factory diff --git a/saltbundlepy-paramiko.spec b/saltbundlepy-paramiko.spec new file mode 100644 index 0000000..4a5267d --- /dev/null +++ b/saltbundlepy-paramiko.spec @@ -0,0 +1,117 @@ +# +# spec file for package saltbundlepy-paramiko +# +# Copyright (c) 2023 SUSE LLC +# +# All modifications and additions to the file contributed by third parties +# remain the property of their copyright owners, unless otherwise agreed +# upon. The license for this file, and modifications and additions to the +# file, is the same license as for the pristine package itself (unless the +# license for the pristine package is not an Open Source License, in which +# case the license is the MIT License). An "Open Source License" is a +# license that conforms to the Open Source Definition (Version 1.9) +# published by the Open Source Initiative. + +# Please submit bugfixes or comments via https://bugs.opensuse.org/ +# + + +%{?!saltbundlepy_module:%define saltbundlepy_module() saltbundlepy-%{**}} +%define pythons saltbundlepy + +# Disable python bytecompile for all distros +# It's called explicitly in the spec +%global __brp_python_bytecompile %{nil} + +%bcond_with test + +Name: saltbundlepy-paramiko +Version: 2.4.3 +Release: 0 +Summary: SSH2 protocol library +License: LGPL-2.1-or-later +Group: Development/Languages/Python +URL: https://www.paramiko.org/ +Source: https://files.pythonhosted.org/packages/source/p/paramiko/paramiko-%{version}.tar.gz +# certificates needed by testsuite +Source1: cert_support.tar.gz +Patch0: paramiko-test_extend_timeout.patch +Patch1: disable-gssapi.patch +Patch2: add-support-for-new-OpenSSH-private-key-format.patch +Patch3: paramiko-fix-1169489.patch +Patch4: support-cryptography-25-and-above.patch +Patch5: CVE-2022-24302-race-condition.patch +# PATCH-FIX-UPSTREAM rsa-key-loading-fix.patch bsc#1205132 mcepl@suse.com +# p and q were being swapped +Patch6: rsa-key-loading-fix.patch + +BuildRequires: %{saltbundlepy_module base >= 3.10} +BuildRequires: %{saltbundlepy_module bcrypt >= 3.1.3} +BuildRequires: %{saltbundlepy_module cryptography >= 2.5} +BuildRequires: %{saltbundlepy_module pyasn1 >= 0.1.7} +BuildRequires: %{saltbundlepy_module pynacl >= 1.0.1} +BuildRequires: %{saltbundlepy_module setuptools} +BuildRequires: fdupes +BuildRequires: saltbundlepy-rpm-macros +Requires: saltbundlepy-bcrypt >= 3.1.3 +Requires: saltbundlepy-cryptography >= 2.5 +Requires: saltbundlepy-pyasn1 >= 0.1.7 +Requires: saltbundlepy-pynacl >= 1.0.1 +BuildArch: noarch +%if %{with test} +BuildRequires: %{saltbundlepy_module mock} +BuildRequires: %{saltbundlepy_module pytest-relaxed} +BuildRequires: %{saltbundlepy_module pytest} +%endif +%python_subpackages + +%description +This is a library for making SSH2 connections (client or server). +Emphasis is on using SSH2 as an alternative to SSL for making secure +connections between python scripts. All major ciphers and hash methods +are supported. SFTP client and server mode are both supported too. + +%package -n saltbundlepy-paramiko-doc +Summary: Documentation for %{name} +Group: Documentation/Other +Provides: %{saltbundlepy_module paramiko-doc = %{version}} + +%description -n saltbundlepy-paramiko-doc +This is a library for making SSH2 connections (client or server). +Emphasis is on using SSH2 as an alternative to SSL for making secure +connections between python scripts. All major ciphers and hash methods +are supported. SFTP client and server mode are both supported too. + +This package contains the documentation. + +%prep +%setup -q -n paramiko-%{version} +%autopatch -p1 + +# Fix non-executable script rpmlint issue: +find demos -name "*.py" -exec sed -i "/#\!\/usr\/bin\/.*/d" {} \; +tar xvzf %{SOURCE1} -C tests/ + +%build +%python_build + +%install +%python_install +%python_expand %fdupes %{buildroot}%{$python_sitelib} + +%if %{with test} +%check +export LANG=en_US.UTF-8 +%python_expand pytest-%{$python_bin_suffix} +%endif + +%files %{python_files} +%license LICENSE +%doc README.rst +%{python_sitelib}/* + +%files -n saltbundlepy-paramiko-doc +%license LICENSE +%doc demos/ + +%changelog diff --git a/support-cryptography-25-and-above.patch b/support-cryptography-25-and-above.patch new file mode 100644 index 0000000..adbcab4 --- /dev/null +++ b/support-cryptography-25-and-above.patch @@ -0,0 +1,173 @@ +From 36fbe57629cbbb7bf0f4a1e98c43352b82fe181d Mon Sep 17 00:00:00 2001 +From: Andrew Wason +Date: Wed, 6 Feb 2019 10:56:53 -0500 +Subject: [PATCH 1/4] Move to cryptography 2.5 and stop using deprecated APIs. + +Fixes #1369 +--- + .travis.yml | 4 ++-- + paramiko/ecdsakey.py | 4 ++-- + paramiko/kex_ecdh_nist.py | 37 +++++++++++++++++++++++++++++-------- + setup.py | 2 +- + tests/test_kex.py | 12 ++++++------ + 5 files changed, 40 insertions(+), 19 deletions(-) + +Index: paramiko-2.4.2/paramiko/ecdsakey.py +=================================================================== +--- paramiko-2.4.2.orig/paramiko/ecdsakey.py ++++ paramiko-2.4.2/paramiko/ecdsakey.py +@@ -160,12 +160,12 @@ class ECDSAKey(PKey): + + pointinfo = msg.get_binary() + try: +- numbers = ec.EllipticCurvePublicNumbers.from_encoded_point( ++ key = ec.EllipticCurvePublicKey.from_encoded_point( + self.ecdsa_curve.curve_class(), pointinfo + ) ++ self.verifying_key = key + except ValueError: + raise SSHException("Invalid public key") +- self.verifying_key = numbers.public_key(backend=default_backend()) + + @classmethod + def supported_key_format_identifiers(cls): +Index: paramiko-2.4.2/paramiko/kex_ecdh_nist.py +=================================================================== +--- paramiko-2.4.2.orig/paramiko/kex_ecdh_nist.py ++++ paramiko-2.4.2/paramiko/kex_ecdh_nist.py +@@ -9,6 +9,7 @@ from paramiko.py3compat import byte_chr, + from paramiko.ssh_exception import SSHException + from cryptography.hazmat.backends import default_backend + from cryptography.hazmat.primitives.asymmetric import ec ++from cryptography.hazmat.primitives import serialization + from binascii import hexlify + + _MSG_KEXECDH_INIT, _MSG_KEXECDH_REPLY = range(30, 32) +@@ -36,7 +37,12 @@ class KexNistp256: + m = Message() + m.add_byte(c_MSG_KEXECDH_INIT) + # SEC1: V2.0 2.3.3 Elliptic-Curve-Point-to-Octet-String Conversion +- m.add_string(self.Q_C.public_numbers().encode_point()) ++ m.add_string( ++ self.Q_C.public_bytes( ++ serialization.Encoding.X962, ++ serialization.PublicFormat.UncompressedPoint, ++ ) ++ ) + self.transport._send_message(m) + self.transport._expect_packet(_MSG_KEXECDH_REPLY) + +@@ -58,11 +64,11 @@ class KexNistp256: + + def _parse_kexecdh_init(self, m): + Q_C_bytes = m.get_string() +- self.Q_C = ec.EllipticCurvePublicNumbers.from_encoded_point( ++ self.Q_C = ec.EllipticCurvePublicKey.from_encoded_point( + self.curve, Q_C_bytes + ) + K_S = self.transport.get_server_key().asbytes() +- K = self.P.exchange(ec.ECDH(), self.Q_C.public_key(default_backend())) ++ K = self.P.exchange(ec.ECDH(), self.Q_C) + K = long(hexlify(K), 16) + # compute exchange hash + hm = Message() +@@ -75,7 +81,12 @@ class KexNistp256: + hm.add_string(K_S) + hm.add_string(Q_C_bytes) + # SEC1: V2.0 2.3.3 Elliptic-Curve-Point-to-Octet-String Conversion +- hm.add_string(self.Q_S.public_numbers().encode_point()) ++ hm.add_string( ++ self.Q_S.public_bytes( ++ serialization.Encoding.X962, ++ serialization.PublicFormat.UncompressedPoint, ++ ) ++ ) + hm.add_mpint(long(K)) + H = self.hash_algo(hm.asbytes()).digest() + self.transport._set_K_H(K, H) +@@ -84,7 +95,12 @@ class KexNistp256: + m = Message() + m.add_byte(c_MSG_KEXECDH_REPLY) + m.add_string(K_S) +- m.add_string(self.Q_S.public_numbers().encode_point()) ++ m.add_string( ++ self.Q_S.public_bytes( ++ serialization.Encoding.X962, ++ serialization.PublicFormat.UncompressedPoint, ++ ) ++ ) + m.add_string(sig) + self.transport._send_message(m) + self.transport._activate_outbound() +@@ -92,11 +108,11 @@ class KexNistp256: + def _parse_kexecdh_reply(self, m): + K_S = m.get_string() + Q_S_bytes = m.get_string() +- self.Q_S = ec.EllipticCurvePublicNumbers.from_encoded_point( ++ self.Q_S = ec.EllipticCurvePublicKey.from_encoded_point( + self.curve, Q_S_bytes + ) + sig = m.get_binary() +- K = self.P.exchange(ec.ECDH(), self.Q_S.public_key(default_backend())) ++ K = self.P.exchange(ec.ECDH(), self.Q_S) + K = long(hexlify(K), 16) + # compute exchange hash and verify signature + hm = Message() +@@ -108,7 +124,12 @@ class KexNistp256: + ) + hm.add_string(K_S) + # SEC1: V2.0 2.3.3 Elliptic-Curve-Point-to-Octet-String Conversion +- hm.add_string(self.Q_C.public_numbers().encode_point()) ++ hm.add_string( ++ self.Q_C.public_bytes( ++ serialization.Encoding.X962, ++ serialization.PublicFormat.UncompressedPoint, ++ ) ++ ) + hm.add_string(Q_S_bytes) + hm.add_mpint(K) + self.transport._set_K_H(K, self.hash_algo(hm.asbytes()).digest()) +Index: paramiko-2.4.2/setup.py +=================================================================== +--- paramiko-2.4.2.orig/setup.py ++++ paramiko-2.4.2/setup.py +@@ -73,7 +73,7 @@ setup( + ], + install_requires=[ + "bcrypt>=3.1.3", +- "cryptography>=1.5", ++ "cryptography>=2.5", + "pynacl>=1.0.1", + "pyasn1>=0.1.7", + ], +Index: paramiko-2.4.3/tests/test_kex.py +=================================================================== +--- paramiko-2.4.3.orig/tests/test_kex.py 2019-06-24 00:45:29.000000000 +0200 ++++ paramiko-2.4.3/tests/test_kex.py 2022-09-02 15:55:02.895289382 +0200 +@@ -42,20 +42,20 @@ + def dummy_generate_key_pair(obj): + private_key_value = 94761803665136558137557783047955027733968423115106677159790289642479432803037 # noqa + public_key_numbers = "042bdab212fa8ba1b7c843301682a4db424d307246c7e1e6083c41d9ca7b098bf30b3d63e2ec6278488c135360456cc054b3444ecc45998c08894cbc1370f5f989" # noqa +- public_key_numbers_obj = ec.EllipticCurvePublicNumbers.from_encoded_point( ++ public_key_numbers_obj = ec.EllipticCurvePublicKey.from_encoded_point( + ec.SECP256R1(), unhexlify(public_key_numbers) +- ) ++ ).public_numbers() + obj.P = ec.EllipticCurvePrivateNumbers( + private_value=private_key_value, public_numbers=public_key_numbers_obj + ).private_key(default_backend()) + if obj.transport.server_mode: +- obj.Q_S = ec.EllipticCurvePublicNumbers.from_encoded_point( ++ obj.Q_S = ec.EllipticCurvePublicKey.from_encoded_point( + ec.SECP256R1(), unhexlify(public_key_numbers) +- ).public_key(default_backend()) ++ ) + return +- obj.Q_C = ec.EllipticCurvePublicNumbers.from_encoded_point( ++ obj.Q_C = ec.EllipticCurvePublicKey.from_encoded_point( + ec.SECP256R1(), unhexlify(public_key_numbers) +- ).public_key(default_backend()) ++ ) + + + class FakeKey(object):