Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(403)

Side by Side Diff: chrome/browser/chromeos/cros/network_library_impl_base.cc

Issue 14192017: Extract certificate policy application from NetworkLibrary. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebased. Created 7 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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/cros/network_library_impl_base.h" 5 #include "chrome/browser/chromeos/cros/network_library_impl_base.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/json/json_writer.h" 8 #include "base/json/json_writer.h"
9 #include "base/memory/scoped_vector.h" 9 #include "base/memory/scoped_vector.h"
10 #include "base/metrics/histogram.h"
11 #include "base/stl_util.h" 10 #include "base/stl_util.h"
12 #include "base/string_util.h" 11 #include "base/string_util.h"
13 #include "chrome/browser/chromeos/cros/network_constants.h" 12 #include "chrome/browser/chromeos/cros/network_constants.h"
14 #include "chrome/browser/chromeos/login/user_manager.h" 13 #include "chrome/browser/chromeos/login/user_manager.h"
15 #include "chrome/browser/chromeos/net/onc_utils.h" 14 #include "chrome/browser/chromeos/net/onc_utils.h"
16 #include "chrome/browser/chromeos/network_login_observer.h" 15 #include "chrome/browser/chromeos/network_login_observer.h"
17 #include "chromeos/network/network_ui_data.h" 16 #include "chromeos/network/network_ui_data.h"
18 #include "chromeos/network/onc/onc_certificate_importer.h"
19 #include "chromeos/network/onc/onc_constants.h" 17 #include "chromeos/network/onc/onc_constants.h"
20 #include "chromeos/network/onc/onc_normalizer.h" 18 #include "chromeos/network/onc/onc_normalizer.h"
21 #include "chromeos/network/onc/onc_signature.h" 19 #include "chromeos/network/onc/onc_signature.h"
22 #include "chromeos/network/onc/onc_translator.h" 20 #include "chromeos/network/onc/onc_translator.h"
23 #include "chromeos/network/onc/onc_utils.h" 21 #include "chromeos/network/onc/onc_utils.h"
24 #include "chromeos/network/onc/onc_validator.h"
25 #include "content/public/browser/browser_thread.h" 22 #include "content/public/browser/browser_thread.h"
26 #include "crypto/nss_util.h" // crypto::GetTPMTokenInfo() for 802.1X and VPN. 23 #include "crypto/nss_util.h" // crypto::GetTPMTokenInfo() for 802.1X and VPN.
27 #include "third_party/cros_system_api/dbus/service_constants.h" 24 #include "third_party/cros_system_api/dbus/service_constants.h"
28 25
29 using content::BrowserThread; 26 using content::BrowserThread;
30 27
31 namespace chromeos { 28 namespace chromeos {
32 29
33 namespace { 30 namespace {
34 31
(...skipping 1021 matching lines...) Expand 10 before | Expand all | Expand 10 after
1056 else if (placeholder == onc::substitutes::kEmailField) 1053 else if (placeholder == onc::substitutes::kEmailField)
1057 *substitute = logged_in_user->email(); 1054 *substitute = logged_in_user->email();
1058 else 1055 else
1059 return false; 1056 return false;
1060 return true; 1057 return true;
1061 } 1058 }
1062 }; 1059 };
1063 1060
1064 } // namespace 1061 } // namespace
1065 1062
1066 bool NetworkLibraryImplBase::LoadOncNetworks( 1063 void NetworkLibraryImplBase::LoadOncNetworks(
1067 const std::string& onc_blob, 1064 const base::ListValue& network_configs,
1068 const std::string& passphrase, 1065 onc::ONCSource source) {
1069 onc::ONCSource source, 1066 VLOG(2) << __func__ << ": called on " << network_configs;
1070 net::CertificateList* onc_trusted_certificates) {
1071 VLOG(2) << __func__ << ": called on " << onc_blob;
1072 NetworkProfile* profile = NULL; 1067 NetworkProfile* profile = NULL;
1073 bool from_policy = (source == onc::ONC_SOURCE_USER_POLICY || 1068 bool from_policy = (source == onc::ONC_SOURCE_USER_POLICY ||
1074 source == onc::ONC_SOURCE_DEVICE_POLICY); 1069 source == onc::ONC_SOURCE_DEVICE_POLICY);
1075 1070
1076 // Policies are applied to a specific Shill profile. User ONC import however 1071 // Policies are applied to a specific Shill profile. User ONC import however
1077 // is applied to whatever profile Shill chooses. This should be the profile 1072 // is applied to whatever profile Shill chooses. This should be the profile
1078 // that is already associated with a network and if no profile is associated 1073 // that is already associated with a network and if no profile is associated
1079 // yet, it should be the user profile. 1074 // yet, it should be the user profile.
1080 if (from_policy) { 1075 if (from_policy) {
1081 profile = GetProfileForType(GetProfileTypeForSource(source)); 1076 profile = GetProfileForType(GetProfileTypeForSource(source));
1082 if (profile == NULL) { 1077 if (profile == NULL) {
1083 VLOG(2) << "Profile for ONC source " << onc::GetSourceAsString(source) 1078 VLOG(2) << "Profile for ONC source " << onc::GetSourceAsString(source)
1084 << " doesn't exist."; 1079 << " doesn't exist.";
1085 return true; 1080 return;
1086 }
1087 }
1088
1089 scoped_ptr<base::DictionaryValue> root_dict =
1090 onc::ReadDictionaryFromJson(onc_blob);
1091 if (root_dict.get() == NULL) {
1092 LOG(ERROR) << "ONC loaded from " << onc::GetSourceAsString(source)
1093 << " is not a valid JSON dictionary.";
1094 return false;
1095 }
1096
1097 // Check and see if this is an encrypted ONC file. If so, decrypt it.
1098 std::string onc_type;
1099 root_dict->GetStringWithoutPathExpansion(onc::toplevel_config::kType,
1100 &onc_type);
1101 if (onc_type == onc::toplevel_config::kEncryptedConfiguration) {
1102 root_dict = onc::Decrypt(passphrase, *root_dict);
1103 if (root_dict.get() == NULL) {
1104 LOG(ERROR) << "Couldn't decrypt the ONC from "
1105 << onc::GetSourceAsString(source);
1106 return false;
1107 }
1108 }
1109
1110 // Validate the ONC dictionary. We are liberal and ignore unknown field
1111 // names and ignore invalid field names in kRecommended arrays.
1112 onc::Validator validator(false, // Ignore unknown fields.
1113 false, // Ignore invalid recommended field names.
1114 true, // Fail on missing fields.
1115 from_policy);
1116 validator.SetOncSource(source);
1117
1118 onc::Validator::Result validation_result;
1119 root_dict = validator.ValidateAndRepairObject(
1120 &onc::kToplevelConfigurationSignature,
1121 *root_dict,
1122 &validation_result);
1123
1124 if (from_policy) {
1125 UMA_HISTOGRAM_BOOLEAN("Enterprise.ONC.PolicyValidation",
1126 validation_result == onc::Validator::VALID);
1127 }
1128
1129 bool success = true;
1130 if (validation_result == onc::Validator::VALID_WITH_WARNINGS) {
1131 LOG(WARNING) << "ONC from " << onc::GetSourceAsString(source)
1132 << " produced warnings.";
1133 success = false;
1134 } else if (validation_result == onc::Validator::INVALID ||
1135 root_dict == NULL) {
1136 LOG(ERROR) << "ONC from " << onc::GetSourceAsString(source)
1137 << " is invalid and couldn't be repaired.";
1138 return false;
1139 }
1140
1141 const base::ListValue* certificates;
1142 bool has_certificates =
1143 root_dict->GetListWithoutPathExpansion(
1144 onc::toplevel_config::kCertificates,
1145 &certificates);
1146
1147 const base::ListValue* network_configs;
1148 bool has_network_configurations = root_dict->GetListWithoutPathExpansion(
1149 onc::toplevel_config::kNetworkConfigurations,
1150 &network_configs);
1151
1152 if (has_certificates) {
1153 VLOG(2) << "ONC file has " << certificates->GetSize() << " certificates";
1154
1155 // Web trust is only granted to certificates imported by the user.
1156 bool allow_trust_imports = source == onc::ONC_SOURCE_USER_IMPORT;
1157 onc::CertificateImporter cert_importer(allow_trust_imports);
1158 if (cert_importer.ParseAndStoreCertificates(
1159 *certificates, onc_trusted_certificates) !=
1160 onc::CertificateImporter::IMPORT_OK) {
1161 LOG(ERROR) << "Cannot parse some of the certificates in the ONC from "
1162 << onc::GetSourceAsString(source);
1163 success = false;
1164 } 1081 }
1165 } 1082 }
1166 1083
1167 std::set<std::string> removal_ids; 1084 std::set<std::string> removal_ids;
1168 std::set<std::string>& network_ids(network_source_map_[source]); 1085 std::set<std::string>& network_ids(network_source_map_[source]);
1169 network_ids.clear(); 1086 network_ids.clear();
1170 if (has_network_configurations) { 1087 VLOG(2) << "ONC file has " << network_configs.GetSize() << " networks";
1171 VLOG(2) << "ONC file has " << network_configs->GetSize() << " networks"; 1088 for (base::ListValue::const_iterator it(network_configs.begin());
1172 for (base::ListValue::const_iterator it(network_configs->begin()); 1089 it != network_configs.end(); ++it) {
1173 it != network_configs->end(); ++it) { 1090 const base::DictionaryValue* network;
1174 const base::DictionaryValue* network; 1091 (*it)->GetAsDictionary(&network);
1175 (*it)->GetAsDictionary(&network);
1176 1092
1177 bool marked_for_removal = false; 1093 bool marked_for_removal = false;
1178 network->GetBooleanWithoutPathExpansion(onc::kRemove, 1094 network->GetBooleanWithoutPathExpansion(onc::kRemove,
1179 &marked_for_removal); 1095 &marked_for_removal);
1180 1096
1181 std::string type; 1097 std::string type;
1182 network->GetStringWithoutPathExpansion(onc::network_config::kType, &type); 1098 network->GetStringWithoutPathExpansion(onc::network_config::kType, &type);
1183 1099
1184 std::string guid; 1100 std::string guid;
1185 network->GetStringWithoutPathExpansion(onc::network_config::kGUID, &guid); 1101 network->GetStringWithoutPathExpansion(onc::network_config::kGUID, &guid);
1186 1102
1187 if (source == onc::ONC_SOURCE_USER_IMPORT && marked_for_removal) { 1103 if (source == onc::ONC_SOURCE_USER_IMPORT && marked_for_removal) {
1188 // User import supports the removal of networks by ID. 1104 // User import supports the removal of networks by ID.
1189 removal_ids.insert(guid); 1105 removal_ids.insert(guid);
1190 continue; 1106 continue;
1107 }
1108
1109 // Don't configure a network that is supposed to be removed. For
1110 // policy-managed networks, the "remove" functionality of ONC is
1111 // irrelevant. Instead, in general, all previously configured networks
1112 // that are no longer configured are removed.
1113 if (marked_for_removal)
1114 continue;
1115
1116 // Expand strings like LoginID
1117 base::DictionaryValue* expanded_network = network->DeepCopy();
1118 UserStringSubstitution substitution;
1119 onc::ExpandStringsInOncObject(onc::kNetworkConfigurationSignature,
1120 substitution,
1121 expanded_network);
1122
1123 // Update the ONC map.
1124 const base::DictionaryValue*& entry = network_onc_map_[guid];
1125 delete entry;
1126 entry = expanded_network;
1127
1128 // Normalize the ONC: Remove irrelevant fields.
1129 onc::Normalizer normalizer(true /* remove recommended fields */);
1130 scoped_ptr<base::DictionaryValue> normalized_network =
1131 normalizer.NormalizeObject(&onc::kNetworkConfigurationSignature,
1132 *expanded_network);
1133
1134 // Configure the network.
1135 scoped_ptr<base::DictionaryValue> shill_dict =
1136 onc::TranslateONCObjectToShill(&onc::kNetworkConfigurationSignature,
1137 *normalized_network);
1138
1139 // Set the ProxyConfig.
1140 const base::DictionaryValue* proxy_settings;
1141 if (normalized_network->GetDictionaryWithoutPathExpansion(
1142 onc::network_config::kProxySettings,
1143 &proxy_settings)) {
1144 scoped_ptr<base::DictionaryValue> proxy_config =
1145 onc::ConvertOncProxySettingsToProxyConfig(*proxy_settings);
1146 std::string proxy_json;
1147 base::JSONWriter::Write(proxy_config.get(), &proxy_json);
1148 shill_dict->SetStringWithoutPathExpansion(
1149 flimflam::kProxyConfigProperty,
1150 proxy_json);
1151 }
1152
1153 // Set the UIData.
1154 scoped_ptr<NetworkUIData> ui_data =
1155 chromeos::CreateUIDataFromONC(source, *normalized_network);
1156 base::DictionaryValue ui_data_dict;
1157 ui_data->FillDictionary(&ui_data_dict);
1158 std::string ui_data_json;
1159 base::JSONWriter::Write(&ui_data_dict, &ui_data_json);
1160 shill_dict->SetStringWithoutPathExpansion(flimflam::kUIDataProperty,
1161 ui_data_json);
1162
1163 // Set the appropriate profile for |source|.
1164 if (profile != NULL) {
1165 shill_dict->SetStringWithoutPathExpansion(flimflam::kProfileProperty,
1166 profile->path);
1167 }
1168
1169 // For Ethernet networks, apply them to the current Ethernet service.
1170 if (type == onc::network_type::kEthernet) {
1171 const EthernetNetwork* ethernet = ethernet_network();
1172 if (ethernet) {
1173 CallConfigureService(ethernet->unique_id(), shill_dict.get());
1174 } else {
1175 LOG(WARNING) << "Tried to import ONC with an Ethernet network when "
1176 << "there is no active Ethernet connection.";
1191 } 1177 }
1178 } else {
1179 CallConfigureService(guid, shill_dict.get());
1180 }
1192 1181
1193 // Don't configure a network that is supposed to be removed. For 1182 // Store the network's identifier. The identifiers are later used to clean
1194 // policy-managed networks, the "remove" functionality of ONC is 1183 // out any previously-existing networks that had been configured through
1195 // irrelevant. Instead, in general, all previously configured networks 1184 // policy but are no longer specified in the updated ONC blob.
1196 // that are no longer configured are removed. 1185 network_ids.insert(guid);
1197 if (marked_for_removal)
1198 continue;
1199
1200 // Expand strings like LoginID
1201 base::DictionaryValue* expanded_network = network->DeepCopy();
1202 UserStringSubstitution substitution;
1203 onc::ExpandStringsInOncObject(onc::kNetworkConfigurationSignature,
1204 substitution,
1205 expanded_network);
1206
1207 // Update the ONC map.
1208 const base::DictionaryValue*& entry = network_onc_map_[guid];
1209 delete entry;
1210 entry = expanded_network;
1211
1212 // Normalize the ONC: Remove irrelevant fields.
1213 onc::Normalizer normalizer(true /* remove recommended fields */);
1214 scoped_ptr<base::DictionaryValue> normalized_network =
1215 normalizer.NormalizeObject(&onc::kNetworkConfigurationSignature,
1216 *expanded_network);
1217
1218 // Configure the network.
1219 scoped_ptr<base::DictionaryValue> shill_dict =
1220 onc::TranslateONCObjectToShill(&onc::kNetworkConfigurationSignature,
1221 *normalized_network);
1222
1223 // Set the ProxyConfig.
1224 const base::DictionaryValue* proxy_settings;
1225 if (normalized_network->GetDictionaryWithoutPathExpansion(
1226 onc::network_config::kProxySettings,
1227 &proxy_settings)) {
1228 scoped_ptr<base::DictionaryValue> proxy_config =
1229 onc::ConvertOncProxySettingsToProxyConfig(*proxy_settings);
1230 std::string proxy_json;
1231 base::JSONWriter::Write(proxy_config.get(), &proxy_json);
1232 shill_dict->SetStringWithoutPathExpansion(
1233 flimflam::kProxyConfigProperty,
1234 proxy_json);
1235 }
1236
1237 // Set the UIData.
1238 scoped_ptr<NetworkUIData> ui_data =
1239 chromeos::CreateUIDataFromONC(source, *normalized_network);
1240 base::DictionaryValue ui_data_dict;
1241 ui_data->FillDictionary(&ui_data_dict);
1242 std::string ui_data_json;
1243 base::JSONWriter::Write(&ui_data_dict, &ui_data_json);
1244 shill_dict->SetStringWithoutPathExpansion(flimflam::kUIDataProperty,
1245 ui_data_json);
1246
1247 // Set the appropriate profile for |source|.
1248 if (profile != NULL) {
1249 shill_dict->SetStringWithoutPathExpansion(flimflam::kProfileProperty,
1250 profile->path);
1251 }
1252
1253 // For Ethernet networks, apply them to the current Ethernet service.
1254 if (type == onc::network_type::kEthernet) {
1255 const EthernetNetwork* ethernet = ethernet_network();
1256 if (ethernet) {
1257 CallConfigureService(ethernet->unique_id(), shill_dict.get());
1258 } else {
1259 LOG(WARNING) << "Tried to import ONC with an Ethernet network when "
1260 << "there is no active Ethernet connection.";
1261 }
1262 } else {
1263 CallConfigureService(guid, shill_dict.get());
1264 }
1265
1266 // Store the network's identifier. The identifiers are later used to clean
1267 // out any previously-existing networks that had been configured through
1268 // policy but are no longer specified in the updated ONC blob.
1269 network_ids.insert(guid);
1270 }
1271 } 1186 }
1272 1187
1273 if (from_policy) { 1188 if (from_policy) {
1274 // For policy-managed networks, go through the list of existing remembered 1189 // For policy-managed networks, go through the list of existing remembered
1275 // networks and clean out the ones that no longer have a definition in the 1190 // networks and clean out the ones that no longer have a definition in the
1276 // ONC blob. We first collect the networks and do the actual deletion later 1191 // ONC blob. We first collect the networks and do the actual deletion later
1277 // because ForgetNetwork() changes the remembered network vectors. 1192 // because ForgetNetwork() changes the remembered network vectors.
1278 ForgetNetworksById(source, network_ids, false); 1193 ForgetNetworksById(source, network_ids, false);
1279 } else if (source == onc::ONC_SOURCE_USER_IMPORT && !removal_ids.empty()) { 1194 } else if (source == onc::ONC_SOURCE_USER_IMPORT && !removal_ids.empty()) {
1280 ForgetNetworksById(source, removal_ids, true); 1195 ForgetNetworksById(source, removal_ids, true);
1281 } 1196 }
1282
1283 return success;
1284 } 1197 }
1285 1198
1286 //////////////////////////////////////////////////////////////////////////// 1199 ////////////////////////////////////////////////////////////////////////////
1287 // Testing functions. 1200 // Testing functions.
1288 1201
1289 bool NetworkLibraryImplBase::SetActiveNetwork( 1202 bool NetworkLibraryImplBase::SetActiveNetwork(
1290 ConnectionType type, const std::string& service_path) { 1203 ConnectionType type, const std::string& service_path) {
1291 Network* network = NULL; 1204 Network* network = NULL;
1292 if (!service_path.empty()) 1205 if (!service_path.empty())
1293 network = FindNetworkByPath(service_path); 1206 network = FindNetworkByPath(service_path);
(...skipping 503 matching lines...) Expand 10 before | Expand all | Expand 10 after
1797 GetTpmInfo(); 1710 GetTpmInfo();
1798 return tpm_slot_; 1711 return tpm_slot_;
1799 } 1712 }
1800 1713
1801 const std::string& NetworkLibraryImplBase::GetTpmPin() { 1714 const std::string& NetworkLibraryImplBase::GetTpmPin() {
1802 GetTpmInfo(); 1715 GetTpmInfo();
1803 return tpm_pin_; 1716 return tpm_pin_;
1804 } 1717 }
1805 1718
1806 } // namespace chromeos 1719 } // namespace chromeos
OLDNEW
« no previous file with comments | « chrome/browser/chromeos/cros/network_library_impl_base.h ('k') | chrome/browser/chromeos/cros/network_library_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698