View Javadoc
1   /*
2    *   Licensed to the Apache Software Foundation (ASF) under one
3    *   or more contributor license agreements.  See the NOTICE file
4    *   distributed with this work for additional information
5    *   regarding copyright ownership.  The ASF licenses this file
6    *   to you under the Apache License, Version 2.0 (the
7    *   "License"); you may not use this file except in compliance
8    *   with the License.  You may obtain a copy of the License at
9    *
10   *     http://www.apache.org/licenses/LICENSE-2.0
11   *
12   *   Unless required by applicable law or agreed to in writing,
13   *   software distributed under the License is distributed on an
14   *   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   *   KIND, either express or implied.  See the License for the
16   *   specific language governing permissions and limitations
17   *   under the License.
18   *
19   */
20  
21  package org.apache.directory.server.core.api.authn.ppolicy;
22  
23  import org.apache.directory.api.ldap.model.entry.Entry;
24  
25  
26  /**
27   * The default password validator.
28   *
29   * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
30   */
31  public class DefaultPasswordValidator implements PasswordValidator
32  {
33  
34      /** the default validator's instance */
35      public static final DefaultPasswordValidator/authn/ppolicy/DefaultPasswordValidator.html#DefaultPasswordValidator">DefaultPasswordValidator INSTANCE = new DefaultPasswordValidator();
36  
37  
38      /**
39       * Creates a new instance of DefaultPasswordValidator.
40       */
41      public DefaultPasswordValidator()
42      {
43      }
44  
45  
46      /**
47       * {@inheritDoc}
48       */
49      public void validate( String password, Entry entry ) throws PasswordPolicyException
50      {
51          checkUsernameSubstring( password, entry );
52          //TODO add more checks
53      }
54  
55  
56      /**
57       * The password does not contain three letter (or more) tokens from the user's account name.
58       *
59       * If the account name is less than three characters long, this check is not performed
60       * because the rate at which passwords would be rejected is too high. For each token that is
61       * three or more characters long, that token is searched for in the password; if it is present,
62       * the password change is rejected. For example, the name "First M. Last" would be split into
63       * three tokens: "First", "M", and "Last". Because the second token is only one character long,
64       * it would be ignored. Therefore, this user could not have a password that included either
65       * "first" or "last" as a substring anywhere in the password. All of these checks are
66       * case-insensitive.
67       */
68      private void checkUsernameSubstring( String password, Entry entry ) throws PasswordPolicyException
69      {
70          String username = entry.getDn().getRdn().getValue();
71          
72          if ( username == null || username.trim().length() == 0 )
73          {
74              return;
75          }
76  
77          String[] tokens = username.split( "[^a-zA-Z]" );
78  
79          for ( String token : tokens )
80          {
81              if ( ( token == null ) || ( token.length() < 4 ) )
82              {
83                  // Two short : continue with the next token
84                  continue;
85              }
86  
87              if ( password.matches( "(?i).*" + token + ".*" ) )
88              {
89                  throw new PasswordPolicyException( "Password shouldn't contain parts of the username", 5 ); // 5 == PasswordPolicyErrorEnum.INSUFFICIENT_PASSWORD_QUALITY
90              }
91          }
92      }
93  }