[SCM] WebKit Debian packaging branch, debian/experimental, updated. upstream/1.3.3-9427-gc2be6fc

ap at apple.com ap at apple.com
Wed Dec 22 11:23:31 UTC 2010


The following commit has been merged in the debian/experimental branch:
commit feb0607b64e99822bdbb972f044c836a50c8ec0d
Author: ap at apple.com <ap at apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Wed Jul 21 16:42:07 2010 +0000

            Reviewed by Darin Adler.
    
            https://bugs.webkit.org/show_bug.cgi?id=42717
            <rdar://problem/7062824> A wrong password entered for site or proxy auth remains in WebCore
            credential storage, and is sent with subsequent requests
    
            Tests: http/tests/security/401-logout/401-logout.php
                   http/tests/xmlhttprequest/remember-bad-password.html
    
            * platform/network/CredentialStorage.cpp: (WebCore::CredentialStorage::remove):
            * platform/network/CredentialStorage.h:
            Added a way to remove stored credentials for a given protection space.
    
            * platform/network/cf/ResourceHandleCFNet.cpp: (WebCore::ResourceHandle::didReceiveAuthenticationChallenge):
            * platform/network/mac/ResourceHandleMac.mm: (WebCore::ResourceHandle::didReceiveAuthenticationChallenge):
            Remove stored credentials if they didn't work the first time.
    
    
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@63834 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog
index d52a00b..e9a0b65 100644
--- a/LayoutTests/ChangeLog
+++ b/LayoutTests/ChangeLog
@@ -1,3 +1,21 @@
+2010-07-20  Alexey Proskuryakov  <ap at apple.com>
+
+        Reviewed by Darin Adler.
+
+        https://bugs.webkit.org/show_bug.cgi?id=42717
+        <rdar://problem/7062824> A wrong password entered for site or proxy auth remains in WebCore
+        credential storage, and is sent with subsequent requests
+
+        Adding tests with and without XMLHttpRequest.
+
+        * http/tests/security/401-logout: Added.
+        * http/tests/security/401-logout/401-logout-expected.txt: Added.
+        * http/tests/security/401-logout/401-logout.php: Added.
+        * http/tests/xmlhttprequest/remember-bad-password-expected.txt: Added.
+        * http/tests/xmlhttprequest/remember-bad-password.html: Added.
+        * http/tests/xmlhttprequest/resources/remember-bad-password: Added.
+        * http/tests/xmlhttprequest/resources/remember-bad-password/count-failures.php: Added.
+
 2010-07-20  Simon Fraser  <simon.fraser at apple.com>
 
         Reviewed by Dan Bernstein.
