Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package python-asyncssh for openSUSE:Factory 
checked in at 2023-12-18 22:57:21
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-asyncssh (Old)
 and      /work/SRC/openSUSE:Factory/.python-asyncssh.new.9037 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-asyncssh"

Mon Dec 18 22:57:21 2023 rev:26 rq:1133889 version:2.14.2

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-asyncssh/python-asyncssh.changes  
2023-11-13 22:20:41.635111844 +0100
+++ 
/work/SRC/openSUSE:Factory/.python-asyncssh.new.9037/python-asyncssh.changes    
    2023-12-18 22:57:30.619055507 +0100
@@ -1,0 +2,14 @@
+Mon Dec 18 15:55:18 UTC 2023 - Dirk Müller <dmuel...@suse.com>
+
+- update to 2.14.2 (bsc#1218165, CVE-2023-48795):
+  * Implemented "strict kex" support and other countermeasures to
+  * protect against the Terrapin Attack described in
+    CVE-2023-48795
+  * Fixed config parser to properly an optional equals delimiter
+    in all config arguments.
+  * Fixed TCP send error handling to avoid race condition when
+    receiving incoming disconnect message.
+  * Improved type signature in SSHConnection async context
+    manager.
+
+-------------------------------------------------------------------

Old:
----
  asyncssh-2.14.1.tar.gz

New:
----
  asyncssh-2.14.2.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-asyncssh.spec ++++++
--- /var/tmp/diff_new_pack.Ol77YX/_old  2023-12-18 22:57:31.707095353 +0100
+++ /var/tmp/diff_new_pack.Ol77YX/_new  2023-12-18 22:57:31.711095500 +0100
@@ -16,10 +16,9 @@
 #
 
 
-%define skip_python2 1
-%define skip_python36 1
+%{?sle15_python_module_pythons}
 Name:           python-asyncssh
-Version:        2.14.1
+Version:        2.14.2
 Release:        0
 Summary:        Asynchronous SSHv2 client and server library
 License:        EPL-2.0 OR GPL-2.0-or-later

++++++ asyncssh-2.14.1.tar.gz -> asyncssh-2.14.2.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/asyncssh-2.14.1/.github/workflows/run_tests.yml 
new/asyncssh-2.14.2/.github/workflows/run_tests.yml
--- old/asyncssh-2.14.1/.github/workflows/run_tests.yml 2023-11-09 
03:28:14.000000000 +0100
+++ new/asyncssh-2.14.2/.github/workflows/run_tests.yml 2023-11-09 
04:54:11.000000000 +0100
@@ -67,7 +67,9 @@
 
       - name: Install Linux dependencies
         if: ${{ runner.os == 'Linux' }}
-        run: sudo apt install -y --no-install-recommends libnettle8 
libsodium-dev libssl-dev libkrb5-dev ssh cmake ninja-build
+        run: |
+          sudo apt update
+          sudo apt install -y --no-install-recommends libnettle8 libsodium-dev 
libssl-dev libkrb5-dev ssh cmake ninja-build
 
       - name: Install macOS dependencies
         if: ${{ runner.os == 'macOS' }}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/asyncssh-2.14.1/PKG-INFO new/asyncssh-2.14.2/PKG-INFO
--- old/asyncssh-2.14.1/PKG-INFO        2023-11-09 04:02:21.000000000 +0100
+++ new/asyncssh-2.14.2/PKG-INFO        2023-12-18 16:49:17.000000000 +0100
@@ -1,6 +1,6 @@
 Metadata-Version: 2.1
 Name: asyncssh
-Version: 2.14.1
+Version: 2.14.2
 Summary: AsyncSSH: Asynchronous SSHv2 client and server library
 Home-page: http://asyncssh.timeheart.net
 Author: Ron Frederick
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/asyncssh-2.14.1/asyncssh/config.py 
new/asyncssh-2.14.2/asyncssh/config.py
--- old/asyncssh-2.14.1/asyncssh/config.py      2022-12-27 22:30:36.000000000 
+0100
+++ new/asyncssh-2.14.2/asyncssh/config.py      2023-12-18 16:45:25.000000000 
+0100
@@ -315,22 +315,26 @@
                     continue
 
                 try:
-                    args = shlex.split(line)
+                    split_args = shlex.split(line)
                 except ValueError as exc:
                     self._error(str(exc))
 
-                option = args.pop(0)
+                args = []
 
-                if option.endswith('='):
-                    option = option[:-1]
-                elif '=' in option:
-                    option, arg = option.split('=', 1)
-                    args[:0] =[arg]
-                elif args and args[0] == '=':
-                    del args[0]
-                elif args and args[0].startswith('='):
-                    args[0] = args[0][1:]
+                for arg in split_args:
+                    if arg.startswith('='):
+                        if len(arg) > 1:
+                            args.append(arg[1:])
+                    elif arg.endswith('='):
+                        args.append(arg[:-1])
+                    elif '=' in arg:
+                        arg, val = arg.split('=', 1)
+                        args.append(arg)
+                        args.append(val)
+                    else:
+                        args.append(arg)
 
+                option = args.pop(0)
                 loption = option.lower()
 
                 if loption in self._no_split:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/asyncssh-2.14.1/asyncssh/connection.py 
new/asyncssh-2.14.2/asyncssh/connection.py
--- old/asyncssh-2.14.1/asyncssh/connection.py  2023-11-09 03:28:14.000000000 
+0100
+++ new/asyncssh-2.14.2/asyncssh/connection.py  2023-12-18 16:45:25.000000000 
+0100
@@ -179,6 +179,7 @@
 _ProtocolFactory = Union[_ClientFactory, _ServerFactory]
 
 _Conn = TypeVar('_Conn', 'SSHClientConnection', 'SSHServerConnection')
+_ConnSelf = TypeVar('_ConnSelf', bound='SSHConnection')
 
 class _TunnelProtocol(Protocol):
     """Base protocol for connections to tunnel SSH over"""
@@ -317,12 +318,6 @@
 
             self._conn.connection_lost(exc)
 
-        def is_closing(self) -> bool:
-            """Return whether the transport is closing or not"""
-
-            assert self._transport is not None
-            return self._transport.is_closing()
-
         def write(self, data: bytes) -> None:
             """Write data to this tunnel"""
 
@@ -866,6 +861,7 @@
         self._kexinit_sent = False
         self._kex_complete = False
         self._ignore_first_kex = False
+        self._strict_kex = False
 
         self._gss: Optional[GSSBase] = None
         self._gss_kex = False
@@ -944,7 +940,7 @@
 
         self._disable_trivial_auth = False
 
-    async def __aenter__(self) -> 'SSHConnection':
+    async def __aenter__(self: _ConnSelf) -> _ConnSelf:
         """Allow SSHConnection to be used as an async context manager"""
 
         return self
@@ -1403,19 +1399,22 @@
             (alg_type, b','.join(local_algs).decode('ascii'),
              b','.join(remote_algs).decode('ascii')))
 
