1116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// Copyright 2014 The Chromium Authors. All rights reserved. 2116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// Use of this source code is governed by a BSD-style license that can be 3116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// found in the LICENSE file. 4116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 5116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "chrome/browser/extensions/extension_install_checker.h" 6116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 7116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "base/strings/utf_string_conversions.h" 8116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "chrome/browser/extensions/blacklist.h" 9116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "chrome/browser/extensions/requirements_checker.h" 10116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "chrome/browser/profiles/profile.h" 11116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "content/public/browser/browser_thread.h" 12116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "extensions/browser/extension_system.h" 13116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "extensions/browser/management_policy.h" 14116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 15116680a4aac90f2aa7413d9095a592090648e557Ben Murdochnamespace extensions { 16116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 17116680a4aac90f2aa7413d9095a592090648e557Ben MurdochExtensionInstallChecker::ExtensionInstallChecker(Profile* profile) 18116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch : profile_(profile), 19116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch blacklist_state_(NOT_BLACKLISTED), 20116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch policy_allows_load_(true), 21116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch current_sequence_number_(0), 22116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch running_checks_(0), 23116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch fail_fast_(false), 24116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch weak_ptr_factory_(this) { 25116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 26116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 27116680a4aac90f2aa7413d9095a592090648e557Ben MurdochExtensionInstallChecker::~ExtensionInstallChecker() { 28116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 29116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 30116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid ExtensionInstallChecker::Start(int enabled_checks, 31116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch bool fail_fast, 32116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const Callback& callback) { 33116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Profile is null in tests. 34116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (profile_) { 35116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DCHECK_CURRENTLY_ON(content::BrowserThread::UI); 36116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (!extension_.get()) { 37116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch NOTREACHED(); 38116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return; 39116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 40116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 41116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 42116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (is_running() || !enabled_checks || callback.is_null()) { 43116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch NOTREACHED(); 44116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return; 45116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 46116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 47116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch running_checks_ = enabled_checks; 48116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch fail_fast_ = fail_fast; 49116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch callback_ = callback; 50116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ResetResults(); 51116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 52116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Execute the management policy check first as it is synchronous. 53116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (enabled_checks & CHECK_MANAGEMENT_POLICY) { 54116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch CheckManagementPolicy(); 55116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (!is_running()) 56116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return; 57116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 58116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 59116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (enabled_checks & CHECK_REQUIREMENTS) { 60116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch CheckRequirements(); 61116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (!is_running()) 62116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return; 63116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 64116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 65116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (enabled_checks & CHECK_BLACKLIST) 66116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch CheckBlacklistState(); 67116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 68116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 69116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid ExtensionInstallChecker::CheckManagementPolicy() { 70116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DCHECK(extension_.get()); 71116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 72116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch base::string16 error; 73116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch bool allow = ExtensionSystem::Get(profile_)->management_policy()->UserMayLoad( 74116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch extension_.get(), &error); 75116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch OnManagementPolicyCheckDone(allow, base::UTF16ToUTF8(error)); 76116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 77116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 78116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid ExtensionInstallChecker::OnManagementPolicyCheckDone( 79116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch bool allows_load, 80116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const std::string& error) { 81116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch policy_allows_load_ = allows_load; 82116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch policy_error_ = error; 83116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DCHECK(policy_allows_load_ || !policy_error_.empty()); 84116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 85116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch running_checks_ &= ~CHECK_MANAGEMENT_POLICY; 86116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch MaybeInvokeCallback(); 87116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 88116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 89116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid ExtensionInstallChecker::CheckRequirements() { 90116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DCHECK(extension_.get()); 91116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 92116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (!requirements_checker_.get()) 93116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch requirements_checker_.reset(new RequirementsChecker()); 94116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch requirements_checker_->Check( 95116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch extension_, 96116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch base::Bind(&ExtensionInstallChecker::OnRequirementsCheckDone, 97116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch weak_ptr_factory_.GetWeakPtr(), 98116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch current_sequence_number_)); 99116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 100116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 101116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid ExtensionInstallChecker::OnRequirementsCheckDone( 102116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch int sequence_number, 103116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch std::vector<std::string> errors) { 104116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Some pending results may arrive after fail fast. 105116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (sequence_number != current_sequence_number_) 106116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return; 107116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 108116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch requirement_errors_ = errors; 109116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 110116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch running_checks_ &= ~CHECK_REQUIREMENTS; 111116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch MaybeInvokeCallback(); 112116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 113116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 114116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid ExtensionInstallChecker::CheckBlacklistState() { 115116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DCHECK(extension_.get()); 116116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 117116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch extensions::Blacklist* blacklist = 118116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ExtensionSystem::Get(profile_)->blacklist(); 119116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch blacklist->IsBlacklisted( 120116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch extension_->id(), 121116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch base::Bind(&ExtensionInstallChecker::OnBlacklistStateCheckDone, 122116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch weak_ptr_factory_.GetWeakPtr(), 123116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch current_sequence_number_)); 124116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 125116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 126116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid ExtensionInstallChecker::OnBlacklistStateCheckDone(int sequence_number, 127116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch BlacklistState state) { 128116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Some pending results may arrive after fail fast. 129116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (sequence_number != current_sequence_number_) 130116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return; 131116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 132116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch blacklist_state_ = state; 133116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 134116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch running_checks_ &= ~CHECK_BLACKLIST; 135116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch MaybeInvokeCallback(); 136116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 137116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 138116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid ExtensionInstallChecker::ResetResults() { 139116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch requirement_errors_.clear(); 140116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch blacklist_state_ = NOT_BLACKLISTED; 141116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch policy_allows_load_ = true; 142116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch policy_error_.clear(); 143116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 144116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 145116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid ExtensionInstallChecker::MaybeInvokeCallback() { 146116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (callback_.is_null()) 147116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return; 148116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 149116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Set bits for failed checks. 150116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch int failed_mask = 0; 151116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (blacklist_state_ == BLACKLISTED_MALWARE) 152116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch failed_mask |= CHECK_BLACKLIST; 153116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (!requirement_errors_.empty()) 154116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch failed_mask |= CHECK_REQUIREMENTS; 155116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (!policy_allows_load_) 156116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch failed_mask |= CHECK_MANAGEMENT_POLICY; 157116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 158116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Invoke callback if all checks are complete or there was at least one 159116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // failure and |fail_fast_| is true. 160116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (!is_running() || (failed_mask && fail_fast_)) { 161116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // If we are failing fast, discard any pending results. 162116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch weak_ptr_factory_.InvalidateWeakPtrs(); 163116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch running_checks_ = 0; 164116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ++current_sequence_number_; 165116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 166116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch Callback callback_copy = callback_; 167116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch callback_.Reset(); 168116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 169116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // This instance may be owned by the callback recipient and deleted here, 170116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // so reset |callback_| first and invoke a copy of the callback. 171116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch callback_copy.Run(failed_mask); 172116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 173116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 174116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 175116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} // namespace extensions 176