* Copyright (c) 2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "update_service_restorer.h"
#include "access_token.h"
#include "accesstoken_kit.h"
#ifndef UPDATER_FUZZ
#include "fs_manager/mount.h"
#endif
#include "ipc_skeleton.h"
#include "string_utils.h"
#include "updaterkits/updaterkits.h"
#include "update_define.h"
#include "update_log.h"
#include "update_system_event.h"
namespace OHOS {
namespace UpdateService {
const std::string MISC_PATH = "/misc";
const std::string MISC_FILE = "/dev/block/by-name/misc";
const std::string CMD_WIPE_DATA = "--user_wipe_data";
static std::string GetCallingAppId()
{
OHOS::Security::AccessToken::AccessTokenID callerToken = IPCSkeleton::GetCallingTokenID();
auto callerTokenType = OHOS::Security::AccessToken::AccessTokenKit::GetTokenType(callerToken);
if (callerTokenType == OHOS::Security::AccessToken::TypeATokenTypeEnum::TOKEN_HAP) {
Security::AccessToken::HapTokenInfo hapTokenInfo;
if (Security::AccessToken::AccessTokenKit::GetHapTokenInfo(callerToken, hapTokenInfo) != 0) {
ENGINE_LOGE("Get hap token info error");
return "";
}
return hapTokenInfo.bundleName;
}
if (callerTokenType == OHOS::Security::AccessToken::TypeATokenTypeEnum::TOKEN_NATIVE) {
return std::to_string(IPCSkeleton::GetCallingUid());
}
return "";
}
static int32_t ExecReset(BusinessError &businessError, bool forceFlag)
{
businessError.errorNum = CallResult::SUCCESS;
auto miscBlockDev = Updater::GetBlockDeviceByMountPoint(MISC_PATH);
ENGINE_LOGI("FactoryReset::misc path : %{public}s", miscBlockDev.c_str());
ENGINE_CHECK(!miscBlockDev.empty(), miscBlockDev = MISC_FILE, "cannot get block device of partition");
const std::string suffix = forceFlag ? "\n--reset_enter:forceFactoryReset|" : "\n--reset_enter:factoryReset|";
const std::string paramData = CMD_WIPE_DATA + suffix + GetCallingAppId();
int32_t ret = RebootAndCleanUserData(miscBlockDev, paramData) ? INT_CALL_SUCCESS : INT_CALL_FAIL;
ENGINE_LOGI("FactoryReset result : %{public}d", ret);
SYS_EVENT_SYSTEM_RESET(
0, ret == INT_CALL_SUCCESS ? UpdateSystemEvent::EVENT_SUCCESS_RESULT : UpdateSystemEvent::EVENT_FAILED_RESULT);
return ret;
}
static int32_t ExecuteDeepReset(BusinessError &businessError, const FactoryResetStrategy factoryResetStrategy)
{
const std::string eraseType = (factoryResetStrategy.scope == FactoryResetScope::DATA) ? "DATA" : "DATA_AND_OS";
const std::string paramData = "\n--reset_enter:deepFactoryReset|" + GetCallingAppId();
bool result = RebootAndSecureErase(eraseType, paramData);
ENGINE_LOGI("ExecuteDeepReset: %{public}s", StringUtils::GetBoolStr(result).c_str());
return result ? INT_CALL_SUCCESS : INT_CALL_FAIL;
}
sptr<StorageManager::IStorageManager> UpdateServiceRestorer::GetStorageMgrProxy()
{
auto samgr = OHOS::SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
if (samgr == nullptr) {
ENGINE_LOGE("samgr empty error");
return nullptr;
}
auto remote = samgr->GetSystemAbility(OHOS::STORAGE_MANAGER_MANAGER_ID);
if (remote == nullptr) {
ENGINE_LOGE("storage manager client samgr ability empty error");
return nullptr;
}
auto storageMgrProxy = iface_cast<StorageManager::IStorageManager>(remote);
if (storageMgrProxy == nullptr) {
ENGINE_LOGE("storageMgrProxy empty error");
return nullptr;
}
return storageMgrProxy;
}
int32_t UpdateServiceRestorer::FileManagerEraseKeys()
{
sptr<StorageManager::IStorageManager> client = GetStorageMgrProxy();
if (client == nullptr) {
ENGINE_LOGE("get storage manager service failed");
return INT_CALL_FAIL;
}
return client->EraseAllUserEncryptedKeys();
}
int32_t UpdateServiceRestorer::FactoryReset(BusinessError &businessError)
{
#ifndef UPDATER_UT
return ExecReset(businessError, false);
#else
return INT_CALL_SUCCESS;
#endif
}
int32_t UpdateServiceRestorer::ForceFactoryReset(BusinessError &businessError)
{
int32_t ret = FileManagerEraseKeys();
if (ret != 0) {
ENGINE_LOGE("file manager erase keys error");
return INT_CALL_FAIL;
}
return ExecReset(businessError, true);
}
int32_t UpdateServiceRestorer::DeepFactoryReset(const FactoryResetStrategy factoryResetStrategy,
BusinessError &businessError)
{
ENGINE_LOGI("DeepFactoryReset, scope %{public}d, strategy %{public}s",
CAST_INT(factoryResetStrategy.scope), factoryResetStrategy.strategy.c_str());
businessError.errorNum = CallResult::SUCCESS;
if (factoryResetStrategy.scope != FactoryResetScope::DATA &&
factoryResetStrategy.scope !=FactoryResetScope::DATA_AND_OS) {
businessError.errorNum = CallResult::FAIL;
businessError.message = "strategy scope type error";
return INT_CALL_FAIL;
}
return ExecuteDeepReset(businessError, factoryResetStrategy);
}
int32_t UpdateServiceRestorer::GetDeepFactoryResetInfo(const FactoryResetStrategy factoryResetStrategy,
FactoryResetInfo &factoryResetInfo, BusinessError &businessError)
{
ENGINE_LOGI("GetDeepFactoryResetInfo, scope %{public}d, strategy %{public}s",
CAST_INT(factoryResetStrategy.scope), factoryResetStrategy.strategy.c_str());
businessError.errorNum = CallResult::SUCCESS;
if (factoryResetStrategy.scope != FactoryResetScope::DATA &&
factoryResetStrategy.scope !=FactoryResetScope::DATA_AND_OS) {
businessError.errorNum = CallResult::FAIL;
businessError.message = "strategy scope type error";
return INT_CALL_FAIL;
}
const std::string eraseType = (factoryResetStrategy.scope == FactoryResetScope::DATA) ? "DATA" : "DATA_AND_OS";
uint32_t uint = EstimatedEraseTime(eraseType);
factoryResetInfo.duration = static_cast<int>(uint);
ENGINE_LOGI("duration %{public}d", factoryResetInfo.duration);
return INT_CALL_SUCCESS;
}
}
}