001/* 002 * The contents of this file are subject to the terms of the Common Development and 003 * Distribution License (the License). You may not use this file except in compliance with the 004 * License. 005 * 006 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the 007 * specific language governing permission and limitations under the License. 008 * 009 * When distributing Covered Software, include this CDDL Header Notice in each file and include 010 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL 011 * Header, with the fields enclosed by brackets [] replaced by your own identifying 012 * information: "Portions Copyright [year] [name of copyright owner]". 013 * 014 * Copyright 2006-2008 Sun Microsystems, Inc. 015 * Portions Copyright 2014-2016 ForgeRock AS. 016 */ 017package org.opends.server.extensions; 018 019import org.forgerock.i18n.LocalizableMessage; 020import java.util.List; 021import java.util.Set; 022 023import org.forgerock.opendj.config.server.ConfigurationChangeListener; 024import org.forgerock.opendj.server.config.server.LengthBasedPasswordValidatorCfg; 025import org.forgerock.opendj.server.config.server.PasswordValidatorCfg; 026import org.opends.server.api.PasswordValidator; 027import org.forgerock.opendj.config.server.ConfigChangeResult; 028import org.forgerock.opendj.config.server.ConfigException; 029import org.opends.server.types.*; 030import org.forgerock.opendj.ldap.ByteString; 031import static org.opends.messages.ExtensionMessages.*; 032import org.forgerock.i18n.LocalizableMessageBuilder; 033 034/** 035 * This class provides a password validator that can ensure that the provided 036 * password meets minimum and/or maximum length requirements. 037 */ 038public class LengthBasedPasswordValidator extends 039 PasswordValidator<LengthBasedPasswordValidatorCfg> implements 040 ConfigurationChangeListener<LengthBasedPasswordValidatorCfg> 041{ 042 /** The current configuration for this password validator. */ 043 private LengthBasedPasswordValidatorCfg currentConfig; 044 045 /** Creates a new instance of this password validator. */ 046 public LengthBasedPasswordValidator() 047 { 048 super(); 049 050 // All initialization must be done in the initializePasswordValidator 051 // method. 052 } 053 054 @Override 055 public void initializePasswordValidator( 056 LengthBasedPasswordValidatorCfg configuration) 057 throws ConfigException, InitializationException 058 { 059 configuration.addLengthBasedChangeListener(this); 060 061 currentConfig = configuration; 062 063 // Make sure that if both the maximum and minimum lengths are set, the 064 // maximum length is greater than or equal to the minimum length. 065 int maxLength = configuration.getMaxPasswordLength(); 066 int minLength = configuration.getMinPasswordLength(); 067 if (maxLength > 0 && minLength > 0 && minLength > maxLength) 068 { 069 LocalizableMessage message = 070 ERR_PWLENGTHVALIDATOR_MIN_GREATER_THAN_MAX.get(minLength, maxLength); 071 throw new ConfigException(message); 072 } 073 } 074 075 @Override 076 public void finalizePasswordValidator() 077 { 078 currentConfig.removeLengthBasedChangeListener(this); 079 } 080 081 @Override 082 public boolean passwordIsAcceptable(ByteString newPassword, 083 Set<ByteString> currentPasswords, 084 Operation operation, Entry userEntry, 085 LocalizableMessageBuilder invalidReason) 086 { 087 LengthBasedPasswordValidatorCfg config = currentConfig; 088 089 int numChars = newPassword.toString().length(); 090 091 int minLength = config.getMinPasswordLength(); 092 if (minLength > 0 && numChars < minLength) 093 { 094 invalidReason.append(ERR_PWLENGTHVALIDATOR_TOO_SHORT.get(minLength)); 095 return false; 096 } 097 098 int maxLength = config.getMaxPasswordLength(); 099 if (maxLength > 0 && numChars > maxLength) 100 { 101 invalidReason.append(ERR_PWLENGTHVALIDATOR_TOO_LONG.get(maxLength)); 102 return false; 103 } 104 105 return true; 106 } 107 108 @Override 109 public boolean isConfigurationAcceptable(PasswordValidatorCfg configuration, 110 List<LocalizableMessage> unacceptableReasons) 111 { 112 LengthBasedPasswordValidatorCfg config = 113 (LengthBasedPasswordValidatorCfg) configuration; 114 return isConfigurationChangeAcceptable(config, unacceptableReasons); 115 } 116 117 @Override 118 public boolean isConfigurationChangeAcceptable( 119 LengthBasedPasswordValidatorCfg configuration, 120 List<LocalizableMessage> unacceptableReasons) 121 { 122 // Make sure that if both the maximum and minimum lengths are set, the 123 // maximum length is greater than or equal to the minimum length. 124 int maxLength = configuration.getMaxPasswordLength(); 125 int minLength = configuration.getMinPasswordLength(); 126 if (maxLength > 0 && minLength > 0 && minLength > maxLength) 127 { 128 LocalizableMessage message = ERR_PWLENGTHVALIDATOR_MIN_GREATER_THAN_MAX.get( 129 minLength, maxLength); 130 unacceptableReasons.add(message); 131 return false; 132 } 133 134 return true; 135 } 136 137 @Override 138 public ConfigChangeResult applyConfigurationChange( 139 LengthBasedPasswordValidatorCfg configuration) 140 { 141 currentConfig = configuration; 142 return new ConfigChangeResult(); 143 } 144}