r47046 - merge forward

hawkowl-TA+aISz0psMTMxyoc4vAAJOcrHinNvQL0E9HWUfgJXw@public.gmane.org Mon, 21 Mar 2016 21:12:09 -0600 (MDT)
Newsgroups gmane.comp.python.twisted.commits
Message-ID <[email protected]>
Author: hawkowl
Date: Mon Mar 21 21:12:04 2016
New Revision: 47046

Modified:
   branches/conch-transport-py3-8232-2/twisted/conch/interfaces.py
   branches/conch-transport-py3-8232-2/twisted/conch/ssh/_kex.py
   branches/conch-transport-py3-8232-2/twisted/conch/ssh/address.py
   branches/conch-transport-py3-8232-2/twisted/conch/ssh/connection.py
   branches/conch-transport-py3-8232-2/twisted/conch/ssh/factory.py
   branches/conch-transport-py3-8232-2/twisted/conch/ssh/service.py
   branches/conch-transport-py3-8232-2/twisted/conch/ssh/transport.py
   branches/conch-transport-py3-8232-2/twisted/conch/ssh/userauth.py
   branches/conch-transport-py3-8232-2/twisted/conch/test/test_transport.py
   branches/conch-transport-py3-8232-2/twisted/conch/test/test_userauth.py
   branches/conch-transport-py3-8232-2/twisted/python/dist3.py

Log:
merge forward

Modified: branches/conch-transport-py3-8232-2/twisted/conch/interfaces.py
==============================================================================
--- branches/conch-transport-py3-8232-2/twisted/conch/interfaces.py	(original)
+++ branches/conch-transport-py3-8232-2/twisted/conch/interfaces.py	Mon Mar 21 21:12:04 2016
@@ -5,8 +5,11 @@
 This module contains interfaces defined for the L{twisted.conch} package.
 """
 
+from __future__ import absolute_import, division
+
 from zope.interface import Interface, Attribute
 
+
 class IConchUser(Interface):
     """
     A user who has been authenticated to Cred through Conch.  This is
@@ -54,6 +57,8 @@
         The method is called with arguments of windowSize, maxPacket, data.
         """
 
+
+
 class ISession(Interface):
 
     def getPty(term, windowSize, modes):
@@ -94,6 +99,7 @@
         """
 
 
+
 class ISFTPServer(Interface):
     """
     SFTP subsystem for server-side communication.
@@ -404,5 +410,3 @@
         @param attrs: a dictionary in the same format as the attrs argument to
         L{openFile}.
         """
-
-

Modified: branches/conch-transport-py3-8232-2/twisted/conch/ssh/_kex.py
==============================================================================
--- branches/conch-transport-py3-8232-2/twisted/conch/ssh/_kex.py	(original)
+++ branches/conch-transport-py3-8232-2/twisted/conch/ssh/_kex.py	Mon Mar 21 21:12:04 2016
@@ -6,11 +6,14 @@
 SSH key exchange handling.
 """
 
+from __future__ import absolute_import, division
+
 from hashlib import sha1, sha256
 
 from zope.interface import Attribute, implementer, Interface
 
 from twisted.conch import error
+from twisted.python.compat import long
 
 
 class _IKexAlgorithm(Interface):
@@ -95,8 +98,8 @@
         '44236841971802161585193689478337958649255415021805654859805036464405'
         '48199239100050792877003355816639229553136239076508735759914822574862'
         '57500742530207744771258955095793777842444242661733472762929938766870'
-        '9205606050270810842907692932019128194467627007L')
-    generator = 2L
+        '9205606050270810842907692932019128194467627007')
+    generator = long(2)
 
 
 
@@ -119,17 +122,17 @@
         '00977202194168647225871031411336429319536193471636533209717077448227'
         '98858856536920864529663607725026895550592836275112117409697299806841'
         '05543595848665832916421362182310789909994486524682624169720359118525'
-        '07045361090559L')
-    generator = 2L
+        '07045361090559')
+    generator = long(2)
 
 
 
 _kexAlgorithms = {
-    "diffie-hellman-group-exchange-sha256": _DHGroupExchangeSHA256(),
-    "diffie-hellman-group-exchange-sha1": _DHGroupExchangeSHA1(),
-    "diffie-hellman-group1-sha1": _DHGroup1SHA1(),
-    "diffie-hellman-group14-sha1": _DHGroup14SHA1(),
-    }
+    b"diffie-hellman-group-exchange-sha256": _DHGroupExchangeSHA256(),
+    b"diffie-hellman-group-exchange-sha1": _DHGroupExchangeSHA1(),
+    b"diffie-hellman-group1-sha1": _DHGroup1SHA1(),
+    b"diffie-hellman-group14-sha1": _DHGroup14SHA1(),
+}
 
 
 

Modified: branches/conch-transport-py3-8232-2/twisted/conch/ssh/address.py
==============================================================================
--- branches/conch-transport-py3-8232-2/twisted/conch/ssh/address.py	(original)
+++ branches/conch-transport-py3-8232-2/twisted/conch/ssh/address.py	Mon Mar 21 21:12:04 2016
@@ -18,7 +18,7 @@
 
 
 @implementer(IAddress)
-class SSHTransportAddress(object, util.FancyEqMixin):
+class SSHTransportAddress(util.FancyEqMixin, object):
     """
     Object representing an SSH Transport endpoint.
 
