Python
  Home arrow Python arrow Page 5 - SSH with Twisted
Dev Shed Forums  
Administration  
AJAX  
Apache  
BrainDump  
DHTML  
Flash  
Java  
JavaScript  
Multimedia  
MySQL  
Oracle  
Perl  
PHP  
Practices  
Python  
Reviews  
Security  
Smartphone Development  
Style-Sheets  
Web Services  
XML  
Zend  
Zope  
Mobile Linux  
App Generation ROI  
IBM® developerWorks  
Forums Sitemap  
E-Commerce Hosting  
Linux Web Hosting  
Managed Hosting  
Small Business Hosting  
VPS Hosting  
Weekly Newsletter

 
Developer Updates  
Free Website Content 
 RSS  Articles
 RSS  Forums
 RSS  All Feeds
Write For Us Get Paid  
Request Media Kit
Contact Us  
Site Map  
Privacy Policy  
Support  
 USERNAME
 
 PASSWORD
 
 
  >>> SIGN UP!  
  Lost Password? 
Google.com  
PYTHON

SSH with Twisted
By: O'Reilly Media
  • Search For More Articles!
  • Disclaimer
  • Author Terms
  • Rating: starstarstarstarstar / 6
    2008-03-06


    Table of Contents:
  • SSH with Twisted
  • Setting Up a Custom SSH Server continued
  • Using Public Keys for Authentication
  • Providing an Administrative Python Shell
  • Running Commands on a Remote Server

  • Rate this Article: Poor Best 
      ADD THIS ARTICLE TO:
      error-file:tidyout.log Del.ici.ous error-file:tidyout.log Digg
      error-file:tidyout.log Blink error-file:tidyout.log Simpy
      error-file:tidyout.log Google error-file:tidyout.log Spurl
      error-file:tidyout.log Y! MyWeb error-file:tidyout.log Furl
    Email Me Similar Content When Posted
    Add Developer Shed Article Feed To Your Site
    Email Article To Friend
    Print Version Of Article
    PDF Version Of Article

     
     
    ADVERTISEMENT


    SSH with Twisted - Running Commands on a Remote Server
    ( Page 5 of 5 )

    This lab demonstrates how to write an SSH client. You can use twisted.conch to communicate with a server using SSH: logging in, executing commands, and
    capturing the output.

    How Do I Do That?

    There are several classes that work together to make up a twisted.conch.ssh SSH client. The transport.SSHClientTransport class sets up the connection and verifies the identity of the server. The userauth.SSHUserAuthClient logs in using your authentication credentials. The connection.SSHConnection class takes over once you’ve logged in, and creates one or more channel.SSHChannel objects, which you then use to communicate with the server over a secure channel. Example 10-4 shows how you can use these classes to make an SSH client that logs into a server, runs a command, and prints the output.

    Example 10-4. sshclient.py

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

    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):
            print 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

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

    if __name__ == "__main__":
        import sys, getpass
        server = sys.argv[1]
        command = sys.argv[2]
        username = raw_input("Username: ")
        password = getpass.getpass("Password: ")
        factory = ClientCommandFactory(username, password, command)
        reactor.connectTCP(server, 22, factory)
        reactor.run()

    Run sshclient.py with two arguments: a hostname and a command. It will ask for your username and password, log into the server, execute the command, and print the output. For example, you could run the who command to get a list of who’s currently logged in to the server:

      $ python sshclient.py myserver.example.com who
     
    Username: abe
     
    Password: password

      root     pts/0       Jun 11 21:35 (192.168.0.13)
      phil     pts/2       Jun 22 13:58 (192.168.0.1)
      phil     pts/3       Jun 22 13:58 (192.168.0.1)

    How Does That Work?

    The ClientCommandTransport in Example 10-4 handles the initial connection to the SSH server. Its verifyHostKey method checks to make sure the server’s public key matches your expectations. Typically, you’d remember each server the first time you connected, and then check on subsequent connections to make sure that another server wasn’t maliciously trying to pass itself off as the server you expected. Here, it just returns a True value without bothering to check the key. The connectionSecure method is called as soon as the initial encrypted connection has been established. This is the appropriate time to send your login credentials, by passing a
    userauth.SSHUserAuthClient to self.requestService, along with a connection.SSHConnection object that should manage the connection after authentication succeeds.

    The PasswordAuth inherits from userauth.SSHUserAuthClient . It has to implement only a single method, getPassword , which returns the password it will use to log in. If you wanted to use public key authentication, you’d implement the methods getPublicKey and getPrivateKey instead, returning the appropriate key as a string in each case.

    The ClientConnection class in Example 10-4 will have its serviceStarted method called as soon as the client has successfully logged in. It calls self.openChannel with a CommandChannel object, which is a subclass of channel.SSHChannel . This object is used to work with an authenticated channel to the SSH server. Its channelOpen method is called when the channel is ready. At this point, you can call self.conn.sendRequest to send a command to the server. You have to encode data sent over SSH as a spe cially formatted network string; to get a string in this format, pass it to the twisted.conch.common.NS function. Set the keyword argument wantReply to True if you’re interested in getting a response from the command; this setting will cause sendRequest to return a Deferred that will be called back when the command is completed. (If you don’t set wantReply to True , sendRequest will return None .) As data is received from the server, it will be passed to dataReceived . Once you’re done using the channel, close it by calling self.conn.sendEOF . The closed method will be called to let you know when the channel has been successfully closed.



     
     
    >>> More Python Articles          >>> More By O'Reilly Media
     

       

    PYTHON ARTICLES

    - Tuples and Other Python Object Types
    - The Dictionary Python Object Type
    - String and List Python Object Types
    - Introducing Python Object Types
    - Mobile Programming using PyS60: Advanced UI ...
    - Nested Functions in Python
    - Python Parameters, Functions and Arguments
    - Python Statements and Functions
    - Statements and Iterators in Python
    - Sequences and Sets in Python
    - Python Expressions and Operators
    - Dictionaries, Variables and Statements in Py...
    - Data Types in Python
    - The Python Language
    - SSH with Twisted





    © 2003-2009 by Developer Shed. All rights reserved. DS Cluster 5 Hosted by Hostway
    For more Enterprise Application Development news, visit eWeek