From b84035c4abcd133d3ef3812bb4ebb699aef01d72 Mon Sep 17 00:00:00 2001 From: mattk42 Date: Wed, 8 Jul 2015 10:27:14 -0600 Subject: [PATCH 1/2] Move to regex Patterns instead of InetAddresses in the whitelist --- .../http/auth/InetAddressWhitelist.java | 51 +++++++++++-------- 1 file changed, 29 insertions(+), 22 deletions(-) diff --git a/src/main/java/com/asquera/elasticsearch/plugins/http/auth/InetAddressWhitelist.java b/src/main/java/com/asquera/elasticsearch/plugins/http/auth/InetAddressWhitelist.java index dd416f2..268cafa 100644 --- a/src/main/java/com/asquera/elasticsearch/plugins/http/auth/InetAddressWhitelist.java +++ b/src/main/java/com/asquera/elasticsearch/plugins/http/auth/InetAddressWhitelist.java @@ -7,28 +7,30 @@ import java.util.Set; import java.util.Iterator; import java.util.Arrays; +import java.util.regex.Pattern; import java.net.InetAddress; import java.net.UnknownHostException; /** * * Wraps the configured whitelisted ips. - * It uses a set of {@link InetAddress} internally. + * It uses a set of {@link Pattern} internally. *

* * * - * @author Ernesto Miguez (ernesto.miguez@asquera.de) + * @author Matthew Knox */ public class InetAddressWhitelist { - private Set whitelist; + private Set whitelist; + /** * * * @param whitelist */ - public InetAddressWhitelist(Set whitelist) { + public InetAddressWhitelist(Set whitelist) { this.whitelist = whitelist; } @@ -39,44 +41,49 @@ public InetAddressWhitelist(Set whitelist) { * */ public InetAddressWhitelist(String[] sWhitelist) { - this(toInetAddress(Arrays.asList(sWhitelist))); + this(toPattern(Arrays.asList(sWhitelist))); } /** * Checks the request ip for inclusion. - * Since that ip comes in a {@link InetAddress} representation, it is checked - * against the whitelist. + * Since that ip comes in a {@link InetAddress} representation, the IP + * string is grabbed and compared to the patterns. * * @param candidate * @return if the ip is included in the whitelist */ public Boolean contains(InetAddress candidate) { - return this.whitelist.contains(candidate); + return contains(candidate.getHostAddress()); } /** * - * Checks the xForwardedFor defined client ip for inclusion. - * Since that ip comes in a String representation, it is checked against - * the String representation of the defined whitelist. + * Checks a defined client ip for inclusion. + * Since that ip comes in a String representation, it is matched against + * the patterns defined in the whitelist. * * @param candidate * @return if the ip is included in the String representation of the * whitelist ips */ public Boolean contains(String candidate) { - return getStringWhitelist().contains(candidate); + for (Pattern pattern : whitelist){ + if (pattern.matcher(candidate).matches()){ + return true; + } + } + return false; } /** * @return set of the string representations of the whitelist */ Set getStringWhitelist() { - Iterator iterator = this.whitelist.iterator(); + Iterator iterator = this.whitelist.iterator(); Set set = new HashSet(); while (iterator.hasNext()) { - InetAddress next = iterator.next(); - set.add(next.getHostAddress()); + Pattern next = iterator.next(); + set.add(next.toString()); } return set; } @@ -89,20 +96,20 @@ Set getStringWhitelist() { * @return a list of {@link InetAddress} objects * */ - static Set toInetAddress(List ips) { - List listIps = new ArrayList(); + static Set toPattern(List ips) { + List listIps = new ArrayList(); Iterator iterator = ips.iterator(); while (iterator.hasNext()) { String next = iterator.next(); try { - listIps.add(InetAddress.getByName(next)); - } catch (UnknownHostException e) { - String template = "an ip set in the whitelist settings raised an " + - "UnknownHostException: {}, dropping it"; + listIps.add(Pattern.compile(next)); + } catch (Exception e) { + String template = "an ip set in the whitelist settings raised an Exception, dropping it:" + + e.getMessage(); Loggers.getLogger(InetAddressWhitelist.class).info(template, e.getMessage()); } } - return new HashSet(listIps); + return new HashSet(listIps); } /** From a027e17a69c3feae4e665e6d99fba4df289086a5 Mon Sep 17 00:00:00 2001 From: mattk42 Date: Thu, 9 Jul 2015 07:35:02 -0600 Subject: [PATCH 2/2] Re-factored for ideintical original functionality with regex support. Added unit tests. --- .../http/auth/InetAddressWhitelist.java | 111 ++++++++++++------ .../http/auth/InetAddressWhitelistTest.java | 16 ++- 2 files changed, 88 insertions(+), 39 deletions(-) diff --git a/src/main/java/com/asquera/elasticsearch/plugins/http/auth/InetAddressWhitelist.java b/src/main/java/com/asquera/elasticsearch/plugins/http/auth/InetAddressWhitelist.java index 268cafa..a0edf0c 100644 --- a/src/main/java/com/asquera/elasticsearch/plugins/http/auth/InetAddressWhitelist.java +++ b/src/main/java/com/asquera/elasticsearch/plugins/http/auth/InetAddressWhitelist.java @@ -1,36 +1,36 @@ package com.asquera.elasticsearch.plugins.http.auth; -import org.elasticsearch.common.logging.Loggers; - +import java.net.Inet4Address; +import java.net.InetAddress; +import java.net.UnknownHostException; import java.util.ArrayList; -import java.util.List; +import java.util.Arrays; import java.util.HashSet; -import java.util.Set; import java.util.Iterator; -import java.util.Arrays; +import java.util.List; +import java.util.Set; import java.util.regex.Pattern; -import java.net.InetAddress; -import java.net.UnknownHostException; + +import org.elasticsearch.common.logging.Loggers; /** * * Wraps the configured whitelisted ips. - * It uses a set of {@link Pattern} internally. + * It uses a set of {@link InetAddress} internally. *

* * * - * @author Matthew Knox + * @author Ernesto Miguez (ernesto.miguez@asquera.de) */ public class InetAddressWhitelist { - private Set whitelist; - + private Set whitelist; /** * * * @param whitelist */ - public InetAddressWhitelist(Set whitelist) { + public InetAddressWhitelist(Set whitelist) { this.whitelist = whitelist; } @@ -41,49 +41,78 @@ public InetAddressWhitelist(Set whitelist) { * */ public InetAddressWhitelist(String[] sWhitelist) { - this(toPattern(Arrays.asList(sWhitelist))); + this(toInetAddress(Arrays.asList(sWhitelist))); } /** * Checks the request ip for inclusion. - * Since that ip comes in a {@link InetAddress} representation, the IP - * string is grabbed and compared to the patterns. + * Since that ip comes in a {@link InetAddress} representation, it is checked + * against the whitelist. * * @param candidate * @return if the ip is included in the whitelist */ public Boolean contains(InetAddress candidate) { - return contains(candidate.getHostAddress()); + if (this.whitelist.contains(candidate)){ + return true; + } + + //We also need to itterate through each of the patterns to make sure it doesn't match there + for (Object obj : whitelist){ + if (obj.getClass() == Pattern.class){ + Pattern pattern = (Pattern)obj; + if (pattern.matcher(candidate.getHostAddress()).matches()){ + return true; + } + } + } + + return false; } /** * - * Checks a defined client ip for inclusion. - * Since that ip comes in a String representation, it is matched against - * the patterns defined in the whitelist. + * Checks the xForwardedFor defined client ip for inclusion. + * Since that ip comes in a String representation, it is checked against + * the String representation of the defined whitelist. * * @param candidate * @return if the ip is included in the String representation of the * whitelist ips */ public Boolean contains(String candidate) { - for (Pattern pattern : whitelist){ - if (pattern.matcher(candidate).matches()){ - return true; - } - } - return false; + if (getStringWhitelist().contains(candidate)){ + return true; + } + + //We also need to itterate through each of the patterns to make sure it doesn't match there + for (Object obj : whitelist){ + if (obj.getClass() == Pattern.class){ + Pattern pattern = (Pattern)obj; + if (pattern.matcher(candidate).matches()){ + return true; + } + } + } + + return false; } /** * @return set of the string representations of the whitelist */ Set getStringWhitelist() { - Iterator iterator = this.whitelist.iterator(); + Iterator iterator = this.whitelist.iterator(); Set set = new HashSet(); while (iterator.hasNext()) { - Pattern next = iterator.next(); - set.add(next.toString()); + Object next = iterator.next(); + if (next.getClass() == Pattern.class){ + set.add(next.toString()); + } + else{ + InetAddress add = (InetAddress)next; + set.add(add.getHostAddress()); + } } return set; } @@ -96,20 +125,26 @@ Set getStringWhitelist() { * @return a list of {@link InetAddress} objects * */ - static Set toPattern(List ips) { - List listIps = new ArrayList(); + static Set toInetAddress(List ips) { + List listIps = new ArrayList(); Iterator iterator = ips.iterator(); while (iterator.hasNext()) { String next = iterator.next(); - try { - listIps.add(Pattern.compile(next)); - } catch (Exception e) { - String template = "an ip set in the whitelist settings raised an Exception, dropping it:" + - e.getMessage(); - Loggers.getLogger(InetAddressWhitelist.class).info(template, e.getMessage()); + if (next != null && next.startsWith("~")){ + Pattern pattern = Pattern.compile(next.substring(1)); + listIps.add(pattern); + } + else { + try { + listIps.add(InetAddress.getByName(next)); + } catch (UnknownHostException e) { + String template = "an ip set in the whitelist settings raised an " + + "UnknownHostException: {}, dropping it"; + Loggers.getLogger(InetAddressWhitelist.class).info(template, e.getMessage()); + } } } - return new HashSet(listIps); + return new HashSet(listIps); } /** @@ -120,4 +155,4 @@ public String toString() { return whitelist.toString(); } -} +} \ No newline at end of file diff --git a/src/test/java/com/asquera/elasticsearch/plugins/http/auth/InetAddressWhitelistTest.java b/src/test/java/com/asquera/elasticsearch/plugins/http/auth/InetAddressWhitelistTest.java index 8112a9a..78e0424 100644 --- a/src/test/java/com/asquera/elasticsearch/plugins/http/auth/InetAddressWhitelistTest.java +++ b/src/test/java/com/asquera/elasticsearch/plugins/http/auth/InetAddressWhitelistTest.java @@ -12,6 +12,7 @@ public class InetAddressWhitelistTest { static final String localhost = "localhost"; static final String containedIp = "1.1.1.1"; static String notContainedIp = "2.2.2.2"; + static String containedRegex = "~1.1.*"; private InetAddressWhitelist whitelist(String ip) { String[] w = { ip }; return new InetAddressWhitelist(w); @@ -21,10 +22,12 @@ private InetAddressWhitelist whitelist(String ip) { public void testInnetLocalhost() throws UnknownHostException { assertTrue(whitelist(localhost).contains(InetAddress.getByName(localhost))); } + @Test public void testInnetNullDefaultsToLocalhost() throws UnknownHostException { assertTrue(whitelist(null).contains(InetAddress.getByName(localhost))); } + @Test public void testStringLocalhostNotMatched() throws UnknownHostException { // the ip that "localhost" resolves to its matched ip and not the string @@ -46,10 +49,21 @@ public void testEmptyWhitelist() throws UnknownHostException { public void testNotContained() throws UnknownHostException { assertFalse(whitelist(containedIp).contains(notContainedIp)); } - + @Test public void invalidIpIsDropped() throws UnknownHostException { String invalidIp = "555.555.555.555"; assertFalse(whitelist(invalidIp).contains(invalidIp)); } + + @Test + public void testRegexContained() throws UnknownHostException { + assertTrue(whitelist(containedRegex).contains(containedIp)); + } + + @Test + public void testRegexNotContained() throws UnknownHostException { + assertFalse(whitelist(containedRegex).contains(notContainedIp)); + } + }