// Copyright 2015 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 "content/browser/devtools/protocol/security_handler.h"

#include <memory>
#include <string>
#include <utility>
#include <vector>

#include "base/base64.h"
#include "content/browser/devtools/devtools_session.h"
#include "content/browser/frame_host/render_frame_host_impl.h"
#include "content/public/browser/navigation_controller.h"
#include "content/public/browser/navigation_entry.h"
#include "content/public/browser/security_style_explanations.h"
#include "content/public/browser/ssl_status.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_contents_delegate.h"
#include "net/cert/x509_certificate.h"
#include "net/cert/x509_util.h"
#include "third_party/WebKit/public/platform/WebMixedContentContextType.h"

namespace content {
namespace protocol {

using Explanations = protocol::Array<Security::SecurityStateExplanation>;

namespace {

std::string SecurityStyleToProtocolSecurityState(
    blink::WebSecurityStyle security_style) {
  switch (security_style) {
    case blink::kWebSecurityStyleUnknown:
      return Security::SecurityStateEnum::Unknown;
    case blink::kWebSecurityStyleNeutral:
      return Security::SecurityStateEnum::Neutral;
    case blink::kWebSecurityStyleInsecure:
      return Security::SecurityStateEnum::Insecure;
    case blink::kWebSecurityStyleSecure:
      return Security::SecurityStateEnum::Secure;
    default:
      NOTREACHED();
      return Security::SecurityStateEnum::Unknown;
  }
}

std::string MixedContentTypeToProtocolMixedContentType(
    blink::WebMixedContentContextType mixed_content_type) {
  switch (mixed_content_type) {
    case blink::WebMixedContentContextType::kNotMixedContent:
      return Security::MixedContentTypeEnum::None;
    case blink::WebMixedContentContextType::kBlockable:
      return Security::MixedContentTypeEnum::Blockable;
    case blink::WebMixedContentContextType::kOptionallyBlockable:
      return Security::MixedContentTypeEnum::OptionallyBlockable;
    case blink::WebMixedContentContextType::kShouldBeBlockable:
      // kShouldBeBlockable is not used for explanations.
      NOTREACHED();
      return Security::MixedContentTypeEnum::OptionallyBlockable;
    default:
      NOTREACHED();
      return Security::MixedContentTypeEnum::None;
  }
}

void AddExplanations(
    const std::string& security_style,
    const std::vector<SecurityStyleExplanation>& explanations_to_add,
    Explanations* explanations) {
  for (const auto& it : explanations_to_add) {
    std::unique_ptr<protocol::Array<String>> certificate =
        protocol::Array<String>::create();
    if (it.certificate) {
      std::string encoded;
      base::Base64Encode(net::x509_util::CryptoBufferAsStringPiece(
                             it.certificate->cert_buffer()),
                         &encoded);
      certificate->addItem(encoded);

      for (const auto& cert : it.certificate->intermediate_buffers()) {
        base::Base64Encode(
            net::x509_util::CryptoBufferAsStringPiece(cert.get()), &encoded);
        certificate->addItem(encoded);
      }
    }

    explanations->addItem(
        Security::SecurityStateExplanation::Create()
            .SetSecurityState(security_style)
            .SetTitle(it.title)
            .SetSummary(it.summary)
            .SetDescription(it.description)
            .SetCertificate(std::move(certificate))
            .SetMixedContentType(MixedContentTypeToProtocolMixedContentType(
                it.mixed_content_type))
            .Build());
  }
}

}  // namespace

// static
std::vector<SecurityHandler*> SecurityHandler::ForAgentHost(
    DevToolsAgentHostImpl* host) {
  return DevToolsSession::HandlersForAgentHost<SecurityHandler>(
      host, Security::Metainfo::domainName);
}

SecurityHandler::SecurityHandler()
    : DevToolsDomainHandler(Security::Metainfo::domainName),
      enabled_(false),
      host_(nullptr) {
}

SecurityHandler::~SecurityHandler() {
}

void SecurityHandler::Wire(UberDispatcher* dispatcher) {
  frontend_.reset(new Security::Frontend(dispatcher->channel()));
  Security::Dispatcher::wire(dispatcher, this);
}

void SecurityHandler::AttachToRenderFrameHost() {
  DCHECK(host_);
  WebContents* web_contents = WebContents::FromRenderFrameHost(host_);
  WebContentsObserver::Observe(web_contents);

  // Send an initial DidChangeVisibleSecurityState event.
  DCHECK(enabled_);
  DidChangeVisibleSecurityState();
}

void SecurityHandler::SetRenderer(int process_host_id,
                                  RenderFrameHostImpl* frame_host) {
  host_ = frame_host;
  if (enabled_ && host_)
    AttachToRenderFrameHost();
}

void SecurityHandler::DidChangeVisibleSecurityState() {
  DCHECK(enabled_);
  if (!web_contents()->GetDelegate())
    return;

  SecurityStyleExplanations security_style_explanations;
  blink::WebSecurityStyle security_style =
      web_contents()->GetDelegate()->GetSecurityStyle(
          web_contents(), &security_style_explanations);

  const std::string security_state =
      SecurityStyleToProtocolSecurityState(security_style);

  std::unique_ptr<Explanations> explanations = Explanations::create();
  AddExplanations(Security::SecurityStateEnum::Insecure,
                  security_style_explanations.insecure_explanations,
                  explanations.get());
  AddExplanations(Security::SecurityStateEnum::Neutral,
                  security_style_explanations.neutral_explanations,
                  explanations.get());
  AddExplanations(Security::SecurityStateEnum::Secure,
                  security_style_explanations.secure_explanations,
                  explanations.get());
  AddExplanations(Security::SecurityStateEnum::Info,
                  security_style_explanations.info_explanations,
                  explanations.get());

  std::unique_ptr<Security::InsecureContentStatus> insecure_status =
      Security::InsecureContentStatus::Create()
          .SetRanMixedContent(security_style_explanations.ran_mixed_content)
          .SetDisplayedMixedContent(
              security_style_explanations.displayed_mixed_content)
          .SetContainedMixedForm(
              security_style_explanations.contained_mixed_form)
          .SetRanContentWithCertErrors(
              security_style_explanations.ran_content_with_cert_errors)
          .SetDisplayedContentWithCertErrors(
              security_style_explanations.displayed_content_with_cert_errors)
          .SetRanInsecureContentStyle(SecurityStyleToProtocolSecurityState(
              security_style_explanations.ran_insecure_content_style))
          .SetDisplayedInsecureContentStyle(
              SecurityStyleToProtocolSecurityState(
                  security_style_explanations.displayed_insecure_content_style))
          .Build();

  frontend_->SecurityStateChanged(
      security_state,
      security_style_explanations.scheme_is_cryptographic,
      std::move(explanations),
      std::move(insecure_status),
      Maybe<std::string>(security_style_explanations.summary));
}

void SecurityHandler::DidFinishNavigation(NavigationHandle* navigation_handle) {
  if (cert_error_override_mode_ == CertErrorOverrideMode::kHandleEvents)
    FlushPendingCertificateErrorNotifications();
}

void SecurityHandler::FlushPendingCertificateErrorNotifications() {
  for (auto callback : cert_error_callbacks_)
    callback.second.Run(content::CERTIFICATE_REQUEST_RESULT_TYPE_CANCEL);
  cert_error_callbacks_.clear();
}

bool SecurityHandler::NotifyCertificateError(int cert_error,
                                             const GURL& request_url,
                                             CertErrorCallback handler) {
  if (cert_error_override_mode_ == CertErrorOverrideMode::kIgnoreAll) {
    if (handler)
      handler.Run(content::CERTIFICATE_REQUEST_RESULT_TYPE_CONTINUE);
    return true;
  }

  if (!enabled_)
    return false;

  frontend_->CertificateError(++last_cert_error_id_,
                              net::ErrorToShortString(cert_error),
                              request_url.spec());

  if (!handler ||
      cert_error_override_mode_ != CertErrorOverrideMode::kHandleEvents) {
    return false;
  }

  cert_error_callbacks_[last_cert_error_id_] = handler;
  return true;
}

Response SecurityHandler::Enable() {
  enabled_ = true;
  if (host_)
    AttachToRenderFrameHost();

  return Response::OK();
}

Response SecurityHandler::Disable() {
  enabled_ = false;
  cert_error_override_mode_ = CertErrorOverrideMode::kDisabled;
  WebContentsObserver::Observe(nullptr);
  FlushPendingCertificateErrorNotifications();
  return Response::OK();
}

Response SecurityHandler::HandleCertificateError(int event_id,
                                                 const String& action) {
  if (cert_error_callbacks_.find(event_id) == cert_error_callbacks_.end()) {
    return Response::Error(
        String("Unknown event id: " + std::to_string(event_id)));
  }
  content::CertificateRequestResultType type =
      content::CERTIFICATE_REQUEST_RESULT_TYPE_CANCEL;
  Response response = Response::OK();
  if (action == Security::CertificateErrorActionEnum::Continue) {
    type = content::CERTIFICATE_REQUEST_RESULT_TYPE_CONTINUE;
  } else if (action == Security::CertificateErrorActionEnum::Cancel) {
    type = content::CERTIFICATE_REQUEST_RESULT_TYPE_CANCEL;
  } else {
    response =
        Response::Error(String("Unknown Certificate Error Action: " + action));
  }
  cert_error_callbacks_[event_id].Run(type);
  cert_error_callbacks_.erase(event_id);
  return response;
}

Response SecurityHandler::SetOverrideCertificateErrors(bool override) {
  if (override) {
    if (!enabled_)
      return Response::Error("Security domain not enabled");
    if (cert_error_override_mode_ == CertErrorOverrideMode::kIgnoreAll)
      return Response::Error("Certificate errors are already being ignored.");
    cert_error_override_mode_ = CertErrorOverrideMode::kHandleEvents;
  } else {
    cert_error_override_mode_ = CertErrorOverrideMode::kDisabled;
    FlushPendingCertificateErrorNotifications();
  }
  return Response::OK();
}

Response SecurityHandler::SetIgnoreCertificateErrors(bool ignore) {
  if (ignore) {
    if (cert_error_override_mode_ == CertErrorOverrideMode::kHandleEvents)
      return Response::Error("Certificate errors are already overridden.");
    cert_error_override_mode_ = CertErrorOverrideMode::kIgnoreAll;
  } else {
    cert_error_override_mode_ = CertErrorOverrideMode::kDisabled;
  }
  return Response::OK();
}

}  // namespace protocol
}  // namespace content
