Search in sources :

Example 21 with PwmUnrecoverableException

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);
    }
}
Also used : ErrorInformation(password.pwm.error.ErrorInformation) ChaiUnavailableException(com.novell.ldapchai.exception.ChaiUnavailableException) PasswordData(password.pwm.util.PasswordData) PwmError(password.pwm.error.PwmError) PwmUnrecoverableException(password.pwm.error.PwmUnrecoverableException)

Example 22 with PwmUnrecoverableException

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;
}
Also used : ChaiProvider(com.novell.ldapchai.provider.ChaiProvider) ChaiUser(com.novell.ldapchai.ChaiUser) PasswordData(password.pwm.util.PasswordData) PwmUnrecoverableException(password.pwm.error.PwmUnrecoverableException) PwmOperationalException(password.pwm.error.PwmOperationalException) ChaiUnavailableException(com.novell.ldapchai.exception.ChaiUnavailableException) ChaiOperationException(com.novell.ldapchai.exception.ChaiOperationException) IOException(java.io.IOException)

Example 23 with PwmUnrecoverableException

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();
}
Also used : ChaiConfiguration(com.novell.ldapchai.provider.ChaiConfiguration) PwmUnrecoverableException(password.pwm.error.PwmUnrecoverableException) PwmOperationalException(password.pwm.error.PwmOperationalException) ChaiUnavailableException(com.novell.ldapchai.exception.ChaiUnavailableException) ChaiOperationException(com.novell.ldapchai.exception.ChaiOperationException) IOException(java.io.IOException) X509Certificate(java.security.cert.X509Certificate) Answer(com.novell.ldapchai.cr.Answer) ChaiSetting(com.novell.ldapchai.provider.ChaiSetting) X509TrustManager(javax.net.ssl.X509TrustManager) Map(java.util.Map) HashMap(java.util.HashMap)

Example 24 with PwmUnrecoverableException

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;
}
Also used : Percent(password.pwm.util.java.Percent) Instant(java.time.Instant) TimeDuration(password.pwm.util.java.TimeDuration) PwmUnrecoverableException(password.pwm.error.PwmUnrecoverableException) HashSet(java.util.HashSet)

Example 25 with PwmUnrecoverableException

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());
            }
        }
    }
}
Also used : ErrorInformation(password.pwm.error.ErrorInformation) PwmError(password.pwm.error.PwmError) PwmUnrecoverableException(password.pwm.error.PwmUnrecoverableException) ChaiException(com.novell.ldapchai.exception.ChaiException) PwmOperationalException(password.pwm.error.PwmOperationalException)

Aggregations

PwmUnrecoverableException (password.pwm.error.PwmUnrecoverableException)282 ErrorInformation (password.pwm.error.ErrorInformation)201 PwmOperationalException (password.pwm.error.PwmOperationalException)85 ChaiUnavailableException (com.novell.ldapchai.exception.ChaiUnavailableException)75 IOException (java.io.IOException)72 PwmException (password.pwm.error.PwmException)69 PwmApplication (password.pwm.PwmApplication)48 UserIdentity (password.pwm.bean.UserIdentity)48 Configuration (password.pwm.config.Configuration)43 ServletException (javax.servlet.ServletException)38 LinkedHashMap (java.util.LinkedHashMap)37 Instant (java.time.Instant)35 ArrayList (java.util.ArrayList)31 PwmSession (password.pwm.http.PwmSession)30 Map (java.util.Map)28 ChaiUser (com.novell.ldapchai.ChaiUser)26 ChaiOperationException (com.novell.ldapchai.exception.ChaiOperationException)25 FormConfiguration (password.pwm.config.value.data.FormConfiguration)24 HashMap (java.util.HashMap)23 ChaiException (com.novell.ldapchai.exception.ChaiException)22