[Curl] Suppress extra didReceiveAuthenticationChallenge call when accessing a server which checks basic auth.
https://bugs.webkit.org/show_bug.cgi?id=197650

Patch by Takashi Komori <Takashi.Komori@sony.com> on 2019-05-12
Reviewed by Fujii Hironori.

Source/WebCore:

When Curl port accesses a page which checks Basic Authentication credential and server trust challenge occurs,
Curl port calls extra didReceiveAuthenticationChallenge unnecessarily.
This is because Curl port discards information about allowed server trust challenge before in NetworkDataTaskCurl::restartWithCredential.

Test: http/tests/ssl/curl/certificate-and-authentication.html

* platform/network/curl/CurlRequest.h:
(WebCore::CurlRequest::isServerTrustEvaluationDisabled):

Source/WebKit:

* NetworkProcess/curl/NetworkDataTaskCurl.cpp:
(WebKit::NetworkDataTaskCurl::restartWithCredential):

LayoutTests:

* TestExpectations:
* http/tests/resources/basic-auth.php: Added.
* http/tests/ssl/curl/certificate-and-authentication-expected.txt: Added.
* http/tests/ssl/curl/certificate-and-authentication.html: Added.
* platform/wincairo-wk1/TestExpectations:
* platform/wincairo/TestExpectations:

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@245215 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog
index 1885fbe..cd9ea7b 100644
--- a/LayoutTests/ChangeLog
+++ b/LayoutTests/ChangeLog
@@ -1,3 +1,17 @@
+2019-05-12  Takashi Komori  <Takashi.Komori@sony.com>
+
+        [Curl] Suppress extra didReceiveAuthenticationChallenge call when accessing a server which checks basic auth.
+        https://bugs.webkit.org/show_bug.cgi?id=197650
+
+        Reviewed by Fujii Hironori.
+
+        * TestExpectations:
+        * http/tests/resources/basic-auth.php: Added.
+        * http/tests/ssl/curl/certificate-and-authentication-expected.txt: Added.
+        * http/tests/ssl/curl/certificate-and-authentication.html: Added.
+        * platform/wincairo-wk1/TestExpectations:
+        * platform/wincairo/TestExpectations:
+
 2019-05-11  Simon Fraser  <simon.fraser@apple.com>
 
         Overflow scroll that becomes non-scrollable should stop being composited
diff --git a/LayoutTests/TestExpectations b/LayoutTests/TestExpectations
index 18521e1..cdf8129 100644
--- a/LayoutTests/TestExpectations
+++ b/LayoutTests/TestExpectations
@@ -52,6 +52,7 @@
 http/tests/preload/viewport [ Skip ]
 http/tests/gzip-content-encoding [ Skip ]
 http/tests/cookies/same-site [ Skip ]
+http/tests/ssl/curl [ Skip ]
 system-preview [ Skip ]
 editing/images [ Skip ]
 pointerevents/ios [ Skip ]
