Sandro Bonazzola has uploaded a new change for review.

Change subject: packaging: stricter FQDN validation
......................................................................

packaging: stricter FQDN validation

common_utils.getConfiguredIps now returns only Ips configured on
non loopback devices.

engine_validators.validateFQDN now tolerates that the FQDN provided
could not be resolved through a DNS but just only by /etc/hosts.
However, if the FQDN is resolved by DNS, it has also to reverse
resolve the ip address provided by the DNS.

engine-setup doesn't accept anymore a FQDN that doesn't pass the
validation, avoiding failures at later stages.

Change-Id: I512446c80dfa9c83adb179a445bfae82736d403f
Bug-Url: https://bugzilla.redhat.com/948311
Bug-Url: https://bugzilla.redhat.com/928667
Signed-off-by: Sandro Bonazzola <[email protected]>
---
M packaging/fedora/setup/common_utils.py
M packaging/fedora/setup/engine-setup.py
M packaging/fedora/setup/engine_validators.py
M packaging/fedora/setup/output_messages.py
4 files changed, 86 insertions(+), 46 deletions(-)


  git pull ssh://gerrit.ovirt.org:29418/ovirt-engine refs/changes/29/14529/1

diff --git a/packaging/fedora/setup/common_utils.py 
b/packaging/fedora/setup/common_utils.py
index 444cf20..94e02cc 100755
--- a/packaging/fedora/setup/common_utils.py
+++ b/packaging/fedora/setup/common_utils.py
@@ -576,27 +576,50 @@
     output, rc = execCmd(cmdList=cmd)
     return output
 
+
 def getConfiguredIps():
+    interfaces = {}
+    addresses = {}
+    interfacere = re.compile(
+        '^\d+:\s+(?P<interface>\w+):\s+<(?P<options>[^>]+).*'
+    )
+    addressre = re.compile(
+        '\s+inet (?P<address>\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}).+'
+        '\s+(?P<interface>\w+)$'
+    )
+    cmd = [
+        basedefs.EXEC_IP, "addr",
+    ]
     try:
-        iplist=set()
-        cmd = [
-            basedefs.EXEC_IP, "addr",
-        ]
-        output, rc = execCmd(cmdList=cmd, failOnError=True, 
msg=output_messages.ERR_EXP_GET_CFG_IPS_CODES)
-        ipaddrPattern=re.compile('\s+inet 
(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}).+')
-        list=output.splitlines()
-        for line in list:
-            foundIp = ipaddrPattern.search(line)
-            if foundIp:
-                if foundIp.group(1) != "127.0.0.1":
-                    ipAddr = foundIp.group(1)
-                    logging.debug("Found IP Address: %s"%(ipAddr))
-                    iplist.add(ipAddr)
-        return iplist
-    except:
+        output, rc = execCmd(
+            cmdList=cmd,
+            failOnError=True,
+            msg=output_messages.ERR_EXP_GET_CFG_IPS_CODES
+        )
+        for line in output.splitlines():
+            interfacematch = interfacere.match(line)
+            addressmatch = addressre.match(line)
+            if interfacematch is not None:
+                interfaces[interfacematch.group('interface')] = \
+                    'LOOPBACK' in interfacematch.group('options')
+            elif addressmatch is not None:
+                addresses.setdefault(
+                    addressmatch.group('interface'),
+                    []
+                ).append(
+                    addressmatch.group('address')
+                )
+    except Exception:
         logging.error(traceback.format_exc())
         raise Exception(output_messages.ERR_EXP_GET_CFG_IPS)
 
+    iplist = []
+    for interface, loopback in interfaces.iteritems():
+        if not loopback:
+            iplist.extend(addresses.get(interface, []))
+    return set(iplist)
+
+
 def getCurrentDateTime(isUtc=None):
     now = None
     if (isUtc is not None):
diff --git a/packaging/fedora/setup/engine-setup.py 
b/packaging/fedora/setup/engine-setup.py
index 19d6915..57a4f0b 100755
--- a/packaging/fedora/setup/engine-setup.py
+++ b/packaging/fedora/setup/engine-setup.py
@@ -305,7 +305,7 @@
                 "VALIDATION_FUNC" :validate.validateFQDN,
                 "DEFAULT_VALUE"   :socket.getfqdn(),
                 "MASK_INPUT"      : False,
-                "LOOSE_VALIDATION": True,
+                "LOOSE_VALIDATION": False,
                 "CONF_NAME"       : "HOST_FQDN",
                 "USE_DEFAULT"     : False,
                 "NEED_CONFIRM"    : False,
diff --git a/packaging/fedora/setup/engine_validators.py 
b/packaging/fedora/setup/engine_validators.py
index 0997945..c5f3fad 100644
--- a/packaging/fedora/setup/engine_validators.py
+++ b/packaging/fedora/setup/engine_validators.py
@@ -12,6 +12,7 @@
 import os.path
 import tempfile
 import cracklib
+import socket
 from setup_controller import Controller
 
 def validateNFSMountPoint(param, options=[]):
@@ -304,7 +305,7 @@
 
 
 def validateFQDN(param, options=[]):
-    logging.info("Validating %s as a FQDN"%(param))
+    logging.info("Validating %s as a FQDN on non loopback devices" % (param))
     # Ensure that it isn't an IP address.
     if re.match("\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}", param):
         logging.error(output_messages.ERR_CANT_USE_IP_AS_FQDN % (param))
@@ -323,17 +324,29 @@
         #resolve fqdn
         pattern = 'Address: (\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})'
         resolvedAddresses = _getPatternFromNslookup(param, pattern)
