Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DS-1235 IP authentication configuration does not apply netmask and CIDR ranges correctly #255

Merged
merged 1 commit into from
Sep 4, 2013
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
37 changes: 36 additions & 1 deletion dspace-api/src/main/java/org/dspace/authenticate/IPMatcher.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
*/
package org.dspace.authenticate;

import org.apache.log4j.Logger;

import java.net.Inet6Address;
import java.net.UnknownHostException;

Expand All @@ -30,9 +32,13 @@
*
* @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;

Expand Down Expand Up @@ -139,13 +145,26 @@ public IPMatcher(String ipSpec) throws IPMatcherException
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++)
Expand All @@ -166,6 +185,14 @@ public IPMatcher(String ipSpec) throws IPMatcherException
}
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]);
}
}
}
}

Expand Down Expand Up @@ -236,6 +263,7 @@ private static int ipToBytes(String ip, byte[] bytes, boolean mustHave4)
*/
public boolean match(String ipIn) throws IPMatcherException
{
log.debug("ipIn: "+ipIn);
byte[] candidate;

if (ipIn.indexOf(':') < 0)
Expand All @@ -258,6 +286,13 @@ public boolean match(String ipIn) throws IPMatcherException
{
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;
}
}
Expand Down
228 changes: 224 additions & 4 deletions dspace-api/src/test/java/org/dspace/authenticate/IPMatcherTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,23 +10,29 @@
*/
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
{
private static final String IP6_FULL_ADDRESS1 = "2001:18e8:3:171:218:8bff:fe2a:56a4";
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;

Expand Down Expand Up @@ -116,7 +122,221 @@ public void testIp6MaskedMatch()
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<String> exceptions = new ArrayList<String>();
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<String> exceptions = new ArrayList<String>();
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<String> exceptions = new ArrayList<String>();
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<String> getAllIp4Except(ArrayList<String> exceptions) {
int d1 = 0, d2 = 0, d3 = 0, d4 = 0;
ArrayList<String> ips = new ArrayList<String>();
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<String> 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()
{
Expand Down