aboutsummaryrefslogtreecommitdiff
path: root/paramiko
diff options
context:
space:
mode:
authorJeremy T. Bouse <jbouse@debian.org>2015-03-12 21:35:58 -0400
committerJeremy T. Bouse <jbouse@debian.org>2015-03-12 21:35:58 -0400
commitf784a533d6e1d09e89dc254f3493b491e19c94f0 (patch)
tree6079fb034538b346b999a6fefcae4b1c557713c5 /paramiko
parent941814e1efaf9a46992476e50badcecbcbfc9a41 (diff)
downloadpython-paramiko-f784a533d6e1d09e89dc254f3493b491e19c94f0.tar
python-paramiko-f784a533d6e1d09e89dc254f3493b491e19c94f0.tar.gz
Imported Upstream version 1.15.2
Diffstat (limited to 'paramiko')
-rw-r--r--paramiko/_version.py2
-rw-r--r--paramiko/_winapi.py8
-rw-r--r--paramiko/agent.py3
-rw-r--r--paramiko/auth_handler.py2
-rw-r--r--paramiko/ber.py6
-rw-r--r--paramiko/channel.py8
-rw-r--r--paramiko/common.py6
-rw-r--r--paramiko/config.py54
-rw-r--r--paramiko/dsskey.py2
-rw-r--r--paramiko/ecdsakey.py2
-rw-r--r--paramiko/file.py16
-rw-r--r--paramiko/hostkeys.py4
-rw-r--r--paramiko/pkey.py4
-rw-r--r--paramiko/proxy.py19
-rw-r--r--paramiko/rsakey.py2
-rw-r--r--paramiko/sftp_attr.py7
-rw-r--r--paramiko/sftp_client.py4
-rw-r--r--paramiko/sftp_server.py4
-rw-r--r--paramiko/transport.py94
-rw-r--r--paramiko/util.py20
-rw-r--r--paramiko/win_pageant.py5
21 files changed, 146 insertions, 126 deletions
diff --git a/paramiko/_version.py b/paramiko/_version.py
index d9f7874..3bf9dac 100644
--- a/paramiko/_version.py
+++ b/paramiko/_version.py
@@ -1,2 +1,2 @@
-__version_info__ = (1, 15, 1)
+__version_info__ = (1, 15, 2)
__version__ = '.'.join(map(str, __version_info__))
diff --git a/paramiko/_winapi.py b/paramiko/_winapi.py
index 0d55d29..f48e189 100644
--- a/paramiko/_winapi.py
+++ b/paramiko/_winapi.py
@@ -213,12 +213,14 @@ class SECURITY_ATTRIBUTES(ctypes.Structure):
super(SECURITY_ATTRIBUTES, self).__init__(*args, **kwargs)
self.nLength = ctypes.sizeof(SECURITY_ATTRIBUTES)
- def _get_descriptor(self):
+ @property
+ def descriptor(self):
return self._descriptor
- def _set_descriptor(self, descriptor):
+
+ @descriptor.setter
+ def descriptor(self, value):
self._descriptor = descriptor
self.lpSecurityDescriptor = ctypes.addressof(descriptor)
- descriptor = property(_get_descriptor, _set_descriptor)
def GetTokenInformation(token, information_class):
"""
diff --git a/paramiko/agent.py b/paramiko/agent.py
index 4f46344..a75ac59 100644
--- a/paramiko/agent.py
+++ b/paramiko/agent.py
@@ -73,7 +73,8 @@ class AgentSSH(object):
self._keys = tuple(keys)
def _close(self):
- #self._conn.close()
+ if self._conn is not None:
+ self._conn.close()
self._conn = None
self._keys = ()
diff --git a/paramiko/auth_handler.py b/paramiko/auth_handler.py
index b5fea65..c001aee 100644
--- a/paramiko/auth_handler.py
+++ b/paramiko/auth_handler.py
@@ -195,7 +195,7 @@ class AuthHandler (object):
if (e is None) or issubclass(e.__class__, EOFError):
e = AuthenticationException('Authentication failed.')
raise e
- if event.isSet():
+ if event.is_set():
break
if not self.is_authenticated():
e = self.transport.get_exception()
diff --git a/paramiko/ber.py b/paramiko/ber.py
index 0515230..a388df0 100644
--- a/paramiko/ber.py
+++ b/paramiko/ber.py
@@ -45,7 +45,7 @@ class BER(object):
def decode(self):
return self.decode_next()
-
+
def decode_next(self):
if self.idx >= len(self.content):
return None
@@ -89,6 +89,7 @@ class BER(object):
# 1: boolean (00 false, otherwise true)
raise BERException('Unknown ber encoding type %d (robey is lazy)' % ident)
+ @staticmethod
def decode_sequence(data):
out = []
ber = BER(data)
@@ -98,7 +99,6 @@ class BER(object):
break
out.append(x)
return out
- decode_sequence = staticmethod(decode_sequence)
def encode_tlv(self, ident, val):
# no need to support ident > 31 here
@@ -125,9 +125,9 @@ class BER(object):
else:
raise BERException('Unknown type for encoding: %s' % repr(type(x)))
+ @staticmethod
def encode_sequence(data):
ber = BER()
for item in data:
ber.encode(item)
return ber.asbytes()
- encode_sequence = staticmethod(encode_sequence)
diff --git a/paramiko/channel.py b/paramiko/channel.py
index 9de278c..8a97c97 100644
--- a/paramiko/channel.py
+++ b/paramiko/channel.py
@@ -290,7 +290,7 @@ class Channel (ClosingContextManager):
.. versionadded:: 1.7.3
"""
- return self.closed or self.status_event.isSet()
+ return self.closed or self.status_event.is_set()
def recv_exit_status(self):
"""
@@ -305,7 +305,7 @@ class Channel (ClosingContextManager):
.. versionadded:: 1.2
"""
self.status_event.wait()
- assert self.status_event.isSet()
+ assert self.status_event.is_set()
return self.exit_status
def send_exit_status(self, status):
@@ -890,7 +890,7 @@ class Channel (ClosingContextManager):
self.out_max_packet_size = self.transport. \
_sanitize_packet_size(max_packet_size)
self.active = 1
- self._log(DEBUG, 'Max packet out: %d bytes' % max_packet_size)
+ self._log(DEBUG, 'Max packet out: %d bytes' % self.out_max_packet_size)
def _request_success(self, m):
self._log(DEBUG, 'Sesch channel %d request ok' % self.chanid)
@@ -1077,7 +1077,7 @@ class Channel (ClosingContextManager):
def _wait_for_event(self):
self.event.wait()
- assert self.event.isSet()
+ assert self.event.is_set()
if self.event_ready:
return
e = self.transport.get_exception()
diff --git a/paramiko/common.py b/paramiko/common.py
index 97b2f95..0b0cc2a 100644
--- a/paramiko/common.py
+++ b/paramiko/common.py
@@ -195,7 +195,11 @@ DEFAULT_MAX_PACKET_SIZE = 2 ** 15
# lower bound on the max packet size we'll accept from the remote host
# Minimum packet size is 32768 bytes according to
# http://www.ietf.org/rfc/rfc4254.txt
-MIN_PACKET_SIZE = 2 ** 15
+MIN_WINDOW_SIZE = 2 ** 15
+
+# However, according to http://www.ietf.org/rfc/rfc4253.txt it is perfectly
+# legal to accept a size much smaller, as OpenSSH client does as size 16384.
+MIN_PACKET_SIZE = 2 ** 12
# Max windows size according to http://www.ietf.org/rfc/rfc4254.txt
MAX_WINDOW_SIZE = 2**32 -1
diff --git a/paramiko/config.py b/paramiko/config.py
index 20ca4aa..233a87d 100644
--- a/paramiko/config.py
+++ b/paramiko/config.py
@@ -24,6 +24,7 @@ Configuration file (aka ``ssh_config``) support.
import fnmatch
import os
import re
+import shlex
import socket
SSH_PORT = 22
@@ -54,7 +55,6 @@ class SSHConfig (object):
:param file file_obj: a file-like object to read the config file from
"""
-
host = {"host": ['*'], "config": {}}
for line in file_obj:
line = line.rstrip('\r\n').lstrip()
@@ -73,6 +73,9 @@ class SSHConfig (object):
'host': self._get_hosts(value),
'config': {}
}
+ elif key == 'proxycommand' and value.lower() == 'none':
+ # Proxycommands of none should not be added as an actual value. (Issue #415)
+ continue
else:
if value.startswith('"') and value.endswith('"'):
value = value[1:-1]
@@ -93,13 +96,15 @@ class SSHConfig (object):
"""
Return a dict of config options for a given hostname.
- The host-matching rules of OpenSSH's ``ssh_config`` man page are used,
- which means that all configuration options from matching host
- specifications are merged, with more specific hostmasks taking
- precedence. In other words, if ``"Port"`` is set under ``"Host *"``
- and also ``"Host *.example.com"``, and the lookup is for
- ``"ssh.example.com"``, then the port entry for ``"Host *.example.com"``
- will win out.
+ The host-matching rules of OpenSSH's ``ssh_config`` man page are used:
+ For each parameter, the first obtained value will be used. The
+ configuration files contain sections separated by ``Host''
+ specifications, and that section is only applied for hosts that match
+ one of the patterns given in the specification.
+
+ Since the first obtained value for each parameter is used, more host-
+ specific declarations should be given near the beginning of the file,
+ and general defaults at the end.
The keys in the returned dict are all normalized to lowercase (look for
``"port"``, not ``"Port"``. The values are processed according to the
@@ -126,6 +131,16 @@ class SSHConfig (object):
ret = self._expand_variables(ret, hostname)
return ret
+ def get_hostnames(self):
+ """
+ Return the set of literal hostnames defined in the SSH config (both
+ explicit hostnames and wildcard entries).
+ """
+ hosts = set()
+ for entry in self._config:
+ hosts.update(entry['host'])
+ return hosts
+
def _allowed(self, hosts, hostname):
match = False
for host in hosts:
@@ -210,25 +225,10 @@ class SSHConfig (object):
"""
Return a list of host_names from host value.
"""
- i, length = 0, len(host)
- hosts = []
- while i < length:
- if host[i] == '"':
- end = host.find('"', i + 1)
- if end < 0:
- raise Exception("Unparsable host %s" % host)
- hosts.append(host[i + 1:end])
- i = end + 1
- elif not host[i].isspace():
- end = i + 1
- while end < length and not host[end].isspace() and host[end] != '"':
- end += 1
- hosts.append(host[i:end])
- i = end
- else:
- i += 1
-
- return hosts
+ try:
+ return shlex.split(host)
+ except ValueError:
+ raise Exception("Unparsable host %s" % host)
class LazyFqdn(object):
diff --git a/paramiko/dsskey.py b/paramiko/dsskey.py
index 1901596..d7dd627 100644
--- a/paramiko/dsskey.py
+++ b/paramiko/dsskey.py
@@ -154,6 +154,7 @@ class DSSKey (PKey):
def write_private_key(self, file_obj, password=None):
self._write_private_key('DSA', file_obj, self._encode_key(), password)
+ @staticmethod
def generate(bits=1024, progress_func=None):
"""
Generate a new private DSS key. This factory function can be used to
@@ -169,7 +170,6 @@ class DSSKey (PKey):
key = DSSKey(vals=(dsa.p, dsa.q, dsa.g, dsa.y))
key.x = dsa.x
return key
- generate = staticmethod(generate)
### internals...
diff --git a/paramiko/ecdsakey.py b/paramiko/ecdsakey.py
index a7f3c5e..6b04795 100644
--- a/paramiko/ecdsakey.py
+++ b/paramiko/ecdsakey.py
@@ -126,6 +126,7 @@ class ECDSAKey (PKey):
key = self.signing_key or self.verifying_key
self._write_private_key('EC', file_obj, key.to_der(), password)
+ @staticmethod
def generate(curve=curves.NIST256p, progress_func=None):
"""
Generate a new private RSA key. This factory function can be used to
@@ -139,7 +140,6 @@ class ECDSAKey (PKey):
signing_key = SigningKey.generate(curve)
key = ECDSAKey(vals=(signing_key, signing_key.get_verifying_key()))
return key
- generate = staticmethod(generate)
### internals...
diff --git a/paramiko/file.py b/paramiko/file.py
index 311e198..e3b0a16 100644
--- a/paramiko/file.py
+++ b/paramiko/file.py
@@ -206,6 +206,7 @@ class BufferedFile (ClosingContextManager):
if not (self._flags & self.FLAG_READ):
raise IOError('File not open for reading')
line = self._rbuffer
+ truncated = False
while True:
if self._at_trailing_cr and (self._flags & self.FLAG_UNIVERSAL_NEWLINE) and (len(line) > 0):
# edge case: the newline may be '\r\n' and we may have read
@@ -220,11 +221,11 @@ class BufferedFile (ClosingContextManager):
# enough.
if (size is not None) and (size >= 0):
if len(line) >= size:
- # truncate line and return
+ # truncate line
self._rbuffer = line[size:]
line = line[:size]
- self._pos += len(line)
- return line if self._flags & self.FLAG_BINARY else u(line)
+ truncated = True
+ break
n = size - len(line)
else:
n = self._bufsize
@@ -246,10 +247,17 @@ class BufferedFile (ClosingContextManager):
rpos = line.find(cr_byte)
if (rpos >= 0) and (rpos < pos or pos < 0):
pos = rpos
+ if pos == -1:
+ # we couldn't find a newline in the truncated string, return it
+ self._pos += len(line)
+ return line if self._flags & self.FLAG_BINARY else u(line)
xpos = pos + 1
if (line[pos] == cr_byte_value) and (xpos < len(line)) and (line[xpos] == linefeed_byte_value):
xpos += 1
- self._rbuffer = line[xpos:]
+ # if the string was truncated, _rbuffer needs to have the string after
+ # the newline character plus the truncated part of the line we stored
+ # earlier in _rbuffer
+ self._rbuffer = line[xpos:] + self._rbuffer if truncated else line[xpos:]
lf = line[pos:xpos]
line = line[:pos] + linefeed_byte
if (len(self._rbuffer) == 0) and (lf == cr_byte):
diff --git a/paramiko/hostkeys.py b/paramiko/hostkeys.py
index b94ff0d..8486887 100644
--- a/paramiko/hostkeys.py
+++ b/paramiko/hostkeys.py
@@ -255,6 +255,7 @@ class HostKeys (MutableMapping):
ret.append(self.lookup(k))
return ret
+ @staticmethod
def hash_host(hostname, salt=None):
"""
Return a "hashed" form of the hostname, as used by OpenSSH when storing
@@ -274,7 +275,6 @@ class HostKeys (MutableMapping):
hmac = HMAC(salt, b(hostname), sha1).digest()
hostkey = '|1|%s|%s' % (u(encodebytes(salt)), u(encodebytes(hmac)))
return hostkey.replace('\n', '')
- hash_host = staticmethod(hash_host)
class InvalidHostKey(Exception):
@@ -294,6 +294,7 @@ class HostKeyEntry:
self.hostnames = hostnames
self.key = key
+ @classmethod
def from_line(cls, line, lineno=None):
"""
Parses the given line of text to find the names for the host,
@@ -336,7 +337,6 @@ class HostKeyEntry:
raise InvalidHostKey(line, e)
return cls(names, key)
- from_line = classmethod(from_line)
def to_line(self):
"""
diff --git a/paramiko/pkey.py b/paramiko/pkey.py
index 2daf372..1b4af01 100644
--- a/paramiko/pkey.py
+++ b/paramiko/pkey.py
@@ -160,6 +160,7 @@ class PKey (object):
"""
return False
+ @classmethod
def from_private_key_file(cls, filename, password=None):
"""
Create a key object by reading a private key file. If the private
@@ -181,8 +182,8 @@ class PKey (object):
"""
key = cls(filename=filename, password=password)
return key
- from_private_key_file = classmethod(from_private_key_file)
+ @classmethod
def from_private_key(cls, file_obj, password=None):
"""
Create a key object by reading a private key from a file (or file-like)
@@ -202,7 +203,6 @@ class PKey (object):
"""
key = cls(file_obj=file_obj, password=password)
return key
- from_private_key = classmethod(from_private_key)
def write_private_key_file(self, filename, password=None):
"""
diff --git a/paramiko/proxy.py b/paramiko/proxy.py
index 0664ac6..ca602c4 100644
--- a/paramiko/proxy.py
+++ b/paramiko/proxy.py
@@ -24,6 +24,7 @@ import signal
from subprocess import Popen, PIPE
from select import select
import socket
+import time
from paramiko.ssh_exception import ProxyCommandFailure
from paramiko.util import ClosingContextManager
@@ -79,20 +80,24 @@ class ProxyCommand(ClosingContextManager):
:return: the length of the read content, as an `int`
"""
try:
- start = datetime.now()
+ start = time.time()
while len(self.buffer) < size:
+ select_timeout = None
if self.timeout is not None:
- elapsed = (datetime.now() - start).microseconds
- timeout = self.timeout * 1000 * 1000 # to microseconds
- if elapsed >= timeout:
+ elapsed = (time.time() - start)
+ if elapsed >= self.timeout:
raise socket.timeout()
- r, w, x = select([self.process.stdout], [], [], 0.0)
+ select_timeout = self.timeout - elapsed
+
+ r, w, x = select(
+ [self.process.stdout], [], [], select_timeout)
if r and r[0] == self.process.stdout:
- b = os.read(self.process.stdout.fileno(), 1)
+ b = os.read(
+ self.process.stdout.fileno(), size - len(self.buffer))
# Store in class-level buffer for persistence across
# timeouts; this makes us act more like a real socket
# (where timeouts don't actually drop data.)
- self.buffer.append(b)
+ self.buffer.extend(b)
result = ''.join(self.buffer)
self.buffer = []
return result
diff --git a/paramiko/rsakey.py b/paramiko/rsakey.py
index d1f3ecf..4ebd835 100644
--- a/paramiko/rsakey.py
+++ b/paramiko/rsakey.py
@@ -131,6 +131,7 @@ class RSAKey (PKey):
def write_private_key(self, file_obj, password=None):
self._write_private_key('RSA', file_obj, self._encode_key(), password)
+ @staticmethod
def generate(bits, progress_func=None):
"""
Generate a new private RSA key. This factory function can be used to
@@ -148,7 +149,6 @@ class RSAKey (PKey):
key.p = rsa.p
key.q = rsa.q
return key
- generate = staticmethod(generate)
### internals...
diff --git a/paramiko/sftp_attr.py b/paramiko/sftp_attr.py
index d12eff8..cf48f65 100644
--- a/paramiko/sftp_attr.py
+++ b/paramiko/sftp_attr.py
@@ -60,6 +60,7 @@ class SFTPAttributes (object):
self.st_mtime = None
self.attr = {}
+ @classmethod
def from_stat(cls, obj, filename=None):
"""
Create an `.SFTPAttributes` object from an existing ``stat`` object (an
@@ -79,13 +80,12 @@ class SFTPAttributes (object):
if filename is not None:
attr.filename = filename
return attr
- from_stat = classmethod(from_stat)
def __repr__(self):
return '<SFTPAttributes: %s>' % self._debug_str()
### internals...
-
+ @classmethod
def _from_msg(cls, msg, filename=None, longname=None):
attr = cls()
attr._unpack(msg)
@@ -94,7 +94,6 @@ class SFTPAttributes (object):
if longname is not None:
attr.longname = longname
return attr
- _from_msg = classmethod(_from_msg)
def _unpack(self, msg):
self._flags = msg.get_int()
@@ -159,6 +158,7 @@ class SFTPAttributes (object):
out += ']'
return out
+ @staticmethod
def _rwx(n, suid, sticky=False):
if suid:
suid = 2
@@ -168,7 +168,6 @@ class SFTPAttributes (object):
else:
out += '-xSs'[suid + (n & 1)]
return out
- _rwx = staticmethod(_rwx)
def __str__(self):
"""create a unix-style long description of the file (like ls -l)"""
diff --git a/paramiko/sftp_client.py b/paramiko/sftp_client.py
index 62127cc..89840ea 100644
--- a/paramiko/sftp_client.py
+++ b/paramiko/sftp_client.py
@@ -65,7 +65,7 @@ class SFTPClient(BaseSFTP, ClosingContextManager):
Used to open an SFTP session across an open SSH `.Transport` and perform
remote file operations.
-
+
Instances of this class may be used as context managers.
"""
def __init__(self, sock):
@@ -101,6 +101,7 @@ class SFTPClient(BaseSFTP, ClosingContextManager):
raise SSHException('EOF during negotiation')
self._log(INFO, 'Opened sftp connection (server version %d)' % server_version)
+ @classmethod
def from_transport(cls, t, window_size=None, max_packet_size=None):
"""
Create an SFTP client channel from an open `.Transport`.
@@ -129,7 +130,6 @@ class SFTPClient(BaseSFTP, ClosingContextManager):
return None
chan.invoke_subsystem('sftp')
return cls(chan)
- from_transport = classmethod(from_transport)
def _log(self, level, msg, *args):
if isinstance(msg, list):
diff --git a/paramiko/sftp_server.py b/paramiko/sftp_server.py
index 2d8d190..ce287e8 100644
--- a/paramiko/sftp_server.py
+++ b/paramiko/sftp_server.py
@@ -129,6 +129,7 @@ class SFTPServer (BaseSFTP, SubsystemHandler):
self.file_table = {}
self.folder_table = {}
+ @staticmethod
def convert_errno(e):
"""
Convert an errno value (as from an ``OSError`` or ``IOError``) into a
@@ -146,8 +147,8 @@ class SFTPServer (BaseSFTP, SubsystemHandler):
return SFTP_NO_SUCH_FILE
else:
return SFTP_FAILURE
- convert_errno = staticmethod(convert_errno)
+ @staticmethod
def set_file_attr(filename, attr):
"""
Change a file's attributes on the local filesystem. The contents of
@@ -173,7 +174,6 @@ class SFTPServer (BaseSFTP, SubsystemHandler):
if attr._flags & attr.FLAG_SIZE:
with open(filename, 'w+') as f:
f.truncate(attr.st_size)
- set_file_attr = staticmethod(set_file_attr)
### internals...
diff --git a/paramiko/transport.py b/paramiko/transport.py
index bf30c78..36da304 100644
--- a/paramiko/transport.py
+++ b/paramiko/transport.py
@@ -43,8 +43,8 @@ from paramiko.common import xffffffff, cMSG_CHANNEL_OPEN, cMSG_IGNORE, \
MSG_CHANNEL_OPEN_SUCCESS, MSG_CHANNEL_OPEN_FAILURE, MSG_CHANNEL_OPEN, \
MSG_CHANNEL_SUCCESS, MSG_CHANNEL_FAILURE, MSG_CHANNEL_DATA, \
MSG_CHANNEL_EXTENDED_DATA, MSG_CHANNEL_WINDOW_ADJUST, MSG_CHANNEL_REQUEST, \
- MSG_CHANNEL_EOF, MSG_CHANNEL_CLOSE, MIN_PACKET_SIZE, MAX_WINDOW_SIZE, \
- DEFAULT_WINDOW_SIZE, DEFAULT_MAX_PACKET_SIZE
+ MSG_CHANNEL_EOF, MSG_CHANNEL_CLOSE, MIN_WINDOW_SIZE, MIN_PACKET_SIZE, \
+ MAX_WINDOW_SIZE, DEFAULT_WINDOW_SIZE, DEFAULT_MAX_PACKET_SIZE
from paramiko.compress import ZlibCompressor, ZlibDecompressor
from paramiko.dsskey import DSSKey
from paramiko.kex_gex import KexGex
@@ -88,7 +88,7 @@ class Transport (threading.Thread, ClosingContextManager):
`channels <.Channel>`, across the session. Multiple channels can be
multiplexed across a single session (and often are, in the case of port
forwardings).
-
+
Instances of this class may be used as context managers.
"""
_PROTO_ID = '2.0'
@@ -277,7 +277,7 @@ class Transport (threading.Thread, ClosingContextManager):
self._channels = ChannelMap()
self.channel_events = {} # (id -> Event)
self.channels_seen = {} # (id -> True)
- self._channel_counter = 1
+ self._channel_counter = 0
self.default_max_packet_size = default_max_packet_size
self.default_window_size = default_window_size
self._forward_agent_handler = None
@@ -405,7 +405,7 @@ class Transport (threading.Thread, ClosingContextManager):
if e is not None:
raise e
raise SSHException('Negotiation failed.')
- if event.isSet():
+ if event.is_set():
break
def start_server(self, event=None, server=None):
@@ -470,7 +470,7 @@ class Transport (threading.Thread, ClosingContextManager):
if e is not None:
raise e
raise SSHException('Negotiation failed.')
- if event.isSet():
+ if event.is_set():
break
def add_server_key(self, key):
@@ -508,6 +508,7 @@ class Transport (threading.Thread, ClosingContextManager):
pass
return None
+ @staticmethod
def load_server_moduli(filename=None):
"""
(optional)
@@ -547,7 +548,6 @@ class Transport (threading.Thread, ClosingContextManager):
# none succeeded
Transport._modulus_pack = None
return False
- load_server_moduli = staticmethod(load_server_moduli)
def close(self):
"""
@@ -729,7 +729,7 @@ class Transport (threading.Thread, ClosingContextManager):
if e is None:
e = SSHException('Unable to open channel.')
raise e
- if event.isSet():
+ if event.is_set():
break
chan = self._channels.get(chanid)
if chan is not None:
@@ -849,7 +849,7 @@ class Transport (threading.Thread, ClosingContextManager):
if e is not None:
raise e
raise SSHException('Negotiation failed.')
- if self.completion_event.isSet():
+ if self.completion_event.is_set():
break
return
@@ -900,7 +900,7 @@ class Transport (threading.Thread, ClosingContextManager):
self.completion_event.wait(0.1)
if not self.active:
return None
- if self.completion_event.isSet():
+ if self.completion_event.is_set():
break
return self.global_response
@@ -1074,6 +1074,8 @@ class Transport (threading.Thread, ClosingContextManager):
supplied, this method returns ``None``.
:returns: server supplied banner (`str`), or ``None``.
+
+ .. versionadded:: 1.13
"""
if not self.active or (self.auth_handler is None):
return None
@@ -1459,7 +1461,7 @@ class Transport (threading.Thread, ClosingContextManager):
self._log(DEBUG, 'Dropping user packet because connection is dead.')
return
self.clear_to_send_lock.acquire()
- if self.clear_to_send.isSet():
+ if self.clear_to_send.is_set():
break
self.clear_to_send_lock.release()
if time.time() > start + self.clear_to_send_timeout:
@@ -1552,7 +1554,7 @@ class Transport (threading.Thread, ClosingContextManager):
def _sanitize_window_size(self, window_size):
if window_size is None:
window_size = self.default_window_size
- return clamp_value(MIN_PACKET_SIZE, window_size, MAX_WINDOW_SIZE)
+ return clamp_value(MIN_WINDOW_SIZE, window_size, MAX_WINDOW_SIZE)
def _sanitize_packet_size(self, max_packet_size):
if max_packet_size is None:
@@ -2149,7 +2151,7 @@ class Transport (threading.Thread, ClosingContextManager):
always_display = m.get_boolean()
msg = m.get_string()
lang = m.get_string()
- self._log(DEBUG, 'Debug msg: ' + util.safe_string(msg))
+ self._log(DEBUG, 'Debug msg: {0}'.format(util.safe_string(msg)))
def _get_subsystem_handler(self, name):
try:
@@ -2207,21 +2209,6 @@ class SecurityOptions (object):
"""
return '<paramiko.SecurityOptions for %s>' % repr(self._transport)
- def _get_ciphers(self):
- return self._transport._preferred_ciphers
-
- def _get_digests(self):
- return self._transport._preferred_macs
-
- def _get_key_types(self):
- return self._transport._preferred_keys
-
- def _get_kex(self):
- return self._transport._preferred_kex
-
- def _get_compression(self):
- return self._transport._preferred_compression
-
def _set(self, name, orig, x):
if type(x) is list:
x = tuple(x)
@@ -2233,30 +2220,51 @@ class SecurityOptions (object):
raise ValueError('unknown cipher')
setattr(self._transport, name, x)
- def _set_ciphers(self, x):
+ @property
+ def ciphers(self):
+ """Symmetric encryption ciphers"""
+ return self._transport._preferred_ciphers
+
+ @ciphers.setter
+ def ciphers(self, x):
self._set('_preferred_ciphers', '_cipher_info', x)
- def _set_digests(self, x):
+ @property
+ def digests(self):
+ """Digest (one-way hash) algorithms"""
+ return self._transport._preferred_macs
+
+ @digests.setter
+ def digests(self, x):
self._set('_preferred_macs', '_mac_info', x)
- def _set_key_types(self, x):
+ @property
+ def key_types(self):
+ """Public-key algorithms"""
+ return self._transport._preferred_keys
+
+ @key_types.setter
+ def key_types(self, x):
self._set('_preferred_keys', '_key_info', x)
- def _set_kex(self, x):
+
+ @property
+ def kex(self):
+ """Key exchange algorithms"""
+ return self._transport._preferred_kex
+
+ @kex.setter
+ def kex(self, x):
self._set('_preferred_kex', '_kex_info', x)
- def _set_compression(self, x):
- self._set('_preferred_compression', '_compression_info', x)
+ @property
+ def compression(self):
+ """Compression algorithms"""
+ return self._transport._preferred_compression
- ciphers = property(_get_ciphers, _set_ciphers, None,
- "Symmetric encryption ciphers")
- digests = property(_get_digests, _set_digests, None,
- "Digest (one-way hash) algorithms")
- key_types = property(_get_key_types, _set_key_types, None,
- "Public-key algorithms")
- kex = property(_get_kex, _set_kex, None, "Key exchange algorithms")
- compression = property(_get_compression, _set_compression, None,
- "Compression algorithms")
+ @compression.setter
+ def compression(self, x):
+ self._set('_preferred_compression', '_compression_info', x)
class ChannelMap (object):
diff --git a/paramiko/util.py b/paramiko/util.py
index 88ca2bc..d9a29d7 100644
--- a/paramiko/util.py
+++ b/paramiko/util.py
@@ -23,7 +23,6 @@ Useful functions used by the rest of paramiko.
from __future__ import generators
import array
-from binascii import hexlify, unhexlify
import errno
import sys
import struct
@@ -106,21 +105,14 @@ def format_binary_line(data):
return '%-50s %s' % (left, right)
-def hexify(s):
- return hexlify(s).upper()
-
-
-def unhexify(s):
- return unhexlify(s)
-
-
def safe_string(s):
- out = ''
+ out = b('')
for c in s:
- if (byte_ord(c) >= 32) and (byte_ord(c) <= 127):
- out += c
+ i = byte_ord(c)
+ if 32 <= i <= 127:
+ out += byte_chr(i)
else:
- out += '%%%02X' % byte_ord(c)
+ out += b('%%%02X' % i)
return out
@@ -307,9 +299,9 @@ class Counter (object):
self.value = array.array('c', zero_byte * (self.blocksize - len(x)) + x)
return self.value.tostring()
+ @classmethod
def new(cls, nbits, initial_value=long(1), overflow=long(0)):
return cls(nbits, initial_value=initial_value, overflow=overflow)
- new = classmethod(new)
def constant_time_bytes_eq(a, b):
diff --git a/paramiko/win_pageant.py b/paramiko/win_pageant.py
index 20b1b0b..4b482be 100644
--- a/paramiko/win_pageant.py
+++ b/paramiko/win_pageant.py
@@ -26,6 +26,7 @@ import ctypes.wintypes
import platform
import struct
from paramiko.util import *
+from paramiko.py3compat import b
try:
import _thread as thread # Python 3.x
@@ -43,7 +44,7 @@ win32con_WM_COPYDATA = 74
def _get_pageant_window_object():
- return ctypes.windll.user32.FindWindowA('Pageant', 'Pageant')
+ return ctypes.windll.user32.FindWindowA(b('Pageant'), b('Pageant'))
def can_talk_to_agent():
@@ -90,7 +91,7 @@ def _query_pageant(msg):
with pymap:
pymap.write(msg)
# Create an array buffer containing the mapped filename
- char_buffer = array.array("c", b(map_name) + zero_byte)
+ char_buffer = array.array("b", b(map_name) + zero_byte)
char_buffer_address, char_buffer_size = char_buffer.buffer_info()
# Create a string to use for the SendMessage function call
cds = COPYDATASTRUCT(_AGENT_COPYDATA_ID, char_buffer_size,