summaryrefslogtreecommitdiffstats
path: root/net/http/http_auth_handler_digest_unittest.cc
diff options
context:
space:
mode:
authorericroman@google.com <ericroman@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2008-09-27 03:19:42 +0000
committerericroman@google.com <ericroman@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2008-09-27 03:19:42 +0000
commitc3b35c2100dba30c517116bc9a5a4e4149c3a8e5 (patch)
treeff42c902c4ee9afd7864a2bda8e5e815a876bc76 /net/http/http_auth_handler_digest_unittest.cc
parente5be6612288df667ca6ae4a86060bc883a498eea (diff)
downloadchromium_src-c3b35c2100dba30c517116bc9a5a4e4149c3a8e5.zip
chromium_src-c3b35c2100dba30c517116bc9a5a4e4149c3a8e5.tar.gz
chromium_src-c3b35c2100dba30c517116bc9a5a4e4149c3a8e5.tar.bz2
Initial stab at http authentication (basic + digest) in new http stack.
General design: - class HttpAuth -- utility class for http-auth logic. - class HttpAuth::ChallengeTokenizer -- parsing of www-Authenticate headers. - class HttpAuthHandler -- base class for authentication schemes (inspired by nsIHttpAuthenticator) - class HttpAuthHandlerBasic : HttpAuthHandler -- logic for basic auth. - class HttpAuthHandlerDigest : HttpAuthHandler -- logic for digest auth. - The auth integration in HttpNetworkTransaction mimics that of HttpTransactionWinHttp: + HttpNetworkTransaction::ApplyAuth() -- set the authorization headers. + HttpNetworkTransaction::PopulateAuthChallenge() -- process the challenges. BUG=2346 Review URL: http://codereview.chromium.org/4063 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@2658 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net/http/http_auth_handler_digest_unittest.cc')
-rw-r--r--net/http/http_auth_handler_digest_unittest.cc210
1 files changed, 210 insertions, 0 deletions
diff --git a/net/http/http_auth_handler_digest_unittest.cc b/net/http/http_auth_handler_digest_unittest.cc
new file mode 100644
index 0000000..41df781
--- /dev/null
+++ b/net/http/http_auth_handler_digest_unittest.cc
@@ -0,0 +1,210 @@
+// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "testing/gtest/include/gtest/gtest.h"
+
+#include "base/basictypes.h"
+#include "net/http/http_auth_handler_digest.h"
+
+namespace net {
+
+TEST(HttpAuthHandlerDigestTest, ParseChallenge) {
+ static const struct {
+ // The challenge string.
+ const char* challenge;
+ // Expected return value of ParseChallenge.
+ bool parsed_success;
+ // The expected values that were parsed.
+ const char* parsed_realm;
+ const char* parsed_nonce;
+ const char* parsed_domain;
+ const char* parsed_opaque;
+ bool parsed_stale;
+ int parsed_algorithm;
+ int parsed_qop;
+ } tests[] = {
+ {
+ "Digest nonce=\"xyz\", realm=\"Thunder Bluff\"",
+ true,
+ "Thunder Bluff",
+ "xyz",
+ "",
+ "",
+ false,
+ HttpAuthHandlerDigest::ALGORITHM_UNSPECIFIED,
+ HttpAuthHandlerDigest::QOP_UNSPECIFIED
+ },
+
+ {// Check that when algorithm has an unsupported value, parsing fails.
+ "Digest nonce=\"xyz\", algorithm=\"awezum\", realm=\"Thunder\"",
+ false,
+ // The remaining values don't matter (but some have been set already).
+ "",
+ "xyz",
+ "",
+ "",
+ false,
+ HttpAuthHandlerDigest::ALGORITHM_UNSPECIFIED,
+ HttpAuthHandlerDigest::QOP_UNSPECIFIED
+ },
+
+ { // Check that algorithm's value is case insensitive.
+ "Digest nonce=\"xyz\", algorithm=\"mD5\", realm=\"Oblivion\"",
+ true,
+ "Oblivion",
+ "xyz",
+ "",
+ "",
+ false,
+ HttpAuthHandlerDigest::ALGORITHM_MD5,
+ HttpAuthHandlerDigest::QOP_UNSPECIFIED
+ },
+
+ { // Check that md5-sess is recognized, as is single QOP
+ "Digest nonce=\"xyz\", algorithm=\"md5-sess\", "
+ "realm=\"Oblivion\", qop=\"auth\"",
+ true,
+ "Oblivion",
+ "xyz",
+ "",
+ "",
+ false,
+ HttpAuthHandlerDigest::ALGORITHM_MD5_SESS,
+ HttpAuthHandlerDigest::QOP_AUTH
+ },
+
+ { // The realm can't be missing.
+ "Digest nonce=\"xyz\"",
+ false, // FAILED parse.
+ "",
+ "xyz",
+ "",
+ "",
+ false,
+ HttpAuthHandlerDigest::ALGORITHM_UNSPECIFIED,
+ HttpAuthHandlerDigest::QOP_UNSPECIFIED
+ }
+ };
+
+ for (int i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
+ std::string challenge(tests[i].challenge);
+
+ HttpAuthHandlerDigest auth;
+ bool ok = auth.ParseChallenge(challenge.begin(), challenge.end());
+
+ EXPECT_EQ(tests[i].parsed_success, ok);
+ EXPECT_STREQ(tests[i].parsed_realm, auth.realm_.c_str());
+ EXPECT_STREQ(tests[i].parsed_nonce, auth.nonce_.c_str());
+ EXPECT_STREQ(tests[i].parsed_domain, auth.domain_.c_str());
+ EXPECT_STREQ(tests[i].parsed_opaque, auth.opaque_.c_str());
+ EXPECT_EQ(tests[i].parsed_stale, auth.stale_);
+ EXPECT_EQ(tests[i].parsed_algorithm, auth.algorithm_);
+ EXPECT_EQ(tests[i].parsed_qop, auth.qop_);
+ }
+}
+
+TEST(HttpAuthHandlerDigestTest, AssembleCredentials) {
+ static const struct {
+ const char* req_method;
+ const char* req_path;
+ const char* challenge;
+ const char* username;
+ const char* password;
+ const char* cnonce;
+ int nonce_count;
+ const char* expected_creds;
+ } tests[] = {
+ { // MD5 with username/password
+ "GET",
+ "/test/drealm1",
+
+ // Challenge
+ "Digest realm=\"DRealm1\", "
+ "nonce=\"claGgoRXBAA=7583377687842fdb7b56ba0555d175baa0b800e3\", "
+ "algorithm=MD5, qop=\"auth\"",
+
+ "foo", "bar", // username/password
+ "082c875dcb2ca740", // cnonce
+ 1, // nc
+
+ // Authorization
+ "Digest username=\"foo\", realm=\"DRealm1\", "
+ "nonce=\"claGgoRXBAA=7583377687842fdb7b56ba0555d175baa0b800e3\", "
+ "uri=\"/test/drealm1\", algorithm=MD5, "
+ "response=\"bcfaa62f1186a31ff1b474a19a17cf57\", "
+ "qop=auth, nc=00000001, cnonce=\"082c875dcb2ca740\""
+ },
+
+ { // MD5 with username but empty password. username has space in it.
+ "GET",
+ "/test/drealm1/",
+
+ // Challenge
+ "Digest realm=\"DRealm1\", "
+ "nonce=\"Ure30oRXBAA=7eca98bbf521ac6642820b11b86bd2d9ed7edc70\", "
+ "algorithm=MD5, qop=\"auth\"",
+
+ "foo bar", "", // Username/password
+ "082c875dcb2ca740", // cnonce
+ 1, // nc
+
+ // Authorization
+ "Digest username=\"foo bar\", realm=\"DRealm1\", "
+ "nonce=\"Ure30oRXBAA=7eca98bbf521ac6642820b11b86bd2d9ed7edc70\", "
+ "uri=\"/test/drealm1/\", algorithm=MD5, "
+ "response=\"93c9c6d5930af3b0eb26c745e02b04a0\", "
+ "qop=auth, nc=00000001, cnonce=\"082c875dcb2ca740\""
+ },
+
+ { // No algorithm, and no qop.
+ "GET",
+ "/",
+
+ // Challenge
+ "Digest realm=\"Oblivion\", nonce=\"nonce-value\"",
+
+ "FooBar", "pass", // Username/password
+ "", // cnonce
+ 1, // nc
+
+ // Authorization
+ "Digest username=\"FooBar\", realm=\"Oblivion\", "
+ "nonce=\"nonce-value\", uri=\"/\", "
+ "response=\"f72ff54ebde2f928860f806ec04acd1b\""
+ },
+
+ { // MD5-sess
+ "GET",
+ "/",
+
+ // Challenge
+ "Digest realm=\"Baztastic\", nonce=\"AAAAAAAA\", "
+ "algorithm=\"md5-sess\", qop=auth",
+
+ "USER", "123", // Username/password
+ "15c07961ed8575c4", // cnonce
+ 1, // nc
+
+ // Authorization
+ "Digest username=\"USER\", realm=\"Baztastic\", "
+ "nonce=\"AAAAAAAA\", uri=\"/\", algorithm=MD5-sess, "
+ "response=\"cbc1139821ee7192069580570c541a03\", "
+ "qop=auth, nc=00000001, cnonce=\"15c07961ed8575c4\""
+ }
+ };
+ for (int i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
+ HttpAuthHandlerDigest digest;
+ std::string challenge = tests[i].challenge;
+ EXPECT_TRUE(digest.InitFromChallenge(
+ challenge.begin(), challenge.end(), HttpAuth::AUTH_SERVER));
+
+ std::string creds = digest.AssembleCredentials(tests[i].req_method,
+ tests[i].req_path, tests[i].username, tests[i].password,
+ tests[i].cnonce, tests[i].nonce_count);
+
+ EXPECT_STREQ(tests[i].expected_creds, creds.c_str());
+ }
+}
+
+} // namespace net