Check USB device path access when prompting users to select a device.
[chromium-blink-merge.git] / chrome / browser / net / proxy_policy_handler.cc
blob73b05215599203a8478099e59731f8cad155a3d8
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
3 // found in the LICENSE file.
5 #include "chrome/browser/net/proxy_policy_handler.h"
7 #include "base/logging.h"
8 #include "base/prefs/pref_value_map.h"
9 #include "base/strings/string_number_conversions.h"
10 #include "base/values.h"
11 #include "chrome/browser/prefs/proxy_config_dictionary.h"
12 #include "chrome/browser/prefs/proxy_prefs.h"
13 #include "chrome/common/pref_names.h"
14 #include "components/policy/core/browser/configuration_policy_handler.h"
15 #include "components/policy/core/browser/policy_error_map.h"
16 #include "components/policy/core/common/policy_map.h"
17 #include "grit/components_strings.h"
18 #include "policy/policy_constants.h"
20 namespace {
22 // This is used to check whether for a given ProxyMode value, the ProxyPacUrl,
23 // the ProxyBypassList and the ProxyServer policies are allowed to be specified.
24 // |error_message_id| is the message id of the localized error message to show
25 // when the policies are not specified as allowed. Each value of ProxyMode
26 // has a ProxyModeValidationEntry in the |kProxyModeValidationMap| below.
27 struct ProxyModeValidationEntry {
28 const char* mode_value;
29 bool pac_url_allowed;
30 bool bypass_list_allowed;
31 bool server_allowed;
32 int error_message_id;
35 // List of entries determining which proxy policies can be specified, depending
36 // on the ProxyMode.
37 const ProxyModeValidationEntry kProxyModeValidationMap[] = {
38 { ProxyPrefs::kDirectProxyModeName,
39 false, false, false, IDS_POLICY_PROXY_MODE_DISABLED_ERROR },
40 { ProxyPrefs::kAutoDetectProxyModeName,
41 false, false, false, IDS_POLICY_PROXY_MODE_AUTO_DETECT_ERROR },
42 { ProxyPrefs::kPacScriptProxyModeName,
43 true, false, false, IDS_POLICY_PROXY_MODE_PAC_URL_ERROR },
44 { ProxyPrefs::kFixedServersProxyModeName,
45 false, true, true, IDS_POLICY_PROXY_MODE_FIXED_SERVERS_ERROR },
46 { ProxyPrefs::kSystemProxyModeName,
47 false, false, false, IDS_POLICY_PROXY_MODE_SYSTEM_ERROR },
50 } // namespace
52 namespace policy {
54 // The proxy policies have the peculiarity that they are loaded from individual
55 // policies, but the providers then expose them through a unified
56 // DictionaryValue. Once Dictionary policies are fully supported, the individual
57 // proxy policies will be deprecated. http://crbug.com/108996
59 ProxyPolicyHandler::ProxyPolicyHandler() {}
61 ProxyPolicyHandler::~ProxyPolicyHandler() {
64 bool ProxyPolicyHandler::CheckPolicySettings(const PolicyMap& policies,
65 PolicyErrorMap* errors) {
66 const base::Value* mode = GetProxyPolicyValue(policies, key::kProxyMode);
67 const base::Value* server = GetProxyPolicyValue(policies, key::kProxyServer);
68 const base::Value* server_mode =
69 GetProxyPolicyValue(policies, key::kProxyServerMode);
70 const base::Value* pac_url = GetProxyPolicyValue(policies, key::kProxyPacUrl);
71 const base::Value* bypass_list =
72 GetProxyPolicyValue(policies, key::kProxyBypassList);
74 if ((server || pac_url || bypass_list) && !(mode || server_mode)) {
75 errors->AddError(key::kProxySettings,
76 key::kProxyMode,
77 IDS_POLICY_NOT_SPECIFIED_ERROR);
78 return false;
81 std::string mode_value;
82 if (!CheckProxyModeAndServerMode(policies, errors, &mode_value))
83 return false;
85 // If neither ProxyMode nor ProxyServerMode are specified, mode_value will be
86 // empty and the proxy shouldn't be configured at all.
87 if (mode_value.empty())
88 return true;
90 bool is_valid_mode = false;
91 for (size_t i = 0; i != arraysize(kProxyModeValidationMap); ++i) {
92 const ProxyModeValidationEntry& entry = kProxyModeValidationMap[i];
93 if (entry.mode_value != mode_value)
94 continue;
96 is_valid_mode = true;
98 if (!entry.pac_url_allowed && pac_url) {
99 errors->AddError(key::kProxySettings,
100 key::kProxyPacUrl,
101 entry.error_message_id);
103 if (!entry.bypass_list_allowed && bypass_list) {
104 errors->AddError(key::kProxySettings,
105 key::kProxyBypassList,
106 entry.error_message_id);
108 if (!entry.server_allowed && server) {
109 errors->AddError(key::kProxySettings,
110 key::kProxyServer,
111 entry.error_message_id);
114 if ((!entry.pac_url_allowed && pac_url) ||
115 (!entry.bypass_list_allowed && bypass_list) ||
116 (!entry.server_allowed && server)) {
117 return false;
121 if (!is_valid_mode) {
122 errors->AddError(key::kProxySettings,
123 mode ? key::kProxyMode : key::kProxyServerMode,
124 IDS_POLICY_OUT_OF_RANGE_ERROR,
125 mode_value);
126 return false;
128 return true;
131 void ProxyPolicyHandler::ApplyPolicySettings(const PolicyMap& policies,
132 PrefValueMap* prefs) {
133 const base::Value* mode = GetProxyPolicyValue(policies, key::kProxyMode);
134 const base::Value* server = GetProxyPolicyValue(policies, key::kProxyServer);
135 const base::Value* server_mode =
136 GetProxyPolicyValue(policies, key::kProxyServerMode);
137 const base::Value* pac_url = GetProxyPolicyValue(policies, key::kProxyPacUrl);
138 const base::Value* bypass_list =
139 GetProxyPolicyValue(policies, key::kProxyBypassList);
141 ProxyPrefs::ProxyMode proxy_mode;
142 if (mode) {
143 std::string string_mode;
144 CHECK(mode->GetAsString(&string_mode));
145 CHECK(ProxyPrefs::StringToProxyMode(string_mode, &proxy_mode));
146 } else if (server_mode) {
147 int int_mode = 0;
148 CHECK(server_mode->GetAsInteger(&int_mode));
150 switch (int_mode) {
151 case PROXY_SERVER_MODE:
152 proxy_mode = ProxyPrefs::MODE_DIRECT;
153 break;
154 case PROXY_AUTO_DETECT_PROXY_SERVER_MODE:
155 proxy_mode = ProxyPrefs::MODE_AUTO_DETECT;
156 break;
157 case PROXY_MANUALLY_CONFIGURED_PROXY_SERVER_MODE:
158 proxy_mode = ProxyPrefs::MODE_FIXED_SERVERS;
159 if (pac_url)
160 proxy_mode = ProxyPrefs::MODE_PAC_SCRIPT;
161 break;
162 case PROXY_USE_SYSTEM_PROXY_SERVER_MODE:
163 proxy_mode = ProxyPrefs::MODE_SYSTEM;
164 break;
165 default:
166 proxy_mode = ProxyPrefs::MODE_DIRECT;
167 NOTREACHED();
169 } else {
170 return;
173 switch (proxy_mode) {
174 case ProxyPrefs::MODE_DIRECT:
175 prefs->SetValue(prefs::kProxy, ProxyConfigDictionary::CreateDirect());
176 break;
177 case ProxyPrefs::MODE_AUTO_DETECT:
178 prefs->SetValue(prefs::kProxy, ProxyConfigDictionary::CreateAutoDetect());
179 break;
180 case ProxyPrefs::MODE_PAC_SCRIPT: {
181 std::string pac_url_string;
182 if (pac_url && pac_url->GetAsString(&pac_url_string)) {
183 prefs->SetValue(
184 prefs::kProxy,
185 ProxyConfigDictionary::CreatePacScript(pac_url_string, false));
186 } else {
187 NOTREACHED();
189 break;
191 case ProxyPrefs::MODE_FIXED_SERVERS: {
192 std::string proxy_server;
193 std::string bypass_list_string;
194 if (server->GetAsString(&proxy_server)) {
195 if (bypass_list)
196 bypass_list->GetAsString(&bypass_list_string);
197 prefs->SetValue(prefs::kProxy,
198 ProxyConfigDictionary::CreateFixedServers(
199 proxy_server, bypass_list_string));
201 break;
203 case ProxyPrefs::MODE_SYSTEM:
204 prefs->SetValue(prefs::kProxy, ProxyConfigDictionary::CreateSystem());
205 break;
206 case ProxyPrefs::kModeCount:
207 NOTREACHED();
211 const base::Value* ProxyPolicyHandler::GetProxyPolicyValue(
212 const PolicyMap& policies, const char* policy_name) {
213 // See note on the ProxyPolicyHandler implementation above.
214 const base::Value* value = policies.GetValue(key::kProxySettings);
215 const base::DictionaryValue* settings;
216 if (!value || !value->GetAsDictionary(&settings))
217 return NULL;
219 const base::Value* policy_value = NULL;
220 std::string tmp;
221 if (!settings->Get(policy_name, &policy_value) ||
222 policy_value->IsType(base::Value::TYPE_NULL) ||
223 (policy_value->IsType(base::Value::TYPE_STRING) &&
224 policy_value->GetAsString(&tmp) &&
225 tmp.empty())) {
226 return NULL;
228 return policy_value;
231 bool ProxyPolicyHandler::CheckProxyModeAndServerMode(const PolicyMap& policies,
232 PolicyErrorMap* errors,
233 std::string* mode_value) {
234 const base::Value* mode = GetProxyPolicyValue(policies, key::kProxyMode);
235 const base::Value* server = GetProxyPolicyValue(policies, key::kProxyServer);
236 const base::Value* server_mode =
237 GetProxyPolicyValue(policies, key::kProxyServerMode);
238 const base::Value* pac_url = GetProxyPolicyValue(policies, key::kProxyPacUrl);
240 // If there's a server mode, convert it into a mode.
241 // When both are specified, the mode takes precedence.
242 if (mode) {
243 if (server_mode) {
244 errors->AddError(key::kProxySettings,
245 key::kProxyServerMode,
246 IDS_POLICY_OVERRIDDEN,
247 key::kProxyMode);
249 if (!mode->GetAsString(mode_value)) {
250 errors->AddError(key::kProxySettings,
251 key::kProxyMode,
252 IDS_POLICY_TYPE_ERROR,
253 ValueTypeToString(base::Value::TYPE_BOOLEAN));
254 return false;
257 ProxyPrefs::ProxyMode mode;
258 if (!ProxyPrefs::StringToProxyMode(*mode_value, &mode)) {
259 errors->AddError(key::kProxySettings,
260 key::kProxyMode,
261 IDS_POLICY_INVALID_PROXY_MODE_ERROR);
262 return false;
265 if (mode == ProxyPrefs::MODE_PAC_SCRIPT && !pac_url) {
266 errors->AddError(key::kProxySettings,
267 key::kProxyPacUrl,
268 IDS_POLICY_NOT_SPECIFIED_ERROR);
269 return false;
270 } else if (mode == ProxyPrefs::MODE_FIXED_SERVERS && !server) {
271 errors->AddError(key::kProxySettings,
272 key::kProxyServer,
273 IDS_POLICY_NOT_SPECIFIED_ERROR);
274 return false;
276 } else if (server_mode) {
277 int server_mode_value;
278 if (!server_mode->GetAsInteger(&server_mode_value)) {
279 errors->AddError(key::kProxySettings,
280 key::kProxyServerMode,
281 IDS_POLICY_TYPE_ERROR,
282 ValueTypeToString(base::Value::TYPE_INTEGER));
283 return false;
286 switch (server_mode_value) {
287 case PROXY_SERVER_MODE:
288 *mode_value = ProxyPrefs::kDirectProxyModeName;
289 break;
290 case PROXY_AUTO_DETECT_PROXY_SERVER_MODE:
291 *mode_value = ProxyPrefs::kAutoDetectProxyModeName;
292 break;
293 case PROXY_MANUALLY_CONFIGURED_PROXY_SERVER_MODE:
294 if (server && pac_url) {
295 int message_id = IDS_POLICY_PROXY_BOTH_SPECIFIED_ERROR;
296 errors->AddError(key::kProxySettings,
297 key::kProxyServer,
298 message_id);
299 errors->AddError(key::kProxySettings,
300 key::kProxyPacUrl,
301 message_id);
302 return false;
304 if (!server && !pac_url) {
305 int message_id = IDS_POLICY_PROXY_NEITHER_SPECIFIED_ERROR;
306 errors->AddError(key::kProxySettings,
307 key::kProxyServer,
308 message_id);
309 errors->AddError(key::kProxySettings,
310 key::kProxyPacUrl,
311 message_id);
312 return false;
314 if (pac_url)
315 *mode_value = ProxyPrefs::kPacScriptProxyModeName;
316 else
317 *mode_value = ProxyPrefs::kFixedServersProxyModeName;
318 break;
319 case PROXY_USE_SYSTEM_PROXY_SERVER_MODE:
320 *mode_value = ProxyPrefs::kSystemProxyModeName;
321 break;
322 default:
323 errors->AddError(key::kProxySettings,
324 key::kProxyServerMode,
325 IDS_POLICY_OUT_OF_RANGE_ERROR,
326 base::IntToString(server_mode_value));
327 return false;
330 return true;
333 } // namespace policy