@@ -43,4 +43,3 @@
 
     def __hash__(self):
         return hash(('SSH', self.address))
-

Modified: branches/conch-transport-py3-8232-2/twisted/conch/ssh/connection.py
==============================================================================
--- branches/conch-transport-py3-8232-2/twisted/conch/ssh/connection.py	(original)
+++ branches/conch-transport-py3-8232-2/twisted/conch/ssh/connection.py	Mon Mar 21 21:12:04 2016
@@ -143,7 +143,7 @@
                     channel.localWindowSize,
                     channel.localMaxPacket)+channel.specificData)
             log.callWithLogger(channel, channel.channelOpen, packet)
-        except Exception, e:
+        except Exception as e:
             log.err(e, 'channel open failed')
             if isinstance(e, error.ConchError):
                 textualInfo, reason = e.args
@@ -630,7 +630,7 @@
         messages[value] = name # doesn't handle doubles
 
 import string
-alphanums = string.letters + string.digits
+alphanums = string.ascii_letters + string.digits
 TRANSLATE_TABLE = ''.join([chr(i) in alphanums and chr(i) or '_'
     for i in range(256)])
 SSHConnection.protocolMessages = messages

Modified: branches/conch-transport-py3-8232-2/twisted/conch/ssh/factory.py
==============================================================================
--- branches/conch-transport-py3-8232-2/twisted/conch/ssh/factory.py	(original)
+++ branches/conch-transport-py3-8232-2/twisted/conch/ssh/factory.py	Mon Mar 21 21:12:04 2016
@@ -8,12 +8,16 @@
 Maintainer: Paul Swartz
 """
 
+from __future__ import absolute_import, division
+
+from functools import cmp_to_key
+
 from twisted.internet import protocol
 from twisted.python import log
+from twisted.python.compat import cmp
 
 from twisted.conch import error
-from twisted.conch.ssh import _kex
-import transport, userauth, connection
+from twisted.conch.ssh import _kex, transport, userauth, connection
 
 import random
 
@@ -103,8 +107,8 @@
         @type bits: C{int}
         @rtype:     C{tuple}
         """
-        primesKeys = self.primes.keys()
-        primesKeys.sort(lambda x, y: cmp(abs(x - bits), abs(y - bits)))
+        primesKeys = list(self.primes.keys())
+        primesKeys.sort(key=cmp_to_key(lambda x, y: cmp(abs(x - bits),  abs(y - bits))))
         realBits = primesKeys[0]
         return random.choice(self.primes[realBits])
 

