Способ отклонить сообщение - вернуть строку с кодом ошибки из вашего process_message
метода; например,
return '550 No such user here'
Однако RFC 821 не позволяет возвращать код ошибки 550 после передачи данных сообщения (их следует возвращать после команды RCPT
), а модуль smtpd, к сожалению, не обеспечивает простого способа вернуть код ошибки на этом этапе. Кроме того, smtpd.py затрудняет создание подклассов для своих классов, используя автоматическое изменение атрибутов "private" с двойным подчеркиванием.
Вы можете использовать следующие пользовательские подклассы классов smtpd, но я не тестировал этот код:
class RecipientValidatingSMTPChannel(smtpd.SMTPChannel):
def smtp_RCPT(self, arg):
print >> smtpd.DEBUGSTREAM, '===> RCPT', arg
if not self._SMTPChannel__mailfrom:
self.push('503 Error: need MAIL command')
return
address = self._SMTPChannel__getaddr('TO:', arg)
if not address:
self.push('501 Syntax: RCPT TO: <address>')
return
if self._SMTPChannel__server.is_valid_recipient(address):
self._SMTPChannel__rcpttos.append(address)
print >> smtpd.DEBUGSTREAM, 'recips:', self._SMTPChannel__rcpttos
self.push('250 Ok')
else:
self.push('550 No such user here')
class MailProcessorServer(smtpd.SMTPServer):
def handle_accept(self):
conn, addr = self.accept()
print >> smtpd.DEBUGSTREAM, 'Incoming connection from %s' % repr(addr)
channel = RecipientValidatingSMTPChannel(self, conn, addr)
def is_valid_recipient(self, address):
# insert your own tests here, return True if it's valid
return False