bug 300536: allow a really long banner before the SSH handshake.

This commit is contained in:
Robey Pointer 2009-02-17 18:30:48 -08:00
parent 5def112013
commit 74b581c170
3 changed files with 35 additions and 4 deletions

View File

@ -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]

View File

@ -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:

View File

@ -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