Search in sources :

Example 1 with Challenge

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

the class NmasCrFactory method readNmasAssignedChallengeSetPolicy.

private static ChallengeSet readNmasAssignedChallengeSetPolicy(final ChaiProvider provider, final String challengeSetDN, final Locale locale, final String identifer) throws ChaiUnavailableException, ChaiOperationException, ChaiValidationException {
    if (challengeSetDN == null || challengeSetDN.length() < 1) {
        LOGGER.trace("challengeSetDN is null, return null for readNmasAssignedChallengeSetPolicy()");
        return null;
    }
    final List<Challenge> challenges = new ArrayList<>();
    final ChaiEntry csSetEntry = provider.getEntryFactory().newChaiEntry(challengeSetDN);
    final Map<String, String> allValues = csSetEntry.readStringAttributes(Collections.emptySet());
    final String requiredQuestions = allValues.get("nsimRequiredQuestions");
    final String randomQuestions = allValues.get("nsimRandomQuestions");
    try {
        if (requiredQuestions != null && requiredQuestions.length() > 0) {
            challenges.addAll(NmasResponseSet.parseNmasPolicyXML(requiredQuestions, locale));
        }
        if (randomQuestions != null && randomQuestions.length() > 0) {
            challenges.addAll(NmasResponseSet.parseNmasPolicyXML(randomQuestions, locale));
        }
    } catch (JDOMException e) {
        LOGGER.debug(e);
    } catch (IOException e) {
        LOGGER.debug(e);
    }
    final int minRandQuestions = StringHelper.convertStrToInt(allValues.get("nsimNumberRandomQuestions"), 0);
    return new ChaiChallengeSet(challenges, minRandQuestions, locale, identifer);
}
Also used : ArrayList(java.util.ArrayList) ChaiChallengeSet(com.novell.ldapchai.cr.ChaiChallengeSet) ChaiEntry(com.novell.ldapchai.ChaiEntry) IOException(java.io.IOException) JDOMException(org.jdom2.JDOMException) Challenge(com.novell.ldapchai.cr.Challenge)

Example 2 with Challenge

use of com.novell.ldapchai.cr.Challenge 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 3 with Challenge

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

the class NmasResponseSet method parseNmasPolicyXML.

static List<Challenge> parseNmasPolicyXML(final String str, final Locale locale) throws IOException, JDOMException {
    final List<Challenge> returnList = new ArrayList<Challenge>();
    final Reader xmlreader = new StringReader(str);
    final SAXBuilder builder = new SAXBuilder();
    final Document doc = builder.build(xmlreader);
    final boolean required = doc.getRootElement().getName().equals("RequiredQuestions");
    for (final Iterator questionIterator = doc.getDescendants(new ElementFilter("Question")); questionIterator.hasNext(); ) {
        final Element loopQ = (Element) questionIterator.next();
        final int maxLength = StringHelper.convertStrToInt(loopQ.getAttributeValue("MaxLength"), 255);
        final int minLength = StringHelper.convertStrToInt(loopQ.getAttributeValue("MinLength"), 1);
        final String challengeText = readDisplayString(loopQ, locale);
        final Challenge challenge = new ChaiChallenge(required, challengeText, minLength, maxLength, true, 0, false);
        returnList.add(challenge);
    }
    for (Iterator iter = doc.getDescendants(new ElementFilter("UserDefined")); iter.hasNext(); ) {
        final Element loopQ = (Element) iter.next();
        final int maxLength = StringHelper.convertStrToInt(loopQ.getAttributeValue("MaxLength"), 255);
        final int minLength = StringHelper.convertStrToInt(loopQ.getAttributeValue("MinLength"), 1);
        final Challenge challenge = new ChaiChallenge(required, null, minLength, maxLength, false, 0, false);
        returnList.add(challenge);
    }
    return returnList;
}
Also used : SAXBuilder(org.jdom2.input.SAXBuilder) Element(org.jdom2.Element) ArrayList(java.util.ArrayList) Reader(java.io.Reader) StringReader(java.io.StringReader) Document(org.jdom2.Document) Challenge(com.novell.ldapchai.cr.Challenge) ChaiChallenge(com.novell.ldapchai.cr.ChaiChallenge) ElementFilter(org.jdom2.filter.ElementFilter) StringReader(java.io.StringReader) Iterator(java.util.Iterator) ChaiChallenge(com.novell.ldapchai.cr.ChaiChallenge)

