blob: 82bb1b421758e378ce76f6c585872fab876bee16 [file] [log] [blame]
// Copyright 2013 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/chromeos/policy/user_network_configuration_updater.h"
#include <utility>
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/logging.h"
#include "base/task/post_task.h"
#include "base/values.h"
#include "chrome/browser/chrome_notification_types.h"
#include "chrome/browser/chromeos/login/session/user_session_manager.h"
#include "chrome/browser/net/nss_context.h"
#include "chrome/browser/profiles/profile.h"
#include "chromeos/network/managed_network_configuration_handler.h"
#include "chromeos/network/network_cert_loader.h"
#include "chromeos/network/onc/onc_certificate_importer_impl.h"
#include "chromeos/network/onc/onc_parsed_certificates.h"
#include "chromeos/network/onc/onc_utils.h"
#include "components/policy/policy_constants.h"
#include "components/user_manager/user.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/notification_source.h"
namespace policy {
UserNetworkConfigurationUpdater::~UserNetworkConfigurationUpdater() {
// NetworkCertLoader may be not initialized in tests.
if (chromeos::NetworkCertLoader::IsInitialized()) {
chromeos::NetworkCertLoader::Get()->SetUserPolicyCertificateProvider(
nullptr);
}
}
// static
std::unique_ptr<UserNetworkConfigurationUpdater>
UserNetworkConfigurationUpdater::CreateForUserPolicy(
Profile* profile,
bool allow_trusted_certs_from_policy,
const user_manager::User& user,
PolicyService* policy_service,
chromeos::ManagedNetworkConfigurationHandler* network_config_handler) {
std::unique_ptr<UserNetworkConfigurationUpdater> updater(
new UserNetworkConfigurationUpdater(
profile, allow_trusted_certs_from_policy, user, policy_service,
network_config_handler));
updater->Init();
return updater;
}
void UserNetworkConfigurationUpdater::SetClientCertificateImporterForTest(
std::unique_ptr<chromeos::onc::CertificateImporter>
client_certificate_importer) {
SetClientCertificateImporter(std::move(client_certificate_importer));
}
UserNetworkConfigurationUpdater::UserNetworkConfigurationUpdater(
Profile* profile,
bool allow_trusted_certs_from_policy,
const user_manager::User& user,
PolicyService* policy_service,
chromeos::ManagedNetworkConfigurationHandler* network_config_handler)
: NetworkConfigurationUpdater(onc::ONC_SOURCE_USER_POLICY,
key::kOpenNetworkConfiguration,
allow_trusted_certs_from_policy,
policy_service,
network_config_handler),
user_(&user),
weak_factory_(this) {
// The updater is created with |client_certificate_importer_| unset and is
// responsible for creating it. This requires |GetNSSCertDatabaseForProfile|
// call, which is not safe before the profile initialization is finalized.
// Thus, listen for PROFILE_ADDED notification, on which |cert_importer_|
// creation should start.
registrar_.Add(this,
chrome::NOTIFICATION_PROFILE_ADDED,
content::Source<Profile>(profile));
// Make sure that the |NetworkCertLoader| which makes certificates available
// to the chromeos network code gets policy-pushed certificates from the
// primary profile. This assumes that a |UserNetworkConfigurationUpdater| is
// only created for the primary profile. NetworkCertLoader may be not
// initialized in tests.
if (chromeos::NetworkCertLoader::IsInitialized())
chromeos::NetworkCertLoader::Get()->SetUserPolicyCertificateProvider(this);
}
void UserNetworkConfigurationUpdater::ImportClientCertificates() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
// If certificate importer is not yet set, the import of client certificates
// will be re-triggered in SetClientCertificateImporter.
if (client_certificate_importer_) {
client_certificate_importer_->ImportClientCertificates(
GetClientCertificates(), base::DoNothing());
}
}
void UserNetworkConfigurationUpdater::ApplyNetworkPolicy(
base::ListValue* network_configs_onc,
base::DictionaryValue* global_network_config) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DCHECK(user_);
chromeos::onc::ExpandStringPlaceholdersInNetworksForUser(user_,
network_configs_onc);
// Call on UserSessionManager to send the user's password to session manager
// if the password substitution variable exists in the ONC.
bool send_password =
chromeos::onc::HasUserPasswordSubsitutionVariable(network_configs_onc);
chromeos::UserSessionManager::GetInstance()->OnUserNetworkPolicyParsed(
send_password);
network_config_handler_->SetPolicy(onc_source_,
user_->username_hash(),
*network_configs_onc,
*global_network_config);
}
void UserNetworkConfigurationUpdater::Observe(
int type,
const content::NotificationSource& source,
const content::NotificationDetails& details) {
DCHECK_EQ(type, chrome::NOTIFICATION_PROFILE_ADDED);
Profile* profile = content::Source<Profile>(source).ptr();
GetNSSCertDatabaseForProfile(
profile, base::AdaptCallbackForRepeating(
base::BindOnce(&UserNetworkConfigurationUpdater::
CreateAndSetClientCertificateImporter,
weak_factory_.GetWeakPtr())));
}
void UserNetworkConfigurationUpdater::CreateAndSetClientCertificateImporter(
net::NSSCertDatabase* database) {
DCHECK(database);
SetClientCertificateImporter(
std::make_unique<chromeos::onc::CertificateImporterImpl>(
base::CreateSingleThreadTaskRunnerWithTraits(
{content::BrowserThread::IO}),
database));
}
void UserNetworkConfigurationUpdater::SetClientCertificateImporter(
std::unique_ptr<chromeos::onc::CertificateImporter>
client_certificate_importer) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
bool initial_client_certificate_importer =
client_certificate_importer_ == nullptr;
client_certificate_importer_ = std::move(client_certificate_importer);
if (initial_client_certificate_importer && !GetClientCertificates().empty()) {
client_certificate_importer_->ImportClientCertificates(
GetClientCertificates(), base::DoNothing());
}
}
} // namespace policy