Diff
Modified: trunk/Source/WebKit/ChangeLog (244520 => 244521)
--- trunk/Source/WebKit/ChangeLog 2019-04-22 23:05:30 UTC (rev 244520)
+++ trunk/Source/WebKit/ChangeLog 2019-04-22 23:05:48 UTC (rev 244521)
@@ -1,3 +1,29 @@
+2019-04-22 Alex Christensen <achristen...@webkit.org>
+
+ REGRESSION(r230681) Do not use stored credentials if WKBundlePageResourceLoadClient.shouldUseCredentialStorage returns false
+ https://bugs.webkit.org/show_bug.cgi?id=197093
+ <rdar://problem/49708268>
+
+ Reviewed by Chris Dumez.
+
+ Only get the StoredCredentialsPolicy from the NetworkLoadChecker if we haven't already been told not to use credentials.
+ Also add some test infrastructure for clearing persistent credentials added by the test.
+
+ * NetworkProcess/NetworkProcess.cpp:
+ (WebKit::NetworkProcess::removeCredential):
+ * NetworkProcess/NetworkProcess.h:
+ * NetworkProcess/NetworkProcess.messages.in:
+ * NetworkProcess/NetworkResourceLoader.cpp:
+ (WebKit::NetworkResourceLoader::startNetworkLoad):
+ * NetworkProcess/cocoa/NetworkProcessCocoa.mm:
+ (WebKit::NetworkProcess::removeCredential):
+ * UIProcess/API/Cocoa/WKProcessPool.mm:
+ (-[WKProcessPool _removeCredential:forProtectionSpace:completionHandler:]):
+ * UIProcess/API/Cocoa/WKProcessPoolPrivate.h:
+ * UIProcess/WebProcessPool.cpp:
+ (WebKit::WebProcessPool::removeCredential):
+ * UIProcess/WebProcessPool.h:
+
2019-04-22 Chris Dumez <cdu...@apple.com>
Delayed WebProcessLaunch may break the _relatedWebView SPI
Modified: trunk/Source/WebKit/NetworkProcess/NetworkProcess.cpp (244520 => 244521)
--- trunk/Source/WebKit/NetworkProcess/NetworkProcess.cpp 2019-04-22 23:05:30 UTC (rev 244520)
+++ trunk/Source/WebKit/NetworkProcess/NetworkProcess.cpp 2019-04-22 23:05:48 UTC (rev 244521)
@@ -2470,6 +2470,11 @@
}
#if !PLATFORM(COCOA)
+void NetworkProcess::removeCredential(WebCore::Credential&&, WebCore::ProtectionSpace&&, CompletionHandler<void()>&& completionHandler)
+{
+ completionHandler();
+}
+
void NetworkProcess::initializeProcess(const AuxiliaryProcessInitializationParameters&)
{
}
Modified: trunk/Source/WebKit/NetworkProcess/NetworkProcess.h (244520 => 244521)
--- trunk/Source/WebKit/NetworkProcess/NetworkProcess.h 2019-04-22 23:05:30 UTC (rev 244520)
+++ trunk/Source/WebKit/NetworkProcess/NetworkProcess.h 2019-04-22 23:05:48 UTC (rev 244521)
@@ -72,6 +72,7 @@
class CertificateInfo;
class CurlProxySettings;
class DownloadID;
+class ProtectionSpace;
class StorageQuotaManager;
class NetworkStorageSession;
class ResourceError;
@@ -426,6 +427,8 @@
void platformSyncAllCookies(CompletionHandler<void()>&&);
+ void removeCredential(WebCore::Credential&&, WebCore::ProtectionSpace&&, CompletionHandler<void()>&&);
+
void registerURLSchemeAsSecure(const String&) const;
void registerURLSchemeAsBypassingContentSecurityPolicy(const String&) const;
void registerURLSchemeAsLocal(const String&) const;
Modified: trunk/Source/WebKit/NetworkProcess/NetworkProcess.messages.in (244520 => 244521)
--- trunk/Source/WebKit/NetworkProcess/NetworkProcess.messages.in 2019-04-22 23:05:30 UTC (rev 244520)
+++ trunk/Source/WebKit/NetworkProcess/NetworkProcess.messages.in 2019-04-22 23:05:48 UTC (rev 244521)
@@ -171,4 +171,5 @@
ClearAdClickAttribution(PAL::SessionID sessionID) -> () Async
SetAdClickAttributionOverrideTimerForTesting(PAL::SessionID sessionID, bool value) -> () Async
SetAdClickAttributionConversionURLForTesting(PAL::SessionID sessionID, URL url) -> () Async
+ RemoveCredential(WebCore::Credential credential, WebCore::ProtectionSpace protectionSpace) -> () Async
}
Modified: trunk/Source/WebKit/NetworkProcess/NetworkResourceLoader.cpp (244520 => 244521)
--- trunk/Source/WebKit/NetworkProcess/NetworkResourceLoader.cpp 2019-04-22 23:05:30 UTC (rev 244520)
+++ trunk/Source/WebKit/NetworkProcess/NetworkResourceLoader.cpp 2019-04-22 23:05:48 UTC (rev 244521)
@@ -270,7 +270,7 @@
NetworkLoadParameters parameters = m_parameters;
parameters.networkActivityTracker = m_networkActivityTracker;
- if (m_networkLoadChecker)
+ if (parameters.storedCredentialsPolicy == WebCore::StoredCredentialsPolicy::Use && m_networkLoadChecker)
parameters.storedCredentialsPolicy = m_networkLoadChecker->storedCredentialsPolicy();
if (request.url().protocolIsBlob())
Modified: trunk/Source/WebKit/NetworkProcess/cocoa/NetworkProcessCocoa.mm (244520 => 244521)
--- trunk/Source/WebKit/NetworkProcess/cocoa/NetworkProcessCocoa.mm 2019-04-22 23:05:30 UTC (rev 244520)
+++ trunk/Source/WebKit/NetworkProcess/cocoa/NetworkProcessCocoa.mm 2019-04-22 23:05:48 UTC (rev 244521)
@@ -205,6 +205,18 @@
}).get());
}
+void NetworkProcess::removeCredential(WebCore::Credential&& credential, WebCore::ProtectionSpace&& protectionSpace, CompletionHandler<void()>&& completionHandler)
+{
+ NSURLProtectionSpace *nsSpace = protectionSpace.nsSpace();
+ NSURLCredential *nsCredential = [[[NSURLCredentialStorage sharedCredentialStorage] credentialsForProtectionSpace:nsSpace] objectForKey:credential.user()];
+ RELEASE_ASSERT(nsCredential);
+ RELEASE_ASSERT([nsCredential.user isEqualToString:credential.user()]);
+ RELEASE_ASSERT([nsCredential.password isEqualToString:credential.password()]);
+ [[NSURLCredentialStorage sharedCredentialStorage] removeCredential:nsCredential forProtectionSpace:nsSpace];
+ RELEASE_ASSERT(![[[NSURLCredentialStorage sharedCredentialStorage] credentialsForProtectionSpace:nsSpace] objectForKey:credential.user()]);
+ completionHandler();
+}
+
#if PLATFORM(MAC)
void NetworkProcess::setSharedHTTPCookieStorage(const Vector<uint8_t>& identifier)
{
Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/WKProcessPool.mm (244520 => 244521)
--- trunk/Source/WebKit/UIProcess/API/Cocoa/WKProcessPool.mm 2019-04-22 23:05:30 UTC (rev 244520)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/WKProcessPool.mm 2019-04-22 23:05:48 UTC (rev 244521)
@@ -519,6 +519,13 @@
_processPool->preconnectToServer(serverURL);
}
+- (void)_removeCredential:(NSURLCredential *)credential forProtectionSpace:(NSURLProtectionSpace *)protectionSpace completionHandler:(void(^)())completionHandler
+{
+ _processPool->removeCredential(WebCore::Credential(credential), WebCore::ProtectionSpace(protectionSpace), [completionHandler = makeBlockPtr(completionHandler)] {
+ completionHandler();
+ });
+}
+
- (size_t)_pluginProcessCount
{
#if !PLATFORM(IOS_FAMILY)
Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/WKProcessPoolPrivate.h (244520 => 244521)
--- trunk/Source/WebKit/UIProcess/API/Cocoa/WKProcessPoolPrivate.h 2019-04-22 23:05:30 UTC (rev 244520)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/WKProcessPoolPrivate.h 2019-04-22 23:05:48 UTC (rev 244521)
@@ -116,6 +116,9 @@
- (void)_preconnectToServer:(NSURL *)serverURL WK_API_AVAILABLE(macos(10.13.4), ios(11.3));
// Test only.
+- (void)_removeCredential:(NSURLCredential *)credential forProtectionSpace:(NSURLProtectionSpace *)protectionSpace completionHandler:(void(^)(void))completionHandler WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA));
+
+// Test only.
- (void)_setAllowsAnySSLCertificateForServiceWorker:(BOOL)allows WK_API_AVAILABLE(macos(10.13.4), ios(11.3));
- (void)_registerURLSchemeServiceWorkersCanHandle:(NSString *)scheme WK_API_AVAILABLE(macos(10.13.4), ios(11.3));
- (void)_getActivePagesOriginsInWebProcessForTesting:(pid_t)pid completionHandler:(void(^)(NSArray<NSString *> *))completionHandler WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA));
Modified: trunk/Source/WebKit/UIProcess/WebProcessPool.cpp (244520 => 244521)
--- trunk/Source/WebKit/UIProcess/WebProcessPool.cpp 2019-04-22 23:05:30 UTC (rev 244520)
+++ trunk/Source/WebKit/UIProcess/WebProcessPool.cpp 2019-04-22 23:05:48 UTC (rev 244521)
@@ -1721,6 +1721,11 @@
m_shouldUseTestingNetworkSession = true;
}
+void WebProcessPool::removeCredential(WebCore::Credential&& credential, WebCore::ProtectionSpace&& protectionSpace, CompletionHandler<void()>&& completionHandler)
+{
+ m_networkProcess->sendWithAsyncReply(Messages::NetworkProcess::RemoveCredential(credential, protectionSpace), WTFMove(completionHandler));
+}
+
template<typename T, typename U>
void WebProcessPool::sendSyncToNetworkingProcess(T&& message, U&& reply)
{
Modified: trunk/Source/WebKit/UIProcess/WebProcessPool.h (244520 => 244521)
--- trunk/Source/WebKit/UIProcess/WebProcessPool.h 2019-04-22 23:05:30 UTC (rev 244520)
+++ trunk/Source/WebKit/UIProcess/WebProcessPool.h 2019-04-22 23:05:48 UTC (rev 244521)
@@ -507,6 +507,8 @@
void disableDelayedWebProcessLaunch() { m_isDelayedWebProcessLaunchDisabled = true; }
+ void removeCredential(WebCore::Credential&&, WebCore::ProtectionSpace&&, CompletionHandler<void()>&&);
+
private:
void platformInitialize();
Modified: trunk/Tools/ChangeLog (244520 => 244521)
--- trunk/Tools/ChangeLog 2019-04-22 23:05:30 UTC (rev 244520)
+++ trunk/Tools/ChangeLog 2019-04-22 23:05:48 UTC (rev 244521)
@@ -1,3 +1,33 @@
+2019-04-22 Alex Christensen <achristen...@webkit.org>
+
+ REGRESSION(r230681) Do not use stored credentials if WKBundlePageResourceLoadClient.shouldUseCredentialStorage returns false
+ https://bugs.webkit.org/show_bug.cgi?id=197093
+ <rdar://problem/49708268>
+
+ Reviewed by Chris Dumez.
+
+ Add a test that does two loads. The first load shouldUseCredentialStorage returns true and we provide a persistent credential.
+ The second load shouldUseCredentialStorage returns false and we verify that a challenge is received with no suggested credential.
+ We also need to make the TCPServer able to handle more than one connection because we need these two loads to come from the same protection space,
+ and our current Cocoa implementation of NetworkSession uses two NSURLSessions that don't share a connection cache, one for loads with credentials
+ and one for loads without credentials, so there are two TCP connections to the same server in this test.
+
+ * TestWebKitAPI/TCPServer.cpp:
+ (TestWebKitAPI::TCPServer::TCPServer):
+ (TestWebKitAPI::TCPServer::~TCPServer):
+ (TestWebKitAPI::TCPServer::socketBindListen):
+ (TestWebKitAPI::TCPServer::waitForAndReplyToRequests): Deleted.
+ * TestWebKitAPI/TCPServer.h:
+ * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
+ * TestWebKitAPI/Tests/WebKitCocoa/BasicProposedCredentialPlugIn.mm: Added.
+ (-[BasicProposedCredentialPlugIn webProcessPlugIn:didCreateBrowserContextController:]):
+ * TestWebKitAPI/Tests/WebKitCocoa/Challenge.mm:
+ (respondWithChallengeThenOK):
+ (TestWebKitAPI::TEST):
+ (-[ProposedCredentialDelegate webView:didFinishNavigation:]):
+ (-[ProposedCredentialDelegate webView:didReceiveAuthenticationChallenge:completionHandler:]):
+ (TEST):
+
2019-04-22 Chris Dumez <cdu...@apple.com>
Delayed WebProcessLaunch may break the _relatedWebView SPI
Modified: trunk/Tools/TestWebKitAPI/TCPServer.cpp (244520 => 244521)
--- trunk/Tools/TestWebKitAPI/TCPServer.cpp 2019-04-22 23:05:30 UTC (rev 244520)
+++ trunk/Tools/TestWebKitAPI/TCPServer.cpp 2019-04-22 23:05:48 UTC (rev 244521)
@@ -29,35 +29,39 @@
#include <netinet/in.h>
#include <thread>
#include <unistd.h>
-#include <vector>
+#include <wtf/Optional.h>
namespace TestWebKitAPI {
-TCPServer::TCPServer(Function<void(Socket)>&& socketHandler)
- : m_socketHandler(WTFMove(socketHandler))
+TCPServer::TCPServer(Function<void(Socket)>&& connectionHandler, size_t connections)
+ : m_connectionHandler(WTFMove(connectionHandler))
{
- socketBindListen();
- m_thread = std::thread(&TCPServer::waitForAndReplyToRequests, this);
+ auto listeningSocket = socketBindListen(connections);
+ ASSERT(listeningSocket);
+ m_listeningThread = std::thread([this, listeningSocket = *listeningSocket, connections] {
+ for (size_t i = 0; i < connections; ++i) {
+ Socket connectionSocket = accept(listeningSocket, nullptr, nullptr);
+ m_connectionThreads.append(std::thread([this, connectionSocket] {
+ m_connectionHandler(connectionSocket);
+ shutdown(connectionSocket, SHUT_RDWR);
+ close(connectionSocket);
+ }));
+ }
+ });
}
TCPServer::~TCPServer()
{
- m_thread.join();
- if (m_listeningSocket != InvalidSocket) {
- close(m_listeningSocket);
- m_listeningSocket = InvalidSocket;
- }
- if (m_connectionSocket != InvalidSocket) {
- close(m_connectionSocket);
- m_connectionSocket = InvalidSocket;
- }
+ m_listeningThread.join();
+ for (auto& connectionThreads : m_connectionThreads)
+ connectionThreads.join();
}
-void TCPServer::socketBindListen()
+auto TCPServer::socketBindListen(size_t connections) -> Optional<Socket>
{
- m_listeningSocket = socket(PF_INET, SOCK_STREAM, 0);
- if (m_listeningSocket == InvalidSocket)
- return;
+ Socket listeningSocket = socket(PF_INET, SOCK_STREAM, 0);
+ if (listeningSocket == -1)
+ return WTF::nullopt;
// Ports 49152-65535 are unallocated ports. Try until we find one that's free.
for (Port port = 49152; port; port++) {
@@ -66,34 +70,22 @@
name.sin_family = AF_INET;
name.sin_port = htons(port);
name.sin_addr.s_addr = htonl(INADDR_ANY);
- if (bind(m_listeningSocket, reinterpret_cast<sockaddr*>(&name), sizeof(name)) < 0) {
+ if (bind(listeningSocket, reinterpret_cast<sockaddr*>(&name), sizeof(name)) < 0) {
// This port is busy. Try the next port.
continue;
}
- const unsigned maxConnections = 1;
- if (listen(m_listeningSocket, maxConnections) == -1) {
+ if (listen(listeningSocket, connections) == -1) {
// Listening failed.
- close(m_listeningSocket);
- m_listeningSocket = InvalidSocket;
- return;
+ close(listeningSocket);
+ return WTF::nullopt;
}
m_port = port;
- return; // Successfully set up listening port.
+ return listeningSocket; // Successfully set up listening port.
}
// Couldn't find an available port.
- close(m_listeningSocket);
- m_listeningSocket = InvalidSocket;
+ close(listeningSocket);
+ return WTF::nullopt;
}
-void TCPServer::waitForAndReplyToRequests()
-{
- if (m_listeningSocket == InvalidSocket)
- return;
-
- m_connectionSocket = accept(m_listeningSocket, nullptr, nullptr);
- m_socketHandler(m_connectionSocket);
- shutdown(m_connectionSocket, SHUT_RDWR);
-}
-
} // namespace TestWebKitAPI
Modified: trunk/Tools/TestWebKitAPI/TCPServer.h (244520 => 244521)
--- trunk/Tools/TestWebKitAPI/TCPServer.h 2019-04-22 23:05:30 UTC (rev 244520)
+++ trunk/Tools/TestWebKitAPI/TCPServer.h 2019-04-22 23:05:48 UTC (rev 244521)
@@ -27,6 +27,7 @@
#include <thread>
#include <wtf/Function.h>
+#include <wtf/Vector.h>
namespace TestWebKitAPI {
@@ -33,24 +34,21 @@
class TCPServer {
public:
using Socket = int;
- static constexpr Socket InvalidSocket = -1;
using Port = uint16_t;
static constexpr Port InvalidPort = 0;
- TCPServer(Function<void(Socket)>&&);
+ TCPServer(Function<void(Socket)>&&, size_t connections = 1);
~TCPServer();
Port port() const { return m_port; }
private:
- void socketBindListen();
- void waitForAndReplyToRequests();
+ Optional<Socket> socketBindListen(size_t connections);
Port m_port { InvalidPort };
- Socket m_listeningSocket { InvalidSocket };
- Socket m_connectionSocket { InvalidSocket };
- std::thread m_thread;
- Function<void(Socket)> m_socketHandler;
+ std::thread m_listeningThread;
+ Vector<std::thread> m_connectionThreads;
+ Function<void(Socket)> m_connectionHandler;
};
} // namespace TestWebKitAPI
Modified: trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj (244520 => 244521)
--- trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj 2019-04-22 23:05:30 UTC (rev 244520)
+++ trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj 2019-04-22 23:05:48 UTC (rev 244521)
@@ -314,6 +314,7 @@
5C23DF0B2246015800F454B6 /* Challenge.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5C23DF0A2245C9D700F454B6 /* Challenge.mm */; };
5C2936931D5BF70D00DEAB1E /* CookieAcceptPolicy.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5C2936911D5BF63E00DEAB1E /* CookieAcceptPolicy.mm */; };
5C2936961D5C00ED00DEAB1E /* CookieMessage.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 5C2936941D5BFD1900DEAB1E /* CookieMessage.html */; };
+ 5C4259462266A68A0039AA7A /* BasicProposedCredentialPlugIn.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5C42594422669E9B0039AA7A /* BasicProposedCredentialPlugIn.mm */; };
5C4A84951F7EEFFC00ACFC54 /* Configuration.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5C4A84941F7EEFD400ACFC54 /* Configuration.mm */; };
5C69BDD51F82A7EF000F4F4B /* _javascript_DuringNavigation.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5C69BDD41F82A7EB000F4F4B /* _javascript_DuringNavigation.mm */; };
5C6E27A7224EEBEA00128736 /* URLCanonicalization.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5C6E27A6224EEBEA00128736 /* URLCanonicalization.mm */; };
@@ -1728,6 +1729,7 @@
5C23DF0A2245C9D700F454B6 /* Challenge.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = Challenge.mm; sourceTree = "<group>"; };
5C2936911D5BF63E00DEAB1E /* CookieAcceptPolicy.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = CookieAcceptPolicy.mm; sourceTree = "<group>"; };
5C2936941D5BFD1900DEAB1E /* CookieMessage.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = CookieMessage.html; sourceTree = "<group>"; };
+ 5C42594422669E9B0039AA7A /* BasicProposedCredentialPlugIn.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = BasicProposedCredentialPlugIn.mm; sourceTree = "<group>"; };
5C4A84941F7EEFD400ACFC54 /* Configuration.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = Configuration.mm; sourceTree = "<group>"; };
5C5E633D1D0B67940085A025 /* UniqueRef.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = UniqueRef.cpp; sourceTree = "<group>"; };
5C69BDD41F82A7EB000F4F4B /* _javascript_DuringNavigation.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = _javascript_DuringNavigation.mm; sourceTree = "<group>"; };
@@ -2529,6 +2531,7 @@
754CEC801F6722DC00D0039A /* AutoFillAvailable.mm */,
2DD355351BD08378005DF4A7 /* AutoLayoutIntegration.mm */,
07CD32F52065B5420064A4BE /* AVFoundationPreference.mm */,
+ 5C42594422669E9B0039AA7A /* BasicProposedCredentialPlugIn.mm */,
374B7A5E1DF36EEE00ACCB6C /* BundleEditingDelegate.mm */,
374B7A5F1DF36EEE00ACCB6C /* BundleEditingDelegatePlugIn.mm */,
374B7A621DF3734C00ACCB6C /* BundleEditingDelegateProtocol.h */,
@@ -4483,6 +4486,7 @@
files = (
37E7DD671EA071F3009B396D /* AdditionalReadAccessAllowedURLsPlugin.mm in Sources */,
754CEC811F6722F200D0039A /* AutoFillAvailable.mm in Sources */,
+ 5C4259462266A68A0039AA7A /* BasicProposedCredentialPlugIn.mm in Sources */,
374B7A611DF371CF00ACCB6C /* BundleEditingDelegatePlugIn.mm in Sources */,
A13EBBB01B87436F00097110 /* BundleParametersPlugIn.mm in Sources */,
37A709AF1E3EA97E00CA5969 /* BundleRangeHandlePlugIn.mm in Sources */,
Added: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/BasicProposedCredentialPlugIn.mm (0 => 244521)
--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/BasicProposedCredentialPlugIn.mm (rev 0)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/BasicProposedCredentialPlugIn.mm 2019-04-22 23:05:48 UTC (rev 244521)
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2019 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import "config.h"
+
+#import <WebKit/WKBundlePage.h>
+#import <WebKit/WKBundlePageResourceLoadClient.h>
+#import <WebKit/WKWebProcessPlugIn.h>
+#import <WebKit/WKWebProcessPlugInBrowserContextControllerPrivate.h>
+
+@interface BasicProposedCredentialPlugIn : NSObject<WKWebProcessPlugIn>
+@end
+
+@implementation BasicProposedCredentialPlugIn
+
+- (void)webProcessPlugIn:(WKWebProcessPlugInController *)plugInController didCreateBrowserContextController:(WKWebProcessPlugInBrowserContextController *)browserContextController
+{
+ WKBundlePageResourceLoadClientV1 client;
+ memset(&client, 0, sizeof(client));
+ client.base.version = 1;
+ client.shouldUseCredentialStorage = [](auto...) {
+ static size_t queries { 0 };
+ ASSERT(queries < 2);
+ return !queries++;
+ };
+ WKBundlePageSetResourceLoadClient([browserContextController _bundlePageRef], &client.base);
+}
+
+@end
Modified: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/Challenge.mm (244520 => 244521)
--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/Challenge.mm 2019-04-22 23:05:30 UTC (rev 244520)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/Challenge.mm 2019-04-22 23:05:48 UTC (rev 244521)
@@ -29,7 +29,38 @@
#import "TCPServer.h"
#import "Test.h"
#import "TestWKWebView.h"
+#import "WKWebViewConfigurationExtras.h"
+#import <WebKit/WKProcessPoolPrivate.h>
+static bool navigationFinished;
+
+static void respondWithChallengeThenOK(int socket)
+{
+ char readBuffer[1000];
+ auto bytesRead = ::read(socket, readBuffer, sizeof(readBuffer));
+ EXPECT_GT(bytesRead, 0);
+ EXPECT_TRUE(static_cast<size_t>(bytesRead) < sizeof(readBuffer));
+
+ const char* challengeHeader =
+ "HTTP/1.1 401 Unauthorized\r\n"
+ "Date: Sat, 23 Mar 2019 06:29:01 GMT\r\n"
+ "Content-Length: 0\r\n"
+ "WWW-Authenticate: Basic realm=\"testrealm\"\r\n\r\n";
+ auto bytesWritten = ::write(socket, challengeHeader, strlen(challengeHeader));
+ EXPECT_EQ(static_cast<size_t>(bytesWritten), strlen(challengeHeader));
+
+ bytesRead = ::read(socket, readBuffer, sizeof(readBuffer));
+ EXPECT_GT(bytesRead, 0);
+ EXPECT_TRUE(static_cast<size_t>(bytesRead) < sizeof(readBuffer));
+
+ const char* responseHeader =
+ "HTTP/1.1 200 OK\r\n"
+ "Content-Length: 13\r\n\r\n"
+ "Hello, World!";
+ bytesWritten = ::write(socket, responseHeader, strlen(responseHeader));
+ EXPECT_EQ(static_cast<size_t>(bytesWritten), strlen(responseHeader));
+}
+
#if PLATFORM(MAC)
static std::pair<RetainPtr<NSURLCredential>, RetainPtr<NSString>> credentialWithIdentityAndKeychainPath()
@@ -170,7 +201,6 @@
};
}
-static bool navigationFinished;
static RetainPtr<NSString> keychainPath;
@interface ChallengeDelegate : NSObject <WKNavigationDelegate>
@@ -208,31 +238,7 @@
TEST(Challenge, SecIdentity)
{
- TCPServer server([] (auto socket) {
- char readBuffer[1000];
- auto bytesRead = ::read(socket, readBuffer, sizeof(readBuffer));
- EXPECT_GT(bytesRead, 0);
- EXPECT_TRUE(static_cast<size_t>(bytesRead) < sizeof(readBuffer));
-
- const char* challengeHeader =
- "HTTP/1.1 401 Unauthorized\r\n"
- "Date: Sat, 23 Mar 2019 06:29:01 GMT\r\n"
- "Content-Length: 0\r\n"
- "WWW-Authenticate: Basic realm=\"testrealm\"\r\n\r\n";
- auto bytesWritten = ::write(socket, challengeHeader, strlen(challengeHeader));
- EXPECT_EQ(static_cast<size_t>(bytesWritten), strlen(challengeHeader));
-
- bytesRead = ::read(socket, readBuffer, sizeof(readBuffer));
- EXPECT_GT(bytesRead, 0);
- EXPECT_TRUE(static_cast<size_t>(bytesRead) < sizeof(readBuffer));
-
- const char* responseHeader =
- "HTTP/1.1 200 OK\r\n"
- "Content-Length: 13\r\n\r\n"
- "Hello, World!";
- bytesWritten = ::write(socket, responseHeader, strlen(responseHeader));
- EXPECT_EQ(static_cast<size_t>(bytesWritten), strlen(responseHeader));
- });
+ TCPServer server(respondWithChallengeThenOK);
auto webView = adoptNS([WKWebView new]);
auto delegate = adoptNS([ChallengeDelegate new]);
@@ -250,3 +256,55 @@
} // namespace TestWebKitAPI
#endif
+
+static bool receivedSecondChallenge;
+static RetainPtr<NSURLCredential> persistentCredential;
+
+@interface ProposedCredentialDelegate : NSObject <WKNavigationDelegate>
+@end
+
+@implementation ProposedCredentialDelegate
+
+- (void)webView:(WKWebView *)webView didFinishNavigation:(null_unspecified WKNavigation *)navigation
+{
+ navigationFinished = true;
+}
+
+- (void)webView:(WKWebView *)webView didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition, NSURLCredential *))completionHandler
+{
+ static bool firstChallenge = true;
+ if (firstChallenge) {
+ firstChallenge = false;
+ persistentCredential = adoptNS([[NSURLCredential alloc] initWithUser:@"testuser" password:@"testpassword" persistence:NSURLCredentialPersistencePermanent]);
+ return completionHandler(NSURLSessionAuthChallengeUseCredential, persistentCredential.get());
+
+ }
+ receivedSecondChallenge = true;
+ return completionHandler(NSURLSessionAuthChallengeUseCredential, nil);
+}
+
+@end
+
+TEST(Challenge, BasicProposedCredential)
+{
+ using namespace TestWebKitAPI;
+ TCPServer server(respondWithChallengeThenOK, 2);
+ auto configuration = retainPtr([WKWebViewConfiguration _test_configurationWithTestPlugInClassName:@"BasicProposedCredentialPlugIn"]);
+ auto webView = adoptNS([[WKWebView alloc] initWithFrame:CGRectZero configuration:configuration.get()]);
+ auto delegate = adoptNS([ProposedCredentialDelegate new]);
+ [webView setNavigationDelegate:delegate.get()];
+ RetainPtr<NSURLRequest> request = [NSURLRequest requestWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"http://127.0.0.1:%d/", server.port()]]];
+ [webView loadRequest:request.get()];
+ Util::run(&navigationFinished);
+ navigationFinished = false;
+ [webView loadRequest:request.get()];
+ Util::run(&navigationFinished);
+ EXPECT_TRUE(receivedSecondChallenge);
+
+ NSURLProtectionSpace *protectionSpace = [[[NSURLProtectionSpace alloc] initWithHost:@"127.0.0.1" port:server.port() protocol:NSURLProtectionSpaceHTTP realm:@"testrealm" authenticationMethod:NSURLAuthenticationMethodHTTPBasic] autorelease];
+ __block bool removedCredential = false;
+ [[webView configuration].processPool _removeCredential:persistentCredential.get() forProtectionSpace:protectionSpace completionHandler:^{
+ removedCredential = true;
+ }];
+ Util::run(&removedCredential);
+}