// 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 "chrome/browser/ssl/ssl_error_handler.h"

#include <stdint.h>
#include <utility>

#include "base/callback_helpers.h"
#include "base/macros.h"
#include "base/metrics/field_trial.h"
#include "base/metrics/histogram.h"
#include "base/strings/stringprintf.h"
#include "base/time/clock.h"
#include "base/time/time.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ssl/bad_clock_blocking_page.h"
#include "chrome/browser/ssl/ssl_blocking_page.h"
#include "chrome/browser/ssl/ssl_cert_reporter.h"
#include "components/ssl_errors/error_classification.h"
#include "components/ssl_errors/error_info.h"
#include "content/public/browser/notification_service.h"
#include "content/public/browser/notification_source.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/web_contents.h"
#include "net/base/net_errors.h"

#if defined(ENABLE_CAPTIVE_PORTAL_DETECTION)
#include "chrome/browser/captive_portal/captive_portal_service.h"
#include "chrome/browser/captive_portal/captive_portal_service_factory.h"
#include "chrome/browser/captive_portal/captive_portal_tab_helper.h"
#include "chrome/browser/ssl/captive_portal_blocking_page.h"
#endif

namespace {

// The delay in milliseconds before displaying the SSL interstitial.
// This can be changed in tests.
// - If there is a name mismatch and a suggested URL available result arrives
//   during this time, the user is redirected to the suggester URL.
// - If a "captive portal detected" result arrives during this time,
//   a captive portal interstitial is displayed.
// - Otherwise, an SSL interstitial is displayed.
int64_t g_interstitial_delay_in_milliseconds = 2000;

// Callback to call when the interstitial timer is started. Used for testing.
SSLErrorHandler::TimerStartedCallback* g_timer_started_callback = nullptr;

// The clock to use when deciding which error type to display. Used for testing.
base::Clock* g_testing_clock = nullptr;

// Events for UMA.
enum SSLErrorHandlerEvent {
  HANDLE_ALL,
  SHOW_CAPTIVE_PORTAL_INTERSTITIAL_NONOVERRIDABLE,
  SHOW_CAPTIVE_PORTAL_INTERSTITIAL_OVERRIDABLE,
  SHOW_SSL_INTERSTITIAL_NONOVERRIDABLE,
  SHOW_SSL_INTERSTITIAL_OVERRIDABLE,
  WWW_MISMATCH_FOUND,
  WWW_MISMATCH_URL_AVAILABLE,
  WWW_MISMATCH_URL_NOT_AVAILABLE,
  SHOW_BAD_CLOCK,
  SSL_ERROR_HANDLER_EVENT_COUNT
};

// Adds a message to console after navigation commits and then, deletes itself.
// Also deletes itself if the navigation is stopped.
class CommonNameMismatchRedirectObserver
    : public content::WebContentsObserver,
      public content::WebContentsUserData<CommonNameMismatchRedirectObserver> {
 public:
  static void AddToConsoleAfterNavigation(
      content::WebContents* web_contents,
      const std::string& request_url_hostname,
      const std::string& suggested_url_hostname) {
    web_contents->SetUserData(
        UserDataKey(),
        new CommonNameMismatchRedirectObserver(
            web_contents, request_url_hostname, suggested_url_hostname));
  }

 private:
  CommonNameMismatchRedirectObserver(content::WebContents* web_contents,
                                     const std::string& request_url_hostname,
                                     const std::string& suggested_url_hostname)
      : WebContentsObserver(web_contents),
        web_contents_(web_contents),
        request_url_hostname_(request_url_hostname),
        suggested_url_hostname_(suggested_url_hostname) {}
  ~CommonNameMismatchRedirectObserver() override {}

  // WebContentsObserver:
  void NavigationStopped() override {
    // Deletes |this|.
    web_contents_->RemoveUserData(UserDataKey());
  }

  void NavigationEntryCommitted(
      const content::LoadCommittedDetails& /* load_details */) override {
    web_contents_->GetMainFrame()->AddMessageToConsole(
        content::CONSOLE_MESSAGE_LEVEL_LOG,
        base::StringPrintf(
            "Redirecting navigation %s -> %s because the server presented a "
            "certificate valid for %s but not for %s.",
            request_url_hostname_.c_str(), suggested_url_hostname_.c_str(),
            suggested_url_hostname_.c_str(), request_url_hostname_.c_str()));
    web_contents_->RemoveUserData(UserDataKey());
  }

  void WebContentsDestroyed() override {
    web_contents_->RemoveUserData(UserDataKey());
  }

  content::WebContents* web_contents_;
  const std::string request_url_hostname_;
  const std::string suggested_url_hostname_;

  DISALLOW_COPY_AND_ASSIGN(CommonNameMismatchRedirectObserver);
};

void RecordUMA(SSLErrorHandlerEvent event) {
  UMA_HISTOGRAM_ENUMERATION("interstitial.ssl_error_handler", event,
                            SSL_ERROR_HANDLER_EVENT_COUNT);
}

#if defined(ENABLE_CAPTIVE_PORTAL_DETECTION)
bool IsCaptivePortalInterstitialEnabled() {
  return base::FieldTrialList::FindFullName("CaptivePortalInterstitial") ==
         "Enabled";
}
#endif

bool IsSSLCommonNameMismatchHandlingEnabled() {
  return base::FieldTrialList::FindFullName("SSLCommonNameMismatchHandling") ==
         "Enabled";
}

bool IsErrorDueToBadClock(const base::Time& now, int error) {
  if (ssl_errors::ErrorInfo::NetErrorToErrorType(error) !=
      ssl_errors::ErrorInfo::CERT_DATE_INVALID) {
    return false;
  }
  return ssl_errors::IsUserClockInThePast(now) ||
         ssl_errors::IsUserClockInTheFuture(now);
}

}  // namespace

