void ResourceHandle::receivedCredential(const AuthenticationChallenge& challenge, const Credential& credential) { LOG(Network, "CFNet - receivedCredential()"); ASSERT(!challenge.isNull()); ASSERT(challenge.cfURLAuthChallengeRef()); if (challenge != d->m_currentWebChallenge) return; // FIXME: Support empty credentials. Currently, an empty credential cannot be stored in WebCore credential storage, as that's empty value for its map. if (credential.isEmpty()) { receivedRequestToContinueWithoutCredential(challenge); return; } if (credential.persistence() == CredentialPersistenceForSession) { // Manage per-session credentials internally, because once NSURLCredentialPersistencePerSession is used, there is no way // to ignore it for a particular request (short of removing it altogether). Credential webCredential(credential.user(), credential.password(), CredentialPersistenceNone); RetainPtr<CFURLCredentialRef> cfCredential = adoptCF(createCF(webCredential)); URL urlToStore; if (challenge.failureResponse().httpStatusCode() == 401) urlToStore = challenge.failureResponse().url(); CredentialStorage::set(webCredential, challenge.protectionSpace(), urlToStore); CFURLConnectionUseCredential(d->m_connection.get(), cfCredential.get(), challenge.cfURLAuthChallengeRef()); } else { RetainPtr<CFURLCredentialRef> cfCredential = adoptCF(createCF(credential)); CFURLConnectionUseCredential(d->m_connection.get(), cfCredential.get(), challenge.cfURLAuthChallengeRef()); } clearAuthentication(); }
CFURLAuthChallengeRef createCF(const AuthenticationChallenge& coreChallenge) { CFURLProtectionSpaceRef protectionSpace = createCF(coreChallenge.protectionSpace()); CFURLCredentialRef credential = createCF(coreChallenge.proposedCredential()); CFURLAuthChallengeRef result = CFURLAuthChallengeCreate(0, protectionSpace, credential, coreChallenge.previousFailureCount(), coreChallenge.failureResponse().cfURLResponse(), coreChallenge.error()); CFRelease(protectionSpace); CFRelease(credential); return result; }
CFURLAuthChallengeRef createCF(const AuthenticationChallenge& coreChallenge) { // FIXME: Why not cache CFURLAuthChallengeRef in m_cfChallenge? Foundation counterpart does that. CFURLProtectionSpaceRef protectionSpace = createCF(coreChallenge.protectionSpace()); CFURLCredentialRef credential = createCF(coreChallenge.proposedCredential()); CFURLAuthChallengeRef result = CFURLAuthChallengeCreate(0, protectionSpace, credential, coreChallenge.previousFailureCount(), coreChallenge.failureResponse().cfURLResponse(), coreChallenge.error()); CFRelease(protectionSpace); CFRelease(credential); return result; }
void Download::useCredential(const WebCore::AuthenticationChallenge& challenge, const WebCore::Credential& credential) { if (!m_download) return; RetainPtr<CFURLCredentialRef> cfCredential(AdoptCF, createCF(credential)); CFURLDownloadUseCredential(m_download.get(), cfCredential.get(), challenge.cfURLAuthChallengeRef()); }
void ResourceHandle::didReceiveAuthenticationChallenge(const AuthenticationChallenge& challenge) { LOG(Network, "CFNet - didReceiveAuthenticationChallenge()"); ASSERT(d->m_currentWebChallenge.isNull()); // Since CFURLConnection networking relies on keeping a reference to the original CFURLAuthChallengeRef, // we make sure that is actually present ASSERT(challenge.cfURLAuthChallengeRef()); ASSERT(challenge.authenticationClient() == this); // Should be already set. if (!d->m_user.isNull() && !d->m_pass.isNull()) { RetainPtr<CFStringRef> user(AdoptCF, d->m_user.createCFString()); RetainPtr<CFStringRef> pass(AdoptCF, d->m_pass.createCFString()); RetainPtr<CFURLCredentialRef> credential(AdoptCF, CFURLCredentialCreate(kCFAllocatorDefault, user.get(), pass.get(), 0, kCFURLCredentialPersistenceNone)); KURL urlToStore; if (challenge.failureResponse().httpStatusCode() == 401) urlToStore = firstRequest().url(); CredentialStorage::set(core(credential.get()), challenge.protectionSpace(), urlToStore); CFURLConnectionUseCredential(d->m_connection.get(), credential.get(), challenge.cfURLAuthChallengeRef()); d->m_user = String(); d->m_pass = String(); // FIXME: Per the specification, the user shouldn't be asked for credentials if there were incorrect ones provided explicitly. return; } if (!client() || client()->shouldUseCredentialStorage(this)) { if (!d->m_initialCredential.isEmpty() || challenge.previousFailureCount()) { // The stored credential wasn't accepted, stop using it. // There is a race condition here, since a different credential might have already been stored by another ResourceHandle, // but the observable effect should be very minor, if any. CredentialStorage::remove(challenge.protectionSpace()); } if (!challenge.previousFailureCount()) { Credential credential = CredentialStorage::get(challenge.protectionSpace()); if (!credential.isEmpty() && credential != d->m_initialCredential) { ASSERT(credential.persistence() == CredentialPersistenceNone); if (challenge.failureResponse().httpStatusCode() == 401) { // Store the credential back, possibly adding it as a default for this directory. CredentialStorage::set(credential, challenge.protectionSpace(), firstRequest().url()); } RetainPtr<CFURLCredentialRef> cfCredential(AdoptCF, createCF(credential)); CFURLConnectionUseCredential(d->m_connection.get(), cfCredential.get(), challenge.cfURLAuthChallengeRef()); return; } } } d->m_currentWebChallenge = challenge; if (client()) client()->didReceiveAuthenticationChallenge(this, d->m_currentWebChallenge); }
bool ResourceHandle::tryHandlePasswordBasedAuthentication(const AuthenticationChallenge& challenge) { if (!challenge.protectionSpace().isPasswordBased()) return false; if (!d->m_user.isNull() && !d->m_pass.isNull()) { RetainPtr<CFURLCredentialRef> cfCredential = adoptCF(CFURLCredentialCreate(kCFAllocatorDefault, d->m_user.createCFString().get(), d->m_pass.createCFString().get(), 0, kCFURLCredentialPersistenceNone)); #if PLATFORM(COCOA) Credential credential = Credential(cfCredential.get()); #else Credential credential = core(cfCredential.get()); #endif URL urlToStore; if (challenge.failureResponse().httpStatusCode() == 401) urlToStore = challenge.failureResponse().url(); d->m_context->storageSession().credentialStorage().set(credential, challenge.protectionSpace(), urlToStore); CFURLConnectionUseCredential(d->m_connection.get(), cfCredential.get(), challenge.cfURLAuthChallengeRef()); d->m_user = String(); d->m_pass = String(); // FIXME: Per the specification, the user shouldn't be asked for credentials if there were incorrect ones provided explicitly. return true; } if (!client() || client()->shouldUseCredentialStorage(this)) { if (!d->m_initialCredential.isEmpty() || challenge.previousFailureCount()) { // The stored credential wasn't accepted, stop using it. // There is a race condition here, since a different credential might have already been stored by another ResourceHandle, // but the observable effect should be very minor, if any. d->m_context->storageSession().credentialStorage().remove(challenge.protectionSpace()); } if (!challenge.previousFailureCount()) { Credential credential = d->m_context->storageSession().credentialStorage().get(challenge.protectionSpace()); if (!credential.isEmpty() && credential != d->m_initialCredential) { ASSERT(credential.persistence() == CredentialPersistenceNone); if (challenge.failureResponse().httpStatusCode() == 401) { // Store the credential back, possibly adding it as a default for this directory. d->m_context->storageSession().credentialStorage().set(credential, challenge.protectionSpace(), challenge.failureResponse().url()); } #if PLATFORM(COCOA) CFURLConnectionUseCredential(d->m_connection.get(), credential.cfCredential(), challenge.cfURLAuthChallengeRef()); #else RetainPtr<CFURLCredentialRef> cfCredential = adoptCF(createCF(credential)); CFURLConnectionUseCredential(d->m_connection.get(), cfCredential.get(), challenge.cfURLAuthChallengeRef()); #endif return true; } } } return false; }
bool ProtectionSpace::receivesCredentialSecurely() const { #if USE(CFNETWORK) && !PLATFORM(MAC) RetainPtr<CFURLProtectionSpaceRef> cfSpace = adoptCF(createCF(*this)); return cfSpace && CFURLProtectionSpaceReceivesCredentialSecurely(cfSpace.get()); #else return (m_serverType == ProtectionSpaceServerHTTPS || m_serverType == ProtectionSpaceServerFTPS || m_serverType == ProtectionSpaceProxyHTTPS || m_authenticationScheme == ProtectionSpaceAuthenticationSchemeHTTPDigest); #endif }
void ResourceHandle::receivedCredential(const AuthenticationChallenge& challenge, const Credential& credential) { LOG(Network, "CFNet - receivedCredential()"); ASSERT(!challenge.isNull()); ASSERT(challenge.cfURLAuthChallengeRef()); if (challenge != d->m_currentWebChallenge) return; CFURLCredentialRef cfCredential = createCF(credential); CFURLConnectionUseCredential(d->m_connection.get(), cfCredential, challenge.cfURLAuthChallengeRef()); CFRelease(cfCredential); clearAuthentication(); }
void ResourceHandle::didReceiveAuthenticationChallenge(const AuthenticationChallenge& challenge) { LOG(Network, "CFNet - didReceiveAuthenticationChallenge()"); ASSERT(d->m_currentWebChallenge.isNull()); // Since CFURLConnection networking relies on keeping a reference to the original CFURLAuthChallengeRef, // we make sure that is actually present ASSERT(challenge.cfURLAuthChallengeRef()); ASSERT(challenge.authenticationClient() == this); // Should be already set. #if !PLATFORM(WIN) // Proxy authentication is handled by CFNetwork internally. We can get here if the user cancels // CFNetwork authentication dialog, and we shouldn't ask the client to display another one in that case. if (challenge.protectionSpace().isProxy()) { // Cannot use receivedRequestToContinueWithoutCredential(), because current challenge is not yet set. CFURLConnectionUseCredential(d->m_connection.get(), 0, challenge.cfURLAuthChallengeRef()); return; } #endif if (!d->m_user.isNull() && !d->m_pass.isNull()) { RetainPtr<CFURLCredentialRef> cfCredential = adoptCF(CFURLCredentialCreate(kCFAllocatorDefault, d->m_user.createCFString().get(), d->m_pass.createCFString().get(), 0, kCFURLCredentialPersistenceNone)); #if PLATFORM(COCOA) Credential credential = Credential(cfCredential.get()); #else Credential credential = core(cfCredential.get()); #endif URL urlToStore; if (challenge.failureResponse().httpStatusCode() == 401) urlToStore = challenge.failureResponse().url(); CredentialStorage::set(credential, challenge.protectionSpace(), urlToStore); CFURLConnectionUseCredential(d->m_connection.get(), cfCredential.get(), challenge.cfURLAuthChallengeRef()); d->m_user = String(); d->m_pass = String(); // FIXME: Per the specification, the user shouldn't be asked for credentials if there were incorrect ones provided explicitly. return; } if (!client() || client()->shouldUseCredentialStorage(this)) { if (!d->m_initialCredential.isEmpty() || challenge.previousFailureCount()) { // The stored credential wasn't accepted, stop using it. // There is a race condition here, since a different credential might have already been stored by another ResourceHandle, // but the observable effect should be very minor, if any. CredentialStorage::remove(challenge.protectionSpace()); } if (!challenge.previousFailureCount()) { Credential credential = CredentialStorage::get(challenge.protectionSpace()); if (!credential.isEmpty() && credential != d->m_initialCredential) { ASSERT(credential.persistence() == CredentialPersistenceNone); if (challenge.failureResponse().httpStatusCode() == 401) { // Store the credential back, possibly adding it as a default for this directory. CredentialStorage::set(credential, challenge.protectionSpace(), challenge.failureResponse().url()); } #if PLATFORM(COCOA) CFURLConnectionUseCredential(d->m_connection.get(), credential.cfCredential(), challenge.cfURLAuthChallengeRef()); #else RetainPtr<CFURLCredentialRef> cfCredential = adoptCF(createCF(credential)); CFURLConnectionUseCredential(d->m_connection.get(), cfCredential.get(), challenge.cfURLAuthChallengeRef()); #endif return; } } } d->m_currentWebChallenge = challenge; if (client()) client()->didReceiveAuthenticationChallenge(this, d->m_currentWebChallenge); }
Credential CredentialStorage::getFromPersistentStorage(const ProtectionSpace& protectionSpace) { RetainPtr<CFURLProtectionSpaceRef> protectionSpaceCF(AdoptCF, createCF(protectionSpace)); RetainPtr<CFURLCredentialRef> credentialCF(AdoptCF, wkCopyCredentialFromCFPersistentStorage(protectionSpaceCF.get())); return core(credentialCF.get()); }