| OLD | NEW | 
|---|
| (Empty) |  | 
|  | 1 // Copyright (c) 2010 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/plugin_group.h" | 
|  | 6 | 
|  | 7 #include "base/string_util.h" | 
|  | 8 #include "base/utf_string_conversions.h" | 
|  | 9 #include "base/values.h" | 
|  | 10 #include "base/version.h" | 
|  | 11 #include "webkit/glue/plugins/plugin_list.h" | 
|  | 12 | 
|  | 13 #if defined(OS_MACOSX) | 
|  | 14 // Plugin Groups for Mac. | 
|  | 15 // Plugins are listed here as soon as vulnerabilities and solutions | 
|  | 16 // (new versions) are published. | 
|  | 17 // TODO(panayiotis): Track Java as soon as it's supported on Chrome Mac. | 
|  | 18 // TODO(panayiotis): Get the Real Player version on Mac, somehow. | 
|  | 19 static const PluginGroupDefinition kGroupDefinitions[] = { | 
|  | 20   { "Quicktime", "QuickTime Plug-in", "", "", "7.6.6", | 
|  | 21     "http://www.apple.com/quicktime/download/" }, | 
|  | 22   { "Flash", "Shockwave Flash", "", "", "10.1.53", | 
|  | 23     "http://get.adobe.com/flashplayer/" }, | 
|  | 24   { "Silverlight 3", "Silverlight", "0", "4", "3.0.50106.0", | 
|  | 25     "http://go.microsoft.com/fwlink/?LinkID=185927" }, | 
|  | 26   { "Silverlight 4", "Silverlight", "4", "5", "", | 
|  | 27     "http://go.microsoft.com/fwlink/?LinkID=185927" }, | 
|  | 28   { "Flip4Mac", "Flip4Mac", "",  "", "2.2.1", | 
|  | 29     "http://www.telestream.net/flip4mac-wmv/overview.htm" }, | 
|  | 30   { "Shockwave", "Shockwave for Director", "",  "", "11.5.7.609", | 
|  | 31     "http://www.adobe.com/shockwave/download/" } | 
|  | 32 }; | 
|  | 33 | 
|  | 34 #elif defined(OS_WIN) | 
|  | 35 // TODO(panayiotis): We should group "RealJukebox NS Plugin" with the rest of | 
|  | 36 // the RealPlayer files. | 
|  | 37 static const PluginGroupDefinition kGroupDefinitions[] = { | 
|  | 38   { "Quicktime", "QuickTime Plug-in", "", "", "7.6.6", | 
|  | 39     "http://www.apple.com/quicktime/download/" }, | 
|  | 40   { "Java 6", "Java", "", "6", "6.0.200", | 
|  | 41     "http://www.java.com/" }, | 
|  | 42   { "Adobe Reader 9", "Adobe Acrobat", "9", "10", "9.3.3", | 
|  | 43     "http://get.adobe.com/reader/" }, | 
|  | 44   { "Adobe Reader 8", "Adobe Acrobat", "0", "9",  "8.2.3", | 
|  | 45     "http://get.adobe.com/reader/" }, | 
|  | 46   { "Flash", "Shockwave Flash", "", "", "10.1.53", | 
|  | 47     "http://get.adobe.com/flashplayer/" }, | 
|  | 48   { "Silverlight 3", "Silverlight", "0", "4", "3.0.50106.0", | 
|  | 49     "http://go.microsoft.com/fwlink/?LinkID=185927" }, | 
|  | 50   { "Silverlight 4", "Silverlight", "4", "5", "", | 
|  | 51     "http://go.microsoft.com/fwlink/?LinkID=185927" }, | 
|  | 52   { "Shockwave", "Shockwave for Director", "", "", "11.5.7.609", | 
|  | 53     "http://www.adobe.com/shockwave/download/" }, | 
|  | 54   { "DivX Player", "DivX Web Player", "",  "", "1.4.3.4", | 
|  | 55     "http://download.divx.com/divx/autoupdate/player/DivXWebPlayerInstaller.exe"
      }, | 
|  | 56   // These are here for grouping, no vulnerabilies known. | 
|  | 57   { "Windows Media Player",  "Windows Media Player",  "",  "",   "", "" }, | 
|  | 58   { "Microsoft Office",  "Microsoft Office",  "",  "",   "", "" }, | 
|  | 59   // TODO(panayiotis): The vulnerable versions are | 
|  | 60   //  (v >=  6.0.12.1040 && v <= 6.0.12.1663) | 
|  | 61   //  || v == 6.0.12.1698  || v == 6.0.12.1741 | 
|  | 62   { "RealPlayer", "RealPlayer", "",  "",  "", | 
|  | 63     "http://www.adobe.com/shockwave/download/" }, | 
|  | 64 }; | 
|  | 65 | 
|  | 66 #else | 
|  | 67 static const PluginGroupDefinition kGroupDefinitions[] = {}; | 
|  | 68 #endif | 
|  | 69 | 
|  | 70 /*static*/ | 
|  | 71 const PluginGroupDefinition* PluginGroup::GetPluginGroupDefinitions() { | 
|  | 72   return kGroupDefinitions; | 
|  | 73 } | 
|  | 74 | 
|  | 75 /*static*/ | 
|  | 76 size_t PluginGroup::GetPluginGroupDefinitionsSize() { | 
|  | 77   // TODO(viettrungluu): |arraysize()| doesn't work with zero-size arrays. | 
|  | 78   return ARRAYSIZE_UNSAFE(kGroupDefinitions); | 
|  | 79 } | 
|  | 80 | 
|  | 81 PluginGroup::PluginGroup(const string16& group_name, | 
|  | 82                          const string16& name_matcher, | 
|  | 83                          const std::string& version_range_low, | 
|  | 84                          const std::string& version_range_high, | 
|  | 85                          const std::string& min_version, | 
|  | 86                          const std::string& update_url) { | 
|  | 87   group_name_ = group_name; | 
|  | 88   name_matcher_ = name_matcher; | 
|  | 89   version_range_low_str_ = version_range_low; | 
|  | 90   if (!version_range_low.empty()) { | 
|  | 91     version_range_low_.reset( | 
|  | 92         Version::GetVersionFromString(version_range_low)); | 
|  | 93   } | 
|  | 94   version_range_high_str_ = version_range_high; | 
|  | 95   if (!version_range_high.empty()) { | 
|  | 96     version_range_high_.reset( | 
|  | 97         Version::GetVersionFromString(version_range_high)); | 
|  | 98   } | 
|  | 99   min_version_str_ = min_version; | 
|  | 100   if (!min_version.empty()) { | 
|  | 101     min_version_.reset(Version::GetVersionFromString(min_version)); | 
|  | 102   } | 
|  | 103   update_url_ = update_url; | 
|  | 104   enabled_ = false; | 
|  | 105   max_version_.reset(Version::GetVersionFromString("0")); | 
|  | 106 } | 
|  | 107 | 
|  | 108 PluginGroup* PluginGroup::FromPluginGroupDefinition( | 
|  | 109     const PluginGroupDefinition& definition) { | 
|  | 110   return new PluginGroup(ASCIIToUTF16(definition.name), | 
|  | 111                          ASCIIToUTF16(definition.name_matcher), | 
|  | 112                          definition.version_matcher_low, | 
|  | 113                          definition.version_matcher_high, | 
|  | 114                          definition.min_version, | 
|  | 115                          definition.update_url); | 
|  | 116 } | 
|  | 117 | 
|  | 118 PluginGroup* PluginGroup::FromWebPluginInfo(const WebPluginInfo& wpi) { | 
|  | 119   // Create a matcher from the name of this plugin. | 
|  | 120   return new PluginGroup(wpi.name, wpi.name, | 
|  | 121                          "", "", "", ""); | 
|  | 122 } | 
|  | 123 | 
|  | 124 PluginGroup* PluginGroup::FindHardcodedPluginGroup(const WebPluginInfo& info) { | 
|  | 125   static std::vector<linked_ptr<PluginGroup> >* hardcoded_plugin_groups = NULL; | 
|  | 126   if (!hardcoded_plugin_groups) { | 
|  | 127     std::vector<linked_ptr<PluginGroup> >* groups = | 
|  | 128         new std::vector<linked_ptr<PluginGroup> >(); | 
|  | 129     const PluginGroupDefinition* definitions = GetPluginGroupDefinitions(); | 
|  | 130     for (size_t i = 0; i < GetPluginGroupDefinitionsSize(); ++i) { | 
|  | 131       PluginGroup* definition_group = PluginGroup::FromPluginGroupDefinition( | 
|  | 132           definitions[i]); | 
|  | 133       groups->push_back(linked_ptr<PluginGroup>(definition_group)); | 
|  | 134     } | 
|  | 135     hardcoded_plugin_groups = groups; | 
|  | 136   } | 
|  | 137 | 
|  | 138   // See if this plugin matches any of the hardcoded groups. | 
|  | 139   PluginGroup* hardcoded_group = FindGroupMatchingPlugin( | 
|  | 140       *hardcoded_plugin_groups, info); | 
|  | 141   if (hardcoded_group) { | 
|  | 142     // Make a copy. | 
|  | 143     return hardcoded_group->Copy(); | 
|  | 144   } else { | 
|  | 145     // Not found in our hardcoded list, create a new one. | 
|  | 146     return PluginGroup::FromWebPluginInfo(info); | 
|  | 147   } | 
|  | 148 } | 
|  | 149 | 
|  | 150 PluginGroup* PluginGroup::FindGroupMatchingPlugin( | 
|  | 151     std::vector<linked_ptr<PluginGroup> >& plugin_groups, | 
|  | 152     const WebPluginInfo& plugin) { | 
|  | 153   for (std::vector<linked_ptr<PluginGroup> >::iterator it = | 
|  | 154        plugin_groups.begin(); | 
|  | 155        it != plugin_groups.end(); | 
|  | 156        ++it) { | 
|  | 157     if ((*it)->Match(plugin)) { | 
|  | 158       return it->get(); | 
|  | 159     } | 
|  | 160   } | 
|  | 161   return NULL; | 
|  | 162 } | 
|  | 163 | 
|  | 164 bool PluginGroup::Match(const WebPluginInfo& plugin) const { | 
|  | 165   if (name_matcher_.empty()) { | 
|  | 166     return false; | 
|  | 167   } | 
|  | 168 | 
|  | 169   // Look for the name matcher anywhere in the plugin name. | 
|  | 170   if (plugin.name.find(name_matcher_) == string16::npos) { | 
|  | 171     return false; | 
|  | 172   } | 
|  | 173 | 
|  | 174   if (version_range_low_.get() == NULL || | 
|  | 175       version_range_high_.get() == NULL) { | 
|  | 176     return true; | 
|  | 177   } | 
|  | 178 | 
|  | 179   // There's a version range, we must be in it. | 
|  | 180   scoped_ptr<Version> plugin_version( | 
|  | 181       Version::GetVersionFromString(UTF16ToWide(plugin.version))); | 
|  | 182   if (plugin_version.get() == NULL) { | 
|  | 183     // No version could be extracted, assume we don't match the range. | 
|  | 184     return false; | 
|  | 185   } | 
|  | 186 | 
|  | 187   // We match if we are in the range: [low, high) | 
|  | 188   return (version_range_low_->CompareTo(*plugin_version) <= 0 && | 
|  | 189           version_range_high_->CompareTo(*plugin_version) > 0); | 
|  | 190 } | 
|  | 191 | 
|  | 192 void PluginGroup::AddPlugin(const WebPluginInfo& plugin, int position) { | 
|  | 193   web_plugin_infos_.push_back(plugin); | 
|  | 194   // The position of this plugin relative to the global list of plugins. | 
|  | 195   web_plugin_positions_.push_back(position); | 
|  | 196   description_ = plugin.desc; | 
|  | 197 | 
|  | 198   // A group is enabled if any of the files are enabled. | 
|  | 199   if (plugin.enabled) { | 
|  | 200     enabled_ = true; | 
|  | 201   } | 
|  | 202 | 
|  | 203   // update max_version_. Remove spaces and ')' from the version string, | 
|  | 204   // Replace any instances of 'r', ',' or '(' with a dot. | 
|  | 205   std::wstring version = UTF16ToWide(plugin.version); | 
|  | 206   RemoveChars(version, L") ", &version); | 
|  | 207   std::replace(version.begin(), version.end(), 'r', '.'); | 
|  | 208   std::replace(version.begin(), version.end(), ',', '.'); | 
|  | 209   std::replace(version.begin(), version.end(), '(', '.'); | 
|  | 210 | 
|  | 211   scoped_ptr<Version> plugin_version( | 
|  | 212       Version::GetVersionFromString(version)); | 
|  | 213   if (plugin_version.get() != NULL) { | 
|  | 214     if (plugin_version->CompareTo(*(max_version_)) > 0) { | 
|  | 215       max_version_.reset(plugin_version.release()); | 
|  | 216     } | 
|  | 217   } | 
|  | 218 } | 
|  | 219 | 
|  | 220 DictionaryValue* PluginGroup::GetSummary() const { | 
|  | 221   DictionaryValue* result = new DictionaryValue(); | 
|  | 222   result->SetStringFromUTF16(L"name", group_name_); | 
|  | 223   result->SetBoolean(L"enabled", enabled_); | 
|  | 224   return result; | 
|  | 225 } | 
|  | 226 | 
|  | 227 DictionaryValue* PluginGroup::GetDataForUI() const { | 
|  | 228   DictionaryValue* result = new DictionaryValue(); | 
|  | 229   result->SetStringFromUTF16(L"name", group_name_); | 
|  | 230   result->SetStringFromUTF16(L"description", description_); | 
|  | 231   result->SetString(L"version", max_version_->GetString()); | 
|  | 232   result->SetString(L"update_url", update_url_); | 
|  | 233   result->SetBoolean(L"critical", IsVulnerable()); | 
|  | 234   result->SetBoolean(L"enabled", enabled_); | 
|  | 235 | 
|  | 236   ListValue* plugin_files = new ListValue(); | 
|  | 237   for (size_t i = 0; i < web_plugin_infos_.size(); ++i) { | 
|  | 238     const WebPluginInfo& web_plugin = web_plugin_infos_[i]; | 
|  | 239     int priority = web_plugin_positions_[i]; | 
|  | 240     DictionaryValue* plugin_file = new DictionaryValue(); | 
|  | 241     plugin_file->SetStringFromUTF16(L"name", web_plugin.name); | 
|  | 242     plugin_file->SetStringFromUTF16(L"description", web_plugin.desc); | 
|  | 243     plugin_file->SetString(L"path", web_plugin.path.value()); | 
|  | 244     plugin_file->SetStringFromUTF16(L"version", web_plugin.version); | 
|  | 245     plugin_file->SetBoolean(L"enabled", web_plugin.enabled); | 
|  | 246     plugin_file->SetInteger(L"priority", priority); | 
|  | 247 | 
|  | 248     ListValue* mime_types = new ListValue(); | 
|  | 249     for (std::vector<WebPluginMimeType>::const_iterator type_it = | 
|  | 250          web_plugin.mime_types.begin(); | 
|  | 251          type_it != web_plugin.mime_types.end(); | 
|  | 252          ++type_it) { | 
|  | 253       DictionaryValue* mime_type = new DictionaryValue(); | 
|  | 254       mime_type->SetString(L"mimeType", type_it->mime_type); | 
|  | 255       mime_type->SetStringFromUTF16(L"description", type_it->description); | 
|  | 256 | 
|  | 257       ListValue* file_extensions = new ListValue(); | 
|  | 258       for (std::vector<std::string>::const_iterator ext_it = | 
|  | 259            type_it->file_extensions.begin(); | 
|  | 260            ext_it != type_it->file_extensions.end(); | 
|  | 261            ++ext_it) { | 
|  | 262         file_extensions->Append(new StringValue(*ext_it)); | 
|  | 263       } | 
|  | 264       mime_type->Set(L"fileExtensions", file_extensions); | 
|  | 265 | 
|  | 266       mime_types->Append(mime_type); | 
|  | 267     } | 
|  | 268     plugin_file->Set(L"mimeTypes", mime_types); | 
|  | 269 | 
|  | 270     plugin_files->Append(plugin_file); | 
|  | 271   } | 
|  | 272   result->Set(L"plugin_files", plugin_files); | 
|  | 273 | 
|  | 274   return result; | 
|  | 275 } | 
|  | 276 | 
|  | 277 // Returns true if the latest version of this plugin group is vulnerable. | 
|  | 278 bool PluginGroup::IsVulnerable() const { | 
|  | 279   if (min_version_.get() == NULL || max_version_->GetString() == "0") { | 
|  | 280     return false; | 
|  | 281   } | 
|  | 282   return max_version_->CompareTo(*min_version_) < 0; | 
|  | 283 } | 
|  | 284 | 
|  | 285 void PluginGroup::Enable(bool enable) { | 
|  | 286   for (std::vector<WebPluginInfo>::const_iterator it = | 
|  | 287        web_plugin_infos_.begin(); | 
|  | 288        it != web_plugin_infos_.end(); ++it) { | 
|  | 289     if (enable) { | 
|  | 290       NPAPI::PluginList::Singleton()->EnablePlugin(FilePath(it->path)); | 
|  | 291     } else { | 
|  | 292       NPAPI::PluginList::Singleton()->DisablePlugin(FilePath(it->path)); | 
|  | 293     } | 
|  | 294   } | 
|  | 295 } | 
| OLD | NEW | 
|---|