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