[Twisted-Python] Twisted Conch SSH timeout

ray terrill rayjohnterrill at gmail.com
Mon Feb 2 12:22:01 MST 2009


I've got a Twisted Conch/SSH script that I inherited which I'm using to run
commands remotely on some servers.  I'd like to add a timeout for servers
that are down, etc (the script currently hangs on these), but I'm not sure
where to add that functionality.

Any help would be appreciated.
Thanks,
-Ray

=========Script Follows=========

#!/usr/bin/python

from twisted.conch import error
from twisted.conch.ssh import transport, connection, keys, userauth,
channel, common
from twisted.internet import defer, protocol, reactor

#a class to store the data returned from the ssh client code
class SSHData():
   data = ''

class ClientCommandTransport(transport.SSHClientTransport):
   def __init__(self, username, password, command):
      self.username = username
      self.password = password
      self.command = command

   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.command)))

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, cmd, *args, **kwargs):
      connection.SSHConnection.__init__(self)
      self.command = cmd

   def serviceStarted(self):
      self.openChannel(CommandChannel(self.command, conn=self))

class CommandChannel(channel.SSHChannel):
   name = 'session'

   def __init__(self, command, *args, **kwargs):
      channel.SSHChannel.__init__(self, *args, **kwargs)
      self.command = command

   def channelOpen(self, data):
      self.conn.sendRequest(
         self, 'exec', common.NS(self.command), wantReply=True).addCallback(
         self._gotResponse)

   def _gotResponse(self, _):
      self.conn.sendEOF(self)

   def dataReceived(self, data):
      SSHData.data = data

   def closed(self):
      reactor.stop()

class ClientCommandFactory(protocol.ClientFactory):
   def __init__(self, username, password, command):
      self.username = username
      self.password = password
      self.command = command
      self.deferred = defer.Deferred()

   def buildProtocol(self, addr):
      protocol = ClientCommandTransport(
      self.username, self.password, self.command)
      return protocol

def testConnect(username, password, command, server):
   testFactory = ClientCommandFactory(username, password, command)
   reactor.connectTCP(server, 22, testFactory)
   return testFactory.deferred

def handleSuccess(result, port):
   print "Connected to port %i" % port
   reactor.stop()

def handleFailure(failure, port):
   print "Error connecting to port %i: %s" % (
      port, failure.getErrorMessage())
   reactor.stop()

if __name__ == "__main__":
   import sys, getpass

   server = sys.argv[1]
   command = sys.argv[2]
   username = raw_input("Username: ")
   password = getpass.getpass("Password: ")

   connecting = testConnect(username, password, command, server)
   #connecting.addCallback(handleSuccess, server)
   #connecting.addErrback(handleFailure, server)
   connecting.setTimeout(1, handleError)
   reactor.run()

   print "The data I got back from the ssh client is " + SSHData.data
-------------- next part --------------
An HTML attachment was scrubbed...
URL: </pipermail/twisted-python/attachments/20090202/bbde2fc8/attachment.html>


More information about the Twisted-Python mailing list