Search in sources :

Example 1 with ChallengeSet

use of com.novell.ldapchai.cr.ChallengeSet in project ldapchai by ldapchai.

the class NmasResponseSet method readNmasUserResponseSet.

static NmasResponseSet readNmasUserResponseSet(final ChaiUser theUser) throws ChaiUnavailableException, ChaiValidationException {
    final GetLoginConfigRequest request = new GetLoginConfigRequest();
    request.setObjectDN(theUser.getEntryDN());
    request.setTag("ChallengeResponseQuestions");
    request.setMethodID(NMASChallengeResponse.METHOD_ID);
    request.setMethodIDLen(NMASChallengeResponse.METHOD_ID.length * 4);
    try {
        final ExtendedResponse response = theUser.getChaiProvider().extendedOperation(request);
        final byte[] responseValue = response.getEncodedValue();
        if (responseValue == null) {
            return null;
        }
        final String xmlString = new String(responseValue, "UTF8");
        LOGGER.trace("[parse v3]: read ChallengeResponseQuestions from server: " + xmlString);
        ChallengeSet cs = null;
        int parseAttempts = 0;
        final StringBuilder parsingErrorMsg = new StringBuilder();
        {
            final int beginIndex = xmlString.indexOf("<");
            if (beginIndex > 0) {
                try {
                    parseAttempts++;
                    final String xmlSubstring = xmlString.substring(beginIndex, xmlString.length());
                    LOGGER.trace("attempting parse of index stripped value: " + xmlSubstring);
                    cs = parseNmasUserResponseXML(xmlSubstring);
                    LOGGER.trace("successfully parsed nmas ChallengeResponseQuestions response after index " + beginIndex);
                } catch (JDOMException e) {
                    if (parsingErrorMsg.length() > 0) {
                        parsingErrorMsg.append(", ");
                    }
                    parsingErrorMsg.append("error parsing index stripped value: ").append(e.getMessage());
                    LOGGER.trace("unable to parse index stripped ChallengeResponseQuestions nmas response; error: " + e.getMessage());
                }
            }
        }
        if (cs == null) {
            if (xmlString.startsWith("<?xml")) {
                try {
                    parseAttempts++;
                    cs = parseNmasUserResponseXML(xmlString);
                } catch (JDOMException e) {
                    parsingErrorMsg.append("error parsing raw value: ").append(e.getMessage());
                    LOGGER.trace("unable to parse raw ChallengeResponseQuestions nmas response; will retry after stripping header; error: " + e.getMessage());
                }
                LOGGER.trace("successfully parsed full nmas ChallengeResponseQuestions response");
            }
        }
        if (cs == null) {
            if (xmlString.length() > 16) {
                // first 16 bytes are non-xml header.
                final String strippedXml = xmlString.substring(16);
                try {
                    parseAttempts++;
                    cs = parseNmasUserResponseXML(strippedXml);
                    LOGGER.trace("successfully parsed full nmas ChallengeResponseQuestions response");
                } catch (JDOMException e) {
                    if (parsingErrorMsg.length() > 0) {
                        parsingErrorMsg.append(", ");
                    }
                    parsingErrorMsg.append("error parsing header stripped value: ").append(e.getMessage());
                    LOGGER.trace("unable to parse stripped ChallengeResponseQuestions nmas response; error: " + e.getMessage());
                }
            }
        }
        if (cs == null) {
            final String logMsg = "unable to parse nmas ChallengeResponseQuestions: " + parsingErrorMsg;
            if (parseAttempts > 0 && xmlString.length() > 16) {
                LOGGER.error(logMsg);
            } else {
                LOGGER.trace(logMsg);
            }
            return null;
        }
        final Map<Challenge, String> crMap = new HashMap<Challenge, String>();
        for (final Challenge loopChallenge : cs.getChallenges()) {
            crMap.put(loopChallenge, null);
        }
        return new NmasResponseSet(crMap, cs.getLocale(), cs.getMinRandomRequired(), AbstractResponseSet.STATE.READ, theUser, cs.getIdentifier());
    } catch (ChaiOperationException e) {
        LOGGER.error("error reading nmas user response for " + theUser.getEntryDN() + ", error: " + e.getMessage());
    } catch (IOException e) {
        LOGGER.error("error reading nmas user response for " + theUser.getEntryDN() + ", error: " + e.getMessage());
    }
    return null;
}
Also used : ChallengeSet(com.novell.ldapchai.cr.ChallengeSet) ChaiChallengeSet(com.novell.ldapchai.cr.ChaiChallengeSet) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) IOException(java.io.IOException) JDOMException(org.jdom2.JDOMException) GetLoginConfigRequest(com.novell.security.nmas.jndi.ldap.ext.GetLoginConfigRequest) Challenge(com.novell.ldapchai.cr.Challenge) ChaiChallenge(com.novell.ldapchai.cr.ChaiChallenge) ExtendedResponse(javax.naming.ldap.ExtendedResponse) ChaiOperationException(com.novell.ldapchai.exception.ChaiOperationException)