diff --git a/LayoutTests/http/tests/security/401-logout/401-logout-expected.txt b/LayoutTests/http/tests/security/401-logout/401-logout-expected.txt
new file mode 100644
index 0000000..7562ba0
--- /dev/null
+++ b/LayoutTests/http/tests/security/401-logout/401-logout-expected.txt
@@ -0,0 +1,3 @@
+<unknown> - didReceiveAuthenticationChallenge - Responding with username:password
+<unknown> - didReceiveAuthenticationChallenge - Simulating cancelled authentication sheet
+PASS
diff --git a/LayoutTests/http/tests/security/401-logout/401-logout.php b/LayoutTests/http/tests/security/401-logout/401-logout.php
new file mode 100644
index 0000000..5badcf0
--- /dev/null
+++ b/LayoutTests/http/tests/security/401-logout/401-logout.php
@@ -0,0 +1,46 @@
+<?php
+  if (!isset($_REQUEST['uid'])) {
+    // Step 1 - navigate to a page that will make us remember credentials.
+    echo "<script>\n";
+    echo "if (!window.layoutTestController) {\n";
+    echo "    document.write('This test only works as an automated one');\n";
+    echo "    throw 0;\n";
+    echo "}\n";
+    echo "layoutTestController.waitUntilDone();\n";
+    echo "layoutTestController.dumpAsText();\n";
+    echo "layoutTestController.setHandlesAuthenticationChallenges(true)\n";
+    echo "layoutTestController.setAuthenticationUsername('username')\n";
+    echo "layoutTestController.setAuthenticationPassword('password')\n";
+    echo "location = 'http://127.0.0.1:8000/security/401-logout/401-logout.php?uid=username';\n";
+    echo "</script>\n";
+  } else if (!isset($_SERVER['PHP_AUTH_USER']) || ($_REQUEST['uid'] != $_SERVER['PHP_AUTH_USER'])) {
+    if (isset($_REQUEST['laststep'])) {
+      // Step 4 - Credentials are no longer being sent
+      echo "PASS";
+      echo "<script>\n";
+      echo "if (window.layoutTestController) {\n";
+      echo "    layoutTestController.notifyDone();\n";
+      echo "}\n";
+      echo "</script>\n";
+    } else {
+      // Ask for credentials if there are none
+      header('WWW-Authenticate: Basic realm="401-logout"');
+      header('HTTP/1.0 401 Unauthorized');
+    }
+  } else {
+    if (!isset($_REQUEST['logout'])) {
+      // Step 2 - navigate to a page that will make us forget the credentials
+      echo "<script>\n";
+      echo "layoutTestController.setHandlesAuthenticationChallenges(false)\n";
+      echo "location = 'http://127.0.0.1:8000/security/401-logout/401-logout.php?uid=username&logout=1';\n";
+      echo "</script>\n";
+    } else {
+      // Step 3 - logout
+      header('WWW-Authenticate: Basic realm="401-logout"');
+      header('HTTP/1.0 401 Unauthorized');
+      echo "<script>\n";
+      echo "location = 'http://127.0.0.1:8000/security/401-logout/401-logout.php?uid=username&laststep=1';\n";
+      echo "</script>\n";
+    }
+  }
+?>
diff --git a/LayoutTests/http/tests/xmlhttprequest/remember-bad-password-expected.txt b/LayoutTests/http/tests/xmlhttprequest/remember-bad-password-expected.txt
new file mode 100644
index 0000000..6e8ac8d
--- /dev/null
+++ b/LayoutTests/http/tests/xmlhttprequest/remember-bad-password-expected.txt
@@ -0,0 +1,13 @@
+<unknown> - didReceiveAuthenticationChallenge - Simulating cancelled authentication sheet
+<unknown> - didReceiveAuthenticationChallenge - Simulating cancelled authentication sheet
+rdar://problem/7062824 A wrong password entered for site or proxy auth remains in WebCore credential storage, and is sent with subsequent requests.
+
+This test counts the number of failed requests server side.
+
+PASS
+
+Sync
+With credentials Without credentials
+Async
+With credentials Without credentials 
+Status
diff --git a/LayoutTests/http/tests/xmlhttprequest/remember-bad-password.html b/LayoutTests/http/tests/xmlhttprequest/remember-bad-password.html
new file mode 100644
index 0000000..bba1ca9
--- /dev/null
+++ b/LayoutTests/http/tests/xmlhttprequest/remember-bad-password.html
@@ -0,0 +1,68 @@
+<body>
+<p><a href="rdar://problem/7062824">rdar://problem/7062824</a> A wrong password entered for site or proxy auth remains in WebCore credential storage, and is sent with subsequent requests.</p>
+<p>This test counts the number of failed requests server side.</p>
+<div id = result>Testing... Please cancel all authentication dialogs.</div></br>
+<div>Sync</div>
+<button onclick="sendWithCredentials(false)">With credentials</button>
+<button onclick="sendWithoutCredentials(false)">Without credentials</button>
+<div>Async</div>
+<button onclick="sendWithCredentials(true)">With credentials</button>
+<button onclick="sendWithoutCredentials(true)">Without credentials</button>
+<br>
+<button onclick="status()">Status</button>
+<script>
+if (window.layoutTestController) {
+    layoutTestController.dumpAsText();
+    layoutTestController.waitUntilDone()
+}
+
+function sendWithCredentials(next)
+{
+    var xhr = new XMLHttpRequest;
+    xhr.open("GET", "resources/remember-bad-password/count-failures.php", next ? true : false, "foo", "bar");
+    xhr.send("");
+    if (next) {
+        xhr.onload = next;
+        xhr.onerror = next;
+    }
+}
+
+function sendWithoutCredentials(next)
+{
+    var xhr = new XMLHttpRequest;
+    xhr.open("GET", "resources/remember-bad-password/count-failures.php", next ? true : false);
+    xhr.send("");
+
+    if (next) {
+        xhr.onload = next;
+        xhr.onerror = next;
+    }
+}
+
+function status()
+{
+    var xhr = new XMLHttpRequest;
+    xhr.open("GET", "resources/remember-bad-password/count-failures.php?command=status", false);
+    xhr.send("");
+    return xhr.responseText;
+}
+
+function reset()
+{
+    var xhr = new XMLHttpRequest;
+    xhr.open("GET", "resources/remember-bad-password/count-failures.php?command=reset", false);
+    xhr.send("");
+}
+
+reset();
+sendWithCredentials();
+sendWithoutCredentials();
+sendWithCredentials(function() {
+sendWithoutCredentials(function() {
+var s = status();
+document.getElementById("result").innerHTML = (s == 2 ? "PASS" : ("FAIL: " + s));
+if (window.layoutTestController)
+    layoutTestController.notifyDone();
+})});
+</script>
+</body>
diff --git a/LayoutTests/http/tests/xmlhttprequest/resources/remember-bad-password/count-failures.php b/LayoutTests/http/tests/xmlhttprequest/resources/remember-bad-password/count-failures.php
new file mode 100644
index 0000000..b05115f
--- /dev/null
+++ b/LayoutTests/http/tests/xmlhttprequest/resources/remember-bad-password/count-failures.php
@@ -0,0 +1,48 @@
+<?php
+require_once '../../../resources/portabilityLayer.php';
+
+header("Expires: Thu, 01 Dec 2003 16:00:00 GMT");
+header("Cache-Control: no-cache, no-store, must-revalidate");
+header("Pragma: no-cache");
+
+if (!sys_get_temp_dir()) {
+    echo "FAIL: No temp dir was returned.\n";
+    exit();
+}
+
+function setState($newState, $file)
+{
+    file_put_contents($file, $newState);
+}
+
+function getState($file)
+{
+    if (!file_exists($file)) {
+        return "0";
+    }
+    return file_get_contents($file);
+}
+
+$stateFile = sys_get_temp_dir() . "/remember-bad-password-status";
+
+$command = $_GET['command'];
+if ($command) {
+    if ($command == "status")
+        echo getState($stateFile);
+    else if ($command == "reset")
+        echo setState("0", $stateFile);
+    exit();
+}
+
+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';
+        if (isset($_SERVER['PHP_AUTH_USER'])) {
+        setState(getState($stateFile) + 1, $stateFile);
+    }
+    exit;
+} else {
+    echo "User: {$_SERVER['PHP_AUTH_USER']}, password: {$_SERVER['PHP_AUTH_PW']}.";
+}
+?>
diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index b8574b7..0594d0a 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,22 @@
+2010-07-20  Alexey Proskuryakov  <ap at apple.com>
+
+        Reviewed by Darin Adler.
+
+        https://bugs.webkit.org/show_bug.cgi?id=42717
+        <rdar://problem/7062824> A wrong password entered for site or proxy auth remains in WebCore
+        credential storage, and is sent with subsequent requests
+
+        Tests: http/tests/security/401-logout/401-logout.php
+               http/tests/xmlhttprequest/remember-bad-password.html
+
+        * platform/network/CredentialStorage.cpp: (WebCore::CredentialStorage::remove):
+        * platform/network/CredentialStorage.h:
+        Added a way to remove stored credentials for a given protection space.
+
+        * platform/network/cf/ResourceHandleCFNet.cpp: (WebCore::ResourceHandle::didReceiveAuthenticationChallenge):
+        * platform/network/mac/ResourceHandleMac.mm: (WebCore::ResourceHandle::didReceiveAuthenticationChallenge):
+        Remove stored credentials if they didn't work the first time.
+
 2010-07-20  Steve Falkenburg  <sfalken at apple.com>
 
         Reviewed by Adam Roben.
