From 4834c06ae25b70b8b6fc7e84987dafd0e71d6c4e Mon Sep 17 00:00:00 2001
From: dugan <dugan@localhost>
Date: Thu, 05 Jul 2007 11:35:50 +0000
Subject: [PATCH] Fix for unresolved issue 670 that can be fixed using some code from from a previous fix for issue 471. Issue 670.
---
opends/src/server/org/opends/server/types/AddressMask.java | 166 +++++++++++----------------
opends/src/server/org/opends/server/messages/ProtocolMessages.java | 2
opends/tests/unit-tests-testng/src/server/org/opends/server/types/TestAddressMask.java | 188 ++++++++++++++++++++++--------
3 files changed, 206 insertions(+), 150 deletions(-)
diff --git a/opends/src/server/org/opends/server/messages/ProtocolMessages.java b/opends/src/server/org/opends/server/messages/ProtocolMessages.java
index f96dac6..aa9a360 100644
--- a/opends/src/server/org/opends/server/messages/ProtocolMessages.java
+++ b/opends/src/server/org/opends/server/messages/ProtocolMessages.java
@@ -6531,7 +6531,7 @@
"Cannot decode the provided address mask because an prefix mask"+
"was specified with an wild card \"*\" match character");
registerMessage(MSGID_ADDRESSMASK_FORMAT_DECODE_ERROR,
- "Cannot decode the provided address mask because the it has an" +
+ "Cannot decode the provided address mask because the it has an " +
"invalid format");
diff --git a/opends/src/server/org/opends/server/types/AddressMask.java b/opends/src/server/org/opends/server/types/AddressMask.java
index 3775380..d33a46b 100644
--- a/opends/src/server/org/opends/server/types/AddressMask.java
+++ b/opends/src/server/org/opends/server/types/AddressMask.java
@@ -30,19 +30,14 @@
import static org.opends.server.messages.ProtocolMessages.*;
import static org.opends.server.messages.MessageHandler.*;
import java.util.BitSet;
-
-//This import statements causes problems in checkstyles so
-//it has been turned off until issue #??? is fixed.
-//import sun.net.util.IPAddressUtil;
-//import java.net.Inet6Address;
-
+import java.net.Inet6Address;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
/**
* This class defines an address mask, which can be used to perform
* efficient comparisons against IP addresses to determine whether a
* particular IP address is in a given range.
- * Currently IPV6 is not supported. Issue #670 will track IPV6
- * support.
*/
public final class AddressMask
@@ -52,7 +47,7 @@
* Types of rules we have.
*
* IPv4 - ipv4 rule
- * IPv6 - ipv6 rule (begin with '['). Not supported see issue #670
+ * IPv6 - ipv6 rule (begin with '[' or contains an ':').
* HOST - hostname match (foo.sun.com)
* HOSTPATTERN - host pattern match (begin with '.')
* ALLWILDCARD - *.*.*.* (first HOST is applied then ipv4)
@@ -61,7 +56,7 @@
enum RuleType
{
- IPv4, IPv6, HOSTPATTERN, ALLWILDCARD, HOST;
+ IPv4, IPv6, HOSTPATTERN, ALLWILDCARD, HOST
}
// Type of rule determined
@@ -75,8 +70,8 @@
private int IPV4MAXPREFIX = 32;
// IPv6 values for number of bytes and max CIDR prefix
- //private int IN6ADDRSZ = 16;
- //private int IPV6MAXPREFIX = 128;
+ private int IN6ADDRSZ = 16;
+ private int IPV6MAXPREFIX = 128;
//Holds binary representations of rule and mask respectively.
private byte[] ruleMask, prefixMask;
@@ -104,14 +99,14 @@
determineRuleType(rule);
switch (ruleType)
{
+ case IPv6:
+ processIPv6(rule);
+ break;
+
case IPv4:
processIpv4(rule);
break;
- /* case IPv6:
- processIPv6(rule);
- break;
- */
case HOST:
processHost(rule);
break;
@@ -148,13 +143,10 @@
{
ruleType=RuleType.HOSTPATTERN;
}
- else if(ruleString.startsWith("["))
+ else if(ruleString.startsWith("[") ||
+ (ruleString.indexOf(':') != -1))
{
- int msgID=MSGID_ADDRESSMASK_FORMAT_DECODE_ERROR;
- String message = getMessage(msgID);
- throw new ConfigException(msgID, message);
- //IPV6 is not supported see issue #670
- //ruleType=RuleType.IPv6;
+ ruleType=RuleType.IPv6;
}
else
{
@@ -164,17 +156,14 @@
// hostname (can't begin with digit) or ipv4 address.
//Default to IPv4 ruletype.
ruleType=RuleType.HOST;
- for(int i=0;i<s.length;i++)
- {
- if(s[i].equals("*"))
- {
+ for (String value : s) {
+ if (value.equals("*")) {
wildCount++;
continue;
}
//Looks like an ipv4 address
- if(Character.isDigit(s[i].charAt(0)))
- {
- ruleType=RuleType.IPv4;
+ if (Character.isDigit(value.charAt(0))) {
+ ruleType = RuleType.IPv4;
break;
}
}
@@ -196,10 +185,10 @@
private void processIpv4(String rule)
throws ConfigException {
String[] s = rule.split("/", -1);
- ruleMask=new byte[IN4ADDRSZ];
- prefixMask=new byte[IN4ADDRSZ];
+ this.ruleMask=new byte[IN4ADDRSZ];
+ this.prefixMask=new byte[IN4ADDRSZ];
prefixMask(processPrefix(s,IPV4MAXPREFIX));
- processIpv4Subnet((s.length == 0) ? rule : s[0]);
+ processIPv4Subnet((s.length == 0) ? rule : s[0]);
}
/**
@@ -266,13 +255,13 @@
*/
private void prefixMask(int prefix)
{
- int i=0;
+ int i;
for( i=0;prefix > 8 ; i++)
{
- prefixMask[i] = (byte) 0xff;
+ this.prefixMask[i] = (byte) 0xff;
prefix -= 8;
}
- prefixMask[i] = (byte) ((0xff) << (8 - prefix));
+ this.prefixMask[i] = (byte) ((0xff) << (8 - prefix));
}
/**
@@ -282,7 +271,7 @@
* @throws ConfigException If the subnet string is not a valid
* IPv4 subnet string.
*/
- private void processIpv4Subnet(String subnet)
+ private void processIPv4Subnet(String subnet)
throws ConfigException {
String[] s = subnet.split("\\.", -1);
try {
@@ -397,12 +386,11 @@
* <CODE>false</CODE> if it does not.
*/
public static boolean maskListContains(byte[] remoteAddr,
- String remoteName,
- AddressMask[] masks)
+ String remoteName,
+ AddressMask[] masks)
{
- for(int i=0; i < masks.length; i++)
- {
- if(masks[i].match(remoteAddr, remoteName))
+ for (AddressMask mask : masks) {
+ if(mask.match(remoteAddr, remoteName))
return true;
}
return false;
@@ -431,6 +419,7 @@
boolean ret=false;
switch(ruleType) {
+ case IPv6:
case IPv4:
//this Address mask is an IPv4 rule
ret=matchAddress(remoteAddr);
@@ -441,15 +430,6 @@
ret=matchHostName(remoteName);
break;
- /*
- case IPv6:
- //IPv6 rule only valid of addr is an Inet6Address
- if(addr instanceof Inet6Address) {
- Inet6Address addr6 = (Inet6Address) addr;
- ret=match(addr6.getAddress());
- }
- break;
- */
case HOSTPATTERN:
//HOSTPATTERN rule
ret=matchPattern(remoteName);
@@ -473,12 +453,8 @@
*/
private boolean matchPattern(String remoteHostName) {
int len=remoteHostName.length() - hostPattern.length();
- if(len > 0)
- {
- return remoteHostName.regionMatches(true,len,
- hostPattern,0,hostPattern.length());
- }
- return false;
+ return len > 0 && remoteHostName.regionMatches(true, len,
+ hostPattern, 0, hostPattern.length());
}
/**
@@ -532,48 +508,44 @@
return true;
}
- /* Turned off until IPV6 issue #670 is fixed.
-
- private void processIPv6(String rule)
- throws ConfigException {
- String[] s = rule.split("/", -1);
- //ipv6 rule must end with ']''
- if(!s[0].endsWith("]"))
- {
- int msgID=MSGID_ADDRESSMASK_FORMAT_DECODE_ERROR;
- String message = getMessage(msgID);
- throw new ConfigException(msgID,message);
- }
- String subnet = s[0].substring(1, s[0].length() -1);
- byte[] tmpMask=IPAddressUtil.textToNumericFormatV6(subnet);
- //don't have a vaild ipv6 address bail
- if (tmpMask == null)
- {
- int msgID=MSGID_ADDRESSMASK_FORMAT_DECODE_ERROR;
- String message = getMessage(msgID);
- throw new ConfigException(msgID, message);remoteMask
- }
- //we were returned an ipv4-mapped address ::ffff:<ipv4 addr>
- //make sure we don't have a prefix
- if((tmpMask.length == IN4ADDRSZ) &&
- (s.length == 2)) {
- int msgID = MSGID_ADDRESSMASK_FORMAT_DECODE_ERROR;
- String message = getMessage(msgID);
- throw new ConfigException(msgID, message);
- //build a ipv4 structure using a 32-bit prefix
- } else if (tmpMask.length == IN4ADDRSZ) {
- setRuleType(Rtype.IPv4);
- setRuleMask(tmpMask);
- setPrefixMask(new byte[IN4ADDRSZ]);
- prefixMask(32);
- } else { //plain Ipv6 address
- setRuleMask(tmpMask);
- setPrefixMask(new byte[IN6ADDRSZ]);
- prefixMask(processPrefix(s,IPV6MAXPREFIX));
- setRuleType(Rtype.IPv6);
- }
- }
+ /**
+ * The rule string is an IPv6 rule. Build both the prefix
+ * mask array and rule mask from the string.
+ *
+ * @param rule The rule string containing the IPv6 rule.
+ * @throws ConfigException If the rule string is not a valid
+ * IPv6 rule.
*/
+ private void processIPv6(String rule) throws ConfigException {
+ String[] s = rule.split("/", -1);
+ InetAddress addr;
+ try {
+ addr = InetAddress.getByName(s[0]);
+ } catch (UnknownHostException ex) {
+ int msgID=MSGID_ADDRESSMASK_FORMAT_DECODE_ERROR;
+ String message = getMessage(msgID);
+ throw new ConfigException(msgID, message);
+ }
+ if(addr instanceof Inet6Address) {
+ this.ruleType=RuleType.IPv6;
+ Inet6Address addr6 = (Inet6Address) addr;
+ this.ruleMask=addr6.getAddress();
+ this.prefixMask=new byte[IN6ADDRSZ];
+ prefixMask(processPrefix(s,IPV6MAXPREFIX));
+ } else {
+ //The address might be an IPv4-compat address.
+ //Throw an error if the rule has a prefix.
+ if(s.length == 2) {
+ int msgID = MSGID_ADDRESSMASK_FORMAT_DECODE_ERROR;
+ String message = getMessage(msgID);
+ throw new ConfigException(msgID, message);
+ }
+ this.ruleMask=addr.getAddress();
+ this.ruleType=RuleType.IPv4;
+ this.prefixMask=new byte[IN4ADDRSZ];
+ prefixMask(processPrefix(s,IPV4MAXPREFIX));
+ }
+ }
}
diff --git a/opends/tests/unit-tests-testng/src/server/org/opends/server/types/TestAddressMask.java b/opends/tests/unit-tests-testng/src/server/org/opends/server/types/TestAddressMask.java
index 40ae20f..4648147 100644
--- a/opends/tests/unit-tests-testng/src/server/org/opends/server/types/TestAddressMask.java
+++ b/opends/tests/unit-tests-testng/src/server/org/opends/server/types/TestAddressMask.java
@@ -26,12 +26,14 @@
*/
package org.opends.server.types;
-import org.opends.server.types.AddressMask;
import org.opends.server.config.ConfigException;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
import static org.testng.Assert.*;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+
public class TestAddressMask extends TypesTestCase {
/* These are all valid rules -- should all pass. */
@@ -70,7 +72,6 @@
{"129.**.56.67"},
{"foo bar.com"},
{"12foo.example.com"},
- {"[2001:fecd:ba23:cd1f:dcb1:1010:9234:4088]/124"},
{"123.45."},
{".central.sun day.com"},
{"129.34.45.45/4/3/"}
@@ -106,8 +107,8 @@
"Invalid mask <" + mask + "> did not throw an exception.");
}
- @DataProvider(name = "matchRules")
- public Object[][] ruleMatchData() {
+ @DataProvider(name = "matchRules")
+ public Object[][] ruleMatchData() {
return new Object[][] {
{
//Rules
@@ -121,7 +122,7 @@
"128.153.147.32/21",//7
"128.153.146.32/26",//8
"90.89.78.67/26"}, //9
- //Addresses
+ //Addresses
new String[] {
"128.153.147.45", //rule 7
"128.153.146.60", //rule 8
@@ -130,7 +131,7 @@
"148.45.45.47", //host
"148.45.45.48", //host
"90.89.78.65"}, //rule 5
- //Hostnames
+ //Hostnames
new String[] {
"some.host.name", //addr
"some.host.name", //addr
@@ -159,9 +160,9 @@
"128.153.147.32/21",//7
"128.153.146.32/26",//8
"90.89.78.67/26"}, //9
- //Addresses
+ //Addresses
new String[] {
- "128.153.140.45",
+ "128.153.140.45",
"128.153.143.255",
"148.45.45.46",
"126.56.78.22",
@@ -169,7 +170,7 @@
"148.45.45.48",
"90.89.78.128",
"148.45.45.49"},
- //Hostnames
+ //Hostnames
new String[] {
"some.host.name",
"some.host.name",
@@ -191,12 +192,12 @@
//Rules
new String[] {
"*.*.*",
- "*.*.*.*"},
- //Addresses
+ "*.*.*.*"},
+ //Addresses
new String[] {
"129.34.45.12",
- "129.34.45.13"},
- //Hostnames
+ "129.34.45.13"},
+ //Hostnames
new String[] {
"some.host.name" ,
"some.host.name"}
@@ -206,7 +207,7 @@
@Test(dataProvider = "matchRules")
public void testMatch(String[] rules, String[] addrs, String[]hostNames) {
- boolean ret=true;
+ boolean ret;
ret=match(rules,addrs,hostNames);
assertTrue(ret);
}
@@ -214,7 +215,7 @@
@Test(dataProvider = "matchWCRules")
public void testWildCardMatch(String[] rules, String[] addrs,
String[]hostNames) {
- boolean ret=true;
+ boolean ret;
ret=match(rules,addrs,hostNames);
assertTrue(ret);
}
@@ -222,7 +223,7 @@
@Test(dataProvider = "noMatchRules")
public void testNoMatch(String[] rules, String[] addrs,
String[] hostNames) {
- boolean ret=false;
+ boolean ret;
ret=match(rules,addrs,hostNames);
assertFalse(ret);
}
@@ -234,47 +235,130 @@
assertEquals(rule, m.toString());
} catch (ConfigException ce) {
throw new RuntimeException(
- "Invalid mask <" + rule +
+ "Invalid mask <" + rule +
"> all data should be valid for this test");
}
}
- private byte[] getAddress(String remote) {
- byte[] addr=new byte[AddressMask.IN4ADDRSZ];
- String[] s = remote.split("\\.", -1);
- try {
- for(int i=0;i<AddressMask.IN4ADDRSZ;i++) {
- long val = Integer.parseInt(s[i]);
- addr[i] = (byte) (val & 0xff);
- }
- } catch (NumberFormatException nfex) {
- return addr;
- }
- return addr;
+ private boolean match(String[] rules, String[] addrs, String[]hostNames) {
+ boolean ret=true;
+ int i=0;
+
+ AddressMask[] m = new AddressMask[rules.length];
+ try {
+ for (i = 0; i < rules.length; i++) {
+ m[i] = AddressMask.decode(rules[i]);
+ }
+ } catch (ConfigException ce) {
+ throw new RuntimeException(
+ "Invalid mask <" + rules[i] +
+ "> all data must be valid for this test");
+ }
+ for(int j = 0; j < addrs.length; j++) {
+ try {
+ InetAddress addr = InetAddress.getByName(addrs[j]);
+ if(!AddressMask.maskListContains(addr.getAddress(), hostNames[j], m)) {
+ ret=false;
+ break;
+ }
+ } catch (UnknownHostException ex) {
+ ret=false;
+ }
+ }
+ return ret;
+ }
+
+ /*
+ IPV6 data and tests.
+ */
+
+ //Invalid IPv6 expressions.
+ @DataProvider(name = "invalid6Rules")
+ public Object[][] inValid6Data() {
+ return new Object[][] {
+ {"2001:feca:ba23:cd1f:dcb1:1010:9234:4088///124"},
+ {"2001:feca:ba23:cd1f:dcb1:1010:9234:4088?124"},
+ {"2001:fecz:ba23:cd1f:dcb1:1010:9234:4088/124"},
+ {"2001:fecd:ba23:cd1ff:dcb1:1010:9234:4088/46"},
+ {"0:0:0:0:0:ffff:101..45.75.219"},
+ {"0:0:0:0:0:0:101.45.75.700"},
+ {"1080::8:800:200C:417A/500"},
+ {"1080::8:800:*:417A/66"},
+ {"2001:fecd:ba23:cd1ff:dcb1:1010:202.45.66.20"},
+ };
+ }
+
+ //Valid IPv6 expressions.
+ @DataProvider(name = "valid6Rules")
+ public Object[][] valid6Data() {
+ return new Object[][] {
+ {"2001:fecd:ba23:cd1f:dcb1:1010:9234:4088/124"},
+ {"2001:fecd:ba23:cd1f:dcb1:1010:9234:4088"},
+ {"[2001:fecd:ba23:cd1f:dcb1:1010:9234:4088]/45"},
+ {"::/128"},
+ {"::1/128"},
+ {"::"},
+ {"0:0:0:0:0:ffff:101.45.75.219"},
+ {"1080::8:800:200C:417A"},
+ {"0:0:0:0:0:0:101.45.75.219"},
+ {"::101.45.75.219"}
+ };
+ }
+
+
+ @DataProvider(name = "match6Rules")
+ public Object[][] ruleMatch6Data() {
+ return new Object[][] {
+ {
+ //IPV6 Rules
+ new String[] {
+ "[12ab:0:0:cd30::]/60",
+ "::ffff:72.56.78.9",
+ "::",
+ "42ab:0:0:dd30::"},
+ //IPv6 Addresses
+ new String[] {
+ "12ab:0:0:cd3f:0000:0000:23DC:DC30",
+ "72.56.78.9",
+ "::",
+ "42ab:0000:0000:dd30:0000:0000:0000:0000"},
+ //ignored Hostnames
+ new String[] {
+ "ignored.host.name",
+ "ignored.host.name",
+ "ignored.host.name",
+ "ignored.host.name"
+ }
+ }
+ };
}
- private boolean match(String[] rules, String[] addrs,
- String[]hostNames) {
- boolean ret=true;
- int i=0;
+ @Test(dataProvider = "valid6Rules")
+ public void testValid6Decode(String mask)
+ throws Exception {
+ AddressMask.decode(mask);
+ }
- AddressMask[] m = new AddressMask[rules.length];
- try {
- for (i = 0; i < rules.length; i++) {
- m[i] = AddressMask.decode(rules[i]);
- }
- } catch (ConfigException ce) {
- throw new RuntimeException(
- "Invalid mask <" + rules[i] +
- "> all data must be valid for this test");
- }
- for(int j =0; j < addrs.length; j++) {
- if(!AddressMask.maskListContains(getAddress(addrs[j]),
- hostNames[j],m)) {
- ret=false;
- break;
- }
- }
- return ret;
- }
+ @Test(expectedExceptions=ConfigException.class, dataProvider="invalid6Rules")
+ public void testInvalid6Decode(String mask)
+ throws Exception {
+ try {
+ AddressMask.decode(mask);
+ } catch (ConfigException e) {
+ throw e;
+ } catch (Exception e) {
+ System.out.println(
+ "Invalid mask <" + mask + "> threw wrong exception type.");
+ throw e;
+ }
+ throw new RuntimeException(
+ "Invalid mask <" + mask + "> did not throw an exception.");
+ }
+
+ @Test(dataProvider = "match6Rules")
+ public void testMatch6(String[] rules, String[] addrs, String[]hostNames) {
+ boolean ret;
+ ret=match(rules,addrs,hostNames);
+ assertTrue(ret);
+ }
}
--
Gitblit v1.10.0