summaryrefslogtreecommitdiffhomepage
path: root/paramiko/transport.py
diff options
context:
space:
mode:
Diffstat (limited to 'paramiko/transport.py')
-rw-r--r--paramiko/transport.py365
1 files changed, 250 insertions, 115 deletions
diff --git a/paramiko/transport.py b/paramiko/transport.py
index eed00bc7..96bd4a07 100644
--- a/paramiko/transport.py
+++ b/paramiko/transport.py
@@ -16,7 +16,6 @@
# along with Paramiko; if not, write to the Free Software Foundation, Inc.,
# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
-# flake8: noqa
"""
Core protocol implementation
"""
@@ -57,7 +56,7 @@ from paramiko.dsskey import DSSKey
from paramiko.kex_gex import KexGex, KexGexSHA256
from paramiko.kex_group1 import KexGroup1
from paramiko.kex_group14 import KexGroup14
-from paramiko.kex_gss import KexGSSGex, KexGSSGroup1, KexGSSGroup14, NullHostKey
+from paramiko.kex_gss import KexGSSGex, KexGSSGroup1, KexGSSGroup14
from paramiko.message import Message
from paramiko.packet import Packetizer, NeedRekeyException
from paramiko.primes import ModulusPack
@@ -66,8 +65,9 @@ from paramiko.rsakey import RSAKey
from paramiko.ecdsakey import ECDSAKey
from paramiko.server import ServerInterface
from paramiko.sftp_client import SFTPClient
-from paramiko.ssh_exception import (SSHException, BadAuthenticationType,
- ChannelException, ProxyCommandFailure)
+from paramiko.ssh_exception import (
+ SSHException, BadAuthenticationType, ChannelException, ProxyCommandFailure,
+)
from paramiko.util import retry_on_signal, ClosingContextManager, clamp_value
@@ -125,7 +125,7 @@ class Transport (threading.Thread, ClosingContextManager):
'ssh-rsa',
'ssh-dss',
) + tuple(ECDSAKey.supported_key_format_identifiers())
- _preferred_kex = (
+ _preferred_kex = (
'diffie-hellman-group1-sha1',
'diffie-hellman-group14-sha1',
'diffie-hellman-group-exchange-sha1',
@@ -242,8 +242,8 @@ class Transport (threading.Thread, ClosingContextManager):
gss_deleg_creds=True):
"""
Create a new SSH session over an existing socket, or socket-like
- object. This only creates the `.Transport` object; it doesn't begin the
- SSH session yet. Use `connect` or `start_client` to begin a client
+ object. This only creates the `.Transport` object; it doesn't begin
+ the SSH session yet. Use `connect` or `start_client` to begin a client
session, or `start_server` to begin a server session.
If the object is not actually a socket, it must have the following
@@ -298,10 +298,13 @@ class Transport (threading.Thread, ClosingContextManager):
# connect to the given (host, port)
hostname, port = sock
reason = 'No suitable address family'
- for (family, socktype, proto, canonname, sockaddr) in socket.getaddrinfo(hostname, port, socket.AF_UNSPEC, socket.SOCK_STREAM):
+ addrinfos = socket.getaddrinfo(
+ hostname, port, socket.AF_UNSPEC, socket.SOCK_STREAM
+ )
+ for family, socktype, proto, canonname, sockaddr in addrinfos:
if socktype == socket.SOCK_STREAM:
af = family
- addr = sockaddr
+ # addr = sockaddr
sock = socket.socket(af, socket.SOCK_STREAM)
try:
retry_on_signal(lambda: sock.connect((hostname, port)))
@@ -361,7 +364,8 @@ class Transport (threading.Thread, ClosingContextManager):
self.in_kex = False
self.authenticated = False
self._expected_packet = tuple()
- self.lock = threading.Lock() # synchronization (always higher level than write_lock)
+ # synchronization (always higher level than write_lock)
+ self.lock = threading.Lock()
# tracking open channels
self._channels = ChannelMap()
@@ -382,11 +386,15 @@ class Transport (threading.Thread, ClosingContextManager):
self.logger = util.get_logger(self.log_name)
self.packetizer.set_log(self.logger)
self.auth_handler = None
- self.global_response = None # response Message from an arbitrary global request
- 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.
-
+ # response Message from an arbitrary global request
+ self.global_response = None
+ # user-defined event callbacks
+ self.completion_event = None
+ # how long (seconds) to wait for the SSH banner
+ self.banner_timeout = 15
+ # how long (seconds) to wait for the handshake to finish after SSH
+ # banner sent.
+ self.handshake_timeout = 15
# server mode:
self.server_mode = False
@@ -405,8 +413,10 @@ class Transport (threading.Thread, ClosingContextManager):
out += ' (unconnected)'
else:
if self.local_cipher != '':
- out += ' (cipher %s, %d bits)' % (self.local_cipher,
- self._cipher_info[self.local_cipher]['key-size'] * 8)
+ out += ' (cipher %s, %d bits)' % (
+ self.local_cipher,
+ self._cipher_info[self.local_cipher]['key-size'] * 8
+ )
if self.is_authenticated():
out += ' (active; %d open channel(s))' % len(self._channels)
elif self.initial_kex_done:
@@ -683,7 +693,12 @@ class Transport (threading.Thread, ClosingContextManager):
"""
return self.active
- def open_session(self, window_size=None, max_packet_size=None, timeout=None):
+ def open_session(
+ self,
+ window_size=None,
+ max_packet_size=None,
+ timeout=None,
+ ):
"""
Request a new channel to the server, of type ``"session"``. This is
just an alias for calling `open_channel` with an argument of
@@ -744,7 +759,8 @@ class Transport (threading.Thread, ClosingContextManager):
def open_forwarded_tcpip_channel(self, src_addr, dest_addr):
"""
- Request a new channel back to the client, of type ``"forwarded-tcpip"``.
+ Request a new channel back to the client, of type ``forwarded-tcpip``.
+
This is used after a client has requested port forwarding, for sending
incoming connections back to the client.
@@ -853,7 +869,11 @@ class Transport (threading.Thread, ClosingContextManager):
If a handler is given, that handler is called from a different thread
whenever a forwarded connection arrives. The handler parameters are::
- handler(channel, (origin_addr, origin_port), (server_addr, server_port))
+ handler(
+ channel,
+ (origin_addr, origin_port),
+ (server_addr, server_port),
+ )
where ``server_addr`` and ``server_port`` are the address and port that
the server was listening on.
@@ -876,15 +896,17 @@ class Transport (threading.Thread, ClosingContextManager):
if not self.active:
raise SSHException('SSH session not active')
port = int(port)
- response = self.global_request('tcpip-forward', (address, port), wait=True)
+ response = self.global_request(
+ 'tcpip-forward', (address, port), wait=True
+ )
if response is None:
raise SSHException('TCP forwarding request denied')
if port == 0:
port = response.get_int()
if handler is None:
def default_handler(channel, src_addr, dest_addr_port):
- #src_addr, src_port = src_addr_port
- #dest_addr, dest_port = dest_addr_port
+ # src_addr, src_port = src_addr_port
+ # dest_addr, dest_port = dest_addr_port
self._queue_incoming_channel(channel)
handler = default_handler
self._tcp_handler = handler
@@ -970,8 +992,9 @@ class Transport (threading.Thread, ClosingContextManager):
seconds to wait before sending a keepalive packet (or
0 to disable keepalives).
"""
- self.packetizer.set_keepalive(interval,
- lambda x=weakref.proxy(self): x.global_request('keepalive@lag.net', wait=False))
+ def _request(x=weakref.proxy(self)):
+ return x.global_request('keepalive@lag.net', wait=False)
+ self.packetizer.set_keepalive(interval, _request)
def global_request(self, kind, data=None, wait=True):
"""
@@ -1013,8 +1036,8 @@ class Transport (threading.Thread, ClosingContextManager):
def accept(self, timeout=None):
"""
Return the next channel opened by the client over this transport, in
- server mode. If no channel is opened before the given timeout, ``None``
- is returned.
+ server mode. If no channel is opened before the given timeout,
+ ``None`` is returned.
:param int timeout:
seconds to wait for a channel, or ``None`` to wait forever
@@ -1035,8 +1058,17 @@ class Transport (threading.Thread, ClosingContextManager):
self.lock.release()
return chan
- def connect(self, hostkey=None, username='', password=None, pkey=None,
- gss_host=None, gss_auth=False, gss_kex=False, gss_deleg_creds=True):
+ def connect(
+ self,
+ hostkey=None,
+ username='',
+ password=None,
+ pkey=None,
+ gss_host=None,
+ gss_auth=False,
+ gss_kex=False,
+ gss_deleg_creds=True,
+ ):
"""
Negotiate an SSH2 session, and optionally verify the server's host key
and authenticate using a password or private key. This is a shortcut
@@ -1088,16 +1120,23 @@ class Transport (threading.Thread, ClosingContextManager):
# the host key.
if (hostkey is not None) and not gss_kex:
key = self.get_remote_server_key()
- if (key.get_name() != hostkey.get_name()) or (key.asbytes() != hostkey.asbytes()):
+ if (
+ key.get_name() != hostkey.get_name() or
+ key.asbytes() != hostkey.asbytes()
+ ):
self._log(DEBUG, 'Bad host key from server')
- self._log(DEBUG, 'Expected: %s: %s' % (hostkey.get_name(), repr(hostkey.asbytes())))
- self._log(DEBUG, 'Got : %s: %s' % (key.get_name(), repr(key.asbytes())))
+ self._log(DEBUG, 'Expected: %s: %s' % (
+ hostkey.get_name(), repr(hostkey.asbytes()))
+ )
+ self._log(DEBUG, 'Got : %s: %s' % (
+ key.get_name(), repr(key.asbytes()))
+ )
raise SSHException('Bad host key from server')
self._log(DEBUG, 'Host key verified (%s)' % hostkey.get_name())
if (pkey is not None) or (password is not None) or gss_auth or gss_kex:
if gss_auth:
- self._log(DEBUG, 'Attempting GSS-API auth... (gssapi-with-mic)')
+ self._log(DEBUG, 'Attempting GSS-API auth... (gssapi-with-mic)') # noqa
self.auth_gssapi_with_mic(username, gss_host, gss_deleg_creds)
elif gss_kex:
self._log(DEBUG, 'Attempting GSS-API auth... (gssapi-keyex)')
@@ -1160,7 +1199,11 @@ class Transport (threading.Thread, ClosingContextManager):
successfully; False if authentication failed and/or the session is
closed.
"""
- return self.active and (self.auth_handler is not None) and self.auth_handler.is_authenticated()
+ return (
+ self.active and
+ self.auth_handler is not None and
+ self.auth_handler.is_authenticated()
+ )
def get_username(self):
"""
@@ -1259,7 +1302,8 @@ class Transport (threading.Thread, ClosingContextManager):
:raises SSHException: if there was a network error
"""
if (not self.active) or (not self.initial_kex_done):
- # we should never try to send the password unless we're on a secure link
+ # we should never try to send the password unless we're on a secure
+ # link
raise SSHException('No existing session')
if event is None:
my_event = threading.Event()
@@ -1273,7 +1317,8 @@ class Transport (threading.Thread, ClosingContextManager):
try:
return self.auth_handler.wait_for_response(my_event)
except BadAuthenticationType as e:
- # if password auth isn't allowed, but keyboard-interactive *is*, try to fudge it
+ # if password auth isn't allowed, but keyboard-interactive *is*,
+ # try to fudge it
if not fallback or ('keyboard-interactive' not in e.allowed_types):
raise
try:
@@ -1387,7 +1432,9 @@ class Transport (threading.Thread, ClosingContextManager):
raise SSHException('No existing session')
my_event = threading.Event()
self.auth_handler = AuthHandler(self)
- self.auth_handler.auth_interactive(username, handler, my_event, submethods)
+ self.auth_handler.auth_interactive(
+ username, handler, my_event, submethods
+ )
return self.auth_handler.wait_for_response(my_event)
def auth_interactive_dumb(self, username, handler=None, submethods=''):
@@ -1405,8 +1452,8 @@ class Transport (threading.Thread, ClosingContextManager):
print(title.strip())
if instructions:
print(instructions.strip())
- for prompt,show_input in prompt_list:
- print(prompt.strip(),end=' ')
+ for prompt, show_input in prompt_list:
+ print(prompt.strip(), end=' ')
answers.append(input())
return answers
return self.auth_interactive(username, handler, submethods)
@@ -1432,7 +1479,9 @@ class Transport (threading.Thread, ClosingContextManager):
raise SSHException('No existing session')
my_event = threading.Event()
self.auth_handler = AuthHandler(self)
- self.auth_handler.auth_gssapi_with_mic(username, gss_host, gss_deleg_creds, my_event)
+ self.auth_handler.auth_gssapi_with_mic(
+ username, gss_host, gss_deleg_creds, my_event
+ )
return self.auth_handler.wait_for_response(my_event)
def auth_gssapi_keyex(self, username):
@@ -1526,9 +1575,10 @@ class Transport (threading.Thread, ClosingContextManager):
def getpeername(self):
"""
Return the address of the remote side of this Transport, if possible.
- This is effectively a wrapper around ``'getpeername'`` on the underlying
- socket. If the socket-like object has no ``'getpeername'`` method,
- then ``("unknown", 0)`` is returned.
+
+ This is effectively a wrapper around ``getpeername`` on the underlying
+ socket. If the socket-like object has no ``getpeername`` method, then
+ ``("unknown", 0)`` is returned.
:return:
the address of the remote host, if known, as a ``(str, int)``
@@ -1555,12 +1605,14 @@ class Transport (threading.Thread, ClosingContextManager):
# our socket and packetizer are both closed (but where we'd
# otherwise be sitting forever on that recv()).
while (
- self.is_alive() and self is not threading.current_thread()
- and not self.sock._closed and not self.packetizer.closed
+ self.is_alive() and
+ self is not threading.current_thread() and
+ not self.sock._closed and
+ not self.packetizer.closed
):
self.join(0.1)
- ### internals...
+ # internals...
def _log(self, level, msg, *args):
if issubclass(type(msg), list):
@@ -1598,28 +1650,32 @@ class Transport (threading.Thread, ClosingContextManager):
while True:
self.clear_to_send.wait(0.1)
if not self.active:
- self._log(DEBUG, 'Dropping user packet because connection is dead.')
+ self._log(DEBUG, 'Dropping user packet because connection is dead.') # noqa
return
self.clear_to_send_lock.acquire()
if self.clear_to_send.is_set():
break
self.clear_to_send_lock.release()
if time.time() > start + self.clear_to_send_timeout:
- raise SSHException('Key-exchange timed out waiting for key negotiation')
+ raise SSHException('Key-exchange timed out waiting for key negotiation') # noqa
try:
self._send_message(data)
finally:
self.clear_to_send_lock.release()
def _set_K_H(self, k, h):
- """used by a kex object to set the K (root key) and H (exchange hash)"""
+ """
+ Used by a kex obj to set the K (root key) and H (exchange hash).
+ """
self.K = k
self.H = h
if self.session_id is None:
self.session_id = h
def _expect_packet(self, *ptypes):
- """used by a kex object to register the next packet type it expects to see"""
+ """
+ Used by a kex obj to register the next packet type it expects to see.
+ """
self._expected_packet = tuple(ptypes)
def _verify_key(self, host_key, sig):
@@ -1627,7 +1683,7 @@ class Transport (threading.Thread, ClosingContextManager):
if key is None:
raise SSHException('Unknown host key type')
if not key.verify_ssh_sig(self.H, Message(sig)):
- raise SSHException('Signature verification (%s) failed.' % self.host_key_type)
+ raise SSHException('Signature verification (%s) failed.' % self.host_key_type) # noqa
self.host_key = key
def _compute_key(self, id, nbytes):
@@ -1640,7 +1696,9 @@ class Transport (threading.Thread, ClosingContextManager):
# Fallback to SHA1 for kex engines that fail to specify a hex
# algorithm, or for e.g. transport tests that don't run kexinit.
hash_algo = getattr(self.kex_engine, 'hash_algo', None)
- hash_select_msg = "kex engine %s specified hash_algo %r" % (self.kex_engine.__class__.__name__, hash_algo)
+ hash_select_msg = "kex engine %s specified hash_algo %r" % (
+ self.kex_engine.__class__.__name__, hash_algo
+ )
if hash_algo is None:
hash_algo = sha1
hash_select_msg += ", falling back to sha1"
@@ -1736,14 +1794,15 @@ class Transport (threading.Thread, ClosingContextManager):
# active=True occurs before the thread is launched, to avoid a race
_active_threads.append(self)
+ tid = hex(long(id(self)) & xffffffff)
if self.server_mode:
- self._log(DEBUG, 'starting thread (server mode): %s' % hex(long(id(self)) & xffffffff))
+ self._log(DEBUG, 'starting thread (server mode): %s' % tid)
else:
- self._log(DEBUG, 'starting thread (client mode): %s' % hex(long(id(self)) & xffffffff))
+ self._log(DEBUG, 'starting thread (client mode): %s' % tid)
try:
try:
self.packetizer.write_all(b(self.local_version + '\r\n'))
- self._log(DEBUG, 'Local version/idstring: %s' % self.local_version)
+ self._log(DEBUG, 'Local version/idstring: %s' % self.local_version) # noqa
self._check_banner()
# The above is actually very much part of the handshake, but
# sometimes the banner can be read but the machine is not
@@ -1775,7 +1834,7 @@ class Transport (threading.Thread, ClosingContextManager):
continue
if len(self._expected_packet) > 0:
if ptype not in self._expected_packet:
- raise SSHException('Expecting packet from %r, got %d' % (self._expected_packet, ptype))
+ raise SSHException('Expecting packet from %r, got %d' % (self._expected_packet, ptype)) # noqa
self._expected_packet = tuple()
if (ptype >= 30) and (ptype <= 41):
self.kex_engine.parse_next(ptype, m)
@@ -1789,13 +1848,17 @@ class Transport (threading.Thread, ClosingContextManager):
if chan is not None:
self._channel_handler_table[ptype](chan, m)
elif chanid in self.channels_seen:
- self._log(DEBUG, 'Ignoring message for dead channel %d' % chanid)
+ self._log(DEBUG, 'Ignoring message for dead channel %d' % chanid) # noqa
else:
- self._log(ERROR, 'Channel request for unknown channel %d' % chanid)
+ self._log(ERROR, 'Channel request for unknown channel %d' % chanid) # noqa
self.active = False
self.packetizer.close()
- elif (self.auth_handler is not None) and (ptype in self.auth_handler._handler_table):
- self.auth_handler._handler_table[ptype](self.auth_handler, m)
+ elif (
+ self.auth_handler is not None and
+ ptype in self.auth_handler._handler_table
+ ):
+ handler = self.auth_handler._handler_table[ptype]
+ handler(self.auth_handler, m)
else:
self._log(WARNING, 'Oops, unhandled type %d' % ptype)
msg = Message()
@@ -1862,7 +1925,7 @@ class Transport (threading.Thread, ClosingContextManager):
msg += "local={0}, remote={1}".format(local, remote)
self._log(DEBUG, msg)
- ### protocol stages
+ # protocol stages
def _negotiate_keys(self, m):
# throws SSHException on anything unusual
@@ -1891,7 +1954,9 @@ class Transport (threading.Thread, ClosingContextManager):
except ProxyCommandFailure:
raise
except Exception as e:
- raise SSHException('Error reading SSH protocol banner' + str(e))
+ raise SSHException(
+ 'Error reading SSH protocol banner' + str(e)
+ )
if buf[:4] == 'SSH-':
break
self._log(DEBUG, 'Banner: ' + buf)
@@ -1913,8 +1978,10 @@ class Transport (threading.Thread, ClosingContextManager):
version = segs[1]
client = segs[2]
if version != '1.99' and version != '2.0':
- raise SSHException('Incompatible version (%s instead of 2.0)' % (version,))
- self._log(INFO, 'Connected (version %s, client %s)' % (version, client))
+ msg = 'Incompatible version ({0} instead of 2.0)'
+ raise SSHException(msg.format(version))
+ msg = 'Connected (version {0}, client {1})'.format(version, client)
+ self._log(INFO, msg)
def _send_kex_init(self):
"""
@@ -1929,14 +1996,24 @@ class Transport (threading.Thread, ClosingContextManager):
self.in_kex = True
if self.server_mode:
mp_required_prefix = 'diffie-hellman-group-exchange-sha'
- kex_mp = [k for k in self._preferred_kex if k.startswith(mp_required_prefix)]
+ kex_mp = [
+ k for k
+ in self._preferred_kex
+ if k.startswith(mp_required_prefix)
+ ]
if (self._modulus_pack is None) and (len(kex_mp) > 0):
- # can't do group-exchange if we don't have a pack of potential primes
- pkex = [k for k in self.get_security_options().kex
- if not k.startswith(mp_required_prefix)]
+ # can't do group-exchange if we don't have a pack of potential
+ # primes
+ pkex = [
+ k for k
+ in self.get_security_options().kex
+ if not k.startswith(mp_required_prefix)
+ ]
self.get_security_options().kex = pkex
- available_server_keys = list(filter(list(self.server_key_dict.keys()).__contains__,
- self._preferred_keys))
+ available_server_keys = list(filter(
+ list(self.server_key_dict.keys()).__contains__,
+ self._preferred_keys
+ ))
else:
available_server_keys = self._preferred_keys
@@ -1960,7 +2037,7 @@ class Transport (threading.Thread, ClosingContextManager):
self._send_message(m)
def _parse_kex_init(self, m):
- cookie = m.get_bytes(16)
+ m.get_bytes(16) # cookie, discarded
kex_algo_list = m.get_list()
server_key_algo_list = m.get_list()
client_encrypt_algo_list = m.get_list()
@@ -1972,18 +2049,21 @@ class Transport (threading.Thread, ClosingContextManager):
client_lang_list = m.get_list()
server_lang_list = m.get_list()
kex_follows = m.get_boolean()
- unused = m.get_int()
-
- self._log(DEBUG, 'kex algos:' + str(kex_algo_list) + ' server key:' + str(server_key_algo_list) +
- ' client encrypt:' + str(client_encrypt_algo_list) +
- ' server encrypt:' + str(server_encrypt_algo_list) +
- ' client mac:' + str(client_mac_algo_list) +
- ' server mac:' + str(server_mac_algo_list) +
- ' client compress:' + str(client_compress_algo_list) +
- ' server compress:' + str(server_compress_algo_list) +
- ' client lang:' + str(client_lang_list) +
- ' server lang:' + str(server_lang_list) +
- ' kex follows?' + str(kex_follows))
+ m.get_int() # unused
+
+ self._log(DEBUG,
+ 'kex algos:' + str(kex_algo_list) +
+ ' server key:' + str(server_key_algo_list) +
+ ' client encrypt:' + str(client_encrypt_algo_list) +
+ ' server encrypt:' + str(server_encrypt_algo_list) +
+ ' client mac:' + str(client_mac_algo_list) +
+ ' server mac:' + str(server_mac_algo_list) +
+ ' client compress:' + str(client_compress_algo_list) +
+ ' server compress:' + str(server_compress_algo_list) +
+ ' client lang:' + str(client_lang_list) +
+ ' server lang:' + str(server_lang_list) +
+ ' kex follows?' + str(kex_follows)
+ )
# as a server, we pick the first item in the client's list that we
# support.
@@ -2000,34 +2080,48 @@ class Transport (threading.Thread, ClosingContextManager):
self._preferred_kex
))
if len(agreed_kex) == 0:
- raise SSHException('Incompatible ssh peer (no acceptable kex algorithm)')
+ raise SSHException('Incompatible ssh peer (no acceptable kex algorithm)') # noqa
self.kex_engine = self._kex_info[agreed_kex[0]](self)
self._log(DEBUG, "Kex agreed: %s" % agreed_kex[0])
if self.server_mode:
- available_server_keys = list(filter(list(self.server_key_dict.keys()).__contains__,
- self._preferred_keys))
- agreed_keys = list(filter(available_server_keys.__contains__, server_key_algo_list))
+ available_server_keys = list(filter(
+ list(self.server_key_dict.keys()).__contains__,
+ self._preferred_keys
+ ))
+ agreed_keys = list(filter(
+ available_server_keys.__contains__, server_key_algo_list
+ ))
else:
- agreed_keys = list(filter(server_key_algo_list.__contains__, self._preferred_keys))
+ agreed_keys = list(filter(
+ server_key_algo_list.__contains__, self._preferred_keys
+ ))
if len(agreed_keys) == 0:
- raise SSHException('Incompatible ssh peer (no acceptable host key)')
+ raise SSHException('Incompatible ssh peer (no acceptable host key)') # noqa
self.host_key_type = agreed_keys[0]
if self.server_mode and (self.get_server_key() is None):
- raise SSHException('Incompatible ssh peer (can\'t match requested host key type)')
+ raise SSHException('Incompatible ssh peer (can\'t match requested host key type)') # noqa
if self.server_mode:
- agreed_local_ciphers = list(filter(self._preferred_ciphers.__contains__,
- server_encrypt_algo_list))
- agreed_remote_ciphers = list(filter(self._preferred_ciphers.__contains__,
- client_encrypt_algo_list))
+ agreed_local_ciphers = list(filter(
+ self._preferred_ciphers.__contains__,
+ server_encrypt_algo_list
+ ))
+ agreed_remote_ciphers = list(filter(
+ self._preferred_ciphers.__contains__,
+ client_encrypt_algo_list
+ ))
else:
- agreed_local_ciphers = list(filter(client_encrypt_algo_list.__contains__,
- self._preferred_ciphers))
- agreed_remote_ciphers = list(filter(server_encrypt_algo_list.__contains__,
- self._preferred_ciphers))
- if (len(agreed_local_ciphers) == 0) or (len(agreed_remote_ciphers) == 0):
- raise SSHException('Incompatible ssh server (no acceptable ciphers)')
+ agreed_local_ciphers = list(filter(
+ client_encrypt_algo_list.__contains__,
+ self._preferred_ciphers
+ ))
+ agreed_remote_ciphers = list(filter(
+ server_encrypt_algo_list.__contains__,
+ self._preferred_ciphers
+ ))
+ if len(agreed_local_ciphers) == 0 or len(agreed_remote_ciphers) == 0:
+ raise SSHException('Incompatible ssh server (no acceptable ciphers)') # noqa
self.local_cipher = agreed_local_ciphers[0]
self.remote_cipher = agreed_remote_ciphers[0]
self._log_agreement(
@@ -2035,11 +2129,19 @@ class Transport (threading.Thread, ClosingContextManager):
)
if self.server_mode:
- agreed_remote_macs = list(filter(self._preferred_macs.__contains__, client_mac_algo_list))
- agreed_local_macs = list(filter(self._preferred_macs.__contains__, server_mac_algo_list))
+ agreed_remote_macs = list(filter(
+ self._preferred_macs.__contains__, client_mac_algo_list
+ ))
+ agreed_local_macs = list(filter(
+ self._preferred_macs.__contains__, server_mac_algo_list
+ ))
else:
- agreed_local_macs = list(filter(client_mac_algo_list.__contains__, self._preferred_macs))
- agreed_remote_macs = list(filter(server_mac_algo_list.__contains__, self._preferred_macs))
+ agreed_local_macs = list(filter(
+ client_mac_algo_list.__contains__, self._preferred_macs
+ ))
+ agreed_remote_macs = list(filter(
+ server_mac_algo_list.__contains__, self._preferred_macs
+ ))
if (len(agreed_local_macs) == 0) or (len(agreed_remote_macs) == 0):
raise SSHException('Incompatible ssh server (no acceptable macs)')
self.local_mac = agreed_local_macs[0]
@@ -2049,13 +2151,32 @@ class Transport (threading.Thread, ClosingContextManager):
)
if self.server_mode:
- agreed_remote_compression = list(filter(self._preferred_compression.__contains__, client_compress_algo_list))
- agreed_local_compression = list(filter(self._preferred_compression.__contains__, server_compress_algo_list))
+ agreed_remote_compression = list(filter(
+ self._preferred_compression.__contains__,
+ client_compress_algo_list
+ ))
+ agreed_local_compression = list(filter(
+ self._preferred_compression.__contains__,
+ server_compress_algo_list
+ ))
else:
- agreed_local_compression = list(filter(client_compress_algo_list.__contains__, self._preferred_compression))
- agreed_remote_compression = list(filter(server_compress_algo_list.__contains__, self._preferred_compression))
- if (len(agreed_local_compression) == 0) or (len(agreed_remote_compression) == 0):
- raise SSHException('Incompatible ssh server (no acceptable compression) %r %r %r' % (agreed_local_compression, agreed_remote_compression, self._preferred_compression))
+ agreed_local_compression = list(filter(
+ client_compress_algo_list.__contains__,
+ self._preferred_compression
+ ))
+ agreed_remote_compression = list(filter(
+ server_compress_algo_list.__contains__,
+ self._preferred_compression
+ ))
+ if (
+ len(agreed_local_compression) == 0 or
+ len(agreed_remote_compression) == 0
+ ):
+ msg = 'Incompatible ssh server (no acceptable compression) {0!r} {1!r} {2!r}' # noqa
+ raise SSHException(msg.format(
+ agreed_local_compression, agreed_remote_compression,
+ self._preferred_compression,
+ ))
self.local_compression = agreed_local_compression[0]
self.remote_compression = agreed_remote_compression[0]
self._log_agreement(
@@ -2077,11 +2198,17 @@ class Transport (threading.Thread, ClosingContextManager):
block_size = self._cipher_info[self.remote_cipher]['block-size']
if self.server_mode:
IV_in = self._compute_key('A', block_size)
- key_in = self._compute_key('C', self._cipher_info[self.remote_cipher]['key-size'])
+ key_in = self._compute_key(
+ 'C', self._cipher_info[self.remote_cipher]['key-size']
+ )
else:
IV_in = self._compute_key('B', block_size)
- key_in = self._compute_key('D', self._cipher_info[self.remote_cipher]['key-size'])
- engine = self._get_cipher(self.remote_cipher, key_in, IV_in, self._DECRYPT)
+ key_in = self._compute_key(
+ 'D', self._cipher_info[self.remote_cipher]['key-size']
+ )
+ engine = self._get_cipher(
+ self.remote_cipher, key_in, IV_in, self._DECRYPT
+ )
mac_size = self._mac_info[self.remote_mac]['size']
mac_engine = self._mac_info[self.remote_mac]['class']
# initial mac keys are done in the hash's natural size (not the
@@ -2090,9 +2217,17 @@ class Transport (threading.Thread, ClosingContextManager):
mac_key = self._compute_key('E', mac_engine().digest_size)
else:
mac_key = self._compute_key('F', mac_engine().digest_size)
- self.packetizer.set_inbound_cipher(engine, block_size, mac_engine, mac_size, mac_key)
+ self.packetizer.set_inbound_cipher(
+ engine, block_size, mac_engine, mac_size, mac_key
+ )
compress_in = self._compression_info[self.remote_compression][1]
- if (compress_in is not None) and ((self.remote_compression != 'zlib@openssh.com') or self.authenticated):
+ if (
+ compress_in is not None and
+ (
+ self.remote_compression != 'zlib@openssh.com' or
+ self.authenticated
+ )
+ ):
self._log(DEBUG, 'Switching on inbound compression ...')
self.packetizer.set_inbound_compressor(compress_in())