use of password.pwm.error.PwmUnrecoverableException in project pwm by pwm-project.
the class LdapOperationsHelper method openProxyChaiProvider.
static ChaiProvider openProxyChaiProvider(final ChaiProviderFactory chaiProviderFactory, final SessionLabel sessionLabel, final LdapProfile ldapProfile, final Configuration config, final StatisticsManager statisticsManager) throws PwmUnrecoverableException {
LOGGER.trace(sessionLabel, "opening new ldap proxy connection");
final String proxyDN = ldapProfile.readSettingAsString(PwmSetting.LDAP_PROXY_USER_DN);
final PasswordData proxyPW = ldapProfile.readSettingAsPassword(PwmSetting.LDAP_PROXY_USER_PASSWORD);
try {
return createChaiProvider(chaiProviderFactory, sessionLabel, ldapProfile, config, proxyDN, proxyPW);
} catch (ChaiUnavailableException e) {
if (statisticsManager != null) {
statisticsManager.incrementValue(Statistic.LDAP_UNAVAILABLE_COUNT);
}
final StringBuilder errorMsg = new StringBuilder();
errorMsg.append("error connecting as proxy user: ");
final PwmError pwmError = PwmError.forChaiError(e.getErrorCode());
if (pwmError != null && pwmError != PwmError.ERROR_UNKNOWN) {
errorMsg.append(new ErrorInformation(pwmError, e.getMessage()).toDebugStr());
} else {
errorMsg.append(e.getMessage());
}
final ErrorInformation errorInformation = new ErrorInformation(PwmError.ERROR_DIRECTORY_UNAVAILABLE, errorMsg.toString());
LOGGER.fatal(sessionLabel, "check ldap proxy settings: " + errorInformation.toDebugStr());
throw new PwmUnrecoverableException(errorInformation);
}
}
use of password.pwm.error.PwmUnrecoverableException in project pwm by pwm-project.
the class LdapOperationsHelper method readLdapPassword.
public static PasswordData readLdapPassword(final PwmApplication pwmApplication, final SessionLabel sessionLabel, final UserIdentity userIdentity) throws ChaiUnavailableException, PwmUnrecoverableException {
if (userIdentity == null || userIdentity.getUserDN() == null || userIdentity.getUserDN().length() < 1) {
throw new NullPointerException("invalid user (null)");
}
final ChaiProvider chaiProvider = pwmApplication.getProxyChaiProvider(userIdentity.getLdapProfileID());
final ChaiUser chaiUser = chaiProvider.getEntryFactory().newChaiUser(userIdentity.getUserDN());
// use chai (nmas) to retrieve user password
if (pwmApplication.getConfig().readSettingAsBoolean(PwmSetting.EDIRECTORY_READ_USER_PWD)) {
String currentPass = null;
try {
final String readPassword = chaiUser.readPassword();
if (readPassword != null && readPassword.length() > 0) {
currentPass = readPassword;
LOGGER.debug(sessionLabel, "successfully retrieved user's current password from ldap, now conducting standard authentication");
}
} catch (Exception e) {
LOGGER.debug(sessionLabel, "unable to retrieve user password from ldap: " + e.getMessage());
}
// actually do the authentication since we have user pw.
if (currentPass != null && currentPass.length() > 0) {
return new PasswordData(currentPass);
}
} else {
LOGGER.trace(sessionLabel, "skipping attempt to read user password, option disabled");
}
return null;
}
use of password.pwm.error.PwmUnrecoverableException in project pwm by pwm-project.
the class LdapOperationsHelper method createChaiConfiguration.
public static ChaiConfiguration createChaiConfiguration(final Configuration config, final LdapProfile ldapProfile, final List<String> ldapURLs, final String userDN, final PasswordData userPassword) throws PwmUnrecoverableException {
final ChaiConfiguration.ChaiConfigurationBuilder configBuilder = ChaiConfiguration.builder(ldapURLs, userDN, userPassword == null ? null : userPassword.getStringValue());
configBuilder.setSetting(ChaiSetting.PROMISCUOUS_SSL, config.readAppProperty(AppProperty.LDAP_PROMISCUOUS_ENABLE));
{
final boolean enableNmasExtensions = Boolean.parseBoolean(config.readAppProperty(AppProperty.LDAP_EXTENSIONS_NMAS_ENABLE));
configBuilder.setSetting(ChaiSetting.EDIRECTORY_ENABLE_NMAS, Boolean.toString(enableNmasExtensions));
}
configBuilder.setSetting(ChaiSetting.CR_CHAI_STORAGE_ATTRIBUTE, ldapProfile.readSettingAsString(PwmSetting.CHALLENGE_USER_ATTRIBUTE));
configBuilder.setSetting(ChaiSetting.CR_ALLOW_DUPLICATE_RESPONSES, Boolean.toString(config.readSettingAsBoolean(PwmSetting.CHALLENGE_ALLOW_DUPLICATE_RESPONSES)));
configBuilder.setSetting(ChaiSetting.CR_CASE_INSENSITIVE, Boolean.toString(config.readSettingAsBoolean(PwmSetting.CHALLENGE_CASE_INSENSITIVE)));
{
final String setting = config.readAppProperty(AppProperty.SECURITY_RESPONSES_HASH_ITERATIONS);
if (setting != null && setting.length() > 0) {
final int intValue = Integer.parseInt(setting);
configBuilder.setSetting(ChaiSetting.CR_CHAI_SALT_COUNT, Integer.toString(intValue));
}
}
// can cause issues with previous password authentication
configBuilder.setSetting(ChaiSetting.JNDI_ENABLE_POOL, "false");
configBuilder.setSetting(ChaiSetting.CR_DEFAULT_FORMAT_TYPE, Answer.FormatType.SHA1_SALT.toString());
final String storageMethodString = config.readSettingAsString(PwmSetting.CHALLENGE_STORAGE_HASHED);
try {
final Answer.FormatType formatType = Answer.FormatType.valueOf(storageMethodString);
configBuilder.setSetting(ChaiSetting.CR_DEFAULT_FORMAT_TYPE, formatType.toString());
} catch (Exception e) {
LOGGER.warn("unknown CR storage format type '" + storageMethodString + "' ");
}
final List<X509Certificate> ldapServerCerts = ldapProfile.readSettingAsCertificate(PwmSetting.LDAP_SERVER_CERTS);
if (ldapServerCerts != null && ldapServerCerts.size() > 0) {
final X509TrustManager tm = new X509Utils.CertMatchingTrustManager(config, ldapServerCerts);
configBuilder.setTrustManager(new X509TrustManager[] { tm });
}
final String idleTimeoutMsString = config.readAppProperty(AppProperty.LDAP_CONNECTION_TIMEOUT);
configBuilder.setSetting(ChaiSetting.LDAP_CONNECT_TIMEOUT, idleTimeoutMsString);
// set the watchdog idle timeout.
final int idleTimeoutMs = (int) config.readSettingAsLong(PwmSetting.LDAP_IDLE_TIMEOUT) * 1000;
if (idleTimeoutMs > 0) {
configBuilder.setSetting(ChaiSetting.WATCHDOG_ENABLE, "true");
configBuilder.setSetting(ChaiSetting.WATCHDOG_IDLE_TIMEOUT, idleTimeoutMsString);
} else {
configBuilder.setSetting(ChaiSetting.WATCHDOG_ENABLE, "false");
}
configBuilder.setSetting(ChaiSetting.LDAP_SEARCH_PAGING_ENABLE, config.readAppProperty(AppProperty.LDAP_SEARCH_PAGING_ENABLE));
configBuilder.setSetting(ChaiSetting.LDAP_SEARCH_PAGING_SIZE, config.readAppProperty(AppProperty.LDAP_SEARCH_PAGING_SIZE));
if (config.readSettingAsBoolean(PwmSetting.AD_ENFORCE_PW_HISTORY_ON_SET)) {
configBuilder.setSetting(ChaiSetting.AD_SET_POLICY_HINTS_ON_PW_SET, "true");
}
// write out any configured values;
final String rawValue = config.readAppProperty(AppProperty.LDAP_CHAI_SETTINGS);
final String[] rawValues = rawValue != null ? rawValue.split(AppProperty.VALUE_SEPARATOR) : new String[0];
final Map<String, String> configuredSettings = StringUtil.convertStringListToNameValuePair(Arrays.asList(rawValues), "=");
for (final Map.Entry<String, String> entry : configuredSettings.entrySet()) {
final String key = entry.getKey();
if (key != null && !key.isEmpty()) {
final ChaiSetting theSetting = ChaiSetting.forKey(key);
if (theSetting == null) {
LOGGER.warn("ignoring unknown chai setting '" + key + "'");
} else {
configBuilder.setSetting(theSetting, entry.getValue());
}
}
}
// set ldap referrals
configBuilder.setSetting(ChaiSetting.LDAP_FOLLOW_REFERRALS, String.valueOf(config.readSettingAsBoolean(PwmSetting.LDAP_FOLLOW_REFERRALS)));
// enable wire trace;
if (config.readSettingAsBoolean(PwmSetting.LDAP_ENABLE_WIRE_TRACE)) {
configBuilder.setSetting(ChaiSetting.WIRETRACE_ENABLE, "true");
}
return configBuilder.build();
}
use of password.pwm.error.PwmUnrecoverableException in project pwm by pwm-project.
the class PasswordChangeProgressChecker method figureReplicationStatusCompletion.
private ProgressRecord figureReplicationStatusCompletion(final ProgressTracker tracker) {
final long initDelayMs = Long.parseLong(pwmApplication.getConfig().readAppProperty(AppProperty.LDAP_PASSWORD_REPLICA_CHECK_INIT_DELAY_MS));
final long cycleDelayMs = Long.parseLong(pwmApplication.getConfig().readAppProperty(AppProperty.LDAP_PASSWORD_REPLICA_CHECK_CYCLE_DELAY_MS));
final TimeDuration initialReplicaDelay = new TimeDuration(initDelayMs);
final TimeDuration cycleReplicaDelay = new TimeDuration(cycleDelayMs);
if (passwordSyncCheckMode == PasswordSyncCheckMode.DISABLED) {
LOGGER.trace(pwmSession, "skipping replica sync check, disabled");
return tracker.itemCompletions.get(PROGRESS_KEY_REPLICATION);
}
if (tracker.itemCompletions.containsKey(PROGRESS_KEY_REPLICATION)) {
if (tracker.itemCompletions.get(PROGRESS_KEY_REPLICATION).complete) {
LOGGER.trace(pwmSession, "skipping replica sync check, replica sync completed previously");
return tracker.itemCompletions.get(PROGRESS_KEY_REPLICATION);
}
}
if (tracker.lastReplicaCheckTime == null) {
if (TimeDuration.fromCurrent(tracker.beginTime).isShorterThan(initialReplicaDelay)) {
LOGGER.trace(pwmSession, "skipping replica sync check, initDelay has not yet passed");
return null;
}
} else if (TimeDuration.fromCurrent(tracker.lastReplicaCheckTime).isShorterThan(cycleReplicaDelay)) {
LOGGER.trace(pwmSession, "skipping replica sync check, cycleDelay has not yet passed");
return null;
}
tracker.lastReplicaCheckTime = Instant.now();
LOGGER.trace(pwmSession, "beginning password replication time check for " + userIdentity.toDelimitedKey());
try {
final Map<String, Instant> checkResults = PasswordUtility.readIndividualReplicaLastPasswordTimes(pwmApplication, pwmSession, userIdentity);
if (checkResults.size() <= 1) {
LOGGER.trace("only one replica returned data, marking as complete");
return completedReplicationRecord;
} else {
final HashSet<Instant> tempHashSet = new HashSet<>();
int duplicateValues = 0;
for (final Instant date : checkResults.values()) {
if (tempHashSet.contains(date)) {
duplicateValues++;
} else {
tempHashSet.add(date);
}
}
final Percent pctComplete = new Percent(duplicateValues + 1, checkResults.size());
final ProgressRecord progressRecord = makeReplicaProgressRecord(pctComplete);
LOGGER.trace("read password replication sync status as: " + JsonUtil.serialize(progressRecord));
return progressRecord;
}
} catch (PwmUnrecoverableException e) {
LOGGER.error(pwmSession, "error during password replication status check: " + e.getMessage());
}
return null;
}
use of password.pwm.error.PwmUnrecoverableException in project pwm by pwm-project.
the class LDAPAuthenticationRequest method testCredentials.
private void testCredentials(final UserIdentity userIdentity, final PasswordData password) throws ChaiUnavailableException, PwmUnrecoverableException, PwmOperationalException {
log(PwmLogLevel.TRACE, "beginning testCredentials process");
if (userIdentity == null || userIdentity.getUserDN() == null || userIdentity.getUserDN().length() < 1) {
final String errorMsg = "attempt to authenticate with null userDN";
log(PwmLogLevel.DEBUG, errorMsg);
throw new PwmOperationalException(new ErrorInformation(PwmError.ERROR_WRONGPASSWORD, errorMsg));
}
if (password == null) {
final String errorMsg = "attempt to authenticate with null password";
log(PwmLogLevel.DEBUG, errorMsg);
throw new PwmOperationalException(new ErrorInformation(PwmError.ERROR_WRONGPASSWORD, errorMsg));
}
// try authenticating the user using a normal ldap BIND operation.
log(PwmLogLevel.TRACE, "attempting authentication using ldap BIND");
boolean bindSucceeded = false;
try {
// read a provider using the user's DN and password.
userProvider = LdapOperationsHelper.createChaiProvider(pwmApplication, sessionLabel, userIdentity.getLdapProfile(pwmApplication.getConfig()), pwmApplication.getConfig(), userIdentity.getUserDN(), password);
// issue a read operation to trigger a bind.
userProvider.readStringAttribute(userIdentity.getUserDN(), ChaiConstant.ATTR_LDAP_OBJECTCLASS);
bindSucceeded = true;
} catch (ChaiException e) {
if (e.getErrorCode() != null && e.getErrorCode() == ChaiError.INTRUDER_LOCKOUT) {
final String errorMsg = "intruder lockout detected for user " + userIdentity + " marking session as locked out: " + e.getMessage();
final ErrorInformation errorInformation = new ErrorInformation(PwmError.ERROR_INTRUDER_LDAP, errorMsg);
log(PwmLogLevel.WARN, errorInformation.toDebugStr());
throw new PwmUnrecoverableException(errorInformation);
}
final PwmError pwmError = PwmError.forChaiError(e.getErrorCode());
final ErrorInformation errorInformation;
if (pwmError != null && PwmError.ERROR_UNKNOWN != pwmError) {
errorInformation = new ErrorInformation(pwmError, e.getMessage());
} else {
errorInformation = new ErrorInformation(PwmError.ERROR_WRONGPASSWORD, "ldap error during password check: " + e.getMessage());
}
log(PwmLogLevel.DEBUG, errorInformation.toDebugStr());
throw new PwmOperationalException(errorInformation);
} finally {
if (!bindSucceeded && userProvider != null) {
try {
userProvider.close();
userProvider = null;
} catch (Throwable e) {
log(PwmLogLevel.ERROR, "unexpected error closing invalid ldap connection after failed login attempt: " + e.getMessage());
}
}
}
}
Aggregations