3 # Copyright (c) Twisted Matrix Laboratories.
4 # See LICENSE for details.
6 from twisted.conch.ssh import transport, userauth, connection, common, keys, channel
7 from twisted.internet import defer, protocol, reactor
8 from twisted.python import log
9 import struct, sys, getpass, os
11 USER = 'z3p' # replace this with a valid username
12 HOST = 'localhost' # and a valid host
14 class SimpleTransport(transport.SSHClientTransport):
15 def verifyHostKey(self, hostKey, fingerprint):
16 print 'host key fingerprint: %s' % fingerprint
17 return defer.succeed(1)
19 def connectionSecure(self):
24 class SimpleUserAuth(userauth.SSHUserAuthClient):
25 def getPassword(self):
26 return defer.succeed(getpass.getpass("%s@%s's password: " % (USER, HOST)))
28 def getGenericAnswers(self, name, instruction, questions):
32 for prompt, echo in questions:
34 answer = raw_input(prompt)
36 answer = getpass.getpass(prompt)
37 answers.append(answer)
38 return defer.succeed(answers)
40 def getPublicKey(self):
41 path = os.path.expanduser('~/.ssh/id_dsa')
42 # this works with rsa too
43 # just change the name here and in getPrivateKey
44 if not os.path.exists(path) or self.lastPublicKey:
45 # the file doesn't exist, or we've tried a public key
47 return keys.Key.fromFile(filename=path+'.pub').blob()
49 def getPrivateKey(self):
50 path = os.path.expanduser('~/.ssh/id_dsa')
51 return defer.succeed(keys.Key.fromFile(path).keyObject)
53 class SimpleConnection(connection.SSHConnection):
54 def serviceStarted(self):
55 self.openChannel(TrueChannel(2**16, 2**15, self))
56 self.openChannel(FalseChannel(2**16, 2**15, self))
57 self.openChannel(CatChannel(2**16, 2**15, self))
59 class TrueChannel(channel.SSHChannel):
60 name = 'session' # needed for commands
62 def openFailed(self, reason):
63 print 'true failed', reason
65 def channelOpen(self, ignoredData):
66 self.conn.sendRequest(self, 'exec', common.NS('true'))
68 def request_exit_status(self, data):
69 status = struct.unpack('>L', data)[0]
70 print 'true status was: %s' % status
73 class FalseChannel(channel.SSHChannel):
76 def openFailed(self, reason):
77 print 'false failed', reason
79 def channelOpen(self, ignoredData):
80 self.conn.sendRequest(self, 'exec', common.NS('false'))
82 def request_exit_status(self, data):
83 status = struct.unpack('>L', data)[0]
84 print 'false status was: %s' % status
87 class CatChannel(channel.SSHChannel):
90 def openFailed(self, reason):
91 print 'echo failed', reason
93 def channelOpen(self, ignoredData):
95 d = self.conn.sendRequest(self, 'exec', common.NS('cat'), wantReply = 1)
96 d.addCallback(self._cbRequest)
98 def _cbRequest(self, ignored):
99 self.write('hello conch\n')
100 self.conn.sendEOF(self)
102 def dataReceived(self, data):
106 print 'got data from cat: %s' % repr(self.data)
107 self.loseConnection()
110 protocol.ClientCreator(reactor, SimpleTransport).connectTCP(HOST, 22)