| Index: third_party/twisted_8_1/twisted/conch/test/test_conch.py
 | 
| diff --git a/third_party/twisted_8_1/twisted/conch/test/test_conch.py b/third_party/twisted_8_1/twisted/conch/test/test_conch.py
 | 
| deleted file mode 100644
 | 
| index 308b1d941c8bb6a0feac2c76c950f8f03d2507c5..0000000000000000000000000000000000000000
 | 
| --- a/third_party/twisted_8_1/twisted/conch/test/test_conch.py
 | 
| +++ /dev/null
 | 
| @@ -1,594 +0,0 @@
 | 
| -# -*- test-case-name: twisted.conch.test.test_conch -*-
 | 
| -# Copyright (c) 2001-2008 Twisted Matrix Laboratories.
 | 
| -# See LICENSE for details.
 | 
| -
 | 
| -import os, sys
 | 
| -
 | 
| -try:
 | 
| -    import Crypto
 | 
| -except:
 | 
| -    Crypto = None
 | 
| -
 | 
| -from twisted.cred import portal
 | 
| -from twisted.internet import reactor, defer, protocol
 | 
| -from twisted.internet.error import ProcessExitedAlready
 | 
| -from twisted.python import log, runtime
 | 
| -from twisted.python.filepath import FilePath
 | 
| -from twisted.trial import unittest
 | 
| -from twisted.conch.error import ConchError
 | 
| -from twisted.conch.test.test_ssh import ConchTestRealm
 | 
| -from twisted.python.procutils import which
 | 
| -
 | 
| -from twisted.conch.test.keydata import publicRSA_openssh, privateRSA_openssh
 | 
| -from twisted.conch.test.keydata import publicDSA_openssh, privateDSA_openssh
 | 
| -
 | 
| -
 | 
| -
 | 
| -class Echo(protocol.Protocol):
 | 
| -    def connectionMade(self):
 | 
| -        log.msg('ECHO CONNECTION MADE')
 | 
| -
 | 
| -
 | 
| -    def connectionLost(self, reason):
 | 
| -        log.msg('ECHO CONNECTION DONE')
 | 
| -
 | 
| -
 | 
| -    def dataReceived(self, data):
 | 
| -        self.transport.write(data)
 | 
| -        if '\n' in data:
 | 
| -            self.transport.loseConnection()
 | 
| -
 | 
| -
 | 
| -
 | 
| -class EchoFactory(protocol.Factory):
 | 
| -    protocol = Echo
 | 
| -
 | 
| -
 | 
| -
 | 
| -class ConchTestOpenSSHProcess(protocol.ProcessProtocol):
 | 
| -    """
 | 
| -    Test protocol for launching an OpenSSH client process.
 | 
| -
 | 
| -    @ivar deferred: Set by whatever uses this object. Accessed using
 | 
| -    L{_getDeferred}, which destroys the value so the Deferred is not
 | 
| -    fired twice. Fires when the process is terminated.
 | 
| -    """
 | 
| -
 | 
| -    deferred = None
 | 
| -    buf = ''
 | 
| -
 | 
| -    def _getDeferred(self):
 | 
| -        d, self.deferred = self.deferred, None
 | 
| -        return d
 | 
| -
 | 
| -
 | 
| -    def outReceived(self, data):
 | 
| -        self.buf += data
 | 
| -
 | 
| -
 | 
| -    def processEnded(self, reason):
 | 
| -        """
 | 
| -        Called when the process has ended.
 | 
| -
 | 
| -        @param reason: a Failure giving the reason for the process' end.
 | 
| -        """
 | 
| -        if reason.value.exitCode != 0:
 | 
| -            self._getDeferred().errback(
 | 
| -                ConchError("exit code was not 0: %s" %
 | 
| -                                 reason.value.exitCode))
 | 
| -        else:
 | 
| -            buf = self.buf.replace('\r\n', '\n')
 | 
| -            self._getDeferred().callback(buf)
 | 
| -
 | 
| -
 | 
| -
 | 
| -class ConchTestForwardingProcess(protocol.ProcessProtocol):
 | 
