1 // Copyright (c) 2006-2008 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 "net/http/http_auth_handler.h" 9 10 // This is needed for the FRIEND_TEST() macro. 11 #include "testing/gtest/include/gtest/gtest_prod.h" 12 13 namespace net { 14 15 // Code for handling http digest authentication. 16 class HttpAuthHandlerDigest : public HttpAuthHandler { 17 public: 18 virtual std::string GenerateCredentials(const std::wstring& username, 19 const std::wstring& password, 20 const HttpRequestInfo* request, 21 const ProxyInfo* proxy); 22 23 protected: Init(std::string::const_iterator challenge_begin,std::string::const_iterator challenge_end)24 virtual bool Init(std::string::const_iterator challenge_begin, 25 std::string::const_iterator challenge_end) { 26 nonce_count_ = 0; 27 return ParseChallenge(challenge_begin, challenge_end); 28 } 29 30 private: 31 FRIEND_TEST(HttpAuthHandlerDigestTest, ParseChallenge); 32 FRIEND_TEST(HttpAuthHandlerDigestTest, AssembleCredentials); 33 34 // Possible values for the "algorithm" property. 35 enum DigestAlgorithm { 36 // No algorithm was specified. According to RFC 2617 this means 37 // we should default to ALGORITHM_MD5. 38 ALGORITHM_UNSPECIFIED, 39 40 // Hashes are run for every request. 41 ALGORITHM_MD5, 42 43 // Hash is run only once during the first WWW-Authenticate handshake. 44 // (SESS means session). 45 ALGORITHM_MD5_SESS, 46 }; 47 48 // Possible values for "qop" -- may be or-ed together if there were 49 // multiple comma separated values. 50 enum QualityOfProtection { 51 QOP_UNSPECIFIED = 0, 52 QOP_AUTH = 1 << 0, 53 QOP_AUTH_INT = 1 << 1, 54 }; 55 ~HttpAuthHandlerDigest()56 ~HttpAuthHandlerDigest() {} 57 58 // Parse the challenge, saving the results into this instance. 59 // Returns true on success. 60 bool ParseChallenge(std::string::const_iterator challenge_begin, 61 std::string::const_iterator challenge_end); 62 63 // Parse an individual property. Returns true on success. 64 bool ParseChallengeProperty(const std::string& name, 65 const std::string& value); 66 67 // Generates a random string, to be used for client-nonce. 68 static std::string GenerateNonce(); 69 70 // Convert enum value back to string. 71 static std::string QopToString(int qop); 72 static std::string AlgorithmToString(int algorithm); 73 74 // Extract the method and path of the request, as needed by 75 // the 'A2' production. (path may be a hostname for proxy). 76 void GetRequestMethodAndPath(const HttpRequestInfo* request, 77 const ProxyInfo* proxy, 78 std::string* method, 79 std::string* path) const; 80 81 // Build up the 'response' production. 82 std::string AssembleResponseDigest(const std::string& method, 83 const std::string& path, 84 const std::string& username, 85 const std::string& password, 86 const std::string& cnonce, 87 const std::string& nc) const; 88 89 // Build up the value for (Authorization/Proxy-Authorization). 90 std::string AssembleCredentials(const std::string& method, 91 const std::string& path, 92 const std::string& username, 93 const std::string& password, 94 const std::string& cnonce, 95 int nonce_count) const; 96 97 // Information parsed from the challenge. 98 std::string nonce_; 99 std::string domain_; 100 std::string opaque_; 101 bool stale_; 102 DigestAlgorithm algorithm_; 103 int qop_; // Bitfield of QualityOfProtection 104 105 int nonce_count_; 106 }; 107 108 } // namespace net 109 110 #endif // NET_HTTP_HTTP_AUTH_HANDLER_DIGEST_H_ 111