Title: [292177] branches/safari-613-branch/Source/WebKit

Diff

Modified: branches/safari-613-branch/Source/WebKit/ChangeLog (292176 => 292177)


--- branches/safari-613-branch/Source/WebKit/ChangeLog	2022-03-31 21:22:25 UTC (rev 292176)
+++ branches/safari-613-branch/Source/WebKit/ChangeLog	2022-03-31 21:22:29 UTC (rev 292177)
@@ -1,5 +1,30 @@
 2022-03-31  Alan Coon  <[email protected]>
 
+        Apply patch. rdar://problem/90957287
+
+    2022-03-11  J Pascoe  <[email protected]>
+
+            [WebAuthn] Cancel running operations in ASA on navigation
+            https://bugs.webkit.org/show_bug.cgi?id=237452
+            rdar://problem/89781990
+
+            Reviewed by Brent Fulgham.
+
+            Pre-ASA WebAuthn calls cancel requests on navigation via calling authenticatorManager.cancelRequest
+            in WebPageProxy. In WebAuthn calls that go through ASA, the authenticatorManager lives in the ASA
+            process, so calls won't be cancelled on navigation.
+
+            This patch attempts to cancel ongoing operations whenever a WebAuthenticatorCoordinatorProxy that
+            uses ASA is destroyed, effectively cancelling requests on reload or navigation.
+
+            * Platform/spi/Cocoa/AuthenticationServicesCoreSPI.h:
+            * UIProcess/WebAuthentication/Cocoa/WebAuthenticatorCoordinatorProxy.mm:
+            * UIProcess/WebAuthentication/WebAuthenticatorCoordinatorProxy.cpp:
+            (WebKit::WebAuthenticatorCoordinatorProxy::~WebAuthenticatorCoordinatorProxy):
+            * UIProcess/WebAuthentication/WebAuthenticatorCoordinatorProxy.h:
+
+2022-03-31  Alan Coon  <[email protected]>
+
         Apply patch. rdar://problem/90957317
 
     2022-03-08  J Pascoe  <[email protected]>

Modified: branches/safari-613-branch/Source/WebKit/Platform/spi/Cocoa/AuthenticationServicesCoreSPI.h (292176 => 292177)


--- branches/safari-613-branch/Source/WebKit/Platform/spi/Cocoa/AuthenticationServicesCoreSPI.h	2022-03-31 21:22:25 UTC (rev 292176)
+++ branches/safari-613-branch/Source/WebKit/Platform/spi/Cocoa/AuthenticationServicesCoreSPI.h	2022-03-31 21:22:29 UTC (rev 292177)
@@ -324,6 +324,8 @@
 - (void)requestCompletedWithCredential:(nullable id<ASCCredentialProtocol>)credential error:(nullable NSError *)error;
 #endif
 
+- (void)cancelCurrentRequest;
+
 @end
 
 @interface ASCAgentProxy : NSObject <ASCAgentProtocol>

Modified: branches/safari-613-branch/Source/WebKit/UIProcess/WebAuthentication/Cocoa/WebAuthenticatorCoordinatorProxy.mm (292176 => 292177)


--- branches/safari-613-branch/Source/WebKit/UIProcess/WebAuthentication/Cocoa/WebAuthenticatorCoordinatorProxy.mm	2022-03-31 21:22:25 UTC (rev 292176)
+++ branches/safari-613-branch/Source/WebKit/UIProcess/WebAuthentication/Cocoa/WebAuthenticatorCoordinatorProxy.mm	2022-03-31 21:22:29 UTC (rev 292177)
@@ -308,78 +308,91 @@
     return result;
 }
 