| -    """
 | 
| -    Manages a third-party process which launches a server.
 | 
| -
 | 
| -    Uses L{ConchTestForwardingPort} to connect to the third-party server.
 | 
| -    Once L{ConchTestForwardingPort} has disconnected, kill the process and fire
 | 
| -    a Deferred with the data received by the L{ConchTestForwardingPort}.
 | 
| -
 | 
| -    @ivar deferred: Set by whatever uses this object. Accessed using
 | 
| -    L{_getDeferred}, which destroys the value so the Deferred is not
 | 
| -    fired twice. Fires when the process is terminated.
 | 
| -    """
 | 
| -
 | 
| -    deferred = None
 | 
| -
 | 
| -    def __init__(self, port, data):
 | 
| -        """
 | 
| -        @type port: C{int}
 | 
| -        @param port: The port on which the third-party server is listening.
 | 
| -        (it is assumed that the server is running on localhost).
 | 
| -
 | 
| -        @type data: C{str}
 | 
| -        @param data: This is sent to the third-party server. Must end with '\n'
 | 
| -        in order to trigger a disconnect.
 | 
| -        """
 | 
| -        self.port = port
 | 
| -        self.buffer = None
 | 
| -        self.data = data
 | 
| -
 | 
| -
 | 
| -    def _getDeferred(self):
 | 
| -        d, self.deferred = self.deferred, None
 | 
| -        return d
 | 
| -
 | 
| -
 | 
| -    def connectionMade(self):
 | 
| -        self._connect()
 | 
| -
 | 
| -
 | 
| -    def _connect(self):
 | 
| -        """
 | 
| -        Connect to the server, which is often a third-party process.
 | 
| -        Tries to reconnect if it fails because we have no way of determining
 | 
| -        exactly when the port becomes available for listening -- we can only
 | 
| -        know when the process starts.
 | 
| -        """
 | 
| -        cc = protocol.ClientCreator(reactor, ConchTestForwardingPort, self,
 | 
| -                                    self.data)
 | 
| -        d = cc.connectTCP('127.0.0.1', self.port)
 | 
| -        d.addErrback(self._ebConnect)
 | 
| -        return d
 | 
| -
 | 
| -
 | 
| -    def _ebConnect(self, f):
 | 
| -        reactor.callLater(1, self._connect)
 | 
| -
 | 
| -
 | 
| -    def forwardingPortDisconnected(self, buffer):
 | 
| -        """
 | 
| -        The network connection has died; save the buffer of output
 | 
| -        from the network and attempt to quit the process gracefully,
 | 
| -        and then (after the reactor has spun) send it a KILL signal.
 | 
| -        """
 | 
| -        self.buffer = buffer
 | 
| -        self.transport.write('\x03')
 | 
| -        self.transport.loseConnection()
 | 
| -        reactor.callLater(0, self._reallyDie)
 | 
| -
 | 
| -
 | 
| -    def _reallyDie(self):
 | 
| -        try:
 | 
| -            self.transport.signalProcess('KILL')
 | 
| -        except ProcessExitedAlready:
 | 
| -            pass
 | 
| -
 | 
| -
 | 
| -    def processEnded(self, reason):
 | 
| -        """
 | 
| -        Fire the Deferred at self.deferred with the data collected
 | 
| -        from the L{ConchTestForwardingPort} connection, if any.
 | 
| -        """
 | 
| -        self._getDeferred().callback(self.buffer)
 | 
| -
 | 
| -
 | 
| -
 | 
| -class ConchTestForwardingPort(protocol.Protocol):
 | 
| -    """
 | 
| -    Connects to server launched by a third-party process (managed by
 | 
| -    L{ConchTestForwardingProcess}) sends data, then reports whatever it
 | 
| -    received back to the L{ConchTestForwardingProcess} once the connection
 | 
| -    is ended.
 | 
| -    """
 | 
| -
 | 
| -
 | 
| -    def __init__(self, protocol, data):
 | 
