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.
5 #include "chrome/browser/content_settings/content_settings_policy_provider.h"
10 #include "base/json/json_reader.h"
11 #include "base/prefs/pref_service.h"
12 #include "base/values.h"
13 #include "chrome/browser/content_settings/content_settings_utils.h"
14 #include "chrome/common/pref_names.h"
15 #include "components/content_settings/core/browser/content_settings_rule.h"
16 #include "components/content_settings/core/common/content_settings_pattern.h"
17 #include "components/pref_registry/pref_registry_syncable.h"
18 #include "content/public/browser/browser_thread.h"
20 using content::BrowserThread
;
24 // The preferences used to manage ContentSettingsTypes.
25 const char* kPrefToManageType
[] = {
26 prefs::kManagedDefaultCookiesSetting
,
27 prefs::kManagedDefaultImagesSetting
,
28 prefs::kManagedDefaultJavaScriptSetting
,
29 prefs::kManagedDefaultPluginsSetting
,
30 prefs::kManagedDefaultPopupsSetting
,
31 prefs::kManagedDefaultGeolocationSetting
,
32 prefs::kManagedDefaultNotificationsSetting
,
33 NULL
, // No policy for default value of content type auto-select-certificate
34 NULL
, // No policy for default value of fullscreen requests
35 NULL
, // No policy for default value of mouse lock requests
36 NULL
, // No policy for default value of mixed script blocking
37 prefs::kManagedDefaultMediaStreamSetting
,
38 NULL
, // No policy for default value of media stream mic
39 NULL
, // No policy for default value of media stream camera
40 NULL
, // No policy for default value of protocol handlers
41 NULL
, // No policy for default value of PPAPI broker
42 NULL
, // No policy for default value of multiple automatic downloads
43 NULL
, // No policy for default value of MIDI system exclusive requests
44 NULL
, // No policy for default value of push messaging requests
45 NULL
, // No policy for default value of SSL certificate decisions
47 NULL
, // No policy for default value of "switch to desktop"
48 #elif defined(OS_ANDROID) || defined(OS_CHROMEOS)
49 NULL
, // No policy for default value of protected media identifier
51 #if defined(OS_ANDROID)
52 NULL
, // No policy for default value of app banners
55 COMPILE_ASSERT(arraysize(kPrefToManageType
) == CONTENT_SETTINGS_NUM_TYPES
,
56 managed_content_settings_pref_names_array_size_incorrect
);
58 struct PrefsForManagedContentSettingsMapEntry
{
59 const char* pref_name
;
60 ContentSettingsType content_type
;
61 ContentSetting setting
;
64 const PrefsForManagedContentSettingsMapEntry
65 kPrefsForManagedContentSettingsMap
[] = {
67 prefs::kManagedCookiesAllowedForUrls
,
68 CONTENT_SETTINGS_TYPE_COOKIES
,
71 prefs::kManagedCookiesSessionOnlyForUrls
,
72 CONTENT_SETTINGS_TYPE_COOKIES
,
73 CONTENT_SETTING_SESSION_ONLY
75 prefs::kManagedCookiesBlockedForUrls
,
76 CONTENT_SETTINGS_TYPE_COOKIES
,
79 prefs::kManagedImagesAllowedForUrls
,
80 CONTENT_SETTINGS_TYPE_IMAGES
,
83 prefs::kManagedImagesBlockedForUrls
,
84 CONTENT_SETTINGS_TYPE_IMAGES
,
87 prefs::kManagedJavaScriptAllowedForUrls
,
88 CONTENT_SETTINGS_TYPE_JAVASCRIPT
,
91 prefs::kManagedJavaScriptBlockedForUrls
,
92 CONTENT_SETTINGS_TYPE_JAVASCRIPT
,
95 prefs::kManagedPluginsAllowedForUrls
,
96 CONTENT_SETTINGS_TYPE_PLUGINS
,
99 prefs::kManagedPluginsBlockedForUrls
,
100 CONTENT_SETTINGS_TYPE_PLUGINS
,
101 CONTENT_SETTING_BLOCK
103 prefs::kManagedPopupsAllowedForUrls
,
104 CONTENT_SETTINGS_TYPE_POPUPS
,
105 CONTENT_SETTING_ALLOW
107 prefs::kManagedPopupsBlockedForUrls
,
108 CONTENT_SETTINGS_TYPE_POPUPS
,
109 CONTENT_SETTING_BLOCK
111 prefs::kManagedNotificationsAllowedForUrls
,
112 CONTENT_SETTINGS_TYPE_NOTIFICATIONS
,
113 CONTENT_SETTING_ALLOW
115 prefs::kManagedNotificationsBlockedForUrls
,
116 CONTENT_SETTINGS_TYPE_NOTIFICATIONS
,
117 CONTENT_SETTING_BLOCK
123 namespace content_settings
{
126 void PolicyProvider::RegisterProfilePrefs(
127 user_prefs::PrefRegistrySyncable
* registry
) {
128 registry
->RegisterListPref(prefs::kManagedAutoSelectCertificateForUrls
,
129 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF
);
130 registry
->RegisterListPref(prefs::kManagedCookiesAllowedForUrls
,
131 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF
);
132 registry
->RegisterListPref(prefs::kManagedCookiesBlockedForUrls
,
133 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF
);
134 registry
->RegisterListPref(prefs::kManagedCookiesSessionOnlyForUrls
,
135 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF
);
136 registry
->RegisterListPref(prefs::kManagedImagesAllowedForUrls
,
137 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF
);
138 registry
->RegisterListPref(prefs::kManagedImagesBlockedForUrls
,
139 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF
);
140 registry
->RegisterListPref(prefs::kManagedJavaScriptAllowedForUrls
,
141 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF
);
142 registry
->RegisterListPref(prefs::kManagedJavaScriptBlockedForUrls
,
143 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF
);
144 registry
->RegisterListPref(prefs::kManagedPluginsAllowedForUrls
,
145 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF
);
146 registry
->RegisterListPref(prefs::kManagedPluginsBlockedForUrls
,
147 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF
);
148 registry
->RegisterListPref(prefs::kManagedPopupsAllowedForUrls
,
149 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF
);
150 registry
->RegisterListPref(prefs::kManagedPopupsBlockedForUrls
,
151 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF
);
152 registry
->RegisterListPref(prefs::kManagedNotificationsAllowedForUrls
,
153 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF
);
154 registry
->RegisterListPref(prefs::kManagedNotificationsBlockedForUrls
,
155 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF
);
156 // Preferences for default content setting policies. If a policy is not set of
157 // the corresponding preferences below is set to CONTENT_SETTING_DEFAULT.
158 registry
->RegisterIntegerPref(
159 prefs::kManagedDefaultCookiesSetting
,
160 CONTENT_SETTING_DEFAULT
,
161 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF
);
162 registry
->RegisterIntegerPref(
163 prefs::kManagedDefaultImagesSetting
,
164 CONTENT_SETTING_DEFAULT
,
165 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF
);
166 registry
->RegisterIntegerPref(
167 prefs::kManagedDefaultJavaScriptSetting
,
168 CONTENT_SETTING_DEFAULT
,
169 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF
);
170 registry
->RegisterIntegerPref(
171 prefs::kManagedDefaultPluginsSetting
,
172 CONTENT_SETTING_DEFAULT
,
173 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF
);
174 registry
->RegisterIntegerPref(
175 prefs::kManagedDefaultPopupsSetting
,
176 CONTENT_SETTING_DEFAULT
,
177 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF
);
178 registry
->RegisterIntegerPref(
179 prefs::kManagedDefaultGeolocationSetting
,
180 CONTENT_SETTING_DEFAULT
,
181 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF
);
182 registry
->RegisterIntegerPref(
183 prefs::kManagedDefaultNotificationsSetting
,
184 CONTENT_SETTING_DEFAULT
,
185 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF
);
186 registry
->RegisterIntegerPref(
187 prefs::kManagedDefaultMediaStreamSetting
,
188 CONTENT_SETTING_DEFAULT
,
189 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF
);
192 PolicyProvider::PolicyProvider(PrefService
* prefs
) : prefs_(prefs
) {
193 ReadManagedDefaultSettings();
194 ReadManagedContentSettings(false);
196 pref_change_registrar_
.Init(prefs_
);
197 PrefChangeRegistrar::NamedChangeCallback callback
=
198 base::Bind(&PolicyProvider::OnPreferenceChanged
, base::Unretained(this));
199 pref_change_registrar_
.Add(
200 prefs::kManagedAutoSelectCertificateForUrls
, callback
);
201 pref_change_registrar_
.Add(prefs::kManagedCookiesBlockedForUrls
, callback
);
202 pref_change_registrar_
.Add(prefs::kManagedCookiesAllowedForUrls
, callback
);
203 pref_change_registrar_
.Add(
204 prefs::kManagedCookiesSessionOnlyForUrls
, callback
);
205 pref_change_registrar_
.Add(prefs::kManagedImagesBlockedForUrls
, callback
);
206 pref_change_registrar_
.Add(prefs::kManagedImagesAllowedForUrls
, callback
);
207 pref_change_registrar_
.Add(prefs::kManagedJavaScriptBlockedForUrls
, callback
);
208 pref_change_registrar_
.Add(prefs::kManagedJavaScriptAllowedForUrls
, callback
);
209 pref_change_registrar_
.Add(prefs::kManagedPluginsBlockedForUrls
, callback
);
210 pref_change_registrar_
.Add(prefs::kManagedPluginsAllowedForUrls
, callback
);
211 pref_change_registrar_
.Add(prefs::kManagedPopupsBlockedForUrls
, callback
);
212 pref_change_registrar_
.Add(prefs::kManagedPopupsAllowedForUrls
, callback
);
213 pref_change_registrar_
.Add(
214 prefs::kManagedNotificationsAllowedForUrls
, callback
);
215 pref_change_registrar_
.Add(
216 prefs::kManagedNotificationsBlockedForUrls
, callback
);
217 // The following preferences are only used to indicate if a default content
218 // setting is managed and to hold the managed default setting value. If the
219 // value for any of the following preferences is set then the corresponding
220 // default content setting is managed. These preferences exist in parallel to
221 // the preference default content settings. If a default content settings type
222 // is managed any user defined exceptions (patterns) for this type are
224 pref_change_registrar_
.Add(prefs::kManagedDefaultCookiesSetting
, callback
);
225 pref_change_registrar_
.Add(prefs::kManagedDefaultImagesSetting
, callback
);
226 pref_change_registrar_
.Add(prefs::kManagedDefaultJavaScriptSetting
, callback
);
227 pref_change_registrar_
.Add(prefs::kManagedDefaultPluginsSetting
, callback
);
228 pref_change_registrar_
.Add(prefs::kManagedDefaultPopupsSetting
, callback
);
229 pref_change_registrar_
.Add(
230 prefs::kManagedDefaultGeolocationSetting
, callback
);
231 pref_change_registrar_
.Add(
232 prefs::kManagedDefaultNotificationsSetting
, callback
);
233 pref_change_registrar_
.Add(
234 prefs::kManagedDefaultMediaStreamSetting
, callback
);
237 PolicyProvider::~PolicyProvider() {
241 RuleIterator
* PolicyProvider::GetRuleIterator(
242 ContentSettingsType content_type
,
243 const ResourceIdentifier
& resource_identifier
,
244 bool incognito
) const {
245 return value_map_
.GetRuleIterator(content_type
, resource_identifier
, &lock_
);
248 void PolicyProvider::GetContentSettingsFromPreferences(
249 OriginIdentifierValueMap
* value_map
) {
250 for (size_t i
= 0; i
< arraysize(kPrefsForManagedContentSettingsMap
); ++i
) {
251 const char* pref_name
= kPrefsForManagedContentSettingsMap
[i
].pref_name
;
252 // Skip unset policies.
253 if (!prefs_
->HasPrefPath(pref_name
)) {
254 VLOG(2) << "Skipping unset preference: " << pref_name
;
258 const PrefService::Preference
* pref
= prefs_
->FindPreference(pref_name
);
260 DCHECK(pref
->IsManaged());
262 const base::ListValue
* pattern_str_list
= NULL
;
263 if (!pref
->GetValue()->GetAsList(&pattern_str_list
)) {
268 for (size_t j
= 0; j
< pattern_str_list
->GetSize(); ++j
) {
269 std::string original_pattern_str
;
270 if (!pattern_str_list
->GetString(j
, &original_pattern_str
)) {
275 PatternPair pattern_pair
= ParsePatternString(original_pattern_str
);
276 // Ignore invalid patterns.
277 if (!pattern_pair
.first
.IsValid()) {
278 VLOG(1) << "Ignoring invalid content settings pattern: " <<
279 original_pattern_str
;
283 ContentSettingsType content_type
=
284 kPrefsForManagedContentSettingsMap
[i
].content_type
;
285 DCHECK_NE(content_type
, CONTENT_SETTINGS_TYPE_AUTO_SELECT_CERTIFICATE
);
286 // If only one pattern was defined auto expand it to a pattern pair.
287 ContentSettingsPattern secondary_pattern
=
288 !pattern_pair
.second
.IsValid() ? ContentSettingsPattern::Wildcard()
289 : pattern_pair
.second
;
290 value_map
->SetValue(pattern_pair
.first
,
293 NO_RESOURCE_IDENTIFIER
,
294 new base::FundamentalValue(
295 kPrefsForManagedContentSettingsMap
[i
].setting
));
300 void PolicyProvider::GetAutoSelectCertificateSettingsFromPreferences(
301 OriginIdentifierValueMap
* value_map
) {
302 const char* pref_name
= prefs::kManagedAutoSelectCertificateForUrls
;
304 if (!prefs_
->HasPrefPath(pref_name
)) {
305 VLOG(2) << "Skipping unset preference: " << pref_name
;
309 const PrefService::Preference
* pref
= prefs_
->FindPreference(pref_name
);
311 DCHECK(pref
->IsManaged());
313 const base::ListValue
* pattern_filter_str_list
= NULL
;
314 if (!pref
->GetValue()->GetAsList(&pattern_filter_str_list
)) {
319 // Parse the list of pattern filter strings. A pattern filter string has
320 // the following JSON format:
323 // "pattern": <content settings pattern string>,
324 // "filter" : <certificate filter in JSON format>
329 // "pattern": "[*.]example.com",
336 for (size_t j
= 0; j
< pattern_filter_str_list
->GetSize(); ++j
) {
337 std::string pattern_filter_json
;
338 if (!pattern_filter_str_list
->GetString(j
, &pattern_filter_json
)) {
343 scoped_ptr
<base::Value
> value(base::JSONReader::Read(pattern_filter_json
,
344 base::JSON_ALLOW_TRAILING_COMMAS
));
345 if (!value
|| !value
->IsType(base::Value::TYPE_DICTIONARY
)) {
346 VLOG(1) << "Ignoring invalid certificate auto select setting. Reason:"
347 " Invalid JSON object: " << pattern_filter_json
;
351 scoped_ptr
<base::DictionaryValue
> pattern_filter_pair(
352 static_cast<base::DictionaryValue
*>(value
.release()));
353 std::string pattern_str
;
354 bool pattern_read
= pattern_filter_pair
->GetStringWithoutPathExpansion(
355 "pattern", &pattern_str
);
356 base::DictionaryValue
* cert_filter
= NULL
;
357 pattern_filter_pair
->GetDictionaryWithoutPathExpansion("filter",
359 if (!pattern_read
|| !cert_filter
) {
360 VLOG(1) << "Ignoring invalid certificate auto select setting. Reason:"
361 " Missing pattern or filter.";
365 ContentSettingsPattern pattern
=
366 ContentSettingsPattern::FromString(pattern_str
);
367 // Ignore invalid patterns.
368 if (!pattern
.IsValid()) {
369 VLOG(1) << "Ignoring invalid certificate auto select setting:"
370 " Invalid content settings pattern: " << pattern
.ToString();
374 // Don't pass removed values from |value|, because base::Values read with
375 // JSONReader use a shared string buffer. Instead, DeepCopy here.
376 value_map
->SetValue(pattern
,
377 ContentSettingsPattern::Wildcard(),
378 CONTENT_SETTINGS_TYPE_AUTO_SELECT_CERTIFICATE
,
380 cert_filter
->DeepCopy());
384 void PolicyProvider::ReadManagedDefaultSettings() {
385 for (size_t type
= 0; type
< arraysize(kPrefToManageType
); ++type
) {
386 if (kPrefToManageType
[type
] == NULL
) {
389 UpdateManagedDefaultSetting(ContentSettingsType(type
));
393 void PolicyProvider::UpdateManagedDefaultSetting(
394 ContentSettingsType content_type
) {
395 // If a pref to manage a default-content-setting was not set (NOTICE:
396 // "HasPrefPath" returns false if no value was set for a registered pref) then
397 // the default value of the preference is used. The default value of a
398 // preference to manage a default-content-settings is CONTENT_SETTING_DEFAULT.
399 // This indicates that no managed value is set. If a pref was set, than it
401 DCHECK(!prefs_
->HasPrefPath(kPrefToManageType
[content_type
]) ||
402 prefs_
->IsManagedPreference(kPrefToManageType
[content_type
]));
403 base::AutoLock
auto_lock(lock_
);
405 int setting
= prefs_
->GetInteger(kPrefToManageType
[content_type
]);
406 if (setting
== CONTENT_SETTING_DEFAULT
) {
407 value_map_
.DeleteValue(
408 ContentSettingsPattern::Wildcard(),
409 ContentSettingsPattern::Wildcard(),
413 value_map_
.SetValue(ContentSettingsPattern::Wildcard(),
414 ContentSettingsPattern::Wildcard(),
417 new base::FundamentalValue(setting
));
422 void PolicyProvider::ReadManagedContentSettings(bool overwrite
) {
423 base::AutoLock
auto_lock(lock_
);
426 GetContentSettingsFromPreferences(&value_map_
);
427 GetAutoSelectCertificateSettingsFromPreferences(&value_map_
);
430 // Since the PolicyProvider is a read only content settings provider, all
431 // methodes of the ProviderInterface that set or delete any settings do nothing.
432 bool PolicyProvider::SetWebsiteSetting(
433 const ContentSettingsPattern
& primary_pattern
,
434 const ContentSettingsPattern
& secondary_pattern
,
435 ContentSettingsType content_type
,
436 const ResourceIdentifier
& resource_identifier
,
437 base::Value
* value
) {
441 void PolicyProvider::ClearAllContentSettingsRules(
442 ContentSettingsType content_type
) {
445 void PolicyProvider::ShutdownOnUIThread() {
446 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
447 RemoveAllObservers();
450 pref_change_registrar_
.RemoveAll();
454 void PolicyProvider::OnPreferenceChanged(const std::string
& name
) {
455 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
457 if (name
== prefs::kManagedDefaultCookiesSetting
) {
458 UpdateManagedDefaultSetting(CONTENT_SETTINGS_TYPE_COOKIES
);
459 } else if (name
== prefs::kManagedDefaultImagesSetting
) {
460 UpdateManagedDefaultSetting(CONTENT_SETTINGS_TYPE_IMAGES
);
461 } else if (name
== prefs::kManagedDefaultJavaScriptSetting
) {
462 UpdateManagedDefaultSetting(CONTENT_SETTINGS_TYPE_JAVASCRIPT
);
463 } else if (name
== prefs::kManagedDefaultPluginsSetting
) {
464 UpdateManagedDefaultSetting(CONTENT_SETTINGS_TYPE_PLUGINS
);
465 } else if (name
== prefs::kManagedDefaultPopupsSetting
) {
466 UpdateManagedDefaultSetting(CONTENT_SETTINGS_TYPE_POPUPS
);
467 } else if (name
== prefs::kManagedDefaultGeolocationSetting
) {
468 UpdateManagedDefaultSetting(CONTENT_SETTINGS_TYPE_GEOLOCATION
);
469 } else if (name
== prefs::kManagedDefaultNotificationsSetting
) {
470 UpdateManagedDefaultSetting(CONTENT_SETTINGS_TYPE_NOTIFICATIONS
);
471 } else if (name
== prefs::kManagedDefaultMediaStreamSetting
) {
472 UpdateManagedDefaultSetting(CONTENT_SETTINGS_TYPE_MEDIASTREAM
);
473 } else if (name
== prefs::kManagedAutoSelectCertificateForUrls
||
474 name
== prefs::kManagedCookiesAllowedForUrls
||
475 name
== prefs::kManagedCookiesBlockedForUrls
||
476 name
== prefs::kManagedCookiesSessionOnlyForUrls
||
477 name
== prefs::kManagedImagesAllowedForUrls
||
478 name
== prefs::kManagedImagesBlockedForUrls
||
479 name
== prefs::kManagedJavaScriptAllowedForUrls
||
480 name
== prefs::kManagedJavaScriptBlockedForUrls
||
481 name
== prefs::kManagedPluginsAllowedForUrls
||
482 name
== prefs::kManagedPluginsBlockedForUrls
||
483 name
== prefs::kManagedPopupsAllowedForUrls
||
484 name
== prefs::kManagedPopupsBlockedForUrls
||
485 name
== prefs::kManagedNotificationsAllowedForUrls
||
486 name
== prefs::kManagedNotificationsBlockedForUrls
) {
487 ReadManagedContentSettings(true);
488 ReadManagedDefaultSettings();
491 NotifyObservers(ContentSettingsPattern(),
492 ContentSettingsPattern(),
493 CONTENT_SETTINGS_TYPE_DEFAULT
,
497 } // namespace content_settings