blob: aecb59e2cad35c15b4dbf18f135b5a1474c5374e [file] [log] [blame]
// Copyright 2021 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 "services/network/sct_auditing/sct_auditing_handler.h"
#include "base/metrics/histogram_functions.h"
#include "base/time/time.h"
#include "net/base/hash_value.h"
#include "net/traffic_annotation/network_traffic_annotation.h"
#include "services/network/network_context.h"
#include "services/network/network_service.h"
#include "services/network/public/mojom/network_context.mojom.h"
#include "services/network/public/mojom/url_loader_factory.mojom.h"
#include "services/network/public/proto/sct_audit_report.pb.h"
#include "services/network/sct_auditing/sct_auditing_cache.h"
#include "services/network/sct_auditing/sct_auditing_reporter.h"
namespace network {
SCTAuditingHandler::SCTAuditingHandler(NetworkContext* context,
size_t cache_size)
: owner_network_context_(context), pending_reporters_(cache_size) {}
SCTAuditingHandler::~SCTAuditingHandler() = default;
void SCTAuditingHandler::AddReporter(
net::HashValue reporter_key,
std::unique_ptr<sct_auditing::SCTClientReport> report) {
if (!enabled_) {
return;
}
// Get the ReportURI and traffic annotation as configured on the
// SCTAuditingCache.
auto report_uri = owner_network_context_->network_service()
->sct_auditing_cache()
->report_uri();
auto traffic_annotation = owner_network_context_->network_service()
->sct_auditing_cache()
->traffic_annotation();
auto reporter = std::make_unique<SCTAuditingReporter>(
reporter_key, std::move(report), GetURLLoaderFactory(), report_uri,
traffic_annotation,
base::BindOnce(&SCTAuditingHandler::OnReporterFinished, GetWeakPtr()));
reporter->Start();
pending_reporters_.Put(reporter->key(), std::move(reporter));
if (pending_reporters_.size() > pending_reporters_size_hwm_)
pending_reporters_size_hwm_ = pending_reporters_.size();
}
void SCTAuditingHandler::ClearPendingReports() {
// Delete any outstanding Reporters. This will delete any extant URLLoader
// instances owned by the Reporters, which will cancel any outstanding
// requests/connections. Pending (delayed) retry tasks will fast-fail when
// they trigger as they use a WeakPtr to the Reporter instance that posted the
// task.
pending_reporters_.Clear();
// TODO(crbug.com/1144205): Clear any persisted state.
}
void SCTAuditingHandler::SetEnabled(bool enabled) {
enabled_ = enabled;
// High-water-mark metrics get logged hourly (rather than once-per-session at
// shutdown, as Network Service shutdown is not consistent and non-browser
// processes can fail to report metrics during shutdown). The timer should
// only be running if SCT auditing is enabled.
if (enabled) {
histogram_timer_.Start(FROM_HERE, base::Hours(1), this,
&SCTAuditingHandler::ReportHWMMetrics);
} else {
histogram_timer_.Stop();
ClearPendingReports();
}
}
base::WeakPtr<SCTAuditingHandler> SCTAuditingHandler::GetWeakPtr() {
return weak_factory_.GetWeakPtr();
}
void SCTAuditingHandler::OnReporterFinished(net::HashValue reporter_key) {
auto it = pending_reporters_.Get(reporter_key);
if (it != pending_reporters_.end()) {
pending_reporters_.Erase(it);
}
}
void SCTAuditingHandler::ReportHWMMetrics() {
if (!enabled_) {
return;
}
base::UmaHistogramCounts1000("Security.SCTAuditing.OptIn.ReportersHWM",
pending_reporters_size_hwm_);
}
network::mojom::URLLoaderFactory* SCTAuditingHandler::GetURLLoaderFactory() {
// Create the URLLoaderFactory as needed.
if (url_loader_factory_ && url_loader_factory_.is_connected()) {
return url_loader_factory_.get();
}
network::mojom::URLLoaderFactoryParamsPtr params =
network::mojom::URLLoaderFactoryParams::New();
params->process_id = network::mojom::kBrowserProcessId;
params->is_corb_enabled = false;
params->is_trusted = true;
params->automatically_assign_isolation_info = true;
url_loader_factory_.reset();
owner_network_context_->CreateURLLoaderFactory(
url_loader_factory_.BindNewPipeAndPassReceiver(), std::move(params));
return url_loader_factory_.get();
}
} // namespace network