From 405da071d109ec683676d56fac3bccfc4606535e Mon Sep 17 00:00:00 2001 From: Felipe Barreto Date: Mon, 23 Oct 2017 09:45:56 -0200 Subject: 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 Reviewed-By: Martin Basti --- ipapython/config.py | 17 ++++++++++++----- ipapython/install/cli.py | 5 ++++- ipapython/ipautil.py | 19 +++++++++++++++++++ 3 files changed, 35 insertions(+), 6 deletions(-) (limited to 'ipapython') diff --git a/ipapython/config.py b/ipapython/config.py index 8393e0d5d..aa4b3e48f 100644 --- a/ipapython/config.py +++ b/ipapython/config.py @@ -23,6 +23,7 @@ from optparse import ( # 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 @@ from six.moves.urllib.parse import urlsplit # 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 @@ class IPAFormatter(IndentedHelpFormatter): 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: @@ -95,9 +100,11 @@ class IPAOption(Option): security-sensitive such as passwords. """ ATTRS = Option.ATTRS + ["sensitive", "constructor"] - TYPES = Option.TYPES + ("ip", "dn", "constructor") + TYPES = Option.TYPES + ("ip", "dn", "constructor", "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 TYPE_CHECKER["constructor"] = check_constructor diff --git a/ipapython/install/cli.py b/ipapython/install/cli.py index 1cac24d50..e8f67a3de 100644 --- a/ipapython/install/cli.py +++ b/ipapython/install/cli.py @@ -16,7 +16,8 @@ import six from ipapython import admintool from ipapython.ipa_log_manager import standard_logging_setup -from ipapython.ipautil import CheckedIPAddress, private_ccache +from ipapython.ipautil import (CheckedIPAddress, CheckedIPAddressLoopback, + private_ccache) from . import core, common @@ -166,6 +167,8 @@ class ConfigureTool(admintool.AdminTool): 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 71ed4a174..c4149a184 100644 --- a/ipapython/ipautil.py +++ b/ipapython/ipautil.py @@ -244,6 +244,25 @@ class CheckedIPAddress(UnsafeIPAddress): 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) -- cgit