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/manifest_handlers/permissions_parser.h" 15#include "extensions/common/permissions/api_permission.h" 16#include "extensions/common/permissions/api_permission_set.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 24namespace extensions { 25 26namespace keys = manifest_keys; 27 28namespace { 29 30struct PluginManifestData : Extension::ManifestData { 31 // Optional list of NPAPI plugins and associated properties for an extension. 32 PluginInfo::PluginVector plugins; 33}; 34 35} // namespace 36 37PluginInfo::PluginInfo(const base::FilePath& plugin_path, bool plugin_is_public) 38 : path(plugin_path), is_public(plugin_is_public) { 39} 40 41PluginInfo::~PluginInfo() { 42} 43 44// static 45const 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 53bool 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 59PluginsHandler::PluginsHandler() { 60} 61 62PluginsHandler::~PluginsHandler() { 63} 64 65const std::vector<std::string> PluginsHandler::Keys() const { 66 return SingleKey(keys::kPlugins); 67} 68 69bool 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 = base::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 = base::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 PermissionsParser::AddAPIPermission(extension, APIPermission::kPlugin); 122 } 123 124 return true; 125} 126 127bool PluginsHandler::Validate(const Extension* extension, 128 std::string* error, 129 std::vector<InstallWarning>* warnings) const { 130 // Validate claimed plugin paths. 131 if (extensions::PluginInfo::HasPlugins(extension)) { 132 const extensions::PluginInfo::PluginVector* plugins = 133 extensions::PluginInfo::GetPlugins(extension); 134 CHECK(plugins); 135 for (std::vector<extensions::PluginInfo>::const_iterator plugin = 136 plugins->begin(); 137 plugin != plugins->end(); ++plugin) { 138 if (!base::PathExists(plugin->path)) { 139 *error = l10n_util::GetStringFUTF8( 140 IDS_EXTENSION_LOAD_PLUGIN_PATH_FAILED, 141 plugin->path.LossyDisplayName()); 142 return false; 143 } 144 } 145 } 146 return true; 147} 148 149} // namespace extensions 150