Merge pull request #375 from ThomasWaldmann/validate-registration-email
validate email address in registration form
This commit is contained in:
commit
bd0fa0f040
75
nsupdate/accounts/registration_form.py
Normal file
75
nsupdate/accounts/registration_form.py
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
import re
|
||||||
|
|
||||||
|
import logging
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
from django import forms
|
||||||
|
from django.conf import settings
|
||||||
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
|
from registration.forms import RegistrationForm
|
||||||
|
|
||||||
|
import dns.resolver
|
||||||
|
import dns.name
|
||||||
|
|
||||||
|
|
||||||
|
resolver = dns.resolver.Resolver()
|
||||||
|
resolver.search = [dns.name.root, ]
|
||||||
|
resolver.lifetime = 5.0
|
||||||
|
resolver.nameservers = settings.NAMESERVERS
|
||||||
|
|
||||||
|
|
||||||
|
maildomain_blacklist = settings.MAILDOMAIN_BLACKLIST.strip().splitlines()
|
||||||
|
|
||||||
|
|
||||||
|
def check_mx(domain):
|
||||||
|
valid = False
|
||||||
|
try:
|
||||||
|
mx_answers = resolver.query(domain, 'MX')
|
||||||
|
# domain exists in DNS, domain has MX
|
||||||
|
mx_entries = sorted([(mx_rdata.preference, mx_rdata.exchange) for mx_rdata in mx_answers])
|
||||||
|
for preference, mx in mx_entries:
|
||||||
|
try:
|
||||||
|
addr_answers = resolver.query(mx, 'A')
|
||||||
|
except dns.resolver.NoAnswer:
|
||||||
|
addr_answers = resolver.query(mx, 'AAAA')
|
||||||
|
# MX has IP addr
|
||||||
|
mx_addrs = [addr_rdata.address for addr_rdata in addr_answers]
|
||||||
|
for mx_addr in mx_addrs:
|
||||||
|
if mx_addr not in (u'127.0.0.1', u'::1', u'0.0.0.0', ):
|
||||||
|
valid = True
|
||||||
|
break
|
||||||
|
if valid:
|
||||||
|
break
|
||||||
|
except (dns.resolver.Timeout, dns.resolver.NoAnswer, dns.resolver.NoNameservers, dns.resolver.NXDOMAIN, ):
|
||||||
|
# expected exceptions (e.g. due to non-existing or misconfigured crap domains)
|
||||||
|
pass
|
||||||
|
return valid
|
||||||
|
|
||||||
|
|
||||||
|
def check_blacklist(domain):
|
||||||
|
for blacklisted_re in maildomain_blacklist:
|
||||||
|
if re.search(blacklisted_re, domain):
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
class RegistrationFormValidateEmail(RegistrationForm):
|
||||||
|
def clean_email(self):
|
||||||
|
"""
|
||||||
|
Validate the supplied email address to avoid undeliverable email and mailer daemon spam.
|
||||||
|
"""
|
||||||
|
email = self.cleaned_data.get('email')
|
||||||
|
valid_mx = False
|
||||||
|
try:
|
||||||
|
domain = email.split('@')[1]
|
||||||
|
valid_mx = check_mx(domain)
|
||||||
|
except Exception as e:
|
||||||
|
logger.exception('RegistrationFormValidateEmail raised an exception:')
|
||||||
|
not_blacklisted = check_blacklist(domain)
|
||||||
|
if valid_mx and not_blacklisted:
|
||||||
|
return email
|
||||||
|
logger.info('RegistrationFormValidateEmail: rejecting email address %r' % email)
|
||||||
|
raise forms.ValidationError(_("Enter a valid email address."))
|
@ -51,6 +51,21 @@ BAD_AGENTS = set([]) # list can have str elements
|
|||||||
from netaddr import IPSet, IPAddress, IPNetwork
|
from netaddr import IPSet, IPAddress, IPNetwork
|
||||||
BAD_IPS_HOST = IPSet([]) # inner list can have IPAddress and IPNetwork elements
|
BAD_IPS_HOST = IPSet([]) # inner list can have IPAddress and IPNetwork elements
|
||||||
|
|
||||||
|
# nameservers used e.g. for MX lookups in the registration email validation.
|
||||||
|
# google / cloudflare DNS IPs are only given as example / fallback -
|
||||||
|
# please configure your own nameservers in your local settings file.
|
||||||
|
NAMESERVERS = ['8.8.8.8', '1.1.1.1', ]
|
||||||
|
|
||||||
|
# registration email validation: disallow specific email domains,
|
||||||
|
# e.g. domains that have a non-working mx / that are frequently abused.
|
||||||
|
# we use a multiline string here with one regex per line (used with re.search).
|
||||||
|
# the domains given below are just examples, please configure your own
|
||||||
|
# regexes in your local settings file.
|
||||||
|
MAILDOMAIN_BLACKLIST = """
|
||||||
|
mailcatch\.com$
|
||||||
|
mailspam\.xyz$
|
||||||
|
"""
|
||||||
|
|
||||||
# Local time zone for this installation. Choices can be found here:
|
# Local time zone for this installation. Choices can be found here:
|
||||||
# http://en.wikipedia.org/wiki/List_of_tz_zones_by_name
|
# http://en.wikipedia.org/wiki/List_of_tz_zones_by_name
|
||||||
# although not all choices may be available on all operating systems.
|
# although not all choices may be available on all operating systems.
|
||||||
@ -245,6 +260,7 @@ SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
|
|||||||
|
|
||||||
ACCOUNT_ACTIVATION_DAYS = 7
|
ACCOUNT_ACTIVATION_DAYS = 7
|
||||||
REGISTRATION_EMAIL_HTML = False # we override the text, but not the html email template
|
REGISTRATION_EMAIL_HTML = False # we override the text, but not the html email template
|
||||||
|
REGISTRATION_FORM = 'nsupdate.accounts.registration_form.RegistrationFormValidateEmail'
|
||||||
|
|
||||||
LOGIN_REDIRECT_URL = '/overview/'
|
LOGIN_REDIRECT_URL = '/overview/'
|
||||||
LOGOUT_REDIRECT_URL = '/'
|
LOGOUT_REDIRECT_URL = '/'
|
||||||
|
Loading…
x
Reference in New Issue
Block a user