Chromium Code Reviews| 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/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_reader.h" | 8 #include "base/json/json_reader.h" |
| 9 #include "base/json/json_writer.h" | |
| 9 #include "base/memory/scoped_vector.h" | 10 #include "base/memory/scoped_vector.h" |
| 10 #include "base/metrics/histogram.h" | 11 #include "base/metrics/histogram.h" |
| 11 #include "base/stl_util.h" | 12 #include "base/stl_util.h" |
| 12 #include "chrome/browser/chromeos/cros/native_network_parser.h" | |
| 13 #include "chrome/browser/chromeos/cros/network_constants.h" | 13 #include "chrome/browser/chromeos/cros/network_constants.h" |
| 14 #include "chrome/browser/chromeos/cros/onc_network_parser.h" | 14 #include "chrome/browser/chromeos/login/user_manager.h" |
| 15 #include "chrome/browser/chromeos/net/onc_utils.h" | |
| 15 #include "chrome/browser/chromeos/network_login_observer.h" | 16 #include "chrome/browser/chromeos/network_login_observer.h" |
| 16 #include "chromeos/network/onc/onc_certificate_importer.h" | 17 #include "chromeos/network/onc/onc_certificate_importer.h" |
| 17 #include "chromeos/network/onc/onc_constants.h" | 18 #include "chromeos/network/onc/onc_constants.h" |
| 18 #include "chromeos/network/onc/onc_signature.h" | 19 #include "chromeos/network/onc/onc_signature.h" |
| 20 #include "chromeos/network/onc/onc_translator.h" | |
| 19 #include "chromeos/network/onc/onc_utils.h" | 21 #include "chromeos/network/onc/onc_utils.h" |
| 20 #include "chromeos/network/onc/onc_validator.h" | 22 #include "chromeos/network/onc/onc_validator.h" |
| 21 #include "content/public/browser/browser_thread.h" | 23 #include "content/public/browser/browser_thread.h" |
| 22 #include "crypto/nss_util.h" // crypto::GetTPMTokenInfo() for 802.1X and VPN. | 24 #include "crypto/nss_util.h" // crypto::GetTPMTokenInfo() for 802.1X and VPN. |
| 23 #include "grit/generated_resources.h" | 25 #include "grit/generated_resources.h" |
| 24 #include "third_party/cros_system_api/dbus/service_constants.h" | 26 #include "third_party/cros_system_api/dbus/service_constants.h" |
| 25 #include "ui/base/l10n/l10n_util.h" | 27 #include "ui/base/l10n/l10n_util.h" |
| 26 | 28 |
| 27 using content::BrowserThread; | 29 using content::BrowserThread; |
| 28 | 30 |
| (...skipping 994 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1023 continue; | 1025 continue; |
| 1024 if (!wifi->preferred()) // All preferred networks are sorted in front. | 1026 if (!wifi->preferred()) // All preferred networks are sorted in front. |
| 1025 break; | 1027 break; |
| 1026 if (wifi->auto_connect()) { | 1028 if (wifi->auto_connect()) { |
| 1027 ConnectToWifiNetwork(wifi); | 1029 ConnectToWifiNetwork(wifi); |
| 1028 break; | 1030 break; |
| 1029 } | 1031 } |
| 1030 } | 1032 } |
| 1031 } | 1033 } |
| 1032 | 1034 |
| 1035 namespace { | |
| 1036 | |
| 1037 class UserStringSubstitution : public onc::StringSubstitution { | |
| 1038 public: | |
| 1039 UserStringSubstitution() {} | |
| 1040 virtual bool GetSubstitute(std::string placeholder, | |
| 1041 std::string* substitute) { | |
| 1042 if (!content::BrowserThread::IsMessageLoopValid( | |
| 1043 content::BrowserThread::UI) || | |
|
stevenjb
2012/12/21 18:38:36
This is an odd place for a thread check. I would e
pneubeck (no reviews)
2013/01/09 17:04:05
Yeah, I dropped the original comment during copy/p
| |
| 1044 !UserManager::Get()->IsUserLoggedIn()) { | |
| 1045 return false; | |
| 1046 } | |
| 1047 | |
| 1048 const User* logged_in_user = UserManager::Get()->GetLoggedInUser(); | |
| 1049 if (placeholder == onc::substitutes::kLoginIDField) | |
| 1050 *substitute = logged_in_user->GetAccountName(false); | |
| 1051 else if (placeholder == onc::substitutes::kEmailField) | |
| 1052 *substitute = logged_in_user->email(); | |
| 1053 else | |
| 1054 return false; | |
| 1055 return true; | |
| 1056 } | |
| 1057 }; | |
| 1058 | |
| 1059 } // namespace | |
| 1060 | |
| 1033 bool NetworkLibraryImplBase::LoadOncNetworks(const std::string& onc_blob, | 1061 bool NetworkLibraryImplBase::LoadOncNetworks(const std::string& onc_blob, |
| 1034 const std::string& passphrase, | 1062 const std::string& passphrase, |
| 1035 onc::ONCSource source, | 1063 onc::ONCSource source, |
| 1036 bool allow_web_trust_from_policy) { | 1064 bool allow_web_trust_from_policy) { |
| 1037 VLOG(2) << __func__ << ": called on " << onc_blob; | 1065 VLOG(2) << __func__ << ": called on " << onc_blob; |
| 1038 NetworkProfile* profile = NULL; | 1066 NetworkProfile* profile = NULL; |
| 1039 bool from_policy = (source == onc::ONC_SOURCE_USER_POLICY || | 1067 bool from_policy = (source == onc::ONC_SOURCE_USER_POLICY || |
| 1040 source == onc::ONC_SOURCE_DEVICE_POLICY); | 1068 source == onc::ONC_SOURCE_DEVICE_POLICY); |
| 1041 | 1069 |
| 1042 // Policies are applied to a specific Shill profile. User ONC import however | 1070 // Policies are applied to a specific Shill profile. User ONC import however |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 1073 } | 1101 } |
| 1074 | 1102 |
| 1075 // Validate the ONC dictionary. We are liberal and ignore unknown field | 1103 // Validate the ONC dictionary. We are liberal and ignore unknown field |
| 1076 // names and ignore invalid field names in kRecommended arrays. | 1104 // names and ignore invalid field names in kRecommended arrays. |
| 1077 onc::Validator validator(false, // Ignore unknown fields. | 1105 onc::Validator validator(false, // Ignore unknown fields. |
| 1078 false, // Ignore invalid recommended field names. | 1106 false, // Ignore invalid recommended field names. |
| 1079 true, // Fail on missing fields. | 1107 true, // Fail on missing fields. |
| 1080 from_policy); | 1108 from_policy); |
| 1081 | 1109 |
| 1082 onc::Validator::Result validation_result; | 1110 onc::Validator::Result validation_result; |
| 1083 validator.ValidateAndRepairObject(&onc::kToplevelConfigurationSignature, | 1111 root_dict = validator.ValidateAndRepairObject( |
| 1084 *root_dict, | 1112 &onc::kToplevelConfigurationSignature, |
| 1085 &validation_result); | 1113 *root_dict, |
| 1114 &validation_result); | |
| 1086 | 1115 |
| 1087 if (from_policy) { | 1116 if (from_policy) { |
| 1088 UMA_HISTOGRAM_BOOLEAN("Enterprise.ONC.PolicyValidation", | 1117 UMA_HISTOGRAM_BOOLEAN("Enterprise.ONC.PolicyValidation", |
| 1089 validation_result == onc::Validator::VALID); | 1118 validation_result == onc::Validator::VALID); |
| 1090 } | 1119 } |
| 1091 | 1120 |
| 1092 bool success = true; | |
| 1093 if (validation_result == onc::Validator::VALID_WITH_WARNINGS) { | 1121 if (validation_result == onc::Validator::VALID_WITH_WARNINGS) { |
| 1094 LOG(WARNING) << "ONC from " << onc::GetSourceAsString(source) | 1122 LOG(WARNING) << "ONC from " << onc::GetSourceAsString(source) |
| 1095 << " produced warnings."; | 1123 << " produced warnings."; |
| 1096 } else if (validation_result == onc::Validator::INVALID) { | 1124 } else if (validation_result == onc::Validator::INVALID || |
| 1125 root_dict == NULL) { | |
| 1097 LOG(ERROR) << "ONC from " << onc::GetSourceAsString(source) | 1126 LOG(ERROR) << "ONC from " << onc::GetSourceAsString(source) |
| 1098 << " is invalid and couldn't be repaired."; | 1127 << " is invalid and couldn't be repaired."; |
| 1099 success = false; | 1128 return false; |
| 1100 } | 1129 } |
| 1101 | 1130 |
| 1102 const base::ListValue* certificates; | 1131 const base::ListValue* certificates; |
| 1103 bool has_certificates = | 1132 bool has_certificates = |
| 1104 root_dict->GetListWithoutPathExpansion(onc::kCertificates, &certificates); | 1133 root_dict->GetListWithoutPathExpansion(onc::kCertificates, &certificates); |
| 1105 | 1134 |
| 1106 const base::ListValue* network_configs; | 1135 const base::ListValue* network_configs; |
| 1107 bool has_network_configurations = root_dict->GetListWithoutPathExpansion( | 1136 bool has_network_configurations = root_dict->GetListWithoutPathExpansion( |
| 1108 onc::kNetworkConfigurations, | 1137 onc::kNetworkConfigurations, |
| 1109 &network_configs); | 1138 &network_configs); |
| 1110 | 1139 |
| 1140 bool success = true; | |
| 1111 if (has_certificates) { | 1141 if (has_certificates) { |
| 1112 VLOG(2) << "ONC file has " << certificates->GetSize() << " certificates"; | 1142 VLOG(2) << "ONC file has " << certificates->GetSize() << " certificates"; |
| 1113 | 1143 |
| 1114 onc::CertificateImporter cert_importer(source, allow_web_trust_from_policy); | 1144 onc::CertificateImporter cert_importer(source, allow_web_trust_from_policy); |
| 1115 if (cert_importer.ParseAndStoreCertificates(*certificates) != | 1145 if (cert_importer.ParseAndStoreCertificates(*certificates) != |
| 1116 onc::CertificateImporter::IMPORT_OK) { | 1146 onc::CertificateImporter::IMPORT_OK) { |
| 1117 LOG(ERROR) << "Cannot parse some of the certificates in the ONC from " | 1147 LOG(ERROR) << "Cannot parse some of the certificates in the ONC from " |
| 1118 << onc::GetSourceAsString(source); | 1148 << onc::GetSourceAsString(source); |
| 1119 success = false; | 1149 success = false; |
| 1120 } | 1150 } |
| 1121 } | 1151 } |
| 1122 | 1152 |
| 1123 std::set<std::string> removal_ids; | 1153 std::set<std::string> removal_ids; |
| 1124 std::set<std::string>& network_ids(network_source_map_[source]); | 1154 std::set<std::string>& network_ids(network_source_map_[source]); |
| 1125 network_ids.clear(); | 1155 network_ids.clear(); |
| 1126 if (has_network_configurations) { | 1156 if (has_network_configurations) { |
| 1127 VLOG(2) << "ONC file has " << network_configs->GetSize() << " networks"; | 1157 VLOG(2) << "ONC file has " << network_configs->GetSize() << " networks"; |
| 1128 OncNetworkParser parser(*network_configs, source); | 1158 for (base::ListValue::const_iterator it(network_configs->begin()); |
| 1159 it != network_configs->end(); ++it) { | |
| 1160 const base::DictionaryValue* network; | |
| 1161 (*it)->GetAsDictionary(&network); | |
| 1129 | 1162 |
| 1130 for (int i = 0; i < parser.GetNetworkConfigsSize(); i++) { | |
| 1131 // Parse Open Network Configuration blob into a temporary Network object. | |
| 1132 bool marked_for_removal = false; | 1163 bool marked_for_removal = false; |
| 1133 scoped_ptr<Network> network(parser.ParseNetwork(i, &marked_for_removal)); | 1164 network->GetBooleanWithoutPathExpansion(onc::kRemove, |
| 1134 if (!network) { | 1165 &marked_for_removal); |
| 1135 LOG(ERROR) << "Error during ONC parsing network at index " << i | 1166 |
| 1136 << " from " << onc::GetSourceAsString(source); | 1167 std::string type; |
| 1137 success = false; | 1168 network->GetStringWithoutPathExpansion(onc::kType, |
| 1138 continue; | 1169 &type); |
|
stevenjb
2012/12/21 18:38:36
one line
pneubeck (no reviews)
2013/01/09 17:04:05
Done.
| |
| 1139 } | |
| 1140 | 1170 |
| 1141 // Disallow anything but WiFi and Ethernet for device-level policy (which | 1171 // Disallow anything but WiFi and Ethernet for device-level policy (which |
| 1142 // corresponds to shared networks). See also http://crosbug.com/28741. | 1172 // corresponds to shared networks). See also http://crosbug.com/28741. |
| 1143 if (source == onc::ONC_SOURCE_DEVICE_POLICY && | 1173 if (source == onc::ONC_SOURCE_DEVICE_POLICY && |
| 1144 network->type() != TYPE_WIFI && | 1174 type != onc::kWiFi && |
| 1145 network->type() != TYPE_ETHERNET) { | 1175 type != onc::kEthernet) { |
| 1146 LOG(WARNING) << "Ignoring device-level policy-pushed network of type " | 1176 LOG(WARNING) << "Ignoring device-level policy-pushed network of type " |
| 1147 << network->type(); | 1177 << type; |
| 1148 continue; | 1178 continue; |
| 1149 } | 1179 } |
| 1150 | 1180 |
| 1181 std::string guid; | |
| 1182 network->GetStringWithoutPathExpansion(onc::kGUID, | |
| 1183 &guid); | |
|
stevenjb
2012/12/21 18:38:36
one line
pneubeck (no reviews)
2013/01/09 17:04:05
Done.
| |
| 1184 | |
| 1151 if (source == onc::ONC_SOURCE_USER_IMPORT && marked_for_removal) { | 1185 if (source == onc::ONC_SOURCE_USER_IMPORT && marked_for_removal) { |
| 1152 // User import supports the removal of networks by ID. | 1186 // User import supports the removal of networks by ID. |
| 1153 removal_ids.insert(network->unique_id()); | 1187 removal_ids.insert(guid); |
| 1154 continue; | 1188 continue; |
| 1155 } | 1189 } |
| 1156 | 1190 |
| 1157 if (marked_for_removal) { | 1191 if (marked_for_removal) { |
| 1158 // Don't configure a network that is supposed to be removed. For | 1192 // Don't configure a network that is supposed to be removed. For |
| 1159 // policy-managed networks, the "remove" functionality of ONC is | 1193 // policy-managed networks, the "remove" functionality of ONC is |
| 1160 // irrelevant. Instead in general, all previously configured networks | 1194 // irrelevant. Instead in general, all previously configured networks |
| 1161 // that are no longer configured are removed. | 1195 // that are no longer configured are removed. |
| 1162 continue; | 1196 continue; |
| 1163 } | 1197 } |
| 1164 | 1198 |
| 1199 // Expand strings like LoginID | |
| 1200 base::DictionaryValue* expanded_network = network->DeepCopy(); | |
| 1201 UserStringSubstitution substitution; | |
| 1202 ExpandStringsInOncObject(onc::kNetworkConfigurationSignature, | |
| 1203 &substitution, | |
| 1204 expanded_network); | |
| 1205 | |
| 1165 // Update the ONC map. | 1206 // Update the ONC map. |
| 1166 const base::DictionaryValue*& entry = | 1207 const base::DictionaryValue*& entry = network_onc_map_[guid]; |
| 1167 network_onc_map_[network->unique_id()]; | |
| 1168 delete entry; | 1208 delete entry; |
| 1169 entry = parser.GetNetworkConfig(i)->DeepCopy(); | 1209 entry = expanded_network; |
| 1170 | 1210 |
| 1171 // Configure the network. | 1211 // Configure the network. |
| 1172 base::DictionaryValue dict; | 1212 scoped_ptr<base::DictionaryValue> shill_dict = |
| 1173 for (Network::PropertyMap::const_iterator props = | 1213 onc::TranslateONCObjectToShill(&onc::kNetworkConfigurationSignature, |
| 1174 network->property_map_.begin(); | 1214 *expanded_network); |
| 1175 props != network->property_map_.end(); ++props) { | 1215 |
| 1176 std::string key = | 1216 // Set the ProxyConfig. |
| 1177 NativeNetworkParser::property_mapper()->GetKey(props->first); | 1217 const base::DictionaryValue* proxy_settings; |
| 1178 if (!key.empty()) | 1218 if (expanded_network->GetDictionaryWithoutPathExpansion( |
| 1179 dict.SetWithoutPathExpansion(key, props->second->DeepCopy()); | 1219 onc::kProxySettings, |
| 1180 else | 1220 &proxy_settings)) { |
| 1181 VLOG(2) << "Property " << props->first << " will not be sent"; | 1221 scoped_ptr<base::DictionaryValue> proxy_config = |
| 1222 onc::ConvertOncProxySettingsToProxyConfig(*proxy_settings); | |
| 1223 std::string proxy_json; | |
| 1224 base::JSONWriter::Write(proxy_config.get(), &proxy_json); | |
| 1225 shill_dict->SetStringWithoutPathExpansion( | |
| 1226 flimflam::kProxyConfigProperty, | |
| 1227 proxy_json); | |
| 1182 } | 1228 } |
| 1183 | 1229 |
| 1230 // Set the UIData. | |
| 1231 scoped_ptr<base::DictionaryValue> ui_data = | |
| 1232 CreateUIData(source, *expanded_network); | |
| 1233 std::string ui_data_json; | |
| 1234 base::JSONWriter::Write(ui_data.get(), &ui_data_json); | |
| 1235 shill_dict->SetStringWithoutPathExpansion( | |
| 1236 flimflam::kUIDataProperty, | |
| 1237 ui_data_json); | |
| 1238 | |
| 1184 // Set the appropriate profile for |source|. | 1239 // Set the appropriate profile for |source|. |
| 1185 if (profile != NULL) | 1240 if (profile != NULL) { |
| 1186 dict.SetString(flimflam::kProfileProperty, profile->path); | 1241 shill_dict->SetStringWithoutPathExpansion(flimflam::kProfileProperty, |
| 1242 profile->path); | |
| 1243 } | |
| 1187 | 1244 |
| 1188 // For Ethernet networks, apply them to the current Ethernet service. | 1245 // For Ethernet networks, apply them to the current Ethernet service. |
| 1189 if (network->type() == TYPE_ETHERNET) { | 1246 if (type == onc::kEthernet) { |
| 1190 const EthernetNetwork* ethernet = ethernet_network(); | 1247 const EthernetNetwork* ethernet = ethernet_network(); |
| 1191 if (ethernet) { | 1248 if (ethernet) { |
| 1192 CallConfigureService(ethernet->unique_id(), &dict); | 1249 CallConfigureService(ethernet->unique_id(), shill_dict.get()); |
| 1193 } else { | 1250 } else { |
| 1194 LOG(WARNING) << "Tried to import ONC with an Ethernet network when " | 1251 LOG(WARNING) << "Tried to import ONC with an Ethernet network when " |
| 1195 << "there is no active Ethernet connection."; | 1252 << "there is no active Ethernet connection."; |
| 1196 } | 1253 } |
| 1197 } else { | 1254 } else { |
| 1198 CallConfigureService(network->unique_id(), &dict); | 1255 CallConfigureService(guid, shill_dict.get()); |
| 1199 } | 1256 } |
| 1200 | 1257 |
| 1201 // Store the unique identifier of the network that is defined in the ONC | 1258 network_ids.insert(guid); |
| 1202 // blob in |network_ids|. The identifiers are later used to clean out any | |
| 1203 // previously-existing networks that had been configured through policy | |
| 1204 // but are no longer specified in the updated ONC blob. | |
| 1205 network_ids.insert(network->unique_id()); | |
| 1206 } | 1259 } |
| 1207 } | 1260 } |
| 1208 | 1261 |
| 1209 if (from_policy) { | 1262 if (from_policy) { |
| 1210 // For policy-managed networks, go through the list of existing remembered | 1263 // For policy-managed networks, go through the list of existing remembered |
| 1211 // networks and clean out the ones that no longer have a definition in the | 1264 // networks and clean out the ones that no longer have a definition in the |
| 1212 // ONC blob. We first collect the networks and do the actual deletion later | 1265 // ONC blob. We first collect the networks and do the actual deletion later |
| 1213 // because ForgetNetwork() changes the remembered network vectors. | 1266 // because ForgetNetwork() changes the remembered network vectors. |
| 1214 ForgetNetworksById(source, network_ids, false); | 1267 ForgetNetworksById(source, network_ids, false); |
| 1215 } else if (source == onc::ONC_SOURCE_USER_IMPORT && !removal_ids.empty()) { | 1268 } else if (source == onc::ONC_SOURCE_USER_IMPORT && !removal_ids.empty()) { |
| (...skipping 517 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1733 GetTpmInfo(); | 1786 GetTpmInfo(); |
| 1734 return tpm_slot_; | 1787 return tpm_slot_; |
| 1735 } | 1788 } |
| 1736 | 1789 |
| 1737 const std::string& NetworkLibraryImplBase::GetTpmPin() { | 1790 const std::string& NetworkLibraryImplBase::GetTpmPin() { |
| 1738 GetTpmInfo(); | 1791 GetTpmInfo(); |
| 1739 return tpm_pin_; | 1792 return tpm_pin_; |
| 1740 } | 1793 } |
| 1741 | 1794 |
| 1742 } // namespace chromeos | 1795 } // namespace chromeos |
| OLD | NEW |