URL: https://github.com/freeipa/freeipa/pull/284
Author: tomaskrizek
 Title: #284: ipautil: check for open ports on all resolved IPs
Action: opened

PR body:
"""
When a hostname is provided to host_port_open, it should check if
ports are open for ALL IPs that are resolved from the hostname, instead
of checking whether the port is reachable on at least one of the IPs.

https://fedorahosted.org/freeipa/ticket/6522
"""

To pull the PR as Git branch:
git remote add ghfreeipa https://github.com/freeipa/freeipa
git fetch ghfreeipa pull/284/head:pr284
git checkout pr284
From 15f9f9168630f44003e9975253b69ea921b1446e Mon Sep 17 00:00:00 2001
From: Tomas Krizek <tkri...@redhat.com>
Date: Tue, 29 Nov 2016 18:19:07 +0100
Subject: [PATCH] ipautil: check for open ports on all resolved IPs

When a hostname is provided to host_port_open, it should check if
ports are open for ALL IPs that are resolved from the hostname, instead
of checking whether the port is reachable on at least one of the IPs.

https://fedorahosted.org/freeipa/ticket/6522
---
 install/tools/ipa-replica-conncheck |  5 +++--
 ipapython/ipautil.py                | 39 +++++++++++++++++++++++++++++++------
 2 files changed, 36 insertions(+), 8 deletions(-)

diff --git a/install/tools/ipa-replica-conncheck b/install/tools/ipa-replica-conncheck
index 544116e..9a30385 100755
--- a/install/tools/ipa-replica-conncheck
+++ b/install/tools/ipa-replica-conncheck
@@ -315,8 +315,9 @@ def port_check(host, port_list):
     ports_udp_warning = []  # conncheck could not verify that port is open
     for port in port_list:
         try:
-            port_open = ipautil.host_port_open(host, port.port,
-                    port.port_type, socket_timeout=CONNECT_TIMEOUT)
+            port_open = ipautil.host_port_open(
+                host, port.port, port.port_type,
+                socket_timeout=CONNECT_TIMEOUT, log_errors=True)
         except socket.gaierror:
             raise RuntimeError("Port check failed! Unable to resolve host name '%s'" % host)
         if port_open:
diff --git a/ipapython/ipautil.py b/ipapython/ipautil.py
index 1c95a81..167479d 100644
--- a/ipapython/ipautil.py
+++ b/ipapython/ipautil.py
@@ -55,6 +55,12 @@
 GEN_TMP_PWD_LEN = 12  # only for OTP password that is manually retyped by user
 
 
+PROTOCOL_NAMES = {
+    socket.SOCK_STREAM: 'tcp',
+    socket.SOCK_DGRAM: 'udp'
+}
+
+
 class UnsafeIPAddress(netaddr.IPAddress):
     """Any valid IP address with or without netmask."""
 
@@ -866,7 +872,17 @@ def user_input(prompt, default = None, allow_empty = True):
                 return ret
 
 
-def host_port_open(host, port, socket_type=socket.SOCK_STREAM, socket_timeout=None):
+def host_port_open(host, port, socket_type=socket.SOCK_STREAM,
+                   socket_timeout=None, log_errors=False):
+    """
+    host: either hostname or IP address;
+          if hostname is provided, port MUST be open on ALL resolved IPs
+
+    returns True is port is open, False otherwise
+    """
+    port_open = True
+
+    # port has to be open on ALL resolved IPs
     for res in socket.getaddrinfo(host, port, socket.AF_UNSPEC, socket_type):
         af, socktype, proto, _canonname, sa = res
         try:
@@ -874,7 +890,7 @@ def host_port_open(host, port, socket_type=socket.SOCK_STREAM, socket_timeout=No
                 s = socket.socket(af, socktype, proto)
             except socket.error:
                 s = None
-                continue
+                raise
 
             if socket_timeout is not None:
                 s.settimeout(socket_timeout)
@@ -884,15 +900,26 @@ def host_port_open(host, port, socket_type=socket.SOCK_STREAM, socket_timeout=No
             if socket_type == socket.SOCK_DGRAM:
                 s.send('')
                 s.recv(512)
-
-            return True
         except socket.error:
-            pass
+            port_open = False
+
+            if log_errors:
+                msg = ('Failed to connect to port %(port)d %(proto)s on '
+                       '%(addr)s' % dict(port=port,
+                                         proto=PROTOCOL_NAMES[socket_type],
+                                         addr=sa[0]))
+
+                # Do not log udp failures as errors (to be consistent with
+                # the rest of the code that checks for open ports)
+                if socket_type == socket.SOCK_DGRAM:
+                    root_logger.debug(msg)
+                else:
+                    root_logger.error(msg)
         finally:
             if s:
                 s.close()
 
-    return False
+    return port_open
 
 def bind_port_responder(port, socket_type=socket.SOCK_STREAM, socket_timeout=None, responder_data=None):
     host = None   # all available interfaces
-- 
Manage your subscription for the Freeipa-devel mailing list:
https://www.redhat.com/mailman/listinfo/freeipa-devel
Contribute to FreeIPA: http://www.freeipa.org/page/Contribute/Code

Reply via email to