diff options
-rw-r--r-- | paramiko/client.py | 60 | ||||
-rw-r--r-- | paramiko/common.py | 7 | ||||
-rw-r--r-- | paramiko/hostkeys.py | 3 | ||||
-rw-r--r-- | paramiko/util.py | 26 |
4 files changed, 66 insertions, 30 deletions
diff --git a/paramiko/client.py b/paramiko/client.py index 18139416..3bb78e9f 100644 --- a/paramiko/client.py +++ b/paramiko/client.py @@ -197,14 +197,16 @@ class SSHClient (ClosingContextManager): :returns: Yields an iterable of ``(family, address)`` tuples """ guess = True - addrinfos = 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: yield family, sockaddr guess = False - # some OS like AIX don't indicate SOCK_STREAM support, so just guess. :( - # We only do this if we did not get a single result marked as socktype == SOCK_STREAM. + # some OS like AIX don't indicate SOCK_STREAM support, so just + # guess. :( We only do this if we did not get a single result marked + # as socktype == SOCK_STREAM. if guess: for family, _, _, _, sockaddr in addrinfos: yield family, sockaddr @@ -323,7 +325,8 @@ class SSHClient (ClosingContextManager): if len(errors) == len(to_try): raise NoValidConnectionsError(errors) - t = self._transport = Transport(sock, gss_kex=gss_kex, gss_deleg_creds=gss_deleg_creds) + t = self._transport = Transport( + sock, gss_kex=gss_kex, gss_deleg_creds=gss_deleg_creds) t.use_compression(compress=compress) if gss_kex and gss_host is None: t.set_gss_host(hostname) @@ -357,7 +360,8 @@ class SSHClient (ClosingContextManager): our_server_key = self._host_keys.get(server_hostkey_name, {}).get(keytype, None) if our_server_key is None: - # will raise exception if the key is rejected; let that fall out + # will raise exception if the key is rejected; + # let that fall out self._policy.missing_host_key(self, server_hostkey_name, server_key) # if the callback returns, assume the key is ok @@ -485,7 +489,7 @@ class SSHClient (ClosingContextManager): saved_exception = None two_factor = False allowed_types = set() - two_factor_types = set(['keyboard-interactive','password']) + two_factor_types = set(['keyboard-interactive', 'password']) # If GSS-API support and GSS-PI Key Exchange was performed, we attempt # authentication with gssapi-keyex. @@ -510,8 +514,11 @@ class SSHClient (ClosingContextManager): if pkey is not None: try: - self._log(DEBUG, 'Trying SSH key %s' % hexlify(pkey.get_fingerprint())) - allowed_types = set(self._transport.auth_publickey(username, pkey)) + self._log( + DEBUG, + 'Trying SSH key %s' % hexlify(pkey.get_fingerprint())) + allowed_types = set( + self._transport.auth_publickey(username, pkey)) two_factor = (allowed_types & two_factor_types) if not two_factor: return @@ -522,9 +529,14 @@ class SSHClient (ClosingContextManager): for key_filename in key_filenames: for pkey_class in (RSAKey, DSSKey, ECDSAKey): try: - key = pkey_class.from_private_key_file(key_filename, password) - self._log(DEBUG, 'Trying key %s from %s' % (hexlify(key.get_fingerprint()), key_filename)) - allowed_types = set(self._transport.auth_publickey(username, key)) + key = pkey_class.from_private_key_file( + key_filename, password) + self._log( + DEBUG, + 'Trying key %s from %s' % ( + hexlify(key.get_fingerprint()), key_filename)) + allowed_types = set( + self._transport.auth_publickey(username, key)) two_factor = (allowed_types & two_factor_types) if not two_factor: return @@ -538,9 +550,14 @@ class SSHClient (ClosingContextManager): for key in self._agent.get_keys(): try: - self._log(DEBUG, 'Trying SSH agent key %s' % hexlify(key.get_fingerprint())) - # for 2-factor auth a successfully auth'd key password will return an allowed 2fac auth method - allowed_types = set(self._transport.auth_publickey(username, key)) + self._log( + DEBUG, + 'Trying SSH agent key %s' % hexlify( + key.get_fingerprint())) + # for 2-factor auth a successfully auth'd key password + # will return an allowed 2fac auth method + allowed_types = set( + self._transport.auth_publickey(username, key)) two_factor = (allowed_types & two_factor_types) if not two_factor: return @@ -576,9 +593,15 @@ class SSHClient (ClosingContextManager): for pkey_class, filename in keyfiles: try: key = pkey_class.from_private_key_file(filename, password) - self._log(DEBUG, 'Trying discovered key %s in %s' % (hexlify(key.get_fingerprint()), filename)) - # for 2-factor auth a successfully auth'd key will result in ['password'] - allowed_types = set(self._transport.auth_publickey(username, key)) + self._log( + DEBUG, + 'Trying discovered key %s in %s' % ( + hexlify(key.get_fingerprint()), filename)) + + # for 2-factor auth a successfully auth'd key will result + # in ['password'] + allowed_types = set( + self._transport.auth_publickey(username, key)) two_factor = (allowed_types & two_factor_types) if not two_factor: return @@ -662,4 +685,5 @@ class WarningPolicy (MissingHostKeyPolicy): """ def missing_host_key(self, client, hostname, key): warnings.warn('Unknown %s host key for %s: %s' % - (key.get_name(), hostname, hexlify(key.get_fingerprint()))) + (key.get_name(), hostname, hexlify( + key.get_fingerprint()))) diff --git a/paramiko/common.py b/paramiko/common.py index 0b0cc2a7..3dc4421d 100644 --- a/paramiko/common.py +++ b/paramiko/common.py @@ -22,8 +22,8 @@ Common constants and global variables. import logging from paramiko.py3compat import byte_chr, PY2, bytes_types, string_types, b, long -MSG_DISCONNECT, MSG_IGNORE, MSG_UNIMPLEMENTED, MSG_DEBUG, MSG_SERVICE_REQUEST, \ - MSG_SERVICE_ACCEPT = range(1, 7) +MSG_DISCONNECT, MSG_IGNORE, MSG_UNIMPLEMENTED, MSG_DEBUG, \ + MSG_SERVICE_REQUEST, MSG_SERVICE_ACCEPT = range(1, 7) MSG_KEXINIT, MSG_NEWKEYS = range(20, 22) MSG_USERAUTH_REQUEST, MSG_USERAUTH_FAILURE, MSG_USERAUTH_SUCCESS, \ MSG_USERAUTH_BANNER = range(50, 54) @@ -55,7 +55,8 @@ cMSG_USERAUTH_INFO_REQUEST = byte_chr(MSG_USERAUTH_INFO_REQUEST) cMSG_USERAUTH_INFO_RESPONSE = byte_chr(MSG_USERAUTH_INFO_RESPONSE) cMSG_USERAUTH_GSSAPI_RESPONSE = byte_chr(MSG_USERAUTH_GSSAPI_RESPONSE) cMSG_USERAUTH_GSSAPI_TOKEN = byte_chr(MSG_USERAUTH_GSSAPI_TOKEN) -cMSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE = byte_chr(MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE) +cMSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE = \ + byte_chr(MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE) cMSG_USERAUTH_GSSAPI_ERROR = byte_chr(MSG_USERAUTH_GSSAPI_ERROR) cMSG_USERAUTH_GSSAPI_ERRTOK = byte_chr(MSG_USERAUTH_GSSAPI_ERRTOK) cMSG_USERAUTH_GSSAPI_MIC = byte_chr(MSG_USERAUTH_GSSAPI_MIC) diff --git a/paramiko/hostkeys.py b/paramiko/hostkeys.py index b2a80ca1..001471ac 100644 --- a/paramiko/hostkeys.py +++ b/paramiko/hostkeys.py @@ -233,6 +233,9 @@ class HostKeys (MutableMapping): raise KeyError(key) return ret + def __delitem__(self, key): + pass # Needed for instantiating HostKeys. + def __setitem__(self, hostname, entry): # don't use this please. if len(entry) == 0: diff --git a/paramiko/util.py b/paramiko/util.py index b69e8882..f6885c60 100644 --- a/paramiko/util.py +++ b/paramiko/util.py @@ -35,7 +35,8 @@ from paramiko.config import SSHConfig def inflate_long(s, always_positive=False): - """turns a normalized byte string into a long-int (adapted from Crypto.Util.number)""" + """turns a normalized byte string into a long-int + (adapted from Crypto.Util.number)""" out = long(0) negative = 0 if not always_positive and (len(s) > 0) and (byte_ord(s[0]) >= 0x80): @@ -48,17 +49,19 @@ def inflate_long(s, always_positive=False): # noinspection PyAugmentAssignment s = filler * (4 - len(s) % 4) + s for i in range(0, len(s), 4): - out = (out << 32) + struct.unpack('>I', s[i:i+4])[0] + out = (out << 32) + struct.unpack('>I', s[i:i + 4])[0] if negative: out -= (long(1) << (8 * len(s))) return out + deflate_zero = zero_byte if PY2 else 0 deflate_ff = max_byte if PY2 else 0xff def deflate_long(n, add_sign_padding=True): - """turns a long-int into a normalized byte string (adapted from Crypto.Util.number)""" + """turns a long-int into a normalized byte string + (adapted from Crypto.Util.number)""" # after much testing, this algorithm was deemed to be the fastest s = bytes() n = long(n) @@ -91,7 +94,7 @@ def format_binary(data, prefix=''): x = 0 out = [] while len(data) > x + 16: - out.append(format_binary_line(data[x:x+16])) + out.append(format_binary_line(data[x:x + 16])) x += 16 if x < len(data): out.append(format_binary_line(data[x:])) @@ -100,7 +103,7 @@ def format_binary(data, prefix=''): def format_binary_line(data): left = ' '.join(['%02X' % byte_ord(c) for c in data]) - right = ''.join([('.%c..' % c)[(byte_ord(c)+63)//95] for c in data]) + right = ''.join([('.%c..' % c)[(byte_ord(c) + 63) // 95] for c in data]) return '%-50s %s' % (left, right) @@ -215,6 +218,7 @@ def mod_inverse(x, m): u2 += m return u2 + _g_thread_ids = {} _g_thread_counter = 0 _g_thread_lock = threading.Lock() @@ -236,15 +240,17 @@ def get_thread_id(): def log_to_file(filename, level=DEBUG): - """send paramiko logs to a logfile, if they're not already going somewhere""" + """send paramiko logs to a logfile, + if they're not already going somewhere""" l = logging.getLogger("paramiko") if len(l.handlers) > 0: return l.setLevel(level) f = open(filename, 'a') lh = logging.StreamHandler(f) - lh.setFormatter(logging.Formatter('%(levelname)-.3s [%(asctime)s.%(msecs)03d] thr=%(_threadid)-3d %(name)s: %(message)s', - '%Y%m%d-%H:%M:%S')) + frm = '%(levelname)-.3s [%(asctime)s.%(msecs)03d] thr=%(_threadid)-3d ' \ + '%(name)s: %(message)s' + lh.setFormatter(logging.Formatter(frm, '%Y%m%d-%H:%M:%S')) l.addHandler(lh) @@ -253,6 +259,8 @@ class PFilter (object): def filter(self, record): record._threadid = get_thread_id() return True + + _pfilter = PFilter() @@ -277,7 +285,7 @@ def constant_time_bytes_eq(a, b): return False res = 0 # noinspection PyUnresolvedReferences - for i in (xrange if PY2 else range)(len(a)): + for i in (xrange if PY2 else range)(len(a)): # noqa: F821 res |= byte_ord(a[i]) ^ byte_ord(b[i]) return res == 0 |