summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Mailman/Cgi/admindb.py8
-rw-r--r--Mailman/Cgi/confirm.py24
-rw-r--r--Mailman/Cgi/create.py4
-rw-r--r--Mailman/Cgi/options.py2
-rw-r--r--Mailman/Defaults.py.in18
-rw-r--r--Mailman/MTA/Postfix.py45
-rw-r--r--Mailman/Queue/LMTPRunner.py2
-rw-r--r--Mailman/SecurityManager.py21
-rw-r--r--Mailman/configuration.py2
9 files changed, 70 insertions, 56 deletions
diff --git a/Mailman/Cgi/admindb.py b/Mailman/Cgi/admindb.py
index 7d762a172..a589d1019 100644
--- a/Mailman/Cgi/admindb.py
+++ b/Mailman/Cgi/admindb.py
@@ -179,7 +179,7 @@ def main():
mlist.Save()
return
- admindburl = mlist.GetScriptURL('admindb', absolute=1)
+ admindburl = mlist.GetScriptURL('admindb')
form = Form(admindburl)
# Add the instructions template
if details == 'instructions':
@@ -199,7 +199,7 @@ def main():
_('Discard all messages marked <em>Defer</em>')
))
# Add a link back to the overview, if we're not viewing the overview!
- adminurl = mlist.GetScriptURL('admin', absolute=1)
+ adminurl = mlist.GetScriptURL('admin')
d = {'listname' : mlist.real_name,
'detailsurl': admindburl + '?details=instructions',
'summaryurl': admindburl,
@@ -265,7 +265,7 @@ def handle_no_list(msg=''):
doc.SetTitle(header)
doc.AddItem(Header(2, header))
doc.AddItem(msg)
- url = Utils.ScriptURL('admin', absolute=1)
+ url = Utils.ScriptURL('admin')
link = Link(url, _('list of available mailing lists.')).Format()
doc.AddItem(_('You must specify a list name. Here is the %(link)s'))
doc.AddItem('<hr>')
@@ -385,7 +385,7 @@ def show_helds_overview(mlist, form):
if not bysender:
return 0
# Add the by-sender overview tables
- admindburl = mlist.GetScriptURL('admindb', absolute=1)
+ admindburl = mlist.GetScriptURL('admindb')
table = Table(border=0)
form.AddItem(table)
senders = bysender.keys()
diff --git a/Mailman/Cgi/confirm.py b/Mailman/Cgi/confirm.py
index 783f2053d..626a80c02 100644
--- a/Mailman/Cgi/confirm.py
+++ b/Mailman/Cgi/confirm.py
@@ -86,7 +86,7 @@ def main():
return
days = int(config.PENDING_REQUEST_LIFE / config.days(1) + 0.5)
- confirmurl = mlist.GetScriptURL('confirm', absolute=1)
+ confirmurl = mlist.GetScriptURL('confirm')
# Avoid cross-site scripting attacks
safecookie = Utils.websafe(cookie)
badconfirmstr = _('''<b>Invalid confirmation string:</b>
@@ -189,7 +189,7 @@ def expunge(mlist, cookie):
def ask_for_cookie(mlist, doc, extra=''):
title = _('Enter confirmation cookie')
doc.SetTitle(title)
- form = Form(mlist.GetScriptURL('confirm', 1))
+ form = Form(mlist.GetScriptURL('confirm'))
table = Table(border=0, width='100%')
table.AddRow([Center(Bold(FontAttr(title, size='+1')))])
table.AddCellInfo(table.GetCurrentRowIndex(), 0,
@@ -227,7 +227,7 @@ def subscription_prompt(mlist, doc, cookie, userdesc):
title = _('Confirm subscription request')
doc.SetTitle(title)
- form = Form(mlist.GetScriptURL('confirm', 1))
+ form = Form(mlist.GetScriptURL('confirm'))
table = Table(border=0, width='100%')
table.AddRow([Center(Bold(FontAttr(title, size='+1')))])
table.AddCellInfo(table.GetCurrentRowIndex(), 0,
@@ -384,7 +384,7 @@ def subscription_confirm(mlist, doc, cookie, cgidata):
# The response
listname = mlist.real_name
title = _('Subscription request confirmed')
- optionsurl = mlist.GetOptionsURL(addr, absolute=1)
+ optionsurl = mlist.GetOptionsURL(addr)
doc.SetTitle(title)
doc.AddItem(Header(3, Bold(FontAttr(title, size='+2'))))
doc.AddItem(_('''\
@@ -434,7 +434,7 @@ def unsubscription_confirm(mlist, doc, cookie):
# The response
listname = mlist.real_name
title = _('Unsubscription request confirmed')
- listinfourl = mlist.GetScriptURL('listinfo', absolute=1)
+ listinfourl = mlist.GetScriptURL('listinfo')
doc.SetTitle(title)
doc.AddItem(Header(3, Bold(FontAttr(title, size='+2'))))
doc.AddItem(_("""\
@@ -454,7 +454,7 @@ def unsubscription_prompt(mlist, doc, cookie, addr):
i18n.set_language(lang)
doc.set_language(lang)
- form = Form(mlist.GetScriptURL('confirm', 1))
+ form = Form(mlist.GetScriptURL('confirm'))
table = Table(border=0, width='100%')
table.AddRow([Center(Bold(FontAttr(title, size='+1')))])
table.AddCellInfo(table.GetCurrentRowIndex(), 0,
@@ -529,7 +529,7 @@ def addrchange_confirm(mlist, doc, cookie):
# The response
listname = mlist.real_name
title = _('Change of address request confirmed')
- optionsurl = mlist.GetOptionsURL(newaddr, absolute=1)
+ optionsurl = mlist.GetOptionsURL(newaddr)
doc.SetTitle(title)
doc.AddItem(Header(3, Bold(FontAttr(title, size='+2'))))
doc.AddItem(_("""\
@@ -550,7 +550,7 @@ def addrchange_prompt(mlist, doc, cookie, oldaddr, newaddr, globally):
i18n.set_language(lang)
doc.set_language(lang)
- form = Form(mlist.GetScriptURL('confirm', 1))
+ form = Form(mlist.GetScriptURL('confirm'))
table = Table(border=0, width='100%')
table.AddRow([Center(Bold(FontAttr(title, size='+1')))])
table.AddCellInfo(table.GetCurrentRowIndex(), 0,
@@ -656,7 +656,7 @@ def heldmsg_confirm(mlist, doc, cookie):
def heldmsg_prompt(mlist, doc, cookie, id):
title = _('Cancel held message posting')
doc.SetTitle(title)
- form = Form(mlist.GetScriptURL('confirm', 1))
+ form = Form(mlist.GetScriptURL('confirm'))
table = Table(border=0, width='100%')
table.AddRow([Center(Bold(FontAttr(title, size='+1')))])
table.AddCellInfo(table.GetCurrentRowIndex(), 0,
@@ -752,7 +752,7 @@ def reenable_confirm(mlist, doc, cookie):
# The response
listname = mlist.real_name
title = _('Membership re-enabled.')
- optionsurl = mlist.GetOptionsURL(addr, absolute=1)
+ optionsurl = mlist.GetOptionsURL(addr)
doc.SetTitle(title)
doc.AddItem(Header(3, Bold(FontAttr(title, size='+2'))))
doc.AddItem(_("""\
@@ -769,7 +769,7 @@ def reenable_confirm(mlist, doc, cookie):
def reenable_prompt(mlist, doc, cookie, list, member):
title = _('Re-enable mailing list membership')
doc.SetTitle(title)
- form = Form(mlist.GetScriptURL('confirm', 1))
+ form = Form(mlist.GetScriptURL('confirm'))
table = Table(border=0, width='100%')
table.AddRow([Center(Bold(FontAttr(title, size='+1')))])
table.AddCellInfo(table.GetCurrentRowIndex(), 0,
@@ -782,7 +782,7 @@ def reenable_prompt(mlist, doc, cookie, list, member):
realname = mlist.real_name
info = mlist.getBounceInfo(member)
if not info:
- listinfourl = mlist.GetScriptURL('listinfo', absolute=1)
+ listinfourl = mlist.GetScriptURL('listinfo')
# They've already be unsubscribed
table.AddRow([_("""We're sorry, but you have already been unsubscribed
from this mailing list. To re-subscribe, please visit the
diff --git a/Mailman/Cgi/create.py b/Mailman/Cgi/create.py
index 1ae8867cf..378fa8f37 100644
--- a/Mailman/Cgi/create.py
+++ b/Mailman/Cgi/create.py
@@ -232,8 +232,8 @@ def process_request(doc, cgidata):
text, mlist.preferred_language)
msg.send(mlist)
# Success!
- listinfo_url = mlist.GetScriptURL('listinfo', absolute=True)
- admin_url = mlist.GetScriptURL('admin', absolute=True)
+ listinfo_url = mlist.GetScriptURL('listinfo')
+ admin_url = mlist.GetScriptURL('admin')
create_url = Utils.ScriptURL('create')
title = _('Mailing list creation results')
diff --git a/Mailman/Cgi/options.py b/Mailman/Cgi/options.py
index bfc63920e..fceeaaaf6 100644
--- a/Mailman/Cgi/options.py
+++ b/Mailman/Cgi/options.py
@@ -487,7 +487,7 @@ address. Upon confirmation, any other mailing list containing the address
# drop them back into their options page, because that's gone now!
fqdn_listname = mlist.GetListEmail()
owneraddr = mlist.GetOwnerEmail()
- url = mlist.GetScriptURL('listinfo', absolute=1)
+ url = mlist.GetScriptURL('listinfo')
title = _('Unsubscription results')
doc.SetTitle(title)
diff --git a/Mailman/Defaults.py.in b/Mailman/Defaults.py.in
index 9149110c6..a1e11e550 100644
--- a/Mailman/Defaults.py.in
+++ b/Mailman/Defaults.py.in
@@ -718,7 +718,7 @@ USE_MAILDIR = No
USE_LMTP = No
# NOTE: If you set USE_LMTP = Yes, add the following line to your mailman.cfg
# file (uncommented of course!)
-# QRUNNERS.append(('LMTPRunner', 1))
+# add_runner('LMTPRunner')
# Change LMTP_HOST and LMTP_PORT for your convenience.
# You should be careful enough to use firewall if you
@@ -726,18 +726,30 @@ USE_LMTP = No
LMTP_HOST = 'localhost'
LMTP_PORT = 8025
+# Name of the domains which operate on LMTP mailman only.
+# Currently valid only for Postfix alias generation.
+LMTP_ONLY_DOMAINS = []
+
+# If the list is not present in LMTP_ONLY_DOMAINS, LMTPRunner would return
+# 550 response to the master SMTP agent. This may cause 'bounce spam relay'
+# in that a spammer expects to deliver the message as bounce info to the
+# 'From:' address. You can override this behavior by setting
+# LMTP_ERR_550 = '250 Ok. But, blackholed because mailbox unavailable'.
+LMTP_ERR_550 = '550 Requested action not taken: mailbox unavailable'
+
# Experimental WSGI Server.
#
# You must enable PROXY of Apache httpd server and configure to pass Mailman
# CGI requests to this WSGI Server:
#
-# ProxyPass /mailman/ http://localhost:2580/
+# ProxyPass /mailman/ http://localhost:2580/mailman/
#
+# Note that local URI part should be the same.
# XXX If you are running Apache 2.2, you will probably also want to set
# ProxyPassReverseCookiePath
#
# Also you have to add following line to <prefix>/etc/mailman.cfg
-# QRUNNERS.append(('HTTPRunner', 1))
+# add_runner('HTTPRunner')
HTTP_HOST = 'localhost'
HTTP_PORT = 2580
diff --git a/Mailman/MTA/Postfix.py b/Mailman/MTA/Postfix.py
index 96645f40a..595581718 100644
--- a/Mailman/MTA/Postfix.py
+++ b/Mailman/MTA/Postfix.py
@@ -168,9 +168,11 @@ def _addvirtual(mlist, fp):
# Blech.
-def _check_for_virtual_loopaddr(mlist, filename):
+def _check_for_virtual_loopaddr(mlist, filename, func):
loopaddr = mlist.no_reply_address
loopdest = Utils.ParseEmail(loopaddr)[0]
+ if func is _addtransport:
+ loopdest = 'local:' + loopdest
infp = open(filename)
omask = os.umask(007)
try:
@@ -212,6 +214,9 @@ def _check_for_virtual_loopaddr(mlist, filename):
def _addtransport(mlist, fp):
+ # Set up the mailman-loop address
+ loopaddr = mlist.no_reply_address
+ loopdest = Utils.ParseEmail(loopaddr)[0]
# create/add postfix transport file for mailman
fp.seek(0, 2)
if not fp.tell():
@@ -220,11 +225,24 @@ def _addtransport(mlist, fp):
# binary hash file transport.db. YOU SHOULD NOT MANUALLY EDIT THIS FILE
# unless you know what you're doing, and can keep the two files properly
# in sync. If you screw it up, you're on your own.
-"""
- if mlist is None:
- return
+
+# LOOP ADDRESSES START
+%s\tlocal:%s
+# LOOP ADDRESSES END
+""" % (loopaddr, loopdest)
+ # List LMTP_ONLY_DOMAINS
+ if config.LMTP_ONLY_DOMAINS:
+ print >> fp, '# LMTP ONLY DOMAINS START'
+ for dom in config.LMTP_ONLY_DOMAINS:
+ print >> fp, '%s\tlmtp:%s:%s' % (dom,
+ config.LMTP_HOST,
+ config.LMTP_PORT)
+ print >> fp, '# LMTP ONLY DOMAINS END\n'
listname = mlist.internal_name()
hostname = mlist.host_name
+ # No need of individual local part if the domain is LMTP only
+ if hostname in config.LMTP_ONLY_DOMAINS:
+ return
fieldsz = len(listname) + len(hostname) + len('-unsubscribe') + 1
# The text file entries get a little extra info
print >> fp, '# STANZA START: %s@%s' % (listname, hostname)
@@ -256,8 +274,8 @@ def _do_create(mlist, textfile, func):
finally:
fp.close()
# Now double check the virtual plain text file
- if func is _addvirtual:
- _check_for_virtual_loopaddr(mlist, textfile)
+ if func in (_addvirtual, _addtransport):
+ _check_for_virtual_loopaddr(mlist, textfile, func)
def create(mlist, cgi=False, nolock=False, quiet=False):
@@ -268,11 +286,13 @@ def create(mlist, cgi=False, nolock=False, quiet=False):
lock.lock()
# Do the aliases file, which need to be done in any case
try:
- _do_create(mlist, ALIASFILE, _addlist)
if config.USE_LMTP:
_do_create(mlist, TRPTFILE, _addtransport)
- if mlist and mlist.host_name in config.POSTFIX_STYLE_VIRTUAL_DOMAINS:
- _do_create(mlist, VIRTFILE, _addvirtual)
+ _do_create(None, ALIASFILE, _addlist)
+ else:
+ _do_create(mlist, ALIASFILE, _addlist)
+ if mlist.host_name in config.POSTFIX_STYLE_VIRTUAL_DOMAINS:
+ _do_create(mlist, VIRTFILE, _addvirtual)
_update_maps()
finally:
if lock:
@@ -334,11 +354,12 @@ def remove(mlist, cgi=False):
lock = makelock()
lock.lock()
try:
- _do_remove(mlist, ALIASFILE)
if config.USE_LMTP:
_do_remove(mlist, TRPTFILE)
- if mlist.host_name in config.POSTFIX_STYLE_VIRTUAL_DOMAINS:
- _do_remove(mlist, VIRTFILE)
+ else:
+ _do_remove(mlist, ALIASFILE)
+ if mlist.host_name in config.POSTFIX_STYLE_VIRTUAL_DOMAINS:
+ _do_remove(mlist, VIRTFILE)
# Regenerate the alias and map files
_update_maps()
finally:
diff --git a/Mailman/Queue/LMTPRunner.py b/Mailman/Queue/LMTPRunner.py
index d8bcfcf89..3e6e6f46b 100644
--- a/Mailman/Queue/LMTPRunner.py
+++ b/Mailman/Queue/LMTPRunner.py
@@ -68,7 +68,7 @@ DASH = '-'
CRLF = '\r\n'
ERR_451 = '451 Requested action aborted: error in processing'
ERR_502 = '502 Error: command HELO not implemented'
-ERR_550 = '550 Requested action not taken: mailbox unavailable'
+ERR_550 = config.LMTP_ERR_550
# XXX Blech
smtpd.__version__ = 'Python LMTP queue runner 1.0'
diff --git a/Mailman/SecurityManager.py b/Mailman/SecurityManager.py
index 14b699594..3865071b5 100644
--- a/Mailman/SecurityManager.py
+++ b/Mailman/SecurityManager.py
@@ -227,26 +227,7 @@ class SecurityManager:
return False
def _cookie_path(self):
- # We could be reverse proxied, in which case our cookie path must
- # match the path as seen by the upstream server, otherwise the client
- # won't send us our cookie data. We try to figure this out by looking
- # at the HTTP_REFERER header, which should include the uri of the
- # admin login screen as seen by the client. This is a hack because
- # we're not guaranteed to see that envar, but there's really no other
- # way to do it -- the original uri that's proxied to us is not
- # included in the backend request. XXX what happens when Apache 2.2's
- # ProxyPassReverseCookiePath is set?
- target = '%s/%s' % (os.environ['SCRIPT_NAME'], self.fqdn_listname)
- referer = os.environ.get('HTTP_REFERER')
- if not referer:
- return target
- # Python 2.5 XXX urlparse(referer).path
- path = urlparse(referer)[2]
- i = path.find(target)
- if i < 0:
- return target
- prefix = path[:i]
- return prefix + target
+ return '/'.join(os.environ['SCRIPT_NAME'].split('/')[:-1]) + '/'
def MakeCookie(self, authcontext, user=None):
key, secret = self.AuthContextInfo(authcontext, user)
diff --git a/Mailman/configuration.py b/Mailman/configuration.py
index bf2da60fc..0cb656c89 100644
--- a/Mailman/configuration.py
+++ b/Mailman/configuration.py
@@ -148,7 +148,7 @@ class Configuration(object):
E.g. 'HTTPRunner' or 'LMTPRunner'. count is the number of qrunner
slices to create, by default, 1.
"""
- self.QRUNNERS.append((name, count))
+ Defaults.QRUNNERS.append((name, count))