Skip to content

bpo-35800: Remove smtpd.MailmanProxy since 3.11 #26617

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 9, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 0 additions & 18 deletions Doc/library/smtpd.rst
Original file line number Diff line number Diff line change
Expand Up @@ -142,24 +142,6 @@ PureProxy Objects
chance to make you into an open relay, so please be careful.


MailmanProxy Objects
--------------------


.. class:: MailmanProxy(localaddr, remoteaddr)

.. deprecated-removed:: 3.9 3.11

:class:`MailmanProxy` is deprecated, it depends on a ``Mailman``
module which no longer exists and therefore is already broken.


Create a new pure proxy server. Arguments are as per :class:`SMTPServer`.
Everything will be relayed to *remoteaddr*, unless local mailman configurations
knows about an address, in which case it will be handled via mailman. Note that
running this has a good chance to make you into an open relay, so please be
careful.

SMTPChannel Objects
-------------------

Expand Down
7 changes: 7 additions & 0 deletions Doc/whatsnew/3.11.rst
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,13 @@ fractions
Support :PEP:`515`-style initialization of :class:`~fractions.Fraction` from
string. (Contributed by Sergey B Kirpichev in :issue:`44258`.)


Removed
=======
* :class:`smtpd.MailmanProxy` is now removed as it is unusable without
an external module, ``mailman``. (Contributed by Dong-hee Na in :issue:`35800`.)


Optimizations
=============

Expand Down
93 changes: 0 additions & 93 deletions Lib/smtpd.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,13 +60,6 @@
# SMTP errors from the backend server at all. This should be fixed
# (contributions are welcome!).
#
# MailmanProxy - An experimental hack to work with GNU Mailman
# <www.list.org>. Using this server as your real incoming smtpd, your
# mailhost will automatically recognize and accept mail destined to Mailman
# lists when those lists are created. Every message not destined for a list
# gets forwarded to a real backend smtpd, as with PureProxy. Again, errors
# are not handled correctly yet.
#
#
# Author: Barry Warsaw <[email protected]>
#
Expand All @@ -91,7 +84,6 @@

__all__ = [
"SMTPChannel", "SMTPServer", "DebuggingServer", "PureProxy",
"MailmanProxy",
]

program = sys.argv[0]
Expand Down Expand Up @@ -777,91 +769,6 @@ def _deliver(self, mailfrom, rcpttos, data):
return refused


class MailmanProxy(PureProxy):
def __init__(self, *args, **kwargs):
warn('MailmanProxy is deprecated and will be removed '
'in future', DeprecationWarning, 2)
if 'enable_SMTPUTF8' in kwargs and kwargs['enable_SMTPUTF8']:
raise ValueError("MailmanProxy does not support SMTPUTF8.")
super(PureProxy, self).__init__(*args, **kwargs)

def process_message(self, peer, mailfrom, rcpttos, data):
from io import StringIO
from Mailman import Utils
from Mailman import Message
from Mailman import MailList
# If the message is to a Mailman mailing list, then we'll invoke the
# Mailman script directly, without going through the real smtpd.
# Otherwise we'll forward it to the local proxy for disposition.
listnames = []
for rcpt in rcpttos:
local = rcpt.lower().split('@')[0]
# We allow the following variations on the theme
# listname
# listname-admin
# listname-owner
# listname-request
# listname-join
# listname-leave
parts = local.split('-')
if len(parts) > 2:
continue
listname = parts[0]
if len(parts) == 2:
command = parts[1]
else:
command = ''
if not Utils.list_exists(listname) or command not in (
'', 'admin', 'owner', 'request', 'join', 'leave'):
continue
listnames.append((rcpt, listname, command))
# Remove all list recipients from rcpttos and forward what we're not
# going to take care of ourselves. Linear removal should be fine
# since we don't expect a large number of recipients.
for rcpt, listname, command in listnames:
rcpttos.remove(rcpt)
# If there's any non-list destined recipients left,
print('forwarding recips:', ' '.join(rcpttos), file=DEBUGSTREAM)
if rcpttos:
refused = self._deliver(mailfrom, rcpttos, data)
# TBD: what to do with refused addresses?
print('we got refusals:', refused, file=DEBUGSTREAM)
# Now deliver directly to the list commands
mlists = {}
s = StringIO(data)
msg = Message.Message(s)
# These headers are required for the proper execution of Mailman. All
# MTAs in existence seem to add these if the original message doesn't
# have them.
if not msg.get('from'):
msg['From'] = mailfrom
if not msg.get('date'):
msg['Date'] = time.ctime(time.time())
for rcpt, listname, command in listnames:
print('sending message to', rcpt, file=DEBUGSTREAM)
mlist = mlists.get(listname)
if not mlist:
mlist = MailList.MailList(listname, lock=0)
mlists[listname] = mlist
# dispatch on the type of command
if command == '':
# post
msg.Enqueue(mlist, tolist=1)
elif command == 'admin':
msg.Enqueue(mlist, toadmin=1)
elif command == 'owner':
msg.Enqueue(mlist, toowner=1)
elif command == 'request':
msg.Enqueue(mlist, torequest=1)
elif command in ('join', 'leave'):
# TBD: this is a hack!
if command == 'join':
msg['Subject'] = 'subscribe'
else:
msg['Subject'] = 'unsubscribe'
msg.Enqueue(mlist, torequest=1)


class Options:
setuid = True
classname = 'PureProxy'
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
:class:`smtpd.MailmanProxy` is now removed as it is unusable without an
external module, ``mailman``. Patch by Dong-hee Na.