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