blob: 8d1ecc519166b53b41576fa9ca7f4e46fbb2b315 [file] [log] [blame]
// 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.
#ifndef NET_HTTP_HTTP_AUTH_H_
#define NET_HTTP_HTTP_AUTH_H_
#include "net/http/http_util.h"
template <class T> class scoped_refptr;
namespace net {
class HttpAuthHandler;
class HttpAuthHandlerFactory;
class HttpResponseHeaders;
// Utility class for http authentication.
class HttpAuth {
public:
// Http authentication can be done the the proxy server, origin server,
// or both. This enum tracks who the target is.
enum Target {
AUTH_NONE = -1,
// We depend on the valid targets (!= AUTH_NONE) being usable as indexes
// in an array, so start from 0.
AUTH_PROXY = 0,
AUTH_SERVER = 1,
};
// Describes where the identity used for authentication came from.
enum IdentitySource {
// Came from nowhere -- the identity is not initialized.
IDENT_SRC_NONE,
// The identity came from the auth cache, by doing a path-based
// lookup (premptive authorization).
IDENT_SRC_PATH_LOOKUP,
// The identity was extracted from a URL of the form:
// http://<username>:<password>@host:port
IDENT_SRC_URL,
// The identity was retrieved from the auth cache, by doing a
// realm lookup.
IDENT_SRC_REALM_LOOKUP,
// The identity was provided by RestartWithAuth -- it likely
// came from a prompt (or maybe the password manager).
IDENT_SRC_EXTERNAL,
// The identity used the default credentials for the computer,
// on schemes that support single sign-on.
IDENT_SRC_DEFAULT_CREDENTIALS,
};
// Helper structure used by HttpNetworkTransaction to track
// the current identity being used for authorization.
struct Identity {
Identity() : source(IDENT_SRC_NONE), invalid(true) { }
IdentitySource source;
bool invalid;
// TODO(wtc): |username| and |password| should be string16.
std::wstring username;
std::wstring password;
};
// Get the name of the header containing the auth challenge
// (either WWW-Authenticate or Proxy-Authenticate).
static std::string GetChallengeHeaderName(Target target);
// Get the name of the header where the credentials go
// (either Authorization or Proxy-Authorization).
static std::string GetAuthorizationHeaderName(Target target);
// Iterate through the challenge headers, and pick the best one that
// we support. Obtains the implementation class for handling the challenge,
// and passes it back in |*handler|. If the existing handler in |*handler|
// should continue to be used (such as for the NTLM authentication scheme),
// |*handler| is unchanged. If no supported challenge was found, |*handler|
// is set to NULL.
//
// |origin| is used by the NTLM authentication scheme to construct the
// service principal name. It is ignored by other schemes.
//
// TODO(wtc): Continuing to use the existing handler in |*handler| (for
// NTLM) is new behavior. Rename ChooseBestChallenge to fully encompass
// what it does now.
static void ChooseBestChallenge(
HttpAuthHandlerFactory* http_auth_handler_factory,
const HttpResponseHeaders* headers,
Target target,
const GURL& origin,
scoped_refptr<HttpAuthHandler>* handler);
// ChallengeTokenizer breaks up a challenge string into the the auth scheme
// and parameter list, according to RFC 2617 Sec 1.2:
// challenge = auth-scheme 1*SP 1#auth-param
//
// Check valid() after each iteration step in case it was malformed.
// Also note that value() will give whatever is to the right of the equals
// sign, quotemarks and all. Use unquoted_value() to get the logical value.
class ChallengeTokenizer {
public:
ChallengeTokenizer(std::string::const_iterator begin,
std::string::const_iterator end)
: props_(begin, end, ','), valid_(true), expect_base64_token_(false) {
Init(begin, end);
}
// Get the auth scheme of the challenge.
std::string::const_iterator scheme_begin() const { return scheme_begin_; }
std::string::const_iterator scheme_end() const { return scheme_end_; }
std::string scheme() const {
return std::string(scheme_begin_, scheme_end_);
}
// Returns false if there was a parse error.
bool valid() const {
return valid_;
}
// Advances the iterator to the next name-value pair, if any.
// Returns true if there is none to consume.
bool GetNext();
// Inform the tokenizer whether the next token should be treated as a base64
// encoded value. If |expect_base64_token| is true, |GetNext| will treat the
// next token as a base64 encoded value, and will include the trailing '='
// padding rather than attempt to split the token into a name/value pair.
// In this case, |name| will be empty, and |value| will contain the token.
// Subsequent calls to |GetNext()| will not treat the token like a base64
// encoded token unless the caller again calls |set_expect_base64_token|.
void set_expect_base64_token(bool expect_base64_token) {
expect_base64_token_ = expect_base64_token;
}
// The name of the current name-value pair.
std::string::const_iterator name_begin() const { return name_begin_; }
std::string::const_iterator name_end() const { return name_end_; }
std::string name() const {
return std::string(name_begin_, name_end_);
}
// The value of the current name-value pair.
std::string::const_iterator value_begin() const { return value_begin_; }
std::string::const_iterator value_end() const { return value_end_; }
std::string value() const {
return std::string(value_begin_, value_end_);
}
// If value() has quotemarks, unquote it.
std::string unquoted_value() const;
// True if the name-value pair's value has quote marks.
bool value_is_quoted() const { return value_is_quoted_; }
private:
void Init(std::string::const_iterator begin,
std::string::const_iterator end);
HttpUtil::ValuesIterator props_;
bool valid_;
std::string::const_iterator scheme_begin_;
std::string::const_iterator scheme_end_;
std::string::const_iterator name_begin_;
std::string::const_iterator name_end_;
std::string::const_iterator value_begin_;
std::string::const_iterator value_end_;
bool value_is_quoted_;
bool expect_base64_token_;
};
};
} // namespace net
#endif // NET_HTTP_HTTP_AUTH_H_