| 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/memory/scoped_vector.h" | 9 #include "base/memory/scoped_vector.h" |
| 10 #include "base/metrics/histogram.h" | 10 #include "base/metrics/histogram.h" |
| (...skipping 1008 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1019 ConnectToWifiNetwork(wifi); | 1019 ConnectToWifiNetwork(wifi); |
| 1020 break; | 1020 break; |
| 1021 } | 1021 } |
| 1022 } | 1022 } |
| 1023 } | 1023 } |
| 1024 | 1024 |
| 1025 bool NetworkLibraryImplBase::LoadOncNetworks(const std::string& onc_blob, | 1025 bool NetworkLibraryImplBase::LoadOncNetworks(const std::string& onc_blob, |
| 1026 const std::string& passphrase, | 1026 const std::string& passphrase, |
| 1027 onc::ONCSource source, | 1027 onc::ONCSource source, |
| 1028 bool allow_web_trust_from_policy) { | 1028 bool allow_web_trust_from_policy) { |
| 1029 VLOG(2) << __func__ << ": called on " << onc_blob; |
| 1029 NetworkProfile* profile = NULL; | 1030 NetworkProfile* profile = NULL; |
| 1030 bool from_policy = (source == onc::ONC_SOURCE_USER_POLICY || | 1031 bool from_policy = (source == onc::ONC_SOURCE_USER_POLICY || |
| 1031 source == onc::ONC_SOURCE_DEVICE_POLICY); | 1032 source == onc::ONC_SOURCE_DEVICE_POLICY); |
| 1032 | 1033 |
| 1033 // Policies are applied to a specific Shill profile. User ONC import however | 1034 // Policies are applied to a specific Shill profile. User ONC import however |
| 1034 // is applied to whatever profile Shill chooses. This should be the profile | 1035 // is applied to whatever profile Shill chooses. This should be the profile |
| 1035 // that is already associated with a network and if no profile is associated | 1036 // that is already associated with a network and if no profile is associated |
| 1036 // yet, it should be the user profile. | 1037 // yet, it should be the user profile. |
| 1037 if (from_policy) { | 1038 if (from_policy) { |
| 1038 profile = GetProfileForType(GetProfileTypeForSource(source)); | 1039 profile = GetProfileForType(GetProfileTypeForSource(source)); |
| 1039 if (profile == NULL) { | 1040 if (profile == NULL) { |
| 1040 DLOG(WARNING) << "Profile for ONC source " | 1041 VLOG(2) << "Profile for ONC source " << onc::GetSourceAsString(source) |
| 1041 << onc::GetSourceAsString(source) | 1042 << " doesn't exist."; |
| 1042 << " doesn't exist."; | 1043 return true; |
| 1043 return false; | |
| 1044 } | 1044 } |
| 1045 } | 1045 } |
| 1046 | 1046 |
| 1047 VLOG(2) << __func__ << ": called on " << onc_blob; | |
| 1048 scoped_ptr<base::DictionaryValue> root_dict = | 1047 scoped_ptr<base::DictionaryValue> root_dict = |
| 1049 onc::ReadDictionaryFromJson(onc_blob); | 1048 onc::ReadDictionaryFromJson(onc_blob); |
| 1050 if (root_dict.get() == NULL) { | 1049 if (root_dict.get() == NULL) { |
| 1051 LOG(WARNING) << "ONC loaded from " << onc::GetSourceAsString(source) | 1050 LOG(ERROR) << "ONC loaded from " << onc::GetSourceAsString(source) |
| 1052 << " is not a valid JSON dictionary."; | 1051 << " is not a valid JSON dictionary."; |
| 1053 return false; | 1052 return false; |
| 1054 } | 1053 } |
| 1055 | 1054 |
| 1056 // Check and see if this is an encrypted ONC file. If so, decrypt it. | 1055 // Check and see if this is an encrypted ONC file. If so, decrypt it. |
| 1057 std::string onc_type; | 1056 std::string onc_type; |
| 1058 root_dict->GetStringWithoutPathExpansion(onc::kType, &onc_type); | 1057 root_dict->GetStringWithoutPathExpansion(onc::kType, &onc_type); |
| 1059 if (onc_type == onc::kEncryptedConfiguration) { | 1058 if (onc_type == onc::kEncryptedConfiguration) { |
| 1060 root_dict = onc::Decrypt(passphrase, *root_dict); | 1059 root_dict = onc::Decrypt(passphrase, *root_dict); |
| 1061 if (root_dict.get() == NULL) { | 1060 if (root_dict.get() == NULL) { |
| 1062 LOG(WARNING) << "Couldn't decrypt the ONC from " | 1061 LOG(ERROR) << "Couldn't decrypt the ONC from " |
| 1063 << onc::GetSourceAsString(source); | 1062 << onc::GetSourceAsString(source); |
| 1064 return false; | 1063 return false; |
| 1065 } | 1064 } |
| 1066 } | 1065 } |
| 1067 | 1066 |
| 1068 // Validate the ONC dictionary. We are liberal and ignore unknown field | 1067 // Validate the ONC dictionary. We are liberal and ignore unknown field |
| 1069 // names and ignore invalid field names in kRecommended arrays. | 1068 // names and ignore invalid field names in kRecommended arrays. |
| 1070 onc::Validator validator(false, // Ignore unknown fields. | 1069 onc::Validator validator(false, // Ignore unknown fields. |
| 1071 false, // Ignore invalid recommended field names. | 1070 false, // Ignore invalid recommended field names. |
| 1072 true, // Fail on missing fields. | 1071 true, // Fail on missing fields. |
| 1073 from_policy); | 1072 from_policy); |
| 1074 | 1073 |
| 1075 // Unknown fields are removed from the result. | 1074 // Unknown fields are removed from the result. |
| 1076 scoped_ptr<base::DictionaryValue> validation_result = | 1075 onc::Validator::Result validation_result; |
| 1077 validator.ValidateAndRepairObject( | 1076 validator.ValidateAndRepairObject(&onc::kToplevelConfigurationSignature, |
| 1078 &onc::kUnencryptedConfigurationSignature, | 1077 *root_dict, |
| 1079 *root_dict); | 1078 &validation_result); |
| 1080 | 1079 |
| 1081 if (from_policy) { | 1080 if (from_policy) { |
| 1082 UMA_HISTOGRAM_BOOLEAN("Enterprise.ONC.PolicyValidation", | 1081 UMA_HISTOGRAM_BOOLEAN("Enterprise.ONC.PolicyValidation", |
| 1083 validation_result.get() != NULL); | 1082 validation_result == onc::Validator::VALID); |
| 1084 } | 1083 } |
| 1085 | 1084 |
| 1086 if (validation_result.get() == NULL) { | 1085 if (validation_result == onc::Validator::VALID_WITH_WARNINGS) { |
| 1087 LOG(WARNING) << "ONC from source " << source | 1086 LOG(WARNING) << "ONC from " << onc::GetSourceAsString(source) |
| 1088 << " is invalid and couldn't be repaired."; | 1087 << " produced warnings."; |
| 1088 } else if (validation_result == onc::Validator::INVALID) { |
| 1089 LOG(ERROR) << "ONC from " << onc::GetSourceAsString(source) |
| 1090 << " is invalid and couldn't be repaired."; |
| 1089 } | 1091 } |
| 1090 | 1092 |
| 1091 const base::ListValue* certificates; | 1093 const base::ListValue* certificates; |
| 1092 bool has_certificates = | 1094 bool has_certificates = |
| 1093 root_dict->GetListWithoutPathExpansion(onc::kCertificates, &certificates); | 1095 root_dict->GetListWithoutPathExpansion(onc::kCertificates, &certificates); |
| 1094 | 1096 |
| 1095 const base::ListValue* network_configs; | 1097 const base::ListValue* network_configs; |
| 1096 bool has_network_configurations = root_dict->GetListWithoutPathExpansion( | 1098 bool has_network_configurations = root_dict->GetListWithoutPathExpansion( |
| 1097 onc::kNetworkConfigurations, | 1099 onc::kNetworkConfigurations, |
| 1098 &network_configs); | 1100 &network_configs); |
| 1099 | 1101 |
| 1100 // At least one of NetworkConfigurations or Certificates is required. | |
| 1101 LOG_IF(WARNING, (!has_network_configurations && !has_certificates)) | |
| 1102 << "ONC from source " << source | |
| 1103 << " has neither NetworkConfigurations nor Certificates."; | |
| 1104 | |
| 1105 if (has_certificates) { | 1102 if (has_certificates) { |
| 1106 VLOG(2) << "ONC file has " << certificates->GetSize() << " certificates"; | 1103 VLOG(2) << "ONC file has " << certificates->GetSize() << " certificates"; |
| 1107 | 1104 |
| 1108 onc::CertificateImporter cert_importer(source, allow_web_trust_from_policy); | 1105 onc::CertificateImporter cert_importer(source, allow_web_trust_from_policy); |
| 1109 if (cert_importer.ParseAndStoreCertificates(*certificates) != | 1106 if (cert_importer.ParseAndStoreCertificates(*certificates) != |
| 1110 onc::CertificateImporter::IMPORT_OK) { | 1107 onc::CertificateImporter::IMPORT_OK) { |
| 1111 LOG(WARNING) << "Cannot parse some of the certificates in the ONC from " | 1108 LOG(ERROR) << "Cannot parse some of the certificates in the ONC from " |
| 1112 << onc::GetSourceAsString(source); | 1109 << onc::GetSourceAsString(source); |
| 1113 return false; | 1110 return false; |
| 1114 } | 1111 } |
| 1115 } | 1112 } |
| 1116 | 1113 |
| 1117 std::set<std::string> removal_ids; | 1114 std::set<std::string> removal_ids; |
| 1118 std::set<std::string>& network_ids(network_source_map_[source]); | 1115 std::set<std::string>& network_ids(network_source_map_[source]); |
| 1119 network_ids.clear(); | 1116 network_ids.clear(); |
| 1120 if (has_network_configurations) { | 1117 if (has_network_configurations) { |
| 1121 VLOG(2) << "ONC file has " << network_configs->GetSize() << " networks"; | 1118 VLOG(2) << "ONC file has " << network_configs->GetSize() << " networks"; |
| 1122 OncNetworkParser parser(*network_configs, source); | 1119 OncNetworkParser parser(*network_configs, source); |
| 1123 | 1120 |
| 1124 // Parse all networks. Bail out if that fails. | 1121 // Parse all networks. Bail out if that fails. |
| 1125 NetworkOncMap added_onc_map; | 1122 NetworkOncMap added_onc_map; |
| 1126 ScopedVector<Network> networks; | 1123 ScopedVector<Network> networks; |
| 1127 for (int i = 0; i < parser.GetNetworkConfigsSize(); i++) { | 1124 for (int i = 0; i < parser.GetNetworkConfigsSize(); i++) { |
| 1128 // Parse Open Network Configuration blob into a temporary Network object. | 1125 // Parse Open Network Configuration blob into a temporary Network object. |
| 1129 bool marked_for_removal = false; | 1126 bool marked_for_removal = false; |
| 1130 Network* network = parser.ParseNetwork(i, &marked_for_removal); | 1127 Network* network = parser.ParseNetwork(i, &marked_for_removal); |
| 1131 if (!network) { | 1128 if (!network) { |
| 1132 LOG(WARNING) << "Error during parsing network at index " << i | 1129 LOG(ERROR) << "Error during ONC parsing network at index " << i |
| 1133 << " from ONC source " << onc::GetSourceAsString(source); | 1130 << " from " << onc::GetSourceAsString(source); |
| 1134 return false; | 1131 return false; |
| 1135 } | 1132 } |
| 1136 | 1133 |
| 1137 // Disallow anything but WiFi and Ethernet for device-level policy (which | 1134 // Disallow anything but WiFi and Ethernet for device-level policy (which |
| 1138 // corresponds to shared networks). See also http://crosbug.com/28741. | 1135 // corresponds to shared networks). See also http://crosbug.com/28741. |
| 1139 if (source == onc::ONC_SOURCE_DEVICE_POLICY && | 1136 if (source == onc::ONC_SOURCE_DEVICE_POLICY && |
| 1140 network->type() != TYPE_WIFI && | 1137 network->type() != TYPE_WIFI && |
| 1141 network->type() != TYPE_ETHERNET) { | 1138 network->type() != TYPE_ETHERNET) { |
| 1142 LOG(WARNING) << "Ignoring device-level policy-pushed network of type " | 1139 LOG(WARNING) << "Ignoring device-level policy-pushed network of type " |
| 1143 << network->type(); | 1140 << network->type(); |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1194 // Set the appropriate profile for |source|. | 1191 // Set the appropriate profile for |source|. |
| 1195 if (profile != NULL) | 1192 if (profile != NULL) |
| 1196 dict.SetString(flimflam::kProfileProperty, profile->path); | 1193 dict.SetString(flimflam::kProfileProperty, profile->path); |
| 1197 | 1194 |
| 1198 // For Ethernet networks, apply them to the current Ethernet service. | 1195 // For Ethernet networks, apply them to the current Ethernet service. |
| 1199 if (network->type() == TYPE_ETHERNET) { | 1196 if (network->type() == TYPE_ETHERNET) { |
| 1200 const EthernetNetwork* ethernet = ethernet_network(); | 1197 const EthernetNetwork* ethernet = ethernet_network(); |
| 1201 if (ethernet) { | 1198 if (ethernet) { |
| 1202 CallConfigureService(ethernet->unique_id(), &dict); | 1199 CallConfigureService(ethernet->unique_id(), &dict); |
| 1203 } else { | 1200 } else { |
| 1204 DLOG(WARNING) << "Tried to import ONC with an Ethernet network when " | 1201 LOG(WARNING) << "Tried to import ONC with an Ethernet network when " |
| 1205 << "there is no active Ethernet connection."; | 1202 << "there is no active Ethernet connection."; |
| 1206 } | 1203 } |
| 1207 } else { | 1204 } else { |
| 1208 CallConfigureService(network->unique_id(), &dict); | 1205 CallConfigureService(network->unique_id(), &dict); |
| 1209 } | 1206 } |
| 1210 | 1207 |
| 1211 network_ids.insert(network->unique_id()); | 1208 network_ids.insert(network->unique_id()); |
| 1212 } | 1209 } |
| 1213 } | 1210 } |
| 1214 | 1211 |
| 1215 if (from_policy) { | 1212 if (from_policy) { |
| (...skipping 526 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1742 GetTpmInfo(); | 1739 GetTpmInfo(); |
| 1743 return tpm_slot_; | 1740 return tpm_slot_; |
| 1744 } | 1741 } |
| 1745 | 1742 |
| 1746 const std::string& NetworkLibraryImplBase::GetTpmPin() { | 1743 const std::string& NetworkLibraryImplBase::GetTpmPin() { |
| 1747 GetTpmInfo(); | 1744 GetTpmInfo(); |
| 1748 return tpm_pin_; | 1745 return tpm_pin_; |
| 1749 } | 1746 } |
| 1750 | 1747 |
| 1751 } // namespace chromeos | 1748 } // namespace chromeos |
| OLD | NEW |