| -        """
 | 
| -        @type protocol: L{ConchTestForwardingProcess}
 | 
| -        @param protocol: The L{ProcessProtocol} which made this connection.
 | 
| -
 | 
| -        @type data: str
 | 
| -        @param data: The data to be sent to the third-party server.
 | 
| -        """
 | 
| -        self.protocol = protocol
 | 
| -        self.data = data
 | 
| -
 | 
| -
 | 
| -    def connectionMade(self):
 | 
| -        self.buffer = ''
 | 
| -        self.transport.write(self.data)
 | 
| -
 | 
| -
 | 
| -    def dataReceived(self, data):
 | 
| -        self.buffer += data
 | 
| -
 | 
| -
 | 
| -    def connectionLost(self, reason):
 | 
| -        self.protocol.forwardingPortDisconnected(self.buffer)
 | 
| -
 | 
| -
 | 
| -
 | 
| -if Crypto:
 | 
| -    from twisted.conch.client import options, default, connect
 | 
| -    from twisted.conch.ssh import forwarding
 | 
| -    from twisted.conch.ssh import connection
 | 
| -
 | 
| -    from twisted.conch.test.test_ssh import ConchTestServerFactory
 | 
| -    from twisted.conch.test.test_ssh import ConchTestPublicKeyChecker
 | 
| -
 | 
| -
 | 
| -    class SSHTestConnectionForUnix(connection.SSHConnection):
 | 
| -        """
 | 
| -        @ivar stopDeferred: Deferred that will be fired when C{serviceStopped}
 | 
| -            is called.
 | 
| -        @type stopDeferred: C{defer.Deferred}
 | 
| -        """
 | 
| -
 | 
| -        def __init__(self, p, exe=None, cmds=None):
 | 
| -            connection.SSHConnection.__init__(self)
 | 
| -            if p:
 | 
| -                self.spawn = (p, exe, cmds)
 | 
| -            else:
 | 
| -                self.spawn = None
 | 
| -            self.connected = 0
 | 
| -            self.remoteForwards = {}
 | 
| -            self.stopDeferred = defer.Deferred()
 | 
| -
 | 
| -        def serviceStopped(self):
 | 
| -            self.stopDeferred.callback(None)
 | 
| -
 | 
| -        def serviceStarted(self):
 | 
| -            if self.spawn:
 | 
| -                env = os.environ.copy()
 | 
| -                env['PYTHONPATH'] = os.pathsep.join(sys.path)
 | 
| -                reactor.callLater(0,reactor.spawnProcess, env=env, *self.spawn)
 | 
| -            self.connected = 1
 | 
| -
 | 
| -        def requestRemoteForwarding(self, remotePort, hostport):
 | 
| -            data = forwarding.packGlobal_tcpip_forward(('0.0.0.0', remotePort))
 | 
| -            d = self.sendGlobalRequest('tcpip-forward', data,
 | 
| -                                       wantReply=1)
 | 
| -            log.msg('requesting remote forwarding %s:%s' %(remotePort, hostport))
 | 
| -            d.addCallback(self._cbRemoteForwarding, remotePort, hostport)
 | 
| -            d.addErrback(self._ebRemoteForwarding, remotePort, hostport)
 | 
| -
 | 
| -        def _cbRemoteForwarding(self, result, remotePort, hostport):
 | 
| -            log.msg('accepted remote forwarding %s:%s' % (remotePort, hostport))
 | 
| -            self.remoteForwards[remotePort] = hostport
 | 
| -            log.msg(repr(self.remoteForwards))
 | 
| -
 | 
| -        def _ebRemoteForwarding(self, f, remotePort, hostport):
 | 
| -            log.msg('remote forwarding %s:%s failed' % (remotePort, hostport))
 | 
| -            log.msg(f)
 | 
| -
 | 
| -        def cancelRemoteForwarding(self, remotePort):
 | 
| -            data = forwarding.packGlobal_tcpip_forward(('0.0.0.0', remotePort))
 | 
| -            self.sendGlobalRequest('cancel-tcpip-forward', data)
 | 
| -            log.msg('cancelling remote forwarding %s' % remotePort)
 | 
