Python 书籍:twisted网络编程要点,示例9-1不起作用
我要读Jessica McKellar和Abe Fetting的《扭曲网络编程要点》第二版。我被困在下面扭曲的cred auth示例9-1中。我一行一行地仔细检查了我的密码。代码将运行,当我连接到telnet客户端并输入“用户密码”时,它将不会让我登录。我刚收到未经授权的消息。脚本本身不会生成任何错误消息或异常 谢谢Python 书籍:twisted网络编程要点,示例9-1不起作用,python,authentication,twisted,telnet,credentials,Python,Authentication,Twisted,Telnet,Credentials,我要读Jessica McKellar和Abe Fetting的《扭曲网络编程要点》第二版。我被困在下面扭曲的cred auth示例9-1中。我一行一行地仔细检查了我的密码。代码将运行,当我连接到telnet客户端并输入“用户密码”时,它将不会让我登录。我刚收到未经授权的消息。脚本本身不会生成任何错误消息或异常 谢谢 import sys from zope.interface import implements, Interface from twisted.cred import chec
import sys
from zope.interface import implements, Interface
from twisted.cred import checkers, credentials, portal
from twisted.internet import protocol, reactor
from twisted.protocols import basic
from twisted.python.log import startLogging; startLogging(sys.stdout)
class IPortocolAvatar(Interface):
def logout():
"""
Clean up per-login resource allocated to this avatar.
"""
class EchoAvatar(object):
implements(IPortocolAvatar)
def logout(self):
pass
class Echo(basic.LineReceiver):
portal = None
avatar = None
logout = None
def connectionLost(self, reason):
if self.logout:
self.logout()
self.avatar = None
self.logout = None
def lineReceived(self, line):
if not self.avatar:
# print "line [32]: %s" % (line,)
username, password = line.strip().split(" ")
self.tryLogin(username, password)
else:
self.sendLine(line)
def tryLogin(self, username, password):
self.portal.login(credentials.UsernamePassword(username, password), None, PortocolAvatar).addCallbacks(self._cbLogin, self._ebLogin)
def _cbLogin(self, (interface, avatar, logout)):
self.avatar = avatar
self.logout = logout
self.sendLine("Login sucessful, please proceed.")
def _ebLogin(self, failure):
self.sendLine("Login denied, goodbye.")
self.transport.loseConnection()
class EchoFactory(protocol.Factory):
def __init__(self, portal):
self.portal = portal
def buildProtocol(self, addr):
proto = Echo()
proto.portal = self.portal
return proto
class Realm(object):
implements(portal.IRealm)
def requestAvatar(self, avatarId, mind, *interfaces):
if IPortocolAvatar in interfaces:
avatar = EchoAvatar()
return IPortocolAvatar, avatar, avatar.logout
raise NotImplementedError(
"This realm only supports the IPortocolAvatar interface.")
realm = Realm()
myPortal = portal.Portal(realm)
checker = checkers.InMemoryUsernamePasswordDatabaseDontUse()
checker.addUser("user", "pass")
myPortal.registerChecker(checker)
reactor.listenTCP(8000, EchoFactory(myPortal))
reactor.run()
您在
tryLogin
(ProtocolAvatar
->IProtocolAvatar
)中有一个输入错误:
更新
还有另一个输入错误:IPortocolAvatar
->IProtocolAvatar
运行服务器后,请尝试以下测试客户端代码:
import telnetlib
import time
t = telnetlib.Telnet('localhost', 8000)
t.write(b'user pass\r\n')
t.write(b'blah blah\r\n')
time.sleep(1)
print(t.read_eager())
我还使用python3运行了这个示例。 这是我修改后的“示例9-1”代码。echo_cred.py“摘自《扭曲网络编程概要》第二版”
from zope.interface import Interface, implementer
from twisted.cred import checkers, credentials, portal, error
from twisted.internet import protocol, reactor, defer
from twisted.protocols import basic
class IProtocolAvatar(Interface):
def logout():
"""
Clean up per-login resources allocated to this avatar.
"""
@implementer(IProtocolAvatar)
class EchoAvatar():
def logout(self):
pass
class Echo(basic.LineReceiver):
portal = None
avatar = None
logout = None
def connectionLost(self, reason):
if self.logout:
self.logout()
self.avatar = None
self.logout = None
def lineReceived(self, line):
print('line received')
if not self.avatar:
username, password = line.strip().split()
# convert 2 text code
username, password = username.decode(), password.decode()
d = defer.maybeDeferred(self.tryLogin, username, password)
d.addCallbacks(self._cbLogin, self._ebLogin)
else:
self.sendLine(line)
def tryLogin(self, username, password):
if self.portal is not None:
return self.portal.login(
credentials.UsernamePassword(username, password),
None,
IProtocolAvatar
)
raise error.UnauthorizedLogin()
def _cbLogin(self, ial):
interface, avatar, logout = ial
self.avatar = avatar
self.logout = logout
# convert 2 byte code
self.sendLine("Login successful, please proceed.".encode())
def _ebLogin(self, failure):
self.sendLine("Login denied, goodbye.".encode())
self.transport.loseConnection()
class EchoFactory(protocol.Factory):
def __init__(self, portal):
self.portal = portal
def buildProtocol(self, addr):
proto = Echo()
proto.portal = self.portal
return proto
@implementer(portal.IRealm)
class Realm():
def requestAvatar(self, avatarId, mind, *interfaces):
if IProtocolAvatar in interfaces:
avatar = EchoAvatar()
return IProtocolAvatar, avatar, avatar.logout
raise NotImplementedError("This realm only supports the IProtocolAvatar interface.")
if __name__ == '__main__':
realm = Realm()
myPortal = portal.Portal(realm)
checker = checkers.InMemoryUsernamePasswordDatabaseDontUse()
checker.addUser("user", "pass")
myPortal.registerChecker(checker)
reactor.listenTCP(8000, EchoFactory(myPortal))
reactor.run()
如果启用日志记录,您将看到类似本例产生的错误:
from twisted.python.log import startLogging;惊人日志(sys.stdout)
谢谢,太酷了。我会把它加到我的其他剧本里,我不知道发生了什么。我的原始代码缺少“I”。我仍然没有得到一个错误或正确的结果。脚本终端:erik@couriosity:/srv/twisted/ch9$python echo_cred.py 2013-10-04 09:30:32-0700[-]日志已打开。2013-10-04 09:30:32-0700[-]EchoFactory从8000开始2013-10-04 09:30:32-0700[-]从TELNET开始工厂:登录被拒绝,再见。与主机的连接丢失。按任意键继续…@Eman,我发现另一个打字错误。请参阅更新。我还添加了测试客户端代码,就是这样。有三次我错过了《阿凡达》。谢谢你的帮助
from zope.interface import Interface, implementer
from twisted.cred import checkers, credentials, portal, error
from twisted.internet import protocol, reactor, defer
from twisted.protocols import basic
class IProtocolAvatar(Interface):
def logout():
"""
Clean up per-login resources allocated to this avatar.
"""
@implementer(IProtocolAvatar)
class EchoAvatar():
def logout(self):
pass
class Echo(basic.LineReceiver):
portal = None
avatar = None
logout = None
def connectionLost(self, reason):
if self.logout:
self.logout()
self.avatar = None
self.logout = None
def lineReceived(self, line):
print('line received')
if not self.avatar:
username, password = line.strip().split()
# convert 2 text code
username, password = username.decode(), password.decode()
d = defer.maybeDeferred(self.tryLogin, username, password)
d.addCallbacks(self._cbLogin, self._ebLogin)
else:
self.sendLine(line)
def tryLogin(self, username, password):
if self.portal is not None:
return self.portal.login(
credentials.UsernamePassword(username, password),
None,
IProtocolAvatar
)
raise error.UnauthorizedLogin()
def _cbLogin(self, ial):
interface, avatar, logout = ial
self.avatar = avatar
self.logout = logout
# convert 2 byte code
self.sendLine("Login successful, please proceed.".encode())
def _ebLogin(self, failure):
self.sendLine("Login denied, goodbye.".encode())
self.transport.loseConnection()
class EchoFactory(protocol.Factory):
def __init__(self, portal):
self.portal = portal
def buildProtocol(self, addr):
proto = Echo()
proto.portal = self.portal
return proto
@implementer(portal.IRealm)
class Realm():
def requestAvatar(self, avatarId, mind, *interfaces):
if IProtocolAvatar in interfaces:
avatar = EchoAvatar()
return IProtocolAvatar, avatar, avatar.logout
raise NotImplementedError("This realm only supports the IProtocolAvatar interface.")
if __name__ == '__main__':
realm = Realm()
myPortal = portal.Portal(realm)
checker = checkers.InMemoryUsernamePasswordDatabaseDontUse()
checker.addUser("user", "pass")
myPortal.registerChecker(checker)
reactor.listenTCP(8000, EchoFactory(myPortal))
reactor.run()