summaryrefslogtreecommitdiff
path: root/paramiko
diff options
context:
space:
mode:
Diffstat (limited to 'paramiko')
-rw-r--r--paramiko/_version.py2
-rw-r--r--paramiko/agent.py14
-rw-r--r--paramiko/client.py5
-rw-r--r--paramiko/hostkeys.py6
-rw-r--r--paramiko/server.py3
-rw-r--r--paramiko/transport.py4
6 files changed, 30 insertions, 4 deletions
diff --git a/paramiko/_version.py b/paramiko/_version.py
index 06833102..ba3f1b3c 100644
--- a/paramiko/_version.py
+++ b/paramiko/_version.py
@@ -1,2 +1,2 @@
-__version_info__ = (3, 0, 0)
+__version_info__ = (3, 1, 0)
__version__ = ".".join(map(str, __version_info__))
diff --git a/paramiko/agent.py b/paramiko/agent.py
index 73fa1f82..30ec1590 100644
--- a/paramiko/agent.py
+++ b/paramiko/agent.py
@@ -65,6 +65,9 @@ class AgentSSH:
no SSH agent was running (or it couldn't be contacted), an empty list
will be returned.
+ This method performs no IO, just returns the list of keys retrieved
+ when the connection was made.
+
:return:
a tuple of `.AgentKey` objects representing keys available on the
SSH agent
@@ -277,6 +280,17 @@ class AgentClientProxy:
class AgentServerProxy(AgentSSH):
"""
+ Allows an SSH server to access a forwarded agent.
+
+ This also creates a unix domain socket on the system to allow external
+ programs to also access the agent. For this reason, you probably only want
+ to create one of these.
+
+ :meth:`connect` must be called before it is usable. This will also load the
+ list of keys the agent contains. You must also call :meth:`close` in
+ order to clean up the unix socket and the thread that maintains it.
+ (:class:`contextlib.closing` might be helpful to you.)
+
:param .Transport t: Transport used for SSH Agent communication forwarding
:raises: `.SSHException` -- mostly if we lost the agent
diff --git a/paramiko/client.py b/paramiko/client.py
index e9bcfb56..1fe14b07 100644
--- a/paramiko/client.py
+++ b/paramiko/client.py
@@ -233,6 +233,7 @@ class SSHClient(ClosingContextManager):
gss_host=None,
banner_timeout=None,
auth_timeout=None,
+ channel_timeout=None,
gss_trust_dns=True,
passphrase=None,
disabled_algorithms=None,
@@ -311,6 +312,8 @@ class SSHClient(ClosingContextManager):
for the SSH banner to be presented.
:param float auth_timeout: an optional timeout (in seconds) to wait for
an authentication response.
+ :param float channel_timeout: an optional timeout (in seconds) to wait
+ for a channel open response.
:param dict disabled_algorithms:
an optional dict passed directly to `.Transport` and its keyword
argument of the same name.
@@ -406,6 +409,8 @@ class SSHClient(ClosingContextManager):
t.banner_timeout = banner_timeout
if auth_timeout is not None:
t.auth_timeout = auth_timeout
+ if channel_timeout is not None:
+ t.channel_timeout = channel_timeout
if port == SSH_PORT:
server_hostkey_name = hostname
diff --git a/paramiko/hostkeys.py b/paramiko/hostkeys.py
index b189aac6..bbfa5755 100644
--- a/paramiko/hostkeys.py
+++ b/paramiko/hostkeys.py
@@ -20,6 +20,7 @@
from base64 import encodebytes, decodebytes
import binascii
import os
+import re
from collections.abc import MutableMapping
from hashlib import sha1
@@ -328,7 +329,8 @@ class HostKeyEntry:
"""
Parses the given line of text to find the names for the host,
the type of key, and the key data. The line is expected to be in the
- format used by the OpenSSH known_hosts file.
+ format used by the OpenSSH known_hosts file. Fields are separated by a
+ single space or tab.
Lines are expected to not have leading or trailing whitespace.
We don't bother to check for comments or empty lines. All of
@@ -337,7 +339,7 @@ class HostKeyEntry:
:param str line: a line from an OpenSSH known_hosts file
"""
log = get_logger("paramiko.hostkeys")
- fields = line.split(" ")
+ fields = re.split(" |\t", line)
if len(fields) < 3:
# Bad number of fields
msg = "Not enough fields found in known_hosts in line {} ({!r})"
diff --git a/paramiko/server.py b/paramiko/server.py
index 3875b8a2..6b0bb0f6 100644
--- a/paramiko/server.py
+++ b/paramiko/server.py
@@ -517,6 +517,9 @@ class ServerInterface:
:param .Channel channel: the `.Channel` the request arrived on
:return: ``True`` if the AgentForward was loaded; ``False`` if not
+
+ If ``True`` is returned, the server should create an
+ :class:`AgentServerProxy` to access the agent.
"""
return False
diff --git a/paramiko/transport.py b/paramiko/transport.py
index 569c5cdd..98cdae03 100644
--- a/paramiko/transport.py
+++ b/paramiko/transport.py
@@ -516,6 +516,8 @@ class Transport(threading.Thread, ClosingContextManager):
self.handshake_timeout = 15
# how long (seconds) to wait for the auth response.
self.auth_timeout = 30
+ # how long (seconds) to wait for opening a channel
+ self.channel_timeout = 60 * 60
self.disabled_algorithms = disabled_algorithms or {}
self.server_sig_algs = server_sig_algs
@@ -1015,7 +1017,7 @@ class Transport(threading.Thread, ClosingContextManager):
"""
if not self.active:
raise SSHException("SSH session not active")
- timeout = 3600 if timeout is None else timeout
+ timeout = self.channel_timeout if timeout is None else timeout
self.lock.acquire()
try:
window_size = self._sanitize_window_size(window_size)