• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "net/http/http_auth_handler_basic.h"
6 
7 #include <string>
8 
9 #include "base/base64.h"
10 #include "base/string_util.h"
11 #include "base/utf_string_conversions.h"
12 #include "net/base/net_errors.h"
13 #include "net/http/http_auth.h"
14 
15 namespace net {
16 
17 // Note that if a realm was not specified, we will default it to "";
18 // so specifying 'Basic realm=""' is equivalent to 'Basic'.
19 //
20 // This is more generous than RFC 2617, which is pretty clear in the
21 // production of challenge that realm is required.
22 //
23 // We allow it to be compatibility with certain embedded webservers that don't
24 // include a realm (see http://crbug.com/20984.)
Init(HttpAuth::ChallengeTokenizer * challenge)25 bool HttpAuthHandlerBasic::Init(HttpAuth::ChallengeTokenizer* challenge) {
26   auth_scheme_ = HttpAuth::AUTH_SCHEME_BASIC;
27   score_ = 1;
28   properties_ = 0;
29   return ParseChallenge(challenge);
30 }
31 
ParseChallenge(HttpAuth::ChallengeTokenizer * challenge)32 bool HttpAuthHandlerBasic::ParseChallenge(
33     HttpAuth::ChallengeTokenizer* challenge) {
34   // Verify the challenge's auth-scheme.
35   if (!LowerCaseEqualsASCII(challenge->scheme(), "basic"))
36     return false;
37 
38   HttpUtil::NameValuePairsIterator parameters = challenge->param_pairs();
39 
40   // Extract the realm (may be missing).
41   std::string realm;
42   while (parameters.GetNext()) {
43     if (LowerCaseEqualsASCII(parameters.name(), "realm"))
44       realm = parameters.value();
45   }
46 
47   if (!parameters.valid())
48     return false;
49 
50   realm_ = realm;
51   return true;
52 }
53 
HandleAnotherChallenge(HttpAuth::ChallengeTokenizer * challenge)54 HttpAuth::AuthorizationResult HttpAuthHandlerBasic::HandleAnotherChallenge(
55     HttpAuth::ChallengeTokenizer* challenge) {
56   // Basic authentication is always a single round, so any responses
57   // should be treated as a rejection.  However, if the new challenge
58   // is for a different realm, then indicate the realm change.
59   HttpUtil::NameValuePairsIterator parameters = challenge->param_pairs();
60   std::string realm;
61   while (parameters.GetNext()) {
62     if (LowerCaseEqualsASCII(parameters.name(), "realm"))
63       realm = parameters.value();
64   }
65   return (realm_ != realm)?
66       HttpAuth::AUTHORIZATION_RESULT_DIFFERENT_REALM:
67       HttpAuth::AUTHORIZATION_RESULT_REJECT;
68 }
69 
GenerateAuthTokenImpl(const string16 * username,const string16 * password,const HttpRequestInfo *,CompletionCallback *,std::string * auth_token)70 int HttpAuthHandlerBasic::GenerateAuthTokenImpl(
71     const string16* username,
72     const string16* password,
73     const HttpRequestInfo*,
74     CompletionCallback*,
75     std::string* auth_token) {
76   // TODO(eroman): is this the right encoding of username/password?
77   std::string base64_username_password;
78   if (!base::Base64Encode(UTF16ToUTF8(*username) + ":" + UTF16ToUTF8(*password),
79                           &base64_username_password)) {
80     LOG(ERROR) << "Unexpected problem Base64 encoding.";
81     return ERR_UNEXPECTED;
82   }
83   *auth_token = "Basic " + base64_username_password;
84   return OK;
85 }
86 
Factory()87 HttpAuthHandlerBasic::Factory::Factory() {
88 }
89 
~Factory()90 HttpAuthHandlerBasic::Factory::~Factory() {
91 }
92 
CreateAuthHandler(HttpAuth::ChallengeTokenizer * challenge,HttpAuth::Target target,const GURL & origin,CreateReason reason,int digest_nonce_count,const BoundNetLog & net_log,scoped_ptr<HttpAuthHandler> * handler)93 int HttpAuthHandlerBasic::Factory::CreateAuthHandler(
94     HttpAuth::ChallengeTokenizer* challenge,
95     HttpAuth::Target target,
96     const GURL& origin,
97     CreateReason reason,
98     int digest_nonce_count,
99     const BoundNetLog& net_log,
100     scoped_ptr<HttpAuthHandler>* handler) {
101   // TODO(cbentzel): Move towards model of parsing in the factory
102   //                 method and only constructing when valid.
103   scoped_ptr<HttpAuthHandler> tmp_handler(new HttpAuthHandlerBasic());
104   if (!tmp_handler->InitFromChallenge(challenge, target, origin, net_log))
105     return ERR_INVALID_RESPONSE;
106   handler->swap(tmp_handler);
107   return OK;
108 }
109 
110 }  // namespace net
111