DEFINE_WEB_CONTENTS_USER_DATA_KEY(SSLErrorHandler);
DEFINE_WEB_CONTENTS_USER_DATA_KEY(CommonNameMismatchRedirectObserver);

void SSLErrorHandler::HandleSSLError(
    content::WebContents* web_contents,
    int cert_error,
    const net::SSLInfo& ssl_info,
    const GURL& request_url,
    int options_mask,
    scoped_ptr<SSLCertReporter> ssl_cert_reporter,
    const base::Callback<void(bool)>& callback) {
  DCHECK(!FromWebContents(web_contents));
  SSLErrorHandler* error_handler =
      new SSLErrorHandler(web_contents, cert_error, ssl_info, request_url,
                          options_mask, std::move(ssl_cert_reporter), callback);
  web_contents->SetUserData(UserDataKey(), error_handler);
  error_handler->StartHandlingError();
}

// static
void SSLErrorHandler::SetInterstitialDelayForTest(base::TimeDelta delay) {
  g_interstitial_delay_in_milliseconds = delay.InMilliseconds();
}

// static
void SSLErrorHandler::SetInterstitialTimerStartedCallbackForTest(
    TimerStartedCallback* callback) {
  DCHECK(!callback || !callback->is_null());
  g_timer_started_callback = callback;
}

// static
void SSLErrorHandler::SetClockForTest(base::Clock* testing_clock) {
  g_testing_clock = testing_clock;
}

SSLErrorHandler::SSLErrorHandler(content::WebContents* web_contents,
                                 int cert_error,
                                 const net::SSLInfo& ssl_info,
                                 const GURL& request_url,
                                 int options_mask,
                                 scoped_ptr<SSLCertReporter> ssl_cert_reporter,
                                 const base::Callback<void(bool)>& callback)
    : content::WebContentsObserver(web_contents),
      web_contents_(web_contents),
      cert_error_(cert_error),
      ssl_info_(ssl_info),
      request_url_(request_url),
      options_mask_(options_mask),
      callback_(callback),
      profile_(Profile::FromBrowserContext(web_contents->GetBrowserContext())),
      ssl_cert_reporter_(std::move(ssl_cert_reporter)) {}

SSLErrorHandler::~SSLErrorHandler() {
}

