[Twisted-Python] Telnet server using Twisted and AuthenticatingTelnetProtocol

2009-08-20 Thread filoufake-python
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)()
---  ---
  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  followed by PASS  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):

[Twisted-Python] Re : Telnet server using Twisted and AuthenticatingTelnetProtocol

2009-08-24 Thread filoufake-python
Thank you Jean-Paul for replying,

I still have some things that I don't understand:

If I put your piece of code in my factory's protocol, I can connect to the 
server but as soon as I enter the username, I got the an error message telling 
that Server doesn't support "will" ('Server' object has no attribute 'will').

2009-08-25 00:32:40+0200 [-] Log opened.
2009-08-25 00:32:40+0200 [-] twisted.internet.protocol.ServerFactory starting 
on 4738
2009-08-25 00:32:40+0200 [-] Starting factory 

2009-08-25 00:32:45+0200 [AuthenticatingTelnetProtocol,0,127.0.0.1] Unhandled 
Error
Traceback (most recent call last):
  File "C:\Python26\lib\site-packages\twisted\python\log.py", line 84, 
in callWithLogger
return callWithContext({"system": lp}, func, *args, **kw)
  File "C:\Python26\lib\site-packages\twisted\python\log.py", line 69, 
in callWithContext
return context.call({ILogContext: newCtx}, func, *args, **kw)
  File "C:\Python26\lib\site-packages\twisted\python\context.py", line 
59, in callWithContext
return self.currentContext().callWithContext(ctx, func, *args, **kw)
  File "C:\Python26\lib\site-packages\twisted\python\context.py", line 
37, in callWithContext
return func(*args,**kw)
---  ---
  File 
"C:\Python26\lib\site-packages\twisted\internet\selectreactor.py", line 146, in 
_doReadOrWrite
why = getattr(selectable, method)()
  File "C:\Python26\lib\site-packages\twisted\internet\tcp.py", line 
463, in doRead
return self.protocol.dataReceived(data)
  File "C:\Python26\lib\site-packages\twisted\protocols\basic.py", line 
231, in dataReceived
why = self.lineReceived(line)
  File "C:\Python26\lib\site-packages\twisted\conch\telnet.py", line 
925, in lineReceived
newState = getattr(self, "telnet_" + oldState)(line)
  File "C:\Python26\lib\site-packages\twisted\conch\telnet.py", line 
967, in telnet_User
self.transport.will(ECHO)
exceptions.AttributeError: 'Server' object has no attribute 'will'

I understand that this has something to do with TelnetTranport but how to 
implement it?
I read the telnet_echo.tac but in my case I have to manage the portal also and 
that is a litle bit too complex for me.

You say also that AuthenticatingTelnetProtocol  expects to be connected to an 
ITelnetTransport, but the documentation says "When the information is 
collected, it is passed to a portal and an avatar 
implementing ITelnetProtocol is requested". 
I'm lost.

May I abuse to ask you to tell how to do?

Many thanks

Philippe



  

___
Twisted-Python mailing list
Twisted-Python@twistedmatrix.com
http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-python


[Twisted-Python] Re : Re : Telnet server using Twisted and AuthenticatingTelnetProtocol

2009-09-01 Thread filoufake-python
Hello,

Thanks to your help, the server now requests a username and password for the 
authentication.
Once the password has been enterred, nothing happened on the client side. I'm 
even not able to escape from the client. I have to ctrl-c in the server console.
If I well understood the doc, for each state of the connection a method is 
called: telnet_User called when state = 'User', telnet_Password called when 
state = 'Password' and at the end telnet_Command (to be written by me).
I have added my "telnet_Command" method into my ITelnetProtocol implementation 
return by requestAvatar, but it is never called.
In the telnet_Password method, the deferred calls _cbLogin in case of good 
authentication or _ebLogin.
I could verify that _cbLogin is well called but it seems the application blocks 
in.

The method looks like this:
def _cbLogin(self, ial):
interface, protocol, logout = ial
assert interface is ITelnetProtocol
self.protocol = protocol
self.logout = logout
self.state = 'Command'
protocol.makeConnection(self.transport)
self.transport.protocol = protocol

I almost sure this has to do with what requestAvatar returns in my Realm class:
class Realm:
implements(portal.IRealm)

