【帐号】文件异常监控以及补充异常操作DFX打点

Signed-off-by: cclicn <lichenchen22@huawei.com>
This commit is contained in:
cclicn 2023-12-09 20:52:09 +08:00
parent a6b8f4a767
commit b4d92c46de
19 changed files with 1034 additions and 641 deletions

View File

@ -184,5 +184,24 @@ void ReportOhosAccountStateChange(int32_t userId, int32_t operateType, int32_t o
(void)newStat;
#endif // HAS_HISYSEVENT_PART
}
void ReportOsAccountDataTampered(int32_t id, const std::string& dataPath, const std::string& dataLabel)
{
#ifdef HAS_HISYSEVENT_PART
int ret = HiSysEventWrite(HiSysEvent::Domain::ACCOUNT, "DATA_TAMPERED",
HiSysEvent::EventType::SECURITY,
"ID", id,
"DATA_PATH", dataPath,
"DATA_LABEL", dataLabel);
if (ret != 0) {
ACCOUNT_LOGE("sysevent write failed, ret %{public}d, id %{public}d, dataPath %{public}s, dataLabel %{public}s.",
ret, id, dataPath.c_str(), dataLabel.c_str());
}
#else // HAS_HISYSEVENT_PART
(void)id;
(void)dataPath;
(void)dataLabel;
#endif // HAS_HISYSEVENT_PART
}
} // AccountSA
} // OHOS

View File

@ -31,6 +31,7 @@ void ReportAppAccountOperationFail(const std::string &name, const std::string &o
void ReportOsAccountLifeCycle(int32_t id, const std::string& operationStr);
void ReportOsAccountSwitch(int32_t currentId, int32_t oldId);
void ReportOhosAccountStateChange(int32_t userId, int32_t operateType, int32_t oldStat, int32_t newStat);
void ReportOsAccountDataTampered(int32_t id, const std::string& dataPath, const std::string& dataLabel);
} // AccountSA
} // OHOS
#endif // OS_ACCOUNT_DFX_HISYSEVENT_ADAPTER_H

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2021-2022 Huawei Device Co., Ltd.
* Copyright (c) 2021-2023 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
@ -37,16 +37,18 @@ public:
bool IsJsonFormat(const std::string &path);
bool IsJsonFileReady(const std::string &path);
bool IsExistDir(const std::string &path);
bool GetValidWriteFileOptFlag();
void SetValidWriteFileOptFlag(bool flag);
void SetValidDeleteFileOptFlag(const std::string &fileName, bool flag);
bool GetValidDeleteFileOptFlag(const std::string &fileName);
bool GetValidDeleteFileOperationFlag(const std::string &fileName);
void SetValidDeleteFileOperationFlag(const std::string &fileName, bool flag);
bool GetValidModifyFileOperationFlag(const std::string &fileName);
void SetValidModifyFileOperationFlag(const std::string &fileName, bool flag);
std::mutex &GetModifyOperationLock();
std::mutex &GetDeleteOperationLock();
private:
std::mutex validWriteFileOptLock_;
std::mutex validDeleteFileOptLock_;
bool validWriteFileOptFlag_ = false;
std::vector<std::string> validDeleteFileOptFlag_;
std::mutex validModifyFileOperationLock_;
std::mutex validDeleteFileOperationLock_;
std::vector<std::string> validModifyFileOperationFlag_;
std::vector<std::string> validDeleteFileOperationFlag_;
};
} // namespace AccountSA
} // namespace OHOS

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2021-2022 Huawei Device Co., Ltd.
* Copyright (c) 2021-2023 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
@ -13,7 +13,6 @@
* limitations under the License.
*/
#include "account_file_operator.h"
#include <algorithm>
#include <cerrno>
#include <cstdio>
#include <fstream>
@ -32,6 +31,9 @@
#include "hisysevent_adapter.h"
namespace OHOS {
namespace AccountSA {
namespace {
const std::string ACCOUNT_INFO_DIGEST_FILE_PATH = "account_info_digest.json";
}
AccountFileOperator::AccountFileOperator()
{}
@ -58,9 +60,9 @@ ErrCode AccountFileOperator::CreateDir(const std::string &path)
ErrCode AccountFileOperator::DeleteDirOrFile(const std::string &path)
{
std::lock_guard<std::mutex> lock(validDeleteFileOptLock_);
std::lock_guard<std::mutex> lock(validDeleteFileOperationLock_);
bool delFlag = false;
validDeleteFileOptFlag_.emplace_back(path);
SetValidDeleteFileOperationFlag(path, true);
if (IsExistFile(path)) {
delFlag = OHOS::RemoveFile(path);
}
@ -69,45 +71,68 @@ ErrCode AccountFileOperator::DeleteDirOrFile(const std::string &path)
}
if (!delFlag) {
ACCOUNT_LOGE("DeleteDirOrFile failed, path %{public}s errno %{public}d.", path.c_str(), errno);
SetValidDeleteFileOperationFlag(path, false);
return ERR_OSACCOUNT_SERVICE_FILE_DELE_ERROR;
validDeleteFileOptFlag_.erase(std::remove(validDeleteFileOptFlag_.begin(), validDeleteFileOptFlag_.end(), path),
validDeleteFileOptFlag_.end());
}
return ERR_OK;
}
void AccountFileOperator::SetValidDeleteFileOptFlag(const std::string &fileName, bool flag)
std::mutex &AccountFileOperator::GetModifyOperationLock()
{
std::lock_guard<std::mutex> lock(validDeleteFileOptLock_);
if (flag) {
validDeleteFileOptFlag_.emplace_back(fileName);
return;
}
validDeleteFileOptFlag_.erase(std::remove(validDeleteFileOptFlag_.begin(), validDeleteFileOptFlag_.end(), fileName),
validDeleteFileOptFlag_.end());
return validModifyFileOperationLock_;
}
bool AccountFileOperator::GetValidDeleteFileOptFlag(const std::string &fileName)
std::mutex &AccountFileOperator::GetDeleteOperationLock()
{
std::lock_guard<std::mutex> lock(validDeleteFileOptLock_);
for (const auto &iter : validDeleteFileOptFlag_) {
if (fileName.find(iter) != std::string::npos) {
return validDeleteFileOperationLock_;
}
void AccountFileOperator::SetValidModifyFileOperationFlag(const std::string &fileName, bool flag)
{
if (fileName.find(ACCOUNT_INFO_DIGEST_FILE_PATH) != std::string::npos) { // ignore digest file record
return;
}
if (!flag) {
validModifyFileOperationFlag_.erase(
std::remove(validModifyFileOperationFlag_.begin(), validModifyFileOperationFlag_.end(), fileName),
validModifyFileOperationFlag_.end());
return;
}
if (std::find(validModifyFileOperationFlag_.begin(), validModifyFileOperationFlag_.end(), fileName) ==
validModifyFileOperationFlag_.end()) {
validModifyFileOperationFlag_.emplace_back(fileName);
}
}
bool AccountFileOperator::GetValidModifyFileOperationFlag(const std::string &fileName)
{
for (auto iter : validModifyFileOperationFlag_) {
if (iter == fileName) {
return true;
}
}
return false;
}
void AccountFileOperator::SetValidWriteFileOptFlag(bool flag)
void AccountFileOperator::SetValidDeleteFileOperationFlag(const std::string &fileName, bool flag)
{
std::lock_guard<std::mutex> lock(validWriteFileOptLock_);
validWriteFileOptFlag_ = flag;
if (!flag) {
validDeleteFileOperationFlag_.erase(
std::remove(validDeleteFileOperationFlag_.begin(), validDeleteFileOperationFlag_.end(), fileName),
validDeleteFileOperationFlag_.end());
return;
}
validDeleteFileOperationFlag_.emplace_back(fileName);
}
bool AccountFileOperator::GetValidWriteFileOptFlag()
bool AccountFileOperator::GetValidDeleteFileOperationFlag(const std::string &fileName)
{
std::lock_guard<std::mutex> lock(validWriteFileOptLock_);
return validWriteFileOptFlag_;
for (auto iter : validDeleteFileOperationFlag_) {
if (fileName.find(iter) != std::string::npos) {
return true;
}
}
return false;
}
ErrCode AccountFileOperator::InputFileByPathAndContent(const std::string &path, const std::string &content)
@ -121,12 +146,12 @@ ErrCode AccountFileOperator::InputFileByPathAndContent(const std::string &path,
return errCode;
}
}
std::lock_guard<std::mutex> lock(validWriteFileOptLock_);
validWriteFileOptFlag_ = true;
std::lock_guard<std::mutex> lock(validModifyFileOperationLock_);
SetValidModifyFileOperationFlag(path, true);
FILE *fp = fopen(path.c_str(), "wb");
if (fp == nullptr) {
ACCOUNT_LOGE("failed to open %{public}s, errno %{public}d.", path.c_str(), errno);
validWriteFileOptFlag_ = false;
SetValidModifyFileOperationFlag(path, false);
return ERR_ACCOUNT_COMMON_FILE_OPEN_FAILED;
}
do {
@ -152,12 +177,13 @@ ErrCode AccountFileOperator::InputFileByPathAndContent(const std::string &path,
// change mode
if (!ChangeModeFile(path, S_IRUSR | S_IWUSR)) {
ACCOUNT_LOGW("failed to change mode for file %{public}s, errno %{public}d.", path.c_str(), errno);
return ERR_OHOSACCOUNT_SERVICE_FILE_CHANGE_DIR_MODE_ERROR;
}
return ERR_OK;
} while (0);
flock(fileno(fp), LOCK_UN);
fclose(fp);
validWriteFileOptFlag_ = false;
SetValidModifyFileOperationFlag(path, false);
return ERR_ACCOUNT_COMMON_FILE_WRITE_FAILED;
}

View File

@ -61,4 +61,10 @@ DISTRIBUTED_ACCOUNT_CHANGE:
USER_ID: {type: INT32, desc: local account id}
OPERATION_TYPE: {type: INT32, desc: operation type}
OLD_STATE: {type: INT32, desc: ohos account old state}
NEW_STATE: {type: INT32, desc: ohos account new state}
NEW_STATE: {type: INT32, desc: ohos account new state}
DATA_TAMPERED:
__BASE: {type: SECURITY, level: CRITICAL, desc: account data is tampered}
ID: {type: INT32, desc: the id of os account which is tampered}
DATA_PATH: {type: STRING, desc: the file path which is tampered}
DATA_LABEL: {type: STRING, desc: the data label which is tampered}

View File

@ -0,0 +1,90 @@
/*
* Copyright (c) 2023 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.
*/
#ifndef OS_ACCOUNT_SERVICES_ACCOUNTMGR_INCLUDE_ACCOUNT_FILE_WATCHER_MANAGER_H
#define OS_ACCOUNT_SERVICES_ACCOUNTMGR_INCLUDE_ACCOUNT_FILE_WATCHER_MANAGER_H
#include <mutex>
#include <sys/inotify.h>
#include <sys/time.h>
#include "account_error_no.h"
#include "account_file_operator.h"
#include "singleton.h"
namespace OHOS {
namespace AccountSA {
int32_t GenerateAccountInfoDigest(const std::string &inData, uint8_t* outData, uint32_t size);
using CheckNotifyEventCallbackFunc = std::function<bool(const std::string&, const int32_t, uint32_t)>;
class FileWatcher {
public:
FileWatcher(const int32_t id);
FileWatcher(const std::string &filePath);
~FileWatcher();
bool InitNotify();
int32_t GetNotifyId();
std::string GetFilePath();
int32_t GetLocalId();
bool StartNotify(const uint32_t &watchEvents);
bool CloseNotifyFd();
bool CheckNotifyEvent(uint32_t event);
void SetEventCallback(CheckNotifyEventCallbackFunc &func);
public:
int32_t id_ = -1;
private:
int32_t notifyFd_ = -1;
int32_t wd_ = -1;
std::string filePath_;
CheckNotifyEventCallbackFunc eventCallbackFunc_;
};
class AccountFileWatcherMgr {
public:
static AccountFileWatcherMgr &GetInstance();
void StartWatch();
void AddFileWatcher(
const int32_t id, CheckNotifyEventCallbackFunc checkCallbackFunc, const std::string filePath = "");
void RemoveFileWatcher(const int32_t id, const std::string filePath);
ErrCode GetAccountInfoDigestFromFile(const std::string &path, uint8_t *digest, uint32_t size);
ErrCode GenerateAccountInfoDigestStr(
const std::string &userInfoPath, const std::string &accountInfoStr, std::string &digestStr);
ErrCode AddAccountInfoDigest(const std::string accountInfo, const std::string &userInfoPath);
ErrCode DeleteAccountInfoDigest(const std::string &userInfoPath);
private:
void DealWithFileEvent();
void GetNotifyEvent();
AccountFileWatcherMgr();
~AccountFileWatcherMgr();
DISALLOW_COPY_AND_MOVE(AccountFileWatcherMgr);
public:
std::mutex accountInfoDigestFileLock_;
std::mutex fileWatcherMgrLock_;
std::shared_ptr<AccountFileOperator> accountFileOperator_;
std::unordered_map<int32_t, std::shared_ptr<FileWatcher>> fileNameMgrMap_;
fd_set fds_;
int32_t maxNotifyFd_ = -1;
std::vector<int32_t> fdArray_;
bool run_ = false;
};
} // namespace AccountSA
} // namespace OHOS
#endif // OS_ACCOUNT_SERVICES_ACCOUNTMGR_INCLUDE_OSACCOUNT_OS_ACCOUNT_CONTROL_FILE_MANAGER_H

View File

@ -128,23 +128,25 @@ private:
class GetPropCallbackWrapper : public GetPropCallback {
public:
GetPropCallbackWrapper(const sptr<IGetSetPropCallback> &callback);
GetPropCallbackWrapper(int32_t userId, const sptr<IGetSetPropCallback> &callback);
virtual ~GetPropCallbackWrapper() = default;
void OnResult(int32_t result, const Attributes &extraInfo) override;
private:
int32_t userId_;
sptr<IGetSetPropCallback> innerCallback_;
};
class SetPropCallbackWrapper : public SetPropCallback {
public:
SetPropCallbackWrapper(const sptr<IGetSetPropCallback> &callback);
SetPropCallbackWrapper(int32_t userId, const sptr<IGetSetPropCallback> &callback);
virtual ~SetPropCallbackWrapper() = default;
void OnResult(int32_t result, const Attributes &extraInfo) override;
private:
int32_t userId_;
sptr<IGetSetPropCallback> innerCallback_;
};

View File

@ -20,6 +20,8 @@
#include <mutex>
#include <nlohmann/json.hpp>
#include "account_error_no.h"
#include "account_file_operator.h"
#include "account_file_watcher_manager.h"
#include "account_info.h"
namespace OHOS {
@ -32,18 +34,28 @@ public:
ErrCode Init(std::int32_t userId);
ErrCode AccountInfoFromJson(AccountInfo &accountInfo, int32_t userId);
ErrCode AccountInfoToJson(const AccountInfo &accountInfo) const;
ErrCode AccountInfoToJson(const AccountInfo &accountInfo);
~OhosAccountDataDeal() {}
private:
bool DealWithFileModifyEvent(const std::string &fileName, const int32_t id);
void DealWithFileDeleteEvent(const std::string &fileName, const int32_t id);
bool initOk_;
std::string configFileDir_;
std::mutex mutex_;
void BuildJsonFileFromScratch(int32_t userId) const;
ErrCode SaveAccountInfo(const AccountInfo &accountInfo) const;
void BuildJsonFileFromScratch(int32_t userId);
ErrCode SaveAccountInfo(const AccountInfo &accountInfo);
ErrCode GetAccountInfo(AccountInfo &accountInfo, const int32_t userId);
ErrCode ParseJsonFromFile(const std::string &filePath, nlohmann::json &jsonData, int32_t userId);
ErrCode GetAccountInfoFromJson(const nlohmann::json &jsonData, AccountInfo &accountInfo, const int32_t userId);
ErrCode GenerateAccountInfoDigestStr(
const std::string &userInfoPath, const std::string &accountInfoStr, std::string &digestStr);
void AddFileWatcher(const int32_t id);
std::mutex accountInfoFileLock_;
std::shared_ptr<AccountFileOperator> accountFileOperator_;
AccountFileWatcherMgr &accountFileWatcherMgr_;
CheckNotifyEventCallbackFunc checkCallbackFunc_;
};
} // namespace AccountSA
} // namespace OHOS

