summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorTim Savage <tim@savage.company>2016-12-22 19:28:57 +1100
committerTim Savage <tim@savage.company>2016-12-22 19:28:57 +1100
commit0fd54bb9813c2a62dcea7351e05ce780127ccdbe (patch)
treeb6b3a38a8c30d3656ca9966e362655f4192e5337
parentec3fdd72dba89626635e5ea1c31ac65a31091042 (diff)
Added a auth_timeout to handle situations where SSH server stops responding during auth.
This is has been observed with certain windows SSH servers.
-rw-r--r--paramiko/auth_handler.py5
-rw-r--r--paramiko/client.py8
-rw-r--r--paramiko/transport.py2
3 files changed, 12 insertions, 3 deletions
diff --git a/paramiko/auth_handler.py b/paramiko/auth_handler.py
index 38b23729..7a09d8a2 100644
--- a/paramiko/auth_handler.py
+++ b/paramiko/auth_handler.py
@@ -21,6 +21,7 @@
"""
import weakref
+import time
from paramiko.common import cMSG_SERVICE_REQUEST, cMSG_DISCONNECT, \
DISCONNECT_SERVICE_NOT_AVAILABLE, DISCONNECT_NO_MORE_AUTH_METHODS_AVAILABLE, \
cMSG_USERAUTH_REQUEST, cMSG_SERVICE_ACCEPT, DEBUG, AUTH_SUCCESSFUL, INFO, \
@@ -188,6 +189,7 @@ class AuthHandler (object):
return m.asbytes()
def wait_for_response(self, event):
+ max_ts = time.time() + self.transport.auth_timeout if self.transport.auth_timeout is not None else None
while True:
event.wait(0.1)
if not self.transport.is_active():
@@ -197,6 +199,9 @@ class AuthHandler (object):
raise e
if event.is_set():
break
+ elif max_ts is not None and max_ts >= time.time():
+ raise AuthenticationException('Authentication timeout.')
+
if not self.is_authenticated():
e = self.transport.get_exception()
if e is None:
diff --git a/paramiko/client.py b/paramiko/client.py
index a2c02c51..9dc1029e 100644
--- a/paramiko/client.py
+++ b/paramiko/client.py
@@ -226,7 +226,8 @@ class SSHClient (ClosingContextManager):
gss_kex=False,
gss_deleg_creds=True,
gss_host=None,
- banner_timeout=None
+ banner_timeout=None,
+ auth_timeout=None
):
"""
Connect to an SSH server and authenticate to it. The server's host key
@@ -278,7 +279,8 @@ class SSHClient (ClosingContextManager):
The targets name in the kerberos database. default: hostname
:param float banner_timeout: an optional timeout (in seconds) to wait
for the SSH banner to be presented.
-
+ :param float auth_timeout: an optional timeout (in seconds) to wait for
+ an authentication response.
:raises BadHostKeyException: if the server's host key could not be
verified
:raises AuthenticationException: if authentication failed
@@ -335,6 +337,8 @@ class SSHClient (ClosingContextManager):
t.set_log_channel(self._log_channel)
if banner_timeout is not None:
t.banner_timeout = banner_timeout
+ if auth_timeout is not None:
+ t.auth_timeout = auth_timeout
t.start_client(timeout=timeout)
ResourceManager.register(self, t)
diff --git a/paramiko/transport.py b/paramiko/transport.py
index 7906c9f2..22f81dd6 100644
--- a/paramiko/transport.py
+++ b/paramiko/transport.py
@@ -383,7 +383,7 @@ class Transport (threading.Thread, ClosingContextManager):
self.completion_event = None # user-defined event callbacks
self.banner_timeout = 15 # how long (seconds) to wait for the SSH banner
self.handshake_timeout = 15 # how long (seconds) to wait for the handshake to finish after SSH banner sent.
-
+ self.auth_timeout = 15 # how long (seconds) to wait for the auth response.
# server mode:
self.server_mode = False