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