| -            try:
 | 
| -                del self.remoteForwards[remotePort]
 | 
| -            except:
 | 
| -                pass
 | 
| -            log.msg(repr(self.remoteForwards))
 | 
| -
 | 
| -        def channel_forwarded_tcpip(self, windowSize, maxPacket, data):
 | 
| -            log.msg('%s %s' % ('FTCP', repr(data)))
 | 
| -            remoteHP, origHP = forwarding.unpackOpen_forwarded_tcpip(data)
 | 
| -            log.msg(self.remoteForwards)
 | 
| -            log.msg(remoteHP)
 | 
| -            if self.remoteForwards.has_key(remoteHP[1]):
 | 
| -                connectHP = self.remoteForwards[remoteHP[1]]
 | 
| -                log.msg('connect forwarding %s' % (connectHP,))
 | 
| -                return forwarding.SSHConnectForwardingChannel(connectHP,
 | 
| -                                                remoteWindow = windowSize,
 | 
| -                                                remoteMaxPacket = maxPacket,
 | 
| -                                                conn = self)
 | 
| -            else:
 | 
| -                raise ConchError(connection.OPEN_CONNECT_FAILED, "don't know about that port")
 | 
| -
 | 
| -
 | 
| -
 | 
| -def _makeArgs(args, mod="conch"):
 | 
| -    start = [sys.executable, '-c'
 | 
| -"""
 | 
| -### Twisted Preamble
 | 
| -import sys, os
 | 
| -path = os.path.abspath(sys.argv[0])
 | 
| -while os.path.dirname(path) != path:
 | 
| -    if os.path.basename(path).startswith('Twisted'):
 | 
| -        sys.path.insert(0, path)
 | 
| -        break
 | 
| -    path = os.path.dirname(path)
 | 
| -
 | 
| -from twisted.conch.scripts.%s import run
 | 
| -run()""" % mod]
 | 
| -    return start + list(args)
 | 
| -
 | 
| -
 | 
| -
 | 
| -class ForwardingTestBase:
 | 
| -    """
 | 
| -    Template class for tests of the Conch server's ability to forward arbitrary
 | 
| -    protocols over SSH.
 | 
| -
 | 
| -    These tests are integration tests, not unit tests. They launch a Conch
 | 
| -    server, a custom TCP server (just an L{EchoProtocol}) and then call
 | 
| -    L{execute}.
 | 
| -
 | 
| -    L{execute} is implemented by subclasses of L{ForwardingTestBase}. It should
 | 
| -    cause an SSH client to connect to the Conch server, asking it to forward
 | 
| -    data to the custom TCP server.
 | 
| -    """
 | 
| -
 | 
| -    if not Crypto:
 | 
| -        skip = "can't run w/o PyCrypto"
 | 
| -
 | 
| -    def _createFiles(self):
 | 
| -        for f in ['rsa_test','rsa_test.pub','dsa_test','dsa_test.pub',
 | 
| -                  'kh_test']:
 | 
| -            if os.path.exists(f):
 | 
| -                os.remove(f)
 | 
| -        open('rsa_test','w').write(privateRSA_openssh)
 | 
| -        open('rsa_test.pub','w').write(publicRSA_openssh)
 | 
| -        open('dsa_test.pub','w').write(publicDSA_openssh)
 | 
| -        open('dsa_test','w').write(privateDSA_openssh)
 | 
| -        os.chmod('dsa_test', 33152)
 | 
| -        os.chmod('rsa_test', 33152)
 | 
| -        open('kh_test','w').write('127.0.0.1 '+publicRSA_openssh)
 | 
| -
 | 
| -
 | 
| -    def _getFreePort(self):
 | 
| -        f = EchoFactory()
 | 
| -        serv = reactor.listenTCP(0, f)
 | 
| -        port = serv.getHost().port
 | 
| -        serv.stopListening()
 | 
| -        return port
 | 
| -
 | 
| -
 | 
| -    def _makeConchFactory(self):
 | 
| -        """
 | 
| -        Make a L{ConchTestServerFactory}, which allows us to start a
 | 
| -        L{ConchTestServer} -- i.e. an actually listening conch.
 | 
| -        """
 | 
