diff --git a/dspace-api/src/main/java/org/dspace/authenticate/IPMatcher.java b/dspace-api/src/main/java/org/dspace/authenticate/IPMatcher.java index 7df36fc0f2..854eb39798 100644 --- a/dspace-api/src/main/java/org/dspace/authenticate/IPMatcher.java +++ b/dspace-api/src/main/java/org/dspace/authenticate/IPMatcher.java @@ -7,6 +7,8 @@ */ package org.dspace.authenticate; +import org.apache.log4j.Logger; + import java.net.Inet6Address; import java.net.UnknownHostException; @@ -30,9 +32,13 @@ import java.net.UnknownHostException; * * @version $Revision$ * @author Robert Tansley + * @author Ben Bosman + * @author Roeland Dillen */ public class IPMatcher { + private static Logger log = Logger.getLogger(IPMatcher.class); + /** Network to match */ private byte[] network; @@ -139,13 +145,26 @@ public class IPMatcher netmask[1] = (byte) ((fullMask & 0x00FF0000) >>> 16); netmask[2] = (byte) ((fullMask & 0x0000FF00) >>> 8); netmask[3] = (byte) (fullMask & 0x000000FF); + ipToBytes(ipPart, network, mustHave4); + if (log.isDebugEnabled()) { + log.debug("fullMask: "+fullMask); + for (int i = 0; i < network.length; i++) { + log.debug("network[" + i + "]: "+network[i]); + } + for (int i = 0; i < netmask.length; i++) { + log.debug("netmask[" + i + "]: "+netmask[i]); + } + } } else { - // full subnet specified + // full netmask specified + ipToBytes(parts[0],network,true); ipToBytes(parts[1], netmask, true); } + break; + case 1: // Get IP for (int i = 0; i < netmask.length; i++) @@ -166,6 +185,14 @@ public class IPMatcher } network = ip4ToIp6(network); netmask = ip4MaskToIp6(netmask); + if (log.isDebugEnabled()) { + for (int i = 0; i < network.length; i++) { + log.debug("network[" + i + "]: "+network[i]); + } + for (int i = 0; i < netmask.length; i++) { + log.debug("netmask[" + i + "]: "+netmask[i]); + } + } } } @@ -236,6 +263,7 @@ public class IPMatcher */ public boolean match(String ipIn) throws IPMatcherException { + log.debug("ipIn: "+ipIn); byte[] candidate; if (ipIn.indexOf(':') < 0) @@ -258,6 +286,13 @@ public class IPMatcher { if ((candidate[i] & netmask[i]) != (network[i] & netmask[i])) { + if (log.isDebugEnabled()) { + log.debug("candidate[i]: "+candidate[i]); + log.debug("netmask[i]: "+netmask[i]); + log.debug("candidate[i] & netmask[i]: "+(candidate[i] & netmask[i])); + log.debug("network[i]: "+network[i]); + log.debug("network[i] & netmask[i]: "+(network[i] & netmask[i])); + } return false; } } diff --git a/dspace-api/src/test/java/org/dspace/authenticate/IPMatcherTest.java b/dspace-api/src/test/java/org/dspace/authenticate/IPMatcherTest.java index df853a30a2..512786d14c 100644 --- a/dspace-api/src/test/java/org/dspace/authenticate/IPMatcherTest.java +++ b/dspace-api/src/test/java/org/dspace/authenticate/IPMatcherTest.java @@ -10,16 +10,20 @@ */ package org.dspace.authenticate; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - import org.dspace.AbstractUnitTest; import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test; +import java.util.ArrayList; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + /** * @author Mark Wood + * @author Ben Bosman + * @author Roeland Dillen */ public class IPMatcherTest extends AbstractUnitTest { @@ -27,6 +31,8 @@ public class IPMatcherTest extends AbstractUnitTest private static final String IP6_FULL_ADDRESS2 = "2001:18e8:3:171:218:8bff:fe2a:56a3"; private static final String IP6_MASKED_ADDRESS = "2001:18e8:3::/48"; + private final static int increment = 6; + private static IPMatcher ip6FullMatcher; private static IPMatcher ip6MaskedMatcher; @@ -116,7 +122,221 @@ public class IPMatcherTest extends AbstractUnitTest assertTrue("IPv6 masked match fails", ip6MaskedMatcher .match(IP6_FULL_ADDRESS2)); } - + + @Test + public void testIPv4MatchingSuccess() throws Exception + { + final IPMatcher ipMatcher = new IPMatcher("1.1.1.1"); + + assertTrue(ipMatcher.match("1.1.1.1")); + ArrayList exceptions = new ArrayList(); + exceptions.add("1.1.1.1"); + verifyAllIp4Except(exceptions, false, ipMatcher); + } + + @Test + public void testIPv4MatchingFailure() throws Exception + { + final IPMatcher ipMatcher = new IPMatcher("1.1.1.1"); + + assertFalse(ipMatcher.match("1.1.1.0")); + } + + @Test + public void testIPv6MatchingSuccess() throws Exception + { + final IPMatcher ipMatcher = new IPMatcher("::2"); + + assertTrue(ipMatcher.match("0:0:0:0:0:0:0:2")); + } + + @Test + public void testShortFormIPv6MatchingSuccess() throws Exception + { + final IPMatcher ipMatcher = new IPMatcher("::2"); + + assertTrue(ipMatcher.match("::2")); + } + + @Test + public void testIPv6MatchingFailure() throws Exception + { + final IPMatcher ipMatcher = new IPMatcher("::2"); + + assertFalse(ipMatcher.match("0:0:0:0:0:0:0:1")); + } + + + + @Test + public void testAsteriskMatchingSuccess() throws Exception + { + final IPMatcher ipMatcher = new IPMatcher("172.16"); + + assertTrue(ipMatcher.match("172.16.1.1")); + } + + @Test + public void testAsteriskMatchingFailure() throws Exception + { + final IPMatcher ipMatcher = new IPMatcher("172.16"); + + assertFalse(ipMatcher.match("172.15.255.255")); + } + + @Test + public void testIPv4CIDRMatchingSuccess() throws Exception + { + final IPMatcher ipMatcher = new IPMatcher("192.1.2.3/8"); + + assertTrue(ipMatcher.match("192.1.1.1")); + } + + @Test + public void testIPv4CIDRMatchingFailure() throws Exception + { + final IPMatcher ipMatcher = new IPMatcher("192.1.2.3/8"); + + assertTrue(ipMatcher.match("192.2.0.0")); + } + + @Test + public void test2IPv4CIDRMatchingSuccess() throws Exception + { + final IPMatcher ipMatcher = new IPMatcher("192.86.100.72/29"); + + assertTrue(ipMatcher.match("192.86.100.75")); + assertFalse(ipMatcher.match("192.86.100.71")); + assertFalse(ipMatcher.match("192.86.100.80")); + ArrayList exceptions = new ArrayList(); + exceptions.add("192.86.100.72"); + exceptions.add("192.86.100.73"); + exceptions.add("192.86.100.74"); + exceptions.add("192.86.100.75"); + exceptions.add("192.86.100.76"); + exceptions.add("192.86.100.77"); + exceptions.add("192.86.100.78"); + exceptions.add("192.86.100.79"); + verifyAllIp4Except(exceptions, false, ipMatcher); + } + + @Test + public void test3IPv4CIDRMatchingSuccess() throws Exception + { + final IPMatcher ipMatcher = new IPMatcher("192.86.100.72/255.255.255.248"); + + assertTrue(ipMatcher.match("192.86.100.75")); + assertFalse(ipMatcher.match("192.86.100.71")); + assertFalse(ipMatcher.match("192.86.100.80")); + ArrayList exceptions = new ArrayList(); + exceptions.add("192.86.100.72"); + exceptions.add("192.86.100.73"); + exceptions.add("192.86.100.74"); + exceptions.add("192.86.100.75"); + exceptions.add("192.86.100.76"); + exceptions.add("192.86.100.77"); + exceptions.add("192.86.100.78"); + exceptions.add("192.86.100.79"); + verifyAllIp4Except(exceptions, false, ipMatcher); + } + + @Test + public void testIPv6CIDRMatchingSuccess() throws Exception + { + final IPMatcher ipMatcher = new IPMatcher("0:0:0:1::/64"); + + assertTrue(ipMatcher.match("0:0:0:1:ffff:ffff:ffff:ffff")); + } + + @Test + public void testIPv6CIDRMatchingFailure() throws Exception + { + final IPMatcher ipMatcher = new IPMatcher("0:0:0:1::/64"); + + assertFalse(ipMatcher.match("0:0:0:2::")); + } + + + + @Test + public void testIPv4IPv6Matching() throws Exception + { + final IPMatcher ipMatcher = new IPMatcher("0.0.0.1"); + + assertTrue(ipMatcher.match("::1")); + } + + + + @Test + public void testSubnetZeroIPv6CIDRMatching() throws Exception + { + final IPMatcher ipMatcher = new IPMatcher("::1/0"); + + assertTrue(ipMatcher.match("::2")); + } + + @Test + public void testAllOnesSubnetIPv4CIDRMatchingSuccess() throws Exception + { + final IPMatcher ipMatcher = new IPMatcher("192.1.2.3/32"); + + assertTrue(ipMatcher.match("192.1.2.3")); + } + + @Test + public void testAllOnesSubnetIPv4CIDRMatchingFailure() throws Exception + { + final IPMatcher ipMatcher = new IPMatcher("192.1.2.3/32"); + + assertFalse(ipMatcher.match("192.1.2.2")); + } + + + + private ArrayList getAllIp4Except(ArrayList exceptions) { + int d1 = 0, d2 = 0, d3 = 0, d4 = 0; + ArrayList ips = new ArrayList(); + for (d1 = 0; d1 <= 255; d1+=increment) + for (d2 = 0; d2 <= 255; d2+=increment) + for (d3 = 0; d3 <= 255; d3+=increment) + for (d4 = 0; d4 <= 255; d4+=increment) { + String IP = d1+"."+d2+"."+d3+"."+d4; + if (exceptions == null || !exceptions.contains(IP)) { + ips.add(IP); + } + } + return ips; + } + + private void verifyAllIp4Except(ArrayList exceptions, boolean asserted, IPMatcher ipMatcher) throws IPMatcherException { + int d1 = 0, d2 = 0, d3 = 0, d4 = 0; + for (d1 = 0; d1 <= 255; d1+=increment) + for (d2 = 0; d2 <= 255; d2+=increment) + for (d3 = 0; d3 <= 255; d3+=increment) + for (d4 = 0; d4 <= 255; d4+=increment) { + String IP = d1+"."+d2+"."+d3+"."+d4; + if (exceptions != null && exceptions.contains(IP)) { + if (asserted) { + assertFalse(ipMatcher.match(IP)); + } else { + assertTrue(ipMatcher.match(IP)); + } + } else { + if (asserted) { + assertTrue(ipMatcher.match(IP)); + } else { + assertFalse(ipMatcher.match(IP)); + } + } + + } + } + + + + + @AfterClass static public void cleanup() {