/*
* 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 legal-notices/CDDLv1_0.txt
* or http://forgerock.org/license/CDDLv1.0.html.
* 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 legal-notices/CDDLv1_0.txt.
* 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
*
*
* Copyright 2009 Sun Microsystems, Inc.
*/
package org.forgerock.opendj.ldap.schema;
import static com.forgerock.opendj.util.StaticUtils.toLowerCase;
import static org.forgerock.opendj.ldap.CoreMessages.ERR_ATTR_SYNTAX_USERPW_NO_CLOSING_BRACE;
import static org.forgerock.opendj.ldap.CoreMessages.ERR_ATTR_SYNTAX_USERPW_NO_OPENING_BRACE;
import static org.forgerock.opendj.ldap.CoreMessages.ERR_ATTR_SYNTAX_USERPW_NO_SCHEME;
import static org.forgerock.opendj.ldap.CoreMessages.ERR_ATTR_SYNTAX_USERPW_NO_VALUE;
import static org.forgerock.opendj.ldap.schema.SchemaConstants.EMR_USER_PASSWORD_EXACT_OID;
import static org.forgerock.opendj.ldap.schema.SchemaConstants.SYNTAX_USER_PASSWORD_NAME;
import org.forgerock.i18n.LocalizableMessage;
import org.forgerock.i18n.LocalizableMessageBuilder;
import org.forgerock.opendj.ldap.ByteSequence;
import org.forgerock.opendj.ldap.DecodeException;
/**
* This class defines an attribute syntax used for storing values that have been
* encoded using a password storage scheme. The format for attribute values with
* this syntax is the concatenation of the following elements in the given
* order:
*
true if the value appears to be encoded using the
* user password syntax, or false if not.
*/
static boolean isEncoded(final ByteSequence value) {
// If the value is null or empty, then it's not.
if (value == null || value.length() == 0) {
return false;
}
// If the value doesn't start with an opening curly brace, then it's
// not.
if (value.byteAt(0) != '{') {
return false;
}
// There must be a corresponding closing curly brace, and there must
// be at least one character inside the brace.
int closingBracePos = -1;
for (int i = 1; i < value.length(); i++) {
if (value.byteAt(i) == '}') {
closingBracePos = i;
break;
}
}
if (closingBracePos < 0 || closingBracePos == 1) {
return false;
}
// The closing curly brace must not be the last character of the
// password.
if (closingBracePos == value.length() - 1) {
return false;
}
// If we've gotten here, then it looks to be encoded.
return true;
}
@Override
public String getEqualityMatchingRule() {
return EMR_USER_PASSWORD_EXACT_OID;
}
public String getName() {
return SYNTAX_USER_PASSWORD_NAME;
}
public boolean isHumanReadable() {
return true;
}
public boolean valueIsAcceptable(final Schema schema, final ByteSequence value,
final LocalizableMessageBuilder invalidReason) {
// We have to accept any value here because in many cases the value
// will not have been encoded by the time this method is called.
// TODO: Is this correct for client-side use?
return true;
}
}