OLD | NEW |
| (Empty) |
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 | |
3 // found in the LICENSE file. | |
4 | |
5 #include "chrome/browser/policy/configuration_policy_handler_chromeos.h" | |
6 | |
7 #include <string> | |
8 | |
9 #include "base/json/json_reader.h" | |
10 #include "base/json/json_writer.h" | |
11 #include "base/memory/scoped_ptr.h" | |
12 #include "base/prefs/pref_value_map.h" | |
13 #include "base/string_util.h" | |
14 #include "base/values.h" | |
15 #include "chrome/browser/policy/policy_error_map.h" | |
16 #include "chrome/browser/policy/policy_map.h" | |
17 #include "chrome/browser/ui/ash/chrome_launcher_prefs.h" | |
18 #include "chrome/common/pref_names.h" | |
19 #include "chromeos/network/onc/onc_constants.h" | |
20 #include "chromeos/network/onc/onc_signature.h" | |
21 #include "chromeos/network/onc/onc_utils.h" | |
22 #include "chromeos/network/onc/onc_validator.h" | |
23 #include "grit/generated_resources.h" | |
24 #include "policy/policy_constants.h" | |
25 | |
26 namespace onc = chromeos::onc; | |
27 | |
28 namespace { | |
29 | |
30 } // namespace | |
31 | |
32 namespace policy { | |
33 | |
34 NetworkConfigurationPolicyHandler::NetworkConfigurationPolicyHandler( | |
35 const char* policy_name, | |
36 chromeos::onc::ONCSource onc_source) | |
37 : TypeCheckingPolicyHandler(policy_name, base::Value::TYPE_STRING), | |
38 onc_source_(onc_source) {} | |
39 | |
40 NetworkConfigurationPolicyHandler::~NetworkConfigurationPolicyHandler() {} | |
41 | |
42 bool NetworkConfigurationPolicyHandler::CheckPolicySettings( | |
43 const PolicyMap& policies, | |
44 PolicyErrorMap* errors) { | |
45 const base::Value* value; | |
46 if (!CheckAndGetValue(policies, errors, &value)) | |
47 return false; | |
48 | |
49 if (value) { | |
50 std::string onc_blob; | |
51 value->GetAsString(&onc_blob); | |
52 scoped_ptr<base::DictionaryValue> root_dict = | |
53 onc::ReadDictionaryFromJson(onc_blob); | |
54 if (root_dict.get() == NULL) { | |
55 errors->AddError(policy_name(), IDS_POLICY_NETWORK_CONFIG_PARSE_FAILED); | |
56 return false; | |
57 } | |
58 | |
59 // Validate the ONC dictionary. We are liberal and ignore unknown field | |
60 // names and ignore invalid field names in kRecommended arrays. | |
61 onc::Validator validator(false, // Ignore unknown fields. | |
62 false, // Ignore invalid recommended field names. | |
63 true, // Fail on missing fields. | |
64 true); // Validate for managed ONC | |
65 validator.SetOncSource(onc_source_); | |
66 | |
67 // ONC policies are always unencrypted. | |
68 onc::Validator::Result validation_result; | |
69 root_dict = validator.ValidateAndRepairObject( | |
70 &onc::kToplevelConfigurationSignature, *root_dict, &validation_result); | |
71 if (validation_result == onc::Validator::VALID_WITH_WARNINGS) { | |
72 errors->AddError(policy_name(), | |
73 IDS_POLICY_NETWORK_CONFIG_IMPORT_PARTIAL); | |
74 } else if (validation_result == onc::Validator::INVALID) { | |
75 errors->AddError(policy_name(), IDS_POLICY_NETWORK_CONFIG_IMPORT_FAILED); | |
76 } | |
77 | |
78 // In any case, don't reject the policy as some networks or certificates | |
79 // could still be applied. | |
80 } | |
81 | |
82 return true; | |
83 } | |
84 | |
85 void NetworkConfigurationPolicyHandler::ApplyPolicySettings( | |
86 const PolicyMap& policies, | |
87 PrefValueMap* prefs) { | |
88 // Network policy is read directly from the provider and injected into | |
89 // NetworkLibrary, so no need to convert the policy settings into prefs. | |
90 } | |
91 | |
92 void NetworkConfigurationPolicyHandler::PrepareForDisplaying( | |
93 PolicyMap* policies) const { | |
94 const PolicyMap::Entry* entry = policies->Get(policy_name()); | |
95 if (!entry) | |
96 return; | |
97 base::Value* sanitized_config = SanitizeNetworkConfig(entry->value); | |
98 if (!sanitized_config) | |
99 sanitized_config = base::Value::CreateNullValue(); | |
100 | |
101 policies->Set(policy_name(), entry->level, entry->scope, sanitized_config); | |
102 } | |
103 | |
104 // static | |
105 base::Value* NetworkConfigurationPolicyHandler::SanitizeNetworkConfig( | |
106 const base::Value* config) { | |
107 std::string json_string; | |
108 if (!config->GetAsString(&json_string)) | |
109 return NULL; | |
110 | |
111 scoped_ptr<base::Value> json_value( | |
112 base::JSONReader::Read(json_string, base::JSON_ALLOW_TRAILING_COMMAS)); | |
113 if (!json_value.get() || !json_value->IsType(base::Value::TYPE_DICTIONARY)) | |
114 return NULL; | |
115 | |
116 base::DictionaryValue* config_dict = | |
117 static_cast<base::DictionaryValue*>(json_value.get()); | |
118 | |
119 // Strip any sensitive information from the JSON dictionary. | |
120 base::ListValue* config_list = NULL; | |
121 if (config_dict->GetList("NetworkConfigurations", &config_list)) { | |
122 for (base::ListValue::const_iterator network_entry = config_list->begin(); | |
123 network_entry != config_list->end(); | |
124 ++network_entry) { | |
125 if ((*network_entry) && | |
126 (*network_entry)->IsType(base::Value::TYPE_DICTIONARY)) { | |
127 MaskSensitiveValues( | |
128 static_cast<base::DictionaryValue*>(*network_entry)); | |
129 } | |
130 } | |
131 } | |
132 | |
133 // Convert back to a string, pretty printing the contents. | |
134 base::JSONWriter::WriteWithOptions(config_dict, | |
135 base::JSONWriter::OPTIONS_DO_NOT_ESCAPE | | |
136 base::JSONWriter::OPTIONS_PRETTY_PRINT, | |
137 &json_string); | |
138 return base::Value::CreateStringValue(json_string); | |
139 } | |
140 | |
141 // static | |
142 void NetworkConfigurationPolicyHandler::MaskSensitiveValues( | |
143 base::DictionaryValue* network_dict) { | |
144 // Paths of the properties to be replaced by the placeholder. Each entry | |
145 // specifies dictionary key paths. | |
146 static const int kMaxComponents = 3; | |
147 static const char* kFilteredSettings[][kMaxComponents] = { | |
148 { onc::network_config::kEthernet, onc::ethernet::kEAP, | |
149 onc::eap::kPassword }, | |
150 { onc::network_config::kVPN, onc::vpn::kIPsec, onc::vpn::kPSK }, | |
151 { onc::network_config::kVPN, onc::vpn::kL2TP, onc::vpn::kPassword }, | |
152 { onc::network_config::kVPN, onc::vpn::kOpenVPN, onc::vpn::kPassword }, | |
153 { onc::network_config::kVPN, onc::vpn::kOpenVPN, | |
154 onc::vpn::kTLSAuthContents }, | |
155 { onc::network_config::kWiFi, onc::wifi::kEAP, onc::eap::kPassword }, | |
156 { onc::network_config::kWiFi, onc::wifi::kPassphrase }, | |
157 }; | |
158 | |
159 // Placeholder to insert in place of the filtered setting. | |
160 static const char kPlaceholder[] = "********"; | |
161 | |
162 for (size_t i = 0; i < arraysize(kFilteredSettings); ++i) { | |
163 const char** path = kFilteredSettings[i]; | |
164 base::DictionaryValue* dict = network_dict; | |
165 int j = 0; | |
166 for (j = 0; path[j + 1] != NULL && j + 1 < kMaxComponents; ++j) { | |
167 if (!dict->GetDictionaryWithoutPathExpansion(path[j], &dict)) { | |
168 dict = NULL; | |
169 break; | |
170 } | |
171 } | |
172 if (dict && dict->RemoveWithoutPathExpansion(path[j], NULL)) { | |
173 dict->SetWithoutPathExpansion( | |
174 path[j], base::Value::CreateStringValue(kPlaceholder)); | |
175 } | |
176 } | |
177 } | |
178 | |
179 PinnedLauncherAppsPolicyHandler::PinnedLauncherAppsPolicyHandler() | |
180 : ExtensionListPolicyHandler(key::kPinnedLauncherApps, | |
181 prefs::kPinnedLauncherApps, | |
182 false) {} | |
183 | |
184 PinnedLauncherAppsPolicyHandler::~PinnedLauncherAppsPolicyHandler() {} | |
185 | |
186 void PinnedLauncherAppsPolicyHandler::ApplyPolicySettings( | |
187 const PolicyMap& policies, | |
188 PrefValueMap* prefs) { | |
189 PolicyErrorMap errors; | |
190 const base::Value* policy_value = policies.GetValue(policy_name()); | |
191 const base::ListValue* policy_list = NULL; | |
192 if (policy_value && policy_value->GetAsList(&policy_list) && policy_list) { | |
193 base::ListValue* pinned_apps_list = new base::ListValue(); | |
194 for (base::ListValue::const_iterator entry(policy_list->begin()); | |
195 entry != policy_list->end(); ++entry) { | |
196 std::string id; | |
197 if ((*entry)->GetAsString(&id)) { | |
198 base::DictionaryValue* app_dict = new base::DictionaryValue(); | |
199 app_dict->SetString(ash::kPinnedAppsPrefAppIDPath, id); | |
200 pinned_apps_list->Append(app_dict); | |
201 } | |
202 } | |
203 prefs->SetValue(pref_path(), pinned_apps_list); | |
204 } | |
205 } | |
206 | |
207 } // namespace policy | |
OLD | NEW |