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