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

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

View File

@ -184,5 +184,24 @@ void ReportOhosAccountStateChange(int32_t userId, int32_t operateType, int32_t o
(void)newStat; (void)newStat;
#endif // HAS_HISYSEVENT_PART #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 } // AccountSA
} // OHOS } // OHOS

View File

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

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2021-2022 Huawei Device Co., Ltd. * Copyright (c) 2021-2023 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
@ -37,16 +37,18 @@ public:
bool IsJsonFormat(const std::string &path); bool IsJsonFormat(const std::string &path);
bool IsJsonFileReady(const std::string &path); bool IsJsonFileReady(const std::string &path);
bool IsExistDir(const std::string &path); bool IsExistDir(const std::string &path);
bool GetValidWriteFileOptFlag(); bool GetValidDeleteFileOperationFlag(const std::string &fileName);
void SetValidWriteFileOptFlag(bool flag); void SetValidDeleteFileOperationFlag(const std::string &fileName, bool flag);
void SetValidDeleteFileOptFlag(const std::string &fileName, bool flag); bool GetValidModifyFileOperationFlag(const std::string &fileName);
bool GetValidDeleteFileOptFlag(const std::string &fileName); void SetValidModifyFileOperationFlag(const std::string &fileName, bool flag);
std::mutex &GetModifyOperationLock();
std::mutex &GetDeleteOperationLock();
private: private:
std::mutex validWriteFileOptLock_; std::mutex validModifyFileOperationLock_;
std::mutex validDeleteFileOptLock_; std::mutex validDeleteFileOperationLock_;
bool validWriteFileOptFlag_ = false; std::vector<std::string> validModifyFileOperationFlag_;
std::vector<std::string> validDeleteFileOptFlag_; std::vector<std::string> validDeleteFileOperationFlag_;
}; };
} // namespace AccountSA } // namespace AccountSA
} // namespace OHOS } // namespace OHOS

View File

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

View File

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

View File

