content_settings_policy_provider.cc revision 5821806d5e7f356e8fa4b058a389a808ea183019
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. 4 5#include "chrome/browser/content_settings/content_settings_policy_provider.h" 6 7#include <string> 8#include <vector> 9 10#include "base/json/json_reader.h" 11#include "base/values.h" 12#include "chrome/browser/content_settings/content_settings_rule.h" 13#include "chrome/browser/content_settings/content_settings_utils.h" 14#include "chrome/browser/prefs/pref_service.h" 15#include "chrome/common/chrome_notification_types.h" 16#include "chrome/common/content_settings_pattern.h" 17#include "chrome/common/pref_names.h" 18#include "content/public/browser/browser_thread.h" 19#include "content/public/browser/notification_details.h" 20#include "content/public/browser/notification_source.h" 21 22using content::BrowserThread; 23 24namespace { 25 26// The preferences used to manage ContentSettingsTypes. 27const char* kPrefToManageType[] = { 28 prefs::kManagedDefaultCookiesSetting, 29 prefs::kManagedDefaultImagesSetting, 30 prefs::kManagedDefaultJavaScriptSetting, 31 prefs::kManagedDefaultPluginsSetting, 32 prefs::kManagedDefaultPopupsSetting, 33 prefs::kManagedDefaultGeolocationSetting, 34 prefs::kManagedDefaultNotificationsSetting, 35 NULL, // No policy for default value of content type intents 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 protocol handlers 42 NULL, // No policy for default value of PPAPI broker 43}; 44COMPILE_ASSERT(arraysize(kPrefToManageType) == CONTENT_SETTINGS_NUM_TYPES, 45 managed_content_settings_pref_names_array_size_incorrect); 46 47struct PrefsForManagedContentSettingsMapEntry { 48 const char* pref_name; 49 ContentSettingsType content_type; 50 ContentSetting setting; 51}; 52 53const PrefsForManagedContentSettingsMapEntry 54 kPrefsForManagedContentSettingsMap[] = { 55 { 56 prefs::kManagedCookiesAllowedForUrls, 57 CONTENT_SETTINGS_TYPE_COOKIES, 58 CONTENT_SETTING_ALLOW 59 }, { 60 prefs::kManagedCookiesSessionOnlyForUrls, 61 CONTENT_SETTINGS_TYPE_COOKIES, 62 CONTENT_SETTING_SESSION_ONLY 63 }, { 64 prefs::kManagedCookiesBlockedForUrls, 65 CONTENT_SETTINGS_TYPE_COOKIES, 66 CONTENT_SETTING_BLOCK 67 }, { 68 prefs::kManagedImagesAllowedForUrls, 69 CONTENT_SETTINGS_TYPE_IMAGES, 70 CONTENT_SETTING_ALLOW 71 }, { 72 prefs::kManagedImagesBlockedForUrls, 73 CONTENT_SETTINGS_TYPE_IMAGES, 74 CONTENT_SETTING_BLOCK 75 }, { 76 prefs::kManagedJavaScriptAllowedForUrls, 77 CONTENT_SETTINGS_TYPE_JAVASCRIPT, 78 CONTENT_SETTING_ALLOW 79 }, { 80 prefs::kManagedJavaScriptBlockedForUrls, 81 CONTENT_SETTINGS_TYPE_JAVASCRIPT, 82 CONTENT_SETTING_BLOCK 83 }, { 84 prefs::kManagedPluginsAllowedForUrls, 85 CONTENT_SETTINGS_TYPE_PLUGINS, 86 CONTENT_SETTING_ALLOW 87 }, { 88 prefs::kManagedPluginsBlockedForUrls, 89 CONTENT_SETTINGS_TYPE_PLUGINS, 90 CONTENT_SETTING_BLOCK 91 }, { 92 prefs::kManagedPopupsAllowedForUrls, 93 CONTENT_SETTINGS_TYPE_POPUPS, 94 CONTENT_SETTING_ALLOW 95 }, { 96 prefs::kManagedPopupsBlockedForUrls, 97 CONTENT_SETTINGS_TYPE_POPUPS, 98 CONTENT_SETTING_BLOCK 99 }, { 100 prefs::kManagedNotificationsAllowedForUrls, 101 CONTENT_SETTINGS_TYPE_NOTIFICATIONS, 102 CONTENT_SETTING_ALLOW 103 }, { 104 prefs::kManagedNotificationsBlockedForUrls, 105 CONTENT_SETTINGS_TYPE_NOTIFICATIONS, 106 CONTENT_SETTING_BLOCK 107 } 108}; 109 110} // namespace 111 112namespace content_settings { 113 114// static 115void PolicyProvider::RegisterUserPrefs(PrefService* prefs) { 116 prefs->RegisterListPref(prefs::kManagedAutoSelectCertificateForUrls, 117 PrefService::UNSYNCABLE_PREF); 118 prefs->RegisterListPref(prefs::kManagedCookiesAllowedForUrls, 119 PrefService::UNSYNCABLE_PREF); 120 prefs->RegisterListPref(prefs::kManagedCookiesBlockedForUrls, 121 PrefService::UNSYNCABLE_PREF); 122 prefs->RegisterListPref(prefs::kManagedCookiesSessionOnlyForUrls, 123 PrefService::UNSYNCABLE_PREF); 124 prefs->RegisterListPref(prefs::kManagedImagesAllowedForUrls, 125 PrefService::UNSYNCABLE_PREF); 126 prefs->RegisterListPref(prefs::kManagedImagesBlockedForUrls, 127 PrefService::UNSYNCABLE_PREF); 128 prefs->RegisterListPref(prefs::kManagedJavaScriptAllowedForUrls, 129 PrefService::UNSYNCABLE_PREF); 130 prefs->RegisterListPref(prefs::kManagedJavaScriptBlockedForUrls, 131 PrefService::UNSYNCABLE_PREF); 132 prefs->RegisterListPref(prefs::kManagedPluginsAllowedForUrls, 133 PrefService::UNSYNCABLE_PREF); 134 prefs->RegisterListPref(prefs::kManagedPluginsBlockedForUrls, 135 PrefService::UNSYNCABLE_PREF); 136 prefs->RegisterListPref(prefs::kManagedPopupsAllowedForUrls, 137 PrefService::UNSYNCABLE_PREF); 138 prefs->RegisterListPref(prefs::kManagedPopupsBlockedForUrls, 139 PrefService::UNSYNCABLE_PREF); 140 prefs->RegisterListPref(prefs::kManagedNotificationsAllowedForUrls, 141 PrefService::UNSYNCABLE_PREF); 142 prefs->RegisterListPref(prefs::kManagedNotificationsBlockedForUrls, 143 PrefService::UNSYNCABLE_PREF); 144 // Preferences for default content setting policies. If a policy is not set of 145 // the corresponding preferences below is set to CONTENT_SETTING_DEFAULT. 146 prefs->RegisterIntegerPref(prefs::kManagedDefaultCookiesSetting, 147 CONTENT_SETTING_DEFAULT, 148 PrefService::UNSYNCABLE_PREF); 149 prefs->RegisterIntegerPref(prefs::kManagedDefaultImagesSetting, 150 CONTENT_SETTING_DEFAULT, 151 PrefService::UNSYNCABLE_PREF); 152 prefs->RegisterIntegerPref(prefs::kManagedDefaultJavaScriptSetting, 153 CONTENT_SETTING_DEFAULT, 154 PrefService::UNSYNCABLE_PREF); 155 prefs->RegisterIntegerPref(prefs::kManagedDefaultPluginsSetting, 156 CONTENT_SETTING_DEFAULT, 157 PrefService::UNSYNCABLE_PREF); 158 prefs->RegisterIntegerPref(prefs::kManagedDefaultPopupsSetting, 159 CONTENT_SETTING_DEFAULT, 160 PrefService::UNSYNCABLE_PREF); 161 prefs->RegisterIntegerPref(prefs::kManagedDefaultGeolocationSetting, 162 CONTENT_SETTING_DEFAULT, 163 PrefService::UNSYNCABLE_PREF); 164 prefs->RegisterIntegerPref(prefs::kManagedDefaultNotificationsSetting, 165 CONTENT_SETTING_DEFAULT, 166 PrefService::UNSYNCABLE_PREF); 167 prefs->RegisterIntegerPref(prefs::kManagedDefaultMediaStreamSetting, 168 CONTENT_SETTING_DEFAULT, 169 PrefService::UNSYNCABLE_PREF); 170} 171 172PolicyProvider::PolicyProvider(PrefService* prefs) : prefs_(prefs) { 173 ReadManagedDefaultSettings(); 174 ReadManagedContentSettings(false); 175 176 pref_change_registrar_.Init(prefs_); 177 pref_change_registrar_.Add(prefs::kManagedAutoSelectCertificateForUrls, this); 178 pref_change_registrar_.Add(prefs::kManagedCookiesBlockedForUrls, this); 179 pref_change_registrar_.Add(prefs::kManagedCookiesAllowedForUrls, this); 180 pref_change_registrar_.Add(prefs::kManagedCookiesSessionOnlyForUrls, this); 181 pref_change_registrar_.Add(prefs::kManagedImagesBlockedForUrls, this); 182 pref_change_registrar_.Add(prefs::kManagedImagesAllowedForUrls, this); 183 pref_change_registrar_.Add(prefs::kManagedJavaScriptBlockedForUrls, this); 184 pref_change_registrar_.Add(prefs::kManagedJavaScriptAllowedForUrls, this); 185 pref_change_registrar_.Add(prefs::kManagedPluginsBlockedForUrls, this); 186 pref_change_registrar_.Add(prefs::kManagedPluginsAllowedForUrls, this); 187 pref_change_registrar_.Add(prefs::kManagedPopupsBlockedForUrls, this); 188 pref_change_registrar_.Add(prefs::kManagedPopupsAllowedForUrls, this); 189 pref_change_registrar_.Add(prefs::kManagedNotificationsAllowedForUrls, this); 190 pref_change_registrar_.Add(prefs::kManagedNotificationsBlockedForUrls, this); 191 // The following preferences are only used to indicate if a 192 // default content setting is managed and to hold the managed default setting 193 // value. If the value for any of the following perferences is set then the 194 // corresponding default content setting is managed. These preferences exist 195 // in parallel to the preference default content settings. If a 196 // default content settings type is managed any user defined excpetions 197 // (patterns) for this type are ignored. 198 pref_change_registrar_.Add(prefs::kManagedDefaultCookiesSetting, this); 199 pref_change_registrar_.Add(prefs::kManagedDefaultImagesSetting, this); 200 pref_change_registrar_.Add(prefs::kManagedDefaultJavaScriptSetting, this); 201 pref_change_registrar_.Add(prefs::kManagedDefaultPluginsSetting, this); 202 pref_change_registrar_.Add(prefs::kManagedDefaultPopupsSetting, this); 203 pref_change_registrar_.Add(prefs::kManagedDefaultGeolocationSetting, this); 204 pref_change_registrar_.Add(prefs::kManagedDefaultNotificationsSetting, this); 205 pref_change_registrar_.Add(prefs::kManagedDefaultMediaStreamSetting, this); 206} 207 208PolicyProvider::~PolicyProvider() { 209 DCHECK(!prefs_); 210} 211 212RuleIterator* PolicyProvider::GetRuleIterator( 213 ContentSettingsType content_type, 214 const ResourceIdentifier& resource_identifier, 215 bool incognito) const { 216 return value_map_.GetRuleIterator(content_type, resource_identifier, &lock_); 217} 218 219void PolicyProvider::GetContentSettingsFromPreferences( 220 OriginIdentifierValueMap* value_map) { 221 for (size_t i = 0; i < arraysize(kPrefsForManagedContentSettingsMap); ++i) { 222 const char* pref_name = kPrefsForManagedContentSettingsMap[i].pref_name; 223 // Skip unset policies. 224 if (!prefs_->HasPrefPath(pref_name)) { 225 VLOG(2) << "Skipping unset preference: " << pref_name; 226 continue; 227 } 228 229 const PrefService::Preference* pref = prefs_->FindPreference(pref_name); 230 DCHECK(pref); 231 DCHECK(pref->IsManaged()); 232 233 const base::ListValue* pattern_str_list = NULL; 234 if (!pref->GetValue()->GetAsList(&pattern_str_list)) { 235 NOTREACHED(); 236 return; 237 } 238 239 for (size_t j = 0; j < pattern_str_list->GetSize(); ++j) { 240 std::string original_pattern_str; 241 if (!pattern_str_list->GetString(j, &original_pattern_str)) { 242 NOTREACHED(); 243 continue; 244 } 245 246 PatternPair pattern_pair = ParsePatternString(original_pattern_str); 247 // Ignore invalid patterns. 248 if (!pattern_pair.first.IsValid()) { 249 VLOG(1) << "Ignoring invalid content settings pattern: " << 250 original_pattern_str; 251 continue; 252 } 253 254 ContentSettingsType content_type = 255 kPrefsForManagedContentSettingsMap[i].content_type; 256 DCHECK_NE(content_type, CONTENT_SETTINGS_TYPE_AUTO_SELECT_CERTIFICATE); 257 // If only one pattern was defined auto expand it to a pattern pair. 258 ContentSettingsPattern secondary_pattern = 259 !pattern_pair.second.IsValid() ? ContentSettingsPattern::Wildcard() 260 : pattern_pair.second; 261 value_map->SetValue( 262 pattern_pair.first, 263 secondary_pattern, 264 content_type, 265 ResourceIdentifier(NO_RESOURCE_IDENTIFIER), 266 base::Value::CreateIntegerValue( 267 kPrefsForManagedContentSettingsMap[i].setting)); 268 } 269 } 270} 271 272void PolicyProvider::GetAutoSelectCertificateSettingsFromPreferences( 273 OriginIdentifierValueMap* value_map) { 274 const char* pref_name = prefs::kManagedAutoSelectCertificateForUrls; 275 276 if (!prefs_->HasPrefPath(pref_name)) { 277 VLOG(2) << "Skipping unset preference: " << pref_name; 278 return; 279 } 280 281 const PrefService::Preference* pref = prefs_->FindPreference(pref_name); 282 DCHECK(pref); 283 DCHECK(pref->IsManaged()); 284 285 const base::ListValue* pattern_filter_str_list = NULL; 286 if (!pref->GetValue()->GetAsList(&pattern_filter_str_list)) { 287 NOTREACHED(); 288 return; 289 } 290 291 // Parse the list of pattern filter strings. A pattern filter string has 292 // the following JSON format: 293 // 294 // { 295 // "pattern": <content settings pattern string>, 296 // "filter" : <certificate filter in JSON format> 297 // } 298 // 299 // e.g. 300 // { 301 // "pattern": "[*.]example.com", 302 // "filter": { 303 // "ISSUER": { 304 // "CN": "some name" 305 // } 306 // } 307 // } 308 for (size_t j = 0; j < pattern_filter_str_list->GetSize(); ++j) { 309 std::string pattern_filter_json; 310 if (!pattern_filter_str_list->GetString(j, &pattern_filter_json)) { 311 NOTREACHED(); 312 continue; 313 } 314 315 scoped_ptr<base::Value> value(base::JSONReader::Read(pattern_filter_json, 316 base::JSON_ALLOW_TRAILING_COMMAS)); 317 if (!value.get()) { 318 VLOG(1) << "Ignoring invalid certificate auto select setting. Reason:" 319 " Invalid JSON format: " << pattern_filter_json; 320 continue; 321 } 322 323 scoped_ptr<base::DictionaryValue> pattern_filter_pair( 324 static_cast<base::DictionaryValue*>(value.release())); 325 std::string pattern_str; 326 bool pattern_read = pattern_filter_pair->GetString("pattern", &pattern_str); 327 base::Value* cert_filter_ptr = NULL; 328 bool filter_read = pattern_filter_pair->Remove("filter", &cert_filter_ptr); 329 scoped_ptr<base::Value> cert_filter(cert_filter_ptr); 330 if (!pattern_read || !filter_read) { 331 VLOG(1) << "Ignoring invalid certificate auto select setting. Reason:" 332 " Missing pattern or filter."; 333 continue; 334 } 335 336 ContentSettingsPattern pattern = 337 ContentSettingsPattern::FromString(pattern_str); 338 // Ignore invalid patterns. 339 if (!pattern.IsValid()) { 340 VLOG(1) << "Ignoring invalid certificate auto select setting:" 341 " Invalid content settings pattern: " << pattern; 342 continue; 343 } 344 345 DCHECK(cert_filter->IsType(base::Value::TYPE_DICTIONARY)); 346 value_map->SetValue(pattern, 347 ContentSettingsPattern::Wildcard(), 348 CONTENT_SETTINGS_TYPE_AUTO_SELECT_CERTIFICATE, 349 std::string(), 350 cert_filter.release()); 351 } 352} 353 354void PolicyProvider::ReadManagedDefaultSettings() { 355 for (size_t type = 0; type < arraysize(kPrefToManageType); ++type) { 356 if (kPrefToManageType[type] == NULL) { 357 continue; 358 } 359 UpdateManagedDefaultSetting(ContentSettingsType(type)); 360 } 361} 362 363void PolicyProvider::UpdateManagedDefaultSetting( 364 ContentSettingsType content_type) { 365 // If a pref to manage a default-content-setting was not set (NOTICE: 366 // "HasPrefPath" returns false if no value was set for a registered pref) then 367 // the default value of the preference is used. The default value of a 368 // preference to manage a default-content-settings is CONTENT_SETTING_DEFAULT. 369 // This indicates that no managed value is set. If a pref was set, than it 370 // MUST be managed. 371 DCHECK(!prefs_->HasPrefPath(kPrefToManageType[content_type]) || 372 prefs_->IsManagedPreference(kPrefToManageType[content_type])); 373 base::AutoLock auto_lock(lock_); 374 375 int setting = prefs_->GetInteger(kPrefToManageType[content_type]); 376 if (setting == CONTENT_SETTING_DEFAULT) { 377 value_map_.DeleteValue( 378 ContentSettingsPattern::Wildcard(), 379 ContentSettingsPattern::Wildcard(), 380 content_type, 381 std::string()); 382 } else { 383 value_map_.SetValue( 384 ContentSettingsPattern::Wildcard(), 385 ContentSettingsPattern::Wildcard(), 386 content_type, 387 std::string(), 388 Value::CreateIntegerValue(setting)); 389 } 390} 391 392 393void PolicyProvider::ReadManagedContentSettings(bool overwrite) { 394 base::AutoLock auto_lock(lock_); 395 if (overwrite) 396 value_map_.clear(); 397 GetContentSettingsFromPreferences(&value_map_); 398 GetAutoSelectCertificateSettingsFromPreferences(&value_map_); 399} 400 401// Since the PolicyProvider is a read only content settings provider, all 402// methodes of the ProviderInterface that set or delete any settings do nothing. 403bool PolicyProvider::SetWebsiteSetting( 404 const ContentSettingsPattern& primary_pattern, 405 const ContentSettingsPattern& secondary_pattern, 406 ContentSettingsType content_type, 407 const ResourceIdentifier& resource_identifier, 408 Value* value) { 409 return false; 410} 411 412void PolicyProvider::ClearAllContentSettingsRules( 413 ContentSettingsType content_type) { 414} 415 416void PolicyProvider::ShutdownOnUIThread() { 417 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 418 RemoveAllObservers(); 419 if (!prefs_) 420 return; 421 pref_change_registrar_.RemoveAll(); 422 prefs_ = NULL; 423} 424 425void PolicyProvider::OnPreferenceChanged(PrefServiceBase* service, 426 const std::string& name) { 427 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 428 DCHECK_EQ(prefs_, service); 429 430 if (name == prefs::kManagedDefaultCookiesSetting) { 431 UpdateManagedDefaultSetting(CONTENT_SETTINGS_TYPE_COOKIES); 432 } else if (name == prefs::kManagedDefaultImagesSetting) { 433 UpdateManagedDefaultSetting(CONTENT_SETTINGS_TYPE_IMAGES); 434 } else if (name == prefs::kManagedDefaultJavaScriptSetting) { 435 UpdateManagedDefaultSetting(CONTENT_SETTINGS_TYPE_JAVASCRIPT); 436 } else if (name == prefs::kManagedDefaultPluginsSetting) { 437 UpdateManagedDefaultSetting(CONTENT_SETTINGS_TYPE_PLUGINS); 438 } else if (name == prefs::kManagedDefaultPopupsSetting) { 439 UpdateManagedDefaultSetting(CONTENT_SETTINGS_TYPE_POPUPS); 440 } else if (name == prefs::kManagedDefaultGeolocationSetting) { 441 UpdateManagedDefaultSetting(CONTENT_SETTINGS_TYPE_GEOLOCATION); 442 } else if (name == prefs::kManagedDefaultNotificationsSetting) { 443 UpdateManagedDefaultSetting(CONTENT_SETTINGS_TYPE_NOTIFICATIONS); 444 } else if (name == prefs::kManagedDefaultMediaStreamSetting) { 445 UpdateManagedDefaultSetting(CONTENT_SETTINGS_TYPE_MEDIASTREAM); 446 } else if (name == prefs::kManagedAutoSelectCertificateForUrls || 447 name == prefs::kManagedCookiesAllowedForUrls || 448 name == prefs::kManagedCookiesBlockedForUrls || 449 name == prefs::kManagedCookiesSessionOnlyForUrls || 450 name == prefs::kManagedImagesAllowedForUrls || 451 name == prefs::kManagedImagesBlockedForUrls || 452 name == prefs::kManagedJavaScriptAllowedForUrls || 453 name == prefs::kManagedJavaScriptBlockedForUrls || 454 name == prefs::kManagedPluginsAllowedForUrls || 455 name == prefs::kManagedPluginsBlockedForUrls || 456 name == prefs::kManagedPopupsAllowedForUrls || 457 name == prefs::kManagedPopupsBlockedForUrls || 458 name == prefs::kManagedNotificationsAllowedForUrls || 459 name == prefs::kManagedNotificationsBlockedForUrls) { 460 ReadManagedContentSettings(true); 461 ReadManagedDefaultSettings(); 462 } 463 464 NotifyObservers(ContentSettingsPattern(), 465 ContentSettingsPattern(), 466 CONTENT_SETTINGS_TYPE_DEFAULT, 467 std::string()); 468} 469 470} // namespace content_settings 471