| -        realm = ConchTestRealm()
 | 
| -        p = portal.Portal(realm)
 | 
| -        p.registerChecker(ConchTestPublicKeyChecker())
 | 
| -        factory = ConchTestServerFactory()
 | 
| -        factory.portal = p
 | 
| -        return factory
 | 
| -
 | 
| -
 | 
| -    def setUp(self):
 | 
| -        self._createFiles()
 | 
| -        self.conchFactory = self._makeConchFactory()
 | 
| -        self.conchFactory.expectedLoseConnection = 1
 | 
| -        self.conchServer = reactor.listenTCP(0, self.conchFactory,
 | 
| -                                             interface="127.0.0.1")
 | 
| -        self.echoServer = reactor.listenTCP(0, EchoFactory())
 | 
| -        self.echoPort = self.echoServer.getHost().port
 | 
| -
 | 
| -
 | 
| -    def tearDown(self):
 | 
| -        try:
 | 
| -            self.conchFactory.proto.done = 1
 | 
| -        except AttributeError:
 | 
| -            pass
 | 
| -        else:
 | 
| -            self.conchFactory.proto.transport.loseConnection()
 | 
| -        return defer.gatherResults([
 | 
| -                defer.maybeDeferred(self.conchServer.stopListening),
 | 
| -                defer.maybeDeferred(self.echoServer.stopListening)])
 | 
| -
 | 
| -
 | 
| -    def test_exec(self):
 | 
| -        """
 | 
| -        Test that we can use whatever client to send the command "echo goodbye"
 | 
| -        to the Conch server. Make sure we receive "goodbye" back from the
 | 
| -        server.
 | 
| -        """
 | 
| -        d = self.execute('echo goodbye', ConchTestOpenSSHProcess())
 | 
| -        return d.addCallback(self.assertEquals, 'goodbye\n')
 | 
| -
 | 
| -
 | 
| -    def test_localToRemoteForwarding(self):
 | 
| -        """
 | 
| -        Test that we can use whatever client to forward a local port to a
 | 
| -        specified port on the server.
 | 
| -        """
 | 
| -        lport = self._getFreePort()
 | 
| -        process = ConchTestForwardingProcess(lport, 'test\n')
 | 
| -        d = self.execute('', process,
 | 
| -                         sshArgs='-N -L%i:127.0.0.1:%i'
 | 
| -                         % (lport, self.echoPort))
 | 
| -        d.addCallback(self.assertEqual, 'test\n')
 | 
| -        return d
 | 
| -
 | 
| -
 | 
| -    def test_remoteToLocalForwarding(self):
 | 
| -        """
 | 
| -        Test that we can use whatever client to forward a port from the server
 | 
| -        to a port locally.
 | 
| -        """
 | 
| -        localPort = self._getFreePort()
 | 
| -        process = ConchTestForwardingProcess(localPort, 'test\n')
 | 
| -        d = self.execute('', process,
 | 
| -                         sshArgs='-N -R %i:127.0.0.1:%i'
 | 
| -                         % (localPort, self.echoPort))
 | 
| -        d.addCallback(self.assertEqual, 'test\n')
 | 
| -        return d
 | 
| -
 | 
| -
 | 
| -
 | 
| -class OpenSSHClientTestCase(ForwardingTestBase, unittest.TestCase):
 | 
| -
 | 
| -    def execute(self, remoteCommand, process, sshArgs=''):
 | 
| -        """
 | 
| -        Connects to the SSH server started in L{ForwardingTestBase.setUp} by
 | 
| -        running the 'ssh' command line tool.
 | 
| -
 | 
| -        @type remoteCommand: str
 | 
| -        @param remoteCommand: The command (with arguments) to run on the
 | 
| -        remote end.
 | 
| -
 | 
| -        @type process: L{ConchTestOpenSSHProcess}
 | 
| -
 | 
| -        @type sshArgs: str
 | 
| -        @param sshArgs: Arguments to pass to the 'ssh' process.
 | 
| -
 | 
| -        @return: L{defer.Deferred}
 | 
| -        """
 | 
