summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeff Forcier <jeff@bitprophet.org>2019-06-21 12:07:14 -0400
committerJeff Forcier <jeff@bitprophet.org>2019-06-21 12:07:14 -0400
commit37afc45c01242e99baf5264692682c076c3c0052 (patch)
tree7d080e9df937ed7c7f129d7806d2e0b7304e7df8
parentecae381a4840695f8e0e90b2d92c2da042fe780d (diff)
parent467079cdfa036b346cb4dddfc1cac2a440430a9b (diff)
downloadparamiko-37afc45c01242e99baf5264692682c076c3c0052.tar.gz
Merge branch 'master' into 1311-int
-rw-r--r--dev-requirements.txt7
-rw-r--r--paramiko/__init__.py7
-rw-r--r--paramiko/channel.py38
-rw-r--r--paramiko/client.py2
-rw-r--r--paramiko/kex_curve25519.py129
-rw-r--r--paramiko/kex_group1.py2
-rw-r--r--paramiko/kex_group14.py7
-rw-r--r--paramiko/kex_group16.py35
-rw-r--r--paramiko/packet.py87
-rw-r--r--paramiko/transport.py22
-rw-r--r--setup.cfg6
-rw-r--r--sites/www/changelog.rst33
-rw-r--r--tests/stub_sftp.py19
-rw-r--r--tests/test_auth.py4
-rw-r--r--tests/test_buffered_pipe.py9
-rw-r--r--tests/test_channelfile.py60
-rw-r--r--tests/test_client.py62
-rw-r--r--tests/test_file.py26
-rw-r--r--tests/test_gssapi.py4
-rw-r--r--tests/test_hostkeys.py12
-rw-r--r--tests/test_kex.py204
-rw-r--r--tests/test_kex_gss.py4
-rw-r--r--tests/test_message.py16
-rw-r--r--tests/test_packetizer.py10
-rw-r--r--tests/test_pkey.py71
-rw-r--r--tests/test_sftp.py117
-rw-r--r--tests/test_sftp_big.py25
-rw-r--r--tests/test_ssh_gss.py7
-rw-r--r--tests/test_transport.py111
-rw-r--r--tests/test_util.py22
30 files changed, 818 insertions, 340 deletions
diff --git a/dev-requirements.txt b/dev-requirements.txt
index 4c118991..f4f84748 100644
--- a/dev-requirements.txt
+++ b/dev-requirements.txt
@@ -1,11 +1,10 @@
# Invocations for common project tasks
invoke>=1.0,<2.0
invocations>=1.2.0,<2.0
-# NOTE: pytest-relaxed currently only works with pytest >=3, <3.3
-pytest>=3.2,<3.3
-pytest-relaxed==1.1.4
+pytest==4.4.2
+pytest-relaxed==1.1.5
# pytest-xdist for test dir watching and the inv guard task
-pytest-xdist>=1.22,<1.25.0
+pytest-xdist==1.28.0
mock==2.0.0
# Linting!
flake8==3.6.0
diff --git a/paramiko/__init__.py b/paramiko/__init__.py
index ebfa72a8..8ac52579 100644
--- a/paramiko/__init__.py
+++ b/paramiko/__init__.py
@@ -29,7 +29,12 @@ from paramiko.client import (
)
from paramiko.auth_handler import AuthHandler
from paramiko.ssh_gss import GSSAuth, GSS_AUTH_AVAILABLE, GSS_EXCEPTIONS
-from paramiko.channel import Channel, ChannelFile
+from paramiko.channel import (
+ Channel,
+ ChannelFile,
+ ChannelStderrFile,
+ ChannelStdinFile,
+)
from paramiko.ssh_exception import (
SSHException,
PasswordRequiredException,
diff --git a/paramiko/channel.py b/paramiko/channel.py
index 41b18958..72f65012 100644
--- a/paramiko/channel.py
+++ b/paramiko/channel.py
@@ -889,12 +889,30 @@ class Channel(ClosingContextManager):
client, it only makes sense to open this file for reading. For a
server, it only makes sense to open this file for writing.
- :return: `.ChannelFile` object which can be used for Python file I/O.
+ :returns:
+ `.ChannelStderrFile` object which can be used for Python file I/O.
.. versionadded:: 1.1
"""
return ChannelStderrFile(*([self] + list(params)))
+ def makefile_stdin(self, *params):
+ """
+ Return a file-like object associated with this channel's stdin
+ stream.
+
+ The optional ``mode`` and ``bufsize`` arguments are interpreted the
+ same way as by the built-in ``file()`` function in Python. For a
+ client, it only makes sense to open this file for writing. For a
+ server, it only makes sense to open this file for reading.
+
+ :returns:
+ `.ChannelStdinFile` object which can be used for Python file I/O.
+
+ .. versionadded:: 2.6
+ """
+ return ChannelStdinFile(*([self] + list(params)))
+
def fileno(self):
"""
Returns an OS-level file descriptor which can be used for polling, but
@@ -1348,8 +1366,11 @@ class ChannelFile(BufferedFile):
class ChannelStderrFile(ChannelFile):
- def __init__(self, channel, mode="r", bufsize=-1):
- ChannelFile.__init__(self, channel, mode, bufsize)
+ """
+ A file-like wrapper around `.Channel` stderr.
+
+ See `Channel.makefile_stderr` for details.
+ """
def _read(self, size):
return self.channel.recv_stderr(size)
@@ -1359,4 +1380,13 @@ class ChannelStderrFile(ChannelFile):
return len(data)
-# vim: set shiftwidth=4 expandtab :
+class ChannelStdinFile(ChannelFile):
+ """
+ A file-like wrapper around `.Channel` stdin.
+
+ See `Channel.makefile_stdin` for details.
+ """
+
+ def close(self):
+ super(ChannelStdinFile, self).close()
+ self.channel.shutdown_write()
diff --git a/paramiko/client.py b/paramiko/client.py
index 6bf479d4..a47efbfe 100644
--- a/paramiko/client.py
+++ b/paramiko/client.py
@@ -503,7 +503,7 @@ class SSHClient(ClosingContextManager):
if environment:
chan.update_environment(environment)
chan.exec_command(command)
- stdin = chan.makefile("wb", bufsize)
+ stdin = chan.makefile_stdin("wb", bufsize)
stdout = chan.makefile("r", bufsize)
stderr = chan.makefile_stderr("r", bufsize)
return stdin, stdout, stderr
diff --git a/paramiko/kex_curve25519.py b/paramiko/kex_curve25519.py
new file mode 100644
index 00000000..59710c1a
--- /dev/null
+++ b/paramiko/kex_curve25519.py
@@ -0,0 +1,129 @@
+import binascii
+import hashlib
+
+from cryptography.exceptions import UnsupportedAlgorithm
+from cryptography.hazmat.primitives import constant_time, serialization
+from cryptography.hazmat.primitives.asymmetric.x25519 import (
+ X25519PrivateKey,
+ X25519PublicKey,
+)
+
+from paramiko.message import Message
+from paramiko.py3compat import byte_chr, long
+from paramiko.ssh_exception import SSHException
+
+
+_MSG_KEXECDH_INIT, _MSG_KEXECDH_REPLY = range(30, 32)
+c_MSG_KEXECDH_INIT, c_MSG_KEXECDH_REPLY = [byte_chr(c) for c in range(30, 32)]
+
+
+class KexCurve25519(object):
+ hash_algo = hashlib.sha256
+
+ def __init__(self, transport):
+ self.transport = transport
+ self.key = None
+
+ @classmethod
+ def is_available(cls):
+ try:
+ X25519PrivateKey.generate()
+ except UnsupportedAlgorithm:
+ return False
+ else:
+ return True
+
+ def _perform_exchange(self, peer_key):
+ secret = self.key.exchange(peer_key)
+ if constant_time.bytes_eq(secret, b"\x00" * 32):
+ raise SSHException(
+ "peer's curve25519 public value has wrong order"
+ )
+ return secret
+
+ def start_kex(self):
+ self.key = X25519PrivateKey.generate()
+ if self.transport.server_mode:
+ self.transport._expect_packet(_MSG_KEXECDH_INIT)
+ return
+
+ m = Message()
+ m.add_byte(c_MSG_KEXECDH_INIT)
+ m.add_string(
+ self.key.public_key().public_bytes(
+ serialization.Encoding.Raw, serialization.PublicFormat.Raw
+ )
+ )
+ self.transport._send_message(m)
+ self.transport._expect_packet(_MSG_KEXECDH_REPLY)
+
+ def parse_next(self, ptype, m):
+ if self.transport.server_mode and (ptype == _MSG_KEXECDH_INIT):
+ return self._parse_kexecdh_init(m)
+ elif not self.transport.server_mode and (ptype == _MSG_KEXECDH_REPLY):
+ return self._parse_kexecdh_reply(m)
+ raise SSHException(
+ "KexCurve25519 asked to handle packet type {:d}".format(ptype)
+ )
+
+ def _parse_kexecdh_init(self, m):
+ peer_key_bytes = m.get_string()
+ peer_key = X25519PublicKey.from_public_bytes(peer_key_bytes)
+ K = self._perform_exchange(peer_key)
+ K = long(binascii.hexlify(K), 16)
+ # compute exchange hash
+ hm = Message()
+ hm.add(
+ self.transport.remote_version,
+ self.transport.local_version,
+ self.transport.remote_kex_init,
+ self.transport.local_kex_init,
+ )
+ server_key_bytes = self.transport.get_server_key().asbytes()
+ exchange_key_bytes = self.key.public_key().public_bytes(
+ serialization.Encoding.Raw, serialization.PublicFormat.Raw
+ )
+ hm.add_string(server_key_bytes)
+ hm.add_string(peer_key_bytes)
+ hm.add_string(exchange_key_bytes)
+ hm.add_mpint(K)
+ H = self.hash_algo(hm.asbytes()).digest()
+ self.transport._set_K_H(K, H)
+ sig = self.transport.get_server_key().sign_ssh_data(H)
+ # construct reply
+ m = Message()
+ m.add_byte(c_MSG_KEXECDH_REPLY)
+ m.add_string(server_key_bytes)
+ m.add_string(exchange_key_bytes)
+ m.add_string(sig)
+ self.transport._send_message(m)
+ self.transport._activate_outbound()
+
+ def _parse_kexecdh_reply(self, m):
+ peer_host_key_bytes = m.get_string()
+ peer_key_bytes = m.get_string()
+ sig = m.get_binary()
+
+ peer_key = X25519PublicKey.from_public_bytes(peer_key_bytes)
+
+ K = self._perform_exchange(peer_key)
+ K = long(binascii.hexlify(K), 16)
+ # compute exchange hash and verify signature
+ hm = Message()
+ hm.add(
+ self.transport.local_version,
+ self.transport.remote_version,
+ self.transport.local_kex_init,
+ self.transport.remote_kex_init,
+ )
+ hm.add_string(peer_host_key_bytes)
+ hm.add_string(
+ self.key.public_key().public_bytes(
+ serialization.Encoding.Raw, serialization.PublicFormat.Raw
+ )
+ )
+ hm.add_string(peer_key_bytes)
+ hm.add_mpint(K)
+ self.transport._set_K_H(K, self.hash_algo(hm.asbytes()).digest())
+ self.transport._verify_key(peer_host_key_bytes, sig)
+ self.transport._activate_outbound()
diff --git a/paramiko/kex_group1.py b/paramiko/kex_group1.py
index 904835d7..5131e895 100644
--- a/paramiko/kex_group1.py
+++ b/paramiko/kex_group1.py
@@ -116,7 +116,7 @@ class KexGroup1(object):
hm.add_mpint(self.e)
hm.add_mpint(self.f)
hm.add_mpint(K)
- self.transport._set_K_H(K, sha1(hm.asbytes()).digest())
+ self.transport._set_K_H(K, self.hash_algo(hm.asbytes()).digest())
self.transport._verify_key(host_key, sig)
self.transport._activate_outbound()
diff --git a/paramiko/kex_group14.py b/paramiko/kex_group14.py
index 0df302e3..a620c1a3 100644
--- a/paramiko/kex_group14.py
+++ b/paramiko/kex_group14.py
@@ -22,7 +22,7 @@ Standard SSH key exchange ("kex" if you wanna sound cool). Diffie-Hellman of
"""
from paramiko.kex_group1 import KexGroup1
-from hashlib import sha1
+from hashlib import sha1, sha256
class KexGroup14(KexGroup1):
@@ -33,3 +33,8 @@ class KexGroup14(KexGroup1):
name = "diffie-hellman-group14-sha1"
hash_algo = sha1
+
+
+class KexGroup14SHA256(KexGroup14):
+ name = "diffie-hellman-group14-sha256"
+ hash_algo = sha256
diff --git a/paramiko/kex_group16.py b/paramiko/kex_group16.py
new file mode 100644
index 00000000..15b0acfe
--- /dev/null
+++ b/paramiko/kex_group16.py
@@ -0,0 +1,35 @@
+# Copyright (C) 2019 Edgar Sousa <https://github.com/edgsousa>
+#
+# This file is part of paramiko.
+#
+# Paramiko is free software; you can redistribute it and/or modify it under the
+# terms of the GNU Lesser General Public License as published by the Free
+# Software Foundation; either version 2.1 of the License, or (at your option)
+# any later version.
+#
+# Paramiko is distrubuted in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+# details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with Paramiko; if not, write to the Free Software Foundation, Inc.,
+# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+
+"""
+Standard SSH key exchange ("kex" if you wanna sound cool). Diffie-Hellman of
+4096 bit key halves, using a known "p" prime and "g" generator.
+"""
+
+from paramiko.kex_group1 import KexGroup1
+from hashlib import sha512
+
+
+class KexGroup16SHA512(KexGroup1):
+ name = "diffie-hellman-group16-sha512"
+ # http://tools.ietf.org/html/rfc3526#section-5
+ P = 0xFFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6BF12FFA06D98A0864D87602733EC86A64521F2B18177B200CBBE117577A615D6C770988C0BAD946E208E24FA074E5AB3143DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D788719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA2583E9CA2AD44CE8DBBBC2DB04DE8EF92E8EFC141FBECAA6287C59474E6BC05D99B2964FA090C3A2233BA186515BE7ED1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA993B4EA988D8FDDC186FFB7DC90A6C08F4DF435C934063199FFFFFFFFFFFFFFFF # noqa
+ G = 2
+
+ name = "diffie-hellman-group16-sha512"
+ hash_algo = sha512
diff --git a/paramiko/packet.py b/paramiko/packet.py
index cb46835e..12663168 100644
--- a/paramiko/packet.py
+++ b/paramiko/packet.py
@@ -111,6 +111,8 @@ class Packetizer(object):
self.__compress_engine_in = None
self.__sequence_number_out = 0
self.__sequence_number_in = 0
+ self.__etm_out = False
+ self.__etm_in = False
# lock around outbound writes (packet computation)
self.__write_lock = threading.RLock()
@@ -142,9 +144,11 @@ class Packetizer(object):
mac_size,
mac_key,
sdctr=False,
+ etm=False,
):
"""
Switch outbound data cipher.
+ :param etm: Set encrypt-then-mac from OpenSSH
"""
self.__block_engine_out = block_engine
self.__sdctr_out = sdctr
@@ -154,6 +158,7 @@ class Packetizer(object):
self.__mac_key_out = mac_key
self.__sent_bytes = 0
self.__sent_packets = 0
+ self.__etm_out = etm
# wait until the reset happens in both directions before clearing
# rekey flag
self.__init_count |= 1
@@ -162,10 +167,17 @@ class Packetizer(object):
self.__need_rekey = False
def set_inbound_cipher(
- self, block_engine, block_size, mac_engine, mac_size, mac_key
+ self,
+ block_engine,
+ block_size,
+ mac_engine,
+ mac_size,
+ mac_key,
+ etm=False,
):
"""
Switch inbound data cipher.
+ :param etm: Set encrypt-then-mac from OpenSSH
"""
self.__block_engine_in = block_engine
self.__block_size_in = block_size
@@ -176,6 +188,7 @@ class Packetizer(object):
self.__received_packets = 0
self.__received_bytes_overflow = 0
self.__received_packets_overflow = 0
+ self.__etm_in = etm
# wait until the reset happens in both directions before clearing
# rekey flag
self.__init_count |= 2
@@ -396,14 +409,19 @@ class Packetizer(object):
)
self._log(DEBUG, util.format_binary(packet, "OUT: "))
if self.__block_engine_out is not None:
- out = self.__block_engine_out.update(packet)
+ if self.__etm_out:
+ # packet length is not encrypted in EtM
+ out = packet[0:4] + self.__block_engine_out.update(
+ packet[4:]
+ )
+ else:
+ out = self.__block_engine_out.update(packet)
else:
out = packet
# + mac
if self.__block_engine_out is not None:
- payload = (
- struct.pack(">I", self.__sequence_number_out) + packet
- )
+ packed = struct.pack(">I", self.__sequence_number_out)
+ payload = packed + (out if self.__etm_out else packet)
out += compute_hmac(
self.__mac_key_out, payload, self.__mac_engine_out
)[: self.__mac_size_out]
@@ -439,26 +457,54 @@ class Packetizer(object):
:raises: `.NeedRekeyException` -- if the transport should rekey
"""
header = self.read_all(self.__block_size_in, check_rekey=True)
+ if self.__etm_in:
+ packet_size = struct.unpack(">I", header[:4])[0]
+ remaining = packet_size - self.__block_size_in + 4
+ packet = header[4:] + self.read_all(remaining, check_rekey=False)
+ mac = self.read_all(self.__mac_size_in, check_rekey=False)
+ mac_payload = (
+ struct.pack(">II", self.__sequence_number_in, packet_size)
+ + packet
+ )
+ my_mac = compute_hmac(
+ self.__mac_key_in, mac_payload, self.__mac_engine_in
+ )[: self.__mac_size_in]
+ if not util.constant_time_bytes_eq(my_mac, mac):
+ raise SSHException("Mismatched MAC")
+ header = packet
+
if self.__block_engine_in is not None:
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]
- # leftover contains decrypted bytes from the first block (after the
- # length field)
- leftover = header[4:]
- if (packet_size - len(leftover)) % self.__block_size_in != 0:
- raise SSHException("Invalid packet blocking")
- buf = self.read_all(packet_size + self.__mac_size_in - len(leftover))
- 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.update(packet)
+
+ # When ETM is in play, we've already read the packet size & decrypted
+ # everything, so just set the packet back to the header we obtained.
+ if self.__etm_in:
+ packet = header
+ # Otherwise, use the older non-ETM logic
+ else:
+ packet_size = struct.unpack(">I", header[:4])[0]
+
+ # leftover contains decrypted bytes from the first block (after the
+ # length field)
+ leftover = header[4:]
+ if (packet_size - len(leftover)) % self.__block_size_in != 0:
+ raise SSHException("Invalid packet blocking")
+ buf = self.read_all(
+ packet_size + self.__mac_size_in - len(leftover)
+ )
+ 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.update(packet)
+ packet = leftover + packet
+
if self.__dump_packets:
self._log(DEBUG, util.format_binary(packet, "IN: "))
- packet = leftover + packet
- if self.__mac_size_in > 0:
+ if self.__mac_size_in > 0 and not self.__etm_in:
mac = post_packet[: self.__mac_size_in]
mac_payload = (
struct.pack(">II", self.__sequence_number_in, packet_size)
@@ -579,7 +625,10 @@ class Packetizer(object):
def _build_packet(self, payload):
# pad up at least 4 bytes, to nearest block-size (usually 8)
bsize = self.__block_size_out
- padding = 3 + bsize - ((len(payload) + 8) % bsize)
+ # do not include payload length in computations for padding in EtM mode
+ # (payload length won't be encrypted)
+ addlen = 4 if self.__etm_out else 8
+ padding = 3 + bsize - ((len(payload) + addlen) % bsize)
packet = struct.pack(">IB", len(payload) + padding + 1, padding)
packet += payload
if self.__sdctr_out or self.__block_engine_out is None:
diff --git a/paramiko/transport.py b/paramiko/transport.py
index f72eebaf..25213b4a 100644
--- a/paramiko/transport.py
+++ b/paramiko/transport.py
@@ -88,9 +88,11 @@ from paramiko.common import (
from paramiko.compress import ZlibCompressor, ZlibDecompressor
from paramiko.dsskey import DSSKey
from paramiko.ed25519key import Ed25519Key
+from paramiko.kex_curve25519 import KexCurve25519
from paramiko.kex_gex import KexGex, KexGexSHA256
from paramiko.kex_group1 import KexGroup1
-from paramiko.kex_group14 import KexGroup14
+from paramiko.kex_group14 import KexGroup14, KexGroup14SHA256
+from paramiko.kex_group16 import KexGroup16SHA512
from paramiko.kex_ecdh_nist import KexNistp256, KexNistp384, KexNistp521
from paramiko.kex_gss import KexGSSGex, KexGSSGroup1, KexGSSGroup14
from paramiko.message import Message
@@ -156,6 +158,8 @@ class Transport(threading.Thread, ClosingContextManager):
_preferred_macs = (
"hmac-sha2-256",
"hmac-sha2-512",
+ "hmac-sha2-256-etm@openssh.com",
+ "hmac-sha2-512-etm@openssh.com",
"hmac-sha1",
"hmac-md5",
"hmac-sha1-96",
@@ -173,11 +177,15 @@ class Transport(threading.Thread, ClosingContextManager):
"ecdh-sha2-nistp256",
"ecdh-sha2-nistp384",
"ecdh-sha2-nistp521",
+ "diffie-hellman-group16-sha512",
"diffie-hellman-group-exchange-sha256",
+ "diffie-hellman-group14-sha256",
"diffie-hellman-group-exchange-sha1",
"diffie-hellman-group14-sha1",
"diffie-hellman-group1-sha1",
)
+ if KexCurve25519.is_available():
+ _preferred_kex = ("curve25519-sha256@libssh.org",) + _preferred_kex
_preferred_gsskex = (
"gss-gex-sha1-toWM5Slw5Ew8Mqkay+al2g==",
"gss-group14-sha1-toWM5Slw5Ew8Mqkay+al2g==",
@@ -240,7 +248,9 @@ class Transport(threading.Thread, ClosingContextManager):
"hmac-sha1": {"class": sha1, "size": 20},
"hmac-sha1-96": {"class": sha1, "size": 12},
"hmac-sha2-256": {"class": sha256, "size": 32},
+ "hmac-sha2-256-etm@openssh.com": {"class": sha256, "size": 32},
"hmac-sha2-512": {"class": sha512, "size": 64},
+ "hmac-sha2-512-etm@openssh.com": {"class": sha512, "size": 64},
"hmac-md5": {"class": md5, "size": 16},
"hmac-md5-96": {"class": md5, "size": 12},
}
@@ -265,6 +275,8 @@ class Transport(threading.Thread, ClosingContextManager):
"diffie-hellman-group14-sha1": KexGroup14,
"diffie-hellman-group-exchange-sha1": KexGex,
"diffie-hellman-group-exchange-sha256": KexGexSHA256,
+ "diffie-hellman-group14-sha256": KexGroup14SHA256,
+ "diffie-hellman-group16-sha512": KexGroup16SHA512,
"gss-group1-sha1-toWM5Slw5Ew8Mqkay+al2g==": KexGSSGroup1,
"gss-group14-sha1-toWM5Slw5Ew8Mqkay+al2g==": KexGSSGroup14,
"gss-gex-sha1-toWM5Slw5Ew8Mqkay+al2g==": KexGSSGex,
@@ -272,6 +284,8 @@ class Transport(threading.Thread, ClosingContextManager):
"ecdh-sha2-nistp384": KexNistp384,
"ecdh-sha2-nistp521": KexNistp521,
}
+ if KexCurve25519.is_available():
+ _kex_info["curve25519-sha256@libssh.org"] = KexCurve25519
_compression_info = {
# zlib@openssh.com is just zlib, but only turned on after a successful
@@ -2440,6 +2454,7 @@ class Transport(threading.Thread, ClosingContextManager):
engine = self._get_cipher(
self.remote_cipher, key_in, IV_in, self._DECRYPT
)
+ etm = "etm@openssh.com" in self.remote_mac
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
@@ -2449,7 +2464,7 @@ class Transport(threading.Thread, ClosingContextManager):
else:
mac_key = self._compute_key("F", mac_engine().digest_size)
self.packetizer.set_inbound_cipher(
- engine, block_size, mac_engine, mac_size, mac_key
+ engine, block_size, mac_engine, mac_size, mac_key, etm=etm
)
compress_in = self._compression_info[self.remote_compression][1]
if compress_in is not None and (
@@ -2478,6 +2493,7 @@ class Transport(threading.Thread, ClosingContextManager):
engine = self._get_cipher(
self.local_cipher, key_out, IV_out, self._ENCRYPT
)
+ etm = "etm@openssh.com" in self.local_mac
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
@@ -2488,7 +2504,7 @@ class Transport(threading.Thread, ClosingContextManager):
mac_key = self._compute_key("E", mac_engine().digest_size)
sdctr = self.local_cipher.endswith("-ctr")
self.packetizer.set_outbound_cipher(
- engine, block_size, mac_engine, mac_size, mac_key, sdctr
+ engine, block_size, mac_engine, mac_size, mac_key, sdctr, etm=etm
)
compress_out = self._compression_info[self.local_compression][0]
if compress_out is not None and (
diff --git a/setup.cfg b/setup.cfg
index 7ff383c3..44d029c4 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -8,7 +8,7 @@ license_file = LICENSE
omit = paramiko/_winapi.py
[flake8]
-exclude = sites,.git,build,dist,demos,tests
+exclude = sites,.git,build,dist,demos
# NOTE: W503, E203 are concessions to black 18.0b5 and could be reinstated
# later if fixed on that end.
# NOTE: E722 seems to only have started popping up on move to flake8 3.6.0 from
@@ -22,3 +22,7 @@ max-line-length = 79
addopts = -p no:relaxed
# Loop on failure
looponfailroots = tests paramiko
+# Ignore some warnings we cannot easily handle.
+filterwarnings =
+ ignore::DeprecationWarning:pkg_resources
+ ignore::cryptography.utils.CryptographyDeprecationWarning
diff --git a/sites/www/changelog.rst b/sites/www/changelog.rst
index 85542db3..67242b22 100644
--- a/sites/www/changelog.rst
+++ b/sites/www/changelog.rst
@@ -16,6 +16,28 @@ Changelog
but for now, either library will work. Please upgrade to ``gssapi`` when
you can, however, as ``python-gssapi`` is no longer maintained upstream.
+- :bug:`322 major` `SSHClient.exec_command
+ <paramiko.client.SSHClient.exec_command>` previously returned a naive
+ `~paramiko.channel.ChannelFile` object for its ``stdin`` value; such objects
+ don't know to properly shut down the remote end's stdin when they
+ ``.close()``. This lead to issues (such as hangs) when running remote
+ commands that read from stdin.
+
+ A new subclass, `~paramiko.channel.ChannelStdinFile`, has been created which
+ closes remote stdin when it itself is closed.
+ `~paramiko.client.SSHClient.exec_command` has been updated to use that class
+ for its ``stdin`` return value.
+
+ Thanks to Brandon Rhodes for the report & steps to reproduce.
+- :release:`2.5.0 <2019-06-09>`
+- :feature:`1233` (also :issue:`1229`, :issue:`1332`) Add support for
+ encrypt-then-MAC (ETM) schemes (``hmac-sha2-256-etm@openssh.com``,
+ ``hmac-sha2-512-etm@openssh.com``) and two newer Diffie-Hellman group key
+ exchange algorithms (``group14``, using SHA256; and ``group16``, using
+ SHA512). Patch courtesy of Edgar Sousa.
+- :feature:`532` (via :issue:`1384` and :issue:`1258`) Add support for
+ Curve25519 key exchange (aka ``curve25519-sha256@libssh.org``). Thanks to
+ Alex Gaynor and Dan Fuhry for supplying patches.
- :support:`1379` (also :issue:`1369`) Raise Cryptography dependency
requirement to version 2.5 (from 1.5) and update some deprecated uses of its
API.
@@ -60,8 +82,9 @@ Changelog
for this particular channel).
Thanks to Daniel Hoffman for the detailed report.
-- :support:`1292 backported` Backport changes from :issue:`979` (added in
- Paramiko 2.3) to Paramiko 2.0-2.2, using duck-typing to preserve backwards
+- :support:`1292 backported (<2.4)` Backport changes from :issue:`979` (added
+ in Paramiko
+ 2.3) to Paramiko 2.0-2.2, using duck-typing to preserve backwards
compatibility. This allows these older versions to use newer Cryptography
sign/verify APIs when available, without requiring them (as is the case with
Paramiko 2.3+).
@@ -74,9 +97,9 @@ Changelog
This is a no-op for Paramiko 2.3+, which have required newer Cryptography
releases since they were released.
-- :support:`1291 backported` Backport pytest support and application of the
- ``black`` code formatter (both of which previously only existed in the 2.4
- branch and above) to everything 2.0 and newer. This makes back/forward
+- :support:`1291 backported (<2.4)` Backport pytest support and application of
+ the ``black`` code formatter (both of which previously only existed in the
+ 2.4 branch and above) to everything 2.0 and newer. This makes back/forward
porting bugfixes significantly easier.
- :support:`1262 backported` Add ``*.pub`` files to the MANIFEST so distributed
source packages contain some necessary test assets. Credit: Alexander
diff --git a/tests/stub_sftp.py b/tests/stub_sftp.py
index 100076d6..1528a0b8 100644
--- a/tests/stub_sftp.py
+++ b/tests/stub_sftp.py
@@ -21,18 +21,17 @@ A stub SFTP server for loopback SFTP testing.
"""
import os
-import sys
from paramiko import (
- ServerInterface,
- SFTPServerInterface,
- SFTPServer,
+ AUTH_SUCCESSFUL,
+ OPEN_SUCCEEDED,
SFTPAttributes,
SFTPHandle,
- SFTP_OK,
+ SFTPServer,
+ SFTPServerInterface,
SFTP_FAILURE,
- AUTH_SUCCESSFUL,
- OPEN_SUCCEEDED,
+ SFTP_OK,
+ ServerInterface,
)
from paramiko.common import o666
@@ -65,7 +64,8 @@ class StubSFTPHandle(SFTPHandle):
class StubSFTPServer(SFTPServerInterface):
# assume current folder is a fine root
- # (the tests always create and eventually delete a subfolder, so there shouldn't be any mess)
+ # (the tests always create and eventually delete a subfolder, so there
+ # shouldn't be any mess)
ROOT = os.getcwd()
def _realpath(self, path):
@@ -206,7 +206,8 @@ class StubSFTPServer(SFTPServerInterface):
# compute relative to path
abspath = os.path.join(os.path.dirname(path), target_path)
if abspath[: len(self.ROOT)] != self.ROOT:
- # this symlink isn't going to work anyway -- just break it immediately
+ # this symlink isn't going to work anyway -- just break it
+ # immediately
target_path = "<error>"
try:
os.symlink(target_path, path)
diff --git a/tests/test_auth.py b/tests/test_auth.py
index d98a00c4..01fbac5b 100644
--- a/tests/test_auth.py
+++ b/tests/test_auth.py
@@ -250,7 +250,7 @@ class AuthTest(unittest.TestCase):
self.start_server()
self.tc.connect(hostkey=self.public_host_key)
try:
- remain = self.tc.auth_password("bad-server", "hello")
+ self.tc.auth_password("bad-server", "hello")
except:
etype, evalue, etb = sys.exc_info()
self.assertTrue(issubclass(etype, AuthenticationException))
@@ -265,7 +265,7 @@ class AuthTest(unittest.TestCase):
self.start_server()
self.tc.connect()
try:
- remain = self.tc.auth_password("unresponsive-server", "hello")
+ self.tc.auth_password("unresponsive-server", "hello")
except:
etype, evalue, etb = sys.exc_info()
self.assertTrue(issubclass(etype, AuthenticationException))
diff --git a/tests/test_buffered_pipe.py b/tests/test_buffered_pipe.py
index 28d6e4a2..61c99cc0 100644
--- a/tests/test_buffered_pipe.py
+++ b/tests/test_buffered_pipe.py
@@ -26,7 +26,6 @@ import unittest
from paramiko.buffered_pipe import BufferedPipe, PipeTimeout
from paramiko import pipe
-from paramiko.py3compat import b
def delay_thread(p):
@@ -42,7 +41,7 @@ def close_thread(p):
class BufferedPipeTest(unittest.TestCase):
- def test_1_buffered_pipe(self):
+ def test_buffered_pipe(self):
p = BufferedPipe()
self.assertTrue(not p.read_ready())
p.feed("hello.")
@@ -59,7 +58,7 @@ class BufferedPipeTest(unittest.TestCase):
self.assertTrue(not p.read_ready())
self.assertEqual(b"", p.read(1))
- def test_2_delay(self):
+ def test_delay(self):
p = BufferedPipe()
self.assertTrue(not p.read_ready())
threading.Thread(target=delay_thread, args=(p,)).start()
@@ -72,13 +71,13 @@ class BufferedPipeTest(unittest.TestCase):
self.assertEqual(b"b", p.read(1, 1.0))
self.assertEqual(b"", p.read(1))
- def test_3_close_while_reading(self):
+ def test_close_while_reading(self):
p = BufferedPipe()
threading.Thread(target=close_thread, args=(p,)).start()
data = p.read(1, 1.0)
self.assertEqual(b"", data)
- def test_4_or_pipe(self):
+ def test_or_pipe(self):
p = pipe.make_pipe()
p1, p2 = pipe.make_or_pipe(p)
self.assertFalse(p._set)
diff --git a/tests/test_channelfile.py b/tests/test_channelfile.py
new file mode 100644
index 00000000..4448fdfb
--- /dev/null
+++ b/tests/test_channelfile.py
@@ -0,0 +1,60 @@
+from mock import patch, MagicMock
+
+from paramiko import Channel, ChannelFile, ChannelStderrFile, ChannelStdinFile
+
+
+class ChannelFileBase(object):
+ @patch("paramiko.channel.ChannelFile._set_mode")
+ def test_defaults_to_unbuffered_reading(self, setmode):
+ self.klass(Channel(None))
+ setmode.assert_called_once_with("r", -1)
+
+ @patch("paramiko.channel.ChannelFile._set_mode")
+ def test_can_override_mode_and_bufsize(self, setmode):
+ self.klass(Channel(None), mode="w", bufsize=25)
+ setmode.assert_called_once_with("w", 25)
+
+ def test_read_recvs_from_channel(self):
+ chan = MagicMock()
+ cf = self.klass(chan)
+ cf.read(100)
+ chan.recv.assert_called_once_with(100)
+
+ def test_write_calls_channel_sendall(self):
+ chan = MagicMock()
+ cf = self.klass(chan, mode="w")
+ cf.write("ohai")
+ chan.sendall.assert_called_once_with(b"ohai")
+
+
+class TestChannelFile(ChannelFileBase):
+ klass = ChannelFile
+
+
+class TestChannelStderrFile(object):
+ def test_read_calls_channel_recv_stderr(self):
+ chan = MagicMock()
+ cf = ChannelStderrFile(chan)
+ cf.read(100)
+ chan.recv_stderr.assert_called_once_with(100)
+
+ def test_write_calls_channel_sendall(self):
+ chan = MagicMock()
+ cf = ChannelStderrFile(chan, mode="w")
+ cf.write("ohai")
+ chan.sendall_stderr.assert_called_once_with(b"ohai")
+
+
+class TestChannelStdinFile(ChannelFileBase):
+ klass = ChannelStdinFile
+
+ def test_close_calls_channel_shutdown_write(self):
+ chan = MagicMock()
+ cf = ChannelStdinFile(chan, mode="wb")
+ cf.flush = MagicMock()
+ cf.close()
+ # Sanity check that we still call BufferedFile.close()
+ cf.flush.assert_called_once_with()
+ assert cf._closed is True
+ # Actual point of test
+ chan.shutdown_write.assert_called_once_with()
diff --git a/tests/test_client.py b/tests/test_client.py
index 80b28adf..c46c383b 100644
--- a/tests/test_client.py
+++ b/tests/test_client.py
@@ -37,7 +37,6 @@ from pytest_relaxed import raises
import paramiko
from paramiko.pkey import PublicBlob
-from paramiko.common import PY2
from paramiko.ssh_exception import SSHException, AuthenticationException
from .util import _support, slow
@@ -48,9 +47,9 @@ requires_gss_auth = unittest.skipUnless(
)
FINGERPRINTS = {
- "ssh-dss": b"\x44\x78\xf0\xb9\xa2\x3c\xc5\x18\x20\x09\xff\x75\x5b\xc1\xd2\x6c",
- "ssh-rsa": b"\x60\x73\x38\x44\xcb\x51\x86\x65\x7f\xde\xda\xa2\x2b\x5a\x57\xd5",
- "ecdsa-sha2-nistp256": b"\x25\x19\xeb\x55\xe6\xa1\x47\xff\x4f\x38\xd2\x75\x6f\xa5\xd5\x60",
+ "ssh-dss": b"\x44\x78\xf0\xb9\xa2\x3c\xc5\x18\x20\x09\xff\x75\x5b\xc1\xd2\x6c", # noqa
+ "ssh-rsa": b"\x60\x73\x38\x44\xcb\x51\x86\x65\x7f\xde\xda\xa2\x2b\x5a\x57\xd5", # noqa
+ "ecdsa-sha2-nistp256": b"\x25\x19\xeb\x55\xe6\xa1\x47\xff\x4f\x38\xd2\x75\x6f\xa5\xd5\x60", # noqa
"ssh-ed25519": b'\xb3\xd5"\xaa\xf9u^\xe8\xcd\x0e\xea\x02\xb9)\xa2\x80',
}
@@ -212,6 +211,12 @@ class ClientTest(unittest.TestCase):
stdin, stdout, stderr = self.tc.exec_command("yes")
schan = self.ts.accept(1.0)
+ # Nobody else tests the API of exec_command so let's do it here for
+ # now. :weary:
+ assert isinstance(stdin, paramiko.ChannelStdinFile)
+ assert isinstance(stdout, paramiko.ChannelFile)
+ assert isinstance(stderr, paramiko.ChannelStderrFile)
+
schan.send("Hello there.\n")
schan.send_stderr("This is on stderr.\n")
schan.close()
@@ -228,13 +233,13 @@ class ClientTest(unittest.TestCase):
class SSHClientTest(ClientTest):
- def test_1_client(self):
+ def test_client(self):
"""
verify that the SSHClient stuff works too.
"""
self._test_connection(password="pygmalion")
- def test_2_client_dsa(self):
+ def test_client_dsa(self):
"""
verify that SSHClient works with a DSA key.
"""
@@ -246,7 +251,7 @@ class SSHClientTest(ClientTest):
"""
self._test_connection(key_filename=_support("test_rsa.key"))
- def test_2_5_client_ecdsa(self):
+ def test_client_ecdsa(self):
"""
verify that SSHClient works with an ECDSA key.
"""
@@ -255,7 +260,7 @@ class SSHClientTest(ClientTest):
def test_client_ed25519(self):
self._test_connection(key_filename=_support("test_ed25519.key"))
- def test_3_multiple_key_files(self):
+ def test_multiple_key_files(self):
"""
verify that SSHClient accepts and tries multiple key files.
"""
@@ -335,7 +340,7 @@ class SSHClientTest(ClientTest):
# code path (!) so we're punting too, sob.
pass
- def test_4_auto_add_policy(self):
+ def test_auto_add_policy(self):
"""
verify that SSHClient's AutoAddPolicy works.
"""
@@ -358,7 +363,7 @@ class SSHClientTest(ClientTest):
new_host_key = list(self.tc.get_host_keys()[hostname].values())[0]
self.assertEqual(public_host_key, new_host_key)
- def test_5_save_host_keys(self):
+ def test_save_host_keys(self):
"""
verify that SSHClient correctly saves a known_hosts file.
"""
@@ -372,15 +377,13 @@ class SSHClientTest(ClientTest):
os.close(fd)
client = paramiko.SSHClient()
- self.assertEquals(0, len(client.get_host_keys()))
+ assert len(client.get_host_keys()) == 0
host_id = "[%s]:%d" % (self.addr, self.port)
client.get_host_keys().add(host_id, "ssh-rsa", public_host_key)
- self.assertEquals(1, len(client.get_host_keys()))
- self.assertEquals(
- public_host_key, client.get_host_keys()[host_id]["ssh-rsa"]
- )
+ assert len(client.get_host_keys()) == 1
+ assert public_host_key == client.get_host_keys()[host_id]["ssh-rsa"]
client.save_host_keys(localname)
@@ -389,7 +392,7 @@ class SSHClientTest(ClientTest):
os.unlink(localname)
- def test_6_cleanup(self):
+ def test_cleanup(self):
"""
verify that when an SSHClient is collected, its transport (and the
transport's packetizer) is closed.
@@ -431,7 +434,7 @@ class SSHClientTest(ClientTest):
with paramiko.SSHClient() as tc:
self.tc = tc
self.tc.set_missing_host_key_policy(paramiko.AutoAddPolicy())
- self.assertEquals(0, len(self.tc.get_host_keys()))
+ assert len(self.tc.get_host_keys()) == 0
self.tc.connect(**dict(self.connect_kwargs, password="pygmalion"))
self.event.wait(1.0)
@@ -442,7 +445,7 @@ class SSHClientTest(ClientTest):
self.assertTrue(self.tc._transport is None)
- def test_7_banner_timeout(self):
+ def test_banner_timeout(self):
"""
verify that the SSHClient has a configurable banner timeout.
"""
@@ -461,7 +464,7 @@ class SSHClientTest(ClientTest):
kwargs = dict(self.connect_kwargs, banner_timeout=0.5)
self.assertRaises(paramiko.SSHException, self.tc.connect, **kwargs)
- def test_8_auth_trickledown(self):
+ def test_auth_trickledown(self):
"""
Failed key auth doesn't prevent subsequent pw auth from succeeding
"""
@@ -482,7 +485,7 @@ class SSHClientTest(ClientTest):
self._test_connection(**kwargs)
@slow
- def test_9_auth_timeout(self):
+ def test_auth_timeout(self):
"""
verify that the SSHClient has a configurable auth timeout
"""
@@ -495,22 +498,22 @@ class SSHClientTest(ClientTest):
)
@requires_gss_auth
- def test_10_auth_trickledown_gsskex(self):
+ def test_auth_trickledown_gsskex(self):
"""
- Failed gssapi-keyex auth doesn't prevent subsequent key auth from succeeding
+ Failed gssapi-keyex doesn't prevent subsequent key from succeeding
"""
kwargs = dict(gss_kex=True, key_filename=[_support("test_rsa.key")])
self._test_connection(**kwargs)
@requires_gss_auth
- def test_11_auth_trickledown_gssauth(self):
+ def test_auth_trickledown_gssauth(self):
"""
- Failed gssapi-with-mic auth doesn't prevent subsequent key auth from succeeding
+ Failed gssapi-with-mic doesn't prevent subsequent key from succeeding
"""
kwargs = dict(gss_auth=True, key_filename=[_support("test_rsa.key")])
self._test_connection(**kwargs)
- def test_12_reject_policy(self):
+ def test_reject_policy(self):
"""
verify that SSHClient's RejectPolicy works.
"""
@@ -527,12 +530,13 @@ class SSHClientTest(ClientTest):
)
@requires_gss_auth
- def test_13_reject_policy_gsskex(self):
+ def test_reject_policy_gsskex(self):
"""
verify that SSHClient's RejectPolicy works,
even if gssapi-keyex was enabled but not used.
"""
- # Test for a bug present in paramiko versions released before 2017-08-01
+ # Test for a bug present in paramiko versions released before
+ # 2017-08-01
threading.Thread(target=self._run).start()
self.tc = paramiko.SSHClient()
@@ -684,9 +688,9 @@ class PasswordPassphraseTests(ClientTest):
)
@raises(AuthenticationException) # TODO: more granular
- def test_password_kwarg_not_used_for_passphrase_when_passphrase_kwarg_given(
+ def test_password_kwarg_not_used_for_passphrase_when_passphrase_kwarg_given( # noqa
self
- ): # noqa
+ ):
# Sanity: if we're given both fields, the password field is NOT used as
# a passphrase.
self._test_connection(
diff --git a/tests/test_file.py b/tests/test_file.py
index fba14b1b..2a3da74b 100644
--- a/tests/test_file.py
+++ b/tests/test_file.py
@@ -52,7 +52,7 @@ class LoopbackFile(BufferedFile):
class BufferedFileTest(unittest.TestCase):
- def test_1_simple(self):
+ def test_simple(self):
f = LoopbackFile("r")
try:
f.write(b"hi")
@@ -69,7 +69,7 @@ class BufferedFileTest(unittest.TestCase):
pass
f.close()
- def test_2_readline(self):
+ def test_readline(self):
f = LoopbackFile("r+U")
f.write(
b"First line.\nSecond line.\r\nThird line.\n"
@@ -96,7 +96,7 @@ class BufferedFileTest(unittest.TestCase):
self.assertTrue(crlf in f.newlines)
self.assertTrue(cr_byte not in f.newlines)
- def test_3_lf(self):
+ def test_lf(self):
"""
try to trick the linefeed detector.
"""
@@ -108,7 +108,7 @@ class BufferedFileTest(unittest.TestCase):
f.close()
self.assertEqual(f.newlines, crlf)
- def test_4_write(self):
+ def test_write(self):
"""
verify that write buffering is on.
"""
@@ -120,7 +120,7 @@ class BufferedFileTest(unittest.TestCase):
self.assertEqual(f.readline(), "Incomplete line...\n")
f.close()
- def test_5_flush(self):
+ def test_flush(self):
"""
verify that flush will force a write.
"""
@@ -134,7 +134,7 @@ class BufferedFileTest(unittest.TestCase):
self.assertEqual(f.read(3), b"")
f.close()
- def test_6_buffering(self):
+ def test_buffering_flushes(self):
"""
verify that flushing happens automatically on buffer crossing.
"""
@@ -147,7 +147,7 @@ class BufferedFileTest(unittest.TestCase):
self.assertEqual(f.read(20), b"Too small. Enough.")
f.close()
- def test_7_read_all(self):
+ def test_read_all(self):
"""
verify that read(-1) returns everything left in the file.
"""
@@ -162,30 +162,30 @@ class BufferedFileTest(unittest.TestCase):
)
f.close()
- def test_8_buffering(self):
+ def test_buffering_writes(self):
"""
verify that buffered objects can be written
"""
if sys.version_info[0] == 2:
f = LoopbackFile("r+", 16)
- f.write(buffer(b"Too small."))
+ f.write(buffer(b"Too small.")) # noqa
f.close()
- def test_9_readable(self):
+ def test_readable(self):
f = LoopbackFile("r")
self.assertTrue(f.readable())
self.assertFalse(f.writable())
self.assertFalse(f.seekable())
f.close()
- def test_A_writable(self):
+ def test_writable(self):
f = LoopbackFile("w")
self.assertTrue(f.writable())
self.assertFalse(f.readable())
self.assertFalse(f.seekable())
f.close()
- def test_B_readinto(self):
+ def test_readinto(self):
data = bytearray(5)
f = LoopbackFile("r+")
f._write(b"hello")
@@ -215,7 +215,7 @@ class BufferedFileTest(unittest.TestCase):
offsets = range(0, len(data), 8)
with LoopbackFile("rb+") as f:
for offset in offsets:
- f.write(buffer(data, offset, 8))
+ f.write(buffer(data, offset, 8)) # noqa
self.assertEqual(f.read(), data)
@needs_builtin("memoryview")
diff --git a/tests/test_gssapi.py b/tests/test_gssapi.py
index 8e6ec37a..30ffb56d 100644
--- a/tests/test_gssapi.py
+++ b/tests/test_gssapi.py
@@ -31,12 +31,14 @@ from .util import needs_gssapi, KerberosTestCase, update_env
class GSSAPITest(KerberosTestCase):
def setUp(self):
super(GSSAPITest, self).setUp()
+ # TODO: these vars should all come from os.environ or whatever the
+ # approved pytest method is for runtime-configuring test data.
self.krb5_mech = "1.2.840.113554.1.2.2"
self.targ_name = self.realm.hostname
self.server_mode = False
update_env(self, self.realm.env)
- def test_1_pyasn1(self):
+ def test_pyasn1(self):
"""
Test the used methods of pyasn1.
"""
diff --git a/tests/test_hostkeys.py b/tests/test_hostkeys.py
index 295153dd..da47362c 100644
--- a/tests/test_hostkeys.py
+++ b/tests/test_hostkeys.py
@@ -62,7 +62,7 @@ class HostKeysTest(unittest.TestCase):
def tearDown(self):
os.unlink("hostfile.temp")
- def test_1_load(self):
+ def test_load(self):
hostdict = paramiko.HostKeys("hostfile.temp")
self.assertEqual(2, len(hostdict))
self.assertEqual(1, len(list(hostdict.values())[0]))
@@ -72,7 +72,7 @@ class HostKeysTest(unittest.TestCase):
).upper()
self.assertEqual(b"E6684DB30E109B67B70FF1DC5C7F1363", fp)
- def test_2_add(self):
+ def test_add(self):
hostdict = paramiko.HostKeys("hostfile.temp")
hh = "|1|BMsIC6cUIP2zBuXR3t2LRcJYjzM=|hpkJMysjTk/+zzUUzxQEa2ieq6c="
key = paramiko.RSAKey(data=decodebytes(keyblob))
@@ -83,7 +83,7 @@ class HostKeysTest(unittest.TestCase):
self.assertEqual(b"7EC91BB336CB6D810B124B1353C32396", fp)
self.assertTrue(hostdict.check("foo.example.com", key))
- def test_3_dict(self):
+ def test_dict(self):
hostdict = paramiko.HostKeys("hostfile.temp")
self.assertTrue("secure.example.com" in hostdict)
self.assertTrue("not.example.com" not in hostdict)
@@ -98,7 +98,7 @@ class HostKeysTest(unittest.TestCase):
i += 1
self.assertEqual(2, i)
- def test_4_dict_set(self):
+ def test_dict_set(self):
hostdict = paramiko.HostKeys("hostfile.temp")
key = paramiko.RSAKey(data=decodebytes(keyblob))
key_dss = paramiko.DSSKey(data=decodebytes(keyblob_dss))
@@ -122,10 +122,10 @@ class HostKeysTest(unittest.TestCase):
def test_delitem(self):
hostdict = paramiko.HostKeys("hostfile.temp")
target = "happy.example.com"
- entry = hostdict[target] # will KeyError if not present
+ hostdict[target] # will KeyError if not present
del hostdict[target]
try:
- entry = hostdict[target]
+ hostdict[target]
except KeyError:
pass # Good
else:
diff --git a/tests/test_kex.py b/tests/test_kex.py
index d42355a1..0244ae84 100644
--- a/tests/test_kex.py
+++ b/tests/test_kex.py
@@ -24,15 +24,26 @@ from binascii import hexlify, unhexlify
import os
import unittest
+from mock import Mock, patch
+import pytest
+
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives.asymmetric import ec
+try:
+ from cryptography.hazmat.primitives.asymmetric import x25519
+except ImportError:
+ x25519 = None
+
import paramiko.util
from paramiko.kex_group1 import KexGroup1
+from paramiko.kex_group14 import KexGroup14SHA256
from paramiko.kex_gex import KexGex, KexGexSHA256
from paramiko import Message
from paramiko.common import byte_chr
from paramiko.kex_ecdh_nist import KexNistp256
+from paramiko.kex_group16 import KexGroup16SHA512
+from paramiko.kex_curve25519 import KexCurve25519
def dummy_urandom(n):
@@ -40,8 +51,8 @@ def dummy_urandom(n):
def dummy_generate_key_pair(obj):
- private_key_value = 94761803665136558137557783047955027733968423115106677159790289642479432803037
- public_key_numbers = "042bdab212fa8ba1b7c843301682a4db424d307246c7e1e6083c41d9ca7b098bf30b3d63e2ec6278488c135360456cc054b3444ecc45998c08894cbc1370f5f989"
+ private_key_value = 94761803665136558137557783047955027733968423115106677159790289642479432803037 # noqa
+ public_key_numbers = "042bdab212fa8ba1b7c843301682a4db424d307246c7e1e6083c41d9ca7b098bf30b3d63e2ec6278488c135360456cc054b3444ecc45998c08894cbc1370f5f989" # noqa
public_key_numbers_obj = ec.EllipticCurvePublicKey.from_encoded_point(
ec.SECP256R1(), unhexlify(public_key_numbers)
).public_numbers()
@@ -70,7 +81,7 @@ class FakeKey(object):
class FakeModulusPack(object):
- P = 0xFFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381FFFFFFFFFFFFFFFF
+ P = 0xFFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381FFFFFFFFFFFFFFFF # noqa
G = 2
def get_modulus(self, min, ask, max):
@@ -111,7 +122,7 @@ class FakeTransport(object):
class KexTest(unittest.TestCase):
- K = 14730343317708716439807310032871972459448364195094179797249681733965528989482751523943515690110179031004049109375612685505881911274101441415545039654102474376472240501616988799699744135291070488314748284283496055223852115360852283821334858541043710301057312858051901453919067023103730011648890038847384890504
+ K = 14730343317708716439807310032871972459448364195094179797249681733965528989482751523943515690110179031004049109375612685505881911274101441415545039654102474376472240501616988799699744135291070488314748284283496055223852115360852283821334858541043710301057312858051901453919067023103730011648890038847384890504 # noqa
def setUp(self):
self._original_urandom = os.urandom
@@ -119,16 +130,32 @@ class KexTest(unittest.TestCase):
self._original_generate_key_pair = KexNistp256._generate_key_pair
KexNistp256._generate_key_pair = dummy_generate_key_pair
+ if KexCurve25519.is_available():
+ static_x25519_key = x25519.X25519PrivateKey.from_private_bytes(
+ unhexlify(
+ b"2184abc7eb3e656d2349d2470ee695b570c227340c2b2863b6c9ff427af1f040" # noqa
+ )
+ )
+ mock_x25519 = Mock()
+ mock_x25519.generate.return_value = static_x25519_key
+ patcher = patch(
+ "paramiko.kex_curve25519.X25519PrivateKey", mock_x25519
+ )
+ patcher.start()
+ self.x25519_patcher = patcher
+
def tearDown(self):
os.urandom = self._original_urandom
KexNistp256._generate_key_pair = self._original_generate_key_pair
+ if hasattr(self, "x25519_patcher"):
+ self.x25519_patcher.stop()
- def test_1_group1_client(self):
+ def test_group1_client(self):
transport = FakeTransport()
transport.server_mode = False
kex = KexGroup1(transport)
kex.start_kex()
- x = b"1E000000807E2DDB1743F3487D6545F04F1C8476092FB912B013626AB5BCEB764257D88BBA64243B9F348DF7B41B8C814A995E00299913503456983FFB9178D3CD79EB6D55522418A8ABF65375872E55938AB99A84A0B5FC8A1ECC66A7C3766E7E0F80B7CE2C9225FC2DD683F4764244B72963BBB383F529DCF0C5D17740B8A2ADBE9208D4"
+ x = b"1E000000807E2DDB1743F3487D6545F04F1C8476092FB912B013626AB5BCEB764257D88BBA64243B9F348DF7B41B8C814A995E00299913503456983FFB9178D3CD79EB6D55522418A8ABF65375872E55938AB99A84A0B5FC8A1ECC66A7C3766E7E0F80B7CE2C9225FC2DD683F4764244B72963BBB383F529DCF0C5D17740B8A2ADBE9208D4" # noqa
self.assertEqual(x, hexlify(transport._message.asbytes()).upper())
self.assertEqual(
(paramiko.kex_group1._MSG_KEXDH_REPLY,), transport._expect
@@ -147,7 +174,7 @@ class KexTest(unittest.TestCase):
self.assertEqual((b"fake-host-key", b"fake-sig"), transport._verify)
self.assertTrue(transport._activated)
- def test_2_group1_server(self):
+ def test_group1_server(self):
transport = FakeTransport()
transport.server_mode = True
kex = KexGroup1(transport)
@@ -161,13 +188,13 @@ class KexTest(unittest.TestCase):
msg.rewind()
kex.parse_next(paramiko.kex_group1._MSG_KEXDH_INIT, msg)
H = b"B16BF34DD10945EDE84E9C1EF24A14BFDC843389"
- x = b"1F0000000866616B652D6B6579000000807E2DDB1743F3487D6545F04F1C8476092FB912B013626AB5BCEB764257D88BBA64243B9F348DF7B41B8C814A995E00299913503456983FFB9178D3CD79EB6D55522418A8ABF65375872E55938AB99A84A0B5FC8A1ECC66A7C3766E7E0F80B7CE2C9225FC2DD683F4764244B72963BBB383F529DCF0C5D17740B8A2ADBE9208D40000000866616B652D736967"
+ x = b"1F0000000866616B652D6B6579000000807E2DDB1743F3487D6545F04F1C8476092FB912B013626AB5BCEB764257D88BBA64243B9F348DF7B41B8C814A995E00299913503456983FFB9178D3CD79EB6D55522418A8ABF65375872E55938AB99A84A0B5FC8A1ECC66A7C3766E7E0F80B7CE2C9225FC2DD683F4764244B72963BBB383F529DCF0C5D17740B8A2ADBE9208D40000000866616B652D736967" # noqa
self.assertEqual(self.K, transport._K)
self.assertEqual(H, hexlify(transport._H).upper())
self.assertEqual(x, hexlify(transport._message.asbytes()).upper())
self.assertTrue(transport._activated)
- def test_3_gex_client(self):
+ def test_gex_client(self):
transport = FakeTransport()
transport.server_mode = False
kex = KexGex(transport)
@@ -183,7 +210,7 @@ class KexTest(unittest.TestCase):
msg.add_mpint(FakeModulusPack.G)
msg.rewind()
kex.parse_next(paramiko.kex_gex._MSG_KEXDH_GEX_GROUP, msg)
- x = b"20000000807E2DDB1743F3487D6545F04F1C8476092FB912B013626AB5BCEB764257D88BBA64243B9F348DF7B41B8C814A995E00299913503456983FFB9178D3CD79EB6D55522418A8ABF65375872E55938AB99A84A0B5FC8A1ECC66A7C3766E7E0F80B7CE2C9225FC2DD683F4764244B72963BBB383F529DCF0C5D17740B8A2ADBE9208D4"
+ x = b"20000000807E2DDB1743F3487D6545F04F1C8476092FB912B013626AB5BCEB764257D88BBA64243B9F348DF7B41B8C814A995E00299913503456983FFB9178D3CD79EB6D55522418A8ABF65375872E55938AB99A84A0B5FC8A1ECC66A7C3766E7E0F80B7CE2C9225FC2DD683F4764244B72963BBB383F529DCF0C5D17740B8A2ADBE9208D4" # noqa
self.assertEqual(x, hexlify(transport._message.asbytes()).upper())
self.assertEqual(
(paramiko.kex_gex._MSG_KEXDH_GEX_REPLY,), transport._expect
@@ -201,7 +228,7 @@ class KexTest(unittest.TestCase):
self.assertEqual((b"fake-host-key", b"fake-sig"), transport._verify)
self.assertTrue(transport._activated)
- def test_4_gex_old_client(self):
+ def test_gex_old_client(self):
transport = FakeTransport()
transport.server_mode = False
kex = KexGex(transport)
@@ -217,7 +244,7 @@ class KexTest(unittest.TestCase):
msg.add_mpint(FakeModulusPack.G)
msg.rewind()
kex.parse_next(paramiko.kex_gex._MSG_KEXDH_GEX_GROUP, msg)
- x = b"20000000807E2DDB1743F3487D6545F04F1C8476092FB912B013626AB5BCEB764257D88BBA64243B9F348DF7B41B8C814A995E00299913503456983FFB9178D3CD79EB6D55522418A8ABF65375872E55938AB99A84A0B5FC8A1ECC66A7C3766E7E0F80B7CE2C9225FC2DD683F4764244B72963BBB383F529DCF0C5D17740B8A2ADBE9208D4"
+ x = b"20000000807E2DDB1743F3487D6545F04F1C8476092FB912B013626AB5BCEB764257D88BBA64243B9F348DF7B41B8C814A995E00299913503456983FFB9178D3CD79EB6D55522418A8ABF65375872E55938AB99A84A0B5FC8A1ECC66A7C3766E7E0F80B7CE2C9225FC2DD683F4764244B72963BBB383F529DCF0C5D17740B8A2ADBE9208D4" # noqa
self.assertEqual(x, hexlify(transport._message.asbytes()).upper())
self.assertEqual(
(paramiko.kex_gex._MSG_KEXDH_GEX_REPLY,), transport._expect
@@ -235,7 +262,7 @@ class KexTest(unittest.TestCase):
self.assertEqual((b"fake-host-key", b"fake-sig"), transport._verify)
self.assertTrue(transport._activated)
- def test_5_gex_server(self):
+ def test_gex_server(self):
transport = FakeTransport()
transport.server_mode = True
kex = KexGex(transport)
@@ -254,7 +281,7 @@ class KexTest(unittest.TestCase):
msg.add_int(4096)
msg.rewind()
kex.parse_next(paramiko.kex_gex._MSG_KEXDH_GEX_REQUEST, msg)
- x = b"1F0000008100FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381FFFFFFFFFFFFFFFF0000000102"
+ x = b"1F0000008100FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381FFFFFFFFFFFFFFFF0000000102" # noqa
self.assertEqual(x, hexlify(transport._message.asbytes()).upper())
self.assertEqual(
(paramiko.kex_gex._MSG_KEXDH_GEX_INIT,), transport._expect
@@ -264,15 +291,15 @@ class KexTest(unittest.TestCase):
msg.add_mpint(12345)
msg.rewind()
kex.parse_next(paramiko.kex_gex._MSG_KEXDH_GEX_INIT, msg)
- K = 67592995013596137876033460028393339951879041140378510871612128162185209509220726296697886624612526735888348020498716482757677848959420073720160491114319163078862905400020959196386947926388406687288901564192071077389283980347784184487280885335302632305026248574716290537036069329724382811853044654824945750581
+ K = 67592995013596137876033460028393339951879041140378510871612128162185209509220726296697886624612526735888348020498716482757677848959420073720160491114319163078862905400020959196386947926388406687288901564192071077389283980347784184487280885335302632305026248574716290537036069329724382811853044654824945750581 # noqa
H = b"CE754197C21BF3452863B4F44D0B3951F12516EF"
- x = b"210000000866616B652D6B6579000000807E2DDB1743F3487D6545F04F1C8476092FB912B013626AB5BCEB764257D88BBA64243B9F348DF7B41B8C814A995E00299913503456983FFB9178D3CD79EB6D55522418A8ABF65375872E55938AB99A84A0B5FC8A1ECC66A7C3766E7E0F80B7CE2C9225FC2DD683F4764244B72963BBB383F529DCF0C5D17740B8A2ADBE9208D40000000866616B652D736967"
+ x = b"210000000866616B652D6B6579000000807E2DDB1743F3487D6545F04F1C8476092FB912B013626AB5BCEB764257D88BBA64243B9F348DF7B41B8C814A995E00299913503456983FFB9178D3CD79EB6D55522418A8ABF65375872E55938AB99A84A0B5FC8A1ECC66A7C3766E7E0F80B7CE2C9225FC2DD683F4764244B72963BBB383F529DCF0C5D17740B8A2ADBE9208D40000000866616B652D736967" # noqa
self.assertEqual(K, transport._K)
self.assertEqual(H, hexlify(transport._H).upper())
self.assertEqual(x, hexlify(transport._message.asbytes()).upper())
self.assertTrue(transport._activated)
- def test_6_gex_server_with_old_client(self):
+ def test_gex_server_with_old_client(self):
transport = FakeTransport()
transport.server_mode = True
kex = KexGex(transport)
@@ -289,7 +316,7 @@ class KexTest(unittest.TestCase):
msg.add_int(2048)
msg.rewind()
kex.parse_next(paramiko.kex_gex._MSG_KEXDH_GEX_REQUEST_OLD, msg)
- x = b"1F0000008100FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381FFFFFFFFFFFFFFFF0000000102"
+ x = b"1F0000008100FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381FFFFFFFFFFFFFFFF0000000102" # noqa
self.assertEqual(x, hexlify(transport._message.asbytes()).upper())
self.assertEqual(
(paramiko.kex_gex._MSG_KEXDH_GEX_INIT,), transport._expect
@@ -299,15 +326,15 @@ class KexTest(unittest.TestCase):
msg.add_mpint(12345)
msg.rewind()
kex.parse_next(paramiko.kex_gex._MSG_KEXDH_GEX_INIT, msg)
- K = 67592995013596137876033460028393339951879041140378510871612128162185209509220726296697886624612526735888348020498716482757677848959420073720160491114319163078862905400020959196386947926388406687288901564192071077389283980347784184487280885335302632305026248574716290537036069329724382811853044654824945750581
+ K = 67592995013596137876033460028393339951879041140378510871612128162185209509220726296697886624612526735888348020498716482757677848959420073720160491114319163078862905400020959196386947926388406687288901564192071077389283980347784184487280885335302632305026248574716290537036069329724382811853044654824945750581 # noqa
H = b"B41A06B2E59043CEFC1AE16EC31F1E2D12EC455B"
- x = b"210000000866616B652D6B6579000000807E2DDB1743F3487D6545F04F1C8476092FB912B013626AB5BCEB764257D88BBA64243B9F348DF7B41B8C814A995E00299913503456983FFB9178D3CD79EB6D55522418A8ABF65375872E55938AB99A84A0B5FC8A1ECC66A7C3766E7E0F80B7CE2C9225FC2DD683F4764244B72963BBB383F529DCF0C5D17740B8A2ADBE9208D40000000866616B652D736967"
+ x = b"210000000866616B652D6B6579000000807E2DDB1743F3487D6545F04F1C8476092FB912B013626AB5BCEB764257D88BBA64243B9F348DF7B41B8C814A995E00299913503456983FFB9178D3CD79EB6D55522418A8ABF65375872E55938AB99A84A0B5FC8A1ECC66A7C3766E7E0F80B7CE2C9225FC2DD683F4764244B72963BBB383F529DCF0C5D17740B8A2ADBE9208D40000000866616B652D736967" # noqa
self.assertEqual(K, transport._K)
self.assertEqual(H, hexlify(transport._H).upper())
self.assertEqual(x, hexlify(transport._message.asbytes()).upper())
self.assertTrue(transport._activated)
- def test_7_gex_sha256_client(self):
+ def test_gex_sha256_client(self):
transport = FakeTransport()
transport.server_mode = False
kex = KexGexSHA256(transport)
@@ -323,7 +350,7 @@ class KexTest(unittest.TestCase):
msg.add_mpint(FakeModulusPack.G)
msg.rewind()
kex.parse_next(paramiko.kex_gex._MSG_KEXDH_GEX_GROUP, msg)
- x = b"20000000807E2DDB1743F3487D6545F04F1C8476092FB912B013626AB5BCEB764257D88BBA64243B9F348DF7B41B8C814A995E00299913503456983FFB9178D3CD79EB6D55522418A8ABF65375872E55938AB99A84A0B5FC8A1ECC66A7C3766E7E0F80B7CE2C9225FC2DD683F4764244B72963BBB383F529DCF0C5D17740B8A2ADBE9208D4"
+ x = b"20000000807E2DDB1743F3487D6545F04F1C8476092FB912B013626AB5BCEB764257D88BBA64243B9F348DF7B41B8C814A995E00299913503456983FFB9178D3CD79EB6D55522418A8ABF65375872E55938AB99A84A0B5FC8A1ECC66A7C3766E7E0F80B7CE2C9225FC2DD683F4764244B72963BBB383F529DCF0C5D17740B8A2ADBE9208D4" # noqa
self.assertEqual(x, hexlify(transport._message.asbytes()).upper())
self.assertEqual(
(paramiko.kex_gex._MSG_KEXDH_GEX_REPLY,), transport._expect
@@ -341,7 +368,7 @@ class KexTest(unittest.TestCase):
self.assertEqual((b"fake-host-key", b"fake-sig"), transport._verify)
self.assertTrue(transport._activated)
- def test_8_gex_sha256_old_client(self):
+ def test_gex_sha256_old_client(self):
transport = FakeTransport()
transport.server_mode = False
kex = KexGexSHA256(transport)
@@ -357,7 +384,7 @@ class KexTest(unittest.TestCase):
msg.add_mpint(FakeModulusPack.G)
msg.rewind()
kex.parse_next(paramiko.kex_gex._MSG_KEXDH_GEX_GROUP, msg)
- x = b"20000000807E2DDB1743F3487D6545F04F1C8476092FB912B013626AB5BCEB764257D88BBA64243B9F348DF7B41B8C814A995E00299913503456983FFB9178D3CD79EB6D55522418A8ABF65375872E55938AB99A84A0B5FC8A1ECC66A7C3766E7E0F80B7CE2C9225FC2DD683F4764244B72963BBB383F529DCF0C5D17740B8A2ADBE9208D4"
+ x = b"20000000807E2DDB1743F3487D6545F04F1C8476092FB912B013626AB5BCEB764257D88BBA64243B9F348DF7B41B8C814A995E00299913503456983FFB9178D3CD79EB6D55522418A8ABF65375872E55938AB99A84A0B5FC8A1ECC66A7C3766E7E0F80B7CE2C9225FC2DD683F4764244B72963BBB383F529DCF0C5D17740B8A2ADBE9208D4" # noqa
self.assertEqual(x, hexlify(transport._message.asbytes()).upper())
self.assertEqual(
(paramiko.kex_gex._MSG_KEXDH_GEX_REPLY,), transport._expect
@@ -375,7 +402,7 @@ class KexTest(unittest.TestCase):
self.assertEqual((b"fake-host-key", b"fake-sig"), transport._verify)
self.assertTrue(transport._activated)
- def test_9_gex_sha256_server(self):
+ def test_gex_sha256_server(self):
transport = FakeTransport()
transport.server_mode = True
kex = KexGexSHA256(transport)
@@ -394,7 +421,7 @@ class KexTest(unittest.TestCase):
msg.add_int(4096)
msg.rewind()
kex.parse_next(paramiko.kex_gex._MSG_KEXDH_GEX_REQUEST, msg)
- x = b"1F0000008100FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381FFFFFFFFFFFFFFFF0000000102"
+ x = b"1F0000008100FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381FFFFFFFFFFFFFFFF0000000102" # noqa
self.assertEqual(x, hexlify(transport._message.asbytes()).upper())
self.assertEqual(
(paramiko.kex_gex._MSG_KEXDH_GEX_INIT,), transport._expect
@@ -404,15 +431,15 @@ class KexTest(unittest.TestCase):
msg.add_mpint(12345)
msg.rewind()
kex.parse_next(paramiko.kex_gex._MSG_KEXDH_GEX_INIT, msg)
- K = 67592995013596137876033460028393339951879041140378510871612128162185209509220726296697886624612526735888348020498716482757677848959420073720160491114319163078862905400020959196386947926388406687288901564192071077389283980347784184487280885335302632305026248574716290537036069329724382811853044654824945750581
+ K = 67592995013596137876033460028393339951879041140378510871612128162185209509220726296697886624612526735888348020498716482757677848959420073720160491114319163078862905400020959196386947926388406687288901564192071077389283980347784184487280885335302632305026248574716290537036069329724382811853044654824945750581 # noqa
H = b"CCAC0497CF0ABA1DBF55E1A3995D17F4CC31824B0E8D95CDF8A06F169D050D80"
- x = b"210000000866616B652D6B6579000000807E2DDB1743F3487D6545F04F1C8476092FB912B013626AB5BCEB764257D88BBA64243B9F348DF7B41B8C814A995E00299913503456983FFB9178D3CD79EB6D55522418A8ABF65375872E55938AB99A84A0B5FC8A1ECC66A7C3766E7E0F80B7CE2C9225FC2DD683F4764244B72963BBB383F529DCF0C5D17740B8A2ADBE9208D40000000866616B652D736967"
+ x = b"210000000866616B652D6B6579000000807E2DDB1743F3487D6545F04F1C8476092FB912B013626AB5BCEB764257D88BBA64243B9F348DF7B41B8C814A995E00299913503456983FFB9178D3CD79EB6D55522418A8ABF65375872E55938AB99A84A0B5FC8A1ECC66A7C3766E7E0F80B7CE2C9225FC2DD683F4764244B72963BBB383F529DCF0C5D17740B8A2ADBE9208D40000000866616B652D736967" # noqa
self.assertEqual(K, transport._K)
self.assertEqual(H, hexlify(transport._H).upper())
self.assertEqual(x, hexlify(transport._message.asbytes()).upper())
self.assertTrue(transport._activated)
- def test_10_gex_sha256_server_with_old_client(self):
+ def test_gex_sha256_server_with_old_client(self):
transport = FakeTransport()
transport.server_mode = True
kex = KexGexSHA256(transport)
@@ -429,7 +456,7 @@ class KexTest(unittest.TestCase):
msg.add_int(2048)
msg.rewind()
kex.parse_next(paramiko.kex_gex._MSG_KEXDH_GEX_REQUEST_OLD, msg)
- x = b"1F0000008100FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381FFFFFFFFFFFFFFFF0000000102"
+ x = b"1F0000008100FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381FFFFFFFFFFFFFFFF0000000102" # noqa
self.assertEqual(x, hexlify(transport._message.asbytes()).upper())
self.assertEqual(
(paramiko.kex_gex._MSG_KEXDH_GEX_INIT,), transport._expect
@@ -439,16 +466,16 @@ class KexTest(unittest.TestCase):
msg.add_mpint(12345)
msg.rewind()
kex.parse_next(paramiko.kex_gex._MSG_KEXDH_GEX_INIT, msg)
- K = 67592995013596137876033460028393339951879041140378510871612128162185209509220726296697886624612526735888348020498716482757677848959420073720160491114319163078862905400020959196386947926388406687288901564192071077389283980347784184487280885335302632305026248574716290537036069329724382811853044654824945750581
+ K = 67592995013596137876033460028393339951879041140378510871612128162185209509220726296697886624612526735888348020498716482757677848959420073720160491114319163078862905400020959196386947926388406687288901564192071077389283980347784184487280885335302632305026248574716290537036069329724382811853044654824945750581 # noqa
H = b"3DDD2AD840AD095E397BA4D0573972DC60F6461FD38A187CACA6615A5BC8ADBB"
- x = b"210000000866616B652D6B6579000000807E2DDB1743F3487D6545F04F1C8476092FB912B013626AB5BCEB764257D88BBA64243B9F348DF7B41B8C814A995E00299913503456983FFB9178D3CD79EB6D55522418A8ABF65375872E55938AB99A84A0B5FC8A1ECC66A7C3766E7E0F80B7CE2C9225FC2DD683F4764244B72963BBB383F529DCF0C5D17740B8A2ADBE9208D40000000866616B652D736967"
+ x = b"210000000866616B652D6B6579000000807E2DDB1743F3487D6545F04F1C8476092FB912B013626AB5BCEB764257D88BBA64243B9F348DF7B41B8C814A995E00299913503456983FFB9178D3CD79EB6D55522418A8ABF65375872E55938AB99A84A0B5FC8A1ECC66A7C3766E7E0F80B7CE2C9225FC2DD683F4764244B72963BBB383F529DCF0C5D17740B8A2ADBE9208D40000000866616B652D736967" # noqa
self.assertEqual(K, transport._K)
self.assertEqual(H, hexlify(transport._H).upper())
self.assertEqual(x, hexlify(transport._message.asbytes()).upper())
self.assertTrue(transport._activated)
- def test_11_kex_nistp256_client(self):
- K = 91610929826364598472338906427792435253694642563583721654249504912114314269754
+ def test_kex_nistp256_client(self):
+ K = 91610929826364598472338906427792435253694642563583721654249504912114314269754 # noqa
transport = FakeTransport()
transport.server_mode = False
kex = KexNistp256(transport)
@@ -461,7 +488,7 @@ class KexTest(unittest.TestCase):
msg = Message()
msg.add_string("fake-host-key")
Q_S = unhexlify(
- "043ae159594ba062efa121480e9ef136203fa9ec6b6e1f8723a321c16e62b945f573f3b822258cbcd094b9fa1c125cbfe5f043280893e66863cc0cb4dccbe70210"
+ "043ae159594ba062efa121480e9ef136203fa9ec6b6e1f8723a321c16e62b945f573f3b822258cbcd094b9fa1c125cbfe5f043280893e66863cc0cb4dccbe70210" # noqa
)
msg.add_string(Q_S)
msg.add_string("fake-sig")
@@ -473,8 +500,8 @@ class KexTest(unittest.TestCase):
self.assertEqual((b"fake-host-key", b"fake-sig"), transport._verify)
self.assertTrue(transport._activated)
- def test_12_kex_nistp256_server(self):
- K = 91610929826364598472338906427792435253694642563583721654249504912114314269754
+ def test_kex_nistp256_server(self):
+ K = 91610929826364598472338906427792435253694642563583721654249504912114314269754 # noqa
transport = FakeTransport()
transport.server_mode = True
kex = KexNistp256(transport)
@@ -486,7 +513,7 @@ class KexTest(unittest.TestCase):
# fake init
msg = Message()
Q_C = unhexlify(
- "043ae159594ba062efa121480e9ef136203fa9ec6b6e1f8723a321c16e62b945f573f3b822258cbcd094b9fa1c125cbfe5f043280893e66863cc0cb4dccbe70210"
+ "043ae159594ba062efa121480e9ef136203fa9ec6b6e1f8723a321c16e62b945f573f3b822258cbcd094b9fa1c125cbfe5f043280893e66863cc0cb4dccbe70210" # noqa
)
H = b"2EF4957AFD530DD3F05DBEABF68D724FACC060974DA9704F2AEE4C3DE861E7CA"
msg.add_string(Q_C)
@@ -495,3 +522,104 @@ class KexTest(unittest.TestCase):
self.assertEqual(K, transport._K)
self.assertTrue(transport._activated)
self.assertEqual(H, hexlify(transport._H).upper())
+
+ def test_kex_group14_sha256_client(self):
+ transport = FakeTransport()
+ transport.server_mode = False
+ kex = KexGroup14SHA256(transport)
+ kex.start_kex()
+ x = b"1E00000101009850B3A8DE3ECCD3F19644139137C93D9C11BC28ED8BE850908EE294E1D43B88B9295311EFAEF5B736A1B652EBE184CCF36CFB0681C1ED66430088FA448B83619F928E7B9592ED6160EC11D639D51C303603F930F743C646B1B67DA38A1D44598DCE6C3F3019422B898044141420E9A10C29B9C58668F7F20A40F154B2C4768FCF7A9AA7179FB6366A7167EE26DD58963E8B880A0572F641DE0A73DC74C930F7C3A0C9388553F3F8403E40CF8B95FEDB1D366596FCF3FDDEB21A0005ADA650EF1733628D807BE5ACB83925462765D9076570056E39994FB328E3108FE406275758D6BF5F32790EF15D8416BF5548164859E785DB45E7787BB0E727ADE08641ED" # noqa
+ self.assertEqual(x, hexlify(transport._message.asbytes()).upper())
+ self.assertEqual(
+ (paramiko.kex_group1._MSG_KEXDH_REPLY,), transport._expect
+ )
+
+ # fake "reply"
+ msg = Message()
+ msg.add_string("fake-host-key")
+ msg.add_mpint(69)
+ msg.add_string("fake-sig")
+ msg.rewind()
+ kex.parse_next(paramiko.kex_group1._MSG_KEXDH_REPLY, msg)
+ K = 21526936926159575624241589599003964979640840086252478029709904308461709651400109485351462666820496096345766733042945918306284902585618061272525323382142547359684512114160415969631877620660064043178086464811345023251493620331559440565662862858765724251890489795332144543057725932216208403143759943169004775947331771556537814494448612329251887435553890674764339328444948425882382475260315505741818518926349729970262019325118040559191290279100613049085709127598666890434114956464502529053036826173452792849566280474995114751780998069614898221773345705289637708545219204637224261997310181473787577166103031529148842107599 # noqa
+ H = b"D007C23686BE8A7737F828DC9E899F8EB5AF423F495F138437BE2529C1B8455F"
+ self.assertEqual(K, transport._K)
+ self.assertEqual(H, hexlify(transport._H).upper())
+ self.assertEqual((b"fake-host-key", b"fake-sig"), transport._verify)
+ self.assertTrue(transport._activated)
+
+ def test_kex_group16_sha512_client(self):
+ transport = FakeTransport()
+ transport.server_mode = False
+ kex = KexGroup16SHA512(transport)
+ kex.start_kex()
+ x = b"1E0000020100859FF55A23E0F66463561DD8BFC4764C69C05F85665B06EC9E29EF5003A53A8FA890B6A6EB624DEB55A4FB279DE7010A53580A126817E3D235B05A1081662B1500961D0625F0AAD287F1B597CBA9DB9550D9CC26355C4C59F92E613B5C21AC191F152C09A5DB46DCBA5EA58E3CA6A8B0EB7183E27FAC10106022E8521FA91240FB389060F1E1E4A355049D29DCC82921CE6588791743E4B1DEEE0166F7CC5180C3C75F3773342DF95C8C10AAA5D12975257027936B99B3DED6E6E98CF27EADEAEAE04E7F0A28071F578646B985FCE28A59CEB36287CB65759BE0544D4C4018CDF03C9078FE9CA79ECA611CB6966899E6FD29BE0781491C659FE2380E0D99D50D9CFAAB94E61BE311779719C4C43C6D223AD3799C3915A9E55076A21152DBBF911D6594296D6ECDC1B6FA71997CD29DF987B80FCA7F36BB7F19863C72BBBF839746AFBF9A5B407D468C976AA3E36FA118D3EAAD2E08BF6AE219F81F2CE2BE946337F06CC09BBFABE938A4087E413921CBEC1965ED905999B83396ECA226110CDF6EFB80F815F6489AF87561DA3857F13A7705921306D94176231FBB336B17C3724BC17A28BECB910093AB040873D5D760E8C182B88ECCE3E38DDA68CE35BD152DF7550BD908791FCCEDD1FFDF5ED2A57FFAE79599E487A7726D8A3D950B1729A08FBB60EE462A6BBE8BF0F5F0E1358129A37840FE5B3EEB8BF26E99FA222EAE83" # noqa
+ self.assertEqual(x, hexlify(transport._message.asbytes()).upper())
+ self.assertEqual(
+ (paramiko.kex_group1._MSG_KEXDH_REPLY,), transport._expect
+ )
+
+ # fake "reply"
+ msg = Message()
+ msg.add_string("fake-host-key")
+ msg.add_mpint(69)
+ msg.add_string("fake-sig")
+ msg.rewind()
+ kex.parse_next(paramiko.kex_group1._MSG_KEXDH_REPLY, msg)
+ K = 933242830095376162107925500057692534838883186615567574891154103836907630698358649443101764908667358576734565553213003142941996368306996312915844839972197961603283544950658467545799914435739152351344917376359963584614213874232577733869049670230112638724993540996854599166318001059065780674008011575015459772051180901213815080343343801745386220342919837913506966863570473712948197760657442974564354432738520446202131551650771882909329069340612274196233658123593466135642819578182367229641847749149740891990379052266213711500434128970973602206842980669193719602075489724202241641553472106310932258574377789863734311328542715212248147206865762697424822447603031087553480483833829498375309975229907460562402877655519980113688369262871485777790149373908739910846630414678346163764464587129010141922982925829457954376352735653834300282864445132624993186496129911208133529828461690634463092007726349795944930302881758403402084584307180896465875803621285362317770276493727205689466142632599776710824902573926951951209239626732358074877997756011804454926541386215567756538832824717436605031489511654178384081883801272314328403020205577714999460724519735573055540814037716770051316113795603990199374791348798218428912977728347485489266146775472 # noqa
+ H = b"F6E2BCC846B9B62591EFB86663D55D4769CA06B2EDABE469DF831639B2DDD5A271985011900A724CB2C87F19F347B3632A7C1536AF3D12EE463E6EA75281AF0C" # noqa
+ self.assertEqual(K, transport._K)
+ self.assertEqual(H, hexlify(transport._H).upper())
+ self.assertEqual((b"fake-host-key", b"fake-sig"), transport._verify)
+ self.assertTrue(transport._activated)
+
+ @pytest.mark.skipif("not KexCurve25519.is_available()")
+ def test_kex_c25519_client(self):
+ K = 71294722834835117201316639182051104803802881348227506835068888449366462300724 # noqa
+ transport = FakeTransport()
+ transport.server_mode = False
+ kex = KexCurve25519(transport)
+ kex.start_kex()
+ self.assertEqual(
+ (paramiko.kex_curve25519._MSG_KEXECDH_REPLY,), transport._expect
+ )
+
+ # fake reply
+ msg = Message()
+ msg.add_string("fake-host-key")
+ Q_S = unhexlify(
+ "8d13a119452382a1ada8eea4c979f3e63ad3f0c7366786d6c5b54b87219bae49"
+ )
+ msg.add_string(Q_S)
+ msg.add_string("fake-sig")
+ msg.rewind()
+ kex.parse_next(paramiko.kex_curve25519._MSG_KEXECDH_REPLY, msg)
+ H = b"05B6F6437C0CF38D1A6C5A6F6E2558DEB54E7FC62447EBFB1E5D7407326A5475"
+ self.assertEqual(K, kex.transport._K)
+ self.assertEqual(H, hexlify(transport._H).upper())
+ self.assertEqual((b"fake-host-key", b"fake-sig"), transport._verify)
+ self.assertTrue(transport._activated)
+
+ @pytest.mark.skipif("not KexCurve25519.is_available()")
+ def test_kex_c25519_server(self):
+ K = 71294722834835117201316639182051104803802881348227506835068888449366462300724 # noqa
+ transport = FakeTransport()
+ transport.server_mode = True
+ kex = KexCurve25519(transport)
+ kex.start_kex()
+ self.assertEqual(
+ (paramiko.kex_curve25519._MSG_KEXECDH_INIT,), transport._expect
+ )
+
+ # fake init
+ msg = Message()
+ Q_C = unhexlify(
+ "8d13a119452382a1ada8eea4c979f3e63ad3f0c7366786d6c5b54b87219bae49"
+ )
+ H = b"DF08FCFCF31560FEE639D9B6D56D760BC3455B5ADA148E4514181023E7A9B042"
+ msg.add_string(Q_C)
+ msg.rewind()
+ kex.parse_next(paramiko.kex_curve25519._MSG_KEXECDH_INIT, msg)
+ self.assertEqual(K, transport._K)
+ self.assertTrue(transport._activated)
+ self.assertEqual(H, hexlify(transport._H).upper())
diff --git a/tests/test_kex_gss.py b/tests/test_kex_gss.py
index 6bac0120..b0e3970b 100644
--- a/tests/test_kex_gss.py
+++ b/tests/test_kex_gss.py
@@ -137,7 +137,7 @@ class GSSKexTest(KerberosTestCase):
stdout.close()
stderr.close()
- def test_1_gsskex_and_auth(self):
+ def test_gsskex_and_auth(self):
"""
Verify that Paramiko can handle SSHv2 GSS-API / SSPI authenticated
Diffie-Hellman Key Exchange and user authentication with the GSS-API
@@ -146,7 +146,7 @@ class GSSKexTest(KerberosTestCase):
self._test_gsskex_and_auth(gss_host=None)
@unittest.expectedFailure # to be investigated, see https://github.com/paramiko/paramiko/issues/1312
- def test_2_gsskex_and_auth_rekey(self):
+ def test_gsskex_and_auth_rekey(self):
"""
Verify that Paramiko can rekey.
"""
diff --git a/tests/test_message.py b/tests/test_message.py
index b843a705..57766d90 100644
--- a/tests/test_message.py
+++ b/tests/test_message.py
@@ -29,14 +29,14 @@ from paramiko.common import byte_chr, zero_byte
class MessageTest(unittest.TestCase):
__a = (
- b"\x00\x00\x00\x17\x07\x60\xe0\x90\x00\x00\x00\x01\x71\x00\x00\x00\x05\x68\x65\x6c\x6c\x6f\x00\x00\x03\xe8"
+ b"\x00\x00\x00\x17\x07\x60\xe0\x90\x00\x00\x00\x01\x71\x00\x00\x00\x05\x68\x65\x6c\x6c\x6f\x00\x00\x03\xe8" # noqa
+ b"x" * 1000
)
- __b = b"\x01\x00\xf3\x00\x3f\x00\x00\x00\x10\x68\x75\x65\x79\x2c\x64\x65\x77\x65\x79\x2c\x6c\x6f\x75\x69\x65"
- __c = b"\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\xf5\xe4\xd3\xc2\xb1\x09\x00\x00\x00\x01\x11\x00\x00\x00\x07\x00\xf5\xe4\xd3\xc2\xb1\x09\x00\x00\x00\x06\x9a\x1b\x2c\x3d\x4e\xf7"
- __d = b"\x00\x00\x00\x05\xff\x00\x00\x00\x05\x11\x22\x33\x44\x55\xff\x00\x00\x00\x0a\x00\xf0\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x03\x63\x61\x74\x00\x00\x00\x03\x61\x2c\x62"
+ __b = b"\x01\x00\xf3\x00\x3f\x00\x00\x00\x10\x68\x75\x65\x79\x2c\x64\x65\x77\x65\x79\x2c\x6c\x6f\x75\x69\x65" # noqa
+ __c = b"\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\xf5\xe4\xd3\xc2\xb1\x09\x00\x00\x00\x01\x11\x00\x00\x00\x07\x00\xf5\xe4\xd3\xc2\xb1\x09\x00\x00\x00\x06\x9a\x1b\x2c\x3d\x4e\xf7" # noqa
+ __d = b"\x00\x00\x00\x05\xff\x00\x00\x00\x05\x11\x22\x33\x44\x55\xff\x00\x00\x00\x0a\x00\xf0\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x03\x63\x61\x74\x00\x00\x00\x03\x61\x2c\x62" # noqa
- def test_1_encode(self):
+ def test_encode(self):
msg = Message()
msg.add_int(23)
msg.add_int(123789456)
@@ -62,7 +62,7 @@ class MessageTest(unittest.TestCase):
msg.add_mpint(-0x65e4d3c2b109)
self.assertEqual(msg.asbytes(), self.__c)
- def test_2_decode(self):
+ def test_decode(self):
msg = Message(self.__a)
self.assertEqual(msg.get_int(), 23)
self.assertEqual(msg.get_int(), 123789456)
@@ -84,7 +84,7 @@ class MessageTest(unittest.TestCase):
self.assertEqual(msg.get_mpint(), 0xf5e4d3c2b109)
self.assertEqual(msg.get_mpint(), -0x65e4d3c2b109)
- def test_3_add(self):
+ def test_add(self):
msg = Message()
msg.add(5)
msg.add(0x1122334455)
@@ -94,7 +94,7 @@ class MessageTest(unittest.TestCase):
msg.add(["a", "b"])
self.assertEqual(msg.asbytes(), self.__d)
- def test_4_misc(self):
+ def test_misc(self):
msg = Message(self.__d)
self.assertEqual(msg.get_adaptive_int(), 5)
self.assertEqual(msg.get_adaptive_int(), 0x1122334455)
diff --git a/tests/test_packetizer.py b/tests/test_packetizer.py
index 6920f08e..de80770e 100644
--- a/tests/test_packetizer.py
+++ b/tests/test_packetizer.py
@@ -38,7 +38,7 @@ x1f = byte_chr(0x1f)
class PacketizerTest(unittest.TestCase):
- def test_1_write(self):
+ def test_write(self):
rsock = LoopSocket()
wsock = LoopSocket()
rsock.link(wsock)
@@ -64,11 +64,11 @@ class PacketizerTest(unittest.TestCase):
# 32 + 12 bytes of MAC = 44
self.assertEqual(44, len(data))
self.assertEqual(
- b"\x43\x91\x97\xbd\x5b\x50\xac\x25\x87\xc2\xc4\x6b\xc7\xe9\x38\xc0",
+ b"\x43\x91\x97\xbd\x5b\x50\xac\x25\x87\xc2\xc4\x6b\xc7\xe9\x38\xc0", # noqa
data[:16],
)
- def test_2_read(self):
+ def test_read(self):
rsock = LoopSocket()
wsock = LoopSocket()
rsock.link(wsock)
@@ -82,7 +82,7 @@ class PacketizerTest(unittest.TestCase):
).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"
+ 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" # noqa
)
cmd, m = p.read_message()
self.assertEqual(100, cmd)
@@ -90,7 +90,7 @@ class PacketizerTest(unittest.TestCase):
self.assertEqual(1, m.get_int())
self.assertEqual(900, m.get_int())
- def test_3_closed(self):
+ def test_closed(self):
if sys.platform.startswith("win"): # no SIGALRM on windows
return
rsock = LoopSocket()
diff --git a/tests/test_pkey.py b/tests/test_pkey.py
index 08d38e3b..f7dabf26 100644
--- a/tests/test_pkey.py
+++ b/tests/test_pkey.py
@@ -25,7 +25,6 @@ import unittest
import os
from binascii import hexlify
from hashlib import md5
-import base64
from paramiko import RSAKey, DSSKey, ECDSAKey, Ed25519Key, Message, util
from paramiko.py3compat import StringIO, byte_chr, b, bytes, PY2
@@ -34,18 +33,18 @@ from .util import _support
# from openssh's ssh-keygen
-PUB_RSA = "ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAIEA049W6geFpmsljTwfvI1UmKWWJPNFI74+vNKTk4dmzkQY2yAMs6FhlvhlI8ysU4oj71ZsRYMecHbBbxdN79+JRFVYTKaLqjwGENeTd+yv4q+V2PvZv3fLnzApI3l7EJCqhWwJUHJ1jAkZzqDx0tyOL4uoZpww3nmE0kb3y21tH4c="
-PUB_DSS = "ssh-dss AAAAB3NzaC1kc3MAAACBAOeBpgNnfRzr/twmAQRu2XwWAp3CFtrVnug6s6fgwj/oLjYbVtjAy6pl/h0EKCWx2rf1IetyNsTxWrniA9I6HeDj65X1FyDkg6g8tvCnaNB8Xp/UUhuzHuGsMIipRxBxw9LF608EqZcj1E3ytktoW5B5OcjrkEoz3xG7C+rpIjYvAAAAFQDwz4UnmsGiSNu5iqjn3uTzwUpshwAAAIEAkxfFeY8P2wZpDjX0MimZl5wkoFQDL25cPzGBuB4OnB8NoUk/yjAHIIpEShw8V+LzouMK5CTJQo5+Ngw3qIch/WgRmMHy4kBq1SsXMjQCte1So6HBMvBPIW5SiMTmjCfZZiw4AYHK+B/JaOwaG9yRg2Ejg4Ok10+XFDxlqZo8Y+wAAACARmR7CCPjodxASvRbIyzaVpZoJ/Z6x7dAumV+ysrV1BVYd0lYukmnjO1kKBWApqpH1ve9XDQYN8zgxM4b16L21kpoWQnZtXrY3GZ4/it9kUgyB7+NwacIBlXa8cMDL7Q/69o0d54U0X/NeX5QxuYR6OMJlrkQB7oiW/P/1mwjQgE="
-PUB_ECDSA_256 = "ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBJSPZm3ZWkvk/Zx8WP+fZRZ5/NBBHnGQwR6uIC6XHGPDIHuWUzIjAwA0bzqkOUffEsbLe+uQgKl5kbc/L8KA/eo="
-PUB_ECDSA_384 = "ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBBbGibQLW9AAZiGN2hEQxWYYoFaWKwN3PKSaDJSMqmIn1Z9sgRUuw8Y/w502OGvXL/wFk0i2z50l3pWZjD7gfMH7gX5TUiCzwrQkS+Hn1U2S9aF5WJp0NcIzYxXw2r4M2A=="
-PUB_ECDSA_521 = "ecdsa-sha2-nistp521 AAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlzdHA1MjEAAACFBACaOaFLZGuxa5AW16qj6VLypFbLrEWrt9AZUloCMefxO8bNLjK/O5g0rAVasar1TnyHE9qj4NwzANZASWjQNbc4MAG8vzqezFwLIn/kNyNTsXNfqEko9OgHZknlj2Z79dwTJcRAL4QLcT5aND0EHZLB2fAUDXiWIb2j4rg1mwPlBMiBXA=="
+PUB_RSA = "ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAIEA049W6geFpmsljTwfvI1UmKWWJPNFI74+vNKTk4dmzkQY2yAMs6FhlvhlI8ysU4oj71ZsRYMecHbBbxdN79+JRFVYTKaLqjwGENeTd+yv4q+V2PvZv3fLnzApI3l7EJCqhWwJUHJ1jAkZzqDx0tyOL4uoZpww3nmE0kb3y21tH4c=" # noqa
+PUB_DSS = "ssh-dss AAAAB3NzaC1kc3MAAACBAOeBpgNnfRzr/twmAQRu2XwWAp3CFtrVnug6s6fgwj/oLjYbVtjAy6pl/h0EKCWx2rf1IetyNsTxWrniA9I6HeDj65X1FyDkg6g8tvCnaNB8Xp/UUhuzHuGsMIipRxBxw9LF608EqZcj1E3ytktoW5B5OcjrkEoz3xG7C+rpIjYvAAAAFQDwz4UnmsGiSNu5iqjn3uTzwUpshwAAAIEAkxfFeY8P2wZpDjX0MimZl5wkoFQDL25cPzGBuB4OnB8NoUk/yjAHIIpEShw8V+LzouMK5CTJQo5+Ngw3qIch/WgRmMHy4kBq1SsXMjQCte1So6HBMvBPIW5SiMTmjCfZZiw4AYHK+B/JaOwaG9yRg2Ejg4Ok10+XFDxlqZo8Y+wAAACARmR7CCPjodxASvRbIyzaVpZoJ/Z6x7dAumV+ysrV1BVYd0lYukmnjO1kKBWApqpH1ve9XDQYN8zgxM4b16L21kpoWQnZtXrY3GZ4/it9kUgyB7+NwacIBlXa8cMDL7Q/69o0d54U0X/NeX5QxuYR6OMJlrkQB7oiW/P/1mwjQgE=" # noqa
+PUB_ECDSA_256 = "ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBJSPZm3ZWkvk/Zx8WP+fZRZ5/NBBHnGQwR6uIC6XHGPDIHuWUzIjAwA0bzqkOUffEsbLe+uQgKl5kbc/L8KA/eo=" # noqa
+PUB_ECDSA_384 = "ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBBbGibQLW9AAZiGN2hEQxWYYoFaWKwN3PKSaDJSMqmIn1Z9sgRUuw8Y/w502OGvXL/wFk0i2z50l3pWZjD7gfMH7gX5TUiCzwrQkS+Hn1U2S9aF5WJp0NcIzYxXw2r4M2A==" # noqa
+PUB_ECDSA_521 = "ecdsa-sha2-nistp521 AAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlzdHA1MjEAAACFBACaOaFLZGuxa5AW16qj6VLypFbLrEWrt9AZUloCMefxO8bNLjK/O5g0rAVasar1TnyHE9qj4NwzANZASWjQNbc4MAG8vzqezFwLIn/kNyNTsXNfqEko9OgHZknlj2Z79dwTJcRAL4QLcT5aND0EHZLB2fAUDXiWIb2j4rg1mwPlBMiBXA==" # noqa
FINGER_RSA = "1024 60:73:38:44:cb:51:86:65:7f:de:da:a2:2b:5a:57:d5"
FINGER_DSS = "1024 44:78:f0:b9:a2:3c:c5:18:20:09:ff:75:5b:c1:d2:6c"
FINGER_ECDSA_256 = "256 25:19:eb:55:e6:a1:47:ff:4f:38:d2:75:6f:a5:d5:60"
FINGER_ECDSA_384 = "384 c1:8d:a0:59:09:47:41:8e:a8:a6:07:01:29:23:b4:65"
FINGER_ECDSA_521 = "521 44:58:22:52:12:33:16:0e:ce:0e:be:2c:7c:7e:cc:1e"
-SIGNED_RSA = "20:d7:8a:31:21:cb:f7:92:12:f2:a4:89:37:f5:78:af:e6:16:b6:25:b9:97:3d:a2:cd:5f:ca:20:21:73:4c:ad:34:73:8f:20:77:28:e2:94:15:08:d8:91:40:7a:85:83:bf:18:37:95:dc:54:1a:9b:88:29:6c:73:ca:38:b4:04:f1:56:b9:f2:42:9d:52:1b:29:29:b4:4f:fd:c9:2d:af:47:d2:40:76:30:f3:63:45:0c:d9:1d:43:86:0f:1c:70:e2:93:12:34:f3:ac:c5:0a:2f:14:50:66:59:f1:88:ee:c1:4a:e9:d1:9c:4e:46:f0:0e:47:6f:38:74:f1:44:a8"
+SIGNED_RSA = "20:d7:8a:31:21:cb:f7:92:12:f2:a4:89:37:f5:78:af:e6:16:b6:25:b9:97:3d:a2:cd:5f:ca:20:21:73:4c:ad:34:73:8f:20:77:28:e2:94:15:08:d8:91:40:7a:85:83:bf:18:37:95:dc:54:1a:9b:88:29:6c:73:ca:38:b4:04:f1:56:b9:f2:42:9d:52:1b:29:29:b4:4f:fd:c9:2d:af:47:d2:40:76:30:f3:63:45:0c:d9:1d:43:86:0f:1c:70:e2:93:12:34:f3:ac:c5:0a:2f:14:50:66:59:f1:88:ee:c1:4a:e9:d1:9c:4e:46:f0:0e:47:6f:38:74:f1:44:a8" # noqa
RSA_PRIVATE_OUT = """\
-----BEGIN RSA PRIVATE KEY-----
@@ -109,8 +108,8 @@ L4QLcT5aND0EHZLB2fAUDXiWIb2j4rg1mwPlBMiBXA==
x1234 = b"\x01\x02\x03\x04"
-TEST_KEY_BYTESTR_2 = "\x00\x00\x00\x07ssh-rsa\x00\x00\x00\x01#\x00\x00\x00\x81\x00\xd3\x8fV\xea\x07\x85\xa6k%\x8d<\x1f\xbc\x8dT\x98\xa5\x96$\xf3E#\xbe>\xbc\xd2\x93\x93\x87f\xceD\x18\xdb \x0c\xb3\xa1a\x96\xf8e#\xcc\xacS\x8a#\xefVlE\x83\x1epv\xc1o\x17M\xef\xdf\x89DUXL\xa6\x8b\xaa<\x06\x10\xd7\x93w\xec\xaf\xe2\xaf\x95\xd8\xfb\xd9\xbfw\xcb\x9f0)#y{\x10\x90\xaa\x85l\tPru\x8c\t\x19\xce\xa0\xf1\xd2\xdc\x8e/\x8b\xa8f\x9c0\xdey\x84\xd2F\xf7\xcbmm\x1f\x87"
-TEST_KEY_BYTESTR_3 = "\x00\x00\x00\x07ssh-rsa\x00\x00\x00\x01#\x00\x00\x00\x00ӏV\x07k%<\x1fT$E#>ғfD\x18 \x0cae#̬S#VlE\x1epvo\x17M߉DUXL<\x06\x10דw\u2bd5ٿw˟0)#y{\x10l\tPru\t\x19Π\u070e/f0yFmm\x1f"
+TEST_KEY_BYTESTR_2 = "\x00\x00\x00\x07ssh-rsa\x00\x00\x00\x01#\x00\x00\x00\x81\x00\xd3\x8fV\xea\x07\x85\xa6k%\x8d<\x1f\xbc\x8dT\x98\xa5\x96$\xf3E#\xbe>\xbc\xd2\x93\x93\x87f\xceD\x18\xdb \x0c\xb3\xa1a\x96\xf8e#\xcc\xacS\x8a#\xefVlE\x83\x1epv\xc1o\x17M\xef\xdf\x89DUXL\xa6\x8b\xaa<\x06\x10\xd7\x93w\xec\xaf\xe2\xaf\x95\xd8\xfb\xd9\xbfw\xcb\x9f0)#y{\x10\x90\xaa\x85l\tPru\x8c\t\x19\xce\xa0\xf1\xd2\xdc\x8e/\x8b\xa8f\x9c0\xdey\x84\xd2F\xf7\xcbmm\x1f\x87" # noqa
+TEST_KEY_BYTESTR_3 = "\x00\x00\x00\x07ssh-rsa\x00\x00\x00\x01#\x00\x00\x00\x00ӏV\x07k%<\x1fT$E#>ғfD\x18 \x0cae#̬S#VlE\x1epvo\x17M߉DUXL<\x06\x10דw\u2bd5ٿw˟0)#y{\x10l\tPru\t\x19Π\u070e/f0yFmm\x1f" # noqa
class KeyTest(unittest.TestCase):
@@ -131,12 +130,12 @@ class KeyTest(unittest.TestCase):
self.assertEqual(fh.readline()[:-1], "Proc-Type: 4,ENCRYPTED")
self.assertEqual(fh.readline()[0:10], "DEK-Info: ")
- def test_1_generate_key_bytes(self):
+ def test_generate_key_bytes(self):
key = util.generate_key_bytes(md5, x1234, "happy birthday", 30)
- exp = b"\x61\xE1\xF2\x72\xF4\xC1\xC4\x56\x15\x86\xBD\x32\x24\x98\xC0\xE9\x24\x67\x27\x80\xF4\x7B\xB3\x7D\xDA\x7D\x54\x01\x9E\x64"
+ exp = b"\x61\xE1\xF2\x72\xF4\xC1\xC4\x56\x15\x86\xBD\x32\x24\x98\xC0\xE9\x24\x67\x27\x80\xF4\x7B\xB3\x7D\xDA\x7D\x54\x01\x9E\x64" # noqa
self.assertEqual(exp, key)
- def test_2_load_rsa(self):
+ def test_load_rsa(self):
key = RSAKey.from_private_key_file(_support("test_rsa.key"))
self.assertEqual("ssh-rsa", key.get_name())
exp_rsa = b(FINGER_RSA.split()[1].replace(":", ""))
@@ -152,7 +151,7 @@ class KeyTest(unittest.TestCase):
key2 = RSAKey.from_private_key(s)
self.assertEqual(key, key2)
- def test_3_load_rsa_password(self):
+ def test_load_rsa_password(self):
key = RSAKey.from_private_key_file(
_support("test_rsa_password.key"), "television"
)
@@ -163,7 +162,7 @@ class KeyTest(unittest.TestCase):
self.assertEqual(PUB_RSA.split()[1], key.get_base64())
self.assertEqual(1024, key.get_bits())
- def test_4_load_dss(self):
+ def test_load_dss(self):
key = DSSKey.from_private_key_file(_support("test_dss.key"))
self.assertEqual("ssh-dss", key.get_name())
exp_dss = b(FINGER_DSS.split()[1].replace(":", ""))
@@ -179,7 +178,7 @@ class KeyTest(unittest.TestCase):
key2 = DSSKey.from_private_key(s)
self.assertEqual(key, key2)
- def test_5_load_dss_password(self):
+ def test_load_dss_password(self):
key = DSSKey.from_private_key_file(
_support("test_dss_password.key"), "television"
)
@@ -190,7 +189,7 @@ class KeyTest(unittest.TestCase):
self.assertEqual(PUB_DSS.split()[1], key.get_base64())
self.assertEqual(1024, key.get_bits())
- def test_6_compare_rsa(self):
+ def test_compare_rsa(self):
# verify that the private & public keys compare equal
key = RSAKey.from_private_key_file(_support("test_rsa.key"))
self.assertEqual(key, key)
@@ -199,7 +198,7 @@ class KeyTest(unittest.TestCase):
self.assertTrue(not pub.can_sign())
self.assertEqual(key, pub)
- def test_7_compare_dss(self):
+ def test_compare_dss(self):
# verify that the private & public keys compare equal
key = DSSKey.from_private_key_file(_support("test_dss.key"))
self.assertEqual(key, key)
@@ -208,7 +207,7 @@ class KeyTest(unittest.TestCase):
self.assertTrue(not pub.can_sign())
self.assertEqual(key, pub)
- def test_8_sign_rsa(self):
+ def test_sign_rsa(self):
# verify that the rsa private key can sign and verify
key = RSAKey.from_private_key_file(_support("test_rsa.key"))
msg = key.sign_ssh_data(b"ice weasels")
@@ -223,7 +222,7 @@ class KeyTest(unittest.TestCase):
pub = RSAKey(data=key.asbytes())
self.assertTrue(pub.verify_ssh_sig(b"ice weasels", msg))
- def test_9_sign_dss(self):
+ def test_sign_dss(self):
# verify that the dss private key can sign and verify
key = DSSKey.from_private_key_file(_support("test_dss.key"))
msg = key.sign_ssh_data(b"ice weasels")
@@ -238,19 +237,19 @@ class KeyTest(unittest.TestCase):
pub = DSSKey(data=key.asbytes())
self.assertTrue(pub.verify_ssh_sig(b"ice weasels", msg))
- def test_A_generate_rsa(self):
+ def test_generate_rsa(self):
key = RSAKey.generate(1024)
msg = key.sign_ssh_data(b"jerri blank")
msg.rewind()
self.assertTrue(key.verify_ssh_sig(b"jerri blank", msg))
- def test_B_generate_dss(self):
+ def test_generate_dss(self):
key = DSSKey.generate(1024)
msg = key.sign_ssh_data(b"jerri blank")
msg.rewind()
self.assertTrue(key.verify_ssh_sig(b"jerri blank", msg))
- def test_C_generate_ecdsa(self):
+ def test_generate_ecdsa(self):
key = ECDSAKey.generate()
msg = key.sign_ssh_data(b"jerri blank")
msg.rewind()
@@ -279,7 +278,7 @@ class KeyTest(unittest.TestCase):
self.assertEqual(key.get_bits(), 521)
self.assertEqual(key.get_name(), "ecdsa-sha2-nistp521")
- def test_10_load_ecdsa_256(self):
+ def test_load_ecdsa_256(self):
key = ECDSAKey.from_private_key_file(_support("test_ecdsa_256.key"))
self.assertEqual("ecdsa-sha2-nistp256", key.get_name())
exp_ecdsa = b(FINGER_ECDSA_256.split()[1].replace(":", ""))
@@ -295,7 +294,7 @@ class KeyTest(unittest.TestCase):
key2 = ECDSAKey.from_private_key(s)
self.assertEqual(key, key2)
- def test_11_load_ecdsa_password_256(self):
+ def test_load_ecdsa_password_256(self):
key = ECDSAKey.from_private_key_file(
_support("test_ecdsa_password_256.key"), b"television"
)
@@ -306,7 +305,7 @@ class KeyTest(unittest.TestCase):
self.assertEqual(PUB_ECDSA_256.split()[1], key.get_base64())
self.assertEqual(256, key.get_bits())
- def test_12_compare_ecdsa_256(self):
+ def test_compare_ecdsa_256(self):
# verify that the private & public keys compare equal
key = ECDSAKey.from_private_key_file(_support("test_ecdsa_256.key"))
self.assertEqual(key, key)
@@ -315,7 +314,7 @@ class KeyTest(unittest.TestCase):
self.assertTrue(not pub.can_sign())
self.assertEqual(key, pub)
- def test_13_sign_ecdsa_256(self):
+ def test_sign_ecdsa_256(self):
# verify that the rsa private key can sign and verify
key = ECDSAKey.from_private_key_file(_support("test_ecdsa_256.key"))
msg = key.sign_ssh_data(b"ice weasels")
@@ -331,7 +330,7 @@ class KeyTest(unittest.TestCase):
pub = ECDSAKey(data=key.asbytes())
self.assertTrue(pub.verify_ssh_sig(b"ice weasels", msg))
- def test_14_load_ecdsa_384(self):
+ def test_load_ecdsa_384(self):
key = ECDSAKey.from_private_key_file(_support("test_ecdsa_384.key"))
self.assertEqual("ecdsa-sha2-nistp384", key.get_name())
exp_ecdsa = b(FINGER_ECDSA_384.split()[1].replace(":", ""))
@@ -347,7 +346,7 @@ class KeyTest(unittest.TestCase):
key2 = ECDSAKey.from_private_key(s)
self.assertEqual(key, key2)
- def test_15_load_ecdsa_password_384(self):
+ def test_load_ecdsa_password_384(self):
key = ECDSAKey.from_private_key_file(
_support("test_ecdsa_password_384.key"), b"television"
)
@@ -358,7 +357,7 @@ class KeyTest(unittest.TestCase):
self.assertEqual(PUB_ECDSA_384.split()[1], key.get_base64())
self.assertEqual(384, key.get_bits())
- def test_16_compare_ecdsa_384(self):
+ def test_compare_ecdsa_384(self):
# verify that the private & public keys compare equal
key = ECDSAKey.from_private_key_file(_support("test_ecdsa_384.key"))
self.assertEqual(key, key)
@@ -367,7 +366,7 @@ class KeyTest(unittest.TestCase):
self.assertTrue(not pub.can_sign())
self.assertEqual(key, pub)
- def test_17_sign_ecdsa_384(self):
+ def test_sign_ecdsa_384(self):
# verify that the rsa private key can sign and verify
key = ECDSAKey.from_private_key_file(_support("test_ecdsa_384.key"))
msg = key.sign_ssh_data(b"ice weasels")
@@ -383,7 +382,7 @@ class KeyTest(unittest.TestCase):
pub = ECDSAKey(data=key.asbytes())
self.assertTrue(pub.verify_ssh_sig(b"ice weasels", msg))
- def test_18_load_ecdsa_521(self):
+ def test_load_ecdsa_521(self):
key = ECDSAKey.from_private_key_file(_support("test_ecdsa_521.key"))
self.assertEqual("ecdsa-sha2-nistp521", key.get_name())
exp_ecdsa = b(FINGER_ECDSA_521.split()[1].replace(":", ""))
@@ -402,7 +401,7 @@ class KeyTest(unittest.TestCase):
key2 = ECDSAKey.from_private_key(s)
self.assertEqual(key, key2)
- def test_19_load_ecdsa_password_521(self):
+ def test_load_ecdsa_password_521(self):
key = ECDSAKey.from_private_key_file(
_support("test_ecdsa_password_521.key"), b"television"
)
@@ -413,7 +412,7 @@ class KeyTest(unittest.TestCase):
self.assertEqual(PUB_ECDSA_521.split()[1], key.get_base64())
self.assertEqual(521, key.get_bits())
- def test_20_compare_ecdsa_521(self):
+ def test_compare_ecdsa_521(self):
# verify that the private & public keys compare equal
key = ECDSAKey.from_private_key_file(_support("test_ecdsa_521.key"))
self.assertEqual(key, key)
@@ -422,7 +421,7 @@ class KeyTest(unittest.TestCase):
self.assertTrue(not pub.can_sign())
self.assertEqual(key, pub)
- def test_21_sign_ecdsa_521(self):
+ def test_sign_ecdsa_521(self):
# verify that the rsa private key can sign and verify
key = ECDSAKey.from_private_key_file(_support("test_ecdsa_521.key"))
msg = key.sign_ssh_data(b"ice weasels")
@@ -479,7 +478,7 @@ class KeyTest(unittest.TestCase):
def test_ed25519_nonbytes_password(self):
# https://github.com/paramiko/paramiko/issues/1039
- key = Ed25519Key.from_private_key_file(
+ Ed25519Key.from_private_key_file(
_support("test_ed25519_password.key"),
# NOTE: not a bytes. Amusingly, the test above for same key DOES
# explicitly cast to bytes...code smell!
@@ -528,7 +527,7 @@ class KeyTest(unittest.TestCase):
# Delve into blob contents, for test purposes
msg = Message(key.public_blob.key_blob)
self.assertEqual(msg.get_text(), "ssh-rsa-cert-v01@openssh.com")
- nonce = msg.get_string()
+ msg.get_string()
e = msg.get_mpint()
n = msg.get_mpint()
self.assertEqual(e, key.public_numbers.e)
diff --git a/tests/test_sftp.py b/tests/test_sftp.py
index fdb7c9bc..e4e18e5a 100644
--- a/tests/test_sftp.py
+++ b/tests/test_sftp.py
@@ -26,23 +26,18 @@ do test file operations in (so no existing files will be harmed).
import os
import socket
import sys
-import threading
-import unittest
import warnings
from binascii import hexlify
from tempfile import mkstemp
import pytest
-import paramiko
-import paramiko.util
from paramiko.py3compat import PY2, b, u, StringIO
from paramiko.common import o777, o600, o666, o644
from paramiko.sftp_attr import SFTPAttributes
from .util import needs_builtin
-from .stub_sftp import StubServer, StubSFTPServer
-from .util import _support, slow
+from .util import slow
ARTICLE = """
@@ -74,14 +69,21 @@ decreased compared with chicken.
# Here is how unicode characters are encoded over 1 to 6 bytes in utf-8
-# U-00000000 - U-0000007F: 0xxxxxxx
-# U-00000080 - U-000007FF: 110xxxxx 10xxxxxx
-# U-00000800 - U-0000FFFF: 1110xxxx 10xxxxxx 10xxxxxx
-# U-00010000 - U-001FFFFF: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
-# U-00200000 - U-03FFFFFF: 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
-# U-04000000 - U-7FFFFFFF: 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
+# U-00000000 - U-0000007F:
+# 0xxxxxxx
+# U-00000080 - U-000007FF:
+# 110xxxxx 10xxxxxx
+# U-00000800 - U-0000FFFF:
+# 1110xxxx 10xxxxxx 10xxxxxx
+# U-00010000 - U-001FFFFF:
+# 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
+# U-00200000 - U-03FFFFFF:
+# 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
+# U-04000000 - U-7FFFFFFF:
+# 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
# Note that: hex(int('11000011',2)) == '0xc3'
-# Thus, the following 2-bytes sequence is not valid utf8: "invalid continuation byte"
+# Thus, the following 2-bytes sequence is not valid utf8: "invalid continuation
+# byte"
NON_UTF8_DATA = b"\xC3\xC3"
unicode_folder = u"\u00fcnic\u00f8de" if PY2 else "\u00fcnic\u00f8de"
@@ -90,7 +92,7 @@ utf8_folder = b"/\xc3\xbcnic\xc3\xb8\x64\x65"
@slow
class TestSFTP(object):
- def test_1_file(self, sftp):
+ def test_file(self, sftp):
"""
verify that we can create a file.
"""
@@ -101,7 +103,7 @@ class TestSFTP(object):
f.close()
sftp.remove(sftp.FOLDER + "/test")
- def test_2_close(self, sftp):
+ def test_close(self, sftp):
"""
Verify that SFTP session close() causes a socket error on next action.
"""
@@ -109,7 +111,7 @@ class TestSFTP(object):
with pytest.raises(socket.error, match="Socket is closed"):
sftp.open(sftp.FOLDER + "/test2", "w")
- def test_2_sftp_can_be_used_as_context_manager(self, sftp):
+ def test_sftp_can_be_used_as_context_manager(self, sftp):
"""
verify that the sftp session is closed when exiting the context manager
"""
@@ -118,7 +120,7 @@ class TestSFTP(object):
with pytest.raises(socket.error, match="Socket is closed"):
sftp.open(sftp.FOLDER + "/test2", "w")
- def test_3_write(self, sftp):
+ def test_write(self, sftp):
"""
verify that a file can be created and written, and the size is correct.
"""
@@ -129,7 +131,7 @@ class TestSFTP(object):
finally:
sftp.remove(sftp.FOLDER + "/duck.txt")
- def test_3_sftp_file_can_be_used_as_context_manager(self, sftp):
+ def test_sftp_file_can_be_used_as_context_manager(self, sftp):
"""
verify that an opened file can be used as a context manager
"""
@@ -140,7 +142,7 @@ class TestSFTP(object):
finally:
sftp.remove(sftp.FOLDER + "/duck.txt")
- def test_4_append(self, sftp):
+ def test_append(self, sftp):
"""
verify that a file can be opened for append, and tell() still works.
"""
@@ -158,7 +160,7 @@ class TestSFTP(object):
finally:
sftp.remove(sftp.FOLDER + "/append.txt")
- def test_5_rename(self, sftp):
+ def test_rename(self, sftp):
"""
verify that renaming a file works.
"""
@@ -185,7 +187,7 @@ class TestSFTP(object):
except:
pass
- def test_5a_posix_rename(self, sftp):
+ def testa_posix_rename(self, sftp):
"""Test posix-rename@openssh.com protocol extension."""
try:
# first check that the normal rename works as specified
@@ -214,7 +216,7 @@ class TestSFTP(object):
except:
pass
- def test_6_folder(self, sftp):
+ def test_folder(self, sftp):
"""
create a temporary folder, verify that we can create a file in it, then
remove the folder and verify that we can't create a file in it anymore.
@@ -227,7 +229,7 @@ class TestSFTP(object):
with pytest.raises(IOError, match="No such file"):
sftp.open(sftp.FOLDER + "/subfolder/test")
- def test_7_listdir(self, sftp):
+ def test_listdir(self, sftp):
"""
verify that a folder can be created, a bunch of files can be placed in
it, and those files show up in sftp.listdir.
@@ -248,7 +250,7 @@ class TestSFTP(object):
sftp.remove(sftp.FOLDER + "/fish.txt")
sftp.remove(sftp.FOLDER + "/tertiary.py")
- def test_7_5_listdir_iter(self, sftp):
+ def test_listdir_iter(self, sftp):
"""
listdir_iter version of above test
"""
@@ -268,7 +270,7 @@ class TestSFTP(object):
sftp.remove(sftp.FOLDER + "/fish.txt")
sftp.remove(sftp.FOLDER + "/tertiary.py")
- def test_8_setstat(self, sftp):
+ def test_setstat(self, sftp):
"""
verify that the setstat functions (chown, chmod, utime, truncate) work.
"""
@@ -305,7 +307,7 @@ class TestSFTP(object):
finally:
sftp.remove(sftp.FOLDER + "/special")
- def test_9_fsetstat(self, sftp):
+ def test_fsetstat(self, sftp):
"""
verify that the fsetstat functions (chown, chmod, utime, truncate)
work on open files.
@@ -345,12 +347,12 @@ class TestSFTP(object):
finally:
sftp.remove(sftp.FOLDER + "/special")
- def test_A_readline_seek(self, sftp):
+ def test_readline_seek(self, sftp):
"""
- create a text file and write a bunch of text into it. then count the lines
- in the file, and seek around to retrieve particular lines. this should
- verify that read buffering and 'tell' work well together, and that read
- buffering is reset on 'seek'.
+ create a text file and write a bunch of text into it. then count the
+ lines in the file, and seek around to retrieve particular lines. this
+ should verify that read buffering and 'tell' work well together, and
+ that read buffering is reset on 'seek'.
"""
try:
with sftp.open(sftp.FOLDER + "/duck.txt", "w") as f:
@@ -370,17 +372,14 @@ class TestSFTP(object):
f.seek(pos_list[17], f.SEEK_SET)
assert f.readline()[:4] == "duck"
f.seek(pos_list[10], f.SEEK_SET)
- assert (
- f.readline()
- == "duck types were equally resistant to exogenous insulin compared with chicken.\n"
- )
+ expected = "duck types were equally resistant to exogenous insulin compared with chicken.\n" # noqa
+ assert f.readline() == expected
finally:
sftp.remove(sftp.FOLDER + "/duck.txt")
- def test_B_write_seek(self, sftp):
+ def test_write_seek(self, sftp):
"""
- create a text file, seek back and change part of it, and verify that the
- changes worked.
+ Create a text file, seek back, change it, and verify.
"""
try:
with sftp.open(sftp.FOLDER + "/testing.txt", "w") as f:
@@ -395,7 +394,7 @@ class TestSFTP(object):
finally:
sftp.remove(sftp.FOLDER + "/testing.txt")
- def test_C_symlink(self, sftp):
+ def test_symlink(self, sftp):
"""
create a symlink and then check that lstat doesn't follow it.
"""
@@ -442,7 +441,7 @@ class TestSFTP(object):
except:
pass
- def test_D_flush_seek(self, sftp):
+ def test_flush_seek(self, sftp):
"""
verify that buffered writes are automatically flushed on seek.
"""
@@ -462,7 +461,7 @@ class TestSFTP(object):
except:
pass
- def test_E_realpath(self, sftp):
+ def test_realpath(self, sftp):
"""
test that realpath is returning something non-empty and not an
error.
@@ -473,7 +472,7 @@ class TestSFTP(object):
assert len(f) > 0
assert os.path.join(pwd, sftp.FOLDER) == f
- def test_F_mkdir(self, sftp):
+ def test_mkdir(self, sftp):
"""
verify that mkdir/rmdir work.
"""
@@ -484,7 +483,7 @@ class TestSFTP(object):
with pytest.raises(IOError, match="No such file"):
sftp.rmdir(sftp.FOLDER + "/subfolder")
- def test_G_chdir(self, sftp):
+ def test_chdir(self, sftp):
"""
verify that chdir/getcwd work.
"""
@@ -520,7 +519,7 @@ class TestSFTP(object):
except:
pass
- def test_H_get_put(self, sftp):
+ def test_get_put(self, sftp):
"""
verify that get/put work.
"""
@@ -555,7 +554,7 @@ class TestSFTP(object):
os.unlink(localname)
sftp.unlink(sftp.FOLDER + "/bunny.txt")
- def test_I_check(self, sftp):
+ def test_check(self, sftp):
"""
verify that file.check() works against our own server.
(it's an sftp extension that we support, and may be the only ones who
@@ -577,14 +576,12 @@ class TestSFTP(object):
== u(hexlify(sum)).upper()
)
sum = f.check("md5", 0, 0, 510)
- assert (
- u(hexlify(sum)).upper()
- == "EB3B45B8CD55A0707D99B177544A319F373183D241432BB2157AB9E46358C4AC90370B5CADE5D90336FC1716F90B36D6"
- ) # noqa
+ expected = "EB3B45B8CD55A0707D99B177544A319F373183D241432BB2157AB9E46358C4AC90370B5CADE5D90336FC1716F90B36D6" # noqa
+ assert u(hexlify(sum)).upper() == expected
finally:
sftp.unlink(sftp.FOLDER + "/kitty.txt")
- def test_J_x_flag(self, sftp):
+ def test_x_flag(self, sftp):
"""
verify that the 'x' flag works when opening a file.
"""
@@ -599,7 +596,7 @@ class TestSFTP(object):
finally:
sftp.unlink(sftp.FOLDER + "/unusual.txt")
- def test_K_utf8(self, sftp):
+ def test_utf8(self, sftp):
"""
verify that unicode strings are encoded into utf8 correctly.
"""
@@ -615,7 +612,7 @@ class TestSFTP(object):
self.fail("exception " + str(e))
sftp.unlink(b(sftp.FOLDER) + utf8_folder)
- def test_L_utf8_chdir(self, sftp):
+ def test_utf8_chdir(self, sftp):
sftp.mkdir(sftp.FOLDER + "/" + unicode_folder)
try:
sftp.chdir(sftp.FOLDER + "/" + unicode_folder)
@@ -626,7 +623,7 @@ class TestSFTP(object):
sftp.chdir()
sftp.rmdir(sftp.FOLDER + "/" + unicode_folder)
- def test_M_bad_readv(self, sftp):
+ def test_bad_readv(self, sftp):
"""
verify that readv at the end of the file doesn't essplode.
"""
@@ -642,7 +639,7 @@ class TestSFTP(object):
finally:
sftp.unlink(sftp.FOLDER + "/zero")
- def test_N_put_without_confirm(self, sftp):
+ def test_put_without_confirm(self, sftp):
"""
verify that get/put work without confirmation.
"""
@@ -671,11 +668,11 @@ class TestSFTP(object):
os.unlink(localname)
sftp.unlink(sftp.FOLDER + "/bunny.txt")
- def test_O_getcwd(self, sftp):
+ def test_getcwd(self, sftp):
"""
verify that chdir/getcwd work.
"""
- assert sftp.getcwd() == None
+ assert sftp.getcwd() is None
root = sftp.normalize(".")
if root[-1] != "/":
root += "/"
@@ -690,7 +687,7 @@ class TestSFTP(object):
except:
pass
- def XXX_test_M_seek_append(self, sftp):
+ def test_seek_append(self, sftp):
"""
verify that seek does't affect writes during append.
@@ -728,7 +725,7 @@ class TestSFTP(object):
# appear but they're clearly emitted from subthreads that have no error
# handling. No point running it until that is fixed somehow.
@pytest.mark.skip("Doesn't prove anything right now")
- def test_N_file_with_percent(self, sftp):
+ def test_file_with_percent(self, sftp):
"""
verify that we can create a file with a '%' in the filename.
( it needs to be properly escaped by _log() )
@@ -740,7 +737,7 @@ class TestSFTP(object):
f.close()
sftp.remove(sftp.FOLDER + "/test%file")
- def test_O_non_utf8_data(self, sftp):
+ def test_non_utf8_data(self, sftp):
"""Test write() and read() of non utf8 data"""
try:
with sftp.open("%s/nonutf8data" % sftp.FOLDER, "w") as f:
@@ -770,7 +767,7 @@ class TestSFTP(object):
try:
with sftp.open("%s/write_buffer" % sftp.FOLDER, "wb") as f:
for offset in range(0, len(data), 8):
- f.write(buffer(data, offset, 8))
+ f.write(buffer(data, offset, 8)) # noqa
with sftp.open("%s/write_buffer" % sftp.FOLDER, "rb") as f:
assert f.read() == data
diff --git a/tests/test_sftp_big.py b/tests/test_sftp_big.py
index 9df566e8..fc556faf 100644
--- a/tests/test_sftp_big.py
+++ b/tests/test_sftp_big.py
@@ -23,12 +23,10 @@ a real actual sftp server is contacted, and a new folder is created there to
do test file operations in (so no existing files will be harmed).
"""
-import os
import random
import struct
import sys
import time
-import unittest
from paramiko.common import o660
@@ -37,7 +35,7 @@ from .util import slow
@slow
class TestBigSFTP(object):
- def test_1_lots_of_files(self, sftp):
+ def test_lots_of_files(self, sftp):
"""
create a bunch of files over the same session.
"""
@@ -65,7 +63,7 @@ class TestBigSFTP(object):
except:
pass
- def test_2_big_file(self, sftp):
+ def test_big_file(self, sftp):
"""
write a 1MB file with no buffering.
"""
@@ -96,7 +94,7 @@ class TestBigSFTP(object):
finally:
sftp.remove("%s/hongry.txt" % sftp.FOLDER)
- def test_3_big_file_pipelined(self, sftp):
+ def test_big_file_pipelined(self, sftp):
"""
write a 1MB file, with no linefeeds, using pipelining.
"""
@@ -122,7 +120,8 @@ class TestBigSFTP(object):
file_size = f.stat().st_size
f.prefetch(file_size)
- # read on odd boundaries to make sure the bytes aren't getting scrambled
+ # read on odd boundaries to make sure the bytes aren't getting
+ # scrambled
n = 0
k2blob = kblob + kblob
chunk = 629
@@ -140,7 +139,7 @@ class TestBigSFTP(object):
finally:
sftp.remove("%s/hongry.txt" % sftp.FOLDER)
- def test_4_prefetch_seek(self, sftp):
+ def test_prefetch_seek(self, sftp):
kblob = bytes().join([struct.pack(">H", n) for n in range(512)])
try:
with sftp.open("%s/hongry.txt" % sftp.FOLDER, "wb") as f:
@@ -180,7 +179,7 @@ class TestBigSFTP(object):
finally:
sftp.remove("%s/hongry.txt" % sftp.FOLDER)
- def test_5_readv_seek(self, sftp):
+ def test_readv_seek(self, sftp):
kblob = bytes().join([struct.pack(">H", n) for n in range(512)])
try:
with sftp.open("%s/hongry.txt" % sftp.FOLDER, "wb") as f:
@@ -220,7 +219,7 @@ class TestBigSFTP(object):
finally:
sftp.remove("%s/hongry.txt" % sftp.FOLDER)
- def test_6_lots_of_prefetching(self, sftp):
+ def test_lots_of_prefetching(self, sftp):
"""
prefetch a 1MB file a bunch of times, discarding the file object
without using it, to verify that paramiko doesn't get confused.
@@ -255,7 +254,7 @@ class TestBigSFTP(object):
finally:
sftp.remove("%s/hongry.txt" % sftp.FOLDER)
- def test_7_prefetch_readv(self, sftp):
+ def test_prefetch_readv(self, sftp):
"""
verify that prefetch and readv don't conflict with each other.
"""
@@ -296,7 +295,7 @@ class TestBigSFTP(object):
finally:
sftp.remove("%s/hongry.txt" % sftp.FOLDER)
- def test_8_large_readv(self, sftp):
+ def test_large_readv(self, sftp):
"""
verify that a very large readv is broken up correctly and still
returned as a single blob.
@@ -325,7 +324,7 @@ class TestBigSFTP(object):
finally:
sftp.remove("%s/hongry.txt" % sftp.FOLDER)
- def test_9_big_file_big_buffer(self, sftp):
+ def test_big_file_big_buffer(self, sftp):
"""
write a 1MB file, with no linefeeds, and a big buffer.
"""
@@ -342,7 +341,7 @@ class TestBigSFTP(object):
finally:
sftp.remove("%s/hongry.txt" % sftp.FOLDER)
- def test_A_big_file_renegotiate(self, sftp):
+ def test_big_file_renegotiate(self, sftp):
"""
write a 1MB file, forcing key renegotiation in the middle.
"""
diff --git a/tests/test_ssh_gss.py b/tests/test_ssh_gss.py
index 8e4cb962..92801c20 100644
--- a/tests/test_ssh_gss.py
+++ b/tests/test_ssh_gss.py
@@ -139,17 +139,16 @@ class GSSAuthTest(KerberosTestCase):
stdout.close()
stderr.close()
- def test_1_gss_auth(self):
+ def test_gss_auth(self):
"""
Verify that Paramiko can handle SSHv2 GSS-API / SSPI authentication
(gssapi-with-mic) in client and server mode.
"""
self._test_connection(allow_agent=False, look_for_keys=False)
- def test_2_auth_trickledown(self):
+ def test_auth_trickledown(self):
"""
- Failed gssapi-with-mic auth doesn't prevent subsequent key auth from
- succeeding
+ Failed gssapi-with-mic doesn't prevent subsequent key from succeeding
"""
self.hostname = (
"this_host_does_not_exists_and_causes_a_GSSAPI-exception"
diff --git a/tests/test_transport.py b/tests/test_transport.py
index 2b8ee3bc..ad267e28 100644
--- a/tests/test_transport.py
+++ b/tests/test_transport.py
@@ -28,36 +28,32 @@ import socket
import time
import threading
import random
-from hashlib import sha1
import unittest
from mock import Mock
from paramiko import (
- Transport,
- SecurityOptions,
- ServerInterface,
- RSAKey,
- DSSKey,
- SSHException,
+ AuthHandler,
ChannelException,
+ DSSKey,
Packetizer,
- Channel,
- AuthHandler,
+ RSAKey,
+ SSHException,
+ SecurityOptions,
+ ServerInterface,
+ Transport,
)
from paramiko import AUTH_FAILED, AUTH_SUCCESSFUL
from paramiko import OPEN_SUCCEEDED, OPEN_FAILED_ADMINISTRATIVELY_PROHIBITED
from paramiko.common import (
- MSG_KEXINIT,
- cMSG_CHANNEL_WINDOW_ADJUST,
- cMSG_UNIMPLEMENTED,
+ DEFAULT_MAX_PACKET_SIZE,
+ DEFAULT_WINDOW_SIZE,
+ MAX_WINDOW_SIZE,
MIN_PACKET_SIZE,
MIN_WINDOW_SIZE,
- MAX_WINDOW_SIZE,
- DEFAULT_WINDOW_SIZE,
- DEFAULT_MAX_PACKET_SIZE,
- MSG_NAMES,
- MSG_UNIMPLEMENTED,
+ MSG_KEXINIT,
MSG_USERAUTH_SUCCESS,
+ cMSG_CHANNEL_WINDOW_ADJUST,
+ cMSG_UNIMPLEMENTED,
)
from paramiko.py3compat import bytes, byte_chr
from paramiko.message import Message
@@ -185,7 +181,7 @@ class TransportTest(unittest.TestCase):
self.assertTrue(event.is_set())
self.assertTrue(self.ts.is_active())
- def test_1_security_options(self):
+ def test_security_options(self):
o = self.tc.get_security_options()
self.assertEqual(type(o), SecurityOptions)
self.assertTrue(("aes256-cbc", "blowfish-cbc") != o.ciphers)
@@ -202,7 +198,7 @@ class TransportTest(unittest.TestCase):
except TypeError:
pass
- def test_1b_security_options_reset(self):
+ def testb_security_options_reset(self):
o = self.tc.get_security_options()
# should not throw any exceptions
o.ciphers = o.ciphers
@@ -211,17 +207,17 @@ class TransportTest(unittest.TestCase):
o.kex = o.kex
o.compression = o.compression
- def test_2_compute_key(self):
- self.tc.K = 123281095979686581523377256114209720774539068973101330872763622971399429481072519713536292772709507296759612401802191955568143056534122385270077606457721553469730659233569339356140085284052436697480759510519672848743794433460113118986816826624865291116513647975790797391795651716378444844877749505443714557929
- self.tc.H = b"\x0C\x83\x07\xCD\xE6\x85\x6F\xF3\x0B\xA9\x36\x84\xEB\x0F\x04\xC2\x52\x0E\x9E\xD3"
+ def test_compute_key(self):
+ self.tc.K = 123281095979686581523377256114209720774539068973101330872763622971399429481072519713536292772709507296759612401802191955568143056534122385270077606457721553469730659233569339356140085284052436697480759510519672848743794433460113118986816826624865291116513647975790797391795651716378444844877749505443714557929 # noqa
+ self.tc.H = b"\x0C\x83\x07\xCD\xE6\x85\x6F\xF3\x0B\xA9\x36\x84\xEB\x0F\x04\xC2\x52\x0E\x9E\xD3" # noqa
self.tc.session_id = self.tc.H
key = self.tc._compute_key("C", 32)
self.assertEqual(
- b"207E66594CA87C44ECCBA3B3CD39FDDB378E6FDB0F97C54B2AA0CFBF900CD995",
+ b"207E66594CA87C44ECCBA3B3CD39FDDB378E6FDB0F97C54B2AA0CFBF900CD995", # noqa
hexlify(key).upper(),
)
- def test_3_simple(self):
+ def test_simple(self):
"""
verify that we can establish an ssh link with ourselves across the
loopback sockets. this is hardly "simple" but it's simpler than the
@@ -249,7 +245,7 @@ class TransportTest(unittest.TestCase):
self.assertEqual(True, self.tc.is_authenticated())
self.assertEqual(True, self.ts.is_authenticated())
- def test_3a_long_banner(self):
+ def testa_long_banner(self):
"""
verify that a long banner doesn't mess up the handshake.
"""
@@ -268,7 +264,7 @@ class TransportTest(unittest.TestCase):
self.assertTrue(event.is_set())
self.assertTrue(self.ts.is_active())
- def test_4_special(self):
+ def test_special(self):
"""
verify that the client can demand odd handshake settings, and can
renegotiate keys in mid-stream.
@@ -289,7 +285,7 @@ class TransportTest(unittest.TestCase):
self.ts.send_ignore(1024)
@slow
- def test_5_keepalive(self):
+ def test_keepalive(self):
"""
verify that the keepalive will be sent.
"""
@@ -299,7 +295,7 @@ class TransportTest(unittest.TestCase):
time.sleep(2)
self.assertEqual("keepalive@lag.net", self.server._global_request)
- def test_6_exec_command(self):
+ def test_exec_command(self):
"""
verify that exec_command() does something reasonable.
"""
@@ -343,7 +339,7 @@ class TransportTest(unittest.TestCase):
self.assertEqual("This is on stderr.\n", f.readline())
self.assertEqual("", f.readline())
- def test_6a_channel_can_be_used_as_context_manager(self):
+ def testa_channel_can_be_used_as_context_manager(self):
"""
verify that exec_command() does something reasonable.
"""
@@ -359,7 +355,7 @@ class TransportTest(unittest.TestCase):
self.assertEqual("Hello there.\n", f.readline())
self.assertEqual("", f.readline())
- def test_7_invoke_shell(self):
+ def test_invoke_shell(self):
"""
verify that invoke_shell() does something reasonable.
"""
@@ -373,18 +369,18 @@ class TransportTest(unittest.TestCase):
chan.close()
self.assertEqual("", f.readline())
- def test_8_channel_exception(self):
+ def test_channel_exception(self):
"""
verify that ChannelException is thrown for a bad open-channel request.
"""
self.setup_test_server()
try:
- chan = self.tc.open_channel("bogus")
+ self.tc.open_channel("bogus")
self.fail("expected exception")
except ChannelException as e:
self.assertTrue(e.code == OPEN_FAILED_ADMINISTRATIVELY_PROHIBITED)
- def test_9_exit_status(self):
+ def test_exit_status(self):
"""
verify that get_exit_status() works.
"""
@@ -413,7 +409,7 @@ class TransportTest(unittest.TestCase):
self.assertEqual(23, chan.recv_exit_status())
chan.close()
- def test_A_select(self):
+ def test_select(self):
"""
verify that select() on a channel works.
"""
@@ -468,7 +464,7 @@ class TransportTest(unittest.TestCase):
# ...and now is closed.
self.assertEqual(True, p._closed)
- def test_B_renegotiate(self):
+ def test_renegotiate(self):
"""
verify that a transport can correctly renegotiate mid-stream.
"""
@@ -492,7 +488,7 @@ class TransportTest(unittest.TestCase):
schan.close()
- def test_C_compression(self):
+ def test_compression(self):
"""
verify that zlib compression is basically working.
"""
@@ -510,14 +506,15 @@ class TransportTest(unittest.TestCase):
bytes2 = self.tc.packetizer._Packetizer__sent_bytes
block_size = self.tc._cipher_info[self.tc.local_cipher]["block-size"]
mac_size = self.tc._mac_info[self.tc.local_mac]["size"]
- # tests show this is actually compressed to *52 bytes*! including packet overhead! nice!! :)
+ # tests show this is actually compressed to *52 bytes*! including
+ # packet overhead! nice!! :)
self.assertTrue(bytes2 - bytes < 1024)
self.assertEqual(16 + block_size + mac_size, bytes2 - bytes)
chan.close()
schan.close()
- def test_D_x11(self):
+ def test_x11(self):
"""
verify that an x11 port can be requested and opened.
"""
@@ -555,7 +552,7 @@ class TransportTest(unittest.TestCase):
chan.close()
schan.close()
- def test_E_reverse_port_forwarding(self):
+ def test_reverse_port_forwarding(self):
"""
verify that a client can ask the server to open a reverse port for
forwarding.
@@ -563,7 +560,7 @@ class TransportTest(unittest.TestCase):
self.setup_test_server()
chan = self.tc.open_session()
chan.exec_command("yes")
- schan = self.ts.accept(1.0)
+ self.ts.accept(1.0)
requested = []
@@ -594,7 +591,7 @@ class TransportTest(unittest.TestCase):
self.tc.cancel_port_forward("127.0.0.1", port)
self.assertTrue(self.server._listen is None)
- def test_F_port_forwarding(self):
+ def test_port_forwarding(self):
"""
verify that a client can forward new connections from a locally-
forwarded port.
@@ -602,7 +599,7 @@ class TransportTest(unittest.TestCase):
self.setup_test_server()
chan = self.tc.open_session()
chan.exec_command("yes")
- schan = self.ts.accept(1.0)
+ self.ts.accept(1.0)
# open a port on the "server" that the client will ask to forward to.
greeting_server = socket.socket()
@@ -626,7 +623,7 @@ class TransportTest(unittest.TestCase):
self.assertEqual(b"Hello!\n", cs.recv(7))
cs.close()
- def test_G_stderr_select(self):
+ def test_stderr_select(self):
"""
verify that select() on a channel works even if only stderr is
receiving data.
@@ -665,7 +662,7 @@ class TransportTest(unittest.TestCase):
schan.close()
chan.close()
- def test_H_send_ready(self):
+ def test_send_ready(self):
"""
verify that send_ready() indicates when a send would not block.
"""
@@ -689,9 +686,10 @@ class TransportTest(unittest.TestCase):
chan.close()
self.assertEqual(chan.send_ready(), True)
- def test_I_rekey_deadlock(self):
+ def test_rekey_deadlock(self):
"""
- Regression test for deadlock when in-transit messages are received after MSG_KEXINIT is sent
+ Regression test for deadlock when in-transit messages are received
+ after MSG_KEXINIT is sent
Note: When this test fails, it may leak threads.
"""
@@ -714,12 +712,15 @@ class TransportTest(unittest.TestCase):
# MSG_KEXINIT to the remote host.
#
# On the remote host (using any SSH implementation):
- # 5. The MSG_CHANNEL_DATA is received, and MSG_CHANNEL_WINDOW_ADJUST is sent.
- # 6. The MSG_KEXINIT is received, and a corresponding MSG_KEXINIT is sent.
+ # 5. The MSG_CHANNEL_DATA is received, and MSG_CHANNEL_WINDOW_ADJUST
+ # is sent.
+ # 6. The MSG_KEXINIT is received, and a corresponding MSG_KEXINIT is
+ # sent.
#
# In the main thread:
# 7. The user's program calls Channel.send().
- # 8. Channel.send acquires Channel.lock, then calls Transport._send_user_message().
+ # 8. Channel.send acquires Channel.lock, then calls
+ # Transport._send_user_message().
# 9. Transport._send_user_message waits for Transport.clear_to_send
# to be set (i.e., it waits for re-keying to complete).
# Channel.lock is still held.
@@ -854,7 +855,7 @@ class TransportTest(unittest.TestCase):
schan.close()
chan.close()
- def test_J_sanitze_packet_size(self):
+ def test_sanitze_packet_size(self):
"""
verify that we conform to the rfc of packet and window sizes.
"""
@@ -865,7 +866,7 @@ class TransportTest(unittest.TestCase):
]:
self.assertEqual(self.tc._sanitize_packet_size(val), correct)
- def test_K_sanitze_window_size(self):
+ def test_sanitze_window_size(self):
"""
verify that we conform to the rfc of packet and window sizes.
"""
@@ -877,7 +878,7 @@ class TransportTest(unittest.TestCase):
self.assertEqual(self.tc._sanitize_window_size(val), correct)
@slow
- def test_L_handshake_timeout(self):
+ def test_handshake_timeout(self):
"""
verify that we can get a hanshake timeout.
"""
@@ -914,7 +915,7 @@ class TransportTest(unittest.TestCase):
password="pygmalion",
)
- def test_M_select_after_close(self):
+ def test_select_after_close(self):
"""
verify that select works when a channel is already closed.
"""
@@ -969,11 +970,11 @@ class TransportTest(unittest.TestCase):
# send() accepts buffer instances
sent = 0
while sent < len(data):
- sent += chan.send(buffer(data, sent, 8))
+ sent += chan.send(buffer(data, sent, 8)) # noqa
self.assertEqual(sfile.read(len(data)), data)
# sendall() accepts a buffer instance
- chan.sendall(buffer(data))
+ chan.sendall(buffer(data)) # noqa
self.assertEqual(sfile.read(len(data)), data)
@needs_builtin("memoryview")
diff --git a/tests/test_util.py b/tests/test_util.py
index 705baa14..465e75b8 100644
--- a/tests/test_util.py
+++ b/tests/test_util.py
@@ -26,9 +26,11 @@ import os
from hashlib import sha1
import unittest
+import paramiko
import paramiko.util
+from paramiko import SSHConfig
from paramiko.util import lookup_ssh_host_config as host_config, safe_string
-from paramiko.py3compat import StringIO, byte_ord, b
+from paramiko.py3compat import StringIO, byte_ord
# Note some lines in this configuration have trailing spaces on purpose
@@ -62,16 +64,12 @@ BGQ3GQ/Fc7SX6gkpXkwcZryoi4kNFhHu5LvHcZPdxXV1D+uTMfGS1eyd2Yz/DoNWXNAl8TI0cAsW\
"""
-# for test 1:
-from paramiko import *
-
-
class UtilTest(unittest.TestCase):
def test_import(self):
"""
verify that all the classes can be imported from paramiko.
"""
- symbols = list(globals().keys())
+ symbols = paramiko.__all__
self.assertTrue("Transport" in symbols)
self.assertTrue("SSHClient" in symbols)
self.assertTrue("MissingHostKeyPolicy" in symbols)
@@ -172,7 +170,7 @@ class UtilTest(unittest.TestCase):
hex = "".join(["%02x" % byte_ord(c) for c in x])
self.assertEqual(
hex,
- "9110e2f6793b69363e58173e9436b13a5a4b339005741d5c680e505f57d871347b4239f14fb5c46e857d5e100424873ba849ac699cea98d729e57b3e84378e8b",
+ "9110e2f6793b69363e58173e9436b13a5a4b339005741d5c680e505f57d871347b4239f14fb5c46e857d5e100424873ba849ac699cea98d729e57b3e84378e8b", # noqa
)
def test_host_keys(self):
@@ -452,9 +450,7 @@ Host param4 "p a r" "p" "par" para
f = StringIO(test_config_file)
config = paramiko.util.parse_ssh_config(f)
for host, values in res.items():
- self.assertEquals(
- paramiko.util.lookup_ssh_host_config(host, config), values
- )
+ assert paramiko.util.lookup_ssh_host_config(host, config) == values
def test_quoted_params_in_config(self):
test_config_file = """\
@@ -485,9 +481,7 @@ Host param3 parara
f = StringIO(test_config_file)
config = paramiko.util.parse_ssh_config(f)
for host, values in res.items():
- self.assertEquals(
- paramiko.util.lookup_ssh_host_config(host, config), values
- )
+ assert paramiko.util.lookup_ssh_host_config(host, config) == values
def test_quoted_host_in_config(self):
conf = SSHConfig()
@@ -506,7 +500,7 @@ Host param3 parara
}
incorrect_data = ['param"', '"param', 'param "pam', 'param "pam" "p a']
for host, values in correct_data.items():
- self.assertEquals(conf._get_hosts(host), values)
+ assert conf._get_hosts(host) == values
for host in incorrect_data:
self.assertRaises(Exception, conf._get_hosts, host)