Modified: branches/conch-transport-py3-8232-2/twisted/conch/ssh/service.py
==============================================================================
--- branches/conch-transport-py3-8232-2/twisted/conch/ssh/service.py	(original)
+++ branches/conch-transport-py3-8232-2/twisted/conch/ssh/service.py	Mon Mar 21 21:12:04 2016
@@ -8,9 +8,11 @@
 Maintainer: Paul Swartz
 """
 
+from __future__ import absolute_import, division
 
 from twisted.python import log
 
+
 class SSHService(log.Logger):
     name = None # this is the ssh name for the service
     protocolMessages = {} # these map #'s -> protocol names
@@ -45,4 +47,3 @@
         log.msg("couldn't handle %r" % messageNum)
         log.msg(repr(packet))
         self.transport.sendUnimplemented()
-

Modified: branches/conch-transport-py3-8232-2/twisted/conch/ssh/transport.py
==============================================================================
--- branches/conch-transport-py3-8232-2/twisted/conch/ssh/transport.py	(original)
+++ branches/conch-transport-py3-8232-2/twisted/conch/ssh/transport.py	Mon Mar 21 21:12:04 2016
@@ -25,7 +25,9 @@
 
 from twisted.internet import protocol, defer
 from twisted.python import log, randbytes
+from twisted.python.compat import items, _bytesChr as chr, networkString, iterbytes, nativeString
 
+from twisted.conch.error import ConchError
 from twisted.conch.ssh import address, keys, _kex
 from twisted.conch.ssh.common import (
     NS, getNS, MP, getMP, _MPpow, ffs, int_from_bytes
@@ -642,8 +644,9 @@
             del self.first
         packetLen, paddingLen = struct.unpack('!LB', first[:5])
         if packetLen > 1048576: # 1024 ** 2
-            self.sendDisconnect(DISCONNECT_PROTOCOL_ERROR,
-                                b'bad packet length %s' % (packetLen,))
+            self.sendDisconnect(
+                DISCONNECT_PROTOCOL_ERROR,
+                networkString('bad packet length %s' % (packetLen,)))
             return
         if len(self.buf) < packetLen + 4 + ms:
             # Not enough data for a packet
@@ -652,8 +655,9 @@
         if (packetLen + 4) % bs != 0:
             self.sendDisconnect(
                 DISCONNECT_PROTOCOL_ERROR,
-                b'bad packet mod (%i%%%i == %i)' % (packetLen + 4, bs,
-                                                   (packetLen + 4) % bs))
+                networkString(
+                    'bad packet mod (%i%%%i == %i)' % (packetLen + 4, bs,
+                    (packetLen + 4) % bs)))
             return
         encData, self.buf = self.buf[:4 + packetLen], self.buf[4 + packetLen:]
         packet = first + self.currentEncryptions.decrypt(encData[bs:])
@@ -720,7 +724,7 @@
                     self.buf = b'\n'.join(lines[i + 1:])
         packet = self.getPacket()
         while packet:
-            messageNum = ord(packet[0])
+            messageNum = ord(packet[0:1])
             self.dispatchMessage(messageNum, packet[1:])
             packet = self.getPacket()
 
@@ -789,12 +793,13 @@
     def kexAlg(self, value):
         """
         Set the key exchange algorithm name.
-
-        @raises ConchError: if the key exchange algorithm is not found.
         """
-        # Check for supportedness.
-        _kex.getKex(value)
-        self._kexAlg = value
+        try:
+            # Check for supportedness.
+            _kex.getKex(value)
+            self._kexAlg = value
+        except ConchError:
+            self._kexAlg = None
 
     # Client-initiated rekeying looks like this:
     #
@@ -839,6 +844,7 @@
         algorithms, and unhandled data, or C{None} if something went wrong.
         """
         self.otherKexInitPayload = chr(MSG_KEXINIT) + packet
+
         # This is useless to us:
         # cookie = packet[: 16]
         k = getNS(packet[16:], 10)
@@ -848,23 +854,30 @@
         # These are the server directions
         outs = [encSC, macSC, compSC]
         ins = [encCS, macSC, compCS]
+
         if self.isClient:
             outs, ins = ins, outs # Switch directions
+
         server = (self.supportedKeyExchanges, self.supportedPublicKeys,
-                self.supportedCiphers, self.supportedCiphers,
-                self.supportedMACs, self.supportedMACs,
-                self.supportedCompressions, self.supportedCompressions)
+                  self.supportedCiphers, self.supportedCiphers,
+                  self.supportedMACs, self.supportedMACs,
+                  self.supportedCompressions, self.supportedCompressions)
+
         client = (kexAlgs, keyAlgs, outs[0], ins[0], outs[1], ins[1],
                 outs[2], ins[2])
+
         if self.isClient:
             server, client = client, server
+
         self.kexAlg = ffs(client[0], server[0])
         self.keyAlg = ffs(client[1], server[1])
+
         self.nextEncryptions = SSHCiphers(
             ffs(client[2], server[2]),
             ffs(client[3], server[3]),
             ffs(client[4], server[4]),
             ffs(client[5], server[5]))