+        resolvedFromDNS = False
         if len(resolvedAddresses) < 1:
-            logging.error("Failed to resolve %s"%(param))
-            print output_messages.ERR_DIDNT_RESOLVED_IP%(param)
-            return False
-
+            logging.error("Failed to resolve %s using DNS."%(param))
+            try:
+                resolvedAddresses = set(socket.gethostbyname_ex(param)[2])
+            except socket.error:
+                #can't be resolved by /etc/hosts
+                print output_messages.ERR_DIDNT_RESOLVED_IP%(param)
+                return False
+            logging.warning('%s can be resolved only locally!' % param)
+        else:
+            resolvedFromDNS = True
         #string is generated here since we use it in all latter error messages
         prettyString = " ".join(["%s"%string for string in resolvedAddresses])
 
         #compare found IP with list of local IPs and match.
         if not resolvedAddresses.issubset(ipAddresses):
-            logging.error("the following address(es): %s are not configured on 
this host"%(prettyString))
+            logging.error(
+                (
+                    "the following address(es): %s can't be mapped to "
+                    "non loopback devices on this host"
+                ) %(prettyString)
+            )
             #different grammar for plural and single
             if len(resolvedAddresses) > 1:
                 print output_messages.ERR_IPS_NOT_CONFIGED%(prettyString, 
param)
@@ -342,27 +355,28 @@
             return False
 
         #reverse resolved IP and compare with given fqdn
-        counter = 0
-        pattern = '[\w\.-]+\s+name\s\=\s([\w\.\-]+)\.'
-        for address in resolvedAddresses:
-            addressSet = _getPatternFromNslookup(address, pattern)
-            reResolvedAddress = None
-            revResolved = False
-            if len(addressSet) > 0:
-                reResolvedAddress = addressSet.pop()
-                if reResolvedAddress.lower() == param.lower():
-                    counter += 1
-                    revResolved = True
-            if not revResolved:
-                logging.warn("%s did not reverse-resolve into 
%s"%(address,param))
-        if counter < 1:
-            logging.error("The following addresses: %s did not reverse resolve 
into %s"%(prettyString, param))
-            #different grammar for plural and single
-            if len(resolvedAddresses) > 1:
-                print output_messages.ERR_IPS_HAS_NO_PTR%(prettyString, param)
-            else:
-                print output_messages.ERR_IP_HAS_NO_PTR%(prettyString, param)
-            return False
+        if resolvedFromDNS:
+            counter = 0
+            pattern = '[\w\.-]+\s+name\s\=\s([\w\.\-]+)\.'
+            for address in resolvedAddresses:
+                addressSet = _getPatternFromNslookup(address, pattern)
+                reResolvedAddress = None
+                revResolved = False
+                if len(addressSet) > 0:
+                    reResolvedAddress = addressSet.pop()
+                    if reResolvedAddress.lower() == param.lower():
+                        counter += 1
+                        revResolved = True
+                if not revResolved:
+                    logging.warn("%s did not reverse-resolve into 
%s"%(address,param))
+            if counter < 1:
+                logging.error("The following addresses: %s did not reverse 
resolve into %s"%(prettyString, param))
+                #different grammar for plural and single
+                if len(resolvedAddresses) > 1:
+                    print output_messages.ERR_IPS_HAS_NO_PTR%(prettyString, 
param)
+                else:
+                    print output_messages.ERR_IP_HAS_NO_PTR%(prettyString, 
param)
+                return False
 
         #conditions passed
         return True
diff --git a/packaging/fedora/setup/output_messages.py 
b/packaging/fedora/setup/output_messages.py
index 2141da8..8c3bbde 100644
--- a/packaging/fedora/setup/output_messages.py
+++ b/packaging/fedora/setup/output_messages.py
@@ -366,8 +366,11 @@
 #validate fqdn
 ERR_EXP_CANT_FIND_IP="Could not find any configured IP address"
 ERR_DIDNT_RESOLVED_IP="%s did not resolve into an IP address"
-ERR_IPS_NOT_CONFIGED="Some or all of the IP addresses: (%s) which were 
resolved from the FQDN %s are not configured on any interface on this host"
-ERR_IPS_NOT_CONFIGED_ON_INT="The IP (%s) which was resolved from the FQDN %s 
is not configured on any interface on this host"
+ERR_IPS_NOT_CONFIGED="Some or all of the IP addresses: (%s) which were \
+resolved from the FQDN %s are not configured on any non loopback interface \
+on this host"
+ERR_IPS_NOT_CONFIGED_ON_INT="The IP (%s) which was resolved from the FQDN %s \
+is not configured on any non loopback interface on this host"
 ERR_IPS_HAS_NO_PTR="None of the IP addresses on this host(%s) holds a PTR 
record for the FQDN: %s"
 ERR_IP_HAS_NO_PTR="The IP %s does not hold a PTR record for the FQDN: %s"
 ERR_CANT_USE_IP_AS_FQDN="%s is an IP address and not a FQDN. A FQDN is needed \


--
To view, visit http://gerrit.ovirt.org/14529
To unsubscribe, visit http://gerrit.ovirt.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I512446c80dfa9c83adb179a445bfae82736d403f
Gerrit-PatchSet: 1
Gerrit-Project: ovirt-engine
Gerrit-Branch: engine_3.2
Gerrit-Owner: Sandro Bonazzola <[email protected]>
_______________________________________________
Engine-patches mailing list
[email protected]
http://lists.ovirt.org/mailman/listinfo/engine-patches

Reply via email to