Home | History | Annotate | Download | only in http
      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