Commit 890d67c0 authored by Asanka Herath's avatar Asanka Herath Committed by Commit Bot

[net/auth] Reduce use of raw scheme names in the authentication stack.

Shuttling around authentication scheme names as strings carries with it
the overhead of canonicalization everywhere they are used. Scheme names
are considered to be case-insensitive, so this means a lot of
invocations of base::ToLowerASCII() and others.

Instead, this CL introduces two changes:

  1. HttpAuthChallengeTokenizer::scheme() is renamed to auth_scheme() to
     visually disambiguate it from URL schemes.

  2. auth_scheme() always returns the lowercase string.

  3. Multi-round authentication header parse uses HttpAuth::Scheme
     enumeration instead of a string.

  4. HttpAuthGSSAPI doesn't take an authentication scheme as a string
     anymore.  It doesn't make sense to use any scheme other than
     "negotiate" with this class

Bug: 927182
Change-Id: I501af8e978857302d3893f1b7fb2dcd23d2b7e36
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1907418
Commit-Queue: Asanka Herath <asanka@chromium.org>
Reviewed-by: default avatarMatt Menke <mmenke@chromium.org>
Cr-Commit-Position: refs/heads/master@{#715196}
parent 5b86f1f4
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include "base/threading/thread_task_runner_handle.h" #include "base/threading/thread_task_runner_handle.h"
#include "net/base/auth.h" #include "net/base/auth.h"
#include "net/base/net_errors.h" #include "net/base/net_errors.h"
#include "net/http/http_auth.h"
#include "net/http/http_auth_challenge_tokenizer.h" #include "net/http/http_auth_challenge_tokenizer.h"
#include "net/http/http_auth_multi_round_parse.h" #include "net/http/http_auth_multi_round_parse.h"
#include "net/http/http_auth_preferences.h" #include "net/http/http_auth_preferences.h"
...@@ -86,10 +87,11 @@ HttpAuth::AuthorizationResult HttpAuthNegotiateAndroid::ParseChallenge( ...@@ -86,10 +87,11 @@ HttpAuth::AuthorizationResult HttpAuthNegotiateAndroid::ParseChallenge(
net::HttpAuthChallengeTokenizer* tok) { net::HttpAuthChallengeTokenizer* tok) {
if (first_challenge_) { if (first_challenge_) {
first_challenge_ = false; first_challenge_ = false;
return net::ParseFirstRoundChallenge("negotiate", tok); return net::ParseFirstRoundChallenge(HttpAuth::AUTH_SCHEME_NEGOTIATE, tok);
} }
std::string decoded_auth_token; std::string decoded_auth_token;
return net::ParseLaterRoundChallenge("negotiate", tok, &server_auth_token_, return net::ParseLaterRoundChallenge(HttpAuth::AUTH_SCHEME_NEGOTIATE, tok,
&server_auth_token_,
&decoded_auth_token); &decoded_auth_token);
} }
......
...@@ -81,7 +81,7 @@ HttpAuth::AuthorizationResult HttpAuth::HandleChallengeResponse( ...@@ -81,7 +81,7 @@ HttpAuth::AuthorizationResult HttpAuth::HandleChallengeResponse(
HttpAuth::Scheme current_scheme = handler->auth_scheme(); HttpAuth::Scheme current_scheme = handler->auth_scheme();
if (disabled_schemes.find(current_scheme) != disabled_schemes.end()) if (disabled_schemes.find(current_scheme) != disabled_schemes.end())
return HttpAuth::AUTHORIZATION_RESULT_REJECT; return HttpAuth::AUTHORIZATION_RESULT_REJECT;
std::string current_scheme_name = SchemeToString(current_scheme); const char* current_scheme_name = SchemeToString(current_scheme);
const std::string header_name = GetChallengeHeaderName(target); const std::string header_name = GetChallengeHeaderName(target);
size_t iter = 0; size_t iter = 0;
std::string challenge; std::string challenge;
...@@ -90,8 +90,7 @@ HttpAuth::AuthorizationResult HttpAuth::HandleChallengeResponse( ...@@ -90,8 +90,7 @@ HttpAuth::AuthorizationResult HttpAuth::HandleChallengeResponse(
while (response_headers.EnumerateHeader(&iter, header_name, &challenge)) { while (response_headers.EnumerateHeader(&iter, header_name, &challenge)) {
HttpAuthChallengeTokenizer challenge_tokens(challenge.begin(), HttpAuthChallengeTokenizer challenge_tokens(challenge.begin(),
challenge.end()); challenge.end());
if (!base::LowerCaseEqualsASCII(challenge_tokens.scheme(), if (challenge_tokens.auth_scheme() != current_scheme_name)
current_scheme_name))
continue; continue;
authorization_result = handler->HandleAnotherChallenge(&challenge_tokens); authorization_result = handler->HandleAnotherChallenge(&challenge_tokens);
if (authorization_result != HttpAuth::AUTHORIZATION_RESULT_INVALID) { if (authorization_result != HttpAuth::AUTHORIZATION_RESULT_INVALID) {
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
#include "net/http/http_auth_challenge_tokenizer.h" #include "net/http/http_auth_challenge_tokenizer.h"
#include "base/strings/string_piece.h"
#include "base/strings/string_tokenizer.h" #include "base/strings/string_tokenizer.h"
namespace net { namespace net {
...@@ -13,8 +14,6 @@ HttpAuthChallengeTokenizer::HttpAuthChallengeTokenizer( ...@@ -13,8 +14,6 @@ HttpAuthChallengeTokenizer::HttpAuthChallengeTokenizer(
std::string::const_iterator end) std::string::const_iterator end)
: begin_(begin), : begin_(begin),
end_(end), end_(end),
scheme_begin_(begin),
scheme_end_(begin),
params_begin_(end), params_begin_(end),
params_end_(end) { params_end_(end) {
Init(begin, end); Init(begin, end);
...@@ -52,10 +51,10 @@ void HttpAuthChallengeTokenizer::Init(std::string::const_iterator begin, ...@@ -52,10 +51,10 @@ void HttpAuthChallengeTokenizer::Init(std::string::const_iterator begin,
} }
// Save the scheme's position. // Save the scheme's position.
scheme_begin_ = tok.token_begin(); lower_case_scheme_ =
scheme_end_ = tok.token_end(); base::ToLowerASCII(base::StringPiece(tok.token_begin(), tok.token_end()));
params_begin_ = scheme_end_; params_begin_ = tok.token_end();
params_end_ = end; params_end_ = end;
HttpUtil::TrimLWS(&params_begin_, &params_end_); HttpUtil::TrimLWS(&params_begin_, &params_end_);
} }
......
...@@ -32,10 +32,9 @@ class NET_EXPORT_PRIVATE HttpAuthChallengeTokenizer { ...@@ -32,10 +32,9 @@ class NET_EXPORT_PRIVATE HttpAuthChallengeTokenizer {
return std::string(begin_, end_); return std::string(begin_, end_);
} }
// Get the auth scheme of the challenge. // Get the authenthication scheme of the challenge. The returned scheme is
base::StringPiece scheme() const { // always lowercase.
return base::StringPiece(scheme_begin_, scheme_end_); const std::string& auth_scheme() const { return lower_case_scheme_; }
}
std::string::const_iterator params_begin() const { return params_begin_; } std::string::const_iterator params_begin() const { return params_begin_; }
std::string::const_iterator params_end() const { return params_end_; } std::string::const_iterator params_end() const { return params_end_; }
...@@ -49,11 +48,10 @@ class NET_EXPORT_PRIVATE HttpAuthChallengeTokenizer { ...@@ -49,11 +48,10 @@ class NET_EXPORT_PRIVATE HttpAuthChallengeTokenizer {
std::string::const_iterator begin_; std::string::const_iterator begin_;
std::string::const_iterator end_; std::string::const_iterator end_;
std::string::const_iterator scheme_begin_;
std::string::const_iterator scheme_end_;
std::string::const_iterator params_begin_; std::string::const_iterator params_begin_;
std::string::const_iterator params_end_; std::string::const_iterator params_end_;
std::string lower_case_scheme_;
}; };
} // namespace net } // namespace net
......
...@@ -14,7 +14,7 @@ TEST(HttpAuthChallengeTokenizerTest, Basic) { ...@@ -14,7 +14,7 @@ TEST(HttpAuthChallengeTokenizerTest, Basic) {
HttpUtil::NameValuePairsIterator parameters = challenge.param_pairs(); HttpUtil::NameValuePairsIterator parameters = challenge.param_pairs();
EXPECT_TRUE(parameters.valid()); EXPECT_TRUE(parameters.valid());
EXPECT_EQ(std::string("Basic"), challenge.scheme()); EXPECT_EQ(std::string("basic"), challenge.auth_scheme());
EXPECT_TRUE(parameters.GetNext()); EXPECT_TRUE(parameters.GetNext());
EXPECT_TRUE(parameters.valid()); EXPECT_TRUE(parameters.valid());
EXPECT_EQ(std::string("realm"), parameters.name()); EXPECT_EQ(std::string("realm"), parameters.name());
...@@ -30,7 +30,7 @@ TEST(HttpAuthChallengeTokenizerTest, NoQuotes) { ...@@ -30,7 +30,7 @@ TEST(HttpAuthChallengeTokenizerTest, NoQuotes) {
HttpUtil::NameValuePairsIterator parameters = challenge.param_pairs(); HttpUtil::NameValuePairsIterator parameters = challenge.param_pairs();
EXPECT_TRUE(parameters.valid()); EXPECT_TRUE(parameters.valid());
EXPECT_EQ(std::string("Basic"), challenge.scheme()); EXPECT_EQ(std::string("basic"), challenge.auth_scheme());
EXPECT_TRUE(parameters.GetNext()); EXPECT_TRUE(parameters.GetNext());
EXPECT_TRUE(parameters.valid()); EXPECT_TRUE(parameters.valid());
EXPECT_EQ(std::string("realm"), parameters.name()); EXPECT_EQ(std::string("realm"), parameters.name());
...@@ -46,7 +46,7 @@ TEST(HttpAuthChallengeTokenizerTest, MismatchedQuotes) { ...@@ -46,7 +46,7 @@ TEST(HttpAuthChallengeTokenizerTest, MismatchedQuotes) {
HttpUtil::NameValuePairsIterator parameters = challenge.param_pairs(); HttpUtil::NameValuePairsIterator parameters = challenge.param_pairs();
EXPECT_TRUE(parameters.valid()); EXPECT_TRUE(parameters.valid());
EXPECT_EQ(std::string("Basic"), challenge.scheme()); EXPECT_EQ(std::string("basic"), challenge.auth_scheme());
EXPECT_TRUE(parameters.GetNext()); EXPECT_TRUE(parameters.GetNext());
EXPECT_TRUE(parameters.valid()); EXPECT_TRUE(parameters.valid());
EXPECT_EQ(std::string("realm"), parameters.name()); EXPECT_EQ(std::string("realm"), parameters.name());
...@@ -62,7 +62,7 @@ TEST(HttpAuthChallengeTokenizerTest, MismatchedQuotesNoValue) { ...@@ -62,7 +62,7 @@ TEST(HttpAuthChallengeTokenizerTest, MismatchedQuotesNoValue) {
HttpUtil::NameValuePairsIterator parameters = challenge.param_pairs(); HttpUtil::NameValuePairsIterator parameters = challenge.param_pairs();
EXPECT_TRUE(parameters.valid()); EXPECT_TRUE(parameters.valid());
EXPECT_EQ(std::string("Basic"), challenge.scheme()); EXPECT_EQ(std::string("basic"), challenge.auth_scheme());
EXPECT_TRUE(parameters.GetNext()); EXPECT_TRUE(parameters.GetNext());
EXPECT_TRUE(parameters.valid()); EXPECT_TRUE(parameters.valid());
EXPECT_EQ(std::string("realm"), parameters.name()); EXPECT_EQ(std::string("realm"), parameters.name());
...@@ -79,7 +79,7 @@ TEST(HttpAuthChallengeTokenizerTest, MismatchedQuotesSpaces) { ...@@ -79,7 +79,7 @@ TEST(HttpAuthChallengeTokenizerTest, MismatchedQuotesSpaces) {
HttpUtil::NameValuePairsIterator parameters = challenge.param_pairs(); HttpUtil::NameValuePairsIterator parameters = challenge.param_pairs();
EXPECT_TRUE(parameters.valid()); EXPECT_TRUE(parameters.valid());
EXPECT_EQ(std::string("Basic"), challenge.scheme()); EXPECT_EQ(std::string("basic"), challenge.auth_scheme());
EXPECT_TRUE(parameters.GetNext()); EXPECT_TRUE(parameters.GetNext());
EXPECT_TRUE(parameters.valid()); EXPECT_TRUE(parameters.valid());
EXPECT_EQ(std::string("realm"), parameters.name()); EXPECT_EQ(std::string("realm"), parameters.name());
...@@ -96,7 +96,7 @@ TEST(HttpAuthChallengeTokenizerTest, MismatchedQuotesMultiple) { ...@@ -96,7 +96,7 @@ TEST(HttpAuthChallengeTokenizerTest, MismatchedQuotesMultiple) {
HttpUtil::NameValuePairsIterator parameters = challenge.param_pairs(); HttpUtil::NameValuePairsIterator parameters = challenge.param_pairs();
EXPECT_TRUE(parameters.valid()); EXPECT_TRUE(parameters.valid());
EXPECT_EQ(std::string("Digest"), challenge.scheme()); EXPECT_EQ(std::string("digest"), challenge.auth_scheme());
EXPECT_TRUE(parameters.GetNext()); EXPECT_TRUE(parameters.GetNext());
EXPECT_TRUE(parameters.valid()); EXPECT_TRUE(parameters.valid());
EXPECT_EQ(std::string("qop"), parameters.name()); EXPECT_EQ(std::string("qop"), parameters.name());
...@@ -120,7 +120,7 @@ TEST(HttpAuthChallengeTokenizerTest, NoValue) { ...@@ -120,7 +120,7 @@ TEST(HttpAuthChallengeTokenizerTest, NoValue) {
HttpUtil::NameValuePairsIterator parameters = challenge.param_pairs(); HttpUtil::NameValuePairsIterator parameters = challenge.param_pairs();
EXPECT_TRUE(parameters.valid()); EXPECT_TRUE(parameters.valid());
EXPECT_EQ(std::string("Digest"), challenge.scheme()); EXPECT_EQ(std::string("digest"), challenge.auth_scheme());
EXPECT_FALSE(parameters.GetNext()); EXPECT_FALSE(parameters.GetNext());
EXPECT_FALSE(parameters.valid()); EXPECT_FALSE(parameters.valid());
} }
...@@ -134,7 +134,7 @@ TEST(HttpAuthChallengeTokenizerTest, Multiple) { ...@@ -134,7 +134,7 @@ TEST(HttpAuthChallengeTokenizerTest, Multiple) {
HttpUtil::NameValuePairsIterator parameters = challenge.param_pairs(); HttpUtil::NameValuePairsIterator parameters = challenge.param_pairs();
EXPECT_TRUE(parameters.valid()); EXPECT_TRUE(parameters.valid());
EXPECT_EQ(std::string("Digest"), challenge.scheme()); EXPECT_EQ(std::string("digest"), challenge.auth_scheme());
EXPECT_TRUE(parameters.GetNext()); EXPECT_TRUE(parameters.GetNext());
EXPECT_TRUE(parameters.valid()); EXPECT_TRUE(parameters.valid());
EXPECT_EQ(std::string("algorithm"), parameters.name()); EXPECT_EQ(std::string("algorithm"), parameters.name());
...@@ -159,7 +159,7 @@ TEST(HttpAuthChallengeTokenizerTest, NoProperty) { ...@@ -159,7 +159,7 @@ TEST(HttpAuthChallengeTokenizerTest, NoProperty) {
HttpUtil::NameValuePairsIterator parameters = challenge.param_pairs(); HttpUtil::NameValuePairsIterator parameters = challenge.param_pairs();
EXPECT_TRUE(parameters.valid()); EXPECT_TRUE(parameters.valid());
EXPECT_EQ(std::string("NTLM"), challenge.scheme()); EXPECT_EQ(std::string("ntlm"), challenge.auth_scheme());
EXPECT_FALSE(parameters.GetNext()); EXPECT_FALSE(parameters.GetNext());
} }
...@@ -169,7 +169,7 @@ TEST(HttpAuthChallengeTokenizerTest, Base64) { ...@@ -169,7 +169,7 @@ TEST(HttpAuthChallengeTokenizerTest, Base64) {
HttpAuthChallengeTokenizer challenge(challenge_str.begin(), HttpAuthChallengeTokenizer challenge(challenge_str.begin(),
challenge_str.end()); challenge_str.end());
EXPECT_EQ(std::string("NTLM"), challenge.scheme()); EXPECT_EQ(std::string("ntlm"), challenge.auth_scheme());
// Notice the two equal statements below due to padding removal. // Notice the two equal statements below due to padding removal.
EXPECT_EQ(std::string("SGVsbG8sIFdvcmxkCg=="), challenge.base64_param()); EXPECT_EQ(std::string("SGVsbG8sIFdvcmxkCg=="), challenge.base64_param());
} }
......
...@@ -189,7 +189,7 @@ TEST(HttpAuthControllerTest, NoExplicitCredentialsAllowed) { ...@@ -189,7 +189,7 @@ TEST(HttpAuthControllerTest, NoExplicitCredentialsAllowed) {
set_allows_explicit_credentials(false); set_allows_explicit_credentials(false);
set_connection_based(true); set_connection_based(true);
// Pretend to be SCHEME_BASIC so we can test failover logic. // Pretend to be SCHEME_BASIC so we can test failover logic.
if (challenge->scheme() == "Basic") { if (challenge->auth_scheme() == "basic") {
auth_scheme_ = HttpAuth::AUTH_SCHEME_BASIC; auth_scheme_ = HttpAuth::AUTH_SCHEME_BASIC;
--score_; // Reduce score, so we rank below Mock. --score_; // Reduce score, so we rank below Mock.
set_allows_explicit_credentials(true); set_allows_explicit_credentials(true);
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include "base/threading/thread_restrictions.h" #include "base/threading/thread_restrictions.h"
#include "base/values.h" #include "base/values.h"
#include "net/base/net_errors.h" #include "net/base/net_errors.h"
#include "net/http/http_auth.h"
#include "net/http/http_auth_gssapi_posix.h" #include "net/http/http_auth_gssapi_posix.h"
#include "net/http/http_auth_multi_round_parse.h" #include "net/http/http_auth_multi_round_parse.h"
#include "net/log/net_log_event_type.h" #include "net/log/net_log_event_type.h"
...@@ -645,13 +646,8 @@ ScopedSecurityContext::~ScopedSecurityContext() { ...@@ -645,13 +646,8 @@ ScopedSecurityContext::~ScopedSecurityContext() {
} }
} }
HttpAuthGSSAPI::HttpAuthGSSAPI(GSSAPILibrary* library, HttpAuthGSSAPI::HttpAuthGSSAPI(GSSAPILibrary* library, gss_OID gss_oid)
const std::string& scheme, : gss_oid_(gss_oid), library_(library), scoped_sec_context_(library) {
gss_OID gss_oid)
: scheme_(scheme),
gss_oid_(gss_oid),
library_(library),
scoped_sec_context_(library) {
DCHECK(library_); DCHECK(library_);
} }
...@@ -678,10 +674,11 @@ void HttpAuthGSSAPI::SetDelegation(DelegationType delegation_type) { ...@@ -678,10 +674,11 @@ void HttpAuthGSSAPI::SetDelegation(DelegationType delegation_type) {
HttpAuth::AuthorizationResult HttpAuthGSSAPI::ParseChallenge( HttpAuth::AuthorizationResult HttpAuthGSSAPI::ParseChallenge(
HttpAuthChallengeTokenizer* tok) { HttpAuthChallengeTokenizer* tok) {
if (scoped_sec_context_.get() == GSS_C_NO_CONTEXT) { if (scoped_sec_context_.get() == GSS_C_NO_CONTEXT) {
return net::ParseFirstRoundChallenge(scheme_, tok); return net::ParseFirstRoundChallenge(HttpAuth::AUTH_SCHEME_NEGOTIATE, tok);
} }
std::string encoded_auth_token; std::string encoded_auth_token;
return net::ParseLaterRoundChallenge(scheme_, tok, &encoded_auth_token, return net::ParseLaterRoundChallenge(HttpAuth::AUTH_SCHEME_NEGOTIATE, tok,
&encoded_auth_token,
&decoded_server_auth_token_); &decoded_server_auth_token_);
} }
...@@ -710,7 +707,7 @@ int HttpAuthGSSAPI::GenerateAuthToken(const AuthCredentials* credentials, ...@@ -710,7 +707,7 @@ int HttpAuthGSSAPI::GenerateAuthToken(const AuthCredentials* credentials,
output_token.length); output_token.length);
std::string encode_output; std::string encode_output;
base::Base64Encode(encode_input, &encode_output); base::Base64Encode(encode_input, &encode_output);
*auth_token = scheme_ + " " + encode_output; *auth_token = "Negotiate " + encode_output;
return OK; return OK;
} }
......
...@@ -220,7 +220,6 @@ class ScopedSecurityContext { ...@@ -220,7 +220,6 @@ class ScopedSecurityContext {
class NET_EXPORT_PRIVATE HttpAuthGSSAPI : public HttpNegotiateAuthSystem { class NET_EXPORT_PRIVATE HttpAuthGSSAPI : public HttpNegotiateAuthSystem {
public: public:
HttpAuthGSSAPI(GSSAPILibrary* library, HttpAuthGSSAPI(GSSAPILibrary* library,
const std::string& scheme,
const gss_OID gss_oid); const gss_OID gss_oid);
~HttpAuthGSSAPI() override; ~HttpAuthGSSAPI() override;
...@@ -245,7 +244,6 @@ class NET_EXPORT_PRIVATE HttpAuthGSSAPI : public HttpNegotiateAuthSystem { ...@@ -245,7 +244,6 @@ class NET_EXPORT_PRIVATE HttpAuthGSSAPI : public HttpNegotiateAuthSystem {
gss_buffer_t out_token, gss_buffer_t out_token,
const NetLogWithSource& net_log); const NetLogWithSource& net_log);
std::string scheme_;
gss_OID gss_oid_; gss_OID gss_oid_;
GSSAPILibrary* library_; GSSAPILibrary* library_;
std::string decoded_server_auth_token_; std::string decoded_server_auth_token_;
......
...@@ -268,8 +268,7 @@ TEST(HttpAuthGSSAPIPOSIXTest, GSSAPICycle) { ...@@ -268,8 +268,7 @@ TEST(HttpAuthGSSAPIPOSIXTest, GSSAPICycle) {
TEST(HttpAuthGSSAPITest, ParseChallenge_FirstRound) { TEST(HttpAuthGSSAPITest, ParseChallenge_FirstRound) {
// The first round should just consist of an unadorned "Negotiate" header. // The first round should just consist of an unadorned "Negotiate" header.
test::MockGSSAPILibrary mock_library; test::MockGSSAPILibrary mock_library;
HttpAuthGSSAPI auth_gssapi(&mock_library, "Negotiate", HttpAuthGSSAPI auth_gssapi(&mock_library, CHROME_GSS_SPNEGO_MECH_OID_DESC);
CHROME_GSS_SPNEGO_MECH_OID_DESC);
std::string challenge_text = "Negotiate"; std::string challenge_text = "Negotiate";
HttpAuthChallengeTokenizer challenge(challenge_text.begin(), HttpAuthChallengeTokenizer challenge(challenge_text.begin(),
challenge_text.end()); challenge_text.end());
...@@ -282,8 +281,7 @@ TEST(HttpAuthGSSAPITest, ParseChallenge_TwoRounds) { ...@@ -282,8 +281,7 @@ TEST(HttpAuthGSSAPITest, ParseChallenge_TwoRounds) {
// The first round should just have "Negotiate", and the second round should // The first round should just have "Negotiate", and the second round should
// have a valid base64 token associated with it. // have a valid base64 token associated with it.
test::MockGSSAPILibrary mock_library; test::MockGSSAPILibrary mock_library;
HttpAuthGSSAPI auth_gssapi(&mock_library, "Negotiate", HttpAuthGSSAPI auth_gssapi(&mock_library, CHROME_GSS_SPNEGO_MECH_OID_DESC);
CHROME_GSS_SPNEGO_MECH_OID_DESC);
std::string first_challenge_text = "Negotiate"; std::string first_challenge_text = "Negotiate";
HttpAuthChallengeTokenizer first_challenge(first_challenge_text.begin(), HttpAuthChallengeTokenizer first_challenge(first_challenge_text.begin(),
first_challenge_text.end()); first_challenge_text.end());
...@@ -323,8 +321,7 @@ TEST(HttpAuthGSSAPITest, ParseChallenge_UnexpectedTokenFirstRound) { ...@@ -323,8 +321,7 @@ TEST(HttpAuthGSSAPITest, ParseChallenge_UnexpectedTokenFirstRound) {
// If the first round challenge has an additional authentication token, it // If the first round challenge has an additional authentication token, it
// should be treated as an invalid challenge from the server. // should be treated as an invalid challenge from the server.
test::MockGSSAPILibrary mock_library; test::MockGSSAPILibrary mock_library;
HttpAuthGSSAPI auth_gssapi(&mock_library, "Negotiate", HttpAuthGSSAPI auth_gssapi(&mock_library, CHROME_GSS_SPNEGO_MECH_OID_DESC);
CHROME_GSS_SPNEGO_MECH_OID_DESC);
std::string challenge_text = "Negotiate Zm9vYmFy"; std::string challenge_text = "Negotiate Zm9vYmFy";
HttpAuthChallengeTokenizer challenge(challenge_text.begin(), HttpAuthChallengeTokenizer challenge(challenge_text.begin(),
challenge_text.end()); challenge_text.end());
...@@ -336,8 +333,7 @@ TEST(HttpAuthGSSAPITest, ParseChallenge_MissingTokenSecondRound) { ...@@ -336,8 +333,7 @@ TEST(HttpAuthGSSAPITest, ParseChallenge_MissingTokenSecondRound) {
// If a later-round challenge is simply "Negotiate", it should be treated as // If a later-round challenge is simply "Negotiate", it should be treated as
// an authentication challenge rejection from the server or proxy. // an authentication challenge rejection from the server or proxy.
test::MockGSSAPILibrary mock_library; test::MockGSSAPILibrary mock_library;
HttpAuthGSSAPI auth_gssapi(&mock_library, "Negotiate", HttpAuthGSSAPI auth_gssapi(&mock_library, CHROME_GSS_SPNEGO_MECH_OID_DESC);
CHROME_GSS_SPNEGO_MECH_OID_DESC);
std::string first_challenge_text = "Negotiate"; std::string first_challenge_text = "Negotiate";
HttpAuthChallengeTokenizer first_challenge(first_challenge_text.begin(), HttpAuthChallengeTokenizer first_challenge(first_challenge_text.begin(),
first_challenge_text.end()); first_challenge_text.end());
...@@ -361,8 +357,7 @@ TEST(HttpAuthGSSAPITest, ParseChallenge_NonBase64EncodedToken) { ...@@ -361,8 +357,7 @@ TEST(HttpAuthGSSAPITest, ParseChallenge_NonBase64EncodedToken) {
// If a later-round challenge has an invalid base64 encoded token, it should // If a later-round challenge has an invalid base64 encoded token, it should
// be treated as an invalid challenge. // be treated as an invalid challenge.
test::MockGSSAPILibrary mock_library; test::MockGSSAPILibrary mock_library;
HttpAuthGSSAPI auth_gssapi(&mock_library, "Negotiate", HttpAuthGSSAPI auth_gssapi(&mock_library, CHROME_GSS_SPNEGO_MECH_OID_DESC);
CHROME_GSS_SPNEGO_MECH_OID_DESC);
std::string first_challenge_text = "Negotiate"; std::string first_challenge_text = "Negotiate";
HttpAuthChallengeTokenizer first_challenge(first_challenge_text.begin(), HttpAuthChallengeTokenizer first_challenge(first_challenge_text.begin(),
first_challenge_text.end()); first_challenge_text.end());
......
...@@ -65,8 +65,7 @@ bool HttpAuthHandlerBasic::Init(HttpAuthChallengeTokenizer* challenge, ...@@ -65,8 +65,7 @@ bool HttpAuthHandlerBasic::Init(HttpAuthChallengeTokenizer* challenge,
bool HttpAuthHandlerBasic::ParseChallenge( bool HttpAuthHandlerBasic::ParseChallenge(
HttpAuthChallengeTokenizer* challenge) { HttpAuthChallengeTokenizer* challenge) {
// Verify the challenge's auth-scheme. if (challenge->auth_scheme() != kBasicAuthScheme)
if (!base::LowerCaseEqualsASCII(challenge->scheme(), kBasicAuthScheme))
return false; return false;
std::string realm; std::string realm;
......
...@@ -139,7 +139,7 @@ HttpAuth::AuthorizationResult HttpAuthHandlerDigest::HandleAnotherChallengeImpl( ...@@ -139,7 +139,7 @@ HttpAuth::AuthorizationResult HttpAuthHandlerDigest::HandleAnotherChallengeImpl(
// to differentiate between stale and rejected responses. // to differentiate between stale and rejected responses.
// Note that the state of the current handler is not mutated - this way if // Note that the state of the current handler is not mutated - this way if
// there is a rejection the realm hasn't changed. // there is a rejection the realm hasn't changed.
if (!base::LowerCaseEqualsASCII(challenge->scheme(), kDigestAuthScheme)) if (challenge->auth_scheme() != kDigestAuthScheme)
return HttpAuth::AUTHORIZATION_RESULT_INVALID; return HttpAuth::AUTHORIZATION_RESULT_INVALID;
HttpUtil::NameValuePairsIterator parameters = challenge->param_pairs(); HttpUtil::NameValuePairsIterator parameters = challenge->param_pairs();
...@@ -203,7 +203,7 @@ bool HttpAuthHandlerDigest::ParseChallenge( ...@@ -203,7 +203,7 @@ bool HttpAuthHandlerDigest::ParseChallenge(
realm_ = original_realm_ = nonce_ = domain_ = opaque_ = std::string(); realm_ = original_realm_ = nonce_ = domain_ = opaque_ = std::string();
// FAIL -- Couldn't match auth-scheme. // FAIL -- Couldn't match auth-scheme.
if (!base::LowerCaseEqualsASCII(challenge->scheme(), kDigestAuthScheme)) if (challenge->auth_scheme() != kDigestAuthScheme)
return false; return false;
HttpUtil::NameValuePairsIterator parameters = challenge->param_pairs(); HttpUtil::NameValuePairsIterator parameters = challenge->param_pairs();
......
...@@ -200,13 +200,12 @@ int HttpAuthHandlerRegistryFactory::CreateAuthHandler( ...@@ -200,13 +200,12 @@ int HttpAuthHandlerRegistryFactory::CreateAuthHandler(
const NetLogWithSource& net_log, const NetLogWithSource& net_log,
HostResolver* host_resolver, HostResolver* host_resolver,
std::unique_ptr<HttpAuthHandler>* handler) { std::unique_ptr<HttpAuthHandler>* handler) {
auto scheme = challenge->scheme(); auto scheme = challenge->auth_scheme();
if (scheme.empty()) { if (scheme.empty()) {
handler->reset(); handler->reset();
return ERR_INVALID_RESPONSE; return ERR_INVALID_RESPONSE;
} }
std::string lower_scheme = base::ToLowerASCII(scheme); auto it = factory_map_.find(scheme);
auto it = factory_map_.find(lower_scheme);
if (it == factory_map_.end()) { if (it == factory_map_.end()) {
handler->reset(); handler->reset();
return ERR_UNSUPPORTED_AUTH_SCHEME; return ERR_UNSUPPORTED_AUTH_SCHEME;
......
...@@ -121,7 +121,7 @@ HttpAuth::AuthorizationResult HttpAuthHandlerMock::HandleAnotherChallengeImpl( ...@@ -121,7 +121,7 @@ HttpAuth::AuthorizationResult HttpAuthHandlerMock::HandleAnotherChallengeImpl(
return HttpAuth::AUTHORIZATION_RESULT_REJECT; return HttpAuth::AUTHORIZATION_RESULT_REJECT;
} }
if (!base::LowerCaseEqualsASCII(challenge->scheme(), "mock")) { if (challenge->auth_scheme() != "mock") {
state_ = State::DONE; state_ = State::DONE;
return HttpAuth::AUTHORIZATION_RESULT_INVALID; return HttpAuth::AUTHORIZATION_RESULT_INVALID;
} }
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#include "net/base/net_errors.h" #include "net/base/net_errors.h"
#include "net/cert/x509_util.h" #include "net/cert/x509_util.h"
#include "net/dns/host_resolver.h" #include "net/dns/host_resolver.h"
#include "net/http/http_auth.h"
#include "net/http/http_auth_filter.h" #include "net/http/http_auth_filter.h"
#include "net/http/http_auth_preferences.h" #include "net/http/http_auth_preferences.h"
#include "net/log/net_log_capture_mode.h" #include "net/log/net_log_capture_mode.h"
...@@ -59,9 +60,10 @@ std::unique_ptr<HttpNegotiateAuthSystem> CreateAuthSystem( ...@@ -59,9 +60,10 @@ std::unique_ptr<HttpNegotiateAuthSystem> CreateAuthSystem(
#if defined(OS_ANDROID) #if defined(OS_ANDROID)
return std::make_unique<net::android::HttpAuthNegotiateAndroid>(prefs); return std::make_unique<net::android::HttpAuthNegotiateAndroid>(prefs);
#elif defined(OS_WIN) #elif defined(OS_WIN)
return std::make_unique<HttpAuthSSPI>(auth_library, "Negotiate"); return std::make_unique<HttpAuthSSPI>(auth_library,
HttpAuth::AUTH_SCHEME_NEGOTIATE);
#elif defined(OS_POSIX) #elif defined(OS_POSIX)
return std::make_unique<HttpAuthGSSAPI>(auth_library, "Negotiate", return std::make_unique<HttpAuthGSSAPI>(auth_library,
CHROME_GSS_SPNEGO_MECH_OID_DESC); CHROME_GSS_SPNEGO_MECH_OID_DESC);
#endif #endif
} }
......
...@@ -202,7 +202,7 @@ HttpAuth::AuthorizationResult HttpAuthHandlerNTLM::ParseChallenge( ...@@ -202,7 +202,7 @@ HttpAuth::AuthorizationResult HttpAuthHandlerNTLM::ParseChallenge(
auth_data_.clear(); auth_data_.clear();
// Verify the challenge's auth-scheme. // Verify the challenge's auth-scheme.
if (!base::LowerCaseEqualsASCII(tok->scheme(), kNtlmAuthScheme)) if (tok->auth_scheme() != kNtlmAuthScheme)
return HttpAuth::AUTHORIZATION_RESULT_INVALID; return HttpAuth::AUTHORIZATION_RESULT_INVALID;
std::string base64_param = tok->base64_param(); std::string base64_param = tok->base64_param();
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include "base/strings/string_util.h" #include "base/strings/string_util.h"
#include "net/base/net_errors.h" #include "net/base/net_errors.h"
#include "net/dns/host_resolver.h" #include "net/dns/host_resolver.h"
#include "net/http/http_auth.h"
#include "net/http/http_auth_preferences.h" #include "net/http/http_auth_preferences.h"
#include "net/http/http_auth_sspi_win.h" #include "net/http/http_auth_sspi_win.h"
...@@ -43,7 +44,7 @@ int HttpAuthHandlerNTLM::Factory::CreateAuthHandler( ...@@ -43,7 +44,7 @@ int HttpAuthHandlerNTLM::Factory::CreateAuthHandler(
HttpAuthHandlerNTLM::HttpAuthHandlerNTLM( HttpAuthHandlerNTLM::HttpAuthHandlerNTLM(
SSPILibrary* sspi_library, SSPILibrary* sspi_library,
const HttpAuthPreferences* http_auth_preferences) const HttpAuthPreferences* http_auth_preferences)
: auth_sspi_(sspi_library, "NTLM"), : auth_sspi_(sspi_library, HttpAuth::AUTH_SCHEME_NTLM),
http_auth_preferences_(http_auth_preferences) {} http_auth_preferences_(http_auth_preferences) {}
int HttpAuthHandlerNTLM::GenerateAuthTokenImpl( int HttpAuthHandlerNTLM::GenerateAuthTokenImpl(
......
...@@ -14,20 +14,16 @@ namespace net { ...@@ -14,20 +14,16 @@ namespace net {
namespace { namespace {
// Check that the scheme in the challenge matches the expected scheme // Check that the scheme in the challenge matches the expected scheme
bool SchemeIsValid(base::StringPiece scheme, bool SchemeIsValid(HttpAuth::Scheme scheme,
HttpAuthChallengeTokenizer* challenge) { HttpAuthChallengeTokenizer* challenge) {
// There is no guarantee that challenge->scheme() is valid ASCII, but return challenge->auth_scheme() == HttpAuth::SchemeToString(scheme);
// LowerCaseEqualsASCII will do the right thing even if it isn't.
return base::LowerCaseEqualsASCII(challenge->scheme(),
base::ToLowerASCII(scheme));
} }
} // namespace } // namespace
HttpAuth::AuthorizationResult ParseFirstRoundChallenge( HttpAuth::AuthorizationResult ParseFirstRoundChallenge(
base::StringPiece scheme, HttpAuth::Scheme scheme,
HttpAuthChallengeTokenizer* challenge) { HttpAuthChallengeTokenizer* challenge) {
// Verify the challenge's auth-scheme.
if (!SchemeIsValid(scheme, challenge)) if (!SchemeIsValid(scheme, challenge))
return HttpAuth::AUTHORIZATION_RESULT_INVALID; return HttpAuth::AUTHORIZATION_RESULT_INVALID;
...@@ -39,11 +35,10 @@ HttpAuth::AuthorizationResult ParseFirstRoundChallenge( ...@@ -39,11 +35,10 @@ HttpAuth::AuthorizationResult ParseFirstRoundChallenge(
} }
HttpAuth::AuthorizationResult ParseLaterRoundChallenge( HttpAuth::AuthorizationResult ParseLaterRoundChallenge(
base::StringPiece scheme, HttpAuth::Scheme scheme,
HttpAuthChallengeTokenizer* challenge, HttpAuthChallengeTokenizer* challenge,
std::string* encoded_token, std::string* encoded_token,
std::string* decoded_token) { std::string* decoded_token) {
// Verify the challenge's auth-scheme.
if (!SchemeIsValid(scheme, challenge)) if (!SchemeIsValid(scheme, challenge))
return HttpAuth::AUTHORIZATION_RESULT_INVALID; return HttpAuth::AUTHORIZATION_RESULT_INVALID;
...@@ -51,7 +46,6 @@ HttpAuth::AuthorizationResult ParseLaterRoundChallenge( ...@@ -51,7 +46,6 @@ HttpAuth::AuthorizationResult ParseLaterRoundChallenge(
if (encoded_token->empty()) if (encoded_token->empty())
return HttpAuth::AUTHORIZATION_RESULT_REJECT; return HttpAuth::AUTHORIZATION_RESULT_REJECT;
// Make sure the additional token is base64 encoded.
if (!base::Base64Decode(*encoded_token, decoded_token)) if (!base::Base64Decode(*encoded_token, decoded_token))
return HttpAuth::AUTHORIZATION_RESULT_INVALID; return HttpAuth::AUTHORIZATION_RESULT_INVALID;
return HttpAuth::AUTHORIZATION_RESULT_ACCEPT; return HttpAuth::AUTHORIZATION_RESULT_ACCEPT;
......
...@@ -16,11 +16,11 @@ namespace net { ...@@ -16,11 +16,11 @@ namespace net {
class HttpAuthChallengeTokenizer; class HttpAuthChallengeTokenizer;
NET_EXPORT_PRIVATE HttpAuth::AuthorizationResult ParseFirstRoundChallenge( NET_EXPORT_PRIVATE HttpAuth::AuthorizationResult ParseFirstRoundChallenge(
base::StringPiece scheme, HttpAuth::Scheme scheme,
HttpAuthChallengeTokenizer* challenge); HttpAuthChallengeTokenizer* challenge);
NET_EXPORT_PRIVATE HttpAuth::AuthorizationResult ParseLaterRoundChallenge( NET_EXPORT_PRIVATE HttpAuth::AuthorizationResult ParseLaterRoundChallenge(
base::StringPiece scheme, HttpAuth::Scheme scheme,
HttpAuthChallengeTokenizer* challenge, HttpAuthChallengeTokenizer* challenge,
std::string* encoded_token, std::string* encoded_token,
std::string* decoded_token); std::string* decoded_token);
......
...@@ -2,8 +2,12 @@ ...@@ -2,8 +2,12 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#include "net/http/http_auth_challenge_tokenizer.h"
#include "net/http/http_auth_multi_round_parse.h" #include "net/http/http_auth_multi_round_parse.h"
#include "base/strings/string_util.h"
#include "net/http/http_auth.h"
#include "net/http/http_auth_challenge_tokenizer.h"
#include "net/http/http_auth_scheme.h"
#include "testing/gtest/include/gtest/gtest.h" #include "testing/gtest/include/gtest/gtest.h"
namespace net { namespace net {
...@@ -11,11 +15,12 @@ namespace net { ...@@ -11,11 +15,12 @@ namespace net {
TEST(HttpAuthHandlerNegotiateParseTest, ParseFirstRoundChallenge) { TEST(HttpAuthHandlerNegotiateParseTest, ParseFirstRoundChallenge) {
// The first round should just consist of an unadorned header with the scheme // The first round should just consist of an unadorned header with the scheme
// name. // name.
std::string challenge_text = "DummyScheme"; std::string challenge_text = "Negotiate";
HttpAuthChallengeTokenizer challenge(challenge_text.begin(), HttpAuthChallengeTokenizer challenge(challenge_text.begin(),
challenge_text.end()); challenge_text.end());
EXPECT_EQ(HttpAuth::AUTHORIZATION_RESULT_ACCEPT, EXPECT_EQ(
ParseFirstRoundChallenge("dummyscheme", &challenge)); HttpAuth::AUTHORIZATION_RESULT_ACCEPT,
ParseFirstRoundChallenge(HttpAuth::AUTH_SCHEME_NEGOTIATE, &challenge));
} }
TEST(HttpAuthHandlerNegotiateParseTest, TEST(HttpAuthHandlerNegotiateParseTest,
...@@ -25,8 +30,9 @@ TEST(HttpAuthHandlerNegotiateParseTest, ...@@ -25,8 +30,9 @@ TEST(HttpAuthHandlerNegotiateParseTest,
std::string challenge_text = "Negotiate Zm9vYmFy"; std::string challenge_text = "Negotiate Zm9vYmFy";
HttpAuthChallengeTokenizer challenge(challenge_text.begin(), HttpAuthChallengeTokenizer challenge(challenge_text.begin(),
challenge_text.end()); challenge_text.end());
EXPECT_EQ(HttpAuth::AUTHORIZATION_RESULT_INVALID, EXPECT_EQ(
ParseFirstRoundChallenge("negotiate", &challenge)); HttpAuth::AUTHORIZATION_RESULT_INVALID,
ParseFirstRoundChallenge(HttpAuth::AUTH_SCHEME_NEGOTIATE, &challenge));
} }
TEST(HttpAuthHandlerNegotiateParseTest, TEST(HttpAuthHandlerNegotiateParseTest,
...@@ -34,8 +40,9 @@ TEST(HttpAuthHandlerNegotiateParseTest, ...@@ -34,8 +40,9 @@ TEST(HttpAuthHandlerNegotiateParseTest,
std::string challenge_text = "DummyScheme"; std::string challenge_text = "DummyScheme";
HttpAuthChallengeTokenizer challenge(challenge_text.begin(), HttpAuthChallengeTokenizer challenge(challenge_text.begin(),
challenge_text.end()); challenge_text.end());
EXPECT_EQ(HttpAuth::AUTHORIZATION_RESULT_INVALID, EXPECT_EQ(
ParseFirstRoundChallenge("negotiate", &challenge)); HttpAuth::AUTHORIZATION_RESULT_INVALID,
ParseFirstRoundChallenge(HttpAuth::AUTH_SCHEME_NEGOTIATE, &challenge));
} }
TEST(HttpAuthHandlerNegotiateParseTest, ParseLaterRoundChallenge) { TEST(HttpAuthHandlerNegotiateParseTest, ParseLaterRoundChallenge) {
...@@ -45,9 +52,10 @@ TEST(HttpAuthHandlerNegotiateParseTest, ParseLaterRoundChallenge) { ...@@ -45,9 +52,10 @@ TEST(HttpAuthHandlerNegotiateParseTest, ParseLaterRoundChallenge) {
challenge_text.end()); challenge_text.end());
std::string encoded_token; std::string encoded_token;
std::string decoded_token; std::string decoded_token;
EXPECT_EQ(HttpAuth::AUTHORIZATION_RESULT_ACCEPT, EXPECT_EQ(
ParseLaterRoundChallenge("negotiate", &challenge, &encoded_token, HttpAuth::AUTHORIZATION_RESULT_ACCEPT,
&decoded_token)); ParseLaterRoundChallenge(HttpAuth::AUTH_SCHEME_NEGOTIATE, &challenge,
&encoded_token, &decoded_token));
EXPECT_EQ("Zm9vYmFy", encoded_token); EXPECT_EQ("Zm9vYmFy", encoded_token);
EXPECT_EQ("foobar", decoded_token); EXPECT_EQ("foobar", decoded_token);
} }
...@@ -59,9 +67,10 @@ TEST(HttpAuthHandlerNegotiateParseTest, ...@@ -59,9 +67,10 @@ TEST(HttpAuthHandlerNegotiateParseTest,
challenge_text.end()); challenge_text.end());
std::string encoded_token; std::string encoded_token;
std::string decoded_token; std::string decoded_token;
EXPECT_EQ(HttpAuth::AUTHORIZATION_RESULT_REJECT, EXPECT_EQ(
ParseLaterRoundChallenge("negotiate", &challenge, &encoded_token, HttpAuth::AUTHORIZATION_RESULT_REJECT,
&decoded_token)); ParseLaterRoundChallenge(HttpAuth::AUTH_SCHEME_NEGOTIATE, &challenge,
&encoded_token, &decoded_token));
} }
TEST(HttpAuthHandlerNegotiateParseTest, TEST(HttpAuthHandlerNegotiateParseTest,
...@@ -71,9 +80,19 @@ TEST(HttpAuthHandlerNegotiateParseTest, ...@@ -71,9 +80,19 @@ TEST(HttpAuthHandlerNegotiateParseTest,
challenge_text.end()); challenge_text.end());
std::string encoded_token; std::string encoded_token;
std::string decoded_token; std::string decoded_token;
EXPECT_EQ(HttpAuth::AUTHORIZATION_RESULT_INVALID, EXPECT_EQ(
ParseLaterRoundChallenge("negotiate", &challenge, &encoded_token, HttpAuth::AUTHORIZATION_RESULT_INVALID,
&decoded_token)); ParseLaterRoundChallenge(HttpAuth::AUTH_SCHEME_NEGOTIATE, &challenge,
&encoded_token, &decoded_token));
}
// The parser assumes that all authentication scheme names are lowercase.
TEST(HttpAuthHandlerNegotiateParseTest, AllSchemesAreCanonical) {
EXPECT_EQ(base::ToLowerASCII(kBasicAuthScheme), kBasicAuthScheme);
EXPECT_EQ(base::ToLowerASCII(kDigestAuthScheme), kDigestAuthScheme);
EXPECT_EQ(base::ToLowerASCII(kNtlmAuthScheme), kNtlmAuthScheme);
EXPECT_EQ(base::ToLowerASCII(kNegotiateAuthScheme), kNegotiateAuthScheme);
EXPECT_EQ(base::ToLowerASCII(kMockAuthScheme), kMockAuthScheme);
} }
} // namespace net } // namespace net
...@@ -355,11 +355,13 @@ SECURITY_STATUS SSPILibraryDefault::FreeContextBuffer(PVOID pvContextBuffer) { ...@@ -355,11 +355,13 @@ SECURITY_STATUS SSPILibraryDefault::FreeContextBuffer(PVOID pvContextBuffer) {
return ::FreeContextBuffer(pvContextBuffer); return ::FreeContextBuffer(pvContextBuffer);
} }
HttpAuthSSPI::HttpAuthSSPI(SSPILibrary* library, const std::string& scheme) HttpAuthSSPI::HttpAuthSSPI(SSPILibrary* library, HttpAuth::Scheme scheme)
: library_(library), : library_(library),
scheme_(scheme), scheme_(scheme),
delegation_type_(DelegationType::kNone) { delegation_type_(DelegationType::kNone) {
DCHECK(library_); DCHECK(library_);
DCHECK(scheme_ == HttpAuth::AUTH_SCHEME_NEGOTIATE ||
scheme_ == HttpAuth::AUTH_SCHEME_NTLM);
SecInvalidateHandle(&cred_); SecInvalidateHandle(&cred_);
SecInvalidateHandle(&ctxt_); SecInvalidateHandle(&ctxt_);
} }
...@@ -437,7 +439,11 @@ int HttpAuthSSPI::GenerateAuthToken(const AuthCredentials* credentials, ...@@ -437,7 +439,11 @@ int HttpAuthSSPI::GenerateAuthToken(const AuthCredentials* credentials,
base::Base64Encode(encode_input, &encode_output); base::Base64Encode(encode_input, &encode_output);
// OK, we are done with |out_buf| // OK, we are done with |out_buf|
free(out_buf); free(out_buf);
*auth_token = scheme_ + " " + encode_output; if (scheme_ == HttpAuth::AUTH_SCHEME_NEGOTIATE) {
*auth_token = "Negotiate " + encode_output;
} else {
*auth_token = "NTLM " + encode_output;
}
return OK; return OK;
} }
......
...@@ -144,7 +144,7 @@ class SSPILibraryDefault : public SSPILibrary { ...@@ -144,7 +144,7 @@ class SSPILibraryDefault : public SSPILibrary {
class NET_EXPORT_PRIVATE HttpAuthSSPI : public HttpNegotiateAuthSystem { class NET_EXPORT_PRIVATE HttpAuthSSPI : public HttpNegotiateAuthSystem {
public: public:
HttpAuthSSPI(SSPILibrary* sspi_library, const std::string& scheme); HttpAuthSSPI(SSPILibrary* sspi_library, HttpAuth::Scheme scheme);
~HttpAuthSSPI() override; ~HttpAuthSSPI() override;
// HttpNegotiateAuthSystem implementation: // HttpNegotiateAuthSystem implementation:
...@@ -176,7 +176,7 @@ class NET_EXPORT_PRIVATE HttpAuthSSPI : public HttpNegotiateAuthSystem { ...@@ -176,7 +176,7 @@ class NET_EXPORT_PRIVATE HttpAuthSSPI : public HttpNegotiateAuthSystem {
void ResetSecurityContext(); void ResetSecurityContext();
SSPILibrary* library_; SSPILibrary* library_;
std::string scheme_; HttpAuth::Scheme scheme_;
std::string decoded_server_auth_token_; std::string decoded_server_auth_token_;
CredHandle cred_; CredHandle cred_;
CtxtHandle ctxt_; CtxtHandle ctxt_;
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include "base/bind.h" #include "base/bind.h"
#include "base/json/json_reader.h" #include "base/json/json_reader.h"
#include "net/base/net_errors.h" #include "net/base/net_errors.h"
#include "net/http/http_auth.h"
#include "net/http/http_auth_challenge_tokenizer.h" #include "net/http/http_auth_challenge_tokenizer.h"
#include "net/http/mock_sspi_library_win.h" #include "net/http/mock_sspi_library_win.h"
#include "net/log/net_log_entry.h" #include "net/log/net_log_entry.h"
...@@ -81,7 +82,7 @@ TEST(HttpAuthSSPITest, DetermineMaxTokenLength_InvalidPackage) { ...@@ -81,7 +82,7 @@ TEST(HttpAuthSSPITest, DetermineMaxTokenLength_InvalidPackage) {
TEST(HttpAuthSSPITest, ParseChallenge_FirstRound) { TEST(HttpAuthSSPITest, ParseChallenge_FirstRound) {
// The first round should just consist of an unadorned "Negotiate" header. // The first round should just consist of an unadorned "Negotiate" header.
MockSSPILibrary mock_library{NEGOSSP_NAME}; MockSSPILibrary mock_library{NEGOSSP_NAME};
HttpAuthSSPI auth_sspi(&mock_library, "Negotiate"); HttpAuthSSPI auth_sspi(&mock_library, HttpAuth::AUTH_SCHEME_NEGOTIATE);
std::string challenge_text = "Negotiate"; std::string challenge_text = "Negotiate";
HttpAuthChallengeTokenizer challenge(challenge_text.begin(), HttpAuthChallengeTokenizer challenge(challenge_text.begin(),
challenge_text.end()); challenge_text.end());
...@@ -93,7 +94,7 @@ TEST(HttpAuthSSPITest, ParseChallenge_TwoRounds) { ...@@ -93,7 +94,7 @@ TEST(HttpAuthSSPITest, ParseChallenge_TwoRounds) {
// The first round should just have "Negotiate", and the second round should // The first round should just have "Negotiate", and the second round should
// have a valid base64 token associated with it. // have a valid base64 token associated with it.
MockSSPILibrary mock_library{NEGOSSP_NAME}; MockSSPILibrary mock_library{NEGOSSP_NAME};
HttpAuthSSPI auth_sspi(&mock_library, "Negotiate"); HttpAuthSSPI auth_sspi(&mock_library, HttpAuth::AUTH_SCHEME_NEGOTIATE);
std::string first_challenge_text = "Negotiate"; std::string first_challenge_text = "Negotiate";
HttpAuthChallengeTokenizer first_challenge(first_challenge_text.begin(), HttpAuthChallengeTokenizer first_challenge(first_challenge_text.begin(),
first_challenge_text.end()); first_challenge_text.end());
...@@ -118,7 +119,7 @@ TEST(HttpAuthSSPITest, ParseChallenge_UnexpectedTokenFirstRound) { ...@@ -118,7 +119,7 @@ TEST(HttpAuthSSPITest, ParseChallenge_UnexpectedTokenFirstRound) {
// If the first round challenge has an additional authentication token, it // If the first round challenge has an additional authentication token, it
// should be treated as an invalid challenge from the server. // should be treated as an invalid challenge from the server.
MockSSPILibrary mock_library{NEGOSSP_NAME}; MockSSPILibrary mock_library{NEGOSSP_NAME};
HttpAuthSSPI auth_sspi(&mock_library, "Negotiate"); HttpAuthSSPI auth_sspi(&mock_library, HttpAuth::AUTH_SCHEME_NEGOTIATE);
std::string challenge_text = "Negotiate Zm9vYmFy"; std::string challenge_text = "Negotiate Zm9vYmFy";
HttpAuthChallengeTokenizer challenge(challenge_text.begin(), HttpAuthChallengeTokenizer challenge(challenge_text.begin(),
challenge_text.end()); challenge_text.end());
...@@ -130,7 +131,7 @@ TEST(HttpAuthSSPITest, ParseChallenge_MissingTokenSecondRound) { ...@@ -130,7 +131,7 @@ TEST(HttpAuthSSPITest, ParseChallenge_MissingTokenSecondRound) {
// If a later-round challenge is simply "Negotiate", it should be treated as // If a later-round challenge is simply "Negotiate", it should be treated as
// an authentication challenge rejection from the server or proxy. // an authentication challenge rejection from the server or proxy.
MockSSPILibrary mock_library{NEGOSSP_NAME}; MockSSPILibrary mock_library{NEGOSSP_NAME};
HttpAuthSSPI auth_sspi(&mock_library, "Negotiate"); HttpAuthSSPI auth_sspi(&mock_library, HttpAuth::AUTH_SCHEME_NEGOTIATE);
std::string first_challenge_text = "Negotiate"; std::string first_challenge_text = "Negotiate";
HttpAuthChallengeTokenizer first_challenge(first_challenge_text.begin(), HttpAuthChallengeTokenizer first_challenge(first_challenge_text.begin(),
first_challenge_text.end()); first_challenge_text.end());
...@@ -153,7 +154,7 @@ TEST(HttpAuthSSPITest, ParseChallenge_NonBase64EncodedToken) { ...@@ -153,7 +154,7 @@ TEST(HttpAuthSSPITest, ParseChallenge_NonBase64EncodedToken) {
// If a later-round challenge has an invalid base64 encoded token, it should // If a later-round challenge has an invalid base64 encoded token, it should
// be treated as an invalid challenge. // be treated as an invalid challenge.
MockSSPILibrary mock_library{NEGOSSP_NAME}; MockSSPILibrary mock_library{NEGOSSP_NAME};
HttpAuthSSPI auth_sspi(&mock_library, "Negotiate"); HttpAuthSSPI auth_sspi(&mock_library, HttpAuth::AUTH_SCHEME_NEGOTIATE);
std::string first_challenge_text = "Negotiate"; std::string first_challenge_text = "Negotiate";
HttpAuthChallengeTokenizer first_challenge(first_challenge_text.begin(), HttpAuthChallengeTokenizer first_challenge(first_challenge_text.begin(),
first_challenge_text.end()); first_challenge_text.end());
...@@ -175,7 +176,7 @@ TEST(HttpAuthSSPITest, ParseChallenge_NonBase64EncodedToken) { ...@@ -175,7 +176,7 @@ TEST(HttpAuthSSPITest, ParseChallenge_NonBase64EncodedToken) {
// Runs through a full handshake against the MockSSPILibrary. // Runs through a full handshake against the MockSSPILibrary.
TEST(HttpAuthSSPITest, GenerateAuthToken_FullHandshake_AmbientCreds) { TEST(HttpAuthSSPITest, GenerateAuthToken_FullHandshake_AmbientCreds) {
MockSSPILibrary mock_library{NEGOSSP_NAME}; MockSSPILibrary mock_library{NEGOSSP_NAME};
HttpAuthSSPI auth_sspi(&mock_library, "Negotiate"); HttpAuthSSPI auth_sspi(&mock_library, HttpAuth::AUTH_SCHEME_NEGOTIATE);
std::string first_challenge_text = "Negotiate"; std::string first_challenge_text = "Negotiate";
HttpAuthChallengeTokenizer first_challenge(first_challenge_text.begin(), HttpAuthChallengeTokenizer first_challenge(first_challenge_text.begin(),
first_challenge_text.end()); first_challenge_text.end());
...@@ -216,7 +217,7 @@ TEST(HttpAuthSSPITest, GenerateAuthToken_FullHandshake_AmbientCreds) { ...@@ -216,7 +217,7 @@ TEST(HttpAuthSSPITest, GenerateAuthToken_FullHandshake_AmbientCreds) {
TEST(HttpAuthSSPITest, GenerateAuthToken_FullHandshake_AmbientCreds_Logging) { TEST(HttpAuthSSPITest, GenerateAuthToken_FullHandshake_AmbientCreds_Logging) {
BoundTestNetLog net_log; BoundTestNetLog net_log;
MockSSPILibrary mock_library{NEGOSSP_NAME}; MockSSPILibrary mock_library{NEGOSSP_NAME};
HttpAuthSSPI auth_sspi(&mock_library, "Negotiate"); HttpAuthSSPI auth_sspi(&mock_library, HttpAuth::AUTH_SCHEME_NEGOTIATE);
std::string first_challenge_text = "Negotiate"; std::string first_challenge_text = "Negotiate";
HttpAuthChallengeTokenizer first_challenge(first_challenge_text.begin(), HttpAuthChallengeTokenizer first_challenge(first_challenge_text.begin(),
first_challenge_text.end()); first_challenge_text.end());
......
...@@ -22,7 +22,7 @@ bool ShouldRedactChallenge(HttpAuthChallengeTokenizer* challenge) { ...@@ -22,7 +22,7 @@ bool ShouldRedactChallenge(HttpAuthChallengeTokenizer* challenge) {
if (challenge->challenge_text().find(',') != std::string::npos) if (challenge->challenge_text().find(',') != std::string::npos)
return false; return false;
std::string scheme = base::ToLowerASCII(challenge->scheme()); std::string scheme = challenge->auth_scheme();
// Invalid input. // Invalid input.
if (scheme.empty()) if (scheme.empty())
return false; return false;
......
...@@ -63,7 +63,7 @@ class MockHttpAuthHandlerFactory : public HttpAuthHandlerFactory { ...@@ -63,7 +63,7 @@ class MockHttpAuthHandlerFactory : public HttpAuthHandlerFactory {
std::unique_ptr<HttpAuthHandler>* handler) override { std::unique_ptr<HttpAuthHandler>* handler) override {
handler->reset(); handler->reset();
return challenge->scheme() == supported_scheme_ return challenge->auth_scheme() == supported_scheme_
? return_code_ ? return_code_
: ERR_UNSUPPORTED_AUTH_SCHEME; : ERR_UNSUPPORTED_AUTH_SCHEME;
} }
...@@ -139,7 +139,7 @@ TEST_F(URLRequestContextBuilderTest, CustomHttpAuthHandlerFactory) { ...@@ -139,7 +139,7 @@ TEST_F(URLRequestContextBuilderTest, CustomHttpAuthHandlerFactory) {
const int kBasicReturnCode = OK; const int kBasicReturnCode = OK;
std::unique_ptr<HttpAuthHandler> handler; std::unique_ptr<HttpAuthHandler> handler;
builder_.SetHttpAuthHandlerFactory( builder_.SetHttpAuthHandlerFactory(
std::make_unique<MockHttpAuthHandlerFactory>("ExtraScheme", std::make_unique<MockHttpAuthHandlerFactory>("extrascheme",
kBasicReturnCode)); kBasicReturnCode));
std::unique_ptr<URLRequestContext> context(builder_.Build()); std::unique_ptr<URLRequestContext> context(builder_.Build());
SSLInfo null_ssl_info; SSLInfo null_ssl_info;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment