Paramiko has no overall timeout for initial negotiation
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
paramiko |
New
|
Undecided
|
Unassigned |
Bug Description
I've recently used paramiko with a Cisco IP phone which, combined with a flakey network, seems very good at exposing the lack of an overall timeout to SSHClient.connect. There is a timeout to connect() but this only applies to TCP connect - the paramiko Transport will later override it to 0.1s in order to poll the socket for incoming messages.
Please find script attached which will reproduce the issue using simulated network outages using blackhole routes on a Ubuntu machine. To reproduce reliably you need a host which is slow to complete key negotiation - for some reason my Cisco IP phone takes over 4s before I see "Switch to new keys":
2014-07-08 13:08:57,397 {Thread-2 } [DEBUG] paramiko.transport: Ciphers agreed: local=aes128-cbc, remote=aes128-cbc
2014-07-08 13:08:57,397 {Thread-2 } [DEBUG] paramiko.transport: using kex diffie-
2014-07-08 13:09:11,966 {Thread-2 } [DEBUG] paramiko.transport: Switch to new keys ...
If the TCP connection dies silently at this point paramiko will get stuck polling for a message in:
(transport.py, line 1421)
I'm going to work around this issue by extending the Packetizer to add a connect timeout but it would be good to fix this issue properly and make the connect() timeout do what I would expect it to do.
Found in paramiko 1.14.0.