URL: https://github.com/freeipa/freeipa/pull/1278
Author: felipevolpone
 Title: #1278: [Backport][ipa-4-5] Warning the user when using a loopback IP as 
forwarder
Action: opened

PR body:
"""
Manual backport of PR #903 

Changing the --forwarder option to accept a loopback IP.
Previously, an error would be raised, now we just show a
warning message.

Fixes: https://pagure.io/freeipa/issue/5801
Reviewed-By: Stanislav Laznicka <slazn...@redhat.com>
Reviewed-By: Martin Basti <mba...@redhat.com>
"""

To pull the PR as Git branch:
git remote add ghfreeipa https://github.com/freeipa/freeipa
git fetch ghfreeipa pull/1278/head:pr1278
git checkout pr1278
From d1c7c970d46d2e057acf633f68f6afcea6b55e84 Mon Sep 17 00:00:00 2001
From: Felipe Barreto <fbarr...@redhat.com>
Date: Mon, 13 Nov 2017 14:24:45 -0200
Subject: [PATCH] Warning the user when using a loopback IP as forwarder

Changing the --forwarder option to accept a loopback IP.
Previously, an error would be raised, now we just show a
warning message.

Fixes: https://pagure.io/freeipa/issue/5801
Reviewed-By: Stanislav Laznicka <slazn...@redhat.com>
Reviewed-By: Martin Basti <mba...@redhat.com>
---
 install/tools/ipa-dns-install |  2 +-
 ipapython/config.py           | 17 ++++++++++++-----
 ipapython/install/cli.py      |  5 ++++-
 ipapython/ipautil.py          | 19 +++++++++++++++++++
 ipaserver/install/dns.py      |  2 +-
 5 files changed, 37 insertions(+), 8 deletions(-)

