From 5995b93cbc5b084a44ab9c6d7a065d9b47b6d7f7 Mon Sep 17 00:00:00 2001
From: dugan <dugan@localhost>
Date: Tue, 19 Sep 2006 19:49:17 +0000
Subject: [PATCH] Add code to support issue #151 client connection disconnect.
---
opendj-sdk/opends/src/server/org/opends/server/types/AddressMask.java | 597 ++++++++++++++++++++++++++++++---
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/types/TestAddressMask.java | 275 +++++++++++++++
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/types/TypesTestCase.java | 38 ++
opendj-sdk/opends/src/server/org/opends/server/protocols/ldap/LDAPConnectionHandler.java | 76 +--
opendj-sdk/opends/resource/schema/02-config.ldif | 3
opendj-sdk/opends/src/server/org/opends/server/messages/ProtocolMessages.java | 35 +
6 files changed, 924 insertions(+), 100 deletions(-)
diff --git a/opendj-sdk/opends/resource/schema/02-config.ldif b/opendj-sdk/opends/resource/schema/02-config.ldif
index e2073a3..03a17ef 100644
--- a/opendj-sdk/opends/resource/schema/02-config.ldif
+++ b/opendj-sdk/opends/resource/schema/02-config.ldif
@@ -1041,7 +1041,8 @@
objectClasses: ( 1.3.6.1.4.1.26027.1.2.13
NAME 'ds-cfg-connection-handler' SUP top STRUCTURAL
MUST ( cn $ ds-cfg-connection-handler-class $
- ds-cfg-connection-handler-enabled ) X-ORIGIN 'OpenDS Directory Server' )
+ ds-cfg-connection-handler-enabled ) MAY ( ds-cfg-allowed-client $
+ ds-cfg-denied-client ) X-ORIGIN 'OpenDS Directory Server' )
objectClasses: ( 1.3.6.1.4.1.26027.1.2.14
NAME 'ds-cfg-ldap-connection-handler' SUP ds-cfg-connection-handler
STRUCTURAL MUST ds-cfg-listen-port MAY ( ds-cfg-listen-address $
diff --git a/opendj-sdk/opends/src/server/org/opends/server/messages/ProtocolMessages.java b/opendj-sdk/opends/src/server/org/opends/server/messages/ProtocolMessages.java
index 5f73b58..0a96460 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/messages/ProtocolMessages.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/messages/ProtocolMessages.java
@@ -4132,7 +4132,28 @@
public static final int MSGID_ACCTUSABLERES_DECODE_ERROR =
CATEGORY_MASK_PROTOCOL | SEVERITY_MASK_SEVERE_ERROR | 379;
+ /**
+ * The message ID for the message that will be used if an error occurs while
+ * attempting to decode an invalid AddressMask rule prefix.
+ */
+ public static final int MSGID_ADDRESSMASK_PREFIX_DECODE_ERROR =
+ CATEGORY_MASK_PROTOCOL | SEVERITY_MASK_SEVERE_ERROR | 380;
+ /**
+ * The message ID for the message that will be used if an error occurs
+ * because a address mask prefix was specified with an wild card
+ * character "*".
+ */
+ public static final int MSGID_ADDRESSMASK_WILDCARD_DECODE_ERROR =
+ CATEGORY_MASK_PROTOCOL | SEVERITY_MASK_SEVERE_ERROR | 381;
+
+ /**
+ * The message ID for the message that will be used if an error occurs
+ * because a address mask format was invalid.
+ *
+ */
+ public static final int MSGID_ADDRESSMASK_FORMAT_DECODE_ERROR =
+ CATEGORY_MASK_PROTOCOL | SEVERITY_MASK_SEVERE_ERROR | 382;
/**
* Associates a set of generic messages with the message IDs defined in this
@@ -5893,8 +5914,18 @@
"The account availability response control had an " +
"unknown ACCOUNT_USABLE_RESPONSE element type of %s.");
registerMessage(MSGID_ACCTUSABLERES_DECODE_ERROR,
- "Cannot decode the provided account availability " +
- "response control: %s.");
+ "Cannot decode the provided account availability " +
+ "response control: %s.");
+ registerMessage(MSGID_ADDRESSMASK_PREFIX_DECODE_ERROR,
+ "Cannot decode the provided address mask prefix because an" +
+ "invalid value was specified. The permitted values for IPv4" +
+ "are 0 to32 and for IPv6 0 to128");
+ registerMessage(MSGID_ADDRESSMASK_WILDCARD_DECODE_ERROR,
+ "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" +
+ "invalid format.");
}
}
diff --git a/opendj-sdk/opends/src/server/org/opends/server/protocols/ldap/LDAPConnectionHandler.java b/opendj-sdk/opends/src/server/org/opends/server/protocols/ldap/LDAPConnectionHandler.java
index 92f2a62..870d79a 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/protocols/ldap/LDAPConnectionHandler.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/protocols/ldap/LDAPConnectionHandler.java
@@ -1224,12 +1224,44 @@
ServerSocketChannel serverChannel =
(ServerSocketChannel) key.channel();
SocketChannel clientChannel = serverChannel.accept();
- clientChannel.socket().setKeepAlive(useKeepAlive);
- clientChannel.socket().setTcpNoDelay(useTCPNoDelay);
-
LDAPClientConnection clientConnection =
new LDAPClientConnection(this, clientChannel);
+ InetAddress clientAddr=clientConnection.getRemoteAddress();
+ // Check to see if the client is on the denied list. If so,
+ // then reject it immediately.
+ if((deniedClients != null) && (deniedClients.length > 0) &&
+ AddressMask.maskListContains(clientAddr.getAddress(),
+ clientAddr.getHostName(), deniedClients))
+ {
+ clientConnection.disconnect(
+ DisconnectReason.CONNECTION_REJECTED,
+ sendRejectionNotice,
+ MSGID_LDAP_CONNHANDLER_DENIED_CLIENT,
+ clientConnection.getClientHostPort(),
+ clientConnection.getServerHostPort());
+ iterator.remove();
+ continue;
+ }
+ // Check to see if there is an allowed list and if there is
+ // whether the client is on that list. If not, then reject
+ // the connection.
+ if((allowedClients != null) && (allowedClients.length > 0) &&
+ (!AddressMask.maskListContains(clientAddr.getAddress(),
+ clientAddr.getHostName(), allowedClients)))
+ {
+ clientConnection.disconnect(
+ DisconnectReason.CONNECTION_REJECTED,
+ sendRejectionNotice,
+ MSGID_LDAP_CONNHANDLER_DISALLOWED_CLIENT,
+ clientConnection.getClientHostPort(),
+ clientConnection.getServerHostPort());
+
+ iterator.remove();
+ continue;
+ }
+ clientChannel.socket().setKeepAlive(useKeepAlive);
+ clientChannel.socket().setTcpNoDelay(useTCPNoDelay);
ConnectionSecurityProvider connectionSecurityProvider =
securityProvider.newInstance(clientConnection,
clientChannel);
@@ -1246,44 +1278,6 @@
continue;
}
-
- // Check to see if the client is on the denied list. If so,
- // then reject it immediately.
- if ((deniedClients != null) &&
- AddressMask.maskListContains(clientConnection,
- deniedClients))
- {
- clientConnection.disconnect(
- DisconnectReason.CONNECTION_REJECTED,
- sendRejectionNotice,
- MSGID_LDAP_CONNHANDLER_DENIED_CLIENT,
- clientConnection.getClientHostPort(),
- clientConnection.getServerHostPort());
-
- iterator.remove();
- continue;
- }
-
-
- // Check to see if there is an allowed list and if there is
- // whether the client is on that list. If not, then reject
- // the connection.
- if ((allowedClients != null) && (allowedClients.length > 0) &&
- (! AddressMask.maskListContains(clientConnection,
- allowedClients)))
- {
- clientConnection.disconnect(
- DisconnectReason.CONNECTION_REJECTED,
- sendRejectionNotice,
- MSGID_LDAP_CONNHANDLER_DISALLOWED_CLIENT,
- clientConnection.getClientHostPort(),
- clientConnection.getServerHostPort());
-
- iterator.remove();
- continue;
- }
-
-
// If we've gotten here, then we'll take the connection so
// choose a request handler and register the client with it.
try
diff --git a/opendj-sdk/opends/src/server/org/opends/server/types/AddressMask.java b/opendj-sdk/opends/src/server/org/opends/server/types/AddressMask.java
index 21ba599..193ab40 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/types/AddressMask.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/types/AddressMask.java
@@ -26,75 +26,560 @@
*/
package org.opends.server.types;
-
-
-import org.opends.server.api.ClientConnection;
import org.opends.server.config.ConfigException;
+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;
/**
* 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 class AddressMask
+
+public final class AddressMask
{
- // NYI
-
+ /**
+ * The fully-qualified name of this class for debugging purposes.
+ */
+ private static final String CLASS_NAME =
+ "org.opends.server.types.AddressMask";
/**
- * Decodes the provided string as an address mask.
- *
- * @param maskString The string to decode as an address mask.
- *
- * @return AddressMask The address mask decoded from the provided
- * string.
- *
- * @throws ConfigException If the provided string cannot be
- * decoded as an address mask.
- */
- public static AddressMask decode(String maskString)
- throws ConfigException
- {
- // NYI
- return null;
+ * Types of rules we have.
+ *
+ * IPv4 - ipv4 rule
+ * IPv6 - ipv6 rule (begin with '['). Not supported see issue #670
+ * HOST - hostname match (foo.sun.com)
+ * HOSTPATTERN - host pattern match (begin with '.')
+ * ALLWILDCARD - *.*.*.* (first HOST is applied then ipv4)
+ *
+ */
+
+ enum RuleType
+ {
+ IPv4, IPv6, HOSTPATTERN, ALLWILDCARD, HOST;
+ }
+
+ // Type of rule determined
+ private RuleType ruleType;
+
+ // IPv4 values for number of bytes and max CIDR prefix
+ /**
+ * IPv4 address size.
+ */
+ public static int IN4ADDRSZ = 4;
+ private int IPV4MAXPREFIX = 32;
+
+ // IPv6 values for number of bytes and max CIDR prefix
+ //private int IN6ADDRSZ = 16;
+ //private int IPV6MAXPREFIX = 128;
+
+ //Holds binary representations of rule and mask respectively.
+ private byte[] ruleMask, prefixMask;
+
+ //Bit array that holds wildcard info for above binary arrays.
+ private BitSet wildCard = new BitSet();
+
+ //Array that holds each component of a hostname.
+ private String[] hostName;
+
+ //Holds a hostname pattern (ie, rule that begins with '.');'
+ private String hostPattern;
+
+ //Holds string passed into the constructor.
+ private String ruleString;
+
+ /**
+ * Address mask constructor.
+ * @param rule The rule string to process.
+ * @throws ConfigException If the rule string is not valid.
+ */
+ private AddressMask( String rule)
+ throws ConfigException
+ {
+ determineRuleType(rule);
+ switch (ruleType)
+ {
+ case IPv4:
+ processIpv4(rule);
+ break;
+
+ /* case IPv6:
+ processIPv6(rule);
+ break;
+ */
+ case HOST:
+ processHost(rule);
+ break;
+
+ case HOSTPATTERN:
+ processHostPattern(rule);
+ break;
+
+ case ALLWILDCARD:
+ processAllWilds(rule);
+ }
+ ruleString=rule;
+ }
+
+ /**
+ * Try to determine what type of rule string this is. See
+ * RuleType above for valid types.
+ * @param ruleString The rule string to be examined.
+ * @throws ConfigException If the rule type cannot be
+ * determined from the rule string.
+ */
+ private void determineRuleType(String ruleString)
+ throws ConfigException
+ {
+
+ //Rule ending with '.' is invalid'
+ if(ruleString.endsWith("."))
+ {
+ int msgID=MSGID_ADDRESSMASK_FORMAT_DECODE_ERROR;
+ String message = getMessage(msgID);
+ throw new ConfigException(msgID, message);
+ }
+ else if(ruleString.startsWith("."))
+ {
+ ruleType=RuleType.HOSTPATTERN;
+ }
+ else if(ruleString.startsWith("["))
+ {
+ 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;
+ }
+ else
+ {
+ int wildCount=0;
+ String[] s = ruleString.split("\\.", -1);
+ //Try to figure out how many wildcards and if the rule is
+ // 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("*"))
+ {
+ wildCount++;
+ continue;
+ }
+ //Looks like an ipv4 address
+ if(Character.isDigit(s[i].charAt(0)))
+ {
+ ruleType=RuleType.IPv4;
+ break;
+ }
+ }
+ //All wildcards (*.*.*.*)
+ if(wildCount == s.length)
+ {
+ ruleType=RuleType.ALLWILDCARD;
+ }
+ }
+ }
+
+ /**
+ * The rule string is an IPv4 rule. Build both the prefix
+ * mask array and rule mask from the string.
+ * @param rule The rule string containing the IPv4 rule.
+ * @throws ConfigException If the rule string is not a valid
+ * IPv4 rule.
+ */
+ private void processIpv4(String rule)
+ throws ConfigException {
+ String[] s = rule.split("/", -1);
+ ruleMask=new byte[IN4ADDRSZ];
+ prefixMask=new byte[IN4ADDRSZ];
+ prefixMask(processPrefix(s,IPV4MAXPREFIX));
+ processIpv4Subnet((s.length == 0) ? rule : s[0]);
+ }
+
+ /**
+ * The rule string is all wildcards. Set both address wildcard
+ * bitmask and hostname wildcard array.
+ * @param rule The rule string containing all wildcards.
+ */
+ private void processAllWilds(String rule)
+ {
+ String s[]=rule.split("\\.", -1);
+ if(s.length == IN4ADDRSZ)
+ {
+ for(int i=0;i<IN4ADDRSZ;i++)
+ wildCard.set(i);
+ }
+ hostName=rule.split("\\.", -1);
+ }
+
+ /**
+ * Examine the rule string of a host pattern and set the
+ * host pattern from the rule.
+ * @param rule The rule string to examine.
+ * @throws ConfigException If the rule string is not a valid
+ * host pattern rule.
+ */
+ private void processHostPattern(String rule)
+ throws ConfigException
+ {
+ //quick check for invalid chars like " "
+ String s[]=rule.split("^[0-9a-zA-z-.]+");
+ if(s.length > 0)
+ {
+ int msgID=MSGID_ADDRESSMASK_FORMAT_DECODE_ERROR;
+ String message = getMessage(msgID);
+ throw new ConfigException(msgID, message);
+ }
+ hostPattern=rule;
+ }
+
+ /**
+ * Examine rule string and build a hostname string array
+ * of its parts.
+ * @param rule The rule string.
+ * @throws ConfigException If the rule string is not a valid
+ * host name.
+ */
+ private void processHost(String rule)
+ throws ConfigException
+ {
+ //Note that '*' is valid in host rule
+ String s[]=rule.split("^[0-9a-zA-z-.*]+");
+ if(s.length > 0)
+ {
+ int msgID=MSGID_ADDRESSMASK_FORMAT_DECODE_ERROR;
+ String message = getMessage(msgID);
+ throw new ConfigException(msgID, message);
+ }
+ hostName=rule.split("\\.", -1);
+ }
+
+ /**
+ * Build the prefix mask of prefix len bits set in the array.
+ * @param prefix The len of the prefix to use.
+ */
+ private void prefixMask(int prefix)
+ {
+ int i=0;
+ for( i=0;prefix > 8 ; i++)
+ {
+ prefixMask[i] = (byte) 0xff;
+ prefix -= 8;
+ }
+ prefixMask[i] = (byte) ((0xff) << (8 - prefix));
+ }
+
+ /**
+ * Examine the subnet part of a rule string and build a
+ * byte array representation of it.
+ * @param subnet The subnet string part of the rule.
+ * @throws ConfigException If the subnet string is not a valid
+ * IPv4 subnet string.
+ */
+ private void processIpv4Subnet(String subnet)
+ throws ConfigException {
+ String[] s = subnet.split("\\.", -1);
+ try {
+ //Make sure we have four parts
+ if(s.length != IN4ADDRSZ) {
+ int id=MSGID_ADDRESSMASK_FORMAT_DECODE_ERROR;
+ String message = getMessage(id);
+ throw new ConfigException(id, message);
+ }
+ for(int i=0; i < IN4ADDRSZ; i++)
+ {
+ String quad=s[i].trim();
+ if(quad.equals("*"))
+ wildCard.set(i) ; //see wildcard mark bitset
+ else
+ {
+ long val=Integer.parseInt(quad);
+ //must be between 0-255
+ if((val < 0) || (val > 0xff))
+ {
+ int id=MSGID_ADDRESSMASK_FORMAT_DECODE_ERROR;
+ String message = getMessage(id);
+ throw new ConfigException(id, message);
+ }
+ ruleMask[i] = (byte) (val & 0xff);
+ }
+ }
+ } catch (NumberFormatException nfex)
+ {
+ int id=MSGID_ADDRESSMASK_FORMAT_DECODE_ERROR;
+ String message = getMessage(id);
+ throw new ConfigException(id, message);
+ }
+ }
+
+ /**
+ * Examine rule string for correct prefix usage.
+ * @param s The string array with rule string add and prefix
+ * strings.
+ * @param maxPrefix The max value the prefix can be.
+ * @return The prefix integer value.
+ * @throws ConfigException If the string array and prefix
+ * are not valid.
+ */
+ private int processPrefix(String[] s, int maxPrefix)
+ throws ConfigException {
+ int prefix=maxPrefix;
+ try {
+ //can only have one prefix value and a subnet string
+ if((s.length < 1) || (s.length > 2) )
+ {
+ int msgID=MSGID_ADDRESSMASK_FORMAT_DECODE_ERROR;
+ String message = getMessage(msgID);
+ throw new ConfigException(msgID, message);
+ }
+ else if(s.length == 2)
+ {
+ //can't have wildcard with a prefix
+ if(s[0].indexOf('*') > -1)
+ {
+ int msgID=MSGID_ADDRESSMASK_WILDCARD_DECODE_ERROR;
+ String message = getMessage(msgID);
+ throw new ConfigException(msgID, message);
+ }
+ prefix = Integer.parseInt(s[1]);
+ }
+ //must be between 0-maxprefix
+ if((prefix < 0) || (prefix > maxPrefix))
+ {
+ int msgID=MSGID_ADDRESSMASK_PREFIX_DECODE_ERROR;
+ String message = getMessage(msgID);
+ throw new ConfigException(msgID, message);
+ }
+ }
+ catch(NumberFormatException nfex)
+ {
+ int msgID=MSGID_ADDRESSMASK_FORMAT_DECODE_ERROR;
+ String msg = getMessage(msgID);
+ throw new ConfigException(msgID,msg);
+ }
+ return prefix;
+ }
+
+
+ /**
+ * Decodes the provided string as an address mask.
+ *
+ * @param maskString The string to decode as an address mask.
+ *
+ * @return AddressMask The address mask decoded from the
+ * provided string.
+ *
+ * @throws ConfigException If the provided string cannot be
+ * decoded as an address mask.
+ */
+
+
+ public static AddressMask decode(String maskString)
+ throws ConfigException {
+ return new AddressMask(maskString);
+ }
+
+ /**
+ * Indicates whether provided address or hostname matches one of
+ * the address masks in the provided array.
+ *
+ * @param remoteAddr The remote address byte array.
+ * @param remoteName The remote host name string.
+ * @param masks An array of address masks to check.
+ * @return <CODE>true</CODE> if the provided address or hostname
+ * does match one of the given address masks, or
+ * <CODE>false</CODE> if it does not.
+ */
+ public static boolean maskListContains(byte[] remoteAddr,
+ String remoteName,
+ AddressMask[] masks)
+ {
+ for(int i=0; i < masks.length; i++)
+ {
+ if(masks[i].match(remoteAddr, remoteName))
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Retrieves a string representation of this address mask.
+ *
+ * @return A string representation of this address mask.
+ */
+ public String toString()
+ {
+ return new String(ruleString);
+ }
+
+ /**
+ * Main match function that determines which rule-type match
+ * function to use.
+ * @param remoteAddr The remote client address byte array.
+ * @param remoteName The remote client host name.
+ * @return <CODE>true</CODE>if one of the match functions found
+ * a match or <CODE>false</CODE>if not.
+ */
+ private boolean match(byte[] remoteAddr, String remoteName)
+ {
+ boolean ret=false;
+
+ switch(ruleType) {
+ case IPv4:
+ //this Address mask is an IPv4 rule
+ ret=matchAddress(remoteAddr);
+ break;
+
+ case HOST:
+ // HOST rule use hostname
+ 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);
+ break;
+
+ case ALLWILDCARD:
+ //first try ipv4 addr match, then hostname
+ ret=matchAddress(remoteAddr);
+ if(!ret)
+ ret=matchHostName(remoteName);
+ break;
+ }
+ return ret;
+ }
+
+ /**
+ * Try to match remote host name string against the pattern rule.
+ * @param remoteHostName The remote client host name.
+ * @return <CODE>true</CODE>if the remote host name matches or
+ * <CODE>false</CODE>if not.
+ */
+ 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;
+ }
+
+ /**
+ * Try to match remote client host name against rule host name.
+ * @param remoteHostName The remote host name string.
+ * @return <CODE>true</CODE>if the remote client host name matches
+ * <CODE>false</CODE> if it does not.
+ */
+ private boolean matchHostName(String remoteHostName) {
+ String[] s = remoteHostName.split("\\.", -1);
+ if(s.length != hostName.length)
+ return false;
+ if(ruleType == RuleType.ALLWILDCARD)
+ return true;
+ for(int i=0;i<s.length;i++)
+ {
+ if(!hostName[i].equals("*")) //skip if wildcard
+ {
+ if(!s[i].equalsIgnoreCase(hostName[i]))
+ return false;
+ }
+ }
+ return true;
+ }
+
+
+ /**
+ * Try to match remote client address using prefix mask and
+ * rule mask.
+ * @param remoteMask The byte array with remote client address.
+ * @return <CODE>true</CODE> if remote client address matches or
+ * <CODE>false</CODE>if not.
+ */
+ private boolean matchAddress(byte[] remoteMask)
+ {
+ if(prefixMask== null)
+ return false;
+ if(remoteMask.length != prefixMask.length)
+ return false;
+ if(ruleType == RuleType.ALLWILDCARD)
+ return true;
+ for(int i=0;i < prefixMask.length; i++)
+ {
+ if(!wildCard.get(i))
+ {
+ if((ruleMask[i] & prefixMask[i]) !=
+ (remoteMask[i] & prefixMask[i]))
+ return false;
+ }
+ }
+ 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);
+ }
}
-
-
-
- /**
- * Indicates whether the provided address matches one of the address
- * masks in the provided array.
- *
- * @param clientConnection The client connection for which to make
- * the determination.
- * @param masks The set of address masks to check.
- *
- * @return <CODE>true</CODE> if the provided address does match one
- * or more of the given address masks, or
- * <CODE>false</CODE> if it does not.
- */
- public static boolean maskListContains(
- ClientConnection clientConnection,
- AddressMask[] masks)
- {
- // NYI
- return false;
- }
-
-
-
- /**
- * Retrieves a string representation of this address mask.
- *
- * @return A string representation of this address mask.
- */
- public String toString()
- {
- // NYI
- return null;
- }
+ */
}
+
diff --git a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/types/TestAddressMask.java b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/types/TestAddressMask.java
new file mode 100644
index 0000000..043eca6
--- /dev/null
+++ b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/types/TestAddressMask.java
@@ -0,0 +1,275 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE
+ * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable,
+ * add the following below this CDDL HEADER, with the fields enclosed
+ * by brackets "[]" replaced with your own identifying * information:
+ * Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ *
+ * Portions Copyright 2006 Sun Microsystems, Inc.
+ */
+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.*;
+
+public class TestAddressMask extends TypesTestCase {
+
+ /* These are all valid rules -- should all pass. */
+ @DataProvider(name = "validRules")
+ public Object[][] validData() {
+ return new Object[][] {
+ { "129.34.55.67"},
+ { "129.*.78.55"},
+ {".central.sun.com"},
+ {"foo.central.sun.com"},
+ {"foo.*.sun.*"},
+ {"128.*.*.*"},
+ {"129.45.23.67/22"},
+ {"128.33.23.21/32"},
+ {"*.*.*.*"},
+ {"129.45.67.34/0"},
+ {"foo.com"},
+ {"foo"}
+ };
+ }
+
+ @DataProvider(name = "invalidRules")
+ public Object[][] invalidData() {
+ return new Object[][] {
+ { "129.*.900.67" },
+ { "129.67" },
+ {" "},
+ {"129.56.78.90/2000"},
+ {"677.777.AG.BC"},
+ {"/34"},
+ {"234.12.12.*/31"},
+ {"234.12.12.90/"},
+ {"129.34.56.78/-100"},
+ {"129"},
+ {"129.34.-90.67"},
+ {"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/"}
+ };
+ }
+
+ @DataProvider(name = "toStringRule")
+ public Object[][] toStringData() {
+ return new Object[][] {
+ {"129.35.45.66/12"}
+ };
+ }
+
+@Test(dataProvider = "validRules")
+ public void testValidDecode(String mask)
+ throws Exception {
+ AddressMask.decode(mask);
+ }
+
+ @Test(expectedExceptions=ConfigException.class, dataProvider="invalidRules")
+ public void testInvalidDecode(String mask)
+ throws Exception {
+ try {
+ AddressMask.decode(mask);
+ } catch (ConfigException e) {
+ throw e;
+ } catch (Exception e) {
+ //MPD FIX this
+ System.out.println(
+ "Invalid mask <" + mask + "> threw wrong exception type.");
+ throw e;
+ }
+ throw new RuntimeException(
+ "Invalid mask <" + mask + "> did not throw an exception.");
+ }
+
+ @DataProvider(name = "matchRules")
+ public Object[][] ruleMatchData() {
+ return new Object[][] {
+ {
+ //Rules
+ new String[] {
+ "129.56.*.22", //1
+ "*.domain.com", //2
+ "foo.example.com", //3
+ "126.67.89.90", //4
+ "90.89.78.67/30", //5
+ ".test.com", //6
+ "128.153.147.32/21",//7
+ "128.153.146.32/26",//8
+ "90.89.78.67/26"}, //9
+ //Addresses
+ new String[] {
+ "128.153.147.45", //rule 7
+ "128.153.146.60", //rule 8
+ "148.45.45.46", //host
+ "129.56.78.22", //rule 1
+ "148.45.45.47", //host
+ "148.45.45.48", //host
+ "90.89.78.65"}, //rule 5
+ //Hostnames
+ new String[] {
+ "some.host.name", //addr
+ "some.host.name", //addr
+ "foo.example.com", //rule 3
+ "some.host.name", //addr
+ "foo.test.com", //rule 6
+ "foo.domain.com", //rule 2
+ "some.host.name" //addr
+ }
+ }
+ };
+ }
+
+ @DataProvider(name = "noMatchRules")
+ public Object[][] ruleNoMatchData() {
+ return new Object[][] {
+ {
+ // Rule to not match
+ new String[] {
+ "129.56.*.22", //1
+ "*.domain.com", //2
+ "foo.example.com", //3
+ "126.67.89.90", //4
+ "90.89.78.67/30", //5
+ ".test.com", //6
+ "128.153.147.32/21",//7
+ "128.153.146.32/26",//8
+ "90.89.78.67/26"}, //9
+ //Addresses
+ new String[] {
+ "128.153.140.45",
+ "128.153.143.255",
+ "148.45.45.46",
+ "126.56.78.22",
+ "148.45.45.47",
+ "148.45.45.48",
+ "90.89.78.128",
+ "148.45.45.49"},
+ //Hostnames
+ new String[] {
+ "some.host.name",
+ "some.host.name",
+ "foo.examplee.com",
+ "some.host.name",
+ "foo.ttest.com",
+ "foo.domain.comm",
+ "some.host.name",
+ "f.e.c",
+ "foo.domain.cm"}
+ }
+ };
+ }
+
+ @DataProvider(name = "matchWCRules")
+ public Object[][] ruleMatchWCData() {
+ return new Object[][] {
+ {
+ //Rules
+ new String[] {
+ "*.*.*",
+ "*.*.*.*"},
+ //Addresses
+ new String[] {
+ "129.34.45.12",
+ "129.34.45.13"},
+ //Hostnames
+ new String[] {
+ "some.host.name" ,
+ "some.host.name"}
+ }
+ };
+ }
+
+ @Test(dataProvider = "matchRules")
+ public void testMatch(String[] rules, String[] addrs, String[]hostNames) {
+ boolean ret=true;
+ ret=match(rules,addrs,hostNames);
+ assertTrue(ret);
+ }
+
+ @Test(dataProvider = "matchWCRules")
+ public void testWildCardMatch(String[] rules, String[] addrs, String[]hostNames) {
+ boolean ret=true;
+ ret=match(rules,addrs,hostNames);
+ assertTrue(ret);
+ }
+
+ @Test(dataProvider = "noMatchRules")
+ public void testNoMatch(String[] rules, String[] addrs, String[] hostNames) {
+ boolean ret=false;
+ ret=match(rules,addrs,hostNames);
+ assertFalse(ret);
+ }
+
+ @Test(dataProvider="toStringRule")
+ public void testToString(String rule) {
+ try {
+ AddressMask m = AddressMask.decode(rule);
+ assertEquals(rule, m.toString());
+ } catch (ConfigException ce) {
+ throw new RuntimeException(
+ "Invalid mask <" + rule + "> data should be all 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++) {
+ if(!AddressMask.maskListContains(getAddress(addrs[j]),hostNames[j],m)) {
+ ret=false;
+ break;
+ }
+ }
+ return ret;
+ }
+}
diff --git a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/types/TypesTestCase.java b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/types/TypesTestCase.java
new file mode 100644
index 0000000..e409e72
--- /dev/null
+++ b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/types/TypesTestCase.java
@@ -0,0 +1,38 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE
+ * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable,
+ * add the following below this CDDL HEADER, with the fields enclosed
+ * by brackets "[]" replaced with your own identifying * information:
+ * Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ *
+ * Portions Copyright 2006 Sun Microsystems, Inc.
+ */
+package org.opends.server.types ;
+
+import org.opends.server.DirectoryServerTestCase;
+import org.testng.annotations.Test;
+
+/**
+ * An abstract class that all types unit test should extend.
+ */
+
+@Test(groups = { "precommit, types" })
+public abstract class TypesTestCase extends DirectoryServerTestCase
+{}
--
Gitblit v1.10.0