View File

@ -19,6 +19,7 @@
#include <memory>
#include <mutex>
#include <sys/inotify.h>
#include "account_file_watcher_manager.h"
#include "ios_account_control.h"
#include "os_account_constants.h"
#ifdef HAS_KV_STORE_PART
@ -32,30 +33,6 @@ using CheckNotifyEventCallbackFunc = std::function<bool(const std::string&, cons
bool GetValidAccountID(const std::string& dirName, std::int32_t& accountID);
class FileWatcher {
public:
FileWatcher(const int32_t id);
FileWatcher(const std::string &filePath);
~FileWatcher();
bool InitNotify();
int32_t GetNotifyId();
std::string GetFilePath();
int32_t GetLocalId();
bool StartNotify(const uint32_t &watchEvents);
bool CloseNotifyFd();
bool CheckNotifyEvent(uint32_t event);
void SetEventCallback(CheckNotifyEventCallbackFunc &func);
private:
int32_t notifyFd_ = -1;
int32_t id_ = -1;
int32_t wd_ = -1;
std::string filePath_;
CheckNotifyEventCallbackFunc eventCallbackFunc_;
};
class OsAccountControlFileManager : public IOsAccountControl {
public:
OsAccountControlFileManager();
@ -115,6 +92,7 @@ public:
ErrCode UpdateAccountIndex(const OsAccountInfo &osAccountInfo, const bool isDelete) override;
private:
ErrCode RemoveAccountIndex(const int32_t id);
int GetNextLocalId(const std::vector<std::string> &accountIdList);
ErrCode UpdateAccountList(const std::string &idStr, bool isAdd);
ErrCode GetAccountListFromFile(Json& accountListJson);
@ -124,6 +102,7 @@ private:
void BuildAndSaveAccountListJsonFile(const std::vector<std::string>& accounts);
void RecoverAccountListJsonFile();
void RecoverAccountInfoDigestJsonFile();
void BuildAndSaveOsAccountIndexJsonFile();
void BuildAndSaveBaseOAConstraintsJsonFile();
void BuildAndSaveGlobalOAConstraintsJsonFile();
void BuildAndSaveSpecificOAConstraintsJsonFile();
@ -144,16 +123,11 @@ private:
ErrCode RemoveOAGlobalConstraintsInfo(const int32_t id);
ErrCode RemoveOASpecificConstraintsInfo(const int32_t id);
ErrCode GetAccountInfoDigestFromFile(const std::string &path, uint8_t *digest, uint32_t size);
void WatchOsAccountInfoFile();
void AddFileWatcher(const int32_t id);
void RemoveFileWatcher(const int32_t id);
void GetNotifyEvent();
void DealWithFileEvent();
bool DealWithFileModifyEvent(const std::string &fileName, const int32_t id);
bool DealWithFileDeleteEvent(const std::string &fileName, const int32_t id);
bool DealWithFileMoveEvent(const std::string &fileName, const int32_t id);
void InitFileWatcherInfo(std::vector<std::string> &accountIdList);
void SubscribeEventFunction(std::shared_ptr<FileWatcher> &fileWatcher);
bool RecoverAccountData(const std::string &fileName, const int32_t id);
private:
@ -164,20 +138,16 @@ private:
std::int32_t nextLocalId_ = Constants::START_USER_ID;
std::shared_ptr<OsAccountFileOperator> osAccountFileOperator_;
std::shared_ptr<OsAccountPhotoOperator> osAccountPhotoOperator_;
AccountFileWatcherMgr &accountFileWatcherMgr_;
std::mutex fileWatcherMgrLock_;
std::mutex accountListFileLock_;
std::mutex accountInfoFileLock_;
std::mutex accountInfoDigestFileLock_;
std::mutex operatingIdMutex_;
std::mutex baseOAConstraintsFileLock_;
std::mutex globalOAConstraintsFileLock_;
std::mutex specificOAConstraintsFileLock_;
std::unordered_map<int32_t, std::shared_ptr<FileWatcher>> fileNameMgrMap_;
fd_set fds_;
int32_t maxNotifyFd_ = -1;
std::vector<int32_t> fdArray_;
bool run_ = false;
CheckNotifyEventCallbackFunc eventCallbackFunc_;
};
} // namespace AccountSA
} // namespace OHOS

View File

@ -115,7 +115,7 @@
"OHOS::AccountSA::DelCredCallback::DelCredCallback(int, bool, OHOS::sptr<OHOS::AccountSA::IIDMCallback> const&)";
"OHOS::AccountSA::DomainAccountPluginProxy::DomainAccountPluginProxy(OHOS::sptr<OHOS::IRemoteObject> const&)";
"OHOS::AccountSA::GetCredInfoCallbackWrapper::GetCredInfoCallbackWrapper(int, int, OHOS::sptr<OHOS::AccountSA::IGetCredInfoCallback> const&)";
"OHOS::AccountSA::GetPropCallbackWrapper::GetPropCallbackWrapper(OHOS::sptr<OHOS::AccountSA::IGetSetPropCallback> const&)";
"OHOS::AccountSA::GetPropCallbackWrapper::GetPropCallbackWrapper(int, OHOS::sptr<OHOS::AccountSA::IGetSetPropCallback> const&)";
"OHOS::AccountSA::GetValidAccountID(std::__h::basic_string<char, std::__h::char_traits<char>, std::__h::allocator<char>> const&, int&)";
"OHOS::AccountSA::IAccountContext::instance_";
"OHOS::AccountSA::AccountMgrService::GetCallingUserID()";
@ -225,7 +225,7 @@
"OHOS::AccountSA::SessionConnection::SessionConnection(std::__h::basic_string<char, std::__h::char_traits<char>, std::__h::allocator<char>> const&)";
"OHOS::AccountSA::SessionServerDeathRecipient::OnRemoteDied(OHOS::wptr<OHOS::IRemoteObject> const&)";
"OHOS::AccountSA::SessionServerDeathRecipient::SessionServerDeathRecipient(std::__h::basic_string<char, std::__h::char_traits<char>, std::__h::allocator<char>> const&)";
"OHOS::AccountSA::SetPropCallbackWrapper::SetPropCallbackWrapper(OHOS::sptr<OHOS::AccountSA::IGetSetPropCallback> const&)";
"OHOS::AccountSA::SetPropCallbackWrapper::SetPropCallbackWrapper(int, OHOS::sptr<OHOS::AccountSA::IGetSetPropCallback> const&)";
"vtable for OHOS::AccountSA::AccountStub";
"OHOS::AccountSA::AccountStub::AccountStub()";
"vtable for OHOS::AccountSA::OsAccountStopUserCallback";
@ -246,6 +246,7 @@
"OHOS::AccountSA::UpdateTraceLabelAdapter()";
"OHOS::AccountSA::StartTraceAdapter(std::__h::basic_string<char, std::__h::char_traits<char>, std::__h::allocator<char>> const&)";
*OHOS::AccountSA::CountTraceAdapter*;
*OHOS::AccountSA::AccountFileWatcherMgr*;
"OHOS::AccountSA::FinishTraceAdapter()";
"OHOS::AccountSA::DomainAccountStub::DomainAccountStub()";
"OHOS::AccountSA::DomainAccountStub::~DomainAccountStub()";
@ -278,6 +279,7 @@
"non-virtual thunk to OHOS::AccountSA::AccountIAMMgrStub::~AccountIAMMgrStub()";
"virtual thunk to OHOS::AccountSA::AccountIAMMgrStub::~AccountIAMMgrStub()";
"OHOS::AccountSA::InnerDomainAccountManager::AuthUser(int, std::__h::vector<unsigned char, std::__h::allocator<unsigned char>> const&, OHOS::sptr<OHOS::AccountSA::IDomainAccountCallback> const&)";
"OHOS::AccountSA::GenerateAccountInfoDigest(std::__h::basic_string<char, std::__h::char_traits<char>, std::__h::allocator<char>> const&, unsigned char*, unsigned int)";
};
local:
*;

View File