| -        process.deferred = defer.Deferred()
 | 
| -        cmdline = ('ssh -2 -l testuser -p %i '
 | 
| -                   '-oUserKnownHostsFile=kh_test '
 | 
| -                   '-oPasswordAuthentication=no '
 | 
| -                   # Always use the RSA key, since that's the one in kh_test.
 | 
| -                   '-oHostKeyAlgorithms=ssh-rsa '
 | 
| -                   '-a '
 | 
| -                   '-i dsa_test ') + sshArgs + \
 | 
| -                   ' 127.0.0.1 ' + remoteCommand
 | 
| -        port = self.conchServer.getHost().port
 | 
| -        cmds = (cmdline % port).split()
 | 
| -        reactor.spawnProcess(process, "ssh", cmds)
 | 
| -        return process.deferred
 | 
| -
 | 
| -
 | 
| -
 | 
| -class CmdLineClientTestCase(ForwardingTestBase, unittest.TestCase):
 | 
| -    def setUp(self):
 | 
| -        if runtime.platformType == 'win32':
 | 
| -            raise unittest.SkipTest("can't run cmdline client on win32")
 | 
| -        ForwardingTestBase.setUp(self)
 | 
| -
 | 
| -
 | 
| -    def execute(self, remoteCommand, process, sshArgs=''):
 | 
| -        """
 | 
| -        As for L{OpenSSHClientTestCase.execute}, except it runs the 'conch'
 | 
| -        command line tool, not 'ssh'.
 | 
| -        """
 | 
| -        process.deferred = defer.Deferred()
 | 
| -        port = self.conchServer.getHost().port
 | 
| -        cmd = ('-p %i -l testuser '
 | 
| -               '--known-hosts kh_test '
 | 
| -               '--user-authentications publickey '
 | 
| -               '--host-key-algorithms ssh-rsa '
 | 
| -               '-a -I '
 | 
| -               '-K direct '
 | 
| -               '-i dsa_test '
 | 
| -               '-v ') % port + sshArgs + \
 | 
| -               ' 127.0.0.1 ' + remoteCommand
 | 
| -        cmds = _makeArgs(cmd.split())
 | 
| -        log.msg(str(cmds))
 | 
| -        env = os.environ.copy()
 | 
| -        env['PYTHONPATH'] = os.pathsep.join(sys.path)
 | 
| -        reactor.spawnProcess(process, sys.executable, cmds, env=env)
 | 
| -        return process.deferred
 | 
| -
 | 
| -
 | 
| -
 | 
| -class _UnixFixHome(object):
 | 
| -    """
 | 
| -    Mixin class to fix the HOME environment variable to something usable.
 | 
| -
 | 
| -    @ivar home: FilePath pointing at C{homePath}.
 | 
| -    @type home: L{FilePath}
 | 
| -
 | 
| -    @ivar homePath: relative path to the directory used as HOME during the
 | 
| -        tests.
 | 
| -    @type homePath: C{str}
 | 
| -    """
 | 
| -
 | 
| -    def setUp(self):
 | 
| -        path = self.mktemp()
 | 
| -        self.home = FilePath(path)
 | 
| -        self.homePath = os.path.join(*self.home.segmentsFrom(FilePath(".")))
 | 
| -        if len(self.home.path) >= 70:
 | 
| -            # UNIX_MAX_PATH is 108, and the socket file is generally of length
 | 
| -            # 30, so we can't rely on mktemp...
 | 
| -            self.homePath = "_tmp"
 | 
| -            self.home = FilePath(self.homePath)
 | 
| -        self.home.makedirs()
 | 
| -        self.savedEnviron = os.environ.copy()
 | 
| -        os.environ["HOME"] = self.homePath
 | 
| -
 | 
| -
 | 
| -    def tearDown(self):
 | 
| -        os.environ.clear()
 | 
| -        os.environ.update(self.savedEnviron)
 | 
| -        self.home.remove()
 | 
| -
 | 
| -
 | 