Example 2 with ChallengeSet

use of com.novell.ldapchai.cr.ChallengeSet in project pwm by pwm-project.

the class CrService method validateResponses.

public void validateResponses(final ChallengeSet challengeSet, final Map<Challenge, String> responseMap, final int minRandomRequiredSetup) throws PwmDataValidationException, PwmUnrecoverableException {
    // strip null keys from responseMap;
    responseMap.keySet().removeIf(Objects::isNull);
    {
        // check for missing question texts
        for (final Challenge challenge : responseMap.keySet()) {
            if (!challenge.isAdminDefined()) {
                final String text = challenge.getChallengeText();
                if (text == null || text.length() < 1) {
                    final ErrorInformation errorInformation = new ErrorInformation(PwmError.ERROR_MISSING_CHALLENGE_TEXT);
                    throw new PwmDataValidationException(errorInformation);
                }
            }
        }
    }
    {
        // check responses against wordlist
        final WordlistManager wordlistManager = pwmApplication.getWordlistManager();
        if (wordlistManager.status() == PwmService.STATUS.OPEN) {
            for (final Map.Entry<Challenge, String> entry : responseMap.entrySet()) {
                final Challenge loopChallenge = entry.getKey();
                if (loopChallenge.isEnforceWordlist()) {
                    final String answer = entry.getValue();
                    if (wordlistManager.containsWord(answer)) {
                        final ErrorInformation errorInfo = new ErrorInformation(PwmError.ERROR_RESPONSE_WORDLIST, null, new String[] { loopChallenge.getChallengeText() });
                        throw new PwmDataValidationException(errorInfo);
                    }
                }
            }
        }
    }
    {
        // check for duplicate questions.  need to check the actual req params because the following dupes wont populate duplicates
        final Set<String> userQuestionTexts = new HashSet<>();
        for (final Challenge challenge : responseMap.keySet()) {
            final String text = challenge.getChallengeText();
            if (text != null) {
                if (userQuestionTexts.contains(text.toLowerCase())) {
                    final String errorMsg = "duplicate challenge text: " + text;
                    final ErrorInformation errorInformation = new ErrorInformation(PwmError.ERROR_CHALLENGE_DUPLICATE, errorMsg, new String[] { text });
                    throw new PwmDataValidationException(errorInformation);
                } else {
                    userQuestionTexts.add(text.toLowerCase());
                }
            }
        }
    }
    int randomCount = 0;
    for (final Challenge loopChallenge : responseMap.keySet()) {
        if (!loopChallenge.isRequired()) {
            randomCount++;
        }
    }
    if (minRandomRequiredSetup == 0) {
        // if using recover style, then all readResponseSet must be supplied at this point.
        if (randomCount < challengeSet.getRandomChallenges().size()) {
            final String errorMsg = "all randoms required, but not all randoms are completed";
            final ErrorInformation errorInfo = new ErrorInformation(PwmError.ERROR_MISSING_RANDOM_RESPONSE, errorMsg);
            throw new PwmDataValidationException(errorInfo);
        }
    }
    if (randomCount < minRandomRequiredSetup) {
        final String errorMsg = minRandomRequiredSetup + " randoms required, but not only " + randomCount + " randoms are completed";
        final ErrorInformation errorInfo = new ErrorInformation(PwmError.ERROR_MISSING_RANDOM_RESPONSE, errorMsg);
        throw new PwmDataValidationException(errorInfo);
    }
    if (JavaHelper.isEmpty(responseMap)) {
        final String errorMsg = "empty response set";
        final ErrorInformation errorInfo = new ErrorInformation(PwmError.ERROR_MISSING_PARAMETER, errorMsg);
        throw new PwmDataValidationException(errorInfo);
    }
}
Also used : ErrorInformation(password.pwm.error.ErrorInformation) PwmDataValidationException(password.pwm.error.PwmDataValidationException) ChaiChallengeSet(com.novell.ldapchai.cr.ChaiChallengeSet) Set(java.util.Set) ResponseSet(com.novell.ldapchai.cr.ResponseSet) ChallengeSet(com.novell.ldapchai.cr.ChallengeSet) HashSet(java.util.HashSet) LinkedHashSet(java.util.LinkedHashSet) Objects(java.util.Objects) WordlistManager(password.pwm.svc.wordlist.WordlistManager) Challenge(com.novell.ldapchai.cr.Challenge) ChaiChallenge(com.novell.ldapchai.cr.ChaiChallenge)

