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