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/common/extensions/api/plugins/plugins_handler.h" 6 7 #include "base/file_util.h" 8 #include "base/strings/string_number_conversions.h" 9 #include "base/strings/utf_string_conversions.h" 10 #include "base/values.h" 11 #include "extensions/common/error_utils.h" 12 #include "extensions/common/manifest.h" 13 #include "extensions/common/manifest_constants.h" 14 #include "extensions/common/permissions/api_permission.h" 15 #include "extensions/common/permissions/api_permission_set.h" 16 #include "extensions/common/permissions/permissions_data.h" 17 #include "grit/generated_resources.h" 18 #include "ui/base/l10n/l10n_util.h" 19 20 #if defined(OS_WIN) 21 #include "base/win/metro.h" 22 #endif 23 24 namespace extensions { 25 26 namespace keys = manifest_keys; 27 28 namespace { 29 30 struct PluginManifestData : Extension::ManifestData { 31 // Optional list of NPAPI plugins and associated properties for an extension. 32 PluginInfo::PluginVector plugins; 33 }; 34 35 } // namespace 36 37 PluginInfo::PluginInfo(const base::FilePath& plugin_path, bool plugin_is_public) 38 : path(plugin_path), is_public(plugin_is_public) { 39 } 40 41 PluginInfo::~PluginInfo() { 42 } 43 44 // static 45 const PluginInfo::PluginVector* PluginInfo::GetPlugins( 46 const Extension* extension) { 47 PluginManifestData* data = static_cast<PluginManifestData*>( 48 extension->GetManifestData(keys::kPlugins)); 49 return data ? &data->plugins : NULL; 50 } 51 52 // static 53 bool PluginInfo::HasPlugins(const Extension* extension) { 54 PluginManifestData* data = static_cast<PluginManifestData*>( 55 extension->GetManifestData(keys::kPlugins)); 56 return data && !data->plugins.empty() ? true : false; 57 } 58 59 PluginsHandler::PluginsHandler() { 60 } 61 62 PluginsHandler::~PluginsHandler() { 63 } 64 65 const std::vector<std::string> PluginsHandler::Keys() const { 66 return SingleKey(keys::kPlugins); 67 } 68 69 bool PluginsHandler::Parse(Extension* extension, base::string16* error) { 70 const base::ListValue* list_value = NULL; 71 if (!extension->manifest()->GetList(keys::kPlugins, &list_value)) { 72 *error = ASCIIToUTF16(manifest_errors::kInvalidPlugins); 73 return false; 74 } 75 76 scoped_ptr<PluginManifestData> plugins_data(new PluginManifestData); 77 78 for (size_t i = 0; i < list_value->GetSize(); ++i) { 79 const base::DictionaryValue* plugin_value = NULL; 80 if (!list_value->GetDictionary(i, &plugin_value)) { 81 *error = ASCIIToUTF16(manifest_errors::kInvalidPlugins); 82 return false; 83 } 84 // Get plugins[i].path. 85 std::string path_str; 86 if (!plugin_value->GetString(keys::kPluginsPath, &path_str)) { 87 *error = ErrorUtils::FormatErrorMessageUTF16( 88 manifest_errors::kInvalidPluginsPath, base::IntToString(i)); 89 return false; 90 } 91 92 // Get plugins[i].content (optional). 93 bool is_public = false; 94 if (plugin_value->HasKey(keys::kPluginsPublic)) { 95 if (!plugin_value->GetBoolean(keys::kPluginsPublic, &is_public)) { 96 *error = ErrorUtils::FormatErrorMessageUTF16( 97 manifest_errors::kInvalidPluginsPublic, 98 base::IntToString(i)); 99 return false; 100 } 101 } 102 103 // We don't allow extensions to load NPAPI plugins on Chrome OS, or under 104 // Windows 8 Metro mode, but still parse the entries to display consistent 105 // error messages. If the extension actually requires the plugins then 106 // LoadRequirements will prevent it loading. 107 #if defined(OS_CHROMEOS) 108 continue; 109 #elif defined(OS_WIN) 110 if (base::win::IsMetroProcess()) { 111 continue; 112 } 113 #endif // defined(OS_WIN). 114 plugins_data->plugins.push_back(PluginInfo( 115 extension->path().Append(base::FilePath::FromUTF8Unsafe(path_str)), 116 is_public)); 117 } 118 119 if (!plugins_data->plugins.empty()) { 120 extension->SetManifestData(keys::kPlugins, plugins_data.release()); 121 PermissionsData::GetInitialAPIPermissions(extension)->insert( 122 APIPermission::kPlugin); 123 } 124 125 return true; 126 } 127 128 bool PluginsHandler::Validate(const Extension* extension, 129 std::string* error, 130 std::vector<InstallWarning>* warnings) const { 131 // Validate claimed plugin paths. 132 if (extensions::PluginInfo::HasPlugins(extension)) { 133 const extensions::PluginInfo::PluginVector* plugins = 134 extensions::PluginInfo::GetPlugins(extension); 135 CHECK(plugins); 136 for (std::vector<extensions::PluginInfo>::const_iterator plugin = 137 plugins->begin(); 138 plugin != plugins->end(); ++plugin) { 139 if (!base::PathExists(plugin->path)) { 140 *error = l10n_util::GetStringFUTF8( 141 IDS_EXTENSION_LOAD_PLUGIN_PATH_FAILED, 142 plugin->path.LossyDisplayName()); 143 return false; 144 } 145 } 146 } 147 return true; 148 } 149 150 } // namespace extensions 151