diff options
author | Olle Lundberg <geek@nerd.sh> | 2014-08-15 12:23:02 +0200 |
---|---|---|
committer | Olle Lundberg <geek@nerd.sh> | 2014-08-15 21:14:33 +0200 |
commit | 74bd98fcf5cdd1fa63e5caf085e5b8fdafb0cb4e (patch) | |
tree | 7ca447638095d661cacbd88580ea2861ea1f77c8 /tests/test_packetizer.py | |
parent | 6fe52ccac45f527ced2d4dc3f2d4911f9db7a396 (diff) |
Let packetizer handle 0-length sends from channel.
If the channel is closed the send method returs a response length
of 0. This is not handled correctly by the packetizer and puts it
in an infinite loop. (Fixes #156 for real :-)
We make sure we don't do more than 10 iteration on a 0 length respose,
but raise an EOFError.
Diffstat (limited to 'tests/test_packetizer.py')
-rw-r--r-- | tests/test_packetizer.py | 46 |
1 files changed, 46 insertions, 0 deletions
diff --git a/tests/test_packetizer.py b/tests/test_packetizer.py index a8c0f973..8faec03c 100644 --- a/tests/test_packetizer.py +++ b/tests/test_packetizer.py @@ -74,3 +74,49 @@ class PacketizerTest (unittest.TestCase): self.assertEqual(100, m.get_int()) self.assertEqual(1, m.get_int()) self.assertEqual(900, m.get_int()) + + def test_3_closed(self): + rsock = LoopSocket() + wsock = LoopSocket() + rsock.link(wsock) + p = Packetizer(wsock) + p.set_log(util.get_logger('paramiko.transport')) + p.set_hexdump(True) + cipher = AES.new(zero_byte * 16, AES.MODE_CBC, x55 * 16) + p.set_outbound_cipher(cipher, 16, sha1, 12, x1f * 20) + + # message has to be at least 16 bytes long, so we'll have at least one + # block of data encrypted that contains zero random padding bytes + m = Message() + m.add_byte(byte_chr(100)) + m.add_int(100) + m.add_int(1) + m.add_int(900) + wsock.send = lambda x: 0 + from functools import wraps + import errno + import os + import signal + + class TimeoutError(Exception): + pass + + def timeout(seconds=1, error_message=os.strerror(errno.ETIME)): + def decorator(func): + def _handle_timeout(signum, frame): + raise TimeoutError(error_message) + + def wrapper(*args, **kwargs): + signal.signal(signal.SIGALRM, _handle_timeout) + signal.alarm(seconds) + try: + result = func(*args, **kwargs) + finally: + signal.alarm(0) + return result + + return wraps(func)(wrapper) + + return decorator + send = timeout()(p.send_message) + self.assertRaises(EOFError, send, m) |