-void WebAuthenticatorCoordinatorProxy::performRequest(RetainPtr<ASCCredentialRequestContext> requestContext, RequestCompletionHandler&& handler)
+static inline void continueAfterRequest(RetainPtr<id <ASCCredentialProtocol>> credential, RetainPtr<NSError> error, RequestCompletionHandler&& handler)
 {
-    auto proxy = adoptNS([allocASCAgentProxyInstance() init]);
+    AuthenticatorResponseData response = { };
+    AuthenticatorAttachment attachment;
+    ExceptionData exceptionData = { };
 
-    RetainPtr<NSWindow> window = m_webPageProxy.platformWindow();
-    [proxy performAuthorizationRequestsForContext:requestContext.get() withClearanceHandler:makeBlockPtr([weakThis = WeakPtr { *this }, handler = WTFMove(handler), window = WTFMove(window), proxy = WTFMove(proxy)](NSXPCListenerEndpoint *daemonEndpoint, NSError *error) mutable {
-        callOnMainRunLoop([weakThis, handler = WTFMove(handler), window = WTFMove(window), proxy = WTFMove(proxy), daemonEndpoint = retainPtr(daemonEndpoint), error = retainPtr(error)] () mutable {
-            if (!weakThis || !daemonEndpoint) {
-                LOG_ERROR("Could not connect to authorization daemon: %@\n", error.get());
-                handler({ }, (AuthenticatorAttachment)0, ExceptionData { NotAllowedError, "Operation failed." });
-                return;
-            }
+    if ([credential isKindOfClass:getASCPlatformPublicKeyCredentialRegistrationClass()]) {
+        attachment = AuthenticatorAttachment::Platform;
+        response.isAuthenticatorAttestationResponse = true;
 
-            weakThis->m_presenter = adoptNS([allocASCAuthorizationRemotePresenterInstance() init]);
-            [weakThis->m_presenter presentWithWindow:window.get() daemonEndpoint:daemonEndpoint.get() completionHandler:makeBlockPtr([handler = WTFMove(handler), proxy = WTFMove(proxy)](id <ASCCredentialProtocol> credential, NSError *error) mutable {
-                AuthenticatorResponseData response = { };
-                AuthenticatorAttachment attachment;
-                ExceptionData exceptionData = { };
+        ASCPlatformPublicKeyCredentialRegistration *registrationCredential = credential.get();
+        response.rawId = toArrayBuffer(registrationCredential.credentialID);
+        response.attestationObject = toArrayBuffer(registrationCredential.attestationObject);
+    } else if ([credential isKindOfClass:getASCSecurityKeyPublicKeyCredentialRegistrationClass()]) {
+        attachment = AuthenticatorAttachment::CrossPlatform;
+        response.isAuthenticatorAttestationResponse = true;
 
-                if ([credential isKindOfClass:getASCPlatformPublicKeyCredentialRegistrationClass()]) {
-                    attachment = AuthenticatorAttachment::Platform;
-                    response.isAuthenticatorAttestationResponse = true;
+        ASCSecurityKeyPublicKeyCredentialRegistration *registrationCredential = credential.get();
+        response.rawId = toArrayBuffer(registrationCredential.credentialID);
+        response.attestationObject = toArrayBuffer(registrationCredential.attestationObject);
+    } else if ([credential isKindOfClass:getASCPlatformPublicKeyCredentialAssertionClass()]) {
+        attachment = AuthenticatorAttachment::Platform;
+        response.isAuthenticatorAttestationResponse = false;
 
-                    ASCPlatformPublicKeyCredentialRegistration *registrationCredential = credential;
-                    response.rawId = toArrayBuffer(registrationCredential.credentialID);
-                    response.attestationObject = toArrayBuffer(registrationCredential.attestationObject);
-                } else if ([credential isKindOfClass:getASCSecurityKeyPublicKeyCredentialRegistrationClass()]) {
-                    attachment = AuthenticatorAttachment::CrossPlatform;
-                    response.isAuthenticatorAttestationResponse = true;
+        ASCPlatformPublicKeyCredentialAssertion *assertionCredential = credential.get();
+        response.rawId = toArrayBuffer(assertionCredential.credentialID);
+        response.authenticatorData = toArrayBuffer(assertionCredential.authenticatorData);
+        response.signature = toArrayBuffer(assertionCredential.signature);
+        response.userHandle = toArrayBuffer(assertionCredential.userHandle);
+    } else if ([credential isKindOfClass:getASCSecurityKeyPublicKeyCredentialAssertionClass()]) {
+        attachment = AuthenticatorAttachment::CrossPlatform;
+        response.isAuthenticatorAttestationResponse = false;
 
-                    ASCSecurityKeyPublicKeyCredentialRegistration *registrationCredential = credential;
-                    response.rawId = toArrayBuffer(registrationCredential.credentialID);
-                    response.attestationObject = toArrayBuffer(registrationCredential.attestationObject);
-                } else if ([credential isKindOfClass:getASCPlatformPublicKeyCredentialAssertionClass()]) {
-                    attachment = AuthenticatorAttachment::Platform;
-                    response.isAuthenticatorAttestationResponse = false;
+        ASCSecurityKeyPublicKeyCredentialAssertion *assertionCredential = credential.get();
+        response.rawId = toArrayBuffer(assertionCredential.credentialID);
+        response.authenticatorData = toArrayBuffer(assertionCredential.authenticatorData);
+        response.signature = toArrayBuffer(assertionCredential.signature);
+        response.userHandle = toArrayBuffer(assertionCredential.userHandle);
+    } else {
+        attachment = (AuthenticatorAttachment) 0;
+        ExceptionCode exceptionCode;
+        NSString *errorMessage = nil;
+        if ([error.get().domain isEqualToString:WKErrorDomain]) {
+            exceptionCode = toExceptionCode(error.get().code);
+            errorMessage = error.get().userInfo[NSLocalizedDescriptionKey];
+        } else {
+            exceptionCode = NotAllowedError;
 
-                    ASCPlatformPublicKeyCredentialAssertion *assertionCredential = credential;
-                    response.rawId = toArrayBuffer(assertionCredential.credentialID);
-                    response.authenticatorData = toArrayBuffer(assertionCredential.authenticatorData);
-                    response.signature = toArrayBuffer(assertionCredential.signature);
-                    response.userHandle = toArrayBuffer(assertionCredential.userHandle);
-                } else if ([credential isKindOfClass:getASCSecurityKeyPublicKeyCredentialAssertionClass()]) {
-                    attachment = AuthenticatorAttachment::CrossPlatform;
-                    response.isAuthenticatorAttestationResponse = false;
+            if ([error.get().domain isEqualToString:ASCAuthorizationErrorDomain] && error.get().code == ASCAuthorizationErrorUserCanceled)
+                errorMessage = @"This request has been cancelled by the user.";
+            else
+                errorMessage = @"Operation failed.";
+        }
 
-                    ASCSecurityKeyPublicKeyCredentialAssertion *assertionCredential = credential;
-                    response.rawId = toArrayBuffer(assertionCredential.credentialID);
-                    response.authenticatorData = toArrayBuffer(assertionCredential.authenticatorData);
-                    response.signature = toArrayBuffer(assertionCredential.signature);
-                    response.userHandle = toArrayBuffer(assertionCredential.userHandle);
-                } else {
-                    attachment = (AuthenticatorAttachment) 0;
-                    ExceptionCode exceptionCode;
-                    NSString *errorMessage = nil;
-                    if ([error.domain isEqualToString:WKErrorDomain]) {
-                        exceptionCode = toExceptionCode(error.code);
-                        errorMessage = error.userInfo[NSLocalizedDescriptionKey];
-                    } else {
-                        exceptionCode = NotAllowedError;
+        exceptionData = { exceptionCode, errorMessage };
+    }
 
-                        if ([error.domain isEqualToString:ASCAuthorizationErrorDomain] && error.code == ASCAuthorizationErrorUserCanceled)
-                            errorMessage = @"This request has been cancelled by the user.";
-                        else
-                            errorMessage = @"Operation failed.";
-                    }
+    handler(response, attachment, exceptionData);
+}
 
-                    exceptionData = { exceptionCode, errorMessage };
-                }
+void WebAuthenticatorCoordinatorProxy::performRequest(RetainPtr<ASCCredentialRequestContext> requestContext, RequestCompletionHandler&& handler)
+{
+    m_proxy = adoptNS([allocASCAgentProxyInstance() init]);
+#if PLATFORM(IOS)
+    [m_proxy performAuthorizationRequestsForContext:requestContext.get() withCompletionHandler:makeBlockPtr([handler = WTFMove(handler)](id<ASCCredentialProtocol> credential, NSError *error) mutable {
+        callOnMainRunLoop([handler = WTFMove(handler), proxy = WTFMove(proxy), credential = retainPtr(credential), error = retainPtr(error)] () mutable {
+#elif PLATFORM(MAC)
+    RetainPtr<NSWindow> window = m_webPageProxy.platformWindow();
+    [m_proxy performAuthorizationRequestsForContext:requestContext.get() withClearanceHandler:makeBlockPtr([weakThis = WeakPtr { *this }, handler = WTFMove(handler), window = WTFMove(window)](NSXPCListenerEndpoint *daemonEndpoint, NSError *error) mutable {
+        callOnMainRunLoop([weakThis, handler = WTFMove(handler), window = WTFMove(window), daemonEndpoint = retainPtr(daemonEndpoint), error = retainPtr(error)] () mutable {
+            if (!weakThis || !daemonEndpoint) {
+                LOG_ERROR("Could not connect to authorization daemon: %@\n", error.get());
+                handler({ }, (AuthenticatorAttachment)0, ExceptionData { NotAllowedError, "Operation failed." });
+                return;
+            }
 
-                handler(response, attachment, exceptionData);
+            weakThis->m_presenter = adoptNS([allocASCAuthorizationRemotePresenterInstance() init]);
+            [weakThis->m_presenter presentWithWindow:window.get() daemonEndpoint:daemonEndpoint.get() completionHandler:makeBlockPtr([handler = WTFMove(handler)](id<ASCCredentialProtocol> credentialNotRetain, NSError *errorNotRetain) mutable {
+                auto credential = retainPtr(credentialNotRetain);
+                auto error = retainPtr(errorNotRetain);
+#endif
+                continueAfterRequest(credential, error, WTFMove(handler));
+#if PLATFORM(MAC)
             }).get()];
+#endif
         });
     }).get()];
 }
@@ -394,6 +407,12 @@
     handler(LocalService::isAvailable());
 }
 
+void WebAuthenticatorCoordinatorProxy::cancel()
+{
+    if (m_proxy)
+        [m_proxy cancelCurrentRequest];
+}
+
 } // namespace WebKit
 
 #endif // HAVE(UNIFIED_ASC_AUTH_UI)

Modified: branches/safari-613-branch/Source/WebKit/UIProcess/WebAuthentication/WebAuthenticatorCoordinatorProxy.cpp (292176 => 292177)


--- branches/safari-613-branch/Source/WebKit/UIProcess/WebAuthentication/WebAuthenticatorCoordinatorProxy.cpp	2022-03-31 21:22:25 UTC (rev 292176)
+++ branches/safari-613-branch/Source/WebKit/UIProcess/WebAuthentication/WebAuthenticatorCoordinatorProxy.cpp	2022-03-31 21:22:29 UTC (rev 292177)
@@ -53,6 +53,9 @@
 
 WebAuthenticatorCoordinatorProxy::~WebAuthenticatorCoordinatorProxy()
 {
+#if HAVE(UNIFIED_ASC_AUTH_UI)
+    cancel();
+#endif // HAVE(UNIFIED_ASC_AUTH_UI)
     m_webPageProxy.process().removeMessageReceiver(Messages::WebAuthenticatorCoordinatorProxy::messageReceiverName(), m_webPageProxy.webPageID());
 }
 

Modified: branches/safari-613-branch/Source/WebKit/UIProcess/WebAuthentication/WebAuthenticatorCoordinatorProxy.h (292176 => 292177)


--- branches/safari-613-branch/Source/WebKit/UIProcess/WebAuthentication/WebAuthenticatorCoordinatorProxy.h	2022-03-31 21:22:25 UTC (rev 292176)
+++ branches/safari-613-branch/Source/WebKit/UIProcess/WebAuthentication/WebAuthenticatorCoordinatorProxy.h	2022-03-31 21:22:29 UTC (rev 292177)
@@ -44,6 +44,7 @@
 #if HAVE(UNIFIED_ASC_AUTH_UI)
 OBJC_CLASS ASCAuthorizationRemotePresenter;
 OBJC_CLASS ASCCredentialRequestContext;
+OBJC_CLASS ASCAgentProxy;
 #endif
 
 namespace WebKit {
@@ -53,6 +54,8 @@
 struct FrameInfoData;
 struct WebAuthenticationRequestData;
 
+using RequestCompletionHandler = CompletionHandler<void(const WebCore::AuthenticatorResponseData&, WebCore::AuthenticatorAttachment, const WebCore::ExceptionData&)>;
+
 class WebAuthenticatorCoordinatorProxy : public IPC::MessageReceiver {
     WTF_MAKE_FAST_ALLOCATED;
     WTF_MAKE_NONCOPYABLE(WebAuthenticatorCoordinatorProxy);
@@ -61,7 +64,6 @@
     ~WebAuthenticatorCoordinatorProxy();
 
 private:
-    using RequestCompletionHandler = CompletionHandler<void(const WebCore::AuthenticatorResponseData&, WebCore::AuthenticatorAttachment, const WebCore::ExceptionData&)>;
     using QueryCompletionHandler = CompletionHandler<void(bool)>;
 
     // IPC::MessageReceiver.
@@ -77,9 +79,11 @@
     WebPageProxy& m_webPageProxy;
 
 #if HAVE(UNIFIED_ASC_AUTH_UI)
+    void cancel();
     RetainPtr<ASCCredentialRequestContext> contextForRequest(WebAuthenticationRequestData&&);
     void performRequest(RetainPtr<ASCCredentialRequestContext>, RequestCompletionHandler&&);
     RetainPtr<ASCAuthorizationRemotePresenter> m_presenter;
+    RetainPtr<ASCAgentProxy> m_proxy;
 #endif // HAVE(UNIFIED_ASC_AUTH_UI)
 };
 
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to