OLD | NEW |
---|---|
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 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 "chromeos/network/policy_util.h" | 5 #include "chromeos/network/policy_util.h" |
6 | 6 |
7 #include "base/logging.h" | 7 #include "base/logging.h" |
8 #include "base/values.h" | 8 #include "base/values.h" |
9 #include "chromeos/network/network_profile.h" | 9 #include "chromeos/network/network_profile.h" |
10 #include "chromeos/network/network_ui_data.h" | 10 #include "chromeos/network/network_ui_data.h" |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
118 policy_wifi->GetStringWithoutPathExpansion(::onc::wifi::kSSID, | 118 policy_wifi->GetStringWithoutPathExpansion(::onc::wifi::kSSID, |
119 &policy_ssid); | 119 &policy_ssid); |
120 std::string actual_ssid; | 120 std::string actual_ssid; |
121 actual_wifi->GetStringWithoutPathExpansion(::onc::wifi::kSSID, | 121 actual_wifi->GetStringWithoutPathExpansion(::onc::wifi::kSSID, |
122 &actual_ssid); | 122 &actual_ssid); |
123 return (policy_ssid == actual_ssid); | 123 return (policy_ssid == actual_ssid); |
124 } | 124 } |
125 return false; | 125 return false; |
126 } | 126 } |
127 | 127 |
128 base::DictionaryValue* GetOrCreateDictionary(const std::string& key, | |
129 base::DictionaryValue* dict) { | |
130 base::DictionaryValue* inner_dict = NULL; | |
131 if (!dict->GetDictionaryWithoutPathExpansion(key, &inner_dict)) { | |
132 inner_dict = new base::DictionaryValue; | |
133 dict->SetWithoutPathExpansion(key, inner_dict); | |
134 } | |
135 return inner_dict; | |
136 } | |
137 | |
138 base::DictionaryValue* GetOrCreateNestedDictionary( | |
139 const std::string& key1, | |
140 const std::string& key2, | |
141 base::DictionaryValue* dict) { | |
142 base::DictionaryValue* inner_dict = GetOrCreateDictionary(key1, dict); | |
143 return GetOrCreateDictionary(key2, inner_dict); | |
144 } | |
145 | |
146 void ApplyGlobalAutoconnectPolicy( | |
pneubeck (no reviews)
2014/08/28 16:09:49
this is approximately the function that you propos
stevenjb
2014/08/28 16:19:41
Acknowledged.
| |
147 NetworkProfile::Type profile_type, | |
148 base::DictionaryValue* augmented_onc_network) { | |
149 std::string type; | |
150 if (!augmented_onc_network->GetStringWithoutPathExpansion( | |
151 ::onc::network_config::kType, &type)) { | |
152 LOG(ERROR) << "ONC dictionary with no Type."; | |
153 return; | |
154 } | |
155 | |
156 // Managed dictionaries don't contain empty dictionaries (see onc_merger.cc), | |
157 // so add the Autoconnect dictionary in case Shill didn't report a value. | |
158 base::DictionaryValue* auto_connect_dictionary = NULL; | |
159 if (type == ::onc::network_type::kWiFi) { | |
160 auto_connect_dictionary = | |
161 GetOrCreateNestedDictionary(::onc::network_config::kWiFi, | |
162 ::onc::wifi::kAutoConnect, | |
163 augmented_onc_network); | |
164 } else if (type == ::onc::network_type::kVPN) { | |
165 auto_connect_dictionary = | |
166 GetOrCreateNestedDictionary(::onc::network_config::kVPN, | |
167 ::onc::vpn::kAutoConnect, | |
168 augmented_onc_network); | |
169 } else { | |
170 return; // Network type without auto-connect property. | |
171 } | |
172 | |
173 std::string policy_source; | |
174 if (profile_type == NetworkProfile::TYPE_USER) | |
175 policy_source = ::onc::kAugmentationUserPolicy; | |
176 else if(profile_type == NetworkProfile::TYPE_SHARED) | |
177 policy_source = ::onc::kAugmentationDevicePolicy; | |
178 else | |
179 NOTREACHED(); | |
180 | |
181 auto_connect_dictionary->SetBooleanWithoutPathExpansion(policy_source, false); | |
182 auto_connect_dictionary->SetStringWithoutPathExpansion( | |
183 ::onc::kAugmentationEffectiveSetting, policy_source); | |
184 } | |
185 | |
128 } // namespace | 186 } // namespace |
129 | 187 |
188 scoped_ptr<base::DictionaryValue> CreateManagedONC( | |
189 const base::DictionaryValue* global_policy, | |
190 const base::DictionaryValue* network_policy, | |
191 const base::DictionaryValue* user_settings, | |
192 const base::DictionaryValue* active_settings, | |
193 const NetworkProfile* profile) { | |
194 const base::DictionaryValue* user_policy = NULL; | |
195 const base::DictionaryValue* device_policy = NULL; | |
196 const base::DictionaryValue* nonshared_user_settings = NULL; | |
197 const base::DictionaryValue* shared_user_settings = NULL; | |
198 | |
199 if (profile) { | |
200 if (profile->type() == NetworkProfile::TYPE_SHARED) { | |
201 device_policy = network_policy; | |
202 shared_user_settings = user_settings; | |
203 } else if (profile->type() == NetworkProfile::TYPE_USER) { | |
204 user_policy = network_policy; | |
205 nonshared_user_settings = user_settings; | |
206 } else { | |
207 NOTREACHED(); | |
208 } | |
209 } | |
210 | |
211 // This call also removes credentials from policies. | |
212 scoped_ptr<base::DictionaryValue> augmented_onc_network = | |
213 onc::MergeSettingsAndPoliciesToAugmented( | |
214 onc::kNetworkConfigurationSignature, | |
215 user_policy, | |
216 device_policy, | |
217 nonshared_user_settings, | |
218 shared_user_settings, | |
219 active_settings); | |
220 | |
221 // If present, apply the Autoconnect policy only to networks that are not | |
222 // managed by policy. | |
223 if (!network_policy && global_policy && profile) { | |
224 bool allow_only_policy_autoconnect = false; | |
225 global_policy->GetBooleanWithoutPathExpansion( | |
226 ::onc::global_network_config::kAllowOnlyPolicyNetworksToAutoconnect, | |
227 &allow_only_policy_autoconnect); | |
228 if (allow_only_policy_autoconnect) { | |
229 ApplyGlobalAutoconnectPolicy(profile->type(), | |
230 augmented_onc_network.get()); | |
231 } | |
232 } | |
233 | |
234 return augmented_onc_network.Pass(); | |
235 } | |
236 | |
237 void SetShillPropertiesForGlobalPolicy( | |
238 const base::DictionaryValue& shill_dictionary, | |
239 const base::DictionaryValue* global_network_policy, | |
240 base::DictionaryValue* shill_properties_to_update) { | |
241 if (!global_network_policy) | |
242 return; | |
243 | |
244 // kAllowOnlyPolicyNetworksToAutoconnect is currently the only global config. | |
245 | |
246 std::string type; | |
247 shill_dictionary.GetStringWithoutPathExpansion(shill::kTypeProperty, &type); | |
248 if (NetworkTypePattern::Ethernet().MatchesType(type)) | |
249 return; // Autoconnect for Ethernet cannot be configured. | |
250 | |
251 // By default all networks are allowed to autoconnect. | |
252 bool only_policy_autoconnect = false; | |
253 global_network_policy->GetBooleanWithoutPathExpansion( | |
254 ::onc::global_network_config::kAllowOnlyPolicyNetworksToAutoconnect, | |
255 &only_policy_autoconnect); | |
256 if (!only_policy_autoconnect) | |
257 return; | |
258 | |
259 bool old_autoconnect = false; | |
260 if (shill_dictionary.GetBooleanWithoutPathExpansion( | |
261 shill::kAutoConnectProperty, &old_autoconnect) && | |
262 !old_autoconnect) { | |
263 // Autoconnect is already explictly disabled. No need to set it again. | |
264 return; | |
265 } | |
266 | |
267 // If autconnect is not explicitly set yet, it might automatically be enabled | |
268 // by Shill. To prevent that, disable it explicitly. | |
269 shill_properties_to_update->SetBooleanWithoutPathExpansion( | |
270 shill::kAutoConnectProperty, false); | |
271 } | |
272 | |
130 scoped_ptr<base::DictionaryValue> CreateShillConfiguration( | 273 scoped_ptr<base::DictionaryValue> CreateShillConfiguration( |
131 const NetworkProfile& profile, | 274 const NetworkProfile& profile, |
132 const std::string& guid, | 275 const std::string& guid, |
133 const base::DictionaryValue* policy, | 276 const base::DictionaryValue* global_policy, |
134 const base::DictionaryValue* settings) { | 277 const base::DictionaryValue* network_policy, |
278 const base::DictionaryValue* user_settings) { | |
135 scoped_ptr<base::DictionaryValue> effective; | 279 scoped_ptr<base::DictionaryValue> effective; |
136 ::onc::ONCSource onc_source = ::onc::ONC_SOURCE_NONE; | 280 ::onc::ONCSource onc_source = ::onc::ONC_SOURCE_NONE; |
137 if (policy) { | 281 if (network_policy) { |
138 if (profile.type() == NetworkProfile::TYPE_SHARED) { | 282 if (profile.type() == NetworkProfile::TYPE_SHARED) { |
139 effective = onc::MergeSettingsAndPoliciesToEffective( | 283 effective = onc::MergeSettingsAndPoliciesToEffective( |
140 NULL, // no user policy | 284 NULL, // no user policy |
141 policy, // device policy | 285 network_policy, // device policy |
142 NULL, // no user settings | 286 NULL, // no user settings |
143 settings); // shared settings | 287 user_settings); // shared settings |
144 onc_source = ::onc::ONC_SOURCE_DEVICE_POLICY; | 288 onc_source = ::onc::ONC_SOURCE_DEVICE_POLICY; |
145 } else if (profile.type() == NetworkProfile::TYPE_USER) { | 289 } else if (profile.type() == NetworkProfile::TYPE_USER) { |
146 effective = onc::MergeSettingsAndPoliciesToEffective( | 290 effective = onc::MergeSettingsAndPoliciesToEffective( |
147 policy, // user policy | 291 network_policy, // user policy |
148 NULL, // no device policy | 292 NULL, // no device policy |
149 settings, // user settings | 293 user_settings, // user settings |
150 NULL); // no shared settings | 294 NULL); // no shared settings |
151 onc_source = ::onc::ONC_SOURCE_USER_POLICY; | 295 onc_source = ::onc::ONC_SOURCE_USER_POLICY; |
152 } else { | 296 } else { |
153 NOTREACHED(); | 297 NOTREACHED(); |
154 } | 298 } |
155 } else if (settings) { | 299 } else if (user_settings) { |
156 effective.reset(settings->DeepCopy()); | 300 effective.reset(user_settings->DeepCopy()); |
157 // TODO(pneubeck): change to source ONC_SOURCE_USER | 301 // TODO(pneubeck): change to source ONC_SOURCE_USER |
158 onc_source = ::onc::ONC_SOURCE_NONE; | 302 onc_source = ::onc::ONC_SOURCE_NONE; |
159 } else { | 303 } else { |
160 NOTREACHED(); | 304 NOTREACHED(); |
161 onc_source = ::onc::ONC_SOURCE_NONE; | 305 onc_source = ::onc::ONC_SOURCE_NONE; |
162 } | 306 } |
163 | 307 |
164 RemoveFakeCredentials(onc::kNetworkConfigurationSignature, | 308 RemoveFakeCredentials(onc::kNetworkConfigurationSignature, |
165 effective.get()); | 309 effective.get()); |
166 | 310 |
167 effective->SetStringWithoutPathExpansion(::onc::network_config::kGUID, guid); | 311 effective->SetStringWithoutPathExpansion(::onc::network_config::kGUID, guid); |
168 | 312 |
169 // Remove irrelevant fields. | 313 // Remove irrelevant fields. |
170 onc::Normalizer normalizer(true /* remove recommended fields */); | 314 onc::Normalizer normalizer(true /* remove recommended fields */); |
171 effective = normalizer.NormalizeObject(&onc::kNetworkConfigurationSignature, | 315 effective = normalizer.NormalizeObject(&onc::kNetworkConfigurationSignature, |
172 *effective); | 316 *effective); |
173 | 317 |
174 scoped_ptr<base::DictionaryValue> shill_dictionary( | 318 scoped_ptr<base::DictionaryValue> shill_dictionary( |
175 onc::TranslateONCObjectToShill(&onc::kNetworkConfigurationSignature, | 319 onc::TranslateONCObjectToShill(&onc::kNetworkConfigurationSignature, |
176 *effective)); | 320 *effective)); |
177 | 321 |
178 shill_dictionary->SetStringWithoutPathExpansion(shill::kProfileProperty, | 322 shill_dictionary->SetStringWithoutPathExpansion(shill::kProfileProperty, |
179 profile.path); | 323 profile.path); |
180 | 324 |
325 if (!network_policy) { | |
326 // The network isn't managed. Global network policies have to be applied. | |
327 SetShillPropertiesForGlobalPolicy( | |
328 *shill_dictionary, global_policy, shill_dictionary.get()); | |
329 } | |
330 | |
181 scoped_ptr<NetworkUIData> ui_data(NetworkUIData::CreateFromONC(onc_source)); | 331 scoped_ptr<NetworkUIData> ui_data(NetworkUIData::CreateFromONC(onc_source)); |
182 | 332 |
183 if (settings) { | 333 if (user_settings) { |
184 // Shill doesn't know that sensitive data is contained in the UIData | 334 // Shill doesn't know that sensitive data is contained in the UIData |
185 // property and might write it into logs or other insecure places. Thus, we | 335 // property and might write it into logs or other insecure places. Thus, we |
186 // have to remove or mask credentials. | 336 // have to remove or mask credentials. |
187 // | 337 // |
188 // Shill's GetProperties doesn't return credentials. Masking credentials | 338 // Shill's GetProperties doesn't return credentials. Masking credentials |
189 // instead of just removing them, allows remembering if a credential is set | 339 // instead of just removing them, allows remembering if a credential is set |
190 // or not. | 340 // or not. |
191 scoped_ptr<base::DictionaryValue> sanitized_settings( | 341 scoped_ptr<base::DictionaryValue> sanitized_user_settings( |
192 onc::MaskCredentialsInOncObject(onc::kNetworkConfigurationSignature, | 342 onc::MaskCredentialsInOncObject(onc::kNetworkConfigurationSignature, |
193 *settings, | 343 *user_settings, |
194 kFakeCredential)); | 344 kFakeCredential)); |
195 ui_data->set_user_settings(sanitized_settings.Pass()); | 345 ui_data->set_user_settings(sanitized_user_settings.Pass()); |
196 } | 346 } |
197 | 347 |
198 shill_property_util::SetUIData(*ui_data, shill_dictionary.get()); | 348 shill_property_util::SetUIData(*ui_data, shill_dictionary.get()); |
199 | 349 |
200 VLOG(2) << "Created Shill properties: " << *shill_dictionary; | 350 VLOG(2) << "Created Shill properties: " << *shill_dictionary; |
201 | 351 |
202 return shill_dictionary.Pass(); | 352 return shill_dictionary.Pass(); |
203 } | 353 } |
204 | 354 |
205 const base::DictionaryValue* FindMatchingPolicy( | 355 const base::DictionaryValue* FindMatchingPolicy( |
206 const GuidToPolicyMap& policies, | 356 const GuidToPolicyMap& policies, |
207 const base::DictionaryValue& actual_network) { | 357 const base::DictionaryValue& actual_network) { |
208 for (GuidToPolicyMap::const_iterator it = policies.begin(); | 358 for (GuidToPolicyMap::const_iterator it = policies.begin(); |
209 it != policies.end(); ++it) { | 359 it != policies.end(); ++it) { |
210 if (IsPolicyMatching(*it->second, actual_network)) | 360 if (IsPolicyMatching(*it->second, actual_network)) |
211 return it->second; | 361 return it->second; |
212 } | 362 } |
213 return NULL; | 363 return NULL; |
214 } | 364 } |
215 | 365 |
216 } // namespace policy_util | 366 } // namespace policy_util |
217 | 367 |
218 } // namespace chromeos | 368 } // namespace chromeos |
OLD | NEW |