Author: kayyagari
Date: Tue Apr 19 13:33:54 2011
New Revision: 1095083
URL: http://svn.apache.org/viewvc?rev=1095083&view=rev
Log:
o created an interface for validating password quality and added an implementation
o updated the authenticator and policy config to use the validator
o added dependency on shared-ldap-extras-codec (required to resolve PasswordPolicyErrorEnum)
Added:
directory/apacheds/trunk/core-api/src/main/java/org/apache/directory/server/core/ppolicy/DefaultPasswordValidator.java
directory/apacheds/trunk/core-api/src/main/java/org/apache/directory/server/core/ppolicy/PasswordValidator.java
Modified:
directory/apacheds/trunk/core-api/pom.xml
directory/apacheds/trunk/core-api/src/main/java/org/apache/directory/server/core/ppolicy/PasswordPolicyConfiguration.java
directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/authn/AuthenticationInterceptor.java
Modified: directory/apacheds/trunk/core-api/pom.xml
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/core-api/pom.xml?rev=1095083&r1=1095082&r2=1095083&view=diff
==============================================================================
--- directory/apacheds/trunk/core-api/pom.xml (original)
+++ directory/apacheds/trunk/core-api/pom.xml Tue Apr 19 13:33:54 2011
@@ -117,6 +117,12 @@
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache-core</artifactId>
</dependency>
+
+ <dependency>
+ <groupId>org.apache.directory.shared</groupId>
+ <artifactId>shared-ldap-extras-codec</artifactId>
+ <scope>provided</scope>
+ </dependency>
</dependencies>
Added: directory/apacheds/trunk/core-api/src/main/java/org/apache/directory/server/core/ppolicy/DefaultPasswordValidator.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/core-api/src/main/java/org/apache/directory/server/core/ppolicy/DefaultPasswordValidator.java?rev=1095083&view=auto
==============================================================================
--- directory/apacheds/trunk/core-api/src/main/java/org/apache/directory/server/core/ppolicy/DefaultPasswordValidator.java
(added)
+++ directory/apacheds/trunk/core-api/src/main/java/org/apache/directory/server/core/ppolicy/DefaultPasswordValidator.java
Tue Apr 19 13:33:54 2011
@@ -0,0 +1,88 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+package org.apache.directory.server.core.ppolicy;
+
+
+import static org.apache.directory.shared.ldap.extras.controls.ppolicy.PasswordPolicyErrorEnum.INSUFFICIENT_PASSWORD_QUALITY;
+
+
+/**
+ * The default password validator.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+public class DefaultPasswordValidator implements PasswordValidator
+{
+
+ /** the default validator's instance */
+ public final static DefaultPasswordValidator INSTANCE = new DefaultPasswordValidator();
+
+
+ /**
+ * Creates a new instance of DefaultPasswordValidator.
+ */
+ public DefaultPasswordValidator()
+ {
+ }
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public void validate( String password, String entryRdnVal ) throws PasswordPolicyException
+ {
+ checkUsernameSubstring( password, entryRdnVal );
+ //TODO add more checks
+ }
+
+
+ /**
+ * The password does not contain three letter (or more) tokens from the user's account
name.
+ *
+ * If the account name is less than three characters long, this check is not performed
+ * because the rate at which passwords would be rejected is too high. For each token
that is
+ * three or more characters long, that token is searched for in the password; if it is
present,
+ * the password change is rejected. For example, the name "First M. Last" would be split
into
+ * three tokens: "First", "M", and "Last". Because the second token is only one character
long,
+ * it would be ignored. Therefore, this user could not have a password that included
either
+ * "first" or "last" as a substring anywhere in the password. All of these checks are
+ * case-insensitive.
+ */
+ private void checkUsernameSubstring( String password, String username ) throws PasswordPolicyException
+ {
+ if ( username == null || username.trim().length() == 0 )
+ {
+ return;
+ }
+
+ String[] tokens = username.split( "[^a-zA-Z]" );
+
+ for ( int ii = 0; ii < tokens.length; ii++ )
+ {
+ if ( password.matches( "(?i).*" + tokens[ii] + ".*" ) )
+ {
+ throw new PasswordPolicyException( "Password shouldn't contain parts of the
username",
+ INSUFFICIENT_PASSWORD_QUALITY );
+ }
+ }
+ }
+
+}
Modified: directory/apacheds/trunk/core-api/src/main/java/org/apache/directory/server/core/ppolicy/PasswordPolicyConfiguration.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/core-api/src/main/java/org/apache/directory/server/core/ppolicy/PasswordPolicyConfiguration.java?rev=1095083&r1=1095082&r2=1095083&view=diff
==============================================================================
--- directory/apacheds/trunk/core-api/src/main/java/org/apache/directory/server/core/ppolicy/PasswordPolicyConfiguration.java
(original)
+++ directory/apacheds/trunk/core-api/src/main/java/org/apache/directory/server/core/ppolicy/PasswordPolicyConfiguration.java
Tue Apr 19 13:33:54 2011
@@ -151,6 +151,9 @@ public class PasswordPolicyConfiguration
*/
private int pwdMaxIdle = 0;
+ /** validator used for checking the quality of password */
+ //TODO to be injected from config
+ private PasswordValidator pwdValidator = DefaultPasswordValidator.INSTANCE;
public String getPwdAttribute()
{
@@ -393,6 +396,24 @@ public class PasswordPolicyConfiguration
/**
+ * @return the pwdValidator
+ */
+ public PasswordValidator getPwdValidator()
+ {
+ return pwdValidator;
+ }
+
+
+ /**
+ * @param pwdValidator the pwdValidator to set
+ */
+ public void setPwdValidator( PasswordValidator pwdValidator )
+ {
+ this.pwdValidator = pwdValidator;
+ }
+
+
+ /**
* validates the policy configuration and throws a LdapException if there are any errors
*
* @throws LdapException if there are any errors in the configuration
Added: directory/apacheds/trunk/core-api/src/main/java/org/apache/directory/server/core/ppolicy/PasswordValidator.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/core-api/src/main/java/org/apache/directory/server/core/ppolicy/PasswordValidator.java?rev=1095083&view=auto
==============================================================================
--- directory/apacheds/trunk/core-api/src/main/java/org/apache/directory/server/core/ppolicy/PasswordValidator.java
(added)
+++ directory/apacheds/trunk/core-api/src/main/java/org/apache/directory/server/core/ppolicy/PasswordValidator.java
Tue Apr 19 13:33:54 2011
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+package org.apache.directory.server.core.ppolicy;
+
+/**
+ * An interface for implementing password quality verifiers.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+public interface PasswordValidator
+{
+ /**
+ * checks if the given password meets the required quality contraints.<br>
+ * <p>Note: the length based validations are already done before calling this method<br>
+ *
+ * so the implementor should concentrate on the content checking.</p>
+ *
+ * @param password the password value
+ * @param entryRdnVal the value of entry's RDN(typically this is the username) e.x 'admin'
if the entry's DN is {uid/cn/etc..}=admin,ou=system
+ * @throws PasswordPolicyException if the password doesn't meet the quality contraints
+ */
+ void validate( String password, String entryRdnVal ) throws PasswordPolicyException;
+}
Modified: directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/authn/AuthenticationInterceptor.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/authn/AuthenticationInterceptor.java?rev=1095083&r1=1095082&r2=1095083&view=diff
==============================================================================
--- directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/authn/AuthenticationInterceptor.java
(original)
+++ directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/authn/AuthenticationInterceptor.java
Tue Apr 19 13:33:54 2011
@@ -95,7 +95,6 @@ import org.apache.directory.shared.ldap.
import org.apache.directory.shared.ldap.model.entry.Entry;
import org.apache.directory.shared.ldap.model.entry.Modification;
import org.apache.directory.shared.ldap.model.entry.ModificationOperation;
-import org.apache.directory.shared.ldap.model.entry.StringValue;
import org.apache.directory.shared.ldap.model.entry.Value;
import org.apache.directory.shared.ldap.model.exception.LdapAuthenticationException;
import org.apache.directory.shared.ldap.model.exception.LdapException;
@@ -357,14 +356,9 @@ public class AuthenticationInterceptor e
BinaryValue userPassword = ( BinaryValue ) entry.get( SchemaConstants.USER_PASSWORD_AT
).get();
- if ( entry.get( SchemaConstants.CN_AT ) != null )
- {
- StringValue attr = ( StringValue ) entry.get( SchemaConstants.CN_AT ).get();
- username = attr.getString();
- }
-
try
{
+ username = entry.getDn().getRdn().getUpValue().getString();
check( username, userPassword.getValue(), policyConfig );
}
catch ( PasswordPolicyException e )
@@ -588,16 +582,11 @@ public class AuthenticationInterceptor e
byte[] newPassword = null;
if ( ( pwdModDetails != null ) )
{
- String userName = null;
- if ( entry.get( SchemaConstants.CN_AT ) != null )
- {
- StringValue attr = ( StringValue ) entry.get( SchemaConstants.CN_AT ).get();
- userName = attr.getString();
- }
-
newPassword = pwdModDetails.getNewPwd();
+
try
{
+ String userName = entry.getDn().getRdn().getUpValue().getString();
check( userName, newPassword, policyConfig );
}
catch ( PasswordPolicyException e )
@@ -1191,9 +1180,11 @@ public class AuthenticationInterceptor e
}
String strPassword = Strings.utf8ToString(password);
+
+ // perform the length validation
validatePasswordLength( strPassword, policyConfig );
- checkUsernameSubstring( username, strPassword, policyConfig );
- // checkPasswordChars( strPassword );
+
+ policyConfig.getPwdValidator().validate( strPassword, username );
}
@@ -1227,38 +1218,6 @@ public class AuthenticationInterceptor e
}
- /**
- * The password does not contain three letter (or more) tokens from the user's account
name.
- *
- * If the account name is less than three characters long, this check is not performed
- * because the rate at which passwords would be rejected is too high. For each token
that is
- * three or more characters long, that token is searched for in the password; if it is
present,
- * the password change is rejected. For example, the name "First M. Last" would be split
into
- * three tokens: "First", "M", and "Last". Because the second token is only one character
long,
- * it would be ignored. Therefore, this user could not have a password that included
either
- * "first" or "last" as a substring anywhere in the password. All of these checks are
- * case-insensitive.
- */
- private void checkUsernameSubstring( String username, String password, PasswordPolicyConfiguration
policyConfig ) throws PasswordPolicyException
- {
- if ( username == null || username.trim().length() == 0 )
- {
- return;
- }
-
- String[] tokens = username.split( "[^a-zA-Z]" );
-
- for ( int ii = 0; ii < tokens.length; ii++ )
- {
- if ( password.matches( "(?i).*" + tokens[ii] + ".*" ) )
- {
- throw new PasswordPolicyException( "Password shouldn't contain parts of the
username",
- INSUFFICIENT_PASSWORD_QUALITY );
- }
- }
- }
-
-
private int getPwdTimeBeforeExpiry( Entry userEntry, PasswordPolicyConfiguration policyConfig
) throws LdapException
{
if ( policyConfig.getPwdMaxAge() == 0 )
|