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 |
30 VersionRange::VersionRange(const VersionRangeDefinition& definition) | 107 VersionRange::VersionRange(const VersionRangeDefinition& definition) |
31 : low_str(definition.version_matcher_low), | 108 : low_str(definition.version_matcher_low), |
32 high_str(definition.version_matcher_high), | 109 high_str(definition.version_matcher_high), |
33 min_str(definition.min_version), | 110 min_str(definition.min_version), |
34 requires_authorization(definition.requires_authorization) { | 111 requires_authorization(definition.requires_authorization) { |
35 if (!low_str.empty()) | 112 if (!low_str.empty()) |
36 low.reset(Version::GetVersionFromString(low_str)); | 113 low.reset(Version::GetVersionFromString(low_str)); |
37 if (!high_str.empty()) | 114 if (!high_str.empty()) |
38 high.reset(Version::GetVersionFromString(high_str)); | 115 high.reset(Version::GetVersionFromString(high_str)); |
39 if (!min_str.empty()) | 116 if (!min_str.empty()) |
(...skipping 21 matching lines...) Expand all Loading... |
61 requires_authorization = other.requires_authorization; | 138 requires_authorization = other.requires_authorization; |
62 } | 139 } |
63 | 140 |
64 PluginGroup::PluginGroup(const string16& group_name, | 141 PluginGroup::PluginGroup(const string16& group_name, |
65 const string16& name_matcher, | 142 const string16& name_matcher, |
66 const std::string& update_url, | 143 const std::string& update_url, |
67 const std::string& identifier) | 144 const std::string& identifier) |
68 : identifier_(identifier), | 145 : identifier_(identifier), |
69 group_name_(group_name), | 146 group_name_(group_name), |
70 name_matcher_(name_matcher), | 147 name_matcher_(name_matcher), |
71 update_url_(update_url) { | 148 update_url_(update_url), |
| 149 enabled_(false), |
| 150 version_(Version::GetVersionFromString("0")) { |
72 } | 151 } |
73 | 152 |
74 void PluginGroup::InitFrom(const PluginGroup& other) { | 153 void PluginGroup::InitFrom(const PluginGroup& other) { |
75 identifier_ = other.identifier_; | 154 identifier_ = other.identifier_; |
76 group_name_ = other.group_name_; | 155 group_name_ = other.group_name_; |
77 name_matcher_ = other.name_matcher_; | 156 name_matcher_ = other.name_matcher_; |
| 157 description_ = other.description_; |
78 update_url_ = other.update_url_; | 158 update_url_ = other.update_url_; |
| 159 enabled_ = other.enabled_; |
79 version_ranges_ = other.version_ranges_; | 160 version_ranges_ = other.version_ranges_; |
| 161 version_.reset(other.version_->Clone()); |
80 web_plugin_infos_ = other.web_plugin_infos_; | 162 web_plugin_infos_ = other.web_plugin_infos_; |
81 } | 163 } |
82 | 164 |
83 PluginGroup::PluginGroup(const PluginGroup& other) { | 165 PluginGroup::PluginGroup(const PluginGroup& other) { |
84 InitFrom(other); | 166 InitFrom(other); |
85 } | 167 } |
86 | 168 |
87 PluginGroup& PluginGroup::operator=(const PluginGroup& other) { | 169 PluginGroup& PluginGroup::operator=(const PluginGroup& other) { |
88 InitFrom(other); | 170 InitFrom(other); |
89 return *this; | 171 return *this; |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
167 RemoveChars(version, ") ", &version); | 249 RemoveChars(version, ") ", &version); |
168 std::replace(version.begin(), version.end(), 'd', '.'); | 250 std::replace(version.begin(), version.end(), 'd', '.'); |
169 std::replace(version.begin(), version.end(), 'r', '.'); | 251 std::replace(version.begin(), version.end(), 'r', '.'); |
170 std::replace(version.begin(), version.end(), ',', '.'); | 252 std::replace(version.begin(), version.end(), ',', '.'); |
171 std::replace(version.begin(), version.end(), '(', '.'); | 253 std::replace(version.begin(), version.end(), '(', '.'); |
172 std::replace(version.begin(), version.end(), '_', '.'); | 254 std::replace(version.begin(), version.end(), '_', '.'); |
173 | 255 |
174 return Version::GetVersionFromString(version); | 256 return Version::GetVersionFromString(version); |
175 } | 257 } |
176 | 258 |
| 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 |
177 void PluginGroup::AddPlugin(const WebPluginInfo& plugin) { | 286 void PluginGroup::AddPlugin(const WebPluginInfo& plugin) { |
178 // Check if this group already contains this plugin. | 287 // Check if this group already contains this plugin. |
179 for (size_t i = 0; i < web_plugin_infos_.size(); ++i) { | 288 for (size_t i = 0; i < web_plugin_infos_.size(); ++i) { |
180 if (FilePath::CompareEqualIgnoreCase(web_plugin_infos_[i].path.value(), | 289 if (FilePath::CompareEqualIgnoreCase(web_plugin_infos_[i].path.value(), |
181 plugin.path.value())) { | 290 plugin.path.value())) { |
182 return; | 291 return; |
183 } | 292 } |
184 } | 293 } |
185 web_plugin_infos_.push_back(plugin); | 294 web_plugin_infos_.push_back(plugin); |
| 295 UpdateActivePlugin(web_plugin_infos_.back()); |
186 } | 296 } |
187 | 297 |
188 bool PluginGroup::RemovePlugin(const FilePath& filename) { | 298 bool PluginGroup::RemovePlugin(const FilePath& filename) { |
189 bool did_remove = false; | 299 bool did_remove = false; |
| 300 ResetGroupState(); |
190 for (size_t i = 0; i < web_plugin_infos_.size();) { | 301 for (size_t i = 0; i < web_plugin_infos_.size();) { |
191 if (web_plugin_infos_[i].path == filename) { | 302 if (web_plugin_infos_[i].path == filename) { |
192 web_plugin_infos_.erase(web_plugin_infos_.begin() + i); | 303 web_plugin_infos_.erase(web_plugin_infos_.begin() + i); |
193 did_remove = true; | 304 did_remove = true; |
194 } else { | 305 } else { |
| 306 UpdateActivePlugin(web_plugin_infos_[i]); |
195 i++; | 307 i++; |
196 } | 308 } |
197 } | 309 } |
198 return did_remove; | 310 return did_remove; |
199 } | 311 } |
200 | 312 |
| 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 |
201 string16 PluginGroup::GetGroupName() const { | 347 string16 PluginGroup::GetGroupName() const { |
202 if (!group_name_.empty()) | 348 if (!group_name_.empty()) |
203 return group_name_; | 349 return group_name_; |
204 DCHECK_EQ(1u, web_plugin_infos_.size()); | 350 DCHECK_EQ(1u, web_plugin_infos_.size()); |
205 FilePath::StringType path = | 351 FilePath::StringType path = |
206 web_plugin_infos_[0].path.BaseName().RemoveExtension().value(); | 352 web_plugin_infos_[0].path.BaseName().RemoveExtension().value(); |
207 #if defined(OS_POSIX) | 353 #if defined(OS_POSIX) |
208 return UTF8ToUTF16(path); | 354 return UTF8ToUTF16(path); |
209 #elif defined(OS_WIN) | 355 #elif defined(OS_WIN) |
210 return WideToUTF16(path); | 356 return WideToUTF16(path); |
211 #endif | 357 #endif |
212 } | 358 } |
213 | 359 |
214 bool PluginGroup::ContainsPlugin(const FilePath& path) const { | 360 bool PluginGroup::ContainsPlugin(const FilePath& path) const { |
215 for (size_t i = 0; i < web_plugin_infos_.size(); ++i) { | 361 for (size_t i = 0; i < web_plugin_infos_.size(); ++i) { |
216 if (web_plugin_infos_[i].path == path) | 362 if (web_plugin_infos_[i].path == path) |
217 return true; | 363 return true; |
218 } | 364 } |
219 return false; | 365 return false; |
220 } | 366 } |
221 | 367 |
| 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 |
222 /*static*/ | 453 /*static*/ |
223 bool PluginGroup::IsVersionInRange(const Version& version, | 454 bool PluginGroup::IsVersionInRange(const Version& version, |
224 const VersionRange& range) { | 455 const VersionRange& range) { |
225 DCHECK(range.low.get() != NULL || range.high.get() == NULL) | 456 DCHECK(range.low.get() != NULL || range.high.get() == NULL) |
226 << "Lower bound of version range must be defined."; | 457 << "Lower bound of version range must be defined."; |
227 return (range.low.get() == NULL && range.high.get() == NULL) || | 458 return (range.low.get() == NULL && range.high.get() == NULL) || |
228 (range.low->CompareTo(version) <= 0 && | 459 (range.low->CompareTo(version) <= 0 && |
229 (range.high.get() == NULL || range.high->CompareTo(version) > 0)); | 460 (range.high.get() == NULL || range.high->CompareTo(version) > 0)); |
230 } | 461 } |
231 | 462 |
232 /*static*/ | 463 /*static*/ |
233 bool PluginGroup::IsPluginOutdated(const Version& plugin_version, | 464 bool PluginGroup::IsPluginOutdated(const Version& plugin_version, |
234 const VersionRange& version_range) { | 465 const VersionRange& version_range) { |
235 if (IsVersionInRange(plugin_version, version_range)) { | 466 if (IsVersionInRange(plugin_version, version_range)) { |
236 if (version_range.min.get() && | 467 if (version_range.min.get() && |
237 plugin_version.CompareTo(*version_range.min) < 0) { | 468 plugin_version.CompareTo(*version_range.min) < 0) { |
238 return true; | 469 return true; |
239 } | 470 } |
240 } | 471 } |
241 return false; | 472 return false; |
242 } | 473 } |
243 | 474 |
244 // Returns true if the latest version of this plugin group is vulnerable. | 475 bool PluginGroup::IsWhitelisted() const { |
245 bool PluginGroup::IsVulnerable(const WebPluginInfo& plugin) const { | 476 for (size_t i = 0; i < web_plugin_infos_.size(); ++i) { |
246 scoped_ptr<Version> version(CreateVersionFromString(plugin.version)); | 477 if (web_plugin_infos_[i].enabled & WebPluginInfo::POLICY_ENABLED) |
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])) | |
252 return true; | 478 return true; |
253 } | 479 } |
254 return false; | 480 return false; |
255 } | 481 } |
256 | 482 |
257 bool PluginGroup::RequiresAuthorization(const WebPluginInfo& plugin) const { | 483 // Returns true if the latest version of this plugin group is vulnerable. |
258 scoped_ptr<Version> version(CreateVersionFromString(plugin.version)); | 484 bool PluginGroup::IsVulnerable() const { |
259 if (!version.get()) | 485 // A plugin isn't considered vulnerable if it's explicitly whitelisted. |
| 486 if (IsWhitelisted()) |
260 return false; | 487 return false; |
261 | 488 |
262 for (size_t i = 0; i < version_ranges_.size(); ++i) { | 489 for (size_t i = 0; i < version_ranges_.size(); ++i) { |
263 if (IsVersionInRange(*version, version_ranges_[i]) && | 490 if (IsPluginOutdated(*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]) && |
264 version_ranges_[i].requires_authorization) | 503 version_ranges_[i].requires_authorization) |
265 return true; | 504 return true; |
266 } | 505 } |
267 return false; | 506 return false; |
268 } | 507 } |
269 | 508 |
270 bool PluginGroup::IsEmpty() const { | 509 bool PluginGroup::IsEmpty() const { |
271 return web_plugin_infos_.empty(); | 510 return web_plugin_infos_.empty(); |
272 } | 511 } |
273 | 512 |
| 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 |
274 } // namespace npapi | 622 } // namespace npapi |
275 } // namespace webkit | 623 } // namespace webkit |
OLD | NEW |