Home | History | Annotate | Download | only in policy
      1 // Copyright (c) 2012 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/network_configuration_updater_impl_cros.h"
      6 
      7 #include <string>
      8 
      9 #include "base/bind.h"
     10 #include "base/bind_helpers.h"
     11 #include "base/logging.h"
     12 #include "base/values.h"
     13 #include "chrome/browser/chromeos/cros/network_library.h"
     14 #include "chrome/browser/policy/policy_map.h"
     15 #include "chromeos/network/onc/onc_certificate_importer.h"
     16 #include "chromeos/network/onc/onc_constants.h"
     17 #include "chromeos/network/onc/onc_utils.h"
     18 #include "policy/policy_constants.h"
     19 
     20 namespace policy {
     21 
     22 NetworkConfigurationUpdaterImplCros::NetworkConfigurationUpdaterImplCros(
     23     PolicyService* device_policy_service,
     24     chromeos::NetworkLibrary* network_library,
     25     scoped_ptr<chromeos::onc::CertificateImporter> certificate_importer)
     26     : policy_change_registrar_(
     27           device_policy_service,
     28           PolicyNamespace(POLICY_DOMAIN_CHROME, std::string())),
     29       network_library_(network_library),
     30       certificate_importer_(certificate_importer.Pass()),
     31       user_policy_service_(NULL),
     32       device_policy_service_(device_policy_service) {
     33   DCHECK(network_library_);
     34   policy_change_registrar_.Observe(
     35       key::kDeviceOpenNetworkConfiguration,
     36       base::Bind(&NetworkConfigurationUpdaterImplCros::OnPolicyChanged,
     37                  base::Unretained(this),
     38                  chromeos::onc::ONC_SOURCE_DEVICE_POLICY));
     39   policy_change_registrar_.Observe(
     40       key::kOpenNetworkConfiguration,
     41       base::Bind(&NetworkConfigurationUpdaterImplCros::OnPolicyChanged,
     42                  base::Unretained(this),
     43                  chromeos::onc::ONC_SOURCE_USER_POLICY));
     44 
     45   network_library_->AddNetworkProfileObserver(this);
     46   if (device_policy_service_->IsInitializationComplete(POLICY_DOMAIN_CHROME)) {
     47     // Apply the current policies immediately.
     48     VLOG(1) << "Device policy service is already initialized.";
     49     ApplyNetworkConfigurations();
     50   } else {
     51     device_policy_service_->AddObserver(POLICY_DOMAIN_CHROME, this);
     52   }
     53 }
     54 
     55 NetworkConfigurationUpdaterImplCros::~NetworkConfigurationUpdaterImplCros() {
     56   network_library_->RemoveNetworkProfileObserver(this);
     57   DCHECK(!user_policy_service_);
     58   device_policy_service_->RemoveObserver(POLICY_DOMAIN_CHROME, this);
     59 }
     60 
     61 void NetworkConfigurationUpdaterImplCros::OnProfileListChanged() {
     62   VLOG(1) << "Network profile list changed, applying policies.";
     63   ApplyNetworkConfigurations();
     64 }
     65 
     66 void NetworkConfigurationUpdaterImplCros::SetUserPolicyService(
     67     bool allow_trust_certs_from_policy,
     68     const std::string& hashed_username,
     69     PolicyService* user_policy_service) {
     70   VLOG(1) << "Got user policy service.";
     71   user_policy_service_ = user_policy_service;
     72   if (allow_trust_certs_from_policy)
     73     SetAllowTrustedCertsFromPolicy();
     74 
     75   if (user_policy_service_->IsInitializationComplete(POLICY_DOMAIN_CHROME)) {
     76     VLOG(1) << "User policy service is already initialized.";
     77     ApplyNetworkConfigurations();
     78   } else {
     79     user_policy_service_->AddObserver(POLICY_DOMAIN_CHROME, this);
     80   }
     81 }
     82 
     83 void NetworkConfigurationUpdaterImplCros::UnsetUserPolicyService() {
     84   if (!user_policy_service_)
     85     return;
     86 
     87   user_policy_service_->RemoveObserver(POLICY_DOMAIN_CHROME, this);
     88   user_policy_service_ = NULL;
     89 }
     90 
     91 void NetworkConfigurationUpdaterImplCros::OnPolicyUpdated(
     92     const PolicyNamespace& ns,
     93     const PolicyMap& previous,
     94     const PolicyMap& current) {
     95   // Ignore this call. Policy changes are already observed by the registrar.
     96 }
     97 
     98 void NetworkConfigurationUpdaterImplCros::OnPolicyServiceInitialized(
     99     PolicyDomain domain) {
    100   if (domain != POLICY_DOMAIN_CHROME)
    101     return;
    102 
    103   // We don't know which policy service called this function, thus check
    104   // both. Multiple removes are handled gracefully.
    105   if (device_policy_service_->IsInitializationComplete(POLICY_DOMAIN_CHROME)) {
    106     VLOG(1) << "Device policy service initialized.";
    107     device_policy_service_->RemoveObserver(POLICY_DOMAIN_CHROME, this);
    108   }
    109   if (user_policy_service_ &&
    110       user_policy_service_->IsInitializationComplete(POLICY_DOMAIN_CHROME)) {
    111     VLOG(1) << "User policy service initialized.";
    112     user_policy_service_->RemoveObserver(POLICY_DOMAIN_CHROME, this);
    113   }
    114 
    115   ApplyNetworkConfigurations();
    116 }
    117 
    118 void NetworkConfigurationUpdaterImplCros::OnPolicyChanged(
    119     chromeos::onc::ONCSource onc_source,
    120     const base::Value* previous,
    121     const base::Value* current) {
    122   VLOG(1) << "Policy for ONC source "
    123           << chromeos::onc::GetSourceAsString(onc_source) << " changed.";
    124   ApplyNetworkConfigurations();
    125 }
    126 
    127 void NetworkConfigurationUpdaterImplCros::ApplyNetworkConfigurations() {
    128   if (!device_policy_service_->IsInitializationComplete(POLICY_DOMAIN_CHROME))
    129     return;
    130 
    131   ApplyNetworkConfiguration(key::kDeviceOpenNetworkConfiguration,
    132                             chromeos::onc::ONC_SOURCE_DEVICE_POLICY,
    133                             device_policy_service_);
    134   if (user_policy_service_ &&
    135       user_policy_service_->IsInitializationComplete(POLICY_DOMAIN_CHROME)) {
    136     ApplyNetworkConfiguration(key::kOpenNetworkConfiguration,
    137                               chromeos::onc::ONC_SOURCE_USER_POLICY,
    138                               user_policy_service_);
    139   }
    140 }
    141 
    142 void NetworkConfigurationUpdaterImplCros::ApplyNetworkConfiguration(
    143     const std::string& policy_key,
    144     chromeos::onc::ONCSource onc_source,
    145     PolicyService* policy_service) {
    146   VLOG(1) << "Apply policy for ONC source "
    147           << chromeos::onc::GetSourceAsString(onc_source);
    148   const PolicyMap& policies = policy_service->GetPolicies(
    149       PolicyNamespace(POLICY_DOMAIN_CHROME, std::string()));
    150   const base::Value* policy_value = policies.GetValue(policy_key);
    151 
    152   std::string onc_blob;
    153   if (policy_value != NULL) {
    154     // If the policy is not a string, we issue a warning, but still clear the
    155     // network configuration.
    156     if (!policy_value->GetAsString(&onc_blob)) {
    157       LOG(WARNING) << "ONC policy for source "
    158                    << chromeos::onc::GetSourceAsString(onc_source)
    159                    << " is not a string value.";
    160     }
    161   }
    162 
    163   base::ListValue network_configs;
    164   base::ListValue certificates;
    165   chromeos::onc::ParseAndValidateOncForImport(
    166       onc_blob, onc_source, "", &network_configs, &certificates);
    167 
    168   scoped_ptr<net::CertificateList> web_trust_certs(new net::CertificateList);
    169   certificate_importer_->ImportCertificates(
    170       certificates, onc_source, web_trust_certs.get());
    171 
    172   network_library_->LoadOncNetworks(network_configs, onc_source);
    173 
    174   if (onc_source == chromeos::onc::ONC_SOURCE_USER_POLICY)
    175     SetTrustAnchors(web_trust_certs.Pass());
    176 }
    177 
    178 }  // namespace policy
    179