| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include <algorithm> | 5 #include <algorithm> |
| 6 | 6 |
| 7 #include "webkit/plugins/npapi/plugin_group.h" | 7 #include "webkit/plugins/npapi/plugin_group.h" |
| 8 | 8 |
| 9 #include "base/memory/linked_ptr.h" | 9 #include "base/memory/linked_ptr.h" |
| 10 #include "base/string_util.h" | 10 #include "base/string_util.h" |
| 11 #include "base/sys_string_conversions.h" | 11 #include "base/sys_string_conversions.h" |
| 12 #include "base/utf_string_conversions.h" | 12 #include "base/utf_string_conversions.h" |
| 13 #include "base/values.h" | 13 #include "base/values.h" |
| 14 #include "base/version.h" | 14 #include "base/version.h" |
| 15 #include "webkit/plugins/npapi/plugin_list.h" | 15 #include "webkit/plugins/npapi/plugin_list.h" |
| 16 #include "webkit/plugins/webplugininfo.h" | 16 #include "webkit/plugins/webplugininfo.h" |
| 17 | 17 |
| 18 namespace webkit { | 18 namespace webkit { |
| 19 namespace npapi { | 19 namespace npapi { |
| 20 | 20 |
| 21 const char* PluginGroup::kAdobeReaderGroupName = "Adobe Acrobat"; | 21 const char* PluginGroup::kAdobeReaderGroupName = "Adobe Acrobat"; |
| 22 const char* PluginGroup::kAdobeReaderUpdateURL = "http://get.adobe.com/reader/"; | 22 const char* PluginGroup::kAdobeReaderUpdateURL = "http://get.adobe.com/reader/"; |
| 23 const char* PluginGroup::kJavaGroupName = "Java"; | 23 const char* PluginGroup::kJavaGroupName = "Java"; |
| 24 const char* PluginGroup::kQuickTimeGroupName = "QuickTime"; | 24 const char* PluginGroup::kQuickTimeGroupName = "QuickTime"; |
| 25 const char* PluginGroup::kShockwaveGroupName = "Shockwave"; | 25 const char* PluginGroup::kShockwaveGroupName = "Shockwave"; |
| 26 const char* PluginGroup::kRealPlayerGroupName = "RealPlayer"; | 26 const char* PluginGroup::kRealPlayerGroupName = "RealPlayer"; |
| 27 const char* PluginGroup::kSilverlightGroupName = "Silverlight"; | 27 const char* PluginGroup::kSilverlightGroupName = "Silverlight"; |
| 28 const char* PluginGroup::kWindowsMediaPlayerGroupName = "Windows Media Player"; | 28 const char* PluginGroup::kWindowsMediaPlayerGroupName = "Windows Media Player"; |
| 29 | 29 |
| 30 /*static*/ | |
| 31 std::set<string16>* PluginGroup::policy_disabled_plugin_patterns_; | |
| 32 /*static*/ | |
| 33 std::set<string16>* PluginGroup::policy_disabled_plugin_exception_patterns_; | |
| 34 /*static*/ | |
| 35 std::set<string16>* PluginGroup::policy_enabled_plugin_patterns_; | |
| 36 | |
| 37 /*static*/ | |
| 38 void PluginGroup::SetPolicyEnforcedPluginPatterns( | |
| 39 const std::set<string16>& plugins_disabled, | |
| 40 const std::set<string16>& plugins_disabled_exceptions, | |
| 41 const std::set<string16>& plugins_enabled) { | |
| 42 if (!policy_disabled_plugin_patterns_) | |
| 43 policy_disabled_plugin_patterns_ = new std::set<string16>(plugins_disabled); | |
| 44 else | |
| 45 *policy_disabled_plugin_patterns_ = plugins_disabled; | |
| 46 | |
| 47 if (!policy_disabled_plugin_exception_patterns_) | |
| 48 policy_disabled_plugin_exception_patterns_ = | |
| 49 new std::set<string16>(plugins_disabled_exceptions); | |
| 50 else | |
| 51 *policy_disabled_plugin_exception_patterns_ = plugins_disabled_exceptions; | |
| 52 | |
| 53 if (!policy_enabled_plugin_patterns_) | |
| 54 policy_enabled_plugin_patterns_ = new std::set<string16>(plugins_enabled); | |
| 55 else | |
| 56 *policy_enabled_plugin_patterns_ = plugins_enabled; | |
| 57 } | |
| 58 | |
| 59 /*static*/ | |
| 60 bool PluginGroup::IsStringMatchedInSet(const string16& name, | |
| 61 const std::set<string16>* pattern_set) { | |
| 62 if (!pattern_set) | |
| 63 return false; | |
| 64 | |
| 65 std::set<string16>::const_iterator pattern(pattern_set->begin()); | |
| 66 while (pattern != pattern_set->end()) { | |
| 67 if (MatchPattern(name, *pattern)) | |
| 68 return true; | |
| 69 ++pattern; | |
| 70 } | |
| 71 | |
| 72 return false; | |
| 73 } | |
| 74 | |
| 75 /*static*/ | |
| 76 bool PluginGroup::IsPluginNameDisabledByPolicy(const string16& plugin_name) { | |
| 77 // A plugin that matches some "disabled" pattern but also matches an "enabled" | |
| 78 // pattern will be enabled. Example: disable "*", enable "Flash, Java". | |
| 79 // Same for matching an "exception" pattern. | |
| 80 return IsStringMatchedInSet(plugin_name, policy_disabled_plugin_patterns_) && | |
| 81 !IsStringMatchedInSet(plugin_name, policy_enabled_plugin_patterns_) && | |
| 82 !IsStringMatchedInSet(plugin_name, | |
| 83 policy_disabled_plugin_exception_patterns_); | |
| 84 } | |
| 85 | |
| 86 /*static*/ | |
| 87 bool PluginGroup::IsPluginFileNameDisabledByPolicy(const string16& plugin_name, | |
| 88 const string16& group_name) { | |
| 89 // This handles a specific plugin within a group that is allowed, | |
| 90 // but whose name matches a disabled pattern. | |
| 91 // Example: disable "*", exception "Java". | |
| 92 bool group_has_exception = IsStringMatchedInSet( | |
| 93 group_name, | |
| 94 policy_disabled_plugin_exception_patterns_); | |
| 95 | |
| 96 return !IsPluginNameEnabledByPolicy(plugin_name) && | |
| 97 !group_has_exception && | |
| 98 IsPluginNameDisabledByPolicy(plugin_name); | |
| 99 } | |
| 100 | |
| 101 /*static*/ | |
| 102 bool PluginGroup::IsPluginNameEnabledByPolicy(const string16& plugin_name) { | |
| 103 // There are no exceptions to enabled plugins. | |
| 104 return IsStringMatchedInSet(plugin_name, policy_enabled_plugin_patterns_); | |
| 105 } | |
| 106 | |
| 107 VersionRange::VersionRange(const VersionRangeDefinition& definition) | 30 VersionRange::VersionRange(const VersionRangeDefinition& definition) |
| 108 : low_str(definition.version_matcher_low), | 31 : low_str(definition.version_matcher_low), |
| 109 high_str(definition.version_matcher_high), | 32 high_str(definition.version_matcher_high), |
| 110 min_str(definition.min_version), | 33 min_str(definition.min_version), |
| 111 requires_authorization(definition.requires_authorization) { | 34 requires_authorization(definition.requires_authorization) { |
| 112 if (!low_str.empty()) | 35 if (!low_str.empty()) |
| 113 low.reset(Version::GetVersionFromString(low_str)); | 36 low.reset(Version::GetVersionFromString(low_str)); |
| 114 if (!high_str.empty()) | 37 if (!high_str.empty()) |
| 115 high.reset(Version::GetVersionFromString(high_str)); | 38 high.reset(Version::GetVersionFromString(high_str)); |
| 116 if (!min_str.empty()) | 39 if (!min_str.empty()) |
| (...skipping 21 matching lines...) Expand all Loading... |
| 138 requires_authorization = other.requires_authorization; | 61 requires_authorization = other.requires_authorization; |
| 139 } | 62 } |
| 140 | 63 |
| 141 PluginGroup::PluginGroup(const string16& group_name, | 64 PluginGroup::PluginGroup(const string16& group_name, |
| 142 const string16& name_matcher, | 65 const string16& name_matcher, |
| 143 const std::string& update_url, | 66 const std::string& update_url, |
| 144 const std::string& identifier) | 67 const std::string& identifier) |
| 145 : identifier_(identifier), | 68 : identifier_(identifier), |
| 146 group_name_(group_name), | 69 group_name_(group_name), |
| 147 name_matcher_(name_matcher), | 70 name_matcher_(name_matcher), |
| 148 update_url_(update_url), | 71 update_url_(update_url) { |
| 149 enabled_(false), | |
| 150 version_(Version::GetVersionFromString("0")) { | |
| 151 } | 72 } |
| 152 | 73 |
| 153 void PluginGroup::InitFrom(const PluginGroup& other) { | 74 void PluginGroup::InitFrom(const PluginGroup& other) { |
| 154 identifier_ = other.identifier_; | 75 identifier_ = other.identifier_; |
| 155 group_name_ = other.group_name_; | 76 group_name_ = other.group_name_; |
| 156 name_matcher_ = other.name_matcher_; | 77 name_matcher_ = other.name_matcher_; |
| 157 description_ = other.description_; | |
| 158 update_url_ = other.update_url_; | 78 update_url_ = other.update_url_; |
| 159 enabled_ = other.enabled_; | |
| 160 version_ranges_ = other.version_ranges_; | 79 version_ranges_ = other.version_ranges_; |
| 161 version_.reset(other.version_->Clone()); | |
| 162 web_plugin_infos_ = other.web_plugin_infos_; | 80 web_plugin_infos_ = other.web_plugin_infos_; |
| 163 } | 81 } |
| 164 | 82 |
| 165 PluginGroup::PluginGroup(const PluginGroup& other) { | 83 PluginGroup::PluginGroup(const PluginGroup& other) { |
| 166 InitFrom(other); | 84 InitFrom(other); |
| 167 } | 85 } |
| 168 | 86 |
| 169 PluginGroup& PluginGroup::operator=(const PluginGroup& other) { | 87 PluginGroup& PluginGroup::operator=(const PluginGroup& other) { |
| 170 InitFrom(other); | 88 InitFrom(other); |
| 171 return *this; | 89 return *this; |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 249 RemoveChars(version, ") ", &version); | 167 RemoveChars(version, ") ", &version); |
| 250 std::replace(version.begin(), version.end(), 'd', '.'); | 168 std::replace(version.begin(), version.end(), 'd', '.'); |
| 251 std::replace(version.begin(), version.end(), 'r', '.'); | 169 std::replace(version.begin(), version.end(), 'r', '.'); |
| 252 std::replace(version.begin(), version.end(), ',', '.'); | 170 std::replace(version.begin(), version.end(), ',', '.'); |
| 253 std::replace(version.begin(), version.end(), '(', '.'); | 171 std::replace(version.begin(), version.end(), '(', '.'); |
| 254 std::replace(version.begin(), version.end(), '_', '.'); | 172 std::replace(version.begin(), version.end(), '_', '.'); |
| 255 | 173 |
| 256 return Version::GetVersionFromString(version); | 174 return Version::GetVersionFromString(version); |
| 257 } | 175 } |
| 258 | 176 |
| 259 void PluginGroup::UpdateActivePlugin(const WebPluginInfo& plugin) { | |
| 260 // A group is enabled if any of the files are enabled. | |
| 261 if (IsPluginEnabled(plugin)) { | |
| 262 // The description of the group needs update either when it's state is | |
| 263 // about to change to enabled or if has never been set. | |
| 264 if (!enabled_ || description_.empty()) | |
| 265 UpdateDescriptionAndVersion(plugin); | |
| 266 // In case an enabled plugin has been added to a group that is currently | |
| 267 // disabled then we should enable the group. | |
| 268 if (!enabled_) | |
| 269 enabled_ = true; | |
| 270 } else { | |
| 271 // If this is the first plugin and it's disabled, | |
| 272 // use its description for now. | |
| 273 if (description_.empty()) | |
| 274 UpdateDescriptionAndVersion(plugin); | |
| 275 } | |
| 276 } | |
| 277 | |
| 278 void PluginGroup::UpdateDescriptionAndVersion(const WebPluginInfo& plugin) { | |
| 279 description_ = plugin.desc; | |
| 280 if (Version* new_version = CreateVersionFromString(plugin.version)) | |
| 281 version_.reset(new_version); | |
| 282 else | |
| 283 version_.reset(Version::GetVersionFromString("0")); | |
| 284 } | |
| 285 | |
| 286 void PluginGroup::AddPlugin(const WebPluginInfo& plugin) { | 177 void PluginGroup::AddPlugin(const WebPluginInfo& plugin) { |
| 287 // Check if this group already contains this plugin. | 178 // Check if this group already contains this plugin. |
| 288 for (size_t i = 0; i < web_plugin_infos_.size(); ++i) { | 179 for (size_t i = 0; i < web_plugin_infos_.size(); ++i) { |
| 289 if (FilePath::CompareEqualIgnoreCase(web_plugin_infos_[i].path.value(), | 180 if (FilePath::CompareEqualIgnoreCase(web_plugin_infos_[i].path.value(), |
| 290 plugin.path.value())) { | 181 plugin.path.value())) { |
| 291 return; | 182 return; |
| 292 } | 183 } |
| 293 } | 184 } |
| 294 web_plugin_infos_.push_back(plugin); | 185 web_plugin_infos_.push_back(plugin); |
| 295 UpdateActivePlugin(web_plugin_infos_.back()); | |
| 296 } | 186 } |
| 297 | 187 |
| 298 bool PluginGroup::RemovePlugin(const FilePath& filename) { | 188 bool PluginGroup::RemovePlugin(const FilePath& filename) { |
| 299 bool did_remove = false; | 189 bool did_remove = false; |
| 300 ResetGroupState(); | |
| 301 for (size_t i = 0; i < web_plugin_infos_.size();) { | 190 for (size_t i = 0; i < web_plugin_infos_.size();) { |
| 302 if (web_plugin_infos_[i].path == filename) { | 191 if (web_plugin_infos_[i].path == filename) { |
| 303 web_plugin_infos_.erase(web_plugin_infos_.begin() + i); | 192 web_plugin_infos_.erase(web_plugin_infos_.begin() + i); |
| 304 did_remove = true; | 193 did_remove = true; |
| 305 } else { | 194 } else { |
| 306 UpdateActivePlugin(web_plugin_infos_[i]); | |
| 307 i++; | 195 i++; |
| 308 } | 196 } |
| 309 } | 197 } |
| 310 return did_remove; | 198 return did_remove; |
| 311 } | 199 } |
| 312 | 200 |
| 313 bool PluginGroup::EnablePlugin(const FilePath& filename) { | |
| 314 bool did_enable = false; | |
| 315 ResetGroupState(); | |
| 316 for (size_t i = 0; i < web_plugin_infos_.size(); ++i) { | |
| 317 if (web_plugin_infos_[i].path == filename) { | |
| 318 did_enable = Enable( | |
| 319 &web_plugin_infos_[i], | |
| 320 IsPluginNameEnabledByPolicy(web_plugin_infos_[i].name) ? | |
| 321 WebPluginInfo::USER_ENABLED_POLICY_ENABLED : | |
| 322 WebPluginInfo::USER_ENABLED); | |
| 323 } | |
| 324 UpdateActivePlugin(web_plugin_infos_[i]); | |
| 325 } | |
| 326 return did_enable; | |
| 327 } | |
| 328 | |
| 329 bool PluginGroup::DisablePlugin(const FilePath& filename) { | |
| 330 bool did_disable = false; | |
| 331 ResetGroupState(); | |
| 332 for (size_t i = 0; i < web_plugin_infos_.size(); ++i) { | |
| 333 if (web_plugin_infos_[i].path == filename) { | |
| 334 // We are only called for user intervention however we should respect a | |
| 335 // policy that might as well be active on this plugin. | |
| 336 did_disable = Disable( | |
| 337 &web_plugin_infos_[i], | |
| 338 IsPluginNameDisabledByPolicy(web_plugin_infos_[i].name) ? | |
| 339 WebPluginInfo::USER_DISABLED_POLICY_DISABLED : | |
| 340 WebPluginInfo::USER_DISABLED); | |
| 341 } | |
| 342 UpdateActivePlugin(web_plugin_infos_[i]); | |
| 343 } | |
| 344 return did_disable; | |
| 345 } | |
| 346 | |
| 347 string16 PluginGroup::GetGroupName() const { | 201 string16 PluginGroup::GetGroupName() const { |
| 348 if (!group_name_.empty()) | 202 if (!group_name_.empty()) |
| 349 return group_name_; | 203 return group_name_; |
| 350 DCHECK_EQ(1u, web_plugin_infos_.size()); | 204 DCHECK_EQ(1u, web_plugin_infos_.size()); |
| 351 FilePath::StringType path = | 205 FilePath::StringType path = |
| 352 web_plugin_infos_[0].path.BaseName().RemoveExtension().value(); | 206 web_plugin_infos_[0].path.BaseName().RemoveExtension().value(); |
| 353 #if defined(OS_POSIX) | 207 #if defined(OS_POSIX) |
| 354 return UTF8ToUTF16(path); | 208 return UTF8ToUTF16(path); |
| 355 #elif defined(OS_WIN) | 209 #elif defined(OS_WIN) |
| 356 return WideToUTF16(path); | 210 return WideToUTF16(path); |
| 357 #endif | 211 #endif |
| 358 } | 212 } |
| 359 | 213 |
| 360 bool PluginGroup::ContainsPlugin(const FilePath& path) const { | 214 bool PluginGroup::ContainsPlugin(const FilePath& path) const { |
| 361 for (size_t i = 0; i < web_plugin_infos_.size(); ++i) { | 215 for (size_t i = 0; i < web_plugin_infos_.size(); ++i) { |
| 362 if (web_plugin_infos_[i].path == path) | 216 if (web_plugin_infos_[i].path == path) |
| 363 return true; | 217 return true; |
| 364 } | 218 } |
| 365 return false; | 219 return false; |
| 366 } | 220 } |
| 367 | 221 |
| 368 | |
| 369 DictionaryValue* PluginGroup::GetSummary() const { | |
| 370 DictionaryValue* result = new DictionaryValue(); | |
| 371 result->SetString("name", GetGroupName()); | |
| 372 result->SetBoolean("enabled", enabled_); | |
| 373 return result; | |
| 374 } | |
| 375 | |
| 376 DictionaryValue* PluginGroup::GetDataForUI() const { | |
| 377 string16 name = GetGroupName(); | |
| 378 DictionaryValue* result = new DictionaryValue(); | |
| 379 result->SetString("name", name); | |
| 380 result->SetString("description", description_); | |
| 381 result->SetString("version", version_->GetString()); | |
| 382 result->SetString("update_url", update_url_); | |
| 383 result->SetBoolean("critical", IsVulnerable()); | |
| 384 | |
| 385 bool group_disabled_by_policy = IsPluginNameDisabledByPolicy(name); | |
| 386 bool group_enabled_by_policy = IsPluginNameEnabledByPolicy(name); | |
| 387 ListValue* plugin_files = new ListValue(); | |
| 388 bool all_plugins_disabled_by_policy = true; | |
| 389 bool all_plugins_enabled_by_policy = true; | |
| 390 for (size_t i = 0; i < web_plugin_infos_.size(); ++i) { | |
| 391 DictionaryValue* plugin_file = new DictionaryValue(); | |
| 392 plugin_file->SetString("name", web_plugin_infos_[i].name); | |
| 393 plugin_file->SetString("description", web_plugin_infos_[i].desc); | |
| 394 plugin_file->SetString("path", web_plugin_infos_[i].path.value()); | |
| 395 plugin_file->SetString("version", web_plugin_infos_[i].version); | |
| 396 | |
| 397 bool plugin_disabled_by_policy = group_disabled_by_policy || | |
| 398 ((web_plugin_infos_[i].enabled & WebPluginInfo::POLICY_DISABLED) != 0); | |
| 399 bool plugin_enabled_by_policy = group_enabled_by_policy || | |
| 400 ((web_plugin_infos_[i].enabled & WebPluginInfo::POLICY_ENABLED) != 0); | |
| 401 | |
| 402 if (!plugin_disabled_by_policy) | |
| 403 all_plugins_disabled_by_policy = false; | |
| 404 if (!plugin_enabled_by_policy) | |
| 405 all_plugins_enabled_by_policy = false; | |
| 406 | |
| 407 if (plugin_disabled_by_policy) { | |
| 408 plugin_file->SetString("enabledMode", "disabledByPolicy"); | |
| 409 } else if (plugin_enabled_by_policy) { | |
| 410 plugin_file->SetString("enabledMode", "enabledByPolicy"); | |
| 411 } else { | |
| 412 plugin_file->SetString( | |
| 413 "enabledMode", IsPluginEnabled(web_plugin_infos_[i]) ? | |
| 414 "enabledByUser" : "disabledByUser"); | |
| 415 } | |
| 416 | |
| 417 ListValue* mime_types = new ListValue(); | |
| 418 const std::vector<WebPluginMimeType>& plugin_mime_types = | |
| 419 web_plugin_infos_[i].mime_types; | |
| 420 for (size_t j = 0; j < plugin_mime_types.size(); ++j) { | |
| 421 DictionaryValue* mime_type = new DictionaryValue(); | |
| 422 mime_type->SetString("mimeType", plugin_mime_types[j].mime_type); | |
| 423 mime_type->SetString("description", plugin_mime_types[j].description); | |
| 424 | |
| 425 ListValue* file_extensions = new ListValue(); | |
| 426 const std::vector<std::string>& mime_file_extensions = | |
| 427 plugin_mime_types[j].file_extensions; | |
| 428 for (size_t k = 0; k < mime_file_extensions.size(); ++k) | |
| 429 file_extensions->Append(new StringValue(mime_file_extensions[k])); | |
| 430 mime_type->Set("fileExtensions", file_extensions); | |
| 431 | |
| 432 mime_types->Append(mime_type); | |
| 433 } | |
| 434 plugin_file->Set("mimeTypes", mime_types); | |
| 435 | |
| 436 plugin_files->Append(plugin_file); | |
| 437 } | |
| 438 | |
| 439 if (group_disabled_by_policy || all_plugins_disabled_by_policy) { | |
| 440 result->SetString("enabledMode", "disabledByPolicy"); | |
| 441 } else if (group_enabled_by_policy || all_plugins_enabled_by_policy) { | |
| 442 result->SetString("enabledMode", "enabledByPolicy"); | |
| 443 } else { | |
| 444 result->SetString("enabledMode", enabled_ ? | |
| 445 "enabledByUser" : | |
| 446 "disabledByUser"); | |
| 447 } | |
| 448 result->Set("plugin_files", plugin_files); | |
| 449 | |
| 450 return result; | |
| 451 } | |
| 452 | |
| 453 /*static*/ | 222 /*static*/ |
| 454 bool PluginGroup::IsVersionInRange(const Version& version, | 223 bool PluginGroup::IsVersionInRange(const Version& version, |
| 455 const VersionRange& range) { | 224 const VersionRange& range) { |
| 456 DCHECK(range.low.get() != NULL || range.high.get() == NULL) | 225 DCHECK(range.low.get() != NULL || range.high.get() == NULL) |
| 457 << "Lower bound of version range must be defined."; | 226 << "Lower bound of version range must be defined."; |
| 458 return (range.low.get() == NULL && range.high.get() == NULL) || | 227 return (range.low.get() == NULL && range.high.get() == NULL) || |
| 459 (range.low->CompareTo(version) <= 0 && | 228 (range.low->CompareTo(version) <= 0 && |
| 460 (range.high.get() == NULL || range.high->CompareTo(version) > 0)); | 229 (range.high.get() == NULL || range.high->CompareTo(version) > 0)); |
| 461 } | 230 } |
| 462 | 231 |
| 463 /*static*/ | 232 /*static*/ |
| 464 bool PluginGroup::IsPluginOutdated(const Version& plugin_version, | 233 bool PluginGroup::IsPluginOutdated(const Version& plugin_version, |
| 465 const VersionRange& version_range) { | 234 const VersionRange& version_range) { |
| 466 if (IsVersionInRange(plugin_version, version_range)) { | 235 if (IsVersionInRange(plugin_version, version_range)) { |
| 467 if (version_range.min.get() && | 236 if (version_range.min.get() && |
| 468 plugin_version.CompareTo(*version_range.min) < 0) { | 237 plugin_version.CompareTo(*version_range.min) < 0) { |
| 469 return true; | 238 return true; |
| 470 } | 239 } |
| 471 } | 240 } |
| 472 return false; | 241 return false; |
| 473 } | 242 } |
| 474 | 243 |
| 475 bool PluginGroup::IsWhitelisted() const { | 244 // Returns true if the latest version of this plugin group is vulnerable. |
| 476 for (size_t i = 0; i < web_plugin_infos_.size(); ++i) { | 245 bool PluginGroup::IsVulnerable(const WebPluginInfo& plugin) const { |
| 477 if (web_plugin_infos_[i].enabled & WebPluginInfo::POLICY_ENABLED) | 246 scoped_ptr<Version> version(CreateVersionFromString(plugin.version)); |
| 247 if (!version.get()) |
| 248 return false; |
| 249 |
| 250 for (size_t i = 0; i < version_ranges_.size(); ++i) { |
| 251 if (IsPluginOutdated(*version, version_ranges_[i])) |
| 478 return true; | 252 return true; |
| 479 } | 253 } |
| 480 return false; | 254 return false; |
| 481 } | 255 } |
| 482 | 256 |
| 483 // Returns true if the latest version of this plugin group is vulnerable. | 257 bool PluginGroup::RequiresAuthorization(const WebPluginInfo& plugin) const { |
| 484 bool PluginGroup::IsVulnerable() const { | 258 scoped_ptr<Version> version(CreateVersionFromString(plugin.version)); |
| 485 // A plugin isn't considered vulnerable if it's explicitly whitelisted. | 259 if (!version.get()) |
| 486 if (IsWhitelisted()) | |
| 487 return false; | 260 return false; |
| 488 | 261 |
| 489 for (size_t i = 0; i < version_ranges_.size(); ++i) { | 262 for (size_t i = 0; i < version_ranges_.size(); ++i) { |
| 490 if (IsPluginOutdated(*version_, version_ranges_[i])) | 263 if (IsVersionInRange(*version, version_ranges_[i]) && |
| 491 return true; | |
| 492 } | |
| 493 return false; | |
| 494 } | |
| 495 | |
| 496 bool PluginGroup::RequiresAuthorization() const { | |
| 497 // A plugin doesn't require authorization if it's explicitly whitelisted. | |
| 498 if (IsWhitelisted()) | |
| 499 return false; | |
| 500 | |
| 501 for (size_t i = 0; i < version_ranges_.size(); ++i) { | |
| 502 if (IsVersionInRange(*version_, version_ranges_[i]) && | |
| 503 version_ranges_[i].requires_authorization) | 264 version_ranges_[i].requires_authorization) |
| 504 return true; | 265 return true; |
| 505 } | 266 } |
| 506 return false; | 267 return false; |
| 507 } | 268 } |
| 508 | 269 |
| 509 bool PluginGroup::IsEmpty() const { | 270 bool PluginGroup::IsEmpty() const { |
| 510 return web_plugin_infos_.empty(); | 271 return web_plugin_infos_.empty(); |
| 511 } | 272 } |
| 512 | 273 |
| 513 bool PluginGroup::EnableGroup(bool enable) { | |
| 514 bool group_disabled_by_policy = IsPluginNameDisabledByPolicy(group_name_); | |
| 515 bool group_enabled_by_policy = IsPluginNameEnabledByPolicy(group_name_); | |
| 516 | |
| 517 // We can't enable nor disable groups controlled by policy. | |
| 518 if ((group_disabled_by_policy && enable) || | |
| 519 (group_enabled_by_policy && !enable)) | |
| 520 return false; | |
| 521 | |
| 522 ResetGroupState(); | |
| 523 for (size_t i = 0; i < web_plugin_infos_.size(); ++i) { | |
| 524 bool policy_enabled = | |
| 525 IsPluginNameEnabledByPolicy(web_plugin_infos_[i].name); | |
| 526 bool policy_disabled = | |
| 527 IsPluginFileNameDisabledByPolicy(web_plugin_infos_[i].name, | |
| 528 group_name_); | |
| 529 if (policy_disabled) { | |
| 530 Disable(&web_plugin_infos_[i], WebPluginInfo::POLICY_DISABLED); | |
| 531 } else if (policy_enabled) { | |
| 532 Enable(&web_plugin_infos_[i], WebPluginInfo::POLICY_ENABLED); | |
| 533 } else if (enable) { | |
| 534 Enable(&web_plugin_infos_[i], WebPluginInfo::USER_ENABLED); | |
| 535 } else { | |
| 536 Disable(&web_plugin_infos_[i], WebPluginInfo::USER_DISABLED); | |
| 537 } | |
| 538 UpdateActivePlugin(web_plugin_infos_[i]); | |
| 539 } | |
| 540 return enabled_ == enable; | |
| 541 } | |
| 542 | |
| 543 void PluginGroup::EnforceGroupPolicy() { | |
| 544 bool group_disabled_by_policy = IsPluginNameDisabledByPolicy(group_name_); | |
| 545 bool group_enabled_by_policy = IsPluginNameEnabledByPolicy(group_name_); | |
| 546 | |
| 547 ResetGroupState(); | |
| 548 for (size_t i = 0; i < web_plugin_infos_.size(); ++i) { | |
| 549 bool policy_enabled = | |
| 550 group_enabled_by_policy || | |
| 551 IsPluginNameEnabledByPolicy(web_plugin_infos_[i].name); | |
| 552 bool policy_disabled = | |
| 553 !policy_enabled && | |
| 554 (group_disabled_by_policy || | |
| 555 IsPluginFileNameDisabledByPolicy(web_plugin_infos_[i].name, | |
| 556 group_name_)); | |
| 557 if (policy_disabled) { | |
| 558 Disable(&web_plugin_infos_[i], WebPluginInfo::POLICY_DISABLED); | |
| 559 } else if (policy_enabled) { | |
| 560 Enable(&web_plugin_infos_[i], WebPluginInfo::POLICY_ENABLED); | |
| 561 } else { | |
| 562 // If not managed, use the user's preference. | |
| 563 if ((web_plugin_infos_[i].enabled & WebPluginInfo::USER_MASK) == | |
| 564 WebPluginInfo::USER_ENABLED) { | |
| 565 Enable(&web_plugin_infos_[i], WebPluginInfo::POLICY_UNMANAGED); | |
| 566 } else { | |
| 567 Disable(&web_plugin_infos_[i], WebPluginInfo::POLICY_UNMANAGED); | |
| 568 } | |
| 569 } | |
| 570 UpdateActivePlugin(web_plugin_infos_[i]); | |
| 571 } | |
| 572 } | |
| 573 | |
| 574 void PluginGroup::ResetGroupState() { | |
| 575 enabled_ = false; | |
| 576 description_.clear(); | |
| 577 version_.reset(Version::GetVersionFromString("0")); | |
| 578 } | |
| 579 | |
| 580 /*static*/ | |
| 581 bool PluginGroup::SetPluginState(WebPluginInfo* plugin, | |
| 582 int new_reason, | |
| 583 bool state_changes) { | |
| 584 // If we are only stripping the policy then mask the policy bits. | |
| 585 if (new_reason == WebPluginInfo::POLICY_UNMANAGED) { | |
| 586 plugin->enabled &= WebPluginInfo::USER_MASK; | |
| 587 return true; | |
| 588 } | |
| 589 if (new_reason & WebPluginInfo::MANAGED_MASK) { | |
| 590 // Policy-enforced change: preserve the user's preference, and override | |
| 591 // a possible previous policy flag. | |
| 592 plugin->enabled = (plugin->enabled & WebPluginInfo::USER_MASK) | new_reason; | |
| 593 } else if (state_changes && (plugin->enabled & WebPluginInfo::MANAGED_MASK)) { | |
| 594 // Refuse change when managed. | |
| 595 return false; | |
| 596 } else { | |
| 597 // Accept the user update, but keep the policy flag if present. | |
| 598 plugin->enabled = (plugin->enabled & WebPluginInfo::MANAGED_MASK) | | |
| 599 new_reason; | |
| 600 } | |
| 601 return true; | |
| 602 } | |
| 603 | |
| 604 /*static*/ | |
| 605 bool PluginGroup::Enable(WebPluginInfo* plugin, int new_reason) { | |
| 606 DCHECK(new_reason == WebPluginInfo::USER_ENABLED || | |
| 607 new_reason == WebPluginInfo::POLICY_ENABLED || | |
| 608 new_reason == WebPluginInfo::USER_ENABLED_POLICY_ENABLED || | |
| 609 new_reason == WebPluginInfo::POLICY_UNMANAGED); | |
| 610 return SetPluginState(plugin, new_reason, !IsPluginEnabled(*plugin)); | |
| 611 } | |
| 612 | |
| 613 /*static*/ | |
| 614 bool PluginGroup::Disable(WebPluginInfo* plugin, int new_reason) { | |
| 615 DCHECK(new_reason == WebPluginInfo::USER_DISABLED || | |
| 616 new_reason == WebPluginInfo::POLICY_DISABLED || | |
| 617 new_reason == WebPluginInfo::USER_DISABLED_POLICY_DISABLED || | |
| 618 new_reason == WebPluginInfo::POLICY_UNMANAGED); | |
| 619 return SetPluginState(plugin, new_reason, IsPluginEnabled(*plugin)); | |
| 620 } | |
| 621 | |
| 622 } // namespace npapi | 274 } // namespace npapi |
| 623 } // namespace webkit | 275 } // namespace webkit |
| OLD | NEW |