// Copyright 2014 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 "components/data_reduction_proxy/browser/data_reduction_proxy_auth_request_handler.h"

#include "base/bind.h"
#include "base/command_line.h"
#include "base/single_thread_task_runner.h"
#include "base/strings/string_split.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "base/time/time.h"
#include "components/data_reduction_proxy/browser/data_reduction_proxy_params.h"
#include "components/data_reduction_proxy/browser/data_reduction_proxy_protocol.h"
#include "components/data_reduction_proxy/browser/data_reduction_proxy_settings.h"
#include "components/data_reduction_proxy/common/data_reduction_proxy_headers.h"
#include "components/data_reduction_proxy/common/data_reduction_proxy_switches.h"
#include "components/data_reduction_proxy/common/version.h"
#include "crypto/random.h"
#include "net/proxy/proxy_server.h"
#include "net/url_request/url_request.h"
#include "url/gurl.h"

namespace data_reduction_proxy {

// The empty version for the authentication protocol. Currently used by
// Android webview.
#if defined(OS_ANDROID)
const char kAndroidWebViewProtocolVersion[] = "";
#endif

// The clients supported by the data reduction proxy.
const char kClientAndroidWebview[] = "webview";
const char kClientChromeAndroid[] = "android";
const char kClientChromeIOS[] = "ios";

// static
bool DataReductionProxyAuthRequestHandler::IsKeySetOnCommandLine() {
  const CommandLine& command_line = *CommandLine::ForCurrentProcess();
  return command_line.HasSwitch(
      data_reduction_proxy::switches::kDataReductionProxyKey);
}

DataReductionProxyAuthRequestHandler::DataReductionProxyAuthRequestHandler(
    const std::string& client,
    DataReductionProxyParams* params,
    scoped_refptr<base::SingleThreadTaskRunner> network_task_runner)
    : client_(client),
      data_reduction_proxy_params_(params),
      network_task_runner_(network_task_runner) {
  GetChromiumBuildAndPatch(ChromiumVersion(), &build_number_, &patch_number_);
  Init();
}

DataReductionProxyAuthRequestHandler::DataReductionProxyAuthRequestHandler(
    const std::string& client,
    const std::string& version,
    DataReductionProxyParams* params,
    scoped_refptr<base::SingleThreadTaskRunner> network_task_runner)
    : client_(client),
      data_reduction_proxy_params_(params),
      network_task_runner_(network_task_runner) {
  GetChromiumBuildAndPatch(version, &build_number_, &patch_number_);
  Init();
}

std::string DataReductionProxyAuthRequestHandler::ChromiumVersion() const {
#if defined(PRODUCT_VERSION)
  return PRODUCT_VERSION;
#else
  return std::string();
#endif
}


void DataReductionProxyAuthRequestHandler::GetChromiumBuildAndPatch(
    const std::string& version,
    std::string* build,
    std::string* patch) const {
  std::vector<std::string> version_parts;
  base::SplitString(version, '.', &version_parts);
  if (version_parts.size() != 4)
    return;
  *build = version_parts[2];
  *patch = version_parts[3];
}

void DataReductionProxyAuthRequestHandler::Init() {
  InitAuthenticationOnUI(GetDefaultKey());
}


DataReductionProxyAuthRequestHandler::~DataReductionProxyAuthRequestHandler() {
}

// static
base::string16 DataReductionProxyAuthRequestHandler::AuthHashForSalt(
    int64 salt,
    const std::string& key) {
  std::string salted_key =
      base::StringPrintf("%lld%s%lld",
                         static_cast<long long>(salt),
                         key.c_str(),
                         static_cast<long long>(salt));
  return base::UTF8ToUTF16(base::MD5String(salted_key));
}



base::Time DataReductionProxyAuthRequestHandler::Now() const {
  return base::Time::Now();
}

void DataReductionProxyAuthRequestHandler::RandBytes(
    void* output, size_t length) {
  crypto::RandBytes(output, length);
}

void DataReductionProxyAuthRequestHandler::MaybeAddRequestHeader(
    net::URLRequest* request,
    const net::ProxyServer& proxy_server,
    net::HttpRequestHeaders* request_headers) {
  DCHECK(network_task_runner_->BelongsToCurrentThread());
  if (!proxy_server.is_valid())
    return;
  if (data_reduction_proxy_params_ &&
      data_reduction_proxy_params_->IsDataReductionProxy(
          proxy_server.host_port_pair(), NULL)) {
    AddAuthorizationHeader(request_headers);
  }
}

void DataReductionProxyAuthRequestHandler::AddAuthorizationHeader(
    net::HttpRequestHeaders* headers) {
  base::Time now = Now();
  if (now - last_update_time_ > base::TimeDelta::FromHours(24)) {
    last_update_time_ = now;
    ComputeCredentials(last_update_time_, &session_, &credentials_);
  }
  const char kChromeProxyHeader[] = "Chrome-Proxy";
  std::string header_value;
  if (headers->HasHeader(kChromeProxyHeader)) {
    headers->GetHeader(kChromeProxyHeader, &header_value);
    headers->RemoveHeader(kChromeProxyHeader);
    header_value += ", ";
  }
  header_value +=
      "ps=" + session_ + ", sid=" + credentials_;
  if (!build_number_.empty() && !patch_number_.empty())
    header_value += ", b=" + build_number_ + ", p=" + patch_number_;
  if (!client_.empty())
    header_value += ", c=" + client_;
  headers->SetHeader(kChromeProxyHeader, header_value);
}

void DataReductionProxyAuthRequestHandler::InitAuthenticationOnUI(
    const std::string& key) {
  network_task_runner_->PostTask(FROM_HERE, base::Bind(
      &DataReductionProxyAuthRequestHandler::InitAuthentication,
      base::Unretained(this),
      key));
}

void DataReductionProxyAuthRequestHandler::ComputeCredentials(
    const base::Time& now,
    std::string* session,
    std::string* credentials) {
  DCHECK(session);
  DCHECK(credentials);
  int64 timestamp =
      (now - base::Time::UnixEpoch()).InMilliseconds() / 1000;

  int32 rand[3];
  RandBytes(rand, 3 * sizeof(rand[0]));
  *session = base::StringPrintf("%lld-%u-%u-%u",
                                static_cast<long long>(timestamp),
                                rand[0],
                                rand[1],
                                rand[2]);
  *credentials = base::UTF16ToUTF8(AuthHashForSalt(timestamp, key_));

  DVLOG(1) << "session: [" << *session << "] "
           << "password: [" << *credentials  << "]";
}

void DataReductionProxyAuthRequestHandler::InitAuthentication(
    const std::string& key) {
  DCHECK(network_task_runner_->BelongsToCurrentThread());
  key_ = key;
  last_update_time_ = Now();
  ComputeCredentials(last_update_time_, &session_, &credentials_);
}

void DataReductionProxyAuthRequestHandler::SetKeyOnUI(const std::string& key) {
  if (!key.empty())
    InitAuthenticationOnUI(key);
}


std::string DataReductionProxyAuthRequestHandler::GetDefaultKey() const {
  const CommandLine& command_line = *CommandLine::ForCurrentProcess();
  std::string key =
    command_line.GetSwitchValueASCII(switches::kDataReductionProxyKey);
#if defined(SPDY_PROXY_AUTH_VALUE)
  if (key.empty())
    key = SPDY_PROXY_AUTH_VALUE;
#endif
  return key;
}

}  // namespace data_reduction_proxy
