/* See LICENSE for licensing and NOTICE for copyright. */ package org.ldaptive.auth; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import org.ldaptive.CompareOperation; import org.ldaptive.CompareRequest; import org.ldaptive.Connection; import org.ldaptive.LdapAttribute; import org.ldaptive.LdapException; import org.ldaptive.LdapUtils; import org.ldaptive.Response; /** * Provides implementation common to compare authentication handlers. * * @author Middleware Services */ public abstract class AbstractCompareAuthenticationHandler extends AbstractAuthenticationHandler { /** Default password scheme. Value is {@value}. */ protected static final String DEFAULT_SCHEME = "SHA"; /** Default password attribute. Value is {@value}. */ protected static final String DEFAULT_ATTRIBUTE = "userPassword"; /** Password scheme. */ private String passwordScheme = DEFAULT_SCHEME; /** Password attribute. */ private String passwordAttribute = DEFAULT_ATTRIBUTE; /** * Returns the password scheme. * * @return password scheme */ public String getPasswordScheme() { return passwordScheme; } /** * Sets the password scheme. Must equal a known message digest algorithm. * * @param s password scheme */ public void setPasswordScheme(final String s) { passwordScheme = s; } /** * Returns the password attribute. * * @return password attribute */ public String getPasswordAttribute() { return passwordAttribute; } /** * Sets the password attribute. Must equal a readable attribute in LDAP scheme. * * @param s password attribute */ public void setPasswordAttribute(final String s) { passwordAttribute = s; } @Override protected AuthenticationHandlerResponse authenticateInternal( final Connection c, final AuthenticationCriteria criteria) throws LdapException { byte[] hash; try { final MessageDigest md = MessageDigest.getInstance(passwordScheme); md.update(criteria.getCredential().getBytes()); hash = md.digest(); } catch (NoSuchAlgorithmException e) { throw new LdapException(e); } final LdapAttribute la = new LdapAttribute( passwordAttribute, String.format("{%s}%s", passwordScheme, LdapUtils.base64Encode(hash)).getBytes()); final CompareOperation compare = new CompareOperation(c); final CompareRequest request = new CompareRequest(criteria.getDn(), la); request.setControls(getAuthenticationControls()); final Response<Boolean> compareResponse = compare.execute(request); return new AuthenticationHandlerResponse( compareResponse.getResult(), compareResponse.getResultCode(), c, compareResponse.getMessage(), compareResponse.getControls(), compareResponse.getMessageId()); } /** * Returns a connection that the compare operation should be performed on. * * @return connection * * @throws LdapException if an error occurs provisioning the connection */ @Override protected abstract Connection getConnection() throws LdapException; }