// 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 "chrome/browser/net/spdyproxy/http_auth_handler_spdyproxy.h"

#include <algorithm>
#include <string>
#include <vector>

#include "base/i18n/icu_string_conversions.h"
#include "base/metrics/histogram.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "net/base/net_errors.h"
#include "net/http/http_auth.h"
#include "net/http/http_request_info.h"

namespace spdyproxy {

using net::AuthCredentials;
using net::BoundNetLog;
using net::CompletionCallback;
using net::HttpAuth;
using net::HttpAuthHandler;
using net::HttpAuthHandlerFactory;
using net::HttpRequestInfo;
using net::HttpUtil;

HttpAuthHandlerSpdyProxy::Factory::Factory(
    const std::vector<GURL>& authorized_spdyproxy_origins) {
  for (unsigned int i = 0; i < authorized_spdyproxy_origins.size(); ++i) {
    if (authorized_spdyproxy_origins[i].possibly_invalid_spec().empty()) {
      VLOG(1) << "SpdyProxy auth without configuring authorized origin.";
      return;
    }
  }
  authorized_spdyproxy_origins_ = authorized_spdyproxy_origins;
}

HttpAuthHandlerSpdyProxy::Factory::~Factory() {
}

int HttpAuthHandlerSpdyProxy::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 a spdyproxy auth proxy has not been set, refuse all requests to use this
  // auth handler.
  if (authorized_spdyproxy_origins_.empty())
    return net::ERR_UNSUPPORTED_AUTH_SCHEME;

  // We ensure that this authentication handler is used only with an authorized
  // SPDY proxy, since otherwise a user's authentication token can be
  // sniffed by a malicious proxy that presents an appropriate challenge.
  const GURL origin_origin = origin.GetOrigin();
  if (!(std::find(authorized_spdyproxy_origins_.begin(),
                  authorized_spdyproxy_origins_.end(),
                  origin_origin) != authorized_spdyproxy_origins_.end())) {
    UMA_HISTOGRAM_COUNTS("Net.UnexpectedSpdyProxyAuth", 1);
    VLOG(1) << "SpdyProxy auth request with an unexpected config."
            << " origin: " << origin_origin.possibly_invalid_spec();
    return net::ERR_UNSUPPORTED_AUTH_SCHEME;
  }

  scoped_ptr<HttpAuthHandler> tmp_handler(new HttpAuthHandlerSpdyProxy());
  if (!tmp_handler->InitFromChallenge(challenge, target, origin, net_log))
    return net::ERR_INVALID_RESPONSE;
  handler->swap(tmp_handler);
  return net::OK;
}

HttpAuth::AuthorizationResult
HttpAuthHandlerSpdyProxy::HandleAnotherChallenge(
    HttpAuth::ChallengeTokenizer* challenge) {
  // SpdyProxy authentication is always a single round, so any responses
  // should be treated as a rejection.
  return HttpAuth::AUTHORIZATION_RESULT_REJECT;
}

bool HttpAuthHandlerSpdyProxy::NeedsIdentity() {
  return true;
}

bool HttpAuthHandlerSpdyProxy::AllowsDefaultCredentials() {
  return false;
}

bool HttpAuthHandlerSpdyProxy::AllowsExplicitCredentials() {
  return true;
}

HttpAuthHandlerSpdyProxy::~HttpAuthHandlerSpdyProxy() {}

bool HttpAuthHandlerSpdyProxy::Init(
    HttpAuth::ChallengeTokenizer* challenge) {
  auth_scheme_ = HttpAuth::AUTH_SCHEME_SPDYPROXY;
  score_ = 5;
  properties_ = ENCRYPTS_IDENTITY;
  return ParseChallenge(challenge);
}

int HttpAuthHandlerSpdyProxy::GenerateAuthTokenImpl(
    const AuthCredentials* credentials, const HttpRequestInfo* request,
    const CompletionCallback&, std::string* auth_token) {
  DCHECK(credentials);
  if (credentials->password().length() == 0) {
    DVLOG(1) << "Received a SpdyProxy auth token request without an "
             << "available token.";
    return -1;
  }
  *auth_token = "SpdyProxy ps=\"" + ps_token_ + "\", sid=\"" +
      UTF16ToUTF8(credentials->password()) + "\"";
  return net::OK;
}

bool HttpAuthHandlerSpdyProxy::ParseChallenge(
    HttpAuth::ChallengeTokenizer* challenge) {

  // Verify the challenge's auth-scheme.
  if (!LowerCaseEqualsASCII(challenge->scheme(), "spdyproxy")) {
    VLOG(1) << "Parsed challenge without SpdyProxy type";
    return false;
  }

  HttpUtil::NameValuePairsIterator parameters = challenge->param_pairs();

  // Loop through all the properties.
  while (parameters.GetNext()) {
    // FAIL -- couldn't parse a property.
    if (!ParseChallengeProperty(parameters.name(),
                                parameters.value()))
      return false;
  }
  // Check if tokenizer failed.
  if (!parameters.valid())
    return false;

  // Check that the required properties were provided.
  if (realm_.empty())
    return false;

  if (ps_token_.empty())
    return false;

  return true;
}

bool HttpAuthHandlerSpdyProxy::ParseChallengeProperty(
    const std::string& name, const std::string& value) {
  if (LowerCaseEqualsASCII(name, "realm")) {
    std::string realm;
    if (!base::ConvertToUtf8AndNormalize(value, base::kCodepageLatin1, &realm))
      return false;
    realm_ = realm;
  } else if (LowerCaseEqualsASCII(name, "ps")) {
    ps_token_ = value;
  } else {
    VLOG(1) << "Skipping unrecognized SpdyProxy auth property, " << name;
  }
  return true;
}

}  // namespace spdyproxy
