From 52af9e41190a6df9c2b5ffe604824a7967371854 Mon Sep 17 00:00:00 2001 From: guoliang47 Date: Sun, 30 Mar 2025 12:48:48 +0800 Subject: [PATCH 1/4] push all dm_v2 Signed-off-by: guoliang47 --- bundle.json | 3 +- common/include/dm_constants.h | 1 + common/include/dm_error_type.h | 8 +- common/src/dm_constants.cpp | 1 + .../include/deviceprofile_connector.h | 28 +- .../include/multiple_user_connector.h | 3 +- .../src/deviceprofile_connector.cpp | 360 +++- .../src/multiple_user_connector.cpp | 9 + .../ets/UIExtAbility/ConfirmUIExtAbility.ets | 3 + .../ets/UIExtAbility/InputUIExtAbility.ets | 3 + .../ets/UIExtAbility/PincodeUIExtAbility.ets | 3 + .../src/main/ets/pages/ConfirmDialog.ets | 19 +- .../main/ets/pages/ConfirmDialogWearable.ets | 10 +- .../src/main/ets/pages/InputPinDialog.ets | 10 +- .../main/ets/pages/InputPinDialogWearable.ets | 10 +- .../entry/src/main/ets/pages/PinDialog.ets | 18 +- .../src/main/ets/pages/PinDialogWearable.ets | 10 +- ext/pin_auth/BUILD.gn | 1 + services/implementation/BUILD.gn | 18 + .../include/ability/dm_dialog_manager.h | 5 + .../authentication/auth_message_processor.h | 11 - .../include/authentication/dm_auth_manager.h | 12 +- .../include/authentication_v2/auth_manager.h | 209 +++ .../authentication_v2/dm_auth_context.h | 233 +++ .../authentication_v2/dm_auth_manager_base.h | 216 +++ .../dm_auth_message_processor.h | 321 ++++ .../include/authentication_v2/dm_auth_state.h | 387 +++++ .../authentication_v2/dm_auth_state_machine.h | 119 ++ .../include/cryptomgr/crypto_mgr.h | 1 + .../hichain/hichain_auth_connector.h | 24 + .../dependency/hichain/hichain_connector.h | 2 +- .../hichain/hichain_connector_callback.h | 3 +- .../dependency/softbus/softbus_connector.h | 8 +- .../include/device_manager_service_impl.h | 74 +- .../ability/standard/dm_dialog_manager.cpp | 49 +- .../authentication/auth_message_processor.cpp | 11 - .../src/authentication/dm_auth_manager.cpp | 116 +- .../src/authentication_v2/auth_manager.cpp | 1106 +++++++++++++ .../auth_stages/auth_acl.cpp | 160 ++ .../auth_stages/auth_confirm.cpp | 349 ++++ .../auth_stages/auth_credential.cpp | 531 ++++++ .../auth_stages/auth_negotiate.cpp | 250 +++ .../auth_stages/auth_pin_auth.cpp | 543 ++++++ .../src/authentication_v2/dm_auth_context.cpp | 87 + .../dm_auth_manager_base.cpp | 417 +++++ .../dm_auth_message_processor.cpp | 1461 +++++++++++++++++ .../src/authentication_v2/dm_auth_state.cpp | 600 +++++++ .../dm_auth_state_machine.cpp | 347 ++++ .../src/cryptomgr/crypto_mgr.cpp | 12 + .../hichain/hichain_auth_connector.cpp | 292 +++- .../dependency/softbus/softbus_connector.cpp | 97 +- .../dependency/softbus/softbus_session.cpp | 51 +- .../src/device_manager_service_impl.cpp | 1094 +++++++++++- .../include/idevice_manager_service_impl.h | 2 + .../relationship_sync_mgr.h | 2 + .../service/src/device_manager_service.cpp | 4 + .../relationship_sync_mgr.cpp | 25 +- test/commonfuzztest/BUILD.gn | 2 + .../dmauthmanagerv2_fuzzer/BUILD.gn | 79 + .../dmauthmanagerv2_fuzzer/corpus/init | 13 + .../dm_auth_manager_fuzzer.cpp | 121 ++ .../dm_auth_manager_fuzzer.h | 21 + .../dmauthmanagerv2_fuzzer/project.xml | 25 + .../ondatareceivedv2_fuzzer/BUILD.gn | 78 + .../ondatareceivedv2_fuzzer/corpus/init | 13 + .../on_data_received_fuzzer.cpp | 71 + .../on_data_received_fuzzer.h | 21 + .../ondatareceivedv2_fuzzer/project.xml | 25 + .../UTTest_hichain_auth_connector.cpp | 7 + .../UTTest_hichain_auth_connector.h | 1 + test/unittest/BUILD.gn | 95 ++ .../unittest/UTTest_auth_credential_state.cpp | 1104 +++++++++++++ test/unittest/UTTest_auth_credential_state.h | 50 + test/unittest/UTTest_auth_negotiate_state.cpp | 175 ++ test/unittest/UTTest_auth_negotiate_state.h | 48 + test/unittest/UTTest_auth_pin_auth_state.cpp | 562 +++++++ test/unittest/UTTest_auth_pin_auth_state.h | 45 + .../mock/dm_auth_message_processor_mock.cpp | 27 + .../mock/dm_auth_message_processor_mock.h | 34 + .../mock/dm_auth_state_machine_mock.cpp | 27 + .../mock/dm_auth_state_machine_mock.h | 33 + .../mock/hichain_auth_connector_mock.cpp | 44 + .../mock/hichain_auth_connector_mock.h | 25 + test/unittest/mock/softbus_connector_mock.cpp | 5 + test/unittest/mock/softbus_connector_mock.h | 2 + test/unittest/mock/softbus_session_mock.cpp | 15 + test/unittest/mock/softbus_session_mock.h | 7 + 87 files changed, 12231 insertions(+), 293 deletions(-) create mode 100644 services/implementation/include/authentication_v2/auth_manager.h create mode 100644 services/implementation/include/authentication_v2/dm_auth_context.h create mode 100644 services/implementation/include/authentication_v2/dm_auth_manager_base.h create mode 100644 services/implementation/include/authentication_v2/dm_auth_message_processor.h create mode 100644 services/implementation/include/authentication_v2/dm_auth_state.h create mode 100644 services/implementation/include/authentication_v2/dm_auth_state_machine.h create mode 100644 services/implementation/src/authentication_v2/auth_manager.cpp create mode 100644 services/implementation/src/authentication_v2/auth_stages/auth_acl.cpp create mode 100644 services/implementation/src/authentication_v2/auth_stages/auth_confirm.cpp create mode 100644 services/implementation/src/authentication_v2/auth_stages/auth_credential.cpp create mode 100644 services/implementation/src/authentication_v2/auth_stages/auth_negotiate.cpp create mode 100644 services/implementation/src/authentication_v2/auth_stages/auth_pin_auth.cpp create mode 100644 services/implementation/src/authentication_v2/dm_auth_context.cpp create mode 100644 services/implementation/src/authentication_v2/dm_auth_manager_base.cpp create mode 100644 services/implementation/src/authentication_v2/dm_auth_message_processor.cpp create mode 100644 services/implementation/src/authentication_v2/dm_auth_state.cpp create mode 100644 services/implementation/src/authentication_v2/dm_auth_state_machine.cpp create mode 100644 test/commonfuzztest/dmauthmanagerv2_fuzzer/BUILD.gn create mode 100644 test/commonfuzztest/dmauthmanagerv2_fuzzer/corpus/init create mode 100644 test/commonfuzztest/dmauthmanagerv2_fuzzer/dm_auth_manager_fuzzer.cpp create mode 100644 test/commonfuzztest/dmauthmanagerv2_fuzzer/dm_auth_manager_fuzzer.h create mode 100644 test/commonfuzztest/dmauthmanagerv2_fuzzer/project.xml create mode 100644 test/commonfuzztest/ondatareceivedv2_fuzzer/BUILD.gn create mode 100644 test/commonfuzztest/ondatareceivedv2_fuzzer/corpus/init create mode 100644 test/commonfuzztest/ondatareceivedv2_fuzzer/on_data_received_fuzzer.cpp create mode 100644 test/commonfuzztest/ondatareceivedv2_fuzzer/on_data_received_fuzzer.h create mode 100644 test/commonfuzztest/ondatareceivedv2_fuzzer/project.xml create mode 100644 test/unittest/UTTest_auth_credential_state.cpp create mode 100644 test/unittest/UTTest_auth_credential_state.h create mode 100644 test/unittest/UTTest_auth_negotiate_state.cpp create mode 100644 test/unittest/UTTest_auth_negotiate_state.h create mode 100644 test/unittest/UTTest_auth_pin_auth_state.cpp create mode 100644 test/unittest/UTTest_auth_pin_auth_state.h create mode 100644 test/unittest/mock/dm_auth_message_processor_mock.cpp create mode 100644 test/unittest/mock/dm_auth_message_processor_mock.h create mode 100644 test/unittest/mock/dm_auth_state_machine_mock.cpp create mode 100644 test/unittest/mock/dm_auth_state_machine_mock.h diff --git a/bundle.json b/bundle.json index 6f03c8187..0158bd785 100644 --- a/bundle.json +++ b/bundle.json @@ -59,7 +59,8 @@ "resource_management", "wifi", "screenlock_mgr", - "mbedtls" + "mbedtls", + "zlib" ], "third_party": [] }, diff --git a/common/include/dm_constants.h b/common/include/dm_constants.h index 88adb121b..884100500 100755 --- a/common/include/dm_constants.h +++ b/common/include/dm_constants.h @@ -30,6 +30,7 @@ EXPORT extern const char* TAG_GROUP_ID; EXPORT extern const char* TAG_GROUP_NAME; EXPORT extern const char* TAG_REQUEST_ID; EXPORT extern const char* TAG_DEVICE_ID; +EXPORT extern const char* TAG_USER_ID; EXPORT extern const char* TAG_AUTH_TYPE; EXPORT extern const char* TAG_CRYPTO_SUPPORT; EXPORT extern const char* TAG_VER; diff --git a/common/include/dm_error_type.h b/common/include/dm_error_type.h index 2d2b96fe2..0ee98c188 100644 --- a/common/include/dm_error_type.h +++ b/common/include/dm_error_type.h @@ -119,8 +119,12 @@ enum { ERR_DM_NAME_EMPTY = 96929831, ERR_DM_HICHAIN_PROOFMISMATCH = 96929832, ERR_DM_PROCESS_SESSION_KEY_FAILED = 96929833, - ERR_DM_HILINKSVC_SCAS_CHECK_FAILED = 96929834, - ERR_DM_FIND_NETWORKID_LIST_EMPTY = 96929835, + ERR_DM_GET_SESSION_KEY_FAILED = 96929834, + ERR_DM_QUADRUPLE_NOT_SAME = 96929835, + ERR_DM_NEXT_STATE_INVALID = 96929836, + ERR_DM_HILINKSVC_SCAS_CHECK_FAILED = 96929837, + ERR_DM_FIND_NETWORKID_LIST_EMPTY = 96929838, + ERR_DM_LOGIC_SESSION_CREATE_FAILED = 96929839, }; } // namespace DistributedHardware } // namespace OHOS diff --git a/common/src/dm_constants.cpp b/common/src/dm_constants.cpp index db8a8118b..ead180935 100644 --- a/common/src/dm_constants.cpp +++ b/common/src/dm_constants.cpp @@ -21,6 +21,7 @@ const char* TAG_GROUP_ID = "groupId"; const char* TAG_GROUP_NAME = "GROUPNAME"; const char* TAG_REQUEST_ID = "REQUESTID"; const char* TAG_DEVICE_ID = "DEVICEID"; +const char* TAG_USER_ID = "USERID"; const char* TAG_AUTH_TYPE = "AUTHTYPE"; const char* TAG_CRYPTO_SUPPORT = "CRYPTOSUPPORT"; const char* TAG_VER = "ITF_VER"; diff --git a/commondependency/include/deviceprofile_connector.h b/commondependency/include/deviceprofile_connector.h index 64533caa1..1fac75678 100644 --- a/commondependency/include/deviceprofile_connector.h +++ b/commondependency/include/deviceprofile_connector.h @@ -89,6 +89,7 @@ typedef struct DmAccessee { typedef struct DmOfflineParam { uint32_t bindType; std::vector processVec; + std::vector credIdVec; int32_t leftAclNumber; } DmOfflineParam; @@ -112,8 +113,12 @@ public: class DeviceProfileConnector : public IDeviceProfileConnector { DM_DECLARE_SINGLE_INSTANCE(DeviceProfileConnector); public: + EXPORT DmOfflineParam DeleteAccessControlList_v2(const uint32_t tokenId, const std::string &localDeviceId, + const std::string &remoteDeviceId, int32_t bindLevel, const std::string &extra); EXPORT std::vector GetAccessControlProfile(); + EXPORT DmOfflineParam HandleServiceUnBindEvent(int32_t remoteUserId, + const std::string &remoteUdid, const std::string &localUdid, int32_t tokenId); std::vector GetAccessControlProfileByUserId(int32_t userId); std::vector GetAclProfileByDeviceIdAndUserId( const std::string &deviceId, int32_t userId); @@ -164,13 +169,12 @@ public: int32_t userId, const std::string &accountId, const std::string &localUdid); int32_t HandleAccountLogoutEvent(int32_t remoteUserId, const std::string &remoteAccountHash, const std::string &remoteUdid, const std::string &localUdid); - EXPORT int32_t HandleDevUnBindEvent(int32_t remoteUserId, - const std::string &remoteUdid, const std::string &localUdid); - EXPORT OHOS::DistributedHardware::ProcessInfo HandleAppUnBindEvent( - int32_t remoteUserId, const std::string &remoteUdid, int32_t tokenId, const std::string &localUdid); - EXPORT OHOS::DistributedHardware::ProcessInfo HandleAppUnBindEvent( - int32_t remoteUserId, const std::string &remoteUdid, int32_t tokenId, const std::string &localUdid, - int32_t peerTokenId); + EXPORT int32_t HandleDevUnBindEvent(DmOfflineParam &offlineParam, + int32_t remoteUserId, const std::string &remoteUdid, const std::string &localUdid); + EXPORT DmOfflineParam HandleAppUnBindEvent(int32_t remoteUserId, const std::string &remoteUdid, + int32_t tokenId, const std::string &localUdid); + EXPORT DmOfflineParam HandleAppUnBindEvent(int32_t remoteUserId, const std::string &remoteUdid, + int32_t tokenId, const std::string &localUdid, int32_t peerTokenId); EXPORT std::vector GetAllAccessControlProfile(); EXPORT void DeleteAccessControlById(int64_t accessControlId); @@ -205,6 +209,7 @@ public: const std::vector &localUserIds, std::string &localUdid); EXPORT void HandleDeviceUnBind(int32_t bindType, const std::string &peerUdid, const std::string &localUdid, int32_t localUserId, const std::string &localAccountId); + EXPORT int32_t DeleteSessionKey(int32_t sessionKeyId); EXPORT int32_t SubscribeDeviceProfileInited( sptr dpInitedCallback); EXPORT int32_t UnSubscribeDeviceProfileInited(); @@ -267,6 +272,15 @@ private: bool CheckAclStatusNotMatch(const DistributedDeviceProfile::AccessControlProfile &profile, const std::string &localUdid, const std::vector &foregroundUserIds, const std::vector &backgroundUserIds); + void DeleteAppBindLevel_v2(DmOfflineParam &offlineParam, const uint32_t tokenId, + const std::vector &profiles, const std::string &localUdid, + const std::string &remoteUdid); + void DeleteAppBindLevel_v2(DmOfflineParam &offlineParam, const uint32_t tokenId, + const std::vector &profiles, const std::string &localUdid, + const std::string &remoteUdid, const std::string &extra); + void DeleteServiceBindLevel_v2(DmOfflineParam &offlineParam, const uint32_t tokenId, + const std::vector &profiles, const std::string &localUdid, + const std::string &remoteUdid); }; extern "C" IDeviceProfileConnector *CreateDpConnectorInstance(); diff --git a/commondependency/include/multiple_user_connector.h b/commondependency/include/multiple_user_connector.h index a96752c43..5baeae25b 100644 --- a/commondependency/include/multiple_user_connector.h +++ b/commondependency/include/multiple_user_connector.h @@ -83,7 +83,7 @@ public: * @tc.type: FUNC */ static std::string GetSwitchOldAccountId(void); - + /** * @tc.name: MultipleUserConnector::SetSwitchOldAccountName * @tc.desc: Set Switch Old AccountName of the Multiple User Connector @@ -108,6 +108,7 @@ public: EXPORT static void SetAccountInfo(int32_t userId, DMAccountInfo dmAccountInfo); EXPORT static DMAccountInfo GetAccountInfoByUserId(int32_t userId); EXPORT static void DeleteAccountInfoByUserId(int32_t userId); + EXPORT static void GetTokenId(uint32_t &tokenId); EXPORT static void GetTokenIdAndForegroundUserId(uint32_t &tokenId, int32_t &userId); EXPORT static void GetCallerUserId(int32_t &userId); diff --git a/commondependency/src/deviceprofile_connector.cpp b/commondependency/src/deviceprofile_connector.cpp index 1146f3e8e..7a5844d45 100644 --- a/commondependency/src/deviceprofile_connector.cpp +++ b/commondependency/src/deviceprofile_connector.cpp @@ -39,11 +39,205 @@ const uint32_t DM_INVALIED_BINDTYPE = 2048; const uint32_t DEVICE = 1; const uint32_t SERVICE = 2; const uint32_t APP = 3; +const uint32_t USER = 1; constexpr uint32_t MAX_SESSION_KEY_LENGTH = 512; namespace OHOS { namespace DistributedHardware { DM_IMPLEMENT_SINGLE_INSTANCE(DeviceProfileConnector); +EXPORT DmOfflineParam DeviceProfileConnector::DeleteAccessControlList_v2(const uint32_t tokenId, + const std::string &localDeviceId, const std::string &remoteDeviceId, int32_t bindLevel, const std::string &extra) +{ + LOGI("localDeviceId %{public}s, remoteDeviceId %{public}s, bindLevel %{public}d.", + GetAnonyString(localDeviceId).c_str(), GetAnonyString(remoteDeviceId).c_str(), bindLevel); + DmOfflineParam offlineParam; + offlineParam.bindType = INVALIED_TYPE; + if (static_cast(bindLevel) > APP || static_cast(bindLevel) < USER) { + LOGE("Invalied bindlevel."); + return offlineParam; + } + int32_t userId = -1; + MultipleUserConnector::GetCallerUserId(userId); + std::vector profiles = GetAclProfileByDeviceIdAndUserId(localDeviceId, userId); + if (profiles.empty()) { + LOGE("Acl is empty."); + return offlineParam; + } + switch (bindLevel) { + case APP: + if (extra == "") { + DeleteAppBindLevel_v2(offlineParam, tokenId, profiles, localDeviceId, remoteDeviceId); + } else { + DeleteAppBindLevel_v2(offlineParam, tokenId, profiles, localDeviceId, remoteDeviceId, extra); + } + break; + case SERVICE: + DeleteServiceBindLevel_v2(offlineParam, tokenId, profiles, localDeviceId, remoteDeviceId); + break; + case DEVICE: + DeleteDeviceBindLevel(offlineParam, profiles, localDeviceId, remoteDeviceId); + break; + default: + break; + } + return offlineParam; +} + +void DeviceProfileConnector::DeleteAppBindLevel_v2(DmOfflineParam &offlineParam, const uint32_t tokenId, + const std::vector &profiles, const std::string &localUdid, + const std::string &remoteUdid) +{ + int32_t bindNums = 0; + int32_t deleteNums = 0; + for (auto &item : profiles) { + if (item.GetTrustDeviceId() != remoteUdid || item.GetBindType() == DM_IDENTICAL_ACCOUNT || + item.GetBindLevel() != APP) { + continue; + } + bindNums++; + if ((item.GetAccesser().GetAccesserTokenId() == static_cast(tokenId) || + item.GetAccesser().GetAccesserTokenId() == 0) && + item.GetAccesser().GetAccesserDeviceId() == localUdid && + item.GetAccessee().GetAccesseeDeviceId() == remoteUdid) { + DistributedDeviceProfileClient::GetInstance().DeleteAccessControlProfile(item.GetAccessControlId()); + deleteNums++; + offlineParam.bindType = APP; + ProcessInfo processInfo; + processInfo.pkgName = item.GetAccesser().GetAccesserBundleName(); + processInfo.userId = item.GetAccesser().GetAccesserUserId(); + offlineParam.processVec.push_back(processInfo); + offlineParam.credIdVec.push_back(item.GetAccesser().GetAccesserCredentialId()); + LOGI("Src delete acl bindType %{public}d, localUdid %{public}s, remoteUdid %{public}s", + item.GetBindType(), GetAnonyString(localUdid).c_str(), + GetAnonyString(remoteUdid).c_str()); + continue; + } + if ((item.GetAccessee().GetAccesseeTokenId() == static_cast(tokenId) || + item.GetAccessee().GetAccesseeTokenId() == 0) && + item.GetAccessee().GetAccesseeDeviceId() == localUdid && + item.GetAccesser().GetAccesserDeviceId() == remoteUdid) { + DistributedDeviceProfileClient::GetInstance().DeleteAccessControlProfile(item.GetAccessControlId()); + deleteNums++; + offlineParam.bindType = APP; + ProcessInfo processInfo; + processInfo.pkgName = item.GetAccessee().GetAccesseeBundleName(); + processInfo.userId = item.GetAccessee().GetAccesseeUserId(); + offlineParam.processVec.push_back(processInfo); + offlineParam.credIdVec.push_back(item.GetAccessee().GetAccesseeCredentialId()); + LOGI("Sink delete acl bindType %{public}d, localUdid %{public}s, remoteUdid %{public}s", + item.GetBindType(), GetAnonyString(localUdid).c_str(), + GetAnonyString(remoteUdid).c_str()); + continue; + } + } + offlineParam.leftAclNumber = bindNums - deleteNums; +} + +void DeviceProfileConnector::DeleteAppBindLevel_v2(DmOfflineParam &offlineParam, const uint32_t tokenId, + const std::vector &profiles, const std::string &localUdid, + const std::string &remoteUdid, const std::string &extra) +{ + LOGI("DeviceProfileConnector::DeleteAppBindLevel extra %{public}s", extra.c_str()); + int32_t bindNums = 0; + int32_t deleteNums = 0; + uint32_t peerTokenId = std::atoi(extra.c_str()); + for (auto &item : profiles) { + if (item.GetTrustDeviceId() != remoteUdid || item.GetBindType() == DM_IDENTICAL_ACCOUNT || + item.GetBindLevel() != APP) { + continue; + } + bindNums++; + if ((item.GetAccesser().GetAccesserTokenId() == static_cast(tokenId) || + item.GetAccesser().GetAccesserTokenId() == 0) && + (item.GetAccessee().GetAccesseeTokenId() == static_cast(peerTokenId) || + item.GetAccessee().GetAccesseeTokenId() == 0) && + item.GetAccesser().GetAccesserDeviceId() == localUdid && + item.GetAccessee().GetAccesseeDeviceId() == remoteUdid) { + DistributedDeviceProfileClient::GetInstance().DeleteAccessControlProfile(item.GetAccessControlId()); + deleteNums++; + offlineParam.bindType = APP; + ProcessInfo processInfo; + processInfo.pkgName = item.GetAccesser().GetAccesserBundleName(); + processInfo.userId = item.GetAccesser().GetAccesserUserId(); + offlineParam.processVec.push_back(processInfo); + offlineParam.credIdVec.push_back(item.GetAccesser().GetAccesserCredentialId()); + LOGI("Src delete acl bindType %{public}d, localUdid %{public}s, remoteUdid %{public}s", + item.GetBindType(), GetAnonyString(localUdid).c_str(), + GetAnonyString(remoteUdid).c_str()); + continue; + } + if ((item.GetAccessee().GetAccesseeTokenId() == static_cast(tokenId) || + item.GetAccessee().GetAccesseeTokenId() == 0) && + (item.GetAccesser().GetAccesserTokenId() == static_cast(peerTokenId) || + item.GetAccesser().GetAccesserTokenId() == 0) && + item.GetAccessee().GetAccesseeDeviceId() == localUdid && + item.GetAccesser().GetAccesserDeviceId() == remoteUdid) { + DistributedDeviceProfileClient::GetInstance().DeleteAccessControlProfile(item.GetAccessControlId()); + deleteNums++; + offlineParam.bindType = APP; + ProcessInfo processInfo; + processInfo.pkgName = item.GetAccessee().GetAccesseeBundleName(); + processInfo.userId = item.GetAccessee().GetAccesseeUserId(); + offlineParam.processVec.push_back(processInfo); + offlineParam.credIdVec.push_back(item.GetAccessee().GetAccesseeCredentialId()); + LOGI("Sink delete acl bindType %{public}d, localUdid %{public}s, remoteUdid %{public}s", + item.GetBindType(), GetAnonyString(localUdid).c_str(), + GetAnonyString(remoteUdid).c_str()); + continue; + } + } + offlineParam.leftAclNumber = bindNums - deleteNums; +} + +void DeviceProfileConnector::DeleteServiceBindLevel_v2(DmOfflineParam &offlineParam, const uint32_t tokenId, + const std::vector &profiles, const std::string &localUdid, + const std::string &remoteUdid) +{ + int32_t bindNums = 0; + int32_t deleteNums = 0; + for (auto &item : profiles) { + if (item.GetTrustDeviceId() != remoteUdid || item.GetBindType() == DM_IDENTICAL_ACCOUNT || + item.GetBindLevel() != SERVICE) { + continue; + } + bindNums++; + if ((item.GetAccesser().GetAccesserTokenId() == static_cast(tokenId) || + item.GetAccesser().GetAccesserTokenId() == 0) && + item.GetAccesser().GetAccesserDeviceId() == localUdid && + item.GetAccessee().GetAccesseeDeviceId() == remoteUdid) { + DistributedDeviceProfileClient::GetInstance().DeleteAccessControlProfile(item.GetAccessControlId()); + deleteNums++; + offlineParam.bindType = SERVICE; + ProcessInfo processInfo; + processInfo.pkgName = item.GetAccessee().GetAccesseeBundleName(); + processInfo.userId = item.GetAccessee().GetAccesseeUserId(); + offlineParam.processVec.push_back(processInfo); + offlineParam.credIdVec.push_back(item.GetAccesser().GetAccesserCredentialId()); + LOGI("Src delete acl bindType %{public}d, localUdid %{public}s, remoteUdid %{public}s", + item.GetBindType(), GetAnonyString(localUdid).c_str(), + GetAnonyString(remoteUdid).c_str()); + continue; + } + if ((item.GetAccessee().GetAccesseeTokenId() == static_cast(tokenId) || + item.GetAccessee().GetAccesseeTokenId() == 0) && + item.GetAccessee().GetAccesseeDeviceId() == localUdid && + item.GetAccesser().GetAccesserDeviceId() == remoteUdid) { + DistributedDeviceProfileClient::GetInstance().DeleteAccessControlProfile(item.GetAccessControlId()); + deleteNums++; + offlineParam.bindType = SERVICE; + ProcessInfo processInfo; + processInfo.pkgName = item.GetAccesser().GetAccesserBundleName(); + processInfo.userId = item.GetAccesser().GetAccesserUserId(); + offlineParam.processVec.push_back(processInfo); + offlineParam.credIdVec.push_back(item.GetAccessee().GetAccesseeCredentialId()); + LOGI("Sink delete acl bindType %{public}d, localUdid %{public}s, remoteUdid %{public}s", + item.GetBindType(), GetAnonyString(localUdid).c_str(), + GetAnonyString(remoteUdid).c_str()); + continue; + } + } + offlineParam.leftAclNumber = bindNums - deleteNums; +} EXPORT std::vector DeviceProfileConnector::GetAccessControlProfile() { @@ -434,7 +628,7 @@ EXPORT std::vector DeviceProfileConnector::SyncAclByBindType( return bindType; } -EXPORT +EXPORT std::vector DeviceProfileConnector::GetProcessInfoFromAclByUserId( const std::string &localDeviceId, const std::string &targetDeviceId, int32_t userId) { @@ -751,6 +945,7 @@ void DeviceProfileConnector::DeleteDeviceBindLevel(DmOfflineParam &offlineParam, DistributedDeviceProfileClient::GetInstance().DeleteAccessControlProfile(item.GetAccessControlId()); deleteNums++; offlineParam.bindType = DEVICE; + offlineParam.credIdVec.push_back(item.GetAccesser().GetAccesserCredentialId()); LOGI("Src delete acl bindType %{public}d, localUdid %{public}s, remoteUdid %{public}s", item.GetBindType(), GetAnonyString(localUdid).c_str(), GetAnonyString(remoteUdid).c_str()); continue; @@ -760,6 +955,7 @@ void DeviceProfileConnector::DeleteDeviceBindLevel(DmOfflineParam &offlineParam, DistributedDeviceProfileClient::GetInstance().DeleteAccessControlProfile(item.GetAccessControlId()); deleteNums++; offlineParam.bindType = DEVICE; + offlineParam.credIdVec.push_back(item.GetAccessee().GetAccesseeCredentialId()); LOGI("Sink delete acl bindType %{public}d, localUdid %{public}s, remoteUdid %{public}s", item.GetBindType(), GetAnonyString(localUdid).c_str(), GetAnonyString(remoteUdid).c_str()); continue; @@ -1204,11 +1400,13 @@ int32_t DeviceProfileConnector::HandleAccountLogoutEvent(int32_t remoteUserId, return bindType; } -EXPORT int32_t DeviceProfileConnector::HandleDevUnBindEvent(int32_t remoteUserId, - const std::string &remoteUdid, const std::string &localUdid) +EXPORT int32_t DeviceProfileConnector::HandleDevUnBindEvent(DmOfflineParam &offlineParam, + int32_t remoteUserId, const std::string &remoteUdid, const std::string &localUdid) { LOGI("RemoteUserId %{public}d, remoteUdid %{public}s, localUdid %{public}s.", remoteUserId, GetAnonyString(remoteUdid).c_str(), GetAnonyString(localUdid).c_str()); + int32_t bindNums = 0; + int32_t deleteNums = 0; std::vector profiles = GetAclProfileByDeviceIdAndUserId(remoteUdid, remoteUserId); int32_t bindType = DM_INVALIED_BINDTYPE; for (const auto &item : profiles) { @@ -1219,85 +1417,192 @@ EXPORT int32_t DeviceProfileConnector::HandleDevUnBindEvent(int32_t remoteUserId bindType = DM_IDENTICAL_ACCOUNT; continue; } - DistributedDeviceProfileClient::GetInstance().DeleteAccessControlProfile(item.GetAccessControlId()); - bindType = std::min(bindType, static_cast(item.GetBindType())); + bindNums++; + if (item.GetAccesser().GetAccesserDeviceId() == localUdid && + item.GetAccessee().GetAccesseeDeviceId() == remoteUdid) { + DistributedDeviceProfileClient::GetInstance().DeleteAccessControlProfile(item.GetAccessControlId()); + deleteNums++; + offlineParam.bindType = DEVICE; + offlineParam.credIdVec.push_back(item.GetAccesser().GetAccesserCredentialId()); + LOGI("Src delete acl bindType %{public}d, localUdid %{public}s, remoteUdid %{public}s", item.GetBindType(), + GetAnonyString(localUdid).c_str(), GetAnonyString(remoteUdid).c_str()); + bindType = std::min(bindType, static_cast(item.GetBindType())); + continue; + } + if (item.GetAccessee().GetAccesseeDeviceId() == localUdid && + item.GetAccesser().GetAccesserDeviceId() == remoteUdid) { + DistributedDeviceProfileClient::GetInstance().DeleteAccessControlProfile(item.GetAccessControlId()); + deleteNums++; + offlineParam.bindType = DEVICE; + offlineParam.credIdVec.push_back(item.GetAccessee().GetAccesseeCredentialId()); + LOGI("Sink delete acl bindType %{public}d, localUdid %{public}s, remoteUdid %{public}s", item.GetBindType(), + GetAnonyString(localUdid).c_str(), GetAnonyString(remoteUdid).c_str()); + bindType = std::min(bindType, static_cast(item.GetBindType())); + continue; + } } + offlineParam.leftAclNumber = bindNums - deleteNums; return bindType; } -EXPORT OHOS::DistributedHardware::ProcessInfo DeviceProfileConnector::HandleAppUnBindEvent( - int32_t remoteUserId, const std::string &remoteUdid, int32_t tokenId, const std::string &localUdid) +EXPORT DmOfflineParam DeviceProfileConnector::HandleAppUnBindEvent(int32_t remoteUserId, + const std::string &remoteUdid, int32_t tokenId, const std::string &localUdid) { LOGI("RemoteUserId %{public}d, remoteUdid %{public}s, tokenId %{public}d, localUdid %{public}s.", remoteUserId, GetAnonyString(remoteUdid).c_str(), tokenId, GetAnonyString(localUdid).c_str()); - std::vector profiles = GetAccessControlProfile(); - ProcessInfo processInfo; + std::vector profiles = GetAclProfileByDeviceIdAndUserId(remoteUdid, remoteUserId); + DmOfflineParam offlineParam; + int32_t bindNums = 0; + int32_t deleteNums = 0; for (const auto &item : profiles) { if (item.GetTrustDeviceId() != remoteUdid || item.GetBindType() == DM_IDENTICAL_ACCOUNT || item.GetBindLevel() != APP) { continue; } + bindNums++; if (item.GetAccesser().GetAccesserUserId() == remoteUserId && item.GetAccesser().GetAccesserDeviceId() == remoteUdid && - static_cast(item.GetAccesser().GetAccesserTokenId()) == tokenId && + (static_cast(item.GetAccesser().GetAccesserTokenId()) == tokenId || + static_cast(item.GetAccesser().GetAccesserTokenId()) == 0) && item.GetAccessee().GetAccesseeDeviceId() == localUdid) { LOGI("Src device unbind."); DistributedDeviceProfileClient::GetInstance().DeleteAccessControlProfile(item.GetAccessControlId()); + deleteNums++; + offlineParam.bindType = APP; + ProcessInfo processInfo; processInfo.pkgName = item.GetAccessee().GetAccesseeBundleName(); processInfo.userId = item.GetAccessee().GetAccesseeUserId(); + offlineParam.processVec.push_back(processInfo); + offlineParam.credIdVec.push_back(item.GetAccessee().GetAccesseeCredentialId()); continue; } if (item.GetAccessee().GetAccesseeUserId() == remoteUserId && item.GetAccessee().GetAccesseeDeviceId() == remoteUdid && - static_cast(item.GetAccessee().GetAccesseeTokenId()) == tokenId && + (static_cast(item.GetAccessee().GetAccesseeTokenId()) == tokenId || + static_cast(item.GetAccessee().GetAccesseeTokenId()) == 0) && item.GetAccesser().GetAccesserDeviceId() == localUdid) { LOGI("Sink device unbind."); DistributedDeviceProfileClient::GetInstance().DeleteAccessControlProfile(item.GetAccessControlId()); + deleteNums++; + offlineParam.bindType = APP; + ProcessInfo processInfo; processInfo.pkgName = item.GetAccesser().GetAccesserBundleName(); processInfo.userId = item.GetAccesser().GetAccesserUserId(); + offlineParam.processVec.push_back(processInfo); + offlineParam.credIdVec.push_back(item.GetAccesser().GetAccesserCredentialId()); continue; } } - return processInfo; + offlineParam.leftAclNumber = bindNums - deleteNums; + return offlineParam; } -EXPORT OHOS::DistributedHardware::ProcessInfo DeviceProfileConnector::HandleAppUnBindEvent( - int32_t remoteUserId, const std::string &remoteUdid, int32_t tokenId, - const std::string &localUdid, int32_t peerTokenId) +EXPORT DmOfflineParam DeviceProfileConnector::HandleAppUnBindEvent(int32_t remoteUserId, + const std::string &remoteUdid, int32_t tokenId, const std::string &localUdid, int32_t peerTokenId) { LOGI("RemoteUserId %{public}d, remoteUdid %{public}s, tokenId %{public}d, localUdid %{public}s.", remoteUserId, GetAnonyString(remoteUdid).c_str(), tokenId, GetAnonyString(localUdid).c_str()); - std::vector profiles = GetAccessControlProfile(); - ProcessInfo processInfo; + std::vector profiles = GetAclProfileByDeviceIdAndUserId(remoteUdid, remoteUserId); + DmOfflineParam offlineParam; + int32_t bindNums = 0; + int32_t deleteNums = 0; for (const auto &item : profiles) { if (item.GetTrustDeviceId() != remoteUdid || item.GetBindType() == DM_IDENTICAL_ACCOUNT || item.GetBindLevel() != APP) { continue; } + bindNums++; if (item.GetAccesser().GetAccesserUserId() == remoteUserId && item.GetAccesser().GetAccesserDeviceId() == remoteUdid && - static_cast(item.GetAccesser().GetAccesserTokenId()) == tokenId && - static_cast(item.GetAccessee().GetAccesseeTokenId()) == peerTokenId && + (static_cast(item.GetAccesser().GetAccesserTokenId()) == tokenId || + static_cast(item.GetAccesser().GetAccesserTokenId()) == 0) && + (static_cast(item.GetAccessee().GetAccesseeTokenId()) == peerTokenId || + static_cast(item.GetAccessee().GetAccesseeTokenId()) == 0) && item.GetAccessee().GetAccesseeDeviceId() == localUdid) { LOGI("Src device unbind."); DistributedDeviceProfileClient::GetInstance().DeleteAccessControlProfile(item.GetAccessControlId()); + deleteNums++; + offlineParam.bindType = APP; + ProcessInfo processInfo; processInfo.pkgName = item.GetAccessee().GetAccesseeBundleName(); processInfo.userId = item.GetAccessee().GetAccesseeUserId(); + offlineParam.processVec.push_back(processInfo); + offlineParam.credIdVec.push_back(item.GetAccessee().GetAccesseeCredentialId()); continue; } if (item.GetAccessee().GetAccesseeUserId() == remoteUserId && item.GetAccessee().GetAccesseeDeviceId() == remoteUdid && - static_cast(item.GetAccessee().GetAccesseeTokenId()) == tokenId && - static_cast(item.GetAccesser().GetAccesserTokenId()) == peerTokenId && + (static_cast(item.GetAccessee().GetAccesseeTokenId()) == tokenId || + static_cast(item.GetAccessee().GetAccesseeTokenId()) == 0) && + (static_cast(item.GetAccesser().GetAccesserTokenId()) == peerTokenId || + static_cast(item.GetAccesser().GetAccesserTokenId()) == 0) && item.GetAccesser().GetAccesserDeviceId() == localUdid) { LOGI("Sink device unbind."); DistributedDeviceProfileClient::GetInstance().DeleteAccessControlProfile(item.GetAccessControlId()); + deleteNums++; + offlineParam.bindType = APP; + ProcessInfo processInfo; processInfo.pkgName = item.GetAccesser().GetAccesserBundleName(); processInfo.userId = item.GetAccesser().GetAccesserUserId(); + offlineParam.processVec.push_back(processInfo); + offlineParam.credIdVec.push_back(item.GetAccesser().GetAccesserCredentialId()); continue; } } - return processInfo; + offlineParam.leftAclNumber = bindNums - deleteNums; + return offlineParam; +} + +DmOfflineParam DeviceProfileConnector::HandleServiceUnBindEvent(int32_t remoteUserId, + const std::string &remoteUdid, const std::string &localUdid, int32_t tokenId) +{ + LOGI("RemoteUserId %{public}d, remoteUdid %{public}s, tokenId %{public}d, localUdid %{public}s.", + remoteUserId, GetAnonyString(remoteUdid).c_str(), tokenId, GetAnonyString(localUdid).c_str()); + std::vector profiles = GetAclProfileByDeviceIdAndUserId(remoteUdid, remoteUserId); + DmOfflineParam offlineParam; + int32_t bindNums = 0; + int32_t deleteNums = 0; + for (const auto &item : profiles) { + if (item.GetTrustDeviceId() != remoteUdid || item.GetBindType() == DM_IDENTICAL_ACCOUNT || + item.GetBindLevel() != SERVICE) { + continue; + } + bindNums++; + if (item.GetAccesser().GetAccesserUserId() == remoteUserId && + item.GetAccesser().GetAccesserDeviceId() == remoteUdid && + (static_cast(item.GetAccesser().GetAccesserTokenId()) == tokenId || + static_cast(item.GetAccesser().GetAccesserTokenId()) == 0) && + item.GetAccessee().GetAccesseeDeviceId() == localUdid) { + LOGI("Src device unbind."); + DistributedDeviceProfileClient::GetInstance().DeleteAccessControlProfile(item.GetAccessControlId()); + deleteNums++; + offlineParam.bindType = SERVICE; + ProcessInfo processInfo; + processInfo.pkgName = item.GetAccessee().GetAccesseeBundleName(); + processInfo.userId = item.GetAccessee().GetAccesseeUserId(); + offlineParam.processVec.push_back(processInfo); + offlineParam.credIdVec.push_back(item.GetAccessee().GetAccesseeCredentialId()); + continue; + } + if (item.GetAccessee().GetAccesseeUserId() == remoteUserId && + item.GetAccessee().GetAccesseeDeviceId() == remoteUdid && + (static_cast(item.GetAccessee().GetAccesseeTokenId()) == tokenId || + static_cast(item.GetAccessee().GetAccesseeTokenId()) == 0) && + item.GetAccesser().GetAccesserDeviceId() == localUdid) { + LOGI("Sink device unbind."); + DistributedDeviceProfileClient::GetInstance().DeleteAccessControlProfile(item.GetAccessControlId()); + deleteNums++; + offlineParam.bindType = SERVICE; + ProcessInfo processInfo; + processInfo.pkgName = item.GetAccesser().GetAccesserBundleName(); + processInfo.userId = item.GetAccesser().GetAccesserUserId(); + offlineParam.processVec.push_back(processInfo); + offlineParam.credIdVec.push_back(item.GetAccesser().GetAccesserCredentialId()); + continue; + } + } + offlineParam.leftAclNumber = bindNums - deleteNums; + return offlineParam; } EXPORT std::vector DeviceProfileConnector::GetAllAccessControlProfile() @@ -1844,6 +2149,17 @@ int32_t DeviceProfileConnector::PutSessionKey(const std::vector & return DM_OK; } +int32_t DeviceProfileConnector::DeleteSessionKey(int32_t sessionKeyId) +{ + uint32_t userId = static_cast(MultipleUserConnector::GetCurrentAccountUserID()); + int32_t ret = DistributedDeviceProfileClient::GetInstance().DeleteSessionKey(userId, sessionKeyId); + if (ret != DM_OK) { + LOGE("failed: %{public}d", ret); + return ret; + } + return DM_OK; +} + bool DeviceProfileConnector::CheckAclStatusNotMatch(const DistributedDeviceProfile::AccessControlProfile &profile, const std::string &localUdid, const std::vector &foregroundUserIds, const std::vector &backgroundUserIds) diff --git a/commondependency/src/multiple_user_connector.cpp b/commondependency/src/multiple_user_connector.cpp index 1bcaa8d8e..93eb150e4 100644 --- a/commondependency/src/multiple_user_connector.cpp +++ b/commondependency/src/multiple_user_connector.cpp @@ -122,6 +122,15 @@ void MultipleUserConnector::GetTokenIdAndForegroundUserId(uint32_t &tokenId, int userId = GetFirstForegroundUserId(); } +EXPORT void MultipleUserConnector::GetTokenId(uint32_t &tokenId) +{ +#if !(defined(__LITEOS_M__) || defined(LITE_DEVICE)) + tokenId = OHOS::IPCSkeleton::GetCallingTokenID(); +#else + (void)tokenId; +#endif +} + void MultipleUserConnector::GetCallerUserId(int32_t &userId) { #if (defined(__LITEOS_M__) || defined(LITE_DEVICE)) diff --git a/display/entry/src/main/ets/UIExtAbility/ConfirmUIExtAbility.ets b/display/entry/src/main/ets/UIExtAbility/ConfirmUIExtAbility.ets index 6b5055fe7..512d9660c 100644 --- a/display/entry/src/main/ets/UIExtAbility/ConfirmUIExtAbility.ets +++ b/display/entry/src/main/ets/UIExtAbility/ConfirmUIExtAbility.ets @@ -39,6 +39,9 @@ export default class ConfirmUIExtAbility extends UIExtensionAbility { if (want.parameters.hostPkgLabel) { AppStorage.setOrCreate('hostPkgLabel', want.parameters.hostPkgLabel); } + if (want.parameters.tokenId) { + AppStorage.setOrCreate('tokenId', want.parameters.tokenId); + } let param: Record = { 'session': session diff --git a/display/entry/src/main/ets/UIExtAbility/InputUIExtAbility.ets b/display/entry/src/main/ets/UIExtAbility/InputUIExtAbility.ets index 15a8081dc..07200108d 100644 --- a/display/entry/src/main/ets/UIExtAbility/InputUIExtAbility.ets +++ b/display/entry/src/main/ets/UIExtAbility/InputUIExtAbility.ets @@ -27,6 +27,9 @@ export default class InputUIExtAbility extends UIExtensionAbility { if (want.parameters && want.parameters.model) { AppStorage.setOrCreate('model', want.parameters.model); } + if (want.parameters && want.parameters.tokenId) { + AppStorage.setOrCreate('tokenId', want.parameters.tokenId); + } let param: Record = { 'session': session diff --git a/display/entry/src/main/ets/UIExtAbility/PincodeUIExtAbility.ets b/display/entry/src/main/ets/UIExtAbility/PincodeUIExtAbility.ets index ad4d9c6dd..c6fcd9d9e 100644 --- a/display/entry/src/main/ets/UIExtAbility/PincodeUIExtAbility.ets +++ b/display/entry/src/main/ets/UIExtAbility/PincodeUIExtAbility.ets @@ -24,6 +24,9 @@ export default class InputUIExtAbility extends UIExtensionAbility { if (want.parameters && want.parameters.pinCode) { AppStorage.setOrCreate('pinCode', want.parameters.pinCode); } + if (want.parameters && want.parameters.tokenId) { + AppStorage.setOrCreate('tokenId', want.parameters.tokenId); + } let param: Record = { 'session': session diff --git a/display/entry/src/main/ets/pages/ConfirmDialog.ets b/display/entry/src/main/ets/pages/ConfirmDialog.ets index d29860af2..55cc5c7ba 100644 --- a/display/entry/src/main/ets/pages/ConfirmDialog.ets +++ b/display/entry/src/main/ets/pages/ConfirmDialog.ets @@ -39,6 +39,7 @@ struct ConfirmCustomDialog { @State peerCustomDescription: string = ''; @State peerDeviceName: string = ''; @State peerDeviceType: number = 0; + @State tokenId: number = 0; @State secondsNum: number = 30; @State times: number = 0; @State isAvailableType: boolean = false; @@ -80,6 +81,11 @@ struct ConfirmCustomDialog { console.log('peerDeviceType is ' + this.peerDeviceType); } + if (AppStorage.get('tokenId') != null) { + this.tokenId = AppStorage.get('tokenId') as number; + console.log('tokenId is ' + this.tokenId); + } + this.times = setInterval(() => { console.info('devicemanagerui confirm dialog run seconds:' + this.secondsNum); this.secondsNum--; @@ -138,7 +144,8 @@ struct ConfirmCustomDialog { return; } try { - dmClass.setUserOperation(operation, 'extra'); + let paramJsonStr = `{"tokenId": ${this.tokenId}}`; + dmClass.setUserOperation(operation, paramJsonStr); } catch (error) { console.log(TAG + 'dmClass setUserOperation failed') } @@ -348,6 +355,7 @@ struct ConfirmCustomDialog { @Entry @Component struct dialogPlusPage { + @State tokenId: number = 0; dialogController: CustomDialogController = new CustomDialogController({ builder: ConfirmCustomDialog(), autoCancel: false, @@ -365,7 +373,11 @@ struct dialogPlusPage { console.log(TAG + 'deviceManager exist') return } - deviceManager.createDeviceManager('com.ohos.devicemanagerui.confirm', + if (AppStorage.get('tokenId') != null) { + this.tokenId = AppStorage.get('tokenId') as number; + console.log('tokenId is ' + this.tokenId); + } + deviceManager.createDeviceManager('com.ohos.devicemanagerui.confirm' + ' ' + this.tokenId, (err: Error, dm: deviceManager.DeviceManager) => { if (err) { console.log('createDeviceManager err:' + JSON.stringify(err) + ' --fail:' + JSON.stringify(dm)) @@ -398,7 +410,8 @@ struct dialogPlusPage { return; } try { - dmClass.setUserOperation(operation, 'extra'); + let paramJsonStr = `{"tokenId": ${this.tokenId}}`; + dmClass.setUserOperation(operation, paramJsonStr); } catch (error) { console.log(TAG + 'dmClass setUserOperation failed') } diff --git a/display/entry/src/main/ets/pages/ConfirmDialogWearable.ets b/display/entry/src/main/ets/pages/ConfirmDialogWearable.ets index 62435a1ba..152c65370 100644 --- a/display/entry/src/main/ets/pages/ConfirmDialogWearable.ets +++ b/display/entry/src/main/ets/pages/ConfirmDialogWearable.ets @@ -34,6 +34,7 @@ struct Index { @State peerCustomDescription: string = ''; @State peerDeviceName: string = ''; @State peerDeviceType: number = 0; + @State tokenId: number = 0; @State secondsNum: number = 30; @State times: number = 0; @State isAvailableType: boolean = false; @@ -45,7 +46,11 @@ struct Index { console.log(TAG + 'deviceManager exist'); return; } - deviceManager.createDeviceManager('com.ohos.devicemanagerui.confirm', + if (AppStorage.get('tokenId') != null) { + this.tokenId = AppStorage.get('tokenId') as number; + console.log('tokenId is ' + this.tokenId); + } + deviceManager.createDeviceManager('com.ohos.devicemanagerui.confirm' + ' ' + this.tokenId, (err: Error, dm: deviceManager.DeviceManager) => { if (err) { console.log('createDeviceManager err:' + JSON.stringify(err) + ' --fail:' + JSON.stringify(dm)); @@ -133,7 +138,8 @@ struct Index { } try { this.isUserOperate = true; - dmClass.setUserOperation(operation, 'extra'); + let paramJsonStr = `{"tokenId": ${this.tokenId}}`; + dmClass.setUserOperation(operation, paramJsonStr); } catch (error) { console.log(TAG + 'dmClass setUserOperation failed'); } diff --git a/display/entry/src/main/ets/pages/InputPinDialog.ets b/display/entry/src/main/ets/pages/InputPinDialog.ets index 1add1ade8..cec6e619e 100644 --- a/display/entry/src/main/ets/pages/InputPinDialog.ets +++ b/display/entry/src/main/ets/pages/InputPinDialog.ets @@ -41,6 +41,7 @@ struct InputCustomDialog { @State errorTipsVisible: Visibility = Visibility.None; @State heightNum: number = 600; @State targetDeviceName: string = ''; + @State tokenId: number = 0; @State model: string = MODEL_PIN; @State isPC: boolean = false; @State btnColor: ResourceColor = Color.Transparent; @@ -80,7 +81,11 @@ struct InputCustomDialog { this.model = AppStorage.get('model') as string; console.log('model is ' + this.model); } - deviceManager.createDeviceManager('com.ohos.devicemanagerui.input', + if (AppStorage.get('tokenId') != null) { + this.tokenId = AppStorage.get('tokenId') as number; + console.log('tokenId is ' + this.tokenId); + } + deviceManager.createDeviceManager('com.ohos.devicemanagerui.input' + ' ' + this.tokenId, (err: Error, dm: deviceManager.DeviceManager) => { if (err) { console.log('createDeviceManager err:' + JSON.stringify(err) + ' --fail:' + '${dm}'); @@ -179,7 +184,8 @@ struct InputCustomDialog { return; } try { - dmClass.setUserOperation(operation, extra); + let paramJsonStr = `{"pinCode": ${extra}, "tokenId": ${this.tokenId}}`; + dmClass.setUserOperation(operation, paramJsonStr); } catch (error) { console.log('dmClass setUserOperation failed'); } diff --git a/display/entry/src/main/ets/pages/InputPinDialogWearable.ets b/display/entry/src/main/ets/pages/InputPinDialogWearable.ets index 581575719..1f95a3cca 100644 --- a/display/entry/src/main/ets/pages/InputPinDialogWearable.ets +++ b/display/entry/src/main/ets/pages/InputPinDialogWearable.ets @@ -30,6 +30,7 @@ const MAX_PINCODE_LENGTH = 6; @Component struct Index { @State isTimes: number = 3; + @State tokenId: number = 0; @State passwordCircle: string[] = ['', '', '', '', '', '']; @State errorTips: Resource = $r('app.plural.dm_incorrect_code', this.isTimes, this.isTimes); @State @Watch('onChangeInput') input: string = ''; @@ -55,7 +56,11 @@ struct Index { console.log(TAG + 'deviceManager exist'); return; } - deviceManager.createDeviceManager('com.ohos.devicemanagerui.input', + if (AppStorage.get('tokenId') != null) { + this.tokenId = AppStorage.get('tokenId') as number; + console.log('tokenId is ' + this.tokenId); + } + deviceManager.createDeviceManager('com.ohos.devicemanagerui.input' + ' ' + this.tokenId, (err: Error, dm: deviceManager.DeviceManager) => { if (err) { console.log('createDeviceManager err:' + JSON.stringify(err) + ' --fail:' + '${dm}'); @@ -132,7 +137,8 @@ struct Index { } try { this.isUserOperate = true; - dmClass.setUserOperation(operation, extra); + let paramJsonStr = `{"pinCode": ${extra}, "tokenId": ${this.tokenId}}`; + dmClass.setUserOperation(operation, paramJsonStr); } catch (error) { console.log('dmClass setUserOperation failed'); } diff --git a/display/entry/src/main/ets/pages/PinDialog.ets b/display/entry/src/main/ets/pages/PinDialog.ets index df0408e3a..0f0a58faf 100644 --- a/display/entry/src/main/ets/pages/PinDialog.ets +++ b/display/entry/src/main/ets/pages/PinDialog.ets @@ -28,6 +28,7 @@ const MSG_CANCEL_PIN_CODE_SHOW: number = 2; @CustomDialog struct PinCustomDialog { @State pinCode: string = ''; + @State tokenId: number = 0; @State pinCodeArr: Array = []; @State btnColor: ResourceColor = Color.Transparent; @State isPC: boolean = false; @@ -53,6 +54,10 @@ struct PinCustomDialog { this.pinCode = AppStorage.get('pinCode') as string; this.pinCodeArr = this.pinCode.split(''); console.log(TAG + 'this.pinCodeArr' + this.pinCodeArr); + if (AppStorage.get('tokenId') != null) { + this.tokenId = AppStorage.get('tokenId') as number; + console.log('tokenId is ' + this.tokenId); + } } setUserOperation(operation: number) { @@ -62,7 +67,8 @@ struct PinCustomDialog { return; } try { - dmClass.setUserOperation(operation, 'extra'); + let paramJsonStr = `{"tokenId": ${this.tokenId}}`; + dmClass.setUserOperation(operation, paramJsonStr); } catch (error) { console.log(TAG + 'dmClass setUserOperation failed'); } @@ -176,6 +182,7 @@ struct PinCustomDialog { @Entry @Component struct dialogPlusPage { + @State tokenId: number = 0; dialogController: CustomDialogController = new CustomDialogController({ builder: PinCustomDialog(), cancel: this.onCancel, @@ -227,7 +234,11 @@ struct dialogPlusPage { console.log(TAG + 'deviceManager exist'); return; } - deviceManager.createDeviceManager('com.ohos.devicemanagerui.pin', + if (AppStorage.get('tokenId') != null) { + this.tokenId = AppStorage.get('tokenId') as number; + console.log('tokenId is ' + this.tokenId); + } + deviceManager.createDeviceManager('com.ohos.devicemanagerui.pin' + ' ' + this.tokenId, (err: Error, dm: deviceManager.DeviceManager) => { if (err) { console.log('createDeviceManager err:' + JSON.stringify(err) + ' --fail:' + JSON.stringify(dm)) @@ -252,7 +263,8 @@ struct dialogPlusPage { return; } try { - dmClass.setUserOperation(operation, 'extra'); + let paramJsonStr = `{"tokenId": ${this.tokenId}}`; + dmClass.setUserOperation(operation, paramJsonStr); } catch (error) { console.log(TAG + 'dmClass setUserOperation failed') } diff --git a/display/entry/src/main/ets/pages/PinDialogWearable.ets b/display/entry/src/main/ets/pages/PinDialogWearable.ets index 58bf8acfd..8e9fd0b49 100644 --- a/display/entry/src/main/ets/pages/PinDialogWearable.ets +++ b/display/entry/src/main/ets/pages/PinDialogWearable.ets @@ -25,6 +25,7 @@ const MSG_CANCEL_PIN_CODE_SHOW: number = 2; @Component struct PinDialog { @State pinCode: string = ''; + @State tokenId: number = 0; @State pinCodeArr: Array = []; @State btnColor: ResourceColor = Color.Transparent; @State isUserOperate: boolean = false; @@ -83,7 +84,11 @@ struct PinDialog { console.log(TAG + 'deviceManager exist'); return; } - deviceManager.createDeviceManager('com.ohos.devicemanagerui.pin', + if (AppStorage.get('tokenId') != null) { + this.tokenId = AppStorage.get('tokenId') as number; + console.log('tokenId is ' + this.tokenId); + } + deviceManager.createDeviceManager('com.ohos.devicemanagerui.pin' + ' ' + this.tokenId, (err: Error, dm: deviceManager.DeviceManager) => { if (err) { console.log('createDeviceManager err:' + JSON.stringify(err) + ' --fail:' + JSON.stringify(dm)); @@ -109,7 +114,8 @@ struct PinDialog { } try { this.isUserOperate = true; - dmClass.setUserOperation(operation, 'extra'); + let paramJsonStr = `{"tokenId": ${this.tokenId}}`; + dmClass.setUserOperation(operation, paramJsonStr); } catch (error) { console.log(TAG + 'dmClass setUserOperation failed'); } diff --git a/ext/pin_auth/BUILD.gn b/ext/pin_auth/BUILD.gn index 93ef54845..4d4dcacbb 100644 --- a/ext/pin_auth/BUILD.gn +++ b/ext/pin_auth/BUILD.gn @@ -95,6 +95,7 @@ ohos_shared_library("devicemanagerext_pin_auth") { "resource_management:resmgr_napi_core", "safwk:system_ability_fwk", "samgr:samgr_proxy", + "cJSON:cjson" ] defines = [ diff --git a/services/implementation/BUILD.gn b/services/implementation/BUILD.gn index 652b2e073..6d426e430 100644 --- a/services/implementation/BUILD.gn +++ b/services/implementation/BUILD.gn @@ -44,6 +44,8 @@ if (defined(ohos_lite)) { "${utils_path}/include/fwkload/lite", "${utils_path}/include/timer/lite", "//third_party/json/include", + "//third_party/zlib/zlib.h", + "//third_party/cJSON/cJson.h", "${services_path}/include", "${services_path}/include/ipc/lite", "${interfaces_path}/c/ipc/include", @@ -89,6 +91,8 @@ if (defined(ohos_lite)) { "//foundation/systemabilitymgr/safwk_lite:safwk_lite", "//foundation/systemabilitymgr/samgr_lite/samgr:samgr", "//third_party/bounds_checking_function:libsec_shared", + "//third_party/zlib", + "//third_party/cJSON" ] cflags = [ @@ -114,6 +118,7 @@ if (defined(ohos_lite)) { "include/config", "include/adapter", "include/authentication", + "include/authentication_v2", "include/authentication/showconfirm/standard", "include/ability", "include/credential", @@ -180,6 +185,17 @@ if (defined(ohos_lite)) { "src/authentication/auth_ui_state_manager.cpp", "src/authentication/dm_auth_manager.cpp", "src/authentication/showconfirm/standard/show_confirm.cpp", + "src/authentication_v2/auth_stages/auth_acl.cpp", + "src/authentication_v2/auth_stages/auth_confirm.cpp", + "src/authentication_v2/auth_stages/auth_credential.cpp", + "src/authentication_v2/auth_stages/auth_negotiate.cpp", + "src/authentication_v2/auth_stages/auth_pin_auth.cpp", + "src/authentication_v2/auth_manager.cpp", + "src/authentication_v2/dm_auth_message_processor.cpp", + "src/authentication_v2/dm_auth_state_machine.cpp", + "src/authentication_v2/dm_auth_state.cpp", + "src/authentication_v2/dm_auth_context.cpp", + "src/authentication_v2/dm_auth_manager_base.cpp", "src/config/dm_config_manager.cpp", "src/credential/dm_credential_manager.cpp", "src/cryptomgr/crypto_mgr.cpp", @@ -233,8 +249,10 @@ if (defined(ohos_lite)) { "mbedtls:mbedtls_shared", "openssl:libcrypto_shared", "os_account:libaccountkits", + "os_account:os_account_innerkits", "resource_management:resmgr_napi_core", "samgr:samgr_proxy", + "zlib:shared_libz", ] if (support_screenlock && device_manager_feature_product == "default") { diff --git a/services/implementation/include/ability/dm_dialog_manager.h b/services/implementation/include/ability/dm_dialog_manager.h index 1a42ff984..1ac717de7 100644 --- a/services/implementation/include/ability/dm_dialog_manager.h +++ b/services/implementation/include/ability/dm_dialog_manager.h @@ -77,6 +77,10 @@ public: { return hostPkgLabel_; } + static uint64_t GetTokenId() + { + return tokenId_; + } private: DmDialogManager(); ~DmDialogManager(); @@ -98,6 +102,7 @@ private: static std::string customDescriptionStr_; static std::string pinCode_; static std::string hostPkgLabel_; + static uint64_t tokenId_; static int32_t deviceType_; static std::atomic isConnectSystemUI_; static sptr dialogConnectionCallback_; diff --git a/services/implementation/include/authentication/auth_message_processor.h b/services/implementation/include/authentication/auth_message_processor.h index dde7dbf83..2c34222d5 100644 --- a/services/implementation/include/authentication/auth_message_processor.h +++ b/services/implementation/include/authentication/auth_message_processor.h @@ -27,7 +27,6 @@ namespace OHOS { namespace DistributedHardware { -extern const char* TAG_REPLY; extern const char* TAG_NET_ID; extern const char* TAG_TARGET; extern const char* TAG_APP_OPERATION; @@ -48,35 +47,25 @@ extern const char* TAG_CRYPTO_NAME; extern const char* TAG_CRYPTO_VERSION; extern const char* TAG_IDENTICAL_ACCOUNT; extern const char* TAG_ACCOUNT_GROUPID; -extern const char* APP_THUMBNAIL; extern const char* QR_CODE_KEY; extern const char* TAG_AUTH_TOKEN; extern const char* NFC_CODE_KEY; extern const char* OLD_VERSION_ACCOUNT; -extern const char* TAG_AUTH_FINISH; extern const char* TAG_HAVE_CREDENTIAL; extern const char* TAG_PUBLICKEY; extern const char* TAG_SESSIONKEY; -extern const char* TAG_BIND_LEVEL; -extern const char* TAG_LOCAL_USERID; extern const char* TAG_BIND_TYPE_SIZE; extern const char* TAG_ISONLINE; extern const char* TAG_AUTHED; extern const char* TAG_LOCAL_ACCOUNTID; -extern const char* TAG_DMVERSION; extern const char* TAG_HOST_PKGNAME; extern const char* TAG_TOKENID; extern const char* TAG_HAVECREDENTIAL; extern const char* TAG_CONFIRM_OPERATION; -extern const char* TAG_DATA; -extern const char* TAG_DATA_LEN; extern const char* TAG_IMPORT_AUTH_CODE; extern const char* TAG_HOST_PKGLABEL; -extern const char* TAG_EDITION; -extern const char* TAG_BUNDLE_NAME; extern const char* TAG_CRYPTIC_MSG; -extern const char* TAG_PEER_BUNDLE_NAME; extern const char* TAG_REMOTE_DEVICE_NAME; extern const char* TAG_SESSIONKEY_ID; diff --git a/services/implementation/include/authentication/dm_auth_manager.h b/services/implementation/include/authentication/dm_auth_manager.h index 3dee55dac..a25620753 100644 --- a/services/implementation/include/authentication/dm_auth_manager.h +++ b/services/implementation/include/authentication/dm_auth_manager.h @@ -28,6 +28,7 @@ #include "deviceprofile_connector.h" #include "dm_ability_manager.h" #include "dm_adapter_manager.h" +#include "dm_auth_manager_base.h" #include "dm_constants.h" #include "dm_device_info.h" #include "dm_timer.h" @@ -203,10 +204,7 @@ typedef struct DmAuthResponseContext { class AuthMessageProcessor; -class DmAuthManager final : public ISoftbusSessionCallback, - public ISoftbusConnectorCallback, - public IHiChainConnectorCallback, - public IDmDeviceAuthCallback, +class DmAuthManager final : public AuthManagerBase, public std::enable_shared_from_this { public: DmAuthManager(std::shared_ptr softbusConnector, @@ -483,7 +481,7 @@ public: * @tc.type: FUNC */ int32_t BindTarget(const std::string &pkgName, const PeerTargetId &targetId, - const std::map &bindParam); + const std::map &bindParam, int sessionId, int64_t logicalSessionId); void HandleSessionHeartbeat(std::string name); @@ -492,6 +490,7 @@ public: static bool IsPinCodeValid(int32_t numpin); bool IsImportedAuthCodeValid(); bool IsSrc(); + bool IsAuthManagerConstructSuccess(); private: bool IsHmlSessionType(); @@ -546,6 +545,7 @@ public: void AuthDeviceError(int64_t requestId, int32_t errorCode); void GetRemoteDeviceId(std::string &deviceId); void AuthDeviceSessionKey(int64_t requestId, const uint8_t *sessionKey, uint32_t sessionKeyLen); + char *AuthDeviceRequest(int64_t requestId, int operationCode, const char *reqParams); int32_t GetSessionKeyIdSync(int64_t requestId); void OnAuthDeviceDataReceived(const int32_t sessionId, const std::string message); void OnScreenLocked(); @@ -578,8 +578,6 @@ private: void SrcAuthenticateFinish(); std::string GetBundleLable(const std::string &bundleName); bool IsScreenLocked(); - std::string ConvertSrcVersion(const std::string &version, const std::string &edition); - std::string ConvertSinkVersion(const std::string &version); void NegotiateRespMsg(const std::string &version); void SetAuthType(int32_t authType); int32_t GetTaskTimeout(const char* taskName, int32_t taskTimeOut); diff --git a/services/implementation/include/authentication_v2/auth_manager.h b/services/implementation/include/authentication_v2/auth_manager.h new file mode 100644 index 000000000..93308dd04 --- /dev/null +++ b/services/implementation/include/authentication_v2/auth_manager.h @@ -0,0 +1,209 @@ +/* + * Copyright (c) 2025 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 OHOS_DM_AUTH_MANAGER_V2_H +#define OHOS_DM_AUTH_MANAGER_V2_H + +#include +#include "json_object.h" +#include "hichain_auth_connector.h" +#include "hichain_connector.h" +#include "softbus_connector.h" +#include "softbus_session.h" +#include "auth_ui_state_manager.h" +#include "dm_auth_manager_base.h" + +namespace OHOS { +namespace DistributedHardware { +struct DmAuthContext; + +class AuthManager : public AuthManagerBase, + public std::enable_shared_from_this { +public: + AuthManager(std::shared_ptr softbusConnector, + std::shared_ptr listener, + std::shared_ptr hiChainAuthConnector); + virtual ~AuthManager(); + + // External API begin + /** + * @tc.name: DmAuthManager::OnUserOperation + * @tc.desc: User Operation of the DeviceManager Authenticate Manager + * @tc.type: FUNC + */ + virtual int32_t OnUserOperation(int32_t action, const std::string ¶ms) = 0; + + /** + * @tc.name: AuthManager::GeneratePincode + * @tc.desc: Generate Pincode of the DeviceManager Authenticate Manager + * @tc.type: FUNC + */ + int32_t BindTarget(const std::string &sessionName, const PeerTargetId &targetId, + const std::map &bindParam, int sessionId, int64_t logicalSessionId); + + /** + * @tc.name: AuthManager::OnUserOperation + * @tc.desc: User Operation of the DeviceManager Authenticate Manager + * @tc.type: FUNC + */ + int32_t GeneratePincode(); + + /** + * @tc.name: AuthManager::ImportAuthCode + * @tc.desc: Import auth code + * @tc.type: FUNC + */ + int32_t ImportAuthCode(const std::string &sessionName, const std::string &authCode); + + /** + * @tc.name: AuthManager::RegisterUiStateCallback + * @tc.desc: Register ui state callback + * @tc.type: FUNC + */ + int32_t RegisterUiStateCallback(const std::string sessionName); + + /** + * @tc.name: AuthManager::UnRegisterUiStateCallback + * @tc.desc: Unregister ui state callback + * @tc.type: FUNC + */ + int32_t UnRegisterUiStateCallback(const std::string sessionName); + + /** + * @tc.name: AuthManager::UnAuthenticateDevice + * @tc.desc: UnAuthenticate Device of the DeviceManager Authenticate Manager + * @tc.type: FUNC + */ + int32_t UnAuthenticateDevice(const std::string &sessionName, const std::string &udid, int32_t bindLevel); + + /** + * @brief UnBind device. + * @param sessionName package name. + * @param deviceId device id. + * @return Return 0 if success. + */ + int32_t UnBindDevice(const std::string &sessionName, const std::string &udid, + int32_t bindLevel, const std::string &extra); + + void HandleDeviceNotTrust(const std::string &udid); + + int32_t RegisterAuthenticationType(int32_t authenticationType); + void OnScreenLocked(); + int32_t StopAuthenticateDevice(const std::string &sessionName); + // External API begin end + + // Internal API begin + void SetAuthContext(std::shared_ptr context); + std::shared_ptr GetAuthContext(); + static bool IsHmlSessionType(std::string sessionType); + int32_t GetTokenIdByBundleName(int32_t userId, std::string &bundleName, int64_t &tokenId); + void GetBindTargetParams(std::string &pkgName, PeerTargetId &targetId, + std::map &bindParam); + int32_t GetReason(); + + // Extract the local ACL for message parsing and bus usage. + int32_t GetAclListStr(std::string &aclList); + + bool IsAuthManagerConstructSuccess(); + // Internal API end + + void RegisterCleanNotifyCallback(CleanNotifyCallback cleanNotifyCallback); + +protected: + std::shared_ptr context_; + std::map bindParam_; + + int32_t GetPinCode(int32_t &code); + void GetRemoteDeviceId(std::string &deviceId); +private: + bool CheckProcessNameInWhiteList(const std::string &processName); + int32_t ParseAuthType(const std::map &bindParam, int32_t &authType); + void ParseHmlInfoInJsonObject(const JsonObject &jsonObject); + void ParseJsonObject(const JsonObject &jsonObject); + void GetAuthIds(std::string realPkgName, const std::string &sessionName, const JsonObject &jsonObject); + void GetAuthParam(const std::string &sessionName, int32_t authType, + const std::string &deviceId, const std::string &extra); + std::string GetBundleName(const JsonObject &jsonObject); + void SetAuthType(int32_t authType); + bool IsAuthTypeSupported(const int32_t &authType); + bool IsAuthCodeReady(const std::string &sessionName); + int32_t CheckAuthParamVaild(const std::string &sessionName, int32_t authType, + const std::string &deviceId, const std::string &extra); + void InitAuthState(const std::string &sessionName, int32_t authType, + const std::string &deviceId, const std::string &extra); + int32_t AuthenticateDevice(const std::string &sessionName, int32_t authType, + const std::string &deviceId, const std::string &extra); +}; + +class AuthSrcManager : public AuthManager { +public: + AuthSrcManager(std::shared_ptr softbusConnector, + std::shared_ptr listener, + std::shared_ptr hiChainAuthConnector); + virtual ~AuthSrcManager() override = default; + + // External API begin + int32_t OnUserOperation(int32_t action, const std::string ¶ms) override; + // External API end + + // IDmDeviceAuthCallback implement begin + bool AuthDeviceTransmit(int64_t requestId, const uint8_t *data, uint32_t dataLen) override; + void AuthDeviceError(int64_t requestId, int32_t errorCode) override; + void AuthDeviceFinish(int64_t requestId) override; + void AuthDeviceSessionKey(int64_t requestId, const uint8_t *sessionKey, uint32_t sessionKeyLen) override; + char *AuthDeviceRequest(int64_t requestId, int operationCode, const char *reqParams) override; + // IDmDeviceAuthCallback implement end + + // ISoftbusSessionCallback implement begin + void OnSessionOpened(int32_t sessionId, int32_t sessionSide, int32_t result) override; + void OnSessionClosed(int32_t sessionId) override; + void OnDataReceived(int32_t sessionId, std::string message) override; + + bool GetIsCryptoSupport() override; + void OnAuthDeviceDataReceived(int32_t sessionId, std::string message) override; + // ISoftbusSessionCallback implement end +}; + +class AuthSinkManager : public AuthManager { +public: + AuthSinkManager(std::shared_ptr softbusConnector, + std::shared_ptr listener, + std::shared_ptr hiChainAuthConnector); + virtual ~AuthSinkManager() override = default; + + // External API begin + int32_t OnUserOperation(int32_t action, const std::string ¶ms) override; + // External API end + + // IDmDeviceAuthCallback implement begin + bool AuthDeviceTransmit(int64_t requestId, const uint8_t *data, uint32_t dataLen) override; + void AuthDeviceError(int64_t requestId, int32_t errorCode) override; + void AuthDeviceFinish(int64_t requestId) override; + void AuthDeviceSessionKey(int64_t requestId, const uint8_t *sessionKey, uint32_t sessionKeyLen) override; + char *AuthDeviceRequest(int64_t requestId, int operationCode, const char *reqParams) override; + // IDmDeviceAuthCallback implement end + + // ISoftbusSessionCallback implement begin + void OnSessionOpened(int32_t sessionId, int32_t sessionSide, int32_t result) override; + void OnSessionClosed(int32_t sessionId) override; + void OnDataReceived(int32_t sessionId, std::string message) override; + bool GetIsCryptoSupport() override; + void OnAuthDeviceDataReceived(int32_t sessionId, std::string message) override; + // ISoftbusSessionCallback implement end +}; + +} // namespace DistributedHardware +} // namespace OHOS +#endif // OHOS_DM_AUTH_MANAGER_V2_H \ No newline at end of file diff --git a/services/implementation/include/authentication_v2/dm_auth_context.h b/services/implementation/include/authentication_v2/dm_auth_context.h new file mode 100644 index 000000000..43c0265dd --- /dev/null +++ b/services/implementation/include/authentication_v2/dm_auth_context.h @@ -0,0 +1,233 @@ +/* + * Copyright (c) 2025 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 OHOS_DM_AUTH_CONTEXT_V2_H +#define OHOS_DM_AUTH_CONTEXT_V2_H +#include +#include + +#include "auth_ui_state_manager.h" +#include "hichain_auth_connector.h" +#include "hichain_connector.h" +#include "softbus_connector.h" +#include "softbus_session.h" +#include "authentication.h" +#include "access_control_profile.h" + +#include "dm_timer.h" +#include "dm_auth_message_processor.h" +#include "dm_device_info.h" +#include "dm_ability_manager.h" +#include "dm_log.h" +#include "dm_anonymous.h" +#include "dm_constants.h" + +namespace OHOS { +namespace DistributedHardware { + +class DmAuthStateMachine; +class DmAuthMessageProcessor; + +using CleanNotifyCallback = std::function; + +// PIN Code Authentication Type +enum DmAuthType : int32_t { + AUTH_TYPE_CRE = 0, // Not used in the new protocol + AUTH_TYPE_PIN, // Input PIN code + AUTH_TYPE_QR_CODE, // Not used in the new protocol + AUTH_TYPE_NFC, // Not used in the new protocol + AUTH_TYPE_NO_INTER_ACTION, // Not used in the new protocol + AUTH_TYPE_IMPORT_AUTH_CODE, // Import PIN code + AUTH_TYPE_UNKNOW, // Not used in the new protocol + AUTH_TYPE_PIN_ULTRASONIC, // Ultrasonic PIN code +}; + +enum DmAuthDirection { + DM_AUTH_SOURCE = 0, + DM_AUTH_SINK, +}; + +enum DmBindType { + DM_AUTH_USERID = 1, + DM_AUTH_SYSTEM_SERVICE, + DM_AUTH_APP_SERVICE, + DM_AUTH_DEVICEID, +}; + +enum DmAuthSide { + DM_AUTH_LOCAL_SIDE = 0, + DM_AUTH_REMOTE_SIDE, +}; + +enum DmAuthScope { + DM_AUTH_SCOPE_DEVICE = 1, + DM_AUTH_SCOPE_USER, + DM_AUTH_SCOPE_APP, +}; + +enum DmRole { + DM_ROLE_UNKNOWN = 0, + DM_ROLE_DEVICE = 1, + DM_ROLE_USER = 1, + DM_ROLE_SA, + DM_ROLE_FA, +}; + +// Used for one-touch pairing +struct DmPeerTargetAddress { + // directly establish a Bluetooth connection + std::string peerBrMacAddress; + std::string peerBleMacAddress; + std::string peerWifiMacAddress; + std::string peerActionMacAddress; + + std::string peerWifiChannel; + std::string peerWifiIp; + uint16_t peerWifiPort; +}; + +struct DmPeerTarget { + DmBindType peerType; + std::string peerDeviceId; + int64_t peerServiceId; + uint64_t peerSaTokenId; + std::string peerBundleName; + DmPeerTargetAddress peerTargetAddress; +}; + +struct DmAccess { + std::string deviceName; + int32_t deviceType; // Device types such as PC, mobile, watch, large screen, etc. + std::string deviceId; + std::string deviceIdHash; + std::string addr; + int32_t userId; + std::string userIdHash; + int32_t displayId{0}; // Logical screen ID, used for query userId + std::string accountId; + std::string accountIdHash; + uint64_t tokenId; + std::string tokenIdHash; + std::string token; + std::string networkId; + std::string bundleName; // Stores the PacketName + std::string language; + int64_t serviceId; // Reserved field, to be used in HM 6.0 + std::string accesserHapSignature; + int32_t bindLevel; + std::string lnnCredentialId; // User-level credential ID + std::string transmitCredentialId; // Application-level credential ID + std::string lnnPublicKey; // User-level public key + std::string ephemeralPublicKey; // Application-level public key + std::vector bindType; // such as DM_AUTH_CREDENTIAL_ACCOUNT_RELATED + std::string publicKey; + int32_t status; // Indicates whether the service is in the foreground or background + int32_t sessionKeyId; // Used as key delivery material, retrieves the SK from the bus + int32_t transmitSessionKeyId; // Permanent application SKID on this end, returned by DP for ACL updates and aging + int32_t lnnSessionKeyId; // Permanent user SKID on this end, returned by DP for ACL updates and aging + int64_t transmitSkTimeStamp; // Used for aging, time is 2 days, application-level credential timestamp + int64_t lnnSkTimeStamp; // Used for aging, time is 2 days, user-level credential timestamp + int64_t skTimeStamp; // Used for aging, time is 2 days + bool isAuthed; + bool isOnline; + std::string dmVersion; + std::string edition; // Used for compatibility before version 5.1.0, assists in version negotiation + std::string aclList; // Trust relationship list, used for data aging, KV format + std::vector accesserStrList; + std::vector accesseeStrList; + std::map credentialInfos; // map: , cred is string tranformed by json + std::vector credentialTypeLists; // point-to-point, same account, etc. + // map: + std::map aclProfiles; + std::string extraInfo; // Expandable field, JSON format, KV structure + std::string openAuthDeviceId; +}; + +struct DmAuthContext { + bool isOnline; + int64_t logicalSessionId; + DmMessageType msgType; + int32_t sessionId; + int64_t requestId; // HiChain authentication ID + int32_t authBoxType{1}; // Authentication box type + UiAction pinInputResult; + // Authorization result (using 0, 1, 6, representing single use, cancel, and always trust, enum UiAction) + UiAction authResult{UiAction::USER_OPERATION_TYPE_ALLOW_AUTH}; + DmAuthType authType{DmAuthType::AUTH_TYPE_PIN}; // PIN code, ultrasonic PIN code, imported PIN code + std::vector authTypeList; + uint32_t currentAuthTypeIdx{0}; + int32_t inputPinAuthFailTimes{0}; // Number of failed PIN authentication attempts, exceeding 3 results in failure + int32_t pinCode{INVALID_PINCODE}; + bool serviceInfoFound{false}; + // Link delay release time, does not automatically disconnect after + // authorization (used for specific business needs), reserved field + int32_t connDelayCloseTime; + int32_t reason{DM_OK}; + int32_t reply; + int32_t state; + int32_t hmlActionId = 0; + bool normalFinishAuth; + bool authenticating; // Indicator whether authentication is in progress + bool isFinished{false}; + bool isAppCredentialVerified{false}; // Whether the application credential has been verified + bool hmlEnable160M{false}; + std::string sessionName; // Business-provided identifier, custom-defined by business, carries risk of spoofing + std::string pkgLabel; + std::string importCodeBundleName; // Bundle name for imported PIN code + std::string appThumbnail; // Application thumbnail + // Description of the operation this binding is used for, displayed in authorization dialog + std::string appOperation; + // Custom business field, provides detailed information to the user about this binding operation + std::string customData; + std::string connSessionType; + std::string extraInfo; // Expandable field, key-value structure + DmAuthDirection direction; // Indicator of authentication direction + ProcessInfo processInfo; + DmPeerTarget peerTarget; + DmAccess accesser; + DmAccess accessee; + std::multimap proxy; // Multimap where the key is the accessor and the value is the accesssee + + std::shared_ptr authStateMachine; + std::shared_ptr authUiStateMgr; + std::shared_ptr hiChainAuthConnector; + std::shared_ptr authMessageProcessor; + std::shared_ptr softbusConnector; + std::shared_ptr listener; + std::shared_ptr authPtr; // Pointer to authentication interface + std::shared_ptr timer; + std::string transmitData; // Data returned from onTrasmit function + std::string importSessionName = ""; + std::string importAuthCode = ""; + std::map> authenticationMap; + PeerTargetId peerTargetId; + bool pinNegotiateStarted{false}; + bool isAuthenticateDevice{false}; // Whether device authentication is in progress + bool needAgreeCredential{true}; + + CleanNotifyCallback cleanNotifyCallback; + + std::string GetDeviceId(DmAuthSide side); + int32_t GetUserId(DmAuthSide side); + std::string GetCredentialId(DmAuthSide side, DmAuthScope authorizedScope); + std::string GetPublicKey(DmAuthSide side, DmAuthScope authorizedScope); + void SetCredentialId(DmAuthSide side, DmAuthScope authorizedScope, const std::string &credentialId); + void SetPublicKey(DmAuthSide side, DmAuthScope authorizedScope, const std::string &publicKey); + std::string GetAccountId(DmAuthSide side); +}; + +} // namespace DistributedHardware +} // namespace OHOS +#endif // OHOS_DM_AUTH_CONTEXT_V2_H diff --git a/services/implementation/include/authentication_v2/dm_auth_manager_base.h b/services/implementation/include/authentication_v2/dm_auth_manager_base.h new file mode 100644 index 000000000..98ee6a839 --- /dev/null +++ b/services/implementation/include/authentication_v2/dm_auth_manager_base.h @@ -0,0 +1,216 @@ +/* + * Copyright (c) 2025 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 OHOS_DM_AUTH_ADAPTER_V2_H +#define OHOS_DM_AUTH_ADAPTER_V2_H + +#include +#include +#include +#include + +#include "softbus_session_callback.h" +#include "hichain_connector_callback.h" +#include "hichain_connector_callback.h" +#include "auth_request_state.h" +#include "auth_response_state.h" +#include "dm_device_info.h" + +namespace OHOS { +namespace DistributedHardware { + +extern const char* DM_VERSION_4_1_5_1; +extern const char* DM_VERSION_5_0_1; +extern const char* DM_VERSION_5_0_2; +extern const char* DM_VERSION_5_0_3; +extern const char* DM_VERSION_5_0_4; +extern const char* DM_VERSION_5_0_5; +extern const char* DM_VERSION_5_1_0; +extern const char* DM_VERSION_5_0_OLD_MAX; // 预估的旧版本最高版本号 + +extern const char* TAG_DMVERSION; +extern const char* TAG_EDITION; +extern const char* TAG_DATA; +extern const char* TAG_DATA_LEN; +extern const char* TAG_BUNDLE_NAME; +extern const char* TAG_PEER_BUNDLE_NAME; +extern const char* TAG_BIND_LEVEL; +extern const char* TAG_REPLY; +extern const char* TAG_APP_THUMBNAIL2; // Naming Add 2 to resolve conflicts with TAG_APP_THUMBNAIL +extern const char* TAG_AUTH_FINISH; +extern const char* TAG_LOCAL_USERID; + +extern const char* APP_OPERATION_KEY; +extern const char* TARGET_PKG_NAME_KEY; +extern const char* CUSTOM_DESCRIPTION_KEY; +extern const char* CANCEL_DISPLAY_KEY; +extern const char* BUNDLE_NAME_KEY; + +extern const char* AUTHENTICATE_TIMEOUT_TASK; +extern const char* NEGOTIATE_TIMEOUT_TASK; +extern const char* CONFIRM_TIMEOUT_TASK; +extern const char* INPUT_TIMEOUT_TASK; +extern const char* SESSION_HEARTBEAT_TIMEOUT_TASK; +extern const char* WAIT_REQUEST_TIMEOUT_TASK; +extern const char* AUTH_DEVICE_TIMEOUT_TASK; +extern const char* WAIT_PIN_AUTH_TIMEOUT_TASK; +extern const char* WAIT_NEGOTIATE_TIMEOUT_TASK; +extern const char* ADD_TIMEOUT_TASK; +extern const char* WAIT_SESSION_CLOSE_TIMEOUT_TASK; +extern const char* CLOSE_SESSION_TASK_SEPARATOR; + +extern const int32_t AUTHENTICATE_TIMEOUT; +extern const int32_t CONFIRM_TIMEOUT; +extern const int32_t NEGOTIATE_TIMEOUT; +extern const int32_t INPUT_TIMEOUT; +extern const int32_t ADD_TIMEOUT; +extern const int32_t WAIT_NEGOTIATE_TIMEOUT; +extern const int32_t WAIT_REQUEST_TIMEOUT; +extern const int32_t CLONE_AUTHENTICATE_TIMEOUT; +extern const int32_t CLONE_CONFIRM_TIMEOUT; +extern const int32_t CLONE_NEGOTIATE_TIMEOUT; +extern const int32_t CLONE_ADD_TIMEOUT; +extern const int32_t CLONE_WAIT_NEGOTIATE_TIMEOUT; +extern const int32_t CLONE_WAIT_REQUEST_TIMEOUT; +extern const int32_t CLONE_SESSION_HEARTBEAT_TIMEOUT; +extern const int32_t CLONE_PIN_AUTH_TIMEOUT; +extern const int32_t HML_SESSION_TIMEOUT; +extern const int32_t SESSION_HEARTBEAT_TIMEOUT; +extern const int32_t PIN_AUTH_TIMEOUT; +extern const int32_t EVENT_TIMEOUT; + +extern const int32_t DM_AUTH_TYPE_MAX; +extern const int32_t DM_AUTH_TYPE_MIN; +extern const int32_t MIN_PIN_TOKEN; +extern const int32_t MAX_PIN_TOKEN; + +using CleanNotifyCallback = std::function; + +class AuthManagerBase : public ISoftbusSessionCallback, + public IHiChainConnectorCallback, + public IDmDeviceAuthCallback { +public: + virtual int32_t AuthenticateDevice(const std::string &pkgName, int32_t authType, const std::string &deviceId, + const std::string &extra); + + virtual int32_t UnAuthenticateDevice(const std::string &pkgName, const std::string &udid, int32_t bindLevel); + + virtual int32_t UnBindDevice(const std::string &pkgName, const std::string &udid, + int32_t bindLevel, const std::string &extra); + + virtual void OnSessionOpened(int32_t sessionId, int32_t sessionSide, int32_t result); + + virtual void OnSessionClosed(const int32_t sessionId); + + virtual void OnDataReceived(const int32_t sessionId, const std::string message); + + virtual void OnGroupCreated(int64_t requestId, const std::string &groupId); + + virtual void OnMemberJoin(int64_t requestId, int32_t status); + + virtual int32_t EstablishAuthChannel(const std::string &deviceId); + + virtual void StartNegotiate(const int32_t &sessionId); + + virtual void RespNegotiate(const int32_t &sessionId); + + virtual void SendAuthRequest(const int32_t &sessionId); + + virtual int32_t StartAuthProcess(const int32_t &action); + + virtual void StartRespAuthProcess(); + + virtual int32_t CreateGroup(); + + virtual int32_t ProcessPincode(int32_t pinCode); + + virtual std::string GetConnectAddr(std::string deviceId); + + virtual int32_t JoinNetwork(); + + virtual void AuthenticateFinish(); + + virtual bool GetIsCryptoSupport(); + + virtual int32_t SetAuthRequestState(std::shared_ptr authRequestState); + + virtual int32_t SetAuthResponseState(std::shared_ptr authResponseState); + + virtual int32_t GetPinCode(int32_t &code); + + virtual std::string GenerateGroupName(); + + virtual void HandleAuthenticateTimeout(std::string name); + + virtual int32_t GeneratePincode(); + + virtual void ShowConfigDialog(); + + virtual void ShowAuthInfoDialog(bool authDeviceError = false); + + virtual void ShowStartAuthDialog(); + + virtual int32_t OnUserOperation(int32_t action, const std::string ¶ms); + + virtual int32_t SetPageId(int32_t pageId); + + virtual int32_t SetReasonAndFinish(int32_t reason, int32_t state); + + virtual bool IsIdenticalAccount(); + + virtual int32_t RegisterUiStateCallback(const std::string pkgName); + + virtual int32_t UnRegisterUiStateCallback(const std::string pkgName); + + virtual int32_t ImportAuthCode(const std::string &pkgName, const std::string &authCode); + + virtual int32_t BindTarget(const std::string &pkgName, const PeerTargetId &targetId, + const std::map &bindParam, int sessionId, int64_t logicalSessionId); + + virtual int32_t RegisterAuthenticationType(int32_t authenticationType); + + virtual int32_t StopAuthenticateDevice(const std::string &pkgName); + + virtual void OnScreenLocked() = 0; + + virtual void HandleDeviceNotTrust(const std::string &udid) = 0; + + virtual int32_t DeleteGroup(const std::string &pkgName, const std::string &deviceId); + + // New interface added in version 5.1.0 + virtual int32_t GetReason(); + // When switching from the new protocol to the old protocol, the previous parameters + // need to be obtained for use by the old protocol + virtual void GetBindTargetParams(std::string &pkgName, PeerTargetId &targetId, + std::map &bindParam); + + // Check if the authManager has been initialized successfully + virtual bool IsAuthManagerConstructSuccess() = 0; + + // Register the notification function when the auth_mgr event is complete. + virtual void RegisterCleanNotifyCallback(CleanNotifyCallback cleanNotifyCallback); + + // Public functions + static std::string ConvertSrcVersion(const std::string &version, const std::string &edition); + static std::string ConvertSinkVersion(const std::string &version); + static int32_t DmGetUserId(int32_t displayId, int32_t targetUserId); + + // Public variables + bool isAuthNewVersion_ = true; +}; + +} // namespace DistributedHardware +} // namespace OHOS +#endif // OHOS_DM_AUTH_ADAPTER_V2_H diff --git a/services/implementation/include/authentication_v2/dm_auth_message_processor.h b/services/implementation/include/authentication_v2/dm_auth_message_processor.h new file mode 100644 index 000000000..a024f8731 --- /dev/null +++ b/services/implementation/include/authentication_v2/dm_auth_message_processor.h @@ -0,0 +1,321 @@ +/* + * Copyright (c) 2025 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 OHOS_DM_AUTH_MESSAGE_PROCESSOR_V2_H +#define OHOS_DM_AUTH_MESSAGE_PROCESSOR_V2_H + +#include +#include "json_object.h" +#include "crypto_mgr.h" +#include "access_control_profile.h" +#include "deviceprofile_connector.h" + +namespace OHOS { +namespace DistributedHardware { +struct DmAuthContext; +struct DmAccess; + +extern const char* TAG_LNN_PUBLICK_KEY; +extern const char* TAG_TRANSMIT_PUBLICK_KEY; +extern const char* TAG_LNN_CREDENTIAL_ID; +extern const char* TAG_TRANSMIT_CREDENTIAL_ID; +extern const char* TAG_AUTH_RESULT; +extern const char* TAG_AUTH_TYPE_LIST; +extern const char* TAG_CURRENT_AUTH_TYPE_IDX; + +// IS interface input parameter json format string key +extern const char* TAG_METHOD; +extern const char* TAG_PEER_USER_SPACE_ID; +extern const char* TAG_SUBJECT; +extern const char* TAG_CRED_TYPE; +extern const char* TAG_KEY_FORMAT; +extern const char* TAG_ALGORITHM_TYPE; +extern const char* TAG_PROOF_TYPE; +extern const char* TAG_KEY_VALUE; +extern const char* TAG_AUTHORIZED_SCOPE; +extern const char* TAG_AUTHRIZED_APP_LIST; +extern const char* TAG_CREDENTIAL_OWNER; +extern const char* TAG_SYNC; +extern const char* TAG_ACCESS; +extern const char* TAG_PROXY; +extern const char* TAG_ACL; +extern const char* TAG_ACCESSER; +extern const char* TAG_ACCESSEE; +extern const char* TAG_SERVICEINFO; +// The local SK information is synchronized to the remote end to construct acl-accesser/accessee. +extern const char* TAG_TRANSMIT_SK_ID; +extern const char* TAG_LNN_SK_ID; +extern const char* TAG_TRANSMIT_SK_TIMESTAMP; +extern const char* TAG_LNN_SK_TIMESTAMP; +extern const char* TAG_TOKEN_ID; +extern const char* TAG_ISSUER; + +extern const char* TAG_DEVICE_VERSION; +extern const char* TAG_DEVICE_NAME; +extern const char* TAG_DEVICE_ID_HASH; +extern const char* TAG_USER_ID_HASH; +extern const char* TAG_ACCOUNT_ID_HASH; +extern const char* TAG_TOKEN_ID_HASH; +extern const char* TAG_SESSION_NAME; +extern const char* TAG_ACL_CHECKSUM; +extern const char* TAG_COMPRESS_ORI_LEN; +extern const char* TAG_COMPRESS; +extern const char* TAG_REPLY; +extern const char* TAG_STATE; +extern const char* TAG_REASON; +extern const char* TAG_PEER_USER_ID; +extern const char* TAG_PEER_DISPLAY_ID; +extern const char* TAG_EXTRA_INFO; + +extern const char* TAG_IS_ONLINE; +extern const char* TAG_IS_AUTHED; +extern const char* TAG_CREDENTIAL_INFO; +extern const char* TAG_CERT_INFO; +extern const char* TAG_LANGUAGE; + +// Accesser table content is used for ACL synchronization. +extern const char* TAG_ACCESSER_DEVICE_ID; +extern const char* TAG_ACCESSER_USER_ID; +extern const char* TAG_ACCESSER_ACOUNT_ID; +extern const char* TAG_ACCESSER_TOKEN_ID; +extern const char* TAG_ACCESSER_SERVICE_NAME; +extern const char* TAG_ACCESSER_BUNDLE_NAME; +extern const char* TAG_ACCESSER_HAP_SIGNATURE; +extern const char* TAG_ACCESSER_BIND_LEVEL; +extern const char* TAG_ACCESSER_CREDENTIAL_ID; +extern const char* TAG_ACCESSER_STATUS; +extern const char* TAG_ACCESSER_SK_ID; +extern const char* TAG_ACCESSER_SK_TIMESTAMP; + +// Accessee table content is used for ACL synchronization. +extern const char* TAG_ACCESSEE_DEVICE_ID; +extern const char* TAG_ACCESSEE_USER_ID; +extern const char* TAG_ACCESSEE_ACOUNT_ID; +extern const char* TAG_ACCESSEE_TOKEN_ID; +extern const char* TAG_ACCESSEE_SERVICE_NAME; +extern const char* TAG_ACCESSEE_BUNDLE_NAME; +extern const char* TAG_ACCESSEE_HAP_SIGNATURE; +extern const char* TAG_ACCESSEE_BIND_LEVEL; +extern const char* TAG_ACCESSEE_CREDENTIAL_ID; +extern const char* TAG_ACCESSEE_STATUS; +extern const char* TAG_ACCESSEE_SK_ID; +extern const char* TAG_ACCESSEE_SK_TIMESTAMP; + +// 逻辑会话Tag +constexpr const char* DM_TAG_LOGICAL_SESSION_ID = "logicalSessionId"; + +// 报文类型 +enum DmMessageType { + // Terminate/Exception Message + MSG_TYPE_UNKNOWN = 0, + MSG_TYPE_AUTH_TERMINATE = 1, + // Normal Message + MSG_TYPE_REQ_ACL_NEGOTIATE = 80, + MSG_TYPE_RESP_ACL_NEGOTIATE = 90, + MSG_TYPE_REQ_USER_CONFIRM = 100, + MSG_TYPE_RESP_USER_CONFIRM = 110, + MSG_TYPE_REQ_PIN_AUTH_START = 120, + MSG_TYPE_RESP_PIN_AUTH_START = 130, + MSG_TYPE_REQ_PIN_AUTH_MSG_NEGOTIATE = 121, + MSG_TYPE_RESP_PIN_AUTH_MSG_NEGOTIATE = 131, + MSG_TYPE_REQ_CREDENTIAL_EXCHANGE = 140, + MSG_TYPE_RESP_CREDENTIAL_EXCHANGE = 150, + MSG_TYPE_REQ_CREDENTIAL_AUTH_START = 160, + MSG_TYPE_RESP_CREDENTIAL_AUTH_START = 170, + MSG_TYPE_REQ_CREDENTIAL_AUTH_NEGOTIATE = 161, + MSG_TYPE_RESP_CREDENTIAL_AUTH_NEGOTIATE = 171, + MSG_TYPE_REQ_DATA_SYNC = 180, + MSG_TYPE_RESP_DATA_SYNC = 190, + MSG_TYPE_AUTH_REQ_FINISH = 200, + MSG_TYPE_AUTH_RESP_FINISH = 201, +}; +// 对齐数据库ACL TABLE字段 +// 注意:修改本结构体 需要同步修改dm_auth_message_processor.cpp中的From/ToJson函数 +struct DmAccessControlTable { + int32_t accessControlId; + int64_t accesserId; + int64_t accesseeId; + std::string deviceId; + std::string sessionKey; + int32_t bindType; + uint32_t authType; + uint32_t deviceType; + std::string deviceIdHash; + int32_t status; + int32_t validPeriod; + int32_t lastAuthTime; + uint32_t bindLevel; +}; + +// Structure used for synchronizing ACL access +// Attention: Modifying this structure requires updating the From/ToJson functions in dm_auth_message_processor.cpp. +struct DmAccessToSync { + std::string deviceName; + // For A->B communication, whether it's the A end or B end, the Accesser object stores + // the A end's deviceId, and the Accessee object stores the B end's deviceId + std::string deviceId; + int32_t userId; + std::string accountId; + uint64_t tokenId; + std::string bundleName; // Stores the PacketName + int32_t bindLevel; // Passed through for business purposes, no custom definition required + int32_t sessionKeyId; // User credential ID + int64_t skTimeStamp; // Used for aging, time is 2 days, user-level credential timestamp +}; + +// json and struct conversion functions +void ToJson(JsonItemObject &itemObject, const DmAccessControlTable &table); +void FromJson(const JsonItemObject &itemObject, DmAccessControlTable &table); +void ToJson(JsonItemObject &itemObject, const DmAccessToSync &table); +void FromJson(const JsonItemObject &itemObject, DmAccessToSync &table); + +class DmAuthMessageProcessor { +public: + using CreateMessageFuncPtr = + int32_t (DmAuthMessageProcessor::*)(std::shared_ptr, JsonObject &jsonObject); + using ParaseMessageFuncPtr = + int32_t (DmAuthMessageProcessor::*)(const JsonObject &, std::shared_ptr); + + DmAuthMessageProcessor(); + ~DmAuthMessageProcessor(); + // Parse the message, and save the parsed information to the context + int32_t ParseMessage(std::shared_ptr context, const std::string &message); + // Create a message, construct the corresponding message based on msgType + std::string CreateMessage(DmMessageType msgType, std::shared_ptr context); + + // Create and send a message + void CreateAndSendMsg(DmMessageType msgType, std::shared_ptr context); + + // Save the session key + int32_t SaveSessionKey(const uint8_t *sessionKey, const uint32_t keyLen); + + // Save the permanent session key to the data profile + int32_t SaveSessionKeyToDP(int32_t &skId); + + // Save the current access control list + int32_t PutAccessControlList(std::shared_ptr context, + DmAccess &access, std::string trustDeviceId); + + // Calculate the checksum for the access control list + bool ChecksumAcl(DistributedDeviceProfile::AccessControlProfile &acl, + std::vector &accesserStrList, std::vector &accesseeStrList); + + // Extract the access control list (ACL) for message parsing and bus usage. + // If no ACL is available, return an empty string. The returned string is in + // JSON format: {dmversion:x,accesser:[{accesserDeviceId:y,...},...], accessee:{...}} + int32_t GetAclListStr(std::shared_ptr &context, std::string &aclList); +private: + // Internal implementations for various message types + + // Used to encrypt the synchronization message + int32_t EncryptSyncMessage(std::shared_ptr &context, DmAccess &accessSide, std::string &encSyncMsg); + // Parse the authentication start message + int32_t ParseAuthStartMessage(const JsonObject &jsonObject, std::shared_ptr context); + + // Parse the 80 message + int32_t ParseNegotiateMessage(const JsonObject &jsonObject, std::shared_ptr context); + // Parse the 90 message + int32_t ParseMessageRespAclNegotiate(const JsonObject &json, std::shared_ptr context); + // Parse the 100 message + int32_t ParseMessageReqUserConfirm(const JsonObject &json, std::shared_ptr context); + // Parse the 110 message + int32_t ParseMessageRespUserConfirm(const JsonObject &json, std::shared_ptr context); + // Parse the 120 message + int32_t ParseMessageReqPinAuthStart(const JsonObject &json, std::shared_ptr context); + // Parse the 130 message + int32_t ParseMessageRespPinAuthStart(const JsonObject &json, std::shared_ptr context); + // Parse the 121 message + int32_t ParseMessageReqPinAuthNegotiate(const JsonObject &json, std::shared_ptr context); + // Parse the 131 message + int32_t ParseMessageRespPinAuthNegotiate(const JsonObject &jsonObject, std::shared_ptr context); + // Parse the 140 message + int32_t ParseMessageReqCredExchange(const JsonObject &jsonObject, std::shared_ptr context); + // Parse the 150 message + int32_t ParseMessageRspCredExchange(const JsonObject &jsonObject, std::shared_ptr context); + // Parse the 161, 170, and 171 messages + int32_t ParseMessageNegotiateTransmit(const JsonObject &jsonObject, std::shared_ptr context); + // Parse the 180 message + int32_t ParseMessageSyncReq(const JsonObject &jsonObject, std::shared_ptr context); + // Parse the 190 message + int32_t ParseMessageSyncResp(const JsonObject &jsonObject, std::shared_ptr context); + // Parse the 200 message + int32_t ParseMessageSinkFinish(const JsonObject &jsonObject, std::shared_ptr context); + // Parse the 201 message + int32_t ParseMessageSrcFinish(const JsonObject &jsonObject, std::shared_ptr context); + + // Create the 80 message + int32_t CreateNegotiateMessage(std::shared_ptr context, JsonObject &jsonObject); + // Create the 90 message + int32_t CreateRespNegotiateMessage(std::shared_ptr context, JsonObject &jsonObject); + // Create the 100 message + int32_t CreateMessageReqUserConfirm(std::shared_ptr context, JsonObject &json); + // Create the 110 message + int32_t CreateMessageRespUserConfirm(std::shared_ptr context, JsonObject &json); + // Create the 120 message + int32_t CreateMessageReqPinAuthStart(std::shared_ptr context, JsonObject &json); + // Create the 130 message + int32_t CreateMessageRespPinAuthStart(std::shared_ptr context, JsonObject &json); + // Create the 121 message + int32_t CreateMessageReqPinAuthNegotiate(std::shared_ptr context, JsonObject &json); + // Create the 131 message + int32_t CreateMessageRespPinAuthNegotiate(std::shared_ptr context, JsonObject &json); + // Create the 140 message + int32_t CreateMessageReqCredExchange(std::shared_ptr context, JsonObject &jsonObject); + // Create the 150 message + int32_t CreateMessageRspCredExchange(std::shared_ptr context, JsonObject &jsonObject); + // Create the 160 message + int32_t CreateMessageReqCredAuthStart(std::shared_ptr context, JsonObject &jsonObject); + // Construct the 161, 170, and 171 credential authentication messages + int32_t CreateCredentialNegotiateMessage(std::shared_ptr context, JsonObject &jsonObject); + // Construct the 180 and 190 sync messages + int32_t CreateSyncMessage(std::shared_ptr context, JsonObject &jsonObject); + // Create the 190 message + int32_t CreateMessageSyncResp(std::shared_ptr context, JsonObject &jsonObject); + // Create the 200 message + int32_t CreateMessageFinish(std::shared_ptr context, JsonObject &jsonObject); + + // Compress the sync message + std::string CompressSyncMsg(std::string &inputStr); + // Decompress the sync message + std::string DecompressSyncMsg(std::string& compressed, uint32_t oriLen); + // Serialize the ACL + int32_t ACLToStr(DistributedDeviceProfile::AccessControlProfile acl, std::string aclStr); + // Decrypt the 180 and 190 messages + int32_t DecryptSyncMessage(std::shared_ptr &context, + DmAccess &access, std::string &enSyncMsg); + // Parse the sync message + int32_t ParseSyncMessage(std::shared_ptr &context, + DmAccess &access, JsonObject &jsonObject); + + // Convert the accesser_table record in DP to a string + std::string AccesserToStr(DistributedDeviceProfile::AccessControlProfile acl); + // Convert the accessee_table record in DP to a string + std::string AccesseeToStr(DistributedDeviceProfile::AccessControlProfile acl); + std::string Base64Encode(std::string &inputStr); + std::string Base64Decode(std::string &inputStr); + void SetAccessControlList(std::shared_ptr context, + DistributedDeviceProfile::AccessControlProfile &profile); + void SetTransmitAccessControlList(std::shared_ptr context, + DistributedDeviceProfile::Accesser &accesser, DistributedDeviceProfile::Accessee &accessee); + void SetLnnAccessControlList(std::shared_ptr context, + DistributedDeviceProfile::Accesser &accesser, DistributedDeviceProfile::Accessee &accessee); + std::shared_ptr cryptoMgr_ = nullptr; + std::unordered_map createMessageFuncMap_; + std::unordered_map paraseMessageFuncMap_; +}; + +} // namespace DistributedHardware +} // namespace OHOS +#endif // OHOS_DM_AUTH_MESSAGE_PROCESSOR_V2_H \ No newline at end of file diff --git a/services/implementation/include/authentication_v2/dm_auth_state.h b/services/implementation/include/authentication_v2/dm_auth_state.h new file mode 100644 index 000000000..4e175c20f --- /dev/null +++ b/services/implementation/include/authentication_v2/dm_auth_state.h @@ -0,0 +1,387 @@ +/* + * Copyright (c) 2025 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 OHOS_DM_AUTH_STATE_V2_H +#define OHOS_DM_AUTH_STATE_V2_H + +#include + +#include "access_control_profile.h" +#include "dm_auth_context.h" + +namespace OHOS { +namespace DistributedHardware { + +// 状态类型 +enum class DmAuthStateType { + AUTH_IDLE_STATE = 0, // 设备初始化时 + // source端的状态 + AUTH_SRC_START_STATE = 1, // 用户触发BindTarget + AUTH_SRC_NEGOTIATE_STATE = 2, // 收到软总线回调函数OnSessionOpened,发送80报文 + AUTH_SRC_CONFIRM_STATE = 3, // 收到90授权结果报文,发送100报文 + AUTH_SRC_PIN_NEGOTIATE_START_STATE = 4, // 开始协商PIN码,收到110授权结果报文 或回退 或 90跳转 + AUTH_SRC_PIN_INPUT_STATE = 5, // 输入PIN + AUTH_SRC_PIN_NEGOTIATE_ULTRASONIC_PIN_STATE = 6, // 超声PIN协商 + AUTH_SRC_PIN_AUTH_START_STATE = 7, // 开始做认证,发送120报文 + AUTH_SRC_PIN_AUTH_MSG_NEGOTIATE_STATE = 8, // 收到130认证PIN结果报文,发送121报文 + AUTH_SRC_PIN_AUTH_DONE_STATE = 9, // 收到131认证PIN结果报文,调用processData + AUTH_SRC_CREDENTIAL_EXCHANGE_STATE = 10, // 触发Onfinish回调事件,发送140报文 + AUTH_SRC_CREDENTIAL_AUTH_START_STATE = 11, // 收到150加密报文,发送160报文 + AUTH_SRC_CREDENTIAL_AUTH_NEGOTIATE_STATE = 12, // 收到170凭据认证报文,发送161报文 + AUTH_SRC_CREDENTIAL_AUTH_DONE_STATE = 13, // 收到171凭据认证报文,回复160报文或者180报文 + AUTH_SRC_DATA_SYNC_STATE = 14, // 收到190报文,发送200报文 + AUTH_SRC_FINISH_STATE = 15, // 收到201报文 + + // sink端的状态 + AUTH_SINK_START_STATE = 50, // 总线触发OnSessionOpened + AUTH_SINK_NEGOTIATE_STATE = 51, // 收到80可信关系协商报文,发送90报文 + AUTH_SINK_CONFIRM_STATE = 52, // 收到100用户授权报文,发送110报文 + AUTH_SINK_PIN_NEGOTIATE_START_STATE = 53, // 开始协商PIN码,CONFIRM_STATE 主动迁移或者 错误回退 + AUTH_SINK_PIN_DISPLAY_STATE = 54, // 生成并显示PIN + AUTH_SINK_PIN_NEGOTIATE_ULTRASONIC_PIN_STATE = 55, // 协商超声PIN状态 (收src端报文)被动触发 或 其他状态主动迁移 进入超声码协商状态 + AUTH_SINK_PIN_AUTH_START_STATE = 56, // 收到120认证PIN报文,发送130报文 + AUTH_SINK_PIN_AUTH_MSG_NEGOTIATE_STATE = 57, // 收到121认证PIN报文,发送131报文 + AUTH_SINK_PIN_AUTH_DONE_STATE = 58, // 触发Onfinish回调事件 + AUTH_SINK_CREDENTIAL_EXCHANGE_STATE = 59, // 收到140加密报文,发送150报文 + AUTH_SINK_CREDENTIAL_AUTH_START_STATE = 60, // 收到160凭证认证报文,发送170报文 + AUTH_SINK_CREDENTIAL_AUTH_NEGOTIATE_STATE = 61, // 收到161凭据协商报文,回复171报文 + AUTH_SINK_DATA_SYNC_STATE = 62, // 收到180同步报文,发送190报文 + AUTH_SINK_FINISH_STATE = 63, // 收到200结束报文, 发送201报文 +}; + +// 凭据添加方式 +enum DmAuthCredentialAddMethod : uint8_t { + DM_AUTH_CREDENTIAL_ADD_METHOD_GENERATE = 1, // 生成 + DM_AUTH_CREDENTIAL_ADD_METHOD_IMPORT, // 导入 +}; + +// 凭据主体 +enum DmAuthCredentialSubject : uint8_t { + DM_AUTH_CREDENTIAL_SUBJECT_PRIMARY = 1, // 主控 + DM_AUTH_CREDENTIAL_SUBJECT_SUPPLEMENT, // 配件 +}; + +// 凭据与账号关联 +enum DmAuthCredentialAccountRelation : uint8_t { + DM_AUTH_CREDENTIAL_INVALID = 0, // 无效 + DM_AUTH_CREDENTIAL_ACCOUNT_RELATED = 1, // 账号相关 + DM_AUTH_CREDENTIAL_ACCOUNT_UNRELATED = 2, // 账号无关 + DM_AUTH_CREDENTIAL_ACCOUNT_ACROSS = 3, // 分享 +}; + +// 秘钥类型 +enum DmAuthKeyFormat : uint8_t { + DM_AUTH_KEY_FORMAT_SYMM_IMPORT = 1, // 对称密钥(仅在导入下支持) + DM_AUTH_KEY_FORMAT_ASYMM_IMPORT, // 非对称密钥公钥(仅在导入下支持) + DM_AUTH_KEY_FORMAT_ASYMM_GENERATE, // 非对称密钥(仅在生成下支持) + DM_AUTH_KEY_FORMAT_X509, // X509证书 +}; + +// 算法类型 +enum DmAuthAlgorithmType : uint8_t { + DM_AUTH_ALG_TYPE_AES256 = 1, // AES256 + DM_AUTH_ALG_TYPE_AES128, // AES128 + DM_AUTH_ALG_TYPE_P256, // P256 + DM_AUTH_ALG_TYPE_ED25519 // ED25519 +}; + +// 凭据证明类型 +enum DmAuthCredentialProofType : uint8_t { + DM_AUTH_CREDENTIAL_PROOF_PSK = 1, // PSK + DM_AUTH_CREDENTIAL_PROOF_PKI, // PKI +}; + +class DmAuthState { +public: + virtual ~DmAuthState() {}; + virtual DmAuthStateType GetStateType() = 0; + virtual int32_t Action(std::shared_ptr context) = 0; // 执行状态对应的action动作 + void SyncAclList(std::shared_ptr context, + std::string credId, int32_t sessionKeyId, int32_t aclId); + void SourceFinish(std::shared_ptr context); + void SinkFinish(std::shared_ptr context); + std::string GenerateBindResultContent(DmAccess &access); + static bool IsScreenLocked(); + static int32_t GetTaskTimeout(std::shared_ptr context, const char* taskName, int32_t taskTimeOut); + static void HandleAuthenticateTimeout(std::shared_ptr context, std::string name); + static bool IsImportAuthCodeCompatibility(DmAuthType authType); + + // 比较明文阶段和密文阶段四元组、绑定级别是否相同 + bool IsQuadrupleAndBindLevelSame(std::shared_ptr context); + // 查询ACL列表 + std::vector GetAclList(std::shared_ptr context); +protected: + int32_t GetAuthCredentialInfo(std::shared_ptr context); + bool NeedReqUserConfirm(std::shared_ptr context); + bool NeedPinAuth(std::shared_ptr context); + bool NeedAgreeCredential(std::shared_ptr context); + bool NeedAgreeAcl(std::shared_ptr context); +}; + +class AuthSrcConfirmState : public DmAuthState { +public: + virtual ~AuthSrcConfirmState() {}; + DmAuthStateType GetStateType() override; + int32_t Action(std::shared_ptr context) override; +private: + void NegotiateCredential(std::shared_ptr context); + void NegotiateAcl(std::shared_ptr context); +}; + +class AuthSinkStatePinAuthComm { +public: + static bool IsPinCodeValid(int32_t numpin); + static bool IsPinCodeValid(const std::string& strpin); + static bool IsAuthCodeReady(std::shared_ptr context); + static void GeneratePincode(std::shared_ptr context); + static int32_t ShowAuthInfoDialog(std::shared_ptr context); +private: + static void HandleSessionHeartbeat(std::shared_ptr context, std::string name); +}; + +class AuthSinkConfirmState : public DmAuthState { +public: + virtual ~AuthSinkConfirmState() {}; + DmAuthStateType GetStateType() override; + int32_t Action(std::shared_ptr context) override; +private: + void NegotiateCredential(std::shared_ptr context); + void NegotiateAcl(std::shared_ptr context); + int32_t ShowConfigDialog(std::shared_ptr context); + void ReadServiceInfo(std::shared_ptr context); + void MatchFallBackCandidateList(std::shared_ptr context, DmAuthType authType); +}; + +class AuthSrcPinNegotiateStartState : public DmAuthState { +public: + virtual ~AuthSrcPinNegotiateStartState() {}; + DmAuthStateType GetStateType() override; + int32_t Action(std::shared_ptr context) override; +private: + int32_t NegotiatePinAuth(std::shared_ptr context, bool firstTime); +}; + +class AuthSrcPinInputState : public DmAuthState { +public: + virtual ~AuthSrcPinInputState() {}; + DmAuthStateType GetStateType() override; + int32_t Action(std::shared_ptr context) override; +private: + int32_t ShowStartAuthDialog(std::shared_ptr context); +}; + +class AuthSinkPinNegotiateStartState : public DmAuthState { +public: + virtual ~AuthSinkPinNegotiateStartState() {}; + DmAuthStateType GetStateType() override; + int32_t Action(std::shared_ptr context) override; +}; + +class AuthSinkPinDisplayState : public DmAuthState { +public: + virtual ~AuthSinkPinDisplayState() {}; + DmAuthStateType GetStateType() override; + int32_t Action(std::shared_ptr context) override; +}; + +class AuthSrcPinNegotiateUltrasonicPinState : public DmAuthState { +public: + virtual ~AuthSrcPinNegotiateUltrasonicPinState() {}; + DmAuthStateType GetStateType() override; + int32_t Action(std::shared_ptr context) override; +}; + +class AuthSinkPinNegotiateUltrasonicPinState : public DmAuthState { +public: + virtual ~AuthSinkPinNegotiateUltrasonicPinState() {}; + DmAuthStateType GetStateType() override; + int32_t Action(std::shared_ptr context) override; +}; + +class AuthSrcPinAuthStartState : public DmAuthState { +public: + virtual ~AuthSrcPinAuthStartState() {}; + DmAuthStateType GetStateType() override; + int32_t Action(std::shared_ptr context) override; +private: + int32_t ShowStartAuthDialog(std::shared_ptr context); // 向用户显示PIN输入框 +}; + +class AuthSinkPinAuthStartState : public DmAuthState { +public: + virtual ~AuthSinkPinAuthStartState() {}; + DmAuthStateType GetStateType() override; + int32_t Action(std::shared_ptr context) override; +}; + +class AuthSrcPinAuthMsgNegotiateState : public DmAuthState { +public: + virtual ~AuthSrcPinAuthMsgNegotiateState() {}; + DmAuthStateType GetStateType() override; + int32_t Action(std::shared_ptr context) override; +}; + +class AuthSinkPinAuthMsgNegotiateState : public DmAuthState { +public: + virtual ~AuthSinkPinAuthMsgNegotiateState() {}; + DmAuthStateType GetStateType() override; + int32_t Action(std::shared_ptr context) override; +}; + +class AuthSinkPinAuthDoneState : public DmAuthState { +public: + virtual ~AuthSinkPinAuthDoneState() {}; + DmAuthStateType GetStateType() override; + int32_t Action(std::shared_ptr context) override; +}; + +// 收到131认证PIN结果报文,调用processData +class AuthSrcPinAuthDoneState : public DmAuthState { +public: + virtual ~AuthSrcPinAuthDoneState() {}; + DmAuthStateType GetStateType() override; + int32_t Action(std::shared_ptr context) override; +}; + +class AuthSrcStartState : public DmAuthState { +public: + virtual ~AuthSrcStartState() {}; + DmAuthStateType GetStateType() override; + int32_t Action(std::shared_ptr context) override; +}; + +class AuthSrcNegotiateStateMachine : public DmAuthState { +public: + virtual ~AuthSrcNegotiateStateMachine() {}; + DmAuthStateType GetStateType() override; + int32_t Action(std::shared_ptr context) override; +}; + +// 凭据协商阶段,AuthSrcCredentialExchangeState AuthSinkCredentialExchangeState AuthSrcCredentialAuthStartState +// 中间类 封装业务相关的公共接口 +class AuthCredentialAgreeState : public DmAuthState { +public: + virtual ~AuthCredentialAgreeState() {}; +protected: + // 生成凭据协商状态下的authParams的json格式字符串 + std::string CreateAuthParamsString(DmAuthScope authorizedScope, DmAuthCredentialAddMethod method, + const std::shared_ptr &authContext); + int32_t GenerateCredIdAndPublicKey(DmAuthScope authorizedScope, std::shared_ptr &authContext); + // 协商凭据得到协商凭据Id + int32_t AgreeCredential(DmAuthScope authorizedScope, std::shared_ptr &authContext); +}; + +// 收到131报文,发送140报文 +class AuthSrcCredentialExchangeState : public AuthCredentialAgreeState { +public: + virtual ~AuthSrcCredentialExchangeState() {}; + DmAuthStateType GetStateType() override; + int32_t Action(std::shared_ptr context) override; +}; + +// AuthSinkCredentialExchangeState 收到140报文发送150报文 +class AuthSinkCredentialExchangeState : public AuthCredentialAgreeState { +public: + virtual ~AuthSinkCredentialExchangeState() {}; + DmAuthStateType GetStateType() override; + int32_t Action(std::shared_ptr context) override; +}; + +// AuthSrcCredentialAuthStartState, // 收到150加密报文,发送160报文 +class AuthSrcCredentialAuthStartState : public AuthCredentialAgreeState { +public: + virtual ~AuthSrcCredentialAuthStartState() {}; + DmAuthStateType GetStateType() override; + int32_t Action(std::shared_ptr context) override; +}; +// 收到170凭据认证报文,解析ontransmit,回复161报文 +class AuthSrcCredentialAuthNegotiateState : public DmAuthState { +public: + virtual ~AuthSrcCredentialAuthNegotiateState() {}; + DmAuthStateType GetStateType() override; + int32_t Action(std::shared_ptr context) override; // 执行状态对应的action动作 +}; + +// 收到171凭据认证报文 发送160/180 报文 +class AuthSrcCredentialAuthDoneState : public DmAuthState { +public: + virtual ~AuthSrcCredentialAuthDoneState() {}; + DmAuthStateType GetStateType() override; + int32_t Action(std::shared_ptr context) override; // 执行状态对应的action动作 +}; + +// 收到160凭证认证报文 发送170报文 +class AuthSinkCredentialAuthStartState : public DmAuthState { +public: + virtual ~AuthSinkCredentialAuthStartState() {}; + DmAuthStateType GetStateType() override; + int32_t Action(std::shared_ptr context) override; // 执行状态对应的action动作 +}; + +// 收到161凭据协商报文 并回复171报文 +class AuthSinkCredentialAuthNegotiateState : public DmAuthState { +public: + virtual ~AuthSinkCredentialAuthNegotiateState() {}; + DmAuthStateType GetStateType() override; + int32_t Action(std::shared_ptr context) override; // 执行状态对应的action动作 +}; + +// 收到80报文,准备发送90报文 +class AuthSinkNegotiateStateMachine : public DmAuthState { +public: + virtual ~AuthSinkNegotiateStateMachine() {}; + DmAuthStateType GetStateType() override; + int32_t Action(std::shared_ptr context) override; + +private: + int32_t RespQueryAcceseeIds(std::shared_ptr context); + int32_t ProcRespNegotiate5_1_0(std::shared_ptr context); +}; + + +// AuthSinkDataSyncState // 收到180同步报文,发送190报文 +class AuthSinkDataSyncState : public DmAuthState { +public: + virtual ~AuthSinkDataSyncState() {}; + DmAuthStateType GetStateType() override; + int32_t Action(std::shared_ptr context) override; +}; + +// AuthSrcDataSyncState // 收到190报文,发送200报文 +class AuthSrcDataSyncState : public DmAuthState { +public: + virtual ~AuthSrcDataSyncState() {}; + DmAuthStateType GetStateType() override; + int32_t Action(std::shared_ptr context) override; +}; + +// AuthSinkFinishState // 收到200结束报文,发送201 sink结束 +class AuthSinkFinishState : public DmAuthState { +public: + virtual ~AuthSinkFinishState() {}; + DmAuthStateType GetStateType() override; + int32_t Action(std::shared_ptr context) override; +}; + +// AuthSrcFinishState // 收到201结束报文 source结束 +class AuthSrcFinishState : public DmAuthState { +public: + virtual ~AuthSrcFinishState() {}; + DmAuthStateType GetStateType() override; + int32_t Action(std::shared_ptr context) override; +}; +} // namespace DistributedHardware +} // namespace OHOS +#endif // OHOS_DM_AUTH_STATE_V2_H \ No newline at end of file diff --git a/services/implementation/include/authentication_v2/dm_auth_state_machine.h b/services/implementation/include/authentication_v2/dm_auth_state_machine.h new file mode 100644 index 000000000..b41ce4820 --- /dev/null +++ b/services/implementation/include/authentication_v2/dm_auth_state_machine.h @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2025 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 OHOS_DM_AUTH_STATE_MACHINE_V2_H +#define OHOS_DM_AUTH_STATE_MACHINE_V2_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "dm_auth_state.h" + +namespace OHOS { +namespace DistributedHardware { + +// Define the state transition table type +using StateTransitionTable = std::map>; + +enum DmEventType { + ON_TRANSMIT = 0, + ON_SESSION_KEY_RETURNED, + ON_REQUEST, + ON_FINISH, + ON_ERROR, + + ON_TIMEOUT, + ON_USER_OPERATION, + ON_FAIL, + ON_SCREEN_LOCKED, + ON_SESSION_OPENED, +}; + +class DmAuthStateMachine { +public: + DmAuthStateMachine(std::shared_ptr context); + ~DmAuthStateMachine(); + + // Notify state transition, execute the corresponding action for the state, and handle exceptions + // only allowed to be called within OnDataReceived + int32_t TransitionTo(std::shared_ptr state); + + // Wait for the expected event within the action, block until the expected event is completed or + // an exception occurs, returning the actual event that occurred (only allowed to be called within actions) + DmEventType WaitExpectEvent(DmEventType eventType); + + // Notify the completion of an event, passing the event enumeration + // (only allowed to be called when the event is triggered). If it's an exception event, + // record it in the context's reason or reply. + void NotifyEventFinish(DmEventType eventType); + + DmAuthStateType GetCurState(); + + // Stop the thread + void Stop(); + +private: + // Loop to wait for state transitions and execute actions + void Run(std::shared_ptr context); + void InsertSrcTransTable(); + void InsertSinkTransTable(); + + // Fetch the current state and execute it + std::optional> FetchAndSetCurState(); + + void SetCurState(DmAuthStateType state); + + bool CheckStateTransitValid(DmAuthStateType nextState); + + DmAuthStateType curState_; + + // State transition table for normal state transitions (all state transitions to the Finish state are valid) + StateTransitionTable stateTransitionTable_; + + std::queue eventQueue_; + + // Set of exception events + std::set exceptionEvent_; + + // Thread for state machine execution + std::thread thread_; + + // Atomic flag to control the state machine's running state + std::atomic running_; + + // Queue for storing states + std::queue> statesQueue_; + + // Synchronization primitives + std::mutex stateMutex_; + std::condition_variable stateCv_; + std::mutex eventMutex_; + std::condition_variable eventCv_; + + // Direction of authentication + DmAuthDirection direction_; + int32_t reason{DM_OK}; +}; + +} // namespace DistributedHardware +} // namespace OHOS +#endif // OHOS_DM_AUTH_STATE_MACHINE_V2_H diff --git a/services/implementation/include/cryptomgr/crypto_mgr.h b/services/implementation/include/cryptomgr/crypto_mgr.h index 86a759081..8afd26aa6 100644 --- a/services/implementation/include/cryptomgr/crypto_mgr.h +++ b/services/implementation/include/cryptomgr/crypto_mgr.h @@ -45,6 +45,7 @@ public: int32_t SaveSessionKey(const uint8_t *sessionKey, const uint32_t keyLen); int32_t ProcessSessionKey(const uint8_t *sessionKey, const uint32_t keyLen); void ClearSessionKey(); + uint32_t GetSessionKey(uint8_t *sesionKey); private: int32_t DoEncryptData(AesGcmCipherKey *cipherKey, const unsigned char *input, uint32_t inLen, diff --git a/services/implementation/include/dependency/hichain/hichain_auth_connector.h b/services/implementation/include/dependency/hichain/hichain_auth_connector.h index 460a4094d..da5edf66d 100644 --- a/services/implementation/include/dependency/hichain/hichain_auth_connector.h +++ b/services/implementation/include/dependency/hichain/hichain_auth_connector.h @@ -16,7 +16,9 @@ #ifndef OHOS_HICHAIN_AUTH_CONNECTOR_H #define OHOS_HICHAIN_AUTH_CONNECTOR_H +#include #include + #include "device_auth.h" #include "device_auth_defines.h" #include "hichain_connector_callback.h" @@ -53,16 +55,38 @@ public: int32_t ProcessAuthData(int64_t requestId, std::string authData, int32_t osAccountId); int32_t GenerateCredential(std::string &localUdid, int32_t osAccountId, std::string &publicKey); bool QueryCredential(std::string &localUdid, int32_t osAccountId); + int32_t QueryCredentialInfo(int32_t userId, const JsonObject &queryParams, JsonObject &resultJson); int32_t ImportCredential(int32_t osAccountId, std::string deviceId, std::string publicKey); int32_t DeleteCredential(const std::string &deviceId, int32_t userId); int32_t RegisterHiChainAuthCallback(std::shared_ptr callback); + int32_t RegisterHiChainAuthCallbackById(int64_t id, std::shared_ptr callback); int32_t GetCredential(std::string &localUdid, int32_t osAccountId, std::string &publicKey); + + // 处理凭据认证报文 + int32_t ProcessCredData(int64_t authReqId, const std::string &data); + // 生成凭据,返回凭据Id + int32_t AddCredential(int32_t osAccountId, const std::string &authParams, std::string &creId); + // 根据凭据Id导出公钥 + int32_t ExportCredential(int32_t osAccountId, const std::string &credId, std::string &publicKey); + // 凭据协商 + int32_t AgreeCredential(int32_t osAccountId, const std::string selfCredId, const std::string &authParams, + std::string &credId); + // 删除凭据 + int32_t DeleteCredential(int32_t osAccountId, const std::string &creId); + // 凭据认证 pinCode pin码(点对点临时凭据必填) + int32_t AuthCredential(int32_t osAccountId, int64_t authReqId, const std::string &credId, + const std::string &pinCode); + // pin码 认证 + int32_t AuthCredentialPinCode(int32_t osAccountId, int64_t authReqId, int32_t pinCode); + private: void FreeJsonString(char *jsonStr); + static std::shared_ptr GetDeviceAuthCallback(int64_t id); private: DeviceAuthCallback deviceAuthCallback_; static std::shared_ptr dmDeviceAuthCallback_; + static std::map> dmDeviceAuthCallbackMap_; static std::mutex dmDeviceAuthCallbackMutex_; }; } // namespace DistributedHardware diff --git a/services/implementation/include/dependency/hichain/hichain_connector.h b/services/implementation/include/dependency/hichain/hichain_connector.h index c6e518cad..c6210ddd8 100644 --- a/services/implementation/include/dependency/hichain/hichain_connector.h +++ b/services/implementation/include/dependency/hichain/hichain_connector.h @@ -155,7 +155,7 @@ public: * @tc.type: FUNC */ bool GetGroupInfo(const int32_t userId, const std::string &queryParams, std::vector &groupList); - + bool GetGroupInfoExt(const int32_t userId, const std::string &queryParams, std::vector &groupList); bool GetGroupInfoCommon(const int32_t userId, const std::string &queryParams, const char* pkgName, diff --git a/services/implementation/include/dependency/hichain/hichain_connector_callback.h b/services/implementation/include/dependency/hichain/hichain_connector_callback.h index 1e8e73f43..56dd42bbc 100644 --- a/services/implementation/include/dependency/hichain/hichain_connector_callback.h +++ b/services/implementation/include/dependency/hichain/hichain_connector_callback.h @@ -37,8 +37,7 @@ public: virtual void AuthDeviceFinish(int64_t requestId) = 0; virtual void AuthDeviceError(int64_t requestId, int32_t errorCode) = 0; virtual void AuthDeviceSessionKey(int64_t requestId, const uint8_t *sessionKey, uint32_t sessionKeyLen) = 0; - virtual int32_t GetPinCode(int32_t &code) = 0; - virtual void GetRemoteDeviceId(std::string &deviceId) = 0; + virtual char *AuthDeviceRequest(int64_t requestId, int operationCode, const char *reqParams) = 0; }; } // namespace DistributedHardware } // namespace OHOS diff --git a/services/implementation/include/dependency/softbus/softbus_connector.h b/services/implementation/include/dependency/softbus/softbus_connector.h index 718d7ddeb..cb776062f 100644 --- a/services/implementation/include/dependency/softbus/softbus_connector.h +++ b/services/implementation/include/dependency/softbus/softbus_connector.h @@ -49,7 +49,7 @@ public: * @tc.desc: Get Connect Addr of the SoftbusConnector * @tc.type: FUNC */ - static ConnectionAddr *GetConnectAddr(const std::string &deviceId, std::string &connectAddr); + static shared_ptr GetConnectAddr(const std::string &deviceId, std::string &connectAddr); /** * @tc.name: SoftbusConnector::GetUdidByNetworkId @@ -86,6 +86,11 @@ public: */ static void JoinLnnByHml(int32_t sessionId, int32_t sessionKeyId, int32_t remoteSessionKeyId); + static void JoinLnn(const std::string &deviceId, const std::string &remoteUdidHash); + + static void JoinLNNBySkId(int32_t sessionId, int32_t sessionKeyId, int32_t remoteSessionKeyId, + std::string udid, std::string udidHash); + /** * @tc.name: SoftbusConnector::RegisterConnectorCallback * @tc.desc: RegisterConnectorCallback of the Softbus Connector @@ -120,6 +125,7 @@ public: void HandleDeviceOffline(std::string deviceId); void SetProcessInfo(ProcessInfo processInfo); bool CheckIsOnline(const std::string &targetDeviceId); + bool CheckIsOnline(const std::string &targetDeviceIdHash, bool isHash); void SetProcessInfoVec(std::vector processInfoVec); std::vector GetProcessInfo(); void ClearProcessInfo(); diff --git a/services/implementation/include/device_manager_service_impl.h b/services/implementation/include/device_manager_service_impl.h index f13848c3d..55d8ff54a 100644 --- a/services/implementation/include/device_manager_service_impl.h +++ b/services/implementation/include/device_manager_service_impl.h @@ -16,11 +16,16 @@ #ifndef OHOS_DM_SERVICE_IMPL_H #define OHOS_DM_SERVICE_IMPL_H +#include +#include #include #include +#include +#include #include "access_control_profile.h" #include "dm_ability_manager.h" +#include "dm_auth_manager_base.h" #include "dm_auth_manager.h" #include "dm_common_event_manager.h" #include "dm_credential_manager.h" @@ -31,9 +36,29 @@ #include "dm_single_instance.h" #include "softbus_connector.h" #include "mine_hichain_connector.h" +#include "auth_manager.h" namespace OHOS { namespace DistributedHardware { + +class Session { +public: + Session(int sessionId, std::string deviceId); + int sessionId_; + std::string deviceId_; + std::string version_{""}; + std::atomic flag_{false}; // 只允许创建一个会话,初始化为false,首次新建置true,其他进入失败 + std::set logicalSessionSet_; // 逻辑会话集合 + std::atomic logicalSessionCnt_{0}; +}; + +struct Config { + std::string pkgName; + std::string authCode; + uint64_t tokenId; + int32_t authenticationType{0}; +}; + class DeviceManagerServiceImpl : public IDeviceManagerServiceImpl { public: DeviceManagerServiceImpl(); @@ -137,6 +162,12 @@ public: void DeleteAlwaysAllowTimeOut(); void CheckDeleteCredential(const std::string &remoteUdid); int32_t CheckDeviceInfoPermission(const std::string &localUdid, const std::string &peerDeviceId); + int32_t DeleteAcl(const std::string &sessionName, const std::string &localUdid, const std::string &remoteUdid, + int32_t bindLevel, const std::string &extra); + static void NotifyCleanEvent(int64_t logicalSessionId); + void HandleServiceUnBindEvent(int32_t userId, const std::string &remoteUdid, + int32_t remoteTokenId); + private: int32_t PraseNotifyEventJson(const std::string &event, JsonObject &jsonObject); std::string GetUdidHashByNetworkId(const std::string &networkId); @@ -154,20 +185,57 @@ private: void HandleUserRemoved(int32_t preUserId); void HandleRemoteUserRemoved(int32_t preUserId, const std::string &remoteUdid); DmAuthForm ConvertBindTypeToAuthForm(int32_t bindType); + int32_t InitAndRegisterAuthMgr(bool isSrcSide, uint64_t tokenId, std::shared_ptr session, + int64_t logicalSessionId); + std::shared_ptr GetAuthMgr(); + std::shared_ptr GetAuthMgrByTokenId(uint64_t tokenId); + std::shared_ptr GetCurSession(int sessionId); + std::shared_ptr GetOrCreateSession(const std::string& deviceId, + const std::map &bindParam); + int32_t ParseConnectAddr(const PeerTargetId &targetId, std::string &deviceId, + const std::map &bindParam); + std::shared_ptr GetConfigByTokenId(); + int OpenAuthSession(const std::map &bindParam); + + // 清理资源线程 + void CleanWorker(); + // 停止线程 + void Stop(); + int64_t FetchCleanEvent(); + void CleanAuthMgrByLogicalSessionId(int64_t logicalSessionId); + void CleanSessionMap(int sessionId, std::shared_ptr session); + void CleanSessionMapByLogicalSessionId(int64_t logicalSessionId); private: - std::shared_ptr authMgr_; + std::shared_ptr authMgr_; // 老协议专用 + std::map> authMgrMap_; // 新协议共用 + std::shared_ptr hiChainConnector_; + std::shared_ptr hiChainAuthConnector_; std::shared_ptr deviceStateMgr_; std::shared_ptr softbusConnector_; std::shared_ptr abilityMgr_; - std::shared_ptr hiChainConnector_; std::shared_ptr mineHiChainConnector_; std::shared_ptr credentialMgr_; std::shared_ptr commonEventManager_; - std::shared_ptr hiChainAuthConnector_; std::shared_ptr listener_; std::atomic isCredentialType_ = false; sptr dpInitedCallback_ = nullptr; + + std::map deviceId2SessionIdMap_; // 设备Id对应的会话Id, 只在src端使用 + std::map> sessionsMap_; // sessionId对应会话对象 + std::map deviceIdMutexMap_; // 设备Id对应的锁 + std::mutex mapMutex_; // sessionsMap_的锁 + std::map sessionEnableCvMap_; // 会话对应的条件变量 + std::map sessionEnableMutexMap_; // 会话对应的锁 + std::map logicalSessionId2TokenIdMap_; // 多会话与tokenId的对应关系 + std::map logicalSessionId2SessionIdMap_; // 多会话与物理回话Id的对应关系 + std::map> configsMap_; // authMgr未初始化时导入 + + std::thread thread_; + std::atomic running_; + static std::condition_variable cleanEventCv_; + static std::mutex cleanEventMutex_; + static std::queue cleanEventQueue_; }; using CreateDMServiceFuncPtr = IDeviceManagerServiceImpl *(*)(void); diff --git a/services/implementation/src/ability/standard/dm_dialog_manager.cpp b/services/implementation/src/ability/standard/dm_dialog_manager.cpp index 11b35a762..d7a8f229f 100644 --- a/services/implementation/src/ability/standard/dm_dialog_manager.cpp +++ b/services/implementation/src/ability/standard/dm_dialog_manager.cpp @@ -49,6 +49,7 @@ std::string DmDialogManager::customDescriptionStr_ = ""; std::string DmDialogManager::targetDeviceName_ = ""; std::string DmDialogManager::pinCode_ = ""; std::string DmDialogManager::hostPkgLabel_ = ""; +uint64_t DmDialogManager::tokenId_ = 0; int32_t DmDialogManager::deviceType_ = -1; DmDialogManager DmDialogManager::dialogMgr_; sptr DmDialogManager::dialogConnectionCallback_( @@ -78,24 +79,28 @@ void DmDialogManager::ShowConfirmDialog(const std::string param) std::string appOperationStr = ""; std::string customDescriptionStr = ""; std::string hostPkgLabel = ""; + uint64_t tokenId = 0; int32_t deviceType = -1; JsonObject jsonObject(param); if (!jsonObject.IsDiscarded()) { - if (IsString(jsonObject, TAG_REQUESTER)) { + if (jsonObject[TAG_REQUESTER].IsString()) { deviceName = jsonObject[TAG_REQUESTER].Get(); } - if (IsString(jsonObject, TAG_APP_OPERATION)) { + if (jsonObject[TAG_APP_OPERATION].IsString()) { appOperationStr = jsonObject[TAG_APP_OPERATION].Get(); } - if (IsString(jsonObject, TAG_CUSTOM_DESCRIPTION)) { + if (jsonObject[TAG_CUSTOM_DESCRIPTION].IsString()) { customDescriptionStr = jsonObject[TAG_CUSTOM_DESCRIPTION].Get(); } - if (IsInt32(jsonObject, TAG_LOCAL_DEVICE_TYPE)) { + if (jsonObject[TAG_LOCAL_DEVICE_TYPE].IsNumberInteger()) { deviceType = jsonObject[TAG_LOCAL_DEVICE_TYPE].Get(); } - if (IsString(jsonObject, TAG_HOST_PKGLABEL)) { + if (jsonObject[TAG_HOST_PKGLABEL].IsString()) { hostPkgLabel = jsonObject[TAG_HOST_PKGLABEL].Get(); } + if (jsonObject[TOKENID].IsNumberInteger()) { + tokenId = jsonObject[TOKENID].Get(); + } } bundleName_ = DM_UI_BUNDLE_NAME; @@ -105,14 +110,28 @@ void DmDialogManager::ShowConfirmDialog(const std::string param) customDescriptionStr_ = customDescriptionStr; deviceType_ = deviceType; hostPkgLabel_ = hostPkgLabel; + tokenId_ = tokenId; ConnectExtension(); } void DmDialogManager::ShowPinDialog(const std::string param) { + std::string pinCode; + uint64_t tokenId = 0; bundleName_ = DM_UI_BUNDLE_NAME; abilityName_ = PIN_ABILITY_NAME; - pinCode_ = param; + JsonObject jsonObject(param); + if (!jsonObject.IsDiscarded()) { + if (jsonObject[PIN_CODE_KEY].IsNumberInteger()) { + pinCode = std::to_string(jsonObject[PIN_CODE_KEY].Get()); + } + if (jsonObject[TOKENID].IsNumberInteger()) { + tokenId = jsonObject[TOKENID].Get(); + } + } + + pinCode_ = pinCode; + tokenId_ = tokenId; #if !(defined(__LITEOS_M__) || defined(LITE_DEVICE)) ffrt::submit([]() { ConnectExtension(); }); #else @@ -127,7 +146,20 @@ void DmDialogManager::ShowPinDialog(const std::string param) void DmDialogManager::ShowInputDialog(const std::string param) { - targetDeviceName_ = param; + std::string targetDeviceName; + uint64_t tokenId = 0; + JsonObject jsonObject(param); + if (!jsonObject.IsDiscarded()) { + if (jsonObject[TAG_TARGET_DEVICE_NAME].IsString()) { + targetDeviceName = jsonObject[TAG_TARGET_DEVICE_NAME].Get(); + } + if (jsonObject[TOKENID].IsNumberInteger()) { + tokenId = jsonObject[TOKENID].Get(); + } + } + + targetDeviceName_ = targetDeviceName; + tokenId_ = tokenId; bundleName_ = DM_UI_BUNDLE_NAME; abilityName_ = INPUT_ABILITY_NAME; ConnectExtension(); @@ -201,7 +233,8 @@ void DmDialogManager::DialogAbilityConnection::OnAbilityConnectDone( param[TAG_TARGET_DEVICE_NAME] = DmDialogManager::GetTargetDeviceName(); param[TAG_HOST_PKGLABEL] = DmDialogManager::GetHostPkgLabel(); param["disableUpGesture"] = 1; - std::string paramStr = SafetyDump(param); + param[TOKENID] = DmDialogManager::GetTokenId(); + std::string paramStr = param.Dump(); data.WriteString16(Str8ToStr16(paramStr)); LOGI("show dm dialog is begin"); const uint32_t cmdCode = 1; diff --git a/services/implementation/src/authentication/auth_message_processor.cpp b/services/implementation/src/authentication/auth_message_processor.cpp index 273db6dfb..fc130c5dd 100644 --- a/services/implementation/src/authentication/auth_message_processor.cpp +++ b/services/implementation/src/authentication/auth_message_processor.cpp @@ -22,7 +22,6 @@ namespace OHOS { namespace DistributedHardware { -const char* TAG_REPLY = "REPLY"; const char* TAG_NET_ID = "NETID"; const char* TAG_TARGET = "TARGET"; const char* TAG_APP_OPERATION = "APPOPERATION"; @@ -43,35 +42,25 @@ const char* TAG_CRYPTO_NAME = "CRYPTONAME"; const char* TAG_CRYPTO_VERSION = "CRYPTOVERSION"; const char* TAG_IDENTICAL_ACCOUNT = "IDENTICALACCOUNT"; const char* TAG_ACCOUNT_GROUPID = "ACCOUNTGROUPID"; -const char* APP_THUMBNAIL = "appThumbnail"; const char* QR_CODE_KEY = "qrCode"; const char* TAG_AUTH_TOKEN = "authToken"; const char* NFC_CODE_KEY = "nfcCode"; const char* OLD_VERSION_ACCOUNT = "oldVersionAccount"; -const char* TAG_AUTH_FINISH = "isFinish"; const char* TAG_HAVE_CREDENTIAL = "haveCredential"; const char* TAG_PUBLICKEY = "publicKey"; const char* TAG_SESSIONKEY = "sessionKey"; -const char* TAG_BIND_LEVEL = "bindLevel"; -const char* TAG_LOCAL_USERID = "localUserId"; const char* TAG_BIND_TYPE_SIZE = "bindTypeSize"; const char* TAG_ISONLINE = "isOnline"; const char* TAG_AUTHED = "authed"; const char* TAG_LOCAL_ACCOUNTID = "localAccountId"; -const char* TAG_DMVERSION = "dmVersion"; const char* TAG_HOST_PKGNAME = "hostPkgname"; const char* TAG_TOKENID = "tokenId"; const char* TAG_HAVECREDENTIAL = "haveCredential"; const char* TAG_CONFIRM_OPERATION = "confirmOperation"; -const char* TAG_DATA = "data"; -const char* TAG_DATA_LEN = "dataLen"; const char* TAG_IMPORT_AUTH_CODE = "IMPORT_AUTH_CODE"; const char* TAG_HOST_PKGLABEL = "hostPkgLabel"; -const char* TAG_EDITION = "edition"; -const char* TAG_BUNDLE_NAME = "bundleName"; const char* TAG_CRYPTIC_MSG = "encryptMsg"; -const char* TAG_PEER_BUNDLE_NAME = "PEER_BUNDLE_NAME"; const char* TAG_REMOTE_DEVICE_NAME = "REMOTE_DEVICE_NAME"; const char* TAG_SESSIONKEY_ID = "sessionKeyId"; diff --git a/services/implementation/src/authentication/dm_auth_manager.cpp b/services/implementation/src/authentication/dm_auth_manager.cpp index 9a93051e4..baf9443a9 100644 --- a/services/implementation/src/authentication/dm_auth_manager.cpp +++ b/services/implementation/src/authentication/dm_auth_manager.cpp @@ -52,21 +52,6 @@ namespace OHOS { namespace DistributedHardware { -const int32_t AUTHENTICATE_TIMEOUT = 120; -const int32_t CONFIRM_TIMEOUT = 60; -const int32_t NEGOTIATE_TIMEOUT = 10; -const int32_t INPUT_TIMEOUT = 60; -const int32_t ADD_TIMEOUT = 10; -const int32_t WAIT_NEGOTIATE_TIMEOUT = 10; -const int32_t WAIT_REQUEST_TIMEOUT = 10; -const int32_t CLONE_AUTHENTICATE_TIMEOUT = 20; -const int32_t CLONE_CONFIRM_TIMEOUT = 10; -const int32_t CLONE_NEGOTIATE_TIMEOUT = 10; -const int32_t CLONE_ADD_TIMEOUT = 10; -const int32_t CLONE_WAIT_NEGOTIATE_TIMEOUT = 10; -const int32_t CLONE_WAIT_REQUEST_TIMEOUT = 10; -const int32_t CLONE_SESSION_HEARTBEAT_TIMEOUT = 20; -const int32_t HML_SESSION_TIMEOUT = 10; const int32_t CANCEL_PIN_CODE_DISPLAY = 1; const int32_t DEVICE_ID_HALF = 2; const int32_t MAX_AUTH_TIMES = 3; @@ -79,24 +64,11 @@ const int32_t DM_AUTH_TYPE_MIN = 0; const int32_t AUTH_SESSION_SIDE_SERVER = 0; const int32_t USLEEP_TIME_US_500000 = 500000; // 500ms const int32_t AUTH_DEVICE_TIMEOUT = 10; -const int32_t SESSION_HEARTBEAT_TIMEOUT = 50; const int32_t ALREADY_BIND = 1; const int32_t STRTOLL_BASE_10 = 10; const int32_t MAX_PUT_SESSIONKEY_TIMEOUT = 100; //ms const int32_t SESSION_CLOSE_TIMEOUT = 5; -constexpr const char* AUTHENTICATE_TIMEOUT_TASK = "deviceManagerTimer:authenticate"; -constexpr const char* NEGOTIATE_TIMEOUT_TASK = "deviceManagerTimer:negotiate"; -constexpr const char* CONFIRM_TIMEOUT_TASK = "deviceManagerTimer:confirm"; -constexpr const char* INPUT_TIMEOUT_TASK = "deviceManagerTimer:input"; -constexpr const char* ADD_TIMEOUT_TASK = "deviceManagerTimer:add"; -constexpr const char* WAIT_NEGOTIATE_TIMEOUT_TASK = "deviceManagerTimer:waitNegotiate"; -constexpr const char* WAIT_REQUEST_TIMEOUT_TASK = "deviceManagerTimer:waitRequest"; -constexpr const char* AUTH_DEVICE_TIMEOUT_TASK = "deviceManagerTimer:authDevice_"; -constexpr const char* SESSION_HEARTBEAT_TIMEOUT_TASK = "deviceManagerTimer:sessionHeartbeat"; -constexpr const char* WAIT_SESSION_CLOSE_TIMEOUT_TASK = "deviceManagerTimer:waitSessionClose"; -constexpr const char* CLOSE_SESSION_TASK_SEPARATOR = "#"; - constexpr int32_t PROCESS_NAME_WHITE_LIST_NUM = 1; constexpr const static char* PROCESS_NAME_WHITE_LIST[PROCESS_NAME_WHITE_LIST_NUM] = { "com.example.myapplication", @@ -113,17 +85,6 @@ const std::map TASK_TIME_OUT_MAP = { { std::string(SESSION_HEARTBEAT_TIMEOUT_TASK), CLONE_SESSION_HEARTBEAT_TIMEOUT } }; -constexpr const char* APP_OPERATION_KEY = "appOperation"; -constexpr const char* TARGET_PKG_NAME_KEY = "targetPkgName"; -constexpr const char* CUSTOM_DESCRIPTION_KEY = "customDescription"; -constexpr const char* CANCEL_DISPLAY_KEY = "cancelPinCodeDisplay"; -constexpr const char* BUNDLE_NAME_KEY = "bundleName"; -constexpr const char* DM_VERSION_4_1_5_1 = "4.1.5.1"; -constexpr const char* DM_VERSION_5_0_1 = "5.0.1"; -constexpr const char* DM_VERSION_5_0_2 = "5.0.2"; -constexpr const char* DM_VERSION_5_0_3 = "5.0.3"; -constexpr const char* DM_VERSION_5_0_4 = "5.0.4"; -constexpr const char* DM_VERSION_5_0_5 = "5.0.5"; std::mutex g_authFinishLock; DmAuthManager::DmAuthManager(std::shared_ptr softbusConnector, @@ -337,8 +298,8 @@ void DmAuthManager::ParseJsonObject(JsonObject &jsonObject) authRequestContext_->customDesc = DmLanguageManager::GetInstance(). GetTextBySystemLanguage(jsonObject[CUSTOM_DESCRIPTION_KEY].Get()); } - if (IsString(jsonObject, APP_THUMBNAIL)) { - authRequestContext_->appThumbnail = jsonObject[APP_THUMBNAIL].Get(); + if (IsString(jsonObject, TAG_APP_THUMBNAIL2)) { + authRequestContext_->appThumbnail = jsonObject[TAG_APP_THUMBNAIL2].Get(); } CheckBindLevel(jsonObject, TAG_BIND_LEVEL, authRequestContext_->bindLevel); authRequestContext_->closeSessionDelaySeconds = 0; @@ -1040,7 +1001,7 @@ void DmAuthManager::RespNegotiate(const int32_t &sessionId) remoteDeviceId_ = authResponseContext_->localDeviceId; authResponseContext_->networkId = softbusConnector_->GetLocalDeviceNetworkId(); authResponseContext_->targetDeviceName = softbusConnector_->GetLocalDeviceName(); - remoteVersion_ = ConvertSrcVersion(authResponseContext_->dmVersion, authResponseContext_->edition); + remoteVersion_ = AuthManagerBase::ConvertSrcVersion(authResponseContext_->dmVersion, authResponseContext_->edition); NegotiateRespMsg(remoteVersion_); if (CompareVersion(remoteVersion_, std::string(DM_VERSION_4_1_5_1)) && (static_cast(authResponseContext_->bindLevel) >= DEVICE && @@ -1089,7 +1050,7 @@ void DmAuthManager::SendAuthRequest(const int32_t &sessionId) } remoteDeviceId_ = authResponseContext_->localDeviceId; authRequestContext_->remoteDeviceName = authResponseContext_->targetDeviceName; - remoteVersion_ = ConvertSinkVersion(authResponseContext_->dmVersion); + remoteVersion_ = AuthManagerBase::ConvertSinkVersion(authResponseContext_->dmVersion); if (timer_ != nullptr) { timer_->DeleteTimer(std::string(NEGOTIATE_TIMEOUT_TASK)); } @@ -1804,7 +1765,7 @@ void DmAuthManager::ShowAuthInfoDialog(bool authDeviceError) jsonObj[PIN_CODE_KEY] = authResponseContext_->code; std::string authParam = SafetyDump(jsonObj); pincodeDialogEverShown_ = true; - DmDialogManager::GetInstance().ShowPinDialog(std::to_string(authResponseContext_->code)); + DmDialogManager::GetInstance().ShowPinDialog(authParam); } void DmAuthManager::ShowStartAuthDialog() @@ -1940,7 +1901,16 @@ int32_t DmAuthManager::OnUserOperation(int32_t action, const std::string ¶ms } break; case USER_OPERATION_TYPE_DONE_PINCODE_INPUT: - ProcessPincode(std::atoi(params.c_str())); + { + JsonObject jsonObject(params); + if (jsonObject.IsDiscarded()) { + LOGE("OnUserOperation jsonStr error"); + return ERR_DM_INPUT_PARA_INVALID; + } + if (jsonObject[PIN_CODE_KEY].IsNumberInteger()) { + ProcessPincode(jsonObject[PIN_CODE_KEY].Get()); + } + } info.stageRes = static_cast(StageRes::STAGE_SUCC); if (!DmRadarHelper::GetInstance().ReportAuthInputPinBox(info)) { LOGE("ReportAuthInputPinBox failed"); @@ -2055,7 +2025,7 @@ int32_t DmAuthManager::ImportAuthCode(const std::string &pkgName, const std::str } int32_t DmAuthManager::BindTarget(const std::string &pkgName, const PeerTargetId &targetId, - const std::map &bindParam) + const std::map &bindParam, int sessionId, int64_t logicalSessionId) { struct RadarInfo info = { .funcName = "AuthenticateDevice", @@ -2580,6 +2550,27 @@ int32_t DmAuthManager::GetSessionKeyIdSync(int64_t requestId) return keyid; } +char *DmAuthManager::AuthDeviceRequest(int64_t requestId, int operationCode, const char *reqParams) +{ + LOGI("DmAuthManager::AuthDeviceRequest start."); + (void)requestId; + (void)reqParams; + JsonObject jsonObj; + int32_t pinCode = INVALID_PINCODE; + if (GetPinCode(pinCode) == ERR_DM_FAILED || pinCode == INVALID_PINCODE) { + jsonObj[FIELD_CONFIRMATION] = RequestResponse::REQUEST_REJECTED; + } else { + jsonObj[FIELD_CONFIRMATION] = RequestResponse::REQUEST_ACCEPTED; + jsonObj[FIELD_PIN_CODE] = std::to_string(pinCode); + } + std::string deviceId = ""; + GetRemoteDeviceId(deviceId); + jsonObj[FIELD_PEER_CONN_DEVICE_ID] = deviceId; + std::string jsonStr = SafetyDump(jsonObj); + char *buffer = strdup(jsonStr.c_str()); + return buffer; +} + void DmAuthManager::GetRemoteDeviceId(std::string &deviceId) { LOGI("GetRemoteDeviceId start."); @@ -3022,33 +3013,6 @@ void DmAuthManager::HandleDeviceNotTrust(const std::string &udid) hiChainConnector_->DeleteAllGroupByUdid(udid); } -std::string DmAuthManager::ConvertSrcVersion(const std::string &version, const std::string &edition) -{ - std::string srcVersion = ""; - if (version == "" && edition != "") { - srcVersion = edition; - } else if (version == "" && edition == "") { - srcVersion = DM_VERSION_5_0_1; - } else if (version != "" && edition == "") { - srcVersion = version; - } - LOGI("ConvertSrcVersion version %{public}s, edition %{public}s, srcVersion is %{public}s.", - version.c_str(), edition.c_str(), srcVersion.c_str()); - return srcVersion; -} - -std::string DmAuthManager::ConvertSinkVersion(const std::string &version) -{ - std::string sinkVersion = ""; - if (version == "") { - sinkVersion = DM_VERSION_4_1_5_1; - } else { - sinkVersion = version; - } - LOGI("ConvertSinkVersion version %{public}s, sinkVersion is %{public}s.", version.c_str(), sinkVersion.c_str()); - return sinkVersion; -} - void DmAuthManager::SetAuthType(int32_t authType) { authType_ = authType; @@ -3373,6 +3337,12 @@ int32_t DmAuthManager::GetTokenIdByBundleName(int32_t userId, std::string &bundl return ret; } +bool DmAuthManager::IsAuthManagerConstructSuccess() +{ + LOGI("DmAuthManager::IsAuthManagerConstructSuccess start, nothing to do."); + return true; +} + void DmAuthManager::OnSoftbusJoinLNNResult(const int32_t sessionId, const char *networkId, int32_t result) { (void)networkId; diff --git a/services/implementation/src/authentication_v2/auth_manager.cpp b/services/implementation/src/authentication_v2/auth_manager.cpp new file mode 100644 index 000000000..62308cef5 --- /dev/null +++ b/services/implementation/src/authentication_v2/auth_manager.cpp @@ -0,0 +1,1106 @@ +/* + * Copyright (c) 2025 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 + +#include "app_manager.h" +#include "softbus_common.h" +#include "system_ability_definition.h" +#include "iservice_registry.h" +#include "parameter.h" +#include "deviceprofile_connector.h" +#include "multiple_user_connector.h" + +#include "dm_constants.h" +#include "dm_crypto.h" +#include "dm_random.h" +#include "dm_log.h" +#include "dm_timer.h" +#include "dm_radar_helper.h" +#include "dm_device_info.h" +#include "dm_anonymous.h" +#include "dm_auth_state_machine.h" +#include "dm_auth_context.h" +#include "dm_auth_message_processor.h" +#include "auth_manager.h" +#include "dm_auth_state.h" + +namespace OHOS { +namespace DistributedHardware { +namespace { + +static const char* PICKER_PROXY_SPLIT = "_pickerProxy_"; +constexpr int32_t MIN_PIN_CODE = 100000; +constexpr int32_t MAX_PIN_CODE = 999999; + +constexpr int32_t PROCESS_NAME_WHITE_LIST_NUM = 1; +constexpr const static char* PROCESS_NAME_WHITE_LIST[PROCESS_NAME_WHITE_LIST_NUM] = { + "com.example.myapplication", +}; + +int32_t GetCloseSessionDelaySeconds(std::string &delaySecondsStr) +{ + if (!IsNumberString(delaySecondsStr)) { + LOGE("Invalid parameter, param is not number."); + return 0; + } + const int32_t closeSessionDelaySecondsMax = 10; + int32_t delaySeconds = std::atoi(delaySecondsStr.c_str()); + if (delaySeconds < 0 || delaySeconds > closeSessionDelaySecondsMax) { + LOGE("Invalid parameter, param out of range."); + return 0; + } + return delaySeconds; +} + +std::string GetBundleLable(const std::string &bundleName) +{ + auto samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); + if (samgr == nullptr) { + LOGE("Get ability manager failed"); + return bundleName; + } + + sptr object = samgr->GetSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID); + if (object == nullptr) { + LOGE("object is NULL."); + return bundleName; + } + + sptr bms = iface_cast(object); + if (bms == nullptr) { + LOGE("bundle manager service is NULL."); + return bundleName; + } + + auto bundleResourceProxy = bms->GetBundleResourceProxy(); + if (bundleResourceProxy == nullptr) { + LOGE("GetBundleResourceProxy fail"); + return bundleName; + } + AppExecFwk::BundleResourceInfo resourceInfo; + auto result = bundleResourceProxy->GetBundleResourceInfo(bundleName, + static_cast(OHOS::AppExecFwk::ResourceFlag::GET_RESOURCE_INFO_ALL), resourceInfo); + if (result != ERR_OK) { + LOGE("GetBundleResourceInfo failed"); + return bundleName; + } + LOGI("bundle resource label is %{public}s ", (resourceInfo.label).c_str()); + return resourceInfo.label; +} + +bool IsAllowDeviceBind(void) +{ + if (AppManager::GetInstance().IsSystemSA()) { + return true; + } + return false; +} + +int32_t CheckAuthParamVaildExtra(const std::string &extra) +{ + JsonObject jsonObject(extra); + if (jsonObject.IsDiscarded() || !jsonObject.Contains(TAG_BIND_LEVEL) || + !jsonObject[TAG_BIND_LEVEL].IsNumberInteger()) { + return DM_OK; + } + int32_t bindLevel = jsonObject[TAG_BIND_LEVEL].Get(); + if (static_cast(bindLevel) > APP || bindLevel < INVALID_TYPE) { + LOGE("bindlevel error %{public}d.", bindLevel); + return ERR_DM_INPUT_PARA_INVALID; + } + + if (static_cast(bindLevel) == DEVICE && !IsAllowDeviceBind()) { + LOGE("not allowd device level bind bindlevel: %{public}d.", bindLevel); + return ERR_DM_INPUT_PARA_INVALID; + } + return DM_OK; +} + +std::string ParseExtraFromMap(const std::map &bindParam) +{ + auto iter = bindParam.find(PARAM_KEY_BIND_EXTRA_DATA); + if (iter != bindParam.end()) { + return iter->second; + } + return ConvertMapToJsonString(bindParam); +} + +} // namespace + +bool AuthManager::IsHmlSessionType(std::string sessionType) +{ + return sessionType == CONN_SESSION_TYPE_HML; +} + +AuthManager::AuthManager(std::shared_ptr softbusConnector, + std::shared_ptr listener, + std::shared_ptr hiChainAuthConnector) +{ + LOGI("DmAuthManager constructor"); + context_ = std::make_shared(); + context_->softbusConnector = softbusConnector; + context_->listener = listener; + context_->hiChainAuthConnector = hiChainAuthConnector; + context_->authUiStateMgr = std::make_shared(context_->listener); + context_->authenticationMap[AUTH_TYPE_PIN] = nullptr; + context_->authenticationMap[AUTH_TYPE_IMPORT_AUTH_CODE] = nullptr; + context_->authenticationMap[AUTH_TYPE_PIN_ULTRASONIC] = nullptr; + context_->authenticationMap[AUTH_TYPE_NFC] = nullptr; + context_->accesser.dmVersion = DM_VERSION_5_1_0; + context_->accessee.dmVersion = DM_VERSION_5_1_0; + context_->timer = std::make_shared(); + context_->authMessageProcessor = std::make_shared(); +} + +AuthManager::~AuthManager() +{ + if (context_ != nullptr) { + context_->softbusConnector = nullptr; + context_->listener = nullptr; + context_->hiChainAuthConnector = nullptr; + context_->authUiStateMgr = nullptr; + context_->authenticationMap[AUTH_TYPE_PIN] = nullptr; + context_->authenticationMap[AUTH_TYPE_IMPORT_AUTH_CODE] = nullptr; + context_->authenticationMap[AUTH_TYPE_PIN_ULTRASONIC] = nullptr; + context_->timer = nullptr; + context_->authMessageProcessor = nullptr; + context_->authStateMachine = nullptr; + context_ = nullptr; + } + bindParam_.clear(); +} + +void AuthManager::RegisterCleanNotifyCallback(CleanNotifyCallback cleanNotifyCallback) +{ + context_->cleanNotifyCallback = cleanNotifyCallback; + return; +} + +bool AuthManager::IsAuthManagerConstructSuccess() +{ + return context_ != nullptr && + context_->softbusConnector != nullptr && + context_->listener != nullptr && + context_->hiChainAuthConnector != nullptr && + context_->authUiStateMgr != nullptr && + context_->timer != nullptr && + context_->authMessageProcessor != nullptr && + context_->authStateMachine != nullptr; +} + +void AuthManager::SetAuthContext(std::shared_ptr context) +{ + this->context_ = context; +} + +std::shared_ptr AuthManager::GetAuthContext() +{ + return this->context_; +} + +int32_t AuthManager::ParseAuthType(const std::map &bindParam, int32_t &authType) +{ + auto iter = bindParam.find(PARAM_KEY_AUTH_TYPE); + if (iter == bindParam.end()) { + LOGE("AuthManager::ParseAuthType bind param key: %{public}s not exist.", PARAM_KEY_AUTH_TYPE); + return ERR_DM_INPUT_PARA_INVALID; + } + std::string authTypeStr = iter->second; + if (authTypeStr.empty()) { + LOGE("AuthManager::ParseAuthType bind param %{public}s is empty.", PARAM_KEY_AUTH_TYPE); + return ERR_DM_INPUT_PARA_INVALID; + } + if (authTypeStr.length() > 1) { + LOGE("AuthManager::ParseAuthType bind param %{public}s length is unsupported.", PARAM_KEY_AUTH_TYPE); + return ERR_DM_INPUT_PARA_INVALID; + } + if (!isdigit(authTypeStr[0])) { + LOGE("AuthManager::ParseAuthType bind param %{public}s fromat is unsupported.", PARAM_KEY_AUTH_TYPE); + return ERR_DM_INPUT_PARA_INVALID; + } + authType = std::atoi(authTypeStr.c_str()); + return DM_OK; +} + +int32_t AuthManager::GeneratePincode() +{ + LOGI("AuthManager::GeneratePincode start"); + context_->pinCode = GenRandInt(MIN_PIN_CODE, MAX_PIN_CODE); + return context_->pinCode; +} + +int32_t AuthManager::RegisterUiStateCallback(const std::string sessionName) +{ + LOGI("AuthManager::RegisterUiStateCallback start"); + if (context_->authUiStateMgr == nullptr) { + LOGE("AuthManager::RegisterUiStateCallback context_->authUiStateMgr is null."); + return ERR_DM_FAILED; + } + context_->authUiStateMgr->RegisterUiStateCallback(sessionName); + return DM_OK; +} + +int32_t AuthManager::UnRegisterUiStateCallback(const std::string sessionName) +{ + LOGI("AuthManager::UnRegisterUiStateCallback start"); + if (context_->authUiStateMgr == nullptr) { + LOGE("AuthManager::UnRegisterUiStateCallback context_->authUiStateMgr is null."); + return ERR_DM_FAILED; + } + context_->authUiStateMgr->UnRegisterUiStateCallback(sessionName); + return DM_OK; +} + +int32_t AuthManager::UnAuthenticateDevice(const std::string &sessionName, const std::string &udid, int32_t bindLevel) +{ + LOGI("AuthManager::UnAuthenticateDevice start"); + return ERR_DM_FAILED; +} + +int32_t AuthManager::ImportAuthCode(const std::string &sessionName, const std::string &authCode) +{ + if (authCode.empty() || sessionName.empty()) { + LOGE("ImportAuthCode failed, authCode or sessionName is empty"); + return ERR_DM_INPUT_PARA_INVALID; + } + context_->importAuthCode = authCode; + context_->importSessionName = sessionName; + + if (AuthSinkStatePinAuthComm::IsPinCodeValid(authCode)) { + context_->pinCode = std::stoi(authCode.c_str()); + } else { + AuthSinkStatePinAuthComm::GeneratePincode(context_); + } + LOGI("AuthManager::ImportAuthCode ok"); + return DM_OK; +} + +int32_t AuthManager::UnBindDevice(const std::string &sessionName, const std::string &udid, + int32_t bindLevel, const std::string &extra) +{ + LOGI("AuthManager::UnBindDevice start"); + return ERR_DM_FAILED; +} +int32_t AuthManager::StopAuthenticateDevice(const std::string &sessionName) +{ + (void)sessionName; + LOGI("AuthManager::StopAuthenticateDevice start"); + + context_->reason = STOP_BIND; + if (context_->direction == DM_AUTH_SOURCE) { + context_->authStateMachine->TransitionTo(std::make_shared()); + } else { + context_->authStateMachine->TransitionTo(std::make_shared()); + } + return DM_OK; +} + +void AuthManager::OnScreenLocked() +{ + LOGI("AuthManager::OnScreenLocked start"); + if (DmAuthState::IsImportAuthCodeCompatibility(context_->authType)) { + LOGI("OnScreenLocked authtype is: %{public}d, no need stop bind.", context_->authType); + return; + } + context_->reason = ERR_DM_BIND_USER_CANCEL; + context_->authStateMachine->NotifyEventFinish(DmEventType::ON_FAIL); +} +void AuthManager::HandleDeviceNotTrust(const std::string &udid) +{ + LOGI("AuthManager::HandleDeviceNotTrust start"); +} + +int32_t AuthManager::RegisterAuthenticationType(int32_t authenticationType) +{ + if (authenticationType != USER_OPERATION_TYPE_ALLOW_AUTH && + authenticationType != USER_OPERATION_TYPE_ALLOW_AUTH_ALWAYS) { + LOGE("Invalid parameter."); + return ERR_DM_INPUT_PARA_INVALID; + } + context_->authResult = static_cast(authenticationType); + return DM_OK; +} + +// Extract the local ACL for message parsing and bus usage. +// Without ACL, an empty string will be returned. +// JSON format string: {dmversion:x,accesser:[{accesserDeviceId:y,...},...],accessee:{...}} +int32_t AuthManager::GetAclListStr(std::string &aclList) +{ + return context_->authMessageProcessor->GetAclListStr(context_, aclList); +} + +int32_t AuthManager::GetReason() +{ + return context_->reason; +} + +// 保存秘钥 +void AuthSrcManager::AuthDeviceSessionKey(int64_t requestId, const uint8_t *sessionKey, uint32_t sessionKeyLen) +{ + LOGI("AuthSrcManager::AuthDeviceSessionKey start. keyLen: %{public}u", sessionKeyLen); + if (context_ == nullptr || context_->authMessageProcessor == nullptr || context_->authStateMachine == nullptr) { + LOGE("AuthSrcManager::AuthDeviceSessionKey failed, auth context not initial."); + return; + } + if (requestId != context_->requestId) { + LOGE("AuthSrcManager::onTransmit requestId %{public}" PRId64 "is error.", requestId); + return; + } + int32_t ret = context_->authMessageProcessor->SaveSessionKey(sessionKey, sessionKeyLen); + if (ret != DM_OK) { + LOGE("AuthSrcManager::AuthDeviceSessionKey, save session key error, ret: %{public}d", ret); + } + + // 通知ON_SESSION_KEY_RETURNED事件完成 + context_->authStateMachine->NotifyEventFinish(ON_SESSION_KEY_RETURNED); + LOGI("AuthSrcManager::AuthDeviceSessionKey leave."); +} + +char *AuthSrcManager::AuthDeviceRequest(int64_t requestId, int operationCode, const char *reqParams) +{ + LOGI("AuthSrcManager::AuthDeviceRequest start"); + return nullptr; +} + +void AuthManager::SetAuthType(int32_t authType) +{ + context_->authType = (DmAuthType)authType; +} + +bool AuthManager::IsAuthTypeSupported(const int32_t &authType) +{ + if (context_->authenticationMap.find(authType) == context_->authenticationMap.end()) { + LOGE("IsAuthTypeSupported failed, authType is not supported."); + return false; + } + return true; +} + +bool AuthManager::IsAuthCodeReady(const std::string &sessionName) +{ + if (context_->importAuthCode.empty() || context_->importSessionName.empty()) { + LOGE("AuthManager::IsAuthCodeReady, auth code not ready with authCode %{public}s and sessionName %{public}s.", + context_->importAuthCode.c_str(), context_->importSessionName.c_str()); + return false; + } + if (sessionName != context_->importSessionName) { + LOGE("AuthManager::IsAuthCodeReady sessionName %{public}s not supported with import sessionName %{public}s.", + sessionName.c_str(), context_->importSessionName.c_str()); + return false; + } + return true; +} + +int32_t AuthManager::CheckAuthParamVaild(const std::string &sessionName, int32_t authType, + const std::string &deviceId, const std::string &extra) +{ + LOGI("AuthManager::CheckAuthParamVaild start."); + if (authType < DM_AUTH_TYPE_MIN || authType > DM_AUTH_TYPE_MAX) { + LOGE("CheckAuthParamVaild failed, authType is illegal."); + return ERR_DM_AUTH_FAILED; + } + if (sessionName.empty() || deviceId.empty()) { + LOGE("AuthManager::CheckAuthParamVaild failed, sessionName is %{public}s, deviceId is %{public}s, extra is" + "%{public}s.", sessionName.c_str(), GetAnonyString(deviceId).c_str(), extra.c_str()); + return ERR_DM_INPUT_PARA_INVALID; + } + if (context_->listener == nullptr || context_->authUiStateMgr == nullptr) { + LOGE("AuthManager::CheckAuthParamVaild listener or authUiStateMgr is nullptr."); + return ERR_DM_INPUT_PARA_INVALID; + } + + if (!IsAuthTypeSupported(authType)) { + LOGE("AuthManager::CheckAuthParamVaild authType %{public}d not support.", authType); + context_->listener->OnAuthResult(context_->processInfo, context_->peerTargetId.deviceId, "", + STATUS_DM_AUTH_DEFAULT, + ERR_DM_UNSUPPORTED_AUTH_TYPE); + context_->listener->OnBindResult(context_->processInfo, context_->peerTargetId, + ERR_DM_UNSUPPORTED_AUTH_TYPE, STATUS_DM_AUTH_DEFAULT, ""); + return ERR_DM_UNSUPPORTED_AUTH_TYPE; + } + + if (!context_->softbusConnector->HaveDeviceInMap(deviceId)) { + LOGE("CheckAuthParamVaild failed, the discoveryDeviceInfoMap_ not have this device."); + context_->listener->OnAuthResult(context_->processInfo, context_->peerTargetId.deviceId, "", + STATUS_DM_AUTH_DEFAULT, ERR_DM_INPUT_PARA_INVALID); + context_->listener->OnBindResult(context_->processInfo, context_->peerTargetId, + ERR_DM_INPUT_PARA_INVALID, STATUS_DM_AUTH_DEFAULT, ""); + return ERR_DM_INPUT_PARA_INVALID; + } + + if (DmAuthState::IsImportAuthCodeCompatibility(static_cast(authType)) && + (!IsAuthCodeReady(sessionName))) { + LOGE("Auth code not exist."); + context_->listener->OnAuthResult(context_->processInfo, context_->peerTargetId.deviceId, "", + STATUS_DM_AUTH_DEFAULT, ERR_DM_INPUT_PARA_INVALID); + context_->listener->OnBindResult(context_->processInfo, context_->peerTargetId, + ERR_DM_INPUT_PARA_INVALID, STATUS_DM_AUTH_DEFAULT, ""); + return ERR_DM_INPUT_PARA_INVALID; + } + return DM_OK; +} + +void AuthManager::ParseHmlInfoInJsonObject(const JsonObject &jsonObject) +{ + if (jsonObject[PARAM_KEY_CONN_SESSIONTYPE].IsString()) { + context_->connSessionType = jsonObject[PARAM_KEY_CONN_SESSIONTYPE].Get(); + LOGI("connSessionType %{public}s", context_->connSessionType.c_str()); + } + if (!IsHmlSessionType(context_->connSessionType)) { + return; + } + context_->connDelayCloseTime = HML_SESSION_TIMEOUT; + if (jsonObject[PARAM_KEY_HML_ENABLE_160M].IsBoolean()) { + context_->hmlEnable160M = jsonObject[PARAM_KEY_HML_ENABLE_160M].Get(); + LOGI("hmlEnable160M %{public}d", context_->hmlEnable160M); + } + if (jsonObject[PARAM_KEY_HML_ACTIONID].IsString()) { + std::string actionIdStr = jsonObject[PARAM_KEY_HML_ACTIONID].Get(); + if (IsNumberString(actionIdStr)) { + context_->hmlActionId = std::atoi(actionIdStr.c_str()); + } + if (context_->hmlActionId <= 0) { + context_->hmlActionId = 0; + } + LOGI("hmlActionId %{public}d", context_->hmlActionId); + } + + return; +} + +std::string AuthManager::GetBundleName(const JsonObject &jsonObject) +{ + if (!jsonObject.IsDiscarded() && jsonObject[BUNDLE_NAME_KEY].IsString()) { + return jsonObject[BUNDLE_NAME_KEY].Get(); + } + bool isSystemSA = false; + std::string bundleName; + AppManager::GetInstance().GetCallerName(isSystemSA, bundleName); + return bundleName; +} + +void AuthManager::ParseJsonObject(const JsonObject &jsonObject) +{ + if (jsonObject.IsDiscarded()) { + return; + } + + // 填充context_ + if (jsonObject[APP_OPERATION_KEY].IsString()) { + context_->appOperation = jsonObject[APP_OPERATION_KEY].Get(); + } + if (jsonObject[CUSTOM_DESCRIPTION_KEY].IsString()) { + context_->customData = jsonObject[CUSTOM_DESCRIPTION_KEY].Get(); + } + if (jsonObject[TAG_APP_THUMBNAIL2].IsString()) { + context_->appThumbnail = jsonObject[TAG_APP_THUMBNAIL2].Get(); + } + context_->connDelayCloseTime = 0; + if (jsonObject[PARAM_CLOSE_SESSION_DELAY_SECONDS].IsString()) { + std::string delaySecondsStr = jsonObject[PARAM_CLOSE_SESSION_DELAY_SECONDS].Get(); + context_->connDelayCloseTime = GetCloseSessionDelaySeconds(delaySecondsStr); + } + + // 填充context_->accesser + context_->accesser.bundleName = GetBundleName(jsonObject); + + context_->accessee.bundleName = context_->accesser.bundleName; + // 填充context_accessee + if (jsonObject[TAG_PEER_BUNDLE_NAME].IsString()) { + context_->accessee.bundleName = jsonObject[TAG_PEER_BUNDLE_NAME].Get(); + } + if (jsonObject[TAG_PEER_DISPLAY_ID].IsNumberInteger()) { + context_->accessee.displayId = jsonObject[TAG_PEER_DISPLAY_ID].Get(); + } + return; +} + +bool AuthManager::CheckProcessNameInWhiteList(const std::string &processName) +{ + LOGI("DmAuthManager::CheckProcessNameInWhiteList start"); + if (processName.empty()) { + LOGE("processName is empty"); + return false; + } + uint16_t index = 0; + for (; index < PROCESS_NAME_WHITE_LIST_NUM; ++index) { + std::string whitePkgName(PROCESS_NAME_WHITE_LIST[index]); + if (processName == whitePkgName) { + LOGI("processName = %{public}s in whiteList.", processName.c_str()); + return true; + } + } + LOGI("CheckProcessNameInWhiteList: %{public}s invalid.", processName.c_str()); + return false; +} + +int32_t AuthManager::GetTokenIdByBundleName(int32_t userId, std::string &bundleName, int64_t &tokenId) +{ + int32_t ret = AppManager::GetInstance().GetNativeTokenIdByName(bundleName, tokenId); + if (ret == DM_OK) { + return DM_OK; + } + ret = AppManager::GetInstance().GetHapTokenIdByName(userId, bundleName, 0, tokenId); + if (ret != DM_OK) { + LOGE("get tokenId by bundleName failed %{public}s", GetAnonyString(bundleName).c_str()); + } + return ret; +} + +void AuthManager::GetAuthIds(std::string realPkgName, const std::string &sessionName, const JsonObject &jsonObject) +{ + // Get deviceId + char localDeviceId[DEVICE_UUID_LENGTH] = {0}; + GetDevUdid(localDeviceId, DEVICE_UUID_LENGTH); + std::string localUdid = std::string(localDeviceId); + context_->accesser.deviceId = localUdid; + + // Get userId and tokenId + uint32_t tokenId = 0; + MultipleUserConnector::GetTokenIdAndForegroundUserId(tokenId, context_->accesser.userId); + if (!jsonObject.IsDiscarded() && jsonObject[TAG_LOCAL_USERID].IsNumberInteger()) { + context_->accesser.userId = jsonObject[TAG_LOCAL_USERID].Get(); + } + context_->accesser.tokenId = static_cast(tokenId); + if (realPkgName != sessionName) { + int64_t tmpTokenId = 0; + GetTokenIdByBundleName(context_->accesser.userId, realPkgName, tmpTokenId); + context_->accesser.tokenId = static_cast(tmpTokenId); + } + + // Get accountId + context_->accesser.accountId = MultipleUserConnector::GetOhosAccountIdByUserId(context_->accesser.userId); + + return; +} + +void AuthManager::GetAuthParam(const std::string &sessionName, int32_t authType, + const std::string &deviceId, const std::string &extra) +{ + LOGI("Get auth param with sessionName %{public}s and extra %{public}s.", sessionName.c_str(), extra.c_str()); + + std::string realPkgName = GetSubStr(sessionName, PICKER_PROXY_SPLIT, 1); + realPkgName = realPkgName.empty() ? sessionName : realPkgName; + context_->sessionName = sessionName; + context_->pkgLabel = GetBundleLable(sessionName); + context_->authType = (DmAuthType)authType; + context_->accesser.deviceName = context_->softbusConnector->GetLocalDeviceName(); + context_->accesser.deviceType = context_->softbusConnector->GetLocalDeviceTypeId(); + context_->accesser.isOnline = false; + + context_->accessee.deviceId = deviceId; + context_->accessee.addr = deviceId; + JsonObject jsonObject(extra); + if (jsonObject.IsDiscarded()) { + LOGE("extra string not a json type."); + return; + } + ParseJsonObject(jsonObject); + + GetAuthIds(realPkgName, sessionName, jsonObject); + context_->accesser.token = std::to_string(GenRandInt(MIN_PIN_TOKEN, MAX_PIN_TOKEN)); +} + +void AuthManager::InitAuthState(const std::string &sessionName, int32_t authType, + const std::string &deviceId, const std::string &extra) +{ + auto iter = context_->authenticationMap.find(authType); + if (iter != context_->authenticationMap.end()) { + context_->authPtr = iter->second; + } + + context_->timer->StartTimer(std::string(AUTHENTICATE_TIMEOUT_TASK), + DmAuthState::GetTaskTimeout(context_, AUTHENTICATE_TIMEOUT_TASK, AUTHENTICATE_TIMEOUT), + [this] (std::string name) { + DmAuthState::HandleAuthenticateTimeout(context_, name); + }); + GetAuthParam(sessionName, authType, deviceId, extra); + context_->authStateMachine->TransitionTo(std::make_shared()); + LOGI("AuthManager::AuthenticateDevice complete"); + + return; +} + +int32_t AuthManager::AuthenticateDevice(const std::string &sessionName, int32_t authType, + const std::string &deviceId, const std::string &extra) +{ + LOGI("AuthManager::AuthenticateDevice start auth type %{public}d.", authType); + SetAuthType(authType); + int32_t userId = -1; + MultipleUserConnector::GetCallerUserId(userId); + context_->processInfo.pkgName = sessionName; + context_->processInfo.userId = userId; + int32_t ret = CheckAuthParamVaild(sessionName, authType, deviceId, extra); + if (ret != DM_OK) { + LOGE("AuthManager::AuthenticateDevice failed, param is invaild."); + return ret; + } + ret = CheckAuthParamVaildExtra(extra); + if (ret != DM_OK) { + LOGE("CheckAuthParamVaildExtra failed, param is invaild."); + return ret; + } + context_->isAuthenticateDevice = true; + InitAuthState(sessionName, authType, deviceId, extra); + return DM_OK; +} + +int32_t AuthManager::BindTarget(const std::string &sessionName, const PeerTargetId &targetId, + const std::map &bindParam, int sessionId, int64_t logicalSessionId) +{ + int ret = DM_OK; + LOGI("AuthManager::BindTarget start. sessionName: %{public}s", sessionName.c_str()); + for (auto iter = bindParam.begin(); iter != bindParam.end(); iter++) { + LOGI("AuthManager::BindTarget para: %{public}s : %{public}s ", iter->first.c_str(), iter->second.c_str()); + } + + struct RadarInfo info = { + .funcName = "AuthenticateDevice", + .stageRes = static_cast(StageRes::STAGE_SUCC), + .bizState = static_cast(BizState::BIZ_STATE_END), + }; + if (!DmRadarHelper::GetInstance().ReportDiscoverUserRes(info)) { + LOGE("ReportDiscoverUserRes failed"); + } + if (sessionName.empty()) { + LOGE("AuthManager::BindTarget failed, sessionName is empty."); + return ERR_DM_INPUT_PARA_INVALID; + } + int32_t authType = -1; + if (ParseAuthType(bindParam, authType) != DM_OK) { + LOGE("AuthManager::BindTarget failed, key: %{public}s error.", PARAM_KEY_AUTH_TYPE); + return ERR_DM_INPUT_PARA_INVALID; + } + context_->peerTargetId = targetId; + bindParam_ = bindParam; + if (!targetId.deviceId.empty()) { + ret = AuthenticateDevice(sessionName, authType, targetId.deviceId, ParseExtraFromMap(bindParam)); + if (ret != DM_OK) { + return ret; + } + } else { + LOGE("AuthManager::BindTarget failed, targetId is error."); + return ERR_DM_INPUT_PARA_INVALID; + } + + if (context_->authMessageProcessor == nullptr) { + LOGE("AuthSrcManager::OnSessionOpened but request state is wrong"); + return ERR_DM_AUTH_FAILED; + } + + context_->sessionId = sessionId; + context_->logicalSessionId = logicalSessionId; + context_->requestId = logicalSessionId; + context_->authStateMachine->TransitionTo(std::make_shared()); + info = { .funcName = "BindTarget" }; + info.channelId = sessionId; + DmRadarHelper::GetInstance().ReportAuthSendRequest(info); + return ret; +} + +AuthSinkManager::AuthSinkManager(std::shared_ptr softbusConnector, + std::shared_ptr listener, + std::shared_ptr hiChainAuthConnector) + : AuthManager(softbusConnector, listener, hiChainAuthConnector) +{ + context_->direction = DM_AUTH_SINK; + context_->authStateMachine = std::make_shared(context_); +} + +void AuthSinkManager::OnSessionOpened(int32_t sessionId, int32_t sessionSide, int32_t result) +{ + LOGI("sessionId = %{public}d and sessionSide = %{public}d result = %{public}d", sessionId, sessionSide, result); +} + +void AuthSinkManager::OnSessionClosed(int32_t sessionId) +{ + LOGI("AuthSrcManager::OnSessionClosed sessionId = %{public}d", sessionId); +} + +void AuthSinkManager::OnDataReceived(int32_t sessionId, std::string message) +{ + if (context_->authMessageProcessor == nullptr) { + LOGE("OnDataReceived failed, authMessageProcessor is nullptr."); + return; + } + + context_->sessionId = sessionId; + int32_t ret = context_->authMessageProcessor->ParseMessage(context_, message); + if (ret != DM_OK) { + LOGE("OnDataReceived failed, parse input message error."); + } + + return; +} + +bool AuthSinkManager::GetIsCryptoSupport() +{ + return false; +} + +void AuthSinkManager::OnAuthDeviceDataReceived(int32_t sessionId, std::string message) +{ + if (context_->hiChainAuthConnector == nullptr) { + LOGE("OnAuthDeviceDataReceived param is invalid"); + return; + } + + if (context_->sessionId != sessionId) { + LOGE("OnAuthDeviceDataReceived unmatched sessionId"); + return; + } + + JsonObject jsonObject(message); + if (jsonObject.IsDiscarded()) { + LOGE("DecodeRequestAuth jsonStr error"); + return; + } + if (!jsonObject[TAG_DATA].IsString() || !jsonObject[TAG_DATA_LEN].IsNumberInteger() || + !jsonObject[TAG_MSG_TYPE].IsNumberInteger()) { + LOGE("Auth device data is error."); + return; + } + LOGI("OnAuthDeviceDataReceived start msgType %{public}d.", jsonObject[TAG_MSG_TYPE].Get()); + std::string authData = jsonObject[TAG_DATA].Get(); + int32_t osAccountId = MultipleUserConnector::GetCurrentAccountUserID(); + context_->hiChainAuthConnector->ProcessAuthData(context_->requestId, authData, osAccountId); + + return; +} + +void AuthManager::GetRemoteDeviceId(std::string &deviceId) +{ + deviceId = (context_->direction == DM_AUTH_SOURCE) ? context_->accessee.deviceId : context_->accesser.deviceId; + return; +} +int32_t AuthSinkManager::OnUserOperation(int32_t action, const std::string ¶ms) +{ + LOGI("AuthSinkManager::OnUserOperation start."); + if (context_ == nullptr || context_->authStateMachine == nullptr) { + LOGE("OnUserOperation: Authenticate is not start"); + return ERR_DM_AUTH_NOT_START; + } + + switch (action) { + case USER_OPERATION_TYPE_CANCEL_AUTH: + case USER_OPERATION_TYPE_ALLOW_AUTH: + case USER_OPERATION_TYPE_ALLOW_AUTH_ALWAYS: + context_->authResult = static_cast(action); + context_->reply = USER_OPERATION_TYPE_ALLOW_AUTH; + if (action == USER_OPERATION_TYPE_CANCEL_AUTH) { + LOGI("AuthSinkManager::OnUserOperation USER_OPERATION_TYPE_CANCEL_AUTH."); + context_->reply = USER_OPERATION_TYPE_CANCEL_AUTH; + } + context_->authStateMachine->NotifyEventFinish(DmEventType::ON_USER_OPERATION); + break; + case USER_OPERATION_TYPE_AUTH_CONFIRM_TIMEOUT: + LOGI("AuthSinkManager::OnUserOperation USER_OPERATION_TYPE_AUTH_CONFIRM_TIMEOUT."); + context_->authResult = USER_OPERATION_TYPE_AUTH_CONFIRM_TIMEOUT; + context_->reason = ERR_DM_TIME_OUT; + context_->authStateMachine->NotifyEventFinish(DmEventType::ON_FAIL); + break; + case USER_OPERATION_TYPE_CANCEL_PINCODE_DISPLAY: + LOGI("AuthSinkManager::OnUserOperation USER_OPERATION_TYPE_CANCEL_PINCODE_DISPLAY."); + context_->authResult = USER_OPERATION_TYPE_CANCEL_PINCODE_DISPLAY; + context_->reason = ERR_DM_BIND_USER_CANCEL_PIN_CODE_DISPLAY; + context_->authStateMachine->NotifyEventFinish(DmEventType::ON_FAIL); + break; + default: + LOGE("this action id not support"); + break; + } + LOGI("AuthSinkManager::OnUserOperation leave."); + return DM_OK; +} + +AuthSrcManager::AuthSrcManager(std::shared_ptr softbusConnector, + std::shared_ptr listener, + std::shared_ptr hiChainAuthConnector) + : AuthManager(softbusConnector, listener, hiChainAuthConnector) +{ + context_->direction = DM_AUTH_SOURCE; + context_->authStateMachine = std::make_shared(context_); +} + +void AuthSrcManager::OnSessionOpened(int32_t sessionId, int32_t sessionSide, int32_t result) +{ + LOGI("sessionId = %{public}d and sessionSide = %{public}d result = %{public}d", sessionId, sessionSide, result); +} + +void AuthSrcManager::OnSessionClosed(int32_t sessionId) +{ + LOGI("AuthSrcManager::OnSessionClosed sessionId = %{public}d", sessionId); +} +void AuthSrcManager::OnDataReceived(int32_t sessionId, std::string message) +{ + if (context_->authMessageProcessor == nullptr) { + LOGE("OnDataReceived failed, authMessageProcessor is nullptr."); + return; + } + + context_->sessionId = sessionId; + int32_t ret = context_->authMessageProcessor->ParseMessage(context_, message); + if (ret != DM_OK) { + LOGE("OnDataReceived failed, parse input message error."); + } + + return; +} +bool AuthSrcManager::GetIsCryptoSupport() +{ + return false; +} +void AuthSrcManager::OnAuthDeviceDataReceived(int32_t sessionId, std::string message) +{ + if (context_->hiChainAuthConnector == nullptr) { + LOGE("OnAuthDeviceDataReceived param is invalid"); + return; + } + + if (context_->sessionId != sessionId) { + LOGE("OnAuthDeviceDataReceived unmatched sessionId"); + return; + } + + JsonObject jsonObject(message); + if (jsonObject.IsDiscarded()) { + LOGE("DecodeRequestAuth jsonStr error"); + return; + } + if (!jsonObject[TAG_DATA].IsNumberInteger() || !jsonObject[TAG_DATA_LEN].IsNumberInteger() || + !jsonObject[TAG_MSG_TYPE].IsNumberInteger()) { + LOGE("Auth device data is error."); + return; + } + LOGI("OnAuthDeviceDataReceived start msgType %{public}d.", jsonObject[TAG_MSG_TYPE].Get()); + std::string authData = jsonObject[TAG_DATA].Get(); + int32_t osAccountId = MultipleUserConnector::GetCurrentAccountUserID(); + context_->hiChainAuthConnector->ProcessAuthData(context_->requestId, authData, osAccountId); + + return; +} + +int32_t AuthSrcManager::OnUserOperation(int32_t action, const std::string ¶ms) +{ + LOGI("AuthSrcManager::OnUserOperation start."); + if (context_ == nullptr || context_->authStateMachine == nullptr) { + LOGE("OnUserOperation: Authenticate is not start"); + return ERR_DM_AUTH_NOT_START; + } + + switch (action) { + case USER_OPERATION_TYPE_CANCEL_PINCODE_INPUT: + LOGE("AuthSrcManager OnUserOperation user cancel"); + context_->pinInputResult = USER_OPERATION_TYPE_CANCEL_PINCODE_INPUT; + context_->reason = ERR_DM_BIND_USER_CANCEL_ERROR; + context_->authStateMachine->NotifyEventFinish(DmEventType::ON_FAIL); + break; + case USER_OPERATION_TYPE_DONE_PINCODE_INPUT: + LOGE("AuthSrcManager OnUserOperation user input done"); + context_->pinInputResult = USER_OPERATION_TYPE_DONE_PINCODE_INPUT; + { + JsonObject jsonObject(params); + if (jsonObject.IsDiscarded()) { + LOGE("OnUserOperation jsonStr error"); + return ERR_DM_INPUT_PARA_INVALID; + } + if (jsonObject[PIN_CODE_KEY].IsNumberInteger()) { + context_->pinCode = jsonObject[PIN_CODE_KEY].Get(); + } + } + context_->authStateMachine->NotifyEventFinish(DmEventType::ON_USER_OPERATION); + break; + default: + LOGE("this action id not support"); + break; + } + LOGI("AuthSrcManager::OnUserOperation leave."); + return DM_OK; +} + +void AuthSrcManager::AuthDeviceError(int64_t requestId, int32_t errorCode) +{ + LOGI("AuthSrcManager::AuthDeviceError start."); + auto curState = context_->authStateMachine->GetCurState(); + if (curState == DmAuthStateType::AUTH_SRC_PIN_AUTH_START_STATE || + curState == DmAuthStateType::AUTH_SRC_PIN_AUTH_MSG_NEGOTIATE_STATE || + curState == DmAuthStateType::AUTH_SRC_PIN_AUTH_DONE_STATE) { + LOGI("AuthSrcManager::AuthDeviceError Auth pin err."); + if (context_->authType == DmAuthType::AUTH_TYPE_PIN) { + context_->inputPinAuthFailTimes++; + } + context_->authStateMachine->NotifyEventFinish(DmEventType::ON_ERROR); + context_->authStateMachine->TransitionTo(std::make_shared()); + } else { + LOGI("AuthSrcManager::AuthDeviceError unexpected err."); + context_->reason = errorCode; + context_->authStateMachine->NotifyEventFinish(DmEventType::ON_FAIL); + } + LOGI("AuthSrcManager::AuthDeviceError leave."); +} + +void AuthSinkManager::AuthDeviceError(int64_t requestId, int32_t errorCode) +{ + LOGI("AuthSinkManager::AuthDeviceError start."); + auto curState = context_->authStateMachine->GetCurState(); + if (curState == DmAuthStateType::AUTH_SINK_PIN_AUTH_START_STATE || + curState == DmAuthStateType::AUTH_SINK_PIN_AUTH_MSG_NEGOTIATE_STATE) { + LOGI("AuthSrcManager::AuthDeviceError Auth pin err."); + if (context_->authType == DmAuthType::AUTH_TYPE_PIN) { + context_->inputPinAuthFailTimes++; + } + context_->authStateMachine->NotifyEventFinish(DmEventType::ON_ERROR); + context_->authStateMachine->TransitionTo(std::make_shared()); + } else { + LOGI("AuthSinkManager::AuthDeviceError unexpected err."); + context_->reason = errorCode; + context_->authStateMachine->NotifyEventFinish(DmEventType::ON_FAIL); + } + LOGI("AuthSinkManager::AuthDeviceError leave."); +} + +bool AuthSrcManager::AuthDeviceTransmit(int64_t requestId, const uint8_t *data, uint32_t dataLen) +{ + LOGI("AuthSrcManager::AuthDeviceTransmit start."); + // check request id first + if (requestId != context_->requestId) { + LOGE("AuthSrcManager::onTransmit requestId %{public}" PRId64"is error.", requestId); + return false; + } + + context_->transmitData = std::string(reinterpret_cast(data), dataLen); + context_->authStateMachine->NotifyEventFinish(ON_TRANSMIT); + LOGI("AuthSrcManager::AuthDeviceTransmit leave."); + return true; +} + +bool AuthSinkManager::AuthDeviceTransmit(int64_t requestId, const uint8_t *data, uint32_t dataLen) +{ + LOGI("AuthSinkManager::AuthDeviceTransmit start."); + // check request id first + if (requestId != context_->requestId) { + LOGE("AuthSinkManager::onTransmit requestId %{public}" PRId64"is error.", requestId); + return false; + } + + context_->transmitData = std::string(reinterpret_cast(data), dataLen); + context_->authStateMachine->NotifyEventFinish(ON_TRANSMIT); + LOGI("AuthSinkManager::AuthDeviceTransmit leave."); + return true; +} +void AuthSrcManager::AuthDeviceFinish(int64_t requestId) +{ + LOGI("AuthSrcManager::AuthDeviceFinish start."); + context_->authStateMachine->NotifyEventFinish(ON_FINISH); + // 根据当前状态进行业务处理 + DmAuthStateType curState = context_->authStateMachine->GetCurState(); + switch (curState) { + case DmAuthStateType::AUTH_SRC_PIN_AUTH_DONE_STATE: + // ON_FINISH事件到来,启动凭据交换 + context_->authStateMachine->TransitionTo(std::make_shared()); + break; + default: + break; + } + LOGI("AuthSrcManager::AuthDeviceFinish leave."); +} + +void AuthSinkManager::AuthDeviceFinish(int64_t requestId) +{ + LOGI("AuthSinkManager::AuthDeviceFinish start."); + context_->authStateMachine->NotifyEventFinish(ON_FINISH); + LOGI("AuthSinkManager::AuthDeviceFinish leave."); +} + +void AuthSinkManager::AuthDeviceSessionKey(int64_t requestId, const uint8_t *sessionKey, uint32_t sessionKeyLen) +{ + LOGI("AuthSrcManager::AuthDeviceSessionKey start. keyLen: %{public}u", sessionKeyLen); + if (context_ == nullptr || context_->authMessageProcessor == nullptr || context_->authStateMachine == nullptr) { + LOGE("AuthSrcManager::AuthDeviceSessionKey failed, auth context not initial."); + return; + } + if (requestId != context_->requestId) { + LOGE("AuthSrcManager::onTransmit requestId %{public}" PRId64 "is error.", requestId); + return; + } + int32_t ret = context_->authMessageProcessor->SaveSessionKey(sessionKey, sessionKeyLen); + if (ret != DM_OK) { + LOGE("AuthSrcManager::AuthDeviceSessionKey, save session key error, ret: %{public}d", ret); + } + + // 通知ON_SESSION_KEY_RETURNED事件完成 + context_->authStateMachine->NotifyEventFinish(ON_SESSION_KEY_RETURNED); +} + +char *AuthSinkManager::AuthDeviceRequest(int64_t requestId, int operationCode, const char *reqParams) +{ + LOGI("AuthSrcManager::AuthDeviceRequest start"); + (void)requestId; + (void)reqParams; + JsonObject jsonObj; + + DmAuthStateType curState = context_->authStateMachine->GetCurState(); + if (curState == DmAuthStateType::AUTH_SINK_PIN_AUTH_START_STATE) { + int32_t pinCode = INVALID_PINCODE; + if (GetPinCode(pinCode) == ERR_DM_FAILED || pinCode == INVALID_PINCODE) { + jsonObj[FIELD_CONFIRMATION] = RequestResponse::REQUEST_REJECTED; + } else { + jsonObj[FIELD_CONFIRMATION] = RequestResponse::REQUEST_ACCEPTED; + jsonObj[FIELD_PIN_CODE] = std::to_string(pinCode); + } + } else if (curState == DmAuthStateType::AUTH_SINK_CREDENTIAL_AUTH_START_STATE) { + if (context_->isOnline) { // 非首次认证 + jsonObj[FIELD_CONFIRMATION] = RequestResponse::REQUEST_ACCEPTED; + jsonObj[FIELD_CRED_ID] = context_->accessee.transmitCredentialId; + } else if (!context_->isAppCredentialVerified) { // 首次认证 && 应用凭据认证 + jsonObj[FIELD_CONFIRMATION] = RequestResponse::REQUEST_ACCEPTED; + jsonObj[FIELD_CRED_ID] = context_->accessee.transmitCredentialId; + } else { // 首次认证 && 用户凭据认证 + jsonObj[FIELD_CONFIRMATION] = RequestResponse::REQUEST_ACCEPTED; + jsonObj[FIELD_CRED_ID] = context_->accessee.lnnCredentialId; + } + } + jsonObj[FIELD_SERVICE_PKG_NAME] = std::string(DM_PKG_NAME); + std::string jsonStr = jsonObj.Dump(); + char *buffer = strdup(jsonStr.c_str()); + return buffer; +} + +int32_t AuthManager::GetPinCode(int32_t &code) +{ + if (context_ == nullptr) { + LOGE("AuthManager failed to GetPinCode because context_ is nullptr"); + return ERR_DM_FAILED; + } + LOGI("GetPinCode called."); + code = context_->pinCode; + return DM_OK; +} + +// 重新获取BindParams,以重建链路,一般用于新老协议对象切换 +void AuthManager::GetBindTargetParams(std::string &pkgName, PeerTargetId &targetId, + std::map &bindParam) +{ + pkgName = context_->sessionName; + targetId = context_->peerTargetId; + bindParam = bindParam_; + + LOGI("AuthManager::GetBindTargetParams get pkgName %{public}s to reuse", pkgName.c_str()); + return; +} + +} // namespace DistributedHardware +} // namespace OHOS \ No newline at end of file diff --git a/services/implementation/src/authentication_v2/auth_stages/auth_acl.cpp b/services/implementation/src/authentication_v2/auth_stages/auth_acl.cpp new file mode 100644 index 000000000..a46b14f71 --- /dev/null +++ b/services/implementation/src/authentication_v2/auth_stages/auth_acl.cpp @@ -0,0 +1,160 @@ +/* + * Copyright (c) 2025 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 "dm_auth_state.h" + +#include +#include + +#include "deviceprofile_connector.h" +#include "dm_auth_context.h" +#include "dm_auth_state_machine.h" +#include "dm_constants.h" +#include "auth_manager.h" +#include "multiple_user_connector.h" +#include "dm_crypto.h" +namespace OHOS { +namespace DistributedHardware { + +/* +数据同步,ACL老化与保存(180、190和200报文处理) +source端状态: +AuthSrcDataSyncState, // 收到190报文,发送200报文 +AuthSrcFinishState, // 收到201结束报文 + +sink端状态: +AuthSinkDataSyncState, // 收到180同步报文,发送190报文 +AuthSinkFinishState, // 收到200结束报文 发送201 + +*/ +const int32_t USLEEP_TIME_US_500000 = 500000; // 500ms +// 收到180同步报文,发送190报文 +int32_t AuthSinkDataSyncState::Action(std::shared_ptr context) +{ + LOGI("AuthSinkDataSyncState::Action start"); + // 判断密文阶段和明文阶段的四元组是否相同,两端的bindlevel是否相同,不同则直接结束 + if (!IsQuadrupleAndBindLevelSame(context)) { + LOGE("data between two stages different, stop auth"); + return DM_OK; + } + // 查询sink端acl + std::vector sinkAclList = GetAclList(context); + // 比较双端的acl + for (auto &sinkAcl : sinkAclList) { + bool res = context->authMessageProcessor->ChecksumAcl(sinkAcl, + context->accesser.accesserStrList, context->accesser.accesseeStrList); + if (res) { + continue; + } + SyncAclList(context, sinkAcl.GetAccessee().GetAccesseeCredentialId(), + sinkAcl.GetAccessee().GetAccesseeSessionKeyId(), sinkAcl.GetAccessControlId()); + } + // 同步本端的sp信息,不确定格式,暂不做 + + context->authMessageProcessor->CreateAndSendMsg(MSG_TYPE_RESP_DATA_SYNC, context); + LOGI("AuthSinkDataSyncState::Action ok"); + return DM_OK; +} + +DmAuthStateType AuthSinkDataSyncState::GetStateType() +{ + return DmAuthStateType::AUTH_SINK_DATA_SYNC_STATE; +} + +// 收到190报文,发送200报文 +int32_t AuthSrcDataSyncState::Action(std::shared_ptr context) +{ + LOGI("AuthSrcDataSyncState::Action start"); + + if (NeedAgreeAcl(context)) { + // 判断密文阶段和明文阶段的四元组是否相同,不同则直接结束 + if (!IsQuadrupleAndBindLevelSame(context)) { + LOGE("data between two stages different, stop auth"); + return DM_OK; + } + // 查询sink端acl + std::vector srcAclList = GetAclList(context); + // 比较双端的acl + for (auto &srcAcl : srcAclList) { + bool res = context->authMessageProcessor->ChecksumAcl(srcAcl, + context->accessee.accesserStrList, context->accessee.accesseeStrList); + if (res) { + continue; + } + SyncAclList(context, srcAcl.GetAccesser().GetAccesserCredentialId(), + srcAcl.GetAccesser().GetAccesserSessionKeyId(), srcAcl.GetAccessControlId()); + } + // 保存本次acl + context->authMessageProcessor->PutAccessControlList(context, context->accesser, context->accessee.deviceId); + // 同步本端的sp信息,不确定格式,暂不做 + } + + // 触发组网 + if (!context->accesser.isOnline) { + char udidHashTmp[DM_MAX_DEVICE_ID_LEN] = {0}; + if (Crypto::GetUdidHash(context->accessee.deviceId, reinterpret_cast(udidHashTmp)) != DM_OK) { + LOGE("AuthSrcDataSyncState joinLnn get udidhash by udid: %{public}s failed", + context->accessee.deviceId.c_str()); + return ERR_DM_FAILED; + } + std::string peerUdidHash = std::string(udidHashTmp); + context->softbusConnector->JoinLNNBySkId(context->sessionId, context->accesser.transmitSessionKeyId, + context->accessee.transmitSessionKeyId, context->accessee.addr, peerUdidHash); + } + context->reason = DM_OK; + context->reply = DM_OK; + context->state = static_cast(GetStateType()); + context->authMessageProcessor->CreateAndSendMsg(MSG_TYPE_AUTH_REQ_FINISH, context); + LOGI("AuthSrcDataSyncState::Action ok"); + return DM_OK; +} + +DmAuthStateType AuthSrcDataSyncState::GetStateType() +{ + return DmAuthStateType::AUTH_SRC_DATA_SYNC_STATE; +} + +// 收到200结束报文 发送201 +int32_t AuthSinkFinishState::Action(std::shared_ptr context) +{ + LOGI("AuthSinkFinishState::Action start"); + context->state = static_cast(GetStateType()); + SinkFinish(context); + LOGI("AuthSinkFinishState::Action ok"); + context->cleanNotifyCallback(context->logicalSessionId); + return DM_OK; +} + +DmAuthStateType AuthSinkFinishState::GetStateType() +{ + return DmAuthStateType::AUTH_SINK_FINISH_STATE; +} + +// 收到201结束报文 +int32_t AuthSrcFinishState::Action(std::shared_ptr context) +{ + LOGI("AuthSrcFinishState::Action start"); + SourceFinish(context); + LOGI("AuthSrcFinishState::Action ok"); + context->cleanNotifyCallback(context->logicalSessionId); + return DM_OK; +} + +DmAuthStateType AuthSrcFinishState::GetStateType() +{ + return DmAuthStateType::AUTH_SRC_FINISH_STATE; +} +} // namespace DistributedHardware +} // namespace OHOS \ No newline at end of file diff --git a/services/implementation/src/authentication_v2/auth_stages/auth_confirm.cpp b/services/implementation/src/authentication_v2/auth_stages/auth_confirm.cpp new file mode 100644 index 000000000..78cbb8e17 --- /dev/null +++ b/services/implementation/src/authentication_v2/auth_stages/auth_confirm.cpp @@ -0,0 +1,349 @@ +/* + * Copyright (c) 2025 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 "auth_manager.h" +#include "access_control_profile.h" +#include "deviceprofile_connector.h" +#include "distributed_device_profile_errors.h" +#include "dm_anonymous.h" +#include "dm_auth_context.h" +#include "dm_auth_state.h" +#include "dm_auth_state_machine.h" +#include "dm_dialog_manager.h" +#include "dm_log.h" + +namespace OHOS { +namespace DistributedHardware { + +constexpr const char* TAG_CRED_ID = "credId"; +constexpr const char* TAG_CUSTOM_DESCRIPTION = "CUSTOMDESC"; +constexpr const char* TAG_LOCAL_DEVICE_TYPE = "LOCALDEVICETYPE"; +constexpr const char* TAG_REQUESTER = "REQUESTER"; +constexpr const char* TAG_HOST_PKGLABEL = "hostPkgLabel"; + +// authType fallback table +using FallBackKey = std::pair; // accessee.bundleName, authType +static std::map g_pinAuthTypeFallBackMap = { + {{"CastEngineService", DmAuthType::AUTH_TYPE_NFC}, DmAuthType::AUTH_TYPE_PIN}, +}; +// Maximum number of recursive lookups +constexpr size_t MAX_FALLBACK_LOOPKUP_TIMES = 2; + +DmAuthStateType AuthSrcConfirmState::GetStateType() +{ + return DmAuthStateType::AUTH_SRC_CONFIRM_STATE; +} + +void AuthSrcConfirmState::NegotiateCredential(std::shared_ptr context) +{ + std::vector srcCredTypeList = context->accesser.credentialTypeLists; + std::vector sinkCredTypeList = context->accessee.credentialTypeLists; + + std::sort(srcCredTypeList.begin(), srcCredTypeList.end()); + std::sort(sinkCredTypeList.begin(), sinkCredTypeList.end()); + + // 使用 set_intersection 找出交集 + std::vector intersection; + std::set_intersection(srcCredTypeList.begin(), srcCredTypeList.end(), + sinkCredTypeList.begin(), sinkCredTypeList.end(), std::back_inserter(intersection)); + + if (!intersection.empty() && + (intersection.front() == DM_AUTH_CREDENTIAL_ACCOUNT_RELATED || + intersection.front() == DM_AUTH_CREDENTIAL_ACCOUNT_ACROSS)) { + context->accesser.bindLevel = DmRole::DM_ROLE_USER; // Exceptions: account related is DEVICE + } + + context->accesser.credentialTypeLists.clear(); + if (!intersection.empty()) { + // 如果交集不为空,将第一个值赋值给 context->accesser.credTypeList + JsonObject credInfo(context->accesser.credentialInfos[intersection.front()]); + if (credInfo[TAG_CRED_ID].IsString()) { + context->accesser.credentialTypeLists.push_back(intersection.front()); + context->accesser.transmitCredentialId = credInfo[TAG_CRED_ID].Get(); + context->needAgreeCredential = false; + } + } + + return; +} + +void AuthSrcConfirmState::NegotiateAcl(std::shared_ptr context) +{ + context->accesser.isAuthed = false; + if (context->accesser.credentialTypeLists.size() != 1) { + return; + } + + int32_t credType = context->accesser.credentialTypeLists.front(); + // identical and across credential, online directly + if (credType == DM_AUTH_CREDENTIAL_ACCOUNT_RELATED || credType == DM_AUTH_CREDENTIAL_ACCOUNT_ACROSS) { + context->accesser.isAuthed = true; + return; + } + + if (context->accesser.aclProfiles.find(credType) == context->accesser.aclProfiles.end()) { + return; + } + + DistributedDeviceProfile::Accesser accesser = context->accesser.aclProfiles[credType].GetAccesser(); + DistributedDeviceProfile::Accessee accessee = context->accesser.aclProfiles[credType].GetAccessee(); + context->accesser.transmitSessionKeyId = accesser.GetAccesserSessionKeyId(); + context->accessee.transmitSessionKeyId = accessee.GetAccesseeSessionKeyId(); + context->accesser.isAuthed = true; + + return; +} + +int32_t AuthSrcConfirmState::Action(std::shared_ptr context) +{ + LOGI("AuthSrcConfirmState::Action start"); + // check version compatibility + context->timer->DeleteTimer(std::string(NEGOTIATE_TIMEOUT_TASK)); + if (CompareVersion(context->accessee.dmVersion, std::string(DM_VERSION_5_1_0))) { + LOGE("AuthSrcConfirmState::Action incompatible version %{public}s compare to 5.1.0", + context->accessee.dmVersion.c_str()); + context->reason = ERR_DM_VERSION_INCOMPATIBLE; + return ERR_DM_VERSION_INCOMPATIBLE; + } + + context->accesser.isOnline = context->accessee.isOnline && + context->softbusConnector->CheckIsOnline(context->accessee.deviceIdHash, true); + int32_t ret = GetAuthCredentialInfo(context); + if (ret != DM_OK) { + LOGE("AuthSrcConfirmState::Action GetAuthCredentialInfo failed"); + return ret; + } + + NegotiateCredential(context); + NegotiateAcl(context); + + // not pin import, and have acl + if ((!DmAuthState::IsImportAuthCodeCompatibility(context->authType)) && context->accesser.isAuthed) { + // finished, goto join lnn + context->authStateMachine->TransitionTo(std::make_shared()); + return DM_OK; + } + // send 100 msg + context->authMessageProcessor->CreateAndSendMsg(MSG_TYPE_REQ_USER_CONFIRM, context); + + context->timer->StartTimer(std::string(CONFIRM_TIMEOUT_TASK), + DmAuthState::GetTaskTimeout(context, CONFIRM_TIMEOUT_TASK, CONFIRM_TIMEOUT), + [context] (std::string name) { + HandleAuthenticateTimeout(context, name); + }); + return DM_OK; +} + +DmAuthStateType AuthSinkConfirmState::GetStateType() +{ + return DmAuthStateType::AUTH_SINK_CONFIRM_STATE; +} + +int32_t AuthSinkConfirmState::ShowConfigDialog(std::shared_ptr context) +{ + LOGI("AuthSinkConfirmState::ShowConfigDialog start"); + + if (IsScreenLocked()) { + LOGE("AuthSinkConfirmState::ShowStartAuthDialog screen is locked."); + context->reason = ERR_DM_BIND_USER_CANCEL; + context->authStateMachine->NotifyEventFinish(DmEventType::ON_FAIL); + return STOP_BIND; + } + + JsonObject jsonObj; + jsonObj[TAG_CUSTOM_DESCRIPTION] = context->customData; + jsonObj[TAG_LOCAL_DEVICE_TYPE] = context->accesser.deviceType; + jsonObj[TAG_REQUESTER] = context->accesser.deviceName; + jsonObj[TAG_USER_ID] = context->accessee.userId; + jsonObj[TAG_HOST_PKGLABEL] = context->sessionName; + jsonObj[TOKENID] = context->accessee.tokenId; + + const std::string params = jsonObj.Dump(); + DmDialogManager::GetInstance().ShowConfirmDialog(params); + + LOGI("AuthSinkConfirmState::ShowConfigDialog end"); + return DM_OK; +} + +void AuthSinkConfirmState::NegotiateCredential(std::shared_ptr context) +{ + if (context->accesser.credentialTypeLists.size() != 1) { + return; + } + + // 确定bindLevel + int32_t credType = context->accesser.credentialTypeLists.front(); + if (credType == DM_AUTH_CREDENTIAL_ACCOUNT_RELATED || credType == DM_AUTH_CREDENTIAL_ACCOUNT_ACROSS) { + context->accessee.bindLevel = DmRole::DM_ROLE_USER; // Exceptions: account related is DEVICE + } + + // 凭据与对端凭据不匹配 + std::vector &sinkCredTypeLists = context->accessee.credentialTypeLists; + if (std::find(sinkCredTypeLists.begin(), sinkCredTypeLists.end(), credType) == sinkCredTypeLists.end()) { + LOGI("AuthSinkConfirmState::NegotiateCredential credType %{public}d not found in sink", credType); + return; + } + + JsonObject credInfo(context->accessee.credentialInfos[credType]); + if (credInfo[TAG_CRED_ID].IsString()) { + sinkCredTypeLists.clear(); + sinkCredTypeLists.push_back(credType); + context->accessee.transmitCredentialId = credInfo[TAG_CRED_ID].Get(); + } + + return; +} + +void AuthSinkConfirmState::NegotiateAcl(std::shared_ptr context) +{ + context->accessee.isAuthed = false; + if (!context->accesser.isAuthed || context->accessee.credentialTypeLists.size() != 1) { + return; + } + + int32_t credType = context->accessee.credentialTypeLists.front(); + if (credType == DM_AUTH_CREDENTIAL_ACCOUNT_RELATED || credType == DM_AUTH_CREDENTIAL_ACCOUNT_ACROSS) { + context->accessee.isAuthed = true; + return; + } + if (context->accessee.aclProfiles.find(credType) == context->accessee.aclProfiles.end()) { + return; + } + + context->accessee.isAuthed = true; + DistributedDeviceProfile::Accesser accesser = context->accesser.aclProfiles[credType].GetAccesser(); + DistributedDeviceProfile::Accessee accessee = context->accesser.aclProfiles[credType].GetAccessee(); + context->accesser.transmitSessionKeyId = accesser.GetAccesserSessionKeyId(); + context->accessee.transmitSessionKeyId = accessee.GetAccesseeSessionKeyId(); + + return; +} + +void AuthSinkConfirmState::MatchFallBackCandidateList( + std::shared_ptr context, DmAuthType authType) +{ + for (size_t i = 0; i < MAX_FALLBACK_LOOPKUP_TIMES; i++) { + auto it = g_pinAuthTypeFallBackMap.find({context->accessee.bundleName, authType}); + if (it != g_pinAuthTypeFallBackMap.end()) { + authType = it->second; + context->authTypeList.push_back(authType); + } else { + break; + } + } +} + +void AuthSinkConfirmState::ReadServiceInfo(std::shared_ptr context) +{ + // query ServiceInfo by accessee.bundleName and authType from client + OHOS::DistributedDeviceProfile::LocalServiceInfo srvInfo; + auto ret = DeviceProfileConnector::GetInstance().GetLocalServiceInfoByBundleNameAndPinExchangeType( + context->accessee.bundleName, context->authType, srvInfo); + if (ret == OHOS::DistributedDeviceProfile::DP_SUCCESS) { + LOGI("AuthSinkConfirmState::ReadServiceInfo found"); + // ServiceInfo found + context->serviceInfoFound = true; + context->authBoxType = srvInfo.GetAuthBoxType(); // read authBoxType + if (DmAuthState::IsImportAuthCodeCompatibility(context->authType)) { + std::string pinCode = srvInfo.GetPinCode(); // read pincode + if (AuthSinkStatePinAuthComm::IsPinCodeValid(pinCode)) { + context->pinCode = std::stoi(pinCode.c_str()); + } + srvInfo.SetPinCode("******"); + DeviceProfileConnector::GetInstance().UpdateLocalServiceInfo(srvInfo); + } + if (context->authBoxType == OHOS::DistributedDeviceProfile::NUM_2) { // no authorization box + int32_t authResult = srvInfo.GetAuthType(); // read authResult + if (authResult == 0) { + context->authResult = UiAction::USER_OPERATION_TYPE_ALLOW_AUTH; + } else if (authResult == OHOS::DistributedDeviceProfile::NUM_1) { + context->authResult = UiAction::USER_OPERATION_TYPE_CANCEL_AUTH; + } else if (authResult == OHOS::DistributedDeviceProfile::NUM_6) { + context->authResult = UiAction::USER_OPERATION_TYPE_ALLOW_AUTH_ALWAYS; + } else { + context->authResult = UiAction::USER_OPERATION_TYPE_CANCEL_AUTH; + } + } + context->customData = srvInfo.GetDescription(); // read customData + } else if (DmAuthState::IsImportAuthCodeCompatibility(context->authType) && + AuthSinkStatePinAuthComm::IsAuthCodeReady(context)) { + // only special scenarios can import pincode + context->authBoxType = OHOS::DistributedDeviceProfile::NUM_2; // no authorization box + } else { + // not special scenarios, reset authResult to cancel + context->authResult = UiAction::USER_OPERATION_TYPE_CANCEL_AUTH; + context->authBoxType = OHOS::DistributedDeviceProfile::NUM_1; // default: tristate box + } +} + +int32_t AuthSinkConfirmState::Action(std::shared_ptr context) +{ + LOGI("AuthSinkConfirmState::Action start"); + NegotiateCredential(context); + NegotiateAcl(context); + ReadServiceInfo(context); + bool authTypeCheckOk = false; + if (DmAuthState::IsImportAuthCodeCompatibility(context->authType) && + (context->serviceInfoFound || AuthSinkStatePinAuthComm::IsAuthCodeReady(context)) && + context->authBoxType == OHOS::DistributedDeviceProfile::NUM_2) { + /* The value of authresult may be the default value of temporary trust, + or the value of authresult may be set by the service. */ + authTypeCheckOk = true; + } else if ((context->authType == DmAuthType::AUTH_TYPE_PIN || + context->authType == DmAuthType::AUTH_TYPE_PIN_ULTRASONIC) && + context->authBoxType == OHOS::DistributedDeviceProfile::NUM_1) { + auto& credTypeLists = context->accesser.credentialTypeLists; + if ((!credTypeLists.empty()) && (credTypeLists[0] == DM_AUTH_CREDENTIAL_ACCOUNT_RELATED || + credTypeLists[0] == DM_AUTH_CREDENTIAL_ACCOUNT_ACROSS)) { + // have DM_AUTH_CREDENTIAL_ACCOUNT_RELATED or DM_AUTH_CREDENTIAL_ACCOUNT_ACROSS + context->authResult = UiAction::USER_OPERATION_TYPE_ALLOW_AUTH_ALWAYS; + context->authMessageProcessor->CreateAndSendMsg(MSG_TYPE_RESP_USER_CONFIRM, context); + return DM_OK; + } else { + context->timer->DeleteTimer(std::string(WAIT_REQUEST_TIMEOUT_TASK)); + // show user confirmation dialog + auto ret = ShowConfigDialog(context); + if (ret != DM_OK) { + return ret; + } + // wait for user opration + if (DmEventType::ON_USER_OPERATION != + context->authStateMachine->WaitExpectEvent(DmEventType::ON_USER_OPERATION)) { + LOGE("AuthSinkConfirmState::Action wait ON_USER_OPERATION err"); + return STOP_BIND; + } + if (context->reply != USER_OPERATION_TYPE_ALLOW_AUTH) { + LOGI("AuthSinkConfirmState::Action USER_OPERATION_TYPE_CANCEL_AUTH"); + context->reason = ERR_DM_BIND_USER_CANCEL; + return STOP_BIND; + } + authTypeCheckOk = true; + } + } + context->authTypeList.clear(); + if (authTypeCheckOk) { + context->authTypeList.push_back(context->authType); + MatchFallBackCandidateList(context, context->authType); + // send 110 msg + context->authMessageProcessor->CreateAndSendMsg(MSG_TYPE_RESP_USER_CONFIRM, context); + context->authStateMachine->TransitionTo(std::make_shared()); + return DM_OK; + } + context->authResult = UiAction::USER_OPERATION_TYPE_CANCEL_AUTH; + return ERR_DM_UNSUPPORTED_AUTH_TYPE; +} + +} // namespace DistributedHardware +} // namespace OHOS \ No newline at end of file diff --git a/services/implementation/src/authentication_v2/auth_stages/auth_credential.cpp b/services/implementation/src/authentication_v2/auth_stages/auth_credential.cpp new file mode 100644 index 000000000..da6d8e49d --- /dev/null +++ b/services/implementation/src/authentication_v2/auth_stages/auth_credential.cpp @@ -0,0 +1,531 @@ +/* + * Copyright (c) 2025 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 +#include +#include +#include +#include "dm_auth_context.h" +#include "dm_auth_manager_base.h" +#include "dm_auth_message_processor.h" +#include "dm_auth_state.h" +#include "dm_auth_state_machine.h" +#include "dm_constants.h" +#include "dm_log.h" +#include "deviceprofile_connector.h" +#include "hichain_auth_connector.h" +#include "multiple_user_connector.h" + +namespace OHOS { +namespace DistributedHardware { + +namespace { + +// tag in Lowercase, need by hichain tag +constexpr const char* TAG_LOWER_DEVICE_ID = "deviceId"; +constexpr const char* TAG_LOWER_USER_ID = "userId"; + +constexpr const char* DM_AUTH_CREDENTIAL_OWNER = "DM"; + +int32_t AuthCredentialTransmitDecryptProcess(std::shared_ptr context, DmEventType event) +{ + if (context->transmitData.empty()) { + LOGE("DmAuthMessageProcessor::CreateMessageReqCredAuthStart failed, get onTransmitData failed."); + return ERR_DM_FAILED; + } + + int32_t ret = context->hiChainAuthConnector->ProcessCredData(context->requestId, context->transmitData); + if (ret != DM_OK) { + LOGE("AuthCredentialTransmitDecryptProcess: ProcessCredData transmit data failed"); + return ERR_DM_FAILED; + } + + if (context->authStateMachine->WaitExpectEvent(event) != event) { + LOGE("AuthCredentialTransmitDecryptProcess: Hichain auth transmit data failed"); + return ERR_DM_FAILED; + } + return DM_OK; +} + +int32_t AuthCredentialTransmitSend(std::shared_ptr context, DmMessageType msgType) +{ + if (context->transmitData.empty()) { + LOGE("AuthCredentialTransmitSend: Get onTransmitData failed."); + return ERR_DM_FAILED; + } + + std::string message = + context->authMessageProcessor->CreateMessage(msgType, context); + if (message.empty()) { + LOGE("AuthCredentialTransmitSend: CreateMessage AuthCredential transmit data failed"); + return ERR_DM_FAILED; + } + + return context->softbusConnector->GetSoftbusSession()->SendData(context->sessionId, message); +} + +void SetAuthContext(int32_t skId, int64_t &appSkTimeStamp, int32_t &appSessionKeyId) +{ + appSkTimeStamp = + std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(); + appSessionKeyId = skId; + return; +} + +} + +DmAuthStateType AuthSrcCredentialAuthNegotiateState::GetStateType() +{ + return DmAuthStateType::AUTH_SRC_CREDENTIAL_AUTH_NEGOTIATE_STATE; +} + +// Parse the ontransmit data, respond with 161 message +int32_t AuthSrcCredentialAuthNegotiateState::Action(std::shared_ptr context) +{ + // decrypt and transmit transmitData + int32_t ret = AuthCredentialTransmitDecryptProcess(context, ON_TRANSMIT); + if (ret != DM_OK) { + return ret; + } + + // Send 161 message + return AuthCredentialTransmitSend(context, DmMessageType::MSG_TYPE_REQ_CREDENTIAL_AUTH_NEGOTIATE); +} + +DmAuthStateType AuthSrcCredentialAuthDoneState::GetStateType() +{ + return DmAuthStateType::AUTH_SRC_CREDENTIAL_AUTH_DONE_STATE; +} + +int32_t AuthSrcCredentialAuthDoneState::Action(std::shared_ptr context) +{ + // decrypt and transmit transmitData + int32_t ret = AuthCredentialTransmitDecryptProcess(context, ON_SESSION_KEY_RETURNED); + if (ret != DM_OK) { + return ret; + } + + // Authentication completion triggers the Onfinish callback event. + if (context->authStateMachine->WaitExpectEvent(ON_FINISH) != ON_FINISH) { + LOGE("AuthSrcCredentialAuthDoneState::Action Hichain auth SINK transmit data failed"); + return ERR_DM_FAILED; + } + DmMessageType msgType; + int32_t skId; + ret = context->authMessageProcessor->SaveSessionKeyToDP(skId); + if (ret != DM_OK) { + LOGE("AuthSrcCredentialAuthDoneState::Action DP save user session key failed"); + return ret; + } + + // first time joinLnn, auth lnnCredential + if (context->isOnline == false && context->isAppCredentialVerified == false) { + context->isAppCredentialVerified = true; + SetAuthContext(skId, context->accesser.transmitSkTimeStamp, context->accesser.transmitSessionKeyId); + msgType = MSG_TYPE_REQ_CREDENTIAL_AUTH_START; + ret = context->hiChainAuthConnector->AuthCredential(context->accesser.userId, context->requestId, + context->accesser.lnnCredentialId, std::string("")); + if (ret != DM_OK) { + LOGE("AuthSrcCredentialAuthDoneState::Action Hichain auth credentail failed"); + return ret; + } + + // wait for onTransmit event + if (context->authStateMachine->WaitExpectEvent(ON_TRANSMIT) != ON_TRANSMIT) { + LOGE("AuthSrcCredentialAuthDoneState::Action failed, ON_TRANSMIT event not arrived."); + return ERR_DM_FAILED; + } + } else if (context->isOnline == false) { // First-time authentication and Lnn credential process + SetAuthContext(skId, context->accesser.lnnSkTimeStamp, context->accesser.lnnSessionKeyId); + msgType = MSG_TYPE_REQ_DATA_SYNC; + } else { // Non-first-time authentication transport credential process + SetAuthContext(skId, context->accesser.transmitSkTimeStamp, context->accesser.transmitSessionKeyId); + msgType = MSG_TYPE_REQ_DATA_SYNC; + } + std::string message = + context->authMessageProcessor->CreateMessage(msgType, context); + if (message.empty()) { + LOGE("AuthSrcCredentialAuthDoneState::Action CreateMessage failed"); + return ERR_DM_FAILED; + } + + return context->softbusConnector->GetSoftbusSession()->SendData(context->sessionId, message); +} + +DmAuthStateType AuthSinkCredentialAuthStartState::GetStateType() +{ + return DmAuthStateType::AUTH_SINK_CREDENTIAL_AUTH_START_STATE; +} + +int32_t AuthSinkCredentialAuthStartState::Action(std::shared_ptr context) +{ + context->timer->DeleteTimer(std::string(WAIT_REQUEST_TIMEOUT_TASK)); + + int32_t ret = AuthCredentialTransmitDecryptProcess(context, ON_TRANSMIT); + if (ret != DM_OK) { + return ret; + } + + return AuthCredentialTransmitSend(context, DmMessageType::MSG_TYPE_RESP_CREDENTIAL_AUTH_START); +} + +DmAuthStateType AuthSinkCredentialAuthNegotiateState::GetStateType() +{ + return DmAuthStateType::AUTH_SINK_CREDENTIAL_AUTH_NEGOTIATE_STATE; +} + +int32_t AuthSinkCredentialAuthNegotiateState::Action(std::shared_ptr context) +{ + int32_t ret = AuthCredentialTransmitDecryptProcess(context, ON_TRANSMIT); + if (ret != DM_OK) { + return ret; + } + + // Construct and send 171 message + ret = AuthCredentialTransmitSend(context, DmMessageType::MSG_TYPE_RESP_CREDENTIAL_AUTH_NEGOTIATE); + if (ret != DM_OK) { + return ret; + } + + if (context->authStateMachine->WaitExpectEvent(ON_SESSION_KEY_RETURNED) != ON_SESSION_KEY_RETURNED) { + LOGE("AuthSinkCredentialAuthNegotiateState::Action Hichain auth SINK transmit data failed"); + return ERR_DM_FAILED; + } + + if (context->authStateMachine->WaitExpectEvent(ON_FINISH) != ON_FINISH) { + LOGE("AuthSinkCredentialAuthNegotiateState::Action Hichain auth SINK transmit data failed"); + return ERR_DM_FAILED; + } + int32_t skId; + ret = context->authMessageProcessor->SaveSessionKeyToDP(skId); + if (ret != DM_OK) { + LOGE("AuthSinkCredentialAuthNegotiateState::Action DP save user session key failed"); + return ret; + } + + // First lnn cred auth, second time receiving 161 message + if (context->isOnline == false && + context->isAppCredentialVerified == true) { + context->accessee.lnnSkTimeStamp = + std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()) + .count(); + context->accessee.lnnSessionKeyId = skId; + } else { // Twice transport cred auth + context->isAppCredentialVerified = true; + context->accessee.transmitSkTimeStamp = + std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()) + .count(); + context->accessee.transmitSessionKeyId = skId; + } + return DM_OK; +} + + +// Generate the json string of authParams in the credential negotiation state +std::string AuthCredentialAgreeState::CreateAuthParamsString(DmAuthScope authorizedScope, + DmAuthCredentialAddMethod method, const std::shared_ptr &authContext) +{ + LOGI("AuthCredentialAgreeState::CreateAuthParamsString start."); + + if ((authorizedScope != DM_AUTH_SCOPE_USER && authorizedScope != DM_AUTH_SCOPE_APP) || + (method != DM_AUTH_CREDENTIAL_ADD_METHOD_GENERATE && method != DM_AUTH_CREDENTIAL_ADD_METHOD_IMPORT)) { + return std::string(""); + } + + JsonObject jsonObj; + if (method == DM_AUTH_CREDENTIAL_ADD_METHOD_GENERATE) { + jsonObj[TAG_METHOD] = method; + } + + jsonObj[TAG_LOWER_DEVICE_ID] = (method == DM_AUTH_CREDENTIAL_ADD_METHOD_GENERATE) ? + authContext->GetDeviceId(DM_AUTH_LOCAL_SIDE) : authContext->GetDeviceId(DM_AUTH_REMOTE_SIDE); + if (method == DM_AUTH_CREDENTIAL_ADD_METHOD_IMPORT) { + jsonObj[TAG_PEER_USER_SPACE_ID] = std::to_string(authContext->GetUserId(DM_AUTH_REMOTE_SIDE)); + } + jsonObj[TAG_LOWER_USER_ID] = (method == DM_AUTH_CREDENTIAL_ADD_METHOD_GENERATE) ? + authContext->GetAccountId(DM_AUTH_LOCAL_SIDE) : authContext->GetAccountId(DM_AUTH_REMOTE_SIDE); + jsonObj[TAG_SUBJECT] = DM_AUTH_CREDENTIAL_SUBJECT_PRIMARY; + jsonObj[TAG_CRED_TYPE] = DM_AUTH_CREDENTIAL_ACCOUNT_UNRELATED; + jsonObj[TAG_KEY_FORMAT] = (method == DM_AUTH_CREDENTIAL_ADD_METHOD_GENERATE) ? + DM_AUTH_KEY_FORMAT_ASYMM_GENERATE : DM_AUTH_KEY_FORMAT_ASYMM_IMPORT; + jsonObj[TAG_ALGORITHM_TYPE] = DM_AUTH_ALG_TYPE_ED25519; + jsonObj[TAG_PROOF_TYPE] = DM_AUTH_CREDENTIAL_PROOF_PSK; + if (method == DM_AUTH_CREDENTIAL_ADD_METHOD_IMPORT) { + jsonObj[TAG_KEY_VALUE] = authContext->GetPublicKey(DM_AUTH_REMOTE_SIDE, authorizedScope); + } + jsonObj[TAG_AUTHORIZED_SCOPE] = authorizedScope; + if (authorizedScope == DM_AUTH_SCOPE_APP) { + std::vector tokenIds = {std::to_string(authContext->accesser.tokenId), + std::to_string(authContext->accessee.tokenId)}; + jsonObj[TAG_AUTHRIZED_APP_LIST] = tokenIds; + } + jsonObj[TAG_CREDENTIAL_OWNER] = DM_AUTH_CREDENTIAL_OWNER; + + LOGI("AuthCredentialAgreeState::CreateAuthParamsString leave."); + return jsonObj.Dump(); +} + +// Generate credential ID and public key +int32_t AuthCredentialAgreeState::GenerateCredIdAndPublicKey(DmAuthScope authorizedScope, + std::shared_ptr &authContext) +{ + LOGI("AuthCredentialAgreeState::GenerateCredIdAndPublicKey start."); + if ((authorizedScope != DM_AUTH_SCOPE_USER && authorizedScope != DM_AUTH_SCOPE_APP) || + authContext == nullptr || authContext->hiChainAuthConnector == nullptr) { + return ERR_DM_FAILED; + } + + std::string authParamsString = CreateAuthParamsString(authorizedScope, + DM_AUTH_CREDENTIAL_ADD_METHOD_GENERATE, authContext); + if (authParamsString == "") { + LOGE("AuthCredentialAgreeState::GenerateCredIdAndPublicKey() error, create authParamsString failed."); + return ERR_DM_FAILED; + } + + int32_t osAccountId = (authContext->direction == DM_AUTH_SOURCE) ? + authContext->accesser.userId : authContext->accessee.userId; + std::string credId; + int32_t ret = authContext->hiChainAuthConnector->AddCredential(osAccountId, authParamsString, credId); + if (ret != DM_OK) { + LOGE("AuthCredentialAgreeState::GenerateCredIdAndPublicKey() error, add credential failed."); + return ret; + } + + std::string publicKey; + ret = authContext->hiChainAuthConnector->ExportCredential(osAccountId, credId, publicKey); + if (ret != DM_OK) { + LOGE("AuthCredentialAgreeState::GenerateCredIdAndPublicKey(), export publicKey failed."); + authContext->hiChainAuthConnector->DeleteCredential(osAccountId, credId); + return ret; + } + + (void)authContext->SetCredentialId(DM_AUTH_LOCAL_SIDE, authorizedScope, credId); + (void)authContext->SetPublicKey(DM_AUTH_LOCAL_SIDE, authorizedScope, publicKey); + LOGI("AuthCredentialAgreeState::GenerateCredIdAndPublicKey credId=%{public}s, publicKey=%{public}s.\n", + authContext->GetCredentialId(DM_AUTH_LOCAL_SIDE, authorizedScope).c_str(), + authContext->GetPublicKey(DM_AUTH_LOCAL_SIDE, authorizedScope).c_str()); + LOGI("AuthCredentialAgreeState::GenerateCredIdAndPublicKey leave."); + return DM_OK; +} + +// Get the negotiation credential ID by agree credential +int32_t AuthCredentialAgreeState::AgreeCredential(DmAuthScope authorizedScope, + std::shared_ptr &authContext) +{ + LOGI("AuthCredentialAgreeState::AgreeCredential start."); + if ((authorizedScope != DM_AUTH_SCOPE_USER && authorizedScope != DM_AUTH_SCOPE_APP) || authContext == nullptr) { + return ERR_DM_FAILED; + } + + std::string authParamsString = CreateAuthParamsString(authorizedScope, + DM_AUTH_CREDENTIAL_ADD_METHOD_IMPORT, authContext); + if (authParamsString == "") { + LOGE("AuthCredentialAgreeState::AgreeCredential error, create authParamsString failed."); + return ERR_DM_FAILED; + } + + int32_t osAccountId = authContext->direction == DM_AUTH_SOURCE ? + authContext->accesser.userId : authContext->accessee.userId; + std::string selfCredId = authContext->GetCredentialId(DM_AUTH_LOCAL_SIDE, authorizedScope); + std::string credId; + LOGI("AuthCredentialAgreeState::AgreeCredential agree with accountId %{public}d and param %{public}s.", + osAccountId, authParamsString.c_str()); + int32_t ret = authContext->hiChainAuthConnector->AgreeCredential(osAccountId, selfCredId, + authParamsString, credId); + if (ret != DM_OK) { + LOGE("AuthCredentialAgreeState::AgreeCredential error, agree credential failed."); + } + + (void)authContext->SetCredentialId(DM_AUTH_LOCAL_SIDE, authorizedScope, credId); + LOGI("AuthCredentialAgreeState::AgreeCredential leave."); + return DM_OK; +} + +DmAuthStateType AuthSrcCredentialExchangeState::GetStateType() +{ + return DmAuthStateType::AUTH_SRC_CREDENTIAL_EXCHANGE_STATE; +} + +int32_t AuthSrcCredentialExchangeState::Action(std::shared_ptr context) +{ + LOGI("AuthSrcCredentialExchangeState::Action() start."); + int32_t ret = ERR_DM_FAILED; + context->isAppCredentialVerified = false; + + if (!NeedAgreeAcl(context)) { + context->authStateMachine->TransitionTo(std::make_shared()); + return DM_OK; + } + + if (!NeedAgreeCredential(context)) { + context->authStateMachine->TransitionTo(std::make_shared()); + return DM_OK; + } + + // First authentication, generate LNN credentials and public key + if (!context->isOnline) { + ret = GenerateCredIdAndPublicKey(DM_AUTH_SCOPE_USER, context); + if (ret != DM_OK) { + LOGE("AuthSrcCredentialExchangeState::Action() error, generate user credId and publicKey failed."); + return ret; + } + } + + // Generate transmit credentials and public key + ret = GenerateCredIdAndPublicKey(DM_AUTH_SCOPE_APP, context); + if (ret != DM_OK) { + LOGE("AuthSrcCredentialExchangeState::Action() error, generate app credId and publicKey failed."); + return ret; + } + + std::string message = context->authMessageProcessor->CreateMessage(MSG_TYPE_REQ_CREDENTIAL_EXCHANGE, context); + LOGI("AuthSrcCredentialExchangeState::Action() leave."); + return context->softbusConnector->GetSoftbusSession()->SendData(context->sessionId, message); +} + +DmAuthStateType AuthSinkCredentialExchangeState::GetStateType() +{ + return DmAuthStateType::AUTH_SINK_CREDENTIAL_EXCHANGE_STATE; +} + +int32_t AuthSinkCredentialExchangeState::Action(std::shared_ptr context) +{ + LOGI("AuthSinkCredentialExchangeState::Action start."); + int32_t ret = ERR_DM_FAILED; + std::string tmpCredId; + int32_t osAccountId = context->accessee.userId; + context->isAppCredentialVerified = false; + + if (context == nullptr || context->hiChainAuthConnector == nullptr || + context->authMessageProcessor == nullptr || context->softbusConnector == nullptr) { + return ret; + } + + // First authentication lnn cred + if (!context->isOnline) { + // Generate credentials and public key + ret = GenerateCredIdAndPublicKey(DM_AUTH_SCOPE_USER, context); + if (ret != DM_OK) { + LOGE("AuthSinkCredentialExchangeState::Action failed, generate user cred and publicKey failed."); + return ret; + } + + // Agree credentials + tmpCredId = context->accessee.lnnCredentialId; + ret = AgreeCredential(DM_AUTH_SCOPE_USER, context); + if (ret != DM_OK) { + context->hiChainAuthConnector->DeleteCredential(osAccountId, tmpCredId); + context->SetCredentialId(DM_AUTH_LOCAL_SIDE, DM_AUTH_SCOPE_USER, ""); + LOGE("AuthSinkCredentialExchangeState::Action failed, agree user cred failed."); + return ret; + } + + // Delete temporary credentials + context->hiChainAuthConnector->DeleteCredential(osAccountId, tmpCredId); + } + + // Generate transport credentials and public key + ret = GenerateCredIdAndPublicKey(DM_AUTH_SCOPE_APP, context); + if (ret != DM_OK) { + LOGE("AuthSinkCredentialExchangeState::Action failed, generate app cred and publicKey failed."); + return ret; + } + + // Agree transport credentials and public key + tmpCredId = context->accessee.transmitCredentialId; + ret = AgreeCredential(DM_AUTH_SCOPE_APP, context); + if (ret != DM_OK) { + context->hiChainAuthConnector->DeleteCredential(osAccountId, tmpCredId); + context->SetCredentialId(DM_AUTH_LOCAL_SIDE, DM_AUTH_SCOPE_APP, ""); + LOGE("AuthSinkCredentialExchangeState::Action failed, agree app cred failed."); + return ret; + } + + // Delete temporary transport credentials + context->hiChainAuthConnector->DeleteCredential(osAccountId, tmpCredId); + + std::string message = context->authMessageProcessor->CreateMessage(MSG_TYPE_RESP_CREDENTIAL_EXCHANGE, context); + LOGI("AuthSinkCredentialExchangeState::Action leave."); + return context->softbusConnector->GetSoftbusSession()->SendData(context->sessionId, message); +} + +DmAuthStateType AuthSrcCredentialAuthStartState::GetStateType() +{ + return DmAuthStateType::AUTH_SRC_CREDENTIAL_AUTH_START_STATE; +} + + +int32_t AuthSrcCredentialAuthStartState::Action(std::shared_ptr context) +{ + LOGI(" AuthSrcCredentialAuthStartState::Action start."); + int32_t ret = ERR_DM_FAILED; + std::string tmpCredId; + int32_t osAccountId = context->accesser.userId; + + if (context == nullptr || context->hiChainAuthConnector == nullptr || + context->authMessageProcessor == nullptr || context->softbusConnector == nullptr) { + return ret; + } + + if (NeedAgreeCredential(context)) { + // First authentication + if (!context->isOnline) { + // Agree lnn credentials and public key + tmpCredId = context->accesser.lnnCredentialId; + ret = AgreeCredential(DM_AUTH_SCOPE_USER, context); + if (ret != DM_OK) { + context->hiChainAuthConnector->DeleteCredential(osAccountId, tmpCredId); + context->SetCredentialId(DM_AUTH_LOCAL_SIDE, DM_AUTH_SCOPE_USER, ""); + LOGE("AuthSrcCredentialAuthStartState::Action failed, agree user cred failed."); + return ret; + } + + // Delete temporary lnn credentials + context->hiChainAuthConnector->DeleteCredential(osAccountId, tmpCredId); + } + + // Agree transport credentials and public key + tmpCredId = context->accesser.transmitCredentialId; + ret = AgreeCredential(DM_AUTH_SCOPE_APP, context); + if (ret != DM_OK) { + context->hiChainAuthConnector->DeleteCredential(osAccountId, tmpCredId); + context->SetCredentialId(DM_AUTH_LOCAL_SIDE, DM_AUTH_SCOPE_APP, ""); + LOGE("AuthSrcCredentialAuthStartState::Action failed, agree app cred failed."); + return ret; + } + + // Delete temporary transport credentials + context->hiChainAuthConnector->DeleteCredential(osAccountId, tmpCredId); + } + + // Transport credential authentication + ret = context->hiChainAuthConnector->AuthCredential(osAccountId, context->requestId, + context->accesser.transmitCredentialId, std::string("")); + if (ret != DM_OK) { + LOGE("AuthSrcCredentialAuthStartState::Action failed, auth app cred failed."); + return ret; + } + + if (context->authStateMachine->WaitExpectEvent(ON_TRANSMIT) != ON_TRANSMIT) { + LOGE("AuthSrcCredentialAuthStartState::Action failed, ON_TRANSMIT event not arrived."); + return ERR_DM_FAILED; + } + + std::string message = context->authMessageProcessor->CreateMessage(MSG_TYPE_REQ_CREDENTIAL_AUTH_START, context); + LOGI(" AuthSrcCredentialAuthStartState::Action leave."); + return context->softbusConnector->GetSoftbusSession()->SendData(context->sessionId, message); +} + +} // namespace DistributedHardware +} // namespace OHOS diff --git a/services/implementation/src/authentication_v2/auth_stages/auth_negotiate.cpp b/services/implementation/src/authentication_v2/auth_stages/auth_negotiate.cpp new file mode 100644 index 000000000..872e5eb23 --- /dev/null +++ b/services/implementation/src/authentication_v2/auth_stages/auth_negotiate.cpp @@ -0,0 +1,250 @@ +/* + * Copyright (c) 2025 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 +#include +#include "json_object.h" + +#include "parameter.h" +#include "multiple_user_connector.h" +#include "hap_token_info.h" +#include "deviceprofile_connector.h" +#include "distributed_device_profile_errors.h" +#include "device_auth.h" +#include "os_account_manager.h" +#include "app_manager.h" +#include "accesstoken_kit.h" +#include "access_control_profile.h" +#include "accesser.h" +#include "accessee.h" + +#include "dm_crypto.h" +#include "dm_log.h" +#include "dm_timer.h" +#include "dm_radar_helper.h" +#include "dm_language_manager.h" +#include "dm_constants.h" +#include "dm_anonymous.h" +#include "dm_random.h" +#include "dm_auth_context.h" +#include "auth_manager.h" +#include "dm_auth_state.h" + +using namespace OHOS::Security::AccessToken; + +namespace OHOS { +namespace DistributedHardware { + +namespace { + +const std::string SYSTEM_LANGUAGE_KEY = "persist.global.language"; + +int32_t AuthSrcGetBindLevel(std::shared_ptr context) +{ + int64_t tokenId; + int32_t ret = AppManager::GetInstance().GetHapTokenIdByName(context->accesser.userId, context->accesser.bundleName, + 0, tokenId); + if (ret != DM_OK) { + if (AppManager::GetInstance().GetNativeTokenIdByName(context->accesser.bundleName, tokenId) != DM_OK) { + return DmRole::DM_ROLE_DEVICE; + } + + return DmRole::DM_ROLE_SA; + } + + return DmRole::DM_ROLE_FA; +} + +} + +DmAuthStateType AuthSrcStartState::GetStateType() +{ + return DmAuthStateType::AUTH_SRC_START_STATE; +} + +int32_t AuthSrcStartState::Action(std::shared_ptr context) +{ + return DM_OK; +} + +DmAuthStateType AuthSrcNegotiateStateMachine::GetStateType() +{ + return DmAuthStateType::AUTH_SRC_NEGOTIATE_STATE; +} + +int32_t AuthSrcNegotiateStateMachine::Action(std::shared_ptr context) +{ + LOGI("AuthSrcNegotiateStateMachine::Action sessionId %{public}d.", context->sessionId); + + context->reply = ERR_DM_AUTH_REJECT; + context->accessee.bundleName = context->accesser.bundleName; + context->accessee.dmVersion = ""; + + // 计算哈希值 + context->accesser.deviceIdHash = Crypto::Sha256(context->accesser.deviceId); + context->accesser.userIdHash = Crypto::Sha256(std::to_string(context->accesser.userId)); + context->accesser.accountIdHash = Crypto::Sha256(context->accesser.accountId); + context->accesser.tokenIdHash = Crypto::Sha256(std::to_string(context->accesser.tokenId)); + + context->accesser.bindLevel = AuthSrcGetBindLevel(context); + + std::string message = context->authMessageProcessor->CreateMessage(MSG_TYPE_REQ_ACL_NEGOTIATE, context); + context->softbusConnector->GetSoftbusSession()->SendData(context->sessionId, message); + if (context->timer != nullptr) { + context->timer->StartTimer(std::string(NEGOTIATE_TIMEOUT_TASK), + DmAuthState::GetTaskTimeout(context, NEGOTIATE_TIMEOUT_TASK, NEGOTIATE_TIMEOUT), + [this, context] (std::string name) { + DmAuthState::HandleAuthenticateTimeout(context, name); + }); + } + + return DM_OK; +} + +DmAuthStateType AuthSinkNegotiateStateMachine::GetStateType() +{ + return DmAuthStateType::AUTH_SINK_NEGOTIATE_STATE; +} + +int32_t AuthSinkNegotiateStateMachine::RespQueryAcceseeIds(std::shared_ptr context) +{ + int32_t ret; + + // 1. Get deviceId + char localDeviceId[DEVICE_UUID_LENGTH] = {0}; + GetDevUdid(localDeviceId, DEVICE_UUID_LENGTH); + context->accessee.deviceId = std::string(localDeviceId); + context->accessee.deviceIdHash = Crypto::Sha256(context->accessee.deviceId); + + // 2. Get userId + int32_t userId = AuthManagerBase::DmGetUserId(context->accessee.displayId, context->accessee.userId); + if (userId < 0) { + return ERR_DM_FAILED; + } + context->accessee.userId = userId; + context->accessee.userIdHash = Crypto::Sha256(std::to_string(context->accessee.userId)); + + // 3. Get accountId + context->accessee.accountId = MultipleUserConnector::GetOhosAccountIdByUserId(context->accessee.userId); + context->accessee.accountIdHash = Crypto::Sha256(context->accessee.accountId); + + // 4. Get tokenId + std::string tmpBundleName = context->accessee.bundleName.empty() ? + context->accesser.bundleName : context->accessee.bundleName; + int64_t tokenId; + ret = AppManager::GetInstance().GetHapTokenIdByName(context->accessee.userId, tmpBundleName, 0, tokenId); + if (ret != DM_OK) { + LOGE("RespQueryTokenId: get tokenId by bundleName failed %{public}s", + GetAnonyString(context->accessee.bundleName).c_str()); + if (AppManager::GetInstance().GetNativeTokenIdByName(tmpBundleName, tokenId) != DM_OK) { + // it is FA-device, reject + LOGE("RespQueryTokenId: FA-device, reject"); + context->reason = ERR_DM_NOT_SYSTEM_APP; + context->reply = ERR_DM_NOT_SYSTEM_APP; + return ERR_DM_NOT_SYSTEM_APP; + } + + context->accessee.bindLevel = DmRole::DM_ROLE_SA; + LOGI("RespQueryTokenId: SA-SA"); + } else { + context->accessee.bindLevel = DmRole::DM_ROLE_FA; + } + context->accessee.bundleName = tmpBundleName; + context->accessee.tokenId = static_cast(tokenId); + context->accessee.tokenIdHash = Crypto::Sha256(std::to_string(context->accessee.tokenId)); + + return DM_OK; +} + +int32_t AuthSinkNegotiateStateMachine::ProcRespNegotiate5_1_0(std::shared_ptr context) +{ + int32_t ret = RespQueryAcceseeIds(context); + if (ret != DM_OK) { + LOGE("DmAuthManager::ProcRespNegotiate5_1_0 fail to get all id."); + return ERR_DM_FAILED; + } + + context->accesser.isOnline = context->softbusConnector->CheckIsOnline(context->accesser.deviceIdHash, true); + context->accesser.language = DmLanguageManager::GetInstance().GetSystemParam(SYSTEM_LANGUAGE_KEY); + ret = GetAuthCredentialInfo(context); + if (ret != DM_OK) { + LOGE("DmAuthManager::ProcRespNegotiate5_1_0 fail to get credential."); + return ERR_DM_FAILED; + } + + return DM_OK; +} + +int32_t AuthSinkNegotiateStateMachine::Action(std::shared_ptr context) +{ + LOGI("AuthSinkNegotiateStateMachine::Action sessionid %{public}d", context->sessionId); + + // 1. 创建授权定时器 + if (context->timer != nullptr) { + context->timer->StartTimer(std::string(AUTHENTICATE_TIMEOUT_TASK), + DmAuthState::GetTaskTimeout(context, AUTHENTICATE_TIMEOUT_TASK, AUTHENTICATE_TIMEOUT), + [this, context] (std::string name) { + DmAuthState::HandleAuthenticateTimeout(context, name); + }); + } + + // 2. 获取deviceName和udid + context->accessee.deviceName = context->softbusConnector->GetLocalDeviceName(); + char localDeviceId[DEVICE_UUID_LENGTH] = {0}; + GetDevUdid(localDeviceId, DEVICE_UUID_LENGTH); + context->accessee.deviceId = std::string(localDeviceId); + + context->accessee.networkId = context->softbusConnector->GetLocalDeviceNetworkId(); + // 为兼容历史版本,通过ConvertSrcVersion获取src端实际version + context->accesser.dmVersion = AuthManagerBase::ConvertSrcVersion(context->accesser.dmVersion, + context->accesser.edition); + std::string preVersion = std::string(DM_VERSION_5_0_OLD_MAX); + LOGI("AuthSinkNegotiateStateMachine::Action start version compare %{public}s to %{public}s", + context->accesser.dmVersion.c_str(), preVersion.c_str()); + if (CompareVersion(context->accesser.dmVersion, preVersion) == false) { + LOGE("AuthSinkNegotiateStateMachine::Action incompatible version"); + context->reason = ERR_DM_VERSION_INCOMPATIBLE; + return ERR_DM_VERSION_INCOMPATIBLE; + } + + int32_t ret = ProcRespNegotiate5_1_0(context); + if (ret != DM_OK) { + LOGE("AuthSinkNegotiateStateMachine::Action proc response negotiate failed"); + return ret; + } + context->authMessageProcessor->CreateAndSendMsg(MSG_TYPE_RESP_ACL_NEGOTIATE, context); + context->timer->StartTimer(std::string(WAIT_REQUEST_TIMEOUT_TASK), + DmAuthState::GetTaskTimeout(context, WAIT_REQUEST_TIMEOUT_TASK, WAIT_REQUEST_TIMEOUT), + [this, context] (std::string name) { + DmAuthState::HandleAuthenticateTimeout(context, name); + }); + return DM_OK; +} + +/* +能力协商(80和90报文处理) +source端状态: +AuthIdleState, // 设备初始化时, 无需实现 +AuthSrcStartState, // 用户触发BindTarget +AuthSrcNegotiateState, // 收到软总线回调函数OnSessionOpened,发送80报文 + +sink端状态: +AuthIdleState, // 设备初始化时, 无需实现 +AuthSinkStartState, // 总线触发OnSessionOpened +AuthSinkNegotiateState, // 收到80可信关系协商报文,发送90报文 +*/ + +} // namespace DistributedHardware +} // namespace OHOS \ No newline at end of file diff --git a/services/implementation/src/authentication_v2/auth_stages/auth_pin_auth.cpp b/services/implementation/src/authentication_v2/auth_stages/auth_pin_auth.cpp new file mode 100644 index 000000000..aeb8191cf --- /dev/null +++ b/services/implementation/src/authentication_v2/auth_stages/auth_pin_auth.cpp @@ -0,0 +1,543 @@ +/* + * Copyright (c) 2025 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 "auth_manager.h" +#include "deviceprofile_connector.h" +#include "dm_anonymous.h" +#include "dm_auth_context.h" +#include "dm_auth_message_processor.h" +#include "dm_auth_state_machine.h" +#include "dm_auth_state.h" +#include "dm_auth_state_machine.h" +#include "dm_dialog_manager.h" +#include "dm_log.h" +#include "dm_random.h" +#include "hichain_auth_connector.h" +#include "multiple_user_connector.h" +#include "service_info_profile.h" + +namespace OHOS { +namespace DistributedHardware { + +constexpr int32_t MAX_AUTH_INPUT_PIN_FAIL_TIMES = 3; +constexpr int32_t MIN_PIN_CODE = 100000; +constexpr int32_t MAX_PIN_CODE = 999999; + +int32_t AuthSinkStatePinAuthComm::ShowAuthInfoDialog(std::shared_ptr context) +{ + LOGI("AuthSinkConfirmState::ShowAuthInfoDialog start"); + if (DmAuthState::IsScreenLocked()) { + LOGE("AuthSinkConfirmState::ShowAuthInfoDialog screen is locked."); + context->reason = ERR_DM_BIND_USER_CANCEL; + context->authStateMachine->NotifyEventFinish(DmEventType::ON_FAIL); + return STOP_BIND; + } + + JsonObject jsonObj; + jsonObj[PIN_CODE_KEY] = context->pinCode; + jsonObj[TOKENID] = context->accessee.tokenId; + const std::string params = jsonObj.Dump(); + + DmDialogManager::GetInstance().ShowPinDialog(params); + + context->timer->StartTimer(std::string(SESSION_HEARTBEAT_TIMEOUT_TASK), + DmAuthState::GetTaskTimeout(context, SESSION_HEARTBEAT_TIMEOUT_TASK, SESSION_HEARTBEAT_TIMEOUT), + [context] (std::string name) { + AuthSinkStatePinAuthComm::HandleSessionHeartbeat(context, name); + }); + return DM_OK; +} + +void AuthSinkStatePinAuthComm::HandleSessionHeartbeat(std::shared_ptr context, std::string name) +{ + context->timer->DeleteTimer(std::string(SESSION_HEARTBEAT_TIMEOUT_TASK)); + if (context->isFinished) { + return; + } + + LOGI("DmAuthManager::HandleSessionHeartbeat name %{public}s", name.c_str()); + JsonObject jsonObj; + jsonObj[TAG_SESSION_HEARTBEAT] = TAG_SESSION_HEARTBEAT; + std::string message = jsonObj.Dump(); + context->softbusConnector->GetSoftbusSession()->SendHeartbeatData(context->sessionId, message); + + context->timer->StartTimer(std::string(SESSION_HEARTBEAT_TIMEOUT_TASK), + DmAuthState::GetTaskTimeout(context, SESSION_HEARTBEAT_TIMEOUT_TASK, SESSION_HEARTBEAT_TIMEOUT), + [context] (std::string name) { + AuthSinkStatePinAuthComm::HandleSessionHeartbeat(context, name); + }); + + LOGI("DmAuthManager::HandleSessionHeartbeat complete."); +} + +bool AuthSinkStatePinAuthComm::IsPinCodeValid(int32_t numpin) +{ + if (numpin < MIN_PIN_CODE || numpin > MAX_PIN_CODE) { + return false; + } + return true; +} + +bool AuthSinkStatePinAuthComm::IsPinCodeValid(const std::string& strpin) +{ + if (strpin.empty()) { + return false; + } + for (size_t i = 0; i < strpin.length(); i++) { + if (!isdigit(strpin[i])) { + return false; + } + } + int32_t pinnum = std::atoi(strpin.c_str()); + return IsPinCodeValid(pinnum); +} + +bool AuthSinkStatePinAuthComm::IsAuthCodeReady(std::shared_ptr context) +{ + if (context->importAuthCode.empty() || context->importSessionName.empty()) { + LOGE("AuthSinkStatePinAuthComm::IsAuthCodeReady, auth code not ready with authCode %{public}s and " + "sessionName %{public}s.", context->importAuthCode.c_str(), context->importSessionName.c_str()); + return false; + } + if (context->sessionName != context->importSessionName) { + LOGE("AuthSinkNegotiateStateMachine::IsAuthCodeReady sessionName %{public}s not supported with " + "import sessionName %{public}s.", context->sessionName.c_str(), context->importSessionName.c_str()); + return false; + } + return true; +} + +void AuthSinkStatePinAuthComm::GeneratePincode(std::shared_ptr context) +{ + context->pinCode = GenRandInt(MIN_PIN_CODE, MAX_PIN_CODE); +} + +DmAuthStateType AuthSrcPinAuthStartState::GetStateType() +{ + return DmAuthStateType::AUTH_SRC_PIN_AUTH_START_STATE; +} + +int32_t AuthSrcPinAuthStartState::Action(std::shared_ptr context) +{ + LOGI("AuthSrcPinAuthStartState::Action start"); + // auth pincode + int32_t osAccountId = MultipleUserConnector::GetCurrentAccountUserID(); + auto ret = context->hiChainAuthConnector->AuthCredentialPinCode(osAccountId, context->requestId, + context->pinCode); + if (ret != DM_OK) { + LOGE("AuthSrcPinAuthStartState::AuthDevice call AuthCredentialPinCode failed."); + return ret; + } + // wait for onTransmit from hiChain + auto retEvent = context->authStateMachine->WaitExpectEvent(DmEventType::ON_TRANSMIT); + if (retEvent == DmEventType::ON_TRANSMIT) { + // send 120 msg + context->authMessageProcessor->CreateAndSendMsg(MSG_TYPE_REQ_PIN_AUTH_START, context); + return DM_OK; + } else if (retEvent == DmEventType::ON_ERROR) { + LOGI("AuthSrcPinAuthStartState::AuthDevice ON_ERROR failed, maybe retry."); + return DM_OK; + } + + return STOP_BIND; +} + +DmAuthStateType AuthSinkPinAuthStartState::GetStateType() +{ + return DmAuthStateType::AUTH_SINK_PIN_AUTH_START_STATE; +} + +int32_t AuthSinkPinAuthStartState::Action(std::shared_ptr context) +{ + LOGI("AuthSinkPinAuthStartState::Action start"); + context->timer->DeleteTimer(std::string(WAIT_REQUEST_TIMEOUT_TASK)); + if (!context->pinNegotiateStarted) { + context->pinNegotiateStarted = true; + context->timer->StartTimer(std::string(WAIT_PIN_AUTH_TIMEOUT_TASK), + DmAuthState::GetTaskTimeout(context, WAIT_PIN_AUTH_TIMEOUT_TASK, PIN_AUTH_TIMEOUT), + [context] (std::string name) { + HandleAuthenticateTimeout(context, name); + }); + } + + // Stop the abnormal authentication process + if (context->authTypeList.empty() || + (context->authResult != UiAction::USER_OPERATION_TYPE_ALLOW_AUTH && + context->authResult != UiAction::USER_OPERATION_TYPE_ALLOW_AUTH_ALWAYS)) { + LOGE("AuthSinkPinAuthStartState::Action invalid parameter."); + return ERR_DM_INPUT_PARA_INVALID; + } + + // process pincode auth + auto ret = context->hiChainAuthConnector->ProcessCredData(context->requestId, context->transmitData); + if (ret != DM_OK) { + LOGE("AuthSinkPinAuthStartState::Action call ProcessCredData err."); + return ret; + } + // wait for onTransmit from hiChain + auto retEvent = context->authStateMachine->WaitExpectEvent(DmEventType::ON_TRANSMIT); + if (retEvent == DmEventType::ON_TRANSMIT) { + // send 130 msg + context->authMessageProcessor->CreateAndSendMsg(MSG_TYPE_RESP_PIN_AUTH_START, context); + return DM_OK; + } + if (retEvent == DmEventType::ON_ERROR) { + LOGI("AuthSrcPinAuthStartState::AuthDevice ON_ERROR failed, maybe retry."); + return DM_OK; + } + return STOP_BIND; +} + +DmAuthStateType AuthSrcPinAuthMsgNegotiateState::GetStateType() +{ + return DmAuthStateType::AUTH_SRC_PIN_AUTH_MSG_NEGOTIATE_STATE; +} + +int32_t AuthSrcPinAuthMsgNegotiateState::Action(std::shared_ptr context) +{ + LOGI("AuthSrcPinAuthMsgNegotiateState::Action start"); + auto ret = context->hiChainAuthConnector->ProcessCredData(context->requestId, context->transmitData); + if (ret != DM_OK) { + LOGE("AuthSrcPinAuthMsgNegotiateState::Action call ProcessCredData err."); + return ret; + } + // wait for onTransmit from hiChain + auto retEvent = context->authStateMachine->WaitExpectEvent(DmEventType::ON_TRANSMIT); + if (retEvent == DmEventType::ON_TRANSMIT) { + // send 121 msg + context->authMessageProcessor->CreateAndSendMsg(MSG_TYPE_REQ_PIN_AUTH_MSG_NEGOTIATE, context); + return DM_OK; + } + if (retEvent == DmEventType::ON_ERROR) { + LOGI("AuthSrcPinAuthMsgNegotiateState::AuthDevice ON_ERROR failed, maybe retry."); + return DM_OK; + } + LOGE("AuthSrcPinAuthMsgNegotiateState::Action failed."); + return STOP_BIND; +} + +DmAuthStateType AuthSinkPinAuthMsgNegotiateState::GetStateType() +{ + return DmAuthStateType::AUTH_SINK_PIN_AUTH_MSG_NEGOTIATE_STATE; +} + +int32_t AuthSinkPinAuthMsgNegotiateState::Action(std::shared_ptr context) +{ + LOGI("AuthSinkPinAuthMsgNegotiateState::Action start"); + auto ret = context->hiChainAuthConnector->ProcessCredData(context->requestId, context->transmitData); + if (ret != DM_OK) { + LOGE("AuthSinkPinAuthMsgNegotiateState::Action call ProcessCredData err."); + return ret; + } + // wait for onTransmit from hiChain + auto retEvent = context->authStateMachine->WaitExpectEvent(DmEventType::ON_TRANSMIT); + if (retEvent == DmEventType::ON_TRANSMIT) { + // send 131 msg + context->authMessageProcessor->CreateAndSendMsg(MSG_TYPE_RESP_PIN_AUTH_MSG_NEGOTIATE, context); + } else if (retEvent == DmEventType::ON_ERROR) { + LOGI("AuthSinkPinAuthMsgNegotiateState::AuthDevice WAIT ON_TRANSMIT ON_ERROR failed, maybe retry."); + return DM_OK; + } else { + return STOP_BIND; + } + + retEvent = context->authStateMachine->WaitExpectEvent(DmEventType::ON_SESSION_KEY_RETURNED); + if (retEvent == DmEventType::ON_SESSION_KEY_RETURNED) { + retEvent = context->authStateMachine->WaitExpectEvent(DmEventType::ON_FINISH); + if (retEvent == DmEventType::ON_FINISH || retEvent == DmEventType::ON_ERROR) { + context->authStateMachine->TransitionTo(std::make_shared()); + return DM_OK; + } + } else if (retEvent == DmEventType::ON_ERROR) { + LOGI("AuthSinkPinAuthMsgNegotiateState::AuthDevice WAIT ON_SESSION_KEY_RETURNED ON_ERROR failed, maybe retry."); + return DM_OK; + } + + LOGE("AuthSinkPinAuthMsgNegotiateState::AuthDevice failed."); + return STOP_BIND; +} + +DmAuthStateType AuthSinkPinAuthDoneState::GetStateType() +{ + return DmAuthStateType::AUTH_SINK_PIN_AUTH_DONE_STATE; +} + +int32_t AuthSinkPinAuthDoneState::Action(std::shared_ptr context) +{ + LOGI("AuthSinkPinAuthDoneState Action"); + return DM_OK; +} + +DmAuthStateType AuthSrcPinAuthDoneState::GetStateType() +{ + return DmAuthStateType::AUTH_SRC_PIN_AUTH_DONE_STATE; +} + +int32_t AuthSrcPinAuthDoneState::Action(std::shared_ptr context) +{ + LOGI("AuthSrcPinAuthDoneState::Action start"); + std::string onTransmitData = context->transmitData; + if (context->hiChainAuthConnector->ProcessCredData(context->requestId, onTransmitData) != DM_OK) { + LOGE("AuthSrcPinAuthDoneState::Action failed, processCredData failed."); + return ERR_DM_FAILED; + } + + // wait for ON_SESSION_KEY_RETURNED from hichain + DmEventType ret = context->authStateMachine->WaitExpectEvent(ON_SESSION_KEY_RETURNED); + if (ret != ON_SESSION_KEY_RETURNED) { + if (ret == ON_ERROR) { + LOGE("AuthSrcPinAuthDoneState::Action, ON_SESSION_KEY_RETURNED event not arriverd, maybe retry."); + return DM_OK; + } else { + LOGE("AuthSrcPinAuthDoneState::Action failed, ON_SESSION_KEY_RETURNED event failed, other event arriverd."); + return ERR_DM_FAILED; + } + } + + // wait for ON_FINISH from hichain + ret = context->authStateMachine->WaitExpectEvent(ON_FINISH); + if (ret == ON_FINISH) { + LOGI("AuthSrcPinAuthDoneState::Action wait ON_FINISH done"); + return DM_OK; + } else if (ret == ON_ERROR) { + return DM_OK; + LOGE("AuthSrcPinAuthDoneState::Action, ON_FINISH event not arriverd, maybe retry."); + } + + return ERR_DM_FAILED; +} + +DmAuthStateType AuthSrcPinNegotiateStartState::GetStateType() +{ + return DmAuthStateType::AUTH_SRC_PIN_NEGOTIATE_START_STATE; +} + +int32_t AuthSrcPinNegotiateStartState::NegotiatePinAuth(std::shared_ptr context, bool firstTime) +{ + if (firstTime) { + if (context->authTypeList.empty()) { + LOGE("AuthSrcPinNegotiateStartState::Action authTypeList empty"); + context->reason = ERR_DM_AUTH_REJECT; + return ERR_DM_AUTH_REJECT; + } + context->currentAuthTypeIdx = 0; + context->authType = context->authTypeList[0]; + } else { + if (context->authType == DmAuthType::AUTH_TYPE_PIN && + context->inputPinAuthFailTimes < MAX_AUTH_INPUT_PIN_FAIL_TIMES) { + LOGI("AuthSrcPinNegotiateStartState::Action input pin auth err, retry"); + } else { + // try to fallback to next auth type + if (context->currentAuthTypeIdx + 1 >= context->authTypeList.size()) { + LOGE("AuthSrcPinNegotiateStartState::Action all auth type failed"); + context->reason = ERR_DM_AUTH_REJECT; + return ERR_DM_AUTH_REJECT; + } + context->currentAuthTypeIdx++; + context->authType = context->authTypeList[context->currentAuthTypeIdx]; + } + } + + // restart pin auth timer + context->timer->DeleteTimer(std::string(WAIT_PIN_AUTH_TIMEOUT_TASK)); + context->timer->StartTimer(std::string(WAIT_PIN_AUTH_TIMEOUT_TASK), + DmAuthState::GetTaskTimeout(context, WAIT_PIN_AUTH_TIMEOUT_TASK, PIN_AUTH_TIMEOUT), + [context] (std::string name) { + HandleAuthenticateTimeout(context, name); + }); + if (DmAuthState::IsImportAuthCodeCompatibility(context->authType)) { + if (AuthSinkStatePinAuthComm::IsAuthCodeReady(context)) { + context->authStateMachine->TransitionTo(std::make_shared()); + } else { + LOGE("AuthSrcPinNegotiateStartState::Action auth code not ready"); + context->reason = ERR_DM_INPUT_PARA_INVALID; + return ERR_DM_FAILED; + } + } else if (context->authType == DmAuthType::AUTH_TYPE_PIN) { + context->authStateMachine->TransitionTo(std::make_shared()); + } else if (context->authType == DmAuthType::AUTH_TYPE_PIN_ULTRASONIC) { + context->authStateMachine->TransitionTo(std::make_shared()); + } else { + LOGE("AuthSrcPinNegotiateStartState::Action authType not support"); + return ERR_DM_FAILED; + } + return DM_OK; +} +int32_t AuthSrcPinNegotiateStartState::Action(std::shared_ptr context) +{ + if (!context->pinNegotiateStarted) { + context->pinNegotiateStarted = true; + context->timer->DeleteTimer(std::string(CONFIRM_TIMEOUT_TASK)); + int32_t authResult = context->authResult; + if (authResult != UiAction::USER_OPERATION_TYPE_ALLOW_AUTH && + authResult != UiAction::USER_OPERATION_TYPE_ALLOW_AUTH_ALWAYS) { + LOGE("AuthSrcPinNegotiateStartState::Action authResult not allow"); + context->reason = ERR_DM_BIND_USER_CANCEL; + return ERR_DM_BIND_USER_CANCEL; + } + // import pin code auth always excute + if (DmAuthState::IsImportAuthCodeCompatibility(context->authType) && + (!context->authTypeList.empty()) && + DmAuthState::IsImportAuthCodeCompatibility(context->authTypeList[0])) { + return NegotiatePinAuth(context, true); + } else if (!context->accesser.credentialTypeLists.empty()) { + // have credential available, skip pin auth + context->authStateMachine->TransitionTo(std::make_shared()); + return DM_OK; + } + return NegotiatePinAuth(context, true); + } + return NegotiatePinAuth(context, false); +} + +DmAuthStateType AuthSrcPinInputState::GetStateType() +{ + return DmAuthStateType::AUTH_SRC_PIN_INPUT_STATE; +} + +int32_t AuthSrcPinInputState::ShowStartAuthDialog(std::shared_ptr context) +{ + LOGI("AuthSrcPinInputState::ShowStartAuthDialog start."); + if (DmAuthState::IsScreenLocked()) { + LOGE("AuthSrcPinInputState screen is locked."); + context->reason = ERR_DM_BIND_USER_CANCEL; + return STOP_BIND; + } + + JsonObject jsonObj; + jsonObj[TAG_TARGET_DEVICE_NAME] = context->accessee.deviceName; + jsonObj[TOKENID] = context->accesser.tokenId; + const std::string params = jsonObj.Dump(); + + DmDialogManager::GetInstance().ShowInputDialog(params); + LOGI("AuthSrcPinInputState::ShowStartAuthDialog end."); + return DM_OK; +} + +int32_t AuthSrcPinInputState::Action(std::shared_ptr context) +{ + LOGI("AuthSrcPinInputState::Action start"); + if (context->inputPinAuthFailTimes == 0) { + auto ret = ShowStartAuthDialog(context); + if (ret != DM_OK) { + return ret; + } + } else { + // clear input pin box, and show try again + context->authUiStateMgr->UpdateUiState(DmUiStateMsg::MSG_PIN_CODE_ERROR); + } + + LOGI("AuthSrcPinInputState::Action waitting user operation"); + // wait for user operation + if (DmEventType::ON_USER_OPERATION != + context->authStateMachine->WaitExpectEvent(DmEventType::ON_USER_OPERATION)) { + LOGI("AuthSrcPinInputState::Action wait ON_USER_OPERATION err"); + return STOP_BIND; + } + + if (context->pinInputResult != USER_OPERATION_TYPE_DONE_PINCODE_INPUT) { + LOGE("AuthSrcPinInputState::Action not USER_OPERATION_TYPE_DONE_PINCODE_INPUT err"); + return STOP_BIND; + } + context->authStateMachine->TransitionTo(std::make_shared()); + return DM_OK; +} + +DmAuthStateType AuthSinkPinNegotiateStartState::GetStateType() +{ + return DmAuthStateType::AUTH_SINK_PIN_NEGOTIATE_START_STATE; +} + +int32_t AuthSinkPinNegotiateStartState::Action(std::shared_ptr context) +{ + if (!context->pinNegotiateStarted) { + context->timer->DeleteTimer(std::string(WAIT_REQUEST_TIMEOUT_TASK)); + context->pinNegotiateStarted = true; + } else { + if (context->authType == DmAuthType::AUTH_TYPE_PIN && + context->inputPinAuthFailTimes < MAX_AUTH_INPUT_PIN_FAIL_TIMES) { + LOGI("AuthSinkPinNegotiateStartState::Action input pin auth err, retry"); + } else { + // try to fallback to next auth type + auto idx = context->currentAuthTypeIdx; + if (idx + 1 >= context->authTypeList.size()) { + LOGE("AuthSinkPinNegotiateStartState::Action all auth type failed"); + context->reason = ERR_DM_AUTH_REJECT; + return ERR_DM_AUTH_REJECT; + } + ++idx; + context->currentAuthTypeIdx = idx; + context->authType = context->authTypeList[idx]; + } + } + // restart pin auth timer + context->timer->DeleteTimer(std::string(WAIT_PIN_AUTH_TIMEOUT_TASK)); + context->timer->StartTimer(std::string(WAIT_PIN_AUTH_TIMEOUT_TASK), + DmAuthState::GetTaskTimeout(context, WAIT_PIN_AUTH_TIMEOUT_TASK, PIN_AUTH_TIMEOUT), + [context] (std::string name) { + HandleAuthenticateTimeout(context, name); + }); + if (DmAuthState::IsImportAuthCodeCompatibility(context->authType)) { + LOGI("AuthSinkPinNegotiateStartState::Action import auth code"); + } else if (context->authType == DmAuthType::AUTH_TYPE_PIN) { + LOGI("AuthSinkPinNegotiateStartState::Action input pin"); + context->authStateMachine->TransitionTo(std::make_shared()); + } else if (context->authType == DmAuthType::AUTH_TYPE_PIN_ULTRASONIC) { + LOGI("AuthSinkPinNegotiateStartState::Action ultrasonic pin"); + } else { + LOGE("AuthSrcPinNegotiateStartState::Action authType not support"); + return ERR_DM_FAILED; + } + return DM_OK; +} + +DmAuthStateType AuthSinkPinDisplayState::GetStateType() +{ + return DmAuthStateType::AUTH_SINK_PIN_DISPLAY_STATE; +} + +int32_t AuthSinkPinDisplayState::Action(std::shared_ptr context) +{ + if (context->inputPinAuthFailTimes == 0) { + // gen pincode + AuthSinkStatePinAuthComm::GeneratePincode(context); + // show pincode + return AuthSinkStatePinAuthComm::ShowAuthInfoDialog(context); + } + return DM_OK; +} + +DmAuthStateType AuthSrcPinNegotiateUltrasonicPinState::GetStateType() +{ + return DmAuthStateType::AUTH_SRC_PIN_NEGOTIATE_ULTRASONIC_PIN_STATE; +} + +int32_t AuthSrcPinNegotiateUltrasonicPinState::Action(std::shared_ptr context) +{ + return ERR_DM_FAILED; +} + +DmAuthStateType AuthSinkPinNegotiateUltrasonicPinState::GetStateType() +{ + return DmAuthStateType::AUTH_SINK_PIN_NEGOTIATE_ULTRASONIC_PIN_STATE; +} + +int32_t AuthSinkPinNegotiateUltrasonicPinState::Action(std::shared_ptr context) +{ + return ERR_DM_FAILED; +} + +} // namespace DistributedHardware +} // namespace OHOS \ No newline at end of file diff --git a/services/implementation/src/authentication_v2/dm_auth_context.cpp b/services/implementation/src/authentication_v2/dm_auth_context.cpp new file mode 100644 index 000000000..d2fe062f8 --- /dev/null +++ b/services/implementation/src/authentication_v2/dm_auth_context.cpp @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2025 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 "dm_auth_context.h" + +namespace OHOS { +namespace DistributedHardware { + +// 获取设备ID +std::string DmAuthContext::GetDeviceId(DmAuthSide side) +{ + const DmAccess &localAccess = (direction == DM_AUTH_SOURCE) ? accesser : accessee; + const DmAccess &remoteAccess = (direction == DM_AUTH_SOURCE) ? accessee : accesser; + return (side == DM_AUTH_LOCAL_SIDE) ? localAccess.deviceId : remoteAccess.deviceId; +} + +// 获取用户ID +int32_t DmAuthContext::GetUserId(DmAuthSide side) +{ + const DmAccess &localAccess = (direction == DM_AUTH_SOURCE) ? accesser : accessee; + const DmAccess &remoteAccess = (direction == DM_AUTH_SOURCE) ? accessee : accesser; + return (side == DM_AUTH_LOCAL_SIDE) ? localAccess.userId : remoteAccess.userId; +} + +// 获取凭据ID +std::string DmAuthContext::GetCredentialId(DmAuthSide side, DmAuthScope authorizedScope) +{ + const DmAccess &localAccess = (direction == DM_AUTH_SOURCE) ? accesser : accessee; + const DmAccess &remoteAccess = (direction == DM_AUTH_SOURCE) ? accessee : accesser; + const DmAccess &access = (side == DM_AUTH_LOCAL_SIDE) ? localAccess : remoteAccess; + return (authorizedScope == DM_AUTH_SCOPE_USER) ? access.lnnCredentialId : access.transmitCredentialId; +} + +// 获取公钥 +std::string DmAuthContext::GetPublicKey(DmAuthSide side, DmAuthScope authorizedScope) +{ + const DmAccess &localAccess = (direction == DM_AUTH_SOURCE) ? accesser : accessee; + const DmAccess &remoteAccess = (direction == DM_AUTH_SOURCE) ? accessee : accesser; + const DmAccess &access = (side == DM_AUTH_LOCAL_SIDE) ? localAccess : remoteAccess; + return (authorizedScope == DM_AUTH_SCOPE_USER) ? access.lnnPublicKey : access.ephemeralPublicKey; +} + +// 设置凭据ID +void DmAuthContext::SetCredentialId(DmAuthSide side, DmAuthScope authorizedScope, const std::string &credentialId) +{ + DmAccess &localAccess = (direction == DM_AUTH_SOURCE) ? accesser : accessee; + DmAccess &remoteAccess = (direction == DM_AUTH_SOURCE) ? accessee : accesser; + DmAccess &access = (side == DM_AUTH_LOCAL_SIDE) ? localAccess : remoteAccess; + std::string &credId = (authorizedScope == DM_AUTH_SCOPE_USER) ? + access.lnnCredentialId : access.transmitCredentialId; + credId = credentialId; + return; +} + +// 设置公钥 +void DmAuthContext::SetPublicKey(DmAuthSide side, DmAuthScope authorizedScope, const std::string &publicKey) +{ + DmAccess &localAccess = (direction == DM_AUTH_SOURCE) ? accesser : accessee; + DmAccess &remoteAccess = (direction == DM_AUTH_SOURCE) ? accessee : accesser; + DmAccess &access = (side == DM_AUTH_LOCAL_SIDE) ? localAccess : remoteAccess; + std::string &key = (authorizedScope == DM_AUTH_SCOPE_USER) ? + access.lnnPublicKey : access.ephemeralPublicKey; + key = publicKey; + + return; +} + +std::string DmAuthContext::GetAccountId(DmAuthSide side) +{ + DmAccess &localAccess = (direction == DM_AUTH_SOURCE) ? accesser : accessee; + DmAccess &remoteAccess = (direction == DM_AUTH_SOURCE) ? accessee : accesser; + return (side == DM_AUTH_LOCAL_SIDE) ? localAccess.accountId : remoteAccess.accountId; +} +} // namespace DistributedHardware +} // namespace OHOS \ No newline at end of file diff --git a/services/implementation/src/authentication_v2/dm_auth_manager_base.cpp b/services/implementation/src/authentication_v2/dm_auth_manager_base.cpp new file mode 100644 index 000000000..58087414e --- /dev/null +++ b/services/implementation/src/authentication_v2/dm_auth_manager_base.cpp @@ -0,0 +1,417 @@ +/* + * Copyright (c) 2025 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 "multiple_user_connector.h" +#include "os_account_manager.h" + +#include "dm_error_type.h" +#include "dm_auth_manager_base.h" + +#ifdef OS_ACCOUNT_PART_EXISTS +#include "os_account_manager.h" +using namespace OHOS::AccountSA; +#endif // OS_ACCOUNT_PART_EXISTS + +namespace OHOS { +namespace DistributedHardware { + +const char* DM_VERSION_4_1_5_1 = "4.1.5.1"; +const char* DM_VERSION_5_0_1 = "5.0.1"; +const char* DM_VERSION_5_0_2 = "5.0.2"; +const char* DM_VERSION_5_0_3 = "5.0.3"; +const char* DM_VERSION_5_0_4 = "5.0.4"; +const char* DM_VERSION_5_0_5 = "5.0.5"; +const char* DM_VERSION_5_1_0 = "5.1.0"; +const char* DM_VERSION_5_0_OLD_MAX = "5.0.9"; // 预估的旧版本最高版本号 + +const char* TAG_DMVERSION = "dmVersion"; +const char* TAG_EDITION = "edition"; +const char* TAG_DATA = "data"; +const char* TAG_DATA_LEN = "dataLen"; +const char* TAG_BUNDLE_NAME = "bundleName"; +const char* TAG_PEER_BUNDLE_NAME = "PEER_BUNDLE_NAME"; +const char* TAG_BIND_LEVEL = "bindLevel"; +const char* TAG_REPLY = "REPLY"; +const char* TAG_APP_THUMBNAIL2 = "appThumbnail"; // Naming Add 2 to resolve conflicts with TAG_APP_THUMBNAIL +const char* TAG_AUTH_FINISH = "isFinish"; +const char* TAG_LOCAL_USERID = "localUserId"; + +const char* APP_OPERATION_KEY = "appOperation"; +const char* TARGET_PKG_NAME_KEY = "targetPkgName"; +const char* CUSTOM_DESCRIPTION_KEY = "customDescription"; +const char* CANCEL_DISPLAY_KEY = "cancelPinCodeDisplay"; +const char* BUNDLE_NAME_KEY = "bundleName"; + +const char* AUTHENTICATE_TIMEOUT_TASK = "deviceManagerTimer:authenticate"; +const char* NEGOTIATE_TIMEOUT_TASK = "deviceManagerTimer:negotiate"; +const char* CONFIRM_TIMEOUT_TASK = "deviceManagerTimer:confirm"; +const char* INPUT_TIMEOUT_TASK = "deviceManagerTimer:input"; +const char* SESSION_HEARTBEAT_TIMEOUT_TASK = "deviceManagerTimer:sessionHeartbeat"; +const char* WAIT_REQUEST_TIMEOUT_TASK = "deviceManagerTimer:waitRequest"; +const char* AUTH_DEVICE_TIMEOUT_TASK = "deviceManagerTimer:authDevice_"; +const char* WAIT_PIN_AUTH_TIMEOUT_TASK = "deviceManagerTimer:waitPinAuth"; +const char* WAIT_NEGOTIATE_TIMEOUT_TASK = "deviceManagerTimer:waitNegotiate"; +const char* ADD_TIMEOUT_TASK = "deviceManagerTimer:add"; +const char* WAIT_SESSION_CLOSE_TIMEOUT_TASK = "deviceManagerTimer:waitSessionClose"; +const char* CLOSE_SESSION_TASK_SEPARATOR = "#"; + +const int32_t AUTHENTICATE_TIMEOUT = 120; +const int32_t CONFIRM_TIMEOUT = 60; +const int32_t NEGOTIATE_TIMEOUT = 10; +const int32_t INPUT_TIMEOUT = 60; +const int32_t ADD_TIMEOUT = 10; +const int32_t WAIT_NEGOTIATE_TIMEOUT = 10; +const int32_t WAIT_REQUEST_TIMEOUT = 10; +const int32_t CLONE_AUTHENTICATE_TIMEOUT = 20; +const int32_t CLONE_CONFIRM_TIMEOUT = 10; +const int32_t CLONE_NEGOTIATE_TIMEOUT = 10; +const int32_t CLONE_ADD_TIMEOUT = 10; +const int32_t CLONE_WAIT_NEGOTIATE_TIMEOUT = 10; +const int32_t CLONE_WAIT_REQUEST_TIMEOUT = 10; +const int32_t CLONE_SESSION_HEARTBEAT_TIMEOUT = 20; +const int32_t CLONE_PIN_AUTH_TIMEOUT = 10; +const int32_t HML_SESSION_TIMEOUT = 10; +const int32_t SESSION_HEARTBEAT_TIMEOUT = 50; +const int32_t PIN_AUTH_TIMEOUT = 60; +const int32_t EVENT_TIMEOUT = 5000; // 5000 ms + + +int32_t AuthManagerBase::AuthenticateDevice(const std::string &pkgName, int32_t authType, + const std::string &deviceId, const std::string &extra) +{ + LOGE("AuthenticateDevice is not implemented in the current version"); + return ERR_DM_FAILED; +} + +int32_t AuthManagerBase::UnAuthenticateDevice(const std::string &pkgName, const std::string &udid, int32_t bindLevel) +{ + LOGE("UnAuthenticateDevice is not implemented in the current version"); + return ERR_DM_FAILED; +} + +int32_t AuthManagerBase::UnBindDevice(const std::string &pkgName, const std::string &udid, + int32_t bindLevel, const std::string &extra) +{ + LOGE("UnBindDevice is not implemented in the current version"); + return ERR_DM_FAILED; +} + +void AuthManagerBase::OnSessionOpened(int32_t sessionId, int32_t sessionSide, int32_t result) +{ + LOGE("OnSessionOpened is not implemented in the current version"); +} + +void AuthManagerBase::OnSessionClosed(const int32_t sessionId) +{ + LOGE("OnSessionClosed is not implemented in the current version"); +} + +void AuthManagerBase::OnDataReceived(const int32_t sessionId, const std::string message) +{ + LOGE("OnDataReceived is not implemented in the current version"); +} + +void AuthManagerBase::OnGroupCreated(int64_t requestId, const std::string &groupId) +{ + LOGE("OnGroupCreated is not implemented in the current version"); +} + +void AuthManagerBase::OnMemberJoin(int64_t requestId, int32_t status) +{ + LOGE("OnMemberJoin is not implemented in the current version"); +} + +int32_t AuthManagerBase::EstablishAuthChannel(const std::string &deviceId) +{ + LOGE("EstablishAuthChannel is not implemented in the current version"); + return ERR_DM_FAILED; +} + +void AuthManagerBase::StartNegotiate(const int32_t &sessionId) +{ + LOGE("StartNegotiate is not implemented in the current version"); +} + +void AuthManagerBase::RespNegotiate(const int32_t &sessionId) +{ + LOGE("RespNegotiate is not implemented in the current version"); +} + +void AuthManagerBase::SendAuthRequest(const int32_t &sessionId) +{ + LOGE("SendAuthRequest is not implemented in the current version"); +} + +int32_t AuthManagerBase::StartAuthProcess(const int32_t &action) +{ + LOGE("StartAuthProcess is not implemented in the current version"); + return ERR_DM_FAILED; +} + +void AuthManagerBase::StartRespAuthProcess() +{ + LOGE("StartRespAuthProcess is not implemented in the current version"); +} + +int32_t AuthManagerBase::CreateGroup() +{ + LOGE("CreateGroup is not implemented in the current version"); + return ERR_DM_FAILED; +} + +int32_t AuthManagerBase::ProcessPincode(int32_t pinCode) +{ + LOGE("ProcessPincode is not implemented in the current version"); + return ERR_DM_FAILED; +} + +std::string AuthManagerBase::GetConnectAddr(std::string deviceId) +{ + LOGE("GetConnectAddr is not implemented in the current version"); + return ""; +} + +int32_t AuthManagerBase::JoinNetwork() +{ + LOGE("JoinNetwork is not implemented in the current version"); + return ERR_DM_FAILED; +} + +void AuthManagerBase::AuthenticateFinish() +{ + LOGE("AuthenticateFinish is not implemented in the current version"); +} + +bool AuthManagerBase::GetIsCryptoSupport() +{ + LOGE("GetIsCryptoSupport is not implemented in the current version"); + return false; +} + +int32_t AuthManagerBase::SetAuthRequestState(std::shared_ptr authRequestState) +{ + LOGE("SetAuthRequestState is not implemented in the current version"); + return ERR_DM_FAILED; +} + +int32_t AuthManagerBase::SetAuthResponseState(std::shared_ptr authResponseState) +{ + LOGE("SetAuthResponseState is not implemented in the current version"); + return ERR_DM_FAILED; +} + +int32_t AuthManagerBase::GetPinCode(int32_t &code) +{ + LOGE("GetPinCode is not implemented in the current version"); + return ERR_DM_FAILED; +} + +std::string AuthManagerBase::GenerateGroupName() +{ + LOGE("GenerateGroupName is not implemented in the current version"); + return ""; +} + +void AuthManagerBase::HandleAuthenticateTimeout(std::string name) +{ + LOGE("HandleAuthenticateTimeout is not implemented in the current version"); +} + +int32_t AuthManagerBase::GeneratePincode() +{ + LOGE("GeneratePincode is not implemented in the current version"); + return ERR_DM_FAILED; +} + +void AuthManagerBase::ShowConfigDialog() +{ + LOGE("ShowConfigDialog is not implemented in the current version"); +} + +void AuthManagerBase::ShowAuthInfoDialog(bool authDeviceError) +{ + LOGE("ShowAuthInfoDialog is not implemented in the current version"); +} + +void AuthManagerBase::ShowStartAuthDialog() +{ + LOGE("ShowStartAuthDialog is not implemented in the current version"); +} + +int32_t AuthManagerBase::OnUserOperation(int32_t action, const std::string ¶ms) +{ + LOGE("OnUserOperation is not implemented in the current version"); + return ERR_DM_FAILED; +} + +int32_t AuthManagerBase::SetPageId(int32_t pageId) +{ + LOGE("SetPageId is not implemented in the current version"); + return ERR_DM_FAILED; +} + +int32_t AuthManagerBase::SetReasonAndFinish(int32_t reason, int32_t state) +{ + LOGE("SetReasonAndFinish is not implemented in the current version"); + return ERR_DM_FAILED; +} + +bool AuthManagerBase::IsIdenticalAccount() +{ + LOGE("IsIdenticalAccount is not implemented in the current version"); + return false; +} + +int32_t AuthManagerBase::RegisterUiStateCallback(const std::string pkgName) +{ + LOGE("RegisterUiStateCallback is not implemented in the current version"); + return ERR_DM_FAILED; +} + +int32_t AuthManagerBase::UnRegisterUiStateCallback(const std::string pkgName) +{ + LOGE("UnRegisterUiStateCallback is not implemented in the current version"); + return ERR_DM_FAILED; +} + +int32_t AuthManagerBase::ImportAuthCode(const std::string &pkgName, const std::string &authCode) +{ + LOGE("ImportAuthCode is not implemented in the current version"); + return ERR_DM_FAILED; +} + +int32_t AuthManagerBase::BindTarget(const std::string &pkgName, const PeerTargetId &targetId, + const std::map &bindParam, int sessionId, int64_t logicalSessionId) +{ + LOGE("BindTarget is not implemented in the current version"); + return ERR_DM_FAILED; +} + +int32_t AuthManagerBase::RegisterAuthenticationType(int32_t authenticationType) +{ + LOGE("RegisterAuthenticationType is not implemented in the current version"); + return ERR_DM_FAILED; +} + +int32_t AuthManagerBase::StopAuthenticateDevice(const std::string &pkgName) +{ + LOGE("StopAuthenticateDevice is not implemented in the current version"); + return ERR_DM_FAILED; +} + +int32_t AuthManagerBase::DeleteGroup(const std::string &pkgName, const std::string &deviceId) +{ + LOGE("DeleteGroup is not implemented in the current version"); + return ERR_DM_FAILED; +} + +int32_t AuthManagerBase::GetReason() +{ + LOGE("GetReason is not implemented in the current version"); + return ERR_DM_FAILED; +} + +void AuthManagerBase::GetBindTargetParams(std::string &pkgName, PeerTargetId &targetId, + std::map &bindParam) +{ + LOGE("GetBindTargetParams is not implemented in the current version"); + return; +} + +void AuthManagerBase::RegisterCleanNotifyCallback(CleanNotifyCallback cleanNotifyCallback) +{ + LOGE("RegisterCleanNotifyCallback is not implemented in the current version"); + return; +} + +std::string AuthManagerBase::ConvertSrcVersion(const std::string &version, const std::string &edition) +{ + std::string srcVersion = ""; + if (version == "" && edition != "") { + srcVersion = edition; + } else if (version == "" && edition == "") { + srcVersion = DM_VERSION_5_1_0; + } else if (version != "" && edition == "") { + srcVersion = version; + } + LOGI("ConvertSrcVersion version %{public}s, edition %{public}s, srcVersion is %{public}s.", + version.c_str(), edition.c_str(), srcVersion.c_str()); + return srcVersion; +} + +std::string AuthManagerBase::ConvertSinkVersion(const std::string &version) +{ + std::string sinkVersion = ""; + if (version == "") { + sinkVersion = DM_VERSION_4_1_5_1; + } else { + sinkVersion = version; + } + LOGI("ConvertSinkVersion version %{public}s, sinkVersion is %{public}s.", version.c_str(), sinkVersion.c_str()); + return sinkVersion; +} + +// 场景1:对端指定了userId -> 校验是否为前台用户 +// 场景2:对端未指定userId +// 场景2.1: 单用户 -> 使用当前唯一前台用户 +// 场景2.2: 多用户 -> 使用当前主屏用户 +int32_t AuthManagerBase::DmGetUserId(int32_t displayId, int32_t targetUserId) +{ + int32_t ret; + int32_t userId = -1; + + std::vector userIds; + ret = MultipleUserConnector::GetForegroundUserIds(userIds); + if (ret != DM_OK) { + LOGE("RespQueryTokenId: GetForegroundUserIds failed, ret: %{public}d", ret); + return -1; + } + // 场景1:对端指定了userId -> 校验是否为前台用户 + // 场景2:对端未指定userId + // 场景2.1: 单用户 -> 使用当前唯一前台用户 + // 场景2.2: 多用户 -> 使用当前主屏用户 + if (userIds.size() == 0) { + LOGE("RespQueryTokenId: GetForegroundUserIds no foreground users"); + return -1; + } + + if (displayId != -1) { + ret = AccountSA::OsAccountManager::GetForegroundOsAccountLocalId(displayId, userId); + if (ret != DM_OK) { + LOGE("RespQueryTokenId: fail to get userId by displayId %{public}d", displayId); + return -1; + } + return userId; + } + if (userIds.size() == 1) { + return userIds[0]; + } else { + // userIds.size() > 1的情况下,需要找到主屏用户 +#ifdef OS_ACCOUNT_PART_EXISTS + ret = AccountSA::OsAccountManager::GetForegroundOsAccountLocalId(userId); + if (ret != DM_OK) { + LOGE("AuthManagerBase::DmGetUserId: get foreground user failed in multi users with error %{public}d", ret); + return -1; + } + return userId; +#else + LOGE("AuthManagerBase::DmGetUserId: get foreground user failed because no OsAcccountManager"); + return -1; +#endif + } +} + +} // namespace DistributedHardware +} // namespace OHOS \ No newline at end of file diff --git a/services/implementation/src/authentication_v2/dm_auth_message_processor.cpp b/services/implementation/src/authentication_v2/dm_auth_message_processor.cpp new file mode 100644 index 000000000..3c8944b7a --- /dev/null +++ b/services/implementation/src/authentication_v2/dm_auth_message_processor.cpp @@ -0,0 +1,1461 @@ +/* + * Copyright (c) 2025 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 +#include +#include +#include +#include "dm_anonymous.h" +#include "dm_auth_context.h" +#include "dm_auth_message_processor.h" +#include "distributed_device_profile_client.h" +#include "deviceprofile_connector.h" +#include "service_info_profile.h" +#include "service_info_unique_key.h" +#include "dm_log.h" +#include "dm_constants.h" +#include "dm_anonymous.h" +#include "access_control_profile.h" +#include "dm_auth_manager_base.h" +#include "dm_auth_context.h" +#include "dm_auth_state_machine.h" +#include "dm_crypto.h" + +namespace OHOS { +namespace DistributedHardware { + +const char* TAG_LNN_PUBLICK_KEY = "lnnPublicKey"; +const char* TAG_TRANSMIT_PUBLICK_KEY = "ephemeralPublicKey"; +const char* TAG_LNN_CREDENTIAL_ID = "lnnCredentialId"; +const char* TAG_TRANSMIT_CREDENTIAL_ID = "transmitCredentialId"; +const char* TAG_AUTH_RESULT = "authResult"; +const char* TAG_AUTH_TYPE_LIST = "authTypeList"; +const char* TAG_CURRENT_AUTH_TYPE_IDX = "currentAuthTypeIdx"; + +// IS interface input parameter json format string key +const char* TAG_METHOD = "method"; +const char* TAG_PEER_USER_SPACE_ID = "peerUserSpaceId"; +const char* TAG_SUBJECT = "subject"; +const char* TAG_CRED_TYPE = "credType"; +const char* TAG_KEY_FORMAT = "keyFormat"; +const char* TAG_ALGORITHM_TYPE = "algorithmType"; +const char* TAG_PROOF_TYPE = "proofType"; +const char* TAG_KEY_VALUE = "keyValue"; +const char* TAG_AUTHORIZED_SCOPE = "authorizedScope"; +const char* TAG_AUTHRIZED_APP_LIST = "authorizedAppList"; +const char* TAG_CREDENTIAL_OWNER = "credOwner"; +const char* TAG_SYNC = "syncMessage"; +const char* TAG_ACCESS = "dmAccess"; +const char* TAG_PROXY = "proxy"; +const char* TAG_ACL = "accessControlTable"; +const char* TAG_ACCESSER = "dmAccesser"; +const char* TAG_ACCESSEE = "dmAccessee"; +const char* TAG_SERVICEINFO = "serviceInfo"; +// The local SK information is synchronized to the remote end to construct acl-accesser/accessee. +const char* TAG_TRANSMIT_SK_ID = "accessAppSKId"; +const char* TAG_LNN_SK_ID = "accessUserSKId"; +const char* TAG_TRANSMIT_SK_TIMESTAMP = "accessAppSKTimeStamp"; +const char* TAG_LNN_SK_TIMESTAMP = "accessUserSKTimeStamp"; +const char* TAG_TOKEN_ID = "tokenId"; +const char* TAG_ISSUER = "issuer"; + +const char* TAG_DEVICE_VERSION = "deviceVersion"; +const char* TAG_DEVICE_NAME = "deviceName"; +const char* TAG_DEVICE_ID_HASH = "deviceIdHash"; +const char* TAG_USER_ID_HASH = "userIdHash"; +const char* TAG_ACCOUNT_ID_HASH = "accountIdHash"; +const char* TAG_TOKEN_ID_HASH = "tokenIdHash"; +const char* TAG_SESSION_NAME = "sessionName"; +const char* TAG_ACL_CHECKSUM = "aclCheckSum"; +const char* TAG_COMPRESS_ORI_LEN = "compressOriLen"; +const char* TAG_COMPRESS = "compressMsg"; +const char* TAG_STATE = "state"; +const char* TAG_REASON = "reason"; +const char* TAG_PEER_USER_ID = "peerUserId"; +const char* TAG_PEER_DISPLAY_ID = "peerDisplayId"; +const char* TAG_EXTRA_INFO = "extraInfo"; + +const char* TAG_IS_ONLINE = "isOnline"; +const char* TAG_IS_AUTHED = "isAuthed"; +const char* TAG_CREDENTIAL_INFO = "credentialInfo"; +const char* TAG_CERT_INFO = "certInfo"; +const char* TAG_LANGUAGE = "language"; + +// Accesser table content is used for ACL synchronization. +const char* TAG_ACCESSER_DEVICE_ID = "accesserDeviceId"; +const char* TAG_ACCESSER_USER_ID = "accesserUserId"; +const char* TAG_ACCESSER_ACOUNT_ID = "accesserAcountId"; +const char* TAG_ACCESSER_TOKEN_ID = "accesserTokenId"; +const char* TAG_ACCESSER_SERVICE_NAME = "accesserServiceName"; +const char* TAG_ACCESSER_BUNDLE_NAME = "accesserBundleName"; +const char* TAG_ACCESSER_HAP_SIGNATURE = "accesserHapSignature"; +const char* TAG_ACCESSER_BIND_LEVEL = "accesserBindLevel"; +const char* TAG_ACCESSER_CREDENTIAL_ID = "accesserCredetialId"; +const char* TAG_ACCESSER_STATUS = "accesserStatus"; +const char* TAG_ACCESSER_SK_ID = "accesserSessionKeyId"; +const char* TAG_ACCESSER_SK_TIMESTAMP = "accesserSKTimeStamp"; + +// Accessee table content is used for ACL synchronization. +const char* TAG_ACCESSEE_DEVICE_ID = "accesseeDeviceId"; +const char* TAG_ACCESSEE_USER_ID = "accesseeUserId"; +const char* TAG_ACCESSEE_ACOUNT_ID = "accesseeAcountId"; +const char* TAG_ACCESSEE_TOKEN_ID = "accesseeTokenId"; +const char* TAG_ACCESSEE_SERVICE_NAME = "accesseeServiceName"; +const char* TAG_ACCESSEE_BUNDLE_NAME = "accesseeBundleName"; +const char* TAG_ACCESSEE_HAP_SIGNATURE = "accesseeHapSignature"; +const char* TAG_ACCESSEE_BIND_LEVEL = "accesseeBindLevel"; +const char* TAG_ACCESSEE_CREDENTIAL_ID = "accesseeCredetialId"; +const char* TAG_ACCESSEE_STATUS = "accesseeStatus"; +const char* TAG_ACCESSEE_SK_ID = "accesseeSessionKeyId"; +const char* TAG_ACCESSEE_SK_TIMESTAMP = "accesseeSKTimeStamp"; + +namespace { + +constexpr const int32_t DM_HASH_LEN = 32; +const char* TAG_DEVICE_TYPE = "DEVICETYPE"; + +void CreateNegotiateExtraInfoMessage(std::shared_ptr context, JsonItemObject &jsonExtraObject) +{ + if (context->accessee.displayId != 0) { + jsonExtraObject[TAG_PEER_DISPLAY_ID] = context->accessee.displayId; + } + if (context->accessee.userId != 0) { + jsonExtraObject[TAG_ACCESSEE_USER_ID] = context->accessee.userId; + } + + return; +} + +void ParseNegotiateExtraInfoMessage(const JsonItemObject &jsonExtraObject, std::shared_ptr context) +{ + if (jsonExtraObject[TAG_ACCESSEE_USER_ID].IsNumberInteger()) { + context->accessee.userId = jsonExtraObject[TAG_ACCESSEE_USER_ID].Get(); + } else if (jsonExtraObject[TAG_PEER_DISPLAY_ID].IsNumberInteger()) { + context->accessee.displayId = jsonExtraObject[TAG_PEER_DISPLAY_ID].Get(); + } + return; +} + +void ParseDmAccessToSync(const std::string &jsonString, DmAccess &access) +{ + JsonObject accessjson(jsonString); + DmAccessToSync srcAccessToSync = accessjson.Get(); + access.deviceName = srcAccessToSync.deviceName; + access.deviceId = srcAccessToSync.deviceId; + access.userId = srcAccessToSync.userId; + access.accountId = srcAccessToSync.accountId; + access.tokenId = srcAccessToSync.tokenId; + access.bundleName = srcAccessToSync.bundleName; + access.bindLevel = srcAccessToSync.bindLevel; + access.sessionKeyId = srcAccessToSync.sessionKeyId; + access.skTimeStamp = srcAccessToSync.skTimeStamp; + return; +} + +int32_t ParaseAclChecksumList(const std::string &jsonString, DmAccess &access) +{ + JsonObject aclChecksumjson(jsonString); + if (aclChecksumjson.IsDiscarded()) { + LOGE("ParseSyncMessage aclChecksumjson error"); + return ERR_DM_FAILED; + } + if (!aclChecksumjson[TAG_ACCESSER].IsArray()) { + LOGE("ParseSyncMessage TAG_ACCESSER error"); + return ERR_DM_FAILED; + } + aclChecksumjson[TAG_ACCESSER].Get(access.accesserStrList); + if (!aclChecksumjson[TAG_ACCESSEE].IsArray()) { + LOGE("ParseSyncMessage TAG_ACCESSEE error"); + return ERR_DM_FAILED; + } + aclChecksumjson[TAG_ACCESSEE].Get(access.accesseeStrList); + return DM_OK; +} + +bool IsMessageValid(const JsonItemObject &jsonObject) +{ + if (jsonObject.IsDiscarded()) { + LOGE("DmAuthMessageProcessor::ParseMessage failed, decodeRequestAuth jsonStr error"); + return false; + } + if (!jsonObject[TAG_MSG_TYPE].IsNumberInteger()) { + LOGE("DmAuthMessageProcessor::ParseMessage failed, message type error."); + return false; + } + return true; +} + +} + +int32_t DmAuthMessageProcessor::SaveSessionKey(const uint8_t *sessionKey, const uint32_t keyLen) +{ + if (cryptoMgr_ == nullptr) { + LOGE("DmAuthMessageProcessor::SaveSessionKey failed, cryptoMgr_ is nullptr."); + return ERR_DM_FAILED; + } + return cryptoMgr_->SaveSessionKey(sessionKey, keyLen); +} + +int32_t DmAuthMessageProcessor::SaveSessionKeyToDP(int32_t &skId) +{ + if (cryptoMgr_ == nullptr) { + LOGE("DmAuthMessageProcessor::SaveSessionKey failed, cryptoMgr_ is nullptr."); + return ERR_DM_FAILED; + } + uint32_t skLen = cryptoMgr_->GetSessionKey(nullptr); + uint8_t sessionKey[skLen]; + skLen = cryptoMgr_->GetSessionKey(sessionKey); + std::vector sk(sessionKey, sessionKey + skLen); + return DeviceProfileConnector::GetInstance().PutSessionKey(sk, skId); +} + +void DmAuthMessageProcessor::SetAccessControlList(std::shared_ptr context, + DistributedDeviceProfile::AccessControlProfile &profile) +{ + uint32_t bindType = DM_ACROSS_ACCOUNT; + if (context->accesser.accountId == "ohosAnonymousUid" || context->accessee.accountId == "ohosAnonymousUid") { + bindType = DM_POINT_TO_POINT; + } + uint32_t authenticationType = ALLOW_AUTH_ONCE; + if (context->authResult == USER_OPERATION_TYPE_ALLOW_AUTH_ALWAYS) { + authenticationType = ALLOW_AUTH_ALWAYS; + } + profile.SetBindType(bindType); + profile.SetAuthenticationType(authenticationType); + profile.SetStatus(ACTIVE); + profile.SetDeviceIdType((int32_t)DistributedDeviceProfile::DeviceIdType::UDID); +} + +void DmAuthMessageProcessor::SetTransmitAccessControlList(std::shared_ptr context, + DistributedDeviceProfile::Accesser &accesser, DistributedDeviceProfile::Accessee &accessee) +{ + accesser.SetAccesserDeviceId(context->accesser.deviceId); + accesser.SetAccesserUserId(context->accesser.userId); + accesser.SetAccesserAccountId(context->accesser.accountId); + accesser.SetAccesserTokenId(context->accesser.tokenId); + accesser.SetAccesserBundleName(context->accesser.bundleName); + accesser.SetAccesserDeviceName(context->accesser.deviceName); + accesser.SetAccesserCredentialId(context->accesser.transmitCredentialId); + accesser.SetAccesserSessionKeyId(context->accesser.transmitSessionKeyId); + accesser.SetAccesserSKTimeStamp(context->accesser.transmitSkTimeStamp); + accessee.SetAccesseeDeviceId(context->accessee.deviceId); + accessee.SetAccesseeUserId(context->accessee.userId); + accessee.SetAccesseeAccountId(context->accessee.accountId); + accessee.SetAccesseeTokenId(context->accessee.tokenId); + accessee.SetAccesseeBundleName(context->accessee.bundleName); + accessee.SetAccesseeDeviceName(context->accessee.deviceName); + accessee.SetAccesseeCredentialId(context->accessee.transmitCredentialId); + accessee.SetAccesseeSessionKeyId(context->accessee.transmitSessionKeyId); + accessee.SetAccesseeSKTimeStamp(context->accessee.transmitSkTimeStamp); +} + +void DmAuthMessageProcessor::SetLnnAccessControlList(std::shared_ptr context, + DistributedDeviceProfile::Accesser &accesser, DistributedDeviceProfile::Accessee &accessee) +{ + accesser.SetAccesserDeviceId(context->accesser.deviceId); + accesser.SetAccesserUserId(context->accesser.userId); + accesser.SetAccesserAccountId(context->accesser.accountId); + accesser.SetAccesserTokenId(0); + accesser.SetAccesserDeviceName(context->accesser.deviceName); + accesser.SetAccesserCredentialId(context->accesser.lnnCredentialId); + accesser.SetAccesserSessionKeyId(context->accesser.lnnSessionKeyId); + accesser.SetAccesserSKTimeStamp(context->accesser.lnnSkTimeStamp); + accessee.SetAccesseeDeviceId(context->accessee.deviceId); + accessee.SetAccesseeUserId(context->accessee.userId); + accessee.SetAccesseeAccountId(context->accessee.accountId); + accessee.SetAccesseeTokenId(0); + accessee.SetAccesseeDeviceName(context->accessee.deviceName); + accessee.SetAccesseeCredentialId(context->accessee.lnnCredentialId); + accessee.SetAccesseeSessionKeyId(context->accessee.lnnSessionKeyId); + accessee.SetAccesseeSKTimeStamp(context->accessee.lnnSkTimeStamp); +} + +int32_t DmAuthMessageProcessor::PutAccessControlList(std::shared_ptr context, + DmAccess &access, std::string trustDeviceId) +{ + LOGI("Start."); + DistributedDeviceProfile::Accesser accesser; + DistributedDeviceProfile::Accessee accessee; + SetLnnAccessControlList(context, accesser, accessee); + DistributedDeviceProfile::AccessControlProfile profile; + SetAccessControlList(context, profile); + profile.SetBindLevel(access.bindLevel); + profile.SetTrustDeviceId(trustDeviceId); + profile.SetDeviceIdHash(access.deviceIdHash); + profile.SetAccessee(accessee); + profile.SetAccesser(accesser); + int32_t ret = + DistributedDeviceProfile::DistributedDeviceProfileClient::GetInstance().PutAccessControlProfile(profile); + if (ret != DM_OK) { + LOGE("PutAccessControlProfile failed."); + } + SetTransmitAccessControlList(context, accesser, accessee); + profile.SetAccessee(accessee); + profile.SetAccesser(accesser); + ret = + DistributedDeviceProfile::DistributedDeviceProfileClient::GetInstance().PutAccessControlProfile(profile); + if (ret != DM_OK) { + LOGE("PutAccessControlProfile failed."); + } + return ret; +} + +DmAuthMessageProcessor::DmAuthMessageProcessor() +{ + LOGI("DmAuthMessageProcessor constructor"); + cryptoMgr_ = std::make_shared(); + createMessageFuncMap_ = { + {DmMessageType::MSG_TYPE_REQ_ACL_NEGOTIATE, &DmAuthMessageProcessor::CreateNegotiateMessage}, + {DmMessageType::MSG_TYPE_RESP_ACL_NEGOTIATE, &DmAuthMessageProcessor::CreateRespNegotiateMessage}, + {DmMessageType::MSG_TYPE_REQ_USER_CONFIRM, &DmAuthMessageProcessor::CreateMessageReqUserConfirm}, + {DmMessageType::MSG_TYPE_RESP_USER_CONFIRM, &DmAuthMessageProcessor::CreateMessageRespUserConfirm}, + {DmMessageType::MSG_TYPE_REQ_PIN_AUTH_START, &DmAuthMessageProcessor::CreateMessageReqPinAuthStart}, + {DmMessageType::MSG_TYPE_REQ_PIN_AUTH_MSG_NEGOTIATE, &DmAuthMessageProcessor::CreateMessageReqPinAuthNegotiate}, + {DmMessageType::MSG_TYPE_RESP_PIN_AUTH_START, &DmAuthMessageProcessor::CreateMessageRespPinAuthStart}, + {DmMessageType::MSG_TYPE_RESP_PIN_AUTH_MSG_NEGOTIATE, + &DmAuthMessageProcessor::CreateMessageRespPinAuthNegotiate}, + {DmMessageType::MSG_TYPE_REQ_CREDENTIAL_EXCHANGE, &DmAuthMessageProcessor::CreateMessageReqCredExchange}, + {DmMessageType::MSG_TYPE_RESP_CREDENTIAL_EXCHANGE, &DmAuthMessageProcessor::CreateMessageRspCredExchange}, + {DmMessageType::MSG_TYPE_REQ_CREDENTIAL_AUTH_START, &DmAuthMessageProcessor::CreateMessageReqCredAuthStart}, + {DmMessageType::MSG_TYPE_REQ_CREDENTIAL_AUTH_NEGOTIATE, + &DmAuthMessageProcessor::CreateCredentialNegotiateMessage}, + {DmMessageType::MSG_TYPE_RESP_CREDENTIAL_AUTH_START, &DmAuthMessageProcessor::CreateCredentialNegotiateMessage}, + {DmMessageType::MSG_TYPE_RESP_CREDENTIAL_AUTH_NEGOTIATE, + &DmAuthMessageProcessor::CreateCredentialNegotiateMessage}, + {DmMessageType::MSG_TYPE_REQ_DATA_SYNC, &DmAuthMessageProcessor::CreateSyncMessage}, + {DmMessageType::MSG_TYPE_RESP_DATA_SYNC, &DmAuthMessageProcessor::CreateMessageSyncResp}, + {DmMessageType::MSG_TYPE_AUTH_REQ_FINISH, &DmAuthMessageProcessor::CreateMessageFinish}, + {DmMessageType::MSG_TYPE_AUTH_RESP_FINISH, &DmAuthMessageProcessor::CreateMessageFinish}, + }; + paraseMessageFuncMap_ = { + {DmMessageType::MSG_TYPE_REQ_ACL_NEGOTIATE, &DmAuthMessageProcessor::ParseNegotiateMessage}, + {DmMessageType::MSG_TYPE_RESP_ACL_NEGOTIATE, &DmAuthMessageProcessor::ParseMessageRespAclNegotiate}, + {DmMessageType::MSG_TYPE_REQ_USER_CONFIRM, &DmAuthMessageProcessor::ParseMessageReqUserConfirm}, + {DmMessageType::MSG_TYPE_RESP_USER_CONFIRM, &DmAuthMessageProcessor::ParseMessageRespUserConfirm}, + {DmMessageType::MSG_TYPE_REQ_PIN_AUTH_START, &DmAuthMessageProcessor::ParseMessageReqPinAuthStart}, + {DmMessageType::MSG_TYPE_REQ_PIN_AUTH_MSG_NEGOTIATE, &DmAuthMessageProcessor::ParseMessageReqPinAuthNegotiate}, + {DmMessageType::MSG_TYPE_RESP_PIN_AUTH_START, &DmAuthMessageProcessor::ParseMessageRespPinAuthStart}, + {DmMessageType::MSG_TYPE_RESP_PIN_AUTH_MSG_NEGOTIATE, + &DmAuthMessageProcessor::ParseMessageRespPinAuthNegotiate}, + {DmMessageType::MSG_TYPE_REQ_CREDENTIAL_EXCHANGE, &DmAuthMessageProcessor::ParseMessageReqCredExchange}, + {DmMessageType::MSG_TYPE_RESP_CREDENTIAL_EXCHANGE, &DmAuthMessageProcessor::ParseMessageRspCredExchange}, + {DmMessageType::MSG_TYPE_REQ_CREDENTIAL_AUTH_START, &DmAuthMessageProcessor::ParseAuthStartMessage}, + {DmMessageType::MSG_TYPE_REQ_CREDENTIAL_AUTH_NEGOTIATE, &DmAuthMessageProcessor::ParseMessageNegotiateTransmit}, + {DmMessageType::MSG_TYPE_RESP_CREDENTIAL_AUTH_START, &DmAuthMessageProcessor::ParseMessageNegotiateTransmit}, + {DmMessageType::MSG_TYPE_RESP_CREDENTIAL_AUTH_NEGOTIATE, + &DmAuthMessageProcessor::ParseMessageNegotiateTransmit}, + {DmMessageType::MSG_TYPE_REQ_DATA_SYNC, &DmAuthMessageProcessor::ParseMessageSyncReq}, + {DmMessageType::MSG_TYPE_RESP_DATA_SYNC, &DmAuthMessageProcessor::ParseMessageSyncResp}, + {DmMessageType::MSG_TYPE_AUTH_REQ_FINISH, &DmAuthMessageProcessor::ParseMessageSinkFinish}, + {DmMessageType::MSG_TYPE_AUTH_RESP_FINISH, &DmAuthMessageProcessor::ParseMessageSrcFinish}, + }; + LOGI("DmAuthMessageProcessor constructor leave."); +} + +DmAuthMessageProcessor::~DmAuthMessageProcessor() +{ + if (cryptoMgr_ != nullptr) { + cryptoMgr_->ClearSessionKey(); + cryptoMgr_ = nullptr; + } +} + +int32_t DmAuthMessageProcessor::ParseMessage(std::shared_ptr context, const std::string &message) +{ + JsonObject jsonObject(message); + if (context == nullptr || !IsMessageValid(jsonObject)) { + return ERR_DM_FAILED; + } + DmMessageType msgType = static_cast(jsonObject[TAG_MSG_TYPE].Get()); + context->msgType = msgType; + LOGI("DmAuthMessageProcessor::ParseMessage message type %{public}d", context->msgType); + LOGI("DmAuthMessageProcessor::ParseMessage message is %{public}s", message.c_str()); + auto itr = paraseMessageFuncMap_.find(msgType); + if (itr == paraseMessageFuncMap_.end()) { + LOGI("DmAuthMessageProcessor::ParseMessage message type error %{public}d", context->msgType); + return ERR_DM_FAILED; + } + return (this->*(itr->second))(jsonObject, context); +} + +static std::vector stringToVectorAuthType(const std::string& str) +{ + std::vector vec; + std::istringstream iss(str); + int32_t num; + while (iss >> num) { + vec.push_back(static_cast(num)); + } + return vec; +} + +static std::vector stringToVectorInt32(const std::string& str) +{ + std::vector vec; + std::istringstream iss(str); + int32_t num; + while (iss >> num) { + vec.push_back(static_cast(num)); + } + return vec; +} + +static std::string vectorAuthTypeToString(const std::vector& vec) +{ + std::ostringstream oss; + for (size_t i = 0; i < vec.size(); ++i) { + oss << static_cast(vec[i]); + if (i != vec.size() - 1) { + oss << " "; // Add a separator (e.g. space) + } + } + return oss.str(); +} + +static std::string vectorInt32ToString(const std::vector& vec) +{ + std::ostringstream oss; + for (size_t i = 0; i < vec.size(); ++i) { + oss << static_cast(vec[i]); + if (i != vec.size() - 1) { + oss << " "; // Add a separator (e.g. space) + } + } + return oss.str(); +} + +int32_t DmAuthMessageProcessor::ParseMessageNegotiateTransmit(const JsonObject &jsonObject, + std::shared_ptr context) +{ + if (jsonObject.IsDiscarded() || !jsonObject.Contains(TAG_DATA) || !jsonObject[TAG_DATA].IsString()) { + LOGE("DmAuthMessageProcessor::ParseMessageNegotiateTransmit Unlegal json string failed"); + return ERR_DM_FAILED; + } + + context->transmitData = jsonObject[TAG_DATA].Get(); + + switch (context->msgType) { + case MSG_TYPE_REQ_CREDENTIAL_AUTH_NEGOTIATE: // 161 + context->authStateMachine->TransitionTo(std::make_shared()); + break; + case MSG_TYPE_RESP_CREDENTIAL_AUTH_START: // 170 + context->authStateMachine->TransitionTo(std::make_shared()); + break; + case MSG_TYPE_RESP_CREDENTIAL_AUTH_NEGOTIATE: // 171 + context->authStateMachine->TransitionTo(std::make_shared()); + break; + default: + return ERR_DM_FAILED; + } + + return DM_OK; +} + +int32_t DmAuthMessageProcessor::ParseMessageRespPinAuthNegotiate(const JsonObject &jsonObject, + std::shared_ptr context) +{ + if (jsonObject.IsDiscarded() || !jsonObject[TAG_DATA].IsString()) { + LOGE("DmAuthMessageProcessor::ParseMessageRespPinAuthNegotiate failed, decodeRequestAuth jsonStr error"); + return ERR_DM_FAILED; + } + + context->transmitData = jsonObject[TAG_DATA].Get(); + context->authStateMachine->TransitionTo(std::make_shared()); + return DM_OK; +} + +int32_t DmAuthMessageProcessor::ParseMessageReqCredExchange(const JsonObject &jsonObject, + std::shared_ptr context) +{ + if (jsonObject.IsDiscarded() || !jsonObject[TAG_DATA].IsString()) { + LOGE("DecodeRequestAuth jsonStr error"); + return ERR_DM_FAILED; + } + + std::string plainText; + if (cryptoMgr_->DecryptMessage(jsonObject[TAG_DATA].Get(), plainText) != DM_OK) { + LOGE("DmAuthMessageProcessor::ParseMessageReqCredExchange() error, decrypt data failed."); + return ERR_DM_FAILED; + } + JsonObject jsonData(plainText); + + // First authentication, parse lnn public key + if (!context->isOnline) { + if (!jsonData[TAG_LNN_PUBLICK_KEY].IsString()) { + LOGE("DmAuthMessageProcessor::ParseMessageReqCredExchange() error, first auth, no lnnPublicKey."); + return ERR_DM_FAILED; + } + context->accesser.lnnPublicKey = jsonData[TAG_LNN_PUBLICK_KEY].Get(); + } + + if (!jsonData[TAG_TRANSMIT_PUBLICK_KEY].IsString() || + !jsonData[TAG_DEVICE_ID].IsString() || + !jsonData[TAG_PEER_USER_SPACE_ID].IsNumberInteger() || + !jsonData[TAG_TOKEN_ID].IsNumberInteger()) { + LOGE("DmAuthMessageProcessor::ParseMessageReqCredExchange, MSG_TYPE_REQ_CREDENTIAL_EXCHANGE message error."); + return ERR_DM_FAILED; + } + context->accesser.ephemeralPublicKey = jsonData[TAG_TRANSMIT_PUBLICK_KEY].Get(); + context->accesser.deviceId = jsonData[TAG_DEVICE_ID].Get(); + context->accesser.userId = jsonData[TAG_PEER_USER_SPACE_ID].Get(); + context->accesser.tokenId = jsonData[TAG_TOKEN_ID].Get(); + context->authStateMachine->TransitionTo(std::make_shared()); + return DM_OK; +} + +int32_t DmAuthMessageProcessor::ParseMessageRspCredExchange(const JsonObject &jsonObject, + std::shared_ptr context) +{ + LOGI("DmAuthMessageProcessor::ParseMessageRspCredExchange start."); + if (jsonObject.IsDiscarded() || !jsonObject[TAG_DATA].IsString()) { + LOGE("DmAuthMessageProcessor::ParseMessageRspCredExchange, DecodeRequestAuth jsonStr error"); + return ERR_DM_FAILED; + } + + std::string plainText; + if (cryptoMgr_->DecryptMessage(jsonObject[TAG_DATA].Get(), plainText) != DM_OK) { + LOGE("DmAuthMessageProcessor::ParseMessageRspCredExchange error, decrypt data failed."); + return ERR_DM_FAILED; + } + + LOGI("DmAuthMessageProcessor::ParseMessageRspCredExchange plainText=%{public}s", plainText.c_str()); + + JsonObject jsonData(plainText); + + // First authentication, parse lnn public key + std::string tmpString; + if (!context->isOnline) { + if (!jsonData[TAG_LNN_PUBLICK_KEY].IsString()) { + LOGE("DmAuthMessageProcessor::ParseMessageRspCredExchange failed, first auth but no lnnPublicKey."); + return ERR_DM_FAILED; + } + context->accessee.lnnPublicKey = jsonData[TAG_LNN_PUBLICK_KEY].Get(); + } + + // First authentication, parse transmit public key + if (!jsonData[TAG_TRANSMIT_PUBLICK_KEY].IsString() || + !jsonData[TAG_DEVICE_ID].IsString() || + !jsonData[TAG_PEER_USER_SPACE_ID].IsNumberInteger() || + !jsonData[TAG_TOKEN_ID].IsNumberInteger()) { + LOGE("DmAuthMessageProcessor::ParseMessageRspCredExchange failed, decode MSG_TYPE_RESP_CREDENTIAL_EXCHANGE " + "message error."); + return ERR_DM_FAILED; + } + context->accessee.ephemeralPublicKey = jsonData[TAG_TRANSMIT_PUBLICK_KEY].Get(); + context->accessee.deviceId = jsonData[TAG_DEVICE_ID].Get(); + context->accessee.userId = jsonData[TAG_PEER_USER_SPACE_ID].Get(); + context->accessee.tokenId = jsonData[TAG_TOKEN_ID].Get(); + + context->authStateMachine->TransitionTo(std::make_shared()); + return DM_OK; +} + +std::string DmAuthMessageProcessor::CreateMessage(DmMessageType msgType, std::shared_ptr context) +{ + LOGI("DmAuthMessageProcessor::CreateMessage start. msgType is %{public}d", msgType); + JsonObject jsonObj; + jsonObj[TAG_MSG_TYPE] = msgType; + jsonObj[DM_TAG_LOGICAL_SESSION_ID] = context->logicalSessionId; + auto itr = createMessageFuncMap_.find(msgType); + if (itr == createMessageFuncMap_.end()) { + LOGE("DmAuthMessageProcessor::CreateMessage msgType %{public}d error.", msgType); + return ""; + } + int32_t ret = (this->*(itr->second))(context, jsonObj); + LOGI("DmAuthMessageProcessor::CreateMessage start. message is %{public}s", jsonObj.Dump().c_str()); + return (ret == DM_OK) ? jsonObj.Dump() : ""; +} + +int32_t DmAuthMessageProcessor::CreateCredentialNegotiateMessage(std::shared_ptr context, + JsonObject &jsonObject) +{ + std::string encryptMsg; + jsonObject[TAG_DATA] = context->transmitData; + return DM_OK; +} + +// Create 80 message. +int32_t DmAuthMessageProcessor::CreateNegotiateMessage(std::shared_ptr context, JsonObject &jsonObject) +{ + jsonObject[TAG_SESSION_NAME] = context->sessionName; + jsonObject[TAG_DMVERSION] = context->accesser.dmVersion; + + jsonObject[TAG_USER_ID] = context->accesser.userId; + jsonObject[TAG_TOKEN_ID] = static_cast(context->accesser.tokenId); + + jsonObject[TAG_DEVICE_ID_HASH] = context->accesser.deviceIdHash; + jsonObject[TAG_USER_ID_HASH] = context->accesser.userIdHash; + jsonObject[TAG_ACCOUNT_ID_HASH] = context->accesser.accountIdHash; + jsonObject[TAG_TOKEN_ID_HASH] = context->accesser.tokenIdHash; + + jsonObject[TAG_BUNDLE_NAME] = context->accesser.bundleName; + jsonObject[TAG_PEER_BUNDLE_NAME] = context->accessee.bundleName; + + JsonObject jsonExtraObject; + CreateNegotiateExtraInfoMessage(context, jsonExtraObject); + jsonObject.Insert(TAG_EXTRA_INFO, jsonExtraObject); + + return DM_OK; +} + +// Create 90 message. +int32_t DmAuthMessageProcessor::CreateRespNegotiateMessage(std::shared_ptr context, + JsonObject &jsonObject) +{ + jsonObject[TAG_DEVICE_VERSION] = context->accessee.dmVersion; + jsonObject[TAG_DEVICE_NAME] = context->accessee.deviceName; + + jsonObject[TAG_DEVICE_ID_HASH] = context->accessee.deviceIdHash; + jsonObject[TAG_USER_ID_HASH] = context->accessee.userIdHash; + jsonObject[TAG_ACCOUNT_ID_HASH] = context->accessee.accountIdHash; + jsonObject[TAG_TOKEN_ID_HASH] = context->accessee.tokenIdHash; + + jsonObject[TAG_BUNDLE_NAME] = context->accessee.bundleName; + jsonObject[TAG_IS_ONLINE] = context->isOnline; + jsonObject[TAG_IS_AUTHED] = context->accessee.isAuthed; + jsonObject[TAG_CERT_INFO] = vectorInt32ToString(context->accessee.credentialTypeLists); + jsonObject[TAG_LANGUAGE] = context->accessee.language; + + return DM_OK; +} + +// Create 140 message. +int32_t DmAuthMessageProcessor::CreateMessageReqCredExchange(std::shared_ptr context, + JsonObject &jsonObject) +{ + JsonObject jsonData; + if (!context->isOnline) { + jsonData[TAG_LNN_PUBLICK_KEY] = context->accesser.lnnPublicKey; + } + jsonData[TAG_TRANSMIT_PUBLICK_KEY] = context->accesser.ephemeralPublicKey; + jsonData[TAG_DEVICE_ID] = context->accesser.deviceId; + jsonData[TAG_PEER_USER_SPACE_ID] = context->accesser.userId; + jsonData[TAG_TOKEN_ID] = context->accesser.tokenId; + + std::string plainText = jsonData.Dump(); + std::string cipherText; + int32_t ret = cryptoMgr_->EncryptMessage(plainText, cipherText); + if (ret != DM_OK) { + LOGI("DmAuthMessageProcessor::CreateMessageReqCredExchange encryptMessage failed."); + return ret; + } + jsonObject[TAG_DATA] = cipherText; + return ret; +} + +// Create 150 message. +int32_t DmAuthMessageProcessor::CreateMessageRspCredExchange(std::shared_ptr context, + JsonObject &jsonObject) +{ + LOGI("DmAuthMessageProcessor::CreateMessageRspCredExchange start."); + JsonObject jsonData; + if (!context->isOnline) { + jsonData[TAG_LNN_PUBLICK_KEY] = context->accessee.lnnPublicKey; + } + jsonData[TAG_TRANSMIT_PUBLICK_KEY] = context->accessee.ephemeralPublicKey; + jsonData[TAG_DEVICE_ID] = context->accessee.deviceId; + jsonData[TAG_PEER_USER_SPACE_ID] = context->accessee.userId; + jsonData[TAG_TOKEN_ID] = context->accessee.tokenId; + + std::string plainText = jsonData.Dump(); + std::string cipherText; + LOGI("DmAuthMessageProcessor::CreateMessageRspCredExchange plainText=%{public}s", plainText.c_str()); + int32_t ret = cryptoMgr_->EncryptMessage(plainText, cipherText); + if (ret != DM_OK) { + LOGI("DmAuthMessageProcessor::CreateMessageRspCredExchange encryptMessage failed."); + return ret; + } + jsonObject[TAG_DATA] = cipherText; + return ret; +} + +// Create 160 message. +int32_t DmAuthMessageProcessor::CreateMessageReqCredAuthStart(std::shared_ptr context, + JsonObject &jsonObject) +{ + std::string onTransmitData; + + JsonObject jsonData; + jsonObject[TAG_DATA] = context->transmitData; + return DM_OK; +} + +bool DmAuthMessageProcessor::ChecksumAcl(DistributedDeviceProfile::AccessControlProfile &acl, + std::vector &accesserStrList, std::vector &accesseeStrList) +{ + uint8_t accesserHash[DM_HASH_LEN] = {0}; + std::string accesserStr = AccesserToStr(acl); + Crypto::DmGenerateStrHash(accesserStr.data(), accesserStr.size(), accesserHash, DM_HASH_LEN, 0); + auto accesserIter = find(accesserStrList.begin(), accesserStrList.end(), + std::string(reinterpret_cast(accesserHash))); + + uint8_t accesseeHash[DM_HASH_LEN] = {0}; + std::string accesseeStr = AccesseeToStr(acl); + Crypto::DmGenerateStrHash(accesseeStr.data(), accesseeStr.size(), accesseeHash, DM_HASH_LEN, 0); + auto accesseeIter = find(accesseeStrList.begin(), accesseeStrList.end(), + std::string(reinterpret_cast(accesseeHash))); + return (accesserIter != accesserStrList.end()) && (accesseeIter != accesseeStrList.end()); +} + +// Create 190 message. +int32_t DmAuthMessageProcessor::CreateMessageSyncResp(std::shared_ptr context, + JsonObject &jsonObject) +{ + DmAccess access; + if (context->direction == DM_AUTH_SINK) { + access = context->accessee; + } else { + access = context->accesser; + } + + std::string encSyncMsg; + int32_t ret = EncryptSyncMessage(context, access, encSyncMsg); + if (ret != DM_OK) { + LOGE("DmAuthMessageProcessor::CreateMessageSyncResp encrypt failed"); + return ret; + } + jsonObject[TAG_SYNC] = encSyncMsg; + return ret; +} + +// Create 200 message. +int32_t DmAuthMessageProcessor::CreateMessageFinish(std::shared_ptr context, + JsonObject &jsonObject) +{ + jsonObject[TAG_REPLY] = context->reply; + jsonObject[TAG_STATE] = context->state; + jsonObject[TAG_REASON] = context->reason; + return DM_OK; +} + +int32_t DmAuthMessageProcessor::ParseSyncMessage(std::shared_ptr &context, + DmAccess &access, JsonObject &jsonObject) +{ + // transmit session key is mandatory + if (!jsonObject[TAG_TRANSMIT_SK_ID].IsString()) { + LOGE("ParseSyncMessage TAG_TRANSMIT_SK_ID error"); + return ERR_DM_FAILED; + } + access.transmitSessionKeyId = std::atoi(jsonObject[TAG_TRANSMIT_SK_ID].Get().c_str()); + + if (!jsonObject[TAG_TRANSMIT_SK_TIMESTAMP].IsString()) { + LOGE("ParseSyncMessage TAG_TRANSMIT_SK_TIMESTAMP error"); + return ERR_DM_FAILED; + } + access.transmitSkTimeStamp = std::atoi(jsonObject[TAG_TRANSMIT_SK_TIMESTAMP].Get().c_str()); + + if (!jsonObject[TAG_TRANSMIT_CREDENTIAL_ID].IsString()) { + LOGE("ParseSyncMessage TAG_TRANSMIT_CREDENTIAL_ID error"); + return ERR_DM_FAILED; + } + access.transmitCredentialId = jsonObject[TAG_TRANSMIT_CREDENTIAL_ID].Get().c_str(); + + // lnn session key is optional + if (jsonObject[TAG_LNN_SK_ID].IsString()) { + access.lnnSessionKeyId = std::atoi(jsonObject[TAG_LNN_SK_ID].Get().c_str()); + } + if (jsonObject[TAG_LNN_SK_TIMESTAMP].IsString()) { + access.lnnSkTimeStamp = std::atoi(jsonObject[TAG_LNN_SK_TIMESTAMP].Get().c_str()); + } + + if (jsonObject[TAG_LNN_CREDENTIAL_ID].IsString()) { + access.lnnCredentialId = jsonObject[TAG_LNN_CREDENTIAL_ID].Get().c_str(); + } + + if (!jsonObject[TAG_DMVERSION].IsString()) { + LOGE("ParseSyncMessage TAG_DMVERSION error"); + return ERR_DM_FAILED; + } + + access.dmVersion = jsonObject[TAG_DMVERSION].Get(); + if (!jsonObject[TAG_ACCESS].IsString()) { + LOGE("ParseSyncMessage TAG_ACCESS error"); + return ERR_DM_FAILED; + } + std::string srcAccessStr = jsonObject[TAG_ACCESS].Get(); + // Parse into access + ParseDmAccessToSync(srcAccessStr, access); + if (jsonObject[TAG_PROXY].IsString()) { // Reserved field + std::string proxyInfo = jsonObject[TAG_PROXY].Get(); + } + if (jsonObject[TAG_SERVICEINFO].IsString()) { // sp not yet uploaded + std::string serviceInfo = jsonObject[TAG_SERVICEINFO].Get(); + } + if (!jsonObject[TAG_ACL_CHECKSUM].IsString()) { // Re-parse the acl + LOGE("ParseSyncMessage TAG_ACL_CHECKSUM error"); + return ERR_DM_FAILED; + } + std::string aclChecksumList = jsonObject[TAG_ACL_CHECKSUM].Get(); + return ParaseAclChecksumList(aclChecksumList, access); +} + +int32_t DmAuthMessageProcessor::DecryptSyncMessage(std::shared_ptr &context, + DmAccess &access, std::string &enSyncMsg) +{ + std::string syncMsgCompress = ""; + int32_t ret = cryptoMgr_->DecryptMessage(enSyncMsg, syncMsgCompress); + if (ret != DM_OK) { + LOGE("DecryptSyncMessage syncMsg error"); + return ret; + } + JsonObject plainJson(syncMsgCompress); + if (plainJson.IsDiscarded()) { + LOGE("DecryptSyncMessage plainJson error"); + return ERR_DM_FAILED; + } + if (!plainJson[TAG_COMPRESS_ORI_LEN].IsNumberInteger()) { + LOGE("DecryptSyncMessage TAG_COMPRESS_ORI_LEN json error"); + return ERR_DM_FAILED; + } + int32_t dataLen = plainJson[TAG_COMPRESS_ORI_LEN].Get(); + if (!plainJson[TAG_COMPRESS].IsString()) { + LOGE("DecryptSyncMessage TAG_COMPRESS_ORI_LEN json error"); + return ERR_DM_FAILED; + } + std::string compressMsg = plainJson[TAG_COMPRESS].Get(); + std::string compressBase64 = Base64Decode(compressMsg); + std::string syncMsg = DecompressSyncMsg(compressBase64, dataLen); + JsonObject jsonObject(syncMsg); + if (jsonObject.IsDiscarded()) { + LOGE("DmAuthMessageProcessor::DecryptSyncMessage jsonStr error"); + return ERR_DM_FAILED; + } + + ret = ParseSyncMessage(context, access, jsonObject); + if (ret != DM_OK) { + LOGE("DecryptSyncMessage ParseSyncMessage jsonStr error"); + return ret; + } + return DM_OK; +} + +// 解析 180报文信息 MSG_TYPE_REQ_DATA_SYNC 存放对方密文四元组,acl,sp skid +// Parse 180 message, save remote encrypted quadruple, acl, sp skid +int32_t DmAuthMessageProcessor::ParseMessageSyncReq(const JsonObject &jsonObject, + std::shared_ptr context) +{ + if (!jsonObject[TAG_SYNC].IsString()) { + LOGE("ParseMessageSyncReq json error"); + return ERR_DM_FAILED; + } + std::string enSyncMsg = jsonObject[TAG_SYNC].Get(); + // Decrypt data and parse data into context + int32_t ret = DecryptSyncMessage(context, context->accesser, enSyncMsg); + if (ret != DM_OK) { + LOGE("DecryptSyncMessage enSyncMsg error"); + return ret; + } + context->authStateMachine->TransitionTo(std::make_shared()); + return DM_OK; +} + +// Parse 190 message save the remote encrypted quadruple, acl sp skid +int32_t DmAuthMessageProcessor::ParseMessageSyncResp(const JsonObject &jsonObject, + std::shared_ptr context) +{ + if (!jsonObject[TAG_SYNC].IsString()) { + LOGE("ParseMessageSyncResp json error"); + return ERR_DM_FAILED; + } + std::string enSyncMsg = jsonObject[TAG_SYNC].Get(); + // Decrypt data and parse data into context + int32_t ret = DecryptSyncMessage(context, context->accessee, enSyncMsg); + if (ret != DM_OK) { + LOGE("DecryptSyncMessage enSyncMsg error"); + return ret; + } + context->authStateMachine->TransitionTo(std::make_shared()); + return DM_OK; +} + +// 解析200报文 +int32_t DmAuthMessageProcessor::ParseMessageSinkFinish(const JsonObject &jsonObject, + std::shared_ptr context) +{ + /* In case of an exception, there may be a state waiting for an event. + In the normal process, no state is waiting for events. */ + context->authStateMachine->NotifyEventFinish(DmEventType::ON_FAIL); + if (jsonObject[TAG_REPLY].IsNumberInteger()) { + context->reply = jsonObject[TAG_REPLY].Get(); + } + if (jsonObject[TAG_STATE].IsNumberInteger()) { + context->state = jsonObject[TAG_STATE].Get(); + } + if (jsonObject[TAG_REASON].IsNumberInteger()) { + context->reason = jsonObject[TAG_REASON].Get(); + } + context->authStateMachine->TransitionTo(std::make_shared()); + return DM_OK; +} + +// Parse 201 message +int32_t DmAuthMessageProcessor::ParseMessageSrcFinish(const JsonObject &jsonObject, + std::shared_ptr context) +{ + /* In case of an exception, there may be a state waiting for an event. + In the normal process, no state is waiting for events. */ + context->authStateMachine->NotifyEventFinish(DmEventType::ON_FAIL); + if (jsonObject[TAG_REPLY].IsNumberInteger()) { + context->reply = jsonObject[TAG_REPLY].Get(); + } + if (jsonObject[TAG_STATE].IsNumberInteger()) { + context->state = jsonObject[TAG_STATE].Get(); + } + if (jsonObject[TAG_REASON].IsNumberInteger()) { + context->reason = jsonObject[TAG_REASON].Get(); + } + context->authStateMachine->TransitionTo(std::make_shared()); + return DM_OK; +} + +int32_t DmAuthMessageProcessor::ParseNegotiateMessage(const JsonObject &jsonObject, + std::shared_ptr context) +{ + if (jsonObject[DM_TAG_LOGICAL_SESSION_ID].IsNumberInteger()) { + context->logicalSessionId = jsonObject[DM_TAG_LOGICAL_SESSION_ID].Get(); + context->requestId = context->logicalSessionId; + } + if (jsonObject[TAG_DMVERSION].IsString()) { + context->accesser.dmVersion = jsonObject[TAG_DMVERSION].Get(); + } + if (jsonObject[TAG_EDITION].IsString()) { + context->accesser.edition = jsonObject[TAG_EDITION].Get(); + } + if (jsonObject[TAG_USER_ID].IsNumberInteger()) { + context->accesser.userId = jsonObject[TAG_USER_ID].Get(); + } + if (jsonObject[TAG_TOKEN_ID].IsNumberInteger()) { + context->accesser.tokenId = static_cast(jsonObject[TAG_TOKEN_ID].Get()); + } + + if (jsonObject[TAG_DEVICE_ID_HASH].IsString()) { + context->accesser.deviceIdHash = jsonObject[TAG_DEVICE_ID_HASH].Get(); + } + if (jsonObject[TAG_USER_ID_HASH].IsString()) { + context->accesser.userIdHash = jsonObject[TAG_USER_ID_HASH].Get(); + } + if (jsonObject[TAG_ACCOUNT_ID_HASH].IsString()) { + context->accesser.accountIdHash = jsonObject[TAG_ACCOUNT_ID_HASH].Get(); + } + if (jsonObject[TAG_TOKEN_ID_HASH].IsString()) { + context->accesser.tokenIdHash = jsonObject[TAG_TOKEN_ID_HASH].Get(); + } + + if (jsonObject[TAG_SESSION_NAME].IsString()) { + context->sessionName = jsonObject[TAG_SESSION_NAME].Get(); + } + if (jsonObject[TAG_BUNDLE_NAME].IsString()) { + context->accesser.bundleName = jsonObject[TAG_BUNDLE_NAME].Get(); + } + if (jsonObject[TAG_PEER_BUNDLE_NAME].IsString()) { + context->accessee.bundleName = jsonObject[TAG_PEER_BUNDLE_NAME].Get(); + } + + if (jsonObject.Contains(TAG_EXTRA_INFO) && jsonObject[TAG_EXTRA_INFO].IsObject()) { + ParseNegotiateExtraInfoMessage(jsonObject[TAG_EXTRA_INFO], context); + } + + context->authStateMachine->TransitionTo(std::make_shared()); + return DM_OK; +} + +int32_t DmAuthMessageProcessor::ParseMessageRespAclNegotiate(const JsonObject &jsonObject, + std::shared_ptr context) +{ + if (jsonObject[TAG_DEVICE_VERSION].IsString()) { + context->accessee.dmVersion = jsonObject[TAG_DEVICE_VERSION].Get(); + } + + if (jsonObject[TAG_DEVICE_NAME].IsString()) { + context->accessee.deviceName = jsonObject[TAG_DEVICE_NAME].Get(); + } + + if (jsonObject[TAG_DEVICE_ID_HASH].IsString()) { + context->accessee.deviceIdHash = jsonObject[TAG_DEVICE_ID_HASH].Get(); + } + + if (jsonObject[TAG_USER_ID_HASH].IsString()) { + context->accessee.userIdHash = jsonObject[TAG_USER_ID_HASH].Get(); + } + + if (jsonObject[TAG_ACCOUNT_ID_HASH].IsString()) { + context->accessee.accountIdHash = jsonObject[TAG_ACCOUNT_ID_HASH].Get(); + } + + if (jsonObject[TAG_TOKEN_ID_HASH].IsString()) { + context->accessee.tokenIdHash = jsonObject[TAG_TOKEN_ID_HASH].Get(); + } + + if (jsonObject[TAG_BUNDLE_NAME].IsString()) { + context->accessee.bundleName = jsonObject[TAG_BUNDLE_NAME].Get(); + } + + if (jsonObject[TAG_IS_ONLINE].IsBoolean()) { + context->isOnline = jsonObject[TAG_IS_ONLINE].Get(); + } + + if (jsonObject[TAG_CERT_INFO].IsString()) { + context->accessee.credentialTypeLists = stringToVectorInt32(jsonObject[TAG_CERT_INFO].Get()); + } + + if (jsonObject[TAG_LANGUAGE].IsString()) { + context->accessee.language = jsonObject[TAG_LANGUAGE].Get(); + } + + context->authStateMachine->TransitionTo(std::make_shared()); + return DM_OK; +} + +int32_t DmAuthMessageProcessor::ParseMessageReqUserConfirm(const JsonObject &json, + std::shared_ptr context) +{ + if (json[TAG_DEVICE_TYPE].IsNumberInteger()) { + context->accesser.deviceType = json[TAG_DEVICE_TYPE].Get(); + } + if (json[TAG_DEVICE_NAME].IsString()) { + context->accesser.deviceName = json[TAG_DEVICE_NAME].Get(); + } + if (json[TAG_AUTH_TYPE].IsNumberInteger()) { + context->authType = static_cast(json[TAG_AUTH_TYPE].Get()); + } + if (json[TAG_CERT_INFO].IsString()) { + context->accesser.credentialTypeLists = stringToVectorInt32(json[TAG_CERT_INFO].Get()); + } + context->authStateMachine->TransitionTo(std::make_shared()); + return DM_OK; +} + +int32_t DmAuthMessageProcessor::ParseMessageRespUserConfirm(const JsonObject &json, + std::shared_ptr context) +{ + if (json[TAG_AUTH_RESULT].IsNumberInteger()) { + context->authResult = static_cast(json[TAG_AUTH_RESULT].Get()); + } + + if (json[TAG_AUTH_TYPE_LIST].IsString()) { + auto strList = json[TAG_AUTH_TYPE_LIST].Get(); + context->authTypeList = stringToVectorAuthType(strList); + } + + context->authStateMachine->TransitionTo(std::make_shared()); + return DM_OK; +} + +int32_t DmAuthMessageProcessor::ParseMessageReqPinAuthStart(const JsonObject &json, + std::shared_ptr context) +{ + if (json[TAG_DATA].IsString()) { + context->transmitData = json[TAG_DATA].Get(); + } + + context->authStateMachine->TransitionTo(std::make_shared()); + return DM_OK; +} + +int32_t DmAuthMessageProcessor::ParseMessageRespPinAuthStart(const JsonObject &json, + std::shared_ptr context) +{ + if (json[TAG_DATA].IsString()) { + context->transmitData = json[TAG_DATA].Get(); + } + context->authStateMachine->TransitionTo(std::make_shared()); + return DM_OK; +} + +int32_t DmAuthMessageProcessor::ParseMessageReqPinAuthNegotiate(const JsonObject &json, + std::shared_ptr context) +{ + if (json[TAG_DATA].IsString()) { + context->transmitData = json[TAG_DATA].Get(); + } + context->authStateMachine->TransitionTo(std::make_shared()); + return DM_OK; +} + +int32_t DmAuthMessageProcessor::CreateMessageReqUserConfirm(std::shared_ptr context, JsonObject &json) +{ + json[TAG_AUTH_TYPE] = context->authType; + json[TAG_CERT_INFO] = vectorInt32ToString(context->accesser.credentialTypeLists); + json[TAG_DEVICE_TYPE] = context->accesser.deviceType; + json[TAG_DEVICE_NAME] = context->accesser.deviceName; + return DM_OK; +} + +int32_t DmAuthMessageProcessor::CreateMessageRespUserConfirm(std::shared_ptr context, JsonObject &json) +{ + json[TAG_AUTH_RESULT] = context->authResult; + json[TAG_AUTH_TYPE_LIST] = vectorAuthTypeToString(context->authTypeList); + return DM_OK; +} + +int32_t DmAuthMessageProcessor::CreateMessageReqPinAuthStart(std::shared_ptr context, JsonObject &json) +{ + json[TAG_DATA] = context->transmitData; + return DM_OK; +} + +int32_t DmAuthMessageProcessor::CreateMessageRespPinAuthStart(std::shared_ptr context, JsonObject &json) +{ + json[TAG_DATA] = context->transmitData; + return DM_OK; +} + +int32_t DmAuthMessageProcessor::CreateMessageReqPinAuthNegotiate(std::shared_ptr context, + JsonObject &json) +{ + json[TAG_DATA] = context->transmitData; + return DM_OK; +} + +int32_t DmAuthMessageProcessor::CreateMessageRespPinAuthNegotiate(std::shared_ptr context, + JsonObject &json) +{ + json[TAG_DATA] = context->transmitData; + return DM_OK; +} + +void DmAuthMessageProcessor::CreateAndSendMsg(DmMessageType msgType, std::shared_ptr context) +{ + auto message = CreateMessage(msgType, context); + context->softbusConnector->GetSoftbusSession()->SendData(context->sessionId, message); +} + +std::string DmAuthMessageProcessor::CompressSyncMsg(std::string &inputStr) +{ + uint32_t srcLen = inputStr.size(); + uint32_t boundSize = compressBound(srcLen); // Maximum compression length + std::string compressed(boundSize, '\0'); + + // Compress to reserved space + unsigned long destSize = boundSize; // Actual usable length + int32_t ret = compress(reinterpret_cast(&compressed[0]), &destSize, + reinterpret_cast(inputStr.data()), srcLen); + if (ret != Z_OK) { + LOGE("DmAuthMessageProcessor::CompressSyncMsg zlib compress failed"); + return ""; + } + compressed.resize(destSize); // Actual usage length + return compressed; +} + +std::string DmAuthMessageProcessor::DecompressSyncMsg(std::string& compressed, uint32_t oriLen) +{ + std::string decompressed; + decompressed.resize(oriLen); + unsigned long destLen = oriLen; // Actual usage length + int32_t ret = uncompress(reinterpret_cast(&decompressed[0]), &destLen, + reinterpret_cast(compressed.data()), // Skip header when decompressing + compressed.size()); + if (ret != Z_OK || destLen != oriLen) { + LOGE("DmAuthMessageProcessor::DecompressSyncMsg decompress failed"); + return ""; + } + return decompressed; +} + +std::string DmAuthMessageProcessor::Base64Encode(std::string &inputStr) +{ + // Convert input string to binary + const unsigned char* src = reinterpret_cast(inputStr.data()); + size_t srcLen = inputStr.size(); + + // Calculate the maximum length after base64 encoding + size_t maxEncodeLen = ((srcLen + 2) / 3) * 4 + 1; + std::vector buffer(maxEncodeLen); + + // Actual encoding length + size_t encodedLen = 0; + int32_t ret = mbedtls_base64_encode(buffer.data(), buffer.size(), &encodedLen, src, srcLen); + if (ret != 0) { + LOGE("DmAuthMessageProcessor::Base64Encode mbedtls_base64_encode failed"); + return ""; + } + return std::string(reinterpret_cast(buffer.data()), encodedLen); // No terminator needed +} + +std::string DmAuthMessageProcessor::Base64Decode(std::string &inputStr) +{ + // Convert input string to binary + const unsigned char* src = reinterpret_cast(inputStr.data()); + size_t srcLen = inputStr.size(); + + // Calculate the maximum length after base64 encoding + size_t maxEncodeLen = (srcLen / 4) * 3 + 1; + std::vector buffer(maxEncodeLen); + + // Actual encoding length + size_t decodedLen = 0; + int32_t ret = mbedtls_base64_decode(buffer.data(), buffer.size(), &decodedLen, src, srcLen); + if (ret != 0) { + LOGE("DmAuthMessageProcessor::Base64Decode mbedtls_base64_decode failed"); + return ""; + } + return std::string(reinterpret_cast(buffer.data()), decodedLen); // 无需终止符 +} + + +int32_t DmAuthMessageProcessor::EncryptSyncMessage(std::shared_ptr &context, DmAccess &accessSide, + std::string &encSyncMsg) +{ + JsonObject syncMsgJson; + DmAccessToSync accessToSync; + accessToSync.deviceName = accessSide.deviceName; + accessToSync.deviceId = accessSide.deviceId; + accessToSync.userId = accessSide.userId; + accessToSync.accountId = accessSide.accountId; + accessToSync.tokenId = accessSide.tokenId; + accessToSync.bundleName = accessSide.bundleName; + accessToSync.bindLevel = accessSide.bindLevel; + syncMsgJson[TAG_TRANSMIT_SK_ID] = std::to_string(accessSide.transmitSessionKeyId); + syncMsgJson[TAG_TRANSMIT_SK_TIMESTAMP] = std::to_string(accessSide.transmitSkTimeStamp); + syncMsgJson[TAG_TRANSMIT_CREDENTIAL_ID] = accessSide.transmitCredentialId; + if (!context->isOnline) { // First certification + syncMsgJson[TAG_LNN_SK_ID]=std::to_string(accessSide.lnnSessionKeyId); + syncMsgJson[TAG_LNN_SK_TIMESTAMP]=std::to_string(accessSide.lnnSkTimeStamp); + syncMsgJson[TAG_LNN_CREDENTIAL_ID] = accessSide.lnnCredentialId; + } + + JsonObject accessJsonObj{}; + accessJsonObj = accessToSync; + syncMsgJson[TAG_DMVERSION] = accessSide.dmVersion; + syncMsgJson[TAG_ACCESS] = accessJsonObj.Dump(); + syncMsgJson[TAG_PROXY] = ""; // Reserved field, leave blank + std::string aclHashList; + int32_t ret = GetAclListStr(context, aclHashList); + if (ret != DM_OK) { + LOGE("DmAuthMessageProcessor::EncryptSyncMessage GetAclListStr failed"); + return ERR_DM_FAILED; + } + + syncMsgJson[TAG_ACL_CHECKSUM] = aclHashList; + std::string syncMsg = syncMsgJson.Dump(); + + std::string compressMsg = CompressSyncMsg(syncMsg); + if (compressMsg.empty()) { + LOGE("DmAuthMessageProcessor::EncryptSyncMessage compress failed"); + return ERR_DM_FAILED; + } + JsonObject plainJson; + plainJson[TAG_COMPRESS_ORI_LEN] = syncMsg.size(); + plainJson[TAG_COMPRESS] = Base64Encode(compressMsg); + return cryptoMgr_->EncryptMessage(plainJson.Dump(), encSyncMsg); +} + +int32_t DmAuthMessageProcessor::ACLToStr(DistributedDeviceProfile::AccessControlProfile acl, std::string aclStr) +{ + DmAccessControlTable dmAcl; + dmAcl.accessControlId = acl.GetAccessControlId(); + dmAcl.accesserId = acl.GetAccesserId(); + dmAcl.accesseeId = acl.GetAccesseeId(); + dmAcl.deviceId = acl.GetTrustDeviceId(); + dmAcl.sessionKey = acl.GetSessionKey(); + dmAcl.bindType = acl.GetBindType(); + dmAcl.authType = acl.GetAuthenticationType(); + dmAcl.deviceType = acl.GetDeviceIdType(); + dmAcl.deviceIdHash = acl.GetDeviceIdHash(); + dmAcl.status = acl.GetStatus(); + dmAcl.validPeriod = acl.GetValidPeriod(); + dmAcl.lastAuthTime = acl.GetLastAuthTime(); + dmAcl.bindLevel = acl.GetBindType(); + JsonObject aclJsonObj{}; + aclJsonObj = dmAcl; + aclStr = aclJsonObj.Dump(); + if (aclStr.empty()) { + LOGE("DmAuthMessageProcessor::ACLToStr normalized acl failed"); + return ERR_DM_FAILED; + } + return DM_OK; +} + +std::string DmAuthMessageProcessor::AccesserToStr(DistributedDeviceProfile::AccessControlProfile acl) +{ + JsonObject jsonAccesserObj; + DistributedDeviceProfile::Accesser accesser = acl.GetAccesser(); + jsonAccesserObj[TAG_ACCESSER_DEVICE_ID] = accesser.GetAccesserDeviceId(); + jsonAccesserObj[TAG_ACCESSER_USER_ID] = accesser.GetAccesserUserId(); + jsonAccesserObj[TAG_ACCESSER_ACOUNT_ID] = accesser.GetAccesserAccountId(); + jsonAccesserObj[TAG_ACCESSER_TOKEN_ID] = accesser.GetAccesserTokenId(); + jsonAccesserObj[TAG_ACCESSER_SERVICE_NAME] = std::vector(); // Reserved field + jsonAccesserObj[TAG_ACCESSER_BUNDLE_NAME] = accesser.GetAccesserBundleName(); + jsonAccesserObj[TAG_ACCESSER_HAP_SIGNATURE] = accesser.GetAccesserHapSignature(); + jsonAccesserObj[TAG_ACCESSER_BIND_LEVEL] = accesser.GetAccesserBindLevel(); + jsonAccesserObj[TAG_ACCESSER_CREDENTIAL_ID] = accesser.GetAccesserBindLevel(); + jsonAccesserObj[TAG_ACCESSER_STATUS] = accesser.GetAccesserStatus(); + jsonAccesserObj[TAG_ACCESSER_SK_ID] = accesser.GetAccesserSessionKeyId(); + jsonAccesserObj[TAG_ACCESSER_SK_TIMESTAMP] = accesser.GetAccesserSKTimeStamp(); + return jsonAccesserObj.Dump(); +} + +std::string DmAuthMessageProcessor::AccesseeToStr(DistributedDeviceProfile::AccessControlProfile acl) +{ + JsonObject jsonAccesseeObj; + DistributedDeviceProfile::Accessee accessee = acl.GetAccessee(); + jsonAccesseeObj[TAG_ACCESSEE_DEVICE_ID] = accessee.GetAccesseeDeviceId(); + jsonAccesseeObj[TAG_ACCESSEE_USER_ID] = accessee.GetAccesseeUserId(); + jsonAccesseeObj[TAG_ACCESSEE_ACOUNT_ID] = accessee.GetAccesseeAccountId(); + jsonAccesseeObj[TAG_ACCESSEE_TOKEN_ID] = accessee.GetAccesseeTokenId(); + jsonAccesseeObj[TAG_ACCESSEE_SERVICE_NAME] = std::vector(); // Reserved field + jsonAccesseeObj[TAG_ACCESSEE_BUNDLE_NAME] = accessee.GetAccesseeBundleName(); + jsonAccesseeObj[TAG_ACCESSEE_HAP_SIGNATURE] = accessee.GetAccesseeHapSignature(); + jsonAccesseeObj[TAG_ACCESSEE_BIND_LEVEL] = accessee.GetAccesseeBindLevel(); + jsonAccesseeObj[TAG_ACCESSEE_CREDENTIAL_ID] = accessee.GetAccesseeBindLevel(); + jsonAccesseeObj[TAG_ACCESSEE_STATUS] = accessee.GetAccesseeStatus(); + jsonAccesseeObj[TAG_ACCESSEE_SK_ID] = accessee.GetAccesseeSessionKeyId(); + jsonAccesseeObj[TAG_ACCESSEE_SK_TIMESTAMP] = accessee.GetAccesseeSKTimeStamp(); + return jsonAccesseeObj.Dump(); +} + +int32_t DmAuthMessageProcessor::CreateSyncMessage(std::shared_ptr context, JsonObject &jsonObject) +{ + DmAccess accessSide; + if (context->direction == DM_AUTH_SOURCE) { + accessSide = context->accesser; + } else { + accessSide = context->accessee; + } + std::string encSyncMsg; + int32_t ret = EncryptSyncMessage(context, accessSide, encSyncMsg); + if (ret != DM_OK) { + LOGE("DmAuthMessageProcessor::CreateSyncMessage encrypt failed"); + return ret; + } + jsonObject[TAG_SYNC] = encSyncMsg; + return DM_OK; +} + +int32_t DmAuthMessageProcessor::ParseAuthStartMessage(const JsonObject &jsonObject, + std::shared_ptr context) +{ + if (jsonObject.IsDiscarded() || !jsonObject.Contains(TAG_DATA) || + !jsonObject[TAG_DATA].IsString()) { + LOGE("DmAuthMessageProcessor::ParseAuthStartMessage Unlegal json string failed"); + return ERR_DM_FAILED; + } + context->transmitData = jsonObject[TAG_DATA].Get(); + + context->authStateMachine->TransitionTo(std::make_shared()); + return DM_OK; +} + +int32_t DmAuthMessageProcessor::GetAclListStr(std::shared_ptr &context, std::string &aclList) +{ + JsonObject jsonAclListObj; + jsonAclListObj[TAG_DMVERSION] = context->accesser.dmVersion; + + // Query ACL. + std::vector profiles = + DeviceProfileConnector::GetInstance().GetAccessControlProfile(); + std::vector accceserStrList; + std::vector accceseeStrList; + // Traverse the ACL table to find historical ACL records at both ends. + for (auto &item : profiles) { + if (item.GetAccesser().GetAccesserDeviceId() == context->accesser.deviceId && + item.GetAccesser().GetAccesserUserId() == context->accesser.userId && + item.GetAccessee().GetAccesseeDeviceId() == context->accessee.deviceId && + item.GetAccessee().GetAccesseeUserId() == context->accessee.userId) { + // Save the digest using SHA256. + uint8_t accesserHash[DM_HASH_LEN] = {0}; + std::string accesserStr = AccesserToStr(item); + Crypto::DmGenerateStrHash(accesserStr.data(), accesserStr.size(), accesserHash, DM_HASH_LEN, 0); + accceserStrList.push_back(reinterpret_cast(accesserHash)); + + uint8_t accesseeHash[DM_HASH_LEN] = {0}; + std::string accesseeStr = AccesseeToStr(item); + Crypto::DmGenerateStrHash(accesseeStr.data(), accesseeStr.size(), accesseeHash, DM_HASH_LEN, 0); + accceseeStrList.push_back(reinterpret_cast(accesseeHash)); + } + } + if (accceserStrList.empty() || accceseeStrList.empty()) { + LOGI("DmAuthMessageProcessor::CreateSyncMessage acl lis is empty"); + } + + jsonAclListObj[TAG_ACCESSER] = accceserStrList; + jsonAclListObj[TAG_ACCESSEE] = accceseeStrList; + aclList = jsonAclListObj.Dump(); + return DM_OK; +} + +void ToJson(JsonItemObject &itemObject, const DmAccessControlTable &table) +{ + itemObject["accessControlId"] = table.accessControlId; + itemObject["accesserId"] = table.accesserId; + itemObject["accesseeId"] = table.accesseeId; + itemObject["deviceId"] = table.deviceId; + itemObject["sessionKey"] = table.sessionKey; + itemObject["bindType"] = table.bindType; + itemObject["authType"] = table.authType; + itemObject["deviceType"] = table.deviceType; + itemObject["deviceIdHash"] = table.deviceIdHash; + itemObject["status"] = table.status; + itemObject["validPeriod"] = table.validPeriod; + itemObject["lastAuthTime"] = table.lastAuthTime; + itemObject["bindLevel"] = table.bindLevel; +} + +using JsonTypeCheckFuncPtr = bool (JsonItemObject::*)() const; + +template +void SetValueFromJson(const JsonItemObject &itemObject, const std::string &key, JsonTypeCheckFuncPtr funcPtr, T &value) +{ + if (itemObject.Contains(key) && (itemObject[key].*funcPtr)()) { + value = itemObject[key].Get(); + } +} + + +void FromJson(const JsonItemObject &itemObject, DmAccessControlTable &table) +{ + SetValueFromJson(itemObject, "accessControlId", &JsonItemObject::IsNumberInteger, table.accessControlId); + SetValueFromJson(itemObject, "accesserId", &JsonItemObject::IsNumberInteger, table.accesserId); + SetValueFromJson(itemObject, "accesseeId", &JsonItemObject::IsNumberInteger, table.accesseeId); + SetValueFromJson(itemObject, "deviceId", &JsonItemObject::IsNumberInteger, table.deviceId); + SetValueFromJson(itemObject, "sessionKey", &JsonItemObject::IsString, table.sessionKey); + SetValueFromJson(itemObject, "bindType", &JsonItemObject::IsNumberInteger, table.bindType); + SetValueFromJson(itemObject, "authType", &JsonItemObject::IsNumberInteger, table.authType); + SetValueFromJson(itemObject, "deviceType", &JsonItemObject::IsNumberInteger, table.deviceType); + SetValueFromJson(itemObject, "deviceIdHash", &JsonItemObject::IsString, table.deviceIdHash); + SetValueFromJson(itemObject, "status", &JsonItemObject::IsNumberInteger, table.status); + SetValueFromJson(itemObject, "validPeriod", &JsonItemObject::IsNumberInteger, table.validPeriod); + SetValueFromJson(itemObject, "lastAuthTime", &JsonItemObject::IsNumberInteger, table.lastAuthTime); + SetValueFromJson(itemObject, "bindLevel", &JsonItemObject::IsNumberInteger, table.bindLevel); +} + +void ToJson(JsonItemObject &itemObject, const DmAccessToSync &table) +{ + itemObject["deviceName"] = table.deviceName; + itemObject["deviceId"] = table.deviceId; + itemObject["userId"] = table.userId; + itemObject["accountId"] = table.accountId; + itemObject["tokenId"] = table.tokenId; + itemObject["bundleName"] = table.bundleName; + itemObject["bindLevel"] = table.bindLevel; + itemObject["sessionKeyId"] = table.sessionKeyId; + itemObject["skTimeStamp"] = table.skTimeStamp; +} + +void FromJson(const JsonItemObject &itemObject, DmAccessToSync &table) +{ + SetValueFromJson(itemObject, "deviceName", &JsonItemObject::IsString, table.deviceName); + SetValueFromJson(itemObject, "deviceId", &JsonItemObject::IsString, table.deviceId); + SetValueFromJson(itemObject, "userId", &JsonItemObject::IsNumberInteger, table.userId); + SetValueFromJson(itemObject, "accountId", &JsonItemObject::IsString, table.accountId); + SetValueFromJson(itemObject, "tokenId", &JsonItemObject::IsNumberInteger, table.tokenId); + SetValueFromJson(itemObject, "bundleName", &JsonItemObject::IsString, table.bundleName); + SetValueFromJson(itemObject, "bindLevel", &JsonItemObject::IsNumberInteger, table.bindLevel); + SetValueFromJson(itemObject, "sessionKeyId", &JsonItemObject::IsNumberInteger, table.sessionKeyId); + SetValueFromJson(itemObject, "skTimeStamp", &JsonItemObject::IsNumberInteger, table.skTimeStamp); +} + +} // namespace DistributedHardware +} // namespace OHOS \ No newline at end of file diff --git a/services/implementation/src/authentication_v2/dm_auth_state.cpp b/services/implementation/src/authentication_v2/dm_auth_state.cpp new file mode 100644 index 000000000..713dd8218 --- /dev/null +++ b/services/implementation/src/authentication_v2/dm_auth_state.cpp @@ -0,0 +1,600 @@ +/* + * Copyright (c) 2025 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 "access_control_profile.h" +#include "hichain_auth_connector.h" +#include "multiple_user_connector.h" +#include "dm_crypto.h" +#include "dm_auth_state.h" +#include "dm_auth_context.h" +#include "dm_auth_manager_base.h" +#include "dm_auth_state_machine.h" +#include "dm_crypto.h" +#if defined(SUPPORT_SCREENLOCK) +#include "screenlock_manager.h" +#endif +#include "dm_log.h" + +namespace OHOS { +namespace DistributedHardware { + +namespace { + +enum { + ACCOUNT_RELATED = 1, + ACCOUNT_UNRELATED, + ACCOUNT_ACROSS +}; + +enum { + SCOPE_DEVICE = 1, + SCOPE_USER, + SCOPE_APP, +}; + +enum DM_SUBJECT { + SUBJECT_PRIMARY = 1, + SUBJECT_SECONDARY, +}; + +// Security device auth credential query related definitions, keep consistent with device_auth.h +const char* const FILED_CRED_OWNER = "credOwner"; +const char* const FILED_DEVICE_ID = "deviceId"; +const char* const FILED_USER_ID = "userId"; +const char* const FILED_DEVICE_ID_HASH = "deviceIdHash"; +const char* const FILED_PEER_USER_SPACE_ID = "peerUserSpaceId"; +const char* const FILED_CRED_ID = "credId"; +const char* const FILED_CRED_TYPE = "credType"; +const char* const FILED_AUTHORIZED_SCOPE = "authorizedScope"; +const char* const FILED_AUTHORIZED_APP_LIST = "authorizedAppList"; +const char* const FILED_SUBJECT = "subject"; + +bool HaveSameTokenId(std::shared_ptr context, const std::vector &tokenList) +{ + // Store the token of src and sink. The size must be 2. + if (tokenList.size() != 2) { + LOGE("HaveSameTokenId invalid tokenList size."); + return false; + } + + // tokenIdList = [srcTokenId, sinkTokenId] + std::string srcTokenIdHash = Crypto::Sha256(tokenList[0]); + std::string sinkTokenIdHash = Crypto::Sha256(tokenList[1]); + + return (srcTokenIdHash == context->accesser.tokenIdHash) && + (sinkTokenIdHash == context->accessee.tokenIdHash); +} + +int32_t GetCredentialType(std::shared_ptr context, const JsonItemObject &credInfo, + std::vector &p2pCredIdList, std::vector &lnnCredIdList) +{ + if (!credInfo[FILED_CRED_TYPE].IsNumberInteger() || !credInfo[FILED_AUTHORIZED_SCOPE].IsNumberInteger() || + !credInfo[FILED_SUBJECT].IsNumberInteger()) { + LOGE("credType, authorizedScope or subject invalid."); + return DM_AUTH_CREDENTIAL_INVALID; + } + + int32_t credType = credInfo[FILED_CRED_TYPE].Get(); + int32_t authorizedScope = credInfo[FILED_AUTHORIZED_SCOPE].Get(); + int32_t subject = credInfo[FILED_SUBJECT].Get(); + + if (context->accesser.accountIdHash == context->accessee.accountIdHash && + context->accesser.accountId != "ohosAnonymousUid") { + // identicail credential + if (credType == ACCOUNT_RELATED && authorizedScope == SCOPE_USER) { + return DM_AUTH_CREDENTIAL_ACCOUNT_RELATED; + } + } else if (context->accesser.accountIdHash != context->accessee.accountIdHash && + context->accesser.accountId != "ohosAnonymousUid" && context->accessee.accountId != "ohosAnonymousUid") { + // share credential + if (credType == ACCOUNT_ACROSS && authorizedScope == SCOPE_USER && + context->direction == DM_AUTH_SOURCE && subject == SUBJECT_PRIMARY) { + return DM_AUTH_CREDENTIAL_ACCOUNT_ACROSS; + } + if (credType == ACCOUNT_ACROSS && authorizedScope == SCOPE_USER && + context->direction == DM_AUTH_SINK && subject == SUBJECT_SECONDARY) { + return DM_AUTH_CREDENTIAL_ACCOUNT_ACROSS; + } + } + + // point_to_point identical + std::vector appList; + DmAccess &remoteAccess = context->direction == DM_AUTH_SOURCE ? context->accessee : context->accesser; + credInfo[FILED_AUTHORIZED_APP_LIST].Get(appList); + if (credType == ACCOUNT_UNRELATED && + // 查询时无对端userId,只有查询出来后校验对端userId + remoteAccess.userIdHash == Crypto::Sha256(credInfo[FILED_PEER_USER_SPACE_ID].Get())) { + if (authorizedScope == SCOPE_APP && HaveSameTokenId(context, appList)) { + p2pCredIdList.push_back(credInfo[FILED_CRED_ID].Get()); + return DM_AUTH_CREDENTIAL_ACCOUNT_UNRELATED; + } else if (authorizedScope == SCOPE_USER && appList.empty()) { + lnnCredIdList.push_back(credInfo[FILED_CRED_ID].Get()); + } + } + + return DM_AUTH_CREDENTIAL_INVALID; +} + +int32_t DmQueryDmCredential(std::shared_ptr context, JsonObject &queryResult) +{ + JsonObject queryParams; + + DmAccess &access = context->direction == DM_AUTH_SOURCE ? context->accesser : context->accessee; + DmAccess &remoteAccess = context->direction == DM_AUTH_SOURCE ? context->accessee : context->accesser; + + queryParams[FILED_DEVICE_ID_HASH] = remoteAccess.deviceIdHash; + queryParams[FILED_CRED_TYPE] = DM_AUTH_CREDENTIAL_ACCOUNT_UNRELATED; + queryParams[FILED_CRED_OWNER] = "DM"; + LOGI("DmQueryCredential for userId %{public}d and queryParams %{public}s", + access.userId, queryParams.Dump().c_str()); + + return context->hiChainAuthConnector->QueryCredentialInfo(access.userId, queryParams, queryResult); +} + +int32_t DmQueryOtherCredential(std::shared_ptr context, JsonObject &queryResult) +{ + JsonObject queryParams; + + DmAccess &access = context->direction == DM_AUTH_SOURCE ? context->accesser : context->accessee; + DmAccess &remoteAccess = context->direction == DM_AUTH_SOURCE ? context->accessee : context->accesser; + if (access.accountId == "ohosAnonymousUid" || remoteAccess.accountId == "ohosAnonymousUid") { + LOGI("DmQueryOtherCredential accountId ohosAnonymousUid no need query other credential"); + return DM_OK; + } + + queryParams[FILED_DEVICE_ID] = access.deviceId; + queryParams[FILED_USER_ID] = access.accountId; + + LOGI("DmQueryCredential for userId %{public}d and queryParams %{public}s", + access.userId, queryParams.Dump().c_str()); + + return context->hiChainAuthConnector->QueryCredentialInfo(access.userId, queryParams, queryResult); +} + +int32_t DmDeleteAbnormalCredential(std::shared_ptr context, std::vector &credTypeList, + std::vector &p2pCredIdList, std::vector &lnnCredIdList) +{ + DmAccess &access = context->direction == DM_AUTH_SOURCE ? context->accesser : context->accessee; + + int32_t relatedAccountCount = std::count(credTypeList.begin(), credTypeList.end(), + DM_AUTH_CREDENTIAL_ACCOUNT_RELATED); + int32_t acrossAccountCount = std::count(credTypeList.begin(), credTypeList.end(), + DM_AUTH_CREDENTIAL_ACCOUNT_ACROSS); + int32_t unrelatedAccountCount = std::count(credTypeList.begin(), credTypeList.end(), + DM_AUTH_CREDENTIAL_ACCOUNT_UNRELATED); + if (relatedAccountCount > 1 || acrossAccountCount > 1) { + context->reply = ERR_DM_FAILED; + context->reason = ERR_DM_FAILED; + return ERR_DM_FAILED; + } + + if (lnnCredIdList.size() > 1) { + LOGI("DmDeleteAbnormalCredential found duplicate lnn credential"); + for (std::string credId : lnnCredIdList) { + (void)context->hiChainAuthConnector->DeleteCredential(access.userId, credId); + } + lnnCredIdList.clear(); + } + // unrelatedAccountCount > 1,duplicate p2p credential + // for dfx: + // unrelatedAccountCount <= 1 && lnnCredIdList.size() == 0, no lnn credential, impossible, delete p2p credential too + if (unrelatedAccountCount > 1 || lnnCredIdList.size() == 0) { + LOGI("DmDeleteAbnormalCredential found duplicate p2p credential"); + for (std::string credId : p2pCredIdList) { + (void)context->hiChainAuthConnector->DeleteCredential(access.userId, credId); + } + p2pCredIdList.clear(); + access.credentialInfos.erase(DM_AUTH_CREDENTIAL_ACCOUNT_UNRELATED); + credTypeList.erase(std::remove(credTypeList.begin(), credTypeList.end(), + DM_AUTH_CREDENTIAL_ACCOUNT_UNRELATED), credTypeList.end()); + } + + return DM_OK; +} + +bool DmIsLnnCredential(std::shared_ptr context, const JsonItemObject &credInfo) +{ + if (!credInfo[FILED_CRED_TYPE].IsNumberInteger() || !credInfo[FILED_AUTHORIZED_SCOPE].IsNumberInteger()) { + LOGE("credType or authorizedScope invalid."); + return false; + } + + int32_t credType = credInfo[FILED_CRED_TYPE].Get(); + int32_t authorizedScope = credInfo[FILED_AUTHORIZED_SCOPE].Get(); + + // point_to_point identical + DmAccess &remoteAccess = context->direction == DM_AUTH_SOURCE ? context->accessee : context->accesser; + if (credType == ACCOUNT_UNRELATED && authorizedScope == SCOPE_USER && + // 查询时无对端userId,只有查询出来后校验对端userId + remoteAccess.userIdHash == Crypto::Sha256(credInfo[FILED_PEER_USER_SPACE_ID].Get())) { + return true; + } + + return DM_AUTH_CREDENTIAL_INVALID; +} + +int32_t DmQueryCredential(std::shared_ptr context, JsonObject &queryResult) +{ + int32_t ret; + int32_t credType; + + DmAccess &access = context->direction == DM_AUTH_SOURCE ? context->accesser : context->accessee; + + // 1. 查询点对点凭据 + ret = DmQueryDmCredential(context, queryResult); + if (ret != DM_OK) { + return ret; + } + + // 2. 查询其他账号凭据,如同账号、分享 + ret = DmQueryOtherCredential(context, queryResult); + if (ret != DM_OK) { + return ret; + } + + // 3. 确认凭据类型 + std::vector credTypeList; + std::vector p2pCredIdList; + std::vector lnnCredIdList; + for (auto& item : queryResult.Items()) { + // 确认凭据类型 + LOGI("DmQueryCredential credInfo: %{public}s", item.Dump().c_str()); + credType = GetCredentialType(context, item, p2pCredIdList, lnnCredIdList); + if (credType == DM_AUTH_CREDENTIAL_INVALID) { + continue; + } + + item[FILED_CRED_TYPE] = credType; + LOGI("DmQueryCredential useful credType %{public}d", credType); + access.credentialInfos[credType] = item.Dump(); + credTypeList.push_back(credType); + } + + ret = DmDeleteAbnormalCredential(context, credTypeList, p2pCredIdList, lnnCredIdList); + if (ret != DM_OK) { + access.credentialInfos.clear(); + return ret; + } + + if (lnnCredIdList.size() == 1) { + access.lnnCredentialId = lnnCredIdList.front(); + } else if (lnnCredIdList.empty() && + std::count(credTypeList.begin(), credTypeList.end(), DM_AUTH_CREDENTIAL_ACCOUNT_UNRELATED) > 0) { + // 不存在有点对点凭据,无总线凭据的情况 + LOGE("DmQueryCredential found point-to-point credential but no user credential"); + return ERR_DM_FAILED; + } + access.credentialTypeLists = credTypeList; + + return DM_OK; +} + +// Compares hashs of the device IDs and user IDs +bool AclCompareTwoIds(std::shared_ptr context, + const DistributedDeviceProfile::Accesser &accesser, const DistributedDeviceProfile::Accessee &accessee) +{ + return Crypto::Sha256(accesser.GetAccesserDeviceId()) == context->accesser.deviceIdHash && + Crypto::Sha256(std::to_string(accesser.GetAccesserUserId())) == context->accesser.userIdHash && + Crypto::Sha256(accessee.GetAccesseeDeviceId()) == context->accessee.deviceIdHash && + Crypto::Sha256(std::to_string(accessee.GetAccesseeUserId())) == context->accessee.userIdHash; +} + +// Compares hashs of the device IDs, user IDs, account IDs, and token IDs +bool AclCompareFourIds(std::shared_ptr context, + const DistributedDeviceProfile::Accesser &accesser, const DistributedDeviceProfile::Accessee &accessee) +{ + return AclCompareTwoIds(context, accesser, accessee) && + Crypto::Sha256(accesser.GetAccesserAccountId()) == context->accesser.accountIdHash && + Crypto::Sha256(std::to_string(accesser.GetAccesserTokenId())) == context->accesser.tokenIdHash && + Crypto::Sha256(accessee.GetAccesseeAccountId()) == context->accessee.accountIdHash && + Crypto::Sha256(std::to_string(accessee.GetAccesseeTokenId())) == context->accessee.tokenIdHash; +} + +} + +// clone task timeout map +const std::map TASK_TIME_OUT_MAP = { + { std::string(AUTHENTICATE_TIMEOUT_TASK), CLONE_AUTHENTICATE_TIMEOUT }, + { std::string(NEGOTIATE_TIMEOUT_TASK), CLONE_NEGOTIATE_TIMEOUT }, + { std::string(CONFIRM_TIMEOUT_TASK), CLONE_CONFIRM_TIMEOUT }, + { std::string(ADD_TIMEOUT_TASK), CLONE_ADD_TIMEOUT }, + { std::string(WAIT_NEGOTIATE_TIMEOUT_TASK), CLONE_WAIT_NEGOTIATE_TIMEOUT }, + { std::string(WAIT_REQUEST_TIMEOUT_TASK), CLONE_WAIT_REQUEST_TIMEOUT }, + { std::string(WAIT_PIN_AUTH_TIMEOUT_TASK), CLONE_PIN_AUTH_TIMEOUT }, + { std::string(SESSION_HEARTBEAT_TIMEOUT_TASK), CLONE_SESSION_HEARTBEAT_TIMEOUT } +}; + +int32_t DmAuthState::GetTaskTimeout(std::shared_ptr context, const char* taskName, int32_t taskTimeOut) +{ + LOGI("GetTaskTimeout, taskName: %{public}s, authType_: %{public}d", taskName, context->authType); + if (DmAuthState::IsImportAuthCodeCompatibility(context->authType)) { + auto timeout = TASK_TIME_OUT_MAP.find(std::string(taskName)); + if (timeout != TASK_TIME_OUT_MAP.end()) { + return timeout->second; + } + } + return taskTimeOut; +} + +void DmAuthState::HandleAuthenticateTimeout(std::shared_ptr context, std::string name) +{ + LOGI("DmAuthContext::HandleAuthenticateTimeout start timer name %{public}s", name.c_str()); + context->timer->DeleteTimer(name); + context->reason = ERR_DM_TIME_OUT; + context->authStateMachine->NotifyEventFinish(DmEventType::ON_FAIL); + LOGI("DmAuthContext::HandleAuthenticateTimeout complete"); +} + +bool DmAuthState::IsScreenLocked() +{ + bool isLocked = false; +#if defined(SUPPORT_SCREENLOCK) + isLocked = OHOS::ScreenLock::ScreenLockManager::GetInstance()->IsScreenLocked(); +#endif + LOGI("IsScreenLocked isLocked: %{public}d.", isLocked); + return isLocked; +} + +void DmAuthState::SyncAclList(std::shared_ptr context, + std::string credId, int32_t sessionKeyId, int32_t aclId) +{ + int32_t accountId = MultipleUserConnector::GetCurrentAccountUserID(); + LOGI("SyncAclList accountId:%{public}d, credId:%{public}s, sessionKeyId:%{public}d, aclId:%{public}d", + accountId, credId.c_str(), sessionKeyId, aclId); + // 根据凭据id 删除sink端多余的凭据 + int32_t ret = context->hiChainAuthConnector->DeleteCredential(accountId, credId); + if (ret != DM_OK) { + LOGE("SyncAclList DeleteCredential failed."); + } + // 根据skid删除sk,删除skid + ret = DeviceProfileConnector::GetInstance().DeleteSessionKey(sessionKeyId); + if (ret != DM_OK) { + LOGE("SyncAclList DeleteSessionKey failed."); + } + // 删除本条acl + DeviceProfileConnector::GetInstance().DeleteAccessControlById(aclId); +} + +void DmAuthState::SourceFinish(std::shared_ptr context) +{ + context->listener->OnAuthResult(context->processInfo, context->peerTargetId.deviceId, context->accessee.tokenIdHash, + context->state, context->reason); + context->listener->OnBindResult(context->processInfo, context->peerTargetId, context->reply, + context->state, GenerateBindResultContent(context->accessee)); + context->isFinished = true; + if (context->reason != DM_OK) { + int32_t accountId = MultipleUserConnector::GetCurrentAccountUserID(); + // 根据凭据id 删除sink端多余的凭据 + int32_t ret = + context->hiChainAuthConnector->DeleteCredential(accountId, context->accesser.transmitCredentialId); + if (ret != DM_OK) { + LOGE("SourceFinish DeleteCredential failed."); + } + // 根据skid删除sk,删除skid + ret = DeviceProfileConnector::GetInstance().DeleteSessionKey(context->accesser.transmitSessionKeyId); + if (ret != DM_OK) { + LOGE("SourceFinish DeleteSessionKey failed."); + } + } + context->authUiStateMgr->UpdateUiState(DmUiStateMsg::MSG_CANCEL_PIN_CODE_INPUT); + context->authStateMachine->Stop(); + context->timer->DeleteAll(); +} + +void DmAuthState::SinkFinish(std::shared_ptr context) +{ + context->listener->OnSinkBindResult(context->processInfo, context->peerTargetId, context->reply, + context->state, GenerateBindResultContent(context->accesser)); + context->isFinished = true; + if (context->reason != DM_OK) { + int32_t accountId = MultipleUserConnector::GetCurrentAccountUserID(); + // 根据凭据id 删除sink端多余的凭据 + int32_t ret = + context->hiChainAuthConnector->DeleteCredential(accountId, context->accessee.transmitCredentialId); + if (ret != DM_OK) { + LOGE("SinkFinish DeleteCredential failed."); + } + // 根据skid删除sk,删除skid + ret = DeviceProfileConnector::GetInstance().DeleteSessionKey(context->accessee.transmitSessionKeyId); + if (ret != DM_OK) { + LOGE("SinkFinish DeleteSessionKey failed."); + } + } else { + context->authMessageProcessor->PutAccessControlList(context, context->accessee, context->accesser.deviceId); + } + context->authUiStateMgr->UpdateUiState(DmUiStateMsg::MSG_CANCEL_PIN_CODE_SHOW); + context->authStateMachine->Stop(); + context->timer->DeleteAll(); + context->authMessageProcessor->CreateAndSendMsg(MSG_TYPE_AUTH_RESP_FINISH, context); // 发送201给source侧 +} + +std::string DmAuthState::GenerateBindResultContent(DmAccess &access) +{ + JsonObject jsonObj; + jsonObj[DM_BIND_RESULT_NETWORK_ID] = access.networkId; + if (access.deviceId.empty()) { + jsonObj[TAG_DEVICE_ID] = ""; + } else { + char deviceIdHash[DM_MAX_DEVICE_ID_LEN] = {0}; + Crypto::GetUdidHash(access.deviceId, reinterpret_cast(deviceIdHash)); + jsonObj[TAG_DEVICE_ID] = deviceIdHash; + } + std::string content = jsonObj.Dump(); + return content; +} + +int32_t DmAuthState::GetAuthCredentialInfo(std::shared_ptr context) +{ + int32_t ret; + JsonObject queryResult; + + // 1. Retrieve all credentials + ret = DmQueryCredential(context, queryResult); + if (ret != DM_OK) { + LOGE("AuthSinkNegotiateStateMachine::GetAuthCredentialInfo fail to query credential"); + return ret; + } + + // 2. Retrieve all ACLs + DmAccess &access = context->direction == DM_AUTH_SOURCE ? context->accesser : context->accessee; + std::vector profiles = + DeviceProfileConnector::GetInstance().GetAllAccessControlProfile(); + LOGI("AuthSinkNegotiateStateMachine::GetAuthCredentialInfo success to get %{public}ld acls", profiles.size()); + for (const DistributedDeviceProfile::AccessControlProfile &item : profiles) { + bool isAclMatched = false; + DistributedDeviceProfile::Accesser accesser = item.GetAccesser(); + DistributedDeviceProfile::Accessee accessee = item.GetAccessee(); + + // Ensure credentials match with ACL + std::string credId = context->direction == DM_AUTH_SOURCE ? accesser.GetAccesserCredentialId() : + accessee.GetAccesseeCredentialId(); + if (!queryResult.Contains(credId) || item.GetStatus() != ACTIVE) { + continue; + } + + // Confirm if there is a trusted relationship + uint32_t credType = queryResult[credId][FILED_CRED_TYPE].Get(); + if (credType == DM_AUTH_CREDENTIAL_ACCOUNT_RELATED || credType == DM_AUTH_CREDENTIAL_ACCOUNT_ACROSS) { + isAclMatched = AclCompareTwoIds(context, accesser, accessee); + } else if (credType == DM_AUTH_CREDENTIAL_ACCOUNT_UNRELATED) { + isAclMatched = AclCompareFourIds(context, accesser, accessee); + } + + if (isAclMatched) { + access.aclProfiles[credType] = item; + LOGI("AuthSinkNegotiateStateMachine::GetAuthCredentialInfo get acl credType %{public}d", credType); + } + } + + // 有凭据无可信关系时,作无凭据处理,删除点对点凭据 + if (access.aclProfiles.empty() && + access.credentialInfos.find(DM_AUTH_CREDENTIAL_ACCOUNT_UNRELATED) != access.credentialInfos.end()) { + JsonObject credInfo(access.credentialInfos[DM_AUTH_CREDENTIAL_ACCOUNT_UNRELATED]); + (void)context->hiChainAuthConnector->DeleteCredential(access.userId, + credInfo[FILED_CRED_ID].Get()); + + // 列表中删除对应credType + access.credentialTypeLists.erase(std::remove(access.credentialTypeLists.begin(), + access.credentialTypeLists.end(), DM_AUTH_CREDENTIAL_ACCOUNT_UNRELATED), access.credentialTypeLists.end()); + access.credentialInfos.erase(DM_AUTH_CREDENTIAL_ACCOUNT_UNRELATED); + } + + return DM_OK; +} + +bool DmAuthState::NeedReqUserConfirm(std::shared_ptr context) +{ + // 不管是否有可信关系,都需要走pin码认证,主要指鸿蒙环PIN码导入场景 + if (DmAuthState::IsImportAuthCodeCompatibility(context->authType)) { + return true; + } + + // 有ACL,跳转到结束状态,发200报文,直接组网 + DmAccess access = context->direction == DM_AUTH_SOURCE ? context->accesser : context->accessee; + if (access.isAuthed) { + return false; + } + + return true; +} + +bool DmAuthState::NeedPinAuth(std::shared_ptr context) +{ + if (DmAuthState::IsImportAuthCodeCompatibility(context->authType)) { + return true; + } + + DmAccess access = context->direction == DM_AUTH_SOURCE ? context->accesser : context->accessee; + if (access.isAuthed) { + return false; + } + + std::vector credTypeLists = context->accesser.credentialTypeLists; + if (credTypeLists.size() == 1) { + int32_t credType = credTypeLists.front(); + if (credType == DM_AUTH_CREDENTIAL_ACCOUNT_RELATED || credType == DM_AUTH_CREDENTIAL_ACCOUNT_ACROSS) { + return false; + } + } + + return true; +} + +bool DmAuthState::NeedAgreeCredential(std::shared_ptr context) +{ + return context->needAgreeCredential; +} + +bool DmAuthState::NeedAgreeAcl(std::shared_ptr context) +{ + return (context->direction == DM_AUTH_SOURCE) ? !context->accesser.isAuthed : !context->accessee.isAuthed; +} + +bool DmAuthState::IsImportAuthCodeCompatibility(DmAuthType authType) +{ + if (authType == DmAuthType::AUTH_TYPE_IMPORT_AUTH_CODE || + authType == DmAuthType::AUTH_TYPE_NFC) { + return true; + } + return false; +} + + +bool DmAuthState::IsQuadrupleAndBindLevelSame(std::shared_ptr context) +{ + const DmAccess &access = (context->direction == DM_AUTH_SOURCE) ? context->accessee : context->accesser; + bool isSame = Crypto::Sha256(access.deviceId) == access.deviceIdHash && + Crypto::Sha256(std::to_string(access.userId)) == access.userIdHash && + Crypto::Sha256(access.accountId) == access.accountIdHash && + Crypto::Sha256(std::to_string(access.tokenId)) == access.tokenIdHash && + context->accesser.bindLevel == context->accessee.bindLevel; + if (!isSame) { + context->reason = ERR_DM_QUADRUPLE_NOT_SAME; + context->reply = ERR_DM_QUADRUPLE_NOT_SAME; + context->state = static_cast(GetStateType()); + if (context->direction == DM_AUTH_SOURCE) { + context->authMessageProcessor->CreateAndSendMsg(MSG_TYPE_AUTH_REQ_FINISH, context); + } else { + context->authStateMachine->TransitionTo(std::make_shared()); + } + } + + return isSame; +} + +std::vector DmAuthState::GetAclList(std::shared_ptr + context) +{ + std::vector profiles = + DeviceProfileConnector::GetInstance().GetAccessControlProfile(); + std::vector aclList; + for (auto &item : profiles) { + if (item.GetAccesser().GetAccesserDeviceId() == context->accesser.deviceId && + item.GetAccesser().GetAccesserUserId() == context->accesser.userId && + item.GetAccessee().GetAccesseeDeviceId() == context->accessee.deviceId && + item.GetAccessee().GetAccesseeUserId() == context->accessee.userId) { + aclList.push_back(item); + } + } + + if (aclList.empty()) { + LOGI("DmAuthState::GetAclList acl is empty"); + } + + return aclList; +} + +} // namespace DistributedHardware +} // namespace OHOS diff --git a/services/implementation/src/authentication_v2/dm_auth_state_machine.cpp b/services/implementation/src/authentication_v2/dm_auth_state_machine.cpp new file mode 100644 index 000000000..21680b981 --- /dev/null +++ b/services/implementation/src/authentication_v2/dm_auth_state_machine.cpp @@ -0,0 +1,347 @@ +/* + * Copyright (c) 2025 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 "dm_log.h" +#include "dm_constants.h" +#include "dm_auth_state.h" +#include "dm_auth_context.h" +#include "dm_auth_manager_base.h" +#include "dm_auth_state_machine.h" + +namespace OHOS { +namespace DistributedHardware { + +DmAuthStateMachine::DmAuthStateMachine(std::shared_ptr context) +{ + exceptionEvent_= { + DmEventType::ON_ERROR, // Authentication error, there is a possibility of retry. + DmEventType::ON_TIMEOUT, + DmEventType::ON_FAIL, // Authentication failed + DmEventType::ON_SCREEN_LOCKED, + }; + + running_ = true; + direction_ = context->direction; + + if (direction_ == DM_AUTH_SOURCE) { + this->InsertSrcTransTable(); + } else { + this->InsertSinkTransTable(); + } + + this->SetCurState(DmAuthStateType::AUTH_IDLE_STATE); + thread_ = std::thread(&DmAuthStateMachine::Run, this, context); +} + +DmAuthStateMachine::~DmAuthStateMachine() +{ + Stop(); + thread_.join(); +}; + +void DmAuthStateMachine::InsertSrcTransTable() +{ + // Source-end state transition table + stateTransitionTable_.insert({ + {DmAuthStateType::AUTH_IDLE_STATE, {DmAuthStateType::AUTH_SRC_START_STATE}}, + {DmAuthStateType::AUTH_SRC_START_STATE, {DmAuthStateType::AUTH_SRC_NEGOTIATE_STATE}}, + {DmAuthStateType::AUTH_SRC_NEGOTIATE_STATE, {DmAuthStateType::AUTH_SRC_CONFIRM_STATE}}, + {DmAuthStateType::AUTH_SRC_CONFIRM_STATE, { + DmAuthStateType::AUTH_SRC_PIN_NEGOTIATE_START_STATE, + DmAuthStateType::AUTH_SRC_DATA_SYNC_STATE, + }}, + {DmAuthStateType::AUTH_SRC_PIN_NEGOTIATE_START_STATE, { + DmAuthStateType::AUTH_SRC_CREDENTIAL_AUTH_START_STATE, + DmAuthStateType::AUTH_SRC_PIN_INPUT_STATE, + DmAuthStateType::AUTH_SRC_PIN_NEGOTIATE_ULTRASONIC_PIN_STATE, + DmAuthStateType::AUTH_SRC_PIN_AUTH_START_STATE, + }}, + {DmAuthStateType::AUTH_SRC_PIN_INPUT_STATE, { + DmAuthStateType::AUTH_SRC_PIN_AUTH_START_STATE, + }}, + {DmAuthStateType::AUTH_SRC_PIN_NEGOTIATE_ULTRASONIC_PIN_STATE, { + DmAuthStateType::AUTH_SRC_PIN_AUTH_START_STATE, + DmAuthStateType::AUTH_SRC_PIN_NEGOTIATE_START_STATE, + }}, + {DmAuthStateType::AUTH_SRC_PIN_AUTH_START_STATE, { + DmAuthStateType::AUTH_SRC_PIN_AUTH_MSG_NEGOTIATE_STATE, + DmAuthStateType::AUTH_SRC_PIN_NEGOTIATE_START_STATE, + }}, + {DmAuthStateType::AUTH_SRC_PIN_AUTH_MSG_NEGOTIATE_STATE, { + DmAuthStateType::AUTH_SRC_PIN_AUTH_DONE_STATE, + DmAuthStateType::AUTH_SRC_PIN_NEGOTIATE_START_STATE, + }}, + {DmAuthStateType::AUTH_SRC_PIN_AUTH_DONE_STATE, { + DmAuthStateType::AUTH_SRC_CREDENTIAL_EXCHANGE_STATE, + DmAuthStateType::AUTH_SRC_PIN_NEGOTIATE_START_STATE, + }}, + {DmAuthStateType::AUTH_SRC_CREDENTIAL_EXCHANGE_STATE, { + DmAuthStateType::AUTH_SRC_CREDENTIAL_AUTH_START_STATE, + DmAuthStateType::AUTH_SRC_DATA_SYNC_STATE, + }}, + {DmAuthStateType::AUTH_SRC_CREDENTIAL_AUTH_START_STATE, + {DmAuthStateType::AUTH_SRC_CREDENTIAL_AUTH_NEGOTIATE_STATE}}, + + {DmAuthStateType::AUTH_SRC_CREDENTIAL_AUTH_NEGOTIATE_STATE, + {DmAuthStateType::AUTH_SRC_CREDENTIAL_AUTH_DONE_STATE}}, + + {DmAuthStateType::AUTH_SRC_CREDENTIAL_AUTH_DONE_STATE, + {DmAuthStateType::AUTH_SRC_DATA_SYNC_STATE, DmAuthStateType::AUTH_SRC_CREDENTIAL_AUTH_NEGOTIATE_STATE}}, + + {DmAuthStateType::AUTH_SRC_DATA_SYNC_STATE, {DmAuthStateType::AUTH_SRC_FINISH_STATE}}, + + {DmAuthStateType::AUTH_SRC_FINISH_STATE, {}} + }); + + return; +} + +void DmAuthStateMachine::InsertSinkTransTable() +{ + // Sink-end state transition table + stateTransitionTable_.insert({ + {DmAuthStateType::AUTH_IDLE_STATE, {DmAuthStateType::AUTH_SINK_NEGOTIATE_STATE}}, + {DmAuthStateType::AUTH_SINK_NEGOTIATE_STATE, { + DmAuthStateType::AUTH_SINK_CONFIRM_STATE, + }}, + {DmAuthStateType::AUTH_SINK_CONFIRM_STATE, { + DmAuthStateType::AUTH_SINK_PIN_NEGOTIATE_START_STATE, + DmAuthStateType::AUTH_SINK_CREDENTIAL_AUTH_START_STATE, + }}, + {DmAuthStateType::AUTH_SINK_PIN_NEGOTIATE_START_STATE, { + DmAuthStateType::AUTH_SINK_PIN_DISPLAY_STATE, + DmAuthStateType::AUTH_SINK_PIN_NEGOTIATE_ULTRASONIC_PIN_STATE, + DmAuthStateType::AUTH_SINK_PIN_AUTH_START_STATE, + }}, + {DmAuthStateType::AUTH_SINK_PIN_DISPLAY_STATE, { + DmAuthStateType::AUTH_SINK_PIN_AUTH_START_STATE, + }}, + {DmAuthStateType::AUTH_SINK_PIN_NEGOTIATE_ULTRASONIC_PIN_STATE, { + DmAuthStateType::AUTH_SINK_PIN_AUTH_START_STATE, + DmAuthStateType::AUTH_SINK_PIN_NEGOTIATE_START_STATE, + }}, + {DmAuthStateType::AUTH_SINK_PIN_AUTH_START_STATE, { + DmAuthStateType::AUTH_SINK_PIN_AUTH_MSG_NEGOTIATE_STATE, + DmAuthStateType::AUTH_SINK_PIN_NEGOTIATE_START_STATE, + }}, + {DmAuthStateType::AUTH_SINK_PIN_AUTH_MSG_NEGOTIATE_STATE, { + DmAuthStateType::AUTH_SINK_PIN_AUTH_DONE_STATE, + DmAuthStateType::AUTH_SINK_PIN_NEGOTIATE_START_STATE, + }}, + {DmAuthStateType::AUTH_SINK_PIN_AUTH_DONE_STATE, { + DmAuthStateType::AUTH_SINK_CREDENTIAL_EXCHANGE_STATE, + DmAuthStateType::AUTH_SINK_CREDENTIAL_AUTH_START_STATE, + DmAuthStateType::AUTH_SINK_FINISH_STATE, + }}, + {DmAuthStateType::AUTH_SINK_CREDENTIAL_EXCHANGE_STATE, { + DmAuthStateType::AUTH_SINK_CREDENTIAL_AUTH_START_STATE, + }}, + {DmAuthStateType::AUTH_SINK_CREDENTIAL_AUTH_START_STATE, { + DmAuthStateType::AUTH_SINK_CREDENTIAL_AUTH_NEGOTIATE_STATE, + }}, + {DmAuthStateType::AUTH_SINK_CREDENTIAL_AUTH_NEGOTIATE_STATE, + {DmAuthStateType::AUTH_SINK_DATA_SYNC_STATE, DmAuthStateType::AUTH_SINK_CREDENTIAL_AUTH_START_STATE}}, + + {DmAuthStateType::AUTH_SINK_DATA_SYNC_STATE, {DmAuthStateType::AUTH_SINK_FINISH_STATE}}, + {DmAuthStateType::AUTH_SINK_FINISH_STATE, {}} + }); + + return; +} + +// Notification status transition. The execution status corresponds to specific actions and exception handling. +int32_t DmAuthStateMachine::TransitionTo(std::shared_ptr state) +{ + int32_t ret = DM_OK; + DmAuthStateType nextState = state->GetStateType(); + { + std::lock_guard lock(stateMutex_); + if (this->CheckStateTransitValid(nextState)) { + LOGI("DmAuthStateMachine: The state transition from %{public}d to %{public}d.", + GetCurState(), nextState); + statesQueue_.push(state); + } else { + // The state transition is invalid. + LOGE("DmAuthStateMachine: The state transition does not meet the rule from %{public}d to %{public}d.", + GetCurState(), nextState); + ret = ERR_DM_NEXT_STATE_INVALID; + reason = ERR_DM_NEXT_STATE_INVALID; + if (direction_ == DM_AUTH_SOURCE) { + statesQueue_.push(std::make_shared()); + } else { + statesQueue_.push(std::make_shared()); + } + } + } + stateCv_.notify_one(); + return ret; +} + +/* +Expected event in an action, which is used for blocking. +When the expected event is complete or other exceptions occur, the actual event is returned. +Other normal events continue to be blocked (only in the action). +*/ +DmEventType DmAuthStateMachine::WaitExpectEvent(DmEventType eventType) +{ + /* + 1. Actual event = Expected event, return actual event + 2. Actual event = Abnormal event (event timeout). The actual event is also returned. + 3. Actual event = Other events, continue to block, but there is a timeout limit. + */ + std::unique_lock lock(eventMutex_); + auto startTime = std::chrono::high_resolution_clock::now(); + while (running_.load()) { + eventCv_.wait(lock, [&] { + return !running_.load() || !eventQueue_.empty(); + }); + if (!running_.load()) { + return DmEventType::ON_FAIL; + } + + DmEventType actualEventType = eventQueue_.front(); + eventQueue_.pop(); + // Determine whether the event is an expected event or abnormal event in list. + if (actualEventType == eventType || (exceptionEvent_.find(actualEventType) != exceptionEvent_.end())) { + return actualEventType; + } + // Event Wait Timeout + auto elapsedTime = std::chrono::duration_cast( + std::chrono::high_resolution_clock::now() - startTime); + if (elapsedTime.count() >= EVENT_TIMEOUT) { + break; + } + } + return DmEventType::ON_TIMEOUT; +} + +/* +The event is invoked after the event is complete. +The event enumeration can be invoked only when the event is triggered. +If the event is an abnormal event, the reason or reply of the context must be recorded. +*/ +void DmAuthStateMachine::NotifyEventFinish(DmEventType eventType) +{ + LOGI("DmAuthStateMachine: NotifyEventFinish Event:%{public}d.", eventType); + { + std::unique_lock lock(eventMutex_); + eventQueue_.push(eventType); + } + eventCv_.notify_one(); + if (eventType == DmEventType::ON_FAIL) { + if (direction_ == DM_AUTH_SOURCE) { + this->TransitionTo(std::make_shared()); + } else { + this->TransitionTo(std::make_shared()); + } + } +} + +// Cyclically wait for state transition and execute action. +void DmAuthStateMachine::Run(std::shared_ptr context) +{ + while (running_.load()) { + auto state = FetchAndSetCurState(); + if (!state.has_value()) { + break; + } + if (reason != DM_OK) { + context->reason = reason; + } + // Obtain the status and execute the status action. + DmAuthStateType stateType = state.value()->GetStateType(); + int32_t ret = state.value()->Action(context); + if (ret != DM_OK) { + LOGE("DmAuthStateMachine::Run err:%{public}d", ret); + if (context->reason == DM_OK) { + // If the reason of the context is not set, set this parameter to ret. + context->reason = ret; + } + if (context->direction == DM_AUTH_SOURCE) { + this->TransitionTo(std::make_shared()); + } else { + this->TransitionTo(std::make_shared()); + } + } else { + LOGI("DmAuthStateMachine::Run ok state:%{public}d", stateType); + } + } + LOGI("DmAuthStateMachine::Run end"); +} + +std::optional> DmAuthStateMachine::FetchAndSetCurState() +{ + std::unique_lock lock(stateMutex_); + stateCv_.wait(lock, [&] { + return !running_.load() || !statesQueue_.empty(); + }); + + if (!running_.load()) return std::nullopt; + + std::shared_ptr state = statesQueue_.front(); + statesQueue_.pop(); + SetCurState(state->GetStateType()); + return state; +} + +void DmAuthStateMachine::Stop() +{ + running_.store(false); + stateCv_.notify_all(); + eventCv_.notify_all(); +} + +void DmAuthStateMachine::SetCurState(DmAuthStateType state) +{ + LOGD("DmAuthStateMachine::SetCurState state: %{public}d", state); + curState_ = state; +} + +DmAuthStateType DmAuthStateMachine::GetCurState() +{ + return curState_; +} + +// Verify the validity of the next state transition. +bool DmAuthStateMachine::CheckStateTransitValid(DmAuthStateType nextState) +{ + if (curState_ == nextState || curState_ == DmAuthStateType::AUTH_SRC_FINISH_STATE || + curState_ == DmAuthStateType::AUTH_SINK_FINISH_STATE) { + return false; + } + + /* + Check whether the next state is AuthSrcFinishState or AuthSinkFinishState + which can directly switch to the state and return. + */ + if (nextState == DmAuthStateType::AUTH_SRC_FINISH_STATE || nextState == DmAuthStateType::AUTH_SINK_FINISH_STATE) { + return true; + } + // Check whether the state transition table is met. + DmAuthStateType state = curState_; + if (!statesQueue_.empty()) { + state = statesQueue_.back()->GetStateType(); + } + auto it = stateTransitionTable_.find(state); + if (it != stateTransitionTable_.end()) { + const std::set& allowedStates = it->second; + return allowedStates.find(nextState) != allowedStates.end(); + } + return false; +} + + +} // namespace DistributedHardware +} // namespace OHOS diff --git a/services/implementation/src/cryptomgr/crypto_mgr.cpp b/services/implementation/src/cryptomgr/crypto_mgr.cpp index 91d35dee0..1e9e1cf22 100644 --- a/services/implementation/src/cryptomgr/crypto_mgr.cpp +++ b/services/implementation/src/cryptomgr/crypto_mgr.cpp @@ -17,6 +17,7 @@ #include #include +#include #include "mbedtls/base64.h" #include "mbedtls/cipher.h" @@ -304,10 +305,21 @@ int32_t CryptoMgr::SaveSessionKey(const uint8_t *sessionKey, const uint32_t keyL std::lock_guard lock(sessionKeyMtx_); sessionKey_.key = (uint8_t*)calloc(keyLen, sizeof(uint8_t)); sessionKey_.keyLen = keyLen; + memcpy_s(sessionKey_.key, keyLen, sessionKey, keyLen); } return DM_OK; } +uint32_t CryptoMgr::GetSessionKey(uint8_t *sessionKey) +{ + std::lock_guard lock(sessionKeyMtx_); + if (sessionKey == nullptr) { // 用于获取密钥长度 外部进行内存申请 + return sessionKey_.keyLen; + } + memcpy_s(sessionKey, sessionKey_.keyLen, sessionKey_.key, sessionKey_.keyLen); + return sessionKey_.keyLen; +} + void CryptoMgr::ClearSessionKey() { std::lock_guard lock(sessionKeyMtx_); diff --git a/services/implementation/src/dependency/hichain/hichain_auth_connector.cpp b/services/implementation/src/dependency/hichain/hichain_auth_connector.cpp index e18cbf08b..7f46d513b 100644 --- a/services/implementation/src/dependency/hichain/hichain_auth_connector.cpp +++ b/services/implementation/src/dependency/hichain/hichain_auth_connector.cpp @@ -12,6 +12,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + +#include #include "hichain_auth_connector.h" #include "dm_log.h" @@ -19,12 +21,12 @@ #include "dm_constants.h" #include "hichain_connector_callback.h" #include "parameter.h" -#include "cJSON.h" namespace OHOS { namespace DistributedHardware { std::shared_ptr HiChainAuthConnector::dmDeviceAuthCallback_ = nullptr; +std::map> HiChainAuthConnector::dmDeviceAuthCallbackMap_; std::mutex HiChainAuthConnector::dmDeviceAuthCallbackMutex_; void HiChainAuthConnector::FreeJsonString(char *jsonStr) @@ -47,6 +49,11 @@ HiChainAuthConnector::HiChainAuthConnector() HiChainAuthConnector::~HiChainAuthConnector() { + for (auto& pair : dmDeviceAuthCallbackMap_) { + pair.second = nullptr; + } + dmDeviceAuthCallbackMap_.clear(); + dmDeviceAuthCallback_ = nullptr; LOGI("HiChainAuthConnector::destructor."); } @@ -57,6 +64,25 @@ int32_t HiChainAuthConnector::RegisterHiChainAuthCallback(std::shared_ptr callback) +{ + std::lock_guard lock(dmDeviceAuthCallbackMutex_); + dmDeviceAuthCallbackMap_[id] = callback; + return DM_OK; +} + +std::shared_ptr HiChainAuthConnector::GetDeviceAuthCallback(int64_t id) +{ + if (dmDeviceAuthCallbackMap_.find(id) != dmDeviceAuthCallbackMap_.end()) { + LOGD("HiChainAuthConnector::GetDeviceAuthCallback dmDeviceAuthCallbackMap_ id: %{public}lld.", id); + return dmDeviceAuthCallbackMap_[id]; + } + LOGD("HiChainAuthConnector::GetDeviceAuthCallback dmDeviceAuthCallbackMap_ not found, id: %{public}lld.", id); + return dmDeviceAuthCallback_; // 找不到新协议id注册的回调,则使用老协议注册的回调, 但老协议回调有可能为空 +} + int32_t HiChainAuthConnector::AuthDevice(int32_t pinCode, int32_t osAccountId, std::string udid, int64_t requestId) { LOGI("HiChainAuthConnector::AuthDevice start."); @@ -89,39 +115,204 @@ int32_t HiChainAuthConnector::ProcessAuthData(int64_t requestId, std::string aut return DM_OK; } +// 处理凭据认证报文 +// authReqId 认证Id +// data 对端报文内容 +int32_t HiChainAuthConnector::ProcessCredData(int64_t authReqId, const std::string &data) +{ + LOGI("HiChainAuthConnector::ProcessCredData start."); + const CredAuthManager *credAuthManager = GetCredAuthInstance(); + int32_t ret = credAuthManager->processCredData(authReqId, reinterpret_cast(data.c_str()), + data.length(), &deviceAuthCallback_); + if (ret != HC_SUCCESS) { + LOGE("Hichain processData failed ret %{public}d.", ret); + return ERR_DM_FAILED; + } + LOGI("HiChainAuthConnector::ProcessCredData leave."); + return DM_OK; +} + +// 生成凭据,返回凭据Id +// osAccountId 本段UserId +// authParams json格式字符串,key-value根据上下文确定 +// credId 返回的凭据Id +int32_t HiChainAuthConnector::AddCredential(int32_t osAccountId, const std::string &authParams, std::string &credId) +{ + LOGI("HiChainAuthConnector::AddCredential start."); + LOGI("HiChainAuthConnector::AddCredential osAccount=%{public}d, authParams=%{public}s\n", + osAccountId, authParams.c_str()); + char *returnData = NULL; + const CredManager *credManager = GetCredMgrInstance(); + int32_t ret = credManager->addCredential(osAccountId, authParams.c_str(), &returnData); + if (ret != HC_SUCCESS || returnData == NULL) { + LOGE("Hichain addCredential failed ret %{public}d.", ret); + free(returnData); + return ERR_DM_FAILED; + } + LOGI("HiChainAuthConnector::AddCredential addCredential success ret=%{public}d, returnData=%{public}s.", + ret, returnData); + credId = std::string(returnData); + LOGI("HiChainAuthConnector::AddCredential addCredId=%{public}s.", credId.c_str()); + free(returnData); + LOGI("HiChainAuthConnector::AddCredential leave."); + return DM_OK; +} + +// 根据凭据Id导出公钥 +// osAccountId 本段UserId +// credId 凭据Id +// publicKey 公钥 +int32_t HiChainAuthConnector::ExportCredential(int32_t osAccountId, const std::string &credId, std::string &publicKey) +{ + LOGI("HiChainAuthConnector::ExportCredential start. osAccountId=%{public}d, credId=%{public}s", + osAccountId, credId.c_str()); + char *returnData = NULL; + const CredManager *credManager = GetCredMgrInstance(); + int32_t ret = credManager->exportCredential(osAccountId, credId.c_str(), &returnData); + if (ret != HC_SUCCESS || returnData == NULL) { + LOGE("Hichain exportCredential failed ret %{public}d.", ret); + free(returnData); + return ERR_DM_FAILED; + } + + // 导出的公钥是json格式,需要解析 + JsonObject jsonAuthParam(returnData); + free(returnData); + if (jsonAuthParam.IsDiscarded() || !jsonAuthParam["keyValue"].IsString()) { + LOGE("Hichain exportCredential failed, returnData is invalid."); + return ERR_DM_FAILED; + } + + publicKey = jsonAuthParam["keyValue"].Get(); + LOGI("HiChainAuthConnector::ExportCredential leave. publicKey=%{public}s", publicKey.c_str()); + return DM_OK; +} + +// 凭据协商 +// osAccountId 本段UserId +// selfCredId 本段凭据Id +// authParams 协商参数 +// credId 返回的凭据Id +int32_t HiChainAuthConnector::AgreeCredential(int32_t osAccountId, const std::string selfCredId, + const std::string &authParams, std::string &credId) +{ + LOGI("HiChainAuthConnector::AgreeCredential start."); + LOGI("HiChainAuthConnector::AgreeCredential osAccountId=%{public}d, selfCredId=%{public}s, authParams=%{public}s\n", + osAccountId, selfCredId.c_str(), authParams.c_str()); + char *returnData = NULL; + const CredManager *credManager = GetCredMgrInstance(); + int32_t ret = credManager->agreeCredential(osAccountId, selfCredId.c_str(), authParams.c_str(), &returnData); + if (ret != HC_SUCCESS || returnData == NULL) { + LOGE("Hichain agreeCredential failed ret %{public}d.", ret); + return ERR_DM_FAILED; + } + credId = returnData; + free(returnData); + LOGI("HiChainAuthConnector::AgreeCredential leave agreeCredId=%{public}s.", credId.c_str()); + return DM_OK; +} + +// 删除凭据 +// osAccountId 本段用户Id +// credId 待删除的凭据Id +int32_t HiChainAuthConnector::DeleteCredential(int32_t osAccountId, const std::string &credId) +{ + LOGI("HiChainAuthConnector::DeleteCredential start. osAccountId=%{public}d, credId=%{public}s", osAccountId, + credId.c_str()); + const CredManager *credManager = GetCredMgrInstance(); + int32_t ret = credManager->deleteCredential(osAccountId, credId.c_str()); + if (ret != HC_SUCCESS) { + LOGE("Hichain deleteCredential failed ret %{public}d.", ret); + return ERR_DM_FAILED; + } + LOGI("HiChainAuthConnector::DeleteCredential leave."); + return DM_OK; +} + +// 凭据认证 +// osAccountId 系统用户参数 +// authReqId 认证请求id +// credId 对端凭据Id +// pinCode pin码认证(点对点临时凭据不能为空) +int32_t HiChainAuthConnector::AuthCredential(int32_t osAccountId, int64_t authReqId, const std::string &credId, + const std::string &pinCode) +{ + LOGI("HiChainAuthConnector::AuthCredential start. osAccountId=%{public}d, credId=%{public}s", osAccountId, + credId.c_str()); + if (credId.empty() && pinCode.empty()) { + LOGE("HiChainAuthConnector::AuthCredential failed, credId and pinCode is empty."); + return ERR_DM_FAILED; + } + + // 创建authParams的json格式字符串 + JsonObject jsonAuthParam; + if (!credId.empty()) { + jsonAuthParam["credId"] = credId; + } + if (!pinCode.empty()) { + jsonAuthParam["pinCode"] = pinCode; + } + std::string authParams = jsonAuthParam.Dump(); + + // 凭据认证 + const CredAuthManager *credAuthManager = GetCredAuthInstance(); + int32_t ret = credAuthManager->authCredential(osAccountId, authReqId, authParams.c_str(), &deviceAuthCallback_); + if (ret != HC_SUCCESS) { + LOGE("HiChainAuthConnector::AuthCredential failed ret %{public}d.", ret); + return ERR_DM_FAILED; + } + LOGI("HiChainAuthConnector::AuthCredential leave."); + return DM_OK; +} + +// pin码认证 +int32_t HiChainAuthConnector::AuthCredentialPinCode(int32_t osAccountId, int64_t authReqId, int32_t pinCode) +{ + LOGI("HiChainAuthConnector::AuthCredential start."); + if (pinCode == INVALID_PINCODE) { + LOGE("HiChainAuthConnector::AuthCredentialPinCode failed, pinCode is empty."); + return ERR_DM_FAILED; + } + + // 创建authParams的json格式字符串 + JsonObject jsonAuthParam; + + jsonAuthParam[FIELD_PIN_CODE] = std::to_string(pinCode); + jsonAuthParam[FIELD_SERVICE_PKG_NAME] = std::string(DM_PKG_NAME); + + std::string authParams = jsonAuthParam.Dump(); + + // 凭据认证 + const CredAuthManager *credAuthManager = GetCredAuthInstance(); + int32_t ret = credAuthManager->authCredential(osAccountId, authReqId, authParams.c_str(), &deviceAuthCallback_); + if (ret != HC_SUCCESS) { + LOGE("HiChainAuthConnector::AuthCredential failed ret %{public}d.", ret); + return ERR_DM_FAILED; + } + + return DM_OK; +} + bool HiChainAuthConnector::onTransmit(int64_t requestId, const uint8_t *data, uint32_t dataLen) { LOGI("AuthDevice onTransmit, requestId %{public}" PRId64, requestId); - if (dmDeviceAuthCallback_ == nullptr) { + auto dmDeviceAuthCallback = GetDeviceAuthCallback(requestId); + if (dmDeviceAuthCallback == nullptr) { LOGE("HiChainAuthConnector::onTransmit dmDeviceAuthCallback_ is nullptr."); return false; } - return dmDeviceAuthCallback_->AuthDeviceTransmit(requestId, data, dataLen); + return dmDeviceAuthCallback->AuthDeviceTransmit(requestId, data, dataLen); } char *HiChainAuthConnector::onRequest(int64_t requestId, int operationCode, const char *reqParams) { LOGI("HiChainAuthConnector::onRequest start."); - (void)requestId; - (void)reqParams; - if (dmDeviceAuthCallback_ == nullptr) { + auto dmDeviceAuthCallback = GetDeviceAuthCallback(requestId); + if (dmDeviceAuthCallback == nullptr) { LOGE("HiChainAuthConnector::onRequest dmDeviceAuthCallback_ is nullptr."); return nullptr; } - JsonObject jsonObj; - int32_t pinCode = INVALID_PINCODE; - if (dmDeviceAuthCallback_->GetPinCode(pinCode) == ERR_DM_FAILED || pinCode == INVALID_PINCODE) { - jsonObj[FIELD_CONFIRMATION] = RequestResponse::REQUEST_REJECTED; - } else { - jsonObj[FIELD_CONFIRMATION] = RequestResponse::REQUEST_ACCEPTED; - jsonObj[FIELD_PIN_CODE] = std::to_string(pinCode); - } - std::string deviceId = ""; - dmDeviceAuthCallback_->GetRemoteDeviceId(deviceId); - jsonObj[FIELD_PEER_CONN_DEVICE_ID] = deviceId; - std::string jsonStr = SafetyDump(jsonObj); - char *buffer = strdup(jsonStr.c_str()); - return buffer; + return dmDeviceAuthCallback->AuthDeviceRequest(requestId, operationCode, reqParams); } void HiChainAuthConnector::onFinish(int64_t requestId, int operationCode, const char *returnData) @@ -129,11 +320,12 @@ void HiChainAuthConnector::onFinish(int64_t requestId, int operationCode, const LOGI("HiChainAuthConnector::onFinish reqId:%{public}" PRId64 ", operation:%{public}d.", requestId, operationCode); (void)returnData; - if (dmDeviceAuthCallback_ == nullptr) { + auto dmDeviceAuthCallback = GetDeviceAuthCallback(requestId); + if (dmDeviceAuthCallback == nullptr) { LOGE("HiChainAuthConnector::onFinish dmDeviceAuthCallback_ is nullptr."); return; } - dmDeviceAuthCallback_->AuthDeviceFinish(requestId); + dmDeviceAuthCallback->AuthDeviceFinish(requestId); } void HiChainAuthConnector::onError(int64_t requestId, int operationCode, int errorCode, const char *errorReturn) @@ -142,7 +334,8 @@ void HiChainAuthConnector::onError(int64_t requestId, int operationCode, int err requestId, operationCode, errorCode); (void)operationCode; (void)errorReturn; - if (dmDeviceAuthCallback_ == nullptr) { + auto dmDeviceAuthCallback = GetDeviceAuthCallback(requestId); + if (dmDeviceAuthCallback == nullptr) { LOGE("HiChainAuthConnector::onError dmDeviceAuthCallback_ is nullptr."); return; } @@ -150,17 +343,18 @@ void HiChainAuthConnector::onError(int64_t requestId, int operationCode, int err if (errorCode == PROOF_MISMATCH) { dmErrorCode = ERR_DM_HICHAIN_PROOFMISMATCH; } - dmDeviceAuthCallback_->AuthDeviceError(requestId, dmErrorCode); + dmDeviceAuthCallback->AuthDeviceError(requestId, dmErrorCode); } void HiChainAuthConnector::onSessionKeyReturned(int64_t requestId, const uint8_t *sessionKey, uint32_t sessionKeyLen) { LOGI("HiChainAuthConnector::onSessionKeyReturned start."); - if (dmDeviceAuthCallback_ == nullptr) { + auto dmDeviceAuthCallback = GetDeviceAuthCallback(requestId); + if (dmDeviceAuthCallback == nullptr) { LOGE("HiChainAuthConnector::onSessionKeyReturned dmDeviceAuthCallback_ is nullptr."); return; } - dmDeviceAuthCallback_->AuthDeviceSessionKey(requestId, sessionKey, sessionKeyLen); + dmDeviceAuthCallback->AuthDeviceSessionKey(requestId, sessionKey, sessionKeyLen); } int32_t HiChainAuthConnector::GenerateCredential(std::string &localUdid, int32_t osAccountId, std::string &publicKey) @@ -198,6 +392,52 @@ int32_t HiChainAuthConnector::GenerateCredential(std::string &localUdid, int32_t return DM_OK; } +int32_t HiChainAuthConnector::QueryCredentialInfo(int32_t userId, const JsonObject &queryParams, + JsonObject &resultJson) +{ + int32_t ret; + + const CredManager *cm = GetCredMgrInstance(); + char *credIdList = nullptr; + // Q: 之前都是用的ProcessCredential查询,现在是否可用queryCredentialByParams查询? + ret = cm->queryCredentialByParams(userId, queryParams.Dump().c_str(), + &credIdList); + if (ret != DM_OK) { + LOGE("HiChainAuthConnector::QueryCredentialInfo fail to query credential id list with ret %{public}d.", ret); + return ERR_DM_FAILED; + } + JsonObject credIdListJson(credIdList); + FreeJsonString(credIdList); + if (credIdListJson.IsDiscarded()) { + LOGE("HiChainAuthConnector::QueryCredentialInfo credential id list to jsonStr error"); + return ERR_DM_FAILED; + } + + for (const auto& element : credIdListJson.Items()) { + if (!element.IsString()) { + continue; + } + std::string credId = element.Get(); + + char *returnCredInfo = nullptr; + ret = cm->queryCredInfoByCredId(userId, credId.c_str(), &returnCredInfo); + if (ret != DM_OK) { + LOGE("HiChainAuthConnector::QueryCredentialInfo fail to query credential info."); + return ERR_DM_FAILED; + } + JsonObject credInfoJson(returnCredInfo); + FreeJsonString(returnCredInfo); + if (credInfoJson.IsDiscarded()) { + LOGE("HiChainAuthConnector::QueryCredentialInfo credential info jsonStr error"); + return ERR_DM_FAILED; + } + + resultJson.Insert(credId, credInfoJson); + } + + return DM_OK; +} + bool HiChainAuthConnector::QueryCredential(std::string &localUdid, int32_t osAccountId) { LOGI("HiChainAuthConnector::QueryCredential start."); diff --git a/services/implementation/src/dependency/softbus/softbus_connector.cpp b/services/implementation/src/dependency/softbus/softbus_connector.cpp index 0af963094..46e6449d9 100644 --- a/services/implementation/src/dependency/softbus/softbus_connector.cpp +++ b/services/implementation/src/dependency/softbus/softbus_connector.cpp @@ -92,7 +92,7 @@ void SoftbusConnector::JoinLnn(const std::string &deviceId, bool isForceJoin) { std::string connectAddr; LOGI("start, deviceId: %{public}s.", GetAnonyString(deviceId).c_str()); - ConnectionAddr *addrInfo = GetConnectAddr(deviceId, connectAddr); + auto addrInfo = GetConnectAddr(deviceId, connectAddr); if (addrInfo == nullptr) { LOGE("addrInfo is nullptr."); return; @@ -102,13 +102,70 @@ void SoftbusConnector::JoinLnn(const std::string &deviceId, bool isForceJoin) LOGE("convert remoteUdid hash failed, remoteUdidHash_: %{public}s.", GetAnonyString(remoteUdidHash_).c_str()); return; } - int32_t ret = ::JoinLNN(DM_PKG_NAME, addrInfo, OnSoftbusJoinLNNResult, isForceJoin); + int32_t ret = ::JoinLNN(DM_PKG_NAME, addrInfo.get(), OnSoftbusJoinLNNResult, isForceJoin); if (ret != DM_OK) { LOGE("[SOFTBUS]JoinLNN failed, ret: %{public}d.", ret); } return; } +void SoftbusConnector::JoinLnn(const std::string &deviceId, const std::string &remoteUdidHash) +{ + std::string connectAddr; + LOGI("start, deviceId: %{public}s.", GetAnonyString(deviceId).c_str()); + auto addrInfo = GetConnectAddr(deviceId, connectAddr); + if (addrInfo == nullptr) { + LOGE("addrInfo is nullptr."); + return; + } + if (Crypto::ConvertHexStringToBytes(addrInfo->info.ble.udidHash, UDID_HASH_LEN, + remoteUdidHash.c_str(), remoteUdidHash.length()) != DM_OK) { + LOGE("convert remoteUdid hash failed, remoteUdidHash_: %{public}s.", GetAnonyString(remoteUdidHash).c_str()); + return; + } + int32_t ret = ::JoinLNN(DM_PKG_NAME, addrInfo.get(), OnSoftbusJoinLNNResult, false); + if (ret != DM_OK) { + LOGE("[SOFTBUS]JoinLNN failed, ret: %{public}d.", ret); + } + return; +} + +void SoftbusConnector::JoinLNNBySkId(int32_t sessionId, int32_t sessionKeyId, int32_t remoteSessionKeyId, + std::string udid, std::string udidHash) +{ + LOGI("start, JoinLNNBySkId sessionId: %{public}d, udid: %{public}s.", sessionId, GetAnonyString(udid).c_str()); + std::string connectAddr; + auto addrInfo = GetConnectAddr(udid, connectAddr); + if (addrInfo == nullptr) { + LOGE("addrInfo is nullptr."); + return; + } + if (addrInfo->type == CONNECTION_ADDR_BLE && Crypto::ConvertHexStringToBytes(addrInfo->info.ble.udidHash, UDID_HASH_LEN, + udidHash.c_str(), udidHash.length()) != DM_OK) { + LOGE("convert remoteUdid hash failed, udidHash: %{public}s.", GetAnonyString(udidHash).c_str()); + return; + } + LOGI("addrInfo->type: %{public}d", addrInfo->type); + addrInfo->info.session.sessionId = sessionId; + addrInfo->deviceKeyId.hasDeviceKeyId = true; // 总线修改后适配 + if (sessionKeyId > 0 && remoteSessionKeyId > 0) { + // addrInfo->info.session.localDeviceKeyId = sessionKeyId; + // addrInfo->info.session.remoteDeviceKeyId = remoteSessionKeyId; + addrInfo->deviceKeyId.localDeviceKeyId = sessionKeyId; // 总线修改后适配 + addrInfo->deviceKeyId.remoteDeviceKeyId = remoteSessionKeyId; // 总线修改后适配 + LOGI("sessionKeyId valid"); + } else { + // addrInfo->info.session.localDeviceKeyId = 0; + // addrInfo->info.session.remoteDeviceKeyId = 0; + addrInfo->deviceKeyId.localDeviceKeyId = 0; // 总线修改后适配 + addrInfo->deviceKeyId.remoteDeviceKeyId = 0; // 总线修改后适配 + } + int32_t ret = ::JoinLNN(DM_PKG_NAME, addrInfo.get(), OnSoftbusJoinLNNResult, false); + if (ret != DM_OK) { + LOGE("[SOFTBUS]JoinLNNBySkId failed, ret: %{public}d.", ret); + } +} + void SoftbusConnector::JoinLnnByHml(int32_t sessionId, int32_t sessionKeyId, int32_t remoteSessionKeyId) { LOGI("start, JoinLnnByHml sessionId: %{public}d.", sessionId); @@ -116,12 +173,12 @@ void SoftbusConnector::JoinLnnByHml(int32_t sessionId, int32_t sessionKeyId, int addrInfo.type = CONNECTION_ADDR_SESSION_WITH_KEY; addrInfo.info.session.sessionId = sessionId; if (sessionKeyId > 0 && remoteSessionKeyId > 0) { - addrInfo.info.session.localDeviceKeyId = sessionKeyId; - addrInfo.info.session.remoteDeviceKeyId = remoteSessionKeyId; + addrInfo.deviceKeyId.localDeviceKeyId = sessionKeyId; + addrInfo.deviceKeyId.remoteDeviceKeyId = remoteSessionKeyId; LOGI("sessionKeyId valid"); } else { - addrInfo.info.session.localDeviceKeyId = 0; - addrInfo.info.session.remoteDeviceKeyId = 0; + addrInfo.deviceKeyId.localDeviceKeyId = 0; + addrInfo.deviceKeyId.remoteDeviceKeyId = 0; } int32_t ret = ::JoinLNN(DM_PKG_NAME, &addrInfo, OnSoftbusJoinLNNResult, false); if (ret != DM_OK) { @@ -172,9 +229,11 @@ ConnectionAddr *SoftbusConnector::GetConnectAddrByType(DeviceInfo *deviceInfo, C return nullptr; } -ConnectionAddr *SoftbusConnector::GetConnectAddr(const std::string &deviceId, std::string &connectAddr) +shared_ptr SoftbusConnector::GetConnectAddr(const std::string &deviceId, std::string &connectAddr) { DeviceInfo *deviceInfo = nullptr; + std::shared_ptr deviceInfoPtr; + std::shared_ptr connectAddrPtr = std::make_shared(); { std::lock_guard lock(discoveryDeviceInfoMutex_); auto iter = discoveryDeviceInfoMap_.find(deviceId); @@ -182,6 +241,7 @@ ConnectionAddr *SoftbusConnector::GetConnectAddr(const std::string &deviceId, st LOGE("deviceInfo not found by deviceId: %{public}s.", GetAnonyString(deviceId).c_str()); return nullptr; } + deviceInfoPtr = iter->second; deviceInfo = iter->second.get(); } if (deviceInfo->addrNum <= 0 || deviceInfo->addrNum >= CONNECTION_ADDR_MAX) { @@ -191,33 +251,37 @@ ConnectionAddr *SoftbusConnector::GetConnectAddr(const std::string &deviceId, st JsonObject jsonPara; ConnectionAddr *addr = GetConnectAddrByType(deviceInfo, ConnectionAddrType::CONNECTION_ADDR_ETH); if (addr != nullptr) { + *connectAddrPtr = *addr; LOGI("[SOFTBUS]get ETH ConnectionAddr for deviceId: %{public}s.", GetAnonyString(deviceId).c_str()); jsonPara[ETH_IP] = addr->info.ip.ip; jsonPara[ETH_PORT] = addr->info.ip.port; connectAddr = SafetyDump(jsonPara); - return addr; + return connectAddrPtr; } addr = GetConnectAddrByType(deviceInfo, ConnectionAddrType::CONNECTION_ADDR_WLAN); if (addr != nullptr) { + *connectAddrPtr = *addr; jsonPara[WIFI_IP] = addr->info.ip.ip; jsonPara[WIFI_PORT] = addr->info.ip.port; LOGI("[SOFTBUS]get WLAN ConnectionAddr for deviceId: %{public}s.", GetAnonyString(deviceId).c_str()); connectAddr = SafetyDump(jsonPara); - return addr; + return connectAddrPtr; } addr = GetConnectAddrByType(deviceInfo, ConnectionAddrType::CONNECTION_ADDR_BR); if (addr != nullptr) { + *connectAddrPtr = *addr; jsonPara[BR_MAC] = addr->info.br.brMac; LOGI("[SOFTBUS]get BR ConnectionAddr for deviceId: %{public}s.", GetAnonyString(deviceId).c_str()); connectAddr = SafetyDump(jsonPara); - return addr; + return connectAddrPtr; } addr = GetConnectAddrByType(deviceInfo, ConnectionAddrType::CONNECTION_ADDR_BLE); if (addr != nullptr) { + *connectAddrPtr = *addr; jsonPara[BLE_MAC] = addr->info.ble.bleMac; connectAddr = SafetyDump(jsonPara); addr->info.ble.priority = BLE_PRIORITY_HIGH; - return addr; + return connectAddrPtr; } LOGE("[SOFTBUS]failed to get ConnectionAddr for deviceId: %{public}s.", GetAnonyString(deviceId).c_str()); return nullptr; @@ -455,7 +519,8 @@ void SoftbusConnector::DeleteOffLineTimer(std::string &udidHash) } } -bool SoftbusConnector::CheckIsOnline(const std::string &targetDeviceId) +// isHash:传入的deviceId是否为哈希值 +bool SoftbusConnector::CheckIsOnline(const std::string &targetDeviceIdHash, bool isHash) { LOGI("Check the device is online."); int32_t deviceCount = 0; @@ -472,7 +537,8 @@ bool SoftbusConnector::CheckIsOnline(const std::string &targetDeviceId) LOGE("[SOFTBUS]GetNodeKeyInfo failed."); } std::string udid = reinterpret_cast(mUdid); - if (udid == targetDeviceId) { + if ((isHash == false && udid == targetDeviceIdHash) || + (isHash == true && Crypto::Sha256(udid).find(targetDeviceIdHash) == 0)) { LOGI("The device is online."); FreeNodeInfo(nodeInfo); return true; @@ -483,6 +549,11 @@ bool SoftbusConnector::CheckIsOnline(const std::string &targetDeviceId) return false; } +bool SoftbusConnector::CheckIsOnline(const std::string &targetDeviceId) +{ + return CheckIsOnline(targetDeviceId, false); +} + DmDeviceInfo SoftbusConnector::GetDeviceInfoByDeviceId(const std::string &deviceId) { LOGI("SoftbusConnector::GetDeviceInfoBydeviceId"); diff --git a/services/implementation/src/dependency/softbus/softbus_session.cpp b/services/implementation/src/dependency/softbus/softbus_session.cpp index 125ffce5a..59be600ed 100644 --- a/services/implementation/src/dependency/softbus/softbus_session.cpp +++ b/services/implementation/src/dependency/softbus/softbus_session.cpp @@ -99,12 +99,12 @@ int32_t SoftbusSession::OpenAuthSession(const std::string &deviceId) DmTraceStart(std::string(DM_HITRACE_AUTH_TO_OPPEN_SESSION)); int32_t sessionId = -1; std::string connectAddr; - ConnectionAddr *addrInfo = SoftbusConnector::GetConnectAddr(deviceId, connectAddr); + auto addrInfo = SoftbusConnector::GetConnectAddr(deviceId, connectAddr); if (addrInfo == nullptr) { LOGE("[SOFTBUS]addrInfo is nullptr. sessionId: %{public}d.", sessionId); return sessionId; } - sessionId = ::OpenAuthSession(DM_SESSION_NAME, addrInfo, 1, nullptr); + sessionId = ::OpenAuthSession(DM_SESSION_NAME, addrInfo.get(), 1, nullptr); if (sessionId < 0) { LOGE("[SOFTBUS]open session error, sessionId: %{public}d.", sessionId); return sessionId; @@ -161,20 +161,6 @@ int32_t SoftbusSession::GetPeerDeviceId(int32_t sessionId, std::string &peerDevI int32_t SoftbusSession::SendData(int32_t sessionId, std::string &message) { - JsonObject jsonObject(message); - if (jsonObject.IsDiscarded()) { - LOGE("extrasJson error, message: %{public}s.", GetAnonyString(message).c_str()); - return ERR_DM_FAILED; - } - if (!IsInt32(jsonObject, TAG_MSG_TYPE)) { - LOGE("SoftbusSession::SendData err json string."); - return ERR_DM_FAILED; - } - int32_t msgType = jsonObject[TAG_MSG_TYPE].Get(); - LOGI("start, msgType: %{public}d.", msgType); - if (sessionCallback_->GetIsCryptoSupport()) { - LOGI("SendData Start encryption."); - } int32_t ret = SendBytes(sessionId, message.c_str(), strlen(message.c_str())); if (ret != DM_OK) { LOGE("[SOFTBUS]SendBytes failed."); @@ -195,9 +181,13 @@ int32_t SoftbusSession::SendHeartbeatData(int32_t sessionId, std::string &messag int SoftbusSession::OnSessionOpened(int sessionId, int result) { + LOGD("OnSessionOpened, success, sessionId: %{public}d.", sessionId); + if (sessionCallback_ == nullptr) { + LOGD("Session callback is not registered."); + return DM_OK; + } int32_t sessionSide = GetSessionSide(sessionId); sessionCallback_->OnSessionOpened(sessionId, sessionSide, result); - LOGD("OnSessionOpened, success, sessionId: %{public}d.", sessionId); return DM_OK; } @@ -206,36 +196,13 @@ void SoftbusSession::OnSessionClosed(int sessionId) LOGI("OnSessionClosed, sessionId: %{public}d.", sessionId); CHECK_NULL_VOID(sessionCallback_); sessionCallback_->OnSessionClosed(sessionId); + return; } void SoftbusSession::OnBytesReceived(int sessionId, const void *data, unsigned int dataLen) { - if (sessionId < 0 || data == nullptr || dataLen <= 0 || dataLen > MAX_DATA_LEN) { - LOGI("[SOFTBUS]fail to receive data from softbus with sessionId: %{public}d, dataLen: %{public}d.", sessionId, - dataLen); - return; - } LOGI("start, sessionId: %{public}d, dataLen: %{public}d.", sessionId, dataLen); - if (sessionCallback_->GetIsCryptoSupport()) { - LOGI("Start decryption."); - } - std::string message = std::string(reinterpret_cast(data), dataLen); - JsonObject jsonObject(message); - if (jsonObject.IsDiscarded()) { - LOGE("DecodeRequestAuth jsonStr error"); - return; - } - if (!IsInt32(jsonObject, TAG_MSG_TYPE)) { - LOGE("err json string, first time"); - return; - } - if (jsonObject[TAG_MSG_TYPE].Get() == AUTH_DEVICE_REQ_NEGOTIATE || - jsonObject[TAG_MSG_TYPE].Get() == AUTH_DEVICE_RESP_NEGOTIATE) { - sessionCallback_->OnAuthDeviceDataReceived(sessionId, message); - } else { - sessionCallback_->OnDataReceived(sessionId, message); - } - LOGI("completed."); + return; } } // namespace DistributedHardware } // namespace OHOS diff --git a/services/implementation/src/device_manager_service_impl.cpp b/services/implementation/src/device_manager_service_impl.cpp index 54e5840c1..c399d5cb2 100644 --- a/services/implementation/src/device_manager_service_impl.cpp +++ b/services/implementation/src/device_manager_service_impl.cpp @@ -15,9 +15,13 @@ #include "device_manager_service_impl.h" +#include +#include +#include #include #include "app_manager.h" +#include "dm_error_type.h" #include "dm_anonymous.h" #include "dm_constants.h" #include "dm_crypto.h" @@ -26,28 +30,353 @@ #include "dm_radar_helper.h" #include "dm_softbus_cache.h" #include "multiple_user_connector.h" +#include "ipc_skeleton.h" #if !(defined(__LITEOS_M__) || defined(LITE_DEVICE)) #include "dm_common_event_manager.h" #include "parameter.h" +#include "dm_random.h" #include "common_event_support.h" using namespace OHOS::EventFwk; #endif namespace OHOS { namespace DistributedHardware { + +namespace { + // One year 365 * 24 * 60 * 60 constexpr int32_t MAX_ALWAYS_ALLOW_SECONDS = 31536000; +constexpr int32_t MIN_PIN_CODE = 100000; +constexpr int32_t MAX_PIN_CODE = 999999; +// 新协议字段定义,为避免对新协议头文件依赖,不直接依赖新协议头文件 +constexpr int32_t MSG_TYPE_REQ_ACL_NEGOTIATE = 80; +constexpr int32_t MSG_TYPE_RESP_ACL_NEGOTIATE = 90; +constexpr int32_t MSG_TYPE_REQ_AUTH_TERMINATE = 104; +constexpr int32_t AUTH_SRC_FINISH_STATE = 12; +constexpr int32_t MAX_DATA_LEN = 65535; +constexpr const char* DM_TAG_LOGICAL_SESSION_ID = "logicalSessionId"; +constexpr const char* DM_TAG_PEER_DISPLAY_ID = "peerDisplayId"; +constexpr const char* DM_TAG_ACCESSEE_USER_ID = "accesseeUserId"; +constexpr const char* DM_TAG_EXTRA_INFO = "extraInfo"; +constexpr const char* DM_TAG_ENABLE_NEW_PROTOCOL_FLAG = "enable_new_protocol_flag"; + +static int32_t GetEnableNewProtocolFlag() +{ + return GetIntParameter(DM_TAG_ENABLE_NEW_PROTOCOL_FLAG, 0); +} + +static bool IsMessageOldVersion(const JsonObject &jsonObject, std::shared_ptr session) +{ + std::string dmVersion = ""; + std::string edition = ""; + if (jsonObject[TAG_DMVERSION].IsString()) { + dmVersion = jsonObject[TAG_DMVERSION].Get(); + } + if (jsonObject[TAG_EDITION].IsString()) { + edition = jsonObject[TAG_EDITION].Get(); + } + dmVersion = AuthManagerBase::ConvertSrcVersion(dmVersion, edition); + + // 物理会话版本赋值,并解除信号量 + session->version_ = dmVersion; + + // 若版本号高于5.0.4旧协议最高版本,则不需要切换老协议 + if (CompareVersion(dmVersion, DM_VERSION_5_0_OLD_MAX) == true) { + return false; + } + + return true; +} + +std::string CreateTerminateMessage(void) +{ + JsonObject jsonObject; + jsonObject[TAG_MSG_TYPE] = MSG_TYPE_REQ_AUTH_TERMINATE; + jsonObject[TAG_REPLY] = ERR_DM_VERSION_INCOMPATIBLE; + jsonObject[TAG_AUTH_FINISH] = false; + + return jsonObject.Dump(); +} + +} + +std::condition_variable DeviceManagerServiceImpl::cleanEventCv_; +std::mutex DeviceManagerServiceImpl::cleanEventMutex_; +std::queue DeviceManagerServiceImpl::cleanEventQueue_; + +Session::Session(int sessionId, std::string deviceId) +{ + sessionId_ = sessionId; + deviceId_ = deviceId; +} DeviceManagerServiceImpl::DeviceManagerServiceImpl() { + running_ = true; + thread_ = std::thread(&DeviceManagerServiceImpl::CleanWorker, this); LOGI("DeviceManagerServiceImpl constructor"); } DeviceManagerServiceImpl::~DeviceManagerServiceImpl() { + Stop(); + thread_.join(); LOGI("DeviceManagerServiceImpl destructor"); } +static uint64_t StringToUint64(const std::string& str) +{ + // 计算子字符串的长度,取字符串长度和8的最小值 + size_t subStrLength = std::min(str.length(), 8U); + + // 提取子字符串 + std::string substr = str.substr(str.length() - subStrLength); + + // 将子字符串转换为uint64_t + uint64_t result = 0; + for (size_t i = 0; i < subStrLength; ++i) { + result <<= 8; // 向左位移8位 + result |= static_cast(substr[i]); + } + + return result; +} + + +static uint64_t GetTokenId(bool isSrcSide, int32_t displayId, int32_t userId, std::string &bundleName) +{ + uint64_t tokenId = 0; + if (isSrcSide) { + // src端 + tokenId = IPCSkeleton::GetCallingTokenID(); + } else { + // sink端 + int64_t tmpTokenId; + // 获取userId + int32_t targetUserId = AuthManagerBase::DmGetUserId(displayId, userId); + if (targetUserId == -1) { + return tokenId; + } + if (AppManager::GetInstance().GetHapTokenIdByName(targetUserId, bundleName, 0, tmpTokenId) == DM_OK) { + tokenId = static_cast(tmpTokenId); + } else if (AppManager::GetInstance().GetNativeTokenIdByName(bundleName, tmpTokenId) == DM_OK) { + tokenId = static_cast(tmpTokenId); + } else { + // 获取deviceId, 取其8位字符值作为tokenId + char localDeviceId[DEVICE_UUID_LENGTH] = {0}; + GetDevUdid(localDeviceId, DEVICE_UUID_LENGTH); + std::string deviceId = std::string(localDeviceId); + if (deviceId.length() != 0) { + tokenId = StringToUint64(deviceId); + } + } + } + return tokenId; +} + +int64_t DeviceManagerServiceImpl::FetchCleanEvent() +{ + std::unique_lock lock(cleanEventMutex_); + cleanEventCv_.wait(lock, [&] { + return !running_.load() || !cleanEventQueue_.empty(); + }); + + if (!running_.load()) return 0; + + int64_t logicalSessionId = cleanEventQueue_.front(); + cleanEventQueue_.pop(); + return logicalSessionId; +} + +void DeviceManagerServiceImpl::CleanWorker() +{ + while (running_.load()) { + auto logicalSessionId = FetchCleanEvent(); + LOGD("DeviceManagerServiceImpl::CleanWorker clean auth_mgr, its logicalSessionId: %{public}lld", logicalSessionId); + CleanAuthMgrByLogicalSessionId(logicalSessionId); + } + LOGD("DeviceManagerServiceImpl::CleanWorker end"); +} + +void DeviceManagerServiceImpl::Stop() +{ + running_.store(false); + cleanEventCv_.notify_all(); + std::lock_guard lock(cleanEventMutex_); + while (!cleanEventQueue_.empty()) { + int64_t logicalSessionId = cleanEventQueue_.front(); + cleanEventQueue_.pop(); + CleanAuthMgrByLogicalSessionId(logicalSessionId); + } +} + +void DeviceManagerServiceImpl::NotifyCleanEvent(int64_t logicalSessionId) +{ + LOGD("DeviceManagerServiceImpl::NotifyCleanEvent logicalSessionId: %{public}lld", logicalSessionId); + std::lock_guard lock(cleanEventMutex_); + // 存入到队列中 + cleanEventQueue_.push(logicalSessionId); + cleanEventCv_.notify_one(); +} + +int32_t DeviceManagerServiceImpl::InitAndRegisterAuthMgr(bool isSrcSide, uint64_t tokenId, + std::shared_ptr session, int64_t logicalSessionId) +{ + if (session == nullptr) { + LOGE("InitAndRegisterAuthMgr, The physical link is not created."); + return ERR_DM_AUTH_OPEN_SESSION_FAILED; + } + // 判断version为空,首次创建允许通过,创建新协议auth_mgr,去协商version;后续创建等待,释放后直接使用version创建对应auth_mgr + if (session->version_ == "") { + bool expected = false; + if (session->flag_.compare_exchange_strong(expected, true)) { + LOGI("The physical link is being created and the dual-end device version is aligned."); + } else { + // 不允许同时协商版本,直接报错 + LOGE("Version negotiation is not allowed at the same time."); + return ERR_DM_AUTH_BUSINESS_BUSY; + } + } + if (session->version_ == "" || CompareVersion(session->version_, DM_VERSION_5_0_OLD_MAX)) { + // 首次创建或新协议 + if (authMgrMap_.find(tokenId) == authMgrMap_.end()) { + // 创建新auth_mgr,创建authMgrMap_[tokenId] + if (isSrcSide) { + // src端 + authMgrMap_[tokenId] = std::make_shared(softbusConnector_, + listener_, hiChainAuthConnector_); + } else { + // sink端 + authMgrMap_[tokenId] = std::make_shared(softbusConnector_, + listener_, hiChainAuthConnector_); + } + // 资源销毁通知函数注册 + authMgrMap_[tokenId]->RegisterCleanNotifyCallback(&DeviceManagerServiceImpl::NotifyCleanEvent); + hiChainAuthConnector_->RegisterHiChainAuthCallbackById(logicalSessionId, authMgrMap_[tokenId]); + LOGI("DeviceManagerServiceImpl::Initialize authMgrMap_ token: %{public}llu.", tokenId); + // 导入配置 + if (configsMap_.find(tokenId) != configsMap_.end()) { + authMgrMap_[tokenId]->ImportAuthCode(configsMap_[tokenId]->pkgName, configsMap_[tokenId]->authCode); + authMgrMap_[tokenId]->RegisterAuthenticationType(configsMap_[tokenId]->authenticationType); + configsMap_[tokenId] = nullptr; + configsMap_.erase(tokenId); + LOGI("DeviceManagerServiceImpl::InitAndRegisterAuthMgr import authCode"); + } + return DM_OK; + } + } else { + LOGI("DeviceManagerServiceImpl::InitAndRegisterAuthMgr old authMgr."); + if (authMgr_ == nullptr) { + // 创建老auth_mar,只创建独立的一个 + authMgr_ = std::make_shared(softbusConnector_, hiChainConnector_, listener_, + hiChainAuthConnector_); + softbusConnector_->GetSoftbusSession()->RegisterSessionCallback(authMgr_); + hiChainConnector_->RegisterHiChainCallback(authMgr_); + hiChainAuthConnector_->RegisterHiChainAuthCallback(authMgr_); + return DM_OK; + } + if (GetEnableNewProtocolFlag() == 0) { + return DM_OK; + } + } + // 已创建authMgr_,说明已有绑定事件,其他请求拒绝,返回错误码 + LOGE("BindTarget failed, this device is being bound. Please try again later."); + return ERR_DM_AUTH_BUSINESS_BUSY; +} + +void DeviceManagerServiceImpl::CleanSessionMap(int sessionId, std::shared_ptr session) +{ + session->logicalSessionCnt_.fetch_sub(1); + if (session->logicalSessionCnt_.load(std::memory_order_relaxed) == 0) { + softbusConnector_->GetSoftbusSession()->OnSessionClosed(sessionId); + std::lock_guard lock(mapMutex_); + if (sessionsMap_.find(sessionId) != sessionsMap_.end()) { + sessionsMap_[sessionId] = nullptr; + sessionsMap_.erase(sessionId); + } + if (deviceId2SessionIdMap_.find(session->deviceId_) != deviceId2SessionIdMap_.end()) { + deviceId2SessionIdMap_.erase(session->deviceId_); + } + } + return; +} + +void DeviceManagerServiceImpl::CleanSessionMapByLogicalSessionId(int64_t logicalSessionId) +{ + if (logicalSessionId2SessionIdMap_.find(logicalSessionId) != logicalSessionId2SessionIdMap_.end()) { + auto sessionId = logicalSessionId2SessionIdMap_[logicalSessionId]; + auto session = GetCurSession(sessionId); + if (session != nullptr) { + CleanSessionMap(sessionId, session); + } + logicalSessionId2SessionIdMap_.erase(logicalSessionId); + } + logicalSessionId2TokenIdMap_.erase(logicalSessionId); + return; +} + +void DeviceManagerServiceImpl::CleanAuthMgrByLogicalSessionId(int64_t logicalSessionId) +{ + uint64_t tokenId = 0; + if (logicalSessionId2TokenIdMap_.find(logicalSessionId) != logicalSessionId2TokenIdMap_.end()) { + tokenId = logicalSessionId2TokenIdMap_[logicalSessionId]; + } + + if (authMgrMap_.find(tokenId) != authMgrMap_.end()) { + authMgrMap_[tokenId] = nullptr; + authMgrMap_.erase(tokenId); + } + + if (configsMap_.find(tokenId) != configsMap_.end()) { + configsMap_[tokenId] = nullptr; + configsMap_.erase(tokenId); + } + CleanSessionMapByLogicalSessionId(logicalSessionId); + + return; +} + +std::shared_ptr DeviceManagerServiceImpl::GetAuthMgr() +{ + uint64_t tokenId = IPCSkeleton::GetCallingTokenID(); + if (authMgrMap_.find(tokenId) != authMgrMap_.end()) { + LOGI("DeviceManagerServiceImpl::GetAuthMgr authMgrMap_ token: %{public}llu.", tokenId); + return authMgrMap_[tokenId]; + } + LOGE("DeviceManagerServiceImpl::GetAuthMgr authMgrMap_ not found, token: %{public}llu.", tokenId); + return authMgr_; // 查找不到新协议的authMgr时,返回旧协议authMgr,但可能为空 +} + +// 在回调函数中需要用到 +std::shared_ptr DeviceManagerServiceImpl::GetAuthMgrByTokenId(uint64_t tokenId) +{ + if (authMgrMap_.find(tokenId) != authMgrMap_.end()) { + LOGI("DeviceManagerServiceImpl::GetAuthMgrByTokenId authMgrMap_ token: %{public}llu.", tokenId); + return authMgrMap_[tokenId]; + } + LOGE("DeviceManagerServiceImpl::GetAuthMgrByTokenId authMgrMap_ not found, token: %{public}llu.", tokenId); + return authMgr_; // 查找不到新协议的authMgr时,返回旧协议authMgr,但可能为空 +} + +static int64_t GenerateRandNum(int sessionId) +{ + // 获取当前时间戳 + auto timestamp = std::chrono::duration_cast(std::chrono::high_resolution_clock::now().time_since_epoch()).count(); + + // 生成随机数 + std::random_device rd; + std::mt19937 gen(rd()); + std::uniform_int_distribution<> rand_dis(0, 0xFFFFFFFF); + uint32_t randomNumber = rand_dis(gen); + + // 组合随机数 + int64_t randNum = (static_cast(timestamp) << 32) | + (static_cast(sessionId) << 16) | + static_cast(randomNumber); + + return randNum; +} + int32_t DeviceManagerServiceImpl::Initialize(const std::shared_ptr &listener) { LOGI("DeviceManagerServiceImpl Initialize"); @@ -68,14 +397,6 @@ int32_t DeviceManagerServiceImpl::Initialize(const std::shared_ptrRegisterSoftbusStateCallback(); } - if (authMgr_ == nullptr) { - authMgr_ = std::make_shared(softbusConnector_, hiChainConnector_, listener, - hiChainAuthConnector_); - softbusConnector_->RegisterConnectorCallback(authMgr_); - softbusConnector_->GetSoftbusSession()->RegisterSessionCallback(authMgr_); - hiChainConnector_->RegisterHiChainCallback(authMgr_); - hiChainAuthConnector_->RegisterHiChainAuthCallback(authMgr_); - } if (credentialMgr_ == nullptr) { credentialMgr_ = std::make_shared(hiChainConnector_, listener); } @@ -98,6 +419,24 @@ void DeviceManagerServiceImpl::Release() softbusConnector_->GetSoftbusSession()->UnRegisterSessionCallback(); hiChainConnector_->UnRegisterHiChainCallback(); authMgr_ = nullptr; + for (auto& pair : authMgrMap_) { + pair.second = nullptr; + } + authMgrMap_.clear(); + for (auto& pair : sessionsMap_) { + pair.second = nullptr; + } + sessionsMap_.clear(); + for (auto& pair : configsMap_) { + pair.second = nullptr; + } + deviceId2SessionIdMap_.clear(); + deviceIdMutexMap_.clear(); + sessionEnableMutexMap_.clear(); + sessionEnableCvMap_.clear(); + logicalSessionId2TokenIdMap_.clear(); + logicalSessionId2SessionIdMap_.clear(); + configsMap_.clear(); deviceStateMgr_ = nullptr; softbusConnector_ = nullptr; abilityMgr_ = nullptr; @@ -114,7 +453,12 @@ int32_t DeviceManagerServiceImpl::UnAuthenticateDevice(const std::string &pkgNam pkgName.c_str(), GetAnonyString(udid).c_str()); return ERR_DM_INPUT_PARA_INVALID; } - return authMgr_->UnAuthenticateDevice(pkgName, udid, bindLevel); + auto authMgr = GetAuthMgr(); + if (authMgr == nullptr) { + LOGE("authMgr_ is nullptr"); + return ERR_DM_POINT_NULL; + } + return authMgr->UnAuthenticateDevice(pkgName, udid, bindLevel); } int32_t DeviceManagerServiceImpl::StopAuthenticateDevice(const std::string &pkgName) @@ -123,7 +467,12 @@ int32_t DeviceManagerServiceImpl::StopAuthenticateDevice(const std::string &pkgN LOGE("DeviceManagerServiceImpl::StopAuthenticateDevice failed"); return ERR_DM_INPUT_PARA_INVALID; } - return authMgr_->StopAuthenticateDevice(pkgName); + auto authMgr = GetAuthMgr(); + if (authMgr == nullptr) { + LOGE("authMgr_ is nullptr"); + return ERR_DM_POINT_NULL; + } + return authMgr->StopAuthenticateDevice(pkgName); } int32_t DeviceManagerServiceImpl::UnBindDevice(const std::string &pkgName, const std::string &udid, @@ -135,7 +484,9 @@ int32_t DeviceManagerServiceImpl::UnBindDevice(const std::string &pkgName, const return ERR_DM_INPUT_PARA_INVALID; } std::string extra = ""; - return authMgr_->UnBindDevice(pkgName, udid, bindLevel, extra); + char localDeviceId[DEVICE_UUID_LENGTH] = {0}; + GetDevUdid(localDeviceId, DEVICE_UUID_LENGTH); + return DeleteAcl(pkgName, std::string(localDeviceId), udid, bindLevel, extra); } int32_t DeviceManagerServiceImpl::UnBindDevice(const std::string &pkgName, const std::string &udid, @@ -146,7 +497,9 @@ int32_t DeviceManagerServiceImpl::UnBindDevice(const std::string &pkgName, const pkgName.c_str(), GetAnonyString(udid).c_str()); return ERR_DM_INPUT_PARA_INVALID; } - return authMgr_->UnBindDevice(pkgName, udid, bindLevel, extra); + char localDeviceId[DEVICE_UUID_LENGTH] = {0}; + GetDevUdid(localDeviceId, DEVICE_UUID_LENGTH); + return DeleteAcl(pkgName, std::string(localDeviceId), udid, bindLevel, extra); } int32_t DeviceManagerServiceImpl::SetUserOperation(std::string &pkgName, int32_t action, @@ -157,8 +510,18 @@ int32_t DeviceManagerServiceImpl::SetUserOperation(std::string &pkgName, int32_t "%{public}s", pkgName.c_str(), params.c_str()); return ERR_DM_INPUT_PARA_INVALID; } - if (authMgr_ != nullptr) { - authMgr_->OnUserOperation(action, params); + uint64_t tokenId = 0; + JsonObject jsonObject(params); + if (jsonObject.IsDiscarded()) { + LOGE("OnUserOperation jsonStr error"); + return ERR_DM_INPUT_PARA_INVALID; + } + if (jsonObject[TOKENID].IsNumberInteger()) { + tokenId = jsonObject[TOKENID].Get(); + } + auto authMgr = GetAuthMgrByTokenId(tokenId); + if (authMgr != nullptr) { + authMgr->OnUserOperation(action, params); } return DM_OK; } @@ -301,6 +664,10 @@ std::string DeviceManagerServiceImpl::GetUdidHashByNetworkId(const std::string & int DeviceManagerServiceImpl::OnSessionOpened(int sessionId, int result) { + { + std::lock_guard lock(sessionEnableMutexMap_[sessionId]); + sessionEnableCvMap_[sessionId].notify_all(); + } std::string peerUdid = ""; softbusConnector_->GetSoftbusSession()->GetPeerDeviceId(sessionId, peerUdid); struct RadarInfo info = { @@ -313,17 +680,220 @@ int DeviceManagerServiceImpl::OnSessionOpened(int sessionId, int result) if (!DmRadarHelper::GetInstance().ReportAuthSessionOpenCb(info)) { LOGE("ReportAuthSessionOpenCb failed"); } + + // 获取对端deviceId,sink端给sessionsMap[deviceId] = session; + { + std::lock_guard lock(mapMutex_); + if (sessionsMap_.find(sessionId) == sessionsMap_.end()) { + sessionsMap_[sessionId] = std::make_shared(sessionId, peerUdid); + } + } + return SoftbusSession::OnSessionOpened(sessionId, result); } void DeviceManagerServiceImpl::OnSessionClosed(int sessionId) { + auto session = GetCurSession(sessionId); + if (session != nullptr) { + std::lock_guard lock(mapMutex_); + for (const auto& logicalSessionId : session->logicalSessionSet_) { + logicalSessionId2TokenIdMap_.erase(logicalSessionId); + logicalSessionId2SessionIdMap_.erase(logicalSessionId); + } + if (deviceId2SessionIdMap_.find(session->deviceId_) != deviceId2SessionIdMap_.end()) { + deviceId2SessionIdMap_.erase(session->deviceId_); + } + if (sessionsMap_.find(sessionId) != sessionsMap_.end()) { + sessionsMap_[sessionId] = nullptr; + sessionsMap_.erase(sessionId); + } + } SoftbusSession::OnSessionClosed(sessionId); } +// data 转 json +static JsonObject GetJsonObjectFromData(const void *data, unsigned int dataLen) +{ + std::string message = std::string(reinterpret_cast(data), dataLen); + return JsonObject(message); +} + +// 版本降级时,基于报文判断是src还是sink +// src: 收到90报文 +// sink:收到80报文 +static bool IsAuthManagerSourceByMessage(int32_t msgType) +{ + return msgType == MSG_TYPE_RESP_ACL_NEGOTIATE; +} + + +// 获取当前session对象 +std::shared_ptr DeviceManagerServiceImpl::GetCurSession(int sessionId) +{ + std::shared_ptr curSession = nullptr; + // 获取对端deviceId,sink端给sessionsMap[deviceId] = session; + { + std::lock_guard lock(mapMutex_); + if (sessionsMap_.find(sessionId) != sessionsMap_.end()) { + curSession = sessionsMap_[sessionId]; + } else { + LOGE("OnBytesReceived, The local session cannot be found."); + } + } + return curSession; +} + + void DeviceManagerServiceImpl::OnBytesReceived(int sessionId, const void *data, unsigned int dataLen) { + /* + 1、收到80报文创建auth_mgr + 2、收到80或90报文时,获取版本, 对比进行auth_mgr重建,执行老协议 + 3、分发报文 + */ + int32_t ret = DM_OK; + if (sessionId < 0 || data == nullptr || dataLen <= 0 || dataLen > MAX_DATA_LEN) { + LOGE("[OnBytesReceived] Fail to receive data from softbus with sessionId: %{public}d, dataLen: %{public}d.", + sessionId, dataLen); + return; + } + + LOGI("start, sessionId: %{public}d, dataLen: %{public}d.", sessionId, dataLen); + + JsonObject jsonObject = GetJsonObjectFromData(data, dataLen); + if (jsonObject.IsDiscarded() || !jsonObject[TAG_MSG_TYPE].IsNumberInteger()) { + LOGE("OnBytesReceived, MSG_TYPE parse failed."); + return; + } + int32_t msgType = jsonObject[TAG_MSG_TYPE].Get(); + int64_t logicalSessionId = 0; + if (jsonObject[DM_TAG_LOGICAL_SESSION_ID].IsNumberInteger()) { + logicalSessionId = jsonObject[DM_TAG_LOGICAL_SESSION_ID].Get(); + } + + std::shared_ptr curSession = nullptr; + if (GetEnableNewProtocolFlag() == 1) { + curSession = GetCurSession(sessionId); + if (curSession == nullptr) { + LOGE("InitAndRegisterAuthMgr, The physical link is not created."); + return; + } + } else { + curSession = std::make_shared(0, std::string("")); + curSession->version = DM_VERSION_5_0_5; + } + + uint64_t tokenId = 0; + if (msgType == MSG_TYPE_REQ_ACL_NEGOTIATE) { + if (logicalSessionId != 0) { + curSession->logicalSessionSet_.insert(logicalSessionId); + std::string bundleName; + int32_t displayId = 0; + int32_t userId = 0; + if (jsonObject[TAG_PEER_BUNDLE_NAME].IsString()) { + bundleName = jsonObject[TAG_PEER_BUNDLE_NAME].Get(); + } + if (jsonObject[DM_TAG_PEER_DISPLAY_ID].IsNumberInteger()) { + displayId = jsonObject[DM_TAG_PEER_DISPLAY_ID].Get(); + } + if (jsonObject.Contains(DM_TAG_EXTRA_INFO) && jsonObject[DM_TAG_EXTRA_INFO].IsObject()) { + if (jsonObject[DM_TAG_EXTRA_INFO][DM_TAG_ACCESSEE_USER_ID].IsNumberInteger()) { + userId = jsonObject[DM_TAG_EXTRA_INFO][DM_TAG_ACCESSEE_USER_ID].Get(); + } + } + tokenId = GetTokenId(false, displayId, userId, bundleName); + if (tokenId == 0) { + LOGE("OnBytesReceived, Get tokenId failed."); + return; + } + if (logicalSessionId2TokenIdMap_.find(logicalSessionId) != logicalSessionId2TokenIdMap_.end()) { + LOGE("OnBytesReceived, logicalSessionId exists in logicalSessionId2TokenIdMap_."); + return; + } + logicalSessionId2TokenIdMap_[logicalSessionId] = tokenId; + } + if (InitAndRegisterAuthMgr(false, tokenId, curSession, logicalSessionId) != DM_OK) { + // 内部已完成错误日志打印 + return; + } + + } else { + if (logicalSessionId != 0) { + if (curSession->logicalSessionSet_.find(logicalSessionId) == curSession->logicalSessionSet_.end()) { + LOGE("OnBytesReceived, The logical session ID does not exist in the physical session."); + return; + } + tokenId = logicalSessionId2TokenIdMap_[logicalSessionId]; + } + } + + auto authMgr = GetAuthMgrByTokenId(tokenId); + if (authMgr == nullptr) { + // 内部已完成错误日志打印 + return; + } + + /** + 监听80/90报文 + 新-老:src端收到90报文时发现版本不匹配问题,重新BindTarget + 老-新:sink端收到80报文时发现版本不匹配问题,重新OnSessionOpened和OnBytesReceived + + */ + if (curSession->version_ == "" && authMgr->isAuthNewVersion_ && + (msgType == MSG_TYPE_REQ_ACL_NEGOTIATE || msgType == MSG_TYPE_RESP_ACL_NEGOTIATE)) { + // IsMessageOldVersion内部会对session版本进行赋值,并解除对应物理会话信号量 + if (IsMessageOldVersion(jsonObject, curSession)) { + std::string pkgName; + PeerTargetId peerTargetId; + std::map bindParam; + authMgr->GetBindTargetParams(pkgName, peerTargetId, bindParam); + authMgr = nullptr; + authMgrMap_.erase(tokenId); + if (InitAndRegisterAuthMgr(false, tokenId, curSession, logicalSessionId) != DM_OK) { + // 内部已完成错误日志打印 + return; + } + + authMgr = GetAuthMgrByTokenId(tokenId); // 获取到老协议的authmgr + if (authMgr == nullptr) { + // 内部已完成错误日志打印 + return; + } + authMgr->isAuthNewVersion_ = false; + + if (IsAuthManagerSourceByMessage(msgType)) { + // 发送停止报文 + // 不能走新协议的停止,新协议是信号机制,无法串行停止,会存在时延,导致未停止就创建了新对象, + // 然后新协议的超时机制会再次停止softbus + std::string endMessage = CreateTerminateMessage(); + (void)softbusConnector_->GetSoftbusSession()->SendData(sessionId, endMessage); + // 关闭新协议会话 + CleanSessionMapByLogicalSessionId(logicalSessionId); + + ret = authMgr->BindTarget(pkgName, peerTargetId, bindParam, sessionId, 0); + if (ret != DM_OK) { + LOGE("DeviceManagerServiceImpl::OnBytesReceived authManager BindTarget failed"); + return; + } + LOGI("DeviceManagerServiceImpl::OnBytesReceived src transfer to old version success"); + return; + } + + // 参数2 sessionSide为0,authMgr_为空一定是sink端,src端会在BindTarget时创建协议对象 + authMgr->OnSessionOpened(sessionId, 0, 0); + LOGI("DeviceManagerServiceImpl::OnBytesReceived src transfer to old version success"); + } + } + std::string message = std::string(reinterpret_cast(data), dataLen); + if (msgType == AUTH_DEVICE_REQ_NEGOTIATE || msgType == AUTH_DEVICE_RESP_NEGOTIATE) { + authMgr->OnAuthDeviceDataReceived(sessionId, message); + } else { + authMgr->OnDataReceived(sessionId, message); + } SoftbusSession::OnBytesReceived(sessionId, data, dataLen); + LOGI("DeviceManagerServiceImpl::OnBytesReceived in bytes received"); + return; } int32_t DeviceManagerServiceImpl::RequestCredential(const std::string &reqJsonStr, std::string &returnJsonStr) @@ -452,17 +1022,39 @@ int32_t DeviceManagerServiceImpl::UnRegisterCredentialCallback(const std::string return credentialMgr_->UnRegisterCredentialCallback(pkgName); } +static uint64_t GetSecondElement(const std::string& input) +{ + std::istringstream stream(input); + std::string token; + int count = 0; + uint64_t value = 0; + + // 分割字符串并计数 + while (std::getline(stream, token, ' ')) { + if (count >= 1) { + // 转换为 uint64_t + value = std::stoull(token); + break; + } + count++; + } + + return value; +} + int32_t DeviceManagerServiceImpl::RegisterUiStateCallback(const std::string &pkgName) { if (pkgName.empty()) { LOGE("RegisterUiStateCallback failed, pkgName is empty"); return ERR_DM_INPUT_PARA_INVALID; } - if (authMgr_ == nullptr) { + uint64_t tokenId = GetSecondElement(pkgName); + auto authMgr = GetAuthMgrByTokenId(tokenId); + if (authMgr == nullptr) { LOGE("authMgr_ is nullptr"); return ERR_DM_POINT_NULL; } - return authMgr_->RegisterUiStateCallback(pkgName); + return authMgr->RegisterUiStateCallback(pkgName); } int32_t DeviceManagerServiceImpl::UnRegisterUiStateCallback(const std::string &pkgName) @@ -471,11 +1063,13 @@ int32_t DeviceManagerServiceImpl::UnRegisterUiStateCallback(const std::string &p LOGE("UnRegisterUiStateCallback failed, pkgName is empty"); return ERR_DM_INPUT_PARA_INVALID; } - if (authMgr_ == nullptr) { + uint64_t tokenId = GetSecondElement(pkgName); + auto authMgr = GetAuthMgrByTokenId(tokenId); + if (authMgr == nullptr) { LOGE("authMgr_ is nullptr"); return ERR_DM_POINT_NULL; } - return authMgr_->UnRegisterUiStateCallback(pkgName); + return authMgr->UnRegisterUiStateCallback(pkgName); } int32_t DeviceManagerServiceImpl::PraseNotifyEventJson(const std::string &event, JsonObject &jsonObject) @@ -565,6 +1159,16 @@ int32_t DeviceManagerServiceImpl::GetUdidHashByNetWorkId(const char *networkId, return DM_OK; } +std::shared_ptr DeviceManagerServiceImpl::GetConfigByTokenId() +{ + uint64_t tokenId = IPCSkeleton::GetCallingTokenID(); + if (configsMap_.find(tokenId) == configsMap_.end()) { + configsMap_[tokenId] = std::make_shared(); + } + configsMap_[tokenId]->tokenId = tokenId; + return configsMap_[tokenId]; +} + int32_t DeviceManagerServiceImpl::ImportAuthCode(const std::string &pkgName, const std::string &authCode) { if (pkgName.empty() || authCode.empty()) { @@ -572,25 +1176,263 @@ int32_t DeviceManagerServiceImpl::ImportAuthCode(const std::string &pkgName, con return ERR_DM_INPUT_PARA_INVALID; } - return authMgr_->ImportAuthCode(pkgName, authCode); + LOGI("DeviceManagerServiceImpl::ImportAuthCode pkgName is %{public}s, authCode is %{public}s", + pkgName.c_str(), authCode.c_str()); + auto authMgr = GetAuthMgr(); + if (authMgr == nullptr) { + auto config = GetConfigByTokenId(); + LOGI("DeviceManagerServiceImpl::ImportAuthCode import for tokenId %{public}llu", config->tokenId); + config->pkgName = pkgName; + config->authCode = authCode; // 若多次注册,只保留最后一个 + return DM_OK; + } + + return authMgr->ImportAuthCode(pkgName, authCode); } int32_t DeviceManagerServiceImpl::ExportAuthCode(std::string &authCode) { - int32_t ret = authMgr_->GeneratePincode(); + int32_t ret = GenRandInt(MIN_PIN_CODE, MAX_PIN_CODE); authCode = std::to_string(ret); LOGI("ExportAuthCode success, authCode: %{public}s.", GetAnonyString(authCode).c_str()); return DM_OK; } +static JsonObject GetExtraJsonObject(const std::map &bindParam) +{ + std::string extra; + auto iter = bindParam.find(PARAM_KEY_BIND_EXTRA_DATA); + if (iter != bindParam.end()) { + extra = iter->second; + } else { + extra = ConvertMapToJsonString(bindParam); + } + + return JsonObject(extra); +} + +static int32_t GetHmlInfo(const JsonObject &jsonObject, bool &hmlEnable160M, int32_t &hmlActionId) +{ + if (jsonObject[PARAM_KEY_HML_ENABLE_160M].IsBoolean()) { + hmlEnable160M = jsonObject[PARAM_KEY_HML_ENABLE_160M].Get(); + LOGI("hmlEnable160M %{public}d", hmlEnable160M); + } + if (jsonObject[PARAM_KEY_HML_ACTIONID].IsNumberInteger()) { + hmlActionId = jsonObject[PARAM_KEY_HML_ACTIONID].Get(); + if (hmlActionId < 0) { + hmlActionId = 0; + } + LOGI("hmlActionId %{public}d", hmlActionId); + } + return DM_OK; +} + +static bool IsHmlSessionType(const JsonObject &jsonObject) +{ + std::string connSessionType; + if (jsonObject[PARAM_KEY_CONN_SESSIONTYPE].IsString()) { + connSessionType = jsonObject[PARAM_KEY_CONN_SESSIONTYPE].Get(); + LOGI("connSessionType %{public}s", connSessionType.c_str()); + } + return connSessionType == CONN_SESSION_TYPE_HML; +} + +int DeviceManagerServiceImpl::OpenAuthSession(const std::map &bindParam) +{ + bool hmlEnable160M = false; + int32_t hmlActionId = 0; + JsonObject jsonObject = GetExtraJsonObject(bindParam); + if (jsonObject.IsDiscarded()) { + LOGE("extra string not a json type."); + goto error; + } + if (IsHmlSessionType(jsonObject)) { + if (GetHmlInfo(jsonObject, hmlEnable160M, hmlActionId) != DM_OK) { + goto error; + } + LOGI("hmlActionId %{public}d, hmlEnable160M %{public}d", hmlActionId, hmlEnable160M); + return softbusConnector_->GetSoftbusSession()->OpenAuthSessionWithPara(deviceId, + hmlActionId, hmlEnable160M); + } else { + return softbusConnector_->GetSoftbusSession()->OpenAuthSession(deviceId); + } +} + +std::shared_ptr DeviceManagerServiceImpl::GetOrCreateSession(const std::string& deviceId, + const std::map &bindParam) +{ + std::shared_ptr instance; + int sessionId = -1; + // 获取全局锁,确保maps的线程安全 + { + std::lock_guard lock(mapMutex_); + if (deviceId2SessionIdMap_.find(deviceId) != deviceId2SessionIdMap_.end()) { + sessionId = deviceId2SessionIdMap_[deviceId]; + } + if (sessionsMap_.find(sessionId) != sessionsMap_.end()) { + return sessionsMap_[sessionId]; + } + } + + // 获取deviceId对应的锁 + std::mutex& device_mutex = deviceIdMutexMap_[deviceId]; + std::lock_guard lock(device_mutex); + + // 再次检查是否已经存在对应的对象(因为可能在上一步获取锁的过程中,其他线程已经创建了) + { + std::lock_guard lock(mapMutex_); + if (deviceId2SessionIdMap_.find(deviceId) != deviceId2SessionIdMap_.end()) { + sessionId = deviceId2SessionIdMap_[deviceId]; + } + if (sessionsMap_.find(sessionId) != sessionsMap_.end()) { + return sessionsMap_[sessionId]; + } + + sessionId = OpenAuthSession(bindParam); + + if (sessionId < 0) { + goto error; + } + + std::unique_lock cvLock(sessionEnableMutexMap_[sessionId]); + sessionEnableCvMap_[sessionId].wait(cvLock); + + instance = std::make_shared(sessionId, deviceId); + deviceId2SessionIdMap_[deviceId] = sessionId; + sessionsMap_[sessionId] = instance; + } + return instance; +error: + // 会话打开失败 + LOGE("OpenAuthSession failed, stop the authentication"); + return nullptr; +} + +int32_t DeviceManagerServiceImpl::ParseConnectAddr(const PeerTargetId &targetId, std::string &deviceId, + const std::map &bindParam) +{ + std::string addrType; + if (bindParam.count(PARAM_KEY_CONN_ADDR_TYPE) != 0) { + addrType = bindParam.at(PARAM_KEY_CONN_ADDR_TYPE); + } + int32_t index = 0; + std::shared_ptr deviceInfo = std::make_shared(); + ConnectionAddr addr; + if (!targetId.wifiIp.empty() && targetId.wifiIp.length() <= IP_STR_MAX_LEN) { + LOGI("AuthManager::ParseConnectAddr parse wifiIp: %{public}s.", GetAnonyString(targetId.wifiIp).c_str()); + if (!addrType.empty()) { + addr.type = static_cast(std::atoi(addrType.c_str())); + } else { + addr.type = ConnectionAddrType::CONNECTION_ADDR_WLAN; + } + if (memcpy_s(addr.info.ip.ip, IP_STR_MAX_LEN, targetId.wifiIp.c_str(), targetId.wifiIp.length()) != 0) { + LOGE("get ip addr: %{public}s failed", GetAnonyString(targetId.wifiIp).c_str()); + return ERR_DM_SECURITY_FUNC_FAILED; + } + addr.info.ip.port = targetId.wifiPort; + deviceInfo->addr[index] = addr; + deviceId = targetId.wifiIp; + index++; + } else if (!targetId.brMac.empty() && targetId.brMac.length() <= BT_MAC_LEN) { + LOGI("AuthManager::ParseConnectAddr parse brMac: %{public}s.", GetAnonyString(targetId.brMac).c_str()); + addr.type = ConnectionAddrType::CONNECTION_ADDR_BR; + if (memcpy_s(addr.info.br.brMac, BT_MAC_LEN, targetId.brMac.c_str(), targetId.brMac.length()) != 0) { + LOGE("get brMac addr: %{public}s failed", GetAnonyString(targetId.brMac).c_str()); + return ERR_DM_SECURITY_FUNC_FAILED; + } + deviceInfo->addr[index] = addr; + deviceId = targetId.brMac; + index++; + } else if (!targetId.bleMac.empty() && targetId.bleMac.length() <= BT_MAC_LEN) { + LOGI("AuthManager::ParseConnectAddr parse bleMac: %{public}s.", GetAnonyString(targetId.bleMac).c_str()); + addr.type = ConnectionAddrType::CONNECTION_ADDR_BLE; + if (memcpy_s(addr.info.ble.bleMac, BT_MAC_LEN, targetId.bleMac.c_str(), targetId.bleMac.length()) != 0) { + LOGE("get bleMac addr: %{public}s failed", GetAnonyString(targetId.bleMac).c_str()); + return ERR_DM_SECURITY_FUNC_FAILED; + } + if (!targetId.deviceId.empty()) { + Crypto::ConvertHexStringToBytes(addr.info.ble.udidHash, UDID_HASH_LEN, + targetId.deviceId.c_str(), targetId.deviceId.length()); + } + deviceInfo->addr[index] = addr; + deviceId = targetId.bleMac; + index++; + } else { + LOGE("AuthManager::ParseConnectAddr failed, not addr."); + return ERR_DM_INPUT_PARA_INVALID; + } + + deviceInfo->addrNum = static_cast(index); + if (softbusConnector_->AddMemberToDiscoverMap(deviceId, deviceInfo) != DM_OK) { + LOGE("AuthManager::ParseConnectAddr failed, AddMemberToDiscoverMap failed."); + return ERR_DM_INPUT_PARA_INVALID; + } + deviceInfo = nullptr; + return DM_OK; +} + int32_t DeviceManagerServiceImpl::BindTarget(const std::string &pkgName, const PeerTargetId &targetId, const std::map &bindParam) { + int32_t ret = DM_OK; if (pkgName.empty()) { - LOGE("BindTarget failed, pkgName is empty"); + LOGE("BindTarget failed, pkgName is empty."); return ERR_DM_INPUT_PARA_INVALID; } - return authMgr_->BindTarget(pkgName, targetId, bindParam); + + int sessionId = 0; + int64_t logicalSessionId = 0; + std::shared_ptr curSession = nullptr; + if (GetEnableNewProtocolFlag() == 1) { + std::string deviceId = ""; + ret = ParseConnectAddr(targetId, deviceId, bindParam); + if (ret == DM_OK) { + const_cast(targetId).deviceId = deviceId; + } else { + if (targetId.deviceId.empty()) { + LOGE("DeviceManagerServiceImpl::BindTarget failed, ParseConnectAddr failed."); + return ERR_DM_INPUT_PARA_INVALID; + } + } + // 只在source端创建,新协议同一目标设备不会重复创建 + curSession = GetOrCreateSession(targetId.deviceId, bindParam); + if (curSession == nullptr) { + LOGE("Failed to create the session. Target deviceId: %{public}s.", targetId.deviceId.c_str()); + return ERR_DM_AUTH_OPEN_SESSION_FAILED; + } + + // 逻辑会话随机数 + sessionId = curSession->sessionId_; + logicalSessionId = GenerateRandNum(sessionId); + if (curSession->logicalSessionSet_.find(logicalSessionId) != curSession->logicalSessionSet_.end()) { + LOGE("Failed to create the logical session."); + return ERR_DM_LOGIC_SESSION_CREATE_FAILED; + } + } else { + curSession = std::make_shared(0, std::string("")); + curSession->version = DM_VERSION_5_0_5; + } + + // src端创建 + uint64_t tokenId = IPCSkeleton::GetCallingTokenID(); + ret = InitAndRegisterAuthMgr(true, tokenId, curSession, logicalSessionId); + if (ret != DM_OK) { + // 内部已完成错误日志打印,传递错误码即可 + return ret; + } + + if (GetEnableNewProtocolFlag() == 1) { + curSession->logicalSessionSet_.insert(logicalSessionId); + curSession->logicalSessionCnt_.fetch_add(1); + logicalSessionId2TokenIdMap_[logicalSessionId] = tokenId; + logicalSessionId2SessionIdMap_[logicalSessionId] = sessionId; + } + + auto authMgr = GetAuthMgr(); + if (authMgr != nullptr) { + return authMgr->BindTarget(pkgName, targetId, bindParam, sessionId, logicalSessionId); + } + return ERR_DM_AUTH_FAILED; } void DeviceManagerServiceImpl::PutIdenticalAccountToAcl(std::string requestDeviceId, std::string trustDeviceId) @@ -734,12 +1576,13 @@ void DeviceManagerServiceImpl::ScreenCommonEventCallback(std::string commonEvent { if (commonEventType == EventFwk::CommonEventSupport::COMMON_EVENT_SCREEN_LOCKED) { LOGI("DeviceManagerServiceImpl::ScreenCommonEventCallback on screen locked."); - if (authMgr_ != nullptr) { - authMgr_->OnScreenLocked(); - return; - } else { - LOGE("authMgr_ is null, cannot call OnScreenLocked."); + for (auto& pair : authMgrMap_) { + if (pair.second != nullptr) { + LOGD("DeviceManagerServiceImpl::ScreenCommonEventCallback tokenId: %{public}llu.", pair.first); + pair.second->OnScreenLocked(); + } } + return; } LOGI("DeviceManagerServiceImpl::ScreenCommonEventCallback error."); } @@ -771,8 +1614,9 @@ void DeviceManagerServiceImpl::HandleDeviceNotTrust(const std::string &udid) LOGE("HandleDeviceNotTrust udid is empty."); return; } - CHECK_NULL_VOID(authMgr_); - authMgr_->HandleDeviceNotTrust(udid); + DeviceProfileConnector::GetInstance().DeleteAccessControlList(udid); + CHECK_NULL_VOID(hiChainConnector_); + hiChainConnector_->DeleteAllGroupByUdid(udid); } int32_t DeviceManagerServiceImpl::GetBindLevel(const std::string &pkgName, const std::string &localUdid, @@ -849,13 +1693,27 @@ void DeviceManagerServiceImpl::HandleDevUnBindEvent(int32_t remoteUserId, const char localUdidTemp[DEVICE_UUID_LENGTH] = {0}; GetDevUdid(localUdidTemp, DEVICE_UUID_LENGTH); std::string localUdid = std::string(localUdidTemp); - int32_t bindType = DeviceProfileConnector::GetInstance().HandleDevUnBindEvent(remoteUserId, remoteUdid, localUdid); + DmOfflineParam offlineParam; + int32_t bindType = DeviceProfileConnector::GetInstance().HandleDevUnBindEvent(offlineParam, + remoteUserId, remoteUdid, localUdid); if (static_cast(bindType) == DM_INVALIED_BINDTYPE) { LOGE("Invalied bindtype."); return; } - CHECK_NULL_VOID(authMgr_); - authMgr_->DeleteGroup(DM_PKG_NAME, remoteUdid); + + auto authMgr = GetAuthMgr(); + if (authMgr == nullptr) { + LOGE("authMgr_ is nullptr"); + return; + } + if (authMgr->isAuthNewVersion_) { + int32_t accountId = MultipleUserConnector::GetCurrentAccountUserID(); + for (auto credId : offlineParam.credIdVec) { + hiChainAuthConnector_->DeleteCredential(accountId, credId); + } + } else { + authMgr->DeleteGroup(DM_PKG_NAME, remoteUdid); + } } void DeviceManagerServiceImpl::HandleAppUnBindEvent(int32_t remoteUserId, const std::string &remoteUdid, @@ -864,15 +1722,34 @@ void DeviceManagerServiceImpl::HandleAppUnBindEvent(int32_t remoteUserId, const char localUdidTemp[DEVICE_UUID_LENGTH] = {0}; GetDevUdid(localUdidTemp, DEVICE_UUID_LENGTH); std::string localUdid = std::string(localUdidTemp); - ProcessInfo processInfo = + DmOfflineParam offlineParam = DeviceProfileConnector::GetInstance().HandleAppUnBindEvent(remoteUserId, remoteUdid, tokenId, localUdid); - if (processInfo.pkgName.empty()) { - LOGE("Pkgname is empty."); + CHECK_NULL_VOID(softbusConnector_); + CHECK_NULL_VOID(hiChainAuthConnector_); + if (offlineParam.leftAclNumber != 0) { + LOGI("The sessionName unbind app-level type leftAclNumber not zero."); + softbusConnector_->SetProcessInfoVec(offlineParam.processVec); + softbusConnector_->HandleDeviceOffline(remoteUdid); + return; + } + if (offlineParam.leftAclNumber == 0) { + LOGI("The sessionName unbind app-level type leftAclNumber is zero."); + softbusConnector_->SetProcessInfoVec(offlineParam.processVec); + auto authMgr = GetAuthMgr(); + if (authMgr == nullptr) { + LOGE("authMgr_ is nullptr"); + return; + } + if (authMgr->isAuthNewVersion_) { + int32_t accountId = MultipleUserConnector::GetCurrentAccountUserID(); + for (auto credId : offlineParam.credIdVec) { + hiChainAuthConnector_->DeleteCredential(accountId, credId); + } + } else { + hiChainAuthConnector_->DeleteCredential(remoteUdid, MultipleUserConnector::GetCurrentAccountUserID()); + } return; } - CHECK_NULL_VOID(softbusConnector_); - softbusConnector_->SetProcessInfo(processInfo); - softbusConnector_->HandleDeviceOffline(remoteUdid); } void DeviceManagerServiceImpl::HandleAppUnBindEvent(int32_t remoteUserId, const std::string &remoteUdid, @@ -882,16 +1759,73 @@ void DeviceManagerServiceImpl::HandleAppUnBindEvent(int32_t remoteUserId, const char localUdidTemp[DEVICE_UUID_LENGTH] = {0}; GetDevUdid(localUdidTemp, DEVICE_UUID_LENGTH); std::string localUdid = std::string(localUdidTemp); - ProcessInfo processInfo = + DmOfflineParam offlineParam = DeviceProfileConnector::GetInstance().HandleAppUnBindEvent(remoteUserId, remoteUdid, tokenId, localUdid, peerTokenId); - if (processInfo.pkgName.empty()) { - LOGE("Pkgname is empty."); + CHECK_NULL_VOID(softbusConnector_); + CHECK_NULL_VOID(hiChainAuthConnector_); + if (offlineParam.leftAclNumber != 0) { + LOGI("The sessionName unbind app-level type leftAclNumber not zero."); + softbusConnector_->SetProcessInfoVec(offlineParam.processVec); + softbusConnector_->HandleDeviceOffline(remoteUdid); + return; + } + if (offlineParam.leftAclNumber == 0) { + LOGI("The sessionName unbind app-level type leftAclNumber is zero."); + softbusConnector_->SetProcessInfoVec(offlineParam.processVec); + auto authMgr = GetAuthMgr(); + if (authMgr == nullptr) { + LOGE("authMgr_ is nullptr"); + return; + } + if (authMgr->isAuthNewVersion_) { + int32_t accountId = MultipleUserConnector::GetCurrentAccountUserID(); + for (auto credId : offlineParam.credIdVec) { + hiChainAuthConnector_->DeleteCredential(accountId, credId); + } + } else { + hiChainAuthConnector_->DeleteCredential(remoteUdid, MultipleUserConnector::GetCurrentAccountUserID()); + } return; } +} + +void DeviceManagerServiceImpl::HandleServiceUnBindEvent(int32_t userId, const std::string &remoteUdid, + int32_t remoteTokenId) +{ + LOGI("HandleServiceUnBindEvent remoteTokenId = %{public}d, userId: %{public}d, remoteUdid: %{public}s.", + remoteTokenId, userId, GetAnonyString(remoteUdid).c_str()); + char localUdidTemp[DEVICE_UUID_LENGTH] = {0}; + GetDevUdid(localUdidTemp, DEVICE_UUID_LENGTH); + std::string localUdid = std::string(localUdidTemp); + DmOfflineParam offlineParam = DeviceProfileConnector::GetInstance().HandleServiceUnBindEvent( + userId, remoteUdid, localUdid, remoteTokenId); CHECK_NULL_VOID(softbusConnector_); - softbusConnector_->SetProcessInfo(processInfo); - softbusConnector_->HandleDeviceOffline(remoteUdid); + CHECK_NULL_VOID(hiChainAuthConnector_); + if (offlineParam.leftAclNumber != 0) { + LOGI("The sessionName unbind app-level type leftAclNumber not zero."); + softbusConnector_->SetProcessInfoVec(offlineParam.processVec); + softbusConnector_->HandleDeviceOffline(remoteUdid); + return; + } + if (offlineParam.leftAclNumber == 0) { + LOGI("The sessionName unbind app-level type leftAclNumber is zero."); + softbusConnector_->SetProcessInfoVec(offlineParam.processVec); + auto authMgr = GetAuthMgr(); + if (authMgr == nullptr) { + LOGE("authMgr_ is nullptr"); + return; + } + if (authMgr->isAuthNewVersion_) { + int32_t accountId = MultipleUserConnector::GetCurrentAccountUserID(); + for (auto credId : offlineParam.credIdVec) { + hiChainAuthConnector_->DeleteCredential(accountId, credId); + } + } else { + hiChainAuthConnector_->DeleteCredential(remoteUdid, MultipleUserConnector::GetCurrentAccountUserID()); + } + return; + } } void DeviceManagerServiceImpl::HandleSyncUserIdEvent(const std::vector &foregroundUserIds, @@ -1030,8 +1964,13 @@ void DeviceManagerServiceImpl::HandleDeviceUnBind(int32_t bindType, const std::s int32_t DeviceManagerServiceImpl::RegisterAuthenticationType(int32_t authenticationType) { - CHECK_NULL_RETURN(authMgr_, ERR_DM_POINT_NULL); - return authMgr_->RegisterAuthenticationType(authenticationType); + auto authMgr = GetAuthMgr(); + if (authMgr == nullptr) { + auto config = GetConfigByTokenId(); + config->authenticationType = authenticationType; // 若多次注册,只保留最后一个 + return DM_OK; + } + return authMgr->RegisterAuthenticationType(authenticationType); } void DeviceManagerServiceImpl::DeleteAlwaysAllowTimeOut() @@ -1081,9 +2020,72 @@ int32_t DeviceManagerServiceImpl::CheckDeviceInfoPermission(const std::string &l return DM_OK; } +int32_t DeviceManagerServiceImpl::DeleteAcl(const std::string &sessionName, const std::string &localUdid, + const std::string &remoteUdid, int32_t bindLevel, const std::string &extra) +{ + LOGI("DeleteAcl sessionName %{public}s, localUdid %{public}s, remoteUdid %{public}s, bindLevel %{public}d.", + sessionName.c_str(), GetAnonyString(localUdid).c_str(), GetAnonyString(remoteUdid).c_str(), bindLevel); + uint32_t tokenId = 0; + MultipleUserConnector::GetTokenId(tokenId); + DmOfflineParam offlineParam = DeviceProfileConnector::GetInstance().DeleteAccessControlList_v2( + tokenId, localUdid, remoteUdid, bindLevel, extra); + if (offlineParam.bindType == INVALIED_TYPE) { + LOGE("Acl not contain the sessionName bind data."); + return ERR_DM_FAILED; + } + if (bindLevel == static_cast(APP) || bindLevel == static_cast(SERVICE)) { + if (offlineParam.leftAclNumber != 0) { + LOGI("The sessionName unbind app-level type leftAclNumber not zero."); + softbusConnector_->SetProcessInfoVec(offlineParam.processVec); + softbusConnector_->HandleDeviceOffline(remoteUdid); + return DM_OK; + } + if (offlineParam.leftAclNumber == 0) { + LOGI("The sessionName unbind app-level type leftAclNumber is zero."); + softbusConnector_->SetProcessInfoVec(offlineParam.processVec); + auto authMgr = GetAuthMgr(); + if (authMgr == nullptr) { + LOGE("authMgr_ is nullptr"); + return ERR_DM_POINT_NULL; + } + if (authMgr->isAuthNewVersion_) { + int32_t accountId = MultipleUserConnector::GetCurrentAccountUserID(); + for (auto credId : offlineParam.credIdVec) { + hiChainAuthConnector_->DeleteCredential(accountId, credId); + } + } else { + hiChainAuthConnector_->DeleteCredential(remoteUdid, MultipleUserConnector::GetCurrentAccountUserID()); + } + return DM_OK; + } + } + if (bindLevel == static_cast(DEVICE) && offlineParam.leftAclNumber != 0) { + LOGI("Unbind deivce-level, retain identical account bind type."); + return DM_OK; + } + if (bindLevel == static_cast(DEVICE) && offlineParam.leftAclNumber == 0) { + LOGI("Unbind deivce-level, retain null."); + auto authMgr = GetAuthMgr(); + if (authMgr == nullptr) { + LOGE("authMgr_ is nullptr"); + return ERR_DM_POINT_NULL; + } + if (authMgr->isAuthNewVersion_) { + int32_t accountId = MultipleUserConnector::GetCurrentAccountUserID(); + for (auto credId : offlineParam.credIdVec) { + hiChainAuthConnector_->DeleteCredential(accountId, credId); + } + } else { + hiChainAuthConnector_->DeleteCredential(remoteUdid, MultipleUserConnector::GetCurrentAccountUserID()); + } + return DM_OK; + } + return ERR_DM_FAILED; +} + extern "C" IDeviceManagerServiceImpl *CreateDMServiceObject(void) { return new DeviceManagerServiceImpl; } } // namespace DistributedHardware -} // namespace OHOS +} // namespace OHOS \ No newline at end of file diff --git a/services/service/include/idevice_manager_service_impl.h b/services/service/include/idevice_manager_service_impl.h index 8ba83a8ad..fcccfc92b 100644 --- a/services/service/include/idevice_manager_service_impl.h +++ b/services/service/include/idevice_manager_service_impl.h @@ -260,6 +260,8 @@ public: virtual void DeleteAlwaysAllowTimeOut() = 0; virtual void CheckDeleteCredential(const std::string &remoteUdid) = 0; virtual int32_t CheckDeviceInfoPermission(const std::string &localUdid, const std::string &peerDeviceId) = 0; + virtual void HandleServiceUnBindEvent(int32_t userId, const std::string &remoteUdid, + int32_t remoteTokenId) = 0; }; using CreateDMServiceFuncPtr = IDeviceManagerServiceImpl *(*)(void); diff --git a/services/service/include/relationshipsyncmgr/relationship_sync_mgr.h b/services/service/include/relationshipsyncmgr/relationship_sync_mgr.h index d0787d446..cc6409ce1 100644 --- a/services/service/include/relationshipsyncmgr/relationship_sync_mgr.h +++ b/services/service/include/relationshipsyncmgr/relationship_sync_mgr.h @@ -68,6 +68,7 @@ struct RelationShipChangeMsg { void ToAccountLogoutPayLoad(uint8_t *&msg, uint32_t &len) const; void ToDeviceUnbindPayLoad(uint8_t *&msg, uint32_t &len) const; void ToAppUnbindPayLoad(uint8_t *&msg, uint32_t &len) const; + void ToServiceUnbindPayLoad(uint8_t *&msg, uint32_t &len) const; bool ToSyncFrontOrBackUserIdPayLoad(uint8_t *&msg, uint32_t &len) const; void ToDelUserPayLoad(uint8_t *&msg, uint32_t &len) const; void ToStopUserPayLoad(uint8_t *&msg, uint32_t &len) const; @@ -76,6 +77,7 @@ struct RelationShipChangeMsg { bool FromAccountLogoutPayLoad(const cJSON *payloadJson); bool FromDeviceUnbindPayLoad(const cJSON *payloadJson); bool FromAppUnbindPayLoad(const cJSON *payloadJson); + bool FromServiceUnbindPayLoad(const cJSON *payloadJson); bool FromSyncFrontOrBackUserIdPayLoad(const cJSON *payloadJson); bool FromDelUserPayLoad(const cJSON *payloadJson); bool FromStopUserPayLoad(const cJSON *payloadJson); diff --git a/services/service/src/device_manager_service.cpp b/services/service/src/device_manager_service.cpp index 5279555c5..83cf450f3 100644 --- a/services/service/src/device_manager_service.cpp +++ b/services/service/src/device_manager_service.cpp @@ -2532,6 +2532,10 @@ void DeviceManagerService::HandleDeviceTrustedChange(const std::string &msg) static_cast(relationShipMsg.tokenId)); } break; + case RelationShipChangeType::SERVICE_UNBIND: + dmServiceImpl_->HandleServiceUnBindEvent(relationShipMsg.userId, relationShipMsg.peerUdid, + static_cast(relationShipMsg.tokenId)); + break; case RelationShipChangeType::SYNC_USERID: HandleUserIdsBroadCast(relationShipMsg.userIdInfos, relationShipMsg.peerUdid, relationShipMsg.syncUserIdFlag); diff --git a/services/service/src/relationshipsyncmgr/relationship_sync_mgr.cpp b/services/service/src/relationshipsyncmgr/relationship_sync_mgr.cpp index 962391c13..ce38f2ade 100644 --- a/services/service/src/relationshipsyncmgr/relationship_sync_mgr.cpp +++ b/services/service/src/relationshipsyncmgr/relationship_sync_mgr.cpp @@ -116,6 +116,10 @@ bool RelationShipChangeMsg::ToBroadcastPayLoad(uint8_t *&msg, uint32_t &len) con ToAppUnbindPayLoad(msg, len); ret = true; break; + case RelationShipChangeType::SERVICE_UNBIND: + ToServiceUnbindPayLoad(msg, len); + ret = true; + break; case RelationShipChangeType::SYNC_USERID: ret = ToSyncFrontOrBackUserIdPayLoad(msg, len); break; @@ -152,6 +156,9 @@ bool RelationShipChangeMsg::FromBroadcastPayLoad(const cJSON *payloadJson, Relat case RelationShipChangeType::APP_UNBIND: ret = FromAppUnbindPayLoad(payloadJson); break; + case RelationShipChangeType::SERVICE_UNBIND: + ret = FromServiceUnbindPayLoad(payloadJson); + break; case RelationShipChangeType::SYNC_USERID: ret = FromSyncFrontOrBackUserIdPayLoad(payloadJson); break; @@ -188,6 +195,8 @@ bool RelationShipChangeMsg::IsValid() const ret = (userId != UINT32_MAX); break; case RelationShipChangeType::SERVICE_UNBIND: + ret = (userId != UINT32_MAX); + break; case RelationShipChangeType::APP_UNINSTALL: // current NOT support ret = false; @@ -210,7 +219,8 @@ bool RelationShipChangeMsg::IsChangeTypeValid() { return (type == RelationShipChangeType::ACCOUNT_LOGOUT) || (type == RelationShipChangeType::DEVICE_UNBIND) || (type == RelationShipChangeType::APP_UNBIND) || (type == RelationShipChangeType::SYNC_USERID) || - (type == RelationShipChangeType::DEL_USER) || (type == RelationShipChangeType::STOP_USER); + (type == RelationShipChangeType::DEL_USER) || (type == RelationShipChangeType::STOP_USER) || + (type == RelationShipChangeType::SERVICE_UNBIND); } bool RelationShipChangeMsg::IsChangeTypeValid(uint32_t type) @@ -220,7 +230,8 @@ bool RelationShipChangeMsg::IsChangeTypeValid(uint32_t type) (type == (uint32_t)RelationShipChangeType::APP_UNBIND) || (type == (uint32_t)RelationShipChangeType::SYNC_USERID) || (type == (uint32_t)RelationShipChangeType::DEL_USER) || - (type == (uint32_t)RelationShipChangeType::STOP_USER); + (type == (uint32_t)RelationShipChangeType::STOP_USER) || + (type == (uint32_t)RelationShipChangeType::SERVICE_UNBIND); } void RelationShipChangeMsg::ToAccountLogoutPayLoad(uint8_t *&msg, uint32_t &len) const @@ -263,6 +274,11 @@ void RelationShipChangeMsg::ToAppUnbindPayLoad(uint8_t *&msg, uint32_t &len) con len = APP_UNBIND_PAYLOAD_LEN; } +void RelationShipChangeMsg::ToServiceUnbindPayLoad(uint8_t *&msg, uint32_t &len) const +{ + ToAppUnbindPayLoad(msg, len); +} + bool RelationShipChangeMsg::ToSyncFrontOrBackUserIdPayLoad(uint8_t *&msg, uint32_t &len) const { uint32_t userIdNum = static_cast(userIdInfos.size()); @@ -407,6 +423,11 @@ bool RelationShipChangeMsg::FromAppUnbindPayLoad(const cJSON *payloadJson) return true; } +bool RelationShipChangeMsg::FromServiceUnbindPayLoad(const cJSON *payloadJson) +{ + return FromAppUnbindPayLoad(payloadJson); +} + bool RelationShipChangeMsg::FromSyncFrontOrBackUserIdPayLoad(const cJSON *payloadJson) { if (payloadJson == NULL) { diff --git a/test/commonfuzztest/BUILD.gn b/test/commonfuzztest/BUILD.gn index 4430b898c..c88c67ba2 100644 --- a/test/commonfuzztest/BUILD.gn +++ b/test/commonfuzztest/BUILD.gn @@ -19,12 +19,14 @@ group("fuzztest") { "authenticatedeviceservice_fuzzer:fuzztest", "authenticatedeviceserviceimpl_fuzzer:fuzztest", "dmauthmanager_fuzzer:fuzztest", + "dmauthmanagerv2_fuzzer:fuzztest", "dmcommoneventmanager_fuzzer:fuzztest", "dmcredentialimpl_fuzzer:fuzztest", "generateencrypteduuid_fuzzer:fuzztest", "getdeviceinfo_fuzzer:fuzztest", "hichainconnector_fuzzer:fuzztest", "ondatareceived_fuzzer:fuzztest", + "ondatareceivedv2_fuzzer:fuzztest", "onerror_fuzzer:fuzztest", "onfinish_fuzzer:fuzztest", "onrequest_fuzzer:fuzztest", diff --git a/test/commonfuzztest/dmauthmanagerv2_fuzzer/BUILD.gn b/test/commonfuzztest/dmauthmanagerv2_fuzzer/BUILD.gn new file mode 100644 index 000000000..d81bcb502 --- /dev/null +++ b/test/commonfuzztest/dmauthmanagerv2_fuzzer/BUILD.gn @@ -0,0 +1,79 @@ +# Copyright (c) 2023-2024 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. + +#####################hydra-fuzz################### +import("//build/config/features.gni") +import("//build/test.gni") +import("//foundation/distributedhardware/device_manager/device_manager.gni") + +##############################fuzztest########################################## +ohos_fuzztest("DmAuthManagerV2FuzzTest") { + module_out_path = fuzz_test_output_path + fuzz_config_file = + "${devicemanager_path}/test/commonfuzztest/dmauthmanagerv2_fuzzer" + + include_dirs = [ + "${innerkits_path}/native_cpp/include", + "${servicesimpl_path}/include/ability", + "${servicesimpl_path}/include/adapter", + "${servicesimpl_path}/include/authentication_v2", + "${servicesimpl_path}/include/dependency/hichain", + "${servicesimpl_path}/include/dependency/softbus", + "${servicesimpl_path}/include/dependency/timer", + ] + + cflags = [ + "-g", + "-O0", + "-Dprivate=public", + "-Dprotected=public", + "-Werror", + "-Wno-unused-variable", + "-fno-omit-frame-pointer", + ] + + sources = [ "dm_auth_manager_fuzzer.cpp" ] + + deps = [ + "${innerkits_path}/native_cpp:devicemanagersdk", + "${services_path}:devicemanagerservice", + "${servicesimpl_path}:devicemanagerserviceimpl", + "${utils_path}:devicemanagerutils", + ] + + external_deps = [ + "device_auth:deviceauth_sdk", + "device_info_manager:distributed_device_profile_common", + "device_info_manager:distributed_device_profile_sdk", + "dsoftbus:softbus_client", + "ffrt:libffrt", + "hilog:libhilog", + "ipc:ipc_single", + "safwk:system_ability_fwk", + "cJSON:cjson", + ] + + defines = [ + "HI_LOG_ENABLE", + "DH_LOG_TAG=\"DmAuthManagerV2FuzzTest\"", + "LOG_DOMAIN=0xD004110", + ] +} + +############################################################################### +group("fuzztest") { + testonly = true + + deps = [ ":DmAuthManagerV2FuzzTest" ] +} +############################################################################### diff --git a/test/commonfuzztest/dmauthmanagerv2_fuzzer/corpus/init b/test/commonfuzztest/dmauthmanagerv2_fuzzer/corpus/init new file mode 100644 index 000000000..d9719cafa --- /dev/null +++ b/test/commonfuzztest/dmauthmanagerv2_fuzzer/corpus/init @@ -0,0 +1,13 @@ +# 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. +FUZZ \ No newline at end of file diff --git a/test/commonfuzztest/dmauthmanagerv2_fuzzer/dm_auth_manager_fuzzer.cpp b/test/commonfuzztest/dmauthmanagerv2_fuzzer/dm_auth_manager_fuzzer.cpp new file mode 100644 index 000000000..4c299af1a --- /dev/null +++ b/test/commonfuzztest/dmauthmanagerv2_fuzzer/dm_auth_manager_fuzzer.cpp @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2025-2025 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 +#include +#include "device_manager_service_listener.h" +#include "auth_manager.h" +#include "dm_auth_manager_fuzzer.h" + +namespace OHOS { +namespace DistributedHardware { + +int32_t g_sessionId = 1; +int32_t g_sessionSide = 0; +int32_t g_result = 1; +int32_t g_authType = 1; +int32_t g_status = 1; +int32_t g_pinCode = 1; +int32_t g_action = 1; +int32_t g_userId = 1; +int32_t g_pageId = 1; +int32_t g_reason = 1; +int32_t g_state = 1; +int64_t g_requestId = 1; +int64_t g_operationCode = 1; + +std::map g_bindParam; + +PeerTargetId g_targetId = { + .deviceId = "deviceId", + .brMac = "brMac", + .bleMac = "bleMac", + .wifiIp = "wifiIp", +}; + +// AuthSrcManager fuzz +void DmAuthSrcManagerFuzzTest(const uint8_t* data, size_t size) +{ + if ((data == nullptr) || (size < sizeof(int32_t))) { + return; + } + std::shared_ptr softbusConnector = std::make_shared(); + std::shared_ptr listener = std::make_shared(); + std::shared_ptr hiChainAuthConnector = std::make_shared(); + FuzzedDataProvider fdp(data, size); + std::string str(reinterpret_cast(data), size); + int32_t bindLevel = fdp.ConsumeIntegral(); + std::shared_ptr authManager = std::make_shared(softbusConnector, listener, + hiChainAuthConnector); + + authManager->OnUserOperation(g_action, str); + authManager->BindTarget(str, g_targetId, g_bindParam); + authManager->StopAuthenticateDevice(str); + authManager->ImportAuthCode(str, str); + authManager->RegisterUiStateCallback(str); + authManager->UnRegisterUiStateCallback(str); + authManager->UnAuthenticateDevice(str, str, bindLevel); + authManager->UnBindDevice(str, str, bindLevel, str); + authManager->HandleDeviceNotTrust(str); + authManager->DeleteGroup(str, str); + authManager->AuthDeviceTransmit(g_requestId, data, size); + authManager->AuthDeviceSessionKey(g_requestId, data, size); + authManager->AuthDeviceRequest(g_requestId, g_operationCode, str.c_str()); + authManager->OnDataReceived(g_sessionId, str); + authManager->OnAuthDeviceDataReceived(g_sessionId, str); +} + +// AuthSinkManager fuzz +void DmAuthSinkManagerFuzzTest(const uint8_t* data, size_t size) +{ + if ((data == nullptr) || (size < sizeof(int32_t))) { + return; + } + std::shared_ptr softbusConnector = std::make_shared(); + std::shared_ptr listener = std::make_shared(); + std::shared_ptr hiChainAuthConnector = std::make_shared(); + FuzzedDataProvider fdp(data, size); + std::string str(reinterpret_cast(data), size); + int32_t bindLevel = fdp.ConsumeIntegral(); + std::shared_ptr authManager = std::make_shared(softbusConnector, listener, + hiChainAuthConnector); + + authManager->OnUserOperation(g_action, str); + authManager->BindTarget(str, g_targetId, g_bindParam); + authManager->StopAuthenticateDevice(str); + authManager->ImportAuthCode(str, str); + authManager->RegisterUiStateCallback(str); + authManager->UnRegisterUiStateCallback(str); + authManager->UnAuthenticateDevice(str, str, bindLevel); + authManager->UnBindDevice(str, str, bindLevel, str); + authManager->HandleDeviceNotTrust(str); + authManager->DeleteGroup(str, str); + authManager->AuthDeviceTransmit(g_requestId, data, size); + authManager->AuthDeviceSessionKey(g_requestId, data, size); + authManager->AuthDeviceRequest(g_requestId, g_operationCode, str.c_str()); + authManager->OnDataReceived(g_sessionId, str); + authManager->OnAuthDeviceDataReceived(g_sessionId, str); +} +} +} + +/* Fuzzer entry point */ +extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) +{ + /* Run your code on data */ + OHOS::DistributedHardware::DmAuthSrcManagerFuzzTest(data, size); + OHOS::DistributedHardware::DmAuthSinkManagerFuzzTest(data, size); + return 0; +} \ No newline at end of file diff --git a/test/commonfuzztest/dmauthmanagerv2_fuzzer/dm_auth_manager_fuzzer.h b/test/commonfuzztest/dmauthmanagerv2_fuzzer/dm_auth_manager_fuzzer.h new file mode 100644 index 000000000..35643d1c4 --- /dev/null +++ b/test/commonfuzztest/dmauthmanagerv2_fuzzer/dm_auth_manager_fuzzer.h @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2025 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 DM_AUTH_MANAGER_FUZZER_H +#define DM_AUTH_MANAGER_FUZZER_H + +#define FUZZ_PROJECT_NAME "dmauthmanagerv2_fuzzer" + +#endif // DM_AUTH_MANAGER_FUZZER_H \ No newline at end of file diff --git a/test/commonfuzztest/dmauthmanagerv2_fuzzer/project.xml b/test/commonfuzztest/dmauthmanagerv2_fuzzer/project.xml new file mode 100644 index 000000000..bac4974e9 --- /dev/null +++ b/test/commonfuzztest/dmauthmanagerv2_fuzzer/project.xml @@ -0,0 +1,25 @@ + + + + + + 1000 + + 300 + + 4096 + + \ No newline at end of file diff --git a/test/commonfuzztest/ondatareceivedv2_fuzzer/BUILD.gn b/test/commonfuzztest/ondatareceivedv2_fuzzer/BUILD.gn new file mode 100644 index 000000000..6ecb86c33 --- /dev/null +++ b/test/commonfuzztest/ondatareceivedv2_fuzzer/BUILD.gn @@ -0,0 +1,78 @@ +# Copyright (c) 2023-2024 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. + +#####################hydra-fuzz################### +import("//build/config/features.gni") +import("//build/test.gni") +import("//foundation/distributedhardware/device_manager/device_manager.gni") + +##############################fuzztest########################################## +ohos_fuzztest("OnDataReceivedV2FuzzTest") { + module_out_path = fuzz_test_output_path + fuzz_config_file = + "${devicemanager_path}/test/commonfuzztest/ondatareceivedv2_fuzzer" + + include_dirs = [ + "${innerkits_path}/native_cpp/include", + "${servicesimpl_path}/include/ability", + "${servicesimpl_path}/include/adapter", + "${servicesimpl_path}/include/authentication", + "${servicesimpl_path}/include/dependency/hichain", + "${servicesimpl_path}/include/dependency/softbus", + "${servicesimpl_path}/include/dependency/timer", + ] + + cflags = [ + "-g", + "-O0", + "-Dprivate=public", + "-Dprotected=public", + "-Werror", + "-Wno-unused-variable", + "-fno-omit-frame-pointer", + ] + + sources = [ "on_data_received_fuzzer.cpp" ] + + deps = [ + "${services_path}:devicemanagerservice", + "${servicesimpl_path}:devicemanagerserviceimpl", + "${utils_path}:devicemanagerutils", + ] + + external_deps = [ + "device_auth:deviceauth_sdk", + "device_info_manager:distributed_device_profile_common", + "device_info_manager:distributed_device_profile_sdk", + "dsoftbus:softbus_client", + "ffrt:libffrt", + "hilog:libhilog", + "ipc:ipc_single", + "safwk:system_ability_fwk", + "cJSON:cjson", + ] + + defines = [ + "HI_LOG_ENABLE", + "DH_LOG_TAG=\"OnDataReceivedV2FuzzTest\"", + "LOG_DOMAIN=0xD004110", + ] +} + +############################################################################### +group("fuzztest") { + testonly = true + + deps = [ ":OnDataReceivedV2FuzzTest" ] +} +############################################################################### diff --git a/test/commonfuzztest/ondatareceivedv2_fuzzer/corpus/init b/test/commonfuzztest/ondatareceivedv2_fuzzer/corpus/init new file mode 100644 index 000000000..d9719cafa --- /dev/null +++ b/test/commonfuzztest/ondatareceivedv2_fuzzer/corpus/init @@ -0,0 +1,13 @@ +# 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. +FUZZ \ No newline at end of file diff --git a/test/commonfuzztest/ondatareceivedv2_fuzzer/on_data_received_fuzzer.cpp b/test/commonfuzztest/ondatareceivedv2_fuzzer/on_data_received_fuzzer.cpp new file mode 100644 index 000000000..6b1cec0cc --- /dev/null +++ b/test/commonfuzztest/ondatareceivedv2_fuzzer/on_data_received_fuzzer.cpp @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2023-2024 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 +#include +#include "auth_manager.h" +#include "device_manager_service_listener.h" +#include "on_data_received_fuzzer.h" + +namespace OHOS { +namespace DistributedHardware { +// AuthSrcManager fuzz +void OnDataReceivedSrcFuzzTest(const uint8_t* data, size_t size) +{ + if ((data == nullptr) || (size < sizeof(int32_t))) { + return; + } + + std::shared_ptr softbusConnector = std::make_shared(); + std::shared_ptr listener = std::make_shared(); + std::shared_ptr hiChainAuthConnector = std::make_shared(); + std::shared_ptr authManager = std::make_shared(softbusConnector, listener, + hiChainAuthConnector); + FuzzedDataProvider fdp(data, size); + int32_t sessionId = fdp.ConsumeIntegral(); + std::string message(reinterpret_cast(data), size); + authManager->OnDataReceived(sessionId, message); + authManager->OnSessionClosed(sessionId); +} + +// AuthSinkManager fuzz +void OnDataReceivedSinkFuzzTest(const uint8_t* data, size_t size) +{ + if ((data == nullptr) || (size < sizeof(int32_t))) { + return; + } + + std::shared_ptr softbusConnector = std::make_shared(); + std::shared_ptr listener = std::make_shared(); + std::shared_ptr hiChainAuthConnector = std::make_shared(); + std::shared_ptr authManager = std::make_shared(softbusConnector, listener, + hiChainAuthConnector); + FuzzedDataProvider fdp(data, size); + int32_t sessionId = fdp.ConsumeIntegral(); + std::string message(reinterpret_cast(data), size); + authManager->OnDataReceived(sessionId, message); + authManager->OnSessionClosed(sessionId); +} +} +} + +/* Fuzzer entry point */ +extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) +{ + /* Run your code on data */ + OHOS::DistributedHardware::OnDataReceivedSrcFuzzTest(data, size); + OHOS::DistributedHardware::OnDataReceivedSinkFuzzTest(data, size); + return 0; +} \ No newline at end of file diff --git a/test/commonfuzztest/ondatareceivedv2_fuzzer/on_data_received_fuzzer.h b/test/commonfuzztest/ondatareceivedv2_fuzzer/on_data_received_fuzzer.h new file mode 100644 index 000000000..e59b91fda --- /dev/null +++ b/test/commonfuzztest/ondatareceivedv2_fuzzer/on_data_received_fuzzer.h @@ -0,0 +1,21 @@ +/* + * 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 ON_DATA_RECEIVED_FUZZER_H +#define ON_DATA_RECEIVED_FUZZER_H + +#define FUZZ_PROJECT_NAME "ondatareceivedv2_fuzzer" + +#endif // ON_DATA_RECEIVED_FUZZER_H \ No newline at end of file diff --git a/test/commonfuzztest/ondatareceivedv2_fuzzer/project.xml b/test/commonfuzztest/ondatareceivedv2_fuzzer/project.xml new file mode 100644 index 000000000..bac4974e9 --- /dev/null +++ b/test/commonfuzztest/ondatareceivedv2_fuzzer/project.xml @@ -0,0 +1,25 @@ + + + + + + 1000 + + 300 + + 4096 + + \ No newline at end of file diff --git a/test/commonunittest/UTTest_hichain_auth_connector.cpp b/test/commonunittest/UTTest_hichain_auth_connector.cpp index a33d4b17b..7b193c53d 100644 --- a/test/commonunittest/UTTest_hichain_auth_connector.cpp +++ b/test/commonunittest/UTTest_hichain_auth_connector.cpp @@ -80,6 +80,13 @@ public: { (void)deviceId; } + char *AuthDeviceRequest(int64_t requestId, int operationCode, const char *reqParams) override + { + (void)requestId; + (void)operationCode; + (void)reqParams; + return nullptr; + } private: int32_t pinCode = 0; }; diff --git a/test/commonunittest/UTTest_hichain_auth_connector.h b/test/commonunittest/UTTest_hichain_auth_connector.h index 3c708b598..f2a675310 100644 --- a/test/commonunittest/UTTest_hichain_auth_connector.h +++ b/test/commonunittest/UTTest_hichain_auth_connector.h @@ -46,6 +46,7 @@ public: (int64_t requestId, const uint8_t *sessionKey, uint32_t sessionKeyLen), (override)); MOCK_METHOD(void, GetRemoteDeviceId, (std::string &deviceId), (override)); MOCK_METHOD(int32_t, GetPinCode, (int32_t &code), (override)); + MOCK_METHOD(char *, AuthDeviceRequest, (int64_t requestId, int operationCode, const char *reqParams), (override)); }; } // namespace DistributedHardware } // namespace OHOS diff --git a/test/unittest/BUILD.gn b/test/unittest/BUILD.gn index 4a79508f4..62053a286 100644 --- a/test/unittest/BUILD.gn +++ b/test/unittest/BUILD.gn @@ -91,6 +91,9 @@ group("unittest") { ":UTTest_softbus_listener_two", ":UTTest_softbus_publish", ":UTTest_softbus_session", + ":UTTest_auth_credential_state", + ":UTTest_auth_pin_auth_state", + ":UTTest_auth_negotiate_state", ] } @@ -1975,6 +1978,98 @@ ohos_unittest("UTTest_json_object") { ## UnitTest UTTest_json_object }}} +## UnitTest UTTest_auth_credential_state {{{ + +ohos_unittest("UTTest_auth_credential_state") { + module_out_path = module_out_path + + include_dirs = [ + + ] + + sources = [ + "${devicemanager_path}/test/unittest/UTTest_auth_credential_state.cpp", + "${devicemanager_path}/test/unittest/mock/hichain_auth_connector_mock.cpp", + "${devicemanager_path}/test/unittest/mock/softbus_session_mock.cpp", + "${devicemanager_path}/test/unittest/mock/dm_auth_state_machine_mock.cpp" + ] + + deps = [ ":device_manager_test_common" ] + + external_deps = [ + "googletest:gmock", + "googletest:gmock_main", + "hilog:libhilog", + "device_info_manager:distributed_device_profile_common", + "device_info_manager:distributed_device_profile_sdk", + "device_auth:deviceauth_sdk", + "ffrt:libffrt", + ] +} + + +## UnitTest UTTest_auth_credential_state }}} + +## UnitTest UTTest_auth_negotiate_state {{{ + +ohos_unittest("UTTest_auth_negotiate_state") { + module_out_path = module_out_path + + include_dirs = [ + + ] + + sources = [ + "${devicemanager_path}/test/unittest/UTTest_auth_negotiate_state.cpp", + "${devicemanager_path}/test/unittest/mock/softbus_session_mock.cpp", + "${devicemanager_path}/test/unittest/mock/softbus_connector_mock.cpp", + ] + + deps = [ ":device_manager_test_common" ] + + external_deps = [ + "googletest:gmock", + "googletest:gmock_main", + "hilog:libhilog", + "device_info_manager:distributed_device_profile_common", + "device_info_manager:distributed_device_profile_sdk", + "device_auth:deviceauth_sdk", + "ffrt:libffrt", + ] +} + +## UnitTest UTTest_auth_negotiate_state }}} + +## UnitTest UTTest_auth_pin_auth_state {{{ + +ohos_unittest("UTTest_auth_pin_auth_state") { + module_out_path = module_out_path + + include_dirs = [ + + ] + + sources = [ + "${devicemanager_path}/test/unittest/UTTest_auth_pin_auth_state.cpp", + "${devicemanager_path}/test/unittest/mock/hichain_auth_connector_mock.cpp", + "${devicemanager_path}/test/unittest/mock/dm_auth_state_machine_mock.cpp" + ] + + deps = [ ":device_manager_test_common" ] + + external_deps = [ + "googletest:gmock", + "googletest:gmock_main", + "hilog:libhilog", + "device_info_manager:distributed_device_profile_common", + "device_info_manager:distributed_device_profile_sdk", + "device_auth:deviceauth_sdk", + "ffrt:libffrt", + ] +} + +## UnitTest UTTest_auth_pin_auth_state }}} + ## Build device_manager_test_common.a {{{ config("device_manager_test_common_public_config") { include_dirs = [ diff --git a/test/unittest/UTTest_auth_credential_state.cpp b/test/unittest/UTTest_auth_credential_state.cpp new file mode 100644 index 000000000..27a269233 --- /dev/null +++ b/test/unittest/UTTest_auth_credential_state.cpp @@ -0,0 +1,1104 @@ +/* + * Copyright (c) 2025 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 "dm_auth_state.h" +#include "UTTest_auth_credential_state.h" +#include "dm_auth_message_processor_mock.h" +#include "device_manager_service_listener.h" + +using namespace testing; + +namespace OHOS { +namespace DistributedHardware { + +constexpr const char *TEST_NONE_EMPTY_STRING = "test"; + +void AuthCredentialStateTest::SetUpTestCase() +{ + LOGI("AuthCredentialStateTest::SetUpTestCase start."); + DmHiChainAuthConnector::dmHiChainAuthConnector = dmHiChainAuthConnectorMock; + DmSoftbusSession::dmSoftbusSession = dmSoftbusSessionMock; + DmAuthStateMachineMock::dmAuthStateMachineMock = dmAuthStateMachineMock; + DmAuthMessageProcessorMock::dmAuthMessageProcessorMock = std::make_shared(); +} + +void AuthCredentialStateTest::TearDownTestCase() +{ + LOGI("AuthCredentialStateTest::TearDownTestCase start."); + DmHiChainAuthConnector::dmHiChainAuthConnector = nullptr; + dmHiChainAuthConnectorMock = nullptr; + DmSoftbusSession::dmSoftbusSession = nullptr; + dmSoftbusSessionMock = nullptr; + DmAuthStateMachineMock::dmAuthStateMachineMock = nullptr; + dmAuthStateMachineMock = nullptr; + DmAuthMessageProcessorMock::dmAuthMessageProcessorMock = nullptr; +} + +void AuthCredentialStateTest::SetUp() +{ + LOGI("AuthCredentialStateTest::SetUp start."); + softbusConnector = std::make_shared(); + listener = std::make_shared(); + hiChainAuthConnector = std::make_shared(); + authManager = std::make_shared(softbusConnector, listener, + hiChainAuthConnector); + context = authManager->GetAuthContext(); + + // 重置mock对象的期望 + Mock::VerifyAndClearExpectations(&*DmHiChainAuthConnector::dmHiChainAuthConnector); + Mock::VerifyAndClearExpectations(&*DmSoftbusSession::dmSoftbusSession); + Mock::VerifyAndClearExpectations(&*DmAuthStateMachineMock::dmAuthStateMachineMock); + Mock::VerifyAndClearExpectations(&*DmAuthMessageProcessorMock::dmAuthMessageProcessorMock); +} + +void AuthCredentialStateTest::TearDown() +{ + LOGI("AuthCredentialStateTest::TearDown start."); + softbusConnector = nullptr; + listener = nullptr; + hiChainAuthConnector = nullptr; + authManager = nullptr; + context = nullptr; +} + +// AuthSrcCredentialExchangeState 测试用例 +// GetStateType接口 +HWTEST_F(AuthCredentialStateTest, AuthSrcCredentialExchangeState_001, testing::ext::TestSize.Level1) +{ + std::shared_ptr authState = std::make_shared(); + EXPECT_EQ(authState->GetStateType(), DmAuthStateType::AUTH_SRC_CREDENTIAL_EXCHANGE_STATE); +} + +// AuthSrcCredentialExchangeState 测试用例 +// Action接口 +// 正常流程 期待成功 +// 打桩 AddCredential 期待成功 +// 打桩 ExportCredential 期待成功 +// 打桩 SendData 期待成功 +HWTEST_F(AuthCredentialStateTest, AuthSrcCredentialExchangeState_002, testing::ext::TestSize.Level1) +{ + std::shared_ptr authState = std::make_shared(); + + // 打桩 AddCredential 期待成功 + EXPECT_CALL(*dmHiChainAuthConnectorMock, AddCredential(_, _, _)).WillRepeatedly(Return(DM_OK)); + + // 打桩 ExportCredential 期待成功 + EXPECT_CALL(*dmHiChainAuthConnectorMock, ExportCredential(_, _, _)).WillRepeatedly(Return(DM_OK)); + + // 打桩 SendData 期待成功 + EXPECT_CALL(*dmSoftbusSessionMock, SendData(_, _)).WillOnce(Return(DM_OK)); + + EXPECT_EQ(authState->Action(context), DM_OK); +} + +// AuthSrcCredentialExchangeState 测试用例 +// Action接口 第一次添加凭据失败,期待ERR_DM_FAILED +// 打桩 AddCredential 第一次失败,第二次成功 +HWTEST_F(AuthCredentialStateTest, AuthSrcCredentialExchangeState_003, testing::ext::TestSize.Level1) +{ + std::shared_ptr authState = std::make_shared(); + + // 打桩 AddCredential 第一次失败,第二次成功 + EXPECT_CALL(*dmHiChainAuthConnectorMock, AddCredential(_, _, _)) + .WillOnce(Return(ERR_DM_FAILED)) + .WillOnce(Return(DM_OK)); + + EXPECT_EQ(authState->Action(context), ERR_DM_FAILED); +} + +// AuthSrcCredentialExchangeState 测试用例 +// Action接口 第一次导出公钥失败,期待ERR_DM_FAILED +// 打桩 AddCredential 第一次成功,第二次成功 +// 打桩 ExportCredential 第一次失败,第二次成功 +HWTEST_F(AuthCredentialStateTest, AuthSrcCredentialExchangeState_004, testing::ext::TestSize.Level1) +{ + std::shared_ptr authState = std::make_shared(); + + // 打桩 AddCredential 第一次成功,第二次成功 + EXPECT_CALL(*dmHiChainAuthConnectorMock, AddCredential(_, _, _)) + .WillOnce(Return(DM_OK)) + .WillOnce(Return(DM_OK)); + + // 打桩 ExportCredential 第一次失败,第二次成功 + EXPECT_CALL(*dmHiChainAuthConnectorMock, ExportCredential(_, _, _)) + .WillOnce(Return(ERR_DM_FAILED)) + .WillOnce(Return(DM_OK)); + + EXPECT_EQ(authState->Action(context), ERR_DM_FAILED); +} + +// AuthSrcCredentialExchangeState 测试用例 +// Action接口 第二次添加凭据失败,期待ERR_DM_FAILED +// 打桩 AddCredential 第一次成功,第二次失败 +HWTEST_F(AuthCredentialStateTest, AuthSrcCredentialExchangeState_005, testing::ext::TestSize.Level1) +{ + std::shared_ptr authState = std::make_shared(); + + // 打桩 AddCredential 第一次成功,第二次失败 + EXPECT_CALL(*dmHiChainAuthConnectorMock, AddCredential(_, _, _)) + .WillOnce(Return(DM_OK)) + .WillOnce(Return(ERR_DM_FAILED)); + + EXPECT_EQ(authState->Action(context), ERR_DM_FAILED); +} + +// AuthSrcCredentialExchangeState 测试用例 +// Action接口 第二次导出公钥失败,期待ERR_DM_FAILED +// 打桩 AddCredential 第一次成功,第二次成功 +// 打桩 ExportCredential 第一次成功,第二次失败 +HWTEST_F(AuthCredentialStateTest, AuthSrcCredentialExchangeState_006, testing::ext::TestSize.Level1) +{ + std::shared_ptr authState = std::make_shared(); + + // 打桩 AddCredential 第一次成功,第二次成功 + EXPECT_CALL(*dmHiChainAuthConnectorMock, AddCredential(_, _, _)) + .WillOnce(Return(DM_OK)) + .WillOnce(Return(DM_OK)); + + // 打桩 ExportCredential 第一次成功,第二次失败 + EXPECT_CALL(*dmHiChainAuthConnectorMock, ExportCredential(_, _, _)) + .WillOnce(Return(DM_OK)) + .WillOnce(Return(ERR_DM_FAILED)); + + EXPECT_EQ(authState->Action(context), ERR_DM_FAILED); +} + +// AuthSrcCredentialExchangeState 测试用例 +// Action接口 发送数据失败 期待ERR_DM_FAILED +// 打桩 AddCredential 第一次成功,第二次成功 +// 打桩 ExportCredential 第一次成功,第二次成功 +// 打桩 SendData 期待失败 +HWTEST_F(AuthCredentialStateTest, AuthSrcCredentialExchangeState_007, testing::ext::TestSize.Level1) +{ + std::shared_ptr authState = std::make_shared(); + + // 打桩 AddCredential 第一次成功,第二次成功 + EXPECT_CALL(*dmHiChainAuthConnectorMock, AddCredential(_, _, _)) + .WillOnce(Return(DM_OK)) + .WillOnce(Return(DM_OK)); + + // 打桩 ExportCredential 第一次成功,第二次成功 + EXPECT_CALL(*dmHiChainAuthConnectorMock, ExportCredential(_, _, _)) + .WillOnce(Return(DM_OK)) + .WillOnce(Return(DM_OK)); + + // 打桩 SendData 期待失败 + EXPECT_CALL(*dmSoftbusSessionMock, SendData(_, _)).WillOnce(Return(ERR_DM_FAILED)); + + EXPECT_EQ(authState->Action(context), ERR_DM_FAILED); +} + +// AuthSinkCredentialExchangeState 测试用例 +// GetStateType接口 +HWTEST_F(AuthCredentialStateTest, AuthSinkCredentialExchangeState_001, testing::ext::TestSize.Level1) +{ + std::shared_ptr authState = std::make_shared(); + EXPECT_EQ(authState->GetStateType(), DmAuthStateType::AUTH_SINK_CREDENTIAL_EXCHANGE_STATE); +} + + +// AuthSinkCredentialExchangeState 测试用例 +// Action接口 正常流程 期待成功 +// 打桩 AddCredential 期待成功 +// 打桩 ExportCredential 期待成功 +// 打桩 AgreeCredential 期待成功 +// 打桩 SendData 期待成功 +HWTEST_F(AuthCredentialStateTest, AuthSinkCredentialExchangeState_002, testing::ext::TestSize.Level1) +{ + std::shared_ptr authState = std::make_shared(); + + // 打桩 AddCredential 第一次成功,第二次成功 + EXPECT_CALL(*dmHiChainAuthConnectorMock, AddCredential(_, _, _)) + .WillOnce(Return(DM_OK)) + .WillOnce(Return(DM_OK)); + + // 打桩 ExportCredential 第一次成功,第二次成功 + EXPECT_CALL(*dmHiChainAuthConnectorMock, ExportCredential(_, _, _)) + .WillOnce(Return(DM_OK)) + .WillOnce(Return(DM_OK)); + + // 打桩 AgreeCredential 第一次成功,第二次成功 + EXPECT_CALL(*dmHiChainAuthConnectorMock, AgreeCredential(_, _, _, _)) + .WillOnce(Return(DM_OK)) + .WillOnce(Return(DM_OK)); + + // 打桩 SendData 期待成功 + EXPECT_CALL(*dmSoftbusSessionMock, SendData(_, _)).WillOnce(Return(DM_OK)); + + EXPECT_EQ(authState->Action(context), DM_OK); +} + +// AuthSinkCredentialExchangeState 测试用例 +// Action接口 第一次生成凭据失败,期待ERR_DM_FAILED +// 打桩 AddCredential 第一次失败,第二次成功 +HWTEST_F(AuthCredentialStateTest, AuthSinkCredentialExchangeState_003, testing::ext::TestSize.Level1) +{ + std::shared_ptr authState = std::make_shared(); + + // 打桩 AddCredential 第一次成功,第二次成功 + EXPECT_CALL(*dmHiChainAuthConnectorMock, AddCredential(_, _, _)) + .WillOnce(Return(ERR_DM_FAILED)) + .WillOnce(Return(DM_OK)); + + EXPECT_EQ(authState->Action(context), ERR_DM_FAILED); +} + +// AuthSinkCredentialExchangeState 测试用例 +// Action接口 第二次生成凭据失败,期待ERR_DM_FAILED +// 打桩 AddCredential 第一次成功,第二次失败 +// 打桩 ExportCredential 第一次成功,第二次成功 +// 打桩 AgreeCredential 第一次成功,第二次成功 +// 打桩 SendData 期待成功 +HWTEST_F(AuthCredentialStateTest, AuthSinkCredentialExchangeState_004, testing::ext::TestSize.Level1) +{ + std::shared_ptr authState = std::make_shared(); + + // 打桩 AddCredential 第一次成功,第二次失败 + EXPECT_CALL(*dmHiChainAuthConnectorMock, AddCredential(_, _, _)) + .WillOnce(Return(DM_OK)) + .WillOnce(Return(ERR_DM_FAILED)); + + EXPECT_EQ(authState->Action(context), ERR_DM_FAILED); +} + +// AuthSinkCredentialExchangeState 测试用例 +// Action接口 第一次导出公钥失败,期待ERR_DM_FAILED +// 打桩 AddCredential 第一次成功,第二次成功 +// 打桩 ExportCredential 第一次失败,第二次成功 +HWTEST_F(AuthCredentialStateTest, AuthSinkCredentialExchangeState_005, testing::ext::TestSize.Level1) +{ + std::shared_ptr authState = std::make_shared(); + + // 打桩 AddCredential 第一次成功,第二次成功 + EXPECT_CALL(*dmHiChainAuthConnectorMock, AddCredential(_, _, _)) + .WillOnce(Return(DM_OK)) + .WillOnce(Return(DM_OK)); + + // 打桩 ExportCredential 第一次失败,第二次成功 + EXPECT_CALL(*dmHiChainAuthConnectorMock, ExportCredential(_, _, _)) + .WillOnce(Return(ERR_DM_FAILED)) + .WillOnce(Return(DM_OK)); + + EXPECT_EQ(authState->Action(context), ERR_DM_FAILED); +} + +// AuthSinkCredentialExchangeState 测试用例 +// Action接口 第二次导出公钥失败,期待ERR_DM_FAILED +// 打桩 AddCredential 第一次成功,第二次成功 +// 打桩 ExportCredential 第一次成功,第二次失败 +HWTEST_F(AuthCredentialStateTest, AuthSinkCredentialExchangeState_006, testing::ext::TestSize.Level1) +{ + std::shared_ptr authState = std::make_shared(); + + // 打桩 AddCredential 第一次成功,第二次成功 + EXPECT_CALL(*dmHiChainAuthConnectorMock, AddCredential(_, _, _)) + .WillOnce(Return(DM_OK)) + .WillOnce(Return(DM_OK)); + + // 打桩 ExportCredential 第一次成功,第二次失败 + EXPECT_CALL(*dmHiChainAuthConnectorMock, ExportCredential(_, _, _)) + .WillOnce(Return(DM_OK)) + .WillOnce(Return(ERR_DM_FAILED)); + + EXPECT_EQ(authState->Action(context), ERR_DM_FAILED); +} + +// AuthSinkCredentialExchangeState 测试用例 +// Action接口 第一次协商凭据失败,期待ERR_DM_FAILED +// 打桩 AddCredential 第一次成功,第二次成功 +// 打桩 ExportCredential 第一次成功,第二次成功 +// 打桩 AgreeCredential 第一次失败,第二次成功 +HWTEST_F(AuthCredentialStateTest, AuthSinkCredentialExchangeState_007, testing::ext::TestSize.Level1) +{ + std::shared_ptr authState = std::make_shared(); + + // 打桩 AddCredential 第一次成功,第二次成功 + EXPECT_CALL(*dmHiChainAuthConnectorMock, AddCredential(_, _, _)) + .WillOnce(Return(DM_OK)) + .WillOnce(Return(DM_OK)); + + // 打桩 ExportCredential 第一次成功,第二次成功 + EXPECT_CALL(*dmHiChainAuthConnectorMock, ExportCredential(_, _, _)) + .WillOnce(Return(DM_OK)) + .WillOnce(Return(DM_OK)); + + // 打桩 AgreeCredential 第一次失败,第二次成功 + EXPECT_CALL(*dmHiChainAuthConnectorMock, AgreeCredential(_, _, _, _)) + .WillOnce(Return(ERR_DM_FAILED)) + .WillOnce(Return(DM_OK)); + + EXPECT_EQ(authState->Action(context), ERR_DM_FAILED); +} + +// AuthSinkCredentialExchangeState 测试用例 +// Action接口 第二次协商凭据失败,期待ERR_DM_FAILED +// 打桩 AddCredential 第一次成功,第二次成功 +// 打桩 ExportCredential 第一次成功,第二次成功 +// 打桩 AgreeCredential 第一次成功,第二次失败 +HWTEST_F(AuthCredentialStateTest, AuthSinkCredentialExchangeState_008, testing::ext::TestSize.Level1) +{ + std::shared_ptr authState = std::make_shared(); + + // 打桩 AddCredential 第一次成功,第二次成功 + EXPECT_CALL(*dmHiChainAuthConnectorMock, AddCredential(_, _, _)) + .WillOnce(Return(DM_OK)) + .WillOnce(Return(DM_OK)); + + // 打桩 ExportCredential 第一次成功,第二次成功 + EXPECT_CALL(*dmHiChainAuthConnectorMock, ExportCredential(_, _, _)) + .WillOnce(Return(DM_OK)) + .WillOnce(Return(DM_OK)); + + // 打桩 AgreeCredential 第一次成功,第二次失败 + EXPECT_CALL(*dmHiChainAuthConnectorMock, AgreeCredential(_, _, _, _)) + .WillOnce(Return(DM_OK)) + .WillOnce(Return(ERR_DM_FAILED)); + + EXPECT_EQ(authState->Action(context), ERR_DM_FAILED); +} + +// AuthSinkCredentialExchangeState 测试用例 +// Action接口 第二次协商凭据失败,期待ERR_DM_FAILED +// 打桩 AddCredential 第一次成功,第二次成功 +// 打桩 ExportCredential 第一次成功,第二次成功 +// 打桩 AgreeCredential 第一次成功,第二次成功 +// 打桩 SendData 期待失败 +HWTEST_F(AuthCredentialStateTest, AuthSinkCredentialExchangeState_009, testing::ext::TestSize.Level1) +{ + std::shared_ptr authState = std::make_shared(); + + // 打桩 AddCredential 第一次成功,第二次成功 + EXPECT_CALL(*dmHiChainAuthConnectorMock, AddCredential(_, _, _)) + .WillOnce(Return(DM_OK)) + .WillOnce(Return(DM_OK)); + + // 打桩 ExportCredential 第一次成功,第二次成功 + EXPECT_CALL(*dmHiChainAuthConnectorMock, ExportCredential(_, _, _)) + .WillOnce(Return(DM_OK)) + .WillOnce(Return(DM_OK)); + + // 打桩 AgreeCredential 第一次成功,第二次成功 + EXPECT_CALL(*dmHiChainAuthConnectorMock, AgreeCredential(_, _, _, _)) + .WillOnce(Return(DM_OK)) + .WillOnce(Return(DM_OK)); + + // 打桩 SendData 期待失败 + EXPECT_CALL(*dmSoftbusSessionMock, SendData(_, _)).WillOnce(Return(ERR_DM_FAILED)); + + EXPECT_EQ(authState->Action(context), ERR_DM_FAILED); +} + +// AuthSrcCredentialAuthStartState 测试用例 +// GetStateType接口 +HWTEST_F(AuthCredentialStateTest, AuthSrcCredentialAuthStartState_001, testing::ext::TestSize.Level1) +{ + std::shared_ptr authState = std::make_shared(); + EXPECT_EQ(authState->GetStateType(), DmAuthStateType::AUTH_SRC_CREDENTIAL_AUTH_START_STATE); +} + +// AuthSrcCredentialAuthStartState 测试用例 +// Action接口 正常流程 期待成功 +// 打桩 AgreeCredential 第一次成功,第二次成功 +// 打桩 AuthCredential 期待成功 +// 打桩 WaitExpectEvent 接口 期待成功 +// 打桩 SendData 期待成功 +HWTEST_F(AuthCredentialStateTest, AuthSrcCredentialAuthStartState_002, testing::ext::TestSize.Level1) +{ + std::shared_ptr authState = std::make_shared(); + + // 打桩 AgreeCredential 第一次成功,第二次成功 + EXPECT_CALL(*dmHiChainAuthConnectorMock, AgreeCredential(_, _, _, _)) + .WillOnce(Return(DM_OK)) + .WillOnce(Return(DM_OK)); + + // 打桩 AuthCredential 第一次成功 + EXPECT_CALL(*dmHiChainAuthConnectorMock, AuthCredential(_, _, _, _)).WillOnce(Return(DM_OK)); + + // 打桩 WaitExpectEvent 期待ON_TRANSMIT + EXPECT_CALL(*DmAuthStateMachineMock::dmAuthStateMachineMock, WaitExpectEvent(_)).WillOnce(Return(ON_TRANSMIT)); + + // 打桩 SendData 期待成功 + EXPECT_CALL(*dmSoftbusSessionMock, SendData(_, _)).WillOnce(Return(DM_OK)); + + EXPECT_EQ(authState->Action(context), DM_OK); +} + +// AuthSrcCredentialAuthStartState 测试用例 +// Action接口 第一次协商凭据失败,期待ERR_DM_FAILED +// 打桩 AgreeCredential 第一次失败 +HWTEST_F(AuthCredentialStateTest, AuthSrcCredentialAuthStartState_003, testing::ext::TestSize.Level1) +{ + std::shared_ptr authState = std::make_shared(); + + // 打桩 AgreeCredential 第一次失败 + EXPECT_CALL(*dmHiChainAuthConnectorMock, AgreeCredential(_, _, _, _)) + .WillOnce(Return(ERR_DM_FAILED)); + + EXPECT_EQ(authState->Action(context), ERR_DM_FAILED); +} + +// AuthSrcCredentialAuthStartState 测试用例 +// Action接口 第二次协商凭据失败,期待ERR_DM_FAILED +// 打桩 AgreeCredential 第一次成功,第二次失败 +HWTEST_F(AuthCredentialStateTest, AuthSrcCredentialAuthStartState_005, testing::ext::TestSize.Level1) +{ + std::shared_ptr authState = std::make_shared(); + + // 打桩 AgreeCredential 第一次成功,第二次失败 + EXPECT_CALL(*dmHiChainAuthConnectorMock, AgreeCredential(_, _, _, _)) + .WillOnce(Return(DM_OK)) + .WillOnce(Return(ERR_DM_FAILED)); + + EXPECT_EQ(authState->Action(context), ERR_DM_FAILED); +} + +// AuthSrcCredentialAuthStartState 测试用例 +// Action接口 凭据认证失败,期待ERR_DM_FAILED +// 打桩 AgreeCredential 第一次成功,第二次成功 +// 打桩 AuthCredential 期待失败 +HWTEST_F(AuthCredentialStateTest, AuthSrcCredentialAuthStartState_006, testing::ext::TestSize.Level1) +{ + std::shared_ptr authState = std::make_shared(); + + // 打桩 AgreeCredential 第一次成功,第二次成功 + EXPECT_CALL(*dmHiChainAuthConnectorMock, AgreeCredential(_, _, _, _)) + .WillOnce(Return(DM_OK)) + .WillOnce(Return(DM_OK)); + + // 打桩 AuthCredential 期待失败 + EXPECT_CALL(*dmHiChainAuthConnectorMock, AuthCredential(_, _, _, _)).WillOnce(Return(ERR_DM_FAILED)); + + EXPECT_EQ(authState->Action(context), DM_OK); +} + +// AuthSrcCredentialAuthStartState 测试用例 +// Action接口 WaitExpectEvent接口返回其它事件,期待ERR_DM_FAILED +// 打桩 AgreeCredential 第一次成功,第二次成功 +// 打桩 AuthCredential 期待成功 +// 打桩 WaitExpectEvent接口 其它事件 返回ON_FINISH +HWTEST_F(AuthCredentialStateTest, AuthSrcCredentialAuthStartState_007, testing::ext::TestSize.Level1) +{ + std::shared_ptr authState = std::make_shared(); + + // 打桩 AgreeCredential 第一次成功,第二次成功 + EXPECT_CALL(*dmHiChainAuthConnectorMock, AgreeCredential(_, _, _, _)) + .WillOnce(Return(DM_OK)) + .WillOnce(Return(DM_OK)); + + // 打桩 AuthCredential 期待成功 + EXPECT_CALL(*dmHiChainAuthConnectorMock, AuthCredential(_, _, _, _)).WillOnce(Return(DM_OK)); + + // 打桩 WaitExpectEvent 返回非ON_TRANSMIT,返回ON_FINISH + EXPECT_CALL(*DmAuthStateMachineMock::dmAuthStateMachineMock, WaitExpectEvent(_)).WillOnce(Return(ON_FINISH)); + + EXPECT_EQ(authState->Action(context), ERR_DM_FAILED); +} + +// AuthSrcCredentialAuthStartState 测试用例 +// Action接口 发送数据失败 期待ERR_DM_FAILED +// 打桩 AgreeCredential 第一次成功,第二次成功 +// 打桩 AuthCredential 期待成功 +// 打桩 WaitExpectEvent接口 期待成功 +// 打桩 SendData 期待失败 +HWTEST_F(AuthCredentialStateTest, AuthSrcCredentialAuthStartState_008, testing::ext::TestSize.Level1) +{ + std::shared_ptr authState = std::make_shared(); + + // 打桩 AgreeCredential 第一次成功,第二次成功 + EXPECT_CALL(*dmHiChainAuthConnectorMock, AgreeCredential(_, _, _, _)) + .WillOnce(Return(DM_OK)) + .WillOnce(Return(DM_OK)); + + // 打桩 AuthCredential 第一次成功 + EXPECT_CALL(*dmHiChainAuthConnectorMock, AuthCredential(_, _, _, _)).WillOnce(Return(DM_OK)); + + // 打桩 WaitExpectEvent 期待ON_TRANSMIT + EXPECT_CALL(*DmAuthStateMachineMock::dmAuthStateMachineMock, WaitExpectEvent(_)).WillOnce(Return(ON_TRANSMIT)); + + // 打桩 SendData 期待失败 + EXPECT_CALL(*dmSoftbusSessionMock, SendData(_, _)).WillOnce(Return(ERR_DM_FAILED)); + + EXPECT_EQ(authState->Action(context), ERR_DM_FAILED); +} + +// AuthSinkCredentialAuthStartState 测试用例 +// GetStateType 接口 +HWTEST_F(AuthCredentialStateTest, AuthSinkCredentialAuthStartState_001, testing::ext::TestSize.Level1) +{ + std::shared_ptr authState = std::make_shared(); + EXPECT_EQ(authState->GetStateType(), DmAuthStateType::AUTH_SINK_CREDENTIAL_AUTH_START_STATE); +} + +// AuthSinkCredentialAuthStartState 测试用例 +// Action 接口 正常流程 期待返回DM_OK +// 打桩 ProcessCredData 期待返回DM_OK +// 打桩 WaitExpectEvent 期待返回ON_TRANSMIT +// 打桩 SendData 期待返回DM_OK +HWTEST_F(AuthCredentialStateTest, AuthSinkCredentialAuthStartState_002, testing::ext::TestSize.Level1) +{ + std::shared_ptr authState = std::make_shared(); + + // 打桩 ProcessCredData 期待返回DM_OK + EXPECT_CALL(*dmHiChainAuthConnectorMock, ProcessCredData(_, _)).WillOnce(Return(DM_OK)); + + // 打桩 WaitExpectEvent 期待返回ON_TRANSMIT + EXPECT_CALL(*dmAuthStateMachineMock, WaitExpectEvent(_)).WillOnce(Return(ON_TRANSMIT)); + + // 打桩 SendData 期待返回DM_OK + EXPECT_CALL(*dmSoftbusSessionMock, SendData(_, _)).WillOnce(Return(DM_OK)); + + EXPECT_EQ(authState->Action(context), DM_OK); +} + +// AuthSinkCredentialAuthStartState 测试用例 +// Action 接口 ProcessCredData 失败 期待返回 ERR_DM_FAILED +// 打桩 ProcessCredData 期待返回 ERR_DM_FAILED +HWTEST_F(AuthCredentialStateTest, AuthSinkCredentialAuthStartState_003, testing::ext::TestSize.Level1) +{ + std::shared_ptr authState = std::make_shared(); + + // 打桩 ProcessCredData 期待返回 ERR_DM_FAILED + EXPECT_CALL(*dmHiChainAuthConnectorMock, ProcessCredData(_, _)).WillOnce(Return(ERR_DM_FAILED)); + + EXPECT_EQ(authState->Action(context), ERR_DM_FAILED); +} + +// AuthSinkCredentialAuthStartState 测试用例 +// Action 接口 WaitExpectEvent发生其它事件 期待返回 ERR_DM_FAILED +// 打桩 ProcessCredData 期待返回DM_OK +// 打桩 WaitExpectEvent 期待返回非ON_TRANSMIT +HWTEST_F(AuthCredentialStateTest, AuthSinkCredentialAuthStartState_004, testing::ext::TestSize.Level1) +{ + std::shared_ptr authState = std::make_shared(); + + // 打桩 ProcessCredData 期待返回DM_OK + EXPECT_CALL(*dmHiChainAuthConnectorMock, ProcessCredData(_, _)).WillOnce(Return(DM_OK)); + + // 打桩 WaitExpectEvent 期待返回非ON_TRANSMIT,返回ON_ERROR + EXPECT_CALL(*dmAuthStateMachineMock, WaitExpectEvent(_)).WillOnce(Return(ON_ERROR)); + + EXPECT_EQ(authState->Action(context), ERR_DM_FAILED); +} + +// AuthSinkCredentialAuthStartState 测试用例 +// Action 接口 SendData发送数据失败 期待返回ERR_DM_FAILED +// 打桩 ProcessCredData 期待返回DM_OK +// 打桩 WaitExpectEvent 期待返回ON_TRANSMIT +// 打桩 SendData 期待返回ERR_DM_FAILED +HWTEST_F(AuthCredentialStateTest, AuthSinkCredentialAuthStartState_005, testing::ext::TestSize.Level1) +{ + std::shared_ptr authState = std::make_shared(); + + // 打桩 ProcessCredData 期待返回DM_OK + EXPECT_CALL(*dmHiChainAuthConnectorMock, ProcessCredData(_, _)).WillOnce(Return(DM_OK)); + + // 打桩 WaitExpectEvent 期待返回ON_TRANSMIT + EXPECT_CALL(*dmAuthStateMachineMock, WaitExpectEvent(_)).WillOnce(Return(ON_TRANSMIT)); + + // 打桩 SendData 期待返回ERR_DM_FAILED + EXPECT_CALL(*dmSoftbusSessionMock, SendData(_, _)).WillOnce(Return(ERR_DM_FAILED)); + + EXPECT_EQ(authState->Action(context), ERR_DM_FAILED); +} + +// AuthSrcCredentialAuthNegotiateState 测试用例 +// GetStateType 接口 +HWTEST_F(AuthCredentialStateTest, AuthSrcCredentialAuthNegotiateState_001, testing::ext::TestSize.Level1) +{ + std::shared_ptr authState = std::make_shared(); + EXPECT_EQ(authState->GetStateType(), DmAuthStateType::AUTH_SRC_CREDENTIAL_AUTH_NEGOTIATE_STATE); +} + +// AuthSrcCredentialAuthNegotiateState 测试用例 +// Action 接口 正常流程 期待返回DM_OK +// 打桩 ProcessCredData 期待返回DM_OK +// 打桩 WaitExpectEvent 期待返回ON_TRANSMIT +// 打桩 SendData 期待返回DM_OK +HWTEST_F(AuthCredentialStateTest, AuthSrcCredentialAuthNegotiateState_002, testing::ext::TestSize.Level1) +{ + std::shared_ptr authState = std::make_shared(); + + // 打桩 ProcessCredData 期待返回DM_OK + EXPECT_CALL(*dmHiChainAuthConnectorMock, ProcessCredData(_, _)).WillOnce(Return(DM_OK)); + + // 打桩 WaitExpectEvent 期待返回ON_TRANSMIT + EXPECT_CALL(*dmAuthStateMachineMock, WaitExpectEvent(_)).WillOnce(Return(ON_TRANSMIT)); + + // 打桩 SendData 期待返回DM_OK + EXPECT_CALL(*dmSoftbusSessionMock, SendData(_, _)).WillOnce(Return(DM_OK)); + + EXPECT_EQ(authState->Action(context), DM_OK); +} + +// AuthSrcCredentialAuthNegotiateState 测试用例 +// Action 接口 ProcessCredData失败 期待返回ERR_DM_FAILED +// 打桩 ProcessCredData 期待返回ERR_DM_FAILED +HWTEST_F(AuthCredentialStateTest, AuthSrcCredentialAuthNegotiateState_003, testing::ext::TestSize.Level1) +{ + std::shared_ptr authState = std::make_shared(); + + // 打桩 ProcessCredData 期待返回ERR_DM_FAILED + EXPECT_CALL(*dmHiChainAuthConnectorMock, ProcessCredData(_, _)).WillOnce(Return(ERR_DM_FAILED)); + + EXPECT_EQ(authState->Action(context), ERR_DM_FAILED); +} + +// AuthSrcCredentialAuthNegotiateState 测试用例 +// Action 接口 WaitExpectEvent返回其它事件 期待返回ERR_DM_FAILED +// 打桩 ProcessCredData 期待返回DM_OK +// 打桩 WaitExpectEvent 期待返回非ON_TRANSMIT +HWTEST_F(AuthCredentialStateTest, AuthSrcCredentialAuthNegotiateState_004, testing::ext::TestSize.Level1) +{ + std::shared_ptr authState = std::make_shared(); + + // 打桩 ProcessCredData 期待返回DM_OK + EXPECT_CALL(*dmHiChainAuthConnectorMock, ProcessCredData(_, _)).WillOnce(Return(DM_OK)); + + // 打桩 WaitExpectEvent 期待返回非ON_TRANSMIT + EXPECT_CALL(*dmAuthStateMachineMock, WaitExpectEvent(_)).WillOnce(Return(ON_ERROR)); + + EXPECT_EQ(authState->Action(context), ERR_DM_FAILED); +} + +// AuthSrcCredentialAuthNegotiateState 测试用例 +// Action 接口 SendData发送数失败 期待返回ERR_DM_FAILED +// 打桩 ProcessCredData 期待返回DM_OK +// 打桩 WaitExpectEvent 期待返回ON_TRANSMIT +// 打桩 SendData 期待返回ERR_DM_FAILED +HWTEST_F(AuthCredentialStateTest, AuthSrcCredentialAuthNegotiateState_005, testing::ext::TestSize.Level1) +{ + std::shared_ptr authState = std::make_shared(); + + // 打桩 ProcessCredData 期待返回DM_OK + EXPECT_CALL(*dmHiChainAuthConnectorMock, ProcessCredData(_, _)).WillOnce(Return(DM_OK)); + + // 打桩 WaitExpectEvent 期待返回ON_TRANSMIT + EXPECT_CALL(*dmAuthStateMachineMock, WaitExpectEvent(_)).WillOnce(Return(ON_TRANSMIT)); + + // 打桩 SendData 期待返回ERR_DM_FAILED + EXPECT_CALL(*dmSoftbusSessionMock, SendData(_, _)).WillOnce(Return(ERR_DM_FAILED)); + + EXPECT_EQ(authState->Action(context), ERR_DM_FAILED); +} + +// AuthSinkCredentialAuthNegotiateState 测试用例 +// GetStateType 接口 +HWTEST_F(AuthCredentialStateTest, AuthSinkCredentialAuthNegotiateState_001, testing::ext::TestSize.Level1) +{ + std::shared_ptr authState = std::make_shared(); + EXPECT_EQ(authState->GetStateType(), DmAuthStateType::AUTH_SINK_CREDENTIAL_AUTH_NEGOTIATE_STATE); +} + +// AuthSinkCredentialAuthNegotiateState 测试用例 +// Action 正常流程 期待返回DM_OK +// 打桩 ProcessCredData 期待返回DM_OK +// 打桩 WaitExpectEvent 第一次返回ON_TRANSMIT 第二次返回ON_SESSION_KEY_RETURNED 第三次返回ON_FINISH +// 打桩 SaveSessionKeyToDP 期待返回DM_OK +// 打桩 SendData 期待返回DM_OK +HWTEST_F(AuthCredentialStateTest, AuthSinkCredentialAuthNegotiateState_002, testing::ext::TestSize.Level1) +{ + std::shared_ptr authState = std::make_shared(); + + // 打桩 ProcessCredData 期待返回DM_OK + EXPECT_CALL(*dmHiChainAuthConnectorMock, ProcessCredData(_, _)).WillOnce(Return(DM_OK)); + + // 打桩 WaitExpectEvent 第一次返回ON_TRANSMIT 第二次返回ON_SESSION_KEY_RETURNED 第三次返回ON_FINISH + EXPECT_CALL(*dmAuthStateMachineMock, WaitExpectEvent(_)) + .WillOnce(Return(ON_TRANSMIT)) + .WillOnce(Return(ON_SESSION_KEY_RETURNED)) + .WillOnce(Return(ON_FINISH)); + + // 打桩 SaveSessionKeyToDP 期待返回DM_OK + EXPECT_CALL(*DmAuthMessageProcessorMock::dmAuthMessageProcessorMock, SaveSessionKeyToDP(_)) + .WillOnce(Return(DM_OK)); + + // 打桩 SendData 期待返回DM_OK + EXPECT_CALL(*dmSoftbusSessionMock, SendData(_, _)).WillOnce(Return(DM_OK)); + + EXPECT_EQ(authState->Action(context), DM_OK); +} + +// AuthSinkCredentialAuthNegotiateState 测试用例 +// Action ProcessCredData失败 期待返回ERR_DM_FAILED +// 打桩 ProcessCredData 期待返回ERR_DM_FAILED +HWTEST_F(AuthCredentialStateTest, AuthSinkCredentialAuthNegotiateState_003, testing::ext::TestSize.Level1) +{ + std::shared_ptr authState = std::make_shared(); + + // 打桩 ProcessCredData 期待返回ERR_DM_FAILED + EXPECT_CALL(*dmHiChainAuthConnectorMock, ProcessCredData(_, _)).WillOnce(Return(ERR_DM_FAILED)); + + EXPECT_EQ(authState->Action(context), ERR_DM_FAILED); +} + +// AuthSinkCredentialAuthNegotiateState 测试用例 +// Action 第一次WaitExpectEvent返回其它事件 期待返回ERR_DM_FAILED +// 打桩 ProcessCredData 期待返回DM_OK +// 打桩 WaitExpectEvent 第一次返回非ON_TRANSMIT +HWTEST_F(AuthCredentialStateTest, AuthSinkCredentialAuthNegotiateState_004, testing::ext::TestSize.Level1) +{ + std::shared_ptr authState = std::make_shared(); + + // 打桩 ProcessCredData 期待返回DM_OK + EXPECT_CALL(*dmHiChainAuthConnectorMock, ProcessCredData(_, _)).WillOnce(Return(DM_OK)); + + // 打桩 WaitExpectEvent 第一次返回非ON_TRANSMIT + EXPECT_CALL(*dmAuthStateMachineMock, WaitExpectEvent(_)) + .WillOnce(Return(ON_ERROR)); + + EXPECT_EQ(authState->Action(context), ERR_DM_FAILED); +} + +// AuthSinkCredentialAuthNegotiateState 测试用例 +// Action WaitExpectEvent第二次返回其它事件 期待返回ERR_DM_FAILED +// 打桩 ProcessCredData 期待返回DM_OK +// 打桩 WaitExpectEvent 第一次返回ON_TRANSMIT 第二次返回非ON_SESSION_KEY_RETURNED +// 打桩 SaveSessionKeyToDP 期待返回DM_OK +// 打桩 SendData 期待返回DM_OK +HWTEST_F(AuthCredentialStateTest, AuthSinkCredentialAuthNegotiateState_005, testing::ext::TestSize.Level1) +{ + std::shared_ptr authState = std::make_shared(); + + // 打桩 ProcessCredData 期待返回DM_OK + EXPECT_CALL(*dmHiChainAuthConnectorMock, ProcessCredData(_, _)).WillOnce(Return(DM_OK)); + + // 打桩 WaitExpectEvent 第一次返回ON_TRANSMIT 第二次返回非ON_SESSION_KEY_RETURNED + EXPECT_CALL(*dmAuthStateMachineMock, WaitExpectEvent(_)) + .WillOnce(Return(ON_TRANSMIT)) + .WillOnce(Return(ON_ERROR)); + + EXPECT_EQ(authState->Action(context), ERR_DM_FAILED); +} + +// AuthSinkCredentialAuthNegotiateState 测试用例 +// Action WaitExpectEvent第三次返回其它事件 期待返回ERR_DM_FAILED +// 打桩 ProcessCredData 期待返回DM_OK +// 打桩 WaitExpectEvent 第一次返回ON_TRANSMIT 第二次返回ON_SESSION_KEY_RETURNED 第三次返回非ON_FINISH +HWTEST_F(AuthCredentialStateTest, AuthSinkCredentialAuthNegotiateState_006, testing::ext::TestSize.Level1) +{ + std::shared_ptr authState = std::make_shared(); + + // 打桩 ProcessCredData 期待返回DM_OK + EXPECT_CALL(*dmHiChainAuthConnectorMock, ProcessCredData(_, _)).WillOnce(Return(DM_OK)); + + // 打桩 WaitExpectEvent 第一次返回ON_TRANSMIT 第二次返回ON_SESSION_KEY_RETURNED 第三次返回非ON_FINISH + EXPECT_CALL(*dmAuthStateMachineMock, WaitExpectEvent(_)) + .WillOnce(Return(ON_TRANSMIT)) + .WillOnce(Return(ON_SESSION_KEY_RETURNED)) + .WillOnce(Return(ON_ERROR)); + + EXPECT_EQ(authState->Action(context), ERR_DM_FAILED); +} + +// AuthSinkCredentialAuthNegotiateState 测试用例 +// Action 保存秘钥到DP失败 期待返回ERR_DM_FAILED +// 打桩 ProcessCredData 期待返回DM_OK +// 打桩 WaitExpectEvent 第一次返回ON_TRANSMIT 第二次返回ON_SESSION_KEY_RETURNED 第三次返回ON_FINISH +// 打桩 SaveSessionKeyToDP 期待返回ERR_DM_FAILED +HWTEST_F(AuthCredentialStateTest, AuthSinkCredentialAuthNegotiateState_007, testing::ext::TestSize.Level1) +{ + std::shared_ptr authState = std::make_shared(); + + // 打桩 ProcessCredData 期待返回DM_OK + EXPECT_CALL(*dmHiChainAuthConnectorMock, ProcessCredData(_, _)).WillOnce(Return(DM_OK)); + + // 打桩 WaitExpectEvent 第一次返回ON_TRANSMIT 第二次返回ON_SESSION_KEY_RETURNED 第三次返回ON_FINISH + EXPECT_CALL(*dmAuthStateMachineMock, WaitExpectEvent(_)) + .WillOnce(Return(ON_TRANSMIT)) + .WillOnce(Return(ON_SESSION_KEY_RETURNED)) + .WillOnce(Return(ON_FINISH)); + + // 打桩 SaveSessionKeyToDP 期待返回ERR_DM_FAILED + EXPECT_CALL(*DmAuthMessageProcessorMock::dmAuthMessageProcessorMock, SaveSessionKeyToDP(_)) + .WillOnce(Return(ERR_DM_FAILED)); + + EXPECT_EQ(authState->Action(context), ERR_DM_FAILED); +} + +// AuthSinkCredentialAuthNegotiateState 测试用例 +// Action SendData发送数据失败 期待返回ERR_DM_FAILED +// 打桩 ProcessCredData 期待返回DM_OK +// 打桩 WaitExpectEvent 第一次返回ON_TRANSMIT 第二次返回ON_SESSION_KEY_RETURNED 第三次返回ON_FINISH +// 打桩 SaveSessionKeyToDP 期待返回DM_OK +// 打桩 SendData 期待返回ERR_DM_FAILED +HWTEST_F(AuthCredentialStateTest, AuthSinkCredentialAuthNegotiateState_008, testing::ext::TestSize.Level1) +{ + std::shared_ptr authState = std::make_shared(); + + // 打桩 ProcessCredData 期待返回DM_OK + EXPECT_CALL(*dmHiChainAuthConnectorMock, ProcessCredData(_, _)).WillOnce(Return(DM_OK)); + + // 打桩 WaitExpectEvent 第一次返回ON_TRANSMIT 第二次返回ON_SESSION_KEY_RETURNED 第三次返回ON_FINISH + EXPECT_CALL(*dmAuthStateMachineMock, WaitExpectEvent(_)) + .WillOnce(Return(ON_TRANSMIT)) + .WillOnce(Return(ON_SESSION_KEY_RETURNED)) + .WillOnce(Return(ON_FINISH)); + + // 打桩 SaveSessionKeyToDP 期待返回DM_OK + EXPECT_CALL(*DmAuthMessageProcessorMock::dmAuthMessageProcessorMock, SaveSessionKeyToDP(_)) + .WillOnce(Return(DM_OK)); + + // 打桩 SendData 期待返回ERR_DM_FAILED + EXPECT_CALL(*dmSoftbusSessionMock, SendData(_, _)).WillOnce(Return(ERR_DM_FAILED)); + + EXPECT_EQ(authState->Action(context), ERR_DM_FAILED); +} + +// AuthSrcCredentialAuthDoneState 测试用例 +// GetStateType 接口 +HWTEST_F(AuthCredentialStateTest, AuthSrcCredentialAuthDoneState_001, testing::ext::TestSize.Level1) +{ + std::shared_ptr authState = std::make_shared(); + EXPECT_EQ(authState->GetStateType(), DmAuthStateType::AUTH_SRC_CREDENTIAL_AUTH_DONE_STATE); +} + +// AuthSrcCredentialAuthDoneState 测试用例 +// Action 接口 期待返回DM_OK +// 打桩 ProcessCredData 期待返回DM_OK +// 打桩 WaitExpectEvent 第一次返回ON_SESSION_KEY_RETURNED 第二次返回ON_FINISH 第三次返回ON_TRANSMIT +// 打桩 SaveSessionKeyToDP 期待返回DM_OK +// 打桩 AuthCredential 期待返回DM_OK +// 打桩 CreateMessage 期待返回非空string +// 打桩SendData 期待返回DM_OK +HWTEST_F(AuthCredentialStateTest, AuthSrcCredentialAuthDoneState_002, testing::ext::TestSize.Level1) +{ + std::shared_ptr authState = std::make_shared(); + + // 打桩 ProcessCredData 期待返回DM_OK + EXPECT_CALL(*dmHiChainAuthConnectorMock, ProcessCredData(_, _)).WillOnce(Return(DM_OK)); + + // 打桩 WaitExpectEvent 第一次返回ON_SESSION_KEY_RETURNED 第二次返回ON_FINISH 第三次返回ON_TRANSMIT + EXPECT_CALL(*dmAuthStateMachineMock, WaitExpectEvent(_)) + .WillOnce(Return(ON_SESSION_KEY_RETURNED)) + .WillOnce(Return(ON_FINISH)) + .WillOnce(Return(ON_TRANSMIT)); + + // 打桩 SaveSessionKeyToDP 期待返回DM_OK + EXPECT_CALL(*DmAuthMessageProcessorMock::dmAuthMessageProcessorMock, SaveSessionKeyToDP(_)) + .WillOnce(Return(DM_OK)); + + // 打桩 AuthCredential 期待返回DM_OK + EXPECT_CALL(*dmHiChainAuthConnectorMock, AuthCredential(_, _, _, _)).WillOnce(Return(DM_OK)); + + // 打桩 CreateMessage 期待返回非空string + EXPECT_CALL(*DmAuthMessageProcessorMock::dmAuthMessageProcessorMock, CreateMessage(_, _)) + .WillOnce(Return(TEST_NONE_EMPTY_STRING)); + + // 打桩 SendData 期待返回DM_OK + EXPECT_CALL(*dmSoftbusSessionMock, SendData(_, _)).WillOnce(Return(DM_OK)); + + EXPECT_EQ(authState->Action(context), DM_OK); +} + +// AuthSrcCredentialAuthDoneState 测试用例 +// Action 接口 ProcessCredData处理失败 期待返回ERR_DM_FAILED +// 打桩 ProcessCredData 期待返回ERR_DM_FAILED +HWTEST_F(AuthCredentialStateTest, AuthSrcCredentialAuthDoneState_003, testing::ext::TestSize.Level1) +{ + std::shared_ptr authState = std::make_shared(); + + // 打桩 ProcessCredData 期待返回ERR_DM_FAILED + EXPECT_CALL(*dmHiChainAuthConnectorMock, ProcessCredData(_, _)).WillOnce(Return(ERR_DM_FAILED)); + + EXPECT_EQ(authState->Action(context), ERR_DM_FAILED); +} + +// AuthSrcCredentialAuthDoneState 测试用例 +// Action 接口 WaitExpectEvent 第一次返回其它事件 期待返回ERR_DM_FAILED +// 打桩 ProcessCredData 期待返回DM_OK +// 打桩 WaitExpectEvent 第一次返回非ON_SESSION_KEY_RETURNED + +HWTEST_F(AuthCredentialStateTest, AuthSrcCredentialAuthDoneState_004, testing::ext::TestSize.Level1) +{ + std::shared_ptr authState = std::make_shared(); + + // 打桩 ProcessCredData 期待返回DM_OK + EXPECT_CALL(*dmHiChainAuthConnectorMock, ProcessCredData(_, _)).WillOnce(Return(DM_OK)); + + // 打桩 WaitExpectEvent 第一次返回非ON_SESSION_KEY_RETURNED 第二次返回ON_FINISH 第三次返回ON_TRANSMIT + EXPECT_CALL(*dmAuthStateMachineMock, WaitExpectEvent(_)) + .WillOnce(Return(ON_ERROR)); + + EXPECT_EQ(authState->Action(context), ERR_DM_FAILED); +} + +// AuthSrcCredentialAuthDoneState 测试用例 +// Action 接口 WaitExpectEvent第二次返回其它事件 期待返回ERR_DM_FAILED +// 打桩 ProcessCredData 期待返回DM_OK +// 打桩 WaitExpectEvent 第一次返回ON_SESSION_KEY_RETURNED 第二次返回非ON_FINISH +HWTEST_F(AuthCredentialStateTest, AuthSrcCredentialAuthDoneState_005, testing::ext::TestSize.Level1) +{ + std::shared_ptr authState = std::make_shared(); + + // 打桩 ProcessCredData 期待返回DM_OK + EXPECT_CALL(*dmHiChainAuthConnectorMock, ProcessCredData(_, _)).WillOnce(Return(DM_OK)); + + // 打桩 WaitExpectEvent 第一次返回ON_SESSION_KEY_RETURNED 第二次返回非ON_FINISH + EXPECT_CALL(*dmAuthStateMachineMock, WaitExpectEvent(_)) + .WillOnce(Return(ON_SESSION_KEY_RETURNED)) + .WillOnce(Return(ON_ERROR)); + + EXPECT_EQ(authState->Action(context), ERR_DM_FAILED); +} + +// AuthSrcCredentialAuthDoneState 测试用例 +// Action 接口 WaitExpectEvent第三次返回其它事件 期待返回ERR_DM_FAILED +// 打桩 ProcessCredData 期待返回DM_OK +// 打桩 WaitExpectEvent 第一次返回ON_SESSION_KEY_RETURNED 第二次返回ON_FINISH 第三次返回非ON_TRANSMIT +HWTEST_F(AuthCredentialStateTest, AuthSrcCredentialAuthDoneState_006, testing::ext::TestSize.Level1) +{ + std::shared_ptr authState = std::make_shared(); + + // 打桩 ProcessCredData 期待返回DM_OK + EXPECT_CALL(*dmHiChainAuthConnectorMock, ProcessCredData(_, _)).WillOnce(Return(DM_OK)); + + // 打桩 WaitExpectEvent 第一次返回ON_SESSION_KEY_RETURNED 第二次返回ON_FINISH 第三次返回非ON_TRANSMIT + EXPECT_CALL(*dmAuthStateMachineMock, WaitExpectEvent(_)) + .WillOnce(Return(ON_SESSION_KEY_RETURNED)) + .WillOnce(Return(ON_FINISH)) + .WillOnce(Return(ON_ERROR)); + + EXPECT_EQ(authState->Action(context), ERR_DM_FAILED); +} + +// AuthSrcCredentialAuthDoneState 测试用例 +// Action 接口 SaveSessionKeyToDP保存秘钥到Dp失败 期待返回ERR_DM_FAILED +// 打桩 ProcessCredData 期待返回DM_OK +// 打桩 WaitExpectEvent 第一次返回ON_SESSION_KEY_RETURNED 第二次返回ON_FINISH 第三次返回ON_TRANSMIT +// 打桩 SaveSessionKeyToDP 期待返回ERR_DM_FAILED +HWTEST_F(AuthCredentialStateTest, AuthSrcCredentialAuthDoneState_007, testing::ext::TestSize.Level1) +{ + std::shared_ptr authState = std::make_shared(); + + // 打桩 ProcessCredData 期待返回DM_OK + EXPECT_CALL(*dmHiChainAuthConnectorMock, ProcessCredData(_, _)).WillOnce(Return(DM_OK)); + + // 打桩 WaitExpectEvent 第一次返回ON_SESSION_KEY_RETURNED 第二次返回ON_FINISH 第三次返回ON_TRANSMIT + EXPECT_CALL(*dmAuthStateMachineMock, WaitExpectEvent(_)) + .WillOnce(Return(ON_SESSION_KEY_RETURNED)) + .WillOnce(Return(ON_FINISH)) + .WillOnce(Return(ON_TRANSMIT)); + + // 打桩 SaveSessionKeyToDP 期待返回ERR_DM_FAILED + EXPECT_CALL(*DmAuthMessageProcessorMock::dmAuthMessageProcessorMock, SaveSessionKeyToDP(_)) + .WillOnce(Return(ERR_DM_FAILED)); + + EXPECT_EQ(authState->Action(context), ERR_DM_FAILED); +} + +// AuthSrcCredentialAuthDoneState 测试用例 +// Action 接口 AuthCredential 期待返回ERR_DM_FAILED +// 打桩 ProcessCredData 期待返回DM_OK +// 打桩 WaitExpectEvent 第一次返回ON_SESSION_KEY_RETURNED 第二次返回ON_FINISH 第三次返回ON_TRANSMIT +// 打桩 SaveSessionKeyToDP 期待返回DM_OK +// 打桩 AuthCredential 期待返回ERR_DM_FAILED +HWTEST_F(AuthCredentialStateTest, AuthSrcCredentialAuthDoneState_008, testing::ext::TestSize.Level1) +{ + std::shared_ptr authState = std::make_shared(); + + // 打桩 ProcessCredData 期待返回DM_OK + EXPECT_CALL(*dmHiChainAuthConnectorMock, ProcessCredData(_, _)).WillOnce(Return(DM_OK)); + + // 打桩 WaitExpectEvent 第一次返回ON_SESSION_KEY_RETURNED 第二次返回ON_FINISH 第三次返回ON_TRANSMIT + EXPECT_CALL(*dmAuthStateMachineMock, WaitExpectEvent(_)) + .WillOnce(Return(ON_SESSION_KEY_RETURNED)) + .WillOnce(Return(ON_FINISH)) + .WillOnce(Return(ON_TRANSMIT)); + + // 打桩 SaveSessionKeyToDP 期待返回DM_OK + EXPECT_CALL(*DmAuthMessageProcessorMock::dmAuthMessageProcessorMock, SaveSessionKeyToDP(_)) + .WillOnce(Return(DM_OK)); + + // 打桩 AuthCredential 期待返回ERR_DM_FAILED + EXPECT_CALL(*dmHiChainAuthConnectorMock, AuthCredential(_, _, _, _)).WillOnce(Return(ERR_DM_FAILED)); + + EXPECT_EQ(authState->Action(context), ERR_DM_FAILED); +} + +// AuthSrcCredentialAuthDoneState 测试用例 +// Action 接口 CreateMessage创建空消息字符串 期待返回ERR_DM_FAILED +// 打桩 ProcessCredData 期待返回DM_OK +// 打桩 WaitExpectEvent 第一次返回ON_SESSION_KEY_RETURNED 第二次返回ON_FINISH 第三次返回ON_TRANSMIT +// 打桩 SaveSessionKeyToDP 期待返回DM_OK +// 打桩 AuthCredential 期待返回DM_OK +// 打桩 CreateMessage 期待返回空string +// 打桩SendData 期待返回DM_OK +HWTEST_F(AuthCredentialStateTest, AuthSrcCredentialAuthDoneState_009, testing::ext::TestSize.Level1) +{ + std::shared_ptr authState = std::make_shared(); + + // 打桩 ProcessCredData 期待返回DM_OK + EXPECT_CALL(*dmHiChainAuthConnectorMock, ProcessCredData(_, _)).WillOnce(Return(DM_OK)); + + // 打桩 WaitExpectEvent 第一次返回ON_SESSION_KEY_RETURNED 第二次返回ON_FINISH 第三次返回ON_TRANSMIT + EXPECT_CALL(*dmAuthStateMachineMock, WaitExpectEvent(_)) + .WillOnce(Return(ON_SESSION_KEY_RETURNED)) + .WillOnce(Return(ON_FINISH)) + .WillOnce(Return(ON_TRANSMIT)); + + // 打桩 SaveSessionKeyToDP 期待返回DM_OK + EXPECT_CALL(*DmAuthMessageProcessorMock::dmAuthMessageProcessorMock, SaveSessionKeyToDP(_)) + .WillOnce(Return(DM_OK)); + + // 打桩 AuthCredential 期待返回DM_OK + EXPECT_CALL(*dmHiChainAuthConnectorMock, AuthCredential(_, _, _, _)).WillOnce(Return(DM_OK)); + + // 打桩 CreateMessage 期待返回非空string + EXPECT_CALL(*DmAuthMessageProcessorMock::dmAuthMessageProcessorMock, CreateMessage(_, _)) + .WillOnce(Return("")); + + EXPECT_EQ(authState->Action(context), ERR_DM_FAILED); +} + +// AuthSrcCredentialAuthDoneState 测试用例 +// Action 接口 SendData发送数据失败 期待返回ERR_DM_FAILED +// 打桩 ProcessCredData 期待返回DM_OK +// 打桩 WaitExpectEvent 第一次返回ON_SESSION_KEY_RETURNED 第二次返回ON_FINISH 第三次返回ON_TRANSMIT +// 打桩 SaveSessionKeyToDP 期待返回DM_OK +// 打桩 AuthCredential 期待返回DM_OK +// 打桩 CreateMessage 期待返回非空string +// 打桩 SendData 期待返回ERR_DM_FAILED +HWTEST_F(AuthCredentialStateTest, AuthSrcCredentialAuthDoneState_0010, testing::ext::TestSize.Level1) +{ + std::shared_ptr authState = std::make_shared(); + + // 打桩 ProcessCredData 期待返回DM_OK + EXPECT_CALL(*dmHiChainAuthConnectorMock, ProcessCredData(_, _)).WillOnce(Return(DM_OK)); + + // 打桩 WaitExpectEvent 第一次返回ON_SESSION_KEY_RETURNED 第二次返回ON_FINISH 第三次返回ON_TRANSMIT + EXPECT_CALL(*dmAuthStateMachineMock, WaitExpectEvent(_)) + .WillOnce(Return(ON_SESSION_KEY_RETURNED)) + .WillOnce(Return(ON_FINISH)) + .WillOnce(Return(ON_TRANSMIT)); + + // 打桩 SaveSessionKeyToDP 期待返回DM_OK + EXPECT_CALL(*DmAuthMessageProcessorMock::dmAuthMessageProcessorMock, SaveSessionKeyToDP(_)) + .WillOnce(Return(DM_OK)); + + // 打桩 AuthCredential 期待返回DM_OK + EXPECT_CALL(*dmHiChainAuthConnectorMock, AuthCredential(_, _, _, _)).WillOnce(Return(DM_OK)); + + // 打桩 CreateMessage 期待返回非空string + EXPECT_CALL(*DmAuthMessageProcessorMock::dmAuthMessageProcessorMock, CreateMessage(_, _)) + .WillOnce(Return(TEST_NONE_EMPTY_STRING)); + + // 打桩 SendData 期待返回ERR_DM_FAILED + EXPECT_CALL(*dmSoftbusSessionMock, SendData(_, _)).WillOnce(Return(ERR_DM_FAILED)); + + EXPECT_EQ(authState->Action(context), ERR_DM_FAILED); +} + +} +} \ No newline at end of file diff --git a/test/unittest/UTTest_auth_credential_state.h b/test/unittest/UTTest_auth_credential_state.h new file mode 100644 index 000000000..ba2893051 --- /dev/null +++ b/test/unittest/UTTest_auth_credential_state.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2025 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 UTTEST_AUTH_CREDENTIAL_STATE_H +#define UTTEST_AUTH_CREDENTIAL_STATE_H + +#include +#include "hichain_auth_connector_mock.h" +#include "softbus_session_mock.h" +#include "dm_auth_state_machine_mock.h" +#include "auth_manager.h" + +namespace OHOS { +namespace DistributedHardware { + +class AuthCredentialStateTest : public testing::Test { +public: + static void SetUpTestCase(); + static void TearDownTestCase(); + void SetUp(); + void TearDown(); +private: + static inline std::shared_ptr dmHiChainAuthConnectorMock = + std::make_shared(); + static inline std::shared_ptr dmSoftbusSessionMock = + std::make_shared(); + static inline std::shared_ptr dmAuthStateMachineMock = + std::make_shared(); + std::shared_ptr softbusConnector; + std::shared_ptr listener; + std::shared_ptr hiChainAuthConnector; + std::shared_ptr authManager; + std::shared_ptr context; +}; + +} +} +#endif \ No newline at end of file diff --git a/test/unittest/UTTest_auth_negotiate_state.cpp b/test/unittest/UTTest_auth_negotiate_state.cpp new file mode 100644 index 000000000..65f49abb7 --- /dev/null +++ b/test/unittest/UTTest_auth_negotiate_state.cpp @@ -0,0 +1,175 @@ +/* + * Copyright (c) 2025 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 "device_manager_service_listener.h" +#include "dm_auth_state.h" +#include "UTTest_auth_negotiate_state.h" + +using namespace testing; + +namespace OHOS { +namespace DistributedHardware { + +constexpr const char* TEST_STRING = "test_string"; +constexpr int32_t TEST_NEGATIVE = -1; +constexpr int32_t TEST_POSITIVE = 1; + +void AuthNegotiateStateTest::SetUpTestCase() +{ + LOGI("AuthNegotiateStateTest::SetUpTestCase start."); + + DmSoftbusConnector::dmSoftbusConnector = softbusConnectorMock; + DmSoftbusSession::dmSoftbusSession = softbusSessionMock; +} + +void AuthNegotiateStateTest::TearDownTestCase() +{ + LOGI("AuthNegotiateStateTest::TearDownTestCase done."); + softbusConnectorMock = nullptr; + softbusSessionMock = nullptr; + DmSoftbusConnector::dmSoftbusConnector = nullptr; + DmSoftbusSession::dmSoftbusSession = nullptr; +} + +void AuthNegotiateStateTest::SetUp() +{ + LOGI("AuthNegotiateStateTest::SetUp start."); + softbusConnector = std::make_shared(); + listener = std::make_shared(); + hiChainAuthConnector = std::make_shared(); + authManager = std::make_shared(softbusConnector, listener, + hiChainAuthConnector); + context = authManager->GetAuthContext(); + softbusSession = std::make_shared(); + + Mock::VerifyAndClearExpectations(&*softbusConnectorMock); + Mock::VerifyAndClearExpectations(&*softbusSessionMock); +} + +void AuthNegotiateStateTest::TearDown() +{ + LOGI("AuthNegotiateStateTest::TearDown done."); + softbusConnector = nullptr; + listener = nullptr; + hiChainAuthConnector = nullptr; + authManager = nullptr; + context = nullptr; + softbusSession = nullptr; +} + + +// AuthSrcStartState 状态测试用例 +// GetStateType 接口 +HWTEST_F(AuthNegotiateStateTest, AuthSrcStartState_001, testing::ext::TestSize.Level1) +{ + std::shared_ptr authState = std::make_shared(); + EXPECT_EQ(authState->GetStateType(), DmAuthStateType::AUTH_SRC_START_STATE); +} + +// AuthSrcStartState 状态测试用例 +// Action 接口 正常流程,期待返回DM_OK +// 上下文中设置 connSessionType == CONN_SESSION_TYPE_HML +// 打桩 GetSoftbusSession 接口 返回非空的SoftbusSession对象 +// 打桩 OpenAuthSessionWithPara 接口 期待返回非负数TEST_POSITIVE +HWTEST_F(AuthNegotiateStateTest, AuthSrcStartState_002, testing::ext::TestSize.Level1) +{ + std::shared_ptr authState = std::make_shared(); + + // 上下文中设置 connSessionType == CONN_SESSION_TYPE_HML + context->connSessionType = CONN_SESSION_TYPE_HML; + + // 打桩 GetSoftbusSession 接口 返回非空的SoftbusSession对象 + EXPECT_CALL(*softbusConnectorMock, GetSoftbusSession) + .WillOnce(Return(softbusSession)); + + // 打桩 OpenAuthSessionWithPara 接口 期待返回非负数TEST_POSITIVE + EXPECT_CALL(*softbusSessionMock, OpenAuthSessionWithPara) + .WillOnce(Return(TEST_POSITIVE)); + + EXPECT_EQ(authState->Action(context), DM_OK); +} + +// AuthSrcStartState 状态测试用例 +// Action 接口 正常流程,期待返回DM_OK +// 上下文中设置 connSessionType != CONN_SESSION_TYPE_HML +// 打桩 GetSoftbusSession 接口,返回非空的SoftbusSession对象 +// 打桩 OpenAuthSession 接口,返回非负数TEST_POSITIVE +HWTEST_F(AuthNegotiateStateTest, AuthSrcStartState_003, testing::ext::TestSize.Level1) +{ + std::shared_ptr authState = std::make_shared(); + + // 上下文中设置 connSessionType != CONN_SESSION_TYPE_HML + context->connSessionType = TEST_STRING; + + // 打桩 GetSoftbusSession 接口 返回非空的SoftbusSession对象 + EXPECT_CALL(*softbusConnectorMock, GetSoftbusSession()) + .WillOnce(Return(softbusSession)); + + // 打桩 OpenAuthSession 接口,返回非负数TEST_POSITIVE + EXPECT_CALL(*softbusSessionMock, OpenAuthSession(_)) + .WillOnce(Return(TEST_POSITIVE)); + + EXPECT_EQ(authState->Action(context), DM_OK); +} + +// AuthSrcStartState 状态测试用例 +// Action 接口 异常流程,期待返回ERR_DM_FAILED +// connSessionType != CONN_SESSION_TYPE_HML +// 打桩 GetSoftbusSession 接口,返回非空的SoftbusSession对象 +// 打桩 OpenAuthSession 接口,返回负数TEST_NEGATIVE +HWTEST_F(AuthNegotiateStateTest, AuthSrcStartState_004, testing::ext::TestSize.Level1) +{ + std::shared_ptr authState = std::make_shared(); + + // 上下文中设置 connSessionType == CONN_SESSION_TYPE_HML + context->connSessionType = CONN_SESSION_TYPE_HML; + + // 打桩 GetSoftbusSession 接口 返回非空的SoftbusSession对象 + EXPECT_CALL(*softbusConnectorMock, GetSoftbusSession) + .WillOnce(Return(softbusSession)); + + // 打桩 OpenAuthSession 接口,返回负数TEST_NEGATIVE + EXPECT_CALL(*softbusSessionMock, OpenAuthSessionWithPara) + .WillOnce(Return(TEST_NEGATIVE)); + + EXPECT_EQ(authState->Action(context), ERR_DM_FAILED); +} + + +// AuthSrcNegotiateStateMachine 状态测试用例 +// GetStateType 接口 +HWTEST_F(AuthNegotiateStateTest, AuthSrcNegotiateStateMachine_001, testing::ext::TestSize.Level1) +{ + std::shared_ptr authState = std::make_shared(); + EXPECT_EQ(authState->GetStateType(), DmAuthStateType::AUTH_SRC_NEGOTIATE_STATE); +} + +// AuthSrcNegotiateStateMachine 状态测试用例 +// Actions 接口 正常流程 期待DM_OK +HWTEST_F(AuthNegotiateStateTest, AuthSrcNegotiateStateMachine_002, testing::ext::TestSize.Level1) +{ + std::shared_ptr authState = std::make_shared(); + EXPECT_EQ(authState->Action(context), DM_OK); +} + +// AuthSinkNegotiateStateMachine 状态测试用例 +// GetStateType 接口 +HWTEST_F(AuthNegotiateStateTest, AuthSinkNegotiateStateMachine_001, testing::ext::TestSize.Level1) +{ + std::shared_ptr authState = std::make_shared(); + EXPECT_EQ(authState->GetStateType(), DmAuthStateType::AUTH_SINK_NEGOTIATE_STATE); +} +} +} \ No newline at end of file diff --git a/test/unittest/UTTest_auth_negotiate_state.h b/test/unittest/UTTest_auth_negotiate_state.h new file mode 100644 index 000000000..d385723bc --- /dev/null +++ b/test/unittest/UTTest_auth_negotiate_state.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2025 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 UTTEST_AUTH_NEGOTIATE_STATE_H +#define UTTEST_AUTH_NEGOTIATE_STATE_H + +#include "gtest/gtest.h" +#include "auth_manager.h" +#include "softbus_connector_mock.h" +#include "softbus_session_mock.h" + +namespace OHOS { +namespace DistributedHardware { + +class AuthNegotiateStateTest : public testing::Test { +public: + static void SetUpTestCase(); + static void TearDownTestCase(); + void SetUp(); + void TearDown(); +private: + static inline std::shared_ptr softbusConnectorMock = + std::make_shared(); + static inline std::shared_ptr softbusSessionMock = + std::make_shared(); + std::shared_ptr softbusConnector; + std::shared_ptr listener; + std::shared_ptr hiChainAuthConnector; + std::shared_ptr authManager; + std::shared_ptr context; + std::shared_ptr softbusSession; +}; + +} +} +#endif \ No newline at end of file diff --git a/test/unittest/UTTest_auth_pin_auth_state.cpp b/test/unittest/UTTest_auth_pin_auth_state.cpp new file mode 100644 index 000000000..8851a7562 --- /dev/null +++ b/test/unittest/UTTest_auth_pin_auth_state.cpp @@ -0,0 +1,562 @@ +/* + * Copyright (c) 2025 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 "dm_auth_state_machine_mock.h" +#include "UTTest_auth_pin_auth_state.h" + +using namespace testing; + +namespace OHOS { +namespace DistributedHardware { + +void AuthPinAuthStateTest::SetUpTestCase() +{ + // 创建mock类 + LOGI("AuthPinAuthStateTest::SetUpTestCase start."); + DmHiChainAuthConnector::dmHiChainAuthConnector = hiChainAuthConnectorMock; + DmAuthStateMachineMock::dmAuthStateMachineMock = std::make_shared(); +} + +void AuthPinAuthStateTest::TearDownTestCase() +{ + LOGI("AuthPinAuthStateTest::TearDownTestCase start."); + DmHiChainAuthConnector::dmHiChainAuthConnector = nullptr; + DmAuthStateMachineMock::dmAuthStateMachineMock = nullptr; + hiChainAuthConnectorMock = nullptr; +} + +void AuthPinAuthStateTest::SetUp() +{ + LOGI("AuthPinAuthStateTest::SetUp start."); + softbusConnector = std::make_shared(); + listener = std::make_shared(); + hiChainAuthConnector = std::make_shared(); + authManager = std::make_shared(softbusConnector, listener, + hiChainAuthConnector); + context = authManager->GetAuthContext(); + + Mock::VerifyAndClearExpectations(&*hiChainAuthConnectorMock); + Mock::VerifyAndClearExpectations(&*DmAuthStateMachineMock::dmAuthStateMachineMock); +} + +void AuthPinAuthStateTest::TearDown() +{ + LOGI("AuthPinAuthStateTest::TearDown start."); + softbusConnector = nullptr; + listener = nullptr; + hiChainAuthConnector = nullptr; + authManager = nullptr; + context = nullptr; +} + +// AuthSrcPinAuthStartState 测试用例 +// GetStateType 接口 +HWTEST_F(AuthPinAuthStateTest, AuthSrcPinAuthStartState_001, testing::ext::TestSize.Level1) +{ + std::shared_ptr authState = std::make_shared(); + EXPECT_EQ(authState->GetStateType(), DmAuthStateType::AUTH_SRC_PIN_AUTH_START_STATE); +} + +// AuthSrcPinAuthStartState 测试用例 +// Action接口 正常流程 期待返回DM_OK +// 打桩 AuthCredentialPinCode 期待返回DM_OK +// 打桩 WaitExpectEvent 期待返回ON_TRANSMIT +HWTEST_F(AuthPinAuthStateTest, AuthSrcPinAuthStartState_002, testing::ext::TestSize.Level1) +{ + std::shared_ptr authState = std::make_shared(); + + // 打桩 AuthCredentialPinCode 期待返回DM_OK + EXPECT_CALL(*hiChainAuthConnectorMock, AuthCredentialPinCode(_, _, _)) + .WillOnce(Return(DM_OK)); + + // 打桩 WaitExpectEvent 期待返回ON_TRANSMIT + EXPECT_CALL(*DmAuthStateMachineMock::dmAuthStateMachineMock, WaitExpectEvent(_)) + .WillOnce(Return(ON_TRANSMIT)); + + EXPECT_EQ(authState->Action(context), DM_OK); +} + +// AuthSrcPinAuthStartState 测试用例 +// Action接口 正常流程 期待返回DM_OK +// 打桩 AuthCredentialPinCode 期待返回DM_OK +// 打桩 WaitExpectEvent 期待返回ON_ERROR +HWTEST_F(AuthPinAuthStateTest, AuthSrcPinAuthStartState_003, testing::ext::TestSize.Level1) +{ + std::shared_ptr authState = std::make_shared(); + + // 打桩 AuthCredentialPinCode 期待返回DM_OK + EXPECT_CALL(*hiChainAuthConnectorMock, AuthCredentialPinCode(_, _, _)) + .WillOnce(Return(DM_OK)); + + // 打桩 WaitExpectEvent 期待返回ON_ERROR + EXPECT_CALL(*DmAuthStateMachineMock::dmAuthStateMachineMock, WaitExpectEvent(_)) + .WillOnce(Return(ON_ERROR)); + + EXPECT_EQ(authState->Action(context), DM_OK); +} + +// AuthSrcPinAuthStartState 测试用例 +// Action接口 异常流程 PIN码认证失败 期待返回ERR_DM_FAILED +// 打桩 AuthCredentialPinCode 期待返回ERR_DM_FAILED +HWTEST_F(AuthPinAuthStateTest, AuthSrcPinAuthStartState_004, testing::ext::TestSize.Level1) +{ + std::shared_ptr authState = std::make_shared(); + + // 打桩 AuthCredentialPinCode 期待返回ERR_DM_FAILED + EXPECT_CALL(*hiChainAuthConnectorMock, AuthCredentialPinCode(_, _, _)) + .WillOnce(Return(ERR_DM_FAILED)); + + EXPECT_EQ(authState->Action(context), ERR_DM_FAILED); +} + +// AuthSrcPinAuthStartState 测试用例 +// Action接口 异常流程 未等到期望事件发生 期待返回STOP_BIND +// 打桩 AuthCredentialPinCode 期待返回DM_OK +// 打桩 WaitExpectEvent 期待返回非ON_TRANSMIT且非ON_ERROR +HWTEST_F(AuthPinAuthStateTest, AuthSrcPinAuthStartState_005, testing::ext::TestSize.Level1) +{ + std::shared_ptr authState = std::make_shared(); + + // 打桩 AuthCredentialPinCode 期待返回DM_OK + EXPECT_CALL(*hiChainAuthConnectorMock, AuthCredentialPinCode(_, _, _)) + .WillOnce(Return(DM_OK)); + + // 打桩 WaitExpectEvent 期待返回非ON_TRANSMIT且非ON_ERROR 返回ON_SESSION_KEY_RETURNED + EXPECT_CALL(*DmAuthStateMachineMock::dmAuthStateMachineMock, WaitExpectEvent(_)) + .WillOnce(Return(ON_SESSION_KEY_RETURNED)); + + EXPECT_EQ(authState->Action(context), STOP_BIND); +} + +// AuthSinkPinAuthStartState 测试用例 +// GetStateType 接口 +HWTEST_F(AuthPinAuthStateTest, AuthSinkPinAuthStartState_001, testing::ext::TestSize.Level1) +{ + std::shared_ptr authState = std::make_shared(); + EXPECT_EQ(authState->GetStateType(), DmAuthStateType::AUTH_SINK_PIN_AUTH_START_STATE); +} + +// AuthSinkPinAuthStartState 测试用例 +// Action 接口 正常流程 期待返回DM_OK +// 打桩 ProcessCredData 期待返回DM_OK +// 打桩 WaitExpectEvent 期待返回ON_TRANSMIT +HWTEST_F(AuthPinAuthStateTest, AuthSinkPinAuthStartState_002, testing::ext::TestSize.Level1) +{ + std::shared_ptr authState = std::make_shared(); + + // 打桩 ProcessCredData 期待返回DM_OK + EXPECT_CALL(*hiChainAuthConnectorMock, ProcessCredData(_, _)) + .WillOnce(Return(DM_OK)); + + // 打桩 WaitExpectEvent 期待返回ON_TRANSMIT + EXPECT_CALL(*DmAuthStateMachineMock::dmAuthStateMachineMock, WaitExpectEvent(_)) + .WillOnce(Return(ON_TRANSMIT)); + + EXPECT_EQ(authState->Action(context), DM_OK); +} + +// AuthSinkPinAuthStartState 测试用例 +// Action 接口 正常流程 期待返回DM_OK +// 打桩 ProcessCredData 期待返回DM_OK +// 打桩 WaitExpectEvent 期待返回ON_ERROR +HWTEST_F(AuthPinAuthStateTest, AuthSinkPinAuthStartState_003, testing::ext::TestSize.Level1) +{ + std::shared_ptr authState = std::make_shared(); + + // 打桩 ProcessCredData 期待返回DM_OK + EXPECT_CALL(*hiChainAuthConnectorMock, ProcessCredData(_, _)) + .WillOnce(Return(DM_OK)); + + // 打桩 WaitExpectEvent 期待返回ON_ERROR + EXPECT_CALL(*DmAuthStateMachineMock::dmAuthStateMachineMock, WaitExpectEvent(_)) + .WillOnce(Return(ON_ERROR)); + + EXPECT_EQ(authState->Action(context), DM_OK); +} + +// AuthSinkPinAuthStartState 测试用例 +// Action 接口 异常流程 ProcessCredData处理失败 期待返回ERR_DM_FAILED +// 打桩 ProcessCredData 期待返回ERR_DM_FAILED +HWTEST_F(AuthPinAuthStateTest, AuthSinkPinAuthStartState_004, testing::ext::TestSize.Level1) +{ + std::shared_ptr authState = std::make_shared(); + + // 打桩 ProcessCredData 期待返回ERR_DM_FAILED + EXPECT_CALL(*hiChainAuthConnectorMock, ProcessCredData(_, _)) + .WillOnce(Return(ERR_DM_FAILED)); + + EXPECT_EQ(authState->Action(context), ERR_DM_FAILED); +} + +// AuthSinkPinAuthStartState 测试用例 +// Action 接口 异常流程 期待返回STOP_BIND +// 打桩 ProcessCredData 期待返回DM_OK +// 打桩 WaitExpectEvent 期待返回非ON_ERROR和非ON_TRANSMIT 返回ON_SESSION_KEY_RETURNED +HWTEST_F(AuthPinAuthStateTest, AuthSinkPinAuthStartState_005, testing::ext::TestSize.Level1) +{ + std::shared_ptr authState = std::make_shared(); + + // 打桩 ProcessCredData 期待返回DM_OK + EXPECT_CALL(*hiChainAuthConnectorMock, ProcessCredData(_, _)) + .WillOnce(Return(DM_OK)); + + // 打桩 WaitExpectEvent 期待返回非ON_ERROR和非ON_TRANSMIT 返回ON_SESSION_KEY_RETURNED + EXPECT_CALL(*DmAuthStateMachineMock::dmAuthStateMachineMock, WaitExpectEvent(_)) + .WillOnce(Return(ON_SESSION_KEY_RETURNED)); + + EXPECT_EQ(authState->Action(context), STOP_BIND); +} + +// AuthSrcPinAuthMsgNegotiateState 测试用例 +// GetStateType 接口 +HWTEST_F(AuthPinAuthStateTest, AuthSrcPinAuthMsgNegotiateState_001, testing::ext::TestSize.Level1) +{ + std::shared_ptr authState = std::make_shared(); + EXPECT_EQ(authState->GetStateType(), DmAuthStateType::AUTH_SRC_PIN_AUTH_MSG_NEGOTIATE_STATE); +} + +// AuthSrcPinAuthMsgNegotiateState 测试用例 +// Action 接口 正常流程 期待返回DM_OK +// 打桩 ProcessCredData 期待返回DM_OK +// 打桩 WaitExpectEvent 期待返回ON_TRANSMIT +HWTEST_F(AuthPinAuthStateTest, AuthSrcPinAuthMsgNegotiateState_002, testing::ext::TestSize.Level1) +{ + std::shared_ptr authState = std::make_shared(); + + // 打桩 ProcessCredData 期待返回DM_OK + EXPECT_CALL(*hiChainAuthConnectorMock, ProcessCredData(_, _)) + .WillOnce(Return(DM_OK)); + + // 打桩 WaitExpectEvent 期待返回ON_TRANSMIT + EXPECT_CALL(*DmAuthStateMachineMock::dmAuthStateMachineMock, WaitExpectEvent(_)) + .WillOnce(Return(ON_TRANSMIT)); + + EXPECT_EQ(authState->Action(context), DM_OK); +} + +// AuthSrcPinAuthMsgNegotiateState 测试用例 +// Action 接口 正常流程 期待返回DM_OK +// 打桩 ProcessCredData 期待返回DM_OK +// 打桩 WaitExpectEvent 期待返回ON_ERROR +HWTEST_F(AuthPinAuthStateTest, AuthSrcPinAuthMsgNegotiateState_003, testing::ext::TestSize.Level1) +{ + std::shared_ptr authState = std::make_shared(); + + // 打桩 ProcessCredData 期待返回DM_OK + EXPECT_CALL(*hiChainAuthConnectorMock, ProcessCredData(_, _)) + .WillOnce(Return(DM_OK)); + + // 打桩 WaitExpectEvent 期待返回ON_ERROR + EXPECT_CALL(*DmAuthStateMachineMock::dmAuthStateMachineMock, WaitExpectEvent(_)) + .WillOnce(Return(ON_ERROR)); + + EXPECT_EQ(authState->Action(context), DM_OK); +} + +// AuthSrcPinAuthMsgNegotiateState 测试用例 +// Action 接口 异常流程 期待返回ERR_DM_FAILED +// 打桩 ProcessCredData 期待返回ERR_DM_FAILED +HWTEST_F(AuthPinAuthStateTest, AuthSrcPinAuthMsgNegotiateState_004, testing::ext::TestSize.Level1) +{ + std::shared_ptr authState = std::make_shared(); + + // 打桩 ProcessCredData 期待返回ERR_DM_FAILED + EXPECT_CALL(*hiChainAuthConnectorMock, ProcessCredData(_, _)) + .WillOnce(Return(ERR_DM_FAILED)); + + EXPECT_EQ(authState->Action(context), ERR_DM_FAILED); +} + +// AuthSrcPinAuthMsgNegotiateState 测试用例 +// Action 接口 异常流程 期待返回STOP_BIND +// 打桩 ProcessCredData 期待返回DM_OK +// 打桩 WaitExpectEvent 期待返回ON_REQUEST +HWTEST_F(AuthPinAuthStateTest, AuthSrcPinAuthMsgNegotiateState_005, testing::ext::TestSize.Level1) +{ + std::shared_ptr authState = std::make_shared(); + + // 打桩 ProcessCredData 期待返回DM_OK + EXPECT_CALL(*hiChainAuthConnectorMock, ProcessCredData(_, _)) + .WillOnce(Return(DM_OK)); + + // 打桩 WaitExpectEvent 期待返回ON_REQUEST + EXPECT_CALL(*DmAuthStateMachineMock::dmAuthStateMachineMock, WaitExpectEvent(_)) + .WillOnce(Return(ON_REQUEST)); + + EXPECT_EQ(authState->Action(context), STOP_BIND); +} + +// AuthSinkPinAuthMsgNegotiateState 测试用例 +// GetStateType 接口 +HWTEST_F(AuthPinAuthStateTest, AuthSinkPinAuthMsgNegotiateState_001, testing::ext::TestSize.Level1) +{ + std::shared_ptr authState = std::make_shared(); + EXPECT_EQ(authState->GetStateType(), DmAuthStateType::AUTH_SINK_PIN_AUTH_MSG_NEGOTIATE_STATE); +} + +// AuthSinkPinAuthMsgNegotiateState 测试用例 +// Action 接口 正常流程 期待返回DM_OK +// 打桩 ProcessCredData 期待返回DM_OK +// 打桩 WaitExpectEvent 期待第一次返回ON_TRANSMIT 第二次返回ON_SESSION_KEY_RETURNED 第三次ON_FINISH +HWTEST_F(AuthPinAuthStateTest, AuthSinkPinAuthMsgNegotiateState_002, testing::ext::TestSize.Level1) +{ + std::shared_ptr authState = std::make_shared(); + + // 打桩 ProcessCredData 期待返回DM_OK + EXPECT_CALL(*hiChainAuthConnectorMock, ProcessCredData(_, _)) + .WillOnce(Return(DM_OK)); + + // 打桩 WaitExpectEvent 期待第一次返回ON_TRANSMIT 第二次返回ON_SESSION_KEY_RETURNED 第三次ON_FINISH + EXPECT_CALL(*DmAuthStateMachineMock::dmAuthStateMachineMock, WaitExpectEvent(_)) + .WillOnce(Return(ON_REQUEST)) + .WillOnce(Return(ON_SESSION_KEY_RETURNED)) + .WillOnce(Return(ON_FINISH)); + + EXPECT_EQ(authState->Action(context), DM_OK); +} + +// AuthSinkPinAuthMsgNegotiateState 测试用例 +// Action 接口 异常流程 ProcessCredData处理PIN码失败 期待返回ERR_DM_FAILED +// 打桩 ProcessCredData 期待返回ERR_DM_FAILED +HWTEST_F(AuthPinAuthStateTest, AuthSinkPinAuthMsgNegotiateState_003, testing::ext::TestSize.Level1) +{ + std::shared_ptr authState = std::make_shared(); + + // 打桩 ProcessCredData 期待返回ERR_DM_FAILED + EXPECT_CALL(*hiChainAuthConnectorMock, ProcessCredData(_, _)) + .WillOnce(Return(ERR_DM_FAILED)); + + EXPECT_EQ(authState->Action(context), ERR_DM_FAILED); +} + +// AuthSinkPinAuthMsgNegotiateState 测试用例 +// Action 接口 重试流程 期待返回DM_OK +// 打桩 ProcessCredData 期待返回DM_OK +// 打桩 WaitExpectEvent 期待第一次返回ON_ERROR +HWTEST_F(AuthPinAuthStateTest, AuthSinkPinAuthMsgNegotiateState_004, testing::ext::TestSize.Level1) +{ + std::shared_ptr authState = std::make_shared(); + + // 打桩 ProcessCredData 期待返回DM_OK + EXPECT_CALL(*hiChainAuthConnectorMock, ProcessCredData(_, _)) + .WillOnce(Return(DM_OK)); + + // 打桩 WaitExpectEvent 期待第一次返回ON_ERROR + EXPECT_CALL(*DmAuthStateMachineMock::dmAuthStateMachineMock, WaitExpectEvent(_)) + .WillOnce(Return(ON_ERROR)); + + EXPECT_EQ(authState->Action(context), DM_OK); +} + +// AuthSinkPinAuthMsgNegotiateState 测试用例 +// Action 接口 异常流程 期待返回STOP_BIND +// 打桩 ProcessCredData 期待返回DM_OK +// 打桩 WaitExpectEvent 期待第一次返回ON_SESSION_KEY_RETURNED +HWTEST_F(AuthPinAuthStateTest, AuthSinkPinAuthMsgNegotiateState_005, testing::ext::TestSize.Level1) +{ + std::shared_ptr authState = std::make_shared(); + + // 打桩 ProcessCredData 期待返回DM_OK + EXPECT_CALL(*hiChainAuthConnectorMock, ProcessCredData(_, _)) + .WillOnce(Return(DM_OK)); + + // 打桩 WaitExpectEvent 期待第一次返回ON_SESSION_KEY_RETURNED + EXPECT_CALL(*DmAuthStateMachineMock::dmAuthStateMachineMock, WaitExpectEvent(_)) + .WillOnce(Return(ON_SESSION_KEY_RETURNED)); + + EXPECT_EQ(authState->Action(context), STOP_BIND); +} + +// AuthSinkPinAuthMsgNegotiateState 测试用例 +// Action 接口 重试流程 期待返回DM_OK +// 打桩 ProcessCredData 期待返回DM_OK +// 打桩 WaitExpectEvent 期待第一次返回ON_TRANSMIT 第二次返回ON_ERROR +HWTEST_F(AuthPinAuthStateTest, AuthSinkPinAuthMsgNegotiateState_006, testing::ext::TestSize.Level1) +{ + std::shared_ptr authState = std::make_shared(); + + // 打桩 ProcessCredData 期待返回DM_OK + EXPECT_CALL(*hiChainAuthConnectorMock, ProcessCredData(_, _)) + .WillOnce(Return(DM_OK)); + + // 打桩 WaitExpectEvent 期待第一次返回ON_TRANSMIT 第二次返回ON_ERROR + EXPECT_CALL(*DmAuthStateMachineMock::dmAuthStateMachineMock, WaitExpectEvent(_)) + .WillOnce(Return(ON_TRANSMIT)) + .WillOnce(Return(ON_ERROR)); + + EXPECT_EQ(authState->Action(context), DM_OK); +} + +// AuthSinkPinAuthMsgNegotiateState 测试用例 +// Action 接口 异常流程 期待返回STOP_BIND +// 打桩 ProcessCredData 期待返回DM_OK +// 打桩 WaitExpectEvent 期待第一次返回ON_TRANSMIT 第二次返回ON_SESSION_KEY_RETURNED,第三次返回ON_SESSION_KEY_RETURNED +HWTEST_F(AuthPinAuthStateTest, AuthSinkPinAuthMsgNegotiateState_007, testing::ext::TestSize.Level1) +{ + std::shared_ptr authState = std::make_shared(); + + // 打桩 ProcessCredData 期待返回DM_OK + EXPECT_CALL(*hiChainAuthConnectorMock, ProcessCredData(_, _)) + .WillOnce(Return(DM_OK)); + + // 打桩 WaitExpectEvent 期待第一次返回ON_TRANSMIT 第二次返回ON_ERROR + EXPECT_CALL(*DmAuthStateMachineMock::dmAuthStateMachineMock, WaitExpectEvent(_)) + .WillOnce(Return(ON_TRANSMIT)) + .WillOnce(Return(ON_SESSION_KEY_RETURNED)) + .WillOnce(Return(ON_SESSION_KEY_RETURNED)); + + EXPECT_EQ(authState->Action(context), STOP_BIND); +} + +// AuthSrcPinAuthDoneState 测试用例 +// GetStateType 接口 +HWTEST_F(AuthPinAuthStateTest, AuthSrcPinAuthDoneState_001, testing::ext::TestSize.Level1) +{ + std::shared_ptr authState = std::make_shared(); + EXPECT_EQ(authState->GetStateType(), DmAuthStateType::AUTH_SRC_PIN_AUTH_DONE_STATE); +} + +// AuthSrcPinAuthDoneState 测试用例 +// Action 接口 正常流程 期待返回DM_OK +// 打桩 ProcessCredData 期待返回DM_OK +// 打桩 WaitExpectEvent 期待第一次返回ON_SESSION_KEY_RETURNED 第二次返回ON_FINISH +HWTEST_F(AuthPinAuthStateTest, AuthSrcPinAuthDoneState_002, testing::ext::TestSize.Level1) +{ + std::shared_ptr authState = std::make_shared(); + + // 打桩 ProcessCredData 期待返回DM_OK + EXPECT_CALL(*hiChainAuthConnectorMock, ProcessCredData(_, _)) + .WillOnce(Return(DM_OK)); + + // 打桩 WaitExpectEvent 期待第一次返回ON_SESSION_KEY_RETURNED 第二次返回ON_FINISH + EXPECT_CALL(*DmAuthStateMachineMock::dmAuthStateMachineMock, WaitExpectEvent(_)) + .WillOnce(Return(ON_SESSION_KEY_RETURNED)) + .WillOnce(Return(ON_FINISH)); + + EXPECT_EQ(authState->Action(context), DM_OK); +} + +// AuthSrcPinAuthDoneState 测试用例 +// Action 接口 异常流程处理凭据数据失败 期待返回ERR_DM_FAILED +// 打桩 ProcessCredData 期待返回ERR_DM_FAILED +HWTEST_F(AuthPinAuthStateTest, AuthSrcPinAuthDoneState_003, testing::ext::TestSize.Level1) +{ + std::shared_ptr authState = std::make_shared(); + + // 打桩 ProcessCredData 期待返回ERR_DM_FAILED + EXPECT_CALL(*hiChainAuthConnectorMock, ProcessCredData(_, _)) + .WillOnce(Return(ERR_DM_FAILED)); + + EXPECT_EQ(authState->Action(context), ERR_DM_FAILED); +} + +// AuthSrcPinAuthDoneState 测试用例 +// Action 接口 重试流程 期待返回DM_OK +// 打桩 ProcessCredData 期待返回DM_OK +// 打桩 WaitExpectEvent 期待返回ON_ERROR +HWTEST_F(AuthPinAuthStateTest, AuthSrcPinAuthDoneState_004, testing::ext::TestSize.Level1) +{ + std::shared_ptr authState = std::make_shared(); + + // 打桩 ProcessCredData 期待返回DM_OK + EXPECT_CALL(*hiChainAuthConnectorMock, ProcessCredData(_, _)) + .WillOnce(Return(DM_OK)); + + // 打桩 WaitExpectEvent 期待返回ON_ERROR + EXPECT_CALL(*DmAuthStateMachineMock::dmAuthStateMachineMock, WaitExpectEvent(_)) + .WillOnce(Return(ON_ERROR)); + + EXPECT_EQ(authState->Action(context), DM_OK); +} + +// AuthSrcPinAuthDoneState 测试用例 +// Action 接口 异常流程 第一次返回其它事件 期待返回ERR_DM_FAILED +// 打桩 ProcessCredData 期待返回DM_OK +// 打桩 WaitExpectEvent 期待返回ON_REQUEST +HWTEST_F(AuthPinAuthStateTest, AuthSrcPinAuthDoneState_005, testing::ext::TestSize.Level1) +{ + std::shared_ptr authState = std::make_shared(); + + // 打桩 ProcessCredData 期待返回DM_OK + EXPECT_CALL(*hiChainAuthConnectorMock, ProcessCredData(_, _)) + .WillOnce(Return(DM_OK)); + + // 打桩 WaitExpectEvent 期待返回ON_REQUEST + EXPECT_CALL(*DmAuthStateMachineMock::dmAuthStateMachineMock, WaitExpectEvent(_)) + .WillOnce(Return(ON_REQUEST)); + + EXPECT_EQ(authState->Action(context), ERR_DM_FAILED); +} + +// AuthSrcPinAuthDoneState 测试用例 +// Action 接口 重试流程 期待返回DM_OK +// 打桩 ProcessCredData 期待返回DM_OK +// 打桩 WaitExpectEvent 期待第一次返回ON_SESSION_KEY_RETURNED 第二次返回ON_ERROR +HWTEST_F(AuthPinAuthStateTest, AuthSrcPinAuthDoneState_006, testing::ext::TestSize.Level1) +{ + std::shared_ptr authState = std::make_shared(); + + // 打桩 ProcessCredData 期待返回DM_OK + EXPECT_CALL(*hiChainAuthConnectorMock, ProcessCredData(_, _)) + .WillOnce(Return(DM_OK)); + + // 打桩 WaitExpectEvent 期待第一次返回ON_SESSION_KEY_RETURNED 第二次返回ON_ERROR + EXPECT_CALL(*DmAuthStateMachineMock::dmAuthStateMachineMock, WaitExpectEvent(_)) + .WillOnce(Return(ON_SESSION_KEY_RETURNED)) + .WillOnce(Return(ON_ERROR)); + + EXPECT_EQ(authState->Action(context), DM_OK); +} + +// AuthSrcPinAuthDoneState 测试用例 +// Action 接口 异常流程 期待返回ERR_DM_FAILED +// 打桩 ProcessCredData 期待返回DM_OK +// 打桩 WaitExpectEvent 期待第一次返回ON_SESSION_KEY_RETURNED 第二次返回ON_REQUEST +HWTEST_F(AuthPinAuthStateTest, AuthSrcPinAuthDoneState_007, testing::ext::TestSize.Level1) +{ + std::shared_ptr authState = std::make_shared(); + + // 打桩 ProcessCredData 期待返回DM_OK + EXPECT_CALL(*hiChainAuthConnectorMock, ProcessCredData(_, _)) + .WillOnce(Return(DM_OK)); + + // 打桩 WaitExpectEvent 期待第一次返回ON_SESSION_KEY_RETURNED 第二次返回ON_REQUEST + EXPECT_CALL(*DmAuthStateMachineMock::dmAuthStateMachineMock, WaitExpectEvent(_)) + .WillOnce(Return(ON_SESSION_KEY_RETURNED)) + .WillOnce(Return(ON_REQUEST)); + + EXPECT_EQ(authState->Action(context), ERR_DM_FAILED); +} + +// AuthSinkPinAuthDoneState 测试用例 +// GetStateType 接口 +HWTEST_F(AuthPinAuthStateTest, AuthSinkPinAuthDoneState_001, testing::ext::TestSize.Level1) +{ + std::shared_ptr authState = std::make_shared(); + EXPECT_EQ(authState->GetStateType(), DmAuthStateType::AUTH_SINK_PIN_AUTH_DONE_STATE); +} + +// AuthSinkPinAuthDoneState 测试用例 +// Action 接口 正常流程,期待返回DM_OK +HWTEST_F(AuthPinAuthStateTest, AuthSinkPinAuthDoneState_002, testing::ext::TestSize.Level1) +{ + std::shared_ptr authState = std::make_shared(); + + EXPECT_EQ(authState->Action(context), DM_OK); +} + +} +} \ No newline at end of file diff --git a/test/unittest/UTTest_auth_pin_auth_state.h b/test/unittest/UTTest_auth_pin_auth_state.h new file mode 100644 index 000000000..0cd480ebd --- /dev/null +++ b/test/unittest/UTTest_auth_pin_auth_state.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2025 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 UTTEST_AUTH_PIN_AUTH_STATE_H +#define UTTEST_AUTH_PIN_AUTH_STATE_H + +#include +#include "device_manager_service_listener.h" +#include "hichain_auth_connector_mock.h" +#include "auth_manager.h" + +namespace OHOS { +namespace DistributedHardware { + +class AuthPinAuthStateTest : public testing::Test { +public: + static void SetUpTestCase(); + static void TearDownTestCase(); + void SetUp(); + void TearDown(); +private: + static inline std::shared_ptr hiChainAuthConnectorMock = + std::make_shared(); + std::shared_ptr softbusConnector; + std::shared_ptr listener; + std::shared_ptr hiChainAuthConnector; + std::shared_ptr authManager; + std::shared_ptr context; +}; + +} +} +#endif \ No newline at end of file diff --git a/test/unittest/mock/dm_auth_message_processor_mock.cpp b/test/unittest/mock/dm_auth_message_processor_mock.cpp new file mode 100644 index 000000000..e113adcad --- /dev/null +++ b/test/unittest/mock/dm_auth_message_processor_mock.cpp @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License") = 0; + * 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 "dm_auth_message_processor_mock.h" + +namespace OHOS { +namespace DistributedHardware { + +int32_t DmAuthMessageProcessor::SaveSessionKeyToDP(int32_t &skId) +{ + return DmAuthMessageProcessorMock::dmAuthMessageProcessorMock->SaveSessionKeyToDP(skId); +} + +} +} \ No newline at end of file diff --git a/test/unittest/mock/dm_auth_message_processor_mock.h b/test/unittest/mock/dm_auth_message_processor_mock.h new file mode 100644 index 000000000..5d9d35088 --- /dev/null +++ b/test/unittest/mock/dm_auth_message_processor_mock.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License") = 0; + * 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 DM_AUTH_MESSAGE_PROCESSOR_MOCK_H +#define DM_AUTH_MESSAGE_PROCESSOR_MOCK_H + +#include +#include "dm_auth_message_processor.h" + +namespace OHOS { +namespace DistributedHardware { + +class DmAuthMessageProcessorMock { +public: + MOCK_METHOD(int32_t, SaveSessionKeyToDP, (int32_t &)); + MOCK_METHOD(std::string, CreateMessage, (DmMessageType, std::shared_ptr)); + static inline std::shared_ptr dmAuthMessageProcessorMock = nullptr; +}; + +} +} +#endif \ No newline at end of file diff --git a/test/unittest/mock/dm_auth_state_machine_mock.cpp b/test/unittest/mock/dm_auth_state_machine_mock.cpp new file mode 100644 index 000000000..49da4bfb2 --- /dev/null +++ b/test/unittest/mock/dm_auth_state_machine_mock.cpp @@ -0,0 +1,27 @@ +/* + * 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 "dm_auth_state_machine_mock.h" + +namespace OHOS { +namespace DistributedHardware { + +DmEventType DmAuthStateMachine::WaitExpectEvent(DmEventType eventType) +{ + return DmAuthStateMachineMock::dmAuthStateMachineMock->WaitExpectEvent(eventType); +} + +} +} \ No newline at end of file diff --git a/test/unittest/mock/dm_auth_state_machine_mock.h b/test/unittest/mock/dm_auth_state_machine_mock.h new file mode 100644 index 000000000..9489d08fd --- /dev/null +++ b/test/unittest/mock/dm_auth_state_machine_mock.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License") = 0; + * 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 DM_AUTH_STATE_MACHINE_MOCK_H +#define DM_AUTH_STATE_MACHINE_MOCK_H + +#include +#include "dm_auth_state_machine.h" + +namespace OHOS { +namespace DistributedHardware { + +class DmAuthStateMachineMock { +public: + MOCK_METHOD(DmEventType, WaitExpectEvent, (DmEventType)); + static inline std::shared_ptr dmAuthStateMachineMock = nullptr; +}; + +} +} +#endif \ No newline at end of file diff --git a/test/unittest/mock/hichain_auth_connector_mock.cpp b/test/unittest/mock/hichain_auth_connector_mock.cpp index e6c8451c8..d1d2dcbe8 100644 --- a/test/unittest/mock/hichain_auth_connector_mock.cpp +++ b/test/unittest/mock/hichain_auth_connector_mock.cpp @@ -33,5 +33,49 @@ int32_t HiChainAuthConnector::ImportCredential(int32_t osAccountId, std::string { return DmHiChainAuthConnector::dmHiChainAuthConnector->ImportCredential(osAccountId, deviceId, publicKey); } + +// 处理凭据认证报文 +int32_t HiChainAuthConnector::ProcessCredData(int64_t authReqId, const std::string &data) +{ + return DmHiChainAuthConnector::dmHiChainAuthConnector->ProcessCredData(authReqId, data); +} + +// 生成凭据,返回凭据Id +int32_t HiChainAuthConnector::AddCredential(int32_t osAccountId, const std::string &authParams, std::string &creId) +{ + return DmHiChainAuthConnector::dmHiChainAuthConnector->AddCredential(osAccountId, authParams, creId); +} + +// 根据凭据Id导出公钥 +int32_t HiChainAuthConnector::ExportCredential(int32_t osAccountId, const std::string &credId, std::string &publicKey) +{ + return DmHiChainAuthConnector::dmHiChainAuthConnector->ExportCredential(osAccountId, credId, publicKey); +} + +// 凭据协商 +int32_t HiChainAuthConnector::AgreeCredential(int32_t osAccountId, const std::string selfCredId, + const std::string &authParams, std::string &credId) +{ + return DmHiChainAuthConnector::dmHiChainAuthConnector->AgreeCredential(osAccountId, selfCredId, authParams, credId); +} + +// 删除凭据 +int32_t HiChainAuthConnector::DeleteCredential(int32_t osAccountId, const std::string &creId) +{ + return DmHiChainAuthConnector::dmHiChainAuthConnector->DeleteCredential(osAccountId, creId); +} +// 凭据认证 pinCode pin码(点对点临时凭据必填) +int32_t HiChainAuthConnector::AuthCredential(int32_t osAccountId, int64_t authReqId, const std::string &credId, + const std::string &pinCode) +{ + return DmHiChainAuthConnector::dmHiChainAuthConnector->AuthCredential(osAccountId, authReqId, credId, pinCode); +} + +// pin码 认证 +int32_t HiChainAuthConnector::AuthCredentialPinCode(int32_t osAccountId, int64_t authReqId, int32_t pinCode) +{ + return DmHiChainAuthConnector::dmHiChainAuthConnector->AuthCredentialPinCode(osAccountId, authReqId, pinCode); +} + } // namespace DistributedHardware } // namespace OHOS \ No newline at end of file diff --git a/test/unittest/mock/hichain_auth_connector_mock.h b/test/unittest/mock/hichain_auth_connector_mock.h index 174867f64..a7c8d9e9f 100644 --- a/test/unittest/mock/hichain_auth_connector_mock.h +++ b/test/unittest/mock/hichain_auth_connector_mock.h @@ -30,6 +30,23 @@ public: virtual int32_t AuthDevice(int32_t pinCode, int32_t osAccountId, std::string udid, int64_t requestId) = 0; virtual int32_t ImportCredential(int32_t osAccountId, std::string deviceId, std::string publicKey) = 0; + + // 处理凭据认证报文 + virtual int32_t ProcessCredData(int64_t authReqId, const std::string &data) = 0; + // 生成凭据,返回凭据Id + virtual int32_t AddCredential(int32_t osAccountId, const std::string &authParams, std::string &creId) = 0; + // 根据凭据Id导出公钥 + virtual int32_t ExportCredential(int32_t osAccountId, const std::string &credId, std::string &publicKey) = 0; + // 凭据协商 + virtual int32_t AgreeCredential(int32_t osAccountId, const std::string selfCredId, const std::string &authParams, + std::string &credId) = 0; + // 删除凭据 + virtual int32_t DeleteCredential(int32_t osAccountId, const std::string &creId) = 0; + // 凭据认证 pinCode pin码(点对点临时凭据必填) + virtual int32_t AuthCredential(int32_t osAccountId, int64_t authReqId, const std::string &credId, + const std::string &pinCode) = 0; + // pin码 认证 + virtual int32_t AuthCredentialPinCode(int32_t osAccountId, int64_t authReqId, int32_t pinCode) = 0; public: static inline std::shared_ptr dmHiChainAuthConnector = nullptr; }; @@ -39,6 +56,14 @@ public: MOCK_METHOD(bool, QueryCredential, (std::string &, int32_t)); MOCK_METHOD(int32_t, AuthDevice, (int32_t, int32_t, std::string, int64_t)); MOCK_METHOD(int32_t, ImportCredential, (int32_t, std::string, std::string)); + + MOCK_METHOD(int32_t, ProcessCredData, (int64_t, const std::string &)); + MOCK_METHOD(int32_t, AddCredential, (int32_t, const std::string &, std::string &)); + MOCK_METHOD(int32_t, ExportCredential, (int32_t, const std::string &, std::string &)); + MOCK_METHOD(int32_t, AgreeCredential, (int32_t, const std::string, const std::string &, std::string &)); + MOCK_METHOD(int32_t, DeleteCredential, (int32_t, const std::string &)); + MOCK_METHOD(int32_t, AuthCredential, (int32_t, int64_t, const std::string &, const std::string &)); + MOCK_METHOD(int32_t, AuthCredentialPinCode, (int32_t, int64_t, int32_t)); }; } } diff --git a/test/unittest/mock/softbus_connector_mock.cpp b/test/unittest/mock/softbus_connector_mock.cpp index 171311d9e..77c65ea49 100644 --- a/test/unittest/mock/softbus_connector_mock.cpp +++ b/test/unittest/mock/softbus_connector_mock.cpp @@ -39,5 +39,10 @@ DmDeviceInfo SoftbusConnector::GetDeviceInfoByDeviceId(const std::string &device { return DmSoftbusConnector::dmSoftbusConnector->GetDeviceInfoByDeviceId(deviceId); } + +std::shared_ptr SoftbusConnector::GetSoftbusSession() +{ + return DmSoftbusConnector::dmSoftbusConnector->GetSoftbusSession(); +} } // namespace DistributedHardware } // namespace OHOS \ No newline at end of file diff --git a/test/unittest/mock/softbus_connector_mock.h b/test/unittest/mock/softbus_connector_mock.h index fa25cade0..a8caf1492 100644 --- a/test/unittest/mock/softbus_connector_mock.h +++ b/test/unittest/mock/softbus_connector_mock.h @@ -30,6 +30,7 @@ public: virtual bool CheckIsOnline(const std::string &targetDeviceId) = 0; virtual std::vector GetProcessInfo() = 0; virtual DmDeviceInfo GetDeviceInfoByDeviceId(const std::string &deviceId) = 0; + virtual std::shared_ptr GetSoftbusSession(); public: static inline std::shared_ptr dmSoftbusConnector = nullptr; }; @@ -40,6 +41,7 @@ public: MOCK_METHOD(bool, CheckIsOnline, (const std::string &)); MOCK_METHOD(std::vector, GetProcessInfo, ()); MOCK_METHOD(DmDeviceInfo, GetDeviceInfoByDeviceId, (const std::string &deviceId)); + MOCK_METHOD(std::shared_ptr, GetSoftbusSession, ()); }; } } diff --git a/test/unittest/mock/softbus_session_mock.cpp b/test/unittest/mock/softbus_session_mock.cpp index 1c657174e..c85d7045d 100644 --- a/test/unittest/mock/softbus_session_mock.cpp +++ b/test/unittest/mock/softbus_session_mock.cpp @@ -25,5 +25,20 @@ int32_t SoftbusSession::GetPeerDeviceId(int32_t sessionId, std::string &peerDevI return DmSoftbusSession::dmSoftbusSession->GetPeerDeviceId(sessionId, peerDevId); } +int32_t SoftbusSession::SendData(int32_t sessionId, std::string &message) +{ + return DmSoftbusSession::dmSoftbusSession->SendData(sessionId, message); +} + +int32_t SoftbusSession::OpenAuthSessionWithPara(const std::string &deviceId, int32_t actionId, bool isEnable160m) +{ + return DmSoftbusSession::dmSoftbusSession->OpenAuthSessionWithPara(deviceId, actionId, isEnable160m); +} + +int32_t SoftbusSession::OpenAuthSession(const std::string &deviceId) +{ + return DmSoftbusSession::dmSoftbusSession->OpenAuthSession(deviceId); +} + } // namespace DistributedHardware } // namespace OHOS \ No newline at end of file diff --git a/test/unittest/mock/softbus_session_mock.h b/test/unittest/mock/softbus_session_mock.h index 732174ef4..9f386d183 100644 --- a/test/unittest/mock/softbus_session_mock.h +++ b/test/unittest/mock/softbus_session_mock.h @@ -27,6 +27,10 @@ public: virtual ~DmSoftbusSession() = default; public: virtual int32_t GetPeerDeviceId(int32_t sessionId, std::string &peerDevId) = 0; + virtual int32_t SendData(int32_t sessionId, std::string &message) = 0; + virtual int32_t OpenAuthSessionWithPara(const std::string &deviceId, int32_t actionId, bool isEnable160m) = 0; + virtual int32_t OpenAuthSession(const std::string &deviceId) = 0; + public: static inline std::shared_ptr dmSoftbusSession = nullptr; }; @@ -34,6 +38,9 @@ public: class SoftbusSessionMock : public DmSoftbusSession { public: MOCK_METHOD(int32_t, GetPeerDeviceId, (int32_t, std::string &)); + MOCK_METHOD(int32_t, SendData, (int32_t, std::string &)); + MOCK_METHOD(int32_t, OpenAuthSessionWithPara, (const std::string &, int32_t, bool)); + MOCK_METHOD(int32_t, OpenAuthSession, (const std::string &)); }; } } -- Gitee From 170bb3bab7d21d0835ef3c4759baa0f3393e7430 Mon Sep 17 00:00:00 2001 From: guoliang47 Date: Mon, 31 Mar 2025 11:12:17 +0800 Subject: [PATCH 2/4] merge dm_dev Signed-off-by: guoliang47 --- bundle.json | 2 - ext/pin_auth/BUILD.gn | 2 +- .../dependency/softbus/softbus_connector.h | 2 +- .../include/device_manager_service_impl.h | 11 +- .../src/authentication/dm_auth_manager.cpp | 44 +-- .../src/authentication_v2/auth_manager.cpp | 1 - .../dm_auth_message_processor.cpp | 4 +- .../src/authentication_v2/dm_auth_state.cpp | 54 +-- .../src/cryptomgr/crypto_mgr.cpp | 1 - .../dependency/hichain/hichain_connector.cpp | 4 - .../dependency/softbus/softbus_connector.cpp | 4 - .../src/device_manager_service_impl.cpp | 310 +++++++++--------- .../UTTest_device_manager_service_impl.cpp | 15 + utils/src/timer/dm_timer.cpp | 2 +- 14 files changed, 251 insertions(+), 205 deletions(-) diff --git a/bundle.json b/bundle.json index aabf1cb47..0158bd785 100644 --- a/bundle.json +++ b/bundle.json @@ -99,8 +99,6 @@ ], "header_base": "//foundation/distributedhardware/device_manager/interfaces/mini_tools_kits/native_cpp/include" } - },{ - "name": "//foundation/distributedhardware/device_manager/interfaces/cj/kits:cj_distributed_device_manager_ffi" }], "test": [ "//foundation/distributedhardware/device_manager:device_manager_test" diff --git a/ext/pin_auth/BUILD.gn b/ext/pin_auth/BUILD.gn index 4d4dcacbb..162965b9d 100644 --- a/ext/pin_auth/BUILD.gn +++ b/ext/pin_auth/BUILD.gn @@ -95,7 +95,7 @@ ohos_shared_library("devicemanagerext_pin_auth") { "resource_management:resmgr_napi_core", "safwk:system_ability_fwk", "samgr:samgr_proxy", - "cJSON:cjson" + "cJSON:cjson", ] defines = [ diff --git a/services/implementation/include/dependency/softbus/softbus_connector.h b/services/implementation/include/dependency/softbus/softbus_connector.h index cb776062f..a50897695 100644 --- a/services/implementation/include/dependency/softbus/softbus_connector.h +++ b/services/implementation/include/dependency/softbus/softbus_connector.h @@ -49,7 +49,7 @@ public: * @tc.desc: Get Connect Addr of the SoftbusConnector * @tc.type: FUNC */ - static shared_ptr GetConnectAddr(const std::string &deviceId, std::string &connectAddr); + static std::shared_ptr GetConnectAddr(const std::string &deviceId, std::string &connectAddr); /** * @tc.name: SoftbusConnector::GetUdidByNetworkId diff --git a/services/implementation/include/device_manager_service_impl.h b/services/implementation/include/device_manager_service_impl.h index 9639db127..138e03ef2 100644 --- a/services/implementation/include/device_manager_service_impl.h +++ b/services/implementation/include/device_manager_service_impl.h @@ -55,7 +55,6 @@ public: struct Config { std::string pkgName; std::string authCode; - uint64_t tokenId; int32_t authenticationType{0}; }; @@ -173,6 +172,7 @@ private: std::string GetUdidHashByNetworkId(const std::string &networkId); void HandleOffline(DmDeviceState devState, DmDeviceInfo &devInfo); void HandleOnline(DmDeviceState devState, DmDeviceInfo &devInfo); + void PutIdenticalAccountToAcl(std::string requestDeviceId, std::string trustDeviceId); std::map GetDeviceIdAndBindLevel(int32_t userId); std::multimap GetDeviceIdAndUserId(int32_t userId, const std::string &accountId); void HandleAccountLogoutEvent(int32_t remoteUserId, const std::string &remoteAccountHash, @@ -194,7 +194,14 @@ private: int32_t ParseConnectAddr(const PeerTargetId &targetId, std::string &deviceId, const std::map &bindParam); std::shared_ptr GetConfigByTokenId(); - int OpenAuthSession(const std::map &bindParam); + int OpenAuthSession(const std::string& deviceId, const std::map &bindParam); + + std::shared_ptr GetAuthMgrByMessage(int32_t msgType, int64_t logicalSessionId, + const JsonObject &jsonObject, std::shared_ptr curSession, uint64_t &tokenId); + int32_t TransferOldAuthMgr(int32_t msgType, int64_t logicalSessionId, std::shared_ptr curSession, + uint64_t tokenId, std::shared_ptr authMgr); + int32_t GetDeviceInfo(const PeerTargetId &targetId, std::string &addrType, std::string &deviceId, + std::shared_ptr deviceInfo, int32_t &index); // 清理资源线程 void CleanWorker(); diff --git a/services/implementation/src/authentication/dm_auth_manager.cpp b/services/implementation/src/authentication/dm_auth_manager.cpp index c900e2a20..baf9443a9 100644 --- a/services/implementation/src/authentication/dm_auth_manager.cpp +++ b/services/implementation/src/authentication/dm_auth_manager.cpp @@ -749,7 +749,7 @@ void DmAuthManager::OnGroupCreated(int64_t requestId, const std::string &groupId softbusConnector_->GetSoftbusSession()->SendData(authResponseContext_->sessionId, message); return; } - CompatiblePutAcl(); + int32_t pinCode = -1; if (authResponseContext_->authType == AUTH_TYPE_IMPORT_AUTH_CODE && !importAuthCode_.empty()) { GetAuthCode(authResponseContext_->hostPkgName, pinCode); @@ -807,10 +807,6 @@ void DmAuthManager::MemberJoinAuthRequest(int64_t requestId, int32_t status) if (timer_ != nullptr) { timer_->DeleteTimer(std::string(ADD_TIMEOUT_TASK)); } - if (status == DM_OK) { - LOGI("join group success."); - CompatiblePutAcl(); - } if (authResponseContext_->authType == AUTH_TYPE_IMPORT_AUTH_CODE) { HandleMemberJoinImportAuthCode(requestId, status); return; @@ -963,10 +959,7 @@ void DmAuthManager::AbilityNegotiate() GetDevUdid(localDeviceId, DEVICE_UUID_LENGTH); authResponseContext_->remoteAccountId = authResponseContext_->localAccountId; authResponseContext_->remoteUserId = authResponseContext_->localUserId; - if (GetBinderInfo() != DM_OK) { - LOGE("GetBinderInfo failed."); - return; - } + GetBinderInfo(); bool ret = hiChainConnector_->IsDevicesInP2PGroup(authResponseContext_->localDeviceId, localDeviceId); if (ret) { LOGE("DmAuthManager::EstablishAuthChannel device is in group"); @@ -975,6 +968,10 @@ void DmAuthManager::AbilityNegotiate() CompatiblePutAcl(); } authResponseContext_->reply = ERR_DM_AUTH_PEER_REJECT; + if (!CompareVersion(remoteVersion_, std::string(DM_VERSION_5_0_3)) && + authResponseContext_->authType == AUTH_TYPE_IMPORT_AUTH_CODE && !importAuthCode_.empty()) { + authResponseContext_->importAuthCode = Crypto::Sha256(importAuthCode_); + } } else { authResponseContext_->reply = ERR_DM_AUTH_REJECT; } @@ -1492,6 +1489,9 @@ void DmAuthManager::AuthenticateFinish() isAddingMember_ = false; isAuthenticateDevice_ = false; isAuthDevice_ = false; + if (authResponseContext_->isFinish) { + CompatiblePutAcl(); + } if (DeviceProfileConnector::GetInstance().GetTrustNumber(remoteDeviceId_) >= 1 && CompareVersion(remoteVersion_, std::string(DM_VERSION_4_1_5_1)) && softbusConnector_->CheckIsOnline(remoteDeviceId_) && authResponseContext_->isFinish) { @@ -1499,14 +1499,14 @@ void DmAuthManager::AuthenticateFinish() } DeleteAuthCode(); - if (timer_ != nullptr) { - timer_->DeleteAll(); - } if (authResponseState_ != nullptr) { SinkAuthenticateFinish(); } else if (authRequestState_ != nullptr) { SrcAuthenticateFinish(); } + if (timer_ != nullptr) { + timer_->DeleteAll(); + } isFinishOfLocal_ = true; authResponseContext_ = nullptr; authMessageProcessor_ = nullptr; @@ -2630,10 +2630,7 @@ void DmAuthManager::ProcRespNegotiateExt(const int32_t &sessionId) remoteDeviceId_ = authResponseContext_->localDeviceId; authResponseContext_->remoteAccountId = authResponseContext_->localAccountId; authResponseContext_->remoteUserId = authResponseContext_->localUserId; - if (GetBinderInfo() != DM_OK) { - LOGE("GetBinderInfo failed."); - return; - } + GetBinderInfo(); char localDeviceId[DEVICE_UUID_LENGTH] = {0}; GetDevUdid(localDeviceId, DEVICE_UUID_LENGTH); authResponseContext_->deviceId = authResponseContext_->localDeviceId; @@ -2642,6 +2639,10 @@ void DmAuthManager::ProcRespNegotiateExt(const int32_t &sessionId) DeviceProfileConnector::GetInstance().GetBindTypeByPkgName(authResponseContext_->hostPkgName, authResponseContext_->localDeviceId, authResponseContext_->deviceId); authResponseContext_->authed = !authResponseContext_->bindType.empty(); + if (authResponseContext_->authed && authResponseContext_->authType == AUTH_TYPE_IMPORT_AUTH_CODE && + !importAuthCode_.empty() && !CompareVersion(remoteVersion_, std::string(DM_VERSION_5_0_3))) { + authResponseContext_->importAuthCode = Crypto::Sha256(importAuthCode_); + } authResponseContext_->isIdenticalAccount = false; if (authResponseContext_->localAccountId == authResponseContext_->remoteAccountId && @@ -2688,6 +2689,12 @@ void DmAuthManager::ProcRespNegotiate(const int32_t &sessionId) softbusConnector_->GetSoftbusSession()->SendData(sessionId, message); return; } + if (IsIdenticalAccount()) { + jsonObject[TAG_IDENTICAL_ACCOUNT] = true; + if (authResponseContext_->authType == AUTH_TYPE_IMPORT_AUTH_CODE && !importAuthCode_.empty()) { + jsonObject[TAG_IMPORT_AUTH_CODE] = Crypto::Sha256(importAuthCode_); + } + } jsonObject[TAG_ACCOUNT_GROUPID] = GetAccountGroupIdHash(); authResponseContext_ = authResponseState_->GetAuthContext(); if (jsonObject[TAG_CRYPTO_SUPPORT].Get() == true && authResponseContext_->cryptoSupport) { @@ -3092,12 +3099,9 @@ int32_t DmAuthManager::GetBinderInfo() } ret = AppManager::GetInstance().GetHapTokenIdByName(authResponseContext_->localUserId, authResponseContext_->peerBundleName, 0, authResponseContext_->tokenId); -#ifndef DEVICE_MANAGER_COMMON_FLAG - if (ret == DM_OK && authResponseContext_->bindLevel != APP) { + if (ret != DM_OK) { LOGI("get tokenId by bundleName failed %{public}s", GetAnonyString(authResponseContext_->bundleName).c_str()); - return ERR_DM_FAILED; } -#endif return ret; } diff --git a/services/implementation/src/authentication_v2/auth_manager.cpp b/services/implementation/src/authentication_v2/auth_manager.cpp index 62308cef5..bb08246e8 100644 --- a/services/implementation/src/authentication_v2/auth_manager.cpp +++ b/services/implementation/src/authentication_v2/auth_manager.cpp @@ -41,7 +41,6 @@ namespace OHOS { namespace DistributedHardware { namespace { -static const char* PICKER_PROXY_SPLIT = "_pickerProxy_"; constexpr int32_t MIN_PIN_CODE = 100000; constexpr int32_t MAX_PIN_CODE = 999999; diff --git a/services/implementation/src/authentication_v2/dm_auth_message_processor.cpp b/services/implementation/src/authentication_v2/dm_auth_message_processor.cpp index 3c8944b7a..ff1242b68 100644 --- a/services/implementation/src/authentication_v2/dm_auth_message_processor.cpp +++ b/services/implementation/src/authentication_v2/dm_auth_message_processor.cpp @@ -204,13 +204,13 @@ int32_t DmAuthMessageProcessor::SaveSessionKey(const uint8_t *sessionKey, const LOGE("DmAuthMessageProcessor::SaveSessionKey failed, cryptoMgr_ is nullptr."); return ERR_DM_FAILED; } - return cryptoMgr_->SaveSessionKey(sessionKey, keyLen); + return cryptoMgr_->ProcessSessionKey(sessionKey, keyLen); } int32_t DmAuthMessageProcessor::SaveSessionKeyToDP(int32_t &skId) { if (cryptoMgr_ == nullptr) { - LOGE("DmAuthMessageProcessor::SaveSessionKey failed, cryptoMgr_ is nullptr."); + LOGE("DmAuthMessageProcessor::SaveSessionKeyToDP failed, cryptoMgr_ is nullptr."); return ERR_DM_FAILED; } uint32_t skLen = cryptoMgr_->GetSessionKey(nullptr); diff --git a/services/implementation/src/authentication_v2/dm_auth_state.cpp b/services/implementation/src/authentication_v2/dm_auth_state.cpp index 713dd8218..6fa327d92 100644 --- a/services/implementation/src/authentication_v2/dm_auth_state.cpp +++ b/services/implementation/src/authentication_v2/dm_auth_state.cpp @@ -77,11 +77,42 @@ bool HaveSameTokenId(std::shared_ptr context, const std::vectoraccessee.tokenIdHash); } -int32_t GetCredentialType(std::shared_ptr context, const JsonItemObject &credInfo, - std::vector &p2pCredIdList, std::vector &lnnCredIdList) +int32_t CheckCredInfo(const JsonItemObject &credInfo) { if (!credInfo[FILED_CRED_TYPE].IsNumberInteger() || !credInfo[FILED_AUTHORIZED_SCOPE].IsNumberInteger() || !credInfo[FILED_SUBJECT].IsNumberInteger()) { + return ERR_DM_FAILED; + } + return DM_OK; +} + +int32_t GetCredentialTypeByCrdInfo(std::shared_ptr context, const JsonItemObject &credInfo, + std::vector &p2pCredIdList, std::vector &lnnCredIdList) +{ + // point_to_point identical + int32_t credType = credInfo[FILED_CRED_TYPE].Get(); + int32_t authorizedScope = credInfo[FILED_AUTHORIZED_SCOPE].Get(); + std::vector appList; + DmAccess &remoteAccess = context->direction == DM_AUTH_SOURCE ? context->accessee : context->accesser; + credInfo[FILED_AUTHORIZED_APP_LIST].Get(appList); + if (credType == ACCOUNT_UNRELATED && + // 查询时无对端userId,只有查询出来后校验对端userId + remoteAccess.userIdHash == Crypto::Sha256(credInfo[FILED_PEER_USER_SPACE_ID].Get())) { + if (authorizedScope == SCOPE_APP && HaveSameTokenId(context, appList)) { + p2pCredIdList.push_back(credInfo[FILED_CRED_ID].Get()); + return DM_AUTH_CREDENTIAL_ACCOUNT_UNRELATED; + } else if (authorizedScope == SCOPE_USER && appList.empty()) { + lnnCredIdList.push_back(credInfo[FILED_CRED_ID].Get()); + } + } + + return DM_AUTH_CREDENTIAL_INVALID; +} + +int32_t GetCredentialType(std::shared_ptr context, const JsonItemObject &credInfo, + std::vector &p2pCredIdList, std::vector &lnnCredIdList) +{ + if (CheckCredInfo(credInfo) != DM_OK) { LOGE("credType, authorizedScope or subject invalid."); return DM_AUTH_CREDENTIAL_INVALID; } @@ -109,22 +140,7 @@ int32_t GetCredentialType(std::shared_ptr context, const JsonItem } } - // point_to_point identical - std::vector appList; - DmAccess &remoteAccess = context->direction == DM_AUTH_SOURCE ? context->accessee : context->accesser; - credInfo[FILED_AUTHORIZED_APP_LIST].Get(appList); - if (credType == ACCOUNT_UNRELATED && - // 查询时无对端userId,只有查询出来后校验对端userId - remoteAccess.userIdHash == Crypto::Sha256(credInfo[FILED_PEER_USER_SPACE_ID].Get())) { - if (authorizedScope == SCOPE_APP && HaveSameTokenId(context, appList)) { - p2pCredIdList.push_back(credInfo[FILED_CRED_ID].Get()); - return DM_AUTH_CREDENTIAL_ACCOUNT_UNRELATED; - } else if (authorizedScope == SCOPE_USER && appList.empty()) { - lnnCredIdList.push_back(credInfo[FILED_CRED_ID].Get()); - } - } - - return DM_AUTH_CREDENTIAL_INVALID; + return GetCredentialTypeByCrdInfo(context, credInfo, p2pCredIdList, lnnCredIdList); } int32_t DmQueryDmCredential(std::shared_ptr context, JsonObject &queryResult) @@ -451,7 +467,7 @@ int32_t DmAuthState::GetAuthCredentialInfo(std::shared_ptr contex DmAccess &access = context->direction == DM_AUTH_SOURCE ? context->accesser : context->accessee; std::vector profiles = DeviceProfileConnector::GetInstance().GetAllAccessControlProfile(); - LOGI("AuthSinkNegotiateStateMachine::GetAuthCredentialInfo success to get %{public}ld acls", profiles.size()); + LOGI("AuthSinkNegotiateStateMachine::GetAuthCredentialInfo success to get %{public}" PRId64 " acls", static_cast(profiles.size())); for (const DistributedDeviceProfile::AccessControlProfile &item : profiles) { bool isAclMatched = false; DistributedDeviceProfile::Accesser accesser = item.GetAccesser(); diff --git a/services/implementation/src/cryptomgr/crypto_mgr.cpp b/services/implementation/src/cryptomgr/crypto_mgr.cpp index 1e9e1cf22..9c65dd373 100644 --- a/services/implementation/src/cryptomgr/crypto_mgr.cpp +++ b/services/implementation/src/cryptomgr/crypto_mgr.cpp @@ -305,7 +305,6 @@ int32_t CryptoMgr::SaveSessionKey(const uint8_t *sessionKey, const uint32_t keyL std::lock_guard lock(sessionKeyMtx_); sessionKey_.key = (uint8_t*)calloc(keyLen, sizeof(uint8_t)); sessionKey_.keyLen = keyLen; - memcpy_s(sessionKey_.key, keyLen, sessionKey, keyLen); } return DM_OK; } diff --git a/services/implementation/src/dependency/hichain/hichain_connector.cpp b/services/implementation/src/dependency/hichain/hichain_connector.cpp index a5365a560..01430d31e 100644 --- a/services/implementation/src/dependency/hichain/hichain_connector.cpp +++ b/services/implementation/src/dependency/hichain/hichain_connector.cpp @@ -566,10 +566,6 @@ int32_t HiChainConnector::GetSyncGroupList(std::vector &groupList, st bool HiChainConnector::IsDevicesInP2PGroup(const std::string &hostDevice, const std::string &peerDevice) { LOGI("HiChainConnector::IsDevicesInP2PGroup"); - if (hostDevice == peerDevice || peerDevice == "" || hostDevice == "") { - LOGE("invalid param"); - return false; - } std::vector hostGroupInfoList; GetRelatedGroups(hostDevice, hostGroupInfoList); std::vector peerGroupInfoList; diff --git a/services/implementation/src/dependency/softbus/softbus_connector.cpp b/services/implementation/src/dependency/softbus/softbus_connector.cpp index 46e6449d9..3bcefa4e9 100644 --- a/services/implementation/src/dependency/softbus/softbus_connector.cpp +++ b/services/implementation/src/dependency/softbus/softbus_connector.cpp @@ -149,14 +149,10 @@ void SoftbusConnector::JoinLNNBySkId(int32_t sessionId, int32_t sessionKeyId, in addrInfo->info.session.sessionId = sessionId; addrInfo->deviceKeyId.hasDeviceKeyId = true; // 总线修改后适配 if (sessionKeyId > 0 && remoteSessionKeyId > 0) { - // addrInfo->info.session.localDeviceKeyId = sessionKeyId; - // addrInfo->info.session.remoteDeviceKeyId = remoteSessionKeyId; addrInfo->deviceKeyId.localDeviceKeyId = sessionKeyId; // 总线修改后适配 addrInfo->deviceKeyId.remoteDeviceKeyId = remoteSessionKeyId; // 总线修改后适配 LOGI("sessionKeyId valid"); } else { - // addrInfo->info.session.localDeviceKeyId = 0; - // addrInfo->info.session.remoteDeviceKeyId = 0; addrInfo->deviceKeyId.localDeviceKeyId = 0; // 总线修改后适配 addrInfo->deviceKeyId.remoteDeviceKeyId = 0; // 总线修改后适配 } diff --git a/services/implementation/src/device_manager_service_impl.cpp b/services/implementation/src/device_manager_service_impl.cpp index d494541b9..1a65f1ad2 100644 --- a/services/implementation/src/device_manager_service_impl.cpp +++ b/services/implementation/src/device_manager_service_impl.cpp @@ -58,7 +58,7 @@ constexpr const char* DM_TAG_LOGICAL_SESSION_ID = "logicalSessionId"; constexpr const char* DM_TAG_PEER_DISPLAY_ID = "peerDisplayId"; constexpr const char* DM_TAG_ACCESSEE_USER_ID = "accesseeUserId"; constexpr const char* DM_TAG_EXTRA_INFO = "extraInfo"; -constexpr const char* DM_TAG_ENABLE_NEW_PROTOCOL_FLAG = "enable_new_protocol_flag"; +constexpr const char* DM_TAG_ENABLE_NEW_PROTOCOL_FLAG = "sec_enhance_flag"; static int32_t GetEnableNewProtocolFlag() { @@ -192,7 +192,8 @@ void DeviceManagerServiceImpl::CleanWorker() { while (running_.load()) { auto logicalSessionId = FetchCleanEvent(); - LOGD("DeviceManagerServiceImpl::CleanWorker clean auth_mgr, its logicalSessionId: %{public}lld", logicalSessionId); + LOGD("DeviceManagerServiceImpl::CleanWorker clean auth_mgr, its logicalSessionId: %{public}lld", + logicalSessionId); CleanAuthMgrByLogicalSessionId(logicalSessionId); } LOGD("DeviceManagerServiceImpl::CleanWorker end"); @@ -270,14 +271,12 @@ int32_t DeviceManagerServiceImpl::InitAndRegisterAuthMgr(bool isSrcSide, uint64_ // 创建老auth_mar,只创建独立的一个 authMgr_ = std::make_shared(softbusConnector_, hiChainConnector_, listener_, hiChainAuthConnector_); + authMgr_->isAuthNewVersion_ = false; softbusConnector_->GetSoftbusSession()->RegisterSessionCallback(authMgr_); hiChainConnector_->RegisterHiChainCallback(authMgr_); hiChainAuthConnector_->RegisterHiChainAuthCallback(authMgr_); - return DM_OK; - } - if (GetEnableNewProtocolFlag() == 0) { - return DM_OK; } + return DM_OK; } // 已创建authMgr_,说明已有绑定事件,其他请求拒绝,返回错误码 LOGE("BindTarget failed, this device is being bound. Please try again later."); @@ -361,7 +360,8 @@ std::shared_ptr DeviceManagerServiceImpl::GetAuthMgrByTokenId(u static int64_t GenerateRandNum(int sessionId) { // 获取当前时间戳 - auto timestamp = std::chrono::duration_cast(std::chrono::high_resolution_clock::now().time_since_epoch()).count(); + auto timestamp = std::chrono::duration_cast(std::chrono::high_resolution_clock::now(). + time_since_epoch()).count(); // 生成随机数 std::random_device rd; @@ -744,47 +744,9 @@ std::shared_ptr DeviceManagerServiceImpl::GetCurSession(int sessionId) return curSession; } - -void DeviceManagerServiceImpl::OnBytesReceived(int sessionId, const void *data, unsigned int dataLen) +std::shared_ptr DeviceManagerServiceImpl::GetAuthMgrByMessage(int32_t msgType, + int64_t logicalSessionId, const JsonObject &jsonObject, std::shared_ptr curSession, uint64_t &tokenId) { - /* - 1、收到80报文创建auth_mgr - 2、收到80或90报文时,获取版本, 对比进行auth_mgr重建,执行老协议 - 3、分发报文 - */ - int32_t ret = DM_OK; - if (sessionId < 0 || data == nullptr || dataLen <= 0 || dataLen > MAX_DATA_LEN) { - LOGE("[OnBytesReceived] Fail to receive data from softbus with sessionId: %{public}d, dataLen: %{public}d.", - sessionId, dataLen); - return; - } - - LOGI("start, sessionId: %{public}d, dataLen: %{public}d.", sessionId, dataLen); - - JsonObject jsonObject = GetJsonObjectFromData(data, dataLen); - if (jsonObject.IsDiscarded() || !jsonObject[TAG_MSG_TYPE].IsNumberInteger()) { - LOGE("OnBytesReceived, MSG_TYPE parse failed."); - return; - } - int32_t msgType = jsonObject[TAG_MSG_TYPE].Get(); - int64_t logicalSessionId = 0; - if (jsonObject[DM_TAG_LOGICAL_SESSION_ID].IsNumberInteger()) { - logicalSessionId = jsonObject[DM_TAG_LOGICAL_SESSION_ID].Get(); - } - - std::shared_ptr curSession = nullptr; - if (GetEnableNewProtocolFlag() == 1) { - curSession = GetCurSession(sessionId); - if (curSession == nullptr) { - LOGE("InitAndRegisterAuthMgr, The physical link is not created."); - return; - } - } else { - curSession = std::make_shared(0, std::string("")); - curSession->version = DM_VERSION_5_0_5; - } - - uint64_t tokenId = 0; if (msgType == MSG_TYPE_REQ_ACL_NEGOTIATE) { if (logicalSessionId != 0) { curSession->logicalSessionSet_.insert(logicalSessionId); @@ -797,38 +759,118 @@ void DeviceManagerServiceImpl::OnBytesReceived(int sessionId, const void *data, if (jsonObject[DM_TAG_PEER_DISPLAY_ID].IsNumberInteger()) { displayId = jsonObject[DM_TAG_PEER_DISPLAY_ID].Get(); } - if (jsonObject.Contains(DM_TAG_EXTRA_INFO) && jsonObject[DM_TAG_EXTRA_INFO].IsObject()) { - if (jsonObject[DM_TAG_EXTRA_INFO][DM_TAG_ACCESSEE_USER_ID].IsNumberInteger()) { - userId = jsonObject[DM_TAG_EXTRA_INFO][DM_TAG_ACCESSEE_USER_ID].Get(); - } + if (jsonObject.Contains(DM_TAG_EXTRA_INFO) && jsonObject[DM_TAG_EXTRA_INFO].IsObject() && + jsonObject[DM_TAG_EXTRA_INFO][DM_TAG_ACCESSEE_USER_ID].IsNumberInteger()) { + userId = jsonObject[DM_TAG_EXTRA_INFO][DM_TAG_ACCESSEE_USER_ID].Get(); } tokenId = GetTokenId(false, displayId, userId, bundleName); if (tokenId == 0) { LOGE("OnBytesReceived, Get tokenId failed."); - return; + return nullptr; } if (logicalSessionId2TokenIdMap_.find(logicalSessionId) != logicalSessionId2TokenIdMap_.end()) { LOGE("OnBytesReceived, logicalSessionId exists in logicalSessionId2TokenIdMap_."); - return; + return nullptr; } logicalSessionId2TokenIdMap_[logicalSessionId] = tokenId; } if (InitAndRegisterAuthMgr(false, tokenId, curSession, logicalSessionId) != DM_OK) { // 内部已完成错误日志打印 - return; + return nullptr; } - } else { if (logicalSessionId != 0) { if (curSession->logicalSessionSet_.find(logicalSessionId) == curSession->logicalSessionSet_.end()) { LOGE("OnBytesReceived, The logical session ID does not exist in the physical session."); - return; + return nullptr; } tokenId = logicalSessionId2TokenIdMap_[logicalSessionId]; } } - auto authMgr = GetAuthMgrByTokenId(tokenId); + return GetAuthMgrByTokenId(tokenId); +} + +int32_t DeviceManagerServiceImpl::TransferOldAuthMgr(int32_t msgType, int64_t logicalSessionId, + std::shared_ptr curSession, uint64_t tokenId, std::shared_ptr authMgr) +{ + std::string pkgName; + PeerTargetId peerTargetId; + std::map bindParam; + authMgr->GetBindTargetParams(pkgName, peerTargetId, bindParam); + authMgr = nullptr; + authMgrMap_.erase(tokenId); + if (InitAndRegisterAuthMgr(false, tokenId, curSession, logicalSessionId) != DM_OK) { + // 内部已完成错误日志打印 + return ERR_DM_AUTH_FAILED; + } + + authMgr = GetAuthMgrByTokenId(tokenId); // 获取到老协议的authmgr + if (authMgr == nullptr) { + // 内部已完成错误日志打印 + return ERR_DM_AUTH_FAILED; + } + + int sessionId = curSession->sessionId_; + if (IsAuthManagerSourceByMessage(msgType)) { + // 发送停止报文 + // 不能走新协议的停止,新协议是信号机制,无法串行停止,会存在时延,导致未停止就创建了新对象, + // 然后新协议的超时机制会再次停止softbus + std::string endMessage = CreateTerminateMessage(); + (void)softbusConnector_->GetSoftbusSession()->SendData(sessionId, endMessage); + // 关闭新协议会话 + CleanSessionMapByLogicalSessionId(logicalSessionId); + + if (authMgr->BindTarget(pkgName, peerTargetId, bindParam, sessionId, 0) != DM_OK) { + LOGE("DeviceManagerServiceImpl::OnBytesReceived authManager BindTarget failed"); + return ERR_DM_AUTH_FAILED; + } + LOGI("DeviceManagerServiceImpl::OnBytesReceived src transfer to old version success"); + return DM_OK; + } + + // 参数2 sessionSide为0,authMgr_为空一定是sink端,src端会在BindTarget时创建协议对象 + authMgr->OnSessionOpened(sessionId, 0, 0); + LOGI("DeviceManagerServiceImpl::OnBytesReceived src transfer to old version success"); + return DM_OK; +} + + +void DeviceManagerServiceImpl::OnBytesReceived(int sessionId, const void *data, unsigned int dataLen) +{ + if (sessionId < 0 || data == nullptr || dataLen <= 0 || dataLen > MAX_DATA_LEN) { + LOGE("[OnBytesReceived] Fail to receive data from softbus with sessionId: %{public}d, dataLen: %{public}d.", + sessionId, dataLen); + return; + } + + LOGI("start, sessionId: %{public}d, dataLen: %{public}d.", sessionId, dataLen); + + JsonObject jsonObject = GetJsonObjectFromData(data, dataLen); + if (jsonObject.IsDiscarded() || !jsonObject[TAG_MSG_TYPE].IsNumberInteger()) { + LOGE("OnBytesReceived, MSG_TYPE parse failed."); + return; + } + int32_t msgType = jsonObject[TAG_MSG_TYPE].Get(); + int64_t logicalSessionId = 0; + if (jsonObject[DM_TAG_LOGICAL_SESSION_ID].IsNumberInteger()) { + logicalSessionId = jsonObject[DM_TAG_LOGICAL_SESSION_ID].Get(); + } + + std::shared_ptr curSession = nullptr; + if (GetEnableNewProtocolFlag() == 1) { + curSession = GetCurSession(sessionId); + if (curSession == nullptr) { + LOGE("InitAndRegisterAuthMgr, The physical link is not created."); + return; + } + } else { + curSession = std::make_shared(0, std::string("")); + curSession->version_ = DM_VERSION_5_0_5; + } + + uint64_t tokenId = 0; + auto authMgr = GetAuthMgrByMessage(msgType, logicalSessionId, jsonObject, curSession, tokenId); if (authMgr == nullptr) { // 内部已完成错误日志打印 return; @@ -838,51 +880,14 @@ void DeviceManagerServiceImpl::OnBytesReceived(int sessionId, const void *data, 监听80/90报文 新-老:src端收到90报文时发现版本不匹配问题,重新BindTarget 老-新:sink端收到80报文时发现版本不匹配问题,重新OnSessionOpened和OnBytesReceived - */ if (curSession->version_ == "" && authMgr->isAuthNewVersion_ && (msgType == MSG_TYPE_REQ_ACL_NEGOTIATE || msgType == MSG_TYPE_RESP_ACL_NEGOTIATE)) { - // IsMessageOldVersion内部会对session版本进行赋值,并解除对应物理会话信号量 if (IsMessageOldVersion(jsonObject, curSession)) { - std::string pkgName; - PeerTargetId peerTargetId; - std::map bindParam; - authMgr->GetBindTargetParams(pkgName, peerTargetId, bindParam); - authMgr = nullptr; - authMgrMap_.erase(tokenId); - if (InitAndRegisterAuthMgr(false, tokenId, curSession, logicalSessionId) != DM_OK) { - // 内部已完成错误日志打印 + if (TransferOldAuthMgr(msgType, logicalSessionId, curSession, tokenId, authMgr) != DM_OK) { + LOGE("DeviceManagerServiceImpl::OnBytesReceived TransferOldAuthMgr failed"); return; } - - authMgr = GetAuthMgrByTokenId(tokenId); // 获取到老协议的authmgr - if (authMgr == nullptr) { - // 内部已完成错误日志打印 - return; - } - authMgr->isAuthNewVersion_ = false; - - if (IsAuthManagerSourceByMessage(msgType)) { - // 发送停止报文 - // 不能走新协议的停止,新协议是信号机制,无法串行停止,会存在时延,导致未停止就创建了新对象, - // 然后新协议的超时机制会再次停止softbus - std::string endMessage = CreateTerminateMessage(); - (void)softbusConnector_->GetSoftbusSession()->SendData(sessionId, endMessage); - // 关闭新协议会话 - CleanSessionMapByLogicalSessionId(logicalSessionId); - - ret = authMgr->BindTarget(pkgName, peerTargetId, bindParam, sessionId, 0); - if (ret != DM_OK) { - LOGE("DeviceManagerServiceImpl::OnBytesReceived authManager BindTarget failed"); - return; - } - LOGI("DeviceManagerServiceImpl::OnBytesReceived src transfer to old version success"); - return; - } - - // 参数2 sessionSide为0,authMgr_为空一定是sink端,src端会在BindTarget时创建协议对象 - authMgr->OnSessionOpened(sessionId, 0, 0); - LOGI("DeviceManagerServiceImpl::OnBytesReceived src transfer to old version success"); } } std::string message = std::string(reinterpret_cast(data), dataLen); @@ -892,7 +897,6 @@ void DeviceManagerServiceImpl::OnBytesReceived(int sessionId, const void *data, authMgr->OnDataReceived(sessionId, message); } SoftbusSession::OnBytesReceived(sessionId, data, dataLen); - LOGI("DeviceManagerServiceImpl::OnBytesReceived in bytes received"); return; } @@ -1165,7 +1169,6 @@ std::shared_ptr DeviceManagerServiceImpl::GetConfigByTokenId() if (configsMap_.find(tokenId) == configsMap_.end()) { configsMap_[tokenId] = std::make_shared(); } - configsMap_[tokenId]->tokenId = tokenId; return configsMap_[tokenId]; } @@ -1181,7 +1184,6 @@ int32_t DeviceManagerServiceImpl::ImportAuthCode(const std::string &pkgName, con auto authMgr = GetAuthMgr(); if (authMgr == nullptr) { auto config = GetConfigByTokenId(); - LOGI("DeviceManagerServiceImpl::ImportAuthCode import for tokenId %{public}llu", config->tokenId); config->pkgName = pkgName; config->authCode = authCode; // 若多次注册,只保留最后一个 return DM_OK; @@ -1237,18 +1239,20 @@ static bool IsHmlSessionType(const JsonObject &jsonObject) return connSessionType == CONN_SESSION_TYPE_HML; } -int DeviceManagerServiceImpl::OpenAuthSession(const std::map &bindParam) +int DeviceManagerServiceImpl::OpenAuthSession(const std::string& deviceId, + const std::map &bindParam) { bool hmlEnable160M = false; int32_t hmlActionId = 0; JsonObject jsonObject = GetExtraJsonObject(bindParam); if (jsonObject.IsDiscarded()) { LOGE("extra string not a json type."); - goto error; + return -1; } if (IsHmlSessionType(jsonObject)) { if (GetHmlInfo(jsonObject, hmlEnable160M, hmlActionId) != DM_OK) { - goto error; + LOGE("OpenAuthSession failed, GetHmlInfo failed."); + return -1; } LOGI("hmlActionId %{public}d, hmlEnable160M %{public}d", hmlActionId, hmlEnable160M); return softbusConnector_->GetSoftbusSession()->OpenAuthSessionWithPara(deviceId, @@ -1288,8 +1292,7 @@ std::shared_ptr DeviceManagerServiceImpl::GetOrCreateSession(const std: return sessionsMap_[sessionId]; } - sessionId = OpenAuthSession(bindParam); - + sessionId = OpenAuthSession(deviceId, bindParam); if (sessionId < 0) { goto error; } @@ -1308,18 +1311,12 @@ error: return nullptr; } -int32_t DeviceManagerServiceImpl::ParseConnectAddr(const PeerTargetId &targetId, std::string &deviceId, - const std::map &bindParam) +int32_t DeviceManagerServiceImpl::GetDeviceInfo(const PeerTargetId &targetId, std::string &addrType, + std::string &deviceId, std::shared_ptr deviceInfo, int32_t &index) { - std::string addrType; - if (bindParam.count(PARAM_KEY_CONN_ADDR_TYPE) != 0) { - addrType = bindParam.at(PARAM_KEY_CONN_ADDR_TYPE); - } - int32_t index = 0; - std::shared_ptr deviceInfo = std::make_shared(); ConnectionAddr addr; if (!targetId.wifiIp.empty() && targetId.wifiIp.length() <= IP_STR_MAX_LEN) { - LOGI("AuthManager::ParseConnectAddr parse wifiIp: %{public}s.", GetAnonyString(targetId.wifiIp).c_str()); + LOGI("parse wifiIp: %{public}s.", GetAnonyString(targetId.wifiIp).c_str()); if (!addrType.empty()) { addr.type = static_cast(std::atoi(addrType.c_str())); } else { @@ -1334,7 +1331,7 @@ int32_t DeviceManagerServiceImpl::ParseConnectAddr(const PeerTargetId &targetId, deviceId = targetId.wifiIp; index++; } else if (!targetId.brMac.empty() && targetId.brMac.length() <= BT_MAC_LEN) { - LOGI("AuthManager::ParseConnectAddr parse brMac: %{public}s.", GetAnonyString(targetId.brMac).c_str()); + LOGI("parse brMac: %{public}s.", GetAnonyString(targetId.brMac).c_str()); addr.type = ConnectionAddrType::CONNECTION_ADDR_BR; if (memcpy_s(addr.info.br.brMac, BT_MAC_LEN, targetId.brMac.c_str(), targetId.brMac.length()) != 0) { LOGE("get brMac addr: %{public}s failed", GetAnonyString(targetId.brMac).c_str()); @@ -1344,7 +1341,7 @@ int32_t DeviceManagerServiceImpl::ParseConnectAddr(const PeerTargetId &targetId, deviceId = targetId.brMac; index++; } else if (!targetId.bleMac.empty() && targetId.bleMac.length() <= BT_MAC_LEN) { - LOGI("AuthManager::ParseConnectAddr parse bleMac: %{public}s.", GetAnonyString(targetId.bleMac).c_str()); + LOGI("parse bleMac: %{public}s.", GetAnonyString(targetId.bleMac).c_str()); addr.type = ConnectionAddrType::CONNECTION_ADDR_BLE; if (memcpy_s(addr.info.ble.bleMac, BT_MAC_LEN, targetId.bleMac.c_str(), targetId.bleMac.length()) != 0) { LOGE("get bleMac addr: %{public}s failed", GetAnonyString(targetId.bleMac).c_str()); @@ -1358,13 +1355,29 @@ int32_t DeviceManagerServiceImpl::ParseConnectAddr(const PeerTargetId &targetId, deviceId = targetId.bleMac; index++; } else { - LOGE("AuthManager::ParseConnectAddr failed, not addr."); + LOGE("DeviceManagerServiceImpl::GetDeviceInfo failed, not addr."); return ERR_DM_INPUT_PARA_INVALID; } + return DM_OK; +} +int32_t DeviceManagerServiceImpl::ParseConnectAddr(const PeerTargetId &targetId, std::string &deviceId, + const std::map &bindParam) +{ + std::string addrType; + if (bindParam.count(PARAM_KEY_CONN_ADDR_TYPE) != 0) { + addrType = bindParam.at(PARAM_KEY_CONN_ADDR_TYPE); + } + + std::shared_ptr deviceInfo = std::make_shared(); + int32_t index = 0; + int32_t ret = GetDeviceInfo(targetId, addrType, deviceId, deviceInfo, index); + if (ret != DM_OK) { + LOGE("GetDeviceInfo failed, ret: %{public}d", ret); + } deviceInfo->addrNum = static_cast(index); if (softbusConnector_->AddMemberToDiscoverMap(deviceId, deviceInfo) != DM_OK) { - LOGE("AuthManager::ParseConnectAddr failed, AddMemberToDiscoverMap failed."); + LOGE("DeviceManagerServiceImpl::ParseConnectAddr failed, AddMemberToDiscoverMap failed."); return ERR_DM_INPUT_PARA_INVALID; } deviceInfo = nullptr; @@ -1410,7 +1423,7 @@ int32_t DeviceManagerServiceImpl::BindTarget(const std::string &pkgName, const P } } else { curSession = std::make_shared(0, std::string("")); - curSession->version = DM_VERSION_5_0_5; + curSession->version_ = DM_VERSION_5_0_5; } // src端创建 @@ -1435,6 +1448,28 @@ int32_t DeviceManagerServiceImpl::BindTarget(const std::string &pkgName, const P return ERR_DM_AUTH_FAILED; } +void DeviceManagerServiceImpl::PutIdenticalAccountToAcl(std::string requestDeviceId, std::string trustDeviceId) +{ + LOGI("DeviceManagerServiceImpl::PutIdenticalAccountAcl start."); + char localDeviceId[DEVICE_UUID_LENGTH] = {0}; + Crypto::GetUdidHash(requestDeviceId, reinterpret_cast(localDeviceId)); + std::string localUdidHash = std::string(localDeviceId); + DmAclInfo aclInfo; + aclInfo.bindType = IDENTICAL_ACCOUNT; + aclInfo.trustDeviceId = trustDeviceId; + aclInfo.authenticationType = ALLOW_AUTH_ALWAYS; + aclInfo.deviceIdHash = localUdidHash; + DmAccesser accesser; + accesser.requestUserId = MultipleUserConnector::GetFirstForegroundUserId(); + accesser.requestAccountId = MultipleUserConnector::GetOhosAccountIdByUserId(accesser.requestUserId); + MultipleUserConnector::SetSwitchOldUserId(accesser.requestUserId); + MultipleUserConnector::SetSwitchOldAccountId(accesser.requestAccountId); + accesser.requestDeviceId = requestDeviceId; + DmAccessee accessee; + accessee.trustDeviceId = trustDeviceId; + DeviceProfileConnector::GetInstance().PutAccessControlList(aclInfo, accesser, accessee); +} + int32_t DeviceManagerServiceImpl::DpAclAdd(const std::string &udid) { LOGI("DeviceManagerServiceImpl DpAclAdd start."); @@ -2011,43 +2046,24 @@ int32_t DeviceManagerServiceImpl::DeleteAcl(const std::string &sessionName, cons LOGE("Acl not contain the sessionName bind data."); return ERR_DM_FAILED; } - if (bindLevel == static_cast(APP) || bindLevel == static_cast(SERVICE)) { - if (offlineParam.leftAclNumber != 0) { + auto authMgr = GetAuthMgr(); + if (authMgr == nullptr) { + LOGE("authMgr_ is nullptr"); + return ERR_DM_POINT_NULL; + } + if (offlineParam.leftAclNumber != 0) { + if (bindLevel == static_cast(APP) || bindLevel == static_cast(SERVICE)) { LOGI("The sessionName unbind app-level type leftAclNumber not zero."); softbusConnector_->SetProcessInfoVec(offlineParam.processVec); softbusConnector_->HandleDeviceOffline(remoteUdid); return DM_OK; } - if (offlineParam.leftAclNumber == 0) { - LOGI("The sessionName unbind app-level type leftAclNumber is zero."); - softbusConnector_->SetProcessInfoVec(offlineParam.processVec); - auto authMgr = GetAuthMgr(); - if (authMgr == nullptr) { - LOGE("authMgr_ is nullptr"); - return ERR_DM_POINT_NULL; - } - if (authMgr->isAuthNewVersion_) { - int32_t accountId = MultipleUserConnector::GetCurrentAccountUserID(); - for (auto credId : offlineParam.credIdVec) { - hiChainAuthConnector_->DeleteCredential(accountId, credId); - } - } else { - hiChainAuthConnector_->DeleteCredential(remoteUdid, MultipleUserConnector::GetCurrentAccountUserID()); - } - return DM_OK; - } - } - if (bindLevel == static_cast(DEVICE) && offlineParam.leftAclNumber != 0) { LOGI("Unbind deivce-level, retain identical account bind type."); return DM_OK; } - if (bindLevel == static_cast(DEVICE) && offlineParam.leftAclNumber == 0) { - LOGI("Unbind deivce-level, retain null."); - auto authMgr = GetAuthMgr(); - if (authMgr == nullptr) { - LOGE("authMgr_ is nullptr"); - return ERR_DM_POINT_NULL; - } + if (offlineParam.leftAclNumber == 0) { + LOGI("The sessionName unbind app-level type leftAclNumber is zero."); + softbusConnector_->SetProcessInfoVec(offlineParam.processVec); if (authMgr->isAuthNewVersion_) { int32_t accountId = MultipleUserConnector::GetCurrentAccountUserID(); for (auto credId : offlineParam.credIdVec) { diff --git a/test/unittest/UTTest_device_manager_service_impl.cpp b/test/unittest/UTTest_device_manager_service_impl.cpp index 22b4d9c4b..7c5db51b4 100644 --- a/test/unittest/UTTest_device_manager_service_impl.cpp +++ b/test/unittest/UTTest_device_manager_service_impl.cpp @@ -1305,6 +1305,21 @@ HWTEST_F(DeviceManagerServiceImplTest, BindTarget_001, testing::ext::TestSize.Le EXPECT_EQ(ret, ERR_DM_INPUT_PARA_INVALID); } +/** + * @tc.name: PutIdenticalAccountToAcl_001 + * @tc.type: FUNC + */ +HWTEST_F(DeviceManagerServiceImplTest, PutIdenticalAccountToAcl_001, testing::ext::TestSize.Level1) +{ + std::string requestDeviceId; + std::string trustDeviceId; + if (deviceManagerServiceImpl_ == nullptr) { + deviceManagerServiceImpl_ = std::make_shared(); + } + deviceManagerServiceImpl_->PutIdenticalAccountToAcl(requestDeviceId, trustDeviceId); + EXPECT_NE(deviceManagerServiceImpl_->hiChainConnector_, nullptr); +} + /** * @tc.name: DpAclAdd_001 * @tc.type: FUNC diff --git a/utils/src/timer/dm_timer.cpp b/utils/src/timer/dm_timer.cpp index b0049e9b8..e076bebbf 100644 --- a/utils/src/timer/dm_timer.cpp +++ b/utils/src/timer/dm_timer.cpp @@ -44,7 +44,7 @@ DmTimer::~DmTimer() int32_t DmTimer::StartTimer(std::string name, int32_t timeOut, TimerCallback callback) { - if (name.empty() || timeOut < MIN_TIME_OUT || timeOut > MAX_TIME_OUT || callback == nullptr) { + if (name.empty() || timeOut <= MIN_TIME_OUT || timeOut > MAX_TIME_OUT || callback == nullptr) { LOGE("DmTimer StartTimer input value invalid"); return ERR_DM_INPUT_PARA_INVALID; } -- Gitee From 3489fa4287da7f5e0bde1a1e78c233edebee88da Mon Sep 17 00:00:00 2001 From: zhangyunrui6 <463180417@qq.com> Date: Mon, 31 Mar 2025 10:27:21 +0800 Subject: [PATCH 3/4] fix compile err Signed-off-by: zhangyunrui6 <463180417@qq.com> --- services/implementation/src/authentication_v2/auth_manager.cpp | 3 ++- .../implementation/src/authentication_v2/dm_auth_state.cpp | 2 +- .../src/dependency/softbus/softbus_connector.cpp | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/services/implementation/src/authentication_v2/auth_manager.cpp b/services/implementation/src/authentication_v2/auth_manager.cpp index bb08246e8..8ce6301ca 100644 --- a/services/implementation/src/authentication_v2/auth_manager.cpp +++ b/services/implementation/src/authentication_v2/auth_manager.cpp @@ -41,6 +41,7 @@ namespace OHOS { namespace DistributedHardware { namespace { +const char* PICKER_PROXY_SPLITER = "_pickerProxy_"; constexpr int32_t MIN_PIN_CODE = 100000; constexpr int32_t MAX_PIN_CODE = 999999; @@ -591,7 +592,7 @@ void AuthManager::GetAuthParam(const std::string &sessionName, int32_t authType, { LOGI("Get auth param with sessionName %{public}s and extra %{public}s.", sessionName.c_str(), extra.c_str()); - std::string realPkgName = GetSubStr(sessionName, PICKER_PROXY_SPLIT, 1); + std::string realPkgName = GetSubStr(sessionName, PICKER_PROXY_SPLITER, 1); realPkgName = realPkgName.empty() ? sessionName : realPkgName; context_->sessionName = sessionName; context_->pkgLabel = GetBundleLable(sessionName); diff --git a/services/implementation/src/authentication_v2/dm_auth_state.cpp b/services/implementation/src/authentication_v2/dm_auth_state.cpp index 6fa327d92..1a0e961ba 100644 --- a/services/implementation/src/authentication_v2/dm_auth_state.cpp +++ b/services/implementation/src/authentication_v2/dm_auth_state.cpp @@ -467,7 +467,7 @@ int32_t DmAuthState::GetAuthCredentialInfo(std::shared_ptr contex DmAccess &access = context->direction == DM_AUTH_SOURCE ? context->accesser : context->accessee; std::vector profiles = DeviceProfileConnector::GetInstance().GetAllAccessControlProfile(); - LOGI("AuthSinkNegotiateStateMachine::GetAuthCredentialInfo success to get %{public}" PRId64 " acls", static_cast(profiles.size())); + LOGI("AuthSinkNegotiateStateMachine::GetAuthCredentialInfo success to get %{public}zu acls", profiles.size()); for (const DistributedDeviceProfile::AccessControlProfile &item : profiles) { bool isAclMatched = false; DistributedDeviceProfile::Accesser accesser = item.GetAccesser(); diff --git a/services/implementation/src/dependency/softbus/softbus_connector.cpp b/services/implementation/src/dependency/softbus/softbus_connector.cpp index 3bcefa4e9..dbc04d424 100644 --- a/services/implementation/src/dependency/softbus/softbus_connector.cpp +++ b/services/implementation/src/dependency/softbus/softbus_connector.cpp @@ -225,7 +225,7 @@ ConnectionAddr *SoftbusConnector::GetConnectAddrByType(DeviceInfo *deviceInfo, C return nullptr; } -shared_ptr SoftbusConnector::GetConnectAddr(const std::string &deviceId, std::string &connectAddr) +std::shared_ptr SoftbusConnector::GetConnectAddr(const std::string &deviceId, std::string &connectAddr) { DeviceInfo *deviceInfo = nullptr; std::shared_ptr deviceInfoPtr; -- Gitee From 02ef78bb27a824bca9cb12bff82accbfbc9e3833 Mon Sep 17 00:00:00 2001 From: xw1997-clike <2247596987@qq.com> Date: Mon, 31 Mar 2025 12:40:21 +0800 Subject: [PATCH 4/4] codecheck Signed-off-by: xw1997-clike <2247596987@qq.com> --- .../include/authentication/dm_auth_manager.h | 1 + .../src/authentication/dm_auth_manager.cpp | 23 ++++++++++++------- .../dependency/softbus/softbus_connector.cpp | 6 ++--- .../src/device_manager_service_impl.cpp | 6 ++--- 4 files changed, 20 insertions(+), 16 deletions(-) diff --git a/services/implementation/include/authentication/dm_auth_manager.h b/services/implementation/include/authentication/dm_auth_manager.h index a25620753..13be1cfc7 100644 --- a/services/implementation/include/authentication/dm_auth_manager.h +++ b/services/implementation/include/authentication/dm_auth_manager.h @@ -595,6 +595,7 @@ private: void ProcessReqPublicKey(); int32_t GetTokenIdByBundleName(int32_t userId, std::string &bundleName, int64_t &tokenId); bool CheckBindLevel(const JsonItemObject &jsonObj, const std::string &key, int32_t &bindLevel); + int32_t ProcessPinCode(const std::string &jsonStr); private: std::shared_ptr softbusConnector_; diff --git a/services/implementation/src/authentication/dm_auth_manager.cpp b/services/implementation/src/authentication/dm_auth_manager.cpp index baf9443a9..f966b086a 100644 --- a/services/implementation/src/authentication/dm_auth_manager.cpp +++ b/services/implementation/src/authentication/dm_auth_manager.cpp @@ -1901,15 +1901,8 @@ int32_t DmAuthManager::OnUserOperation(int32_t action, const std::string ¶ms } break; case USER_OPERATION_TYPE_DONE_PINCODE_INPUT: - { - JsonObject jsonObject(params); - if (jsonObject.IsDiscarded()) { - LOGE("OnUserOperation jsonStr error"); + if (ProcessPinCode(params) != DM_OK) { return ERR_DM_INPUT_PARA_INVALID; - } - if (jsonObject[PIN_CODE_KEY].IsNumberInteger()) { - ProcessPincode(jsonObject[PIN_CODE_KEY].Get()); - } } info.stageRes = static_cast(StageRes::STAGE_SUCC); if (!DmRadarHelper::GetInstance().ReportAuthInputPinBox(info)) { @@ -3360,5 +3353,19 @@ void DmAuthManager::CloseAuthSession(const int32_t sessionId) CHECK_NULL_VOID(softbusConnector_->GetSoftbusSession()); softbusConnector_->GetSoftbusSession()->CloseAuthSession(sessionId); } + +int32_t DmAuthManager::ProcessPinCode(const std::string &jsonStr) +{ + JsonObject jsonObject(jsonStr); + if (jsonObject.IsDiscarded()) { + LOGE("OnUserOperation jsonStr error"); + return ERR_DM_FAILED; + } + if (jsonObject.Contains(PIN_CODE_KEY) && jsonObject[PIN_CODE_KEY].IsNumberInteger()) { + ProcessPincode(jsonObject[PIN_CODE_KEY].Get()); + } + return DM_OK; +} + } // namespace DistributedHardware } // namespace OHOS diff --git a/services/implementation/src/dependency/softbus/softbus_connector.cpp b/services/implementation/src/dependency/softbus/softbus_connector.cpp index dbc04d424..f9668189d 100644 --- a/services/implementation/src/dependency/softbus/softbus_connector.cpp +++ b/services/implementation/src/dependency/softbus/softbus_connector.cpp @@ -140,8 +140,8 @@ void SoftbusConnector::JoinLNNBySkId(int32_t sessionId, int32_t sessionKeyId, in LOGE("addrInfo is nullptr."); return; } - if (addrInfo->type == CONNECTION_ADDR_BLE && Crypto::ConvertHexStringToBytes(addrInfo->info.ble.udidHash, UDID_HASH_LEN, - udidHash.c_str(), udidHash.length()) != DM_OK) { + if (addrInfo->type == CONNECTION_ADDR_BLE && Crypto::ConvertHexStringToBytes(addrInfo->info.ble.udidHash, + UDID_HASH_LEN, udidHash.c_str(), udidHash.length()) != DM_OK) { LOGE("convert remoteUdid hash failed, udidHash: %{public}s.", GetAnonyString(udidHash).c_str()); return; } @@ -228,7 +228,6 @@ ConnectionAddr *SoftbusConnector::GetConnectAddrByType(DeviceInfo *deviceInfo, C std::shared_ptr SoftbusConnector::GetConnectAddr(const std::string &deviceId, std::string &connectAddr) { DeviceInfo *deviceInfo = nullptr; - std::shared_ptr deviceInfoPtr; std::shared_ptr connectAddrPtr = std::make_shared(); { std::lock_guard lock(discoveryDeviceInfoMutex_); @@ -237,7 +236,6 @@ std::shared_ptr SoftbusConnector::GetConnectAddr(const std::stri LOGE("deviceInfo not found by deviceId: %{public}s.", GetAnonyString(deviceId).c_str()); return nullptr; } - deviceInfoPtr = iter->second; deviceInfo = iter->second.get(); } if (deviceInfo->addrNum <= 0 || deviceInfo->addrNum >= CONNECTION_ADDR_MAX) { diff --git a/services/implementation/src/device_manager_service_impl.cpp b/services/implementation/src/device_manager_service_impl.cpp index 1a65f1ad2..d32cd18c8 100644 --- a/services/implementation/src/device_manager_service_impl.cpp +++ b/services/implementation/src/device_manager_service_impl.cpp @@ -1442,10 +1442,8 @@ int32_t DeviceManagerServiceImpl::BindTarget(const std::string &pkgName, const P } auto authMgr = GetAuthMgr(); - if (authMgr != nullptr) { - return authMgr->BindTarget(pkgName, targetId, bindParam, sessionId, logicalSessionId); - } - return ERR_DM_AUTH_FAILED; + return (authMgr == nullptr) ? ERR_DM_AUTH_FAILED : + authMgr->BindTarget(pkgName, targetId, bindParam, sessionId, logicalSessionId); } void DeviceManagerServiceImpl::PutIdenticalAccountToAcl(std::string requestDeviceId, std::string trustDeviceId) -- Gitee