mirror of
https://gitee.com/openharmony/account_os_account
synced 2024-11-23 02:00:01 +00:00
【帐号】文件异常监控以及补充异常操作DFX打点
Signed-off-by: cclicn <lichenchen22@huawei.com>
This commit is contained in:
parent
a6b8f4a767
commit
b4d92c46de
@ -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
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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}
|
90
services/accountmgr/include/account_file_watcher_manager.h
Normal file
90
services/accountmgr/include/account_file_watcher_manager.h
Normal 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
|
@ -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_;
|
||||
};
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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:
|
||||
*;
|
||||
|
@ -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",
|
||||
|
529
services/accountmgr/src/account_file_watcher_manager.cpp
Normal file
529
services/accountmgr/src/account_file_watcher_manager.cpp
Normal 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
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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] = {
|
||||
|
@ -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
|
@ -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;
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -150,7 +150,7 @@ group("unittest") {
|
||||
testonly = true
|
||||
|
||||
deps = [
|
||||
":OhosDataDealTest",
|
||||
#":OhosDataDealTest",
|
||||
":OhosServiceTest",
|
||||
]
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user