summaryrefslogtreecommitdiffstats
path: root/net/http/http_auth.cc
diff options
context:
space:
mode:
Diffstat (limited to 'net/http/http_auth.cc')
-rw-r--r--net/http/http_auth.cc73
1 files changed, 33 insertions, 40 deletions
diff --git a/net/http/http_auth.cc b/net/http/http_auth.cc
index aa97640..83da9ad 100644
--- a/net/http/http_auth.cc
+++ b/net/http/http_auth.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Copyright (c) 2010 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.
@@ -8,6 +8,7 @@
#include "base/basictypes.h"
#include "base/string_util.h"
+#include "net/base/net_errors.h"
#include "net/http/http_auth_handler_basic.h"
#include "net/http/http_auth_handler_digest.h"
#include "net/http/http_auth_handler_negotiate.h"
@@ -18,10 +19,14 @@
namespace net {
// static
-void HttpAuth::ChooseBestChallenge(const HttpResponseHeaders* headers,
- Target target,
- const GURL& origin,
- scoped_refptr<HttpAuthHandler>* handler) {
+void HttpAuth::ChooseBestChallenge(
+ HttpAuthHandlerFactory* http_auth_handler_factory,
+ const HttpResponseHeaders* headers,
+ Target target,
+ const GURL& origin,
+ scoped_refptr<HttpAuthHandler>* handler) {
+ DCHECK(http_auth_handler_factory);
+
// A connection-based authentication scheme must continue to use the
// existing handler object in |*handler|.
if (*handler && (*handler)->is_connection_based()) {
@@ -31,8 +36,7 @@ void HttpAuth::ChooseBestChallenge(const HttpResponseHeaders* headers,
while (headers->EnumerateHeader(&iter, header_name, &challenge)) {
ChallengeTokenizer props(challenge.begin(), challenge.end());
if (LowerCaseEqualsASCII(props.scheme(), (*handler)->scheme().c_str()) &&
- (*handler)->InitFromChallenge(challenge.begin(), challenge.end(),
- target, origin))
+ (*handler)->InitFromChallenge(&props, target, origin))
return;
}
}
@@ -44,45 +48,19 @@ void HttpAuth::ChooseBestChallenge(const HttpResponseHeaders* headers,
void* iter = NULL;
while (headers->EnumerateHeader(&iter, header_name, &cur_challenge)) {
scoped_refptr<HttpAuthHandler> cur;
- CreateAuthHandler(cur_challenge, target, origin, &cur);
+ int rv = http_auth_handler_factory->CreateAuthHandlerFromString(
+ cur_challenge, target, origin, &cur);
+ if (rv != OK) {
+ LOG(WARNING) << "Unable to create AuthHandler. Status: "
+ << ErrorToString(rv) << " Challenge: " << cur_challenge;
+ continue;
+ }
if (cur && (!best || best->score() < cur->score()))
best.swap(cur);
}
handler->swap(best);
}
-// static
-void HttpAuth::CreateAuthHandler(const std::string& challenge,
- Target target,
- const GURL& origin,
- scoped_refptr<HttpAuthHandler>* handler) {
- // Find the right auth handler for the challenge's scheme.
- ChallengeTokenizer props(challenge.begin(), challenge.end());
- if (!props.valid()) {
- *handler = NULL;
- return;
- }
-
- scoped_refptr<HttpAuthHandler> tmp_handler;
- if (LowerCaseEqualsASCII(props.scheme(), "basic")) {
- tmp_handler = new HttpAuthHandlerBasic();
- } else if (LowerCaseEqualsASCII(props.scheme(), "digest")) {
- tmp_handler = new HttpAuthHandlerDigest();
- } else if (LowerCaseEqualsASCII(props.scheme(), "negotiate")) {
- tmp_handler = new HttpAuthHandlerNegotiate();
- } else if (LowerCaseEqualsASCII(props.scheme(), "ntlm")) {
- tmp_handler = new HttpAuthHandlerNTLM();
- }
- if (tmp_handler) {
- if (!tmp_handler->InitFromChallenge(challenge.begin(), challenge.end(),
- target, origin)) {
- // Invalid/unsupported challenge.
- tmp_handler = NULL;
- }
- }
- handler->swap(tmp_handler);
-}
-
void HttpAuth::ChallengeTokenizer::Init(std::string::const_iterator begin,
std::string::const_iterator end) {
// The first space-separated token is the auth-scheme.
@@ -115,6 +93,21 @@ bool HttpAuth::ChallengeTokenizer::GetNext() {
value_end_ = props_.value_end();
name_begin_ = name_end_ = value_end_;
+ if (expect_base64_token_) {
+ expect_base64_token_ = false;
+ // Strip off any padding.
+ // (See https://bugzilla.mozilla.org/show_bug.cgi?id=230351.)
+ //
+ // Our base64 decoder requires that the length be a multiple of 4.
+ int encoded_length = value_end_ - value_begin_;
+ while (encoded_length > 0 && encoded_length % 4 != 0 &&
+ value_begin_[encoded_length - 1] == '=') {
+ --encoded_length;
+ --value_end_;
+ }
+ return true;
+ }
+
// Scan for the equals sign.
std::string::const_iterator equals = std::find(value_begin_, value_end_, '=');
if (equals == value_end_ || equals == value_begin_)