• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2011 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 #ifndef NET_HTTP_HTTP_AUTH_HANDLER_DIGEST_H_
6 #define NET_HTTP_HTTP_AUTH_HANDLER_DIGEST_H_
7 #pragma once
8 
9 #include <string>
10 
11 #include "base/basictypes.h"
12 #include "base/gtest_prod_util.h"
13 #include "base/memory/scoped_ptr.h"
14 #include "base/string16.h"
15 #include "net/http/http_auth_handler.h"
16 #include "net/http/http_auth_handler_factory.h"
17 
18 namespace net {
19 
20 // Code for handling http digest authentication.
21 class HttpAuthHandlerDigest : public HttpAuthHandler {
22  public:
23   // A NonceGenerator is a simple interface for generating client nonces.
24   // Unit tests can override the default client nonce behavior with fixed
25   // nonce generation to get reproducible results.
26   class NonceGenerator {
27    public:
28     NonceGenerator();
29     virtual ~NonceGenerator();
30 
31     // Generates a client nonce.
32     virtual std::string GenerateNonce() const = 0;
33    private:
34     DISALLOW_COPY_AND_ASSIGN(NonceGenerator);
35   };
36 
37   // DynamicNonceGenerator does a random shuffle of 16
38   // characters to generate a client nonce.
39   class DynamicNonceGenerator : public NonceGenerator {
40    public:
41     DynamicNonceGenerator();
42     virtual std::string GenerateNonce() const;
43    private:
44     DISALLOW_COPY_AND_ASSIGN(DynamicNonceGenerator);
45   };
46 
47   // FixedNonceGenerator always uses the same string specified at
48   // construction time as the client nonce.
49   class FixedNonceGenerator : public NonceGenerator {
50    public:
51     explicit FixedNonceGenerator(const std::string& nonce);
52 
53     virtual std::string GenerateNonce() const;
54 
55    private:
56     const std::string nonce_;
57     DISALLOW_COPY_AND_ASSIGN(FixedNonceGenerator);
58   };
59 
60   class Factory : public HttpAuthHandlerFactory {
61    public:
62     Factory();
63     virtual ~Factory();
64 
65     // This factory owns the passed in |nonce_generator|.
66     void set_nonce_generator(const NonceGenerator* nonce_generator);
67 
68     virtual int CreateAuthHandler(HttpAuth::ChallengeTokenizer* challenge,
69                                   HttpAuth::Target target,
70                                   const GURL& origin,
71                                   CreateReason reason,
72                                   int digest_nonce_count,
73                                   const BoundNetLog& net_log,
74                                   scoped_ptr<HttpAuthHandler>* handler);
75 
76    private:
77     scoped_ptr<const NonceGenerator> nonce_generator_;
78   };
79 
80   virtual HttpAuth::AuthorizationResult HandleAnotherChallenge(
81       HttpAuth::ChallengeTokenizer* challenge);
82 
83  protected:
84   virtual bool Init(HttpAuth::ChallengeTokenizer* challenge);
85 
86   virtual int GenerateAuthTokenImpl(const string16* username,
87                                     const string16* password,
88                                     const HttpRequestInfo* request,
89                                     CompletionCallback* callback,
90                                     std::string* auth_token);
91 
92  private:
93   FRIEND_TEST_ALL_PREFIXES(HttpAuthHandlerDigestTest, ParseChallenge);
94   FRIEND_TEST_ALL_PREFIXES(HttpAuthHandlerDigestTest, AssembleCredentials);
95   FRIEND_TEST_ALL_PREFIXES(HttpNetworkTransactionTest, DigestPreAuthNonceCount);
96 
97   // Possible values for the "algorithm" property.
98   enum DigestAlgorithm {
99     // No algorithm was specified. According to RFC 2617 this means
100     // we should default to ALGORITHM_MD5.
101     ALGORITHM_UNSPECIFIED,
102 
103     // Hashes are run for every request.
104     ALGORITHM_MD5,
105 
106     // Hash is run only once during the first WWW-Authenticate handshake.
107     // (SESS means session).
108     ALGORITHM_MD5_SESS,
109   };
110 
111   // Possible values for QualityOfProtection.
112   // auth-int is not supported, see http://crbug.com/62890 for justification.
113   enum QualityOfProtection {
114     QOP_UNSPECIFIED,
115     QOP_AUTH,
116   };
117 
118   // |nonce_count| indicates how many times the server-specified nonce has
119   // been used so far.
120   // |nonce_generator| is used to create a client nonce, and is not owned by
121   // the handler. The lifetime of the |nonce_generator| must exceed that of this
122   // handler.
123   HttpAuthHandlerDigest(int nonce_count, const NonceGenerator* nonce_generator);
124   ~HttpAuthHandlerDigest();
125 
126   // Parse the challenge, saving the results into this instance.
127   // Returns true on success.
128   bool ParseChallenge(HttpAuth::ChallengeTokenizer* challenge);
129 
130   // Parse an individual property. Returns true on success.
131   bool ParseChallengeProperty(const std::string& name,
132                               const std::string& value);
133 
134   // Generates a random string, to be used for client-nonce.
135   static std::string GenerateNonce();
136 
137   // Convert enum value back to string.
138   static std::string QopToString(QualityOfProtection qop);
139   static std::string AlgorithmToString(DigestAlgorithm algorithm);
140 
141   // Extract the method and path of the request, as needed by
142   // the 'A2' production. (path may be a hostname for proxy).
143   void GetRequestMethodAndPath(const HttpRequestInfo* request,
144                                std::string* method,
145                                std::string* path) const;
146 
147   // Build up  the 'response' production.
148   std::string AssembleResponseDigest(const std::string& method,
149                                      const std::string& path,
150                                      const string16& username,
151                                      const string16& password,
152                                      const std::string& cnonce,
153                                      const std::string& nc) const;
154 
155   // Build up  the value for (Authorization/Proxy-Authorization).
156   std::string AssembleCredentials(const std::string& method,
157                                   const std::string& path,
158                                   const string16& username,
159                                   const string16& password,
160                                   const std::string& cnonce,
161                                   int nonce_count) const;
162 
163   // Information parsed from the challenge.
164   std::string nonce_;
165   std::string domain_;
166   std::string opaque_;
167   bool stale_;
168   DigestAlgorithm algorithm_;
169   QualityOfProtection qop_;
170 
171   int nonce_count_;
172   const NonceGenerator* nonce_generator_;
173 };
174 
175 }  // namespace net
176 
177 #endif  // NET_HTTP_HTTP_AUTH_HANDLER_DIGEST_H_
178