Пример #1
0
static void authorize(const ChallengeList *challenge, AuthParams &authorization,
    const URI &uri, const std::string &method, const std::string &scheme,
    const std::string &realm, const std::string &username,
    const std::string &password)
{
    if (stricmp(scheme.c_str(), "Basic") == 0) {
        BasicAuth::authorize(authorization, username, password);
    } else if (stricmp(scheme.c_str(), "Digest") == 0) {
        MORDOR_ASSERT(challenge);
        DigestAuth::authorize(
            challengeForSchemeAndRealm(*challenge, "Digest", realm),
            authorization, uri, method, username, password);
    }
}
Пример #2
0
void
authorize(const Response &challenge, Request &nextRequest,
          const std::string &username, const std::string &password)
{
    MORDOR_ASSERT(challenge.status.status == UNAUTHORIZED ||
                  challenge.status.status == PROXY_AUTHENTICATION_REQUIRED);
    bool proxy = challenge.status.status == PROXY_AUTHENTICATION_REQUIRED;
    const ChallengeList &authenticate = proxy ?
                                        challenge.response.proxyAuthenticate :
                                        challenge.response.wwwAuthenticate;
    AuthParams &authorization = proxy ?
                                nextRequest.request.proxyAuthorization :
                                nextRequest.request.authorization;
    authorize(challengeForSchemeAndRealm(authenticate, "Digest"),
              authorization, nextRequest.requestLine.uri,
              nextRequest.requestLine.method, username, password);
}
Пример #3
0
ClientRequest::ptr
AuthRequestBroker::request(Request &requestHeaders, bool forceNewConnection,
    boost::function<void (ClientRequest::ptr)> bodyDg)
{
    ClientRequest::ptr priorRequest;
    std::string scheme, realm, username, password;
    size_t attempts = 0, proxyAttempts = 0;
#ifdef WINDOWS
    boost::scoped_ptr<NegotiateAuth> negotiateAuth, negotiateProxyAuth;
#endif
    while (true) {
#ifdef WINDOWS
        // Reset Negotiate auth sequence if the server didn't continue the
        // handshake
        if (negotiateProxyAuth) {
            const ChallengeList &challenge =
                priorRequest->response().response.proxyAuthenticate;
            if (!isAcceptable(challenge, scheme) ||
                !negotiateProxyAuth->authorize(
                    challengeForSchemeAndRealm(challenge, scheme),
                    requestHeaders.request.proxyAuthorization,
                    requestHeaders.requestLine.uri))
                negotiateProxyAuth.reset();
        }
        if (negotiateAuth) {
            const ChallengeList &challenge =
                priorRequest->response().response.wwwAuthenticate;
            if (!isAcceptable(challenge, scheme) ||
                !negotiateAuth->authorize(
                    challengeForSchemeAndRealm(challenge, scheme),
                    requestHeaders.request.authorization,
                    requestHeaders.requestLine.uri))
                negotiateAuth.reset();
        }
        // Negotiate auth is a multi-request transaction; if we're in the
        // middle of one, just do the next step, and skip asking for
        // credentials again
        if (!negotiateAuth && !negotiateProxyAuth) {
#endif
            // If this is the first try, or the last one failed UNAUTHORIZED,
            // ask for credentials, and use them if we got them
            if ((!priorRequest ||
                priorRequest->response().status.status == UNAUTHORIZED) &&
                m_getCredentialsDg &&
                m_getCredentialsDg(requestHeaders.requestLine.uri, priorRequest,
                scheme, realm, username, password, attempts++)) {
#ifdef WINDOWS
                MORDOR_ASSERT(
                    stricmp(scheme.c_str(), "Negotiate") == 0 ||
                    stricmp(scheme.c_str(), "NTLM") == 0 ||
                    stricmp(scheme.c_str(), "Digest") == 0 ||
                    stricmp(scheme.c_str(), "Basic") == 0);
#else
                    MORDOR_ASSERT(
                    stricmp(scheme.c_str(), "Digest") == 0 ||
                    stricmp(scheme.c_str(), "Basic") == 0);
#endif
#ifdef WINDOWS
                if (scheme == "Negotiate" || scheme == "NTLM") {
                    negotiateAuth.reset(new NegotiateAuth(username, password));
                    negotiateAuth->authorize(
                        challengeForSchemeAndRealm(priorRequest->response().response.wwwAuthenticate, scheme),
                        requestHeaders.request.authorization,
                        requestHeaders.requestLine.uri);
                } else
#endif
                authorize(priorRequest ?
                    &priorRequest->response().response.wwwAuthenticate : NULL,
                    requestHeaders.request.authorization,
                    requestHeaders.requestLine.uri,
                    requestHeaders.requestLine.method,
                    scheme, realm, username, password);
            } else if (priorRequest &&
                priorRequest->response().status.status == UNAUTHORIZED) {
                // caller didn't want to retry
                return priorRequest;
            }
            // If this is the first try, or the last one failed (for a proxy)
            // ask for credentials, and use them if we got them
            if ((!priorRequest ||
                priorRequest->response().status.status ==
                    PROXY_AUTHENTICATION_REQUIRED) &&
                m_getProxyCredentialsDg &&
                m_getProxyCredentialsDg(requestHeaders.requestLine.uri,
                priorRequest, scheme, realm, username, password, proxyAttempts++)) {
#ifdef WINDOWS
                MORDOR_ASSERT(
                    stricmp(scheme.c_str(), "Negotiate") == 0 ||
                    stricmp(scheme.c_str(), "NTLM") == 0 ||
                    stricmp(scheme.c_str(), "Digest") == 0 ||
                    stricmp(scheme.c_str(), "Basic") == 0);
#else
                    MORDOR_ASSERT(
                    stricmp(scheme.c_str(), "Digest") == 0 ||
                    stricmp(scheme.c_str(), "Basic") == 0);
#endif
#ifdef WINDOWS
                if (scheme == "Negotiate" || scheme == "NTLM") {
                    negotiateProxyAuth.reset(new NegotiateAuth(username, password));
                    negotiateProxyAuth->authorize(
                        challengeForSchemeAndRealm(priorRequest->response().response.proxyAuthenticate, scheme),
                        requestHeaders.request.proxyAuthorization,
                        requestHeaders.requestLine.uri);
                } else
#endif
                authorize(priorRequest ?
                    &priorRequest->response().response.proxyAuthenticate : NULL,
                    requestHeaders.request.proxyAuthorization,
                    requestHeaders.requestLine.uri,
                    requestHeaders.requestLine.method,
                    scheme, realm, username, password);
            } else if (priorRequest &&
                priorRequest->response().status.status ==
                    PROXY_AUTHENTICATION_REQUIRED) {
                // Caller didn't want to retry
                return priorRequest;
            }
#ifdef WINDOWS
        }
#endif
        if (priorRequest) {
            priorRequest->finish();
        } else {
            // We're passed our pre-emptive authentication, regardless of what
            // actually happened
            attempts = 1;
            proxyAttempts = 1;
        }
        priorRequest = parent()->request(requestHeaders, forceNewConnection,
            bodyDg);
        const ChallengeList *challengeList = NULL;
        if (priorRequest->response().status.status == UNAUTHORIZED)
            challengeList = &priorRequest->response().response.wwwAuthenticate;
        if (priorRequest->response().status.status == PROXY_AUTHENTICATION_REQUIRED)
            challengeList = &priorRequest->response().response.proxyAuthenticate;
        if (challengeList &&
            (isAcceptable(*challengeList, "Basic") ||
            isAcceptable(*challengeList, "Digest")
#ifdef WINDOWS
            || isAcceptable(*challengeList, "Negotiate") ||
            isAcceptable(*challengeList, "NTLM")
#endif
            ))
            continue;
        return priorRequest;
    }
}