From 28efdf0af0f052eaf5d59f111d73973519203666 Mon Sep 17 00:00:00 2001
From: Chris Ridd <chris.ridd@forgerock.com>
Date: Mon, 23 Jun 2014 16:19:20 +0000
Subject: [PATCH] Fix OPENDJ-1497: pwdHistory stops updating when multiple storage schemes are used
---
opends/src/server/org/opends/server/core/PasswordPolicyState.java | 145 ++++++++++++++++++++++++++++++-----------------
1 files changed, 92 insertions(+), 53 deletions(-)
diff --git a/opends/src/server/org/opends/server/core/PasswordPolicyState.java b/opends/src/server/org/opends/server/core/PasswordPolicyState.java
index b42b52f..3592c94 100644
--- a/opends/src/server/org/opends/server/core/PasswordPolicyState.java
+++ b/opends/src/server/org/opends/server/core/PasswordPolicyState.java
@@ -22,7 +22,7 @@
*
*
* Copyright 2006-2010 Sun Microsystems, Inc.
- * Portions Copyright 2011-2013 ForgeRock AS
+ * Portions Copyright 2011-2014 ForgeRock AS
*/
package org.opends.server.core;
@@ -271,6 +271,58 @@
}
+ /**
+ * Get the broken-down components of the given password value.
+ *
+ * @param v The encoded password value to break down.
+ *
+ * @return An array of components.
+ */
+ private StringBuilder[] getPasswordComponents(AttributeValue v)
+ throws DirectoryException
+ {
+ if (passwordPolicy.isAuthPasswordSyntax())
+ {
+ return AuthPasswordSyntax.decodeAuthPassword(v.toString());
+ }
+ else
+ {
+ String[] userPwComponents = UserPasswordSyntax.decodeUserPassword(v.toString());
+ StringBuilder[] pwComponents = new StringBuilder[userPwComponents.length];
+ for (int i = 0; i < userPwComponents.length; ++i)
+ {
+ pwComponents[i] = new StringBuilder(userPwComponents[i]);
+ }
+ return pwComponents;
+ }
+ }
+
+
+
+ /**
+ * Get the password storage scheme used by a given password value.
+ *
+ * @param v The encoded password value to check.
+ *
+ * @return The scheme used by the password.
+ *
+ * @throws DirectoryException If the password could not be decoded.
+ */
+ private PasswordStorageScheme<?> getPasswordStorageScheme(AttributeValue v)
+ throws DirectoryException
+ {
+ if (passwordPolicy.isAuthPasswordSyntax())
+ {
+ StringBuilder[] pwComps = AuthPasswordSyntax.decodeAuthPassword(v.toString());
+ return DirectoryServer.getAuthPasswordStorageScheme(pwComps[0].toString());
+ }
+ else
+ {
+ String[] pwComps = UserPasswordSyntax.decodeUserPassword(v.toString());
+ return DirectoryServer.getPasswordStorageScheme(pwComps[0]);
+ }
+ }
+
/**
* {@inheritDoc}
@@ -2554,22 +2606,7 @@
{
try
{
- StringBuilder[] pwComponents;
- if (usesAuthPasswordSyntax)
- {
- pwComponents =
- AuthPasswordSyntax.decodeAuthPassword(v.getValue().toString());
- }
- else
- {
- String[] userPwComponents =
- UserPasswordSyntax.decodeUserPassword(v.getValue().toString());
- pwComponents = new StringBuilder[userPwComponents.length];
- for (int i = 0; i < userPwComponents.length; ++i)
- {
- pwComponents[i] = new StringBuilder(userPwComponents[i]);
- }
- }
+ StringBuilder[] pwComponents = getPasswordComponents(v);
String schemeName = pwComponents[0].toString();
PasswordStorageScheme<?> scheme = (usesAuthPasswordSyntax)
@@ -2647,22 +2684,7 @@
{
try
{
- StringBuilder[] pwComponents;
- if (usesAuthPasswordSyntax)
- {
- pwComponents =
- AuthPasswordSyntax.decodeAuthPassword(v.getValue().toString());
- }
- else
- {
- String[] userPwComponents =
- UserPasswordSyntax.decodeUserPassword(v.getValue().toString());
- pwComponents = new StringBuilder[userPwComponents.length];
- for (int i = 0; i < userPwComponents.length; ++i)
- {
- pwComponents[i] = new StringBuilder(userPwComponents[i]);
- }
- }
+ StringBuilder[] pwComponents = getPasswordComponents(v);
String schemeName = pwComponents[0].toString();
PasswordStorageScheme<?> scheme = (usesAuthPasswordSyntax)
@@ -2881,22 +2903,7 @@
try
{
- StringBuilder[] pwComponents;
- if (usesAuthPasswordSyntax)
- {
- pwComponents =
- AuthPasswordSyntax.decodeAuthPassword(v.getValue().toString());
- }
- else
- {
- String[] userPwComponents =
- UserPasswordSyntax.decodeUserPassword(v.getValue().toString());
- pwComponents = new StringBuilder[userPwComponents.length];
- for (int i = 0; i < userPwComponents.length; ++i)
- {
- pwComponents[i] = new StringBuilder(userPwComponents[i]);
- }
- }
+ StringBuilder[] pwComponents = getPasswordComponents(v);
String schemeName = pwComponents[0].toString();
PasswordStorageScheme<?> scheme = (usesAuthPasswordSyntax)
@@ -3081,7 +3088,6 @@
return false;
}
-
// Check to see if the provided password is equal to any of the current
// passwords. If so, then we'll consider it to be in the history.
if (passwordMatches(password))
@@ -3370,8 +3376,10 @@
/**
- * Updates the password history information for this user by adding all
- * current passwords to it.
+ * Updates the password history information for this user by adding one of
+ * the passwords to it. It will choose the first password encoded using a
+ * secure storage scheme, and will fall back to a password encoded using an
+ * insecure storage scheme if necessary.
*/
public void updatePasswordHistory()
{
@@ -3381,9 +3389,40 @@
{
for (Attribute a : attrList)
{
+ boolean usesAuthPasswordSyntax = passwordPolicy.isAuthPasswordSyntax();
+ String insecurePassword = null;
for (AttributeValue v : a)
{
- addPasswordToHistory(v.getValue().toString());
+ try
+ {
+ PasswordStorageScheme<?> scheme = getPasswordStorageScheme(v);
+
+ if (scheme.isStorageSchemeSecure())
+ {
+ addPasswordToHistory(v.getValue().toString());
+ insecurePassword = null;
+ // no need to check any more values for this attribute
+ break;
+ }
+ else if (insecurePassword == null)
+ {
+ insecurePassword = v.getValue().toString();
+ }
+ }
+ catch (DirectoryException e)
+ {
+ if (debugEnabled())
+ {
+ TRACER.debugInfo("Encoded password " + v.getValue().toString() +
+ " cannot be decoded and cannot be added to history.");
+ }
+ }
+ }
+ // If we get here we haven't found a password encoded securely, so we
+ // have to use one of the other values.
+ if (insecurePassword != null)
+ {
+ addPasswordToHistory(insecurePassword);
}
}
}
--
Gitblit v1.10.0