From 34451f14f9d4ef9efb313ecbdd22633eec5fd1ff Mon Sep 17 00:00:00 2001
From: neil_a_wilson <neil_a_wilson@localhost>
Date: Thu, 21 Sep 2006 15:01:12 +0000
Subject: [PATCH] Update the PLAIN, CRAM-MD5, and DIGEST-MD5 SASL mechanism handlers to use the password policy during the process of verifying the credentials rather than just assuming that the password is held in the userPassword attribute.
---
opends/src/server/org/opends/server/extensions/DigestMD5SASLMechanismHandler.java | 206 +++++++++++++--------------------------------------
1 files changed, 53 insertions(+), 153 deletions(-)
diff --git a/opends/src/server/org/opends/server/extensions/DigestMD5SASLMechanismHandler.java b/opends/src/server/org/opends/server/extensions/DigestMD5SASLMechanismHandler.java
index acb0870..121d6e9 100644
--- a/opends/src/server/org/opends/server/extensions/DigestMD5SASLMechanismHandler.java
+++ b/opends/src/server/org/opends/server/extensions/DigestMD5SASLMechanismHandler.java
@@ -45,7 +45,6 @@
import org.opends.server.api.ClientConnection;
import org.opends.server.api.ConfigurableComponent;
import org.opends.server.api.IdentityMapper;
-import org.opends.server.api.PasswordStorageScheme;
import org.opends.server.api.SASLMechanismHandler;
import org.opends.server.config.ConfigAttribute;
import org.opends.server.config.ConfigEntry;
@@ -57,10 +56,8 @@
import org.opends.server.core.DirectoryServer;
import org.opends.server.core.InitializationException;
import org.opends.server.core.LockManager;
+import org.opends.server.core.PasswordPolicyState;
import org.opends.server.protocols.asn1.ASN1OctetString;
-import org.opends.server.types.Attribute;
-import org.opends.server.types.AttributeType;
-import org.opends.server.types.AttributeValue;
import org.opends.server.types.AuthenticationInfo;
import org.opends.server.types.ByteString;
import org.opends.server.types.ConfigChangeResult;
@@ -862,6 +859,7 @@
else
{
// Use the identity mapper to resolve the username to an entry.
+ String userName = responseUserName;
if (lowerUserName.startsWith("u:"))
{
if (lowerUserName.equals("u:"))
@@ -874,13 +872,13 @@
return;
}
- responseUserName = responseUserName.substring(2);
+ userName = responseUserName.substring(2);
}
try
{
- userEntry = identityMapper.getEntryForID(responseUserName);
+ userEntry = identityMapper.getEntryForID(userName);
}
catch (DirectoryException de)
{
@@ -913,154 +911,66 @@
}
- // Get the password attribute from the user entry and iterate through the
- // available values. We can only look at reversible values, so all
- // non-reversible values will be ignored. For each reversible value, see
- // if we can use it in conjunction with the challenge to construct the
- // provided digest.
- // FIXME -- Determine the attribute based on the user's password policy.
- AttributeType pwType = DirectoryServer.getAttributeType(ATTR_USER_PASSWORD);
- if (pwType == null)
+ // Get the clear-text passwords from the user entry, if there are any.
+ List<ByteString> clearPasswords;
+ try
{
- pwType = DirectoryServer.getDefaultAttributeType(ATTR_USER_PASSWORD);
- }
+ PasswordPolicyState pwPolicyState =
+ new PasswordPolicyState(userEntry, false, false);
+ clearPasswords = pwPolicyState.getClearPasswords();
+ if ((clearPasswords == null) || clearPasswords.isEmpty())
+ {
+ bindOperation.setResultCode(ResultCode.INVALID_CREDENTIALS);
- List<Attribute> pwAttr = userEntry.getAttribute(pwType);
- if ((pwAttr == null) || pwAttr.isEmpty())
+ int msgID = MSGID_SASLDIGESTMD5_NO_REVERSIBLE_PASSWORDS;
+ String message = getMessage(msgID, String.valueOf(userEntry.getDN()));
+ bindOperation.setAuthFailureReason(msgID, message);
+ return;
+ }
+ }
+ catch (Exception e)
{
bindOperation.setResultCode(ResultCode.INVALID_CREDENTIALS);
- int msgID = MSGID_SASLDIGESTMD5_NO_PW_ATTR;
- String message = getMessage(msgID, pwType.getNameOrOID());
+ int msgID = MSGID_SASLDIGESTMD5_CANNOT_GET_REVERSIBLE_PASSWORDS;
+ String message = getMessage(msgID, String.valueOf(userEntry.getDN()),
+ String.valueOf(e));
bindOperation.setAuthFailureReason(msgID, message);
return;
}
- boolean reversibleFound = false;
- boolean matchFound = false;
- byte[] passwordBytes = null;
- for (Attribute a : pwAttr)
+
+ // Iterate through the clear-text values and see if any of them can be used
+ // in conjunction with the challenge to construct the provided digest.
+ boolean matchFound = false;
+ byte[] passwordBytes = null;
+ for (ByteString clearPassword : clearPasswords)
{
- for (AttributeValue v : a.getValues())
+ byte[] generatedDigest;
+ try
{
- String valueStr = v.getStringValue();
- int closePos;
- if (valueStr.startsWith(STORAGE_SCHEME_PREFIX) &&
- (closePos = valueStr.indexOf(STORAGE_SCHEME_SUFFIX, 2)) > 0)
- {
- String schemeName =
- toLowerCase(valueStr.substring(1, closePos));
- PasswordStorageScheme scheme =
- DirectoryServer.getPasswordStorageScheme(schemeName);
- if (scheme == null)
- {
- // We can't do anything with this. Append a message to the
- // error message to include in the response and continue.
- int msgID = MSGID_SASLDIGESTMD5_UNKNOWN_STORAGE_SCHEME;
- String message = getMessage(msgID,
- String.valueOf(userEntry.getDN()),
- schemeName);
- logError(ErrorLogCategory.EXTENSIONS,
- ErrorLogSeverity.SEVERE_WARNING, message, msgID);
- continue;
- }
- else if (! scheme.isReversible())
- {
- // It's not a reversible scheme, so we can't get the clear-text
- // password to test. Skip it and go on.
- continue;
- }
- else
- {
- ASN1OctetString encodedPassword =
- new ASN1OctetString(valueStr.substring(closePos+1));
- ByteString clearPassword;
+ generatedDigest =
+ generateResponseDigest(responseUserName, responseAuthzID,
+ clearPassword.value(), responseRealm,
+ responseNonce, responseCNonce,
+ responseNonceCountStr, responseDigestURI,
+ responseQoP, responseCharset);
+ }
+ catch (Exception e)
+ {
+ assert debugException(CLASS_NAME, "processSASLBind", e);
- try
- {
- clearPassword = scheme.getPlaintextValue(encodedPassword);
- reversibleFound = true;
- }
- catch (DirectoryException de)
- {
- assert debugException(CLASS_NAME, "processSASLBind", de);
-
- int msgID = MSGID_SASLDIGESTMD5_CANNOT_GET_CLEAR_PASSWORD;
- String message = getMessage(msgID,
- String.valueOf(userEntry.getDN()),
- schemeName, de.getErrorMessage());
- logError(ErrorLogCategory.EXTENSIONS,
- ErrorLogSeverity.SEVERE_WARNING, message, msgID);
- continue;
- }
-
- byte[] generatedDigest;
- try
- {
- generatedDigest =
- generateResponseDigest(responseUserName, responseAuthzID,
- clearPassword.value(), responseRealm,
- responseNonce, responseCNonce,
- responseNonceCountStr,
- responseDigestURI, responseQoP,
- responseCharset);
- }
- catch (Exception e)
- {
- assert debugException(CLASS_NAME, "processSASLBind", e);
-
- logError(ErrorLogCategory.EXTENSIONS,
- ErrorLogSeverity.SEVERE_WARNING,
- MSGID_SASLDIGESTMD5_CANNOT_GENERATE_RESPONSE_DIGEST,
- stackTraceToSingleLineString(e));
- continue;
- }
-
-
- if (Arrays.equals(responseDigest, generatedDigest))
- {
- matchFound = true;
- passwordBytes = clearPassword.value();
- break;
- }
- }
- }
- else
- {
- reversibleFound = true;
- byte[] generatedDigest;
- try
- {
- generatedDigest =
- generateResponseDigest(responseUserName, responseAuthzID,
- v.getValue().value(), responseRealm,
- responseNonce, responseCNonce,
- responseNonceCountStr,
- responseDigestURI, responseQoP,
- responseCharset);
- }
- catch (Exception e)
- {
- assert debugException(CLASS_NAME, "processSASLBind", e);
-
- logError(ErrorLogCategory.EXTENSIONS,
- ErrorLogSeverity.SEVERE_WARNING,
- MSGID_SASLDIGESTMD5_CANNOT_GENERATE_RESPONSE_DIGEST,
- stackTraceToSingleLineString(e));
- continue;
- }
-
- if (Arrays.equals(responseDigest, generatedDigest))
- {
- matchFound = true;
- passwordBytes = v.getValue().value();
- break;
- }
- }
+ logError(ErrorLogCategory.EXTENSIONS,
+ ErrorLogSeverity.SEVERE_WARNING,
+ MSGID_SASLDIGESTMD5_CANNOT_GENERATE_RESPONSE_DIGEST,
+ stackTraceToSingleLineString(e));
+ continue;
}
- if (matchFound)
+ if (Arrays.equals(responseDigest, generatedDigest))
{
+ matchFound = true;
+ passwordBytes = clearPassword.value();
break;
}
}
@@ -1069,20 +979,10 @@
{
bindOperation.setResultCode(ResultCode.INVALID_CREDENTIALS);
- if (reversibleFound)
- {
- int msgID = MSGID_SASLDIGESTMD5_INVALID_CREDENTIALS;
- String message = getMessage(msgID);
- bindOperation.setAuthFailureReason(msgID, message);
- return;
- }
- else
- {
- int msgID = MSGID_SASLDIGESTMD5_NO_REVERSIBLE_PASSWORDS;
- String message = getMessage(msgID);
- bindOperation.setAuthFailureReason(msgID, message);
- return;
- }
+ int msgID = MSGID_SASLDIGESTMD5_INVALID_CREDENTIALS;
+ String message = getMessage(msgID);
+ bindOperation.setAuthFailureReason(msgID, message);
+ return;
}
--
Gitblit v1.10.0