[BangPypers] Multilevel SSH in Python (davidsnt)

Philippe May phil.nabble at hanjinet.org
Wed Oct 17 15:38:29 CEST 2012


Noufal's suggestion is great (as usual).

Twisted might be a valid alternative as it give access to the full 
protocol stacks and lets you plug in what you need in pure python (see 
the connection object below).

This recent talk seems also to be related to this topic (long video): 
http://www.youtube.com/watch?v=DUm-ZBEmVUE

Philippe


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

class ClientTransport(transport.SSHClientTransport):
     def verifyHostKey(self, pubKey, fingerprint):
         ## If you want to verify the host key:
         #if fingerprint != 
"e8:68:7a:7a:a2:5e:fd:fa:94:f5:c8:2a:c1:10:80:5b":
         #    return defer.fail(error.ConchError('bad key'))
         #else:
         #    return defer.succeed(1)
         return defer.succeed(True)

     def connectionSecure(self):
         self.requestService(ClientUserAuth(os.getlogin(), 
ClientConnection()))



class ClientUserAuth(userauth.SSHUserAuthClient):
     publicKey = keys.Key.fromFile(os.path.join(os.path.expanduser("~"), 
".ssh", "id_dsa.pub"))
     privateKey = 
keys.Key.fromFile(os.path.join(os.path.expanduser("~"), ".ssh", "id_dsa"))

     def getPassword(self, prompt = None):
         return
         # this says we won't do password authentication

     def getPublicKey(self):
         return self.publicKey

     def getPrivateKey(self):
         return defer.succeed(self.privateKey)


class ClientConnection(connection.SSHConnection):

     def serviceStarted(self):
         self.openChannel(CatChannel(conn = self))



class CatChannel(channel.SSHChannel):

     name = 'session'

     def channelOpen(self, data):
         d = self.conn.sendRequest(self, 'exec', common.NS('cat'), 
wantReply = 1)
         d.addCallback(self._cbSendRequest)
         self.catData = ''

     def _cbSendRequest(self, ignored):
         self.write('This data will be echoed back to us by "cat."')

     def dataReceived(self, data):
         self.catData += data
         self.loseConnection()

     def closed(self):
         print 'We got this from "cat":', self.catData
         reactor.stop()



def main():
     factory = protocol.ClientFactory()
     factory.protocol = ClientTransport
     reactor.connectTCP('localhost', 22, factory)
     ## Log all to stdout
     log.startLogging(sys.stdout, setStdout=0)
     reactor.run()

if __name__ == "__main__":
     main()



More information about the BangPypers mailing list