Example 4 with Challenge

use of com.novell.ldapchai.cr.Challenge 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 5 with Challenge

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

the class CrService method applyPwmPolicyToNmasChallenges.

private static ChallengeSet applyPwmPolicyToNmasChallenges(final ChallengeSet challengeSet, final Configuration configuration) throws PwmUnrecoverableException {
    final List<Challenge> newChallenges = new ArrayList<>();
    final boolean applyWordlist = configuration.readSettingAsBoolean(PwmSetting.EDIRECTORY_CR_APPLY_WORDLIST);
    final int questionsInAnswer = (int) configuration.readSettingAsLong(PwmSetting.EDIRECTORY_CR_MAX_QUESTION_CHARS_IN__ANSWER);
    for (final Challenge challenge : challengeSet.getChallenges()) {
        newChallenges.add(new ChaiChallenge(challenge.isRequired(), challenge.getChallengeText(), challenge.getMinLength(), challenge.getMaxLength(), challenge.isAdminDefined(), questionsInAnswer, applyWordlist));
    }
    try {
        return new ChaiChallengeSet(newChallenges, challengeSet.getMinRandomRequired(), challengeSet.getLocale(), challengeSet.getIdentifier());
    } catch (ChaiValidationException e) {
        final String errorMsg = "unexpected error applying policies to nmas challengeset: " + e.getMessage();
        LOGGER.error(errorMsg, e);
        throw new PwmUnrecoverableException(new ErrorInformation(PwmError.ERROR_UNKNOWN, errorMsg));
    }
}
Also used : ErrorInformation(password.pwm.error.ErrorInformation) ChaiValidationException(com.novell.ldapchai.exception.ChaiValidationException) ArrayList(java.util.ArrayList) ChaiChallengeSet(com.novell.ldapchai.cr.ChaiChallengeSet) PwmUnrecoverableException(password.pwm.error.PwmUnrecoverableException) Challenge(com.novell.ldapchai.cr.Challenge) ChaiChallenge(com.novell.ldapchai.cr.ChaiChallenge) ChaiChallenge(com.novell.ldapchai.cr.ChaiChallenge)

Aggregations

Challenge (com.novell.ldapchai.cr.Challenge)16 ChaiChallenge (com.novell.ldapchai.cr.ChaiChallenge)9 ChaiChallengeSet (com.novell.ldapchai.cr.ChaiChallengeSet)6 ArrayList (java.util.ArrayList)6 LinkedHashMap (java.util.LinkedHashMap)5 ChallengeSet (com.novell.ldapchai.cr.ChallengeSet)4 ChaiValidationException (com.novell.ldapchai.exception.ChaiValidationException)4 ErrorInformation (password.pwm.error.ErrorInformation)4 IOException (java.io.IOException)3 HashMap (java.util.HashMap)3 Element (org.jdom2.Element)3 JDOMException (org.jdom2.JDOMException)3 PwmDataValidationException (password.pwm.error.PwmDataValidationException)3 SetupResponsesBean (password.pwm.http.bean.SetupResponsesBean)3 Answer (com.novell.ldapchai.cr.Answer)2 ResponseSet (com.novell.ldapchai.cr.ResponseSet)2 ChaiOperationException (com.novell.ldapchai.exception.ChaiOperationException)2 ChaiUnavailableException (com.novell.ldapchai.exception.ChaiUnavailableException)2 Reader (java.io.Reader)2 StringReader (java.io.StringReader)2