This source file includes following definitions.
- RespondToChallenge
 
- TEST
 
- TEST
 
- TEST
 
- TEST
 
- TEST
 
- TEST
 
- TEST
 
- TEST
 
- TEST
 
- TEST
 
- TEST
 
#include <string>
#include "base/basictypes.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "net/base/net_errors.h"
#include "net/base/test_completion_callback.h"
#include "net/http/http_auth_challenge_tokenizer.h"
#include "net/http/http_auth_handler_digest.h"
#include "net/http/http_request_info.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace net {
namespace {
const char* const kSimpleChallenge =
  "Digest realm=\"Oblivion\", nonce=\"nonce-value\"";
bool RespondToChallenge(HttpAuth::Target target,
                        const std::string& proxy_name,
                        const std::string& request_url,
                        const std::string& challenge,
                        std::string* token) {
  
  if (token == NULL) {
    ADD_FAILURE() << "|token| must be non-NULL";
    return false;
  }
  EXPECT_TRUE(target != HttpAuth::AUTH_PROXY || !proxy_name.empty());
  EXPECT_FALSE(request_url.empty());
  EXPECT_FALSE(challenge.empty());
  token->clear();
  scoped_ptr<HttpAuthHandlerDigest::Factory> factory(
      new HttpAuthHandlerDigest::Factory());
  HttpAuthHandlerDigest::NonceGenerator* nonce_generator =
      new HttpAuthHandlerDigest::FixedNonceGenerator("client_nonce");
  factory->set_nonce_generator(nonce_generator);
  scoped_ptr<HttpAuthHandler> handler;
  
  GURL url_origin(target == HttpAuth::AUTH_SERVER ? request_url : proxy_name);
  int rv_create = factory->CreateAuthHandlerFromString(
    challenge, target, url_origin.GetOrigin(), BoundNetLog(), &handler);
  if (rv_create != OK || handler.get() == NULL) {
    ADD_FAILURE() << "Unable to create auth handler.";
    return false;
  }
  
  
  
  
  TestCompletionCallback callback;
  scoped_ptr<HttpRequestInfo> request(new HttpRequestInfo());
  request->url = GURL(request_url);
  AuthCredentials credentials(base::ASCIIToUTF16("foo"),
                              base::ASCIIToUTF16("bar"));
  int rv_generate = handler->GenerateAuthToken(
      &credentials, request.get(), callback.callback(), token);
  if (rv_generate != OK) {
    ADD_FAILURE() << "Problems generating auth token";
    return false;
  }
  return true;
}
}  
TEST(HttpAuthHandlerDigestTest, ParseChallenge) {
  static const struct {
    
    const char* challenge;
    
    bool parsed_success;
    
    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
    },
    { 
      "Digest nonce=\"xyz\", realm=ThunderBluff",
      true,
      "ThunderBluff",
      "xyz",
      "",
      "",
      false,
      HttpAuthHandlerDigest::ALGORITHM_UNSPECIFIED,
      HttpAuthHandlerDigest::QOP_UNSPECIFIED
    },
    { 
      
      "Digest nonce=\"xyz\"",
      true,
      "",
      "xyz",
      "",
      "",
      false,
      HttpAuthHandlerDigest::ALGORITHM_UNSPECIFIED,
      HttpAuthHandlerDigest::QOP_UNSPECIFIED
    },
    { 
      "Digest realm=\"\", nonce=\"xyz\"",
      true,
      "",
      "xyz",
      "",
      "",
      false,
      HttpAuthHandlerDigest::ALGORITHM_UNSPECIFIED,
      HttpAuthHandlerDigest::QOP_UNSPECIFIED
    },
    
    
    {
      "Digest nonce=\"xyz\", realm=\"foo-\xE5\"",
      true,
      "foo-\xC3\xA5",
      "xyz",
      "",
      "",
      false,
      HttpAuthHandlerDigest::ALGORITHM_UNSPECIFIED,
      HttpAuthHandlerDigest::QOP_UNSPECIFIED,
    },
    { 
      "Digest realm=\"Thunder Bluff\"",
      false,
      "",
      "",
      "",
      "",
      false,
      HttpAuthHandlerDigest::ALGORITHM_UNSPECIFIED,
      HttpAuthHandlerDigest::QOP_UNSPECIFIED
    },
    { 
      
      "Digest nonce=xyz, realm=\"Thunder Bluff\"",
      true,
      "Thunder Bluff",
      "xyz",
      "",
      "",
      false,
      HttpAuthHandlerDigest::ALGORITHM_UNSPECIFIED,
      HttpAuthHandlerDigest::QOP_UNSPECIFIED
    },
    { 
      "Digest nonce=\"xyz\", realm=\"Thunder Bluff\", foo=\"bar\"",
      true,
      "Thunder Bluff",
      "xyz",
      "",
      "",
      false,
      HttpAuthHandlerDigest::ALGORITHM_UNSPECIFIED,
      HttpAuthHandlerDigest::QOP_UNSPECIFIED
    },
    { 
      "Digest nonce=\"xyz\", algorithm=\"awezum\", realm=\"Thunder\"",
      false,
      
      "",
      "xyz",
      "",
      "",
      false,
      HttpAuthHandlerDigest::ALGORITHM_UNSPECIFIED,
      HttpAuthHandlerDigest::QOP_UNSPECIFIED
    },
    { 
      
      "Digest nonce=\"xyz\", algorithm=\"mD5\", realm=\"Oblivion\"",
      true,
      "Oblivion",
      "xyz",
      "",
      "",
      false,
      HttpAuthHandlerDigest::ALGORITHM_MD5,
      HttpAuthHandlerDigest::QOP_UNSPECIFIED
    },
    { 
      "Digest nonce=\"xyz\", algorithm=\"md5-sess\", realm=\"Oblivion\"",
      true,
      "Oblivion",
      "xyz",
      "",
      "",
      false,
      HttpAuthHandlerDigest::ALGORITHM_MD5_SESS,
      HttpAuthHandlerDigest::QOP_UNSPECIFIED,
    },
    { 
      "Digest nonce=\"xyz\", realm=\"Oblivion\", qop=\"aUth\"",
      true,
      "Oblivion",
      "xyz",
      "",
      "",
      false,
      HttpAuthHandlerDigest::ALGORITHM_UNSPECIFIED,
      HttpAuthHandlerDigest::QOP_AUTH
    },
    { 
      "Digest nonce=\"xyz\", realm=\"Oblivion\", qop=\"auth-int\"",
      true,
      "Oblivion",
      "xyz",
      "",
      "",
      false,
      HttpAuthHandlerDigest::ALGORITHM_UNSPECIFIED,
      HttpAuthHandlerDigest::QOP_UNSPECIFIED
    },
    { 
      "Digest nonce=\"xyz\", realm=\"Oblivion\", qop=\"auth,foo\"",
      true,
      "Oblivion",
      "xyz",
      "",
      "",
      false,
      HttpAuthHandlerDigest::ALGORITHM_UNSPECIFIED,
      HttpAuthHandlerDigest::QOP_AUTH
    },
    { 
      "Digest nonce=\"xyz\", realm=\"Oblivion\", qop=\"auth,auth-int\"",
      true,
      "Oblivion",
      "xyz",
      "",
      "",
      false,
      HttpAuthHandlerDigest::ALGORITHM_UNSPECIFIED,
      HttpAuthHandlerDigest::QOP_AUTH
    },
    { 
      "Digest nonce=\"xyz\", realm=\"Thunder Bluff\", opaque=\"foobar\"",
      true,
      "Thunder Bluff",
      "xyz",
      "",
      "foobar",
      false,
      HttpAuthHandlerDigest::ALGORITHM_UNSPECIFIED,
      HttpAuthHandlerDigest::QOP_UNSPECIFIED
    },
    { 
      
      "Digest nonce=\"xyz\", realm=\"Thunder Bluff\", opaque=foobar",
      true,
      "Thunder Bluff",
      "xyz",
      "",
      "foobar",
      false,
      HttpAuthHandlerDigest::ALGORITHM_UNSPECIFIED,
      HttpAuthHandlerDigest::QOP_UNSPECIFIED
    },
    { 
      "Digest nonce=\"xyz\", realm=\"Thunder Bluff\", "
      "domain=\"http://intranet.example.com/protection\"",
      true,
      "Thunder Bluff",
      "xyz",
      "http://intranet.example.com/protection",
      "",
      false,
      HttpAuthHandlerDigest::ALGORITHM_UNSPECIFIED,
      HttpAuthHandlerDigest::QOP_UNSPECIFIED
    },
    { 
      "Digest nonce=\"xyz\", realm=\"Thunder Bluff\", "
      "domain=\"http://intranet.example.com/protection http://www.google.com\"",
      true,
      "Thunder Bluff",
      "xyz",
      "http://intranet.example.com/protection http://www.google.com",
      "",
      false,
      HttpAuthHandlerDigest::ALGORITHM_UNSPECIFIED,
      HttpAuthHandlerDigest::QOP_UNSPECIFIED
    },
    { 
      "Basic realm=\"foo\"",
      false,
      "",
      "",
      "",
      "",
      false,
      HttpAuthHandlerDigest::ALGORITHM_UNSPECIFIED,
      HttpAuthHandlerDigest::QOP_UNSPECIFIED
    },
  };
  GURL origin("http://www.example.com");
  scoped_ptr<HttpAuthHandlerDigest::Factory> factory(
      new HttpAuthHandlerDigest::Factory());
  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
    scoped_ptr<HttpAuthHandler> handler;
    int rv = factory->CreateAuthHandlerFromString(tests[i].challenge,
                                                  HttpAuth::AUTH_SERVER,
                                                  origin,
                                                  BoundNetLog(),
                                                  &handler);
    if (tests[i].parsed_success) {
      EXPECT_EQ(OK, rv);
    } else {
      EXPECT_NE(OK, rv);
      EXPECT_TRUE(handler.get() == NULL);
      continue;
    }
    ASSERT_TRUE(handler.get() != NULL);
    HttpAuthHandlerDigest* digest =
        static_cast<HttpAuthHandlerDigest*>(handler.get());
    EXPECT_STREQ(tests[i].parsed_realm, digest->realm_.c_str());
    EXPECT_STREQ(tests[i].parsed_nonce, digest->nonce_.c_str());
    EXPECT_STREQ(tests[i].parsed_domain, digest->domain_.c_str());
    EXPECT_STREQ(tests[i].parsed_opaque, digest->opaque_.c_str());
    EXPECT_EQ(tests[i].parsed_stale, digest->stale_);
    EXPECT_EQ(tests[i].parsed_algorithm, digest->algorithm_);
    EXPECT_EQ(tests[i].parsed_qop, digest->qop_);
    EXPECT_TRUE(handler->encrypts_identity());
    EXPECT_FALSE(handler->is_connection_based());
    EXPECT_TRUE(handler->NeedsIdentity());
    EXPECT_FALSE(handler->AllowsDefaultCredentials());
  }
}
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[] = {
    { 
      "GET",
      "/test/drealm1",
      
      "Digest realm=\"DRealm1\", "
      "nonce=\"claGgoRXBAA=7583377687842fdb7b56ba0555d175baa0b800e3\", "
      "algorithm=MD5, qop=\"auth\"",
      "foo", "bar", 
      "082c875dcb2ca740", 
      1, 
      
      "Digest username=\"foo\", realm=\"DRealm1\", "
      "nonce=\"claGgoRXBAA=7583377687842fdb7b56ba0555d175baa0b800e3\", "
      "uri=\"/test/drealm1\", algorithm=MD5, "
      "response=\"bcfaa62f1186a31ff1b474a19a17cf57\", "
      "qop=auth, nc=00000001, cnonce=\"082c875dcb2ca740\""
    },
    { 
      "GET",
      "/test/drealm1/",
      
      "Digest realm=\"DRealm1\", "
      "nonce=\"Ure30oRXBAA=7eca98bbf521ac6642820b11b86bd2d9ed7edc70\", "
      "algorithm=MD5, qop=\"auth\"",
      "foo bar", "", 
      "082c875dcb2ca740", 
      1, 
      
      "Digest username=\"foo bar\", realm=\"DRealm1\", "
      "nonce=\"Ure30oRXBAA=7eca98bbf521ac6642820b11b86bd2d9ed7edc70\", "
      "uri=\"/test/drealm1/\", algorithm=MD5, "
      "response=\"93c9c6d5930af3b0eb26c745e02b04a0\", "
      "qop=auth, nc=00000001, cnonce=\"082c875dcb2ca740\""
    },
    { 
      "GET",
      "/test/drealm1/",
      
      "Digest realm=\"DRealm1\", "
      "nonce=\"7thGplhaBAA=41fb92453c49799cf353c8cd0aabee02d61a98a8\", "
      "algorithm=MD5, qop=\"auth\"",
      "", "pass", 
      "6509bc74daed8263", 
      1, 
      
      "Digest username=\"\", realm=\"DRealm1\", "
      "nonce=\"7thGplhaBAA=41fb92453c49799cf353c8cd0aabee02d61a98a8\", "
      "uri=\"/test/drealm1/\", algorithm=MD5, "
      "response=\"bc597110f41a62d07f8b70b6977fcb61\", "
      "qop=auth, nc=00000001, cnonce=\"6509bc74daed8263\""
    },
    { 
      "GET",
      "/test/drealm1/",
      
      "Digest realm=\"DRealm1\", "
      "nonce=\"s3MzvFhaBAA=4c520af5acd9d8d7ae26947529d18c8eae1e98f4\", "
      "algorithm=MD5, qop=\"auth\"",
      "", "", 
      "1522e61005789929", 
      1, 
      
      "Digest username=\"\", realm=\"DRealm1\", "
      "nonce=\"s3MzvFhaBAA=4c520af5acd9d8d7ae26947529d18c8eae1e98f4\", "
      "uri=\"/test/drealm1/\", algorithm=MD5, "
      "response=\"22cfa2b30cb500a9591c6d55ec5590a8\", "
      "qop=auth, nc=00000001, cnonce=\"1522e61005789929\""
    },
    { 
      "GET",
      "/",
      
      "Digest realm=\"Oblivion\", nonce=\"nonce-value\"",
      "FooBar", "pass", 
      "", 
      1, 
      
      "Digest username=\"FooBar\", realm=\"Oblivion\", "
      "nonce=\"nonce-value\", uri=\"/\", "
      "response=\"f72ff54ebde2f928860f806ec04acd1b\""
    },
    { 
      "GET",
      "/",
      
      "Digest realm=\"Baztastic\", nonce=\"AAAAAAAA\", "
      "algorithm=\"md5-sess\", qop=auth",
      "USER", "123", 
      "15c07961ed8575c4", 
      1, 
      
      "Digest username=\"USER\", realm=\"Baztastic\", "
      "nonce=\"AAAAAAAA\", uri=\"/\", algorithm=MD5-sess, "
      "response=\"cbc1139821ee7192069580570c541a03\", "
      "qop=auth, nc=00000001, cnonce=\"15c07961ed8575c4\""
    }
  };
  GURL origin("http://www.example.com");
  scoped_ptr<HttpAuthHandlerDigest::Factory> factory(
      new HttpAuthHandlerDigest::Factory());
  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
    scoped_ptr<HttpAuthHandler> handler;
    int rv = factory->CreateAuthHandlerFromString(tests[i].challenge,
                                                  HttpAuth::AUTH_SERVER,
                                                  origin,
                                                  BoundNetLog(),
                                                  &handler);
    EXPECT_EQ(OK, rv);
    ASSERT_TRUE(handler != NULL);
    HttpAuthHandlerDigest* digest =
        static_cast<HttpAuthHandlerDigest*>(handler.get());
    std::string creds =
        digest->AssembleCredentials(tests[i].req_method,
                                    tests[i].req_path,
                                    AuthCredentials(
                                        base::ASCIIToUTF16(tests[i].username),
                                        base::ASCIIToUTF16(tests[i].password)),
                                    tests[i].cnonce,
                                    tests[i].nonce_count);
    EXPECT_STREQ(tests[i].expected_creds, creds.c_str());
  }
}
TEST(HttpAuthHandlerDigest, HandleAnotherChallenge) {
  scoped_ptr<HttpAuthHandlerDigest::Factory> factory(
      new HttpAuthHandlerDigest::Factory());
  scoped_ptr<HttpAuthHandler> handler;
  std::string default_challenge =
      "Digest realm=\"Oblivion\", nonce=\"nonce-value\"";
  GURL origin("intranet.google.com");
  int rv = factory->CreateAuthHandlerFromString(
      default_challenge, HttpAuth::AUTH_SERVER, origin, BoundNetLog(),
      &handler);
  EXPECT_EQ(OK, rv);
  ASSERT_TRUE(handler.get() != NULL);
  HttpAuthChallengeTokenizer tok_default(default_challenge.begin(),
                                         default_challenge.end());
  EXPECT_EQ(HttpAuth::AUTHORIZATION_RESULT_REJECT,
            handler->HandleAnotherChallenge(&tok_default));
  std::string stale_challenge = default_challenge + ", stale=true";
  HttpAuthChallengeTokenizer tok_stale(stale_challenge.begin(),
                                       stale_challenge.end());
  EXPECT_EQ(HttpAuth::AUTHORIZATION_RESULT_STALE,
            handler->HandleAnotherChallenge(&tok_stale));
  std::string stale_false_challenge = default_challenge + ", stale=false";
  HttpAuthChallengeTokenizer tok_stale_false(stale_false_challenge.begin(),
                                             stale_false_challenge.end());
  EXPECT_EQ(HttpAuth::AUTHORIZATION_RESULT_REJECT,
            handler->HandleAnotherChallenge(&tok_stale_false));
  std::string realm_change_challenge =
      "Digest realm=\"SomethingElse\", nonce=\"nonce-value2\"";
  HttpAuthChallengeTokenizer tok_realm_change(realm_change_challenge.begin(),
                                              realm_change_challenge.end());
  EXPECT_EQ(HttpAuth::AUTHORIZATION_RESULT_DIFFERENT_REALM,
            handler->HandleAnotherChallenge(&tok_realm_change));
}
TEST(HttpAuthHandlerDigest, RespondToServerChallenge) {
  std::string auth_token;
  EXPECT_TRUE(RespondToChallenge(
      HttpAuth::AUTH_SERVER,
      std::string(),
      "http://www.example.com/path/to/resource",
      kSimpleChallenge,
      &auth_token));
  EXPECT_EQ("Digest username=\"foo\", realm=\"Oblivion\", "
            "nonce=\"nonce-value\", uri=\"/path/to/resource\", "
            "response=\"6779f90bd0d658f937c1af967614fe84\"",
            auth_token);
}
TEST(HttpAuthHandlerDigest, RespondToHttpsServerChallenge) {
  std::string auth_token;
  EXPECT_TRUE(RespondToChallenge(
      HttpAuth::AUTH_SERVER,
      std::string(),
      "https://www.example.com/path/to/resource",
      kSimpleChallenge,
      &auth_token));
  EXPECT_EQ("Digest username=\"foo\", realm=\"Oblivion\", "
            "nonce=\"nonce-value\", uri=\"/path/to/resource\", "
            "response=\"6779f90bd0d658f937c1af967614fe84\"",
            auth_token);
}
TEST(HttpAuthHandlerDigest, RespondToProxyChallenge) {
  std::string auth_token;
  EXPECT_TRUE(RespondToChallenge(
      HttpAuth::AUTH_PROXY,
      "http://proxy.intranet.corp.com:3128",
      "http://www.example.com/path/to/resource",
      kSimpleChallenge,
      &auth_token));
  EXPECT_EQ("Digest username=\"foo\", realm=\"Oblivion\", "
            "nonce=\"nonce-value\", uri=\"/path/to/resource\", "
            "response=\"6779f90bd0d658f937c1af967614fe84\"",
            auth_token);
}
TEST(HttpAuthHandlerDigest, RespondToProxyChallengeHttps) {
  std::string auth_token;
  EXPECT_TRUE(RespondToChallenge(
      HttpAuth::AUTH_PROXY,
      "http://proxy.intranet.corp.com:3128",
      "https://www.example.com/path/to/resource",
      kSimpleChallenge,
      &auth_token));
  EXPECT_EQ("Digest username=\"foo\", realm=\"Oblivion\", "
            "nonce=\"nonce-value\", uri=\"www.example.com:443\", "
            "response=\"3270da8467afbe9ddf2334a48d46e9b9\"",
            auth_token);
}
TEST(HttpAuthHandlerDigest, RespondToProxyChallengeWs) {
  std::string auth_token;
  EXPECT_TRUE(RespondToChallenge(
      HttpAuth::AUTH_PROXY,
      "http://proxy.intranet.corp.com:3128",
      "ws://www.example.com/echo",
      kSimpleChallenge,
      &auth_token));
  EXPECT_EQ("Digest username=\"foo\", realm=\"Oblivion\", "
            "nonce=\"nonce-value\", uri=\"www.example.com:80\", "
            "response=\"aa1df184f68d5b6ab9d9aa4f88e41b4c\"",
            auth_token);
}
TEST(HttpAuthHandlerDigest, RespondToProxyChallengeWss) {
  std::string auth_token;
  EXPECT_TRUE(RespondToChallenge(
      HttpAuth::AUTH_PROXY,
      "http://proxy.intranet.corp.com:3128",
      "wss://www.example.com/echo",
      kSimpleChallenge,
      &auth_token));
  EXPECT_EQ("Digest username=\"foo\", realm=\"Oblivion\", "
            "nonce=\"nonce-value\", uri=\"www.example.com:443\", "
            "response=\"3270da8467afbe9ddf2334a48d46e9b9\"",
            auth_token);
}
TEST(HttpAuthHandlerDigest, RespondToChallengeAuthQop) {
  std::string auth_token;
  EXPECT_TRUE(RespondToChallenge(
      HttpAuth::AUTH_SERVER,
      std::string(),
      "http://www.example.com/path/to/resource",
      "Digest realm=\"Oblivion\", nonce=\"nonce-value\", qop=\"auth\"",
      &auth_token));
  EXPECT_EQ("Digest username=\"foo\", realm=\"Oblivion\", "
            "nonce=\"nonce-value\", uri=\"/path/to/resource\", "
            "response=\"5b1459beda5cee30d6ff9e970a69c0ea\", "
            "qop=auth, nc=00000001, cnonce=\"client_nonce\"",
            auth_token);
}
TEST(HttpAuthHandlerDigest, RespondToChallengeOpaque) {
  std::string auth_token;
  EXPECT_TRUE(RespondToChallenge(
      HttpAuth::AUTH_SERVER,
      std::string(),
      "http://www.example.com/path/to/resource",
      "Digest realm=\"Oblivion\", nonce=\"nonce-value\", "
      "qop=\"auth\", opaque=\"opaque text\"",
      &auth_token));
  EXPECT_EQ("Digest username=\"foo\", realm=\"Oblivion\", "
            "nonce=\"nonce-value\", uri=\"/path/to/resource\", "
            "response=\"5b1459beda5cee30d6ff9e970a69c0ea\", "
            "opaque=\"opaque text\", "
            "qop=auth, nc=00000001, cnonce=\"client_nonce\"",
            auth_token);
}
}