Example 3 with ChallengeSet

use of com.novell.ldapchai.cr.ChallengeSet in project pwm by pwm-project.

the class ForgottenPasswordUtil method initBogusForgottenPasswordBean.

static void initBogusForgottenPasswordBean(final PwmRequest pwmRequest) throws PwmUnrecoverableException {
    final ForgottenPasswordBean forgottenPasswordBean = ForgottenPasswordServlet.forgottenPasswordBean(pwmRequest);
    forgottenPasswordBean.setUserIdentity(null);
    forgottenPasswordBean.setPresentableChallengeSet(null);
    final List<Challenge> challengeList = new ArrayList<>();
    {
        final String firstProfile = pwmRequest.getConfig().getChallengeProfileIDs().iterator().next();
        final ChallengeSet challengeSet = pwmRequest.getConfig().getChallengeProfile(firstProfile, PwmConstants.DEFAULT_LOCALE).getChallengeSet();
        challengeList.addAll(challengeSet.getRequiredChallenges());
        for (int i = 0; i < challengeSet.getMinRandomRequired(); i++) {
            challengeList.add(challengeSet.getRandomChallenges().get(i));
        }
    }
    final List<FormConfiguration> formData = new ArrayList<>();
    {
        int counter = 0;
        for (Challenge challenge : challengeList) {
            final FormConfiguration formConfiguration = FormConfiguration.builder().name("challenge" + counter++).type(FormConfiguration.Type.text).labels(Collections.singletonMap("", challenge.getChallengeText())).minimumLength(challenge.getMinLength()).maximumLength(challenge.getMaxLength()).source(FormConfiguration.Source.bogus).build();
            formData.add(formConfiguration);
        }
    }
    forgottenPasswordBean.setAttributeForm(formData);
    forgottenPasswordBean.setBogusUser(true);
    {
        final String profileID = pwmRequest.getConfig().getForgottenPasswordProfiles().keySet().iterator().next();
        forgottenPasswordBean.setForgottenPasswordProfileID(profileID);
    }
    final ForgottenPasswordBean.RecoveryFlags recoveryFlags = new ForgottenPasswordBean.RecoveryFlags(false, Collections.singleton(IdentityVerificationMethod.ATTRIBUTES), Collections.emptySet(), 0);
    forgottenPasswordBean.setRecoveryFlags(recoveryFlags);
}
Also used : ChallengeSet(com.novell.ldapchai.cr.ChallengeSet) ArrayList(java.util.ArrayList) FormConfiguration(password.pwm.config.value.data.FormConfiguration) ForgottenPasswordBean(password.pwm.http.bean.ForgottenPasswordBean) Challenge(com.novell.ldapchai.cr.Challenge)

