aboutsummaryrefslogtreecommitdiffstats
path: root/Mailman
diff options
context:
space:
mode:
Diffstat (limited to 'Mailman')
-rw-r--r--Mailman/Cgi/listinfo.py15
-rwxr-xr-xMailman/Cgi/subscribe.py24
-rwxr-xr-xMailman/Defaults.py.in8
3 files changed, 44 insertions, 3 deletions
diff --git a/Mailman/Cgi/listinfo.py b/Mailman/Cgi/listinfo.py
index b8704486..bab460b6 100644
--- a/Mailman/Cgi/listinfo.py
+++ b/Mailman/Cgi/listinfo.py
@@ -1,4 +1,4 @@
-# Copyright (C) 1998-2017 by the Free Software Foundation, Inc.
+# Copyright (C) 1998-2018 by the Free Software Foundation, Inc.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
@@ -21,6 +21,7 @@
# No lock needed in this script, because we don't change data.
import os
+import re
import cgi
import time
@@ -243,6 +244,18 @@ def list_listinfo(mlist, lang):
replacements['<mm-displang-box>'] = displang
replacements['<mm-lang-form-start>'] = mlist.FormatFormStart('listinfo')
replacements['<mm-fullname-box>'] = mlist.FormatBox('fullname', size=30)
+ # If reCAPTCHA is enabled, display its user interface
+ if mm_cfg.RECAPTCHA_SITE_KEY:
+ rlang = re.sub('_', '-', lang)
+ replacements['<mm-recaptcha-ui>'] = (
+ """<tr><td>&nbsp;</td><td>
+ <script src="https://www.google.com/recaptcha/api.js?hl=%s">
+ </script>
+ <div class="g-recaptcha" data-sitekey="%s"></div>
+ </td></tr>"""
+ % (rlang, mm_cfg.RECAPTCHA_SITE_KEY))
+ else:
+ replacements['<mm-recaptcha-ui>'] = ''
# Do the expansion.
doc.AddItem(mlist.ParseTags('listinfo.html', replacements, lang))
diff --git a/Mailman/Cgi/subscribe.py b/Mailman/Cgi/subscribe.py
index 232048d7..301d1733 100755
--- a/Mailman/Cgi/subscribe.py
+++ b/Mailman/Cgi/subscribe.py
@@ -1,4 +1,4 @@
-# Copyright (C) 1998-2017 by the Free Software Foundation, Inc.
+# Copyright (C) 1998-2018 by the Free Software Foundation, Inc.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
@@ -22,6 +22,9 @@ import os
import cgi
import time
import signal
+import urllib
+import urllib2
+import json
from Mailman import mm_cfg
from Mailman import Utils
@@ -131,6 +134,25 @@ def process_form(mlist, doc, cgidata, lang):
os.environ.get('HTTP_X_FORWARDED_FOR',
os.environ.get('REMOTE_ADDR',
'unidentified origin')))
+
+ # Check reCAPTCHA submission, if enabled
+ if mm_cfg.RECAPTCHA_SECRET_KEY:
+ request = urllib2.Request(
+ url = 'https://www.google.com/recaptcha/api/siteverify',
+ data = urllib.urlencode({
+ 'secret': mm_cfg.RECAPTCHA_SECRET_KEY,
+ 'response': cgidata.getvalue('g-recaptcha-response', ''),
+ 'remoteip': remote}))
+ try:
+ httpresp = urllib2.urlopen(request)
+ captcha_response = json.load(httpresp)
+ httpresp.close()
+ if not captcha_response['success']:
+ results.append(_('reCAPTCHA validation failed: %s' %
+ ', '.join(captcha_response['error-codes'])))
+ except urllib2.URLError as e:
+ results.append(_('reCAPTCHA could not be validated: %s' % e.reason))
+
# Are we checking the hidden data?
if mm_cfg.SUBSCRIBE_FORM_SECRET:
now = int(time.time())
diff --git a/Mailman/Defaults.py.in b/Mailman/Defaults.py.in
index 309d0ba3..4406a1f3 100755
--- a/Mailman/Defaults.py.in
+++ b/Mailman/Defaults.py.in
@@ -1,6 +1,6 @@
# -*- python -*-
-# Copyright (C) 1998-2017 by the Free Software Foundation, Inc.
+# Copyright (C) 1998-2018 by the Free Software Foundation, Inc.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
@@ -131,6 +131,12 @@ SUBSCRIBE_FORM_SECRET = None
# test.
SUBSCRIBE_FORM_MIN_TIME = seconds(5)
+# Use Google reCAPTCHA to protect the subscription form from spam bots. The
+# following must be set to a pair of keys issued by the reCAPTCHA service at
+# https://www.google.com/recaptcha/admin
+RECAPTCHA_SITE_KEY = None
+RECAPTCHA_SECRET_KEY = None
+
# Installation wide ban list. This is a list of email addresses and regexp
# patterns (beginning with ^) which are not allowed to subscribe to any lists
# in the installation. This supplements the individual list's ban_list.