| // Copyright 2021 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "extensions/browser/blocklist_extension_prefs.h" |
| |
| #include "extensions/browser/blocklist_state.h" |
| #include "extensions/browser/extension_prefs.h" |
| |
| namespace extensions { |
| |
| namespace { |
| |
| // If extension is blocklisted by Omaha attributes. |
| constexpr const char kPrefOmahaBlocklistState[] = "omaha_blocklist_state"; |
| |
| // If the user has acknowledged the blocklist state. |
| constexpr const char kPrefAcknowledgedBlocklistState[] = |
| "acknowledged_blocklist_state"; |
| |
| // If extension is blocklisted or greylisted. |
| constexpr const char kPrefBlocklistState[] = "blacklist_state"; |
| |
| // The default value to use for getting blocklist state from the pref. |
| constexpr BitMapBlocklistState kDefaultBitMapBlocklistState = |
| BitMapBlocklistState::NOT_BLOCKLISTED; |
| |
| // Extensions in these states should be put into the extension greylist. |
| // This list is sorted by the precedence order. When two states are presented |
| // at the same time, the state with higher precedence takes effect. |
| const BitMapBlocklistState kGreylistStates[] = { |
| BitMapBlocklistState::BLOCKLISTED_CWS_POLICY_VIOLATION, |
| BitMapBlocklistState::BLOCKLISTED_POTENTIALLY_UNWANTED, |
| BitMapBlocklistState::BLOCKLISTED_SECURITY_VULNERABILITY}; |
| const int kAllGreylistStates = |
| static_cast<int>(BitMapBlocklistState::BLOCKLISTED_SECURITY_VULNERABILITY) | |
| static_cast<int>(BitMapBlocklistState::BLOCKLISTED_CWS_POLICY_VIOLATION) | |
| static_cast<int>(BitMapBlocklistState::BLOCKLISTED_POTENTIALLY_UNWANTED); |
| |
| // Converts BitMapBlocklistState to BlocklistState. |
| BlocklistState BitMapBlocklistStateToBlocklistState( |
| BitMapBlocklistState blocklist_state) { |
| switch (blocklist_state) { |
| case BitMapBlocklistState::NOT_BLOCKLISTED: |
| return NOT_BLOCKLISTED; |
| case BitMapBlocklistState::BLOCKLISTED_MALWARE: |
| return BLOCKLISTED_MALWARE; |
| case BitMapBlocklistState::BLOCKLISTED_SECURITY_VULNERABILITY: |
| return BLOCKLISTED_SECURITY_VULNERABILITY; |
| case BitMapBlocklistState::BLOCKLISTED_CWS_POLICY_VIOLATION: |
| return BLOCKLISTED_CWS_POLICY_VIOLATION; |
| case BitMapBlocklistState::BLOCKLISTED_POTENTIALLY_UNWANTED: |
| return BLOCKLISTED_POTENTIALLY_UNWANTED; |
| } |
| } |
| |
| } // namespace |
| |
| namespace blocklist_prefs { |
| |
| BitMapBlocklistState BlocklistStateToBitMapBlocklistState( |
| BlocklistState blocklist_state) { |
| switch (blocklist_state) { |
| case NOT_BLOCKLISTED: |
| return BitMapBlocklistState::NOT_BLOCKLISTED; |
| case BLOCKLISTED_MALWARE: |
| return BitMapBlocklistState::BLOCKLISTED_MALWARE; |
| case BLOCKLISTED_SECURITY_VULNERABILITY: |
| return BitMapBlocklistState::BLOCKLISTED_SECURITY_VULNERABILITY; |
| case BLOCKLISTED_CWS_POLICY_VIOLATION: |
| return BitMapBlocklistState::BLOCKLISTED_CWS_POLICY_VIOLATION; |
| case BLOCKLISTED_POTENTIALLY_UNWANTED: |
| return BitMapBlocklistState::BLOCKLISTED_POTENTIALLY_UNWANTED; |
| case BLOCKLISTED_UNKNOWN: |
| NOTREACHED() << "The unknown state should not be added into prefs."; |
| return BitMapBlocklistState::NOT_BLOCKLISTED; |
| } |
| } |
| |
| BitMapBlocklistState GetExtensionBlocklistState( |
| const std::string& extension_id, |
| ExtensionPrefs* extension_prefs) { |
| BitMapBlocklistState sb_state = |
| GetSafeBrowsingExtensionBlocklistState(extension_id, extension_prefs); |
| if (sb_state == BitMapBlocklistState::BLOCKLISTED_MALWARE || |
| HasOmahaBlocklistState(extension_id, |
| BitMapBlocklistState::BLOCKLISTED_MALWARE, |
| extension_prefs)) { |
| return BitMapBlocklistState::BLOCKLISTED_MALWARE; |
| } |
| |
| for (auto greylist_state : kGreylistStates) { |
| if (sb_state == greylist_state || |
| HasOmahaBlocklistState(extension_id, greylist_state, extension_prefs)) { |
| return greylist_state; |
| } |
| } |
| |
| return BitMapBlocklistState::NOT_BLOCKLISTED; |
| } |
| |
| bool IsExtensionBlocklisted(const std::string& extension_id, |
| ExtensionPrefs* extension_prefs) { |
| return GetExtensionBlocklistState(extension_id, extension_prefs) == |
| BitMapBlocklistState::BLOCKLISTED_MALWARE; |
| } |
| |
| void AddOmahaBlocklistState(const std::string& extension_id, |
| BitMapBlocklistState state, |
| ExtensionPrefs* extension_prefs) { |
| extension_prefs->ModifyBitMapPrefBits( |
| extension_id, static_cast<int>(state), ExtensionPrefs::BIT_MAP_PREF_ADD, |
| kPrefOmahaBlocklistState, static_cast<int>(kDefaultBitMapBlocklistState)); |
| } |
| |
| void RemoveOmahaBlocklistState(const std::string& extension_id, |
| BitMapBlocklistState state, |
| ExtensionPrefs* extension_prefs) { |
| extension_prefs->ModifyBitMapPrefBits( |
| extension_id, static_cast<int>(state), |
| ExtensionPrefs::BIT_MAP_PREF_REMOVE, kPrefOmahaBlocklistState, |
| static_cast<int>(kDefaultBitMapBlocklistState)); |
| } |
| |
| bool HasOmahaBlocklistState(const std::string& extension_id, |
| BitMapBlocklistState state, |
| ExtensionPrefs* extension_prefs) { |
| int current_states = extension_prefs->GetBitMapPrefBits( |
| extension_id, kPrefOmahaBlocklistState, |
| static_cast<int>(kDefaultBitMapBlocklistState)); |
| return (current_states & static_cast<int>(state)) != 0; |
| } |
| |
| bool HasAnyOmahaGreylistState(const std::string& extension_id, |
| ExtensionPrefs* extension_prefs) { |
| int current_states = extension_prefs->GetBitMapPrefBits( |
| extension_id, kPrefOmahaBlocklistState, |
| static_cast<int>(kDefaultBitMapBlocklistState)); |
| return (current_states & kAllGreylistStates) != 0; |
| } |
| |
| void AddAcknowledgedBlocklistState(const std::string& extension_id, |
| BitMapBlocklistState state, |
| ExtensionPrefs* extension_prefs) { |
| extension_prefs->ModifyBitMapPrefBits( |
| extension_id, static_cast<int>(state), ExtensionPrefs::BIT_MAP_PREF_ADD, |
| kPrefAcknowledgedBlocklistState, |
| static_cast<int>(kDefaultBitMapBlocklistState)); |
| } |
| |
| void RemoveAcknowledgedBlocklistState( |
| const std::string& extension_id, |
| BitMapBlocklistState state, |
| extensions::ExtensionPrefs* extension_prefs) { |
| extension_prefs->ModifyBitMapPrefBits( |
| extension_id, static_cast<int>(state), |
| ExtensionPrefs::BIT_MAP_PREF_REMOVE, kPrefAcknowledgedBlocklistState, |
| static_cast<int>(kDefaultBitMapBlocklistState)); |
| } |
| |
| void ClearAcknowledgedGreylistStates(const std::string& extension_id, |
| ExtensionPrefs* extension_prefs) { |
| for (auto state : kGreylistStates) { |
| RemoveAcknowledgedBlocklistState(extension_id, state, extension_prefs); |
| } |
| } |
| |
| bool HasAcknowledgedBlocklistState(const std::string& extension_id, |
| BitMapBlocklistState state, |
| const ExtensionPrefs* extension_prefs) { |
| int current_states = extension_prefs->GetBitMapPrefBits( |
| extension_id, kPrefAcknowledgedBlocklistState, |
| static_cast<int>(kDefaultBitMapBlocklistState)); |
| return (current_states & static_cast<int>(state)) != 0; |
| } |
| |
| void UpdateCurrentGreylistStatesAsAcknowledged( |
| const std::string& extension_id, |
| ExtensionPrefs* extension_prefs) { |
| for (auto state : kGreylistStates) { |
| bool is_on_sb_list = (GetSafeBrowsingExtensionBlocklistState( |
| extension_id, extension_prefs) == state); |
| bool is_on_omaha_list = |
| HasOmahaBlocklistState(extension_id, state, extension_prefs); |
| if (is_on_sb_list || is_on_omaha_list) { |
| AddAcknowledgedBlocklistState(extension_id, state, extension_prefs); |
| } else { |
| RemoveAcknowledgedBlocklistState(extension_id, state, extension_prefs); |
| } |
| } |
| } |
| |
| void SetSafeBrowsingExtensionBlocklistState( |
| const std::string& extension_id, |
| BitMapBlocklistState bitmap_blocklist_state, |
| ExtensionPrefs* extension_prefs) { |
| if (bitmap_blocklist_state == BitMapBlocklistState::NOT_BLOCKLISTED) { |
| extension_prefs->UpdateExtensionPref(extension_id, kPrefBlocklistState, |
| nullptr); |
| extension_prefs->DeleteExtensionPrefsIfPrefEmpty(extension_id); |
| } else { |
| extension_prefs->UpdateExtensionPref( |
| extension_id, kPrefBlocklistState, |
| std::make_unique<base::Value>( |
| BitMapBlocklistStateToBlocklistState(bitmap_blocklist_state))); |
| } |
| } |
| |
| BitMapBlocklistState GetSafeBrowsingExtensionBlocklistState( |
| const std::string& extension_id, |
| ExtensionPrefs* extension_prefs) { |
| int int_value = -1; |
| if (extension_prefs->ReadPrefAsInteger(extension_id, kPrefBlocklistState, |
| &int_value) && |
| int_value >= 0) { |
| return BlocklistStateToBitMapBlocklistState( |
| static_cast<BlocklistState>(int_value)); |
| } |
| |
| return BitMapBlocklistState::NOT_BLOCKLISTED; |
| } |
| |
| } // namespace blocklist_prefs |
| } // namespace extensions |