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/chrome_notification_types.h"
14 #include "chrome/browser/content_settings/content_settings_rule.h"
15 #include "chrome/browser/content_settings/content_settings_utils.h"
16 #include "chrome/common/content_settings_pattern.h"
17 #include "chrome/common/pref_names.h"
18 #include "components/user_prefs/pref_registry_syncable.h"
19 #include "content/public/browser/browser_thread.h"
20 #include "content/public/browser/notification_details.h"
21 #include "content/public/browser/notification_source.h"
23 using content::BrowserThread
;
27 // The preferences used to manage ContentSettingsTypes.
28 const char* kPrefToManageType
[] = {
29 prefs::kManagedDefaultCookiesSetting
,
30 prefs::kManagedDefaultImagesSetting
,
31 prefs::kManagedDefaultJavaScriptSetting
,
32 prefs::kManagedDefaultPluginsSetting
,
33 prefs::kManagedDefaultPopupsSetting
,
34 prefs::kManagedDefaultGeolocationSetting
,
35 prefs::kManagedDefaultNotificationsSetting
,
36 NULL
, // No policy for default value of content type auto-select-certificate
37 NULL
, // No policy for default value of fullscreen requests
38 NULL
, // No policy for default value of mouse lock requests
39 NULL
, // No policy for default value of mixed script blocking
40 prefs::kManagedDefaultMediaStreamSetting
,
41 NULL
, // No policy for default value of media stream mic
42 NULL
, // No policy for default value of media stream camera
43 NULL
, // No policy for default value of protocol handlers
44 NULL
, // No policy for default value of PPAPI broker
45 NULL
, // No policy for default value of multiple automatic downloads
46 NULL
, // No policy for default value of MIDI system exclusive requests
48 NULL
, // No policy for default value of "switch to desktop"
49 #elif defined(OS_ANDROID) || defined(OS_CHROMEOS)
50 NULL
, // No policy for default value of protected media identifier
53 COMPILE_ASSERT(arraysize(kPrefToManageType
) == CONTENT_SETTINGS_NUM_TYPES
,
54 managed_content_settings_pref_names_array_size_incorrect
);
56 struct PrefsForManagedContentSettingsMapEntry
{
57 const char* pref_name
;
58 ContentSettingsType content_type
;
59 ContentSetting setting
;
62 const PrefsForManagedContentSettingsMapEntry
63 kPrefsForManagedContentSettingsMap
[] = {
65 prefs::kManagedCookiesAllowedForUrls
,
66 CONTENT_SETTINGS_TYPE_COOKIES
,
69 prefs::kManagedCookiesSessionOnlyForUrls
,
70 CONTENT_SETTINGS_TYPE_COOKIES
,
71 CONTENT_SETTING_SESSION_ONLY
73 prefs::kManagedCookiesBlockedForUrls
,
74 CONTENT_SETTINGS_TYPE_COOKIES
,
77 prefs::kManagedImagesAllowedForUrls
,
78 CONTENT_SETTINGS_TYPE_IMAGES
,
81 prefs::kManagedImagesBlockedForUrls
,
82 CONTENT_SETTINGS_TYPE_IMAGES
,
85 prefs::kManagedJavaScriptAllowedForUrls
,
86 CONTENT_SETTINGS_TYPE_JAVASCRIPT
,
89 prefs::kManagedJavaScriptBlockedForUrls
,
90 CONTENT_SETTINGS_TYPE_JAVASCRIPT
,
93 prefs::kManagedPluginsAllowedForUrls
,
94 CONTENT_SETTINGS_TYPE_PLUGINS
,
97 prefs::kManagedPluginsBlockedForUrls
,
98 CONTENT_SETTINGS_TYPE_PLUGINS
,
101 prefs::kManagedPopupsAllowedForUrls
,
102 CONTENT_SETTINGS_TYPE_POPUPS
,
103 CONTENT_SETTING_ALLOW
105 prefs::kManagedPopupsBlockedForUrls
,
106 CONTENT_SETTINGS_TYPE_POPUPS
,
107 CONTENT_SETTING_BLOCK
109 prefs::kManagedNotificationsAllowedForUrls
,
110 CONTENT_SETTINGS_TYPE_NOTIFICATIONS
,
111 CONTENT_SETTING_ALLOW
113 prefs::kManagedNotificationsBlockedForUrls
,
114 CONTENT_SETTINGS_TYPE_NOTIFICATIONS
,
115 CONTENT_SETTING_BLOCK
121 namespace content_settings
{
124 void PolicyProvider::RegisterProfilePrefs(
125 user_prefs::PrefRegistrySyncable
* registry
) {
126 registry
->RegisterListPref(prefs::kManagedAutoSelectCertificateForUrls
,
127 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF
);
128 registry
->RegisterListPref(prefs::kManagedCookiesAllowedForUrls
,
129 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF
);
130 registry
->RegisterListPref(prefs::kManagedCookiesBlockedForUrls
,
131 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF
);
132 registry
->RegisterListPref(prefs::kManagedCookiesSessionOnlyForUrls
,
133 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF
);
134 registry
->RegisterListPref(prefs::kManagedImagesAllowedForUrls
,
135 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF
);
136 registry
->RegisterListPref(prefs::kManagedImagesBlockedForUrls
,
137 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF
);
138 registry
->RegisterListPref(prefs::kManagedJavaScriptAllowedForUrls
,
139 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF
);
140 registry
->RegisterListPref(prefs::kManagedJavaScriptBlockedForUrls
,
141 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF
);
142 registry
->RegisterListPref(prefs::kManagedPluginsAllowedForUrls
,
143 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF
);
144 registry
->RegisterListPref(prefs::kManagedPluginsBlockedForUrls
,
145 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF
);
146 registry
->RegisterListPref(prefs::kManagedPopupsAllowedForUrls
,
147 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF
);
148 registry
->RegisterListPref(prefs::kManagedPopupsBlockedForUrls
,
149 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF
);
150 registry
->RegisterListPref(prefs::kManagedNotificationsAllowedForUrls
,
151 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF
);
152 registry
->RegisterListPref(prefs::kManagedNotificationsBlockedForUrls
,
153 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF
);
154 // Preferences for default content setting policies. If a policy is not set of
155 // the corresponding preferences below is set to CONTENT_SETTING_DEFAULT.
156 registry
->RegisterIntegerPref(
157 prefs::kManagedDefaultCookiesSetting
,
158 CONTENT_SETTING_DEFAULT
,
159 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF
);
160 registry
->RegisterIntegerPref(
161 prefs::kManagedDefaultImagesSetting
,
162 CONTENT_SETTING_DEFAULT
,
163 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF
);
164 registry
->RegisterIntegerPref(
165 prefs::kManagedDefaultJavaScriptSetting
,
166 CONTENT_SETTING_DEFAULT
,
167 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF
);
168 registry
->RegisterIntegerPref(
169 prefs::kManagedDefaultPluginsSetting
,
170 CONTENT_SETTING_DEFAULT
,
171 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF
);
172 registry
->RegisterIntegerPref(
173 prefs::kManagedDefaultPopupsSetting
,
174 CONTENT_SETTING_DEFAULT
,
175 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF
);
176 registry
->RegisterIntegerPref(
177 prefs::kManagedDefaultGeolocationSetting
,
178 CONTENT_SETTING_DEFAULT
,
179 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF
);
180 registry
->RegisterIntegerPref(
181 prefs::kManagedDefaultNotificationsSetting
,
182 CONTENT_SETTING_DEFAULT
,
183 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF
);
184 registry
->RegisterIntegerPref(
185 prefs::kManagedDefaultMediaStreamSetting
,
186 CONTENT_SETTING_DEFAULT
,
187 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF
);
190 PolicyProvider::PolicyProvider(PrefService
* prefs
) : prefs_(prefs
) {
191 ReadManagedDefaultSettings();
192 ReadManagedContentSettings(false);
194 pref_change_registrar_
.Init(prefs_
);
195 PrefChangeRegistrar::NamedChangeCallback callback
=
196 base::Bind(&PolicyProvider::OnPreferenceChanged
, base::Unretained(this));
197 pref_change_registrar_
.Add(
198 prefs::kManagedAutoSelectCertificateForUrls
, callback
);
199 pref_change_registrar_
.Add(prefs::kManagedCookiesBlockedForUrls
, callback
);
200 pref_change_registrar_
.Add(prefs::kManagedCookiesAllowedForUrls
, callback
);
201 pref_change_registrar_
.Add(
202 prefs::kManagedCookiesSessionOnlyForUrls
, callback
);
203 pref_change_registrar_
.Add(prefs::kManagedImagesBlockedForUrls
, callback
);
204 pref_change_registrar_
.Add(prefs::kManagedImagesAllowedForUrls
, callback
);
205 pref_change_registrar_
.Add(prefs::kManagedJavaScriptBlockedForUrls
, callback
);
206 pref_change_registrar_
.Add(prefs::kManagedJavaScriptAllowedForUrls
, callback
);
207 pref_change_registrar_
.Add(prefs::kManagedPluginsBlockedForUrls
, callback
);
208 pref_change_registrar_
.Add(prefs::kManagedPluginsAllowedForUrls
, callback
);
209 pref_change_registrar_
.Add(prefs::kManagedPopupsBlockedForUrls
, callback
);
210 pref_change_registrar_
.Add(prefs::kManagedPopupsAllowedForUrls
, callback
);
211 pref_change_registrar_
.Add(
212 prefs::kManagedNotificationsAllowedForUrls
, callback
);
213 pref_change_registrar_
.Add(
214 prefs::kManagedNotificationsBlockedForUrls
, callback
);
215 // The following preferences are only used to indicate if a
216 // default content setting is managed and to hold the managed default setting
217 // value. If the value for any of the following perferences is set then the
218 // corresponding default content setting is managed. These preferences exist
219 // in parallel to the preference default content settings. If a
220 // default content settings type is managed any user defined excpetions
221 // (patterns) for this type are ignored.
222 pref_change_registrar_
.Add(prefs::kManagedDefaultCookiesSetting
, callback
);
223 pref_change_registrar_
.Add(prefs::kManagedDefaultImagesSetting
, callback
);
224 pref_change_registrar_
.Add(prefs::kManagedDefaultJavaScriptSetting
, callback
);
225 pref_change_registrar_
.Add(prefs::kManagedDefaultPluginsSetting
, callback
);
226 pref_change_registrar_
.Add(prefs::kManagedDefaultPopupsSetting
, callback
);
227 pref_change_registrar_
.Add(
228 prefs::kManagedDefaultGeolocationSetting
, callback
);
229 pref_change_registrar_
.Add(
230 prefs::kManagedDefaultNotificationsSetting
, callback
);
231 pref_change_registrar_
.Add(
232 prefs::kManagedDefaultMediaStreamSetting
, callback
);
235 PolicyProvider::~PolicyProvider() {
239 RuleIterator
* PolicyProvider::GetRuleIterator(
240 ContentSettingsType content_type
,
241 const ResourceIdentifier
& resource_identifier
,
242 bool incognito
) const {
243 return value_map_
.GetRuleIterator(content_type
, resource_identifier
, &lock_
);
246 void PolicyProvider::GetContentSettingsFromPreferences(
247 OriginIdentifierValueMap
* value_map
) {
248 for (size_t i
= 0; i
< arraysize(kPrefsForManagedContentSettingsMap
); ++i
) {
249 const char* pref_name
= kPrefsForManagedContentSettingsMap
[i
].pref_name
;
250 // Skip unset policies.
251 if (!prefs_
->HasPrefPath(pref_name
)) {
252 VLOG(2) << "Skipping unset preference: " << pref_name
;
256 const PrefService::Preference
* pref
= prefs_
->FindPreference(pref_name
);
258 DCHECK(pref
->IsManaged());
260 const base::ListValue
* pattern_str_list
= NULL
;
261 if (!pref
->GetValue()->GetAsList(&pattern_str_list
)) {
266 for (size_t j
= 0; j
< pattern_str_list
->GetSize(); ++j
) {
267 std::string original_pattern_str
;
268 if (!pattern_str_list
->GetString(j
, &original_pattern_str
)) {
273 PatternPair pattern_pair
= ParsePatternString(original_pattern_str
);
274 // Ignore invalid patterns.
275 if (!pattern_pair
.first
.IsValid()) {
276 VLOG(1) << "Ignoring invalid content settings pattern: " <<
277 original_pattern_str
;
281 ContentSettingsType content_type
=
282 kPrefsForManagedContentSettingsMap
[i
].content_type
;
283 DCHECK_NE(content_type
, CONTENT_SETTINGS_TYPE_AUTO_SELECT_CERTIFICATE
);
284 // If only one pattern was defined auto expand it to a pattern pair.
285 ContentSettingsPattern secondary_pattern
=
286 !pattern_pair
.second
.IsValid() ? ContentSettingsPattern::Wildcard()
287 : pattern_pair
.second
;
292 NO_RESOURCE_IDENTIFIER
,
293 base::Value::CreateIntegerValue(
294 kPrefsForManagedContentSettingsMap
[i
].setting
));
299 void PolicyProvider::GetAutoSelectCertificateSettingsFromPreferences(
300 OriginIdentifierValueMap
* value_map
) {
301 const char* pref_name
= prefs::kManagedAutoSelectCertificateForUrls
;
303 if (!prefs_
->HasPrefPath(pref_name
)) {
304 VLOG(2) << "Skipping unset preference: " << pref_name
;
308 const PrefService::Preference
* pref
= prefs_
->FindPreference(pref_name
);
310 DCHECK(pref
->IsManaged());
312 const base::ListValue
* pattern_filter_str_list
= NULL
;
313 if (!pref
->GetValue()->GetAsList(&pattern_filter_str_list
)) {
318 // Parse the list of pattern filter strings. A pattern filter string has
319 // the following JSON format:
322 // "pattern": <content settings pattern string>,
323 // "filter" : <certificate filter in JSON format>
328 // "pattern": "[*.]example.com",
335 for (size_t j
= 0; j
< pattern_filter_str_list
->GetSize(); ++j
) {
336 std::string pattern_filter_json
;
337 if (!pattern_filter_str_list
->GetString(j
, &pattern_filter_json
)) {
342 scoped_ptr
<base::Value
> value(base::JSONReader::Read(pattern_filter_json
,
343 base::JSON_ALLOW_TRAILING_COMMAS
));
344 if (!value
|| !value
->IsType(base::Value::TYPE_DICTIONARY
)) {
345 VLOG(1) << "Ignoring invalid certificate auto select setting. Reason:"
346 " Invalid JSON object: " << pattern_filter_json
;
350 scoped_ptr
<base::DictionaryValue
> pattern_filter_pair(
351 static_cast<base::DictionaryValue
*>(value
.release()));
352 std::string pattern_str
;
353 bool pattern_read
= pattern_filter_pair
->GetString("pattern", &pattern_str
);
354 scoped_ptr
<base::Value
> cert_filter
;
355 bool filter_read
= pattern_filter_pair
->Remove("filter", &cert_filter
);
356 if (!pattern_read
|| !filter_read
||
357 !cert_filter
->IsType(base::Value::TYPE_DICTIONARY
)) {
358 VLOG(1) << "Ignoring invalid certificate auto select setting. Reason:"
359 " Missing pattern or filter.";
363 ContentSettingsPattern pattern
=
364 ContentSettingsPattern::FromString(pattern_str
);
365 // Ignore invalid patterns.
366 if (!pattern
.IsValid()) {
367 VLOG(1) << "Ignoring invalid certificate auto select setting:"
368 " Invalid content settings pattern: " << pattern
;
372 value_map
->SetValue(pattern
,
373 ContentSettingsPattern::Wildcard(),
374 CONTENT_SETTINGS_TYPE_AUTO_SELECT_CERTIFICATE
,
376 cert_filter
.release());
380 void PolicyProvider::ReadManagedDefaultSettings() {
381 for (size_t type
= 0; type
< arraysize(kPrefToManageType
); ++type
) {
382 if (kPrefToManageType
[type
] == NULL
) {
385 UpdateManagedDefaultSetting(ContentSettingsType(type
));
389 void PolicyProvider::UpdateManagedDefaultSetting(
390 ContentSettingsType content_type
) {
391 // If a pref to manage a default-content-setting was not set (NOTICE:
392 // "HasPrefPath" returns false if no value was set for a registered pref) then
393 // the default value of the preference is used. The default value of a
394 // preference to manage a default-content-settings is CONTENT_SETTING_DEFAULT.
395 // This indicates that no managed value is set. If a pref was set, than it
397 DCHECK(!prefs_
->HasPrefPath(kPrefToManageType
[content_type
]) ||
398 prefs_
->IsManagedPreference(kPrefToManageType
[content_type
]));
399 base::AutoLock
auto_lock(lock_
);
401 int setting
= prefs_
->GetInteger(kPrefToManageType
[content_type
]);
402 if (setting
== CONTENT_SETTING_DEFAULT
) {
403 value_map_
.DeleteValue(
404 ContentSettingsPattern::Wildcard(),
405 ContentSettingsPattern::Wildcard(),
410 ContentSettingsPattern::Wildcard(),
411 ContentSettingsPattern::Wildcard(),
414 base::Value::CreateIntegerValue(setting
));
419 void PolicyProvider::ReadManagedContentSettings(bool overwrite
) {
420 base::AutoLock
auto_lock(lock_
);
423 GetContentSettingsFromPreferences(&value_map_
);
424 GetAutoSelectCertificateSettingsFromPreferences(&value_map_
);
427 // Since the PolicyProvider is a read only content settings provider, all
428 // methodes of the ProviderInterface that set or delete any settings do nothing.
429 bool PolicyProvider::SetWebsiteSetting(
430 const ContentSettingsPattern
& primary_pattern
,
431 const ContentSettingsPattern
& secondary_pattern
,
432 ContentSettingsType content_type
,
433 const ResourceIdentifier
& resource_identifier
,
434 base::Value
* value
) {
438 void PolicyProvider::ClearAllContentSettingsRules(
439 ContentSettingsType content_type
) {
442 void PolicyProvider::ShutdownOnUIThread() {
443 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
444 RemoveAllObservers();
447 pref_change_registrar_
.RemoveAll();
451 void PolicyProvider::OnPreferenceChanged(const std::string
& name
) {
452 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
454 if (name
== prefs::kManagedDefaultCookiesSetting
) {
455 UpdateManagedDefaultSetting(CONTENT_SETTINGS_TYPE_COOKIES
);
456 } else if (name
== prefs::kManagedDefaultImagesSetting
) {
457 UpdateManagedDefaultSetting(CONTENT_SETTINGS_TYPE_IMAGES
);
458 } else if (name
== prefs::kManagedDefaultJavaScriptSetting
) {
459 UpdateManagedDefaultSetting(CONTENT_SETTINGS_TYPE_JAVASCRIPT
);
460 } else if (name
== prefs::kManagedDefaultPluginsSetting
) {
461 UpdateManagedDefaultSetting(CONTENT_SETTINGS_TYPE_PLUGINS
);
462 } else if (name
== prefs::kManagedDefaultPopupsSetting
) {
463 UpdateManagedDefaultSetting(CONTENT_SETTINGS_TYPE_POPUPS
);
464 } else if (name
== prefs::kManagedDefaultGeolocationSetting
) {
465 UpdateManagedDefaultSetting(CONTENT_SETTINGS_TYPE_GEOLOCATION
);
466 } else if (name
== prefs::kManagedDefaultNotificationsSetting
) {
467 UpdateManagedDefaultSetting(CONTENT_SETTINGS_TYPE_NOTIFICATIONS
);
468 } else if (name
== prefs::kManagedDefaultMediaStreamSetting
) {
469 UpdateManagedDefaultSetting(CONTENT_SETTINGS_TYPE_MEDIASTREAM
);
470 } else if (name
== prefs::kManagedAutoSelectCertificateForUrls
||
471 name
== prefs::kManagedCookiesAllowedForUrls
||
472 name
== prefs::kManagedCookiesBlockedForUrls
||
473 name
== prefs::kManagedCookiesSessionOnlyForUrls
||
474 name
== prefs::kManagedImagesAllowedForUrls
||
475 name
== prefs::kManagedImagesBlockedForUrls
||
476 name
== prefs::kManagedJavaScriptAllowedForUrls
||
477 name
== prefs::kManagedJavaScriptBlockedForUrls
||
478 name
== prefs::kManagedPluginsAllowedForUrls
||
479 name
== prefs::kManagedPluginsBlockedForUrls
||
480 name
== prefs::kManagedPopupsAllowedForUrls
||
481 name
== prefs::kManagedPopupsBlockedForUrls
||
482 name
== prefs::kManagedNotificationsAllowedForUrls
||
483 name
== prefs::kManagedNotificationsBlockedForUrls
) {
484 ReadManagedContentSettings(true);
485 ReadManagedDefaultSettings();
488 NotifyObservers(ContentSettingsPattern(),
489 ContentSettingsPattern(),
490 CONTENT_SETTINGS_TYPE_DEFAULT
,
494 } // namespace content_settings