| // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef NET_HTTP_HTTP_AUTH_HANDLER_DIGEST_H_ |
| #define NET_HTTP_HTTP_AUTH_HANDLER_DIGEST_H_ |
| #pragma once |
| |
| #include <string> |
| |
| #include "base/basictypes.h" |
| #include "base/gtest_prod_util.h" |
| #include "base/memory/scoped_ptr.h" |
| #include "base/string16.h" |
| #include "net/http/http_auth_handler.h" |
| #include "net/http/http_auth_handler_factory.h" |
| |
| namespace net { |
| |
| // Code for handling http digest authentication. |
| class HttpAuthHandlerDigest : public HttpAuthHandler { |
| public: |
| // A NonceGenerator is a simple interface for generating client nonces. |
| // Unit tests can override the default client nonce behavior with fixed |
| // nonce generation to get reproducible results. |
| class NonceGenerator { |
| public: |
| NonceGenerator(); |
| virtual ~NonceGenerator(); |
| |
| // Generates a client nonce. |
| virtual std::string GenerateNonce() const = 0; |
| private: |
| DISALLOW_COPY_AND_ASSIGN(NonceGenerator); |
| }; |
| |
| // DynamicNonceGenerator does a random shuffle of 16 |
| // characters to generate a client nonce. |
| class DynamicNonceGenerator : public NonceGenerator { |
| public: |
| DynamicNonceGenerator(); |
| virtual std::string GenerateNonce() const; |
| private: |
| DISALLOW_COPY_AND_ASSIGN(DynamicNonceGenerator); |
| }; |
| |
| // FixedNonceGenerator always uses the same string specified at |
| // construction time as the client nonce. |
| class FixedNonceGenerator : public NonceGenerator { |
| public: |
| explicit FixedNonceGenerator(const std::string& nonce); |
| |
| virtual std::string GenerateNonce() const; |
| |
| private: |
| const std::string nonce_; |
| DISALLOW_COPY_AND_ASSIGN(FixedNonceGenerator); |
| }; |
| |
| class Factory : public HttpAuthHandlerFactory { |
| public: |
| Factory(); |
| virtual ~Factory(); |
| |
| // This factory owns the passed in |nonce_generator|. |
| void set_nonce_generator(const NonceGenerator* nonce_generator); |
| |
| virtual int CreateAuthHandler(HttpAuth::ChallengeTokenizer* challenge, |
| HttpAuth::Target target, |
| const GURL& origin, |
| CreateReason reason, |
| int digest_nonce_count, |
| const BoundNetLog& net_log, |
| scoped_ptr<HttpAuthHandler>* handler); |
| |
| private: |
| scoped_ptr<const NonceGenerator> nonce_generator_; |
| }; |
| |
| virtual HttpAuth::AuthorizationResult HandleAnotherChallenge( |
| HttpAuth::ChallengeTokenizer* challenge); |
| |
| protected: |
| virtual bool Init(HttpAuth::ChallengeTokenizer* challenge); |
| |
| virtual int GenerateAuthTokenImpl(const string16* username, |
| const string16* password, |
| const HttpRequestInfo* request, |
| CompletionCallback* callback, |
| std::string* auth_token); |
| |
| private: |
| FRIEND_TEST_ALL_PREFIXES(HttpAuthHandlerDigestTest, ParseChallenge); |
| FRIEND_TEST_ALL_PREFIXES(HttpAuthHandlerDigestTest, AssembleCredentials); |
| FRIEND_TEST_ALL_PREFIXES(HttpNetworkTransactionTest, DigestPreAuthNonceCount); |
| |
| // Possible values for the "algorithm" property. |
| enum DigestAlgorithm { |
| // No algorithm was specified. According to RFC 2617 this means |
| // we should default to ALGORITHM_MD5. |
| ALGORITHM_UNSPECIFIED, |
| |
| // Hashes are run for every request. |
| ALGORITHM_MD5, |
| |
| // Hash is run only once during the first WWW-Authenticate handshake. |
| // (SESS means session). |
| ALGORITHM_MD5_SESS, |
| }; |
| |
| // Possible values for QualityOfProtection. |
| // auth-int is not supported, see http://crbug.com/62890 for justification. |
| enum QualityOfProtection { |
| QOP_UNSPECIFIED, |
| QOP_AUTH, |
| }; |
| |
| // |nonce_count| indicates how many times the server-specified nonce has |
| // been used so far. |
| // |nonce_generator| is used to create a client nonce, and is not owned by |
| // the handler. The lifetime of the |nonce_generator| must exceed that of this |
| // handler. |
| HttpAuthHandlerDigest(int nonce_count, const NonceGenerator* nonce_generator); |
| ~HttpAuthHandlerDigest(); |
| |
| // Parse the challenge, saving the results into this instance. |
| // Returns true on success. |
| bool ParseChallenge(HttpAuth::ChallengeTokenizer* challenge); |
| |
| // Parse an individual property. Returns true on success. |
| bool ParseChallengeProperty(const std::string& name, |
| const std::string& value); |
| |
| // Generates a random string, to be used for client-nonce. |
| static std::string GenerateNonce(); |
| |
| // Convert enum value back to string. |
| static std::string QopToString(QualityOfProtection qop); |
| static std::string AlgorithmToString(DigestAlgorithm algorithm); |
| |
| // Extract the method and path of the request, as needed by |
| // the 'A2' production. (path may be a hostname for proxy). |
| void GetRequestMethodAndPath(const HttpRequestInfo* request, |
| std::string* method, |
| std::string* path) const; |
| |
| // Build up the 'response' production. |
| std::string AssembleResponseDigest(const std::string& method, |
| const std::string& path, |
| const string16& username, |
| const string16& password, |
| const std::string& cnonce, |
| const std::string& nc) const; |
| |
| // Build up the value for (Authorization/Proxy-Authorization). |
| std::string AssembleCredentials(const std::string& method, |
| const std::string& path, |
| const string16& username, |
| const string16& password, |
| const std::string& cnonce, |
| int nonce_count) const; |
| |
| // Information parsed from the challenge. |
| std::string nonce_; |
| std::string domain_; |
| std::string opaque_; |
| bool stale_; |
| DigestAlgorithm algorithm_; |
| QualityOfProtection qop_; |
| |
| int nonce_count_; |
| const NonceGenerator* nonce_generator_; |
| }; |
| |
| } // namespace net |
| |
| #endif // NET_HTTP_HTTP_AUTH_HANDLER_DIGEST_H_ |