001 /* 002 * CDDL HEADER START 003 * 004 * The contents of this file are subject to the terms of the 005 * Common Development and Distribution License, Version 1.0 only 006 * (the "License"). You may not use this file except in compliance 007 * with the License. 008 * 009 * You can obtain a copy of the license at 010 * trunk/opends/resource/legal-notices/OpenDS.LICENSE 011 * or https://OpenDS.dev.java.net/OpenDS.LICENSE. 012 * See the License for the specific language governing permissions 013 * and limitations under the License. 014 * 015 * When distributing Covered Code, include this CDDL HEADER in each 016 * file and include the License file at 017 * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable, 018 * add the following below this CDDL HEADER, with the fields enclosed 019 * by brackets "[]" replaced with your own identifying information: 020 * Portions Copyright [yyyy] [name of copyright owner] 021 * 022 * CDDL HEADER END 023 * 024 * 025 * Copyright 2006-2008 Sun Microsystems, Inc. 026 */ 027 package org.opends.server.schema; 028 029 030 031 import java.util.Arrays; 032 033 import org.opends.server.admin.std.server.EqualityMatchingRuleCfg; 034 import org.opends.server.api.EqualityMatchingRule; 035 import org.opends.server.config.ConfigException; 036 import org.opends.server.protocols.asn1.ASN1OctetString; 037 import org.opends.server.types.ByteString; 038 import org.opends.server.types.DirectoryException; 039 import org.opends.server.types.InitializationException; 040 041 import static org.opends.server.schema.SchemaConstants.*; 042 043 044 045 /** 046 * This class implements the userPasswordExactMatch matching rule, which will 047 * simply compare encoded hashed password values to see if they are exactly 048 * equal to each other. 049 */ 050 public class UserPasswordExactEqualityMatchingRule 051 extends EqualityMatchingRule 052 { 053 /** 054 * Creates a new instance of this userPasswordExactMatch matching rule. 055 */ 056 public UserPasswordExactEqualityMatchingRule() 057 { 058 super(); 059 } 060 061 062 063 /** 064 * {@inheritDoc} 065 */ 066 public void initializeMatchingRule(EqualityMatchingRuleCfg configuration) 067 throws ConfigException, InitializationException 068 { 069 // No initialization is required. 070 } 071 072 073 074 /** 075 * Retrieves the common name for this matching rule. 076 * 077 * @return The common name for this matching rule, or <CODE>null</CODE> if 078 * it does not have a name. 079 */ 080 public String getName() 081 { 082 return EMR_USER_PASSWORD_EXACT_NAME; 083 } 084 085 086 087 /** 088 * Retrieves the OID for this matching rule. 089 * 090 * @return The OID for this matching rule. 091 */ 092 public String getOID() 093 { 094 return EMR_USER_PASSWORD_EXACT_OID; 095 } 096 097 098 099 /** 100 * Retrieves the description for this matching rule. 101 * 102 * @return The description for this matching rule, or <CODE>null</CODE> if 103 * there is none. 104 */ 105 public String getDescription() 106 { 107 // There is no standard description for this matching rule. 108 return EMR_USER_PASSWORD_EXACT_DESCRIPTION; 109 } 110 111 112 113 /** 114 * Retrieves the OID of the syntax with which this matching rule is 115 * associated. 116 * 117 * @return The OID of the syntax with which this matching rule is associated. 118 */ 119 public String getSyntaxOID() 120 { 121 return SYNTAX_USER_PASSWORD_OID; 122 } 123 124 125 126 /** 127 * Retrieves the normalized form of the provided value, which is best suited 128 * for efficiently performing matching operations on that value. 129 * 130 * @param value The value to be normalized. 131 * 132 * @return The normalized version of the provided value. 133 * 134 * @throws DirectoryException If the provided value is invalid according to 135 * the associated attribute syntax. 136 */ 137 public ByteString normalizeValue(ByteString value) 138 throws DirectoryException 139 { 140 // The normalized form of this matching rule is exactly equal to the 141 // non-normalized form, except that the scheme needs to be converted to 142 // lowercase (if there is one). 143 byte[] valueBytes = value.value(); 144 byte[] newValueBytes = new byte[valueBytes.length]; 145 System.arraycopy(valueBytes, 0, newValueBytes, 0, valueBytes.length); 146 147 if (UserPasswordSyntax.isEncoded(value)) 148 { 149 schemeLoop: 150 for (int i=1; i < newValueBytes.length; i++) 151 { 152 switch (newValueBytes[i]) 153 { 154 case 'A': 155 newValueBytes[i] = 'a'; 156 break; 157 case 'B': 158 newValueBytes[i] = 'b'; 159 break; 160 case 'C': 161 newValueBytes[i] = 'c'; 162 break; 163 case 'D': 164 newValueBytes[i] = 'd'; 165 break; 166 case 'E': 167 newValueBytes[i] = 'e'; 168 break; 169 case 'F': 170 newValueBytes[i] = 'f'; 171 break; 172 case 'G': 173 newValueBytes[i] = 'g'; 174 break; 175 case 'H': 176 newValueBytes[i] = 'h'; 177 break; 178 case 'I': 179 newValueBytes[i] = 'i'; 180 break; 181 case 'J': 182 newValueBytes[i] = 'j'; 183 break; 184 case 'K': 185 newValueBytes[i] = 'k'; 186 break; 187 case 'L': 188 newValueBytes[i] = 'l'; 189 break; 190 case 'M': 191 newValueBytes[i] = 'm'; 192 break; 193 case 'N': 194 newValueBytes[i] = 'n'; 195 break; 196 case 'O': 197 newValueBytes[i] = 'o'; 198 break; 199 case 'P': 200 newValueBytes[i] = 'p'; 201 break; 202 case 'Q': 203 newValueBytes[i] = 'q'; 204 break; 205 case 'R': 206 newValueBytes[i] = 'r'; 207 break; 208 case 'S': 209 newValueBytes[i] = 's'; 210 break; 211 case 'T': 212 newValueBytes[i] = 't'; 213 break; 214 case 'U': 215 newValueBytes[i] = 'u'; 216 break; 217 case 'V': 218 newValueBytes[i] = 'v'; 219 break; 220 case 'W': 221 newValueBytes[i] = 'w'; 222 break; 223 case 'X': 224 newValueBytes[i] = 'x'; 225 break; 226 case 'Y': 227 newValueBytes[i] = 'y'; 228 break; 229 case 'Z': 230 newValueBytes[i] = 'z'; 231 break; 232 case '}': 233 break schemeLoop; 234 } 235 } 236 } 237 238 return new ASN1OctetString(newValueBytes); 239 } 240 241 242 243 /** 244 * Indicates whether the two provided normalized values are equal to each 245 * other. 246 * 247 * @param value1 The normalized form of the first value to compare. 248 * @param value2 The normalized form of the second value to compare. 249 * 250 * @return <CODE>true</CODE> if the provided values are equal, or 251 * <CODE>false</CODE> if not. 252 */ 253 public boolean areEqual(ByteString value1, ByteString value2) 254 { 255 // Since the values are already normalized, we just need to compare the 256 // associated byte arrays. 257 return Arrays.equals(value1.value(), value2.value()); 258 } 259 } 260