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