【问题标题】:Add SMTP AUTH support to Python smtpd library... can't override the method?将 SMTP AUTH 支持添加到 Python smtpd 库...无法覆盖该方法?
【发布时间】:2010-11-11 10:12:55
【问题描述】:

所以,我想扩展 Python smtpd SMTPServer 类,以便它可以处理 SMTP AUTH 连接。看起来很简单……

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

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)

为什么它不调用我的方法?

在那之后,我认为我可能只是覆盖整个 found_terminator(self): 方法,但这似乎也不起作用。

 def found_terminator(self):
     # I add this to my child class and it never gets called... 

我是在做傻事还是……?也许我今天还没有完全醒来……

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()

【问题讨论】:

    标签: python smtp smtpd smtp-auth


    【解决方案1】:

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

    说明:

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

    请注意,SMTPChannel 中的函数需要以“smtp_”开头。例如,如果您想响应 HELP,您将创建 smtpd.SMTPChannel.smtp_HELP。

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

    class SMTPChannel(asynchat.async_chat):
      method = getattr(self, 'smtp_' + command, None)
    

    CodeThatWorks

    第 1 步:声明一个将被调用的 FUNCTION

    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 到 localhost 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
    

    【讨论】:

    • 谢谢老 FlyingV:我需要再看一遍。
    【解决方案2】:

    你需要扩展SMTPChannel——这就是smtp_verb 方法的实现;您对SMTPServer 的扩展只需要返回您自己的频道子类。

    【讨论】:

    • 呸,显然我今天睡着了。谢谢!
    • 一个如何覆盖 SMTPChannel 的小例子会让像我这样愚蠢的人开始...... :-)
    猜你喜欢
    • 1970-01-01
    • 2014-11-16
    • 1970-01-01
    • 2021-04-08
    • 2011-03-05
    • 1970-01-01
    • 2015-01-28
    • 2015-04-04
    • 1970-01-01
    相关资源
    最近更新 更多