Hello,
I have created a telnet server in python.
Maybe you wonder why to create a telnet server while Windows has one?
Because the windows telnet server does not allow to interract with the
desktop. If you try to start a GUI app, it will start and run but will
not be displayed on the server desktop.
My telnet server will allow to start a GUI application interracting with the windows desktop of the server.
Ex. : typing "notepad" in the telnet console will pop up the notepad on the Windows desktop of the server.
At the time this server works but has no authentication feature implemented.
I would like to implement the authentication using AuthenticatingTelnetProtocol and credential.
I found the "
cred.py" example on the twistedmatrix website (in the example section) and looked fine as starting point.
I quite well understand this expample.
I modified the code as follow but always got the same error message when a connectiion is attempted.
I have been trying since two weeks but I cannot get it work.
Is there a problem with "AuthenticatingTelnetProtocol"
The error message:
************************************************************
D:\workspace\twisted>telnet_cred.py
2009-08-20 08:57:11+0200 [-] Log opened.
2009-08-20 08:57:11+0200 [-] __main__.ServerFactory starting on 4738
2009-08-20 08:57:11+0200 [-] Starting factory <__main__.ServerFactory instance at 0x00D79C60>
2009-08-20 08:57:15+0200 [__main__.ServerFactory] DEBUG: buildProtocol - addr IPv4Address(TCP, '127.0.0.1', 4978)
2009-08-20 08:57:15+0200 [__main__.ServerFactory] Unhandled Error
Traceback (most recent call last):
File "C:\Python25\lib\site-packages\twisted\python\log.py", line 69, in callWithContext
return context.call({ILogContext: newCtx}, func, *args, **kw)
File "C:\Python25\lib\site-packages\twisted\python\context.py", line 59, in callWithContext
return self.currentContext().callWithContext(ctx, func, *args, **kw)
File "C:\Python25\lib\site-packages\twisted\python\context.py", line 37, in callWithContext
return func(*args,**kw)
File "C:\Python25\lib\site-packages\twisted\internet\selectreactor.py", line 146, in _doReadOrWrite
why = getattr(selectable, method)()
--- <exception caught here> ---
File "C:\Python25\lib\site-packages\twisted\internet\tcp.py", line 932, in doRead
protocol = self.factory.buildProtocol(self._buildAddr(addr))
File "D:\workspace\twisted\telnet_cred.py", line 130, in buildProtocol
p = protocol.ServerFactory.buildProtocol(self, addr)
File "C:\Python25\lib\site-packages\twisted\internet\protocol.py", line 98, in buildProtocol
p = self.protocol()
exceptions.TypeError: __init__() takes exactly 2 arguments (1 given)
************************************************************
The modified code:
************************************************************
# Copyright (c) 2001-2004 Twisted Matrix Laboratories.
# See LICENSE for details.
import sys
from zope.interface import implements, Interface
from twisted.protocols import basic
from twisted.internet import protocol
from twisted.python import log
from twisted.cred import error
from twisted.cred import portal
from twisted.cred import checkers
from twisted.cred import credentials
from twisted.conch.telnet import AuthenticatingTelnetProtocol, ITelnetProtocol, TelnetProtocol
class IProtocolUser(Interface):
def getPrivileges():
"""Return a list of privileges this user has."""
def logout():
"""Cleanup per-login resources allocated to this avatar"""
class
AnonymousUser:
implements(IProtocolUser)
def getPrivileges(self):
return [1, 2, 3]
def logout(self):
print "Cleaning up anonymous user resources"
class RegularUser:
implements(IProtocolUser)
def getPrivileges(self):
return [1, 2, 3, 5, 6]
def logout(self):
print "Cleaning up regular user resources"
class Administrator:
implements(IProtocolUser)
def getPrivileges(self):
return range(50)
def
logout(self):
print "Cleaning up administrator resources"
class Protocol(basic.LineReceiver):
user = None
portal = None
avatar = None
logout = None
def connectionMade(self):
self.sendLine("Login with USER <name> followed by PASS <password> or ANON")
self.sendLine("Check privileges with PRIVS")
def connectionLost(self, reason):
if self.logout:
self.logout()
self.avatar = None
self.logout =
None
def lineReceived(self, line):
f = getattr(self, 'cmd_' + line.upper().split()[0])
if f:
try:
f(*line.split()[1:])
except TypeError:
self.sendLine("Wrong number of arguments.")
except:
self.sendLine("Server error (probably your fault)")
def cmd_ANON(self):
if
self.portal:
self.portal.login(credentials.Anonymous(), None, IProtocolUser
).addCallbacks(self._cbLogin, self._ebLogin
)
else:
self.sendLine("DENIED")
def cmd_USER(self, name):
self.user = name
self.sendLine("Alright. Now PASS?")
def cmd_PASS(self, password):
if not self.user:
self.sendLine("USER required before PASS")
else:
if self.portal:
self.portal.login(
credentials.UsernamePassword(self.user, password),
None,
IProtocolUser
).addCallbacks(self._cbLogin, self._ebLogin
)
else:
self.sendLine("DENIED")
def cmd_PRIVS(self):
self.sendLine("You have the following privileges: ")
self.sendLine(" ".join(map(str, self.avatar.getPrivileges())))
def _cbLogin(self, (interface, avatar, logout)):
assert interface is IProtocolUser
self.avatar = avatar
self.logout = logout
self.sendLine("Login successful. Available commands: PRIVS")
def _ebLogin(self,
failure):
failure.trap(error.UnauthorizedLogin)
self.sendLine("Login denied! Go away.")
class ServerFactory(protocol.ServerFactory):
## protocol = Protocol
protocol = AuthenticatingTelnetProtocol
def __init__(self, portal):
self.portal = portal
def buildProtocol(self, addr):
print "DEBUG: buildProtocol - addr", addr
p = protocol.ServerFactory.buildProtocol(self, addr)
print "DEBUG2: buildProtocol - addr", addr
p.portal = self.portal
return
p
class Realm:
implements(portal.IRealm)
def requestAvatar(self, avatarId, mind, *interfaces):
if IProtocolUser in interfaces:
if avatarId == checkers.ANONYMOUS:
av = AnonymousUser()
elif avatarId.isupper():
# Capitalized usernames are administrators.
av = Administrator()
else:
av = RegularUser()
return IProtocolUser, av, av.logout
elif ITelnetProtocol in interfaces:
print "BEGUG: aaaa"
if avatarId.isupper():
av = TelnetProtocol()
return ITelnetProtocol, av, None
raise NotImplementedError("Only IProtocolUser interface is supported by this realm")
def main():
r = Realm()
p = portal.Portal(r)
c = checkers.InMemoryUsernamePasswordDatabaseDontUse()
c.addUser("auser",
"thepass")
c.addUser("SECONDUSER", "secret")
p.registerChecker(c)
p.registerChecker(checkers.AllowAnonymousAccess())
f = ServerFactory(p)
log.startLogging(sys.stdout)
from twisted.internet import reactor
reactor.listenTCP(4738, f)
reactor.run()
if __name__ == '__main__':
main()
************************************************************
If someone could help me.
Philippe