From 453332215667d6ff9595e6dedeeb3ed5ba7e5bdf Mon Sep 17 00:00:00 2001 From: Martin Basti Date: Thu, 27 Nov 2014 14:16:23 +0100 Subject: [PATCH] Throw zonemgr error message before installation proceeds Ticket: https://fedorahosted.org/freeipa/ticket/4771 Reviewed-By: Jan Cholasta --- ipalib/parameters.py | 35 +++++------------------------------ ipalib/util.py | 45 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+), 30 deletions(-) diff --git a/ipalib/parameters.py b/ipalib/parameters.py index 0cf14a4cd2900459ccd5d6d52912960c642223aa..7fa55fd6a6854ffa97da211ca5ef04b7ad974dc4 100644 --- a/ipalib/parameters.py +++ b/ipalib/parameters.py @@ -112,7 +112,7 @@ from errors import ConversionError, RequirementError, ValidationError from errors import PasswordMismatch, Base64DecodeError from constants import TYPE_ERROR, CALLABLE_ERROR, LDAP_GENERALIZED_TIME_FORMAT from text import Gettext, FixMe -from util import json_serialize +from util import json_serialize, validate_idna_domain from ipapython.dn import DN from ipapython.dnsutil import DNSName import dns.name @@ -1950,36 +1950,11 @@ class DNSNameParam(Param): error = None try: - domain_name = DNSName(value) - except dns.name.BadEscape: - error = _('invalid escape code in domain name') - except dns.name.EmptyLabel: - error = _('empty DNS label') - except dns.name.NameTooLong: - error = _('domain name cannot be longer than 255 characters') - except dns.name.LabelTooLong: - error = _('DNS label cannot be longer than 63 characters') - except dns.exception.SyntaxError: - error = _('invalid domain name') - else: - #compare if IDN normalized and original domain match - #there is N:1 mapping between unicode and IDNA names - #user should use normalized names to avoid mistakes - labels = re.split(u'[.\uff0e\u3002\uff61]', value, flags=re.UNICODE) - try: - map(lambda label: label.encode("ascii"), labels) - except UnicodeError: - # IDNA - is_nonnorm = any(encodings.idna.nameprep(x) != x for x in labels) - if is_nonnorm: - error = _("domain name '%(domain)s' should be normalized to" - ": %(normalized)s") % { - 'domain': value, - 'normalized': '.'.join([encodings.idna.nameprep(x) for x in labels])} - if error: + validate_idna_domain(value) + except ValueError as e: raise ConversionError(name=self.get_param_name(), index=index, - error=error) - value = domain_name + error=unicode(e)) + value = DNSName(value) if self.only_absolute and not value.is_absolute(): value = value.make_absolute() diff --git a/ipalib/util.py b/ipalib/util.py index 7a283106d70ba6a3e25cc7129d57b44b80876882..2c17d80a0427a5c7e45a6a0b64fa1f4d39fffa8a 100644 --- a/ipalib/util.py +++ b/ipalib/util.py @@ -28,6 +28,7 @@ import socket import re import decimal import dns +import encodings import netaddr from types import NoneType from weakref import WeakKeyDictionary @@ -277,6 +278,7 @@ def validate_zonemgr(zonemgr): def validate_zonemgr_str(zonemgr): zonemgr = normalize_zonemgr(zonemgr) + validate_idna_domain(zonemgr) zonemgr = DNSName(zonemgr) return validate_zonemgr(zonemgr) @@ -589,3 +591,46 @@ def validate_dnssec_forwarder(ip_addr): return False return True + + +def validate_idna_domain(value): + """ + Validate if value is valid IDNA domain. + + If domain is not valid, raises ValueError + :param value: + :return: + """ + error = None + + try: + DNSName(value) + except dns.name.BadEscape: + error = _('invalid escape code in domain name') + except dns.name.EmptyLabel: + error = _('empty DNS label') + except dns.name.NameTooLong: + error = _('domain name cannot be longer than 255 characters') + except dns.name.LabelTooLong: + error = _('DNS label cannot be longer than 63 characters') + except dns.exception.SyntaxError: + error = _('invalid domain name') + else: + #compare if IDN normalized and original domain match + #there is N:1 mapping between unicode and IDNA names + #user should use normalized names to avoid mistakes + labels = re.split(u'[.\uff0e\u3002\uff61]', value, flags=re.UNICODE) + try: + map(lambda label: label.encode("ascii"), labels) + except UnicodeError: + # IDNA + is_nonnorm = any(encodings.idna.nameprep(x) != x for x in labels) + if is_nonnorm: + error = _("domain name '%(domain)s' should be normalized to" + ": %(normalized)s") % { + 'domain': value, + 'normalized': '.'.join([encodings.idna.nameprep(x) + for x in labels])} + + if error: + raise ValueError(error) -- 2.1.0