diff --git a/asyncssh/compression.py b/asyncssh/compression.py index f014760..e05ca74 100644 --- a/asyncssh/compression.py +++ b/asyncssh/compression.py @@ -1,4 +1,4 @@ -# Copyright (c) 2013-2021 by Ron Frederick and others. +# Copyright (c) 2013-2024 by Ron Frederick and others. # # This program and the accompanying materials are made available under # the terms of the Eclipse Public License v2.0 which accompanies this @@ -149,9 +149,9 @@ def get_decompressor(alg: bytes) -> Optional[Decompressor]: return _cmp_decompressors[alg]() +register_compression_alg(b'none', + _none, _none, False, True) register_compression_alg(b'zlib@openssh.com', _ZLibCompress, _ZLibDecompress, True, True) register_compression_alg(b'zlib', _ZLibCompress, _ZLibDecompress, False, False) -register_compression_alg(b'none', - _none, _none, False, True) diff --git a/asyncssh/connection.py b/asyncssh/connection.py index 5c1109d..cc4609c 100644 --- a/asyncssh/connection.py +++ b/asyncssh/connection.py @@ -7544,16 +7544,17 @@ class SSHClientConnectionOptions(SSHConnectionOptions): :param compression_algs: (optional) A list of compression algorithms to use during the SSH handshake, taken from :ref:`compression algorithms `, or - `None` to disable compression. + `None` to disable compression. The client prefers to disable + compression, but will enable it if the server requires it. :param signature_algs: (optional) A list of public key signature algorithms to use during the SSH handshake, taken from :ref:`signature algorithms `. :param rekey_bytes: (optional) The number of bytes which can be sent before the SSH session - key is renegotiated. This defaults to 1 GB. + key is renegotiated, defaulting to 1 GB. :param rekey_seconds: (optional) The maximum time in seconds before the SSH session key is - renegotiated. This defaults to 1 hour. + renegotiated, defaulting to 1 hour. :param connect_timeout: (optional) The maximum time in seconds allowed to complete an outbound SSH connection. This includes the time to establish the TCP @@ -8289,26 +8290,28 @@ class SSHServerConnectionOptions(SSHConnectionOptions): this server, defaulting to `'AsyncSSH'` and its version number. :param kex_algs: (optional) A list of allowed key exchange algorithms in the SSH handshake, - taken from :ref:`key exchange algorithms ` + taken from :ref:`key exchange algorithms `, :param encryption_algs: (optional) A list of encryption algorithms to use during the SSH handshake, - taken from :ref:`encryption algorithms ` + taken from :ref:`encryption algorithms `. :param mac_algs: (optional) A list of MAC algorithms to use during the SSH handshake, taken - from :ref:`MAC algorithms ` + from :ref:`MAC algorithms `. :param compression_algs: (optional) A list of compression algorithms to use during the SSH handshake, taken from :ref:`compression algorithms `, or - `None` to disable compression + `None` to disable compression. The server defaults to allowing + either no compression or compression after auth, depending on + what the client requests. :param signature_algs: (optional) A list of public key signature algorithms to use during the SSH - handshake, taken from :ref:`signature algorithms ` + handshake, taken from :ref:`signature algorithms `. :param rekey_bytes: (optional) The number of bytes which can be sent before the SSH session - key is renegotiated, defaulting to 1 GB + key is renegotiated, defaulting to 1 GB. :param rekey_seconds: (optional) The maximum time in seconds before the SSH session key is - renegotiated, defaulting to 1 hour + renegotiated, defaulting to 1 hour. :param connect_timeout: (optional) The maximum time in seconds allowed to complete an outbound SSH connection. This includes the time to establish the TCP @@ -8318,8 +8321,8 @@ class SSHServerConnectionOptions(SSHConnectionOptions): and AsyncSSH's login timeout. :param login_timeout: (optional) The maximum time in seconds allowed for authentication to - complete, defaulting to 2 minutes. Setting this to 0 - will disable the login timeout. + complete, defaulting to 2 minutes. Setting this to 0 will + disable the login timeout. .. note:: This timeout only applies after the SSH TCP connection is established. To set a timeout diff --git a/tests/test_channel.py b/tests/test_channel.py index 6850de6..e535679 100644 --- a/tests/test_channel.py +++ b/tests/test_channel.py @@ -1848,8 +1848,9 @@ async def test_dropbear_client(self): """Test reduced dropbear send packet size""" with patch('asyncssh.connection.SSHServerChannel', _ServerChannel): - async with self.connect(client_version='dropbear', - max_pktsize=32759) as conn: + async with self.connect( + client_version='dropbear', max_pktsize=32759, + compression_algs=['zlib@openssh.com']) as conn: _, stdout, _ = await conn.open_session('send_pktsize') self.assertEqual((await stdout.read()), '32758') @@ -1875,7 +1876,8 @@ async def test_dropbear_server(self): """Test reduced dropbear send packet size""" with patch('asyncssh.connection.SSHClientChannel', _ClientChannel): - async with self.connect() as conn: + async with self.connect( + compression_algs='zlib@openssh.com') as conn: stdin, _, _ = await conn.open_session() self.assertEqual(stdin.channel.get_send_pktsize(), 32758) diff --git a/tests/test_connection.py b/tests/test_connection.py index 1f45023..fcc54fe 100644 --- a/tests/test_connection.py +++ b/tests/test_connection.py @@ -1260,6 +1260,24 @@ def send_newkeys(self, k, h): with self.assertRaises(asyncssh.ProtocolError): await self.connect() + @asynctest + async def test_client_decompression_failure(self): + """Test client decompression failure""" + + def send_packet(self, pkttype, *args, **kwargs): + """Send an SSH packet""" + + asyncssh.connection.SSHConnection.send_packet( + self, pkttype, *args, **kwargs) + + if pkttype == MSG_USERAUTH_SUCCESS: + self._compressor = None + self.send_debug('Test') + + with patch('asyncssh.connection.SSHServerConnection.send_packet', + send_packet): + await self.connect(compression_algs=['zlib@openssh.com']) + @asynctest async def test_packet_decode_error(self): """Test SSH packet decode error"""