1 // Copyright 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/user_network_configuration_updater.h" 6 7 #include "base/bind.h" 8 #include "base/bind_helpers.h" 9 #include "base/logging.h" 10 #include "base/values.h" 11 #include "chrome/browser/chrome_notification_types.h" 12 #include "chrome/browser/chromeos/login/users/user.h" 13 #include "chrome/browser/chromeos/net/onc_utils.h" 14 #include "chrome/browser/net/nss_context.h" 15 #include "chrome/browser/profiles/profile.h" 16 #include "chromeos/network/managed_network_configuration_handler.h" 17 #include "chromeos/network/onc/onc_certificate_importer_impl.h" 18 #include "content/public/browser/notification_source.h" 19 #include "net/cert/x509_certificate.h" 20 #include "policy/policy_constants.h" 21 22 namespace { 23 24 bool skip_certificate_importer_creation_for_test = false; 25 26 } // namespace 27 28 namespace policy { 29 30 UserNetworkConfigurationUpdater::~UserNetworkConfigurationUpdater() {} 31 32 // static 33 scoped_ptr<UserNetworkConfigurationUpdater> 34 UserNetworkConfigurationUpdater::CreateForUserPolicy( 35 Profile* profile, 36 bool allow_trusted_certs_from_policy, 37 const chromeos::User& user, 38 PolicyService* policy_service, 39 chromeos::ManagedNetworkConfigurationHandler* network_config_handler) { 40 scoped_ptr<UserNetworkConfigurationUpdater> updater( 41 new UserNetworkConfigurationUpdater(profile, 42 allow_trusted_certs_from_policy, 43 user, 44 policy_service, 45 network_config_handler)); 46 updater->Init(); 47 return updater.Pass(); 48 } 49 50 void UserNetworkConfigurationUpdater::AddTrustedCertsObserver( 51 WebTrustedCertsObserver* observer) { 52 observer_list_.AddObserver(observer); 53 } 54 55 void UserNetworkConfigurationUpdater::RemoveTrustedCertsObserver( 56 WebTrustedCertsObserver* observer) { 57 observer_list_.RemoveObserver(observer); 58 } 59 60 UserNetworkConfigurationUpdater::UserNetworkConfigurationUpdater( 61 Profile* profile, 62 bool allow_trusted_certs_from_policy, 63 const chromeos::User& user, 64 PolicyService* policy_service, 65 chromeos::ManagedNetworkConfigurationHandler* network_config_handler) 66 : NetworkConfigurationUpdater(onc::ONC_SOURCE_USER_POLICY, 67 key::kOpenNetworkConfiguration, 68 policy_service, 69 network_config_handler), 70 allow_trusted_certificates_from_policy_(allow_trusted_certs_from_policy), 71 user_(&user), 72 weak_factory_(this) { 73 // The updater is created with |certificate_importer_| unset and is 74 // responsible for creating it. This requires |GetNSSCertDatabaseForProfile| 75 // call, which is not safe before the profile initialization is finalized. 76 // Thus, listen for PROFILE_ADDED notification, on which |cert_importer_| 77 // creation should start. This behaviour can be disabled in tests. 78 if (!skip_certificate_importer_creation_for_test) { 79 registrar_.Add(this, 80 chrome::NOTIFICATION_PROFILE_ADDED, 81 content::Source<Profile>(profile)); 82 } 83 } 84 85 void UserNetworkConfigurationUpdater::SetCertificateImporterForTest( 86 scoped_ptr<chromeos::onc::CertificateImporter> certificate_importer) { 87 SetCertificateImporter(certificate_importer.Pass()); 88 } 89 90 // static 91 void UserNetworkConfigurationUpdater:: 92 SetSkipCertificateImporterCreationForTest(bool skip) { 93 skip_certificate_importer_creation_for_test = skip; 94 } 95 96 void UserNetworkConfigurationUpdater::GetWebTrustedCertificates( 97 net::CertificateList* certs) const { 98 *certs = web_trust_certs_; 99 } 100 101 void UserNetworkConfigurationUpdater::ImportCertificates( 102 const base::ListValue& certificates_onc) { 103 // If certificate importer is not yet set, cache the certificate onc. It will 104 // be imported when the certificate importer gets set. 105 if (!certificate_importer_) { 106 pending_certificates_onc_.reset(certificates_onc.DeepCopy()); 107 return; 108 } 109 110 web_trust_certs_.clear(); 111 certificate_importer_->ImportCertificates( 112 certificates_onc, 113 onc_source_, 114 allow_trusted_certificates_from_policy_ ? &web_trust_certs_ : NULL); 115 116 NotifyTrustAnchorsChanged(); 117 } 118 119 void UserNetworkConfigurationUpdater::ApplyNetworkPolicy( 120 base::ListValue* network_configs_onc, 121 base::DictionaryValue* global_network_config) { 122 DCHECK(user_); 123 chromeos::onc::ExpandStringPlaceholdersInNetworksForUser(user_, 124 network_configs_onc); 125 network_config_handler_->SetPolicy(onc_source_, 126 user_->username_hash(), 127 *network_configs_onc, 128 *global_network_config); 129 } 130 131 void UserNetworkConfigurationUpdater::Observe( 132 int type, 133 const content::NotificationSource& source, 134 const content::NotificationDetails& details) { 135 DCHECK_EQ(type, chrome::NOTIFICATION_PROFILE_ADDED); 136 Profile* profile = content::Source<Profile>(source).ptr(); 137 138 if (skip_certificate_importer_creation_for_test) 139 return; 140 141 GetNSSCertDatabaseForProfile( 142 profile, 143 base::Bind( 144 &UserNetworkConfigurationUpdater::CreateAndSetCertificateImporter, 145 weak_factory_.GetWeakPtr())); 146 } 147 148 void UserNetworkConfigurationUpdater::CreateAndSetCertificateImporter( 149 net::NSSCertDatabase* database) { 150 DCHECK(database); 151 SetCertificateImporter(scoped_ptr<chromeos::onc::CertificateImporter>( 152 new chromeos::onc::CertificateImporterImpl(database))); 153 } 154 155 void UserNetworkConfigurationUpdater::SetCertificateImporter( 156 scoped_ptr<chromeos::onc::CertificateImporter> certificate_importer) { 157 certificate_importer_ = certificate_importer.Pass(); 158 159 if (pending_certificates_onc_) 160 ImportCertificates(*pending_certificates_onc_); 161 pending_certificates_onc_.reset(); 162 } 163 164 void UserNetworkConfigurationUpdater::NotifyTrustAnchorsChanged() { 165 FOR_EACH_OBSERVER(WebTrustedCertsObserver, 166 observer_list_, 167 OnTrustAnchorsChanged(web_trust_certs_)); 168 } 169 170 } // namespace policy 171