After much wrangling and a small miracle I have managed to write an object that fetches the output of three commands in the order given through an SSH connection. How come I cannot switch users? Some of the information I need can only be fetched through a root account and security is such that I cannot log in remotely from a root account but must switch once logged in from an account with less than root privileges. Here's the line that instaniates my SSH object (also repeated at the end of my code): myssh = SSH("my.host.com", "myusername", "mypasswd", ["id; su - root; myrootpasswd; id", "pwd", "ls -l"]) The last argument above is a list of three commands. Inside one command ";" separates the piece parts. I am not even able to su to accounts that don't require a password. ###========= CODE STARTS ================### from twisted.conch import error from twisted.conch.ssh import transport, connection, keys, userauth, channel, common from twisted.internet import defer, protocol, reactor import sys, getpass, os, string class ClientCommandTransport(transport.SSHClientTransport): def __init__(self, username, password, cmds, caller): self.username = username self.password = password self.cmds = cmds self.caller = caller def verifyHostKey(self, pubKey, fingerprint): # in a real app, you should verify that the fingerprint matches # the one you expected to get from this server return defer.succeed(True) def connectionSecure(self): self.requestService(PasswordAuth(self.username, self.password, ClientConnection(self.cmds, self.caller))) class PasswordAuth(userauth.SSHUserAuthClient): def __init__(self, user, password, connection): userauth.SSHUserAuthClient.__init__(self, user, connection) self.password = password def getPassword(self, prompt=None): return defer.succeed(self.password) class ClientConnection(connection.SSHConnection): def __init__(self, cmds, caller, *args, **kwargs): connection.SSHConnection.__init__(self) self.cmds = cmds self.caller = caller #====================== def serviceStarted(self): self.d = defer.Deferred() self.d.addCallback(self._cbFirst) self.d.addErrback(self._ebFirst) self.openChannel(CommandChannel(self.cmds[0], lastcmd=0, conn=self)) def _cbFirst(self, result): #print 'CALLBACK Result 1:', result self.caller.responses.append(result.rstrip()) self.d = defer.Deferred() self.d.addCallback(self._cbSecond) self.d.addErrback(self._ebSecond) self.openChannel(CommandChannel(self.cmds[1], lastcmd=0, conn=self)) def _ebFirst(self, f): self.caller.responses.append(None) print "Error 1" self.d = defer.Deferred() self.d.addCallback(self._cbSecond) self.d.addErrback(self._ebSecond) self.openChannel(CommandChannel(self.cmds[1], lastcmd=0, conn=self)) #log.err() def _cbSecond(self, result): #print 'CALLBACK Result 2:', result self.caller.responses.append(result.rstrip()) self.d = defer.Deferred() self.d.addCallback(self._cbThird) self.d.addErrback(self._ebThird) self.openChannel(CommandChannel(self.cmds[2], lastcmd=1, conn=self)) def _ebSecond(self, f): self.caller.responses.append(None) self.d = defer.Deferred() self.d.addCallback(self._cbThird) self.d.addErrback(self._ebThird) self.openChannel(CommandChannel(self.cmds[2], lastcmd=1, conn=self)) #log.err() def _cbThird(self, result): self.caller.responses.append(result.rstrip()) #print 'CALLBACK Result 3:', result reactor.stop() def _ebThird(self, f): self.caller.responses.append(None) log.err() reactor.stop() #====================== class CommandChannel(channel.SSHChannel): name = 'session' def __init__(self, command, lastcmd, *args, **kwargs): channel.SSHChannel.__init__(self, *args, **kwargs) self.command = command self.lastcmd = lastcmd self.data = "" def channelOpen(self, data): self.conn.sendRequest(self, 'exec', common.NS(self.command), wantReply=True).addCallback(self._gotResponse) def _gotResponse(self, _): #print "RESPONSE" self.conn.sendEOF(self) def dataReceived(self, data): #print "Data Received:", data self.data += data def closed(self): self.conn.d.callback(self.data) self.loseConnection() ## if self.lastcmd: ## print "closing reactor." ## reactor.stop() class ClientCommandFactory(protocol.ClientFactory): def __init__(self, username, password, cmds, caller): self.username = username self.password = password self.cmds = cmds self.caller = caller def buildProtocol(self, addr): protocol = ClientCommandTransport(self.username, self.password, self.cmds, self.caller) return protocol class SSH(): """ Contains a SSH connection, runs commands, and stores results. """ def __init__(self, host, username, password, cmds): self.host = host self.username = username self.password = password self.cmds = cmds self.responses = [] self.run_commands() def run_commands(self): factory = ClientCommandFactory(self.username, self.password, self.cmds, self) reactor.connectTCP(self.host, 22, factory) reactor.run() myssh = SSH("my.host.com", "myacct", "mypasswd", ["id; su - root; myrootpasswd; id", "pwd", "ls -l"]) print "=" * 25 for i, response in enumerate(myssh.responses): print i, response print "=" * 25 print "\nDone."