+
         self.outgoingCompressionType = ffs(client[6], server[6])
         self.incomingCompressionType = ffs(client[7], server[7])
         if None in (self.kexAlg, self.keyAlg, self.outgoingCompressionType,
@@ -1224,7 +1237,7 @@
             return
         else:
             kexAlgs, keyAlgs, rest = retval
-        if ord(rest[0]): # Flag first_kex_packet_follows?
+        if ord(rest[0:1]): # Flag first_kex_packet_follows?
             if (kexAlgs[0] != self.supportedKeyExchanges[0] or
                 keyAlgs[0] != self.supportedPublicKeys[0]):
                 self.ignoreNextPacket = True # Guess was wrong
@@ -1404,7 +1417,7 @@
         @param packet: The message data.
         """
         service, rest = getNS(packet)
-        cls = self.factory.getService(self, service)
+        cls = self.factory.getService(self, nativeString(service))
         if not cls:
             self.sendDisconnect(DISCONNECT_SERVICE_NOT_AVAILABLE,
                                 b"don't have service " + service)
@@ -1527,7 +1540,7 @@
         f, packet = getMP(packet)
         signature, packet = getNS(packet)
         fingerprint = b':'.join([binascii.hexlify(ch) for ch in
-                                 md5(pubKey).digest()])
+                                 iterbytes(md5(pubKey).digest())])
         d = self.verifyHostKey(pubKey, fingerprint)
         d.addCallback(self._continueKEXDH_REPLY, pubKey, f, signature)
         d.addErrback(
@@ -1611,8 +1624,8 @@
         pubKey, packet = getNS(packet)
         f, packet = getMP(packet)
         signature, packet = getNS(packet)
-        fingerprint = ':'.join(map(lambda c: '%02x' % (ord(c),),
-            md5(pubKey).digest()))
+        fingerprint = networkString(':'.join(map(lambda c: '%02x' % (ord(c),),
+                                                 iterbytes(md5(pubKey).digest()))))
         d = self.verifyHostKey(pubKey, fingerprint)
         d.addCallback(self._continueGEX_REPLY, pubKey, f, signature)
         d.addErrback(
@@ -1719,7 +1732,7 @@
         @type instance: subclass of L{twisted.conch.ssh.service.SSHService}
         @param instance: The service to run.
         """
-        self.sendPacket(MSG_SERVICE_REQUEST, NS(instance.name))
+        self.sendPacket(MSG_SERVICE_REQUEST, NS(networkString(instance.name)))
         self.instance = instance
 
     # Client methods
@@ -1846,7 +1859,7 @@
 
 
 messages = {}
-for name, value in globals().items():
+for name, value in items(globals()):
     # Avoid legacy messages which overlap with never ones
     if name.startswith('MSG_') and not name.startswith('MSG_KEXDH_'):
         messages[value] = name

Modified: branches/conch-transport-py3-8232-2/twisted/conch/ssh/userauth.py
==============================================================================
--- branches/conch-transport-py3-8232-2/twisted/conch/ssh/userauth.py	(original)
+++ branches/conch-transport-py3-8232-2/twisted/conch/ssh/userauth.py	Mon Mar 21 21:12:04 2016
@@ -20,6 +20,8 @@
 from twisted.cred.error import UnauthorizedLogin
 from twisted.internet import defer, reactor
 from twisted.python import failure, log
+from twisted.python.compat import (items, nativeString, networkString,
+                                   _bytesChr as chr)
 
 
 
@@ -147,7 +149,7 @@
             return defer.fail(
                     error.ConchError('unsupported authentication, failing'))
         kind = kind.replace(b'-', b'_')
-        f = getattr(self, 'auth_%s' % (kind,), None)
+        f = getattr(self, 'auth_%s' % (nativeString(kind),), None)
         if f:
             ret = f(data)
             if not ret:
@@ -174,7 +176,7 @@
         if user != self.user or nextService != self.nextService:
             self.authenticatedWith = [] # clear auth state
         self.user = user
-        self.nextService = nextService
+        self.nextService = nativeString(nextService)
         self.method = method
         d = self.tryAuth(method, user, rest)
         if not d:
@@ -187,12 +189,13 @@
         return d
 
 
-    def _cbFinishedAuth(self, (interface, avatar, logout)):
+    def _cbFinishedAuth(self, args):
         """
         The callback when user has successfully been authenticated.  For a
         description of the arguments, see L{twisted.cred.portal.Portal.login}.
         We start the service requested by the user.
         """
+        (interface, avatar, logout) = args
         self.transport.avatar = avatar
         self.transport.logoutFunction = logout
         service = self.transport.factory.getService(self.transport,
@@ -259,14 +262,15 @@
 
         Create a SSHPublicKey credential and verify it using our portal.
         """
-        hasSig = ord(packet[0])
+        hasSig = ord(packet[0:1])
         algName, blob, rest = getNS(packet[1:], 2)
         pubKey = keys.Key.fromString(blob)
         signature = hasSig and getNS(rest)[0] or None
         if hasSig:
             b = (NS(self.transport.sessionID) + chr(MSG_USERAUTH_REQUEST) +
-                NS(self.user) + NS(self.nextService) + NS(b'publickey') +
-                chr(hasSig) +  NS(pubKey.sshType()) + NS(blob))
+                 NS(self.user) + NS(networkString(self.nextService)) +
+                 NS(b'publickey') + chr(hasSig) + NS(pubKey.sshType()) +
+                 NS(blob))
             c = credentials.SSHPrivateKey(self.user, algName, blob, b,
                     signature)
             return self.portal.login(c, None, interfaces.IConchUser)
@@ -366,7 +370,7 @@
         """
         self.lastAuth = kind
         self.transport.sendPacket(MSG_USERAUTH_REQUEST, NS(self.user) +
-                NS(self.instance.name) + NS(kind) + extraData)
+                NS(networkString(self.instance.name)) + NS(kind) + extraData)
 
 
     def tryAuth(self, kind):
@@ -378,7 +382,7 @@
         """
         kind = kind.replace(b'-', b'_')
         log.msg('trying to auth with %s' % (kind,))
-        f = getattr(self,'auth_%s' % (kind,), None)
+        f = getattr(self, 'auth_%s' % (nativeString(kind),), None)
         if f:
             return f()
 
@@ -473,7 +477,7 @@
         in order to handle this request.
         """
         func = getattr(self, 'ssh_USERAUTH_PK_OK_%s' %
-                       self.lastAuth.replace(b'-', b'_'), None)
+                       nativeString(self.lastAuth.replace(b'-', b'_')), None)
         if func is not None:
             return func(packet)
         else:
