23345145 paramiko 2.0.2 upgrade
authorTomas Kuthan <tomas.kuthan@oracle.com>
Thu, 25 Aug 2016 13:50:44 -0700
changeset 6685 bac278bb0da8
parent 6684 57b59903a65e
child 6686 ef1ef74321e3
23345145 paramiko 2.0.2 upgrade 24411317 Paramiko needs master test results 24411329 Paramiko needs system-test target
components/python/paramiko/Makefile
components/python/paramiko/patches/01-nopycrypto.patch
components/python/paramiko/patches/03-system-test.patch
components/python/paramiko/test/results-all.master
--- a/components/python/paramiko/Makefile	Thu Aug 25 13:31:12 2016 -0700
+++ b/components/python/paramiko/Makefile	Thu Aug 25 13:50:44 2016 -0700
@@ -20,22 +20,22 @@
 #
 
 #
-# Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
 #
 
 include ../../../make-rules/shared-macros.mk
 
 COMPONENT_NAME=		paramiko
-COMPONENT_VERSION=	1.15.2
+COMPONENT_VERSION=	2.0.2
 COMPONENT_SRC=		$(COMPONENT_NAME)-$(COMPONENT_VERSION)
 COMPONENT_ARCHIVE=	$(COMPONENT_SRC).tar.gz
 COMPONENT_ARCHIVE_HASH=	\
-    sha256:4f56a671a3eecbb76e6143e6e4ca007d503a39aa79aa9e14ade667fa53fd6e55
+	sha256:411bf90fa22b078a923ff19ef9772c1115a0953702db93549a2848acefd141dc
 COMPONENT_ARCHIVE_URL=	$(call pypi_url)
 COMPONENT_PROJECT_URL=	http://github.com/paramiko/paramiko/
 COMPONENT_BUGDB=	python-mod/paramiko
 
-TPNO=			21692
+TPNO=			31171
 
 include $(WS_MAKE_RULES)/prep.mk
 include $(WS_MAKE_RULES)/setup.py.mk
@@ -43,13 +43,34 @@
 
 ASLR_MODE = $(ASLR_NOT_APPLICABLE)
 
-COMPONENT_TEST_ARGS=	./test.py
+# Master test results are the same for all versions of Python, so override
+# here, rather than create multiple identical master files.
+COMPONENT_TEST_MASTER = $(COMPONENT_TEST_RESULTS_DIR)/results-all.master
+
+# set LC_ALL for unicode sftp tests test_K_utf8 and test_L_utf8_chdir
+COMPONENT_TEST_ENV=	LC_ALL=en_US.UTF-8 PYTHONPATH=$(SOURCE_DIR)
 COMPONENT_TEST_DIR=	$(SOURCE_DIR)
+COMPONENT_TEST_CMD=	$(PYTHON)
+COMPONENT_TEST_ARGS=	test.py --verbose
+
+# ============== is followed by hard-to-match tracebacks
+COMPONENT_TEST_TRANSFORMS += \
+    '-e "s/\<[.0-9]\+s\>/Xs/g"' \
+    '-e "/==============/q"'
+
+COMPONENT_SYSTEM_TEST_ENV=	LC_ALL=en_US.UTF-8
+COMPONENT_SYSTEM_TEST_DIR=	$(SOURCE_DIR)
+COMPONENT_SYSTEM_TEST_CMD=	$(PYTHON)
+COMPONENT_SYSTEM_TEST_ARGS=	test.py --verbose
 
 # common targets
 build:		$(BUILD_NO_ARCH)
 
 install:	$(INSTALL_NO_ARCH)
 
