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/pref_registry/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
52 #if defined(OS_ANDROID)
53 NULL
, // No policy for default value of app banners
56 COMPILE_ASSERT(arraysize(kPrefToManageType
) == CONTENT_SETTINGS_NUM_TYPES
,
57 managed_content_settings_pref_names_array_size_incorrect
);
59 struct PrefsForManagedContentSettingsMapEntry
{
60 const char* pref_name
;
61 ContentSettingsType content_type
;
62 ContentSetting setting
;
65 const PrefsForManagedContentSettingsMapEntry
66 kPrefsForManagedContentSettingsMap
[] = {
68 prefs::kManagedCookiesAllowedForUrls
,
69 CONTENT_SETTINGS_TYPE_COOKIES
,
72 prefs::kManagedCookiesSessionOnlyForUrls
,
73 CONTENT_SETTINGS_TYPE_COOKIES
,
74 CONTENT_SETTING_SESSION_ONLY
76 prefs::kManagedCookiesBlockedForUrls
,
77 CONTENT_SETTINGS_TYPE_COOKIES
,
80 prefs::kManagedImagesAllowedForUrls
,
81 CONTENT_SETTINGS_TYPE_IMAGES
,
84 prefs::kManagedImagesBlockedForUrls
,
85 CONTENT_SETTINGS_TYPE_IMAGES
,
88 prefs::kManagedJavaScriptAllowedForUrls
,
89 CONTENT_SETTINGS_TYPE_JAVASCRIPT
,
92 prefs::kManagedJavaScriptBlockedForUrls
,
93 CONTENT_SETTINGS_TYPE_JAVASCRIPT
,
96 prefs::kManagedPluginsAllowedForUrls
,
97 CONTENT_SETTINGS_TYPE_PLUGINS
,
100 prefs::kManagedPluginsBlockedForUrls
,
101 CONTENT_SETTINGS_TYPE_PLUGINS
,
102 CONTENT_SETTING_BLOCK
104 prefs::kManagedPopupsAllowedForUrls
,
105 CONTENT_SETTINGS_TYPE_POPUPS
,
106 CONTENT_SETTING_ALLOW
108 prefs::kManagedPopupsBlockedForUrls
,
109 CONTENT_SETTINGS_TYPE_POPUPS
,
110 CONTENT_SETTING_BLOCK
112 prefs::kManagedNotificationsAllowedForUrls
,
113 CONTENT_SETTINGS_TYPE_NOTIFICATIONS
,
114 CONTENT_SETTING_ALLOW
116 prefs::kManagedNotificationsBlockedForUrls
,
117 CONTENT_SETTINGS_TYPE_NOTIFICATIONS
,
118 CONTENT_SETTING_BLOCK
124 namespace content_settings
{
127 void PolicyProvider::RegisterProfilePrefs(
128 user_prefs::PrefRegistrySyncable
* registry
) {
129 registry
->RegisterListPref(prefs::kManagedAutoSelectCertificateForUrls
,
130 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF
);
131 registry
->RegisterListPref(prefs::kManagedCookiesAllowedForUrls
,
132 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF
);
133 registry
->RegisterListPref(prefs::kManagedCookiesBlockedForUrls
,
134 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF
);
135 registry
->RegisterListPref(prefs::kManagedCookiesSessionOnlyForUrls
,
136 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF
);
137 registry
->RegisterListPref(prefs::kManagedImagesAllowedForUrls
,
138 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF
);
139 registry
->RegisterListPref(prefs::kManagedImagesBlockedForUrls
,
140 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF
);
141 registry
->RegisterListPref(prefs::kManagedJavaScriptAllowedForUrls
,
142 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF
);
143 registry
->RegisterListPref(prefs::kManagedJavaScriptBlockedForUrls
,
144 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF
);
145 registry
->RegisterListPref(prefs::kManagedPluginsAllowedForUrls
,
146 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF
);
147 registry
->RegisterListPref(prefs::kManagedPluginsBlockedForUrls
,
148 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF
);
149 registry
->RegisterListPref(prefs::kManagedPopupsAllowedForUrls
,
150 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF
);
151 registry
->RegisterListPref(prefs::kManagedPopupsBlockedForUrls
,
152 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF
);
153 registry
->RegisterListPref(prefs::kManagedNotificationsAllowedForUrls
,
154 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF
);
155 registry
->RegisterListPref(prefs::kManagedNotificationsBlockedForUrls
,
156 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF
);
157 // Preferences for default content setting policies. If a policy is not set of
158 // the corresponding preferences below is set to CONTENT_SETTING_DEFAULT.
159 registry
->RegisterIntegerPref(
160 prefs::kManagedDefaultCookiesSetting
,
161 CONTENT_SETTING_DEFAULT
,
162 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF
);
163 registry
->RegisterIntegerPref(
164 prefs::kManagedDefaultImagesSetting
,
165 CONTENT_SETTING_DEFAULT
,
166 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF
);
167 registry
->RegisterIntegerPref(
168 prefs::kManagedDefaultJavaScriptSetting
,
169 CONTENT_SETTING_DEFAULT
,
170 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF
);
171 registry
->RegisterIntegerPref(
172 prefs::kManagedDefaultPluginsSetting
,
173 CONTENT_SETTING_DEFAULT
,
174 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF
);
175 registry
->RegisterIntegerPref(
176 prefs::kManagedDefaultPopupsSetting
,
177 CONTENT_SETTING_DEFAULT
,
178 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF
);
179 registry
->RegisterIntegerPref(
180 prefs::kManagedDefaultGeolocationSetting
,
181 CONTENT_SETTING_DEFAULT
,
182 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF
);
183 registry
->RegisterIntegerPref(
184 prefs::kManagedDefaultNotificationsSetting
,
185 CONTENT_SETTING_DEFAULT
,
186 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF
);
187 registry
->RegisterIntegerPref(
188 prefs::kManagedDefaultMediaStreamSetting
,
189 CONTENT_SETTING_DEFAULT
,
190 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF
);
193 PolicyProvider::PolicyProvider(PrefService
* prefs
) : prefs_(prefs
) {
194 ReadManagedDefaultSettings();
195 ReadManagedContentSettings(false);
197 pref_change_registrar_
.Init(prefs_
);
198 PrefChangeRegistrar::NamedChangeCallback callback
=
199 base::Bind(&PolicyProvider::OnPreferenceChanged
, base::Unretained(this));
200 pref_change_registrar_
.Add(
201 prefs::kManagedAutoSelectCertificateForUrls
, callback
);
202 pref_change_registrar_
.Add(prefs::kManagedCookiesBlockedForUrls
, callback
);
203 pref_change_registrar_
.Add(prefs::kManagedCookiesAllowedForUrls
, callback
);
204 pref_change_registrar_
.Add(
205 prefs::kManagedCookiesSessionOnlyForUrls
, callback
);
206 pref_change_registrar_
.Add(prefs::kManagedImagesBlockedForUrls
, callback
);
207 pref_change_registrar_
.Add(prefs::kManagedImagesAllowedForUrls
, callback
);
208 pref_change_registrar_
.Add(prefs::kManagedJavaScriptBlockedForUrls
, callback
);
209 pref_change_registrar_
.Add(prefs::kManagedJavaScriptAllowedForUrls
, callback
);
210 pref_change_registrar_
.Add(prefs::kManagedPluginsBlockedForUrls
, callback
);
211 pref_change_registrar_
.Add(prefs::kManagedPluginsAllowedForUrls
, callback
);
212 pref_change_registrar_
.Add(prefs::kManagedPopupsBlockedForUrls
, callback
);
213 pref_change_registrar_
.Add(prefs::kManagedPopupsAllowedForUrls
, callback
);
214 pref_change_registrar_
.Add(
215 prefs::kManagedNotificationsAllowedForUrls
, callback
);
216 pref_change_registrar_
.Add(
217 prefs::kManagedNotificationsBlockedForUrls
, callback
);
218 // The following preferences are only used to indicate if a
219 // default content setting is managed and to hold the managed default setting
220 // value. If the value for any of the following perferences is set then the
221 // corresponding default content setting is managed. These preferences exist
222 // in parallel to the preference default content settings. If a
223 // default content settings type is managed any user defined excpetions
224 // (patterns) for this type are ignored.
225 pref_change_registrar_
.Add(prefs::kManagedDefaultCookiesSetting
, callback
);
226 pref_change_registrar_
.Add(prefs::kManagedDefaultImagesSetting
, callback
);
227 pref_change_registrar_
.Add(prefs::kManagedDefaultJavaScriptSetting
, callback
);
228 pref_change_registrar_
.Add(prefs::kManagedDefaultPluginsSetting
, callback
);
229 pref_change_registrar_
.Add(prefs::kManagedDefaultPopupsSetting
, callback
);
230 pref_change_registrar_
.Add(
231 prefs::kManagedDefaultGeolocationSetting
, callback
);
232 pref_change_registrar_
.Add(
233 prefs::kManagedDefaultNotificationsSetting
, callback
);
234 pref_change_registrar_
.Add(
235 prefs::kManagedDefaultMediaStreamSetting
, callback
);
238 PolicyProvider::~PolicyProvider() {
242 RuleIterator
* PolicyProvider::GetRuleIterator(
243 ContentSettingsType content_type
,
244 const ResourceIdentifier
& resource_identifier
,
245 bool incognito
) const {
246 return value_map_
.GetRuleIterator(content_type
, resource_identifier
, &lock_
);
249 void PolicyProvider::GetContentSettingsFromPreferences(
250 OriginIdentifierValueMap
* value_map
) {
251 for (size_t i
= 0; i
< arraysize(kPrefsForManagedContentSettingsMap
); ++i
) {
252 const char* pref_name
= kPrefsForManagedContentSettingsMap
[i
].pref_name
;
253 // Skip unset policies.
254 if (!prefs_
->HasPrefPath(pref_name
)) {
255 VLOG(2) << "Skipping unset preference: " << pref_name
;
259 const PrefService::Preference
* pref
= prefs_
->FindPreference(pref_name
);
261 DCHECK(pref
->IsManaged());
263 const base::ListValue
* pattern_str_list
= NULL
;
264 if (!pref
->GetValue()->GetAsList(&pattern_str_list
)) {
269 for (size_t j
= 0; j
< pattern_str_list
->GetSize(); ++j
) {
270 std::string original_pattern_str
;
271 if (!pattern_str_list
->GetString(j
, &original_pattern_str
)) {
276 PatternPair pattern_pair
= ParsePatternString(original_pattern_str
);
277 // Ignore invalid patterns.
278 if (!pattern_pair
.first
.IsValid()) {
279 VLOG(1) << "Ignoring invalid content settings pattern: " <<
280 original_pattern_str
;
284 ContentSettingsType content_type
=
285 kPrefsForManagedContentSettingsMap
[i
].content_type
;
286 DCHECK_NE(content_type
, CONTENT_SETTINGS_TYPE_AUTO_SELECT_CERTIFICATE
);
287 // If only one pattern was defined auto expand it to a pattern pair.
288 ContentSettingsPattern secondary_pattern
=
289 !pattern_pair
.second
.IsValid() ? ContentSettingsPattern::Wildcard()
290 : pattern_pair
.second
;
295 NO_RESOURCE_IDENTIFIER
,
296 base::Value::CreateIntegerValue(
297 kPrefsForManagedContentSettingsMap
[i
].setting
));
302 void PolicyProvider::GetAutoSelectCertificateSettingsFromPreferences(
303 OriginIdentifierValueMap
* value_map
) {
304 const char* pref_name
= prefs::kManagedAutoSelectCertificateForUrls
;
306 if (!prefs_
->HasPrefPath(pref_name
)) {
307 VLOG(2) << "Skipping unset preference: " << pref_name
;
311 const PrefService::Preference
* pref
= prefs_
->FindPreference(pref_name
);
313 DCHECK(pref
->IsManaged());
315 const base::ListValue
* pattern_filter_str_list
= NULL
;
316 if (!pref
->GetValue()->GetAsList(&pattern_filter_str_list
)) {
321 // Parse the list of pattern filter strings. A pattern filter string has
322 // the following JSON format:
325 // "pattern": <content settings pattern string>,
326 // "filter" : <certificate filter in JSON format>
331 // "pattern": "[*.]example.com",
338 for (size_t j
= 0; j
< pattern_filter_str_list
->GetSize(); ++j
) {
339 std::string pattern_filter_json
;
340 if (!pattern_filter_str_list
->GetString(j
, &pattern_filter_json
)) {
345 scoped_ptr
<base::Value
> value(base::JSONReader::Read(pattern_filter_json
,
346 base::JSON_ALLOW_TRAILING_COMMAS
));
347 if (!value
|| !value
->IsType(base::Value::TYPE_DICTIONARY
)) {
348 VLOG(1) << "Ignoring invalid certificate auto select setting. Reason:"
349 " Invalid JSON object: " << pattern_filter_json
;
353 scoped_ptr
<base::DictionaryValue
> pattern_filter_pair(
354 static_cast<base::DictionaryValue
*>(value
.release()));
355 std::string pattern_str
;
356 bool pattern_read
= pattern_filter_pair
->GetString("pattern", &pattern_str
);
357 scoped_ptr
<base::Value
> cert_filter
;
358 bool filter_read
= pattern_filter_pair
->Remove("filter", &cert_filter
);
359 if (!pattern_read
|| !filter_read
||
360 !cert_filter
->IsType(base::Value::TYPE_DICTIONARY
)) {
361 VLOG(1) << "Ignoring invalid certificate auto select setting. Reason:"
362 " Missing pattern or filter.";
366 ContentSettingsPattern pattern
=
367 ContentSettingsPattern::FromString(pattern_str
);
368 // Ignore invalid patterns.
369 if (!pattern
.IsValid()) {
370 VLOG(1) << "Ignoring invalid certificate auto select setting:"
371 " Invalid content settings pattern: " << pattern
;
375 value_map
->SetValue(pattern
,
376 ContentSettingsPattern::Wildcard(),
377 CONTENT_SETTINGS_TYPE_AUTO_SELECT_CERTIFICATE
,
379 cert_filter
.release());
383 void PolicyProvider::ReadManagedDefaultSettings() {
384 for (size_t type
= 0; type
< arraysize(kPrefToManageType
); ++type
) {
385 if (kPrefToManageType
[type
] == NULL
) {
388 UpdateManagedDefaultSetting(ContentSettingsType(type
));
392 void PolicyProvider::UpdateManagedDefaultSetting(
393 ContentSettingsType content_type
) {
394 // If a pref to manage a default-content-setting was not set (NOTICE:
395 // "HasPrefPath" returns false if no value was set for a registered pref) then
396 // the default value of the preference is used. The default value of a
397 // preference to manage a default-content-settings is CONTENT_SETTING_DEFAULT.
398 // This indicates that no managed value is set. If a pref was set, than it
400 DCHECK(!prefs_
->HasPrefPath(kPrefToManageType
[content_type
]) ||
401 prefs_
->IsManagedPreference(kPrefToManageType
[content_type
]));
402 base::AutoLock
auto_lock(lock_
);
404 int setting
= prefs_
->GetInteger(kPrefToManageType
[content_type
]);
405 if (setting
== CONTENT_SETTING_DEFAULT
) {
406 value_map_
.DeleteValue(
407 ContentSettingsPattern::Wildcard(),
408 ContentSettingsPattern::Wildcard(),
413 ContentSettingsPattern::Wildcard(),
414 ContentSettingsPattern::Wildcard(),
417 base::Value::CreateIntegerValue(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