Home | History | Annotate | Download | only in content_settings
      1 // Copyright (c) 2013 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_internal_extension_provider.h"
      6 
      7 #include "chrome/browser/chrome_notification_types.h"
      8 #include "chrome/browser/content_settings/content_settings_rule.h"
      9 #include "chrome/browser/extensions/extension_service.h"
     10 #include "chrome/common/chrome_content_client.h"
     11 #include "chrome/common/content_settings.h"
     12 #include "chrome/common/content_settings_pattern.h"
     13 #include "chrome/common/extensions/api/plugins/plugins_handler.h"
     14 #include "content/public/browser/browser_thread.h"
     15 #include "content/public/browser/notification_details.h"
     16 #include "content/public/browser/notification_service.h"
     17 #include "extensions/browser/extension_host.h"
     18 #include "extensions/common/constants.h"
     19 #include "extensions/common/extension.h"
     20 #include "extensions/common/extension_set.h"
     21 #include "extensions/common/features/simple_feature.h"
     22 
     23 using extensions::UnloadedExtensionInfo;
     24 
     25 namespace content_settings {
     26 
     27 InternalExtensionProvider::InternalExtensionProvider(
     28     ExtensionService* extension_service)
     29     : registrar_(new content::NotificationRegistrar) {
     30   // Whitelist all extensions loaded so far.
     31   const extensions::ExtensionSet* extensions = extension_service->extensions();
     32   for (extensions::ExtensionSet::const_iterator it = extensions->begin();
     33        it != extensions->end(); ++it) {
     34     if (extensions::PluginInfo::HasPlugins(it->get()))
     35       SetContentSettingForExtension(it->get(), CONTENT_SETTING_ALLOW);
     36   }
     37   Profile* profile = extension_service->profile();
     38   registrar_->Add(this, chrome::NOTIFICATION_EXTENSION_HOST_CREATED,
     39                   content::Source<Profile>(profile));
     40   registrar_->Add(this,
     41                   chrome::NOTIFICATION_EXTENSION_LOADED_DEPRECATED,
     42                   content::Source<Profile>(profile));
     43   registrar_->Add(this, chrome::NOTIFICATION_EXTENSION_UNLOADED_DEPRECATED,
     44                   content::Source<Profile>(profile));
     45 }
     46 
     47 InternalExtensionProvider::~InternalExtensionProvider() {
     48   DCHECK(!registrar_.get());
     49 }
     50 
     51 RuleIterator* InternalExtensionProvider::GetRuleIterator(
     52     ContentSettingsType content_type,
     53     const ResourceIdentifier& resource_identifier,
     54     bool incognito) const {
     55   return value_map_.GetRuleIterator(content_type, resource_identifier, &lock_);
     56 }
     57 
     58 bool InternalExtensionProvider::SetWebsiteSetting(
     59     const ContentSettingsPattern& primary_pattern,
     60     const ContentSettingsPattern& secondary_pattern,
     61     ContentSettingsType content_type,
     62     const ResourceIdentifier& resource_identifier,
     63     base::Value* value) {
     64   return false;
     65 }
     66 
     67 void InternalExtensionProvider::ClearAllContentSettingsRules(
     68     ContentSettingsType content_type) {}
     69 
     70 void InternalExtensionProvider::Observe(int type,
     71                                   const content::NotificationSource& source,
     72                                   const content::NotificationDetails& details) {
     73   switch (type) {
     74     case chrome::NOTIFICATION_EXTENSION_HOST_CREATED: {
     75       const extensions::ExtensionHost* host =
     76           content::Details<extensions::ExtensionHost>(details).ptr();
     77       if (host->extension()->is_platform_app()) {
     78         SetContentSettingForExtension(host->extension(), CONTENT_SETTING_BLOCK);
     79 
     80         // White-list CRD's v2 app, until crbug.com/134216 is complete.
     81         const char* kAppWhitelist[] = {
     82           "2775E568AC98F9578791F1EAB65A1BF5F8CEF414",
     83           "4AA3C5D69A4AECBD236CAD7884502209F0F5C169",
     84           "97B23E01B2AA064E8332EE43A7A85C628AADC3F2",
     85           "9E930B2B5EABA6243AE6C710F126E54688E8FAF6",
     86           "C449A798C495E6CF7D6AF10162113D564E67AD12",
     87           "E410CDAB2C6E6DD408D731016CECF2444000A912",
     88           "EBA908206905323CECE6DC4B276A58A0F4AC573F",
     89 
     90           // http://crbug.com/327507
     91           "FAFE8EFDD2D6AE2EEB277AFEB91C870C79064D9E",
     92           "3B52D273A271D4E2348233E322426DBAE854B567",
     93           "5DF6ADC8708DF59FCFDDBF16AFBFB451380C2059",
     94           "1037DEF5F6B06EA46153AD87B6C5C37440E3F2D1",
     95           "F5815DAFEB8C53B078DD1853B2059E087C42F139",
     96           "6A08EFFF9C16E090D6DCC7EC55A01CADAE840513",
     97 
     98           // http://crbug.com/354258
     99           "C32D6D93E12F5401DAA3A723E0C3CC5F25429BA4",
    100           "9099782647D39C778E15C8C6E0D23C88F5CDE170",
    101           "B7D5B52D1E5B106288BD7F278CAFA5E8D76108B0",
    102           "89349DBAA2C4022FB244AA50182AB60934EB41EE",
    103           "CB593E510640572A995CB1B6D41BD85ED51E63F8",
    104           "1AD1AC86C87969CD3434FA08D99DBA6840AEA612",
    105           "9C2EA21D7975BDF2B3C01C3A454EE44854067A6D",
    106           "D2C488C80C3C90C3E01A991112A05E37831E17D0",
    107           "6EEC061C0E74B46C7B5BE2EEFA49436368F4988F",
    108           "8B344D9E8A4C505EF82A0DBBC25B8BD1F984E777",
    109           "E06AFCB1EB0EFD237824CC4AC8FDD3D43E8BC868",
    110 
    111           // http://crbug.com/386324
    112           "F76F43EFFF56BF17A9868A5243F339BA28746632",
    113           "C6EA52B92F80878515F94137020F01519357E5B5",
    114           "E466389F058ABD73FF6FDD06F768A351FCBF8532",
    115           "40063F1CF7B68BA847A26FA6620DDF156171D23C",
    116           "A6FD8E15353CF1F5C3D0A7B20E1D10AEA4DD3E6A",
    117           "57AC4D9E6BD8A2D0A70056B5FAC2378CAA588912",
    118           "02037314DA4D913640DCF0E296A7D01F4FD793EC",
    119           "B6EC0809BC63E10B431C5E4AA3645232CA86B2A5",
    120           "48CA541313139786F056DBCB504A1025CFF5D2E3",
    121           "05106136AE7F08A3C181D4648E5438350B1D2B4F"
    122         };
    123         if (extensions::SimpleFeature::IsIdInList(
    124                 host->extension()->id(),
    125                 std::set<std::string>(
    126                     kAppWhitelist, kAppWhitelist + arraysize(kAppWhitelist)))) {
    127           SetContentSettingForExtensionAndResource(
    128               host->extension(),
    129               ChromeContentClient::kRemotingViewerPluginPath,
    130               CONTENT_SETTING_ALLOW);
    131         }
    132       }
    133 
    134       break;
    135     }
    136     case chrome::NOTIFICATION_EXTENSION_LOADED_DEPRECATED: {
    137       const extensions::Extension* extension =
    138           content::Details<extensions::Extension>(details).ptr();
    139       if (extensions::PluginInfo::HasPlugins(extension))
    140         SetContentSettingForExtension(extension, CONTENT_SETTING_ALLOW);
    141       break;
    142     }
    143     case chrome::NOTIFICATION_EXTENSION_UNLOADED_DEPRECATED: {
    144       const UnloadedExtensionInfo& info =
    145           *(content::Details<UnloadedExtensionInfo>(details).ptr());
    146       if (extensions::PluginInfo::HasPlugins(info.extension))
    147         SetContentSettingForExtension(info.extension, CONTENT_SETTING_DEFAULT);
    148       break;
    149     }
    150     default:
    151       NOTREACHED();
    152   }
    153 }
    154 
    155 void InternalExtensionProvider::ShutdownOnUIThread() {
    156   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
    157   RemoveAllObservers();
    158   registrar_.reset();
    159 }
    160 
    161 void InternalExtensionProvider::SetContentSettingForExtension(
    162     const extensions::Extension* extension,
    163     ContentSetting setting) {
    164   SetContentSettingForExtensionAndResource(
    165       extension, ResourceIdentifier(), setting);
    166 }
    167 
    168 void InternalExtensionProvider::SetContentSettingForExtensionAndResource(
    169     const extensions::Extension* extension,
    170     const ResourceIdentifier& resource,
    171     ContentSetting setting) {
    172   scoped_ptr<ContentSettingsPattern::BuilderInterface> pattern_builder(
    173       ContentSettingsPattern::CreateBuilder(false));
    174   pattern_builder->WithScheme(extensions::kExtensionScheme);
    175   pattern_builder->WithHost(extension->id());
    176   pattern_builder->WithPathWildcard();
    177 
    178   ContentSettingsPattern primary_pattern = pattern_builder->Build();
    179   ContentSettingsPattern secondary_pattern = ContentSettingsPattern::Wildcard();
    180   {
    181     base::AutoLock lock(lock_);
    182     if (setting == CONTENT_SETTING_DEFAULT) {
    183       value_map_.DeleteValue(primary_pattern,
    184                              secondary_pattern,
    185                              CONTENT_SETTINGS_TYPE_PLUGINS,
    186                              resource);
    187     } else {
    188       value_map_.SetValue(primary_pattern,
    189                           secondary_pattern,
    190                           CONTENT_SETTINGS_TYPE_PLUGINS,
    191                           resource,
    192                           base::Value::CreateIntegerValue(setting));
    193     }
    194   }
    195   NotifyObservers(primary_pattern,
    196                   secondary_pattern,
    197                   CONTENT_SETTINGS_TYPE_PLUGINS,
    198                   resource);
    199 }
    200 
    201 }  // namespace content_settings
    202