@ -0,0 +1,90 @@
/*
* Copyright (c) 2023 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef OS_ACCOUNT_SERVICES_ACCOUNTMGR_INCLUDE_ACCOUNT_FILE_WATCHER_MANAGER_H
#define OS_ACCOUNT_SERVICES_ACCOUNTMGR_INCLUDE_ACCOUNT_FILE_WATCHER_MANAGER_H
#include <mutex>
#include <sys/inotify.h>
#include <sys/time.h>
#include "account_error_no.h"
#include "account_file_operator.h"
#include "singleton.h"
namespace OHOS {
namespace AccountSA {
int32_t GenerateAccountInfoDigest(const std::string &inData, uint8_t* outData, uint32_t size);
using CheckNotifyEventCallbackFunc = std::function<bool(const std::string&, const int32_t, uint32_t)>;
class FileWatcher {
public:
FileWatcher(const int32_t id);
FileWatcher(const std::string &filePath);
~FileWatcher();
bool InitNotify();
int32_t GetNotifyId();
std::string GetFilePath();
int32_t GetLocalId();
bool StartNotify(const uint32_t &watchEvents);
bool CloseNotifyFd();
bool CheckNotifyEvent(uint32_t event);
void SetEventCallback(CheckNotifyEventCallbackFunc &func);
public:
int32_t id_ = -1;
private:
int32_t notifyFd_ = -1;
int32_t wd_ = -1;
std::string filePath_;
CheckNotifyEventCallbackFunc eventCallbackFunc_;
};
class AccountFileWatcherMgr {
public:
static AccountFileWatcherMgr &GetInstance();
void StartWatch();
void AddFileWatcher(
const int32_t id, CheckNotifyEventCallbackFunc checkCallbackFunc, const std::string filePath = "");
void RemoveFileWatcher(const int32_t id, const std::string filePath);
ErrCode GetAccountInfoDigestFromFile(const std::string &path, uint8_t *digest, uint32_t size);
ErrCode GenerateAccountInfoDigestStr(
const std::string &userInfoPath, const std::string &accountInfoStr, std::string &digestStr);
ErrCode AddAccountInfoDigest(const std::string accountInfo, const std::string &userInfoPath);
ErrCode DeleteAccountInfoDigest(const std::string &userInfoPath);
private:
void DealWithFileEvent();
void GetNotifyEvent();
AccountFileWatcherMgr();
~AccountFileWatcherMgr();
DISALLOW_COPY_AND_MOVE(AccountFileWatcherMgr);
public:
std::mutex accountInfoDigestFileLock_;
std::mutex fileWatcherMgrLock_;
std::shared_ptr<AccountFileOperator> accountFileOperator_;
std::unordered_map<int32_t, std::shared_ptr<FileWatcher>> fileNameMgrMap_;
fd_set fds_;
int32_t maxNotifyFd_ = -1;
std::vector<int32_t> fdArray_;
bool run_ = false;
};
} // namespace AccountSA
} // namespace OHOS
#endif // OS_ACCOUNT_SERVICES_ACCOUNTMGR_INCLUDE_OSACCOUNT_OS_ACCOUNT_CONTROL_FILE_MANAGER_H

View File

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

View File

@ -20,6 +20,8 @@
#include <mutex> #include <mutex>
#include <nlohmann/json.hpp> #include <nlohmann/json.hpp>
#include "account_error_no.h" #include "account_error_no.h"
#include "account_file_operator.h"
#include "account_file_watcher_manager.h"
#include "account_info.h" #include "account_info.h"
namespace OHOS { namespace OHOS {
@ -32,18 +34,28 @@ public:
ErrCode Init(std::int32_t userId); ErrCode Init(std::int32_t userId);
ErrCode AccountInfoFromJson(AccountInfo &accountInfo, int32_t userId); ErrCode AccountInfoFromJson(AccountInfo &accountInfo, int32_t userId);
ErrCode AccountInfoToJson(const AccountInfo &accountInfo) const; ErrCode AccountInfoToJson(const AccountInfo &accountInfo);
~OhosAccountDataDeal() {} ~OhosAccountDataDeal() {}
private: private:
bool DealWithFileModifyEvent(const std::string &fileName, const int32_t id);
void DealWithFileDeleteEvent(const std::string &fileName, const int32_t id);
bool initOk_; bool initOk_;
std::string configFileDir_; std::string configFileDir_;
std::mutex mutex_; std::mutex mutex_;
void BuildJsonFileFromScratch(int32_t userId) const; void BuildJsonFileFromScratch(int32_t userId);
ErrCode SaveAccountInfo(const AccountInfo &accountInfo) const; ErrCode SaveAccountInfo(const AccountInfo &accountInfo);
ErrCode GetAccountInfo(AccountInfo &accountInfo, const int32_t userId); ErrCode GetAccountInfo(AccountInfo &accountInfo, const int32_t userId);
ErrCode ParseJsonFromFile(const std::string &filePath, nlohmann::json &jsonData, 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 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 AccountSA
} // namespace OHOS } // namespace OHOS

View File

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

View File

@ -115,7 +115,7 @@
"OHOS::AccountSA::DelCredCallback::DelCredCallback(int, bool, OHOS::sptr<OHOS::AccountSA::IIDMCallback> const&)"; "OHOS::AccountSA::DelCredCallback::DelCredCallback(int, bool, OHOS::sptr<OHOS::AccountSA::IIDMCallback> const&)";
"OHOS::AccountSA::DomainAccountPluginProxy::DomainAccountPluginProxy(OHOS::sptr<OHOS::IRemoteObject> const&)"; "OHOS::AccountSA::DomainAccountPluginProxy::DomainAccountPluginProxy(OHOS::sptr<OHOS::IRemoteObject> const&)";
"OHOS::AccountSA::GetCredInfoCallbackWrapper::GetCredInfoCallbackWrapper(int, int, OHOS::sptr<OHOS::AccountSA::IGetCredInfoCallback> 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::GetValidAccountID(std::__h::basic_string<char, std::__h::char_traits<char>, std::__h::allocator<char>> const&, int&)";
"OHOS::AccountSA::IAccountContext::instance_"; "OHOS::AccountSA::IAccountContext::instance_";
"OHOS::AccountSA::AccountMgrService::GetCallingUserID()"; "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::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::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::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"; "vtable for OHOS::AccountSA::AccountStub";
"OHOS::AccountSA::AccountStub::AccountStub()"; "OHOS::AccountSA::AccountStub::AccountStub()";
"vtable for OHOS::AccountSA::OsAccountStopUserCallback"; "vtable for OHOS::AccountSA::OsAccountStopUserCallback";
@ -246,6 +246,7 @@
"OHOS::AccountSA::UpdateTraceLabelAdapter()"; "OHOS::AccountSA::UpdateTraceLabelAdapter()";
"OHOS::AccountSA::StartTraceAdapter(std::__h::basic_string<char, std::__h::char_traits<char>, std::__h::allocator<char>> const&)"; "OHOS::AccountSA::StartTraceAdapter(std::__h::basic_string<char, std::__h::char_traits<char>, std::__h::allocator<char>> const&)";
*OHOS::AccountSA::CountTraceAdapter*; *OHOS::AccountSA::CountTraceAdapter*;
*OHOS::AccountSA::AccountFileWatcherMgr*;
"OHOS::AccountSA::FinishTraceAdapter()"; "OHOS::AccountSA::FinishTraceAdapter()";
"OHOS::AccountSA::DomainAccountStub::DomainAccountStub()"; "OHOS::AccountSA::DomainAccountStub::DomainAccountStub()";
"OHOS::AccountSA::DomainAccountStub::~DomainAccountStub()"; "OHOS::AccountSA::DomainAccountStub::~DomainAccountStub()";
@ -278,6 +279,7 @@
"non-virtual thunk to OHOS::AccountSA::AccountIAMMgrStub::~AccountIAMMgrStub()"; "non-virtual thunk to OHOS::AccountSA::AccountIAMMgrStub::~AccountIAMMgrStub()";
"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::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: local:
*; *;

View File

@ -14,6 +14,7 @@ import("../../os_account.gni")
account_service_sources = [ account_service_sources = [
"${services_path}/accountmgr/src/account_event_provider.cpp", "${services_path}/accountmgr/src/account_event_provider.cpp",
"${services_path}/accountmgr/src/account_event_subscribe.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_helper_data.cpp",
"${services_path}/accountmgr/src/account_info_report.cpp", "${services_path}/accountmgr/src/account_info_report.cpp",
"${services_path}/accountmgr/src/account_mgr_service.cpp", "${services_path}/accountmgr/src/account_mgr_service.cpp",

View File

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

View File

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

View File

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

View File

@ -27,7 +27,9 @@
#include "directory_ex.h" #include "directory_ex.h"
#include "file_ex.h" #include "file_ex.h"
#include "hisysevent_adapter.h" #include "hisysevent_adapter.h"
#include "iinner_os_account_manager.h"
#include "ohos_account_data_deal.h" #include "ohos_account_data_deal.h"
namespace OHOS { namespace OHOS {
namespace AccountSA { namespace AccountSA {
namespace { 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_OHOSACCOUNT_SCALABLEDATA = "account_scalableData";
const std::string DATADEAL_JSON_KEY_USERID = "user_id"; const std::string DATADEAL_JSON_KEY_USERID = "user_id";
const std::string DATADEAL_JSON_KEY_BIND_TIME = "bind_time"; const std::string DATADEAL_JSON_KEY_BIND_TIME = "bind_time";
const uint32_t ALG_COMMON_SIZE = 32;
} // namespace } // 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; 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) ErrCode OhosAccountDataDeal::Init(int32_t userId)
@ -80,6 +161,12 @@ ErrCode OhosAccountDataDeal::Init(int32_t userId)
return ERR_ACCOUNT_DATADEAL_JSON_FILE_CORRUPTION; 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; initOk_ = true;
return ERR_OK; return ERR_OK;
} }
@ -93,7 +180,7 @@ ErrCode OhosAccountDataDeal::AccountInfoFromJson(AccountInfo &accountInfo, int32
return GetAccountInfo(accountInfo, userId); return GetAccountInfo(accountInfo, userId);
} }
ErrCode OhosAccountDataDeal::AccountInfoToJson(const AccountInfo &accountInfo) const ErrCode OhosAccountDataDeal::AccountInfoToJson(const AccountInfo &accountInfo)
{ {
if (!initOk_) { if (!initOk_) {
ACCOUNT_LOGE("Not init ok"); ACCOUNT_LOGE("Not init ok");
@ -102,8 +189,9 @@ ErrCode OhosAccountDataDeal::AccountInfoToJson(const AccountInfo &accountInfo) c
return SaveAccountInfo(accountInfo); 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(); std::string scalableDataStr = (accountInfo.ohosAccountInfo_.scalableData_).ToString();
nlohmann::json jsonData = json { nlohmann::json jsonData = json {
{DATADEAL_JSON_KEY_BIND_TIME, accountInfo.bindTime_}, {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 accountInfoValue = jsonData.dump(-1, ' ', false, json::error_handler_t::ignore);
std::string configFile = configFileDir_ + std::to_string(accountInfo.userId_) + ACCOUNT_CFG_FILE_NAME; 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 ErrCode ret = accountFileOperator_->InputFileByPathAndContent(configFile, accountInfoValue);
if (!ChangeModeFile(configFile, S_IRUSR | S_IWUSR)) { if (ret == ERR_OHOSACCOUNT_SERVICE_FILE_CHANGE_DIR_MODE_ERROR) {
ACCOUNT_LOGE("failed to change mode for file %{public}s, errno %{public}d.", configFile.c_str(), errno);
ReportOhosAccountOperationFail(accountInfo.userId_, OPERATION_CHANGE_MODE_FILE, errno, configFile); 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) 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) 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; std::string configFile = configFileDir_ + std::to_string(userId) + ACCOUNT_CFG_FILE_NAME;
if (!FileExists(configFile)) { if (!FileExists(configFile)) {
ACCOUNT_LOGI("file %{public}s not exist, create!", configFile.c_str()); 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); return GetAccountInfoFromJson(jsonData, accountInfo, userId);
} }
void OhosAccountDataDeal::BuildJsonFileFromScratch(int32_t userId) const void OhosAccountDataDeal::BuildJsonFileFromScratch(int32_t userId)
{ {
AccountInfo accountInfo; AccountInfo accountInfo;
accountInfo.userId_ = userId; accountInfo.userId_ = userId;
@ -264,6 +332,7 @@ void OhosAccountDataDeal::BuildJsonFileFromScratch(int32_t userId) const
accountInfo.digest_ = ""; accountInfo.digest_ = "";
accountInfo.ohosAccountInfo_.SetRawUid(DEFAULT_OHOS_ACCOUNT_UID); accountInfo.ohosAccountInfo_.SetRawUid(DEFAULT_OHOS_ACCOUNT_UID);
SaveAccountInfo(accountInfo); SaveAccountInfo(accountInfo);
AddFileWatcher(userId);
} }
} // namespace AccountSA } // namespace AccountSA
} // namespace OHOS } // namespace OHOS

View File

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

View File

@ -27,9 +27,6 @@
#include "account_log_wrapper.h" #include "account_log_wrapper.h"
#include "hisysevent_adapter.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_constants.h"
#include "os_account_interface.h" #include "os_account_interface.h"
@ -38,174 +35,14 @@ namespace AccountSA {
namespace { namespace {
const std::string DEFAULT_ACTIVATED_ACCOUNT_ID = "DefaultActivatedAccountID"; 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 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 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 ALG_COMMON_SIZE = 32;
const uint32_t BUF_COMMON_SIZE = 1024; #ifndef ACCOUNT_TEST
const int32_t TIMES = 4; const std::string ACCOUNT_CFG_DIR_ROOT_PATH = "/data/service/el1/public/account/";
const int32_t MAX_UPDATE_SIZE = 256; #else
const int32_t MAX_OUTDATA_SIZE = MAX_UPDATE_SIZE * TIMES; const std::string ACCOUNT_CFG_DIR_ROOT_PATH = "/data/service/el1/public/account/test/";
const char ACCOUNT_KEY_ALIAS[] = "os_account_info_encryption_key"; #endif // ACCOUNT_TEST
const HksBlob g_keyAlias = { (uint32_t)strlen(ACCOUNT_KEY_ALIAS), (uint8_t *)ACCOUNT_KEY_ALIAS }; const std::string DISTRIBUTED_ACCOUNT_FILE_NAME = "/account.json";
}
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;
} }
bool GetValidAccountID(const std::string& dirName, std::int32_t& accountID) 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); 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) bool OsAccountControlFileManager::RecoverAccountData(const std::string &fileName, const int32_t id)
{ {
#ifdef HAS_KV_STORE_PART #ifdef HAS_KV_STORE_PART
@ -411,10 +75,20 @@ bool OsAccountControlFileManager::RecoverAccountData(const std::string &fileName
Json accountListJson; Json accountListJson;
osAccountDataBaseOperator_->GetAccountListFromStoreID(OS_ACCOUNT_STORE_ID, accountListJson); osAccountDataBaseOperator_->GetAccountListFromStoreID(OS_ACCOUNT_STORE_ID, accountListJson);
recoverDataStr = accountListJson.dump(); recoverDataStr = accountListJson.dump();
} else { } else if (id >= Constants::START_USER_ID) {
OsAccountInfo osAccountInfo; 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(); 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 // recover data
ErrCode result = accountFileOperator_->InputFileByPathAndContent(fileName, recoverDataStr); ErrCode result = accountFileOperator_->InputFileByPathAndContent(fileName, recoverDataStr);
@ -423,37 +97,41 @@ bool OsAccountControlFileManager::RecoverAccountData(const std::string &fileName
return false; return false;
} }
// update local digest // update local digest
std::string digestStr; if (accountFileWatcherMgr_.AddAccountInfoDigest(recoverDataStr, fileName) != ERR_OK) {
if (GenerateAccountInfoDigestStr(fileName, recoverDataStr, digestStr) != ERR_OK) { ACCOUNT_LOGE("failed to update local digest");
return false; return false;
} }
accountFileOperator_->InputFileByPathAndContent(Constants::ACCOUNT_INFO_DIGEST_FILE_PATH, digestStr);
#endif #endif
return true; return true;
} }
bool OsAccountControlFileManager::DealWithFileModifyEvent(const std::string &fileName, const int32_t id) bool OsAccountControlFileManager::DealWithFileModifyEvent(const std::string &fileName, const int32_t id)
{ {
if (accountFileOperator_->GetValidWriteFileOptFlag()) { ACCOUNT_LOGI("enter");
ACCOUNT_LOGD("this is valid service operate, no need to deal with it."); {
accountFileOperator_->SetValidWriteFileOptFlag(false); std::lock_guard<std::mutex> lock(accountFileOperator_->GetModifyOperationLock());
return true; 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::lock_guard<std::mutex> lock(accountInfoFileLock_);
std::string fileInfoStr;
if (accountFileOperator_->GetFileContentByPath(fileName, fileInfoStr) != ERR_OK) { if (accountFileOperator_->GetFileContentByPath(fileName, fileInfoStr) != ERR_OK) {
ACCOUNT_LOGE("get content from file %{public}s failed!", fileName.c_str()); ACCOUNT_LOGE("get content from file %{public}s failed!", fileName.c_str());
return false; return false;
} }
uint8_t localDigestData[ALG_COMMON_SIZE] = {0}; 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}; 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) { if (memcmp(localDigestData, newDigestData, ALG_COMMON_SIZE) == EOK) {
ACCOUNT_LOGD("No need to recover local file data."); ACCOUNT_LOGD("No need to recover local file data.");
return true; return true;
} }
ReportOsAccountDataTampered(id, fileName, "OS_ACCOUNT_INFO");
ACCOUNT_LOGW("local file data has been changed"); ACCOUNT_LOGW("local file data has been changed");
return RecoverAccountData(fileName, id); 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) bool OsAccountControlFileManager::DealWithFileDeleteEvent(const std::string &fileName, const int32_t id)
{ {
ACCOUNT_LOGI("enter"); ACCOUNT_LOGI("enter");
if (accountFileOperator_->GetValidDeleteFileOptFlag(fileName)) { {
ACCOUNT_LOGD("this is valid service operate, no need to deal with it."); std::lock_guard<std::mutex> lock(accountFileOperator_->GetDeleteOperationLock());
accountFileOperator_->SetValidDeleteFileOptFlag(fileName, false); if (accountFileOperator_->GetValidDeleteFileOperationFlag(fileName)) {
return true; 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_); ReportOsAccountDataTampered(id, fileName, "OS_ACCOUNT_INFO");
if (!RecoverAccountData(fileName, id)) { {
ACCOUNT_LOGE("recover account data failed."); 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; return true;
} }
@ -478,52 +162,18 @@ bool OsAccountControlFileManager::DealWithFileMoveEvent(const std::string &fileN
{ {
ACCOUNT_LOGI("enter"); ACCOUNT_LOGI("enter");
// delete old file watcher // delete old file watcher
RemoveFileWatcher(id); accountFileWatcherMgr_.RemoveFileWatcher(id, fileName);
ReportOsAccountDataTampered(id, fileName, "OS_ACCOUNT_INFO");
std::lock_guard<std::mutex> lock(accountInfoFileLock_); std::lock_guard<std::mutex> lock(accountInfoFileLock_);
if (!RecoverAccountData(fileName, id)) { if (!RecoverAccountData(fileName, id)) {
ACCOUNT_LOGE("recover account data failed."); ACCOUNT_LOGE("recover account data failed.");
} }
AddFileWatcher(id); accountFileWatcherMgr_.AddFileWatcher(id, eventCallbackFunc_, fileName);
return true; 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() OsAccountControlFileManager::OsAccountControlFileManager()
: accountFileWatcherMgr_(AccountFileWatcherMgr::GetInstance())
{ {
accountFileOperator_ = std::make_shared<AccountFileOperator>(); accountFileOperator_ = std::make_shared<AccountFileOperator>();
#ifdef HAS_KV_STORE_PART #ifdef HAS_KV_STORE_PART
@ -531,14 +181,30 @@ OsAccountControlFileManager::OsAccountControlFileManager()
#endif #endif
osAccountFileOperator_ = std::make_shared<OsAccountFileOperator>(); osAccountFileOperator_ = std::make_shared<OsAccountFileOperator>();
osAccountPhotoOperator_ = std::make_shared<OsAccountPhotoOperator>(); 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() OsAccountControlFileManager::~OsAccountControlFileManager()
{} {}
void OsAccountControlFileManager::Init() void OsAccountControlFileManager::Init()
{ {
InitEncryptionKey();
osAccountFileOperator_->Init(); osAccountFileOperator_->Init();
FileInit(); FileInit();
Json accountListJson; Json accountListJson;
@ -566,7 +232,6 @@ void OsAccountControlFileManager::FileInit()
Restorecon(Constants::ACCOUNT_LIST_FILE_JSON_PATH.c_str()); Restorecon(Constants::ACCOUNT_LIST_FILE_JSON_PATH.c_str());
#endif // WITH_SELINUX #endif // WITH_SELINUX
} }
AddFileWatcher(-1); // -1 is special refers to accountList file.
if (!accountFileOperator_->IsJsonFileReady(Constants::ACCOUNT_INFO_DIGEST_FILE_PATH)) { if (!accountFileOperator_->IsJsonFileReady(Constants::ACCOUNT_INFO_DIGEST_FILE_PATH)) {
ACCOUNT_LOGI("OsAccountControlFileManager there is not have valid account info digest file, create!"); ACCOUNT_LOGI("OsAccountControlFileManager there is not have valid account info digest file, create!");
RecoverAccountInfoDigestJsonFile(); RecoverAccountInfoDigestJsonFile();
@ -574,6 +239,16 @@ void OsAccountControlFileManager::FileInit()
Restorecon(Constants::ACCOUNT_INFO_DIGEST_FILE_PATH.c_str()); Restorecon(Constants::ACCOUNT_INFO_DIGEST_FILE_PATH.c_str());
#endif // WITH_SELINUX #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)) { if (!accountFileOperator_->IsJsonFileReady(Constants::BASE_OSACCOUNT_CONSTRAINTS_JSON_PATH)) {
ACCOUNT_LOGI("OsAccountControlFileManager there is not have valid account list, create!"); ACCOUNT_LOGI("OsAccountControlFileManager there is not have valid account list, create!");
BuildAndSaveBaseOAConstraintsJsonFile(); BuildAndSaveBaseOAConstraintsJsonFile();
@ -581,6 +256,7 @@ void OsAccountControlFileManager::FileInit()
Restorecon(Constants::BASE_OSACCOUNT_CONSTRAINTS_JSON_PATH.c_str()); Restorecon(Constants::BASE_OSACCOUNT_CONSTRAINTS_JSON_PATH.c_str());
#endif // WITH_SELINUX #endif // WITH_SELINUX
} }
accountFileWatcherMgr_.AddFileWatcher(-1, eventCallbackFunc_, Constants::BASE_OSACCOUNT_CONSTRAINTS_JSON_PATH);
if (!accountFileOperator_->IsJsonFileReady(Constants::GLOBAL_OSACCOUNT_CONSTRAINTS_JSON_PATH)) { if (!accountFileOperator_->IsJsonFileReady(Constants::GLOBAL_OSACCOUNT_CONSTRAINTS_JSON_PATH)) {
ACCOUNT_LOGI("OsAccountControlFileManager there is not have valid account list, create!"); ACCOUNT_LOGI("OsAccountControlFileManager there is not have valid account list, create!");
BuildAndSaveGlobalOAConstraintsJsonFile(); BuildAndSaveGlobalOAConstraintsJsonFile();
@ -588,6 +264,7 @@ void OsAccountControlFileManager::FileInit()
Restorecon(Constants::GLOBAL_OSACCOUNT_CONSTRAINTS_JSON_PATH.c_str()); Restorecon(Constants::GLOBAL_OSACCOUNT_CONSTRAINTS_JSON_PATH.c_str());
#endif // WITH_SELINUX #endif // WITH_SELINUX
} }
accountFileWatcherMgr_.AddFileWatcher(-1, eventCallbackFunc_, Constants::GLOBAL_OSACCOUNT_CONSTRAINTS_JSON_PATH);
if (!accountFileOperator_->IsJsonFileReady(Constants::SPECIFIC_OSACCOUNT_CONSTRAINTS_JSON_PATH)) { if (!accountFileOperator_->IsJsonFileReady(Constants::SPECIFIC_OSACCOUNT_CONSTRAINTS_JSON_PATH)) {
ACCOUNT_LOGI("OsAccountControlFileManager there is not have valid account list, create!"); ACCOUNT_LOGI("OsAccountControlFileManager there is not have valid account list, create!");
BuildAndSaveSpecificOAConstraintsJsonFile(); BuildAndSaveSpecificOAConstraintsJsonFile();
@ -595,19 +272,20 @@ void OsAccountControlFileManager::FileInit()
Restorecon(Constants::SPECIFIC_OSACCOUNT_CONSTRAINTS_JSON_PATH.c_str()); Restorecon(Constants::SPECIFIC_OSACCOUNT_CONSTRAINTS_JSON_PATH.c_str());
#endif // WITH_SELINUX #endif // WITH_SELINUX
} }
accountFileWatcherMgr_.AddFileWatcher(-1, eventCallbackFunc_, Constants::SPECIFIC_OSACCOUNT_CONSTRAINTS_JSON_PATH);
} }
void OsAccountControlFileManager::InitFileWatcherInfo(std::vector<std::string> &accountIdList) void OsAccountControlFileManager::InitFileWatcherInfo(std::vector<std::string> &accountIdList)
{ {
for (std::string i : accountIdList) { for (std::string i : accountIdList) {
AddFileWatcher(stoi(i)); accountFileWatcherMgr_.AddFileWatcher(stoi(i), eventCallbackFunc_);
} }
WatchOsAccountInfoFile();
} }
void OsAccountControlFileManager::BuildAndSaveAccountListJsonFile(const std::vector<std::string>& accounts) void OsAccountControlFileManager::BuildAndSaveAccountListJsonFile(const std::vector<std::string>& accounts)
{ {
ACCOUNT_LOGD("enter."); ACCOUNT_LOGD("enter.");
std::lock_guard<std::mutex> lock(accountInfoFileLock_);
Json accountList = Json { Json accountList = Json {
{Constants::ACCOUNT_LIST, accounts}, {Constants::ACCOUNT_LIST, accounts},
{Constants::COUNT_ACCOUNT_NUM, accounts.size()}, {Constants::COUNT_ACCOUNT_NUM, accounts.size()},
@ -622,6 +300,7 @@ void OsAccountControlFileManager::BuildAndSaveAccountListJsonFile(const std::vec
void OsAccountControlFileManager::BuildAndSaveBaseOAConstraintsJsonFile() void OsAccountControlFileManager::BuildAndSaveBaseOAConstraintsJsonFile()
{ {
ACCOUNT_LOGI("enter."); ACCOUNT_LOGI("enter.");
std::lock_guard<std::mutex> lock(accountInfoFileLock_);
std::vector<std::string> baseOAConstraints; std::vector<std::string> baseOAConstraints;
if (osAccountFileOperator_->GetConstraintsByType(OsAccountType::ADMIN, baseOAConstraints) != ERR_OK) { if (osAccountFileOperator_->GetConstraintsByType(OsAccountType::ADMIN, baseOAConstraints) != ERR_OK) {
ACCOUNT_LOGE("get %{public}d base os account constraints failed.", Constants::START_USER_ID); ACCOUNT_LOGE("get %{public}d base os account constraints failed.", Constants::START_USER_ID);
@ -636,6 +315,7 @@ void OsAccountControlFileManager::BuildAndSaveBaseOAConstraintsJsonFile()
void OsAccountControlFileManager::BuildAndSaveGlobalOAConstraintsJsonFile() void OsAccountControlFileManager::BuildAndSaveGlobalOAConstraintsJsonFile()
{ {
ACCOUNT_LOGI("enter."); ACCOUNT_LOGI("enter.");
std::lock_guard<std::mutex> lock(accountInfoFileLock_);
Json globalOsAccountConstraints = Json { Json globalOsAccountConstraints = Json {
{Constants::DEVICE_OWNER_ID, -1}, {Constants::DEVICE_OWNER_ID, -1},
{Constants::ALL_GLOBAL_CONSTRAINTS, {}} {Constants::ALL_GLOBAL_CONSTRAINTS, {}}
@ -645,6 +325,7 @@ void OsAccountControlFileManager::BuildAndSaveGlobalOAConstraintsJsonFile()
void OsAccountControlFileManager::BuildAndSaveSpecificOAConstraintsJsonFile() void OsAccountControlFileManager::BuildAndSaveSpecificOAConstraintsJsonFile()
{ {
std::lock_guard<std::mutex> lock(accountInfoFileLock_);
Json OsAccountConstraintsList = Json { Json OsAccountConstraintsList = Json {
{Constants::ALL_SPECIFIC_CONSTRAINTS, {}}, {Constants::ALL_SPECIFIC_CONSTRAINTS, {}},
}; };
@ -654,12 +335,28 @@ void OsAccountControlFileManager::BuildAndSaveSpecificOAConstraintsJsonFile()
SaveSpecificOAConstraintsToFile(specificOsAccountConstraints); 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() void OsAccountControlFileManager::RecoverAccountInfoDigestJsonFile()
{ {
std::string listInfoStr; std::string listInfoStr;
accountFileOperator_->GetFileContentByPath(Constants::ACCOUNT_LIST_FILE_JSON_PATH, listInfoStr); accountFileOperator_->GetFileContentByPath(Constants::ACCOUNT_LIST_FILE_JSON_PATH, listInfoStr);
uint8_t digestOutData[ALG_COMMON_SIZE] = {0}; uint8_t digestOutData[ALG_COMMON_SIZE] = {0};
GenerateAccountInfoGigest(listInfoStr, digestOutData, ALG_COMMON_SIZE); GenerateAccountInfoDigest(listInfoStr, digestOutData, ALG_COMMON_SIZE);
Json digestJsonData = Json { Json digestJsonData = Json {
{Constants::ACCOUNT_LIST_FILE_JSON_PATH, digestOutData}, {Constants::ACCOUNT_LIST_FILE_JSON_PATH, digestOutData},
}; };
@ -783,6 +480,7 @@ ErrCode OsAccountControlFileManager::GetConstraintsByType(
ErrCode OsAccountControlFileManager::UpdateBaseOAConstraints(const std::string& idStr, ErrCode OsAccountControlFileManager::UpdateBaseOAConstraints(const std::string& idStr,
const std::vector<std::string>& ConstraintStr, bool isAdd) const std::vector<std::string>& ConstraintStr, bool isAdd)
{ {
std::lock_guard<std::mutex> lock(accountInfoFileLock_);
Json baseOAConstraintsJson; Json baseOAConstraintsJson;
ErrCode result = GetBaseOAConstraintsFromFile(baseOAConstraintsJson); ErrCode result = GetBaseOAConstraintsFromFile(baseOAConstraintsJson);
if (result != ERR_OK) { if (result != ERR_OK) {
@ -818,6 +516,7 @@ ErrCode OsAccountControlFileManager::UpdateBaseOAConstraints(const std::string&
ErrCode OsAccountControlFileManager::UpdateGlobalOAConstraints( ErrCode OsAccountControlFileManager::UpdateGlobalOAConstraints(
const std::string& idStr, const std::vector<std::string>& ConstraintStr, bool isAdd) const std::string& idStr, const std::vector<std::string>& ConstraintStr, bool isAdd)
{ {
std::lock_guard<std::mutex> lock(accountInfoFileLock_);
Json globalOAConstraintsJson; Json globalOAConstraintsJson;
ErrCode result = GetGlobalOAConstraintsFromFile(globalOAConstraintsJson); ErrCode result = GetGlobalOAConstraintsFromFile(globalOAConstraintsJson);
if (result != ERR_OK) { if (result != ERR_OK) {
@ -882,6 +581,7 @@ void OsAccountControlFileManager::GlobalConstraintsDataOperate(const std::string
ErrCode OsAccountControlFileManager::UpdateSpecificOAConstraints( ErrCode OsAccountControlFileManager::UpdateSpecificOAConstraints(
const std::string& idStr, const std::string& targetIdStr, const std::vector<std::string>& ConstraintStr, bool isAdd) 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; Json specificOAConstraintsJson;
ErrCode result = GetSpecificOAConstraintsFromFile(specificOAConstraintsJson); ErrCode result = GetSpecificOAConstraintsFromFile(specificOAConstraintsJson);
if (result != ERR_OK) { if (result != ERR_OK) {
@ -977,6 +677,7 @@ ErrCode OsAccountControlFileManager::RemoveOAConstraintsInfo(const int32_t id)
ErrCode OsAccountControlFileManager::RemoveOABaseConstraintsInfo(const int32_t id) ErrCode OsAccountControlFileManager::RemoveOABaseConstraintsInfo(const int32_t id)
{ {
std::lock_guard<std::mutex> lock(accountInfoFileLock_);
Json baseOAConstraintsJson; Json baseOAConstraintsJson;
ErrCode result = GetBaseOAConstraintsFromFile(baseOAConstraintsJson); ErrCode result = GetBaseOAConstraintsFromFile(baseOAConstraintsJson);
if (result != ERR_OK) { if (result != ERR_OK) {
@ -994,6 +695,7 @@ ErrCode OsAccountControlFileManager::RemoveOABaseConstraintsInfo(const int32_t i
ErrCode OsAccountControlFileManager::RemoveOAGlobalConstraintsInfo(const int32_t id) ErrCode OsAccountControlFileManager::RemoveOAGlobalConstraintsInfo(const int32_t id)
{ {
std::lock_guard<std::mutex> lock(accountInfoFileLock_);
Json globalOAConstraintsJson; Json globalOAConstraintsJson;
ErrCode result = GetGlobalOAConstraintsFromFile(globalOAConstraintsJson); ErrCode result = GetGlobalOAConstraintsFromFile(globalOAConstraintsJson);
if (result != ERR_OK) { if (result != ERR_OK) {
@ -1034,6 +736,7 @@ ErrCode OsAccountControlFileManager::RemoveOAGlobalConstraintsInfo(const int32_t
ErrCode OsAccountControlFileManager::RemoveOASpecificConstraintsInfo(const int32_t id) ErrCode OsAccountControlFileManager::RemoveOASpecificConstraintsInfo(const int32_t id)
{ {
std::lock_guard<std::mutex> lock(accountInfoFileLock_);
Json specificOAConstraintsJson; Json specificOAConstraintsJson;
ErrCode result = GetSpecificOAConstraintsFromFile(specificOAConstraintsJson); ErrCode result = GetSpecificOAConstraintsFromFile(specificOAConstraintsJson);
if (result != ERR_OK) { if (result != ERR_OK) {
@ -1111,6 +814,7 @@ ErrCode OsAccountControlFileManager::UpdateAccountList(const std::string& idStr,
ErrCode OsAccountControlFileManager::UpdateAccountIndex(const OsAccountInfo &osAccountInfo, const bool isDelete) ErrCode OsAccountControlFileManager::UpdateAccountIndex(const OsAccountInfo &osAccountInfo, const bool isDelete)
{ {
std::lock_guard<std::mutex> lock(accountInfoFileLock_);
Json accountIndexJson; Json accountIndexJson;
ErrCode result = GetAccountIndexFromFile(accountIndexJson); ErrCode result = GetAccountIndexFromFile(accountIndexJson);
if (result != ERR_OK) { if (result != ERR_OK) {
@ -1129,7 +833,33 @@ ErrCode OsAccountControlFileManager::UpdateAccountIndex(const OsAccountInfo &osA
accountIndexJson[localIdStr] = accountBaseInfo; accountIndexJson[localIdStr] = accountBaseInfo;
} }
std::string lastAccountIndexStr = accountIndexJson.dump(); 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) ErrCode OsAccountControlFileManager::InsertOsAccount(OsAccountInfo &osAccountInfo)
@ -1164,12 +894,8 @@ ErrCode OsAccountControlFileManager::InsertOsAccount(OsAccountInfo &osAccountInf
#endif #endif
if (osAccountInfo.GetLocalId() >= Constants::START_USER_ID) { if (osAccountInfo.GetLocalId() >= Constants::START_USER_ID) {
std::string digestStr; accountFileWatcherMgr_.AddAccountInfoDigest(accountInfoStr, path);
if (GenerateAccountInfoDigestStr(path, accountInfoStr, digestStr) == ERR_OK) { accountFileWatcherMgr_.AddFileWatcher(osAccountInfo.GetLocalId(), eventCallbackFunc_);
accountFileOperator_->InputFileByPathAndContent(Constants::ACCOUNT_INFO_DIGEST_FILE_PATH, digestStr);
}
AddFileWatcher(osAccountInfo.GetLocalId());
WatchOsAccountInfoFile();
return UpdateAccountList(osAccountInfo.GetPrimeKey(), true); return UpdateAccountList(osAccountInfo.GetPrimeKey(), true);
} }
ACCOUNT_LOGD("end"); ACCOUNT_LOGD("end");
@ -1194,75 +920,16 @@ ErrCode OsAccountControlFileManager::DelOsAccount(const int id)
osAccountDataBaseOperator_->DelOsAccountFromDatabase(id); osAccountDataBaseOperator_->DelOsAccountFromDatabase(id);
#endif #endif
path += Constants::PATH_SEPARATOR + Constants::USER_INFO_FILE_NAME; path += Constants::PATH_SEPARATOR + Constants::USER_INFO_FILE_NAME;
DeleteAccountInfoDigest(path); accountFileWatcherMgr_.DeleteAccountInfoDigest(path);
accountFileWatcherMgr_.RemoveFileWatcher(id, path);
OsAccountInfo osAccountInfo; std::string distributedDataPath =
osAccountInfo.SetLocalId(id); Constants::USER_INFO_BASE + Constants::PATH_SEPARATOR + std::to_string(id) + DISTRIBUTED_ACCOUNT_FILE_NAME;
UpdateAccountIndex(osAccountInfo, true); accountFileWatcherMgr_.DeleteAccountInfoDigest(distributedDataPath);
RemoveFileWatcher(id); accountFileWatcherMgr_.RemoveFileWatcher(id, distributedDataPath);
RemoveAccountIndex(id);
return UpdateAccountList(std::to_string(id), false); 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) ErrCode OsAccountControlFileManager::UpdateOsAccount(OsAccountInfo &osAccountInfo)
{ {
@ -1295,9 +962,7 @@ ErrCode OsAccountControlFileManager::UpdateOsAccount(OsAccountInfo &osAccountInf
#endif // DISTRIBUTED_FEATURE_ENABLED #endif // DISTRIBUTED_FEATURE_ENABLED
std::string digestStr; std::string digestStr;
if (GenerateAccountInfoDigestStr(path, accountInfoStr, digestStr) == ERR_OK) { accountFileWatcherMgr_.AddAccountInfoDigest(accountInfoStr, path);
accountFileOperator_->InputFileByPathAndContent(Constants::ACCOUNT_INFO_DIGEST_FILE_PATH, digestStr);
}
ACCOUNT_LOGD("end"); ACCOUNT_LOGD("end");
return ERR_OK; return ERR_OK;
} }
@ -1407,33 +1072,6 @@ ErrCode OsAccountControlFileManager::GetAllowCreateId(int &id)
return ERR_OK; 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) ErrCode OsAccountControlFileManager::GetAccountListFromFile(Json &accountListJson)
{ {
@ -1463,7 +1101,7 @@ ErrCode OsAccountControlFileManager::GetAccountIndexFromFile(Json &accountIndexJ
{ {
accountIndexJson.clear(); accountIndexJson.clear();
std::string accountIndex; std::string accountIndex;
if (!accountFileOperator_->IsExistFile(Constants::ACCOUNT_INDEX_JSON_PATH)) { if (!accountFileOperator_->IsJsonFileReady(Constants::ACCOUNT_INDEX_JSON_PATH)) {
ErrCode result = GetAccountIndexInfo(accountIndex); ErrCode result = GetAccountIndexInfo(accountIndex);
if (result != ERR_OK) { if (result != ERR_OK) {
ACCOUNT_LOGE("GetAccountIndexInfo error code %{public}d.", result); 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!"); ACCOUNT_LOGE("cannot save save account list file content!");
return result; return result;
} }
std::string digestStr; accountFileWatcherMgr_.AddAccountInfoDigest(accountListJson.dump(), Constants::ACCOUNT_LIST_FILE_JSON_PATH);
result = GenerateAccountInfoDigestStr(Constants::ACCOUNT_LIST_FILE_JSON_PATH, accountListJson.dump(), digestStr);
if (result == ERR_OK) {
accountFileOperator_->InputFileByPathAndContent(Constants::ACCOUNT_INFO_DIGEST_FILE_PATH, digestStr);
}
ACCOUNT_LOGD("save account list file succeed!"); ACCOUNT_LOGD("save account list file succeed!");
return ERR_OK; return ERR_OK;
} }
@ -1690,7 +1324,8 @@ ErrCode OsAccountControlFileManager::SaveBaseOAConstraintsToFile(const Json &bas
ACCOUNT_LOGE("cannot save base osaccount constraints file content!"); ACCOUNT_LOGE("cannot save base osaccount constraints file content!");
return result; return result;
} }
accountFileWatcherMgr_.AddAccountInfoDigest(
baseOAConstraints.dump(), Constants::BASE_OSACCOUNT_CONSTRAINTS_JSON_PATH);
return ERR_OK; return ERR_OK;
} }
@ -1703,7 +1338,8 @@ ErrCode OsAccountControlFileManager::SaveGlobalOAConstraintsToFile(const Json &g
ACCOUNT_LOGE("cannot save global osAccount constraints file content!"); ACCOUNT_LOGE("cannot save global osAccount constraints file content!");
return result; return result;
} }
accountFileWatcherMgr_.AddAccountInfoDigest(
globalOAConstraints.dump(), Constants::GLOBAL_OSACCOUNT_CONSTRAINTS_JSON_PATH);
return ERR_OK; return ERR_OK;
} }
@ -1716,7 +1352,8 @@ ErrCode OsAccountControlFileManager::SaveSpecificOAConstraintsToFile(const Json
ACCOUNT_LOGE("cannot save specific osAccount constraints file content!"); ACCOUNT_LOGE("cannot save specific osAccount constraints file content!");
return result; return result;
} }
accountFileWatcherMgr_.AddAccountInfoDigest(
specificOAConstraints.dump(), Constants::SPECIFIC_OSACCOUNT_CONSTRAINTS_JSON_PATH);
return ERR_OK; return ERR_OK;
} }
@ -1739,6 +1376,7 @@ ErrCode OsAccountControlFileManager::GetDeviceOwnerId(int &deviceOwnerId)
ErrCode OsAccountControlFileManager::UpdateDeviceOwnerId(const int deviceOwnerId) ErrCode OsAccountControlFileManager::UpdateDeviceOwnerId(const int deviceOwnerId)
{ {
std::lock_guard<std::mutex> lock(accountInfoFileLock_);
Json globalOAConstraintsJson; Json globalOAConstraintsJson;
ErrCode result = GetGlobalOAConstraintsFromFile(globalOAConstraintsJson); ErrCode result = GetGlobalOAConstraintsFromFile(globalOAConstraintsJson);
if (result != ERR_OK) { if (result != ERR_OK) {

View File

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

View File

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