void SSLErrorHandler::StartHandlingError() {
  RecordUMA(HANDLE_ALL);

  const base::Time now = g_testing_clock == nullptr
                             ? base::Time::NowFromSystemTime()
                             : g_testing_clock->Now();
  if (IsErrorDueToBadClock(now, cert_error_)) {
    ShowBadClockInterstitial(now);
    return;  // |this| is deleted after showing the interstitial.
  }

  std::vector<std::string> dns_names;
  ssl_info_.cert->GetDNSNames(&dns_names);
  DCHECK(!dns_names.empty());
  GURL suggested_url;
  if (IsSSLCommonNameMismatchHandlingEnabled() &&
      cert_error_ == net::ERR_CERT_COMMON_NAME_INVALID &&
      IsErrorOverridable() && GetSuggestedUrl(dns_names, &suggested_url)) {
    RecordUMA(WWW_MISMATCH_FOUND);
    net::CertStatus extra_cert_errors =
        ssl_info_.cert_status ^ net::CERT_STATUS_COMMON_NAME_INVALID;

    // Show the SSL intersitial if |CERT_STATUS_COMMON_NAME_INVALID| is not
    // the only error. Need not check for captive portal in this case.
    // (See the comment below).
    if (net::IsCertStatusError(extra_cert_errors) &&
        !net::IsCertStatusMinorError(ssl_info_.cert_status)) {
      ShowSSLInterstitial();
      return;
    }
    CheckSuggestedUrl(suggested_url);
    timer_.Start(FROM_HERE, base::TimeDelta::FromMilliseconds(
                                g_interstitial_delay_in_milliseconds),
                 this, &SSLErrorHandler::ShowSSLInterstitial);
    if (g_timer_started_callback)
      g_timer_started_callback->Run(web_contents_);

    // Do not check for a captive portal in this case, because a captive
    // portal most likely cannot serve a valid certificate which passes the
    // similarity check.
    return;
  }

#if defined(ENABLE_CAPTIVE_PORTAL_DETECTION)
  CaptivePortalTabHelper* captive_portal_tab_helper =
      CaptivePortalTabHelper::FromWebContents(web_contents_);
  if (captive_portal_tab_helper) {
    captive_portal_tab_helper->OnSSLCertError(ssl_info_);
  }

  registrar_.Add(this, chrome::NOTIFICATION_CAPTIVE_PORTAL_CHECK_RESULT,
                 content::Source<Profile>(profile_));

  if (IsCaptivePortalInterstitialEnabled()) {
    CheckForCaptivePortal();
    timer_.Start(FROM_HERE, base::TimeDelta::FromMilliseconds(
                                g_interstitial_delay_in_milliseconds),
                 this, &SSLErrorHandler::ShowSSLInterstitial);
    if (g_timer_started_callback)
      g_timer_started_callback->Run(web_contents_);
    return;
  }
#endif
  // Display an SSL interstitial.
  ShowSSLInterstitial();
}

void SSLErrorHandler::CheckForCaptivePortal() {
#if defined(ENABLE_CAPTIVE_PORTAL_DETECTION)
  CaptivePortalService* captive_portal_service =
      CaptivePortalServiceFactory::GetForProfile(profile_);
  captive_portal_service->DetectCaptivePortal();
#else
  NOTREACHED();
#endif
}

bool SSLErrorHandler::GetSuggestedUrl(const std::vector<std::string>& dns_names,
                                      GURL* suggested_url) const {
  return CommonNameMismatchHandler::GetSuggestedUrl(request_url_, dns_names,
                                                    suggested_url);
}

void SSLErrorHandler::CheckSuggestedUrl(const GURL& suggested_url) {
  scoped_refptr<net::URLRequestContextGetter> request_context(
      profile_->GetRequestContext());
  common_name_mismatch_handler_.reset(
      new CommonNameMismatchHandler(request_url_, request_context));

  common_name_mismatch_handler_->CheckSuggestedUrl(
      suggested_url,
      base::Bind(&SSLErrorHandler::CommonNameMismatchHandlerCallback,
                 base::Unretained(this)));
}

void SSLErrorHandler::NavigateToSuggestedURL(const GURL& suggested_url) {
  content::NavigationController::LoadURLParams load_params(suggested_url);
  load_params.transition_type = ui::PAGE_TRANSITION_TYPED;
  web_contents()->GetController().LoadURLWithParams(load_params);
}

bool SSLErrorHandler::IsErrorOverridable() const {
  return SSLBlockingPage::IsOverridable(options_mask_, profile_);
}

