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
How Do I Do That?
There are several classes that work together to make up a twisted.conch.ssh SSH client. The transport.SSHClientTransportclass sets up the connection and verifies the identity of the server. Theuserauth.SSHUserAuthClientlogs in using your authentication credentials. Theconnection.SSHConnectionclass takes over once you’ve logged in, and creates one or morechannel.SSHChannelobjects, 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
def verifyHostKey(self, pubKey, fingerprint):
def getPassword(self, prompt=None):
def __init__(self, command, *args, **kwargs):
def channelOpen(self, data):
def _gotResponse(self, _):
def dataReceived(self, data):
def buildProtocol(self, addr):
if __name__ == "__main__":
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
root pts/0 Jun 11 21:35 (192.168.0.13)
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
ThePasswordAuthinherits fromuserauth.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 methodsgetPublicKeyandgetPrivateKeyinstead, returning the appropriate key as a string in each case.
TheClientConnectionclass in Example 10-4 will have itsserviceStartedmethod called as soon as the client has successfully logged in. It callsself.openChannelwith aCommandChannel object, which is a subclass ofchannel.SSHChannel. This object is used to work with an authenticated channel to the SSH server. ItschannelOpenmethod is called when the channel is ready. At this point, you can callself.conn.sendRequestto send a command to the server. You have to encode data sent over SSH as a specially formatted network string; to get a string in this format, pass it to thetwisted.conch.common.NSfunction. Set the keyword argumentwantReplytoTrueif you’re interested in getting a response from the command; this setting will causesendRequestto return aDeferredthat will be called back when the command is completed. (If you don’t setwantReplytoTrue,sendRequestwill returnNone.) As data is received from the server, it will be passed todataReceived. Once you’re done using the channel, close it by callingself.conn.sendEOF. Theclosed method will be called to let you know when the channel has been successfully closed.
blog comments powered by Disqus