// 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_ANDROID)
#include "net/android/http_auth_negotiate_android.h"
#elif 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_ANDROID)
  typedef net::android::HttpAuthNegotiateAndroid AuthSystem;
  // For Android this isn't a library, but for the Android Account type, which
  // indirectly identifies the Kerberos/SPNEGO authentication app.
  typedef const std::string AuthLibrary;
#elif 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();
    ~Factory() override;

    // |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_provider) {
      auth_library_.reset(auth_provider);
    }

    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_;
#endif
    bool is_unsupported_;
    scoped_ptr<AuthLibrary> auth_library_;
  };

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

  ~HttpAuthHandlerNegotiate() override;

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

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

 protected:
  bool Init(HttpAuthChallengeTokenizer* challenge) override;

  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_