@@ -486,9 +490,10 @@
         signature and try to authenticate with it.
         """
         publicKey = self.lastPublicKey
-        b = (NS(self.transport.sessionID) + chr(MSG_USERAUTH_REQUEST) +
-             NS(self.user) + NS(self.instance.name) + NS(b'publickey') +
-             b'\x01' + NS(publicKey.sshType()) + NS(publicKey.blob()))
+        b = b''.join([NS(self.transport.sessionID), chr(MSG_USERAUTH_REQUEST),
+                      NS(self.user), NS(networkString(self.instance.name)),
+                      NS(b'publickey'), b'\x01', NS(publicKey.sshType()),
+                      NS(publicKey.blob())])
         d  = self.signData(publicKey, b)
         if not d:
             self.askForAuth(b'none', b'')
@@ -519,12 +524,12 @@
         responses.
         """
         name, instruction, lang, data = getNS(packet, 3)
-        numPrompts = struct.unpack('!L', data[:4])[0]
+        numPrompts = struct.unpack('!L', data[:4])[0:1]
         data = data[4:]
         prompts = []
         for i in range(numPrompts):
             prompt, data = getNS(data)
-            echo = bool(ord(data[0]))
+            echo = bool(ord(data[0:1]))
             data = data[1:]
             prompts.append((prompt, echo))
         d = self.getGenericAnswers(name, instruction, prompts)
@@ -746,7 +751,7 @@
 MSG_USERAUTH_PK_OK            = 60
 
 messages = {}
-for k, v in locals().items():
+for k, v in items(locals()):
     if k[:4] == 'MSG_':
         messages[v] = k
 

Modified: branches/conch-transport-py3-8232-2/twisted/conch/test/test_transport.py
==============================================================================
--- branches/conch-transport-py3-8232-2/twisted/conch/test/test_transport.py	(original)
+++ branches/conch-transport-py3-8232-2/twisted/conch/test/test_transport.py	Mon Mar 21 21:12:04 2016
@@ -45,6 +45,7 @@
 from twisted.protocols import loopback
 from twisted.python import randbytes
 from twisted.python.randbytes import insecureRandom
