• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2011 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/content_settings/content_settings_policy_provider.h"
6 
7 #include <string>
8 #include <vector>
9 
10 #include "base/command_line.h"
11 #include "chrome/browser/content_settings/content_settings_details.h"
12 #include "chrome/browser/content_settings/content_settings_pattern.h"
13 #include "chrome/browser/prefs/pref_service.h"
14 #include "chrome/browser/prefs/scoped_user_pref_update.h"
15 #include "chrome/browser/profiles/profile.h"
16 #include "chrome/common/pref_names.h"
17 #include "content/browser/browser_thread.h"
18 #include "content/common/notification_details.h"
19 #include "content/common/notification_service.h"
20 #include "content/common/notification_source.h"
21 #include "webkit/plugins/npapi/plugin_group.h"
22 #include "webkit/plugins/npapi/plugin_list.h"
23 
24 namespace {
25 
26 // Base pref path of the prefs that contain the managed default content
27 // settings values.
28 const std::string kManagedSettings =
29       "profile.managed_default_content_settings";
30 
31 // The preferences used to manage ContentSettingsTypes.
32 const char* kPrefToManageType[CONTENT_SETTINGS_NUM_TYPES] = {
33   prefs::kManagedDefaultCookiesSetting,
34   prefs::kManagedDefaultImagesSetting,
35   prefs::kManagedDefaultJavaScriptSetting,
36   prefs::kManagedDefaultPluginsSetting,
37   prefs::kManagedDefaultPopupsSetting,
38   NULL,  // Not used for Geolocation
39   NULL,  // Not used for Notifications
40 };
41 
42 struct PrefsForManagedContentSettingsMapEntry {
43   const char* pref_name;
44   ContentSettingsType content_type;
45   ContentSetting setting;
46 };
47 
48 const PrefsForManagedContentSettingsMapEntry
49     kPrefsForManagedContentSettingsMap[] = {
50   {
51     prefs::kManagedCookiesAllowedForUrls,
52     CONTENT_SETTINGS_TYPE_COOKIES,
53     CONTENT_SETTING_ALLOW
54   }, {
55     prefs::kManagedCookiesSessionOnlyForUrls,
56     CONTENT_SETTINGS_TYPE_COOKIES,
57     CONTENT_SETTING_SESSION_ONLY
58   }, {
59     prefs::kManagedCookiesBlockedForUrls,
60     CONTENT_SETTINGS_TYPE_COOKIES,
61     CONTENT_SETTING_BLOCK
62   }, {
63     prefs::kManagedImagesAllowedForUrls,
64     CONTENT_SETTINGS_TYPE_IMAGES,
65     CONTENT_SETTING_ALLOW
66   }, {
67     prefs::kManagedImagesBlockedForUrls,
68     CONTENT_SETTINGS_TYPE_IMAGES,
69     CONTENT_SETTING_BLOCK
70   }, {
71     prefs::kManagedJavaScriptAllowedForUrls,
72     CONTENT_SETTINGS_TYPE_JAVASCRIPT,
73     CONTENT_SETTING_ALLOW
74   }, {
75     prefs::kManagedJavaScriptBlockedForUrls,
76     CONTENT_SETTINGS_TYPE_JAVASCRIPT,
77     CONTENT_SETTING_BLOCK
78   }, {
79     prefs::kManagedPluginsAllowedForUrls,
80     CONTENT_SETTINGS_TYPE_PLUGINS,
81     CONTENT_SETTING_ALLOW
82   }, {
83     prefs::kManagedPluginsBlockedForUrls,
84     CONTENT_SETTINGS_TYPE_PLUGINS,
85     CONTENT_SETTING_BLOCK
86   }, {
87     prefs::kManagedPopupsAllowedForUrls,
88     CONTENT_SETTINGS_TYPE_POPUPS,
89     CONTENT_SETTING_ALLOW
90   }, {
91     prefs::kManagedPopupsBlockedForUrls,
92     CONTENT_SETTINGS_TYPE_POPUPS,
93     CONTENT_SETTING_BLOCK
94   }
95 };
96 
97 }  // namespace
98 
99 namespace content_settings {
100 
PolicyDefaultProvider(Profile * profile)101 PolicyDefaultProvider::PolicyDefaultProvider(Profile* profile)
102     : profile_(profile),
103       is_off_the_record_(profile_->IsOffTheRecord()) {
104   PrefService* prefs = profile->GetPrefs();
105 
106   // Read global defaults.
107   DCHECK_EQ(arraysize(kPrefToManageType),
108             static_cast<size_t>(CONTENT_SETTINGS_NUM_TYPES));
109   ReadManagedDefaultSettings();
110 
111   pref_change_registrar_.Init(prefs);
112   // The following preferences are only used to indicate if a
113   // default-content-setting is managed and to hold the managed default-setting
114   // value. If the value for any of the following perferences is set then the
115   // corresponding default-content-setting is managed. These preferences exist
116   // in parallel to the preference default-content-settings.  If a
117   // default-content-settings-type is managed any user defined excpetions
118   // (patterns) for this type are ignored.
119   pref_change_registrar_.Add(prefs::kManagedDefaultCookiesSetting, this);
120   pref_change_registrar_.Add(prefs::kManagedDefaultImagesSetting, this);
121   pref_change_registrar_.Add(prefs::kManagedDefaultJavaScriptSetting, this);
122   pref_change_registrar_.Add(prefs::kManagedDefaultPluginsSetting, this);
123   pref_change_registrar_.Add(prefs::kManagedDefaultPopupsSetting, this);
124   notification_registrar_.Add(this, NotificationType::PROFILE_DESTROYED,
125                               Source<Profile>(profile_));
126 }
127 
~PolicyDefaultProvider()128 PolicyDefaultProvider::~PolicyDefaultProvider() {
129   UnregisterObservers();
130 }
131 
ProvideDefaultSetting(ContentSettingsType content_type) const132 ContentSetting PolicyDefaultProvider::ProvideDefaultSetting(
133     ContentSettingsType content_type) const {
134   base::AutoLock auto_lock(lock_);
135   return managed_default_content_settings_.settings[content_type];
136 }
137 
UpdateDefaultSetting(ContentSettingsType content_type,ContentSetting setting)138 void PolicyDefaultProvider::UpdateDefaultSetting(
139     ContentSettingsType content_type,
140     ContentSetting setting) {
141 }
142 
DefaultSettingIsManaged(ContentSettingsType content_type) const143 bool PolicyDefaultProvider::DefaultSettingIsManaged(
144     ContentSettingsType content_type) const {
145   base::AutoLock lock(lock_);
146   if (managed_default_content_settings_.settings[content_type] !=
147       CONTENT_SETTING_DEFAULT) {
148     return true;
149   } else {
150     return false;
151   }
152 }
153 
ResetToDefaults()154 void PolicyDefaultProvider::ResetToDefaults() {
155 }
156 
Observe(NotificationType type,const NotificationSource & source,const NotificationDetails & details)157 void PolicyDefaultProvider::Observe(NotificationType type,
158                                     const NotificationSource& source,
159                                     const NotificationDetails& details) {
160   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
161 
162   if (type == NotificationType::PREF_CHANGED) {
163     DCHECK_EQ(profile_->GetPrefs(), Source<PrefService>(source).ptr());
164     std::string* name = Details<std::string>(details).ptr();
165     if (*name == prefs::kManagedDefaultCookiesSetting) {
166       UpdateManagedDefaultSetting(CONTENT_SETTINGS_TYPE_COOKIES);
167     } else if (*name == prefs::kManagedDefaultImagesSetting) {
168       UpdateManagedDefaultSetting(CONTENT_SETTINGS_TYPE_IMAGES);
169     } else if (*name == prefs::kManagedDefaultJavaScriptSetting) {
170       UpdateManagedDefaultSetting(CONTENT_SETTINGS_TYPE_JAVASCRIPT);
171     } else if (*name == prefs::kManagedDefaultPluginsSetting) {
172       UpdateManagedDefaultSetting(CONTENT_SETTINGS_TYPE_PLUGINS);
173     } else if (*name == prefs::kManagedDefaultPopupsSetting) {
174       UpdateManagedDefaultSetting(CONTENT_SETTINGS_TYPE_POPUPS);
175     } else {
176       NOTREACHED() << "Unexpected preference observed";
177       return;
178     }
179 
180     if (!is_off_the_record_) {
181       NotifyObservers(ContentSettingsDetails(
182             ContentSettingsPattern(), CONTENT_SETTINGS_TYPE_DEFAULT, ""));
183     }
184   } else if (type == NotificationType::PROFILE_DESTROYED) {
185     DCHECK_EQ(profile_, Source<Profile>(source).ptr());
186     UnregisterObservers();
187   } else {
188     NOTREACHED() << "Unexpected notification";
189   }
190 }
191 
UnregisterObservers()192 void PolicyDefaultProvider::UnregisterObservers() {
193   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
194   if (!profile_)
195     return;
196   pref_change_registrar_.RemoveAll();
197   notification_registrar_.Remove(this, NotificationType::PROFILE_DESTROYED,
198                                  Source<Profile>(profile_));
199   profile_ = NULL;
200 }
201 
202 
NotifyObservers(const ContentSettingsDetails & details)203 void PolicyDefaultProvider::NotifyObservers(
204     const ContentSettingsDetails& details) {
205   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
206   if (profile_ == NULL)
207     return;
208   NotificationService::current()->Notify(
209       NotificationType::CONTENT_SETTINGS_CHANGED,
210       Source<HostContentSettingsMap>(profile_->GetHostContentSettingsMap()),
211       Details<const ContentSettingsDetails>(&details));
212 }
213 
ReadManagedDefaultSettings()214 void PolicyDefaultProvider::ReadManagedDefaultSettings() {
215   for (size_t type = 0; type < arraysize(kPrefToManageType); ++type) {
216     if (kPrefToManageType[type] == NULL) {
217       continue;
218     }
219     UpdateManagedDefaultSetting(ContentSettingsType(type));
220   }
221 }
222 
UpdateManagedDefaultSetting(ContentSettingsType type)223 void PolicyDefaultProvider::UpdateManagedDefaultSetting(
224     ContentSettingsType type) {
225   // If a pref to manage a default-content-setting was not set (NOTICE:
226   // "HasPrefPath" returns false if no value was set for a registered pref) then
227   // the default value of the preference is used. The default value of a
228   // preference to manage a default-content-settings is CONTENT_SETTING_DEFAULT.
229   // This indicates that no managed value is set. If a pref was set, than it
230   // MUST be managed.
231   PrefService* prefs = profile_->GetPrefs();
232   DCHECK(!prefs->HasPrefPath(kPrefToManageType[type]) ||
233           prefs->IsManagedPreference(kPrefToManageType[type]));
234   base::AutoLock auto_lock(lock_);
235   managed_default_content_settings_.settings[type] = IntToContentSetting(
236       prefs->GetInteger(kPrefToManageType[type]));
237 }
238 
239 // static
RegisterUserPrefs(PrefService * prefs)240 void PolicyDefaultProvider::RegisterUserPrefs(PrefService* prefs) {
241   // Preferences for default content setting policies. A policy is not set of
242   // the corresponding preferences below is set to CONTENT_SETTING_DEFAULT.
243   prefs->RegisterIntegerPref(prefs::kManagedDefaultCookiesSetting,
244       CONTENT_SETTING_DEFAULT);
245   prefs->RegisterIntegerPref(prefs::kManagedDefaultImagesSetting,
246       CONTENT_SETTING_DEFAULT);
247   prefs->RegisterIntegerPref(prefs::kManagedDefaultJavaScriptSetting,
248       CONTENT_SETTING_DEFAULT);
249   prefs->RegisterIntegerPref(prefs::kManagedDefaultPluginsSetting,
250       CONTENT_SETTING_DEFAULT);
251   prefs->RegisterIntegerPref(prefs::kManagedDefaultPopupsSetting,
252       CONTENT_SETTING_DEFAULT);
253 }
254 
255 // ////////////////////////////////////////////////////////////////////////////
256 // PolicyProvider
257 
258 // static
RegisterUserPrefs(PrefService * prefs)259 void PolicyProvider::RegisterUserPrefs(PrefService* prefs) {
260   prefs->RegisterListPref(prefs::kManagedCookiesAllowedForUrls);
261   prefs->RegisterListPref(prefs::kManagedCookiesBlockedForUrls);
262   prefs->RegisterListPref(prefs::kManagedCookiesSessionOnlyForUrls);
263   prefs->RegisterListPref(prefs::kManagedImagesAllowedForUrls);
264   prefs->RegisterListPref(prefs::kManagedImagesBlockedForUrls);
265   prefs->RegisterListPref(prefs::kManagedJavaScriptAllowedForUrls);
266   prefs->RegisterListPref(prefs::kManagedJavaScriptBlockedForUrls);
267   prefs->RegisterListPref(prefs::kManagedPluginsAllowedForUrls);
268   prefs->RegisterListPref(prefs::kManagedPluginsBlockedForUrls);
269   prefs->RegisterListPref(prefs::kManagedPopupsAllowedForUrls);
270   prefs->RegisterListPref(prefs::kManagedPopupsBlockedForUrls);
271 }
272 
PolicyProvider(Profile * profile)273 PolicyProvider::PolicyProvider(Profile* profile)
274     : BaseProvider(profile->IsOffTheRecord()),
275       profile_(profile) {
276   Init();
277 }
278 
~PolicyProvider()279 PolicyProvider::~PolicyProvider() {
280   UnregisterObservers();
281 }
282 
ReadManagedContentSettingsTypes(ContentSettingsType content_type)283 void PolicyProvider::ReadManagedContentSettingsTypes(
284     ContentSettingsType content_type) {
285   PrefService* prefs = profile_->GetPrefs();
286   if (kPrefToManageType[content_type] == NULL) {
287     content_type_is_managed_[content_type] = false;
288   } else {
289     content_type_is_managed_[content_type] =
290          prefs->IsManagedPreference(kPrefToManageType[content_type]);
291   }
292 }
293 
Init()294 void PolicyProvider::Init() {
295   PrefService* prefs = profile_->GetPrefs();
296 
297   ReadManagedContentSettings(false);
298   for (int i = 0; i < CONTENT_SETTINGS_NUM_TYPES; ++i)
299     ReadManagedContentSettingsTypes(ContentSettingsType(i));
300 
301   pref_change_registrar_.Init(prefs);
302   pref_change_registrar_.Add(prefs::kManagedCookiesBlockedForUrls, this);
303   pref_change_registrar_.Add(prefs::kManagedCookiesAllowedForUrls, this);
304   pref_change_registrar_.Add(prefs::kManagedCookiesSessionOnlyForUrls, this);
305   pref_change_registrar_.Add(prefs::kManagedImagesBlockedForUrls, this);
306   pref_change_registrar_.Add(prefs::kManagedImagesAllowedForUrls, this);
307   pref_change_registrar_.Add(prefs::kManagedJavaScriptBlockedForUrls, this);
308   pref_change_registrar_.Add(prefs::kManagedJavaScriptAllowedForUrls, this);
309   pref_change_registrar_.Add(prefs::kManagedPluginsBlockedForUrls, this);
310   pref_change_registrar_.Add(prefs::kManagedPluginsAllowedForUrls, this);
311   pref_change_registrar_.Add(prefs::kManagedPopupsBlockedForUrls, this);
312   pref_change_registrar_.Add(prefs::kManagedPopupsAllowedForUrls, this);
313 
314   pref_change_registrar_.Add(prefs::kManagedDefaultCookiesSetting, this);
315   pref_change_registrar_.Add(prefs::kManagedDefaultImagesSetting, this);
316   pref_change_registrar_.Add(prefs::kManagedDefaultJavaScriptSetting, this);
317   pref_change_registrar_.Add(prefs::kManagedDefaultPluginsSetting, this);
318   pref_change_registrar_.Add(prefs::kManagedDefaultPopupsSetting, this);
319 
320   notification_registrar_.Add(this, NotificationType::PROFILE_DESTROYED,
321                               Source<Profile>(profile_));
322 }
323 
ContentSettingsTypeIsManaged(ContentSettingsType content_type)324 bool PolicyProvider::ContentSettingsTypeIsManaged(
325     ContentSettingsType content_type) {
326   return content_type_is_managed_[content_type];
327 }
328 
GetContentSettingsFromPreferences(PrefService * prefs,ContentSettingsRules * rules)329 void PolicyProvider::GetContentSettingsFromPreferences(
330     PrefService* prefs,
331     ContentSettingsRules* rules) {
332   for (size_t i = 0; i < arraysize(kPrefsForManagedContentSettingsMap); ++i) {
333     const char* pref_name = kPrefsForManagedContentSettingsMap[i].pref_name;
334     // Skip unset policies.
335     if (!prefs->HasPrefPath(pref_name)) {
336       VLOG(2) << "Skipping unset preference: " << pref_name;
337       continue;
338     }
339 
340     const PrefService::Preference* pref = prefs->FindPreference(pref_name);
341     DCHECK(pref->IsManaged());
342     DCHECK_EQ(Value::TYPE_LIST, pref->GetType());
343 
344     const ListValue* pattern_str_list =
345         static_cast<const ListValue*>(pref->GetValue());
346     for (size_t j = 0; j < pattern_str_list->GetSize(); ++j) {
347       std::string original_pattern_str;
348       pattern_str_list->GetString(j, &original_pattern_str);
349       ContentSettingsPattern pattern(original_pattern_str);
350       // Ignore invalid patterns.
351       if (!pattern.IsValid()) {
352         VLOG(1) << "Ignoring invalid content settings pattern: " <<
353                    pattern.AsString();
354         continue;
355       }
356       rules->push_back(MakeTuple(
357           pattern,
358           pattern,
359           kPrefsForManagedContentSettingsMap[i].content_type,
360           ProviderInterface::ResourceIdentifier(NO_RESOURCE_IDENTIFIER),
361           kPrefsForManagedContentSettingsMap[i].setting));
362     }
363   }
364 }
365 
ReadManagedContentSettings(bool overwrite)366 void PolicyProvider::ReadManagedContentSettings(bool overwrite) {
367   ContentSettingsRules rules;
368   PrefService* prefs = profile_->GetPrefs();
369   GetContentSettingsFromPreferences(prefs, &rules);
370   {
371     base::AutoLock auto_lock(lock());
372     HostContentSettings* content_settings_map = host_content_settings();
373     if (overwrite)
374       content_settings_map->clear();
375     for (ContentSettingsRules::iterator rule = rules.begin();
376          rule != rules.end();
377          ++rule) {
378       DispatchToMethod(this, &PolicyProvider::UpdateContentSettingsMap, *rule);
379     }
380   }
381 }
382 
383 // Since the PolicyProvider is a read only content settings provider, all
384 // methodes of the ProviderInterface that set or delete any settings do nothing.
SetContentSetting(const ContentSettingsPattern & requesting_pattern,const ContentSettingsPattern & embedding_pattern,ContentSettingsType content_type,const ResourceIdentifier & resource_identifier,ContentSetting content_setting)385 void PolicyProvider::SetContentSetting(
386     const ContentSettingsPattern& requesting_pattern,
387     const ContentSettingsPattern& embedding_pattern,
388     ContentSettingsType content_type,
389     const ResourceIdentifier& resource_identifier,
390     ContentSetting content_setting) {
391 }
392 
GetContentSetting(const GURL & requesting_url,const GURL & embedding_url,ContentSettingsType content_type,const ResourceIdentifier & resource_identifier) const393 ContentSetting PolicyProvider::GetContentSetting(
394     const GURL& requesting_url,
395     const GURL& embedding_url,
396     ContentSettingsType content_type,
397     const ResourceIdentifier& resource_identifier) const {
398   return BaseProvider::GetContentSetting(
399       requesting_url,
400       embedding_url,
401       content_type,
402       NO_RESOURCE_IDENTIFIER);
403 }
404 
ClearAllContentSettingsRules(ContentSettingsType content_type)405 void PolicyProvider::ClearAllContentSettingsRules(
406     ContentSettingsType content_type) {
407 }
408 
ResetToDefaults()409 void PolicyProvider::ResetToDefaults() {
410 }
411 
UnregisterObservers()412 void PolicyProvider::UnregisterObservers() {
413   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
414   if (!profile_)
415     return;
416   pref_change_registrar_.RemoveAll();
417   notification_registrar_.Remove(this, NotificationType::PROFILE_DESTROYED,
418                                  Source<Profile>(profile_));
419   profile_ = NULL;
420 }
421 
NotifyObservers(const ContentSettingsDetails & details)422 void PolicyProvider::NotifyObservers(
423     const ContentSettingsDetails& details) {
424   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
425   if (profile_ == NULL)
426     return;
427   NotificationService::current()->Notify(
428       NotificationType::CONTENT_SETTINGS_CHANGED,
429       Source<HostContentSettingsMap>(profile_->GetHostContentSettingsMap()),
430       Details<const ContentSettingsDetails>(&details));
431 }
432 
Observe(NotificationType type,const NotificationSource & source,const NotificationDetails & details)433 void PolicyProvider::Observe(NotificationType type,
434                              const NotificationSource& source,
435                              const NotificationDetails& details) {
436   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
437 
438   if (type == NotificationType::PREF_CHANGED) {
439     DCHECK_EQ(profile_->GetPrefs(), Source<PrefService>(source).ptr());
440     std::string* name = Details<std::string>(details).ptr();
441     if (*name == prefs::kManagedCookiesAllowedForUrls ||
442         *name == prefs::kManagedCookiesBlockedForUrls ||
443         *name == prefs::kManagedCookiesSessionOnlyForUrls ||
444         *name == prefs::kManagedImagesAllowedForUrls ||
445         *name == prefs::kManagedImagesBlockedForUrls ||
446         *name == prefs::kManagedJavaScriptAllowedForUrls ||
447         *name == prefs::kManagedJavaScriptBlockedForUrls ||
448         *name == prefs::kManagedPluginsAllowedForUrls ||
449         *name == prefs::kManagedPluginsBlockedForUrls ||
450         *name == prefs::kManagedPopupsAllowedForUrls ||
451         *name == prefs::kManagedPopupsBlockedForUrls) {
452       ReadManagedContentSettings(true);
453       NotifyObservers(ContentSettingsDetails(
454           ContentSettingsPattern(), CONTENT_SETTINGS_TYPE_DEFAULT, ""));
455       // We do not want to sent a notification when managed default content
456       // settings change. The DefaultProvider will take care of that. We are
457       // only a passive observer.
458       // TODO(markusheintz): NOTICE: This is still work in progress and part of
459       // a larger refactoring. The code will change and be much cleaner and
460       // clearer in the end.
461     } else if (*name == prefs::kManagedDefaultCookiesSetting) {
462       ReadManagedContentSettingsTypes(CONTENT_SETTINGS_TYPE_COOKIES);
463     } else if (*name == prefs::kManagedDefaultImagesSetting) {
464       ReadManagedContentSettingsTypes(CONTENT_SETTINGS_TYPE_IMAGES);
465     } else if (*name == prefs::kManagedDefaultJavaScriptSetting) {
466       ReadManagedContentSettingsTypes(CONTENT_SETTINGS_TYPE_JAVASCRIPT);
467     } else if (*name == prefs::kManagedDefaultPluginsSetting) {
468       ReadManagedContentSettingsTypes(CONTENT_SETTINGS_TYPE_PLUGINS);
469     } else if (*name == prefs::kManagedDefaultPopupsSetting) {
470       ReadManagedContentSettingsTypes(CONTENT_SETTINGS_TYPE_POPUPS);
471     }
472   } else if (type == NotificationType::PROFILE_DESTROYED) {
473     DCHECK_EQ(profile_, Source<Profile>(source).ptr());
474     UnregisterObservers();
475   } else {
476     NOTREACHED() << "Unexpected notification";
477   }
478 }
479 
480 }  // namespace content_settings
481