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