-    def _get_ext_info_kex_alg(self) -> List[bytes]:
-        """Return the kex alg to add if any to request extension info"""
+    def _get_extra_kex_algs(self) -> List[bytes]:
+        """Return the extra kex algs to add"""
 
-        return [b'ext-info-c' if self.is_client() else b'ext-info-s']
+        if self.is_client():
+            return [b'ext-info-c', b'kex-strict-c-...@openssh.com']
+        else:
+            return [b'ext-info-s', b'kex-strict-s-...@openssh.com']
 
     def _send(self, data: bytes) -> None:
         """Send data to the SSH connection"""
 
         if self._transport:
-            if self._transport.is_closing():
-                self._force_close(BrokenPipeError())
-            else:
+            try:
                 self._transport.write(data)
+            except BrokenPipeError: # pragma: no cover
+                pass
 
     def _send_version(self) -> None:
         """Start the SSH handshake"""
@@ -1551,6 +1550,11 @@
             else:
                 skip_reason = 'kex not in progress'
                 exc_reason = 'Key exchange not in progress'
+        elif self._strict_kex and not self._recv_encryption and \
+                MSG_IGNORE <= pkttype <= MSG_DEBUG:
+            skip_reason = 'strict kex violation'
+            exc_reason = 'Strict key exchange violation: ' \
+                         'unexpected packet type %d received' % pkttype
         elif MSG_USERAUTH_FIRST <= pkttype <= MSG_USERAUTH_LAST:
             if self._auth:
                 handler = self._auth
