[Curl] Fix authentication related bugs
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 23 Oct 2017 17:21:08 +0000 (17:21 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 23 Oct 2017 17:21:08 +0000 (17:21 +0000)
https://bugs.webkit.org/show_bug.cgi?id=178652

Patch by Basuke Suzuki <Basuke.Suzuki@sony.com> on 2017-10-23
Reviewed by Alex Christensen.

* platform/network/curl/AuthenticationChallengeCurl.cpp:
(WebCore::AuthenticationChallenge::protectionSpaceFromHandle):
* platform/network/curl/CurlContext.cpp:
(WebCore::CurlHandle::setHttpAuthUserPass):
* platform/network/curl/CurlRequest.cpp:
(WebCore::CurlRequest::setUserPass):
(WebCore::CurlRequest::setupTransfer):
(WebCore::CurlRequest::didReceiveHeader):
* platform/network/curl/CurlRequest.h:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@223838 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebCore/ChangeLog
Source/WebCore/platform/network/curl/AuthenticationChallengeCurl.cpp
Source/WebCore/platform/network/curl/CurlContext.cpp
Source/WebCore/platform/network/curl/CurlRequest.cpp
Source/WebCore/platform/network/curl/CurlRequest.h

index 436f84f..d70247b 100644 (file)
@@ -1,3 +1,20 @@
+2017-10-23  Basuke Suzuki  <Basuke.Suzuki@sony.com>
+
+        [Curl] Fix authentication related bugs
+        https://bugs.webkit.org/show_bug.cgi?id=178652
+
+        Reviewed by Alex Christensen.
+
+        * platform/network/curl/AuthenticationChallengeCurl.cpp:
+        (WebCore::AuthenticationChallenge::protectionSpaceFromHandle):
+        * platform/network/curl/CurlContext.cpp:
+        (WebCore::CurlHandle::setHttpAuthUserPass):
+        * platform/network/curl/CurlRequest.cpp:
+        (WebCore::CurlRequest::setUserPass):
+        (WebCore::CurlRequest::setupTransfer):
+        (WebCore::CurlRequest::didReceiveHeader):
+        * platform/network/curl/CurlRequest.h:
+
 2017-10-23  Matt Lewis  <jlewis3@apple.com>
 
         Unreviewed, rolling out r223820.
index 9011fb1..5757826 100644 (file)
@@ -68,8 +68,8 @@ ProtectionSpace AuthenticationChallenge::protectionSpaceFromHandle(const CurlRes
 
     String realm;
     const String realmString("realm=");
-    auto authHeader = response.httpHeaderField(HTTPHeaderName::Authorization);
-    auto realmPos = authHeader.find(realmString);
+    auto authHeader = response.httpHeaderField(String("www-authenticate"));
+    auto realmPos = authHeader.findIgnoringCase(realmString);
     if (realmPos != notFound) {
         realm = authHeader.substring(realmPos + realmString.length());
         realm = realm.left(realm.find(','));
index 45b30b1..dea3602 100644 (file)
@@ -428,12 +428,8 @@ void CurlHandle::enableHttpAuthentication(long option)
 
 void CurlHandle::setHttpAuthUserPass(const String& user, const String& password)
 {
-    String userpass = emptyString();
-
-    if (!user.isEmpty() || !password.isEmpty())
-        userpass = user + ":" + password;
-
-    curl_easy_setopt(m_handle, CURLOPT_USERPWD, userpass.utf8().data());
+    curl_easy_setopt(m_handle, CURLOPT_USERNAME, user.utf8().data());
+    curl_easy_setopt(m_handle, CURLOPT_PASSWORD, password.utf8().data());
 }
 
 void CurlHandle::setCACertPath(const char* path)
index 4c2c187..37cf733 100644 (file)
@@ -51,7 +51,7 @@ void CurlRequest::setUserPass(const String& user, const String& password)
     ASSERT(isMainThread());
 
     m_user = user.isolatedCopy();
-    m_password = user.isolatedCopy();
+    m_password = password.isolatedCopy();
 }
 
 void CurlRequest::start(bool isSyncRequest)
@@ -168,7 +168,7 @@ CURL* CurlRequest::setupTransfer()
 
     if (!m_user.isEmpty() || !m_password.isEmpty()) {
         m_curlHandle->enableHttpAuthentication(CURLAUTH_ANY);
-        m_curlHandle->setHttpAuthUserPass(m_user.latin1().data(), m_password.latin1().data());
+        m_curlHandle->setHttpAuthUserPass(m_user, m_password);
     }
 
     m_curlHandle->setHeaderCallbackFunction(didReceiveHeaderCallback, this);
@@ -254,6 +254,16 @@ size_t CurlRequest::didReceiveHeader(String&& header)
     if (m_cancelled)
         return 0;
 
+    // libcurl sends all headers that libcurl received to application.
+    // So, in digest authentication, a block of response headers are received twice consecutively from libcurl.
+    // For example, when authentication succeeds, the first block is "401 Authorization", and the second block is "200 OK".
+    // Also, "100 Continue" and "200 Connection Established" do the same behavior.
+    // In this process, deletes the first block to send a correct headers to WebCore.
+    if (m_didReceiveResponse) {
+        m_didReceiveResponse = false;
+        m_response = CurlResponse { };
+    }
+
     auto receiveBytes = static_cast<size_t>(header.length());
 
     // The HTTP standard requires to use \r\n but for compatibility it recommends to accept also \n.
@@ -270,18 +280,7 @@ size_t CurlRequest::didReceiveHeader(String&& header)
     if (auto code = m_curlHandle->getHttpConnectCode())
         httpConnectCode = *code;
 
-    if ((100 <= statusCode) && (statusCode < 200)) {
-        // Just return when receiving http info, e.g. HTTP/1.1 100 Continue.
-        // If not, the request might be cancelled, because the MIME type will be empty for this response.
-        m_response = CurlResponse { };
-        return receiveBytes;
-    }
-
-    if (!statusCode && (httpConnectCode == 200)) {
-        // Comes here when receiving 200 Connection Established. Just return.
-        m_response = CurlResponse { };
-        return receiveBytes;
-    }
+    m_didReceiveResponse = true;
 
     m_response.url = m_request.url();
     m_response.statusCode = statusCode;
index 40bc5e5..31913fe 100644 (file)
@@ -139,8 +139,9 @@ private:
     std::unique_ptr<FormDataStream> m_formDataStream;
     Vector<char> m_postBuffer;
     CurlSSLVerifier m_sslVerifier;
-    CurlResponse m_response;
 
+    CurlResponse m_response;
+    bool m_didReceiveResponse { false };
     bool m_didNotifyResponse { false };
     bool m_didReturnFromNotify { false };
     Action m_actionAfterInvoke { Action::None };