| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/chromeos/policy/network_configuration_updater_impl_cros
.h" | 5 #include "chrome/browser/chromeos/policy/network_configuration_updater_impl_cros
.h" |
| 6 | 6 |
| 7 #include <string> | 7 #include <string> |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/bind_helpers.h" | 10 #include "base/bind_helpers.h" |
| 11 #include "base/command_line.h" | |
| 12 #include "base/logging.h" | 11 #include "base/logging.h" |
| 13 #include "base/memory/scoped_ptr.h" | 12 #include "base/memory/scoped_ptr.h" |
| 13 #include "base/values.h" |
| 14 #include "chrome/browser/chromeos/cros/network_library.h" | 14 #include "chrome/browser/chromeos/cros/network_library.h" |
| 15 #include "chrome/browser/policy/policy_map.h" | 15 #include "chrome/browser/policy/policy_map.h" |
| 16 #include "chrome/common/chrome_switches.h" | 16 #include "chromeos/network/certificate_handler.h" |
| 17 #include "chromeos/network/onc/onc_constants.h" | 17 #include "chromeos/network/onc/onc_constants.h" |
| 18 #include "chromeos/network/onc/onc_utils.h" | 18 #include "chromeos/network/onc/onc_utils.h" |
| 19 #include "content/public/browser/browser_thread.h" | |
| 20 #include "net/cert/cert_trust_anchor_provider.h" | |
| 21 #include "net/cert/x509_certificate.h" | 19 #include "net/cert/x509_certificate.h" |
| 22 #include "policy/policy_constants.h" | 20 #include "policy/policy_constants.h" |
| 23 | 21 |
| 24 using content::BrowserThread; | |
| 25 | |
| 26 namespace policy { | 22 namespace policy { |
| 27 | 23 |
| 28 namespace { | |
| 29 | |
| 30 // A simple implementation of net::CertTrustAnchorProvider that returns a list | |
| 31 // of certificates that can be set by the owner of this object. | |
| 32 class CrosTrustAnchorProvider : public net::CertTrustAnchorProvider { | |
| 33 public: | |
| 34 CrosTrustAnchorProvider() {} | |
| 35 virtual ~CrosTrustAnchorProvider() {} | |
| 36 | |
| 37 // CertTrustAnchorProvider overrides. | |
| 38 virtual const net::CertificateList& GetAdditionalTrustAnchors() OVERRIDE { | |
| 39 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
| 40 return trust_anchors_; | |
| 41 } | |
| 42 | |
| 43 void SetTrustAnchors(scoped_ptr<net::CertificateList> trust_anchors) { | |
| 44 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
| 45 trust_anchors_.swap(*trust_anchors); | |
| 46 } | |
| 47 | |
| 48 private: | |
| 49 net::CertificateList trust_anchors_; | |
| 50 | |
| 51 DISALLOW_COPY_AND_ASSIGN(CrosTrustAnchorProvider); | |
| 52 }; | |
| 53 | |
| 54 } // namespace | |
| 55 | |
| 56 NetworkConfigurationUpdaterImplCros::NetworkConfigurationUpdaterImplCros( | 24 NetworkConfigurationUpdaterImplCros::NetworkConfigurationUpdaterImplCros( |
| 57 PolicyService* policy_service, | 25 PolicyService* policy_service, |
| 58 chromeos::NetworkLibrary* network_library) | 26 chromeos::NetworkLibrary* network_library, |
| 27 chromeos::CertificateHandler* certificate_handler) |
| 59 : policy_change_registrar_( | 28 : policy_change_registrar_( |
| 60 policy_service, PolicyNamespace(POLICY_DOMAIN_CHROME, std::string())), | 29 policy_service, PolicyNamespace(POLICY_DOMAIN_CHROME, std::string())), |
| 61 network_library_(network_library), | 30 network_library_(network_library), |
| 31 certificate_handler_(certificate_handler), |
| 62 user_policy_initialized_(false), | 32 user_policy_initialized_(false), |
| 63 allow_trusted_certificates_from_policy_(false), | 33 policy_service_(policy_service) { |
| 64 policy_service_(policy_service), | |
| 65 cert_trust_provider_(new CrosTrustAnchorProvider()) { | |
| 66 DCHECK(network_library_); | 34 DCHECK(network_library_); |
| 67 policy_change_registrar_.Observe( | 35 policy_change_registrar_.Observe( |
| 68 key::kDeviceOpenNetworkConfiguration, | 36 key::kDeviceOpenNetworkConfiguration, |
| 69 base::Bind(&NetworkConfigurationUpdaterImplCros::OnPolicyChanged, | 37 base::Bind(&NetworkConfigurationUpdaterImplCros::OnPolicyChanged, |
| 70 base::Unretained(this), | 38 base::Unretained(this), |
| 71 chromeos::onc::ONC_SOURCE_DEVICE_POLICY)); | 39 chromeos::onc::ONC_SOURCE_DEVICE_POLICY)); |
| 72 policy_change_registrar_.Observe( | 40 policy_change_registrar_.Observe( |
| 73 key::kOpenNetworkConfiguration, | 41 key::kOpenNetworkConfiguration, |
| 74 base::Bind(&NetworkConfigurationUpdaterImplCros::OnPolicyChanged, | 42 base::Bind(&NetworkConfigurationUpdaterImplCros::OnPolicyChanged, |
| 75 base::Unretained(this), | 43 base::Unretained(this), |
| 76 chromeos::onc::ONC_SOURCE_USER_POLICY)); | 44 chromeos::onc::ONC_SOURCE_USER_POLICY)); |
| 77 | 45 |
| 78 network_library_->AddNetworkProfileObserver(this); | 46 network_library_->AddNetworkProfileObserver(this); |
| 79 | 47 |
| 80 // Apply the current policies immediately. | 48 // Apply the current policies immediately. |
| 81 ApplyNetworkConfigurations(); | 49 ApplyNetworkConfigurations(); |
| 82 } | 50 } |
| 83 | 51 |
| 84 NetworkConfigurationUpdaterImplCros::~NetworkConfigurationUpdaterImplCros() { | 52 NetworkConfigurationUpdaterImplCros::~NetworkConfigurationUpdaterImplCros() { |
| 85 network_library_->RemoveNetworkProfileObserver(this); | 53 network_library_->RemoveNetworkProfileObserver(this); |
| 86 bool posted = BrowserThread::DeleteSoon( | |
| 87 BrowserThread::IO, FROM_HERE, cert_trust_provider_); | |
| 88 if (!posted) | |
| 89 delete cert_trust_provider_; | |
| 90 } | 54 } |
| 91 | 55 |
| 92 void NetworkConfigurationUpdaterImplCros::OnProfileListChanged() { | 56 void NetworkConfigurationUpdaterImplCros::OnProfileListChanged() { |
| 93 VLOG(1) << "Network profile list changed, applying policies."; | 57 VLOG(1) << "Network profile list changed, applying policies."; |
| 94 ApplyNetworkConfigurations(); | 58 ApplyNetworkConfigurations(); |
| 95 } | 59 } |
| 96 | 60 |
| 97 void NetworkConfigurationUpdaterImplCros::OnUserPolicyInitialized() { | 61 void NetworkConfigurationUpdaterImplCros::OnUserPolicyInitialized() { |
| 98 VLOG(1) << "User policy initialized, applying policies."; | 62 VLOG(1) << "User policy initialized, applying policies."; |
| 99 user_policy_initialized_ = true; | 63 user_policy_initialized_ = true; |
| 100 ApplyNetworkConfigurations(); | 64 ApplyNetworkConfigurations(); |
| 101 } | 65 } |
| 102 | 66 |
| 103 void NetworkConfigurationUpdaterImplCros:: | |
| 104 set_allow_trusted_certificates_from_policy(bool allow) { | |
| 105 allow_trusted_certificates_from_policy_ = allow; | |
| 106 } | |
| 107 | |
| 108 net::CertTrustAnchorProvider* | |
| 109 NetworkConfigurationUpdaterImplCros::GetCertTrustAnchorProvider() { | |
| 110 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
| 111 return cert_trust_provider_; | |
| 112 } | |
| 113 | |
| 114 void NetworkConfigurationUpdaterImplCros::OnPolicyChanged( | 67 void NetworkConfigurationUpdaterImplCros::OnPolicyChanged( |
| 115 chromeos::onc::ONCSource onc_source, | 68 chromeos::onc::ONCSource onc_source, |
| 116 const base::Value* previous, | 69 const base::Value* previous, |
| 117 const base::Value* current) { | 70 const base::Value* current) { |
| 118 VLOG(1) << "Policy for ONC source " | 71 VLOG(1) << "Policy for ONC source " |
| 119 << chromeos::onc::GetSourceAsString(onc_source) << " changed."; | 72 << chromeos::onc::GetSourceAsString(onc_source) << " changed."; |
| 120 ApplyNetworkConfigurations(); | 73 ApplyNetworkConfigurations(); |
| 121 } | 74 } |
| 122 | 75 |
| 123 void NetworkConfigurationUpdaterImplCros::ApplyNetworkConfigurations() { | 76 void NetworkConfigurationUpdaterImplCros::ApplyNetworkConfigurations() { |
| 124 ApplyNetworkConfiguration(key::kDeviceOpenNetworkConfiguration, | 77 ApplyNetworkConfiguration(key::kDeviceOpenNetworkConfiguration, |
| 125 chromeos::onc::ONC_SOURCE_DEVICE_POLICY); | 78 chromeos::onc::ONC_SOURCE_DEVICE_POLICY); |
| 126 if (user_policy_initialized_) { | 79 if (user_policy_initialized_) { |
| 127 ApplyNetworkConfiguration(key::kOpenNetworkConfiguration, | 80 ApplyNetworkConfiguration(key::kOpenNetworkConfiguration, |
| 128 chromeos::onc::ONC_SOURCE_USER_POLICY); | 81 chromeos::onc::ONC_SOURCE_USER_POLICY); |
| 129 } | 82 } |
| 130 } | 83 } |
| 131 | 84 |
| 132 void NetworkConfigurationUpdaterImplCros::ApplyNetworkConfiguration( | 85 void NetworkConfigurationUpdaterImplCros::ApplyNetworkConfiguration( |
| 133 const std::string& policy_key, | 86 const std::string& policy_key, |
| 134 chromeos::onc::ONCSource onc_source) { | 87 chromeos::onc::ONCSource onc_source) { |
| 135 VLOG(1) << "Apply policy for ONC source " | 88 VLOG(1) << "Apply policy for ONC source " |
| 136 << chromeos::onc::GetSourceAsString(onc_source); | 89 << chromeos::onc::GetSourceAsString(onc_source); |
| 137 const PolicyMap& policies = policy_service_->GetPolicies( | 90 const PolicyMap& policies = policy_service_->GetPolicies( |
| 138 PolicyNamespace(POLICY_DOMAIN_CHROME, std::string())); | 91 PolicyNamespace(POLICY_DOMAIN_CHROME, std::string())); |
| 139 const base::Value* policy_value = policies.GetValue(policy_key); | 92 const base::Value* policy_value = policies.GetValue(policy_key); |
| 140 | 93 |
| 141 std::string new_network_config; | 94 std::string onc_blob; |
| 142 if (policy_value != NULL) { | 95 if (policy_value != NULL) { |
| 143 // If the policy is not a string, we issue a warning, but still clear the | 96 // If the policy is not a string, we issue a warning, but still clear the |
| 144 // network configuration. | 97 // network configuration. |
| 145 if (!policy_value->GetAsString(&new_network_config)) { | 98 if (!policy_value->GetAsString(&onc_blob)) { |
| 146 LOG(WARNING) << "ONC policy for source " | 99 LOG(WARNING) << "ONC policy for source " |
| 147 << chromeos::onc::GetSourceAsString(onc_source) | 100 << chromeos::onc::GetSourceAsString(onc_source) |
| 148 << " is not a string value."; | 101 << " is not a string value."; |
| 149 } | 102 } |
| 150 } | 103 } |
| 151 | 104 |
| 152 // An empty string is not a valid ONC and generates warnings and | 105 scoped_ptr<base::ListValue> network_configs; |
| 153 // errors. Replace by a valid empty configuration. | 106 scoped_ptr<base::ListValue> certificates; |
| 154 if (new_network_config.empty()) | 107 ParseAndValidateOncForImport( |
| 155 new_network_config = chromeos::onc::kEmptyUnencryptedConfiguration; | 108 onc_blob, onc_source, "", &network_configs, &certificates); |
| 156 | 109 |
| 157 scoped_ptr<net::CertificateList> web_trust_certs(new net::CertificateList()); | 110 if (network_configs) |
| 158 if (!network_library_->LoadOncNetworks(new_network_config, "", onc_source, | 111 network_library_->LoadOncNetworks(*network_configs, onc_source); |
| 159 web_trust_certs.get())) { | 112 |
| 160 LOG(ERROR) << "Errors occurred during the ONC policy application."; | 113 scoped_ptr<net::CertificateList> web_trust_certs(new net::CertificateList); |
| 114 if (certificates) { |
| 115 certificate_handler_->ImportCertificates( |
| 116 *certificates, onc_source, web_trust_certs.get()); |
| 161 } | 117 } |
| 162 | 118 |
| 163 CommandLine* command_line = CommandLine::ForCurrentProcess(); | 119 if (onc_source == chromeos::onc::ONC_SOURCE_USER_POLICY) |
| 164 if (onc_source == chromeos::onc::ONC_SOURCE_USER_POLICY && | 120 SetTrustAnchors(web_trust_certs.Pass()); |
| 165 allow_trusted_certificates_from_policy_ && | |
| 166 command_line->HasSwitch(switches::kEnableWebTrustCerts)) { | |
| 167 BrowserThread::PostTask( | |
| 168 BrowserThread::IO, FROM_HERE, | |
| 169 base::Bind(&CrosTrustAnchorProvider::SetTrustAnchors, | |
| 170 base::Unretained(static_cast<CrosTrustAnchorProvider*>( | |
| 171 cert_trust_provider_)), | |
| 172 base::Passed(&web_trust_certs))); | |
| 173 } | |
| 174 } | 121 } |
| 175 | 122 |
| 176 } // namespace policy | 123 } // namespace policy |
| OLD | NEW |