void SSLErrorHandler::ShowCaptivePortalInterstitial(const GURL& landing_url) {
#if defined(ENABLE_CAPTIVE_PORTAL_DETECTION)
  // Show captive portal blocking page. The interstitial owns the blocking page.
  RecordUMA(IsErrorOverridable()
                ? SHOW_CAPTIVE_PORTAL_INTERSTITIAL_OVERRIDABLE
                : SHOW_CAPTIVE_PORTAL_INTERSTITIAL_NONOVERRIDABLE);
  (new CaptivePortalBlockingPage(web_contents_, request_url_, landing_url,
                                 std::move(ssl_cert_reporter_), ssl_info_,
                                 callback_))
      ->Show();
  // Once an interstitial is displayed, no need to keep the handler around.
  // This is the equivalent of "delete this". It also destroys the timer.
  web_contents_->RemoveUserData(UserDataKey());
#else
  NOTREACHED();
#endif
}

void SSLErrorHandler::ShowSSLInterstitial() {
  // Show SSL blocking page. The interstitial owns the blocking page.
  RecordUMA(IsErrorOverridable() ? SHOW_SSL_INTERSTITIAL_OVERRIDABLE
                                 : SHOW_SSL_INTERSTITIAL_NONOVERRIDABLE);

  (new SSLBlockingPage(web_contents_, cert_error_, ssl_info_, request_url_,
                       options_mask_, base::Time::NowFromSystemTime(),
                       std::move(ssl_cert_reporter_), callback_))
      ->Show();
  // Once an interstitial is displayed, no need to keep the handler around.
  // This is the equivalent of "delete this".
  web_contents_->RemoveUserData(UserDataKey());
}

void SSLErrorHandler::ShowBadClockInterstitial(const base::Time& now) {
  RecordUMA(SHOW_BAD_CLOCK);
  (new BadClockBlockingPage(web_contents_, cert_error_, ssl_info_, request_url_,
                            now, std::move(ssl_cert_reporter_), callback_))
      ->Show();
  // Once an interstitial is displayed, no need to keep the handler around.
  // This is the equivalent of "delete this".
  web_contents_->RemoveUserData(UserDataKey());
}

void SSLErrorHandler::CommonNameMismatchHandlerCallback(
    const CommonNameMismatchHandler::SuggestedUrlCheckResult& result,
    const GURL& suggested_url) {
  timer_.Stop();
  if (result == CommonNameMismatchHandler::SuggestedUrlCheckResult::
                    SUGGESTED_URL_AVAILABLE) {
    RecordUMA(WWW_MISMATCH_URL_AVAILABLE);
    CommonNameMismatchRedirectObserver::AddToConsoleAfterNavigation(
        web_contents(), request_url_.host(), suggested_url.host());
    NavigateToSuggestedURL(suggested_url);
  } else {
    RecordUMA(WWW_MISMATCH_URL_NOT_AVAILABLE);
    ShowSSLInterstitial();
  }
}

void SSLErrorHandler::Observe(
    int type,
    const content::NotificationSource& source,
    const content::NotificationDetails& details) {
#if defined(ENABLE_CAPTIVE_PORTAL_DETECTION)
  if (type == chrome::NOTIFICATION_CAPTIVE_PORTAL_CHECK_RESULT) {
    timer_.Stop();
    CaptivePortalService::Results* results =
        content::Details<CaptivePortalService::Results>(details).ptr();
    if (results->result == captive_portal::RESULT_BEHIND_CAPTIVE_PORTAL)
      ShowCaptivePortalInterstitial(results->landing_url);
    else
      ShowSSLInterstitial();
  }
#endif
}

void SSLErrorHandler::DidStartNavigationToPendingEntry(
    const GURL& /* url */,
    content::NavigationController::ReloadType /* reload_type */) {
// Destroy the error handler on all new navigations. This ensures that the
// handler is properly recreated when a hanging page is navigated to an SSL
// error, even when the tab's WebContents doesn't change.
  DeleteSSLErrorHandler();
}

void SSLErrorHandler::NavigationStopped() {
// Destroy the error handler when the page load is stopped.
  DeleteSSLErrorHandler();
}

void SSLErrorHandler::DeleteSSLErrorHandler() {
  // Need to explicity deny the certificate via the callback, otherwise memory
  // is leaked.
  if (!callback_.is_null()) {
    base::ResetAndReturn(&callback_).Run(false);
  }
  if (common_name_mismatch_handler_) {
    common_name_mismatch_handler_->Cancel();
    common_name_mismatch_handler_.reset();
  }
  // Deletes |this| and also destroys the timer.
  web_contents_->RemoveUserData(UserDataKey());
}