def requestAvatar(self, avatarId, mind, *interfaces):
if ITelnetProtocol in interfaces:
av = MyTelnet()
return ITelnetProtocol, av, lambda:None
raise NotImplementedError("Only IProtocolUser interface is supported by 
this realm")

MyTelnet being a derived class of StatefulTelnetProtocol.

Is it what you explained in your previous reply?
>AuthenticatingTelnetProtocol is an ITelnetProtocol implementation.  So, 
>it needs to be hooked up to an ITelnetTransport implementation, as all 
>ITelnetProtocol implementations need to.
>
>However, since the only thing it knows how to do is handle 
>authentication, it also wants to get /another/ ITelnetProtocol 
>implementation out of the portal you give it.  After authentication 
>succeeds, that new ITelnetProtocol implementation will be given control 
>of the connection and the AuthenticatingTelnetProtocol will get out of 
>the way.
>
>So you end up with one telnet transport and two telnet protocols.

I think I did all you said but I'm not able to get it work. Do you have another 
idea?
Thanks in advance.

Here is the log on the server:
2009-09-01 22:37:35+0200 [-] Log opened.
2009-09-01 22:37:35+0200 [-] twisted.internet.protocol.ServerFactory starting 
on 4738
2009-09-01 22:37:35+0200 [-] Starting factory 

2009-09-01 22:37:57+0200 [twisted.internet.protocol.ServerFactory] state User
2009-09-01 22:38:01+0200 [TelnetTransport,0,127.0.0.1] state User
2009-09-01 22:38:02+0200 [TelnetTransport,0,127.0.0.1] state Password
2009-09-01 22:38:02+0200 [TelnetTransport,0,127.0.0.1] BEGUG in requestAvatar: 
av = <__main__.MyTelnet instance at 0x00E757D8>
2009-09-01 22:38:02+0200 [TelnetTransport,0,127.0.0.1] BEGUG in _cbLogin: ial = 
(, <__main__.MyTelnet 
instance at 0x00E757D8>, None)
2009-09-01 22:38:02+0200 [TelnetTransport,0,127.0.0.1] BEGUG in _cbLogin: state 
= Command
2009-09-01 22:38:02+0200 [TelnetTransport,0,127.0.0.1] BEGUG in 
telnet_Password: deferred d = 

Regards,
Philippe



  


___
Twisted-Python mailing list
Twisted-Python@twistedmatrix.com
http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-python


[Twisted-Python] Re : Re : Re : Telnet server using Twisted and AuthenticatingTelnetProtocol

2009-09-02 Thread filoufake-python
Hello,

>It's hard to say what's going wrong without being able to see all of the 
>code.  A short, self contained, correct example () 
>would help a lot.

Hereafter is the simplest code that generates the problem.
If you run it, you will see that after entering the password nothing
happened. The "telnet_Command" method of MyTelnet is never called.
I think the problem is what requestAvatar returns.
Thanks again for your support

import sys
from zope.interface import implements
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
from twisted.conch.telnet import StatefulTelnetProtocol
from twisted.conch.telnet import ITelnetProtocol
from twisted.conch.telnet import TelnetTransport

class Realm:
  implements(portal.IRealm)

  def requestAvatar(self, avatarId, mind, *interfaces):
if ITelnetProtocol in interfaces:
  av = MyTelnet()
  return ITelnetProtocol, av, lambda:None
raise NotImplementedError("Not supported by this realm")

class MyTelnet(StatefulTelnetProtocol):
  def telnet_Command(self, line):
print "line received via telnet", line

def main():
  r = Realm()
  p = portal.Portal(r)
  c = checkers.InMemoryUsernamePasswordDatabaseDontUse()
  c.addUser("AA", "aa")
  p.registerChecker(c)
  p.registerChecker(checkers.AllowAnonymousAccess())
  f = protocol.ServerFactory()
  f.protocol = lambda: TelnetTransport(AuthenticatingTelnetProtocol, p)
  log.startLogging(sys.stdout)
  from twisted.internet import reactor
  reactor.listenTCP(4738, f)
  reactor.run()

if __name__ == '__main__':
  main()


  


___
Twisted-Python mailing list
Twisted-Python@twistedmatrix.com
http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-python


[Twisted-Python] Telnet server: localecho "ON" for linux client but not for windows client

2009-11-16 Thread filoufake-python
Hello,

Some month ago, exarkun helped me in the development of a very simplified
telnet server.

I observed that when I connect from a windows client, the LOCALECHO
is set to "OFF" after the authentication. I cannot set it "ON"
afterwards. Everything typed in the client console is hidden.
When I use a linux client, the "ECHO" is OFF just for typing the 
password and then ON again.

Does someone has an idea how to do with the windows client?
I tried to set the ECHO ON using self.transport.will(ECHO) but that
doesn't work.

Here is the code:


import sys
from zope.interface import implements
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
from twisted.conch.telnet import StatefulTelnetProtocol
from twisted.conch.telnet import ITelnetProtocol
from twisted.conch.telnet import TelnetTransport
from twisted.conch.telnet import ECHO

class Realm:
  implements(portal.IRealm)

  def requestAvatar(self, avatarId, mind, *interfaces):
if ITelnetProtocol in interfaces:
  av = MyTelnet()
  av.transport.will(ECHO)
  av.state = 'Command'
  return ITelnetProtocol, av, lambda:None
raise NotImplementedError("Not supported by this realm")

class MyTelnet(StatefulTelnetProtocol):
  def telnet_Command(self, line):
print "line received via telnet", line
self.sendLine('coucou man, you send me %s' % line)

def main():
  r = Realm()
  p = portal.Portal(r)
  c = checkers.InMemoryUsernamePasswordDatabaseDontUse()
  c.addUser("AA", "aa")
  p.registerChecker(c)
  p.registerChecker(checkers.AllowAnonymousAccess())
  f = protocol.ServerFactory()
  f.protocol = lambda: TelnetTransport(AuthenticatingTelnetProtocol, p)
  log.startLogging(sys.stdout)
  from twisted.internet import reactor
  reactor.listenTCP(4738, f)
  reactor.run()

if __name__ == '__main__':
  main()


Best Regards,
Philippe


  

___
Twisted-Python mailing list
Twisted-Python@twistedmatrix.com
http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-python