-# Disable tests until cryptography is integrated and 20917217 is resolved.
-test:		$(NO_TESTS)
+test:		$(TEST_NO_ARCH)
+
+system-test:	$(SYSTEM_TEST_NO_ARCH)
+
+# locale required for unicode sftp tests
+REQUIRED_PACKAGES += system/locale
--- a/components/python/paramiko/patches/01-nopycrypto.patch	Thu Aug 25 13:31:12 2016 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1613 +0,0 @@
-External but not-yet-integrated patch that changes Paramiko to use
-"cryptography" rather than "PyCrypto". The changes have been modified
-from
-
-	https://github.com/paramiko/paramiko/pull/394/files
-
-to patch cleanly into Paramiko 1.15.2.
-This patch is a stop-gap and will be removed when the upstream Paramiko
-completes the transition to "cryptography".
-
---- paramiko-1.15.2/README.~1~	2014-12-19 15:01:22.000000000 -0800
-+++ paramiko-1.15.2/README	2015-04-12 17:36:15.204911382 -0700
[email protected]@ -25,7 +25,7 @@ channels to remote services across the e
- works, for example).
- 
- it is written entirely in python (no C or platform-dependent code) and is
--released under the GNU LGPL (lesser GPL). 
-+released under the GNU LGPL (lesser GPL).
- 
- the package and its API is fairly well documented in the "doc/" folder
- that should have come with this archive.
[email protected]@ -36,8 +36,8 @@ Requirements
- 
-   - Python 2.6 or better <http://www.python.org/> - this includes Python
-     3.2 and higher as well.
--  - pycrypto 2.1 or better <https://www.dlitz.net/software/pycrypto/>
--  - ecdsa 0.9 or better <https://pypi.python.org/pypi/ecdsa>
-+  - Cryptography 0.8 or better <https://cryptography.io>
-+  - pyasn1 0.1.7 or better <https://pypi.python.org/pypi/pyasn1>
- 
- If you have setuptools, you can build and install paramiko and all its
- dependencies with this command (as root)::
---- paramiko-1.15.2/paramiko/_winapi.py.~1~	2014-12-19 15:01:22.000000000 -0800
-+++ paramiko-1.15.2/paramiko/_winapi.py	2015-04-12 17:36:15.205197752 -0700
[email protected]@ -106,7 +106,7 @@ MapViewOfFile.restype = ctypes.wintypes.
- 
- class MemoryMap(object):
-     """
--    A memory map object which can have security attributes overrideden.
-+    A memory map object which can have security attributes overridden.
-     """
-     def __init__(self, name, length, security_attributes=None):
-         self.name = name
---- paramiko-1.15.2/paramiko/agent.py.~1~	2014-12-19 15:01:22.000000000 -0800
-+++ paramiko-1.15.2/paramiko/agent.py	2015-04-12 17:36:15.205474363 -0700
[email protected]@ -32,7 +32,7 @@ from select import select
- from paramiko.common import asbytes, io_sleep
- from paramiko.py3compat import byte_chr
- 
--from paramiko.ssh_exception import SSHException
-+from paramiko.ssh_exception import SSHException, AuthenticationException
- from paramiko.message import Message
- from paramiko.pkey import PKey
- from paramiko.util import retry_on_signal
[email protected]@ -109,9 +109,12 @@ class AgentProxyThread(threading.Thread)
-     def run(self):
-         try:
-             (r, addr) = self.get_connection()
-+            # Found that r should be either a socket from the socket library or None
-             self.__inr = r
--            self.__addr = addr
-+            self.__addr = addr # This should be an IP address as a string? or None
-             self._agent.connect()
-+            if not isinstance(self._agent, int) and (self._agent._conn is None or not hasattr(self._agent._conn, 'fileno')):
-+                raise AuthenticationException("Unable to connect to SSH agent")
-             self._communicate()
-         except:
-             #XXX Not sure what to do here ... raise or pass ?
---- paramiko-1.15.2/paramiko/channel.py.~1~	2014-12-19 15:01:22.000000000 -0800
-+++ paramiko-1.15.2/paramiko/channel.py	2015-04-12 17:36:15.205880064 -0700
[email protected]@ -337,7 +337,7 @@ class Channel (ClosingContextManager):
-         further x11 requests can be made from the server to the client,
-         when an x11 application is run in a shell session.
- 
--        From RFC4254::
-+        From :rfc:`4254`::
- 
-             It is RECOMMENDED that the 'x11 authentication cookie' that is
-             sent be a fake, random cookie, and that the cookie be checked and
---- paramiko-1.15.2/paramiko/client.py.~1~	2014-12-19 15:01:22.000000000 -0800
-+++ paramiko-1.15.2/paramiko/client.py	2015-04-12 17:36:15.206296235 -0700
[email protected]@ -25,6 +25,7 @@ import getpass
- import os
- import socket
- import warnings
-+from errno import ECONNREFUSED, EHOSTUNREACH
- 
- from paramiko.agent import Agent
- from paramiko.common import DEBUG
[email protected]@ -35,7 +36,9 @@ from paramiko.hostkeys import HostKeys
- from paramiko.py3compat import string_types
- from paramiko.resource import ResourceManager
- from paramiko.rsakey import RSAKey
--from paramiko.ssh_exception import SSHException, BadHostKeyException
-+from paramiko.ssh_exception import (
-+    SSHException, BadHostKeyException, NoValidConnectionsError
-+)
- from paramiko.transport import Transport
- from paramiko.util import retry_on_signal, ClosingContextManager
- 
[email protected]@ -172,10 +175,46 @@ class SSHClient (ClosingContextManager):
-         """
-         self._policy = policy
- 
--    def connect(self, hostname, port=SSH_PORT, username=None, password=None, pkey=None,
--                key_filename=None, timeout=None, allow_agent=True, look_for_keys=True,
--                compress=False, sock=None, gss_auth=False, gss_kex=False,
--                gss_deleg_creds=True, gss_host=None, banner_timeout=None):
-+    def _families_and_addresses(self, hostname, port):
-+        """
-+        Yield pairs of address families and addresses to try for connecting.
-+
-+        :param str hostname: the server to connect to
-+        :param int port: the server port to connect to
-+        :returns: Yields an iterable of ``(family, address)`` tuples
-+        """
-+        guess = True
-+        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.
-+        if guess:
-+            for family, _, _, _, sockaddr in addrinfos:
-+                yield family, sockaddr
-+
-+    def connect(
-+        self,
-+        hostname,
-+        port=SSH_PORT,
-+        username=None,
-+        password=None,
-+        pkey=None,
-+        key_filename=None,
-+        timeout=None,
-+        allow_agent=True,
-+        look_for_keys=True,
-+        compress=False,
-+        sock=None,
-+        gss_auth=False,
-+        gss_kex=False,
-+        gss_deleg_creds=True,
-+        gss_host=None,
-+        banner_timeout=None
-+    ):
-         """
-         Connect to an SSH server and authenticate to it.  The server's host key
-         is checked against the system host keys (see `load_system_host_keys`)
[email protected]@ -206,8 +245,10 @@ class SSHClient (ClosingContextManager):
-         :param str key_filename:
-             the filename, or list of filenames, of optional private key(s) to
-             try for authentication
--        :param float timeout: an optional timeout (in seconds) for the TCP connect
--        :param bool allow_agent: set to False to disable connecting to the SSH agent
-+        :param float timeout:
-+            an optional timeout (in seconds) for the TCP connect
-+        :param bool allow_agent:
-+            set to False to disable connecting to the SSH agent
-         :param bool look_for_keys:
-             set to False to disable searching for discoverable private key
-             files in ``~/.ssh/``
[email protected]@ -216,9 +257,11 @@ class SSHClient (ClosingContextManager):
-             an open socket or socket-like object (such as a `.Channel`) to use
-             for communication to the target host
-         :param bool gss_auth: ``True`` if you want to use GSS-API authentication
--        :param bool gss_kex: Perform GSS-API Key Exchange and user authentication
-+        :param bool gss_kex:
-+            Perform GSS-API Key Exchange and user authentication
-         :param bool gss_deleg_creds: Delegate GSS-API client credentials or not
--        :param str gss_host: The targets name in the kerberos database. default: hostname
-+        :param str gss_host:
-+            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.
- 
[email protected]@ -234,21 +277,37 @@ class SSHClient (ClosingContextManager):
-             ``gss_deleg_creds`` and ``gss_host`` arguments.
-         """
-         if not sock:
--            for (family, socktype, proto, canonname, sockaddr) in socket.getaddrinfo(hostname, port, socket.AF_UNSPEC, socket.SOCK_STREAM):
--                if socktype == socket.SOCK_STREAM:
--                    af = family
--                    addr = sockaddr
--                    break
--            else:
--                # some OS like AIX don't indicate SOCK_STREAM support, so just guess. :(
--                af, _, _, _, addr = socket.getaddrinfo(hostname, port, socket.AF_UNSPEC, socket.SOCK_STREAM)
--            sock = socket.socket(af, socket.SOCK_STREAM)
--            if timeout is not None:
-+            errors = {}
-+            # Try multiple possible address families (e.g. IPv4 vs IPv6)
-+            to_try = list(self._families_and_addresses(hostname, port))
-+            for af, addr in to_try:
-                 try:
--                    sock.settimeout(timeout)
--                except:
--                    pass
--            retry_on_signal(lambda: sock.connect(addr))
-+                    sock = socket.socket(af, socket.SOCK_STREAM)
-+                    if timeout is not None:
-+                        try:
-+                            sock.settimeout(timeout)
-+                        except:
-+                            pass
-+                    retry_on_signal(lambda: sock.connect(addr))
-+                    # Break out of the loop on success
-+                    break
-+                except socket.error as e:
-+                    # Raise anything that isn't a straight up connection error
-+                    # (such as a resolution error)
-+                    if e.errno not in (ECONNREFUSED, EHOSTUNREACH):
-+                        raise
-+                    # Capture anything else so we know how the run looks once
-+                    # iteration is complete. Retain info about which attempt
-+                    # this was.
-+                    errors[addr] = e
-+
-+            # Make sure we explode usefully if no address family attempts
-+            # succeeded. We've no way of knowing which error is the "right"
-+            # one, so we construct a hybrid exception containing all the real
-+            # ones, of a subclass that client code should still be watching for
-+            # (socket.error)
-+            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.use_compression(compress=compress)
---- paramiko-1.15.2/paramiko/config.py.~1~	2014-12-19 15:01:22.000000000 -0800
-+++ paramiko-1.15.2/paramiko/config.py	2015-04-12 17:36:15.206521239 -0700
[email protected]@ -98,7 +98,7 @@ class SSHConfig (object):
- 
-         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''
-+        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.
- 
---- paramiko-1.15.2/paramiko/dsskey.py.~1~	2014-12-19 15:01:22.000000000 -0800
-+++ paramiko-1.15.2/paramiko/dsskey.py	2015-04-12 17:36:15.206846024 -0700
[email protected]@ -20,21 +20,23 @@
- DSS keys.
- """
- 
--import os
--from hashlib import sha1
--
--from Crypto.PublicKey import DSA
-+from cryptography.exceptions import InvalidSignature
-+from cryptography.hazmat.backends import default_backend
-+from cryptography.hazmat.primitives import hashes, serialization
-+from cryptography.hazmat.primitives.asymmetric import dsa
-+from cryptography.hazmat.primitives.asymmetric.utils import (
-+    decode_rfc6979_signature, encode_rfc6979_signature
-+)
- 
- from paramiko import util
- from paramiko.common import zero_byte
--from paramiko.py3compat import long
- from paramiko.ssh_exception import SSHException
- from paramiko.message import Message
- from paramiko.ber import BER, BERException
- from paramiko.pkey import PKey
- 
- 
--class DSSKey (PKey):
-+class DSSKey(PKey):
-     """
-     Representation of a DSS key which can be used to sign an verify SSH2
-     data.
[email protected]@ -98,15 +100,21 @@ class DSSKey (PKey):
-         return self.x is not None
- 
-     def sign_ssh_data(self, data):
--        digest = sha1(data).digest()
--        dss = DSA.construct((long(self.y), long(self.g), long(self.p), long(self.q), long(self.x)))
--        # generate a suitable k
--        qsize = len(util.deflate_long(self.q, 0))
--        while True:
--            k = util.inflate_long(os.urandom(qsize), 1)
--            if (k > 2) and (k < self.q):
--                break
--        r, s = dss.sign(util.inflate_long(digest, 1), k)
-+        key = dsa.DSAPrivateNumbers(
-+            x=self.x,
-+            public_numbers=dsa.DSAPublicNumbers(
-+                y=self.y,
-+                parameter_numbers=dsa.DSAParameterNumbers(
-+                    p=self.p,
-+                    q=self.q,
-+                    g=self.g
-+                )
-+            )
-+        ).private_key(backend=default_backend())
-+        signer = key.signer(hashes.SHA1())
-+        signer.update(data)
-+        r, s = decode_rfc6979_signature(signer.finalize())
-+
-         m = Message()
-         m.add_string('ssh-dss')
-         # apparently, in rare cases, r or s may be shorter than 20 bytes!
[email protected]@ -132,27 +140,65 @@ class DSSKey (PKey):
-         # pull out (r, s) which are NOT encoded as mpints
-         sigR = util.inflate_long(sig[:20], 1)
-         sigS = util.inflate_long(sig[20:], 1)
--        sigM = util.inflate_long(sha1(data).digest(), 1)
- 
--        dss = DSA.construct((long(self.y), long(self.g), long(self.p), long(self.q)))
--        return dss.verify(sigM, (sigR, sigS))
-+        signature = encode_rfc6979_signature(sigR, sigS)
- 
--    def _encode_key(self):
--        if self.x is None:
--            raise SSHException('Not enough key information')
--        keylist = [0, self.p, self.q, self.g, self.y, self.x]
-+        key = dsa.DSAPublicNumbers(
-+            y=self.y,
-+            parameter_numbers=dsa.DSAParameterNumbers(
-+                p=self.p,
-+                q=self.q,
-+                g=self.g
-+            )
-+        ).public_key(backend=default_backend())
-+        verifier = key.verifier(signature, hashes.SHA1())
-+        verifier.update(data)
-         try:
--            b = BER()
--            b.encode(keylist)
--        except BERException:
--            raise SSHException('Unable to create ber encoding of key')
--        return b.asbytes()
-+            verifier.verify()
-+        except InvalidSignature:
-+            return False
-+        else:
-+            return True
- 
-     def write_private_key_file(self, filename, password=None):
--        self._write_private_key_file('DSA', filename, self._encode_key(), password)
-+        key = dsa.DSAPrivateNumbers(
-+            x=self.x,
-+            public_numbers=dsa.DSAPublicNumbers(
-+                y=self.y,
-+                parameter_numbers=dsa.DSAParameterNumbers(
-+                    p=self.p,
-+                    q=self.q,
-+                    g=self.g
-+                )
-+            )
-+        ).private_key(backend=default_backend())
-+
-+        self._write_private_key_file(
-+            filename,
-+            key,
-+            serialization.PrivateFormat.TraditionalOpenSSL,
-+            password=password
-+        )
- 
-     def write_private_key(self, file_obj, password=None):
--        self._write_private_key('DSA', file_obj, self._encode_key(), password)
-+        key = dsa.DSAPrivateNumbers(
-+            x=self.x,
-+            public_numbers=dsa.DSAPublicNumbers(
-+                y=self.y,
-+                parameter_numbers=dsa.DSAParameterNumbers(
-+                    p=self.p,
-+                    q=self.q,
-+                    g=self.g
-+                )
-+            )
-+        ).private_key(backend=default_backend())
-+
-+        self._write_private_key(
-+            file_obj,
-+            key,
-+            serialization.PrivateFormat.TraditionalOpenSSL,
-+            password=password
-+        )
- 
-     @staticmethod
-     def generate(bits=1024, progress_func=None):
[email protected]@ -161,14 +207,19 @@ class DSSKey (PKey):
-         generate a new host key or authentication key.
- 
-         :param int bits: number of bits the generated key should be.
--        :param function progress_func:
--            an optional function to call at key points in key generation (used
--            by ``pyCrypto.PublicKey``).
-+        :param function progress_func: Unused
-         :return: new `.DSSKey` private key
-         """
--        dsa = DSA.generate(bits, os.urandom, progress_func)
--        key = DSSKey(vals=(dsa.p, dsa.q, dsa.g, dsa.y))
--        key.x = dsa.x
-+        numbers = dsa.generate_private_key(
-+            bits, backend=default_backend()
-+        ).private_numbers()
-+        key = DSSKey(vals=(
-+            numbers.public_numbers.parameter_numbers.p,
-+            numbers.public_numbers.parameter_numbers.q,
-+            numbers.public_numbers.parameter_numbers.g,
-+            numbers.public_numbers.y
-+        ))
-+        key.x = numbers.x
-         return key
- 
-     ###  internals...
---- paramiko-1.15.2/paramiko/ecdsakey.py.~1~	2014-12-19 15:01:22.000000000 -0800
-+++ paramiko-1.15.2/paramiko/ecdsakey.py	2015-04-12 17:36:15.207208398 -0700
[email protected]@ -21,18 +21,24 @@ ECDSA keys
- """
- 
- import binascii
--from hashlib import sha256
- 
--from ecdsa import SigningKey, VerifyingKey, der, curves
-+from cryptography.exceptions import InvalidSignature
-+from cryptography.hazmat.backends import default_backend
-+from cryptography.hazmat.primitives import hashes, serialization
-+from cryptography.hazmat.primitives.asymmetric import ec
-+from cryptography.hazmat.primitives.asymmetric.utils import (
-+    decode_rfc6979_signature, encode_rfc6979_signature
-+)
- 
- from paramiko.common import four_byte, one_byte
- from paramiko.message import Message
- from paramiko.pkey import PKey
--from paramiko.py3compat import byte_chr, u
-+from paramiko.py3compat import byte_chr
- from paramiko.ssh_exception import SSHException
-+from paramiko.util import deflate_long, inflate_long
- 
- 
--class ECDSAKey (PKey):
-+class ECDSAKey(PKey):
-     """
-     Representation of an ECDSA key which can be used to sign and verify SSH2
-     data.
[email protected]@ -65,9 +71,13 @@ class ECDSAKey (PKey):
-             if pointinfo[0:1] != four_byte:
-                 raise SSHException('Point compression is being used: %s' %
-                                    binascii.hexlify(pointinfo))
--            self.verifying_key = VerifyingKey.from_string(pointinfo[1:],
--                                                          curve=curves.NIST256p,
--                                                          validate_point=validate_point)
-+            curve = ec.SECP256R1()
-+            numbers = ec.EllipticCurvePublicNumbers(
-+                x=inflate_long(pointinfo[1:1 + curve.key_size // 8], always_positive=True),
-+                y=inflate_long(pointinfo[1 + curve.key_size // 8:], always_positive=True),
-+                curve=curve
-+            )
-+            self.verifying_key = numbers.public_key(backend=default_backend())
-         self.size = 256
- 
-     def asbytes(self):
[email protected]@ -76,8 +86,15 @@ class ECDSAKey (PKey):
-         m.add_string('ecdsa-sha2-nistp256')
-         m.add_string('nistp256')
- 
--        point_str = four_byte + key.to_string()
-+        numbers = key.public_numbers()
- 
-+        x_bytes = deflate_long(numbers.x, add_sign_padding=False)
-+        x_bytes = b'\x00' * (len(x_bytes) - key.curve.key_size // 8) + x_bytes
-+
-+        y_bytes = deflate_long(numbers.y, add_sign_padding=False)
-+        y_bytes = b'\x00' * (len(y_bytes) - key.curve.key_size // 8) + y_bytes
-+
-+        point_str = four_byte + x_bytes + y_bytes
-         m.add_string(point_str)
-         return m.asbytes()
- 
[email protected]@ -86,8 +103,8 @@ class ECDSAKey (PKey):
- 
-     def __hash__(self):
-         h = hash(self.get_name())
--        h = h * 37 + hash(self.verifying_key.pubkey.point.x())
--        h = h * 37 + hash(self.verifying_key.pubkey.point.y())
-+        h = h * 37 + hash(self.verifying_key.public_numbers().x)
-+        h = h * 37 + hash(self.verifying_key.public_numbers().y)
-         return hash(h)
- 
-     def get_name(self):
[email protected]@ -100,46 +117,59 @@ class ECDSAKey (PKey):
-         return self.signing_key is not None
- 
-     def sign_ssh_data(self, data):
--        sig = self.signing_key.sign_deterministic(
--            data, sigencode=self._sigencode, hashfunc=sha256)
-+        signer = self.signing_key.signer(ec.ECDSA(hashes.SHA256()))
-+        signer.update(data)
-+        sig = signer.finalize()
-+        r, s = decode_rfc6979_signature(sig)
-+
-         m = Message()
-         m.add_string('ecdsa-sha2-nistp256')
--        m.add_string(sig)
-+        m.add_string(self._sigencode(r, s))
-         return m
- 
-     def verify_ssh_sig(self, data, msg):
-         if msg.get_text() != 'ecdsa-sha2-nistp256':
-             return False
-         sig = msg.get_binary()
-+        sigR, sigS = self._sigdecode(sig)
-+        signature = encode_rfc6979_signature(sigR, sigS)
- 
--        # verify the signature by SHA'ing the data and encrypting it
--        # using the public key.
--        hash_obj = sha256(data).digest()
--        return self.verifying_key.verify_digest(sig, hash_obj,
--                                                sigdecode=self._sigdecode)
-+        verifier = self.verifying_key.verifier(signature, ec.ECDSA(hashes.SHA256()))
-+        verifier.update(data)
-+        try:
-+            verifier.verify()
-+        except InvalidSignature:
-+            return False
-+        else:
-+            return True
- 
-     def write_private_key_file(self, filename, password=None):
--        key = self.signing_key or self.verifying_key
--        self._write_private_key_file('EC', filename, key.to_der(), password)
-+        self._write_private_key_file(
-+            filename,
-+            self.signing_key,
-+            serialization.PrivateFormat.TraditionalOpenSSL,
-+            password=password
-+        )
- 
-     def write_private_key(self, file_obj, password=None):
--        key = self.signing_key or self.verifying_key
--        self._write_private_key('EC', file_obj, key.to_der(), password)
-+        self._write_private_key(
-+            file_obj,
-+            self.signing_key,
-+            serialization.PrivateFormat.TraditionalOpenSSL,
-+            password=password
-+        )
- 
-     @staticmethod
--    def generate(curve=curves.NIST256p, progress_func=None):
-+    def generate(curve=ec.SECP256R1(), progress_func=None):
-         """
-         Generate a new private RSA key.  This factory function can be used to
-         generate a new host key or authentication key.
- 
--        :param function progress_func:
--            an optional function to call at key points in key generation (used
--            by ``pyCrypto.PublicKey``).
-+        :param function progress_func: Unused
-         :returns: A new private key (`.RSAKey`) object
-         """
--        signing_key = SigningKey.generate(curve)
--        key = ECDSAKey(vals=(signing_key, signing_key.get_verifying_key()))
--        return key
-+        private_key = ec.generate_private_key(curve, backend=default_backend())
-+        return ECDSAKey(vals=(private_key, private_key.public_key()))
- 
-     ###  internals...
- 
[email protected]@ -155,23 +185,18 @@ class ECDSAKey (PKey):
-                         byte_chr(5) * 5, byte_chr(6) * 6, byte_chr(7) * 7]
- 
-     def _decode_key(self, data):
--        s, padding = der.remove_sequence(data)
--        if padding:
--            if padding not in self.ALLOWED_PADDINGS:
--                raise ValueError("weird padding: %s" % u(binascii.hexlify(data)))
--            data = data[:-len(padding)]
--        key = SigningKey.from_der(data)
-+        key = serialization.load_der_private_key(data, password=None, backend=default_backend())
-         self.signing_key = key
--        self.verifying_key = key.get_verifying_key()
--        self.size = 256
-+        self.verifying_key = key.public_key()
-+        self.size = key.curve.key_size
- 
--    def _sigencode(self, r, s, order):
-+    def _sigencode(self, r, s):
-         msg = Message()
-         msg.add_mpint(r)
-         msg.add_mpint(s)
-         return msg.asbytes()
- 
--    def _sigdecode(self, sig, order):
-+    def _sigdecode(self, sig):
-         msg = Message(sig)
-         r = msg.get_mpint()
-         s = msg.get_mpint()
---- paramiko-1.15.2/paramiko/kex_gss.py.~1~	2014-12-19 15:01:22.000000000 -0800
-+++ paramiko-1.15.2/paramiko/kex_gss.py	2015-04-12 17:36:15.207554941 -0700
[email protected]@ -21,14 +21,15 @@
- 
- 
- """
--This module provides GSS-API / SSPI Key Exchange as defined in RFC 4462.
-+This module provides GSS-API / SSPI Key Exchange as defined in :rfc:`4462`.
- 
- .. note:: Credential delegation is not supported in server mode.
- 
- .. note::
--    `RFC 4462 Section 2.2 <http://www.ietf.org/rfc/rfc4462.txt>`_ says we are
--    not required to implement GSS-API error messages. Thus, in many methods
--    within this module, if an error occurs an exception will be thrown and the
-+    `RFC 4462 Section 2.2
-+    <https://tools.ietf.org/html/rfc4462.html#section-2.2>`_ says we are not
-+    required to implement GSS-API error messages. Thus, in many methods within
-+    this module, if an error occurs an exception will be thrown and the
-     connection will be terminated.
- 
- .. seealso:: :doc:`/api/ssh_gss`
[email protected]@ -55,8 +56,8 @@ c_MSG_KEXGSS_GROUPREQ, c_MSG_KEXGSS_GROU
- 
- class KexGSSGroup1(object):
-     """
--    GSS-API / SSPI Authenticated Diffie-Hellman Key Exchange
--    as defined in `RFC 4462 Section 2 <http://www.ietf.org/rfc/rfc4462.txt>`_
-+    GSS-API / SSPI Authenticated Diffie-Hellman Key Exchange as defined in `RFC
-+    4462 Section 2 <https://tools.ietf.org/html/rfc4462.html#section-2>`_
-     """
-     # draft-ietf-secsh-transport-09.txt, page 17
-     P = 0xFFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381FFFFFFFFFFFFFFFF
[email protected]@ -278,8 +279,9 @@ class KexGSSGroup1(object):
- 
- class KexGSSGroup14(KexGSSGroup1):
-     """
--    GSS-API / SSPI Authenticated Diffie-Hellman Group14 Key Exchange
--    as defined in `RFC 4462 Section 2 <http://www.ietf.org/rfc/rfc4462.txt>`_
-+    GSS-API / SSPI Authenticated Diffie-Hellman Group14 Key Exchange as defined
-+    in `RFC 4462 Section 2
-+    <https://tools.ietf.org/html/rfc4462.html#section-2>`_
-     """
-     P = 0xFFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AACAA68FFFFFFFFFFFFFFFF
-     G = 2
[email protected]@ -288,8 +290,8 @@ class KexGSSGroup14(KexGSSGroup1):
- 
- class KexGSSGex(object):
-     """
--    GSS-API / SSPI Authenticated Diffie-Hellman Group Exchange
--    as defined in `RFC 4462 Section 2 <http://www.ietf.org/rfc/rfc4462.txt>`_
-+    GSS-API / SSPI Authenticated Diffie-Hellman Group Exchange as defined in
-+    `RFC 4462 Section 2 <https://tools.ietf.org/html/rfc4462.html#section-2>`_
-     """
-     NAME = "gss-gex-sha1-toWM5Slw5Ew8Mqkay+al2g=="
-     min_bits = 1024
[email protected]@ -590,8 +592,9 @@ class KexGSSGex(object):
- 
- class NullHostKey(object):
-     """
--    This class represents the Null Host Key for GSS-API Key Exchange
--    as defined in `RFC 4462 Section 5 <http://www.ietf.org/rfc/rfc4462.txt>`_
-+    This class represents the Null Host Key for GSS-API Key Exchange as defined
-+    in `RFC 4462 Section 5
-+    <https://tools.ietf.org/html/rfc4462.html#section-5>`_
-     """
-     def __init__(self):
-         self.key = ""
---- paramiko-1.15.2/paramiko/packet.py.~1~	2014-12-19 15:01:22.000000000 -0800
-+++ paramiko-1.15.2/paramiko/packet.py	2015-04-12 17:36:15.207839345 -0700
[email protected]@ -307,7 +307,7 @@ class Packetizer (object):
-                 self._log(DEBUG, 'Write packet <%s>, length %d' % (cmd_name, orig_len))
-                 self._log(DEBUG, util.format_binary(packet, 'OUT: '))
-             if self.__block_engine_out is not None:
--                out = self.__block_engine_out.encrypt(packet)
-+                out = self.__block_engine_out.update(packet)
-             else:
-                 out = packet
-             # + mac
[email protected]@ -340,7 +340,7 @@ class Packetizer (object):
-         """
-         header = self.read_all(self.__block_size_in, check_rekey=True)
-         if self.__block_engine_in is not None:
--            header = self.__block_engine_in.decrypt(header)
-+            header = self.__block_engine_in.update(header)
-         if self.__dump_packets:
-             self._log(DEBUG, util.format_binary(header, 'IN: '))
-         packet_size = struct.unpack('>I', header[:4])[0]
[email protected]@ -352,7 +352,7 @@ class Packetizer (object):
-         packet = buf[:packet_size - len(leftover)]
-         post_packet = buf[packet_size - len(leftover):]
-         if self.__block_engine_in is not None:
--            packet = self.__block_engine_in.decrypt(packet)
-+            packet = self.__block_engine_in.update(packet)
-         if self.__dump_packets:
-             self._log(DEBUG, util.format_binary(packet, 'IN: '))
-         packet = leftover + packet
---- paramiko-1.15.2/paramiko/pkey.py.~1~	2014-12-19 15:01:22.000000000 -0800
-+++ paramiko-1.15.2/paramiko/pkey.py	2015-04-12 17:36:15.208139348 -0700
[email protected]@ -21,27 +21,39 @@ Common API for all public keys.
- """
- 
- import base64
--from binascii import hexlify, unhexlify
-+from binascii import unhexlify
- import os
- from hashlib import md5
- 
--from Crypto.Cipher import DES3, AES
-+from cryptography.hazmat.backends import default_backend
-+from cryptography.hazmat.primitives import serialization
-+from cryptography.hazmat.primitives.ciphers import algorithms, modes, Cipher
- 
- from paramiko import util
--from paramiko.common import o600, zero_byte
-+from paramiko.common import o600
- from paramiko.py3compat import u, encodebytes, decodebytes, b
- from paramiko.ssh_exception import SSHException, PasswordRequiredException
- 
- 
--class PKey (object):
-+class PKey(object):
-     """
-     Base class for public keys.
-     """
- 
-     # known encryption types for private key files:
-     _CIPHER_TABLE = {
--        'AES-128-CBC': {'cipher': AES, 'keysize': 16, 'blocksize': 16, 'mode': AES.MODE_CBC},
--        'DES-EDE3-CBC': {'cipher': DES3, 'keysize': 24, 'blocksize': 8, 'mode': DES3.MODE_CBC},
-+        'AES-128-CBC': {
-+            'cipher': algorithms.AES,
-+            'keysize': 16,
-+            'blocksize': 16,
-+            'mode': modes.CBC
-+        },
-+        'DES-EDE3-CBC': {
-+            'cipher': algorithms.TripleDES,
-+            'keysize': 24,
-+            'blocksize': 8,
-+            'mode': modes.CBC
-+        },
-     }
- 
-     def __init__(self, msg=None, data=None):
[email protected]@ -300,9 +312,12 @@ class PKey (object):
-         mode = self._CIPHER_TABLE[encryption_type]['mode']
-         salt = unhexlify(b(saltstr))
-         key = util.generate_key_bytes(md5, salt, password, keysize)
--        return cipher.new(key, mode, salt).decrypt(data)
-+        decryptor = Cipher(
-+            cipher(key), mode(salt), backend=default_backend()
-+        ).decryptor()
-+        return decryptor.update(data) + decryptor.finalize()
- 
--    def _write_private_key_file(self, tag, filename, data, password=None):
-+    def _write_private_key_file(self, filename, key, format, password=None):
-         """
-         Write an SSH2-format private key file in a form that can be read by
-         paramiko or openssh.  If no password is given, the key is written in
[email protected]@ -319,31 +334,16 @@ class PKey (object):
-         with open(filename, 'w', o600) as f:
-             # grrr... the mode doesn't always take hold
-             os.chmod(filename, o600)
--            self._write_private_key(tag, f, data, password)
-+            self._write_private_key(f, key, format)
- 
--    def _write_private_key(self, tag, f, data, password=None):
--        f.write('-----BEGIN %s PRIVATE KEY-----\n' % tag)
--        if password is not None:
--            cipher_name = list(self._CIPHER_TABLE.keys())[0]
--            cipher = self._CIPHER_TABLE[cipher_name]['cipher']
--            keysize = self._CIPHER_TABLE[cipher_name]['keysize']
--            blocksize = self._CIPHER_TABLE[cipher_name]['blocksize']
--            mode = self._CIPHER_TABLE[cipher_name]['mode']
--            salt = os.urandom(blocksize)
--            key = util.generate_key_bytes(md5, salt, password, keysize)
--            if len(data) % blocksize != 0:
--                n = blocksize - len(data) % blocksize
--                #data += os.urandom(n)
--                # that would make more sense ^, but it confuses openssh.
--                data += zero_byte * n
--            data = cipher.new(key, mode, salt).encrypt(data)
--            f.write('Proc-Type: 4,ENCRYPTED\n')
--            f.write('DEK-Info: %s,%s\n' % (cipher_name, u(hexlify(salt)).upper()))
--            f.write('\n')
--        s = u(encodebytes(data))
--        # re-wrap to 64-char lines
--        s = ''.join(s.split('\n'))
--        s = '\n'.join([s[i: i + 64] for i in range(0, len(s), 64)])
--        f.write(s)
--        f.write('\n')
--        f.write('-----END %s PRIVATE KEY-----\n' % tag)
-+    def _write_private_key(self, f, key, format, password=None):
-+        if password is None:
-+            encryption = serialization.NoEncryption()
-+        else:
-+            encryption = serialization.BestEncryption(password)
-+
-+        f.write(key.private_bytes(
-+            serialization.Encoding.PEM,
-+            format,
-+            encryption
-+        ).decode())
---- paramiko-1.15.2/paramiko/rsakey.py.~1~	2014-12-19 15:01:22.000000000 -0800
-+++ paramiko-1.15.2/paramiko/rsakey.py	2015-04-12 17:36:15.208516662 -0700
[email protected]@ -20,34 +20,26 @@
- RSA keys.
- """
- 
--import os
--from hashlib import sha1
-+from cryptography.exceptions import InvalidSignature
-+from cryptography.hazmat.backends import default_backend
-+from cryptography.hazmat.primitives import hashes, serialization
-+from cryptography.hazmat.primitives.asymmetric import rsa, padding
- 
--from Crypto.PublicKey import RSA
--
--from paramiko import util
--from paramiko.common import max_byte, zero_byte, one_byte
- from paramiko.message import Message
--from paramiko.ber import BER, BERException
- from paramiko.pkey import PKey
--from paramiko.py3compat import long
- from paramiko.ssh_exception import SSHException
- 
- SHA1_DIGESTINFO = b'\x30\x21\x30\x09\x06\x05\x2b\x0e\x03\x02\x1a\x05\x00\x04\x14'
- 
- 
--class RSAKey (PKey):
-+class RSAKey(PKey):
-     """
-     Representation of an RSA key which can be used to sign and verify SSH2
-     data.
-     """
- 
--    def __init__(self, msg=None, data=None, filename=None, password=None, vals=None, file_obj=None):
--        self.n = None
--        self.e = None
--        self.d = None
--        self.p = None
--        self.q = None
-+    def __init__(self, msg=None, data=None, filename=None, password=None, key=None, file_obj=None):
-+        self.key = None
-         if file_obj is not None:
-             self._from_private_key(file_obj, password)
-             return
[email protected]@ -56,22 +48,33 @@ class RSAKey (PKey):
-             return
-         if (msg is None) and (data is not None):
-             msg = Message(data)
--        if vals is not None:
--            self.e, self.n = vals
-+        if key is not None:
-+            self.key = key
-         else:
-             if msg is None:
-                 raise SSHException('Key object may not be empty')
-             if msg.get_text() != 'ssh-rsa':
-                 raise SSHException('Invalid key')
--            self.e = msg.get_mpint()
--            self.n = msg.get_mpint()
--        self.size = util.bit_length(self.n)
-+            self.key = rsa.RSAPublicNumbers(
-+                e=msg.get_mpint(), n=msg.get_mpint()
-+            ).public_key(default_backend())
-+
-+    @property
-+    def size(self):
-+        return self.key.key_size
-+
-+    @property
-+    def public_numbers(self):
-+        if isinstance(self.key, rsa.RSAPrivateKey):
-+            return self.key.private_numbers().public_numbers
-+        else:
-+            return self.key.public_numbers()
- 
-     def asbytes(self):
-         m = Message()
-         m.add_string('ssh-rsa')
--        m.add_mpint(self.e)
--        m.add_mpint(self.n)
-+        m.add_mpint(self.public_numbers.e)
-+        m.add_mpint(self.public_numbers.n)
-         return m.asbytes()
- 
-     def __str__(self):
[email protected]@ -79,8 +82,8 @@ class RSAKey (PKey):
- 
-     def __hash__(self):
-         h = hash(self.get_name())
--        h = h * 37 + hash(self.e)
--        h = h * 37 + hash(self.n)
-+        h = h * 37 + hash(self.public_numbers.e)
-+        h = h * 37 + hash(self.public_numbers.n)
-         return hash(h)
- 
-     def get_name(self):
[email protected]@ -90,12 +93,16 @@ class RSAKey (PKey):
-         return self.size
- 
-     def can_sign(self):
--        return self.d is not None
-+        return isinstance(self.key, rsa.RSAPrivateKey)
- 
-     def sign_ssh_data(self, data):
--        digest = sha1(data).digest()
--        rsa = RSA.construct((long(self.n), long(self.e), long(self.d)))
--        sig = util.deflate_long(rsa.sign(self._pkcs1imify(digest), bytes())[0], 0)
-+        signer = self.key.signer(
-+            padding=padding.PKCS1v15(),
-+            algorithm=hashes.SHA1(),
-+        )
-+        signer.update(data)
-+        sig = signer.finalize()
-+
-         m = Message()
-         m.add_string('ssh-rsa')
-         m.add_string(sig)
[email protected]@ -104,32 +111,38 @@ class RSAKey (PKey):
-     def verify_ssh_sig(self, data, msg):
-         if msg.get_text() != 'ssh-rsa':
-             return False
--        sig = util.inflate_long(msg.get_binary(), True)
--        # verify the signature by SHA'ing the data and encrypting it using the
--        # public key.  some wackiness ensues where we "pkcs1imify" the 20-byte
--        # hash into a string as long as the RSA key.
--        hash_obj = util.inflate_long(self._pkcs1imify(sha1(data).digest()), True)
--        rsa = RSA.construct((long(self.n), long(self.e)))
--        return rsa.verify(hash_obj, (sig,))
--
--    def _encode_key(self):
--        if (self.p is None) or (self.q is None):
--            raise SSHException('Not enough key info to write private key file')
--        keylist = [0, self.n, self.e, self.d, self.p, self.q,
--                   self.d % (self.p - 1), self.d % (self.q - 1),
--                   util.mod_inverse(self.q, self.p)]
-+        key = self.key
-+        if isinstance(key, rsa.RSAPrivateKey):
-+            key = key.public_key()
-+
-+        verifier = key.verifier(
-+            signature=msg.get_binary(),
-+            padding=padding.PKCS1v15(),
-+            algorithm=hashes.SHA1(),
-+        )
-+        verifier.update(data)
-         try:
--            b = BER()
--            b.encode(keylist)
--        except BERException:
--            raise SSHException('Unable to create ber encoding of key')
--        return b.asbytes()
-+            verifier.verify()
-+        except InvalidSignature:
-+            return False
-+        else:
-+            return True
- 
-     def write_private_key_file(self, filename, password=None):
--        self._write_private_key_file('RSA', filename, self._encode_key(), password)
-+        self._write_private_key_file(
-+            filename,
-+            self.key,
-+            serialization.PrivateFormat.TraditionalOpenSSL,
-+            password=password
-+        )
- 
-     def write_private_key(self, file_obj, password=None):
--        self._write_private_key('RSA', file_obj, self._encode_key(), password)
-+        self._write_private_key(
-+            file_obj,
-+            self.key,
-+            serialization.PrivateFormat.TraditionalOpenSSL,
-+            password=password
-+        )
- 
-     @staticmethod
-     def generate(bits, progress_func=None):
[email protected]@ -138,29 +151,16 @@ class RSAKey (PKey):
-         generate a new host key or authentication key.
- 
-         :param int bits: number of bits the generated key should be.
--        :param function progress_func:
--            an optional function to call at key points in key generation (used
--            by ``pyCrypto.PublicKey``).
-+        :param function progress_func: Unused
-         :return: new `.RSAKey` private key
-         """
--        rsa = RSA.generate(bits, os.urandom, progress_func)
--        key = RSAKey(vals=(rsa.e, rsa.n))
--        key.d = rsa.d
--        key.p = rsa.p
--        key.q = rsa.q
--        return key
-+        key = rsa.generate_private_key(
-+            public_exponent=65537, key_size=bits, backend=default_backend()
-+        )
-+        return RSAKey(key=key)
- 
-     ###  internals...
- 
--    def _pkcs1imify(self, data):
--        """
--        turn a 20-byte SHA1 hash into a blob of data as large as the key's N,
--        using PKCS1's \"emsa-pkcs1-v1_5\" encoding.  totally bizarre.
--        """
--        size = len(util.deflate_long(self.n, 0))
--        filler = max_byte * (size - len(SHA1_DIGESTINFO) - len(data) - 3)
--        return zero_byte + one_byte + filler + zero_byte + SHA1_DIGESTINFO + data
--
-     def _from_private_key_file(self, filename, password):
-         data = self._read_private_key_file('RSA', filename, password)
-         self._decode_key(data)
[email protected]@ -170,18 +170,8 @@ class RSAKey (PKey):
-         self._decode_key(data)
- 
-     def _decode_key(self, data):
--        # private key file contains:
--        # RSAPrivateKey = { version = 0, n, e, d, p, q, d mod p-1, d mod q-1, q**-1 mod p }
--        try:
--            keylist = BER(data).decode()
--        except BERException:
--            raise SSHException('Unable to parse key file')
--        if (type(keylist) is not list) or (len(keylist) < 4) or (keylist[0] != 0):
--            raise SSHException('Not a valid RSA private key file (bad ber encoding)')
--        self.n = keylist[1]
--        self.e = keylist[2]
--        self.d = keylist[3]
--        # not really needed
--        self.p = keylist[4]
--        self.q = keylist[5]
--        self.size = util.bit_length(self.n)
-+        key = serialization.load_der_private_key(
-+            data, password=None, backend=default_backend()
-+        )
-+        assert isinstance(key, rsa.RSAPrivateKey)
-+        self.key = key
---- paramiko-1.15.2/paramiko/ssh_exception.py.~1~	2014-09-08 10:42:16.000000000 -0700
-+++ paramiko-1.15.2/paramiko/ssh_exception.py	2015-04-12 17:36:15.208756832 -0700
[email protected]@ -16,6 +16,8 @@
- # along with Paramiko; if not, write to the Free Software Foundation, Inc.,
- # 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA.
- 
-+import socket
-+
- 
- class SSHException (Exception):
-     """
[email protected]@ -129,3 +131,39 @@ class ProxyCommandFailure (SSHException)
-         self.error = error
-         # for unpickling
-         self.args = (command, error, )
-+
-+
-+class NoValidConnectionsError(socket.error):
-+    """
-+    Multiple connection attempts were made and no families succeeded.
-+
-+    This exception class wraps multiple "real" underlying connection errors,
-+    all of which represent failed connection attempts. Because these errors are
-+    not guaranteed to all be of the same error type (i.e. different errno,
-+    class, message, etc) we expose a single unified error message and a
-+    ``None`` errno so that instances of this class match most normal handling
-+    of `socket.error` objects.
-+    
-+    To see the wrapped exception objects, access the ``errors`` attribute.
-+    ``errors`` is a dict whose keys are address tuples (e.g. ``('127.0.0.1',
-+    22)``) and whose values are the exception encountered trying to connect to
-+    that address.
-+
-+    It is implied/assumed that all the errors given to a single instance of
-+    this class are from connecting to the same hostname + port (and thus that
-+    the differences are in the resolution of the hostname - e.g. IPv4 vs v6).
-+    """
-+    def __init__(self, errors):
-+        """
-+        :param dict errors:
-+            The errors dict to store, as described by class docstring.
-+        """
-+        addrs = errors.keys()
-+        body = ', '.join([x[0] for x in addrs[:-1]])
-+        tail = addrs[-1][0]
-+        msg = "Unable to connect to port {0} on {1} or {2}"
-+        super(NoValidConnectionsError, self).__init__(
-+            None, # stand-in for errno
-+            msg.format(addrs[0][1], body, tail)
-+        )
-+        self.errors = errors
---- paramiko-1.15.2/paramiko/ssh_gss.py.~1~	2014-12-19 15:01:22.000000000 -0800
-+++ paramiko-1.15.2/paramiko/ssh_gss.py	2015-04-12 17:36:15.209036497 -0700
[email protected]@ -20,7 +20,7 @@
- 
- 
- """
--This module provides GSS-API / SSPI  authentication as defined in RFC 4462.
-+This module provides GSS-API / SSPI  authentication as defined in :rfc:`4462`.
- 
- .. note:: Credential delegation is not supported in server mode.
- 
[email protected]@ -39,22 +39,8 @@ import sys
- """
- GSS_AUTH_AVAILABLE = True
- 
--try:
--    from pyasn1.type.univ import ObjectIdentifier
--    from pyasn1.codec.der import encoder, decoder
--except ImportError:
--    GSS_AUTH_AVAILABLE = False
--    class ObjectIdentifier(object):
--        def __init__(self, *args):
--            raise NotImplementedError("Module pyasn1 not importable")
--
--    class decoder(object):
--        def decode(self):
--            raise NotImplementedError("Module pyasn1 not importable")
--
--    class encoder(object):
--        def encode(self):
--            raise NotImplementedError("Module pyasn1 not importable")
-+from pyasn1.type.univ import ObjectIdentifier
-+from pyasn1.codec.der import encoder, decoder
- 
- from paramiko.common import MSG_USERAUTH_REQUEST
- from paramiko.ssh_exception import SSHException
---- paramiko-1.15.2/paramiko/transport.py.~1~	2014-12-19 15:01:22.000000000 -0800
-+++ paramiko-1.15.2/paramiko/transport.py	2015-04-12 17:36:15.209751892 -0700
[email protected]@ -28,6 +28,9 @@ import time
- import weakref
- from hashlib import md5, sha1
- 
-+from cryptography.hazmat.backends import default_backend
-+from cryptography.hazmat.primitives.ciphers import algorithms, Cipher, modes
-+
- import paramiko
- from paramiko import util
- from paramiko.auth_handler import AuthHandler
[email protected]@ -63,11 +66,6 @@ from paramiko.ssh_exception import (SSHE
-                                     ChannelException, ProxyCommandFailure)
- from paramiko.util import retry_on_signal, ClosingContextManager, clamp_value
- 
--from Crypto.Cipher import Blowfish, AES, DES3, ARC4
--try:
--    from Crypto.Util import Counter
--except ImportError:
--    from paramiko.util import Counter
- 
- 
- # for thread cleanup
[email protected]@ -91,6 +89,9 @@ class Transport (threading.Thread, Closi
- 
-     Instances of this class may be used as context managers.
-     """
-+    _ENCRYPT = object()
-+    _DECRYPT = object()
-+
-     _PROTO_ID = '2.0'
-     _CLIENT_ID = 'paramiko_%s' % paramiko.__version__
- 
[email protected]@ -102,16 +103,57 @@ class Transport (threading.Thread, Closi
-     _preferred_compression = ('none',)
- 
-     _cipher_info = {
--        'aes128-ctr': {'class': AES, 'mode': AES.MODE_CTR, 'block-size': 16, 'key-size': 16},
--        'aes256-ctr': {'class': AES, 'mode': AES.MODE_CTR, 'block-size': 16, 'key-size': 32},
--        'blowfish-cbc': {'class': Blowfish, 'mode': Blowfish.MODE_CBC, 'block-size': 8, 'key-size': 16},
--        'aes128-cbc': {'class': AES, 'mode': AES.MODE_CBC, 'block-size': 16, 'key-size': 16},
--        'aes256-cbc': {'class': AES, 'mode': AES.MODE_CBC, 'block-size': 16, 'key-size': 32},
--        '3des-cbc': {'class': DES3, 'mode': DES3.MODE_CBC, 'block-size': 8, 'key-size': 24},
--        'arcfour128': {'class': ARC4, 'mode': None, 'block-size': 8, 'key-size': 16},
--        'arcfour256': {'class': ARC4, 'mode': None, 'block-size': 8, 'key-size': 32},
-+        'aes128-ctr': {
-+            'class': algorithms.AES,
-+            'mode': modes.CTR,
-+            'block-size': 16,
-+            'key-size': 16
-+        },
-+        'aes256-ctr': {
-+            'class': algorithms.AES,
-+            'mode': modes.CTR,
-+            'block-size': 16,
-+            'key-size': 32
-+        },
-+        'blowfish-cbc': {
-+            'class': algorithms.Blowfish,
-+            'mode': modes.CBC,
-+            'block-size': 8,
-+            'key-size': 16
-+        },
-+        'aes128-cbc': {
-+            'class': algorithms.AES,
-+            'mode': modes.CBC,
-+            'block-size': 16,
-+            'key-size': 16
-+        },
-+        'aes256-cbc': {
-+            'class': algorithms.AES,
-+            'mode': modes.CBC,
-+            'block-size': 16,
-+            'key-size': 32
-+        },
-+        '3des-cbc': {
-+            'class': algorithms.TripleDES,
-+            'mode': modes.CBC,
-+            'block-size': 8,
-+            'key-size': 24
-+        },
-+        'arcfour128': {
-+            'class': algorithms.ARC4,
-+            'mode': None,
-+            'block size': 8,
-+            'key-size': 16
-+        },
-+        'arcfour256': {
-+            'class': algorithms.ARC4,
-+            'mode': None,
-+            'block size': 8,
-+            'key-size': 32
-+        },
-     }
- 
-+
-     _mac_info = {
-         'hmac-sha1': {'class': sha1, 'size': 20},
-         'hmac-sha1-96': {'class': sha1, 'size': 12},
[email protected]@ -1508,22 +1550,34 @@ class Transport (threading.Thread, Closi
-             sofar += digest
-         return out[:nbytes]
- 
--    def _get_cipher(self, name, key, iv):
-+    def _get_cipher(self, name, key, iv, operation):
-         if name not in self._cipher_info:
-             raise SSHException('Unknown client cipher ' + name)
-         if name in ('arcfour128', 'arcfour256'):
-             # arcfour cipher
--            cipher = self._cipher_info[name]['class'].new(key)
-+            cipher = Cipher(
-+                self._cipher_info[name]['class'](key),
-+                None,
-+                backend=default_backend()
-+            )
-+            if operation is self._ENCRYPT:
-+                engine = cipher.encryptor()
-+            else:
-+                engine = cipher.decryptor()
-             # as per RFC 4345, the first 1536 bytes of keystream
-             # generated by the cipher MUST be discarded
--            cipher.encrypt(" " * 1536)
--            return cipher
--        elif name.endswith("-ctr"):
--            # CTR modes, we need a counter
--            counter = Counter.new(nbits=self._cipher_info[name]['block-size'] * 8, initial_value=util.inflate_long(iv, True))
--            return self._cipher_info[name]['class'].new(key, self._cipher_info[name]['mode'], iv, counter)
-+            engine.encrypt(" " * 1536)
-+            return engine
-         else:
--            return self._cipher_info[name]['class'].new(key, self._cipher_info[name]['mode'], iv)
-+            cipher = Cipher(
-+                self._cipher_info[name]['class'](key),
-+                self._cipher_info[name]['mode'](iv),
-+                backend=default_backend(),
-+            )
-+            if operation is self._ENCRYPT:
-+                return cipher.encryptor()
-+            else:
-+                return cipher.decryptor()
- 
-     def _set_forward_agent_handler(self, handler):
-         if handler is None:
[email protected]@ -1879,7 +1933,7 @@ class Transport (threading.Thread, Closi
-         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)
-+        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 potentially truncated
[email protected]@ -1906,7 +1960,7 @@ class Transport (threading.Thread, Closi
-         else:
-             IV_out = self._compute_key('A', block_size)
-             key_out = self._compute_key('C', self._cipher_info[self.local_cipher]['key-size'])
--        engine = self._get_cipher(self.local_cipher, key_out, IV_out)
-+        engine = self._get_cipher(self.local_cipher, key_out, IV_out, self._ENCRYPT)
-         mac_size = self._mac_info[self.local_mac]['size']
-         mac_engine = self._mac_info[self.local_mac]['class']
-         # initial mac keys are done in the hash's natural size (not the potentially truncated
---- paramiko-1.15.2/paramiko/util.py.~1~	2014-12-19 15:01:22.000000000 -0800
-+++ paramiko-1.15.2/paramiko/util.py	2015-04-12 17:36:15.210034924 -0700
[email protected]@ -22,7 +22,6 @@ Useful functions used by the rest of par
- 
- from __future__ import generators
- 
--import array
- import errno
- import sys
- import struct
[email protected]@ -31,7 +30,7 @@ import threading
- import logging
- 
- from paramiko.common import DEBUG, zero_byte, xffffffff, max_byte
--from paramiko.py3compat import PY2, long, byte_ord, b, byte_chr
-+from paramiko.py3compat import PY2, long, byte_chr, byte_ord, b
- from paramiko.config import SSHConfig
- 
- 
[email protected]@ -273,37 +272,6 @@ def retry_on_signal(function):
-                 raise
- 
- 
--class Counter (object):
--    """Stateful counter for CTR mode crypto"""
--    def __init__(self, nbits, initial_value=long(1), overflow=long(0)):
--        self.blocksize = nbits / 8
--        self.overflow = overflow
--        # start with value - 1 so we don't have to store intermediate values when counting
--        # could the iv be 0?
--        if initial_value == 0:
--            self.value = array.array('c', max_byte * self.blocksize)
--        else:
--            x = deflate_long(initial_value - 1, add_sign_padding=False)
--            self.value = array.array('c', zero_byte * (self.blocksize - len(x)) + x)
--
--    def __call__(self):
--        """Increament the counter and return the new value"""
--        i = self.blocksize - 1
--        while i > -1:
--            c = self.value[i] = byte_chr((byte_ord(self.value[i]) + 1) % 256)
--            if c != zero_byte:
--                return self.value.tostring()
--            i -= 1
--        # counter reset
--        x = deflate_long(self.overflow, add_sign_padding=False)
--        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)
--
--
- def constant_time_bytes_eq(a, b):
-     if len(a) != len(b):
-         return False
---- paramiko-1.15.2/setup.py.~1~	2014-12-19 15:01:22.000000000 -0800
-+++ paramiko-1.15.2/setup.py	2015-04-12 17:36:15.210254883 -0700
[email protected]@ -24,7 +24,7 @@ connections between python scripts.  All
- are supported.  SFTP client and server mode are both supported too.
- 
- Required packages:
--    pyCrypto
-+    Cryptography
- 
- To install the `in-development version
- <https://github.com/paramiko/paramiko/tarball/master#egg=paramiko-dev>`_, use
[email protected]@ -41,8 +41,8 @@ try:
-     from setuptools import setup
-     kw = {
-         'install_requires': [
--            'pycrypto >= 2.1, != 2.4',
--            'ecdsa >= 0.11',
-+            'cryptography >= 0.8',
-+            'pyasn1 >= 0.1.7',
-         ],
-     }
- except ImportError:
---- paramiko-1.15.2/tests/test_auth.py.~1~	2014-12-19 15:01:22.000000000 -0800
-+++ paramiko-1.15.2/tests/test_auth.py	2015-04-12 17:36:15.210519848 -0700
[email protected]@ -83,13 +83,13 @@ class NullServer (ServerInterface):
-                 return AUTH_SUCCESSFUL
-             return AUTH_PARTIALLY_SUCCESSFUL
-         return AUTH_FAILED
--    
-+
-     def check_auth_interactive(self, username, submethods):
-         if username == 'commie':
-             self.username = username
-             return InteractiveQuery('password', 'Please enter a password.', ('Password', False))
-         return AUTH_FAILED
--    
-+
-     def check_auth_interactive_response(self, responses):
-         if self.username == 'commie':
-             if (len(responses) == 1) and (responses[0] == 'cat'):
[email protected]@ -111,7 +111,7 @@ class AuthTest (unittest.TestCase):
-         self.ts.close()
-         self.socks.close()
-         self.sockc.close()
--    
-+
-     def start_server(self):
-         host_key = RSAKey.from_private_key_file(test_path('test_rsa.key'))
-         self.public_host_key = RSAKey(data=host_key.asbytes())
[email protected]@ -120,7 +120,7 @@ class AuthTest (unittest.TestCase):
-         self.server = NullServer()
-         self.assertTrue(not self.event.is_set())
-         self.ts.start_server(self.event, self.server)
--    
-+
-     def verify_finished(self):
-         self.event.wait(1.0)
-         self.assertTrue(self.event.is_set())
[email protected]@ -156,7 +156,7 @@ class AuthTest (unittest.TestCase):
-             self.assertTrue(issubclass(etype, AuthenticationException))
-         self.tc.auth_password(username='slowdive', password='pygmalion')
-         self.verify_finished()
--    
-+
-     def test_3_multipart_auth(self):
-         """
-         verify that multipart auth works.
[email protected]@ -187,7 +187,7 @@ class AuthTest (unittest.TestCase):
-         self.assertEqual(self.got_prompts, [('Password', False)])
-         self.assertEqual([], remain)
-         self.verify_finished()
--        
-+
-     def test_5_interactive_auth_fallback(self):
-         """
-         verify that a password auth attempt will fallback to "interactive"
---- paramiko-1.15.2/tests/test_client.py.~1~	2014-12-19 15:01:22.000000000 -0800
-+++ paramiko-1.15.2/tests/test_client.py	2015-04-12 17:36:15.210808627 -0700
[email protected]@ -22,6 +22,8 @@ Some unit tests for SSHClient.
- 
- from __future__ import with_statement
- 
-+import gc
-+import platform
- import socket
- from tempfile import mkstemp
- import threading
[email protected]@ -31,8 +33,9 @@ import warnings
- import os
- import time
- from tests.util import test_path
-+
- import paramiko
--from paramiko.common import PY2, b
-+from paramiko.common import PY2
- from paramiko.ssh_exception import SSHException
- 
- 
[email protected]@ -266,14 +269,13 @@ class SSHClientTest (unittest.TestCase):
-         transport's packetizer) is closed.
-         """
-         # Unclear why this is borked on Py3, but it is, and does not seem worth
--        # pursuing at the moment.
-+        # pursuing at the moment. Skipped on PyPy because it fails on travis
-+        # for unknown reasons, works fine locally.
-         # XXX: It's the release of the references to e.g packetizer that fails
-         # in py3...
--        if not PY2:
-+        if not PY2 or platform.python_implementation() == "PyPy":
-             return
-         threading.Thread(target=self._run).start()
--        host_key = paramiko.RSAKey.from_private_key_file(test_path('test_rsa.key'))
--        public_host_key = paramiko.RSAKey(data=host_key.asbytes())
- 
-         self.tc = paramiko.SSHClient()
-         self.tc.set_missing_host_key_policy(paramiko.AutoAddPolicy())
[email protected]@ -289,14 +291,10 @@ class SSHClientTest (unittest.TestCase):
-         self.tc.close()
-         del self.tc
- 
--        # hrm, sometimes p isn't cleared right away.  why is that?
--        #st = time.time()
--        #while (time.time() - st < 5.0) and (p() is not None):
--        #    time.sleep(0.1)
--
--        # instead of dumbly waiting for the GC to collect, force a collection
--        # to see whether the SSHClient object is deallocated correctly
--        import gc
-+        # force a collection to see whether the SSHClient object is deallocated
-+        # correctly. 2 GCs are needed to make sure it's really collected on
-+        # PyPy
-+        gc.collect()
-         gc.collect()
- 
-         self.assertTrue(p() is None)
[email protected]@ -306,8 +304,6 @@ class SSHClientTest (unittest.TestCase):
-         verify that an SSHClient can be used a context manager
-         """
-         threading.Thread(target=self._run).start()
--        host_key = paramiko.RSAKey.from_private_key_file(test_path('test_rsa.key'))
--        public_host_key = paramiko.RSAKey(data=host_key.asbytes())
- 
-         with paramiko.SSHClient() as tc:
-             self.tc = tc
---- paramiko-1.15.2/tests/test_packetizer.py.~1~	2014-12-19 15:01:22.000000000 -0800
-+++ paramiko-1.15.2/tests/test_packetizer.py	2015-04-12 17:36:15.211084420 -0700
[email protected]@ -23,9 +23,10 @@ Some unit tests for the ssh2 protocol in
- import unittest
- from hashlib import sha1
- 
--from tests.loop import LoopSocket
-+from cryptography.hazmat.backends import default_backend
-+from cryptography.hazmat.primitives.ciphers import algorithms, Cipher, modes
- 
--from Crypto.Cipher import AES
-+from tests.loop import LoopSocket
- 
- from paramiko import Message, Packetizer, util
- from paramiko.common import byte_chr, zero_byte
[email protected]@ -43,8 +44,12 @@ class PacketizerTest (unittest.TestCase)
-         p = Packetizer(wsock)
-         p.set_log(util.get_logger('paramiko.transport'))
-         p.set_hexdump(True)
--        cipher = AES.new(zero_byte * 16, AES.MODE_CBC, x55 * 16)
--        p.set_outbound_cipher(cipher, 16, sha1, 12, x1f * 20)
-+        encryptor = Cipher(
-+            algorithms.AES(zero_byte * 16),
-+            modes.CBC(x55 * 16),
-+            backend=default_backend()
-+        ).encryptor()
-+        p.set_outbound_cipher(encryptor, 16, sha1, 12, x1f * 20)
- 
-         # message has to be at least 16 bytes long, so we'll have at least one
-         # block of data encrypted that contains zero random padding bytes
[email protected]@ -66,8 +71,12 @@ class PacketizerTest (unittest.TestCase)
-         p = Packetizer(rsock)
-         p.set_log(util.get_logger('paramiko.transport'))
-         p.set_hexdump(True)
--        cipher = AES.new(zero_byte * 16, AES.MODE_CBC, x55 * 16)
--        p.set_inbound_cipher(cipher, 16, sha1, 12, x1f * 20)
-+        decryptor = Cipher(
-+            algorithms.AES(zero_byte * 16),
-+            modes.CBC(x55 * 16),
-+            backend=default_backend()
-+        ).decryptor()
-+        p.set_inbound_cipher(decryptor, 16, sha1, 12, x1f * 20)
-         wsock.send(b'\x43\x91\x97\xbd\x5b\x50\xac\x25\x87\xc2\xc4\x6b\xc7\xe9\x38\xc0\x90\xd2\x16\x56\x0d\x71\x73\x61\x38\x7c\x4c\x3d\xfb\x97\x7d\xe2\x6e\x03\xb1\xa0\xc2\x1c\xd6\x41\x41\x4c\xb4\x59')
-         cmd, m = p.read_message()
-         self.assertEqual(100, cmd)
[email protected]@ -82,8 +91,12 @@ class PacketizerTest (unittest.TestCase)
-         p = Packetizer(wsock)
-         p.set_log(util.get_logger('paramiko.transport'))
-         p.set_hexdump(True)
--        cipher = AES.new(zero_byte * 16, AES.MODE_CBC, x55 * 16)
--        p.set_outbound_cipher(cipher, 16, sha1, 12, x1f * 20)
-+        encryptor = Cipher(
-+            algorithms.AES(zero_byte * 16),
-+            modes.CBC(x55 * 16),
-+            backend=default_backend()
-+        ).encryptor()
-+        p.set_outbound_cipher(encryptor, 16, sha1, 12, x1f * 20)
- 
-         # message has to be at least 16 bytes long, so we'll have at least one
-         # block of data encrypted that contains zero random padding bytes
---- paramiko-1.15.2/tests/test_pkey.py.~1~	2014-12-19 15:01:22.000000000 -0800
-+++ paramiko-1.15.2/tests/test_pkey.py	2015-04-12 17:36:15.211328345 -0700
[email protected]@ -42,34 +42,34 @@ SIGNED_RSA = '20:d7:8a:31:21:cb:f7:92:12
- 
- RSA_PRIVATE_OUT = """\
- -----BEGIN RSA PRIVATE KEY-----
--MIICXAIBAAKCAIEA049W6geFpmsljTwfvI1UmKWWJPNFI74+vNKTk4dmzkQY2yAM
--s6FhlvhlI8ysU4oj71ZsRYMecHbBbxdN79+JRFVYTKaLqjwGENeTd+yv4q+V2PvZ
--v3fLnzApI3l7EJCqhWwJUHJ1jAkZzqDx0tyOL4uoZpww3nmE0kb3y21tH4cCASMC
--ggCAEiI6plhqipt4P05L3PYr0pHZq2VPEbE4k9eI/gRKo/c1VJxY3DJnc1cenKsk
--trQRtW3OxCEufqsX5PNec6VyKkW+Ox6beJjMKm4KF8ZDpKi9Nw6MdX3P6Gele9D9
--+ieyhVFljrnAqcXsgChTBOYlL2imqCs3qRGAJ3cMBIAx3VsCQQD3pIFVYW398kE0
--n0e1icEpkbDRV4c5iZVhu8xKy2yyfy6f6lClSb2+Ub9uns7F3+b5v0pYSHbE9+/r
--OpRq83AfAkEA2rMZlr8SnMXgnyka2LuggA9QgMYy18hyao1dUxySubNDa9N+q2QR
--mwDisTUgRFHKIlDHoQmzPbXAmYZX1YlDmQJBAPCRLS5epV0XOAc7pL762OaNhzHC
--veAfQKgVhKBt105PqaKpGyQ5AXcNlWQlPeTK4GBTbMrKDPna6RBkyrEJvV8CQBK+
--5O+p+kfztCrmRCE0p1tvBuZ3Y3GU1ptrM+KNa6mEZN1bRV8l1Z+SXJLYqv6Kquz/
--nBUeFq2Em3rfoSDugiMCQDyG3cxD5dKX3IgkhLyBWls/FLDk4x/DQ+NUTu0F1Cu6
--JJye+5ARLkL0EweMXf0tmIYfWItDLsWB0fKg/56h0js=
-+MIICWgIBAAKBgQDTj1bqB4WmayWNPB+8jVSYpZYk80Ujvj680pOTh2bORBjbIAyz
-+oWGW+GUjzKxTiiPvVmxFgx5wdsFvF03v34lEVVhMpouqPAYQ15N37K/ir5XY+9m/
-+d8ufMCkjeXsQkKqFbAlQcnWMCRnOoPHS3I4vi6hmnDDeeYTSRvfLbW0fhwIBIwKB
-+gBIiOqZYaoqbeD9OS9z2K9KR2atlTxGxOJPXiP4ESqP3NVScWNwyZ3NXHpyrJLa0
-+EbVtzsQhLn6rF+TzXnOlcipFvjsem3iYzCpuChfGQ6SovTcOjHV9z+hnpXvQ/fon
-+soVRZY65wKnF7IAoUwTmJS9opqgrN6kRgCd3DASAMd1bAkEA96SBVWFt/fJBNJ9H
-+tYnBKZGw0VeHOYmVYbvMSstssn8un+pQpUm9vlG/bp7Oxd/m+b9KWEh2xPfv6zqU
-+avNwHwJBANqzGZa/EpzF4J8pGti7oIAPUIDGMtfIcmqNXVMckrmzQ2vTfqtkEZsA
-+4rE1IERRyiJQx6EJsz21wJmGV9WJQ5kCQQDwkS0uXqVdFzgHO6S++tjmjYcxwr3g
-+H0CoFYSgbddOT6miqRskOQF3DZVkJT3kyuBgU2zKygz52ukQZMqxCb1fAkASvuTv
-+qfpH87Qq5kQhNKdbbwbmd2NxlNabazPijWuphGTdW0VfJdWfklyS2Kr+iqrs/5wV
-+HhathJt636Eg7oIjAkA8ht3MQ+XSl9yIJIS8gVpbPxSw5OMfw0PjVE7tBdQruiSc
-+nvuQES5C9BMHjF39LZiGH1iLQy7FgdHyoP+eodI7
- -----END RSA PRIVATE KEY-----
- """
- 
- DSS_PRIVATE_OUT = """\
- -----BEGIN DSA PRIVATE KEY-----
--MIIBvgIBAAKCAIEA54GmA2d9HOv+3CYBBG7ZfBYCncIW2tWe6Dqzp+DCP+guNhtW
--2MDLqmX+HQQoJbHat/Uh63I2xPFaueID0jod4OPrlfUXIOSDqDy28Kdo0Hxen9RS
--G7Me4awwiKlHEHHD0sXrTwSplyPUTfK2S2hbkHk5yOuQSjPfEbsL6ukiNi8CFQDw
--z4UnmsGiSNu5iqjn3uTzwUpshwKCAIEAkxfFeY8P2wZpDjX0MimZl5wkoFQDL25c
--PzGBuB4OnB8NoUk/yjAHIIpEShw8V+LzouMK5CTJQo5+Ngw3qIch/WgRmMHy4kBq
--1SsXMjQCte1So6HBMvBPIW5SiMTmjCfZZiw4AYHK+B/JaOwaG9yRg2Ejg4Ok10+X
--FDxlqZo8Y+wCggCARmR7CCPjodxASvRbIyzaVpZoJ/Z6x7dAumV+ysrV1BVYd0lY
--ukmnjO1kKBWApqpH1ve9XDQYN8zgxM4b16L21kpoWQnZtXrY3GZ4/it9kUgyB7+N
--wacIBlXa8cMDL7Q/69o0d54U0X/NeX5QxuYR6OMJlrkQB7oiW/P/1mwjQgECFGI9
--QPSch9pT9XHqn+1rZ4bK+QGA
-+MIIBuwIBAAKBgQDngaYDZ30c6/7cJgEEbtl8FgKdwhba1Z7oOrOn4MI/6C42G1bY
-+wMuqZf4dBCglsdq39SHrcjbE8Vq54gPSOh3g4+uV9Rcg5IOoPLbwp2jQfF6f1FIb
-+sx7hrDCIqUcQccPSxetPBKmXI9RN8rZLaFuQeTnI65BKM98Ruwvq6SI2LwIVAPDP
-+hSeawaJI27mKqOfe5PPBSmyHAoGBAJMXxXmPD9sGaQ419DIpmZecJKBUAy9uXD8x
-+gbgeDpwfDaFJP8owByCKREocPFfi86LjCuQkyUKOfjYMN6iHIf1oEZjB8uJAatUr
-+FzI0ArXtUqOhwTLwTyFuUojE5own2WYsOAGByvgfyWjsGhvckYNhI4ODpNdPlxQ8
-+ZamaPGPsAoGARmR7CCPjodxASvRbIyzaVpZoJ/Z6x7dAumV+ysrV1BVYd0lYukmn
-+jO1kKBWApqpH1ve9XDQYN8zgxM4b16L21kpoWQnZtXrY3GZ4/it9kUgyB7+NwacI
-+BlXa8cMDL7Q/69o0d54U0X/NeX5QxuYR6OMJlrkQB7oiW/P/1mwjQgECFGI9QPSc
-+h9pT9XHqn+1rZ4bK+QGA
- -----END DSA PRIVATE KEY-----
- """
- 
[email protected]@ -121,7 +121,7 @@ class KeyTest (unittest.TestCase):
-         self.assertEqual(exp_rsa, my_rsa)
-         self.assertEqual(PUB_RSA.split()[1], key.get_base64())
-         self.assertEqual(1024, key.get_bits())
--        
-+
-     def test_4_load_dss(self):
-         key = DSSKey.from_private_key_file(test_path('test_dss.key'))
-         self.assertEqual('ssh-dss', key.get_name())
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/python/paramiko/patches/03-system-test.patch	Thu Aug 25 13:50:44 2016 -0700
@@ -0,0 +1,23 @@
+#
+# Support system-test target.
+# 
+# This patch hacks sys.path in test.py to avoid importing paramiko
+# module from $(SOURCE) directory, but instead import it from PYTHONPATH.
+#
+# Patch source: in-house
+# Solaris specific, not suitable for upstream contribution.
+#
+--- old/test.py
++++ new/test.py
[email protected]@ -27,7 +27,11 @@ import re
+ import sys
+ import unittest
+ from optparse import OptionParser
++
++# to support system-test target, honor PYTHONPATH for paramiko import
++curdir = sys.path.pop(0)
+ import paramiko
++sys.path.insert(0, curdir)
+ import threading
+ from paramiko.py3compat import PY2
+ 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/python/paramiko/test/results-all.master	Thu Aug 25 13:50:44 2016 -0700
@@ -0,0 +1,175 @@
+test_1_encode (tests.test_message.MessageTest) ... ok
+test_2_decode (tests.test_message.MessageTest) ... ok
+test_3_add (tests.test_message.MessageTest) ... ok
+test_4_misc (tests.test_message.MessageTest) ... ok
+test_1_simple (tests.test_file.BufferedFileTest) ... ok
+test_2_readline (tests.test_file.BufferedFileTest) ... ok
+test_3_lf (tests.test_file.BufferedFileTest) ... ok
+test_4_write (tests.test_file.BufferedFileTest) ... ok
+test_5_flush (tests.test_file.BufferedFileTest) ... ok
+test_6_buffering (tests.test_file.BufferedFileTest) ... ok
+test_7_read_all (tests.test_file.BufferedFileTest) ... ok
+test_8_buffering (tests.test_file.BufferedFileTest) ... ok
+test_9_readable (tests.test_file.BufferedFileTest) ... ok
+test_A_writable (tests.test_file.BufferedFileTest) ... ok
+test_B_readinto (tests.test_file.BufferedFileTest) ... ok
+test_1_buffered_pipe (tests.test_buffered_pipe.BufferedPipeTest) ... ok
+test_2_delay (tests.test_buffered_pipe.BufferedPipeTest) ... ok
+test_3_close_while_reading (tests.test_buffered_pipe.BufferedPipeTest) ... ok
+test_4_or_pipe (tests.test_buffered_pipe.BufferedPipeTest) ... ok
+test_10_proxycommand_interpolation (tests.test_util.UtilTest) ... ok
+test_11_host_config_test_identityfile (tests.test_util.UtilTest) ... ok
+test_11_host_config_test_negation (tests.test_util.UtilTest) ... ok
+test_12_config_addressfamily_and_lazy_fqdn (tests.test_util.UtilTest) ... ok
+test_12_host_config_test_proxycommand (tests.test_util.UtilTest) ... ok
+test_13_config_dos_crlf_succeeds (tests.test_util.UtilTest) ... ok
+test_14_get_hostnames (tests.test_util.UtilTest) ... ok
+test_1_import (tests.test_util.UtilTest) ... ok
+test_2_parse_config (tests.test_util.UtilTest) ... ok
+test_3_host_config (tests.test_util.UtilTest) ... ok
+test_4_generate_key_bytes (tests.test_util.UtilTest) ... ok
+test_5_host_keys (tests.test_util.UtilTest) ... ok
+test_7_host_config_expose_issue_33 (tests.test_util.UtilTest) ... ok
+test_8_eintr_retry (tests.test_util.UtilTest) ... ok
+test_9_proxycommand_config_equals_parsing (tests.test_util.UtilTest) ... ok
+test_clamp_value (tests.test_util.UtilTest) ... ok
+test_proxycommand_none_issue_418 (tests.test_util.UtilTest) ... ok
+test_proxycommand_none_masking (tests.test_util.UtilTest) ... ok
+test_quoted_host_in_config (tests.test_util.UtilTest) ... ok
+test_quoted_host_names (tests.test_util.UtilTest) ... ok
+test_quoted_params_in_config (tests.test_util.UtilTest) ... ok
+test_safe_string (tests.test_util.UtilTest) ... ok
+test_1_load (tests.test_hostkeys.HostKeysTest) ... ok
+test_2_add (tests.test_hostkeys.HostKeysTest) ... ok
+test_3_dict (tests.test_hostkeys.HostKeysTest) ... ok
+test_4_dict_set (tests.test_hostkeys.HostKeysTest) ... ok
+test_10_load_ecdsa_256 (tests.test_pkey.KeyTest) ... ERROR
+test_11_load_ecdsa_password_256 (tests.test_pkey.KeyTest) ... ERROR
+test_12_compare_ecdsa_256 (tests.test_pkey.KeyTest) ... ERROR
+test_13_sign_ecdsa_256 (tests.test_pkey.KeyTest) ... ERROR
+test_14_load_ecdsa_384 (tests.test_pkey.KeyTest) ... ERROR
+test_15_load_ecdsa_password_384 (tests.test_pkey.KeyTest) ... ERROR
+test_16_compare_ecdsa_384 (tests.test_pkey.KeyTest) ... ERROR
+test_17_sign_ecdsa_384 (tests.test_pkey.KeyTest) ... ERROR
+test_18_load_ecdsa_521 (tests.test_pkey.KeyTest) ... ERROR
+test_19_load_ecdsa_password_521 (tests.test_pkey.KeyTest) ... ERROR
+test_1_generate_key_bytes (tests.test_pkey.KeyTest) ... ok
+test_20_compare_ecdsa_521 (tests.test_pkey.KeyTest) ... ERROR
+test_21_sign_ecdsa_521 (tests.test_pkey.KeyTest) ... ERROR
+test_2_load_rsa (tests.test_pkey.KeyTest) ... ok
+test_3_load_rsa_password (tests.test_pkey.KeyTest) ... ok
+test_4_load_dss (tests.test_pkey.KeyTest) ... ok
+test_5_load_dss_password (tests.test_pkey.KeyTest) ... ok
+test_6_compare_rsa (tests.test_pkey.KeyTest) ... ok
+test_7_compare_dss (tests.test_pkey.KeyTest) ... ok
+test_8_sign_rsa (tests.test_pkey.KeyTest) ... ok
+test_9_sign_dss (tests.test_pkey.KeyTest) ... ok
+test_A_generate_rsa (tests.test_pkey.KeyTest) ... ok
+test_B_generate_dss (tests.test_pkey.KeyTest) ... ok
+test_C_generate_ecdsa (tests.test_pkey.KeyTest) ... ERROR
+test_salt_size (tests.test_pkey.KeyTest) ... ok
+test_10_gex_sha256_server_with_old_client (tests.test_kex.KexTest) ... ok
+test_1_group1_client (tests.test_kex.KexTest) ... ok
+test_2_group1_server (tests.test_kex.KexTest) ... ok
+test_3_gex_client (tests.test_kex.KexTest) ... ok
+test_4_gex_old_client (tests.test_kex.KexTest) ... ok
+test_5_gex_server (tests.test_kex.KexTest) ... ok
+test_6_gex_server_with_old_client (tests.test_kex.KexTest) ... ok
+test_7_gex_sha256_client (tests.test_kex.KexTest) ... ok
+test_8_gex_sha256_old_client (tests.test_kex.KexTest) ... ok
+test_9_gex_sha256_server (tests.test_kex.KexTest) ... ok
+test_1_write (tests.test_packetizer.PacketizerTest) ... ok
+test_2_read (tests.test_packetizer.PacketizerTest) ... ok
+test_3_closed (tests.test_packetizer.PacketizerTest) ... ok
+test_1_bad_auth_type (tests.test_auth.AuthTest) ... ok
+test_2_bad_password (tests.test_auth.AuthTest) ... ok
+test_3_multipart_auth (tests.test_auth.AuthTest) ... ok
+test_4_interactive_auth (tests.test_auth.AuthTest) ... ok
+test_5_interactive_auth_fallback (tests.test_auth.AuthTest) ... ok
+test_6_auth_utf8 (tests.test_auth.AuthTest) ... ok
+test_7_auth_non_utf8 (tests.test_auth.AuthTest) ... ok
+test_8_auth_gets_disconnected (tests.test_auth.AuthTest) ... ok
+test_1_security_options (tests.test_transport.TransportTest) ... ok
+test_2_compute_key (tests.test_transport.TransportTest) ... ok
+test_3_simple (tests.test_transport.TransportTest) ... ok
+test_3a_long_banner (tests.test_transport.TransportTest) ... ok
+test_4_special (tests.test_transport.TransportTest) ... ok
+test_5_keepalive (tests.test_transport.TransportTest) ... ok
+test_6_exec_command (tests.test_transport.TransportTest) ... ok
+test_6a_channel_can_be_used_as_context_manager (tests.test_transport.TransportTest) ... ok
+test_7_invoke_shell (tests.test_transport.TransportTest) ... ok
+test_8_channel_exception (tests.test_transport.TransportTest) ... ok
+test_9_exit_status (tests.test_transport.TransportTest) ... ok
+test_A_select (tests.test_transport.TransportTest) ... ok
+test_B_renegotiate (tests.test_transport.TransportTest) ... ok
+test_C_compression (tests.test_transport.TransportTest) ... ok
+test_D_x11 (tests.test_transport.TransportTest) ... ok
+test_E_reverse_port_forwarding (tests.test_transport.TransportTest) ... ok
+test_F_port_forwarding (tests.test_transport.TransportTest) ... ok
+test_G_stderr_select (tests.test_transport.TransportTest) ... ok
+test_H_send_ready (tests.test_transport.TransportTest) ... ok
+test_I_rekey_deadlock (tests.test_transport.TransportTest) ... ok
+test_J_sanitze_packet_size (tests.test_transport.TransportTest) ... ok
+test_K_sanitze_window_size (tests.test_transport.TransportTest) ... ok
+test_L_handshake_timeout (tests.test_transport.TransportTest) ... ok
+test_M_select_after_close (tests.test_transport.TransportTest) ... ok
+test_error_message_for_multiple_hosts (tests.test_ssh_exception.NoValidConnectionsErrorTest) ... ok
+test_error_message_for_single_host (tests.test_ssh_exception.NoValidConnectionsErrorTest) ... ok
+test_error_message_for_two_hosts (tests.test_ssh_exception.NoValidConnectionsErrorTest) ... ok
+test_pickling (tests.test_ssh_exception.NoValidConnectionsErrorTest) ... ok
+test_1_client (test_client.SSHClientTest) ... ok
+test_2_5_client_ecdsa (test_client.SSHClientTest) ... ERROR
+test_2_client_dsa (test_client.SSHClientTest) ... ok
+test_3_multiple_key_files (test_client.SSHClientTest) ... ERROR
+test_4_auto_add_policy (test_client.SSHClientTest) ... ok
+test_5_save_host_keys (test_client.SSHClientTest) ... ok
+test_6_cleanup (test_client.SSHClientTest) ... ok
+test_7_banner_timeout (test_client.SSHClientTest) ... ok
+test_8_auth_trickledown (test_client.SSHClientTest) ... ok
+test_client_can_be_used_as_context_manager (test_client.SSHClientTest) ... ok
+test_client_rsa (test_client.SSHClientTest) ... ok
+test_multiple_key_files_failure (test_client.SSHClientTest) ... ok
+test_1_file (tests.test_sftp.SFTPTest) ... ok
+test_2_close (tests.test_sftp.SFTPTest) ... ok
+test_2_sftp_can_be_used_as_context_manager (tests.test_sftp.SFTPTest) ... ok
+test_3_sftp_file_can_be_used_as_context_manager (tests.test_sftp.SFTPTest) ... ok
+test_3_write (tests.test_sftp.SFTPTest) ... ok
+test_4_append (tests.test_sftp.SFTPTest) ... ok
+test_5_rename (tests.test_sftp.SFTPTest) ... ok
+test_6_folder (tests.test_sftp.SFTPTest) ... ok
+test_7_5_listdir_iter (tests.test_sftp.SFTPTest) ... ok
+test_7_listdir (tests.test_sftp.SFTPTest) ... ok
+test_8_setstat (tests.test_sftp.SFTPTest) ... ok
+test_9_fsetstat (tests.test_sftp.SFTPTest) ... ok
+test_A_readline_seek (tests.test_sftp.SFTPTest) ... ok
+test_B_write_seek (tests.test_sftp.SFTPTest) ... ok
+test_C_symlink (tests.test_sftp.SFTPTest) ... ok
+test_D_flush_seek (tests.test_sftp.SFTPTest) ... ok
+test_E_realpath (tests.test_sftp.SFTPTest) ... ok
+test_F_mkdir (tests.test_sftp.SFTPTest) ... ok
+test_G_chdir (tests.test_sftp.SFTPTest) ... ok
+test_H_get_put (tests.test_sftp.SFTPTest) ... ok
+test_I_check (tests.test_sftp.SFTPTest) ... ok
+test_J_x_flag (tests.test_sftp.SFTPTest) ... ok
+test_K_utf8 (tests.test_sftp.SFTPTest) ... ok
+test_L_utf8_chdir (tests.test_sftp.SFTPTest) ... ok
+test_M_bad_readv (tests.test_sftp.SFTPTest) ... ok
+test_N_file_with_percent (tests.test_sftp.SFTPTest) ... ok
+test_N_put_without_confirm (tests.test_sftp.SFTPTest) ... ok
+test_O_getcwd (tests.test_sftp.SFTPTest) ... ok
+test_O_non_utf8_data (tests.test_sftp.SFTPTest)
+Test write() and read() of non utf8 data ... ok
+test_putfo_empty_file (tests.test_sftp.SFTPTest) ... ok
+test_sftp_attributes_empty_str (tests.test_sftp.SFTPTest) ... ok
+test_1_lots_of_files (tests.test_sftp_big.BigSFTPTest) ... ok
+test_2_big_file (tests.test_sftp_big.BigSFTPTest) ... ........ Xs Xs ok
+test_3_big_file_pipelined (tests.test_sftp_big.BigSFTPTest) ... ........ Xs Xs ok
+test_4_prefetch_seek (tests.test_sftp_big.BigSFTPTest) ... ........ Xs ok
+test_5_readv_seek (tests.test_sftp_big.BigSFTPTest) ... ........ Xs ok
+test_6_lots_of_prefetching (tests.test_sftp_big.BigSFTPTest) ... ........ ........ ok
+test_7_prefetch_readv (tests.test_sftp_big.BigSFTPTest) ... ........  ok
+test_8_large_readv (tests.test_sftp_big.BigSFTPTest) ... ........  ok
+test_9_big_file_big_buffer (tests.test_sftp_big.BigSFTPTest) ... ok
+test_A_big_file_renegotiate (tests.test_sftp_big.BigSFTPTest) ... ok
+
+======================================================================