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)
};