diff --git a/LayoutTests/http/tests/resources/basic-auth.php b/LayoutTests/http/tests/resources/basic-auth.php
new file mode 100644
index 0000000..95dce5d
--- /dev/null
+++ b/LayoutTests/http/tests/resources/basic-auth.php
@@ -0,0 +1,10 @@
+<?php
+  if (!isset($_SERVER['PHP_AUTH_USER']) || !isset($_REQUEST['uid']) || ($_REQUEST['uid'] != $_SERVER['PHP_AUTH_USER'])) {
+   header('WWW-Authenticate: Basic realm="WebKit Test Realm"');
+   header('HTTP/1.0 401 Unauthorized');
+   echo 'Authentication canceled';
+   exit;
+  } else {
+   echo "User: {$_SERVER['PHP_AUTH_USER']}, password: {$_SERVER['PHP_AUTH_PW']}.";
+  }
+?>
diff --git a/LayoutTests/http/tests/ssl/curl/certificate-and-authentication-expected.txt b/LayoutTests/http/tests/ssl/curl/certificate-and-authentication-expected.txt
new file mode 100644
index 0000000..b51bdbd
--- /dev/null
+++ b/LayoutTests/http/tests/ssl/curl/certificate-and-authentication-expected.txt
@@ -0,0 +1,4 @@
+localhost:8443 - didReceiveAuthenticationChallenge - ProtectionSpaceAuthenticationSchemeHTTPBasic - Responding with user:
+
+PASS Certificate validation and basic authentication 
+
diff --git a/LayoutTests/http/tests/ssl/curl/certificate-and-authentication.html b/LayoutTests/http/tests/ssl/curl/certificate-and-authentication.html
new file mode 100644
index 0000000..3d69088
--- /dev/null
+++ b/LayoutTests/http/tests/ssl/curl/certificate-and-authentication.html
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<html>
+<head>
+<!-- This is a test for https://bugs.webkit.org/show_bug.cgi?id=197650 -->
+<title>Certificate validation and basic authentication</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+</head>
+<body>
+<script>
+function with_iframe(url) {
+    return new Promise(function(resolve) {
+        var frame = document.createElement('iframe');
+        frame.className = 'test-iframe';
+        frame.src = url;
+        frame.onload = function() { resolve(frame); };
+        document.body.appendChild(frame);
+    });
+}
+
+async function doTest()
+{
+    assert_true(!!window.testRunner, "Test requires testRunner");
+
+    window.testRunner.setAllowsAnySSLCertificate(true);
+    window.testRunner.setHandlesAuthenticationChallenges(true);
+    window.testRunner.setAuthenticationUsername("user");
+    window.testRunner.setAuthenticationPassword("");
+
+    const currentCallbackCounts = window.testRunner.serverTrustEvaluationCallbackCallsCount;
+
+    const iframe = await with_iframe("https://localhost:8443/resources/basic-auth.php?uid=user");
+    iframe.remove();
+
+    assert_equals(window.testRunner.serverTrustEvaluationCallbackCallsCount - currentCallbackCounts, 1);
+}
+
+doTest().then(done, (e) => { assert_unreached("test failed: " + e); done(); });
+
+</script>
+</body>
+</html>
diff --git a/LayoutTests/platform/wincairo-wk1/TestExpectations b/LayoutTests/platform/wincairo-wk1/TestExpectations
index 54a9bb7..97a11f4 100644
--- a/LayoutTests/platform/wincairo-wk1/TestExpectations
+++ b/LayoutTests/platform/wincairo-wk1/TestExpectations
@@ -21,6 +21,7 @@
 http/tests/security/cookies/third-party-cookie-blocking-xslt.xml [ Skip ]
 
 # Server trust evaluation only supported in WK2.
+http/tests/ssl/curl/certificate-and-authentication.html [ Skip ]
 http/tests/ssl/iframe-upgrade.https.html [ Skip ]
 http/tests/ssl/mixedContent/insecure-websocket.html [ Failure ]
 http/tests/ssl/upgrade-origin-usage.html [ Failure ]
diff --git a/LayoutTests/platform/wincairo/TestExpectations b/LayoutTests/platform/wincairo/TestExpectations
index 3291973..4ee7e05e 100644
--- a/LayoutTests/platform/wincairo/TestExpectations
+++ b/LayoutTests/platform/wincairo/TestExpectations
@@ -948,6 +948,7 @@
 http/tests/security/cookies/third-party-cookie-blocking-user-action.html [ Pass ]
 http/tests/security/cookies/third-party-cookie-blocking-xslt.xml [ Pass ]
 
+http/tests/ssl/curl/certificate-and-authentication.html [ Pass ]
 http/tests/ssl/media-stream [ Skip ]
 
 [ Debug ] http/tests/storage/callbacks-are-called-in-correct-context.html [ Skip ]
diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog
index 626c55f..880b4ca 100644
--- a/Source/WebCore/ChangeLog
+++ b/Source/WebCore/ChangeLog
@@ -1,3 +1,19 @@
+2019-05-12  Takashi Komori  <Takashi.Komori@sony.com>
+
+        [Curl] Suppress extra didReceiveAuthenticationChallenge call when accessing a server which checks basic auth.
+        https://bugs.webkit.org/show_bug.cgi?id=197650
+
+        Reviewed by Fujii Hironori.
+
+        When Curl port accesses a page which checks Basic Authentication credential and server trust challenge occurs,
+        Curl port calls extra didReceiveAuthenticationChallenge unnecessarily.
+        This is because Curl port discards information about allowed server trust challenge before in NetworkDataTaskCurl::restartWithCredential.
+
+        Test: http/tests/ssl/curl/certificate-and-authentication.html
+
+        * platform/network/curl/CurlRequest.h:
+        (WebCore::CurlRequest::isServerTrustEvaluationDisabled):
+
 2019-05-11  Simon Fraser  <simon.fraser@apple.com>
 
         Overflow scroll that becomes non-scrollable should stop being composited
diff --git a/Source/WebCore/platform/network/curl/CurlRequest.h b/Source/WebCore/platform/network/curl/CurlRequest.h
index d13766e..91d4dc9 100644
--- a/Source/WebCore/platform/network/curl/CurlRequest.h
+++ b/Source/WebCore/platform/network/curl/CurlRequest.h
@@ -74,6 +74,7 @@
     void invalidateClient();
     WEBCORE_EXPORT void setAuthenticationScheme(ProtectionSpaceAuthenticationScheme);
     WEBCORE_EXPORT void setUserPass(const String&, const String&);
+    bool isServerTrustEvaluationDisabled() { return m_shouldDisableServerTrustEvaluation; }
     void disableServerTrustEvaluation() { m_shouldDisableServerTrustEvaluation = true; }
     void setStartTime(const MonotonicTime& startTime) { m_requestStartTime = startTime; }
 
diff --git a/Source/WebKit/ChangeLog b/Source/WebKit/ChangeLog
index cdb9040..244ae3d 100644
--- a/Source/WebKit/ChangeLog
+++ b/Source/WebKit/ChangeLog
@@ -1,3 +1,13 @@
+2019-05-12  Takashi Komori  <Takashi.Komori@sony.com>
+
+        [Curl] Suppress extra didReceiveAuthenticationChallenge call when accessing a server which checks basic auth.
+        https://bugs.webkit.org/show_bug.cgi?id=197650
+
+        Reviewed by Fujii Hironori.
+
+        * NetworkProcess/curl/NetworkDataTaskCurl.cpp:
+        (WebKit::NetworkDataTaskCurl::restartWithCredential):
+
 2019-05-10  Chris Dumez  <cdumez@apple.com>
 
         [PSON] Prevent flashing when the process-swap is forced by the client
diff --git a/Source/WebKit/NetworkProcess/curl/NetworkDataTaskCurl.cpp b/Source/WebKit/NetworkProcess/curl/NetworkDataTaskCurl.cpp
index 36a6b39..77633ba 100644
--- a/Source/WebKit/NetworkProcess/curl/NetworkDataTaskCurl.cpp
+++ b/Source/WebKit/NetworkProcess/curl/NetworkDataTaskCurl.cpp
@@ -425,12 +425,13 @@
     ASSERT(m_curlRequest);
 
     auto previousRequest = m_curlRequest->resourceRequest();
+    auto shouldDisableServerTrustEvaluation = protectionSpace.authenticationScheme() == ProtectionSpaceAuthenticationSchemeServerTrustEvaluationRequested || m_curlRequest->isServerTrustEvaluationDisabled();
     m_curlRequest->cancel();
 
     m_curlRequest = createCurlRequest(WTFMove(previousRequest), RequestStatus::ReusedRequest);
     m_curlRequest->setAuthenticationScheme(protectionSpace.authenticationScheme());
     m_curlRequest->setUserPass(credential.user(), credential.password());
-    if (protectionSpace.authenticationScheme() == ProtectionSpaceAuthenticationSchemeServerTrustEvaluationRequested)
+    if (shouldDisableServerTrustEvaluation)
         m_curlRequest->disableServerTrustEvaluation();
     m_curlRequest->setStartTime(m_startTime);
     m_curlRequest->start();