@@ -1586,8 +1590,13 @@
                 raise ProtocolError(str(exc)) from None
 
             if not processed:
-                self.logger.debug1('Unknown packet type %d received', pkttype)
-                self.send_packet(MSG_UNIMPLEMENTED, UInt32(seq))
+                if self._strict_kex and not self._recv_encryption:
+                    exc_reason = 'Strict key exchange violation: ' \
+                                 'unexpected packet type %d received' % pkttype
+                else:
+                    self.logger.debug1('Unknown packet type %d received',
+                                       pkttype)
+                    self.send_packet(MSG_UNIMPLEMENTED, UInt32(seq))
 
         if exc_reason:
             raise ProtocolError(exc_reason)
@@ -1596,9 +1605,16 @@
             self._auth_final = True
 
         if self._transport:
-            self._recv_seq = (seq + 1) & 0xffffffff
             self._recv_handler = self._recv_pkthdr
 
+            if self._recv_seq == 0xffffffff and not self._recv_encryption:
+                raise ProtocolError('Sequence rollover before kex complete')
+
+            if pkttype == MSG_NEWKEYS and self._strict_kex:
+                self._recv_seq = 0
+            else:
+                self._recv_seq = (seq + 1) & 0xffffffff
+
         return True
 
     def send_packet(self, pkttype: int, *args: bytes,
@@ -1650,7 +1666,15 @@
             mac = b''
 
         self._send(packet + mac)
-        self._send_seq = (seq + 1) & 0xffffffff
+
+        if self._send_seq == 0xffffffff and not self._send_encryption:
+            self._send_seq = 0
+            raise ProtocolError('Sequence rollover before kex complete')
+
+        if pkttype == MSG_NEWKEYS and self._strict_kex:
+            self._send_seq = 0
+        else:
+            self._send_seq = (seq + 1) & 0xffffffff
 
         if self._kex_complete:
             self._rekey_bytes_sent += pktlen
@@ -1694,7 +1718,7 @@
 
         kex_algs = expand_kex_algs(self._kex_algs, gss_mechs,
                                    bool(self._server_host_key_algs)) + \
-                   self._get_ext_info_kex_alg()
+                   self._get_extra_kex_algs()
 
         host_key_algs = self._server_host_key_algs or [b'null']
 
@@ -2196,13 +2220,27 @@
         if self.is_server():
             self._client_kexinit = packet.get_consumed_payload()
 
-            if b'ext-info-c' in peer_kex_algs and not self._session_id:
-                self._can_send_ext_info = True
+            if not self._session_id:
+                if b'ext-info-c' in peer_kex_algs:
+                    self._can_send_ext_info = True
+
+                if b'kex-strict-c-...@openssh.com' in peer_kex_algs:
+                    self._strict_kex = True
         else:
             self._server_kexinit = packet.get_consumed_payload()
 
-            if b'ext-info-s' in peer_kex_algs and not self._session_id:
-                self._can_send_ext_info = True
+            if not self._session_id:
+                if b'ext-info-s' in peer_kex_algs:
+                    self._can_send_ext_info = True
+
+                if b'kex-strict-s-...@openssh.com' in peer_kex_algs:
+                    self._strict_kex = True
+
+        if self._strict_kex and not self._recv_encryption and \
+                self._recv_seq != 0:
+            raise ProtocolError('Strict key exchange violation: '
+                                'KEXINIT was not the first packet')
+
 
         if self._kexinit_sent:
             self._kexinit_sent = False
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/asyncssh-2.14.1/asyncssh/version.py 
new/asyncssh-2.14.2/asyncssh/version.py
--- old/asyncssh-2.14.1/asyncssh/version.py     2023-11-09 03:30:33.000000000 
+0100
+++ new/asyncssh-2.14.2/asyncssh/version.py     2023-12-18 16:45:49.000000000 
+0100
@@ -26,4 +26,4 @@
 
 __url__ = 'http://asyncssh.timeheart.net'
 
-__version__ = '2.14.1'
+__version__ = '2.14.2'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/asyncssh-2.14.1/asyncssh.egg-info/PKG-INFO 
new/asyncssh-2.14.2/asyncssh.egg-info/PKG-INFO
--- old/asyncssh-2.14.1/asyncssh.egg-info/PKG-INFO      2023-11-09 
04:02:21.000000000 +0100
+++ new/asyncssh-2.14.2/asyncssh.egg-info/PKG-INFO      2023-12-18 
16:49:17.000000000 +0100
@@ -1,6 +1,6 @@
 Metadata-Version: 2.1
 Name: asyncssh
-Version: 2.14.1
+Version: 2.14.2
 Summary: AsyncSSH: Asynchronous SSHv2 client and server library
 Home-page: http://asyncssh.timeheart.net
 Author: Ron Frederick
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/asyncssh-2.14.1/docs/changes.rst 
new/asyncssh-2.14.2/docs/changes.rst
--- old/asyncssh-2.14.1/docs/changes.rst        2023-11-09 03:50:21.000000000 
+0100
+++ new/asyncssh-2.14.2/docs/changes.rst        2023-12-18 16:45:57.000000000 
+0100
@@ -3,13 +3,32 @@
 Change Log
 ==========
 
+Release 2.14.2 (18 Dec 2023)
+----------------------------
+
+* Implemented "strict kex" support and other countermeasures to
+  protect against the Terrapin Attack described in `CVE-2023-48795
+  <https://github.com/advisories/GHSA-hfmc-7525-mj55>`. Thanks once
+  again go to Fabian Bäumer, Marcus Brinkmann, and Jörg Schwenk for
+  identifying and reporting this vulnerability and providing detailed
+  analysis and suggestions about proposed fixes.
+
+* Fixed config parser to properly an optional equals delimiter in all
+  config arguments. Thanks go to Fawaz Orabi for reporting this issue.
+
+* Fixed TCP send error handling to avoid race condition when receiving
+  incoming disconnect message.
+
+* Improved type signature in SSHConnection async context manager. Thanks
+  go to Pieter-Jan Briers for providing this.
+
 Release 2.14.1 (8 Nov 2023)
 ---------------------------
 
 * Hardened AsyncSSH state machine against potential message
   injection attacks, described in more detail in `CVE-2023-46445
-  <https://github.com/advisories/CVE-2023-46445>`_ and `CVE-2023-46446
-  <https://github.com/advisories/CVE-2023-46446>`_. Thanks go to
+  <https://github.com/advisories/GHSA-cfc2-wr2v-gxm5>`_ and `CVE-2023-46446
+  <https://github.com/advisories/GHSA-c35q-ffpf-5qpm>`_. Thanks go to
   Fabian Bäumer, Marcus Brinkmann, and Jörg Schwenk for identifying
   and reporting these vulnerabilities and providing detailed analysis
   and suggestions about the proposed fixes.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/asyncssh-2.14.1/tests/test_connection.py 
new/asyncssh-2.14.2/tests/test_connection.py
--- old/asyncssh-2.14.1/tests/test_connection.py        2023-11-09 
03:28:14.000000000 +0100
+++ new/asyncssh-2.14.2/tests/test_connection.py        2023-12-18 
16:45:25.000000000 +0100
@@ -30,9 +30,10 @@
 from unittest.mock import patch
 
 import asyncssh
-from asyncssh.constants import MSG_DEBUG
+from asyncssh.constants import MSG_IGNORE, MSG_DEBUG
 from asyncssh.constants import MSG_SERVICE_REQUEST, MSG_SERVICE_ACCEPT
-from asyncssh.constants import MSG_KEXINIT, MSG_NEWKEYS, MSG_KEX_FIRST
+from asyncssh.constants import MSG_KEXINIT, MSG_NEWKEYS
+from asyncssh.constants import MSG_KEX_FIRST, MSG_KEX_LAST
 from asyncssh.constants import MSG_USERAUTH_REQUEST, MSG_USERAUTH_SUCCESS
 from asyncssh.constants import MSG_USERAUTH_FAILURE, MSG_USERAUTH_BANNER
 from asyncssh.constants import MSG_USERAUTH_FIRST
@@ -43,6 +44,7 @@
 from asyncssh.crypto.cipher import GCMCipher
 from asyncssh.encryption import get_encryption_algs
 from asyncssh.kex import get_kex_algs
+from asyncssh.kex_dh import MSG_KEX_ECDH_REPLY
 from asyncssh.mac import _HMAC, _mac_handler, get_mac_algs
 from asyncssh.packet import Boolean, NameList, String, UInt32
 from asyncssh.public_key import get_default_public_key_algs
@@ -51,8 +53,8 @@
 
 from .server import Server, ServerTestCase
 
-from .util import asynctest, gss_available, nc_available, patch_gss
-from .util import patch_getnameinfo, x509_available
+from .util import asynctest, patch_extra_kex, patch_getnameinfo, patch_gss
+from .util import gss_available, nc_available, x509_available
 
 
 class _CheckAlgsClientConnection(asyncssh.SSHClientConnection):
@@ -931,22 +933,6 @@
                 await self.connect(kex_algs=['fail'])
 
     @asynctest
-    async def test_skip_ext_info(self):
-        """Test not requesting extension info from the server"""
-
-        def skip_ext_info(self):
-            """Don't request extension information"""
-
-            # pylint: disable=unused-argument
-
-            return []
-
-        with patch('asyncssh.connection.SSHConnection._get_ext_info_kex_alg',
-                   skip_ext_info):
-            async with self.connect():
-                pass
-
-    @asynctest
     async def test_unknown_ext_info(self):
         """Test receiving unknown extension information"""
 
@@ -971,6 +957,54 @@
                 await self.connect()
 
     @asynctest
+    async def test_message_before_kexinit_strict_kex(self):
+        """Test receiving a message before KEXINIT with strict_kex enabled"""
+
+        def send_packet(self, pkttype, *args, **kwargs):
+            if pkttype == MSG_KEXINIT:
+                self.send_packet(MSG_IGNORE, String(b''))
+
+            asyncssh.connection.SSHConnection.send_packet(
+                self, pkttype, *args, **kwargs)
+
+        with patch('asyncssh.connection.SSHClientConnection.send_packet',
+                   send_packet):
+            with self.assertRaises(asyncssh.ProtocolError):
+                await self.connect()
+
+    @asynctest
+    async def test_message_during_kex_strict_kex(self):
+        """Test receiving an unexpected message with strict_kex enabled"""
+
+        def send_packet(self, pkttype, *args, **kwargs):
+            if pkttype == MSG_KEX_ECDH_REPLY:
+                self.send_packet(MSG_IGNORE, String(b''))
+
+            asyncssh.connection.SSHConnection.send_packet(
+                self, pkttype, *args, **kwargs)
+
+        with patch('asyncssh.connection.SSHServerConnection.send_packet',
+                   send_packet):
+            with self.assertRaises(asyncssh.ProtocolError):
+                await self.connect()
+
+    @asynctest
+    async def test_unknown_message_during_kex_strict_kex(self):
+        """Test receiving an unknown message with strict_kex enabled"""
+
+        def send_packet(self, pkttype, *args, **kwargs):
+            if pkttype == MSG_KEX_ECDH_REPLY:
+                self.send_packet(MSG_KEX_LAST)
+
+            asyncssh.connection.SSHConnection.send_packet(
+                self, pkttype, *args, **kwargs)
+
+        with patch('asyncssh.connection.SSHServerConnection.send_packet',
+                   send_packet):
+            with self.assertRaises(asyncssh.ProtocolError):
+                await self.connect()
+
+    @asynctest
     async def test_encryption_algs(self):
         """Test connecting with different encryption algorithms"""
 
@@ -1602,6 +1636,81 @@
             await self.create_connection(_InternalErrorClient)
 
 
+@patch_extra_kex
+class _TestConnectionNoStrictKex(ServerTestCase):
+    """Unit tests for connection API with ext info and strict kex disabled"""
+
+    @classmethod
+    async def start_server(cls):
+        """Start an SSH server to connect to"""
+
+        return (await cls.create_server(_TunnelServer, gss_host=(),
+                                        compression_algs='*',
+                                        encryption_algs='*',
+                                        kex_algs='*', mac_algs='*'))
+
+    @asynctest
+    async def test_skip_ext_info(self):
+        """Test not requesting extension info from the server"""
+
+        async with self.connect():
+            pass
+
+    @asynctest
+    async def test_message_before_kexinit(self):
+        """Test receiving a message before KEXINIT"""
+
+        def send_packet(self, pkttype, *args, **kwargs):
+            if pkttype == MSG_KEXINIT:
+                self.send_packet(MSG_IGNORE, String(b''))
+
+            asyncssh.connection.SSHConnection.send_packet(
+                self, pkttype, *args, **kwargs)
+
+        with patch('asyncssh.connection.SSHClientConnection.send_packet',
+                   send_packet):
+            async with self.connect():
+                pass
+
+    @asynctest
+    async def test_message_during_kex(self):
+        """Test receiving an unexpected message in key exchange"""
+
+        def send_packet(self, pkttype, *args, **kwargs):
+            if pkttype == MSG_KEX_ECDH_REPLY:
+                self.send_packet(MSG_IGNORE, String(b''))
+
+            asyncssh.connection.SSHConnection.send_packet(
+                self, pkttype, *args, **kwargs)
+
+        with patch('asyncssh.connection.SSHServerConnection.send_packet',
+                   send_packet):
+            async with self.connect():
+                pass
+
+    @asynctest
+    async def test_sequence_wrap_during_kex(self):
+        """Test sequence wrap during initial key exchange"""
+
+        def send_packet(self, pkttype, *args, **kwargs):
+            if pkttype == MSG_KEXINIT:
+                if self._options.command == 'send':
+                    self._send_seq = 0xfffffffe
+                else:
+                    self._recv_seq = 0xfffffffe
+
+            asyncssh.connection.SSHConnection.send_packet(
+                self, pkttype, *args, **kwargs)
+
+        with patch('asyncssh.connection.SSHClientConnection.send_packet',
+                   send_packet):
+            with self.assertRaises(asyncssh.ProtocolError):
+                await self.connect(command='send')
+
+            with self.assertRaises(asyncssh.ProtocolError):
+                await self.connect(command='recv')
+
+
 class _TestConnectionListenSock(ServerTestCase):
     """Unit test for specifying a listen socket"""
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/asyncssh-2.14.1/tests/test_connection_auth.py 
new/asyncssh-2.14.2/tests/test_connection_auth.py
--- old/asyncssh-2.14.1/tests/test_connection_auth.py   2023-10-22 
04:09:07.000000000 +0200
+++ new/asyncssh-2.14.2/tests/test_connection_auth.py   2023-12-18 
16:45:25.000000000 +0100
@@ -739,7 +739,7 @@
 
             return []
 
-        with patch('asyncssh.connection.SSHConnection._get_ext_info_kex_alg',
+        with patch('asyncssh.connection.SSHConnection._get_extra_kex_algs',
                    skip_ext_info):
             try:
                 async with self.connect(username='user',
@@ -1245,7 +1245,7 @@
 
             return []
 
-        with patch('asyncssh.connection.SSHConnection._get_ext_info_kex_alg',
+        with patch('asyncssh.connection.SSHConnection._get_extra_kex_algs',
                    skip_ext_info):
             try:
                 async with self.connect(username='ckey', client_keys='ckey',
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/asyncssh-2.14.1/tests/util.py 
new/asyncssh-2.14.2/tests/util.py
--- old/asyncssh-2.14.1/tests/util.py   2023-10-01 02:35:42.000000000 +0200
+++ new/asyncssh-2.14.2/tests/util.py   2023-12-18 16:45:25.000000000 +0100
@@ -106,6 +106,20 @@
     return patch('socket.getnameinfo', getnameinfo)(cls)
 
 
+def patch_extra_kex(cls):
+    """Decorator for skipping extra kex algs"""
+
+    def skip_extra_kex_algs(self):
+        """Don't send extra key exchange algorithms"""
+
+        # pylint: disable=unused-argument
+
+        return []
+
+    return patch('asyncssh.connection.SSHConnection._get_extra_kex_algs',
+                 skip_extra_kex_algs)(cls)
+
+
 def patch_gss(cls):
     """Decorator for patching GSSAPI classes"""
 

Reply via email to