Changeset 141350 in webkit


Ignore:
Timestamp:
Jan 30, 2013 5:26:22 PM (11 years ago)
Author:
commit-queue@webkit.org
Message:

[BlackBerry] Store both proxy and host credentials simultaneously for NetworkJob
https://bugs.webkit.org/show_bug.cgi?id=108388

Patch by Joe Mason <jmason@rim.com> on 2013-01-30
Reviewed by Yong Li.

The platform NetworkRequest interface has been updated again, to store both a proxy and host
credential for each request (to prevent an infinite loop when a request authenticates against a
proxy but fails the host authentication, and then the followup contains the host credential but not
the proxy credential so it fails proxy authentication, so the next followup contains the proxy
credential but not the host credential...)

Complying with the new interface requires the host and proxy challenge to be stored separately in
webkit so they can both be added to the same NetworkRequest.

Internal PR: 281172
Internal Reviewer: Leo Yang

  • platform/network/ResourceHandleInternal.h:

(ResourceHandleInternal):

  • platform/network/blackberry/AuthenticationChallenge.h:

(WebCore::AuthenticationChallenge::hasCredentials):
(AuthenticationChallenge):

  • platform/network/blackberry/NetworkJob.cpp:

(WebCore::NetworkJob::notifyAuthReceived):
(WebCore::NetworkJob::handleRedirect):
(WebCore::NetworkJob::sendRequestWithCredentials):
(WebCore::NetworkJob::storeCredentials):
(WebCore):
(WebCore::NetworkJob::purgeCredentials):
(WebCore::NetworkJob::notifyChallengeResult):
(WebCore::NetworkJob::updateCurrentWebChallenge):

  • platform/network/blackberry/NetworkJob.h:

(NetworkJob):

  • platform/network/blackberry/NetworkManager.cpp:

(WebCore::setAuthCredentials):
(WebCore):
(WebCore::NetworkManager::startJob):

