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