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( |
| 147 NetworkProfile::Type profile_type, |
| 148 base::DictionaryValue* augmented_onc_network) { |
| 149 base::DictionaryValue* type_dictionary = NULL; |
| 150 augmented_onc_network->GetDictionaryWithoutPathExpansion( |
| 151 ::onc::network_config::kType, &type_dictionary); |
| 152 std::string type; |
| 153 if (!type_dictionary || |
| 154 !type_dictionary->GetStringWithoutPathExpansion( |
| 155 ::onc::kAugmentationActiveSetting, &type) || |
| 156 type.empty()) { |
| 157 LOG(ERROR) << "ONC dictionary with no Type."; |
| 158 return; |
| 159 } |
| 160 |
| 161 // Managed dictionaries don't contain empty dictionaries (see onc_merger.cc), |
| 162 // so add the Autoconnect dictionary in case Shill didn't report a value. |
| 163 base::DictionaryValue* auto_connect_dictionary = NULL; |
| 164 if (type == ::onc::network_type::kWiFi) { |
| 165 auto_connect_dictionary = |
| 166 GetOrCreateNestedDictionary(::onc::network_config::kWiFi, |
| 167 ::onc::wifi::kAutoConnect, |
| 168 augmented_onc_network); |
| 169 } else if (type == ::onc::network_type::kVPN) { |
| 170 auto_connect_dictionary = |
| 171 GetOrCreateNestedDictionary(::onc::network_config::kVPN, |
| 172 ::onc::vpn::kAutoConnect, |
| 173 augmented_onc_network); |
| 174 } else { |
| 175 return; // Network type without auto-connect property. |
| 176 } |
| 177 |
| 178 std::string policy_source; |
| 179 if (profile_type == NetworkProfile::TYPE_USER) |
| 180 policy_source = ::onc::kAugmentationUserPolicy; |
| 181 else if(profile_type == NetworkProfile::TYPE_SHARED) |
| 182 policy_source = ::onc::kAugmentationDevicePolicy; |
| 183 else |
| 184 NOTREACHED(); |
| 185 |
| 186 auto_connect_dictionary->SetBooleanWithoutPathExpansion(policy_source, false); |
| 187 auto_connect_dictionary->SetStringWithoutPathExpansion( |
| 188 ::onc::kAugmentationEffectiveSetting, policy_source); |
| 189 } |
| 190 |
128 } // namespace | 191 } // namespace |
129 | 192 |
| 193 scoped_ptr<base::DictionaryValue> CreateManagedONC( |
| 194 const base::DictionaryValue* global_policy, |
| 195 const base::DictionaryValue* network_policy, |
| 196 const base::DictionaryValue* user_settings, |
| 197 const base::DictionaryValue* active_settings, |
| 198 const NetworkProfile* profile) { |
| 199 const base::DictionaryValue* user_policy = NULL; |
| 200 const base::DictionaryValue* device_policy = NULL; |
| 201 const base::DictionaryValue* nonshared_user_settings = NULL; |
| 202 const base::DictionaryValue* shared_user_settings = NULL; |
| 203 |
| 204 if (profile) { |
| 205 if (profile->type() == NetworkProfile::TYPE_SHARED) { |
| 206 device_policy = network_policy; |
| 207 shared_user_settings = user_settings; |
| 208 } else if (profile->type() == NetworkProfile::TYPE_USER) { |
| 209 user_policy = network_policy; |
| 210 nonshared_user_settings = user_settings; |
| 211 } else { |
| 212 NOTREACHED(); |
| 213 } |
| 214 } |
| 215 |
| 216 // This call also removes credentials from policies. |
| 217 scoped_ptr<base::DictionaryValue> augmented_onc_network = |
| 218 onc::MergeSettingsAndPoliciesToAugmented( |
| 219 onc::kNetworkConfigurationSignature, |
| 220 user_policy, |
| 221 device_policy, |
| 222 nonshared_user_settings, |
| 223 shared_user_settings, |
| 224 active_settings); |
| 225 |
| 226 // If present, apply the Autoconnect policy only to networks that are not |
| 227 // managed by policy. |
| 228 if (!network_policy && global_policy && profile) { |
| 229 bool allow_only_policy_autoconnect = false; |
| 230 global_policy->GetBooleanWithoutPathExpansion( |
| 231 ::onc::global_network_config::kAllowOnlyPolicyNetworksToAutoconnect, |
| 232 &allow_only_policy_autoconnect); |
| 233 if (allow_only_policy_autoconnect) { |
| 234 ApplyGlobalAutoconnectPolicy(profile->type(), |
| 235 augmented_onc_network.get()); |
| 236 } |
| 237 } |
| 238 |
| 239 return augmented_onc_network.Pass(); |
| 240 } |
| 241 |
| 242 void SetShillPropertiesForGlobalPolicy( |
| 243 const base::DictionaryValue& shill_dictionary, |
| 244 const base::DictionaryValue& global_network_policy, |
| 245 base::DictionaryValue* shill_properties_to_update) { |
| 246 // kAllowOnlyPolicyNetworksToAutoconnect is currently the only global config. |
| 247 |
| 248 std::string type; |
| 249 shill_dictionary.GetStringWithoutPathExpansion(shill::kTypeProperty, &type); |
| 250 if (NetworkTypePattern::Ethernet().MatchesType(type)) |
| 251 return; // Autoconnect for Ethernet cannot be configured. |
| 252 |
| 253 // By default all networks are allowed to autoconnect. |
| 254 bool only_policy_autoconnect = false; |
| 255 global_network_policy.GetBooleanWithoutPathExpansion( |
| 256 ::onc::global_network_config::kAllowOnlyPolicyNetworksToAutoconnect, |
| 257 &only_policy_autoconnect); |
| 258 if (!only_policy_autoconnect) |
| 259 return; |
| 260 |
| 261 bool old_autoconnect = false; |
| 262 if (shill_dictionary.GetBooleanWithoutPathExpansion( |
| 263 shill::kAutoConnectProperty, &old_autoconnect) && |
| 264 !old_autoconnect) { |
| 265 // Autoconnect is already explictly disabled. No need to set it again. |
| 266 return; |
| 267 } |
| 268 |
| 269 // If autconnect is not explicitly set yet, it might automatically be enabled |
| 270 // by Shill. To prevent that, disable it explicitly. |
| 271 shill_properties_to_update->SetBooleanWithoutPathExpansion( |
| 272 shill::kAutoConnectProperty, false); |
| 273 } |
| 274 |
130 scoped_ptr<base::DictionaryValue> CreateShillConfiguration( | 275 scoped_ptr<base::DictionaryValue> CreateShillConfiguration( |
131 const NetworkProfile& profile, | 276 const NetworkProfile& profile, |
132 const std::string& guid, | 277 const std::string& guid, |
133 const base::DictionaryValue* policy, | 278 const base::DictionaryValue* global_policy, |
| 279 const base::DictionaryValue* network_policy, |
134 const base::DictionaryValue* user_settings) { | 280 const base::DictionaryValue* user_settings) { |
135 scoped_ptr<base::DictionaryValue> effective; | 281 scoped_ptr<base::DictionaryValue> effective; |
136 ::onc::ONCSource onc_source = ::onc::ONC_SOURCE_NONE; | 282 ::onc::ONCSource onc_source = ::onc::ONC_SOURCE_NONE; |
137 if (policy) { | 283 if (network_policy) { |
138 if (profile.type() == NetworkProfile::TYPE_SHARED) { | 284 if (profile.type() == NetworkProfile::TYPE_SHARED) { |
139 effective = onc::MergeSettingsAndPoliciesToEffective( | 285 effective = onc::MergeSettingsAndPoliciesToEffective( |
140 NULL, // no user policy | 286 NULL, // no user policy |
141 policy, // device policy | 287 network_policy, // device policy |
142 NULL, // no user settings | 288 NULL, // no user settings |
143 user_settings); // shared settings | 289 user_settings); // shared settings |
144 onc_source = ::onc::ONC_SOURCE_DEVICE_POLICY; | 290 onc_source = ::onc::ONC_SOURCE_DEVICE_POLICY; |
145 } else if (profile.type() == NetworkProfile::TYPE_USER) { | 291 } else if (profile.type() == NetworkProfile::TYPE_USER) { |
146 effective = onc::MergeSettingsAndPoliciesToEffective( | 292 effective = onc::MergeSettingsAndPoliciesToEffective( |
147 policy, // user policy | 293 network_policy, // user policy |
148 NULL, // no device policy | 294 NULL, // no device policy |
149 user_settings, // user settings | 295 user_settings, // user settings |
150 NULL); // no shared settings | 296 NULL); // no shared settings |
151 onc_source = ::onc::ONC_SOURCE_USER_POLICY; | 297 onc_source = ::onc::ONC_SOURCE_USER_POLICY; |
152 } else { | 298 } else { |
153 NOTREACHED(); | 299 NOTREACHED(); |
154 } | 300 } |
155 } else if (user_settings) { | 301 } else if (user_settings) { |
156 effective.reset(user_settings->DeepCopy()); | 302 effective.reset(user_settings->DeepCopy()); |
157 // TODO(pneubeck): change to source ONC_SOURCE_USER | 303 // TODO(pneubeck): change to source ONC_SOURCE_USER |
(...skipping 13 matching lines...) Expand all Loading... |
171 effective = normalizer.NormalizeObject(&onc::kNetworkConfigurationSignature, | 317 effective = normalizer.NormalizeObject(&onc::kNetworkConfigurationSignature, |
172 *effective); | 318 *effective); |
173 | 319 |
174 scoped_ptr<base::DictionaryValue> shill_dictionary( | 320 scoped_ptr<base::DictionaryValue> shill_dictionary( |
175 onc::TranslateONCObjectToShill(&onc::kNetworkConfigurationSignature, | 321 onc::TranslateONCObjectToShill(&onc::kNetworkConfigurationSignature, |
176 *effective)); | 322 *effective)); |
177 | 323 |
178 shill_dictionary->SetStringWithoutPathExpansion(shill::kProfileProperty, | 324 shill_dictionary->SetStringWithoutPathExpansion(shill::kProfileProperty, |
179 profile.path); | 325 profile.path); |
180 | 326 |
| 327 if (!network_policy && global_policy) { |
| 328 // The network isn't managed. Global network policies have to be applied. |
| 329 SetShillPropertiesForGlobalPolicy( |
| 330 *shill_dictionary, *global_policy, shill_dictionary.get()); |
| 331 } |
| 332 |
181 scoped_ptr<NetworkUIData> ui_data(NetworkUIData::CreateFromONC(onc_source)); | 333 scoped_ptr<NetworkUIData> ui_data(NetworkUIData::CreateFromONC(onc_source)); |
182 | 334 |
183 if (user_settings) { | 335 if (user_settings) { |
184 // Shill doesn't know that sensitive data is contained in the UIData | 336 // 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 | 337 // property and might write it into logs or other insecure places. Thus, we |
186 // have to remove or mask credentials. | 338 // have to remove or mask credentials. |
187 // | 339 // |
188 // Shill's GetProperties doesn't return credentials. Masking credentials | 340 // Shill's GetProperties doesn't return credentials. Masking credentials |
189 // instead of just removing them, allows remembering if a credential is set | 341 // instead of just removing them, allows remembering if a credential is set |
190 // or not. | 342 // or not. |
(...skipping 18 matching lines...) Expand all Loading... |
209 it != policies.end(); ++it) { | 361 it != policies.end(); ++it) { |
210 if (IsPolicyMatching(*it->second, actual_network)) | 362 if (IsPolicyMatching(*it->second, actual_network)) |
211 return it->second; | 363 return it->second; |
212 } | 364 } |
213 return NULL; | 365 return NULL; |
214 } | 366 } |
215 | 367 |
216 } // namespace policy_util | 368 } // namespace policy_util |
217 | 369 |
218 } // namespace chromeos | 370 } // namespace chromeos |
OLD | NEW |