Example 4 with ChallengeSet

use of com.novell.ldapchai.cr.ChallengeSet in project pwm by pwm-project.

the class ForgottenPasswordUtil method verifyRequirementsForAuthMethod.

static void verifyRequirementsForAuthMethod(final PwmRequest pwmRequest, final ForgottenPasswordBean forgottenPasswordBean, final IdentityVerificationMethod recoveryVerificationMethods) throws PwmUnrecoverableException {
    switch(recoveryVerificationMethods) {
        case TOKEN:
            {
                ForgottenPasswordUtil.figureAvailableTokenDestinations(pwmRequest, forgottenPasswordBean);
            }
            break;
        case ATTRIBUTES:
            {
                final List<FormConfiguration> formConfiguration = forgottenPasswordBean.getAttributeForm();
                if (formConfiguration == null || formConfiguration.isEmpty()) {
                    final String errorMsg = "user is required to complete LDAP attribute check, yet there are no LDAP attribute form items configured";
                    final ErrorInformation errorInformation = new ErrorInformation(PwmError.ERROR_INVALID_CONFIG, errorMsg);
                    throw new PwmUnrecoverableException(errorInformation);
                }
            }
            break;
        case OTP:
            {
                final UserInfo userInfo = ForgottenPasswordUtil.readUserInfo(pwmRequest, forgottenPasswordBean);
                if (userInfo.getOtpUserRecord() == null) {
                    final String errorMsg = "could not find a one time password configuration for " + userInfo.getUserIdentity();
                    final ErrorInformation errorInformation = new ErrorInformation(PwmError.ERROR_NO_OTP_CONFIGURATION, errorMsg);
                    throw new PwmUnrecoverableException(errorInformation);
                }
            }
            break;
        case CHALLENGE_RESPONSES:
            {
                final UserInfo userInfo = ForgottenPasswordUtil.readUserInfo(pwmRequest, forgottenPasswordBean);
                final ResponseSet responseSet = ForgottenPasswordUtil.readResponseSet(pwmRequest, forgottenPasswordBean);
                if (responseSet == null) {
                    final ErrorInformation errorInformation = new ErrorInformation(PwmError.ERROR_RESPONSES_NORESPONSES);
                    throw new PwmUnrecoverableException(errorInformation);
                }
                final ChallengeSet challengeSet = userInfo.getChallengeProfile().getChallengeSet();
                try {
                    if (responseSet.meetsChallengeSetRequirements(challengeSet)) {
                        if (challengeSet.getRequiredChallenges().isEmpty() && (challengeSet.getMinRandomRequired() <= 0)) {
                            final String errorMsg = "configured challenge set policy for " + userInfo.getUserIdentity().toString() + " is empty, user not qualified to recover password";
                            final ErrorInformation errorInformation = new ErrorInformation(PwmError.ERROR_NO_CHALLENGES, errorMsg);
                            throw new PwmUnrecoverableException(errorInformation);
                        }
                    }
                } catch (ChaiValidationException e) {
                    final String errorMsg = "stored response set for user '" + userInfo.getUserIdentity() + "' do not meet current challenge set requirements: " + e.getLocalizedMessage();
                    final ErrorInformation errorInformation = new ErrorInformation(PwmError.ERROR_RESPONSES_NORESPONSES, errorMsg);
                    throw new PwmUnrecoverableException(errorInformation);
                }
            }
            break;
        default:
            // continue, assume no data requirements for method.
            break;
    }
}
Also used : ErrorInformation(password.pwm.error.ErrorInformation) ChallengeSet(com.novell.ldapchai.cr.ChallengeSet) ChaiValidationException(com.novell.ldapchai.exception.ChaiValidationException) ResponseSet(com.novell.ldapchai.cr.ResponseSet) List(java.util.List) ArrayList(java.util.ArrayList) PwmUnrecoverableException(password.pwm.error.PwmUnrecoverableException) UserInfo(password.pwm.ldap.UserInfo)

