emails: handle DNS TXT entries as the bytes they are (#41894)

This commit is contained in:
Frédéric Péters 2020-04-20 17:57:36 +02:00
parent df858e44a7
commit 22bbfcdb44
2 changed files with 11 additions and 8 deletions

View File

@ -20,6 +20,7 @@ import socket
from django.conf import settings
from django.core.exceptions import ValidationError
from django.utils.encoding import force_bytes
from django.utils.translation import ugettext_lazy as _
@ -53,16 +54,18 @@ def validate_email_spf(value, strict=False):
if not allowed_records:
return
email_domain = value.split('@')[-1]
txt_records = []
try:
txt_records = sum([r.strings for r in dns.resolver.query(email_domain, 'TXT')], [])
for txt_record in dns.resolver.query(email_domain, 'TXT'):
txt_records.extend(txt_record.strings)
except dns.exception.DNSException:
spf_records = []
else:
spf_records = [x for x in txt_records if x.startswith('v=spf1 ')]
pass
spf_records = [x for x in txt_records if x.startswith(b'v=spf1 ')]
if not strict and not spf_records:
return
allowed_records = [force_bytes(x) for x in allowed_records]
for spf_record in spf_records:
if '+all' in spf_record:
if b'+all' in spf_record:
return
for allowed_record in allowed_records:
if allowed_record in spf_record:

View File

@ -34,11 +34,11 @@ def dns_resolver(monkeypatch):
txt.strings = mock.create_autospec(name.Name)
txt.strings = mock.MagicMock()
if value == 'example-spf.com':
txt.strings = ['v=spf1 include:allowed_mx.com']
txt.strings = [b'v=spf1 include:allowed_mx.com']
elif value == 'example-spf-allow-all.com':
txt.strings = ['v=spf1 +all']
txt.strings = [b'v=spf1 +all']
elif value == 'example-invalid-spf.com':
txt.strings = ['v=spf1 include:not_allowed_mx.com']
txt.strings = [b'v=spf1 include:not_allowed_mx.com']
return [txt]
monkeypatch.setattr(dns.resolver, 'query', fn)