@@ -361,7 +380,7 @@
         * loader/CachedXBLDocument.h:
         * loader/CachedXSLStyleSheet.h:
 
-2010-07-16  James Hawkins  <jhawkins at chromium.org>
+2010-07-20  James Hawkins  <jhawkins at chromium.org>
 
         Reviewed by Darin Fisher.
 
diff --git a/WebCore/platform/network/CredentialStorage.cpp b/WebCore/platform/network/CredentialStorage.cpp
index a48af77..14f4086 100644
--- a/WebCore/platform/network/CredentialStorage.cpp
+++ b/WebCore/platform/network/CredentialStorage.cpp
@@ -106,6 +106,11 @@ Credential CredentialStorage::get(const ProtectionSpace& protectionSpace)
     return protectionSpaceToCredentialMap().get(protectionSpace);
 }
 
+void CredentialStorage::remove(const ProtectionSpace& protectionSpace)
+{
+    protectionSpaceToCredentialMap().remove(protectionSpace);
+}
+
 static PathToDefaultProtectionSpaceMap::iterator findDefaultProtectionSpaceForURL(const KURL& url)
 {
     ASSERT(url.protocolInHTTPFamily());
diff --git a/WebCore/platform/network/CredentialStorage.h b/WebCore/platform/network/CredentialStorage.h
index ff7b5ee..d11384d 100644
--- a/WebCore/platform/network/CredentialStorage.h
+++ b/WebCore/platform/network/CredentialStorage.h
@@ -37,6 +37,7 @@ public:
     // WebCore session credential storage.
     static void set(const Credential&, const ProtectionSpace&, const KURL&);
     static Credential get(const ProtectionSpace&);
+    static void remove(const ProtectionSpace&);
 
     // OS persistent storage.
     static Credential getFromPersistentStorage(const ProtectionSpace&);
diff --git a/WebCore/platform/network/cf/ResourceHandleCFNet.cpp b/WebCore/platform/network/cf/ResourceHandleCFNet.cpp
index 1323fa4..089549e 100644
--- a/WebCore/platform/network/cf/ResourceHandleCFNet.cpp
+++ b/WebCore/platform/network/cf/ResourceHandleCFNet.cpp
@@ -518,17 +518,25 @@ void ResourceHandle::didReceiveAuthenticationChallenge(const AuthenticationChall
         return;
     }
 
-    if (!challenge.previousFailureCount() && (!client() || client()->shouldUseCredentialStorage(this))) {
-        Credential credential = CredentialStorage::get(challenge.protectionSpace());
-        if (!credential.isEmpty() && credential != d->m_initialCredential) {
-            ASSERT(credential.persistence() == CredentialPersistenceNone);
-            if (challenge.failureResponse().httpStatusCode() == 401) {
-                // Store the credential back, possibly adding it as a default for this directory.
-                CredentialStorage::set(credential, challenge.protectionSpace(), firstRequest().url());
+    if (!client() || client()->shouldUseCredentialStorage(this)) {
+        if (!d->m_initialCredential.isEmpty() || challenge.previousFailureCount()) {
+            // The stored credential wasn't accepted, stop using it.
+            // There is a race condition here, since a different credential might have already been stored by another ResourceHandle,
+            // but the observable effect should be very minor, if any.
+            CredentialStorage::remove(challenge.protectionSpace());
+        }
+
+        if (!challenge.previousFailureCount()) {
+            Credential credential = CredentialStorage::get(challenge.protectionSpace());
+            if (!credential.isEmpty() && credential != d->m_initialCredential) {
+                ASSERT(credential.persistence() == CredentialPersistenceNone);
+                if (challenge.failureResponse().httpStatusCode() == 401) {
+                    // Store the credential back, possibly adding it as a default for this directory.
+                    CredentialStorage::set(credential, challenge.protectionSpace(), firstRequest().url());
+                }
+                [challenge.sender() useCredential:mac(credential) forAuthenticationChallenge:mac(challenge)];
+                return;
             }
-            RetainPtr<CFURLCredentialRef> cfCredential(AdoptCF, createCF(credential));
-            CFURLConnectionUseCredential(d->m_connection.get(), cfCredential.get(), challenge.cfURLAuthChallengeRef());
-            return;
         }
     }
 
diff --git a/WebCore/platform/network/mac/ResourceHandleMac.mm b/WebCore/platform/network/mac/ResourceHandleMac.mm
index c8a2b88..f7161ec 100644
--- a/WebCore/platform/network/mac/ResourceHandleMac.mm
+++ b/WebCore/platform/network/mac/ResourceHandleMac.mm
@@ -581,16 +581,25 @@ void ResourceHandle::didReceiveAuthenticationChallenge(const AuthenticationChall
     }
 
 #ifndef BUILDING_ON_TIGER
-    if (!challenge.previousFailureCount() && (!client() || client()->shouldUseCredentialStorage(this))) {
-        Credential credential = CredentialStorage::get(challenge.protectionSpace());
-        if (!credential.isEmpty() && credential != d->m_initialCredential) {
-            ASSERT(credential.persistence() == CredentialPersistenceNone);
-            if (challenge.failureResponse().httpStatusCode() == 401) {
-                // Store the credential back, possibly adding it as a default for this directory.
-                CredentialStorage::set(credential, challenge.protectionSpace(), firstRequest().url());
+    if (!client() || client()->shouldUseCredentialStorage(this)) {
+        if (!d->m_initialCredential.isEmpty() || challenge.previousFailureCount()) {
+            // The stored credential wasn't accepted, stop using it.
+            // There is a race condition here, since a different credential might have already been stored by another ResourceHandle,
+            // but the observable effect should be very minor, if any.
+            CredentialStorage::remove(challenge.protectionSpace());
+        }
+
+        if (!challenge.previousFailureCount()) {
+            Credential credential = CredentialStorage::get(challenge.protectionSpace());
+            if (!credential.isEmpty() && credential != d->m_initialCredential) {
+                ASSERT(credential.persistence() == CredentialPersistenceNone);
+                if (challenge.failureResponse().httpStatusCode() == 401) {
+                    // Store the credential back, possibly adding it as a default for this directory.
+                    CredentialStorage::set(credential, challenge.protectionSpace(), firstRequest().url());
+                }
+                [challenge.sender() useCredential:mac(credential) forAuthenticationChallenge:mac(challenge)];
+                return;
             }
-            [challenge.sender() useCredential:mac(credential) forAuthenticationChallenge:mac(challenge)];
-            return;
         }
     }
 #endif

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list