// 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_NEGOTIATE_H_
#define NET_HTTP_HTTP_AUTH_HANDLER_NEGOTIATE_H_

#include <string>

#include "build/build_config.h"
#include "net/base/address_list.h"
#include "net/base/net_export.h"
#include "net/http/http_auth_handler.h"
#include "net/http/http_auth_handler_factory.h"

#if defined(OS_WIN)
#include "net/http/http_auth_sspi_win.h"
#elif defined(OS_POSIX)
#include "net/http/http_auth_gssapi_posix.h"
#endif

namespace net {

class HostResolver;
class SingleRequestHostResolver;
class URLSecurityManager;

// Handler for WWW-Authenticate: Negotiate protocol.
//
// See http://tools.ietf.org/html/rfc4178 and http://tools.ietf.org/html/rfc4559
// for more information about the protocol.

class NET_EXPORT_PRIVATE HttpAuthHandlerNegotiate : public HttpAuthHandler {
 public:
#if defined(OS_WIN)
  typedef SSPILibrary AuthLibrary;
  typedef HttpAuthSSPI AuthSystem;
#elif defined(OS_POSIX)
  typedef GSSAPILibrary AuthLibrary;
  typedef HttpAuthGSSAPI AuthSystem;
#endif

  class NET_EXPORT_PRIVATE Factory : public HttpAuthHandlerFactory {
   public:
    Factory();
    virtual ~Factory();

    // |disable_cname_lookup()| and |set_disable_cname_lookup()| get/set whether
    // the auth handlers generated by this factory should skip looking up the
    // canonical DNS name of the the host that they are authenticating to when
    // generating the SPN. The default value is false.
    bool disable_cname_lookup() const { return disable_cname_lookup_; }
    void set_disable_cname_lookup(bool disable_cname_lookup) {
      disable_cname_lookup_ = disable_cname_lookup;
    }

    // |use_port()| and |set_use_port()| get/set whether the auth handlers
    // generated by this factory should include the port number of the server
    // they are authenticating to when constructing a Kerberos SPN. The default
    // value is false.
    bool use_port() const { return use_port_; }
    void set_use_port(bool use_port) { use_port_ = use_port; }

    void set_host_resolver(HostResolver* host_resolver);

    // Sets the system library to use, thereby assuming ownership of
    // |auth_library|.
    void set_library(AuthLibrary* auth_library) {
      auth_library_.reset(auth_library);
    }

    virtual int CreateAuthHandler(
        HttpAuthChallengeTokenizer* challenge,
        HttpAuth::Target target,
        const GURL& origin,
        CreateReason reason,
        int digest_nonce_count,
        const BoundNetLog& net_log,
        scoped_ptr<HttpAuthHandler>* handler) OVERRIDE;

   private:
    bool disable_cname_lookup_;
    bool use_port_;
    HostResolver* resolver_;
#if defined(OS_WIN)
    ULONG max_token_length_;
    bool first_creation_;
#endif
    bool is_unsupported_;
    scoped_ptr<AuthLibrary> auth_library_;
  };

  HttpAuthHandlerNegotiate(AuthLibrary* sspi_library,
#if defined(OS_WIN)
                           ULONG max_token_length,
#endif
                           URLSecurityManager* url_security_manager,
                           HostResolver* host_resolver,
                           bool disable_cname_lookup,
                           bool use_port);

  virtual ~HttpAuthHandlerNegotiate();

  // These are public for unit tests
  std::string CreateSPN(const AddressList& address_list, const GURL& orign);
  const std::string& spn() const { return spn_; }

  // HttpAuthHandler:
  virtual HttpAuth::AuthorizationResult HandleAnotherChallenge(
      HttpAuthChallengeTokenizer* challenge) OVERRIDE;
  virtual bool NeedsIdentity() OVERRIDE;
  virtual bool AllowsDefaultCredentials() OVERRIDE;
  virtual bool AllowsExplicitCredentials() OVERRIDE;

 protected:
  virtual bool Init(HttpAuthChallengeTokenizer* challenge) OVERRIDE;

  virtual int GenerateAuthTokenImpl(const AuthCredentials* credentials,
                                    const HttpRequestInfo* request,
                                    const CompletionCallback& callback,
                                    std::string* auth_token) OVERRIDE;

 private:
  enum State {
    STATE_RESOLVE_CANONICAL_NAME,
    STATE_RESOLVE_CANONICAL_NAME_COMPLETE,
    STATE_GENERATE_AUTH_TOKEN,
    STATE_GENERATE_AUTH_TOKEN_COMPLETE,
    STATE_NONE,
  };

  void OnIOComplete(int result);
  void DoCallback(int result);
  int DoLoop(int result);

  int DoResolveCanonicalName();
  int DoResolveCanonicalNameComplete(int rv);
  int DoGenerateAuthToken();
  int DoGenerateAuthTokenComplete(int rv);
  bool CanDelegate() const;

  AuthSystem auth_system_;
  bool disable_cname_lookup_;
  bool use_port_;
  HostResolver* const resolver_;

  // Members which are needed for DNS lookup + SPN.
  AddressList address_list_;
  scoped_ptr<SingleRequestHostResolver> single_resolve_;

  // Things which should be consistent after first call to GenerateAuthToken.
  bool already_called_;
  bool has_credentials_;
  AuthCredentials credentials_;
  std::string spn_;

  // Things which vary each round.
  CompletionCallback callback_;
  std::string* auth_token_;

  State next_state_;

  const URLSecurityManager* url_security_manager_;
};

}  // namespace net

#endif  // NET_HTTP_HTTP_AUTH_HANDLER_NEGOTIATE_H_
