将SMTP验证支持添加到Python smtpd库。。。can';你不能重写这个方法吗?

将SMTP验证支持添加到Python smtpd库。。。can';你不能重写这个方法吗?,python,smtp,smtpd,smtp-auth,Python,Smtp,Smtpd,Smtp Auth,因此,我想扩展Python smtpd SMTPServer类,以便它能够处理SMTP身份验证连接。看起来很简单 所以,看起来我可以这样开始: def smtp_EHLO(self, arg): print 'got in arg: ', arg # do stuff here... 但出于某种原因,这永远不会被调用。Python smtpd库调用其他类似的方法,如下所示: method = None i = line.find(' ')

因此,我想扩展Python smtpd SMTPServer类,以便它能够处理SMTP身份验证连接。看起来很简单

所以,看起来我可以这样开始:

def smtp_EHLO(self, arg):
    print 'got in arg: ', arg
    # do stuff here...
但出于某种原因,这永远不会被调用。Python smtpd库调用其他类似的方法,如下所示:

        method = None
        i = line.find(' ')
        if i < 0:
            command = line.upper()
            arg = None
        else:
            command = line[:i].upper()
            arg = line[i+1:].strip()
        method = getattr(self, 'smtp_' + command, None)
我是在做傻事还是。。。?也许我今天还没有完全醒来

import smtpd
import asyncore

class CustomSMTPServer(smtpd.SMTPServer):

    def smtp_EHLO(self, arg):

        print 'got in arg: ', arg

    def process_message(self, peer, mailfrom, rcpttos, data):
        print 'Receiving message from:', peer
        print 'Message addressed from:', mailfrom
        print 'Message addressed to  :', rcpttos
        print 'Message length        :', len(data)
        print 'HERE WE ARE MAN!'
        return

    # Implementation of base class abstract method
    def found_terminator(self):
        print 'THIS GOT CALLED RIGHT HERE!'

        line = EMPTYSTRING.join(self.__line)
        print >> DEBUGSTREAM, 'Data:', repr(line)
        self.__line = []
        if self.__state == self.COMMAND:
            if not line:
                self.push('500 Error: bad syntax')
                return
            method = None
            i = line.find(' ')
            if i < 0:
                command = line.upper()
                arg = None
            else:
                command = line[:i].upper()
                arg = line[i+1:].strip()
            method = getattr(self, 'smtp_' + command, None)

            print 'looking for: ', command
            print 'method is: ', method

            if not method:
                self.push('502 Error: command "%s" not implemented' % command)
                return
            method(arg)
            return
        else:
            if self.__state != self.DATA:
                self.push('451 Internal confusion')
                return
            # Remove extraneous carriage returns and de-transparency according
            # to RFC 821, Section 4.5.2.
            data = []
            for text in line.split('\r\n'):
                if text and text[0] == '.':
                    data.append(text[1:])
                else:
                    data.append(text)
            self.__data = NEWLINE.join(data)
            status = self.__server.process_message(self.__peer,
                                                   self.__mailfrom,
                                                   self.__rcpttos,
                                                   self.__data)
            self.__rcpttos = []
            self.__mailfrom = None
            self.__state = self.COMMAND
            self.set_terminator('\r\n')
            if not status:
                self.push('250 Ok')
            else:
                self.push(status)

server = CustomSMTPServer(('127.0.0.1', 1025), None)

asyncore.loop()
导入smtpd
导入异步内核
类CustomSMTPServer(smtpd.SMTPServer):
def smtp_EHLO(自身,参数):
打印“已输入参数:”,参数
def过程_消息(自我、对等、邮件发件人、rcpttos、数据):
打印“从:'接收消息”,对等
打印“邮件收件人:”,邮件发件人
打印“邮件地址:”,rcpttos
打印“消息长度:”,len(数据)
打印“我们到了,伙计!”
返回
#基类抽象方法的实现
def发现_终止符(自身):
打印“这个就在这里!”
line=清空字符串。连接(self.\u行)
打印>>调试流,“数据:”,报告(行)
self._行=[]
如果self.\u state==self.COMMAND:
如果不是直线:
self.push('500错误:语法错误')
返回
方法=无
i=行。查找(“”)
如果i<0:
command=line.upper()
arg=无
其他:
命令=行[:i].upper()
arg=行[i+1:][.strip()
method=getattr(self'smtp_'+命令,无)
打印“查找:”,命令
打印“方法为:”,方法为
如果不是,方法:
self.push('502错误:命令“%s”未实现“%s”命令)
返回
方法(arg)
返回
其他:
如果是自我状态自我数据:
self.push('451内部混乱')
返回
#根据需要删除无关的回车和取消透明度
#根据RFC 821第4.5.2节。
数据=[]
对于第.split行('\r\n')中的文本:
如果文本和文本[0]='.':
data.append(文本[1:])
其他:
data.append(文本)
self.\uu data=NEWLINE.join(数据)
状态=self.\u服务器。处理消息(self.\u对等,
self.\uu mailfrom,
赛尔夫,
自我评估(数据)
self.\uu rcptos=[]
self.\uu mailfrom=无
self.\u state=self.COMMAND
self.set\u终止符('\r\n')
如果不是状态:
自我推送('250 Ok')
其他:
自我推送(状态)
服务器=CustomSMTPServer('127.0.0.1',1025),无)
asyncore.loop()

您需要扩展
SMTPChannel
——这就是
smtp\uu
动词方法的实现;您的SMTPServer扩展只需返回您自己的频道子类。

TL&DR:要向SMTPChannel添加附加功能,您只需声明一个函数,然后直接将其添加到smtpd.SMTPChannel

class FakeSMTPServer(smtpd.SMTPServer):

"""A Fake smtp server"""
        smtpd.SMTPChannel.smtp_HELP = smtp_HELP
说明:

SMTPChannel类用于响应用户在开放端口(通常为端口25)上输入的命令。它搜索可以回答哪些命令的方式是基于“内省”的,它检查函数的所有可用属性

请注意,SMTPChannel中的函数需要以“smtp\开头”。例如,如果您想响应帮助,您可以创建smtpd.SMTPChannel.smtp\u帮助

下面的函数来自详细介绍内省的源代码

class SMTPChannel(asynchat.async_chat):
  method = getattr(self, 'smtp_' + command, None)
有效的代码

步骤1:声明将被调用的函数

def smtp_HELP(self,arg):
  self.push("[8675309] GPT Answers to HELP")
步骤2:将以下功能添加到smtpd.SMTPChannel

class FakeSMTPServer(smtpd.SMTPServer):

"""A Fake smtp server"""
        smtpd.SMTPChannel.smtp_HELP = smtp_HELP
步骤3:Telnet到本地主机25并测试

Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
220 vics-imac.fios-router.home ESMTP Sendmail 6.7.4 Sunday 17 March 2019
HELP
[8675309] GPT Answers to HELP

啊,显然我今天睡着了。谢谢一个如何覆盖SMTPChannel的小例子会很好地让像我这样的愚蠢的人开始…:-)