SEC-694: Add check to LdapShaPasswordEncoder to detect use with non-SHA passwords
http://jira.springframework.org/browse/SEC-694
This commit is contained in:
@@ -15,8 +15,6 @@
|
||||
|
||||
package org.springframework.security.providers.ldap.authenticator;
|
||||
|
||||
import org.springframework.security.ldap.LdapDataAccessException;
|
||||
|
||||
import org.springframework.security.providers.encoding.PasswordEncoder;
|
||||
import org.springframework.security.providers.encoding.ShaPasswordEncoder;
|
||||
|
||||
@@ -85,7 +83,7 @@ public class LdapShaPasswordEncoder implements PasswordEncoder {
|
||||
try {
|
||||
sha = MessageDigest.getInstance("SHA");
|
||||
} catch (java.security.NoSuchAlgorithmException e) {
|
||||
throw new LdapDataAccessException("No SHA implementation available!", e);
|
||||
throw new IllegalStateException("No SHA implementation available!", e);
|
||||
}
|
||||
|
||||
sha.update(rawPass.getBytes());
|
||||
@@ -129,23 +127,44 @@ public class LdapShaPasswordEncoder implements PasswordEncoder {
|
||||
*
|
||||
* @return true if they match (independent of the case of the prefix).
|
||||
*/
|
||||
public boolean isPasswordValid(String encPass, String rawPass, Object salt) {
|
||||
String encPassWithoutPrefix;
|
||||
|
||||
if (!encPass.startsWith("{")) {
|
||||
public boolean isPasswordValid(final String encPass, final String rawPass, Object salt) {
|
||||
String prefix = extractPrefix(encPass);
|
||||
|
||||
if (prefix == null) {
|
||||
return encPass.equals(rawPass);
|
||||
}
|
||||
|
||||
if (encPass.startsWith(SSHA_PREFIX) || encPass.startsWith(SSHA_PREFIX_LC)) {
|
||||
encPassWithoutPrefix = encPass.substring(6);
|
||||
if (prefix.equals(SSHA_PREFIX) || prefix.equals(SSHA_PREFIX_LC)) {
|
||||
salt = extractSalt(encPass);
|
||||
} else if (!prefix.equals(SHA_PREFIX) && !prefix.equals(SHA_PREFIX_LC)) {
|
||||
throw new IllegalArgumentException("Unsupported password prefix '" + prefix + "'");
|
||||
} else {
|
||||
encPassWithoutPrefix = encPass.substring(5);
|
||||
salt = null;
|
||||
// Standard SHA
|
||||
salt = null;
|
||||
}
|
||||
|
||||
// Compare the encoded passwords without the prefix
|
||||
return encodePassword(rawPass, salt).endsWith(encPassWithoutPrefix);
|
||||
int startOfHash = prefix.length() + 1;
|
||||
|
||||
String encodedRawPass = encodePassword(rawPass, salt).substring(startOfHash);
|
||||
|
||||
return encodedRawPass.equals(encPass.substring(startOfHash));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the hash prefix or null if there isn't one.
|
||||
*/
|
||||
private String extractPrefix(String encPass) {
|
||||
if (!encPass.startsWith("{")) {
|
||||
return null;
|
||||
}
|
||||
|
||||
int secondBrace = encPass.lastIndexOf('}');
|
||||
|
||||
if (secondBrace < 0) {
|
||||
throw new IllegalArgumentException("Couldn't find closing brace for SHA prefix");
|
||||
}
|
||||
|
||||
return encPass.substring(0, secondBrace + 1);
|
||||
}
|
||||
|
||||
public void setForceLowerCasePrefix(boolean forceLowerCasePrefix) {
|
||||
|
||||
@@ -35,17 +35,11 @@ import java.util.Iterator;
|
||||
|
||||
/**
|
||||
* An {@link org.springframework.security.providers.ldap.LdapAuthenticator LdapAuthenticator} which compares the login
|
||||
* password with the value stored in the directory using an LDAP "compare" operation.
|
||||
* password with the value stored in the directory using a remote LDAP "compare" operation.
|
||||
*
|
||||
* <p>
|
||||
* This can be achieved either by retrieving the password attribute for the user and comparing it locally,
|
||||
* or by peforming an LDAP "compare" operation. If the password attribute (default "userPassword") is found in the
|
||||
* retrieved attributes it will be compared locally. If not, the remote comparison will be attempted.
|
||||
* </p>
|
||||
* <p>
|
||||
* If passwords are stored in digest form in the repository, then a suitable {@link PasswordEncoder}
|
||||
* implementation must be supplied. By default, passwords are encoded using the {@link LdapShaPasswordEncoder}.
|
||||
* </p>
|
||||
*
|
||||
* @author Luke Taylor
|
||||
* @version $Id$
|
||||
|
||||
Reference in New Issue
Block a user