Home | History | Annotate | Download | only in policy
      1 // Copyright 2013 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "chrome/browser/chromeos/policy/user_network_configuration_updater.h"
      6 
      7 #include "base/bind.h"
      8 #include "base/bind_helpers.h"
      9 #include "base/logging.h"
     10 #include "base/values.h"
     11 #include "chrome/browser/chrome_notification_types.h"
     12 #include "chrome/browser/chromeos/login/users/user.h"
     13 #include "chrome/browser/chromeos/net/onc_utils.h"
     14 #include "chrome/browser/net/nss_context.h"
     15 #include "chrome/browser/profiles/profile.h"
     16 #include "chromeos/network/managed_network_configuration_handler.h"
     17 #include "chromeos/network/onc/onc_certificate_importer_impl.h"
     18 #include "content/public/browser/notification_source.h"
     19 #include "net/cert/x509_certificate.h"
     20 #include "policy/policy_constants.h"
     21 
     22 namespace {
     23 
     24 bool skip_certificate_importer_creation_for_test = false;
     25 
     26 }  // namespace
     27 
     28 namespace policy {
     29 
     30 UserNetworkConfigurationUpdater::~UserNetworkConfigurationUpdater() {}
     31 
     32 // static
     33 scoped_ptr<UserNetworkConfigurationUpdater>
     34 UserNetworkConfigurationUpdater::CreateForUserPolicy(
     35     Profile* profile,
     36     bool allow_trusted_certs_from_policy,
     37     const chromeos::User& user,
     38     PolicyService* policy_service,
     39     chromeos::ManagedNetworkConfigurationHandler* network_config_handler) {
     40   scoped_ptr<UserNetworkConfigurationUpdater> updater(
     41       new UserNetworkConfigurationUpdater(profile,
     42                                           allow_trusted_certs_from_policy,
     43                                           user,
     44                                           policy_service,
     45                                           network_config_handler));
     46   updater->Init();
     47   return updater.Pass();
     48 }
     49 
     50 void UserNetworkConfigurationUpdater::AddTrustedCertsObserver(
     51     WebTrustedCertsObserver* observer) {
     52   observer_list_.AddObserver(observer);
     53 }
     54 
     55 void UserNetworkConfigurationUpdater::RemoveTrustedCertsObserver(
     56     WebTrustedCertsObserver* observer) {
     57   observer_list_.RemoveObserver(observer);
     58 }
     59 
     60 UserNetworkConfigurationUpdater::UserNetworkConfigurationUpdater(
     61     Profile* profile,
     62     bool allow_trusted_certs_from_policy,
     63     const chromeos::User& user,
     64     PolicyService* policy_service,
     65     chromeos::ManagedNetworkConfigurationHandler* network_config_handler)
     66     : NetworkConfigurationUpdater(onc::ONC_SOURCE_USER_POLICY,
     67                                   key::kOpenNetworkConfiguration,
     68                                   policy_service,
     69                                   network_config_handler),
     70       allow_trusted_certificates_from_policy_(allow_trusted_certs_from_policy),
     71       user_(&user),
     72       weak_factory_(this) {
     73   // The updater is created with |certificate_importer_| unset and is
     74   // responsible for creating it. This requires |GetNSSCertDatabaseForProfile|
     75   // call, which is not safe before the profile initialization is finalized.
     76   // Thus, listen for PROFILE_ADDED notification, on which |cert_importer_|
     77   // creation should start. This behaviour can be disabled in tests.
     78   if (!skip_certificate_importer_creation_for_test) {
     79     registrar_.Add(this,
     80                    chrome::NOTIFICATION_PROFILE_ADDED,
     81                    content::Source<Profile>(profile));
     82   }
     83 }
     84 
     85 void UserNetworkConfigurationUpdater::SetCertificateImporterForTest(
     86     scoped_ptr<chromeos::onc::CertificateImporter> certificate_importer) {
     87   SetCertificateImporter(certificate_importer.Pass());
     88 }
     89 
     90 // static
     91 void UserNetworkConfigurationUpdater::
     92 SetSkipCertificateImporterCreationForTest(bool skip) {
     93   skip_certificate_importer_creation_for_test = skip;
     94 }
     95 
     96 void UserNetworkConfigurationUpdater::GetWebTrustedCertificates(
     97     net::CertificateList* certs) const {
     98   *certs = web_trust_certs_;
     99 }
    100 
    101 void UserNetworkConfigurationUpdater::ImportCertificates(
    102     const base::ListValue& certificates_onc) {
    103   // If certificate importer is not yet set, cache the certificate onc. It will
    104   // be imported when the certificate importer gets set.
    105   if (!certificate_importer_) {
    106     pending_certificates_onc_.reset(certificates_onc.DeepCopy());
    107     return;
    108   }
    109 
    110   web_trust_certs_.clear();
    111   certificate_importer_->ImportCertificates(
    112       certificates_onc,
    113       onc_source_,
    114       allow_trusted_certificates_from_policy_ ? &web_trust_certs_ : NULL);
    115 
    116   NotifyTrustAnchorsChanged();
    117 }
    118 
    119 void UserNetworkConfigurationUpdater::ApplyNetworkPolicy(
    120     base::ListValue* network_configs_onc,
    121     base::DictionaryValue* global_network_config) {
    122   DCHECK(user_);
    123   chromeos::onc::ExpandStringPlaceholdersInNetworksForUser(user_,
    124                                                            network_configs_onc);
    125   network_config_handler_->SetPolicy(onc_source_,
    126                                      user_->username_hash(),
    127                                      *network_configs_onc,
    128                                      *global_network_config);
    129 }
    130 
    131 void UserNetworkConfigurationUpdater::Observe(
    132     int type,
    133     const content::NotificationSource& source,
    134     const content::NotificationDetails& details) {
    135   DCHECK_EQ(type, chrome::NOTIFICATION_PROFILE_ADDED);
    136   Profile* profile = content::Source<Profile>(source).ptr();
    137 
    138   if (skip_certificate_importer_creation_for_test)
    139     return;
    140 
    141   GetNSSCertDatabaseForProfile(
    142       profile,
    143       base::Bind(
    144           &UserNetworkConfigurationUpdater::CreateAndSetCertificateImporter,
    145           weak_factory_.GetWeakPtr()));
    146 }
    147 
    148 void UserNetworkConfigurationUpdater::CreateAndSetCertificateImporter(
    149     net::NSSCertDatabase* database) {
    150   DCHECK(database);
    151   SetCertificateImporter(scoped_ptr<chromeos::onc::CertificateImporter>(
    152       new chromeos::onc::CertificateImporterImpl(database)));
    153 }
    154 
    155 void UserNetworkConfigurationUpdater::SetCertificateImporter(
    156     scoped_ptr<chromeos::onc::CertificateImporter> certificate_importer) {
    157   certificate_importer_ = certificate_importer.Pass();
    158 
    159   if (pending_certificates_onc_)
    160     ImportCertificates(*pending_certificates_onc_);
    161   pending_certificates_onc_.reset();
    162 }
    163 
    164 void UserNetworkConfigurationUpdater::NotifyTrustAnchorsChanged() {
    165   FOR_EACH_OBSERVER(WebTrustedCertsObserver,
    166                     observer_list_,
    167                     OnTrustAnchorsChanged(web_trust_certs_));
    168 }
    169 
    170 }  // namespace policy
    171