Skip to content

Commit

Permalink
Reject global and channel requests sent prior to auth being completed
Browse files Browse the repository at this point in the history
  • Loading branch information
ronf committed Mar 4, 2018
1 parent f18a104 commit 16e6ebf
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 2 deletions.
4 changes: 4 additions & 0 deletions asyncssh/connection.py
Expand Up @@ -746,6 +746,10 @@ def _recv_packet(self):
elif (self._auth and
MSG_USERAUTH_FIRST <= pkttype <= MSG_USERAUTH_LAST):
processed = self._auth.process_packet(pkttype, seq, packet)
elif pkttype > MSG_USERAUTH_LAST and not self._auth_complete:
raise DisconnectError(DISC_PROTOCOL_ERROR,
'Invalid request received before '
'authentication was complete')
else:
processed = self.process_packet(pkttype, seq, packet,
pkttype not in
Expand Down
35 changes: 33 additions & 2 deletions tests/test_connection.py
Expand Up @@ -130,6 +130,28 @@ def verify_and_decrypt(self, header, data, tag):
return super().verify_and_decrypt(header, data + b'\xff', tag)


class _PreAuthRequestClient(asyncssh.SSHClient):
"""Test sending a request prior to auth complete"""

def __init__(self):
self._conn = None

def connection_made(self, conn):
"""Save connection for use later"""

self._conn = conn

def password_auth_requested(self):
"""Attempt to execute a command before authentication is complete"""

# pylint: disable=protected-access
self._conn._auth_complete = True

self._conn.send_packet(MSG_GLOBAL_REQUEST, String(b'\xff'),
Boolean(True))
return 'pw'


class _InternalErrorClient(asyncssh.SSHClient):
"""Test of internal error exception handler"""

Expand Down Expand Up @@ -970,8 +992,8 @@ def test_abort(self):
yield from self.connect()


class _TestConnectionCloseDurngAuth(ServerTestCase):
"""Unit test for connection close during long auth callback"""
class _TestDuringAuth(ServerTestCase):
"""Unit test for operations during auth"""

@classmethod
@asyncio.coroutine
Expand All @@ -988,6 +1010,15 @@ def test_close_during_auth(self):
yield from asyncio.wait_for(self.connect(username='user',
password=''), 0.5)

@asynctest
def test_request_during_auth(self):
"""Test sending a request prior to auth complete"""

with self.assertRaises(asyncssh.DisconnectError):
yield from self.create_connection(_PreAuthRequestClient,
username='user',
compression_algs=['none'])


@unittest.skipUnless(x509_available, 'X.509 not available')
class _TestServerX509Self(ServerTestCase):
Expand Down

0 comments on commit 16e6ebf

Please sign in to comment.