Example 5 with ChallengeSet

use of com.novell.ldapchai.cr.ChallengeSet in project pwm by pwm-project.

the class SetupResponsesServlet method setupResponses.

private void setupResponses(final PwmRequest pwmRequest, final boolean helpdeskMode) throws PwmUnrecoverableException, IOException, ServletException, ChaiUnavailableException {
    final SetupResponsesBean setupResponsesBean = getSetupResponseBean(pwmRequest);
    final SetupResponsesBean.SetupData setupData = helpdeskMode ? setupResponsesBean.getHelpdeskResponseData() : setupResponsesBean.getResponseData();
    final ChallengeSet challengeSet = setupData.getChallengeSet();
    final Map<Challenge, String> responseMap;
    try {
        // build a response set based on the user's challenge set and the html form response.
        responseMap = readResponsesFromHttpRequest(pwmRequest, setupData);
        // test the responses.
        final int minRandomRequiredSetup = setupData.getMinRandomSetup();
        pwmRequest.getPwmApplication().getCrService().validateResponses(challengeSet, responseMap, minRandomRequiredSetup);
    } catch (PwmDataValidationException e) {
        LOGGER.debug(pwmRequest, "error with new " + (helpdeskMode ? "helpdesk" : "user") + " responses: " + e.getErrorInformation().toDebugStr());
        setLastError(pwmRequest, e.getErrorInformation());
        return;
    }
    LOGGER.trace(pwmRequest, (helpdeskMode ? "helpdesk" : "user") + " responses are acceptable");
    if (helpdeskMode) {
        setupResponsesBean.getHelpdeskResponseData().setResponseMap(responseMap);
        setupResponsesBean.setHelpdeskResponsesSatisfied(true);
    } else {
        setupResponsesBean.getResponseData().setResponseMap(responseMap);
        setupResponsesBean.setResponsesSatisfied(true);
    }
}
Also used : PwmDataValidationException(password.pwm.error.PwmDataValidationException) ChallengeSet(com.novell.ldapchai.cr.ChallengeSet) SetupResponsesBean(password.pwm.http.bean.SetupResponsesBean) Challenge(com.novell.ldapchai.cr.Challenge)

Aggregations

ChallengeSet (com.novell.ldapchai.cr.ChallengeSet)11 ChaiChallengeSet (com.novell.ldapchai.cr.ChaiChallengeSet)4 Challenge (com.novell.ldapchai.cr.Challenge)4 ResponseSet (com.novell.ldapchai.cr.ResponseSet)4 ChallengeProfile (password.pwm.config.profile.ChallengeProfile)4 ErrorInformation (password.pwm.error.ErrorInformation)4 ChaiUser (com.novell.ldapchai.ChaiUser)3 ArrayList (java.util.ArrayList)3 PwmUnrecoverableException (password.pwm.error.PwmUnrecoverableException)3 ChaiChallenge (com.novell.ldapchai.cr.ChaiChallenge)2 ChaiException (com.novell.ldapchai.exception.ChaiException)2 ChaiOperationException (com.novell.ldapchai.exception.ChaiOperationException)2 ChaiValidationException (com.novell.ldapchai.exception.ChaiValidationException)2 List (java.util.List)2 Locale (java.util.Locale)2 PwmApplication (password.pwm.PwmApplication)2 FormConfiguration (password.pwm.config.value.data.FormConfiguration)2 PwmDataValidationException (password.pwm.error.PwmDataValidationException)2 ForgottenPasswordBean (password.pwm.http.bean.ForgottenPasswordBean)2 SetupResponsesBean (password.pwm.http.bean.SetupResponsesBean)2