| -
 | 
| -class UnixClientTestCase(_UnixFixHome, ForwardingTestBase, unittest.TestCase):
 | 
| -    def setUp(self):
 | 
| -        if runtime.platformType == 'win32':
 | 
| -            raise unittest.SkipTest("can't run cmdline client on win32")
 | 
| -        ForwardingTestBase.setUp(self)
 | 
| -        _UnixFixHome.setUp(self)
 | 
| -
 | 
| -
 | 
| -    def tearDown(self):
 | 
| -        d1 = ForwardingTestBase.tearDown(self)
 | 
| -        d2 = defer.maybeDeferred(self.conn.transport.transport.loseConnection)
 | 
| -        d3 = self.conn.stopDeferred
 | 
| -        def clean(ign):
 | 
| -            _UnixFixHome.tearDown(self)
 | 
| -            return ign
 | 
| -        return defer.gatherResults([d1, d2, d3]).addBoth(clean)
 | 
| -
 | 
| -
 | 
| -    def makeOptions(self):
 | 
| -        o = options.ConchOptions()
 | 
| -        def parseArgs(host, *args):
 | 
| -            o['host'] = host
 | 
| -        o.parseArgs = parseArgs
 | 
| -        return o
 | 
| -
 | 
| -
 | 
| -    def makeAuthClient(self, port, options):
 | 
| -        cmds = (('-p %i -l testuser '
 | 
| -                 '--known-hosts kh_test '
 | 
| -                 '--user-authentications publickey '
 | 
| -                 '--host-key-algorithms ssh-rsa '
 | 
| -                 '-a '
 | 
| -                 '-K direct '
 | 
| -                 '-i dsa_test '
 | 
| -                 '127.0.0.1') % port).split()
 | 
| -        options.parseOptions(cmds)
 | 
| -        return default.SSHUserAuthClient(options['user'], options, self.conn)
 | 
| -
 | 
| -
 | 
| -    def execute(self, remoteCommand, process, sshArgs=''):
 | 
| -        """
 | 
| -        Connect to the forwarding process using the 'unix' client found in
 | 
| -        L{twisted.conch.client.unix.connect}.  See
 | 
| -        L{OpenSSHClientTestCase.execute}.
 | 
| -        """
 | 
| -        process.deferred = defer.Deferred()
 | 
| -        port = self.conchServer.getHost().port
 | 
| -        cmd = ('-p %i -l testuser '
 | 
| -               '-K unix '
 | 
| -               '-v ') % port + sshArgs + \
 | 
| -               ' 127.0.0.1 ' + remoteCommand
 | 
| -        cmds = _makeArgs(cmd.split())
 | 
| -        options = self.makeOptions()
 | 
| -        self.conn = SSHTestConnectionForUnix(process, sys.executable, cmds)
 | 
| -        authClient = self.makeAuthClient(port, options)
 | 
| -        d = connect.connect(options['host'], port, options,
 | 
| -                            default.verifyHostKey, authClient)
 | 
| -        return d.addCallback(lambda x : process.deferred)
 | 
| -
 | 
| -
 | 
| -    def test_noHome(self):
 | 
| -        """
 | 
| -        When setting the HOME environment variable to a path that doesn't
 | 
| -        exist, L{connect.connect} should forward the failure, and the created
 | 
| -        process should fail with a L{ConchError}.
 | 
| -        """
 | 
| -        path = self.mktemp()
 | 
| -        # We override the HOME variable, and let tearDown restore the initial
 | 
| -        # value
 | 
| -        os.environ['HOME'] = path
 | 
| -        process = ConchTestOpenSSHProcess()
 | 
| -        d = self.execute('echo goodbye', process)
 | 
| -        def cb(ign):
 | 
| -            return self.assertFailure(process.deferred, ConchError)
 | 
| -        return self.assertFailure(d, OSError).addCallback(cb)
 | 
| -
 | 
| -
 | 
| -
 | 
| -if not which('ssh'):
 | 
| -    OpenSSHClientTestCase.skip = "no ssh command-line client available"
 | 
| 
 |