diff --git a/install/tools/ipa-dns-install b/install/tools/ipa-dns-install
index cb6c5d887f..a497e5d356 100755
--- a/install/tools/ipa-dns-install
+++ b/install/tools/ipa-dns-install
@@ -51,7 +51,7 @@ def parse_options():
                       help="Master Server IP Address. This option can be used "
                            "multiple times")
     parser.add_option("--forwarder", dest="forwarders", action="append",
-                      type="ip", help="Add a DNS forwarder. This option can be used multiple times")
+                      type="ip_with_loopback", help="Add a DNS forwarder. This option can be used multiple times")
     parser.add_option("--no-forwarders", dest="no_forwarders", action="store_true",
                       default=False, help="Do not add any DNS forwarders, use root servers instead")
     parser.add_option("--auto-forwarders", dest="auto_forwarders",
diff --git a/ipapython/config.py b/ipapython/config.py
index 19abfc51ee..70187fae73 100644
--- a/ipapython/config.py
+++ b/ipapython/config.py
@@ -23,6 +23,7 @@
 # pylint: enable=deprecated-module
 from copy import copy
 import socket
+import functools
 
 from dns import resolver, rdatatype
 from dns.exception import DNSException
@@ -33,6 +34,7 @@
 # pylint: enable=import-error
 
 from ipapython.dn import DN
+from ipapython.ipautil import CheckedIPAddress, CheckedIPAddressLoopback
 
 try:
     # pylint: disable=ipa-forbidden-import
@@ -65,13 +67,16 @@ def format_usage(self, usage):
             ret += "%s %s\n" % (spacing, line)
         return ret
 
-def check_ip_option(option, opt, value):
-    from ipapython.ipautil import CheckedIPAddress
 
+def check_ip_option(option, opt, value, allow_loopback=False):
     try:
-        return CheckedIPAddress(value)
+        if allow_loopback:
+            return CheckedIPAddressLoopback(value)
+        else:
+            return CheckedIPAddress(value)
     except Exception as e:
-        raise OptionValueError("option %s: invalid IP address %s: %s" % (opt, value, e))
+        raise OptionValueError("option {}: invalid IP address {}: {}"
+                               .format(opt, value, e))
 
 def check_dn_option(option, opt, value):
     try:
@@ -85,9 +90,11 @@ class IPAOption(Option):
     security-sensitive such as passwords.
     """
     ATTRS = Option.ATTRS + ["sensitive"]
-    TYPES = Option.TYPES + ("ip", "dn")
+    TYPES = Option.TYPES + ("ip", "dn", "ip_with_loopback")
     TYPE_CHECKER = copy(Option.TYPE_CHECKER)
     TYPE_CHECKER["ip"] = check_ip_option
+    TYPE_CHECKER["ip_with_loopback"] = functools.partial(check_ip_option,
+                                                         allow_loopback=True)
     TYPE_CHECKER["dn"] = check_dn_option
 
 class IPAOptionParser(OptionParser):
diff --git a/ipapython/install/cli.py b/ipapython/install/cli.py
index bcee6d7256..c824315b6d 100644
--- a/ipapython/install/cli.py
+++ b/ipapython/install/cli.py
@@ -15,7 +15,8 @@
 import six
 
 from ipapython import admintool, ipa_log_manager
-from ipapython.ipautil import CheckedIPAddress, private_ccache
+from ipapython.ipautil import (CheckedIPAddress, CheckedIPAddressLoopback,
+                               private_ccache)
 
 from . import core, common
 
@@ -174,6 +175,8 @@ def add_options(cls, parser, positional=False):
                 kwargs['type'] = 'int'
             elif knob_scalar_type is long:
                 kwargs['type'] = 'long'
+            elif knob_scalar_type is CheckedIPAddressLoopback:
+                kwargs['type'] = 'ip_with_loopback'
             elif knob_scalar_type is CheckedIPAddress:
                 kwargs['type'] = 'ip'
             elif issubclass(knob_scalar_type, enum.Enum):
diff --git a/ipapython/ipautil.py b/ipapython/ipautil.py
index cc52af6d92..29d2a17dbd 100644
--- a/ipapython/ipautil.py
+++ b/ipapython/ipautil.py
@@ -244,6 +244,25 @@ def set_ip_net(self, ifnet):
         self._net = ifnet
 
 
+class CheckedIPAddressLoopback(CheckedIPAddress):
+    """IPv4 or IPv6 address with additional constraints with
+    possibility to use a loopback IP.
+    Reserved or link-local addresses are never accepted.
+    """
+    def __init__(self, addr, parse_netmask=True, allow_multicast=False):
+
+        super(CheckedIPAddressLoopback, self).__init__(
+                addr, parse_netmask=parse_netmask,
+                allow_multicast=allow_multicast,
+                allow_loopback=True)
+
+        if self.is_loopback():
+            # print is being used instead of a logger, because at this
+            # moment, in execution process, there is no logger configured
+            print("WARNING: You are using a loopback IP: {}".format(addr),
+                  file=sys.stderr)
+
+
 def valid_ip(addr):
     return netaddr.valid_ipv4(addr) or netaddr.valid_ipv6(addr)
 
diff --git a/ipaserver/install/dns.py b/ipaserver/install/dns.py
index 1c1aac06a1..81acb0c4a0 100644
--- a/ipaserver/install/dns.py
+++ b/ipaserver/install/dns.py
@@ -489,7 +489,7 @@ def zonemgr(self, value):
 
     forwarders = knob(
         # pylint: disable=invalid-sequence-index
-        typing.List[ipautil.CheckedIPAddress], None,
+        typing.List[ipautil.CheckedIPAddressLoopback], None,
         description=("Add a DNS forwarder. This option can be used multiple "
                      "times"),
         cli_names='--forwarder',
_______________________________________________
FreeIPA-devel mailing list -- freeipa-devel@lists.fedorahosted.org
To unsubscribe send an email to freeipa-devel-le...@lists.fedorahosted.org

Reply via email to