From 74b581c170bdf177eac2a1c5e1f6480b2eee24bf Mon Sep 17 00:00:00 2001 From: Robey Pointer Date: Tue, 17 Feb 2009 18:30:48 -0800 Subject: [PATCH] bug 300536: allow a really long banner before the SSH handshake. --- paramiko/packet.py | 4 ++-- paramiko/transport.py | 4 ++-- tests/test_transport.py | 31 +++++++++++++++++++++++++++++++ 3 files changed, 35 insertions(+), 4 deletions(-) diff --git a/paramiko/packet.py b/paramiko/packet.py index 4bde2f7..9c6ec26 100644 --- a/paramiko/packet.py +++ b/paramiko/packet.py @@ -268,11 +268,11 @@ class Packetizer (object): Read a line from the socket. We assume no data is pending after the line, so it's okay to attempt large reads. """ - buf = '' + buf = self.__remainder while not '\n' in buf: buf += self._read_timeout(timeout) n = buf.index('\n') - self.__remainder += buf[n+1:] + self.__remainder = buf[n+1:] buf = buf[:n] if (len(buf) > 0) and (buf[-1] == '\r'): buf = buf[:-1] diff --git a/paramiko/transport.py b/paramiko/transport.py index fa6112a..5a871e9 100644 --- a/paramiko/transport.py +++ b/paramiko/transport.py @@ -1471,7 +1471,7 @@ class Transport (threading.Thread): # (use the exposed "run" method, because if we specify a thread target # of a private method, threading.Thread will keep a reference to it # indefinitely, creating a GC cycle and not letting Transport ever be - # GC'd. it's a bug in Thread.) + # GC'd. it's a bug in Thread.) # active=True occurs before the thread is launched, to avoid a race _active_threads.append(self) @@ -1588,7 +1588,7 @@ class Transport (threading.Thread): def _check_banner(self): # this is slow, but we only have to do it once - for i in range(5): + for i in range(100): # give them 15 seconds for the first line, then just 2 seconds # each additional line. (some sites have very high latency.) if i == 0: diff --git a/tests/test_transport.py b/tests/test_transport.py index 4b52c4f..1e380ac 100644 --- a/tests/test_transport.py +++ b/tests/test_transport.py @@ -38,6 +38,19 @@ from paramiko.message import Message from loop import LoopSocket +LONG_BANNER = """\ +Welcome to the super-fun-land BBS, where our MOTD is the primary thing we +provide. All rights reserved. Offer void in Tennessee. Stunt drivers were +used. Do not attempt at home. Some restrictions apply. + +Happy birthday to Commie the cat! + +Note: An SSH banner may eventually appear. + +Maybe. +""" + + class NullServer (ServerInterface): paranoid_did_password = False paranoid_did_public_key = False @@ -182,6 +195,24 @@ class TransportTest (unittest.TestCase): self.assertEquals(True, self.tc.is_authenticated()) self.assertEquals(True, self.ts.is_authenticated()) + def test_3a_long_banner(self): + """ + verify that a long banner doesn't mess up the handshake. + """ + host_key = RSAKey.from_private_key_file('tests/test_rsa.key') + public_host_key = RSAKey(data=str(host_key)) + self.ts.add_server_key(host_key) + event = threading.Event() + server = NullServer() + self.assert_(not event.isSet()) + self.socks.send(LONG_BANNER) + self.ts.start_server(event, server) + self.tc.connect(hostkey=public_host_key, + username='slowdive', password='pygmalion') + event.wait(1.0) + self.assert_(event.isSet()) + self.assert_(self.ts.is_active()) + def test_4_special(self): """ verify that the client can demand odd handshake settings, and can