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 |
index 7c5526c772fe079f77dab601538ee53bfae6262f..e8cb819cef70ec390e5aebc5a3fefd7187d9eeb9 100644 |
--- a/net/http/http_auth_handler_digest.cc |
+++ b/net/http/http_auth_handler_digest.cc |
@@ -74,46 +74,60 @@ std::string HttpAuthHandlerDigest::FixedNonceGenerator::GenerateNonce() const { |
return nonce_; |
} |
-// static |
-std::string HttpAuthHandlerDigest::QopToString(QualityOfProtection qop) { |
- switch (qop) { |
- case QOP_UNSPECIFIED: |
- return ""; |
- case QOP_AUTH: |
- return "auth"; |
- default: |
- NOTREACHED(); |
- return ""; |
- } |
+HttpAuthHandlerDigest::Factory::Factory() |
+ : nonce_generator_(new DynamicNonceGenerator()) { |
} |
-// static |
-std::string HttpAuthHandlerDigest::AlgorithmToString( |
- DigestAlgorithm algorithm) { |
- switch (algorithm) { |
- case ALGORITHM_UNSPECIFIED: |
- return ""; |
- case ALGORITHM_MD5: |
- return "MD5"; |
- case ALGORITHM_MD5_SESS: |
- return "MD5-sess"; |
- default: |
- NOTREACHED(); |
- return ""; |
- } |
+HttpAuthHandlerDigest::Factory::~Factory() { |
} |
-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_); |
+void HttpAuthHandlerDigest::Factory::set_nonce_generator( |
+ const NonceGenerator* nonce_generator) { |
+ nonce_generator_.reset(nonce_generator); |
} |
-HttpAuthHandlerDigest::~HttpAuthHandlerDigest() { |
+int HttpAuthHandlerDigest::Factory::CreateAuthHandler( |
+ HttpAuth::ChallengeTokenizer* 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( |
+ HttpAuth::ChallengeTokenizer* 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. |
+ while (parameters.GetNext()) { |
+ if (!LowerCaseEqualsASCII(parameters.name(), "stale")) |
+ continue; |
+ if (LowerCaseEqualsASCII(parameters.value(), "true")) |
+ return HttpAuth::AUTHORIZATION_RESULT_STALE; |
+ } |
+ |
+ return HttpAuth::AUTHORIZATION_RESULT_REJECT; |
+} |
+ |
+bool HttpAuthHandlerDigest::Init(HttpAuth::ChallengeTokenizer* challenge) { |
+ return ParseChallenge(challenge); |
} |
int HttpAuthHandlerDigest::GenerateAuthTokenImpl( |
@@ -138,112 +152,17 @@ int HttpAuthHandlerDigest::GenerateAuthTokenImpl( |
return OK; |
} |
-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")) { |
- *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 string16& username, |
- const string16& password, |
- const std::string& cnonce, |
- const std::string& nc) const { |
- // ha1 = MD5(A1) |
- // TODO(eroman): is this the right encoding? |
- std::string ha1 = MD5String(UTF16ToUTF8(username) + ":" + realm_ + ":" + |
- UTF16ToUTF8(password)); |
- if (algorithm_ == HttpAuthHandlerDigest::ALGORITHM_MD5_SESS) |
- ha1 = MD5String(ha1 + ":" + nonce_ + ":" + cnonce); |
- |
- // ha2 = MD5(A2) |
- // TODO(eroman): need to add MD5(req-entity-body) for qop=auth-int. |
- std::string ha2 = MD5String(method + ":" + path); |
- |
- std::string nc_part; |
- if (qop_ != HttpAuthHandlerDigest::QOP_UNSPECIFIED) { |
- nc_part = nc + ":" + cnonce + ":" + QopToString(qop_) + ":"; |
- } |
- |
- return MD5String(ha1 + ":" + nonce_ + ":" + nc_part + ha2); |
-} |
- |
-std::string HttpAuthHandlerDigest::AssembleCredentials( |
- const std::string& method, |
- const std::string& path, |
- const string16& username, |
- const string16& password, |
- 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(UTF16ToUTF8(username))); |
- authorization += ", realm=" + HttpUtil::Quote(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, username, |
- password, 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; |
-} |
- |
-bool HttpAuthHandlerDigest::Init(HttpAuth::ChallengeTokenizer* challenge) { |
- return ParseChallenge(challenge); |
+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_); |
} |
-HttpAuth::AuthorizationResult HttpAuthHandlerDigest::HandleAnotherChallenge( |
- HttpAuth::ChallengeTokenizer* 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. |
- while (parameters.GetNext()) { |
- if (!LowerCaseEqualsASCII(parameters.name(), "stale")) |
- continue; |
- if (LowerCaseEqualsASCII(parameters.value(), "true")) |
- return HttpAuth::AUTHORIZATION_RESULT_STALE; |
- } |
- |
- return HttpAuth::AUTHORIZATION_RESULT_REJECT; |
+HttpAuthHandlerDigest::~HttpAuthHandlerDigest() { |
} |
// The digest challenge header looks like: |
@@ -342,34 +261,115 @@ bool HttpAuthHandlerDigest::ParseChallengeProperty(const std::string& name, |
return true; |
} |
-HttpAuthHandlerDigest::Factory::Factory() |
- : nonce_generator_(new DynamicNonceGenerator()) { |
+// static |
+std::string HttpAuthHandlerDigest::QopToString(QualityOfProtection qop) { |
+ switch (qop) { |
+ case QOP_UNSPECIFIED: |
+ return ""; |
+ case QOP_AUTH: |
+ return "auth"; |
+ default: |
+ NOTREACHED(); |
+ return ""; |
+ } |
} |
-HttpAuthHandlerDigest::Factory::~Factory() { |
+// static |
+std::string HttpAuthHandlerDigest::AlgorithmToString( |
+ DigestAlgorithm algorithm) { |
+ switch (algorithm) { |
+ case ALGORITHM_UNSPECIFIED: |
+ return ""; |
+ case ALGORITHM_MD5: |
+ return "MD5"; |
+ case ALGORITHM_MD5_SESS: |
+ return "MD5-sess"; |
+ default: |
+ NOTREACHED(); |
+ return ""; |
+ } |
} |
-void HttpAuthHandlerDigest::Factory::set_nonce_generator( |
- const NonceGenerator* nonce_generator) { |
- nonce_generator_.reset(nonce_generator); |
+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")) { |
+ *method = "CONNECT"; |
+ *path = GetHostAndPort(url); |
+ } else { |
+ *method = request->method; |
+ *path = HttpUtil::PathForRequest(url); |
+ } |
} |
-int HttpAuthHandlerDigest::Factory::CreateAuthHandler( |
- HttpAuth::ChallengeTokenizer* 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; |
+std::string HttpAuthHandlerDigest::AssembleResponseDigest( |
+ const std::string& method, |
+ const std::string& path, |
+ const string16& username, |
+ const string16& password, |
+ const std::string& cnonce, |
+ const std::string& nc) const { |
+ // ha1 = MD5(A1) |
+ // TODO(eroman): is this the right encoding? |
+ std::string ha1 = MD5String(UTF16ToUTF8(username) + ":" + realm_ + ":" + |
+ UTF16ToUTF8(password)); |
+ if (algorithm_ == HttpAuthHandlerDigest::ALGORITHM_MD5_SESS) |
+ ha1 = MD5String(ha1 + ":" + nonce_ + ":" + cnonce); |
+ |
+ // ha2 = MD5(A2) |
+ // TODO(eroman): need to add MD5(req-entity-body) for qop=auth-int. |
+ std::string ha2 = MD5String(method + ":" + path); |
+ |
+ std::string nc_part; |
+ if (qop_ != HttpAuthHandlerDigest::QOP_UNSPECIFIED) { |
+ nc_part = nc + ":" + cnonce + ":" + QopToString(qop_) + ":"; |
+ } |
+ |
+ return MD5String(ha1 + ":" + nonce_ + ":" + nc_part + ha2); |
+} |
+ |
+std::string HttpAuthHandlerDigest::AssembleCredentials( |
+ const std::string& method, |
+ const std::string& path, |
+ const string16& username, |
+ const string16& password, |
+ 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(UTF16ToUTF8(username))); |
+ authorization += ", realm=" + HttpUtil::Quote(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, username, |
+ password, 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 |