diff --git a/management/mailconfig.py b/management/mailconfig.py index b4d51ff0..a9a2c47b 100755 --- a/management/mailconfig.py +++ b/management/mailconfig.py @@ -3,6 +3,7 @@ import subprocess, shutil, os, sqlite3, re import utils from email_validator import validate_email as validate_email_, EmailNotValidError +import idna def validate_email(email, mode=None): # Checks that an email address is syntactically valid. Returns True/False. @@ -52,9 +53,9 @@ def sanitize_idn_email_address(email): # to the underlying protocols. try: localpart, domainpart = email.split("@") - domainpart = domainpart.encode("idna").decode('ascii') + domainpart = idna.encode(domainpart).decode('ascii') return localpart + "@" + domainpart - except: + except idna.IDNAError: # Domain part is not IDNA-valid, so leave unchanged. If there # are non-ASCII characters it will be filtered out by # validate_email. @@ -65,9 +66,9 @@ def prettify_idn_email_address(email): # names in IDNA in the database, but we want to show Unicode to the user. try: localpart, domainpart = email.split("@") - domainpart = domainpart.encode("ascii").decode('idna') + domainpart = idna.decode(domainpart.encode("ascii")) return localpart + "@" + domainpart - except: + except (UnicodeError, idna.IDNAError): # Failed to decode IDNA. Should never happen. return email @@ -238,7 +239,7 @@ def get_domain(emailaddr, as_unicode=True): # Gets the domain part of an email address. Turns IDNA # back to Unicode for display. ret = emailaddr.split('@', 1)[1] - if as_unicode: ret = ret.encode('ascii').decode('idna') + if as_unicode: ret = idna.decode(ret.encode('ascii')) return ret def get_mail_domains(env, filter_aliases=lambda alias : True): diff --git a/management/status_checks.py b/management/status_checks.py index a8df7557..14d95a8d 100755 --- a/management/status_checks.py +++ b/management/status_checks.py @@ -10,6 +10,7 @@ import sys, os, os.path, re, subprocess, datetime, multiprocessing.pool import dns.reversename, dns.resolver import dateutil.parser, dateutil.tz +import idna from dns_update import get_dns_zones, build_tlsa_record, get_custom_dns_config, get_secondary_dns from web_update import get_web_domains, get_default_www_redirects, get_domain_ssl_files @@ -259,7 +260,7 @@ def run_domain_checks_on_domain(domain, rounded_time, env, dns_domains, dns_zone output = BufferedOutput() # The domain is IDNA-encoded, but for display use Unicode. - output.add_heading(domain.encode('ascii').decode('idna')) + output.add_heading(idna.decode(domain.encode('ascii'))) if domain == env["PRIMARY_HOSTNAME"]: check_primary_hostname_dns(domain, env, output, dns_domains, dns_zonefiles) diff --git a/setup/management.sh b/setup/management.sh index 531e7800..ff82a23a 100755 --- a/setup/management.sh +++ b/setup/management.sh @@ -5,7 +5,7 @@ source setup/functions.sh # build-essential libssl-dev libffi-dev python3-dev: Required to pip install cryptography. apt_install python3-flask links duplicity libyaml-dev python3-dnspython python3-dateutil \ build-essential libssl-dev libffi-dev python3-dev -hide_output pip3 install rtyaml email_validator cryptography +hide_output pip3 install rtyaml email_validator idna cryptography # email_validator is repeated in setup/questions.sh # Create a backup directory and a random key for encrypting backups.