Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(269)

Unified Diff: net/http/http_auth_handler_digest.cc

Issue 992733002: Remove //net (except for Android test stuff) and sdch (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « net/http/http_auth_handler_digest.h ('k') | net/http/http_auth_handler_digest_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: net/http/http_auth_handler_digest.cc
diff --git a/net/http/http_auth_handler_digest.cc b/net/http/http_auth_handler_digest.cc
deleted file mode 100644
index 7dee081ddbe9ed7de7ea60ac6a6fa3a64419f2f9..0000000000000000000000000000000000000000
--- a/net/http/http_auth_handler_digest.cc
+++ /dev/null
@@ -1,383 +0,0 @@
-// Copyright (c) 2011 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 "net/http/http_auth_handler_digest.h"
-
-#include <string>
-
-#include "base/logging.h"
-#include "base/md5.h"
-#include "base/rand_util.h"
-#include "base/strings/string_util.h"
-#include "base/strings/stringprintf.h"
-#include "base/strings/utf_string_conversions.h"
-#include "net/base/net_errors.h"
-#include "net/base/net_string_util.h"
-#include "net/base/net_util.h"
-#include "net/http/http_auth.h"
-#include "net/http/http_auth_challenge_tokenizer.h"
-#include "net/http/http_request_info.h"
-#include "net/http/http_util.h"
-#include "url/gurl.h"
-
-namespace net {
-
-// Digest authentication is specified in RFC 2617.
-// The expanded derivations are listed in the tables below.
-
-//==========+==========+==========================================+
-// qop |algorithm | response |
-//==========+==========+==========================================+
-// ? | ?, md5, | MD5(MD5(A1):nonce:MD5(A2)) |
-// | md5-sess | |
-//--------- +----------+------------------------------------------+
-// auth, | ?, md5, | MD5(MD5(A1):nonce:nc:cnonce:qop:MD5(A2)) |
-// auth-int | md5-sess | |
-//==========+==========+==========================================+
-// qop |algorithm | A1 |
-//==========+==========+==========================================+
-// | ?, md5 | user:realm:password |
-//----------+----------+------------------------------------------+
-// | md5-sess | MD5(user:realm:password):nonce:cnonce |
-//==========+==========+==========================================+
-// qop |algorithm | A2 |
-//==========+==========+==========================================+
-// ?, auth | | req-method:req-uri |
-//----------+----------+------------------------------------------+
-// auth-int | | req-method:req-uri:MD5(req-entity-body) |
-//=====================+==========================================+
-
-HttpAuthHandlerDigest::NonceGenerator::NonceGenerator() {
-}
-
-HttpAuthHandlerDigest::NonceGenerator::~NonceGenerator() {
-}
-
-HttpAuthHandlerDigest::DynamicNonceGenerator::DynamicNonceGenerator() {
-}
-
-std::string HttpAuthHandlerDigest::DynamicNonceGenerator::GenerateNonce()
- const {
- // This is how mozilla generates their cnonce -- a 16 digit hex string.
- static const char domain[] = "0123456789abcdef";
- std::string cnonce;
- cnonce.reserve(16);
- for (int i = 0; i < 16; ++i)
- cnonce.push_back(domain[base::RandInt(0, 15)]);
- return cnonce;
-}
-
-HttpAuthHandlerDigest::FixedNonceGenerator::FixedNonceGenerator(
- const std::string& nonce)
- : nonce_(nonce) {
-}
-
-std::string HttpAuthHandlerDigest::FixedNonceGenerator::GenerateNonce() const {
- return nonce_;
-}
-
-HttpAuthHandlerDigest::Factory::Factory()
- : nonce_generator_(new DynamicNonceGenerator()) {
-}
-
-HttpAuthHandlerDigest::Factory::~Factory() {
-}
-
-void HttpAuthHandlerDigest::Factory::set_nonce_generator(
- const NonceGenerator* nonce_generator) {
- nonce_generator_.reset(nonce_generator);
-}
-
-int HttpAuthHandlerDigest::Factory::CreateAuthHandler(
- HttpAuthChallengeTokenizer* challenge,
- HttpAuth::Target target,
- const GURL& origin,
- CreateReason reason,
- int digest_nonce_count,
- const BoundNetLog& net_log,
- scoped_ptr<HttpAuthHandler>* handler) {
- // TODO(cbentzel): Move towards model of parsing in the factory
- // method and only constructing when valid.
- scoped_ptr<HttpAuthHandler> tmp_handler(
- new HttpAuthHandlerDigest(digest_nonce_count, nonce_generator_.get()));
- if (!tmp_handler->InitFromChallenge(challenge, target, origin, net_log))
- return ERR_INVALID_RESPONSE;
- handler->swap(tmp_handler);
- return OK;
-}
-
-HttpAuth::AuthorizationResult HttpAuthHandlerDigest::HandleAnotherChallenge(
- HttpAuthChallengeTokenizer* challenge) {
- // Even though Digest is not connection based, a "second round" is parsed
- // to differentiate between stale and rejected responses.
- // Note that the state of the current handler is not mutated - this way if
- // there is a rejection the realm hasn't changed.
- if (!LowerCaseEqualsASCII(challenge->scheme(), "digest"))
- return HttpAuth::AUTHORIZATION_RESULT_INVALID;
-
- HttpUtil::NameValuePairsIterator parameters = challenge->param_pairs();
-
- // Try to find the "stale" value, and also keep track of the realm
- // for the new challenge.
- std::string original_realm;
- while (parameters.GetNext()) {
- if (LowerCaseEqualsASCII(parameters.name(), "stale")) {
- if (LowerCaseEqualsASCII(parameters.value(), "true"))
- return HttpAuth::AUTHORIZATION_RESULT_STALE;
- } else if (LowerCaseEqualsASCII(parameters.name(), "realm")) {
- original_realm = parameters.value();
- }
- }
- return (original_realm_ != original_realm) ?
- HttpAuth::AUTHORIZATION_RESULT_DIFFERENT_REALM :
- HttpAuth::AUTHORIZATION_RESULT_REJECT;
-}
-
-bool HttpAuthHandlerDigest::Init(HttpAuthChallengeTokenizer* challenge) {
- return ParseChallenge(challenge);
-}
-
-int HttpAuthHandlerDigest::GenerateAuthTokenImpl(
- const AuthCredentials* credentials, const HttpRequestInfo* request,
- const CompletionCallback& callback, std::string* auth_token) {
- // Generate a random client nonce.
- std::string cnonce = nonce_generator_->GenerateNonce();
-
- // Extract the request method and path -- the meaning of 'path' is overloaded
- // in certain cases, to be a hostname.
- std::string method;
- std::string path;
- GetRequestMethodAndPath(request, &method, &path);
-
- *auth_token = AssembleCredentials(method, path, *credentials,
- cnonce, nonce_count_);
- return OK;
-}
-
-HttpAuthHandlerDigest::HttpAuthHandlerDigest(
- int nonce_count, const NonceGenerator* nonce_generator)
- : stale_(false),
- algorithm_(ALGORITHM_UNSPECIFIED),
- qop_(QOP_UNSPECIFIED),
- nonce_count_(nonce_count),
- nonce_generator_(nonce_generator) {
- DCHECK(nonce_generator_);
-}
-
-HttpAuthHandlerDigest::~HttpAuthHandlerDigest() {
-}
-
-// The digest challenge header looks like:
-// WWW-Authenticate: Digest
-// [realm="<realm-value>"]
-// nonce="<nonce-value>"
-// [domain="<list-of-URIs>"]
-// [opaque="<opaque-token-value>"]
-// [stale="<true-or-false>"]
-// [algorithm="<digest-algorithm>"]
-// [qop="<list-of-qop-values>"]
-// [<extension-directive>]
-//
-// Note that according to RFC 2617 (section 1.2) the realm is required.
-// However we allow it to be omitted, in which case it will default to the
-// empty string.
-//
-// This allowance is for better compatibility with webservers that fail to
-// send the realm (See http://crbug.com/20984 for an instance where a
-// webserver was not sending the realm with a BASIC challenge).
-bool HttpAuthHandlerDigest::ParseChallenge(
- HttpAuthChallengeTokenizer* challenge) {
- auth_scheme_ = HttpAuth::AUTH_SCHEME_DIGEST;
- score_ = 2;
- properties_ = ENCRYPTS_IDENTITY;
-
- // Initialize to defaults.
- stale_ = false;
- algorithm_ = ALGORITHM_UNSPECIFIED;
- qop_ = QOP_UNSPECIFIED;
- realm_ = original_realm_ = nonce_ = domain_ = opaque_ = std::string();
-
- // FAIL -- Couldn't match auth-scheme.
- if (!LowerCaseEqualsASCII(challenge->scheme(), "digest"))
- return false;
-
- HttpUtil::NameValuePairsIterator parameters = challenge->param_pairs();
-
- // Loop through all the properties.
- while (parameters.GetNext()) {
- // FAIL -- couldn't parse a property.
- if (!ParseChallengeProperty(parameters.name(),
- parameters.value()))
- return false;
- }
-
- // Check if tokenizer failed.
- if (!parameters.valid())
- return false;
-
- // Check that a minimum set of properties were provided.
- if (nonce_.empty())
- return false;
-
- return true;
-}
-
-bool HttpAuthHandlerDigest::ParseChallengeProperty(const std::string& name,
- const std::string& value) {
- if (LowerCaseEqualsASCII(name, "realm")) {
- std::string realm;
- if (!net::ConvertToUtf8AndNormalize(value, kCharsetLatin1, &realm))
- return false;
- realm_ = realm;
- original_realm_ = value;
- } else if (LowerCaseEqualsASCII(name, "nonce")) {
- nonce_ = value;
- } else if (LowerCaseEqualsASCII(name, "domain")) {
- domain_ = value;
- } else if (LowerCaseEqualsASCII(name, "opaque")) {
- opaque_ = value;
- } else if (LowerCaseEqualsASCII(name, "stale")) {
- // Parse the stale boolean.
- stale_ = LowerCaseEqualsASCII(value, "true");
- } else if (LowerCaseEqualsASCII(name, "algorithm")) {
- // Parse the algorithm.
- if (LowerCaseEqualsASCII(value, "md5")) {
- algorithm_ = ALGORITHM_MD5;
- } else if (LowerCaseEqualsASCII(value, "md5-sess")) {
- algorithm_ = ALGORITHM_MD5_SESS;
- } else {
- DVLOG(1) << "Unknown value of algorithm";
- return false; // FAIL -- unsupported value of algorithm.
- }
- } else if (LowerCaseEqualsASCII(name, "qop")) {
- // Parse the comma separated list of qops.
- // auth is the only supported qop, and all other values are ignored.
- HttpUtil::ValuesIterator qop_values(value.begin(), value.end(), ',');
- qop_ = QOP_UNSPECIFIED;
- while (qop_values.GetNext()) {
- if (LowerCaseEqualsASCII(qop_values.value(), "auth")) {
- qop_ = QOP_AUTH;
- break;
- }
- }
- } else {
- DVLOG(1) << "Skipping unrecognized digest property";
- // TODO(eroman): perhaps we should fail instead of silently skipping?
- }
- return true;
-}
-
-// static
-std::string HttpAuthHandlerDigest::QopToString(QualityOfProtection qop) {
- switch (qop) {
- case QOP_UNSPECIFIED:
- return std::string();
- case QOP_AUTH:
- return "auth";
- default:
- NOTREACHED();
- return std::string();
- }
-}
-
-// static
-std::string HttpAuthHandlerDigest::AlgorithmToString(
- DigestAlgorithm algorithm) {
- switch (algorithm) {
- case ALGORITHM_UNSPECIFIED:
- return std::string();
- case ALGORITHM_MD5:
- return "MD5";
- case ALGORITHM_MD5_SESS:
- return "MD5-sess";
- default:
- NOTREACHED();
- return std::string();
- }
-}
-
-void HttpAuthHandlerDigest::GetRequestMethodAndPath(
- const HttpRequestInfo* request,
- std::string* method,
- std::string* path) const {
- DCHECK(request);
-
- const GURL& url = request->url;
-
- if (target_ == HttpAuth::AUTH_PROXY &&
- (url.SchemeIs("https") || url.SchemeIsWSOrWSS())) {
- *method = "CONNECT";
- *path = GetHostAndPort(url);
- } else {
- *method = request->method;
- *path = HttpUtil::PathForRequest(url);
- }
-}
-
-std::string HttpAuthHandlerDigest::AssembleResponseDigest(
- const std::string& method,
- const std::string& path,
- const AuthCredentials& credentials,
- const std::string& cnonce,
- const std::string& nc) const {
- // ha1 = MD5(A1)
- // TODO(eroman): is this the right encoding?
- std::string ha1 = base::MD5String(base::UTF16ToUTF8(credentials.username()) +
- ":" + original_realm_ + ":" +
- base::UTF16ToUTF8(credentials.password()));
- if (algorithm_ == HttpAuthHandlerDigest::ALGORITHM_MD5_SESS)
- ha1 = base::MD5String(ha1 + ":" + nonce_ + ":" + cnonce);
-
- // ha2 = MD5(A2)
- // TODO(eroman): need to add MD5(req-entity-body) for qop=auth-int.
- std::string ha2 = base::MD5String(method + ":" + path);
-
- std::string nc_part;
- if (qop_ != HttpAuthHandlerDigest::QOP_UNSPECIFIED) {
- nc_part = nc + ":" + cnonce + ":" + QopToString(qop_) + ":";
- }
-
- return base::MD5String(ha1 + ":" + nonce_ + ":" + nc_part + ha2);
-}
-
-std::string HttpAuthHandlerDigest::AssembleCredentials(
- const std::string& method,
- const std::string& path,
- const AuthCredentials& credentials,
- const std::string& cnonce,
- int nonce_count) const {
- // the nonce-count is an 8 digit hex string.
- std::string nc = base::StringPrintf("%08x", nonce_count);
-
- // TODO(eroman): is this the right encoding?
- std::string authorization = (std::string("Digest username=") +
- HttpUtil::Quote(
- base::UTF16ToUTF8(credentials.username())));
- authorization += ", realm=" + HttpUtil::Quote(original_realm_);
- authorization += ", nonce=" + HttpUtil::Quote(nonce_);
- authorization += ", uri=" + HttpUtil::Quote(path);
-
- if (algorithm_ != ALGORITHM_UNSPECIFIED) {
- authorization += ", algorithm=" + AlgorithmToString(algorithm_);
- }
- std::string response = AssembleResponseDigest(method, path, credentials,
- cnonce, nc);
- // No need to call HttpUtil::Quote() as the response digest cannot contain
- // any characters needing to be escaped.
- authorization += ", response=\"" + response + "\"";
-
- if (!opaque_.empty()) {
- authorization += ", opaque=" + HttpUtil::Quote(opaque_);
- }
- if (qop_ != QOP_UNSPECIFIED) {
- // TODO(eroman): Supposedly IIS server requires quotes surrounding qop.
- authorization += ", qop=" + QopToString(qop_);
- authorization += ", nc=" + nc;
- authorization += ", cnonce=" + HttpUtil::Quote(cnonce);
- }
-
- return authorization;
-}
-
-} // namespace net
« no previous file with comments | « net/http/http_auth_handler_digest.h ('k') | net/http/http_auth_handler_digest_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698