diff --git a/credential/credential_base.cpp b/credential/credential_base.cpp index 918441254537d84cf578866b7436c8f5cecedc73..79dd5b04d2d165ac6403e348c192f8fcc4a19310 100644 --- a/credential/credential_base.cpp +++ b/credential/credential_base.cpp @@ -16,7 +16,8 @@ using namespace Hdc; -char HdcCredentialBase::GetPathSep() +namespace HdcCredentialBase { +char GetPathSep() { #ifdef _WIN32 const char sep = '\\'; @@ -26,7 +27,7 @@ char HdcCredentialBase::GetPathSep() return sep; } -int HdcCredentialBase::RemoveDir(const std::string& dir) +int RemoveDir(const std::string& dir) { DIR *pdir = opendir(dir.c_str()); if (pdir == nullptr) { @@ -39,7 +40,7 @@ int HdcCredentialBase::RemoveDir(const std::string& dir) if (ent->d_name[0] == '.') { continue; } - std::string subpath = dir + HdcCredentialBase::GetPathSep() + ent->d_name; + std::string subpath = dir + GetPathSep() + ent->d_name; if (lstat(subpath.c_str(), &st) == -1) { WRITE_LOG(LOG_WARN, "lstat failed subpath:%s", subpath.c_str()); continue; @@ -66,7 +67,7 @@ int HdcCredentialBase::RemoveDir(const std::string& dir) return 0; } -int HdcCredentialBase::RemovePath(const std::string& path) +int RemovePath(const std::string& path) { struct stat st; if (lstat(path.c_str(), &st) == -1) { @@ -81,14 +82,15 @@ int HdcCredentialBase::RemovePath(const std::string& path) if (path == "." || path == "..") { return 0; } - int rc = HdcCredentialBase::RemoveDir(path); + int rc = RemoveDir(path); WRITE_LOG(LOG_INFO, "RemoveDir rc:%d path:%s", rc, path.c_str()); return rc; } + WRITE_LOG(LOG_DEBUG, "Directory removed successfully."); return 0; } -const std::string HdcCredentialBase::StringFormat(const char* const formater, ...) +const std::string StringFormat(const char* const formater, ...) { va_list vaArgs; va_start(vaArgs, formater); @@ -97,7 +99,7 @@ const std::string HdcCredentialBase::StringFormat(const char* const formater, .. return ret; } -const std::string HdcCredentialBase::StringFormat(const char* const formater, va_list& vaArgs) +const std::string StringFormat(const char* const formater, va_list& vaArgs) { std::vector args(MAX_SIZE_IOBUF_STABLE); const int retSize = vsnprintf_s( @@ -107,4 +109,30 @@ const std::string HdcCredentialBase::StringFormat(const char* const formater, va } else { return std::string(args.data(), retSize); } -} \ No newline at end of file +} + +bool CreatePathWithMode(const char* path, mode_t mode) +{ + if (::mkdir(path, mode) != 0) { + WRITE_LOG(LOG_FATAL, "Failed to create directory ,error is :%s", strerror(errno)); + return false; + } + if (::chmod(path, mode) != 0) { + WRITE_LOG(LOG_FATAL, "Failed to set directory permissions, error is :%s", strerror(errno)); + return false; + } + WRITE_LOG(LOG_DEBUG, "Directory created successfully."); + return true; +} + +bool IsUserDir(const std::string& dir) +{ + int userId; + try { + userId = std::stoi(dir); + } catch (const std::invalid_argument&) { + userId = 0; + } + return userId >= MIN_USER_ID && userId <= MAX_USER_ID; +} +} // namespace HdcCredentialBase \ No newline at end of file diff --git a/credential/credential_base.h b/credential/credential_base.h index 8b4589fd13b4ded7751295a8485f5f57c77c7045..471f621f5b7beb99c36de744b9044e20a7ce0e69 100644 --- a/credential/credential_base.h +++ b/credential/credential_base.h @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -49,12 +50,27 @@ constexpr uint32_t MAX_SIZE_IOBUF_STABLE = 60 * 1024; // 60KB, compatible with p const std::string HDC_CREDENTIAL_SOCKET_REAL_PATH = "/data/service/el1/public/hdc_server/hdc_common/hdc_credential.socket"; constexpr uint8_t CMD_ARG1_COUNT = 2; +constexpr int MIN_USER_ID = 100; +constexpr int MAX_USER_ID = 10736; int RemoveDir(const std::string& dir); int RemovePath(const std::string& path); const std::string StringFormat(const char* const formater, ...); const std::string StringFormat(const char* const formater, va_list& vaArgs); char GetPathSep(); +bool CreatePathWithMode(const char* path, mode_t mode); +bool IsUserDir(const std::string& dir); + +/* Calculate diff: return elements in vector a but not in vector b */ +template +std::vector Substract(const std::vector& a, const std::vector& b) +{ + std::set aSet(a.begin(), a.end()); + std::set bSet(b.begin(), b.end()); + std::vector diff; + std::set_difference(aSet.begin(), aSet.end(), bSet.begin(), bSet.end(), std::back_inserter(diff)); + return diff; +} } // namespace HdcCredentialBase #endif // HDC_CREDENTIAL_BASE_H \ No newline at end of file diff --git a/credential/hdc_subscriber.cpp b/credential/hdc_subscriber.cpp index a06b51d1459eb1b76f06590ebaf4c29be1080e5a..a64d386b0c8f6557182cff16fd4324b4d01f99c8 100644 --- a/credential/hdc_subscriber.cpp +++ b/credential/hdc_subscriber.cpp @@ -12,36 +12,31 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#include "credential_base.h" #include "hdc_subscriber.h" +#include +#include "credential_base.h" using namespace Hdc; using namespace OHOS::AccountSA; +namespace fs = std::filesystem; + +namespace { +static const std::string USER_DIR_PREFIX_PATH = "/data/service/el1/public/hdc_server/"; +static const mode_t MODE = (S_IRWXU | S_IRWXG | S_IXOTH | S_ISGID); +} void HdcSubscriber::OnStateChanged(const OHOS::AccountSA::OsAccountStateData& data) { WRITE_LOG(LOG_INFO, "Recv data.state:%d, data.toId:%d", data.state, data.toId); - std::string strId = std::to_string(data.toId); - std::string path = std::string("/data/service/el1/public/hdc_server/") + - strId; - mode_t mode = (S_IRWXU | S_IRWXG | S_IXOTH | S_ISGID); - + std::string path = USER_DIR_PREFIX_PATH + std::to_string(data.toId); switch (data.state) { case OsAccountState::CREATED: - if (::mkdir(path.c_str(), mode) != 0) { - WRITE_LOG(LOG_FATAL, "Failed to create directory ,error is :%s", strerror(errno)); - break; - } - if (::chmod(path.c_str(), mode) != 0) { - WRITE_LOG(LOG_FATAL, "Failed to set directory permissions, error is :%s", strerror(errno)); - break; + if (HdcCredentialBase::CreatePathWithMode(path.c_str(), MODE) != 0) { + WRITE_LOG(LOG_FATAL, "Failed to create directory, error is:%s", strerror(errno)); } - WRITE_LOG(LOG_DEBUG, "Directory created successfully."); break; case OsAccountState::REMOVED: - if (HdcCredentialBase::RemovePath(path.c_str()) == 0) { - WRITE_LOG(LOG_DEBUG, "Directory removed successfully."); - } else { + if (HdcCredentialBase::RemovePath(path.c_str()) != 0) { WRITE_LOG(LOG_FATAL, "Failed to remove directory, error is:%s", strerror(errno)); } break; @@ -49,7 +44,6 @@ void HdcSubscriber::OnStateChanged(const OHOS::AccountSA::OsAccountStateData& da WRITE_LOG(LOG_FATAL, "This state is not support,state is:%d", data.state); break; } - return; } void HdcSubscriber::OnAccountsChanged(const int& id) @@ -81,4 +75,39 @@ int HdcAccountSubscriberMonitor() } return 0; +} + +void FreshAccountsPath() +{ + std::vector osAccountInfos; + OHOS::ErrCode err = OHOS::AccountSA::OsAccountManager::QueryAllCreatedOsAccounts(osAccountInfos); + if (err != 0) { + WRITE_LOG(LOG_FATAL, "QueryAllCreatedOsAccounts failed, error is:%d", err); + return; + } + std::vector existUserIds; + for (const auto& info : osAccountInfos) { + existUserIds.push_back(std::to_string(info.GetLocalId())); + } + std::vector existUserDirs; + for (const auto& entry : fs::directory_iterator(USER_DIR_PREFIX_PATH)) { + std::string dir = entry.path().filename().string(); + if (HdcCredentialBase::IsUserDir(dir)) { + existUserDirs.push_back(dir); + } + } + std::vector needCreate = HdcCredentialBase::Substract(existUserIds, existUserDirs); + std::vector needRemove = HdcCredentialBase::Substract(existUserDirs, existUserIds); + for (const auto& item : needCreate) { + std::string path = USER_DIR_PREFIX_PATH + item; + if (!HdcCredentialBase::CreatePathWithMode(path.c_str(), MODE)) { + WRITE_LOG(LOG_FATAL, "Failed to create directory, error is:%s", strerror(errno)); + } + } + for (const auto& item : needRemove) { + std::string path = USER_DIR_PREFIX_PATH + item; + if (HdcCredentialBase::RemovePath(path.c_str()) != 0) { + WRITE_LOG(LOG_FATAL, "Failed to remove directory, error is:%s", strerror(errno)); + } + } } \ No newline at end of file diff --git a/credential/hdc_subscriber.h b/credential/hdc_subscriber.h index 091db27a13980b2beffac175a4e76bfec69e03e8..2cef3b28e747983f7a1d50bc791f60c2a9fedd4f 100644 --- a/credential/hdc_subscriber.h +++ b/credential/hdc_subscriber.h @@ -28,5 +28,5 @@ public: }; int HdcAccountSubscriberMonitor(); - +void FreshAccountsPath(); #endif // HDC_SUBSCRIBER_H \ No newline at end of file diff --git a/credential/main.cpp b/credential/main.cpp index b019e166c96987bb64cd430b9f414c1014372a22..3b01138a234e5a3531a2a877f355aaa568f79f17 100644 --- a/credential/main.cpp +++ b/credential/main.cpp @@ -229,6 +229,9 @@ int main(int argc, const char *argv[]) WRITE_LOG(LOG_FATAL, "HdcAccountSubscriberMonitor failed"); return 0; } + // fresh all accounts path when process restart. + FreshAccountsPath(); + int sockfd = CreateAndBindSocket(HDC_CREDENTIAL_SOCKET_REAL_PATH.c_str()); if (sockfd < 0) { WRITE_LOG(LOG_FATAL, "Failed to create and bind socket."); diff --git a/src/common/password.cpp b/src/common/password.cpp index e9c5457e02a885d5dd345ff68f7469f05cd33024..23cc0ac75f002f62f575417da0b3d8ab44772ce9 100644 --- a/src/common/password.cpp +++ b/src/common/password.cpp @@ -286,9 +286,11 @@ bool HdcPassword::DecryptPwd(std::vector& encryptData) bool HdcPassword::EncryptPwd(void) { - std::vector encryptData; ClearEncryptPwd(); - encryptData = EncryptGetPwdValue(pwd, PASSWORD_LENGTH); + std::vector encryptData = EncryptGetPwdValue(pwd, PASSWORD_LENGTH); + if (encryptData.size() == 0) { + return false; + } ByteToHex(encryptData); return true; } diff --git a/src/daemon/etc/hdc_credential.cfg b/src/daemon/etc/hdc_credential.cfg index 5bcc5a84a5e2b20348abe9251e77c60263a333f5..2a110830c55160f0852827c8b0d8493627368224 100644 --- a/src/daemon/etc/hdc_credential.cfg +++ b/src/daemon/etc/hdc_credential.cfg @@ -25,7 +25,10 @@ "gid" : "hdc" }], "apl" : "normal", - "permission" : [ "ohos.permission.INTERACT_ACROSS_LOCAL_ACCOUNTS" ], + "permission" : [ + "ohos.permission.INTERACT_ACROSS_LOCAL_ACCOUNTS", + "ohos.permission.MANAGE_LOCAL_ACCOUNTS" + ], "sandbox" : 0, "start-mode" : "condition", "secon" : "u:r:hdc_credential:s0",