Location:
trunk/Source/WebCore
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r141348 r141350  
     12013-01-30  Joe Mason  <jmason@rim.com>
     2
     3        [BlackBerry] Store both proxy and host credentials simultaneously for NetworkJob
     4        https://bugs.webkit.org/show_bug.cgi?id=108388
     5
     6        Reviewed by Yong Li.
     7
     8        The platform NetworkRequest interface has been updated again, to store both a proxy and host
     9        credential for each request (to prevent an infinite loop when a request authenticates against a
     10        proxy but fails the host authentication, and then the followup contains the host credential but not
     11        the proxy credential so it fails proxy authentication, so the next followup contains the proxy
     12        credential but not the host credential...)
     13
     14        Complying with the new interface requires the host and proxy challenge to be stored separately in
     15        webkit so they can both be added to the same NetworkRequest.
     16
     17        Internal PR: 281172
     18        Internal Reviewer: Leo Yang
     19
     20        * platform/network/ResourceHandleInternal.h:
     21        (ResourceHandleInternal):
     22        * platform/network/blackberry/AuthenticationChallenge.h:
     23        (WebCore::AuthenticationChallenge::hasCredentials):
     24        (AuthenticationChallenge):
     25        * platform/network/blackberry/NetworkJob.cpp:
     26        (WebCore::NetworkJob::notifyAuthReceived):
     27        (WebCore::NetworkJob::handleRedirect):
     28        (WebCore::NetworkJob::sendRequestWithCredentials):
     29        (WebCore::NetworkJob::storeCredentials):
     30        (WebCore):
     31        (WebCore::NetworkJob::purgeCredentials):
     32        (WebCore::NetworkJob::notifyChallengeResult):
     33        (WebCore::NetworkJob::updateCurrentWebChallenge):
     34        * platform/network/blackberry/NetworkJob.h:
     35        (NetworkJob):
     36        * platform/network/blackberry/NetworkManager.cpp:
     37        (WebCore::setAuthCredentials):
     38        (WebCore):
     39        (WebCore::NetworkManager::startJob):
     40
    1412013-01-30  Oliver Hunt  <oliver@apple.com>
    242
  • trunk/Source/WebCore/platform/network/ResourceHandleInternal.h

    r140425 r141350  
    224224#endif
    225225        AuthenticationChallenge m_currentWebChallenge;
     226#if PLATFORM(BLACKBERRY)
     227        // We need to store the credentials for host and proxy separately for the platform
     228        // networking layer. One of these will always be equal to m_currentWebChallenge.
     229        AuthenticationChallenge m_hostWebChallenge;
     230        AuthenticationChallenge m_proxyWebChallenge;
     231#endif
    226232
    227233        ResourceHandle::FailureType m_scheduledFailureType;
  • trunk/Source/WebCore/platform/network/blackberry/AuthenticationChallenge.h

    r101312 r141350  
    4040    bool isStored() const { return m_isStored; }
    4141
     42    bool hasCredentials() const
     43    {
     44        if (isNull())
     45            return false;
     46        return !proposedCredential().isEmpty();
     47    }
     48
    4249private:
    4350    // Describes if attached credentials are stored in CredentialStorage.
  • trunk/Source/WebCore/platform/network/blackberry/NetworkJob.cpp

    r141336 r141350  
    4444#include <network/MultipartStream.h>
    4545#include <network/NetworkStreamFactory.h>
     46
     47using BlackBerry::Platform::NetworkRequest;
    4648
    4749namespace WebCore {
     
    269271}
    270272
    271 void NetworkJob::notifyAuthReceived(BlackBerry::Platform::NetworkRequest::AuthType authType, BlackBerry::Platform::NetworkRequest::AuthScheme authScheme, const char* realm, AuthResult result, bool requireCredentials)
    272 {
    273     using BlackBerry::Platform::NetworkRequest;
    274 
     273void NetworkJob::notifyAuthReceived(NetworkRequest::AuthType authType, NetworkRequest::AuthProtocol authProtocol, NetworkRequest::AuthScheme authScheme, const char* realm, AuthResult result, bool requireCredentials)
     274{
    275275    ProtectionSpaceServerType serverType;
    276276    switch (authType) {
    277     case NetworkRequest::AuthTypeHTTP:
    278         serverType = ProtectionSpaceServerHTTP;
     277    case NetworkRequest::AuthTypeHost:
     278        switch (authProtocol) {
     279        case NetworkRequest::AuthProtocolHTTP:
     280            serverType = ProtectionSpaceServerHTTP;
     281            break;
     282        case NetworkRequest::AuthProtocolHTTPS:
     283            serverType = ProtectionSpaceServerHTTPS;
     284            break;
     285        case NetworkRequest::AuthProtocolFTP:
     286            serverType = ProtectionSpaceServerFTP;
     287            break;
     288        case NetworkRequest::AuthProtocolFTPS:
     289            serverType = ProtectionSpaceServerFTPS;
     290            break;
     291        default:
     292            ASSERT_NOT_REACHED();
     293            return;
     294        }
    279295        break;
    280     case NetworkRequest::AuthTypeHTTPS:
    281         serverType = ProtectionSpaceServerHTTPS;
    282         break;
    283     case NetworkRequest::AuthTypeFTP:
    284         serverType = ProtectionSpaceServerFTP;
    285         break;
    286     case NetworkRequest::AuthTypeFTPS:
    287         serverType = ProtectionSpaceServerFTPS;
    288         break;
    289     case NetworkRequest::AuthTypeProxyHTTP:
    290         serverType = ProtectionSpaceProxyHTTP;
    291         break;
    292     case NetworkRequest::AuthTypeProxyHTTPS:
    293         serverType = ProtectionSpaceProxyHTTPS;
    294         break;
    295     case NetworkRequest::AuthTypeProxyFTP:
    296         serverType = ProtectionSpaceProxyFTP;
     296    case NetworkRequest::AuthTypeProxy:
     297        switch (authProtocol) {
     298        case NetworkRequest::AuthProtocolHTTP:
     299            serverType = ProtectionSpaceProxyHTTP;
     300            break;
     301        case NetworkRequest::AuthProtocolHTTPS:
     302            serverType = ProtectionSpaceProxyHTTPS;
     303            break;
     304        case NetworkRequest::AuthProtocolFTP:
     305        case NetworkRequest::AuthProtocolFTPS:
     306            serverType = ProtectionSpaceProxyFTP;
     307            break;
     308        default:
     309            ASSERT_NOT_REACHED();
     310            return;
     311        }
    297312        break;
    298313    default:
     
    330345    else {
    331346        // Update the credentials that will be stored to match the scheme that was actually used
    332         AuthenticationChallenge& challenge = m_handle->getInternal()->m_currentWebChallenge;
    333         if (!challenge.isNull()) {
     347        AuthenticationChallenge& challenge = authType == NetworkRequest::AuthTypeProxy ? m_handle->getInternal()->m_proxyWebChallenge : m_handle->getInternal()->m_hostWebChallenge;
     348        if (challenge.hasCredentials()) {
    334349            const ProtectionSpace& oldSpace = challenge.protectionSpace();
    335350            if (oldSpace.authenticationScheme() != scheme && oldSpace.serverType() == serverType) {
    336351                ProtectionSpace newSpace(oldSpace.host(), oldSpace.port(), oldSpace.serverType(), oldSpace.realm(), scheme);
    337                 m_handle->getInternal()->m_currentWebChallenge = AuthenticationChallenge(newSpace,
    338                                                                                          challenge.proposedCredential(),
    339                                                                                          challenge.previousFailureCount(),
    340                                                                                          challenge.failureResponse(),
    341                                                                                          challenge.error());
     352                updateCurrentWebChallenge(AuthenticationChallenge(newSpace, challenge.proposedCredential(), challenge.previousFailureCount(), challenge.failureResponse(), challenge.error()));
    342353            }
    343354        }
     
    654665    }
    655666
    656     if (!m_handle->getInternal()->m_currentWebChallenge.isNull()) {
    657         // If this request is challenged, store the credentials now because the credential is correct (otherwise, it won't get here).
    658         storeCredentials();
    659         // Do not send existing credentials with the new request.
    660         m_handle->getInternal()->m_currentWebChallenge.nullify();
    661     }
     667    // If this request is challenged, store the credentials now (if they are null this will do nothing)
     668    storeCredentials();
     669
     670    // Do not send existing credentials with the new request.
     671    m_handle->getInternal()->m_currentWebChallenge.nullify();
     672    m_handle->getInternal()->m_proxyWebChallenge.nullify();
     673    m_handle->getInternal()->m_hostWebChallenge.nullify();
    662674
    663675    return startNewJobWithRequest(newRequest, true);
     
    818830    if (!requireCredentials) {
    819831        // Don't overwrite any existing credentials with the empty credential
    820         if (m_handle->getInternal()->m_currentWebChallenge.isNull())
    821             m_handle->getInternal()->m_currentWebChallenge = AuthenticationChallenge(protectionSpace, credential, 0, m_response, ResourceError());
     832        updateCurrentWebChallenge(AuthenticationChallenge(protectionSpace, credential, 0, m_response, ResourceError()), /* allowOverwrite */ false);
    822833    } else if (!(credential = CredentialStorage::get(protectionSpace)).isEmpty()
    823834#if ENABLE(BLACKBERRY_CREDENTIAL_PERSIST)
     
    826837            ) {
    827838        // First search the CredentialStorage and Persistent Credential Storage
    828         m_handle->getInternal()->m_currentWebChallenge = AuthenticationChallenge(protectionSpace, credential, 0, m_response, ResourceError());
    829         m_handle->getInternal()->m_currentWebChallenge.setStored(true);
     839        AuthenticationChallenge challenge(protectionSpace, credential, 0, m_response, ResourceError());
     840        challenge.setStored(true);
     841        updateCurrentWebChallenge(challenge);
    830842    } else {
    831843        if (m_handle->firstRequest().targetType() == ResourceRequest::TargetIsFavicon) {
     
    857869                return false;
    858870
    859             m_handle->getInternal()->m_currentWebChallenge = AuthenticationChallenge();
     871            // DO overwrite any existing credentials with the empty credential
     872            updateCurrentWebChallenge(AuthenticationChallenge(protectionSpace, credential, 0, m_response, ResourceError()));
    860873
    861874            m_isAuthenticationChallenging = true;
     
    869882        credential = Credential(username, password, CredentialPersistenceForSession);
    870883
    871         m_handle->getInternal()->m_currentWebChallenge = AuthenticationChallenge(protectionSpace, credential, 0, m_response, ResourceError());
     884        updateCurrentWebChallenge(AuthenticationChallenge(protectionSpace, credential, 0, m_response, ResourceError()));
    872885    }
    873886
     
    881894        return;
    882895
    883     AuthenticationChallenge& challenge = m_handle->getInternal()->m_currentWebChallenge;
     896    storeCredentials(m_handle->getInternal()->m_hostWebChallenge);
     897    storeCredentials(m_handle->getInternal()->m_proxyWebChallenge);
     898}
     899
     900void NetworkJob::storeCredentials(AuthenticationChallenge& challenge)
     901{
    884902    if (challenge.isNull())
    885903        return;
     
    923941        return;
    924942
    925     AuthenticationChallenge& challenge = m_handle->getInternal()->m_currentWebChallenge;
     943    purgeCredentials(m_handle->getInternal()->m_hostWebChallenge);
     944    purgeCredentials(m_handle->getInternal()->m_proxyWebChallenge);
     945}
     946
     947void NetworkJob::purgeCredentials(AuthenticationChallenge& challenge)
     948{
    926949    if (challenge.isNull())
    927950        return;
     
    9801003        return;
    9811004
    982     if (m_handle->getInternal()->m_currentWebChallenge.isNull())
    983         m_handle->getInternal()->m_currentWebChallenge = AuthenticationChallenge(protectionSpace, credential, 0, m_response, ResourceError());
     1005    updateCurrentWebChallenge(AuthenticationChallenge(protectionSpace, credential, 0, m_response, ResourceError()), /* allowOverwrite */ false);
    9841006
    9851007    ResourceRequest newRequest = m_handle->firstRequest();
     
    10021024}
    10031025
     1026void NetworkJob::updateCurrentWebChallenge(const AuthenticationChallenge& challenge, bool allowOverwrite)
     1027{
     1028    if (allowOverwrite || !m_handle->getInternal()->m_currentWebChallenge.hasCredentials())
     1029        m_handle->getInternal()->m_currentWebChallenge = challenge;
     1030    if (challenge.protectionSpace().serverType() == ProtectionSpaceProxyHTTP || challenge.protectionSpace().serverType() == ProtectionSpaceProxyHTTPS) {
     1031        if (allowOverwrite || !m_handle->getInternal()->m_proxyWebChallenge.hasCredentials())
     1032            m_handle->getInternal()->m_proxyWebChallenge = challenge;
     1033    } else {
     1034        if (allowOverwrite || !m_handle->getInternal()->m_hostWebChallenge.hasCredentials())
     1035            m_handle->getInternal()->m_hostWebChallenge = challenge;
     1036    }
     1037}
     1038
    10041039} // namespace WebCore
  • trunk/Source/WebCore/platform/network/blackberry/NetworkJob.h

    r140022 r141350  
    11/*
    2  * Copyright (C) 2009, 2010, 2011 Research In Motion Limited. All rights reserved.
     2 * Copyright (C) 2009, 2010, 2011, 2012, 2013 Research In Motion Limited. All rights reserved.
    33 *
    44 * This library is free software; you can redistribute it and/or
     
    7474    virtual void notifyHeadersReceived(const BlackBerry::Platform::NetworkRequest::HeaderList& headers);
    7575    virtual void notifyMultipartHeaderReceived(const char* key, const char* value);
    76     virtual void notifyAuthReceived(BlackBerry::Platform::NetworkRequest::AuthType, BlackBerry::Platform::NetworkRequest::AuthScheme, const char* realm, AuthResult, bool requireCredentials);
     76    virtual void notifyAuthReceived(BlackBerry::Platform::NetworkRequest::AuthType,
     77        BlackBerry::Platform::NetworkRequest::AuthProtocol,
     78        BlackBerry::Platform::NetworkRequest::AuthScheme,
     79        const char* realm,
     80        AuthResult,
     81        bool requireCredentials);
    7782    // notifyStringHeaderReceived exists only to resolve ambiguity between char* and String parameters
    7883    void notifyStringHeaderReceived(const String& key, const String& value);
     
    136141
    137142    void storeCredentials();
    138 
     143    void storeCredentials(AuthenticationChallenge&);
    139144    void purgeCredentials();
     145    void purgeCredentials(AuthenticationChallenge&);
    140146
    141147    bool isError(int statusCode) const
     
    143149        return statusCode < 0 || (400 <= statusCode && statusCode < 600);
    144150    }
     151
     152    void updateCurrentWebChallenge(const AuthenticationChallenge&, bool allowOverwrite = true);
    145153
    146154private:
  • trunk/Source/WebCore/platform/network/blackberry/NetworkManager.cpp

    r140022 r141350  
    3535#include <network/NetworkRequest.h>
    3636
     37using BlackBerry::Platform::NetworkRequest;
     38
    3739namespace WebCore {
    3840
     
    5658}
    5759
     60static void setAuthCredentials(NetworkRequest& platformRequest, const AuthenticationChallenge& challenge)
     61{
     62    if (challenge.isNull())
     63        return;
     64
     65    Credential credential = challenge.proposedCredential();
     66    const ProtectionSpace& protectionSpace = challenge.protectionSpace();
     67
     68    String username = credential.user();
     69    String password = credential.password();
     70
     71    NetworkRequest::AuthScheme authScheme = NetworkRequest::AuthSchemeNone;
     72    switch (protectionSpace.authenticationScheme()) {
     73    case ProtectionSpaceAuthenticationSchemeDefault:
     74        authScheme = NetworkRequest::AuthSchemeDefault;
     75        break;
     76    case ProtectionSpaceAuthenticationSchemeHTTPBasic:
     77        authScheme = NetworkRequest::AuthSchemeHTTPBasic;
     78        break;
     79    case ProtectionSpaceAuthenticationSchemeHTTPDigest:
     80        authScheme = NetworkRequest::AuthSchemeHTTPDigest;
     81        break;
     82    case ProtectionSpaceAuthenticationSchemeNegotiate:
     83        authScheme = NetworkRequest::AuthSchemeNegotiate;
     84        break;
     85    case ProtectionSpaceAuthenticationSchemeNTLM:
     86        authScheme = NetworkRequest::AuthSchemeNTLM;
     87        break;
     88    default:
     89        ASSERT_NOT_REACHED();
     90        break;
     91    }
     92
     93    NetworkRequest::AuthType authType = NetworkRequest::AuthTypeNone;
     94    NetworkRequest::AuthProtocol authProtocol = NetworkRequest::AuthProtocolNone;
     95    switch (protectionSpace.serverType()) {
     96    case ProtectionSpaceServerHTTP:
     97        authType = NetworkRequest::AuthTypeHost;
     98        authProtocol = NetworkRequest::AuthProtocolHTTP;
     99        break;
     100    case ProtectionSpaceServerHTTPS:
     101        authType = NetworkRequest::AuthTypeHost;
     102        authProtocol = NetworkRequest::AuthProtocolHTTPS;
     103        break;
     104    case ProtectionSpaceServerFTP:
     105        authType = NetworkRequest::AuthTypeHost;
     106        authProtocol = NetworkRequest::AuthProtocolFTP;
     107        break;
     108    case ProtectionSpaceServerFTPS:
     109        authType = NetworkRequest::AuthTypeHost;
     110        authProtocol = NetworkRequest::AuthProtocolFTPS;
     111        break;
     112    case ProtectionSpaceProxyHTTP:
     113        authType = NetworkRequest::AuthTypeProxy;
     114        authProtocol = NetworkRequest::AuthProtocolHTTP;
     115        break;
     116    case ProtectionSpaceProxyHTTPS:
     117        authType = NetworkRequest::AuthTypeProxy;
     118        authProtocol = NetworkRequest::AuthProtocolHTTPS;
     119        break;
     120    case ProtectionSpaceProxyFTP:
     121        authType = NetworkRequest::AuthTypeProxy;
     122        authProtocol = NetworkRequest::AuthProtocolFTP;
     123        break;
     124    default:
     125        ASSERT_NOT_REACHED();
     126        break;
     127    }
     128
     129    if (authType != NetworkRequest::AuthTypeNone && authProtocol != NetworkRequest::AuthProtocolNone && authScheme != NetworkRequest::AuthSchemeNone)
     130        platformRequest.setCredentials(authType, authProtocol, authScheme, username.utf8().data(), password.utf8().data());
     131}
     132
    58133bool NetworkManager::startJob(int playerId, const String& pageGroupName, PassRefPtr<ResourceHandle> job, const ResourceRequest& request, BlackBerry::Platform::NetworkStreamFactory* streamFactory, Frame* frame, int deferLoadingCount, int redirectCount)
    59134{
     
    79154
    80155    // Attach any applicable auth credentials to the NetworkRequest.
    81     AuthenticationChallenge& challenge = guardJob->getInternal()->m_currentWebChallenge;
    82     if (!challenge.isNull()) {
    83         Credential credential = challenge.proposedCredential();
    84         const ProtectionSpace& protectionSpace = challenge.protectionSpace();
    85 
    86         String username = credential.user();
    87         String password = credential.password();
    88 
    89         BlackBerry::Platform::NetworkRequest::AuthType authType = BlackBerry::Platform::NetworkRequest::AuthTypeNone;
    90         switch (protectionSpace.serverType()) {
    91         case ProtectionSpaceServerHTTP:
    92             authType = BlackBerry::Platform::NetworkRequest::AuthTypeHTTP;
    93             break;
    94         case ProtectionSpaceServerHTTPS:
    95             authType = BlackBerry::Platform::NetworkRequest::AuthTypeHTTPS;
    96             break;
    97         case ProtectionSpaceServerFTP:
    98             authType = BlackBerry::Platform::NetworkRequest::AuthTypeFTP;
    99             break;
    100         case ProtectionSpaceServerFTPS:
    101             authType = BlackBerry::Platform::NetworkRequest::AuthTypeFTPS;
    102             break;
    103         case ProtectionSpaceProxyHTTP:
    104             authType = BlackBerry::Platform::NetworkRequest::AuthTypeProxyHTTP;
    105             break;
    106         case ProtectionSpaceProxyHTTPS:
    107             authType = BlackBerry::Platform::NetworkRequest::AuthTypeProxyHTTPS;
    108             break;
    109         case ProtectionSpaceProxyFTP:
    110             authType = BlackBerry::Platform::NetworkRequest::AuthTypeProxyFTP;
    111             break;
    112         default:
    113             ASSERT_NOT_REACHED();
    114             break;
    115         }
    116 
    117         BlackBerry::Platform::NetworkRequest::AuthScheme authScheme = BlackBerry::Platform::NetworkRequest::AuthSchemeNone;
    118         switch (protectionSpace.authenticationScheme()) {
    119         case ProtectionSpaceAuthenticationSchemeDefault:
    120             authScheme = BlackBerry::Platform::NetworkRequest::AuthSchemeDefault;
    121             break;
    122         case ProtectionSpaceAuthenticationSchemeHTTPBasic:
    123             authScheme = BlackBerry::Platform::NetworkRequest::AuthSchemeHTTPBasic;
    124             break;
    125         case ProtectionSpaceAuthenticationSchemeHTTPDigest:
    126             authScheme = BlackBerry::Platform::NetworkRequest::AuthSchemeHTTPDigest;
    127             break;
    128         case ProtectionSpaceAuthenticationSchemeNegotiate:
    129             authScheme = BlackBerry::Platform::NetworkRequest::AuthSchemeNegotiate;
    130             break;
    131         case ProtectionSpaceAuthenticationSchemeNTLM:
    132             authScheme = BlackBerry::Platform::NetworkRequest::AuthSchemeNTLM;
    133             break;
    134         default:
    135             ASSERT_NOT_REACHED();
    136             break;
    137         }
    138 
    139         if (authType != BlackBerry::Platform::NetworkRequest::AuthTypeNone && authScheme != BlackBerry::Platform::NetworkRequest::AuthSchemeNone)
    140             platformRequest.setCredentials(username.utf8().data(), password.utf8().data(), authType, authScheme);
    141     }
     156    setAuthCredentials(platformRequest, guardJob->getInternal()->m_hostWebChallenge);
     157    setAuthCredentials(platformRequest, guardJob->getInternal()->m_proxyWebChallenge);
    142158
    143159    if (!request.overrideContentType().isEmpty())
Note: See TracChangeset for help on using the changeset viewer.