WebKit Bugzilla
Attachment 358919 Details for
Bug 193355
: Adopt new SPI to evaluate server certificate trust
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch
bug-193355-20190111113938.patch (text/plain), 13.03 KB, created by
youenn fablet
on 2019-01-11 11:39:38 PST
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
youenn fablet
Created:
2019-01-11 11:39:38 PST
Size:
13.03 KB
patch
obsolete
>Subversion Revision: 239774 >diff --git a/Source/WebKit/ChangeLog b/Source/WebKit/ChangeLog >index 891a4f5f895eadbe11fc3e45d24f21f0b5014564..0ab4280adb0cdb2f19430688e277edcd01f3b6db 100644 >--- a/Source/WebKit/ChangeLog >+++ b/Source/WebKit/ChangeLog >@@ -1,3 +1,20 @@ >+2019-01-11 Youenn Fablet <youenn@apple.com> >+ >+ Adopt new SPI to evaluate server certificate trust >+ https://bugs.webkit.org/show_bug.cgi?id=193355 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ Use new SPI provided in NSURLSession to evaluate server certificates. >+ If ssuccessful, let loading proceed as usual. >+ Otherwise, go to the UIProcess to ask for a decision on continuing or not the connection. >+ >+ * NetworkProcess/cocoa/NetworkSessionCocoa.h: >+ * NetworkProcess/cocoa/NetworkSessionCocoa.mm: >+ (canNSURLSessionTrustEvaluate): >+ (-[WKNetworkSessionDelegate URLSession:task:didReceiveChallenge:completionHandler:]): >+ (WebKit::NetworkSessionCocoa::continueDidReceiveChallenge): >+ > 2019-01-09 Michael Catanzaro <mcatanzaro@igalia.com> > > [GTK] Add missing autocleanups >diff --git a/Source/WebKit/NetworkProcess/cocoa/NetworkSessionCocoa.h b/Source/WebKit/NetworkProcess/cocoa/NetworkSessionCocoa.h >index 0d671c29ca0977995aab49ecfd622819f610cd6b..8b7e322c7b422e8f4f307aa3f64b4777694bf9c9 100644 >--- a/Source/WebKit/NetworkProcess/cocoa/NetworkSessionCocoa.h >+++ b/Source/WebKit/NetworkProcess/cocoa/NetworkSessionCocoa.h >@@ -62,6 +62,8 @@ public: > > static bool allowsSpecificHTTPSCertificateForHost(const WebCore::AuthenticationChallenge&); > >+ void continueDidReceiveChallenge(const WebCore::AuthenticationChallenge&, NetworkDataTaskCocoa::TaskIdentifier, NetworkDataTaskCocoa*, WTF::CompletionHandler<void(WebKit::AuthenticationChallengeDisposition, const WebCore::Credential&)>&&); >+ > private: > NetworkSessionCocoa(NetworkProcess&, NetworkSessionCreationParameters&&); > >diff --git a/Source/WebKit/NetworkProcess/cocoa/NetworkSessionCocoa.mm b/Source/WebKit/NetworkProcess/cocoa/NetworkSessionCocoa.mm >index 36554d3431962388c40213c10ba09992d87f377a..931f5615247881bcb5716b428deaebd16a6e5586 100644 >--- a/Source/WebKit/NetworkProcess/cocoa/NetworkSessionCocoa.mm >+++ b/Source/WebKit/NetworkProcess/cocoa/NetworkSessionCocoa.mm >@@ -36,6 +36,7 @@ > #import "NetworkProcess.h" > #import "NetworkSessionCreationParameters.h" > #import "SessionTracker.h" >+#import <CFNetwork/CFNSURLConnection.h> > #import <Foundation/NSURLSession.h> > #import <WebCore/Credential.h> > #import <WebCore/FormDataStreamMac.h> >@@ -54,6 +55,10 @@ > #import <wtf/URL.h> > #import <wtf/text/WTFString.h> > >+@interface NSURLSession () >++ (void)_strictTrustEvaluate:(NSURLAuthenticationChallenge *)challenge queue:(dispatch_queue_t)queue completionHandler:(void (^)(NSURLAuthenticationChallenge *challenge, OSStatus trustResult))cb; >+@end >+ > using namespace WebKit; > > CFStringRef const WebKit2HTTPProxyDefaultsKey = static_cast<CFStringRef>(@"WebKit2HTTPProxy"); >@@ -520,6 +525,11 @@ static NSURLRequest* updateIgnoreStrictTransportSecuritySettingIfNecessary(NSURL > completionHandler(proposedResponse); > } > >+static bool canNSURLSessionTrustEvaluate() >+{ >+ return [NSURLSession respondsToSelector:@selector(_strictTrustEvaluate: queue: completionHandler:)]; >+} >+ > - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential *credential))completionHandler > { > if (!_session) { >@@ -542,61 +552,41 @@ static NSURLRequest* updateIgnoreStrictTransportSecuritySettingIfNecessary(NSURL > return completionHandler(NSURLSessionAuthChallengeUseCredential, [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust]); > > // Handle server trust evaluation at platform-level if requested, for performance reasons and to use ATS defaults. >- if (!_session->networkProcess().canHandleHTTPSServerTrustEvaluation()) >- return completionHandler(NSURLSessionAuthChallengeRejectProtectionSpace, nil); >- } >+ if (!_session->networkProcess().canHandleHTTPSServerTrustEvaluation()) { >+ if (!canNSURLSessionTrustEvaluate()) >+ return completionHandler(NSURLSessionAuthChallengeRejectProtectionSpace, nil); > >- if (auto* networkDataTask = [self existingTask:task]) { >- WebCore::AuthenticationChallenge authenticationChallenge(challenge); >- auto completionHandlerCopy = Block_copy(completionHandler); >- auto sessionID = _session->sessionID(); >- auto challengeCompletionHandler = [completionHandlerCopy, sessionID, authenticationChallenge, taskIdentifier, partition = networkDataTask->partition()](WebKit::AuthenticationChallengeDisposition disposition, const WebCore::Credential& credential) >- { >-#if !LOG_DISABLED >- LOG(NetworkSession, "%llu didReceiveChallenge completionHandler %d", taskIdentifier, disposition); >-#else >- UNUSED_PARAM(taskIdentifier); >-#endif >-#if !USE(CREDENTIAL_STORAGE_WITH_NETWORK_SESSION) >- UNUSED_PARAM(sessionID); >- UNUSED_PARAM(authenticationChallenge); >-#else >- if (credential.persistence() == WebCore::CredentialPersistenceForSession && authenticationChallenge.protectionSpace().isPasswordBased()) { >- >- WebCore::Credential nonPersistentCredential(credential.user(), credential.password(), WebCore::CredentialPersistenceNone); >- URL urlToStore; >- if (authenticationChallenge.failureResponse().httpStatusCode() == 401) >- urlToStore = authenticationChallenge.failureResponse().url(); >- if (auto storageSession = WebCore::NetworkStorageSession::storageSession(sessionID)) >- storageSession->credentialStorage().set(partition, nonPersistentCredential, authenticationChallenge.protectionSpace(), urlToStore); >- else >- ASSERT_NOT_REACHED(); >+ auto completionHandlerCopy = Block_copy(completionHandler); > >- completionHandlerCopy(toNSURLSessionAuthChallengeDisposition(disposition), nonPersistentCredential.nsCredential()); >- } else >-#endif >- completionHandlerCopy(toNSURLSessionAuthChallengeDisposition(disposition), credential.nsCredential()); >- Block_release(completionHandlerCopy); >- }; >- networkDataTask->didReceiveChallenge(challenge, WTFMove(challengeCompletionHandler)); >- } else { >- auto downloadID = _session->downloadID(taskIdentifier); >- if (downloadID.downloadID()) { >- if (auto* download = _session->networkProcess().downloadManager().download(downloadID)) { >- // Received an authentication challenge for a download being resumed. >- WebCore::AuthenticationChallenge authenticationChallenge { challenge }; >- auto completionHandlerCopy = Block_copy(completionHandler); >- auto challengeCompletionHandler = [completionHandlerCopy, authenticationChallenge](WebKit::AuthenticationChallengeDisposition disposition, const WebCore::Credential& credential) { >- completionHandlerCopy(toNSURLSessionAuthChallengeDisposition(disposition), credential.nsCredential()); >+ auto* networkDataTask = [self existingTask:task]; >+ auto decisionHandler = makeBlockPtr([_session = _session.copyRef(), completionHandlerCopy, taskIdentifier, networkDataTask = RefPtr<NetworkDataTaskCocoa>(networkDataTask)](NSURLAuthenticationChallenge *challenge, OSStatus trustResult) mutable { >+ >+ if (trustResult == noErr || networkDataTask->state() == NetworkDataTask::State::Canceling || networkDataTask->state() == NetworkDataTask::State::Completed) { >+ completionHandlerCopy(NSURLSessionAuthChallengePerformDefaultHandling, nil); > Block_release(completionHandlerCopy); >- }; >- download->didReceiveChallenge(challenge, WTFMove(challengeCompletionHandler)); >- return; >- } >+ return; >+ } >+ >+ RetainPtr<SecTrustRef> secTrust = challenge.protectionSpace.serverTrust; >+ _session->continueDidReceiveChallenge(challenge, taskIdentifier, networkDataTask.get(), [completionHandlerCopy, secTrust = WTFMove(secTrust)] (WebKit::AuthenticationChallengeDisposition disposition, const WebCore::Credential& credential) mutable { >+ // FIXME: UIProcess should send us back non nil credentials but the credential IPC encoder currently only serializes ns credentials for username/password. >+ if (disposition == WebKit::AuthenticationChallengeDisposition::UseCredential && !credential.nsCredential()) >+ completionHandlerCopy(NSURLSessionAuthChallengeUseCredential, [NSURLCredential credentialForTrust: secTrust.get()]); >+ else >+ completionHandlerCopy(toNSURLSessionAuthChallengeDisposition(disposition), credential.nsCredential()); >+ Block_release(completionHandlerCopy); >+ }); >+ }); >+ [NSURLSession _strictTrustEvaluate:challenge queue:[NSOperationQueue mainQueue].underlyingQueue completionHandler:decisionHandler.get()]; > } >- LOG(NetworkSession, "%llu didReceiveChallenge completionHandler (cancel)", taskIdentifier); >- completionHandler(NSURLSessionAuthChallengeCancelAuthenticationChallenge, nil); >+ return; > } >+ >+ auto completionHandlerCopy = Block_copy(completionHandler); >+ _session->continueDidReceiveChallenge(challenge, taskIdentifier, [self existingTask:task], [completionHandlerCopy] (WebKit::AuthenticationChallengeDisposition disposition, const WebCore::Credential& credential) mutable { >+ completionHandlerCopy(toNSURLSessionAuthChallengeDisposition(disposition), credential.nsCredential()); >+ Block_release(completionHandlerCopy); >+ }); > } > > - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error >@@ -1035,4 +1025,53 @@ bool NetworkSessionCocoa::allowsSpecificHTTPSCertificateForHost(const WebCore::A > return certificatesMatch(trust.get(), challenge.nsURLAuthenticationChallenge().protectionSpace.serverTrust); > } > >+void NetworkSessionCocoa::continueDidReceiveChallenge(const WebCore::AuthenticationChallenge& challenge, NetworkDataTaskCocoa::TaskIdentifier taskIdentifier, NetworkDataTaskCocoa* networkDataTask, WTF::CompletionHandler<void(WebKit::AuthenticationChallengeDisposition, const WebCore::Credential&)>&& completionHandler) >+ >+{ >+ if (!networkDataTask) { >+ auto downloadID = this->downloadID(taskIdentifier); >+ if (downloadID.downloadID()) { >+ if (auto* download = networkProcess().downloadManager().download(downloadID)) { >+ WebCore::AuthenticationChallenge authenticationChallenge { challenge }; >+ // Received an authentication challenge for a download being resumed. >+ download->didReceiveChallenge(authenticationChallenge, WTFMove(completionHandler)); >+ return; >+ } >+ } >+ LOG(NetworkSession, "%llu didReceiveChallenge completionHandler (cancel)", taskIdentifier); >+ completionHandler(AuthenticationChallengeDisposition::Cancel, { }); >+ return; >+ } >+ >+ auto sessionID = this->sessionID(); >+ WebCore::AuthenticationChallenge authenticationChallenge { challenge }; >+ auto challengeCompletionHandler = [completionHandler = WTFMove(completionHandler), sessionID, authenticationChallenge, taskIdentifier, partition = networkDataTask->partition()](WebKit::AuthenticationChallengeDisposition disposition, const WebCore::Credential& credential) mutable { >+#if !LOG_DISABLED >+ LOG(NetworkSession, "%llu didReceiveChallenge completionHandler %d", taskIdentifier, disposition); >+#else >+ UNUSED_PARAM(taskIdentifier); >+#endif >+#if !USE(CREDENTIAL_STORAGE_WITH_NETWORK_SESSION) >+ UNUSED_PARAM(sessionID); >+ UNUSED_PARAM(authenticationChallenge); >+#else >+ if (credential.persistence() == WebCore::CredentialPersistenceForSession && authenticationChallenge.protectionSpace().isPasswordBased()) { >+ WebCore::Credential nonPersistentCredential(credential.user(), credential.password(), WebCore::CredentialPersistenceNone); >+ URL urlToStore; >+ if (authenticationChallenge.failureResponse().httpStatusCode() == 401) >+ urlToStore = authenticationChallenge.failureResponse().url(); >+ if (auto storageSession = WebCore::NetworkStorageSession::storageSession(sessionID)) >+ storageSession->credentialStorage().set(partition, nonPersistentCredential, authenticationChallenge.protectionSpace(), urlToStore); >+ else >+ ASSERT_NOT_REACHED(); >+ >+ completionHandler(disposition, nonPersistentCredential); >+ return; >+ } >+#endif >+ completionHandler(disposition, credential); >+ }; >+ networkDataTask->didReceiveChallenge(WTFMove(authenticationChallenge), WTFMove(challengeCompletionHandler)); >+} >+ > }
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 193355
:
358919
|
360386
|
360478
|
360497
|
360503