// Copyright (c) 2012 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.

#include "net/http/http_auth_handler_negotiate.h"

#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/logging.h"
#include "base/strings/stringprintf.h"
#include "net/base/address_family.h"
#include "net/base/net_errors.h"
#include "net/dns/host_resolver.h"
#include "net/dns/single_request_host_resolver.h"
#include "net/http/http_auth_filter.h"
#include "net/http/url_security_manager.h"

namespace net {

HttpAuthHandlerNegotiate::Factory::Factory()
    : disable_cname_lookup_(false),
      use_port_(false),
      resolver_(NULL),
#if defined(OS_WIN)
      max_token_length_(0),
      first_creation_(true),
#endif
      is_unsupported_(false) {
}

HttpAuthHandlerNegotiate::Factory::~Factory() {
}

void HttpAuthHandlerNegotiate::Factory::set_host_resolver(
    HostResolver* resolver) {
  resolver_ = resolver;
}

int HttpAuthHandlerNegotiate::Factory::CreateAuthHandler(
    HttpAuth::ChallengeTokenizer* challenge,
    HttpAuth::Target target,
    const GURL& origin,
    CreateReason reason,
    int digest_nonce_count,
    const BoundNetLog& net_log,
    scoped_ptr<HttpAuthHandler>* handler) {
#if defined(OS_WIN)
  if (is_unsupported_ || reason == CREATE_PREEMPTIVE)
    return ERR_UNSUPPORTED_AUTH_SCHEME;
  if (max_token_length_ == 0) {
    int rv = DetermineMaxTokenLength(auth_library_.get(), NEGOSSP_NAME,
                                     &max_token_length_);
    if (rv == ERR_UNSUPPORTED_AUTH_SCHEME)
      is_unsupported_ = true;
    if (rv != OK)
      return rv;
  }
  // TODO(cbentzel): Move towards model of parsing in the factory
  //                 method and only constructing when valid.
  scoped_ptr<HttpAuthHandler> tmp_handler(
      new HttpAuthHandlerNegotiate(auth_library_.get(), max_token_length_,
                                   url_security_manager(), resolver_,
                                   disable_cname_lookup_, use_port_));
  if (!tmp_handler->InitFromChallenge(challenge, target, origin, net_log))
    return ERR_INVALID_RESPONSE;
  handler->swap(tmp_handler);
  return OK;
#elif defined(OS_POSIX)
  if (is_unsupported_)
    return ERR_UNSUPPORTED_AUTH_SCHEME;
  if (!auth_library_->Init()) {
    is_unsupported_ = true;
    return ERR_UNSUPPORTED_AUTH_SCHEME;
  }
  // TODO(ahendrickson): Move towards model of parsing in the factory
  //                     method and only constructing when valid.
  scoped_ptr<HttpAuthHandler> tmp_handler(
      new HttpAuthHandlerNegotiate(auth_library_.get(), url_security_manager(),
                                   resolver_, disable_cname_lookup_,
                                   use_port_));
  if (!tmp_handler->InitFromChallenge(challenge, target, origin, net_log))
    return ERR_INVALID_RESPONSE;
  handler->swap(tmp_handler);
  return OK;
#endif
}

HttpAuthHandlerNegotiate::HttpAuthHandlerNegotiate(
    AuthLibrary* auth_library,
#if defined(OS_WIN)
    ULONG max_token_length,
#endif
    URLSecurityManager* url_security_manager,
    HostResolver* resolver,
    bool disable_cname_lookup,
    bool use_port)
#if defined(OS_WIN)
    : auth_system_(auth_library, "Negotiate", NEGOSSP_NAME, max_token_length),
#elif defined(OS_POSIX)
    : auth_system_(auth_library, "Negotiate", CHROME_GSS_SPNEGO_MECH_OID_DESC),
#endif
      disable_cname_lookup_(disable_cname_lookup),
      use_port_(use_port),
      resolver_(resolver),
      already_called_(false),
      has_credentials_(false),
      auth_token_(NULL),
      next_state_(STATE_NONE),
      url_security_manager_(url_security_manager) {
}

HttpAuthHandlerNegotiate::~HttpAuthHandlerNegotiate() {
}

std::string HttpAuthHandlerNegotiate::CreateSPN(
    const AddressList& address_list, const GURL& origin) {
  // Kerberos Web Server SPNs are in the form HTTP/<host>:<port> through SSPI,
  // and in the form HTTP@<host>:<port> through GSSAPI
  //   http://msdn.microsoft.com/en-us/library/ms677601%28VS.85%29.aspx
  //
  // However, reality differs from the specification. A good description of
  // the problems can be found here:
  //   http://blog.michelbarneveld.nl/michel/archive/2009/11/14/the-reason-why-kb911149-and-kb908209-are-not-the-soluton.aspx
  //
  // Typically the <host> portion should be the canonical FQDN for the service.
  // If this could not be resolved, the original hostname in the URL will be
  // attempted instead. However, some intranets register SPNs using aliases
  // for the same canonical DNS name to allow multiple web services to reside
  // on the same host machine without requiring different ports. IE6 and IE7
  // have hotpatches that allow the default behavior to be overridden.
  //   http://support.microsoft.com/kb/911149
  //   http://support.microsoft.com/kb/938305
  //
  // According to the spec, the <port> option should be included if it is a
  // non-standard port (i.e. not 80 or 443 in the HTTP case). However,
  // historically browsers have not included the port, even on non-standard
  // ports. IE6 required a hotpatch and a registry setting to enable
  // including non-standard ports, and IE7 and IE8 also require the same
  // registry setting, but no hotpatch. Firefox does not appear to have an
  // option to include non-standard ports as of 3.6.
  //   http://support.microsoft.com/kb/908209
  //
  // Without any command-line flags, Chrome matches the behavior of Firefox
  // and IE. Users can override the behavior so aliases are allowed and
  // non-standard ports are included.
  int port = origin.EffectiveIntPort();
  std::string server = address_list.canonical_name();
  if (server.empty())
    server = origin.host();
#if defined(OS_WIN)
  static const char kSpnSeparator = '/';
#elif defined(OS_POSIX)
  static const char kSpnSeparator = '@';
#endif
  if (port != 80 && port != 443 && use_port_) {
    return base::StringPrintf("HTTP%c%s:%d", kSpnSeparator, server.c_str(),
                              port);
  } else {
    return base::StringPrintf("HTTP%c%s", kSpnSeparator, server.c_str());
  }
}

HttpAuth::AuthorizationResult HttpAuthHandlerNegotiate::HandleAnotherChallenge(
    HttpAuth::ChallengeTokenizer* challenge) {
  return auth_system_.ParseChallenge(challenge);
}

// Require identity on first pass instead of second.
bool HttpAuthHandlerNegotiate::NeedsIdentity() {
  return auth_system_.NeedsIdentity();
}

bool HttpAuthHandlerNegotiate::AllowsDefaultCredentials() {
  if (target_ == HttpAuth::AUTH_PROXY)
    return true;
  if (!url_security_manager_)
    return false;
  return url_security_manager_->CanUseDefaultCredentials(origin_);
}

bool HttpAuthHandlerNegotiate::AllowsExplicitCredentials() {
  return auth_system_.AllowsExplicitCredentials();
}

// The Negotiate challenge header looks like:
//   WWW-Authenticate: NEGOTIATE auth-data
bool HttpAuthHandlerNegotiate::Init(HttpAuth::ChallengeTokenizer* challenge) {
#if defined(OS_POSIX)
  if (!auth_system_.Init()) {
    VLOG(1) << "can't initialize GSSAPI library";
    return false;
  }
  // GSSAPI does not provide a way to enter username/password to
  // obtain a TGT. If the default credentials are not allowed for
  // a particular site (based on whitelist), fall back to a
  // different scheme.
  if (!AllowsDefaultCredentials())
    return false;
#endif
  if (CanDelegate())
    auth_system_.Delegate();
  auth_scheme_ = HttpAuth::AUTH_SCHEME_NEGOTIATE;
  score_ = 4;
  properties_ = ENCRYPTS_IDENTITY | IS_CONNECTION_BASED;
  HttpAuth::AuthorizationResult auth_result =
      auth_system_.ParseChallenge(challenge);
  return (auth_result == HttpAuth::AUTHORIZATION_RESULT_ACCEPT);
}

int HttpAuthHandlerNegotiate::GenerateAuthTokenImpl(
    const AuthCredentials* credentials, const HttpRequestInfo* request,
    const CompletionCallback& callback, std::string* auth_token) {
  DCHECK(callback_.is_null());
  DCHECK(auth_token_ == NULL);
  auth_token_ = auth_token;
  if (already_called_) {
    DCHECK((!has_credentials_ && credentials == NULL) ||
           (has_credentials_ && credentials->Equals(credentials_)));
    next_state_ = STATE_GENERATE_AUTH_TOKEN;
  } else {
    already_called_ = true;
    if (credentials) {
      has_credentials_ = true;
      credentials_ = *credentials;
    }
    next_state_ = STATE_RESOLVE_CANONICAL_NAME;
  }
  int rv = DoLoop(OK);
  if (rv == ERR_IO_PENDING)
    callback_ = callback;
  return rv;
}

void HttpAuthHandlerNegotiate::OnIOComplete(int result) {
  int rv = DoLoop(result);
  if (rv != ERR_IO_PENDING)
    DoCallback(rv);
}

void HttpAuthHandlerNegotiate::DoCallback(int rv) {
  DCHECK(rv != ERR_IO_PENDING);
  DCHECK(!callback_.is_null());
  CompletionCallback callback = callback_;
  callback_.Reset();
  callback.Run(rv);
}

int HttpAuthHandlerNegotiate::DoLoop(int result) {
  DCHECK(next_state_ != STATE_NONE);

  int rv = result;
  do {
    State state = next_state_;
    next_state_ = STATE_NONE;
    switch (state) {
      case STATE_RESOLVE_CANONICAL_NAME:
        DCHECK_EQ(OK, rv);
        rv = DoResolveCanonicalName();
        break;
      case STATE_RESOLVE_CANONICAL_NAME_COMPLETE:
        rv = DoResolveCanonicalNameComplete(rv);
        break;
      case STATE_GENERATE_AUTH_TOKEN:
        DCHECK_EQ(OK, rv);
        rv = DoGenerateAuthToken();
        break;
      case STATE_GENERATE_AUTH_TOKEN_COMPLETE:
        rv = DoGenerateAuthTokenComplete(rv);
        break;
      default:
        NOTREACHED() << "bad state";
        rv = ERR_FAILED;
        break;
    }
  } while (rv != ERR_IO_PENDING && next_state_ != STATE_NONE);

  return rv;
}

int HttpAuthHandlerNegotiate::DoResolveCanonicalName() {
  next_state_ = STATE_RESOLVE_CANONICAL_NAME_COMPLETE;
  if (disable_cname_lookup_ || !resolver_)
    return OK;

  // TODO(cbentzel): Add reverse DNS lookup for numeric addresses.
  DCHECK(!single_resolve_.get());
  HostResolver::RequestInfo info(HostPortPair(origin_.host(), 0));
  info.set_host_resolver_flags(HOST_RESOLVER_CANONNAME);
  single_resolve_.reset(new SingleRequestHostResolver(resolver_));
  return single_resolve_->Resolve(
      info,
      DEFAULT_PRIORITY,
      &address_list_,
      base::Bind(&HttpAuthHandlerNegotiate::OnIOComplete,
                 base::Unretained(this)),
      net_log_);
}

int HttpAuthHandlerNegotiate::DoResolveCanonicalNameComplete(int rv) {
  DCHECK_NE(ERR_IO_PENDING, rv);
  if (rv != OK) {
    // Even in the error case, try to use origin_.host instead of
    // passing the failure on to the caller.
    VLOG(1) << "Problem finding canonical name for SPN for host "
            << origin_.host() << ": " << ErrorToString(rv);
    rv = OK;
  }

  next_state_ = STATE_GENERATE_AUTH_TOKEN;
  spn_ = CreateSPN(address_list_, origin_);
  address_list_ = AddressList();
  return rv;
}

int HttpAuthHandlerNegotiate::DoGenerateAuthToken() {
  next_state_ = STATE_GENERATE_AUTH_TOKEN_COMPLETE;
  AuthCredentials* credentials = has_credentials_ ? &credentials_ : NULL;
  // TODO(cbentzel): This should possibly be done async.
  return auth_system_.GenerateAuthToken(credentials, spn_, auth_token_);
}

int HttpAuthHandlerNegotiate::DoGenerateAuthTokenComplete(int rv) {
  DCHECK_NE(ERR_IO_PENDING, rv);
  auth_token_ = NULL;
  return rv;
}

bool HttpAuthHandlerNegotiate::CanDelegate() const {
  // TODO(cbentzel): Should delegation be allowed on proxies?
  if (target_ == HttpAuth::AUTH_PROXY)
    return false;
  if (!url_security_manager_)
    return false;
  return url_security_manager_->CanDelegate(origin_);
}

}  // namespace net