+from twisted.python.compat import _bytesChr as chr, iterbytes
 from twisted.conch.ssh import address, service, common, _kex
 from twisted.test import proto_helpers
 
@@ -939,7 +940,7 @@
         self.transport.loseConnection = stubLoseConnection
         self.proto.loseConnection()
         self.assertEqual(self.packets[0][0], transport.MSG_DISCONNECT)
-        self.assertEqual(self.packets[0][1][3],
+        self.assertEqual(self.packets[0][1][3:4],
                          chr(transport.DISCONNECT_CONNECTION_LOST))
 
 
@@ -954,12 +955,12 @@
             def stubLoseConnection():
                 disconnected[0] = True
             self.transport.loseConnection = stubLoseConnection
-            for c in version + b'\r\n':
+            for c in iterbytes(version + b'\r\n'):
                 self.proto.dataReceived(c)
             self.assertTrue(disconnected[0])
             self.assertEqual(self.packets[0][0], transport.MSG_DISCONNECT)
             self.assertEqual(
-                self.packets[0][1][3],
+                self.packets[0][1][3:4],
                 chr(transport.DISCONNECT_PROTOCOL_VERSION_NOT_SUPPORTED))
         testBad(b'SSH-1.5-OpenSSH')
         testBad(b'SSH-3.0-Twisted')
@@ -975,7 +976,7 @@
         data = (b"""here's some stuff beforehand
 here's some other stuff
 """ + proto.ourVersionString + b"\r\n")
-        [proto.dataReceived(c) for c in data]
+        [proto.dataReceived(c) for c in iterbytes(data)]
         self.assertTrue(proto.gotVersion)
         self.assertEqual(proto.otherVersionString, proto.ourVersionString)
 
@@ -1027,7 +1028,7 @@
             self.assertEqual(self.proto.getPacket(), None)
             self.assertEqual(len(self.packets), 1)
             self.assertEqual(self.packets[0][0], transport.MSG_DISCONNECT)
-            self.assertEqual(self.packets[0][1][3], chr(error))
+            self.assertEqual(self.packets[0][1][3:4], chr(error))
 
         testBad(b'\xff' * 8) # big packet
         testBad(b'\x00\x00\x00\x05\x00BCDE') # length not modulo blocksize
@@ -1056,7 +1057,7 @@
         def checkUnimplemented(seqnum=seqnum):
             self.assertEqual(self.packets[0][0],
                              transport.MSG_UNIMPLEMENTED)
-            self.assertEqual(self.packets[0][1][3], chr(seqnum))
+            self.assertEqual(self.packets[0][1][3:4], chr(seqnum))
             self.proto.packets = []
             seqnum += 1
 
@@ -1148,7 +1149,7 @@
         if kind is None:
             kind = transport.DISCONNECT_PROTOCOL_ERROR
         self.assertEqual(self.packets[-1][0], transport.MSG_DISCONNECT)
-        self.assertEqual(self.packets[-1][1][3], chr(kind))
+        self.assertEqual(self.packets[-1][1][3:4], chr(kind))
 
 
     def connectModifiedProtocol(self, protoModification,
@@ -1281,7 +1282,6 @@
             b'\x00\x00\x12hmac-md5,hmac-sha1\x00\x00\x00\tnone,zlib\x00\x00'
             b'\x00\tnone,zlib\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
             b'\x00\x00\x99\x99\x99\x99')
-
         # Even if as server we prefer diffie-hellman-group-exchange-sha256 the
         # client preference is used.
         self.assertEqual(self.proto.kexAlg,
@@ -1438,7 +1438,7 @@
         self.assertEqual(self.proto.sessionID, b'CD')
         self.assertEqual(self.packets[-1], (transport.MSG_NEWKEYS, b''))
         newKeys = [self.proto._getKey(c, b'AB', b'EF')
-                   for c in b'ABCDEF']
+                   for c in iterbytes(b'ABCDEF')]
         self.assertEqual(
             self.proto.nextEncryptions.keys,
             (newKeys[1], newKeys[3], newKeys[0], newKeys[2], newKeys[5],
@@ -1756,17 +1756,6 @@
         self.assertKexInitResponseForDH(b'diffie-hellman-group1-sha1')
 
 
-    def test_KEXINIT_badKexAlg(self):
-        """
-        Test that the client raises a ConchError if it receives a
-        KEXINIT message but doesn't have a key exchange algorithm that we
-        understand.
-        """
-        self.proto.supportedKeyExchanges = [b'diffie-hellman-group2-sha1']
-        data = self.transport.value().replace(b'group1', b'group2')
-        self.assertRaises(ConchError, self.proto.dataReceived, data)
-
-
     def test_KEXDH_REPLY(self):
         """
         Test that the KEXDH_REPLY message verifies the server.
@@ -1810,7 +1799,8 @@
         self.simulateKeyExchange(b'AB', b'EF')
         self.assertEqual(self.proto.sessionID, b'CD')
         self.assertEqual(self.packets[-1], (transport.MSG_NEWKEYS, b''))
-        newKeys = [self.proto._getKey(c, b'AB', b'EF') for c in b'ABCDEF']
+        newKeys = [self.proto._getKey(c, b'AB', b'EF')
+                   for c in iterbytes(b'ABCDEF')]
         self.assertEqual(self.proto.nextEncryptions.keys,
                           (newKeys[0], newKeys[2], newKeys[1], newKeys[3],
                            newKeys[4], newKeys[5]))
@@ -2052,8 +2042,8 @@
         params = self.ciphers._getMAC(hmacName, secret)
 
         key = secret[:digestSize] + b'\x00' * blockPadSize
-        innerPad = b''.join(chr(ord(b) ^ 0x36) for b in key)
-        outerPad = b''.join(chr(ord(b) ^ 0x5c) for b in key)
+        innerPad = b''.join(chr(ord(b) ^ 0x36) for b in iterbytes(key))
+        outerPad = b''.join(chr(ord(b) ^ 0x5c) for b in iterbytes(key))
         self.assertEqual(
             (hashProcessor, innerPad, outerPad, digestSize), params)
         self.assertEqual(key, params.key)

Modified: branches/conch-transport-py3-8232-2/twisted/conch/test/test_userauth.py
==============================================================================
--- branches/conch-transport-py3-8232-2/twisted/conch/test/test_userauth.py	(original)
+++ branches/conch-transport-py3-8232-2/twisted/conch/test/test_userauth.py	Mon Mar 21 21:12:04 2016
@@ -20,6 +20,7 @@
 from twisted.internet import defer, task
 from twisted.protocols import loopback
 from twisted.python.reflect import requireModule
+from twisted.python.compat import _bytesChr as chr
 from twisted.trial import unittest
 
 if requireModule('cryptography') and requireModule('pyasn1'):

Modified: branches/conch-transport-py3-8232-2/twisted/python/dist3.py
==============================================================================
--- branches/conch-transport-py3-8232-2/twisted/python/dist3.py	(original)
+++ branches/conch-transport-py3-8232-2/twisted/python/dist3.py	Mon Mar 21 21:12:04 2016
@@ -47,11 +47,19 @@
     "twisted.conch.__init__",
     "twisted.conch.checkers",
     "twisted.conch.error",
+    "twisted.conch.interfaces",
+    "twisted.conch.ssh.service",
     "twisted.conch.ssh.__init__",
     "twisted.conch.ssh._cryptography_backports",
+    "twisted.conch.ssh._kex",
+    "twisted.conch.ssh.address",
     "twisted.conch.ssh.common",
+    "twisted.conch.ssh.connection",
+    "twisted.conch.ssh.factory",
     "twisted.conch.ssh.keys",
     "twisted.conch.ssh.sexpy",
+    "twisted.conch.ssh.transport",
+    "twisted.conch.ssh.userauth",
     "twisted.conch.telnet",
     "twisted.conch.test.__init__",
     "twisted.copyright",
@@ -260,7 +268,9 @@
     "twisted.application.test.test_service",
     "twisted.conch.test.test_checkers",
     "twisted.conch.test.test_keys",
+    "twisted.conch.test.test_transport",
     "twisted.conch.test.test_telnet",
+    "twisted.conch.test.test_userauth",
     "twisted.cred.test.test_cramauth",
     "twisted.cred.test.test_cred",
     "twisted.cred.test.test_digestauth",