'Run an async client and server, modifying each using the mod function
provided.  Returns a Deferred called back when both Protocols have
disconnected.
@type mod: C{func}
@rtype: C{defer.Deferred}'

def _runClientServer(self, mod):

    factory = MockFactory()
    server = transport.SSHServerTransport()
    server.factory = factory
    factory.startFactory()
    server.errors = []
    server.receiveError = (lambda code, desc: server.errors.append((code, desc)))
    client = transport.SSHClientTransport()
    client.verifyHostKey = (lambda x, y: defer.succeed(None))
    client.errors = []
    client.receiveError = (lambda code, desc: client.errors.append((code, desc)))
    client.connectionSecure = (lambda : client.loseConnection())
    server.supportedPublicKeys = list(server.factory.getPublicKeys().keys())
    server = mod(server)
    client = mod(client)
    def check(ignored, server, client):
        name = repr([server.supportedCiphers[0], server.supportedMACs[0], server.supportedKeyExchanges[0], server.supportedCompressions[0]])
        self.assertEqual(client.errors, [])
        self.assertEqual(server.errors, [(transport.DISCONNECT_CONNECTION_LOST, 'user    closed    connection')])
        if (server.supportedCiphers[0] == 'none'):
            self.assertFalse(server.isEncrypted(), name)
            self.assertFalse(client.isEncrypted(), name)
        else:
            self.assertTrue(server.isEncrypted(), name)
            self.assertTrue(client.isEncrypted(), name)
        if (server.supportedMACs[0] == 'none'):
            self.assertFalse(server.isVerified(), name)
            self.assertFalse(client.isVerified(), name)
        else:
            self.assertTrue(server.isVerified(), name)
            self.assertTrue(client.isVerified(), name)
    d = loopback.loopbackAsync(server, client)
    d.addCallback(check, server, client)
    return d
