[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