@ -14,6 +14,7 @@ import("../../os_account.gni")
account_service_sources = [
"${services_path}/accountmgr/src/account_event_provider.cpp",
"${services_path}/accountmgr/src/account_event_subscribe.cpp",
"${services_path}/accountmgr/src/account_file_watcher_manager.cpp",
"${services_path}/accountmgr/src/account_helper_data.cpp",
"${services_path}/accountmgr/src/account_info_report.cpp",
"${services_path}/accountmgr/src/account_mgr_service.cpp",

View File

@ -0,0 +1,529 @@
/*
* Copyright (c) 2023 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 "account_file_watcher_manager.h"
#include <dlfcn.h>
#ifdef WITH_SELINUX
#include <policycoreutils.h>
#endif // WITH_SELINUX
#include <pthread.h>
#include <securec.h>
#include <thread>
#include "account_log_wrapper.h"
#include "hks_api.h"
#include "hks_param.h"
#include "hks_type.h"
#include "os_account_constants.h"
namespace OHOS {
namespace AccountSA {
namespace {
const uint32_t BUF_COMMON_SIZE = 1024;
const uint32_t SELECT_WAIT_TIME = 1000;
const struct HksParam g_genSignVerifyParams[] = {
{
.tag = HKS_TAG_ALGORITHM,
.uint32Param = HKS_ALG_HMAC
}, {
.tag = HKS_TAG_PURPOSE,
.uint32Param = HKS_KEY_PURPOSE_MAC
}, {
.tag = HKS_TAG_KEY_SIZE,
.uint32Param = HKS_AES_KEY_SIZE_256
}, {
.tag = HKS_TAG_DIGEST,
.uint32Param = HKS_DIGEST_SHA256
}
};
const uint32_t ALG_COMMON_SIZE = 32;
const int32_t TIMES = 4;
const int32_t MAX_UPDATE_SIZE = 256;
const int32_t MAX_OUTDATA_SIZE = MAX_UPDATE_SIZE * TIMES;
const char ACCOUNT_KEY_ALIAS[] = "os_account_info_encryption_key";
const HksBlob g_keyAlias = { (uint32_t)strlen(ACCOUNT_KEY_ALIAS), (uint8_t *)ACCOUNT_KEY_ALIAS };
}
static int32_t InitParamSet(struct HksParamSet **paramSet, const struct HksParam *params, uint32_t paramCount)
{
int32_t ret = HksInitParamSet(paramSet);
if (ret != 0) {
ACCOUNT_LOGE("HksInitParamSet err = %{public}d", ret);
return ret;
}
ret = HksAddParams(*paramSet, params, paramCount);
if (ret != 0) {
ACCOUNT_LOGE("HksAddParams err = %{public}d", ret);
HksFreeParamSet(paramSet);
return ret;
}
ret = HksBuildParamSet(paramSet);
if (ret != 0) {
ACCOUNT_LOGE("HksBuildParamSet err = %{public}d", ret);
HksFreeParamSet(paramSet);
return ret;
}
return ret;
}
static int32_t MallocAndCheckBlobData(struct HksBlob *blob, const uint32_t blobSize)
{
if (blobSize == 0) {
blob->data = NULL;
return -1;
}
blob->data = (uint8_t *)malloc(blobSize);
if (blob->data == NULL) {
ACCOUNT_LOGE("MallocAndCheckBlobData err");
return -1;
}
return 0;
}
static int32_t HksUpdateOpt(
const struct HksBlob *handle, const struct HksParamSet *paramSet, const struct HksBlob *inData)
{
struct HksBlob inDataSeg = *inData;
inDataSeg.size = MAX_UPDATE_SIZE;
uint8_t *lastPtr = inData->data + inData->size - 1;
struct HksBlob outDataSeg = {
.size = MAX_OUTDATA_SIZE,
.data = NULL
};
bool isFinished = false;
while (inDataSeg.data <= lastPtr) {
if (inDataSeg.data + MAX_UPDATE_SIZE <= lastPtr) {
outDataSeg.size = MAX_OUTDATA_SIZE;
} else {
isFinished = true;
inDataSeg.size = lastPtr - inDataSeg.data + 1;
outDataSeg.size = inDataSeg.size + MAX_UPDATE_SIZE;
}
if (MallocAndCheckBlobData(&outDataSeg, outDataSeg.size) != 0) {
return -1;
}
int32_t ret = HksUpdate(handle, paramSet, &inDataSeg, &outDataSeg);
if (ret != 0) {
ACCOUNT_LOGE("HksUpdate err, ret = %{public}d", ret);
free(outDataSeg.data);
outDataSeg.data = NULL;
return -1;
}
free(outDataSeg.data);
outDataSeg.data = NULL;
if ((isFinished == false) && (inDataSeg.data + MAX_UPDATE_SIZE > lastPtr)) {
return 0;
}
inDataSeg.data += MAX_UPDATE_SIZE;
}
return 0;
}
static int32_t InitEncryptionKey()
{
struct HksParamSet *genParamSet = nullptr;
int32_t ret;
do {
ret = InitParamSet(&genParamSet, g_genSignVerifyParams, sizeof(g_genSignVerifyParams) / sizeof(HksParam));
if (ret != 0) {
ACCOUNT_LOGE("InitParamSet genParamSet err = %{public}d", ret);
break;
}
ret = HksGenerateKey(&g_keyAlias, genParamSet, nullptr);
if (ret != 0) {
ACCOUNT_LOGE("HksGenerateKey err = %{public}d", ret);
break;
}
} while (0);
HksFreeParamSet(&genParamSet);
return ret;
}
static int32_t GetDigestDataFromHuks(struct HksParamSet *genParamSet, struct HksBlob &inDataBlob,
uint8_t* outData, uint32_t size)
{
uint8_t handleTmp[sizeof(uint64_t)] = {0};
struct HksBlob handleGenDigest = { (uint32_t)sizeof(uint64_t), handleTmp };
int32_t ret = HksInit(&g_keyAlias, genParamSet, &handleGenDigest, nullptr);
if (ret != 0) {
ACCOUNT_LOGE("HksInit err = %{public}d", ret);
return ret;
}
ret = HksUpdateOpt(&handleGenDigest, genParamSet, &inDataBlob);
if (ret != 0) {
ACCOUNT_LOGE("HksUpdateOpt err = %{public}d", ret);
HksAbort(&handleGenDigest, genParamSet);
return ret;
}
struct HksBlob finishOut = { 0, nullptr };
uint8_t outDataS[ALG_COMMON_SIZE] = "out";
struct HksBlob outDataBlob = { ALG_COMMON_SIZE, outDataS };
ret = HksFinish(&handleGenDigest, genParamSet, &finishOut, &outDataBlob);
if (ret != 0) {
ACCOUNT_LOGE("HksFinish failed = %{public}d", ret);
HksAbort(&handleGenDigest, genParamSet);
return ret;
}
if (memcpy_s(outData, size, outDataS, outDataBlob.size) != EOK) {
ACCOUNT_LOGE("Get digest failed duo to memcpy_s failed");
return -1;
}
return 0;
}
int32_t GenerateAccountInfoDigest(const std::string &inData, uint8_t* outData, uint32_t size)
{
if (inData.empty()) {
ACCOUNT_LOGW("inData is empty.");
return 0;
}
size_t len = inData.size() + 1;
uint8_t *buffer = static_cast<uint8_t *>(malloc(len));
if (buffer == nullptr) {
ACCOUNT_LOGE("buffer malloc err");
return -1;
}
(void)memcpy_s(buffer, len, inData.c_str(), len);
struct HksBlob inDataBlob = { inData.size(), buffer };
struct HksParamSet *genParamSet = nullptr;
int32_t ret = InitParamSet(&genParamSet, g_genSignVerifyParams, sizeof(g_genSignVerifyParams) / sizeof(HksParam));
if (ret != 0) {
free(buffer);
ACCOUNT_LOGE("InitParamSet err = %{public}d", ret);
return ret;
}
ret = GetDigestDataFromHuks(genParamSet, inDataBlob, outData, size);
HksFreeParamSet(&genParamSet);
free(buffer);
return ret;
}
AccountFileWatcherMgr::AccountFileWatcherMgr()
{
InitEncryptionKey();
accountFileOperator_ = std::make_shared<AccountFileOperator>();
FD_ZERO(&fds_);
}
AccountFileWatcherMgr &AccountFileWatcherMgr::GetInstance()
{
static AccountFileWatcherMgr *instance = new AccountFileWatcherMgr();
return *instance;
}
void AccountFileWatcherMgr::DealWithFileEvent()
{
std::vector<std::pair<std::shared_ptr<FileWatcher>, uint32_t>> eventMap;
{
std::lock_guard<std::mutex> lock(fileWatcherMgrLock_);
for (int32_t i : fdArray_) {
if (FD_ISSET(i, &fds_)) { // check which fd has event
char buf[BUF_COMMON_SIZE] = {0};
struct inotify_event *event = nullptr;
int len, index = 0;
while (((len = read(i, &buf, sizeof(buf))) < 0) && (errno == EINTR)) {};
while (index < len) {
event = reinterpret_cast<inotify_event *>(buf + index);
std::shared_ptr<FileWatcher> fileWatcher = fileNameMgrMap_[i];
eventMap.emplace_back(std::make_pair(fileWatcher, event->mask));
index += sizeof(struct inotify_event) + event->len;
}
} else {
FD_SET(i, &fds_);
}
}
}
for (auto it : eventMap) {
it.first->CheckNotifyEvent(it.second);
}
return;
}
void AccountFileWatcherMgr::GetNotifyEvent()
{
while (run_) {
if (maxNotifyFd_ < 0) {
ACCOUNT_LOGE("failed to run notify because no fd available.");
continue;
}
for (int32_t i : fdArray_) {
FD_SET(i, &fds_);
}
struct timeval timeout = { 0, SELECT_WAIT_TIME }; // select wait time 1000us
if (select(maxNotifyFd_ + 1, &fds_, nullptr, nullptr, &timeout) <= 0) {
continue;
}
DealWithFileEvent();
}
}
void AccountFileWatcherMgr::StartWatch() // start watcher
{
if (run_) {
return;
}
run_ = true;
#ifdef WITH_SELINUX
Restorecon(Constants::ACCOUNT_INFO_DIGEST_FILE_PATH.c_str());
#endif // WITH_SELINUX
auto task = std::bind(&AccountFileWatcherMgr::GetNotifyEvent, this);
std::thread taskThread(task);
pthread_setname_np(taskThread.native_handle(), "fileWatcher");
taskThread.detach();
}
void AccountFileWatcherMgr::AddFileWatcher(
const int32_t id, CheckNotifyEventCallbackFunc checkCallbackFunc, const std::string filePath)
{
std::shared_ptr<FileWatcher> fileWatcher;
if (!filePath.empty()) {
fileWatcher = std::make_shared<FileWatcher>(filePath);
fileWatcher->id_ = id;
} else {
fileWatcher = std::make_shared<FileWatcher>(id);
}
if (!fileWatcher->InitNotify()) {
ACCOUNT_LOGI("fileWatcher InitNotify failed");
return;
}
fileWatcher->SetEventCallback(checkCallbackFunc);
if (!fileWatcher->StartNotify(IN_MODIFY | IN_DELETE_SELF| IN_MOVE_SELF)) {
ACCOUNT_LOGI("fileWatcher StartNotify failed, fileName = %{public}s", filePath.c_str());
return;
}
std::lock_guard<std::mutex> lock(fileWatcherMgrLock_);
if (fileWatcher->GetNotifyId() > maxNotifyFd_) {
maxNotifyFd_ = fileWatcher->GetNotifyId();
}
fileNameMgrMap_[fileWatcher->GetNotifyId()] = fileWatcher;
fdArray_.emplace_back(fileWatcher->GetNotifyId());
{
std::lock_guard<std::mutex> filelock(accountFileOperator_->GetModifyOperationLock());
accountFileOperator_->SetValidModifyFileOperationFlag(filePath, false);
}
FD_SET(fileWatcher->GetNotifyId(), &fds_);
StartWatch();
}
void AccountFileWatcherMgr::RemoveFileWatcher(const int32_t id, const std::string filePath)
{
std::lock_guard<std::mutex> lock(fileWatcherMgrLock_);
int targetFd = -1;
for (auto it : fileNameMgrMap_) {
if ((it.second->GetLocalId() == id) && (it.second->GetFilePath() == filePath)) {
targetFd = it.second->GetNotifyId();
break;
}
}
if (targetFd == -1) {
return;
}
FD_CLR(targetFd, &fds_);
if (!fileNameMgrMap_[targetFd]->CloseNotifyFd()) {
ACCOUNT_LOGE("failed to close notifyId, userId = %{public}d", id);
}
fdArray_.erase(
std::remove(fdArray_.begin(), fdArray_.end(), targetFd), fdArray_.end());
if (maxNotifyFd_ == targetFd) {
maxNotifyFd_ = *max_element(fdArray_.begin(), fdArray_.end());
}
fileNameMgrMap_.erase(targetFd);
return;
}
ErrCode AccountFileWatcherMgr::GetAccountInfoDigestFromFile(const std::string &path, uint8_t *digest, uint32_t size)
{
Json accountInfoDigestJson;
std::string accountInfoDigest;
std::lock_guard<std::mutex> lock(accountInfoDigestFileLock_);
ErrCode errCode = accountFileOperator_->GetFileContentByPath(Constants::ACCOUNT_INFO_DIGEST_FILE_PATH,
accountInfoDigest);
if (errCode != ERR_OK) {
ACCOUNT_LOGE("GetFileContentByPath failed! error code %{public}d.", errCode);
return errCode;
}
try {
accountInfoDigestJson = Json::parse(accountInfoDigest, nullptr, false);
} catch (Json::type_error& err) {
ACCOUNT_LOGE("accountInfoDigestJson parse failed! reason: %{public}s", err.what());
return ERR_ACCOUNT_COMMON_DUMP_JSON_ERROR;
}
std::vector<uint8_t> digestTmp;
OHOS::AccountSA::GetDataByType<std::vector<uint8_t>>(accountInfoDigestJson,
accountInfoDigestJson.end(), path, digestTmp, OHOS::AccountSA::JsonType::ARRAY);
if (memcpy_s(digest, size, digestTmp.data(), ALG_COMMON_SIZE) != EOK) {
ACCOUNT_LOGE("Get digest failed duo to memcpy_s failed");
return ERR_ACCOUNT_COMMON_INSUFFICIENT_MEMORY_ERROR;
}
return ERR_OK;
}
ErrCode AccountFileWatcherMgr::GenerateAccountInfoDigestStr(
const std::string &userInfoPath, const std::string &accountInfoStr, std::string &digestStr)
{
uint8_t digestOutData[ALG_COMMON_SIZE];
GenerateAccountInfoDigest(accountInfoStr, digestOutData, ALG_COMMON_SIZE);
std::string accountInfoDigest;
std::lock_guard<std::mutex> lock(accountInfoDigestFileLock_);
ErrCode errCode = accountFileOperator_->GetFileContentByPath(Constants::ACCOUNT_INFO_DIGEST_FILE_PATH,
accountInfoDigest);
if (errCode != ERR_OK) {
ACCOUNT_LOGE("get file content failed! error code %{public}d.", errCode);
return errCode;
}
Json accountInfoDigestJson;
try {
accountInfoDigestJson = Json::parse(accountInfoDigest, nullptr, false);
} catch (Json::type_error& err) {
ACCOUNT_LOGE("accountInfoDigestJson parse failed! reason: %{public}s", err.what());
}
if (accountInfoDigestJson.is_discarded()) {
accountInfoDigestJson = Json();
}
accountInfoDigestJson[userInfoPath] = digestOutData;
try {
digestStr = accountInfoDigestJson.dump();
} catch (Json::type_error& err) {
ACCOUNT_LOGE("failed to dump json object, reason: %{public}s", err.what());
return ERR_ACCOUNT_COMMON_DUMP_JSON_ERROR;
}
return ERR_OK;
}
ErrCode AccountFileWatcherMgr::AddAccountInfoDigest(const std::string accountInfo, const std::string &userInfoPath)
{
std::string digestStr;
if (GenerateAccountInfoDigestStr(userInfoPath, accountInfo, digestStr) == ERR_OK) {
std::lock_guard<std::mutex> lock(accountInfoDigestFileLock_);
return accountFileOperator_->InputFileByPathAndContent(Constants::ACCOUNT_INFO_DIGEST_FILE_PATH, digestStr);
}
return ERR_OK;
}
ErrCode AccountFileWatcherMgr::DeleteAccountInfoDigest(const std::string &userInfoPath)
{
Json accountInfoDigestJson;
std::string accountInfoDigest;
std::lock_guard<std::mutex> lock(accountInfoDigestFileLock_);
ErrCode errCode = accountFileOperator_->GetFileContentByPath(Constants::ACCOUNT_INFO_DIGEST_FILE_PATH,
accountInfoDigest);
if (errCode != ERR_OK) {
ACCOUNT_LOGE("get file content failed! error code %{public}d.", errCode);
return errCode;
}
try {
accountInfoDigestJson = Json::parse(accountInfoDigest, nullptr, false);
} catch (Json::type_error& err) {
ACCOUNT_LOGE("accountInfoDigestJson parse failed! reason: %{public}s", err.what());
return ERR_ACCOUNT_COMMON_DUMP_JSON_ERROR;
}
accountInfoDigestJson.erase(userInfoPath);
ErrCode result = accountFileOperator_->InputFileByPathAndContent(
Constants::ACCOUNT_INFO_DIGEST_FILE_PATH, accountInfoDigestJson.dump());
if (result != ERR_OK) {
ACCOUNT_LOGE("cannot save digest info to file, code %{public}d.", result);
return result;
}
return ERR_OK;
}
FileWatcher::FileWatcher(const int32_t id) : id_(id)
{
filePath_ = Constants::USER_INFO_BASE + Constants::PATH_SEPARATOR + std::to_string(id) +
Constants::PATH_SEPARATOR + Constants::USER_INFO_FILE_NAME;
}
FileWatcher::FileWatcher(const std::string &filePath) : filePath_(filePath)
{}
FileWatcher::~FileWatcher()
{}
int32_t FileWatcher::GetNotifyId()
{
return notifyFd_;
}
std::string FileWatcher::GetFilePath()
{
return filePath_;
}
bool FileWatcher::InitNotify()
{
notifyFd_ = inotify_init();
if (notifyFd_ < 0) {
ACCOUNT_LOGE("failed to init notify, errCode:%{public}d", errno);
return false;
}
return true;
}
bool FileWatcher::StartNotify(const uint32_t &watchEvents)
{
wd_ = inotify_add_watch(notifyFd_, filePath_.c_str(), watchEvents);
if (wd_ < 0) {
ACCOUNT_LOGE("failed to start notify, errCode:%{public}d", errno);
return false;
}
return true;
}
bool FileWatcher::CheckNotifyEvent(uint32_t event)
{
if (!eventCallbackFunc_(filePath_, id_, event)) {
ACCOUNT_LOGW("deal notify event failed.");
return false;
}
return true;
}
void FileWatcher::SetEventCallback(CheckNotifyEventCallbackFunc &func)
{
eventCallbackFunc_ = func;
}
int32_t FileWatcher::GetLocalId()
{
return id_;
}
bool FileWatcher::CloseNotifyFd()
{
if (inotify_rm_watch(notifyFd_, wd_) == -1) {
ACCOUNT_LOGE("failed to exec inotify_rm_watch, err:%{public}d", errno);
if (access(filePath_.c_str(), F_OK) == 0) {
close(notifyFd_);
return true;
}
}
int closeRet = close(notifyFd_);
if (closeRet != 0) {
ACCOUNT_LOGE("failed to close fd err:%{public}d", closeRet);
return false;
}
notifyFd_ = -1;
return true;
}
} // namespace AccountSA
} // namespace OHOS

View File

@ -18,6 +18,7 @@
#include <securec.h>
#include "account_info_report.h"
#include "account_log_wrapper.h"
#include "hisysevent_adapter.h"
#include "iinner_os_account_manager.h"
#include "inner_account_iam_manager.h"
#include "inner_domain_account_manager.h"
@ -81,6 +82,7 @@ ErrCode AuthCallback::HandleAuthResult(const Attributes &extraInfo)
ErrCode ret = InnerAccountIAMManager::GetInstance().UnlockUserScreen(userId_);
if (ret != 0) {
ACCOUNT_LOGE("failed to unlock user screen");
ReportOsAccountOperationFail(userId_, "unlockUserScreen", ret, "failed to send unlock msg for storage");
return ret;
}
if (authType_ != AuthType::PIN) {
@ -96,6 +98,7 @@ ErrCode AuthCallback::HandleAuthResult(const Attributes &extraInfo)
ret = InnerAccountIAMManager::GetInstance().ActivateUserKey(userId_, token, secret);
if (ret != 0) {
ACCOUNT_LOGE("failed to activate user key");
ReportOsAccountOperationFail(userId_, "activateUserKey", ret, "failed to notice storage to activate user key");
return ret;
}
return ret;
@ -117,6 +120,7 @@ void AuthCallback::OnResult(int32_t result, const Attributes &extraInfo)
if (result != 0) {
ACCOUNT_LOGE("authentication failed");
innerCallback_->OnResult(result, extraInfo);
ReportOsAccountOperationFail(userId_, "authUser", result, "auth user failed");
return AccountInfoReport::ReportSecurityInfo("", userId_, ReportEvent::EVENT_LOGIN, result);
}
if (HandleAuthResult(extraInfo) != ERR_OK) {
@ -157,6 +161,8 @@ void IDMAuthCallback::OnResult(int32_t result, const Attributes &extraInfo)
{
if (result != 0) {
ACCOUNT_LOGE("fail to update user key for authentication failure, error code: %{public}d", result);
ReportOsAccountOperationFail(
userId_, "authentication", result, "fail to update user key for authentication failure");
} else {
std::vector<uint8_t> token;
std::vector<uint8_t> secret;
@ -201,6 +207,9 @@ void AddCredCallback::OnResult(int32_t result, const Attributes &extraInfo)
userId_, challenge, AuthType::PIN, AuthTrustLevel::ATL4, callback);
return;
}
if (result != 0) {
ReportOsAccountOperationFail(userId_, "addCredential", result, "fail to add credential");
}
InnerAccountIAMManager::GetInstance().SetState(userId_, AFTER_OPEN_SESSION);
if (innerCallback_ == nullptr) {
ACCOUNT_LOGE("inner callback is nullptr");
@ -231,6 +240,9 @@ void DelCredCallback::OnResult(int32_t result, const Attributes &extraInfo)
if ((result == 0) && isPIN_) {
(void)IInnerOsAccountManager::GetInstance().SetOsAccountCredentialId(userId_, 0); // 0-invalid credentialId
}
if (result != 0) {
ReportOsAccountOperationFail(userId_, "deleteCredential", result, "fail to delete credential");
}
InnerAccountIAMManager::GetInstance().SetState(userId_, AFTER_OPEN_SESSION);
innerCallback_->OnResult(result, extraInfo);
}
@ -268,7 +280,8 @@ void GetCredInfoCallbackWrapper::OnCredentialInfo(const std::vector<CredentialIn
return innerCallback_->OnCredentialInfo(infoList);
}
GetPropCallbackWrapper::GetPropCallbackWrapper(const sptr<IGetSetPropCallback> &callback) : innerCallback_(callback)
GetPropCallbackWrapper::GetPropCallbackWrapper(int32_t userId, const sptr<IGetSetPropCallback> &callback)
: userId_(userId), innerCallback_(callback)
{}
void GetPropCallbackWrapper::OnResult(int32_t result, const Attributes &extraInfo)
@ -277,10 +290,14 @@ void GetPropCallbackWrapper::OnResult(int32_t result, const Attributes &extraInf
ACCOUNT_LOGE("inner callback is nullptr");
return;
}
if (result != 0) {
ReportOsAccountOperationFail(userId_, "getProperty", result, "fail to get property");
}
innerCallback_->OnResult(result, extraInfo);
}
SetPropCallbackWrapper::SetPropCallbackWrapper(const sptr<IGetSetPropCallback> &callback) : innerCallback_(callback)
SetPropCallbackWrapper::SetPropCallbackWrapper(int32_t userId, const sptr<IGetSetPropCallback> &callback)
: userId_(userId), innerCallback_(callback)
{}
void SetPropCallbackWrapper::OnResult(int32_t result, const Attributes &extraInfo)
@ -289,6 +306,9 @@ void SetPropCallbackWrapper::OnResult(int32_t result, const Attributes &extraInf
ACCOUNT_LOGE("inner callback is nullptr");
return;
}
if (result != 0) {
ReportOsAccountOperationFail(userId_, "setProperty", result, "fail to set property");
}
innerCallback_->OnResult(result, extraInfo);
}

View File

@ -18,6 +18,7 @@
#include "account_iam_callback.h"
#include "account_log_wrapper.h"
#include "domain_account_callback_service.h"
#include "hisysevent_adapter.h"
#include "iinner_os_account_manager.h"
#include "inner_domain_account_manager.h"
#include "iservice_registry.h"
@ -289,7 +290,7 @@ void InnerAccountIAMManager::GetProperty(
return;
}
if (static_cast<int32_t>(request.authType) != static_cast<int32_t>(IAMAuthType::DOMAIN)) {
auto getCallback = std::make_shared<GetPropCallbackWrapper>(callback);
auto getCallback = std::make_shared<GetPropCallbackWrapper>(userId, callback);
UserAuthClient::GetInstance().GetProperty(userId, request, getCallback);
return;
}
@ -307,7 +308,7 @@ void InnerAccountIAMManager::SetProperty(
callback->OnResult(ERR_ACCOUNT_IAM_UNSUPPORTED_AUTH_TYPE, result);
return;
}
auto setCallback = std::make_shared<SetPropCallbackWrapper>(callback);
auto setCallback = std::make_shared<SetPropCallbackWrapper>(userId, callback);
UserAuthClient::GetInstance().SetProperty(userId, request, setCallback);
}
@ -372,7 +373,7 @@ ErrCode InnerAccountIAMManager::UnlockUserScreen(int32_t userId)
ACCOUNT_LOGE("fail to unlock screen");
return result;
}
#endif // HAS_STORAGE_PART
#endif
return ERR_OK;
}
@ -416,6 +417,7 @@ ErrCode InnerAccountIAMManager::UpdateUserKey(int32_t userId, uint64_t secureUid
}
result = UpdateStorageKey(userId, secureUid, token, oldCredInfo.secret, newSecret);
if (result != ERR_OK) {
ReportOsAccountOperationFail(userId, "updateUserKey", result, "failed to notice storage to update user key");
return result;
}
credInfoMap_[userId] = {
@ -439,6 +441,7 @@ ErrCode InnerAccountIAMManager::RemoveUserKey(int32_t userId, const std::vector<
std::vector<uint8_t> newSecret;
result = UpdateStorageKey(userId, 0, token, oldCredInfo.secret, newSecret);
if (result != ERR_OK) {
ReportOsAccountOperationFail(userId, "removeUserKey", result, "failed to notice storage to remove user key");
return result;
}
credInfoMap_[userId] = {

View File

@ -27,7 +27,9 @@
#include "directory_ex.h"
#include "file_ex.h"
#include "hisysevent_adapter.h"
#include "iinner_os_account_manager.h"
#include "ohos_account_data_deal.h"
namespace OHOS {
namespace AccountSA {
namespace {
@ -42,11 +44,90 @@ const std::string DATADEAL_JSON_KEY_OHOSACCOUNT_AVATAR = "account_avatar";
const std::string DATADEAL_JSON_KEY_OHOSACCOUNT_SCALABLEDATA = "account_scalableData";
const std::string DATADEAL_JSON_KEY_USERID = "user_id";
const std::string DATADEAL_JSON_KEY_BIND_TIME = "bind_time";
const uint32_t ALG_COMMON_SIZE = 32;
} // namespace
OhosAccountDataDeal::OhosAccountDataDeal(const std::string &configFileDir) : configFileDir_(configFileDir)
OhosAccountDataDeal::OhosAccountDataDeal(const std::string &configFileDir)
: configFileDir_(configFileDir),
accountFileWatcherMgr_(AccountFileWatcherMgr::GetInstance())
{
accountFileOperator_ = std::make_shared<AccountFileOperator>();
initOk_ = false;
checkCallbackFunc_ = [this](const std::string &fileName, const int32_t id, uint32_t event) {
ACCOUNT_LOGI("inotify event = %{public}d, fileName = %{public}s", event, fileName.c_str());
switch (event) {
case IN_MODIFY: {
return DealWithFileModifyEvent(fileName, id);
}
case IN_MOVE_SELF: {
ReportOsAccountDataTampered(id, fileName, "DISTRIBUTED_ACCOUT_INFO");
break;
}
case IN_DELETE_SELF: {
DealWithFileDeleteEvent(fileName, id);
break;
}
default: {
ACCOUNT_LOGW("get event invalid!");
return false;
}
}
return true;
};
}
bool OhosAccountDataDeal::DealWithFileModifyEvent(const std::string &fileName, const int32_t id)
{
ACCOUNT_LOGI("enter");
{
std::lock_guard<std::mutex> lock(accountFileOperator_->GetModifyOperationLock());
if (accountFileOperator_->GetValidModifyFileOperationFlag(fileName)) {
ACCOUNT_LOGD("this is valid service operate, no need to deal with it.");
accountFileOperator_->SetValidModifyFileOperationFlag(fileName, false);
return true;
}
}
std::lock_guard<std::mutex> lock(accountInfoFileLock_);
std::string fileInfoStr;
if (accountFileOperator_->GetFileContentByPath(fileName, fileInfoStr) != ERR_OK) {
ACCOUNT_LOGE("get content from file %{public}s failed!", fileName.c_str());
return false;
}
uint8_t localDigestData[ALG_COMMON_SIZE] = {0};
accountFileWatcherMgr_.GetAccountInfoDigestFromFile(fileName, localDigestData, ALG_COMMON_SIZE);
uint8_t newDigestData[ALG_COMMON_SIZE] = {0};
GenerateAccountInfoDigest(fileInfoStr, newDigestData, ALG_COMMON_SIZE);
if (memcmp(localDigestData, newDigestData, ALG_COMMON_SIZE) == 0) {
ACCOUNT_LOGD("No need to recover local file data.");
return true;
}
ReportOsAccountDataTampered(id, fileName, "DISTRIBUTED_ACCOUT_INFO");
return true;
}
void OhosAccountDataDeal::DealWithFileDeleteEvent(const std::string &fileName, const int32_t id)
{
{
std::lock_guard<std::mutex> lock(accountFileOperator_->GetDeleteOperationLock());
if (accountFileOperator_->GetValidDeleteFileOperationFlag(fileName)) {
ACCOUNT_LOGD("this is valid service operate, no need to deal with it.");
accountFileOperator_->SetValidDeleteFileOperationFlag(fileName, false);
return;
}
}
std::string fileDir = configFileDir_ + std::to_string(id);
if (!accountFileOperator_->IsExistDir(fileDir)) {
ACCOUNT_LOGI("this id is already removed.");
return;
}
ReportOsAccountDataTampered(id, fileName, "DISTRIBUTED_ACCOUT_INFO");
}
void OhosAccountDataDeal::AddFileWatcher(const int32_t id)
{
std::shared_ptr<FileWatcher> fileWatcher;
std::string configFile = configFileDir_ + std::to_string(id) + ACCOUNT_CFG_FILE_NAME;
accountFileWatcherMgr_.AddFileWatcher(id, checkCallbackFunc_, configFile);
}
ErrCode OhosAccountDataDeal::Init(int32_t userId)
@ -80,6 +161,12 @@ ErrCode OhosAccountDataDeal::Init(int32_t userId)
return ERR_ACCOUNT_DATADEAL_JSON_FILE_CORRUPTION;
}
// recover watch for exist account info
std::vector<OsAccountInfo> osAccountInfos;
IInnerOsAccountManager::GetInstance().QueryAllCreatedOsAccounts(osAccountInfos);
for (const auto &info : osAccountInfos) {
AddFileWatcher(info.GetLocalId());
}
initOk_ = true;
return ERR_OK;
}
@ -93,7 +180,7 @@ ErrCode OhosAccountDataDeal::AccountInfoFromJson(AccountInfo &accountInfo, int32
return GetAccountInfo(accountInfo, userId);
}
ErrCode OhosAccountDataDeal::AccountInfoToJson(const AccountInfo &accountInfo) const
ErrCode OhosAccountDataDeal::AccountInfoToJson(const AccountInfo &accountInfo)
{
if (!initOk_) {
ACCOUNT_LOGE("Not init ok");
@ -102,8 +189,9 @@ ErrCode OhosAccountDataDeal::AccountInfoToJson(const AccountInfo &accountInfo) c
return SaveAccountInfo(accountInfo);
}
ErrCode OhosAccountDataDeal::SaveAccountInfo(const AccountInfo &accountInfo) const
ErrCode OhosAccountDataDeal::SaveAccountInfo(const AccountInfo &accountInfo)
{
std::lock_guard<std::mutex> lock(accountInfoFileLock_);
std::string scalableDataStr = (accountInfo.ohosAccountInfo_.scalableData_).ToString();
nlohmann::json jsonData = json {
{DATADEAL_JSON_KEY_BIND_TIME, accountInfo.bindTime_},
@ -119,40 +207,16 @@ ErrCode OhosAccountDataDeal::SaveAccountInfo(const AccountInfo &accountInfo) con
};
std::string accountInfoValue = jsonData.dump(-1, ' ', false, json::error_handler_t::ignore);
std::string configFile = configFileDir_ + std::to_string(accountInfo.userId_) + ACCOUNT_CFG_FILE_NAME;
FILE *fp = fopen(configFile.c_str(), "wb");
if (fp == nullptr) {
ACCOUNT_LOGE("failed to open %{public}s, errno %{public}d.", configFile.c_str(), errno);
ReportOhosAccountOperationFail(accountInfo.userId_, OPERATION_OPEN_FILE_TO_WRITE, errno, configFile);
return ERR_ACCOUNT_COMMON_FILE_OPEN_FAILED;
}
size_t num = fwrite(accountInfoValue.c_str(), sizeof(char), accountInfoValue.length(), fp);
if (num != accountInfoValue.length()) {
ACCOUNT_LOGE("failed to fwrite %{public}s, errno %{public}d.", configFile.c_str(), errno);
ReportOhosAccountOperationFail(accountInfo.userId_, OPERATION_OPEN_FILE_TO_WRITE, errno, configFile);
fclose(fp);
return ERR_ACCOUNT_COMMON_FILE_WRITE_FAILED;
}
if (fflush(fp) != 0) {
ACCOUNT_LOGE("failed to fflush %{public}s, errno %{public}d.", configFile.c_str(), errno);
ReportOhosAccountOperationFail(accountInfo.userId_, OPERATION_OPEN_FILE_TO_WRITE, errno, configFile);
fclose(fp);
return ERR_ACCOUNT_COMMON_FILE_WRITE_FAILED;
}
if (fsync(fileno(fp)) != 0) {
ACCOUNT_LOGE("failed to fsync %{public}s, errno %{public}d.", configFile.c_str(), errno);
ReportOhosAccountOperationFail(accountInfo.userId_, OPERATION_OPEN_FILE_TO_WRITE, errno, configFile);
fclose(fp);
return ERR_ACCOUNT_COMMON_FILE_WRITE_FAILED;
}
fclose(fp);
// change mode
if (!ChangeModeFile(configFile, S_IRUSR | S_IWUSR)) {
ACCOUNT_LOGE("failed to change mode for file %{public}s, errno %{public}d.", configFile.c_str(), errno);
ErrCode ret = accountFileOperator_->InputFileByPathAndContent(configFile, accountInfoValue);
if (ret == ERR_OHOSACCOUNT_SERVICE_FILE_CHANGE_DIR_MODE_ERROR) {
ReportOhosAccountOperationFail(accountInfo.userId_, OPERATION_CHANGE_MODE_FILE, errno, configFile);
return ERR_OHOSACCOUNT_SERVICE_FILE_CHANGE_DIR_MODE_ERROR;
}
return ERR_OK;
if (ret != ERR_OK && ret != ERR_OHOSACCOUNT_SERVICE_FILE_CHANGE_DIR_MODE_ERROR) {
ReportOhosAccountOperationFail(accountInfo.userId_, OPERATION_OPEN_FILE_TO_WRITE, errno, configFile);
}
accountFileWatcherMgr_.AddAccountInfoDigest(accountInfoValue, configFile);
return ret;
}
ErrCode OhosAccountDataDeal::ParseJsonFromFile(const std::string &filePath, nlohmann::json &jsonData, int32_t userId)
@ -235,6 +299,10 @@ ErrCode OhosAccountDataDeal::GetAccountInfoFromJson(
ErrCode OhosAccountDataDeal::GetAccountInfo(AccountInfo &accountInfo, const int32_t userId)
{
if (userId < 0) {
ACCOUNT_LOGW("invalid userid = %{public}d", userId);
return ERR_OSACCOUNT_SERVICE_MANAGER_ID_ERROR;
}
std::string configFile = configFileDir_ + std::to_string(userId) + ACCOUNT_CFG_FILE_NAME;
if (!FileExists(configFile)) {
ACCOUNT_LOGI("file %{public}s not exist, create!", configFile.c_str());
@ -252,7 +320,7 @@ ErrCode OhosAccountDataDeal::GetAccountInfo(AccountInfo &accountInfo, const int3
return GetAccountInfoFromJson(jsonData, accountInfo, userId);
}
void OhosAccountDataDeal::BuildJsonFileFromScratch(int32_t userId) const
void OhosAccountDataDeal::BuildJsonFileFromScratch(int32_t userId)
{
AccountInfo accountInfo;
accountInfo.userId_ = userId;
@ -264,6 +332,7 @@ void OhosAccountDataDeal::BuildJsonFileFromScratch(int32_t userId) const
accountInfo.digest_ = "";
accountInfo.ohosAccountInfo_.SetRawUid(DEFAULT_OHOS_ACCOUNT_UID);
SaveAccountInfo(accountInfo);
AddFileWatcher(userId);
}
} // namespace AccountSA
} // namespace OHOS

View File

@ -652,6 +652,7 @@ ErrCode IInnerOsAccountManager::RemoveOsAccount(const int id)
errCode = SendMsgForAccountStop(osAccountInfo);
if (errCode != ERR_OK) {
RemoveLocalIdToOperating(id);
ReportOsAccountOperationFail(id, "stop", errCode, "stop os account failed");
return errCode;
}
@ -1490,6 +1491,7 @@ ErrCode IInnerOsAccountManager::DeactivateOsAccount(const int id)
errCode = SendMsgForAccountDeactivate(osAccountInfo);
if (errCode != ERR_OK) {
RemoveLocalIdToOperating(id);
ReportOsAccountOperationFail(id, "deactivate", errCode, "deactivate os account failed");
return errCode;
}
@ -1595,6 +1597,7 @@ ErrCode IInnerOsAccountManager::StopOsAccount(const int id)
errCode = SendMsgForAccountStop(osAccountInfo);
if (errCode != ERR_OK) {
RemoveLocalIdToOperating(id);
ReportOsAccountOperationFail(id, "stop", errCode, "stop os account failed");
ACCOUNT_LOGE("update %{public}d account info failed, errCode %{public}d.", id, errCode);
return errCode;
}

View File

@ -27,9 +27,6 @@
#include "account_log_wrapper.h"
#include "hisysevent_adapter.h"
#include "hks_api.h"
#include "hks_param.h"
#include "hks_type.h"
#include "os_account_constants.h"
#include "os_account_interface.h"
@ -38,174 +35,14 @@ namespace AccountSA {
namespace {
const std::string DEFAULT_ACTIVATED_ACCOUNT_ID = "DefaultActivatedAccountID";
const int32_t MAX_LOCAL_ID = 10736; // int32 max value reduce 200000 be divisible by 200000
const std::string OS_ACCOUNT_STORE_ID = "os_account_info";
const struct HksParam g_genSignVerifyParams[] = {
{
.tag = HKS_TAG_ALGORITHM,
.uint32Param = HKS_ALG_HMAC
}, {
.tag = HKS_TAG_PURPOSE,
.uint32Param = HKS_KEY_PURPOSE_MAC
}, {
.tag = HKS_TAG_KEY_SIZE,
.uint32Param = HKS_AES_KEY_SIZE_256
}, {
.tag = HKS_TAG_DIGEST,
.uint32Param = HKS_DIGEST_SHA256
}
};
const uint32_t ALG_COMMON_SIZE = 32;
const uint32_t BUF_COMMON_SIZE = 1024;
const int32_t TIMES = 4;
const int32_t MAX_UPDATE_SIZE = 256;
const int32_t MAX_OUTDATA_SIZE = MAX_UPDATE_SIZE * TIMES;
const char ACCOUNT_KEY_ALIAS[] = "os_account_info_encryption_key";
const HksBlob g_keyAlias = { (uint32_t)strlen(ACCOUNT_KEY_ALIAS), (uint8_t *)ACCOUNT_KEY_ALIAS };
}
static int32_t InitParamSet(struct HksParamSet **paramSet, const struct HksParam *params, uint32_t paramCount)
{
int32_t ret = HksInitParamSet(paramSet);
if (ret != 0) {
ACCOUNT_LOGE("HksInitParamSet err = %{public}d", ret);
return ret;
}
ret = HksAddParams(*paramSet, params, paramCount);
if (ret != 0) {
ACCOUNT_LOGE("HksAddParams err = %{public}d", ret);
HksFreeParamSet(paramSet);
return ret;
}
ret = HksBuildParamSet(paramSet);
if (ret != 0) {
ACCOUNT_LOGE("HksBuildParamSet err = %{public}d", ret);
HksFreeParamSet(paramSet);
return ret;
}
return ret;
}
static int32_t MallocAndCheckBlobData(struct HksBlob *blob, const uint32_t blobSize)
{
if (blobSize == 0) {
blob->data = NULL;
return -1;
}
blob->data = (uint8_t *)malloc(blobSize);
if (blob->data == NULL) {
ACCOUNT_LOGE("MallocAndCheckBlobData err");
return -1;
}
return 0;
}
static int32_t HksUpdateOpt(
const struct HksBlob *handle, const struct HksParamSet *paramSet, const struct HksBlob *inData)
{
struct HksBlob inDataSeg = *inData;
inDataSeg.size = MAX_UPDATE_SIZE;
uint8_t *lastPtr = inData->data + inData->size - 1;
struct HksBlob outDataSeg = {
.size = MAX_OUTDATA_SIZE,
.data = NULL
};
bool isFinished = false;
while (inDataSeg.data <= lastPtr) {
if (inDataSeg.data + MAX_UPDATE_SIZE <= lastPtr) {
outDataSeg.size = MAX_OUTDATA_SIZE;
} else {
isFinished = true;
inDataSeg.size = lastPtr - inDataSeg.data + 1;
outDataSeg.size = inDataSeg.size + MAX_UPDATE_SIZE;
}
if (MallocAndCheckBlobData(&outDataSeg, outDataSeg.size) != 0) {
return -1;
}
int32_t ret = HksUpdate(handle, paramSet, &inDataSeg, &outDataSeg);
if (ret != 0) {
ACCOUNT_LOGE("HksUpdate err, ret = %{public}d", ret);
free(outDataSeg.data);
outDataSeg.data = NULL;
return -1;
}
free(outDataSeg.data);
outDataSeg.data = NULL;
if ((isFinished == false) && (inDataSeg.data + MAX_UPDATE_SIZE > lastPtr)) {
return 0;
}
inDataSeg.data += MAX_UPDATE_SIZE;
}
return 0;
}
static int32_t InitEncryptionKey()
{
struct HksParamSet *genParamSet = nullptr;
int32_t ret;
do {
ret = InitParamSet(&genParamSet, g_genSignVerifyParams, sizeof(g_genSignVerifyParams) / sizeof(HksParam));
if (ret != 0) {
ACCOUNT_LOGE("InitParamSet genParamSet err = %{public}d", ret);
break;
}
ret = HksGenerateKey(&g_keyAlias, genParamSet, nullptr);
if (ret != 0) {
ACCOUNT_LOGE("HksGenerateKey err = %{public}d", ret);
break;
}
} while (0);
HksFreeParamSet(&genParamSet);
return ret;
}
static int32_t GenerateAccountInfoGigest(const std::string &inData, uint8_t* outData, uint32_t size)
{
if (inData.empty()) {
ACCOUNT_LOGW("inData is empty.");
return 0;
}
const char *tmpInData = inData.c_str();
struct HksBlob inDataBlob = { (uint32_t)strlen(tmpInData), (uint8_t *)tmpInData };
struct HksParamSet *genParamSet = nullptr;
int32_t ret = InitParamSet(&genParamSet, g_genSignVerifyParams, sizeof(g_genSignVerifyParams) / sizeof(HksParam));
if (ret != 0) {
ACCOUNT_LOGE("InitParamSet err = %{public}d", ret);
return ret;
}
uint8_t handleTmp[sizeof(uint64_t)] = {0};
struct HksBlob handleGenDigest = { (uint32_t)sizeof(uint64_t), handleTmp };
ret = HksInit(&g_keyAlias, genParamSet, &handleGenDigest, nullptr);
if (ret != 0) {
ACCOUNT_LOGE("HksInit err = %{public}d", ret);
return ret;
}
// Update loop
ret = HksUpdateOpt(&handleGenDigest, genParamSet, &inDataBlob);
if (ret != 0) {
ACCOUNT_LOGE("HksUpdateOpt err = %{public}d", ret);
HksAbort(&handleGenDigest, genParamSet);
return ret;
}
struct HksBlob finishOut = { 0, nullptr };
uint8_t outDataS[ALG_COMMON_SIZE] = "out";
struct HksBlob outDataBlob = { ALG_COMMON_SIZE, outDataS };
ret = HksFinish(&handleGenDigest, genParamSet, &finishOut, &outDataBlob);
if (ret != 0) {
ACCOUNT_LOGE("HksFinish failed = %{public}d", ret);
HksAbort(&handleGenDigest, genParamSet);
return ret;
}
if (memcpy_s(outData, size, outDataS, outDataBlob.size) != EOK) {
ACCOUNT_LOGE("Get digest failed duo to memcpy_s failed");
return -1;
}
HksFreeParamSet(&genParamSet);
return ret;
#ifndef ACCOUNT_TEST
const std::string ACCOUNT_CFG_DIR_ROOT_PATH = "/data/service/el1/public/account/";
#else
const std::string ACCOUNT_CFG_DIR_ROOT_PATH = "/data/service/el1/public/account/test/";
#endif // ACCOUNT_TEST
const std::string DISTRIBUTED_ACCOUNT_FILE_NAME = "/account.json";
}
bool GetValidAccountID(const std::string& dirName, std::int32_t& accountID)
@ -230,179 +67,6 @@ bool GetValidAccountID(const std::string& dirName, std::int32_t& accountID)
return (accountID >= Constants::ADMIN_LOCAL_ID && accountID <= Constants::MAX_USER_ID);
}
FileWatcher::FileWatcher(const int32_t id) : id_(id)
{
filePath_ = Constants::USER_INFO_BASE + Constants::PATH_SEPARATOR + std::to_string(id) +
Constants::PATH_SEPARATOR + Constants::USER_INFO_FILE_NAME;
}
FileWatcher::FileWatcher(const std::string &filePath) : filePath_(filePath)
{}
FileWatcher::~FileWatcher()
{}
int32_t FileWatcher::GetNotifyId()
{
return notifyFd_;
}
std::string FileWatcher::GetFilePath()
{
return filePath_;
}
bool FileWatcher::InitNotify()
{
notifyFd_ = inotify_init();
if (notifyFd_ < 0) {
ACCOUNT_LOGE("failed to init notify, errCode:%{public}d", errno);
return false;
}
return true;
}
bool FileWatcher::StartNotify(const uint32_t &watchEvents)
{
wd_ = inotify_add_watch(notifyFd_, filePath_.c_str(), watchEvents);
if (wd_ < 0) {
ACCOUNT_LOGE("failed to init notify, errCode:%{public}d", errno);
return false;
}
return true;
}
bool FileWatcher::CheckNotifyEvent(uint32_t event)
{
if (!eventCallbackFunc_(filePath_, id_, event)) {
ACCOUNT_LOGW("deal notify event failed.");
return false;
}
return true;
}
void OsAccountControlFileManager::DealWithFileEvent()
{
std::vector<std::pair<std::shared_ptr<FileWatcher>, uint32_t>> eventMap;
{
std::lock_guard<std::mutex> lock(fileWatcherMgrLock_);
for (int32_t i : fdArray_) {
if (FD_ISSET(i, &fds_)) { // check which fd has event
char buf[BUF_COMMON_SIZE] = {0};
struct inotify_event *event = nullptr;
int len, index = 0;
while (((len = read(i, &buf, sizeof(buf))) < 0) && (errno == EINTR)) {};
while (index < len) {
event = reinterpret_cast<inotify_event *>(buf + index);
std::shared_ptr<FileWatcher> fileWatcher = fileNameMgrMap_[i];
eventMap.emplace_back(std::make_pair(fileWatcher, event->mask));
index += sizeof(struct inotify_event) + event->len;
}
} else {
FD_SET(i, &fds_);
}
}
}
for (auto it : eventMap) {
it.first->CheckNotifyEvent(it.second);
}
return;
}
void OsAccountControlFileManager::GetNotifyEvent()
{
while (run_) {
if (maxNotifyFd_ < 0) {
ACCOUNT_LOGE("failed to run notify because no fd available.");
run_ = false;
break;
}
if (select(maxNotifyFd_ + 1, &fds_, nullptr, nullptr, nullptr) <= 0) {
continue;
}
DealWithFileEvent();
}
}
void FileWatcher::SetEventCallback(CheckNotifyEventCallbackFunc &func)
{
eventCallbackFunc_ = func;
}
int32_t FileWatcher::GetLocalId()
{
return id_;
}
bool FileWatcher::CloseNotifyFd()
{
if (inotify_rm_watch(notifyFd_, wd_) == -1) {
ACCOUNT_LOGE("failed to exec inotify_rm_watch, err:%{public}d", errno);
if (access(filePath_.c_str(), F_OK) == 0) {
close(notifyFd_);
return true;
}
}
int closeRet = close(notifyFd_);
if (closeRet != 0) {
ACCOUNT_LOGE("failed to close fd err:%{public}d", closeRet);
return false;
}
notifyFd_ = -1;
return true;
}
void OsAccountControlFileManager::RemoveFileWatcher(const int32_t id)
{
std::lock_guard<std::mutex> lock(fileWatcherMgrLock_);
int targetFd = -1;
for (auto it : fileNameMgrMap_) {
if (it.second->GetLocalId() == id) {
targetFd = it.second->GetNotifyId();
break;
}
}
if (targetFd == -1) {
return;
}
FD_CLR(targetFd, &fds_);
if (!fileNameMgrMap_[targetFd]->CloseNotifyFd()) {
ACCOUNT_LOGE("failed to close notifyId, userId = %{public}d", id);
}
fdArray_.erase(
std::remove(fdArray_.begin(), fdArray_.end(), targetFd), fdArray_.end());
if (maxNotifyFd_ == targetFd) {
maxNotifyFd_ = *max_element(fdArray_.begin(), fdArray_.end());
}
fileNameMgrMap_.erase(targetFd);
return;
}
void OsAccountControlFileManager::AddFileWatcher(const int32_t id)
{
std::shared_ptr<FileWatcher> fileWatcher;
if (id < Constants::START_USER_ID) {
fileWatcher = std::make_shared<FileWatcher>(Constants::ACCOUNT_LIST_FILE_JSON_PATH);
} else {
fileWatcher = std::make_shared<FileWatcher>(id);
}
if (!fileWatcher->InitNotify()) {
return;
}
SubscribeEventFunction(fileWatcher);
if (!fileWatcher->StartNotify(IN_MODIFY | IN_DELETE_SELF| IN_MOVE_SELF)) {
return;
}
std::lock_guard<std::mutex> lock(fileWatcherMgrLock_);
if (fileWatcher->GetNotifyId() > maxNotifyFd_) {
maxNotifyFd_ = fileWatcher->GetNotifyId();
}
fileNameMgrMap_[fileWatcher->GetNotifyId()] = fileWatcher;
fdArray_.emplace_back(fileWatcher->GetNotifyId());
FD_SET(fileWatcher->GetNotifyId(), &fds_);
}
bool OsAccountControlFileManager::RecoverAccountData(const std::string &fileName, const int32_t id)
{
#ifdef HAS_KV_STORE_PART
@ -411,10 +75,20 @@ bool OsAccountControlFileManager::RecoverAccountData(const std::string &fileName
Json accountListJson;
osAccountDataBaseOperator_->GetAccountListFromStoreID(OS_ACCOUNT_STORE_ID, accountListJson);
recoverDataStr = accountListJson.dump();
} else {
} else if (id >= Constants::START_USER_ID) {
OsAccountInfo osAccountInfo;
GetOsAccountFromDatabase(OS_ACCOUNT_STORE_ID, id, osAccountInfo);
if (GetOsAccountFromDatabase(OS_ACCOUNT_STORE_ID, id, osAccountInfo) != ERR_OK) {
ACCOUNT_LOGW("get recover file data failed");
return false;
}
recoverDataStr = osAccountInfo.ToString();
} else {
ACCOUNT_LOGW("get recover file data failed");
return false;
}
if (recoverDataStr.empty()) {
ACCOUNT_LOGW("get recover file data failed");
return false;
}
// recover data
ErrCode result = accountFileOperator_->InputFileByPathAndContent(fileName, recoverDataStr);
@ -423,37 +97,41 @@ bool OsAccountControlFileManager::RecoverAccountData(const std::string &fileName
return false;
}
// update local digest
std::string digestStr;
if (GenerateAccountInfoDigestStr(fileName, recoverDataStr, digestStr) != ERR_OK) {
if (accountFileWatcherMgr_.AddAccountInfoDigest(recoverDataStr, fileName) != ERR_OK) {
ACCOUNT_LOGE("failed to update local digest");
return false;
}
accountFileOperator_->InputFileByPathAndContent(Constants::ACCOUNT_INFO_DIGEST_FILE_PATH, digestStr);
#endif
return true;
}
bool OsAccountControlFileManager::DealWithFileModifyEvent(const std::string &fileName, const int32_t id)
{
if (accountFileOperator_->GetValidWriteFileOptFlag()) {
ACCOUNT_LOGD("this is valid service operate, no need to deal with it.");
accountFileOperator_->SetValidWriteFileOptFlag(false);
return true;
ACCOUNT_LOGI("enter");
{
std::lock_guard<std::mutex> lock(accountFileOperator_->GetModifyOperationLock());
if (accountFileOperator_->GetValidModifyFileOperationFlag(fileName)) {
ACCOUNT_LOGD("this is valid service operate, no need to deal with it.");
accountFileOperator_->SetValidModifyFileOperationFlag(fileName, false);
return true;
}
}
std::string fileInfoStr;
std::lock_guard<std::mutex> lock(accountInfoFileLock_);
std::string fileInfoStr;
if (accountFileOperator_->GetFileContentByPath(fileName, fileInfoStr) != ERR_OK) {
ACCOUNT_LOGE("get content from file %{public}s failed!", fileName.c_str());
return false;
}
uint8_t localDigestData[ALG_COMMON_SIZE] = {0};
GetAccountInfoDigestFromFile(fileName, localDigestData, ALG_COMMON_SIZE);
accountFileWatcherMgr_.GetAccountInfoDigestFromFile(fileName, localDigestData, ALG_COMMON_SIZE);
uint8_t newDigestData[ALG_COMMON_SIZE] = {0};
GenerateAccountInfoGigest(fileInfoStr, newDigestData, ALG_COMMON_SIZE);
GenerateAccountInfoDigest(fileInfoStr, newDigestData, ALG_COMMON_SIZE);
if (memcmp(localDigestData, newDigestData, ALG_COMMON_SIZE) == EOK) {
ACCOUNT_LOGD("No need to recover local file data.");
return true;
}
ReportOsAccountDataTampered(id, fileName, "OS_ACCOUNT_INFO");
ACCOUNT_LOGW("local file data has been changed");
return RecoverAccountData(fileName, id);
}
@ -461,16 +139,22 @@ bool OsAccountControlFileManager::DealWithFileModifyEvent(const std::string &fil
bool OsAccountControlFileManager::DealWithFileDeleteEvent(const std::string &fileName, const int32_t id)
{
ACCOUNT_LOGI("enter");
if (accountFileOperator_->GetValidDeleteFileOptFlag(fileName)) {
ACCOUNT_LOGD("this is valid service operate, no need to deal with it.");
accountFileOperator_->SetValidDeleteFileOptFlag(fileName, false);
return true;
{
std::lock_guard<std::mutex> lock(accountFileOperator_->GetDeleteOperationLock());
if (accountFileOperator_->GetValidDeleteFileOperationFlag(fileName)) {
ACCOUNT_LOGD("this is valid service operate, no need to deal with it.");
accountFileOperator_->SetValidDeleteFileOperationFlag(fileName, false);
return true;
}
}
std::lock_guard<std::mutex> lock(accountInfoFileLock_);
if (!RecoverAccountData(fileName, id)) {
ACCOUNT_LOGE("recover account data failed.");
ReportOsAccountDataTampered(id, fileName, "OS_ACCOUNT_INFO");
{
std::lock_guard<std::mutex> lock(accountInfoFileLock_);
if (!RecoverAccountData(fileName, id)) {
ACCOUNT_LOGE("recover account data failed.");
}
}
AddFileWatcher(id);
accountFileWatcherMgr_.AddFileWatcher(id, eventCallbackFunc_, fileName);
return true;
}
@ -478,52 +162,18 @@ bool OsAccountControlFileManager::DealWithFileMoveEvent(const std::string &fileN
{
ACCOUNT_LOGI("enter");
// delete old file watcher
RemoveFileWatcher(id);
accountFileWatcherMgr_.RemoveFileWatcher(id, fileName);
ReportOsAccountDataTampered(id, fileName, "OS_ACCOUNT_INFO");
std::lock_guard<std::mutex> lock(accountInfoFileLock_);
if (!RecoverAccountData(fileName, id)) {
ACCOUNT_LOGE("recover account data failed.");
}
AddFileWatcher(id);
accountFileWatcherMgr_.AddFileWatcher(id, eventCallbackFunc_, fileName);
return true;
}
void OsAccountControlFileManager::SubscribeEventFunction(std::shared_ptr<FileWatcher> &fileWatcher)
{
CheckNotifyEventCallbackFunc checkCallbackFunc =
[this](const std::string &fileName, const int32_t id, uint32_t event) {
switch (event) {
case IN_MODIFY: {
return DealWithFileModifyEvent(fileName, id);
}
case IN_MOVE_SELF: {
return DealWithFileMoveEvent(fileName, id);
}
case IN_DELETE_SELF: {
return DealWithFileDeleteEvent(fileName, id);
}
default: {
ACCOUNT_LOGW("get event invalid!");
return false;
}
}
};
fileWatcher->SetEventCallback(checkCallbackFunc);
return;
}
void OsAccountControlFileManager::WatchOsAccountInfoFile()
{
if (run_) {
return;
}
run_ = true;
auto task = std::bind(&OsAccountControlFileManager::GetNotifyEvent, this);
std::thread taskThread(task);
pthread_setname_np(taskThread.native_handle(), "fileWatcher");
taskThread.detach();
}
OsAccountControlFileManager::OsAccountControlFileManager()
: accountFileWatcherMgr_(AccountFileWatcherMgr::GetInstance())
{
accountFileOperator_ = std::make_shared<AccountFileOperator>();
#ifdef HAS_KV_STORE_PART
@ -531,14 +181,30 @@ OsAccountControlFileManager::OsAccountControlFileManager()
#endif
osAccountFileOperator_ = std::make_shared<OsAccountFileOperator>();
osAccountPhotoOperator_ = std::make_shared<OsAccountPhotoOperator>();
FD_ZERO(&fds_);
eventCallbackFunc_ = [this](const std::string &fileName, const int32_t id, uint32_t event) {
ACCOUNT_LOGI("inotify event = %{public}d, fileName = %{public}s", event, fileName.c_str());
switch (event) {
case IN_MODIFY: {
return DealWithFileModifyEvent(fileName, id);
}
case IN_MOVE_SELF: {
return DealWithFileMoveEvent(fileName, id);
}
case IN_DELETE_SELF: {
return DealWithFileDeleteEvent(fileName, id);
}
default: {
ACCOUNT_LOGW("get event invalid!");
return false;
}
}
};
}
OsAccountControlFileManager::~OsAccountControlFileManager()
{}
void OsAccountControlFileManager::Init()
{
InitEncryptionKey();
osAccountFileOperator_->Init();
FileInit();
Json accountListJson;
@ -566,7 +232,6 @@ void OsAccountControlFileManager::FileInit()
Restorecon(Constants::ACCOUNT_LIST_FILE_JSON_PATH.c_str());
#endif // WITH_SELINUX
}
AddFileWatcher(-1); // -1 is special refers to accountList file.
if (!accountFileOperator_->IsJsonFileReady(Constants::ACCOUNT_INFO_DIGEST_FILE_PATH)) {
ACCOUNT_LOGI("OsAccountControlFileManager there is not have valid account info digest file, create!");
RecoverAccountInfoDigestJsonFile();
@ -574,6 +239,16 @@ void OsAccountControlFileManager::FileInit()
Restorecon(Constants::ACCOUNT_INFO_DIGEST_FILE_PATH.c_str());
#endif // WITH_SELINUX
}
// -1 is special refers to conmon account data file.
accountFileWatcherMgr_.AddFileWatcher(-1, eventCallbackFunc_, Constants::ACCOUNT_LIST_FILE_JSON_PATH);
if (!accountFileOperator_->IsJsonFileReady(Constants::ACCOUNT_INDEX_JSON_PATH)) {
ACCOUNT_LOGI("OsAccountControlFileManager there is not have valid account index file, create!");
BuildAndSaveOsAccountIndexJsonFile();
#ifdef WITH_SELINUX
Restorecon(Constants::ACCOUNT_INDEX_JSON_PATH.c_str());
#endif // WITH_SELINUX
}
accountFileWatcherMgr_.AddFileWatcher(-1, eventCallbackFunc_, Constants::ACCOUNT_INDEX_JSON_PATH);
if (!accountFileOperator_->IsJsonFileReady(Constants::BASE_OSACCOUNT_CONSTRAINTS_JSON_PATH)) {
ACCOUNT_LOGI("OsAccountControlFileManager there is not have valid account list, create!");
BuildAndSaveBaseOAConstraintsJsonFile();
@ -581,6 +256,7 @@ void OsAccountControlFileManager::FileInit()
Restorecon(Constants::BASE_OSACCOUNT_CONSTRAINTS_JSON_PATH.c_str());
#endif // WITH_SELINUX
}
accountFileWatcherMgr_.AddFileWatcher(-1, eventCallbackFunc_, Constants::BASE_OSACCOUNT_CONSTRAINTS_JSON_PATH);
if (!accountFileOperator_->IsJsonFileReady(Constants::GLOBAL_OSACCOUNT_CONSTRAINTS_JSON_PATH)) {
ACCOUNT_LOGI("OsAccountControlFileManager there is not have valid account list, create!");
BuildAndSaveGlobalOAConstraintsJsonFile();
@ -588,6 +264,7 @@ void OsAccountControlFileManager::FileInit()
Restorecon(Constants::GLOBAL_OSACCOUNT_CONSTRAINTS_JSON_PATH.c_str());
#endif // WITH_SELINUX
}
accountFileWatcherMgr_.AddFileWatcher(-1, eventCallbackFunc_, Constants::GLOBAL_OSACCOUNT_CONSTRAINTS_JSON_PATH);
if (!accountFileOperator_->IsJsonFileReady(Constants::SPECIFIC_OSACCOUNT_CONSTRAINTS_JSON_PATH)) {
ACCOUNT_LOGI("OsAccountControlFileManager there is not have valid account list, create!");
BuildAndSaveSpecificOAConstraintsJsonFile();
@ -595,19 +272,20 @@ void OsAccountControlFileManager::FileInit()
Restorecon(Constants::SPECIFIC_OSACCOUNT_CONSTRAINTS_JSON_PATH.c_str());
#endif // WITH_SELINUX
}
accountFileWatcherMgr_.AddFileWatcher(-1, eventCallbackFunc_, Constants::SPECIFIC_OSACCOUNT_CONSTRAINTS_JSON_PATH);
}
void OsAccountControlFileManager::InitFileWatcherInfo(std::vector<std::string> &accountIdList)
{
for (std::string i : accountIdList) {
AddFileWatcher(stoi(i));
accountFileWatcherMgr_.AddFileWatcher(stoi(i), eventCallbackFunc_);
}
WatchOsAccountInfoFile();
}
void OsAccountControlFileManager::BuildAndSaveAccountListJsonFile(const std::vector<std::string>& accounts)
{
ACCOUNT_LOGD("enter.");
std::lock_guard<std::mutex> lock(accountInfoFileLock_);
Json accountList = Json {
{Constants::ACCOUNT_LIST, accounts},
{Constants::COUNT_ACCOUNT_NUM, accounts.size()},
@ -622,6 +300,7 @@ void OsAccountControlFileManager::BuildAndSaveAccountListJsonFile(const std::vec
void OsAccountControlFileManager::BuildAndSaveBaseOAConstraintsJsonFile()
{
ACCOUNT_LOGI("enter.");
std::lock_guard<std::mutex> lock(accountInfoFileLock_);
std::vector<std::string> baseOAConstraints;
if (osAccountFileOperator_->GetConstraintsByType(OsAccountType::ADMIN, baseOAConstraints) != ERR_OK) {
ACCOUNT_LOGE("get %{public}d base os account constraints failed.", Constants::START_USER_ID);
@ -636,6 +315,7 @@ void OsAccountControlFileManager::BuildAndSaveBaseOAConstraintsJsonFile()
void OsAccountControlFileManager::BuildAndSaveGlobalOAConstraintsJsonFile()
{
ACCOUNT_LOGI("enter.");
std::lock_guard<std::mutex> lock(accountInfoFileLock_);
Json globalOsAccountConstraints = Json {
{Constants::DEVICE_OWNER_ID, -1},
{Constants::ALL_GLOBAL_CONSTRAINTS, {}}
@ -645,6 +325,7 @@ void OsAccountControlFileManager::BuildAndSaveGlobalOAConstraintsJsonFile()
void OsAccountControlFileManager::BuildAndSaveSpecificOAConstraintsJsonFile()
{
std::lock_guard<std::mutex> lock(accountInfoFileLock_);
Json OsAccountConstraintsList = Json {
{Constants::ALL_SPECIFIC_CONSTRAINTS, {}},
};
@ -654,12 +335,28 @@ void OsAccountControlFileManager::BuildAndSaveSpecificOAConstraintsJsonFile()
SaveSpecificOAConstraintsToFile(specificOsAccountConstraints);
}
void OsAccountControlFileManager::BuildAndSaveOsAccountIndexJsonFile()
{
std::lock_guard<std::mutex> lock(accountInfoFileLock_);
std::string accountIndex;
ErrCode result = GetAccountIndexInfo(accountIndex);
if (result != ERR_OK) {
ACCOUNT_LOGE("get account index info error code %{public}d.", result);
return;
}
result = accountFileOperator_->InputFileByPathAndContent(Constants::ACCOUNT_INDEX_JSON_PATH, accountIndex);
if (result != ERR_OK) {
ACCOUNT_LOGE("failed to input account index info to file!");
}
return;
}
void OsAccountControlFileManager::RecoverAccountInfoDigestJsonFile()
{
std::string listInfoStr;
accountFileOperator_->GetFileContentByPath(Constants::ACCOUNT_LIST_FILE_JSON_PATH, listInfoStr);
uint8_t digestOutData[ALG_COMMON_SIZE] = {0};
GenerateAccountInfoGigest(listInfoStr, digestOutData, ALG_COMMON_SIZE);
GenerateAccountInfoDigest(listInfoStr, digestOutData, ALG_COMMON_SIZE);
Json digestJsonData = Json {
{Constants::ACCOUNT_LIST_FILE_JSON_PATH, digestOutData},
};
@ -783,6 +480,7 @@ ErrCode OsAccountControlFileManager::GetConstraintsByType(
ErrCode OsAccountControlFileManager::UpdateBaseOAConstraints(const std::string& idStr,
const std::vector<std::string>& ConstraintStr, bool isAdd)
{
std::lock_guard<std::mutex> lock(accountInfoFileLock_);
Json baseOAConstraintsJson;
ErrCode result = GetBaseOAConstraintsFromFile(baseOAConstraintsJson);
if (result != ERR_OK) {
@ -818,6 +516,7 @@ ErrCode OsAccountControlFileManager::UpdateBaseOAConstraints(const std::string&
ErrCode OsAccountControlFileManager::UpdateGlobalOAConstraints(
const std::string& idStr, const std::vector<std::string>& ConstraintStr, bool isAdd)
{
std::lock_guard<std::mutex> lock(accountInfoFileLock_);
Json globalOAConstraintsJson;
ErrCode result = GetGlobalOAConstraintsFromFile(globalOAConstraintsJson);
if (result != ERR_OK) {
@ -882,6 +581,7 @@ void OsAccountControlFileManager::GlobalConstraintsDataOperate(const std::string
ErrCode OsAccountControlFileManager::UpdateSpecificOAConstraints(
const std::string& idStr, const std::string& targetIdStr, const std::vector<std::string>& ConstraintStr, bool isAdd)
{
std::lock_guard<std::mutex> lock(accountInfoFileLock_);
Json specificOAConstraintsJson;
ErrCode result = GetSpecificOAConstraintsFromFile(specificOAConstraintsJson);
if (result != ERR_OK) {
@ -977,6 +677,7 @@ ErrCode OsAccountControlFileManager::RemoveOAConstraintsInfo(const int32_t id)
ErrCode OsAccountControlFileManager::RemoveOABaseConstraintsInfo(const int32_t id)
{
std::lock_guard<std::mutex> lock(accountInfoFileLock_);
Json baseOAConstraintsJson;
ErrCode result = GetBaseOAConstraintsFromFile(baseOAConstraintsJson);
if (result != ERR_OK) {
@ -994,6 +695,7 @@ ErrCode OsAccountControlFileManager::RemoveOABaseConstraintsInfo(const int32_t i
ErrCode OsAccountControlFileManager::RemoveOAGlobalConstraintsInfo(const int32_t id)
{
std::lock_guard<std::mutex> lock(accountInfoFileLock_);
Json globalOAConstraintsJson;
ErrCode result = GetGlobalOAConstraintsFromFile(globalOAConstraintsJson);
if (result != ERR_OK) {
@ -1034,6 +736,7 @@ ErrCode OsAccountControlFileManager::RemoveOAGlobalConstraintsInfo(const int32_t
ErrCode OsAccountControlFileManager::RemoveOASpecificConstraintsInfo(const int32_t id)
{
std::lock_guard<std::mutex> lock(accountInfoFileLock_);
Json specificOAConstraintsJson;
ErrCode result = GetSpecificOAConstraintsFromFile(specificOAConstraintsJson);
if (result != ERR_OK) {
@ -1111,6 +814,7 @@ ErrCode OsAccountControlFileManager::UpdateAccountList(const std::string& idStr,
ErrCode OsAccountControlFileManager::UpdateAccountIndex(const OsAccountInfo &osAccountInfo, const bool isDelete)
{
std::lock_guard<std::mutex> lock(accountInfoFileLock_);
Json accountIndexJson;
ErrCode result = GetAccountIndexFromFile(accountIndexJson);
if (result != ERR_OK) {
@ -1129,7 +833,33 @@ ErrCode OsAccountControlFileManager::UpdateAccountIndex(const OsAccountInfo &osA
accountIndexJson[localIdStr] = accountBaseInfo;
}
std::string lastAccountIndexStr = accountIndexJson.dump();
return accountFileOperator_->InputFileByPathAndContent(Constants::ACCOUNT_INDEX_JSON_PATH, lastAccountIndexStr);
result = accountFileOperator_->InputFileByPathAndContent(Constants::ACCOUNT_INDEX_JSON_PATH, lastAccountIndexStr);
if (result != ERR_OK) {
ACCOUNT_LOGE("failed to input account index info to file!");
return result;
}
accountFileWatcherMgr_.AddAccountInfoDigest(lastAccountIndexStr, Constants::ACCOUNT_INDEX_JSON_PATH);
return ERR_OK;
}
ErrCode OsAccountControlFileManager::RemoveAccountIndex(const int32_t id)
{
Json accountIndexJson;
ErrCode result = GetAccountIndexFromFile(accountIndexJson);
if (result != ERR_OK) {
ACCOUNT_LOGE("get account index failed!");
return result;
}
std::string localIdStr = std::to_string(id);
accountIndexJson.erase(localIdStr);
std::string lastAccountIndexStr = accountIndexJson.dump();
result = accountFileOperator_->InputFileByPathAndContent(Constants::ACCOUNT_INDEX_JSON_PATH, lastAccountIndexStr);
if (result != ERR_OK) {
ACCOUNT_LOGE("failed to input account index info to file!");
return result;
}
accountFileWatcherMgr_.AddAccountInfoDigest(lastAccountIndexStr, Constants::ACCOUNT_INDEX_JSON_PATH);
return ERR_OK;
}
ErrCode OsAccountControlFileManager::InsertOsAccount(OsAccountInfo &osAccountInfo)
@ -1164,12 +894,8 @@ ErrCode OsAccountControlFileManager::InsertOsAccount(OsAccountInfo &osAccountInf
#endif
if (osAccountInfo.GetLocalId() >= Constants::START_USER_ID) {
std::string digestStr;
if (GenerateAccountInfoDigestStr(path, accountInfoStr, digestStr) == ERR_OK) {
accountFileOperator_->InputFileByPathAndContent(Constants::ACCOUNT_INFO_DIGEST_FILE_PATH, digestStr);
}
AddFileWatcher(osAccountInfo.GetLocalId());
WatchOsAccountInfoFile();
accountFileWatcherMgr_.AddAccountInfoDigest(accountInfoStr, path);
accountFileWatcherMgr_.AddFileWatcher(osAccountInfo.GetLocalId(), eventCallbackFunc_);
return UpdateAccountList(osAccountInfo.GetPrimeKey(), true);
}
ACCOUNT_LOGD("end");
@ -1194,75 +920,16 @@ ErrCode OsAccountControlFileManager::DelOsAccount(const int id)
osAccountDataBaseOperator_->DelOsAccountFromDatabase(id);
#endif
path += Constants::PATH_SEPARATOR + Constants::USER_INFO_FILE_NAME;
DeleteAccountInfoDigest(path);
OsAccountInfo osAccountInfo;
osAccountInfo.SetLocalId(id);
UpdateAccountIndex(osAccountInfo, true);
RemoveFileWatcher(id);
accountFileWatcherMgr_.DeleteAccountInfoDigest(path);
accountFileWatcherMgr_.RemoveFileWatcher(id, path);
std::string distributedDataPath =
Constants::USER_INFO_BASE + Constants::PATH_SEPARATOR + std::to_string(id) + DISTRIBUTED_ACCOUNT_FILE_NAME;
accountFileWatcherMgr_.DeleteAccountInfoDigest(distributedDataPath);
accountFileWatcherMgr_.RemoveFileWatcher(id, distributedDataPath);
RemoveAccountIndex(id);
return UpdateAccountList(std::to_string(id), false);
}
ErrCode OsAccountControlFileManager::GenerateAccountInfoDigestStr(
const std::string &userInfoPath, const std::string &accountInfoStr, std::string &digestStr)
{
uint8_t digestOutData[ALG_COMMON_SIZE];
GenerateAccountInfoGigest(accountInfoStr, digestOutData, ALG_COMMON_SIZE);
std::string accountInfoDigest;
std::lock_guard<std::mutex> lock(accountInfoDigestFileLock_);
ErrCode errCode = accountFileOperator_->GetFileContentByPath(Constants::ACCOUNT_INFO_DIGEST_FILE_PATH,
accountInfoDigest);
if (errCode != ERR_OK) {
ACCOUNT_LOGE("get file content failed! error code %{public}d.", errCode);
return errCode;
}
Json accountInfoDigestJson;
try {
accountInfoDigestJson = Json::parse(accountInfoDigest, nullptr, false);
} catch (Json::type_error& err) {
ACCOUNT_LOGE("accountInfoDigestJson parse failed! reason: %{public}s", err.what());
}
if (accountInfoDigestJson.is_discarded()) {
accountInfoDigestJson = Json();
}
accountInfoDigestJson[userInfoPath] = digestOutData;
try {
digestStr = accountInfoDigestJson.dump();
} catch (Json::type_error& err) {
ACCOUNT_LOGE("failed to dump json object, reason: %{public}s", err.what());
return ERR_ACCOUNT_COMMON_DUMP_JSON_ERROR;
}
return ERR_OK;
}
ErrCode OsAccountControlFileManager::DeleteAccountInfoDigest(const std::string &userInfoPath)
{
Json accountInfoDigestJson;
std::string accountInfoDigest;
std::lock_guard<std::mutex> lock(accountInfoDigestFileLock_);
ErrCode errCode = accountFileOperator_->GetFileContentByPath(Constants::ACCOUNT_INFO_DIGEST_FILE_PATH,
accountInfoDigest);
if (errCode != ERR_OK) {
ACCOUNT_LOGE("get file content failed! error code %{public}d.", errCode);
return errCode;
}
try {
accountInfoDigestJson = Json::parse(accountInfoDigest, nullptr, false);
} catch (Json::type_error& err) {
ACCOUNT_LOGE("accountInfoDigestJson parse failed! reason: %{public}s", err.what());
return ERR_ACCOUNT_COMMON_DUMP_JSON_ERROR;
}
accountInfoDigestJson.erase(userInfoPath);
ErrCode result = accountFileOperator_->InputFileByPathAndContent(
Constants::ACCOUNT_INFO_DIGEST_FILE_PATH, accountInfoDigestJson.dump());
if (result != ERR_OK) {
ACCOUNT_LOGE("cannot save digest info to file, code %{public}d.", result);
return result;
}
return ERR_OK;
}
ErrCode OsAccountControlFileManager::UpdateOsAccount(OsAccountInfo &osAccountInfo)
{
@ -1295,9 +962,7 @@ ErrCode OsAccountControlFileManager::UpdateOsAccount(OsAccountInfo &osAccountInf
#endif // DISTRIBUTED_FEATURE_ENABLED
std::string digestStr;
if (GenerateAccountInfoDigestStr(path, accountInfoStr, digestStr) == ERR_OK) {
accountFileOperator_->InputFileByPathAndContent(Constants::ACCOUNT_INFO_DIGEST_FILE_PATH, digestStr);
}
accountFileWatcherMgr_.AddAccountInfoDigest(accountInfoStr, path);
ACCOUNT_LOGD("end");
return ERR_OK;
}
@ -1407,33 +1072,6 @@ ErrCode OsAccountControlFileManager::GetAllowCreateId(int &id)
return ERR_OK;
}
ErrCode OsAccountControlFileManager::GetAccountInfoDigestFromFile(
const std::string &path, uint8_t *digest, uint32_t size)
{
Json accountInfoDigestJson;
std::string accountInfoDigest;
std::lock_guard<std::mutex> lock(accountInfoDigestFileLock_);
ErrCode errCode = accountFileOperator_->GetFileContentByPath(Constants::ACCOUNT_INFO_DIGEST_FILE_PATH,
accountInfoDigest);
if (errCode != ERR_OK) {
ACCOUNT_LOGE("GetFileContentByPath failed! error code %{public}d.", errCode);
return errCode;
}
try {
accountInfoDigestJson = Json::parse(accountInfoDigest, nullptr, false);
} catch (Json::type_error& err) {
ACCOUNT_LOGE("accountInfoDigestJson parse failed! reason: %{public}s", err.what());
return ERR_ACCOUNT_COMMON_DUMP_JSON_ERROR;
}
std::vector<uint8_t> digestTmp;
OHOS::AccountSA::GetDataByType<std::vector<uint8_t>>(accountInfoDigestJson,
accountInfoDigestJson.end(), path, digestTmp, OHOS::AccountSA::JsonType::ARRAY);
if (memcpy_s(digest, size, digestTmp.data(), ALG_COMMON_SIZE) != EOK) {
ACCOUNT_LOGE("Get digest failed duo to memcpy_s failed");
return ERR_ACCOUNT_COMMON_INSUFFICIENT_MEMORY_ERROR;
}
return ERR_OK;
}
ErrCode OsAccountControlFileManager::GetAccountListFromFile(Json &accountListJson)
{
@ -1463,7 +1101,7 @@ ErrCode OsAccountControlFileManager::GetAccountIndexFromFile(Json &accountIndexJ
{
accountIndexJson.clear();
std::string accountIndex;
if (!accountFileOperator_->IsExistFile(Constants::ACCOUNT_INDEX_JSON_PATH)) {
if (!accountFileOperator_->IsJsonFileReady(Constants::ACCOUNT_INDEX_JSON_PATH)) {
ErrCode result = GetAccountIndexInfo(accountIndex);
if (result != ERR_OK) {
ACCOUNT_LOGE("GetAccountIndexInfo error code %{public}d.", result);
@ -1672,11 +1310,7 @@ ErrCode OsAccountControlFileManager::SaveAccountListToFile(const Json &accountLi
ACCOUNT_LOGE("cannot save save account list file content!");
return result;
}
std::string digestStr;
result = GenerateAccountInfoDigestStr(Constants::ACCOUNT_LIST_FILE_JSON_PATH, accountListJson.dump(), digestStr);
if (result == ERR_OK) {
accountFileOperator_->InputFileByPathAndContent(Constants::ACCOUNT_INFO_DIGEST_FILE_PATH, digestStr);
}
accountFileWatcherMgr_.AddAccountInfoDigest(accountListJson.dump(), Constants::ACCOUNT_LIST_FILE_JSON_PATH);
ACCOUNT_LOGD("save account list file succeed!");
return ERR_OK;
}
@ -1690,7 +1324,8 @@ ErrCode OsAccountControlFileManager::SaveBaseOAConstraintsToFile(const Json &bas
ACCOUNT_LOGE("cannot save base osaccount constraints file content!");
return result;
}
accountFileWatcherMgr_.AddAccountInfoDigest(
baseOAConstraints.dump(), Constants::BASE_OSACCOUNT_CONSTRAINTS_JSON_PATH);
return ERR_OK;
}
@ -1703,7 +1338,8 @@ ErrCode OsAccountControlFileManager::SaveGlobalOAConstraintsToFile(const Json &g
ACCOUNT_LOGE("cannot save global osAccount constraints file content!");
return result;
}
accountFileWatcherMgr_.AddAccountInfoDigest(
globalOAConstraints.dump(), Constants::GLOBAL_OSACCOUNT_CONSTRAINTS_JSON_PATH);
return ERR_OK;
}
@ -1716,7 +1352,8 @@ ErrCode OsAccountControlFileManager::SaveSpecificOAConstraintsToFile(const Json
ACCOUNT_LOGE("cannot save specific osAccount constraints file content!");
return result;
}
accountFileWatcherMgr_.AddAccountInfoDigest(
specificOAConstraints.dump(), Constants::SPECIFIC_OSACCOUNT_CONSTRAINTS_JSON_PATH);
return ERR_OK;
}
@ -1739,6 +1376,7 @@ ErrCode OsAccountControlFileManager::GetDeviceOwnerId(int &deviceOwnerId)
ErrCode OsAccountControlFileManager::UpdateDeviceOwnerId(const int deviceOwnerId)
{
std::lock_guard<std::mutex> lock(accountInfoFileLock_);
Json globalOAConstraintsJson;
ErrCode result = GetGlobalOAConstraintsFromFile(globalOAConstraintsJson);
if (result != ERR_OK) {

View File

@ -384,7 +384,7 @@ HWTEST_F(AccountIamCallbackTest, GetCredInfoCallbackWrapper_OnCredentialInfo_010
HWTEST_F(AccountIamCallbackTest, GetPropCallbackWrapper_OnResult_0100, TestSize.Level0)
{
Attributes extraInfo;
auto getPropCallback = std::make_shared<GetPropCallbackWrapper>(nullptr);
auto getPropCallback = std::make_shared<GetPropCallbackWrapper>(DEFAULT_USER_ID, nullptr);
EXPECT_TRUE(getPropCallback->innerCallback_ == nullptr);
getPropCallback->OnResult(0, extraInfo);
}
@ -475,7 +475,7 @@ HWTEST_F(AccountIamCallbackTest, GetCredInfoCallbackWrapper_OnCredentialInfo_040
HWTEST_F(AccountIamCallbackTest, SetPropCallbackWrapper_OnResult_0100, TestSize.Level0)
{
Attributes extraInfo;
auto setPropCallback = std::make_shared<SetPropCallbackWrapper>(nullptr);
auto setPropCallback = std::make_shared<SetPropCallbackWrapper>(DEFAULT_USER_ID, nullptr);
EXPECT_TRUE(setPropCallback->innerCallback_ == nullptr);
setPropCallback->OnResult(0, extraInfo);
}

View File

@ -150,7 +150,7 @@ group("unittest") {
testonly = true
deps = [
":OhosDataDealTest",
#":OhosDataDealTest",
":OhosServiceTest",
]
}