1c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Copyright (c) 2010 The Chromium Authors. All rights reserved.
2c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Use of this source code is governed by a BSD-style license that can be
3c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// found in the LICENSE file.
4c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
5c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/http/http_auth_handler.h"
6c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
7c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/logging.h"
8c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/base/net_errors.h"
9c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
10c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottnamespace net {
11c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
12c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochHttpAuthHandler::HttpAuthHandler()
1372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    : auth_scheme_(HttpAuth::AUTH_SCHEME_MAX),
1421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      score_(-1),
15c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      target_(HttpAuth::AUTH_NONE),
16c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      properties_(-1),
17c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      original_callback_(NULL),
18c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      ALLOW_THIS_IN_INITIALIZER_LIST(
19c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          wrapper_callback_(
20c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch              this, &HttpAuthHandler::OnGenerateAuthTokenComplete)) {
21c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
22c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
23c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochHttpAuthHandler::~HttpAuthHandler() {
24c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
25c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
26c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool HttpAuthHandler::InitFromChallenge(
27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    HttpAuth::ChallengeTokenizer* challenge,
28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    HttpAuth::Target target,
29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const GURL& origin,
30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const BoundNetLog& net_log) {
31c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  origin_ = origin;
32c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  target_ = target;
33c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  score_ = -1;
34c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  properties_ = -1;
35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  net_log_ = net_log;
36c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
37c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  auth_challenge_ = challenge->challenge_text();
38c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool ok = Init(challenge);
39c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
40c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Init() is expected to set the scheme, realm, score, and properties.  The
41c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // realm may be empty.
42c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  DCHECK(!ok || score_ != -1);
43c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  DCHECK(!ok || properties_ != -1);
4472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  DCHECK(!ok || auth_scheme_ != HttpAuth::AUTH_SCHEME_MAX);
45c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
46c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return ok;
47c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
48c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace {
50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
51c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochNetLog::EventType EventTypeFromAuthTarget(HttpAuth::Target target) {
52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  switch (target) {
53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case HttpAuth::AUTH_PROXY:
54c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      return NetLog::TYPE_AUTH_PROXY;
55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case HttpAuth::AUTH_SERVER:
56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      return NetLog::TYPE_AUTH_SERVER;
57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    default:
58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NOTREACHED();
59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      return NetLog::TYPE_CANCELLED;
60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}  // namespace
64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickint HttpAuthHandler::GenerateAuthToken(const string16* username,
663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                       const string16* password,
67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                       const HttpRequestInfo* request,
68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                       CompletionCallback* callback,
69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                       std::string* auth_token) {
70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // TODO(cbentzel): Enforce non-NULL callback after cleaning up SocketStream.
71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(request);
72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK((username == NULL) == (password == NULL));
73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(username != NULL || AllowsDefaultCredentials());
74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(auth_token != NULL);
75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(original_callback_ == NULL);
76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  original_callback_ = callback;
77c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  net_log_.BeginEvent(EventTypeFromAuthTarget(target_), NULL);
78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int rv = GenerateAuthTokenImpl(username, password, request,
79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                 &wrapper_callback_, auth_token);
80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (rv != ERR_IO_PENDING)
81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    FinishGenerateAuthToken();
82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return rv;
83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
8521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenbool HttpAuthHandler::NeedsIdentity() {
8621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  return true;
8721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen}
8821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
8921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenbool HttpAuthHandler::AllowsDefaultCredentials() {
9021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  return false;
9121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen}
9221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid HttpAuthHandler::OnGenerateAuthTokenComplete(int rv) {
94c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CompletionCallback* callback = original_callback_;
95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  FinishGenerateAuthToken();
96c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (callback)
97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    callback->Run(rv);
98c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
99c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid HttpAuthHandler::FinishGenerateAuthToken() {
101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // TOOD(cbentzel): Should this be done in OK case only?
102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  net_log_.EndEvent(EventTypeFromAuthTarget(target_), NULL);
103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  original_callback_ = NULL;
104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
106c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}  // namespace net
107