issue #275: ssh: state machine-ish filter_debug()

pull/287/head
David Wilson 6 years ago
parent fbd5837cf2
commit 84fa3ff024

@ -53,21 +53,6 @@ HOSTKEY_FAIL = 'host key verification failed.'
DEBUG_PREFIXES = ('debug1:', 'debug2:', 'debug3:')
def _filter_debug(stream, it, buf):
while True:
if not buf.startswith(DEBUG_PREFIXES):
return buf
while '\n' in buf:
if not buf.startswith(DEBUG_PREFIXES):
return buf
line, _, buf = buf.partition('\n')
LOG.debug('%r: %s', stream, line.rstrip())
try:
buf += next(it)
except StopIteration:
return buf
def filter_debug(stream, it):
"""
Read line chunks from it, either yielding them directly, or building up and
@ -76,11 +61,33 @@ def filter_debug(stream, it):
This contains the mess of dealing with both line-oriented input, and partial
lines such as the password prompt.
"""
state = 'start_of_line'
buf = ''
for chunk in it:
chunk = _filter_debug(stream, it, chunk)
if chunk:
for line in chunk.splitlines():
yield line
buf += chunk
while buf:
if state == 'start_of_line':
if len(buf) < 8:
# short read near the buffer limit, block waiting for at
# least 8 bytes so we can discern either a debug line, or
# the minimum desired interesting token from above
# ('password').
break
elif buf.startswith(DEBUG_PREFIXES):
state = 'in_debug'
else:
state = 'in_plain'
elif state == 'in_debug':
if '\n' not in buf:
break
line, _, buf = buf.partition('\n')
LOG.debug('%r: %s', stream, line.rstrip())
state = 'start_of_line'
elif state == 'in_plain':
line, nl, buf = buf.partition('\n')
yield line + nl
if nl:
state = 'start_of_line'
class PasswordError(mitogen.core.StreamError):
@ -222,7 +229,7 @@ class Stream(mitogen.parent.Stream):
for buf in filter_debug(self, it):
LOG.debug('%r: received %r', self, buf)
if buf.endswith('EC0'):
if buf.endswith('EC0\n'):
self._router.broker.start_receive(self.tty_stream)
self._ec0_received()
return

Loading…
Cancel
Save