[Twisted-Python] Need some help with my first Twisted program

McCann, Brian bmccann at andmore.com
Fri Oct 19 14:53:00 MDT 2007


 

> -----Original Message-----
> From: twisted-python-bounces at twistedmatrix.com 
> [mailto:twisted-python-bounces at twistedmatrix.com] On Behalf 
> Of Jean-Paul Calderone
> Sent: Friday, October 19, 2007 4:29 PM
> To: Twisted general discussion
> Subject: Re: [Twisted-Python] Need some help with my first 
> Twisted program
> 
> On Fri, 19 Oct 2007 16:13:20 -0400, "McCann, Brian" 
> <bmccann at andmore.com> wrote:
> >I'm looking for what is probably an simple solution I can't 
> figure out
> >on my own.  I'm writing an SSH server based on the example on the web
> >(using conch).  I'm trying to figure out how to detect when 
> the client
> >exists (for example, when I just close out PuTTY), but I 
> can't get this
> >to work right.  Looking through the API docs I found 
> "connectionLost()",
> >which I put in my protocol class (EchoProtocol in the 
> example), but it's
> >never getting called.
> >
> >Can someone please tell me what I'm doing wrong?
> 
> You seem to be on the right track.  However, you haven't 
> supplied enough
> details for anyone to be sure why it isn't behaving as you 
> expect.  If you
> can post a minimal example of a program which you think 
> should be working
> (ie, giving you connection lost notification) but isn't, then 
> someone can
> probably point you to a solution.
> 
> Jean-Paul
> 
> _______________________________________________
> Twisted-Python mailing list
> Twisted-Python at twistedmatrix.com
> http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-python
> 
> 

Sorry about that.  Here is most of what is involved.  (Code below)  I
would think that when I close my PuTTY window, the connectionLost
function in the EchoProtocol would be called...but clearly I'm missing
some crucial step.

--Brian

from twisted.cred import portal, checkers
from twisted.conch import error, avatar
from twisted.conch.checkers import SSHPublicKeyDatabase
from twisted.conch.ssh import factory, userauth, connection, keys,
session
from twisted.internet import reactor, protocol, defer
from twisted.python import log
from zope.interface import implements
import sys
import socket
import threading

log.startLogging(sys.stderr)

"""Example of running another protocol over an SSH channel.
log in with username "user" and password "password".
"""
class defaultdict(dict):
    def __init__(self, default=None):
        dict.__init__(self)
        self.default = default
    def __getitem__(self, key):
        try:
            return dict.__getitem__(self, key)
        except KeyError:
            return self.default


class ExampleAvatar(avatar.ConchUser):

    def __init__(self, username):
        avatar.ConchUser.__init__(self)
        self.username = username
        self.channelLookup.update({'session':session.SSHSession})

class ExampleRealm:
    implements(portal.IRealm)

    def requestAvatar(self, avatarId, mind, *interfaces):
        return interfaces[0], ExampleAvatar(avatarId), lambda: None

class EchoProtocol(protocol.Protocol):
    """this is our example protocol that we will run over SSH
    """
    def connectionMade(self):
        self.transport.write("Connected!\r\n")
        self.commandBuffer = ""

    def connectionLost(self,reason):
        print "lost:%s" %reason
        self.serialServerSocket.close()
        self.alive = False
        self.serialSocketReadThread.join()
                
        
publicKey = 'ssh-rsa
AAAAB3NzaC1yc2EAAAABIwAAAGEArzJx8OYOnJmzf4tfBEvLi8DVPrJ3/c9k2I/Az64fxjHf
9imyRJbixtQhlH9lfNjUIx+4LmrJH5QNRsFporcHDKOTwTTYLh5KmRpslkYHRivcJSkbh/C+
BR3utDS555mV'

privateKey = """-----BEGIN RSA PRIVATE KEY-----
MIIByAIBAAJhAK8ycfDmDpyZs3+LXwRLy4vA1T6yd/3PZNiPwM+uH8Yx3/YpskSW
4sbUIZR/ZXzY1CMfuC5qyR+UDUbBaaK3Bwyjk8E02C4eSpkabJZGB0Yr3CUpG4fw
vgUd7rQ0ueeZlQIBIwJgbh+1VZfr7WftK5lu7MHtqE1S1vPWZQYE3+VUn8yJADyb
Z4fsZaCrzW9lkIqXkE3GIY+ojdhZhkO1gbG0118sIgphwSWKRxK0mvh6ERxKqIt1
xJEJO74EykXZV4oNJ8sjAjEA3J9r2ZghVhGN6V8DnQrTk24Td0E8hU8AcP0FVP+8
PQm/g/aXf2QQkQT+omdHVEJrAjEAy0pL0EBH6EVS98evDCBtQw22OZT52qXlAwZ2
gyTriKFVoqjeEjt3SZKKqXHSApP/AjBLpF99zcJJZRq2abgYlf9lv1chkrWqDHUu
DZttmYJeEfiFBBavVYIF1dOlZT0G8jMCMBc7sOSZodFnAiryP+Qg9otSBjJ3bQML
pSTqy7c3a2AScC/YyOwkDaICHnnD3XyjMwIxALRzl0tQEKMXs6hH8ToUdlLROCrP
EhQ0wahUTCk1gKA4uPD6TMTChavbh4K63OvbKg==
-----END RSA PRIVATE KEY-----"""


class InMemoryPublicKeyChecker(SSHPublicKeyDatabase):

    def checkKey(self, credentials):
        return credentials.username == 'user' and \
            keys.getPublicKeyString(data=publicKey) == credentials.blob

class ExampleSession:
    
    def __init__(self, avatar):
        """
        We don't use it, but the adapter is passed the avatar as its
first
        argument.
        """

    def getPty(self, term, windowSize, attrs):
        pass
    
    def execCommand(self, proto, cmd):
        raise Exception("no executing commands")

    def openShell(self, trans):
        ep = EchoProtocol()
        ep.makeConnection(trans)
        trans.makeConnection(session.wrapProtocol(ep))

    def eofReceived(self):
        pass

    def closed(self):
        pass

from twisted.python import components
components.registerAdapter(ExampleSession, ExampleAvatar,
session.ISession)

class ExampleFactory(factory.SSHFactory):
    publicKeys = {
        'ssh-rsa': keys.getPublicKeyString(data=publicKey)
    }
    privateKeys = {
        'ssh-rsa': keys.getPrivateKeyObject(data=privateKey)
    }
    services = {
        'ssh-userauth': userauth.SSHUserAuthServer,
        'ssh-connection': connection.SSHConnection
    }
    

portal = portal.Portal(ExampleRealm())
passwdDB = checkers.InMemoryUsernamePasswordDatabaseDontUse()
passwdDB.addUser('user', 'password')
portal.registerChecker(passwdDB)
portal.registerChecker(InMemoryPublicKeyChecker())
ExampleFactory.portal = portal


if __name__ == '__main__':
    reactor.listenTCP(5022, ExampleFactory())
    reactor.run()




More information about the Twisted-Python mailing list