diff --git a/common/include/dm_constants.h b/common/include/dm_constants.h index e888cde225c58344c6e0da51a09a42526f3c7075..c06637e10c47599c13b94604f6b7a94986e80533 100755 --- a/common/include/dm_constants.h +++ b/common/include/dm_constants.h @@ -158,7 +158,13 @@ DM_EXPORT extern const char* PARAM_KEY_HML_ACTIONID; DM_EXPORT extern const char* CONN_SESSION_TYPE_HML; DM_EXPORT extern const char* CONN_SESSION_TYPE_BLE; DM_EXPORT extern const char* UN_BIND_PARAM_UDID_KEY; - +DM_EXPORT extern const char* PARAM_KEY_IS_PROXY_BIND; +DM_EXPORT extern const char* PARAM_KEY_IS_CALLING_PROXY_AS_SUBJECT; +DM_EXPORT extern const char* PARAM_KEY_SUBJECT_PROXYED_SUBJECTS; +DM_EXPORT extern const char* DM_VAL_TRUE; +DM_EXPORT extern const char* DM_VAL_FALSE; +DM_EXPORT extern const char* APP_USER_DATA; +DM_EXPORT extern const char* BUNDLE_INFO; DM_EXPORT extern const char* DM_BUSINESS_ID; // screen state @@ -185,6 +191,7 @@ 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_1_1; +extern const char* DM_VERSION_5_1_2; extern const char* DM_CURRENT_VERSION; extern const char* DM_ACL_AGING_VERSION; extern const char* DM_VERSION_5_0_OLD_MAX; // Estimated highest version number of the old version diff --git a/common/src/dm_constants.cpp b/common/src/dm_constants.cpp index 73eee5e9c48dbb4fbd72ca726c2bb87022404878..96a897a31c0c4fe40930eb9cdce1f8927935c380 100644 --- a/common/src/dm_constants.cpp +++ b/common/src/dm_constants.cpp @@ -148,7 +148,13 @@ const char* PARAM_KEY_HML_ACTIONID = "hmlActionId"; const char* CONN_SESSION_TYPE_HML = "HML"; const char* CONN_SESSION_TYPE_BLE = "BLE"; const char* UN_BIND_PARAM_UDID_KEY = "udidKey"; - +const char* PARAM_KEY_IS_PROXY_BIND = "isProxyBind"; +const char* PARAM_KEY_IS_CALLING_PROXY_AS_SUBJECT = "isCallingProxyAsSubject"; +const char* PARAM_KEY_SUBJECT_PROXYED_SUBJECTS = "subjectProxyOnes"; +const char* DM_VAL_TRUE = "true"; +const char* DM_VAL_FALSE = "false"; +const char* APP_USER_DATA = "appUserData"; +const char* BUNDLE_INFO = "bundleInfo"; const char* DM_BUSINESS_ID = "business_id"; // errCode map @@ -173,7 +179,8 @@ 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_1_1 = "5.1.1"; -const char* DM_CURRENT_VERSION = DM_VERSION_5_1_1; +const char* DM_VERSION_5_1_2 = "5.1.2"; +const char* DM_CURRENT_VERSION = DM_VERSION_5_1_2; const char* DM_ACL_AGING_VERSION = DM_VERSION_5_1_0; const char* DM_VERSION_5_0_OLD_MAX = "5.0.99"; // Estimated highest version number of the old version } // namespace DistributedHardware diff --git a/commondependency/include/deviceprofile_connector.h b/commondependency/include/deviceprofile_connector.h index 1aa8990e17a5031f78fa60426d4f400ebc7c6ec6..f48abb6c644c7c0e6411ffe1db51ee9cc145511c 100644 --- a/commondependency/include/deviceprofile_connector.h +++ b/commondependency/include/deviceprofile_connector.h @@ -254,6 +254,8 @@ public: const std::string &localUdid, int32_t localUserId, const std::string &localAccountId); DM_EXPORT int32_t DeleteSessionKey(int32_t userId, int32_t sessionKeyId); + DM_EXPORT int32_t GetSessionKey(int32_t userId, int32_t sessionKeyId, + std::vector &sessionKeyArray); DM_EXPORT int32_t SubscribeDeviceProfileInited( sptr dpInitedCallback); DM_EXPORT int32_t UnSubscribeDeviceProfileInited(); diff --git a/commondependency/src/deviceprofile_connector.cpp b/commondependency/src/deviceprofile_connector.cpp index 4b3a3b1dda40d5aa3b6c5316d630de34f47f3499..964636f867a85d96a64890c3a792e496de62f320 100644 --- a/commondependency/src/deviceprofile_connector.cpp +++ b/commondependency/src/deviceprofile_connector.cpp @@ -2756,6 +2756,18 @@ int32_t DeviceProfileConnector::DeleteSessionKey(int32_t userId, int32_t session return DM_OK; } +int32_t DeviceProfileConnector::GetSessionKey(int32_t userId, int32_t sessionKeyId, + std::vector &sessionKeyArray) +{ + int32_t ret = DistributedDeviceProfileClient::GetInstance().GetSessionKey(static_cast(userId), + sessionKeyId, sessionKeyArray); + 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/services/implementation/include/ability/dm_dialog_manager.h b/services/implementation/include/ability/dm_dialog_manager.h index 1a42ff984201e6026c924daaa0128778416c769a..9a0dfc958cf227fdf7146924866a96041b0d7d6e 100644 --- a/services/implementation/include/ability/dm_dialog_manager.h +++ b/services/implementation/include/ability/dm_dialog_manager.h @@ -77,6 +77,14 @@ public: { return hostPkgLabel_; } + static bool GetIsProxyBind() + { + return isProxyBind_; + } + static std::string GetAppUserData() + { + return appUserData_; + } private: DmDialogManager(); ~DmDialogManager(); @@ -102,6 +110,8 @@ private: static std::atomic isConnectSystemUI_; static sptr dialogConnectionCallback_; static DmDialogManager dialogMgr_; + static bool isProxyBind_; + static std::string appUserData_; }; } // namespace DistributedHardware } // namespace OHOS diff --git a/services/implementation/include/authentication_v2/auth_manager.h b/services/implementation/include/authentication_v2/auth_manager.h index 1c5395dfe90a59c1efa284c921e243311435cd12..8d46c6d21885d43b0035b3ea72ba84328efa9388 100644 --- a/services/implementation/include/authentication_v2/auth_manager.h +++ b/services/implementation/include/authentication_v2/auth_manager.h @@ -135,6 +135,8 @@ protected: void GetRemoteDeviceId(std::string &deviceId); private: void ParseHmlInfoInJsonObject(const JsonObject &jsonObject); + void ParseProxyJsonObject(const JsonObject &jsonObject); + void GetBindLevelByBundleName(std::string &bundleName, int32_t userId, int32_t &bindLevel); void ParseJsonObject(const JsonObject &jsonObject); void GetAuthParam(const std::string &sessionName, int32_t authType, const std::string &deviceId, const std::string &extra); @@ -144,6 +146,7 @@ private: bool IsAuthCodeReady(const std::string &sessionName); int32_t CheckAuthParamVaild(const std::string &sessionName, int32_t authType, const std::string &deviceId, const std::string &extra); + int32_t CheckProxyAuthParamVaild(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, diff --git a/services/implementation/include/authentication_v2/dm_auth_context.h b/services/implementation/include/authentication_v2/dm_auth_context.h index c2212ab40d15701ffc53a087e1b66a578377ae98..ca5c95eefca9ca27ca5b274107c5e0e5b5b2e7c8 100644 --- a/services/implementation/include/authentication_v2/dm_auth_context.h +++ b/services/implementation/include/authentication_v2/dm_auth_context.h @@ -96,6 +96,53 @@ enum DmUltrasonicInfo { DM_Ultrasonic_Invalid = 2, }; +typedef struct DmProxyAccess { + std::string pkgName; + std::string pkgLabel; + std::string bundleInfo; + std::string bundleName; + std::string peerBundleName; + int64_t tokenId; + std::string tokenIdHash; + int32_t bindLevel; + std::string transmitCredentialId; + std::string transmitPublicKey; + std::string publicKey; + int32_t sessionKeyId; + int32_t transmitSessionKeyId; + int64_t transmitSkTimeStamp; + int64_t skTimeStamp; // Used for aging, time is 2 days + bool isAuthed; + std::string aclTypeList; // Trust relationship list, used for data aging, KV format + std::string credTypeList; + std::string aclStrList; + std::map credentialInfos; + std::map aclProfiles; + std::string credInfoJson; + std::string aclTypeJson; +} DmProxyAccess; + +struct DmProxyAuthContext { + std::string proxyContextId; + std::string customData; + std::string pkgLabel; + bool needBind{true}; + bool needAgreeCredential{true}; + bool needAuth{true}; + bool IsNeedSetProxyRelationShip{false}; + DmProxyAccess proxyAccesser; + DmProxyAccess proxyAccessee; + bool operator==(const DmProxyAuthContext &other) const + { + return (proxyContextId == other.proxyContextId); + } + + bool operator<(const DmProxyAuthContext &other) const + { + return proxyContextId < other.proxyContextId; + } +}; + // Used for one-touch pairing struct DmPeerTargetAddress { // directly establish a Bluetooth connection @@ -153,6 +200,7 @@ struct DmAccess { int64_t lnnSkTimeStamp{0}; // Used for aging, time is 2 days, user-level credential timestamp int64_t skTimeStamp; // Used for aging, time is 2 days bool isAuthed; + bool isUserLevelAuthed; bool isOnline; bool isGenerateLnnCredential{true}; bool isPutLnnAcl{true}; @@ -197,6 +245,7 @@ struct DmAuthContext { int32_t connDelayCloseTime; int32_t reason{DM_OK}; int32_t reply; + std::string userOperationParam; int32_t state; int32_t hmlActionId = 0; bool authenticating; // Indicator whether authentication is in progress @@ -222,6 +271,13 @@ struct DmAuthContext { DmAccess accessee; std::multimap proxy; // Multimap where the key is the accessor and the value is the accesssee bool isNeedJoinLnn{true}; + bool IsProxyBind{false}; + bool IsCallingProxyAsSubject{true}; + bool IsNeedSetProxy{false}; + bool isNeedAuthorize{false}; + std::vector subjectProxyOnes; + std::string reUseCreId; + std::string srvExtarInfo; std::shared_ptr authStateMachine; std::shared_ptr authUiStateMgr; diff --git a/services/implementation/include/authentication_v2/dm_auth_manager_base.h b/services/implementation/include/authentication_v2/dm_auth_manager_base.h index 923379717bf71cf40f4907b38ae7284554189de7..01be5c0bdf4c0b3971cfa4a3f5dfd1f9d77c840a 100644 --- a/services/implementation/include/authentication_v2/dm_auth_manager_base.h +++ b/services/implementation/include/authentication_v2/dm_auth_manager_base.h @@ -56,6 +56,7 @@ extern const char* TAG_TOKENID; extern const char* TAG_HOST_PKGLABEL; extern const char* TAG_REMOTE_DEVICE_NAME; extern const char* TAG_HOST; +extern const char* TAG_PROXY_CONTEXT_ID; extern const char* APP_OPERATION_KEY; extern const char* TARGET_PKG_NAME_KEY; diff --git a/services/implementation/include/authentication_v2/dm_auth_message_processor.h b/services/implementation/include/authentication_v2/dm_auth_message_processor.h index a9b348b2f6e3855fbc3e849bceb6e04ff889550e..5192992bde31ffe817560ce771a8f50b76e43029 100644 --- a/services/implementation/include/authentication_v2/dm_auth_message_processor.h +++ b/services/implementation/include/authentication_v2/dm_auth_message_processor.h @@ -28,6 +28,8 @@ namespace OHOS { namespace DistributedHardware { struct DmAuthContext; struct DmAccess; +struct DmProxyAuthContext; +struct DmProxyAccess; extern const char* TAG_LNN_PUBLIC_KEY; extern const char* TAG_TRANSMIT_PUBLIC_KEY; @@ -200,11 +202,20 @@ public: // Save the permanent session key to the data profile int32_t SaveSessionKeyToDP(int32_t userId, int32_t &skId); - + int32_t SaveDerivativeSessionKeyToDP(int32_t userId, const std::string &suffix, int32_t &skId); + int32_t GetSessionKey(int32_t userId, int32_t &skId); // Save the current access control list int32_t PutAccessControlList(std::shared_ptr context, DmAccess &access, std::string trustDeviceId); - + int32_t SetProxyAccess(std::shared_ptr context, DmProxyAuthContext &proxyAuthContext, + DistributedDeviceProfile::Accesser &accesser, DistributedDeviceProfile::Accessee &accessee); + int32_t PutProxyAccessControlList(std::shared_ptr context, + DistributedDeviceProfile::AccessControlProfile &profile, DistributedDeviceProfile::Accesser &accesser, + DistributedDeviceProfile::Accessee &accessee); + bool IsExistTheToken(JsonObject &proxyObj, int64_t tokenId); + void SetAclProxyRelate(std::shared_ptr context); + void SetAclProxyRelate(std::shared_ptr context, + DistributedDeviceProfile::AccessControlProfile &profile); // 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:{...}} @@ -217,17 +228,22 @@ private: // Used to encrypt the synchronization message int32_t EncryptSyncMessage(std::shared_ptr &context, DmAccess &accessSide, std::string &encSyncMsg); + int32_t CreateProxyAccessMessage(std::shared_ptr &context, JsonObject &syncMsgJson); // 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); + int32_t ParseProxyNegotiateMessage(const JsonObject &jsonObject, std::shared_ptr context); // Parse the 90 message int32_t ParseMessageRespAclNegotiate(const JsonObject &json, std::shared_ptr context); + int32_t ParseMessageProxyRespAclNegotiate(const JsonObject &jsonObject, std::shared_ptr context); // Parse the 100 message int32_t ParseMessageReqUserConfirm(const JsonObject &json, std::shared_ptr context); + int32_t ParseMessageProxyReqUserConfirm(const JsonObject &json, std::shared_ptr context); // Parse the 110 message int32_t ParseMessageRespUserConfirm(const JsonObject &json, std::shared_ptr context); + int32_t ParseMessageProxyRespUserConfirm(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 @@ -240,6 +256,7 @@ private: int32_t ParseMessageReqCredExchange(const JsonObject &jsonObject, std::shared_ptr context); // Parse the 150 message int32_t ParseMessageRspCredExchange(const JsonObject &jsonObject, std::shared_ptr context); + int32_t ParseProxyCredExchangeToSync(std::shared_ptr &context, JsonObject &jsonObject); // Parse the 161, 170, and 171 messages int32_t ParseMessageNegotiateTransmit(const JsonObject &jsonObject, std::shared_ptr context); // Parse the 180 message @@ -262,10 +279,13 @@ private: // Create the 80 message int32_t CreateNegotiateMessage(std::shared_ptr context, JsonObject &jsonObject); + int32_t CreateProxyNegotiateMessage(std::shared_ptr context, JsonObject &jsonObject); // Create the 90 message int32_t CreateRespNegotiateMessage(std::shared_ptr context, JsonObject &jsonObject); + int32_t CreateProxyRespNegotiateMessage(std::shared_ptr context, JsonObject &jsonObject); // Create the 100 message int32_t CreateMessageReqUserConfirm(std::shared_ptr context, JsonObject &json); + int32_t CreateMessageProxyReqUserConfirm(std::shared_ptr context, JsonObject &json); // Create the 110 message int32_t CreateMessageRespUserConfirm(std::shared_ptr context, JsonObject &json); // Create the 120 message @@ -280,6 +300,7 @@ private: int32_t CreateMessageReqCredExchange(std::shared_ptr context, JsonObject &jsonObject); // Create the 150 message int32_t CreateMessageRspCredExchange(std::shared_ptr context, JsonObject &jsonObject); + int32_t CreateProxyCredExchangeMessage(std::shared_ptr &context, JsonObject &jsonData); // Create the 160 message int32_t CreateMessageReqCredAuthStart(std::shared_ptr context, JsonObject &jsonObject); // Construct the 161, 170, and 171 credential authentication messages @@ -304,6 +325,7 @@ private: // Parse the sync message int32_t ParseSyncMessage(std::shared_ptr &context, DmAccess &access, JsonObject &jsonObject); + int32_t ParseProxyAccessToSync(std::shared_ptr &context, JsonObject &jsonObject); int32_t CreateMessageForwardUltrasonicStart(std::shared_ptr context, JsonObject &jsonObject); int32_t CreateMessageReverseUltrasonicStart(std::shared_ptr context, JsonObject &jsonObject); int32_t CreateMessageForwardUltrasonicNegotiate(std::shared_ptr context, JsonObject &jsonObject); diff --git a/services/implementation/include/authentication_v2/dm_auth_state.h b/services/implementation/include/authentication_v2/dm_auth_state.h index e761287008a2a2dd77de8afdc459d2821d3f99ec..d128017708d85f3cdcf2a5ad176b7ec7538f4967 100644 --- a/services/implementation/include/authentication_v2/dm_auth_state.h +++ b/services/implementation/include/authentication_v2/dm_auth_state.h @@ -155,19 +155,36 @@ public: void SetAclInfo(std::shared_ptr context); void FilterProfilesByContext(std::vector &profiles, std::shared_ptr context); + void UpdateCredInfo(std::shared_ptr context); + bool IsNeedBind(std::shared_ptr context); + bool IsNeedAgreeCredential(std::shared_ptr context); + bool IsNeedAuth(std::shared_ptr context); + bool GetSessionKey(std::shared_ptr context); + bool IsAclHasCredential(const DistributedDeviceProfile::AccessControlProfile &profile, + const std::string &credInfoJson, std::string &credId); int32_t GetAclBindType(std::shared_ptr context, std::string credId); int32_t GetOutputState(int32_t state); int32_t GetOutputReplay(const std::string &processName, int32_t replay); static uint64_t GetSysTimeMs(); static void DeleteAcl(std::shared_ptr context, const DistributedDeviceProfile::AccessControlProfile &profile); + static void DeleteCredential(std::shared_ptr context, int32_t userId, + const JsonItemObject &credInfo, const DistributedDeviceProfile::AccessControlProfile &profile); + static void DirectlyDeleteCredential(std::shared_ptr context, int32_t userId, + const JsonItemObject &credInfo); + static void DeleteAclAndSk(std::shared_ptr context, + const DistributedDeviceProfile::AccessControlProfile &profile); protected: bool NeedReqUserConfirm(std::shared_ptr context); - bool NeedAgreeCredential(std::shared_ptr context); bool NeedAgreeAcl(std::shared_ptr context); + bool ProxyNeedAgreeAcl(std::shared_ptr context); + bool GetReuseSkId(std::shared_ptr context, int32_t &skId); + void GetReuseACL(std::shared_ptr context, DistributedDeviceProfile::AccessControlProfile &profile); uint32_t GetCredType(std::shared_ptr context, const JsonItemObject &credInfo); + int32_t GetProxyCredInfo(std::shared_ptr context, const JsonItemObject &credInfo, + const std::vector &tokenIdHashList); uint32_t GetCredentialType(std::shared_ptr context, const JsonItemObject &credInfo); - bool HaveSameTokenId(std::shared_ptr context, const std::vector &tokenList); + bool HaveSameTokenId(std::shared_ptr context, const std::vector &tokenIdHashList); void SetProcessInfo(std::shared_ptr context); }; @@ -178,7 +195,9 @@ public: int32_t Action(std::shared_ptr context) override; private: void NegotiateCredential(std::shared_ptr context, JsonObject &credTypeNegoRsult); + void NegotiateProxyCredential(std::shared_ptr context); void NegotiateAcl(std::shared_ptr context, JsonObject &aclNegoRsult); + void NegotiateProxyAcl(std::shared_ptr context); void GetSrcCredentialInfo(std::shared_ptr context, JsonObject &credInfo); void GetIdenticalCredentialInfo(std::shared_ptr context, JsonObject &credInfo); void GetShareCredentialInfo(std::shared_ptr context, JsonObject &credInfo); @@ -186,6 +205,8 @@ private: void GetSrcAclInfo(std::shared_ptr context, JsonObject &credInfo, JsonObject &aclInfo); void GetSrcAclInfoForP2P(std::shared_ptr context, const DistributedDeviceProfile::AccessControlProfile &profile, JsonObject &credInfo, JsonObject &aclInfo); + void GetSrcProxyAclInfoForP2P(std::shared_ptr context, + const DistributedDeviceProfile::AccessControlProfile &profile); bool IdenticalAccountAclCompare(std::shared_ptr context, const DistributedDeviceProfile::Accesser &accesser, const DistributedDeviceProfile::Accessee &accessee); bool ShareAclCompare(std::shared_ptr context, @@ -203,7 +224,9 @@ private: JsonObject &credTypeJson); void GetSrcCredTypeForP2P(std::shared_ptr context, const JsonItemObject &credObj, JsonObject &aclInfo, JsonObject &credTypeJson, int32_t credType, std::vector &deleteCredInfo); + void GetSrcProxyCredTypeForP2P(std::shared_ptr context, std::vector &deleteCredInfo); void GetCustomDescBySinkLanguage(std::shared_ptr context); + void ResetBindLevel(std::shared_ptr context); }; class AuthSinkStatePinAuthComm { @@ -224,11 +247,19 @@ public: int32_t Action(std::shared_ptr context) override; private: void NegotiateCredential(std::shared_ptr context, JsonObject &credTypeNegoRsult); + void NegotiateProxyCredential(std::shared_ptr context); void NegotiateAcl(std::shared_ptr context, JsonObject &aclNegoRsult); + void NegotiateProxyAcl(std::shared_ptr context); int32_t ShowConfigDialog(std::shared_ptr context); + int32_t CreateProxyData(std::shared_ptr context, JsonObject &jsonObj); + void GetBundleLabel(std::shared_ptr context); void ReadServiceInfo(std::shared_ptr context); void MatchFallBackCandidateList(std::shared_ptr context, DmAuthType authType); int32_t ProcessBindAuthorize(std::shared_ptr context); + int32_t ProcessUserAuthorize(std::shared_ptr context); + bool ProcessUserOption(std::shared_ptr context, const std::string &authorizeInfo); + bool ProcessServerAuthorize(std::shared_ptr context); + bool IsUserAuthorize(JsonObject ¶mObj, DmProxyAccess &access); int32_t ProcessNoBindAuthorize(std::shared_ptr context); std::string GetCredIdByCredType(std::shared_ptr context, int32_t credType); }; @@ -391,6 +422,7 @@ public: protected: std::string CreateAuthParamsString(DmAuthScope authorizedScope, DmAuthCredentialAddMethod method, const std::shared_ptr &authContext); + void GenerateTokenIds(const std::shared_ptr &authContext, JsonObject &jsonObj); int32_t GenerateCredIdAndPublicKey(DmAuthScope authorizedScope, std::shared_ptr &authContext); int32_t AgreeCredential(DmAuthScope authorizedScope, std::shared_ptr &authContext); }; @@ -428,6 +460,9 @@ public: virtual ~AuthSrcCredentialAuthDoneState() {}; DmAuthStateType GetStateType() override; int32_t Action(std::shared_ptr context) override; + int32_t SendCredentialAuthMessage(std::shared_ptr context, DmMessageType &msgType); + int32_t DerivativeSessionKey(std::shared_ptr context); + int32_t DerivativeProxySessionKey(std::shared_ptr context); private: std::string GenerateCertificate(std::shared_ptr context); }; @@ -444,6 +479,7 @@ public: virtual ~AuthSinkCredentialAuthNegotiateState() {}; DmAuthStateType GetStateType() override; int32_t Action(std::shared_ptr context) override; + int32_t DerivativeSessionKey(std::shared_ptr context); }; class AuthSinkNegotiateStateMachine : public DmAuthState { @@ -454,6 +490,7 @@ public: private: int32_t RespQueryAcceseeIds(std::shared_ptr context); + int32_t RespQueryProxyAcceseeIds(std::shared_ptr context); int32_t ProcRespNegotiate5_1_0(std::shared_ptr context); void GetSinkCredentialInfo(std::shared_ptr context, JsonObject &credInfo); void GetIdenticalCredentialInfo(std::shared_ptr context, JsonObject &credInfo); @@ -462,6 +499,8 @@ private: void GetSinkAclInfo(std::shared_ptr context, JsonObject &credInfo, JsonObject &aclInfo); void GetSinkAclInfoForP2P(std::shared_ptr context, const DistributedDeviceProfile::AccessControlProfile &profile, JsonObject &credInfo, JsonObject &aclInfo); + void GetSinkProxyAclInfoForP2P(std::shared_ptr context, + const DistributedDeviceProfile::AccessControlProfile &profile); bool IdenticalAccountAclCompare(std::shared_ptr context, const DistributedDeviceProfile::Accesser &accesser, const DistributedDeviceProfile::Accessee &accessee); bool ShareAclCompare(std::shared_ptr context, @@ -479,6 +518,7 @@ private: JsonObject &credTypeJson); void GetSinkCredTypeForP2P(std::shared_ptr context, const JsonItemObject &credObj, JsonObject &aclInfo, JsonObject &credTypeJson, int32_t credType, std::vector &deleteCredInfo); + void GetSinkProxyCredTypeForP2P(std::shared_ptr context, std::vector &deleteCredInfo); bool IsAntiDisturbanceMode(const std::string &businessId); bool ParseAndCheckAntiDisturbanceMode(const std::string &businessId, const std::string &businessValue); }; @@ -488,6 +528,7 @@ public: virtual ~AuthSinkDataSyncState() {}; DmAuthStateType GetStateType() override; int32_t Action(std::shared_ptr context) override; + int32_t DerivativeSessionKey(std::shared_ptr context); private: int32_t VerifyCertificate(std::shared_ptr context); }; @@ -497,6 +538,7 @@ public: virtual ~AuthSrcDataSyncState() {}; DmAuthStateType GetStateType() override; int32_t Action(std::shared_ptr context) override; + void GetPeerDeviceId(std::shared_ptr context, std::string &peerDeviceId); }; class AuthSinkFinishState : public DmAuthState { diff --git a/services/implementation/include/authentication_v2/dm_negotiate_process.h b/services/implementation/include/authentication_v2/dm_negotiate_process.h index 8a5938d40ff3c6bdf85ed9ed9ae648a05d31140c..fcca97d87fe2ec0140b5a2c532725f438ab4610d 100644 --- a/services/implementation/include/authentication_v2/dm_negotiate_process.h +++ b/services/implementation/include/authentication_v2/dm_negotiate_process.h @@ -180,6 +180,9 @@ public: NegotiateProcess(); ~NegotiateProcess(); int32_t HandleNegotiateResult(std::shared_ptr context); + int32_t HandleProxyNegotiateResult(std::shared_ptr context, int32_t result); + bool IsNeedSetProxyRelationShip(std::shared_ptr context, DmProxyAuthContext &proxyContext); + bool IsExistTheTokenId(const std::string extraData, const std::string tokenIdHash); private: CredType ConvertCredType(const std::string &credType); AclType ConvertAclType(const std::string &aclType); diff --git a/services/implementation/include/dependency/hichain/hichain_auth_connector.h b/services/implementation/include/dependency/hichain/hichain_auth_connector.h index 3a3fe46c6d7506eeae64655d41222496cd6af0d3..8c3234d36ec9a9af73b753ddfa7d5739bbf667d0 100644 --- a/services/implementation/include/dependency/hichain/hichain_auth_connector.h +++ b/services/implementation/include/dependency/hichain/hichain_auth_connector.h @@ -75,9 +75,11 @@ public: int32_t AuthCredential(int32_t osAccountId, int64_t authReqId, const std::string &credId, const std::string &pinCode); int32_t AuthCredentialPinCode(int32_t osAccountId, int64_t authReqId, const std::string &pinCode); - + int32_t AddTokensToCredential(const std::string &credId, int32_t userId, std::vector &tokenIds); + int32_t UpdateCredential(const std::string &credId, int32_t userId, std::vector &tokenIds); private: void FreeJsonString(char *jsonStr); + void FreeCharArray(char *charArray); static std::shared_ptr GetDeviceAuthCallback(int64_t id); private: diff --git a/services/implementation/src/ability/standard/dm_dialog_manager.cpp b/services/implementation/src/ability/standard/dm_dialog_manager.cpp index 11b35a76255b36d9020965614aa379a5bb77df07..22a398f7bf6e2fd3544c430a97f100e2bda69632 100644 --- a/services/implementation/src/ability/standard/dm_dialog_manager.cpp +++ b/services/implementation/src/ability/standard/dm_dialog_manager.cpp @@ -50,6 +50,8 @@ std::string DmDialogManager::targetDeviceName_ = ""; std::string DmDialogManager::pinCode_ = ""; std::string DmDialogManager::hostPkgLabel_ = ""; int32_t DmDialogManager::deviceType_ = -1; +bool DmDialogManager::isProxyBind_ = false; +std::string DmDialogManager::appUserData_ = ""; DmDialogManager DmDialogManager::dialogMgr_; sptr DmDialogManager::dialogConnectionCallback_( new (std::nothrow) DialogAbilityConnection()); @@ -96,6 +98,12 @@ void DmDialogManager::ShowConfirmDialog(const std::string param) if (IsString(jsonObject, TAG_HOST_PKGLABEL)) { hostPkgLabel = jsonObject[TAG_HOST_PKGLABEL].Get(); } + if (IsBool(jsonObject, PARAM_KEY_IS_PROXY_BIND)) { + isProxyBind_ = jsonObject[PARAM_KEY_IS_PROXY_BIND].Get(); + } + if (IsString(jsonObject, APP_USER_DATA)) { + appUserData_ = jsonObject[APP_USER_DATA].Get(); + } } bundleName_ = DM_UI_BUNDLE_NAME; @@ -193,6 +201,8 @@ void DmDialogManager::DialogAbilityConnection::OnAbilityConnectDone( if (DmDialogManager::GetAbilityName() == INPUT_ABILITY_NAME) { param["sysDialogZOrder"] = WINDOW_LEVEL_UPPER; } + param["isProxyBind"] = DmDialogManager::GetIsProxyBind(); + param["appUserData"] = DmDialogManager::GetAppUserData(); param["pinCode"] = DmDialogManager::GetPinCode(); param["deviceName"] = DmDialogManager::GetDeviceName(); param["appOperationStr"] = DmDialogManager::GetAppOperationStr(); diff --git a/services/implementation/src/authentication_v2/auth_manager.cpp b/services/implementation/src/authentication_v2/auth_manager.cpp index 8bd8aef10a3aceb80274bbba23adcfb7b4a65c0a..24967de41d9d5f65091e6c1fadf905dc46214c2b 100644 --- a/services/implementation/src/authentication_v2/auth_manager.cpp +++ b/services/implementation/src/authentication_v2/auth_manager.cpp @@ -469,6 +469,7 @@ void AuthManager::ParseJsonObject(const JsonObject &jsonObject) } ParseHmlInfoInJsonObject(jsonObject); + ParseProxyJsonObject(jsonObject); return; } @@ -613,6 +614,11 @@ int32_t AuthManager::AuthenticateDevice(const std::string &pkgName, int32_t auth LOGE("AuthManager::AuthenticateDevice failed, param is invaild."); return ret; } + ret = CheckProxyAuthParamVaild(extra); + if (ret != DM_OK) { + LOGE("CheckProxyAuthParamVaild failed."); + return ret; + } context_->isAuthenticateDevice = true; if (authType == AUTH_TYPE_CRE) { LOGI("AuthManager::AuthenticateDevice for credential type, joinLNN directly."); @@ -753,6 +759,7 @@ int32_t AuthSinkManager::OnUserOperation(int32_t action, const std::string ¶ case USER_OPERATION_TYPE_ALLOW_AUTH_ALWAYS: context_->confirmOperation = static_cast(action); context_->reply = USER_OPERATION_TYPE_ALLOW_AUTH; + context_->userOperationParam = params; if (action == USER_OPERATION_TYPE_CANCEL_AUTH) { LOGI("AuthSinkManager::OnUserOperation USER_OPERATION_TYPE_CANCEL_AUTH."); context_->reply = USER_OPERATION_TYPE_CANCEL_AUTH; @@ -1119,5 +1126,103 @@ int32_t AuthManager::HandleBusinessEvents(const std::string &businessId, int32_t LOGI("HandleBusinessEvents successfully stored reject_event."); return DM_OK; } +int32_t AuthManager::CheckProxyAuthParamVaild(const std::string &extra) +{ + LOGI("start."); + JsonObject jsonObject(extra); + if (jsonObject.IsDiscarded() || !IsString(jsonObject, PARAM_KEY_IS_PROXY_BIND)) { + return DM_OK; + } + if (jsonObject[PARAM_KEY_IS_PROXY_BIND].Get() != DM_VAL_TRUE) { + return DM_OK; + } + if (!AppManager::GetInstance().IsSystemSA()) { + LOGE("no proxy permission"); + return ERR_DM_NO_PERMISSION; + } + if (!jsonObject.Contains(PARAM_KEY_SUBJECT_PROXYED_SUBJECTS) || + !IsString(jsonObject, PARAM_KEY_SUBJECT_PROXYED_SUBJECTS)) { + LOGE("no subject proxyed apps"); + return ERR_DM_INPUT_PARA_INVALID; + } + std::string subjectProxyOnesStr = jsonObject[PARAM_KEY_SUBJECT_PROXYED_SUBJECTS].Get(); + JsonObject allProxyObj; + allProxyObj.Parse(subjectProxyOnesStr); + for (auto const &item : allProxyObj.Items()) { + if (!item.Contains(TAG_BUNDLE_NAME) || !IsString(item, TAG_BUNDLE_NAME)) { + LOGE("bundleName invalid"); + return ERR_DM_INPUT_PARA_INVALID; + } + if (!item.Contains(TAG_TOKENID) || !IsInt64(item, TAG_TOKENID)) { + LOGE("tokenId invalid"); + return ERR_DM_INPUT_PARA_INVALID; + } + } + return DM_OK; +} + +void AuthManager::ParseProxyJsonObject(const JsonObject &jsonObject) +{ + if (context_ == nullptr || jsonObject.IsDiscarded() || !IsString(jsonObject, PARAM_KEY_IS_PROXY_BIND) || + jsonObject[PARAM_KEY_IS_PROXY_BIND].Get() != DM_VAL_TRUE) { + return; + } + context_->IsProxyBind = true; + if (IsString(jsonObject, PARAM_KEY_IS_CALLING_PROXY_AS_SUBJECT) && + jsonObject[PARAM_KEY_IS_CALLING_PROXY_AS_SUBJECT].Get() == DM_VAL_FALSE) { + context_->IsCallingProxyAsSubject = false; + } + if (!jsonObject.Contains(PARAM_KEY_SUBJECT_PROXYED_SUBJECTS) || + !IsString(jsonObject, PARAM_KEY_SUBJECT_PROXYED_SUBJECTS)) { + LOGE("no subject proxyed apps"); + return; + } + std::string subjectProxyOnesStr = jsonObject[PARAM_KEY_SUBJECT_PROXYED_SUBJECTS].Get(); + JsonObject allProxyObj; + allProxyObj.Parse(subjectProxyOnesStr); + for (auto const &item : allProxyObj.Items()) { + if (!item.Contains(TAG_BUNDLE_NAME) || !IsString(item, TAG_BUNDLE_NAME)) { + LOGE("bundleName invalid"); + return; + } + if (!item.Contains(TAG_TOKENID) || !IsInt64(item, TAG_TOKENID)) { + LOGE("tokenId invalid"); + return; + } + std::string bundleName = item[TAG_BUNDLE_NAME].Get(); + if (context_->accesser.bundleName == bundleName) { + LOGE("proxy bundleName same as caller bundleName"); + return; + } + std::string peerBundleName = bundleName; + if (item.Contains(PARAM_KEY_PEER_BUNDLE_NAME) && IsString(item, PARAM_KEY_PEER_BUNDLE_NAME)) { + peerBundleName = item[PARAM_KEY_PEER_BUNDLE_NAME].Get(); + } + DmProxyAuthContext proxyAuthContext; + proxyAuthContext.proxyContextId = Crypto::Sha256(bundleName + peerBundleName); + if (std::find(context_->subjectProxyOnes.begin(), context_->subjectProxyOnes.end(), proxyAuthContext) == + context_->subjectProxyOnes.end()) { + proxyAuthContext.proxyAccesser.bundleName = bundleName; + proxyAuthContext.proxyAccesser.tokenId = item[TAG_TOKENID].Get(); + proxyAuthContext.proxyAccesser.tokenIdHash = + Crypto::GetTokenIdHash(std::to_string(proxyAuthContext.proxyAccesser.tokenId)); + proxyAuthContext.proxyAccessee.bundleName = peerBundleName; + GetBindLevelByBundleName(bundleName, context_->accesser.userId, proxyAuthContext.proxyAccesser.bindLevel); + context_->subjectProxyOnes.push_back(proxyAuthContext); + } + } +} + +void AuthManager::GetBindLevelByBundleName(std::string &bundleName, int32_t userId, int32_t &bindLevel) +{ + int64_t tokenId = 0; + if (AppManager::GetInstance().GetHapTokenIdByName(userId, bundleName, 0, tokenId) == DM_OK) { + bindLevel = DmRole::DM_ROLE_FA; + } else if (AppManager::GetInstance().GetNativeTokenIdByName(bundleName, tokenId) == DM_OK) { + bindLevel = DmRole::DM_ROLE_SA; + } else { + LOGE("src not contain the bundlename %{public}s.", bundleName.c_str()); + } +} } // 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 index 40a6620897f1b14dd13874948c57282e22345424..c0a6e1a8ab08ce06129d46869b0ff71b9c4463f0 100644 --- a/services/implementation/src/authentication_v2/auth_stages/auth_acl.cpp +++ b/services/implementation/src/authentication_v2/auth_stages/auth_acl.cpp @@ -92,6 +92,9 @@ int32_t AuthSinkDataSyncState::Action(std::shared_ptr context) // Query the ACL of the sink end. Compare the ACLs at both ends. context->softbusConnector->SyncLocalAclListProcess({context->accessee.deviceId, context->accessee.userId}, {context->accesser.deviceId, context->accesser.userId}, context->accesser.aclStrList); + if (GetSessionKey(context)) { + DerivativeSessionKey(context); + } // Synchronize the local SP information, the format is uncertain, not done for now context->authMessageProcessor->CreateAndSendMsg(MSG_TYPE_RESP_DATA_SYNC, context); context->accessee.deviceName = context->softbusConnector->GetLocalDeviceName(); @@ -104,11 +107,54 @@ DmAuthStateType AuthSinkDataSyncState::GetStateType() return DmAuthStateType::AUTH_SINK_DATA_SYNC_STATE; } +int32_t AuthSinkDataSyncState::DerivativeSessionKey(std::shared_ptr context) +{ + CHECK_NULL_RETURN(context, ERR_DM_POINT_NULL); + if (!context->IsProxyBind || context->subjectProxyOnes.empty()) { + return DM_OK; + } + context->accessee.transmitCredentialId = context->reUseCreId; + if (context->IsCallingProxyAsSubject && !context->accessee.isAuthed) { + int32_t skId = 0; + std::string suffix = context->accesser.deviceIdHash + context->accessee.deviceIdHash + + context->accesser.tokenIdHash + context->accessee.tokenIdHash; + int32_t ret = + context->authMessageProcessor->SaveDerivativeSessionKeyToDP(context->accessee.userId, suffix, skId); + if (ret != DM_OK) { + LOGE("AuthSinkDataSyncState::Action DP save user session key failed"); + return ret; + } + context->accessee.transmitSkTimeStamp = static_cast(DmAuthState::GetSysTimeMs()); + context->accessee.transmitSessionKeyId = skId; + } + for (auto &app : context->subjectProxyOnes) { + if (app.proxyAccessee.isAuthed) { + continue; + } + int32_t skId = 0; + std::string suffix = context->accesser.deviceIdHash + context->accessee.deviceIdHash + + app.proxyAccesser.tokenIdHash + app.proxyAccessee.tokenIdHash; + int32_t ret = + context->authMessageProcessor->SaveDerivativeSessionKeyToDP(context->accessee.userId, suffix, skId); + if (ret != DM_OK) { + LOGE("AuthSrcCredentialAuthDoneState::Action DP save user session key failed"); + return ret; + } + app.proxyAccessee.skTimeStamp = static_cast(DmAuthState::GetSysTimeMs()); + app.proxyAccessee.transmitSessionKeyId = skId; + if (!context->reUseCreId.empty()) { + app.proxyAccessee.transmitCredentialId = context->reUseCreId; + continue; + } + app.proxyAccessee.transmitCredentialId = context->accessee.transmitCredentialId; + } + return DM_OK; +} + // Received 190 message, sent 200 message int32_t AuthSrcDataSyncState::Action(std::shared_ptr context) { LOGI("AuthSrcDataSyncState::Action start"); - if (NeedAgreeAcl(context)) { // Query the ACL of the sink end. Compare the ACLs at both ends. context->softbusConnector->SyncLocalAclListProcess({context->accesser.deviceId, context->accesser.userId}, @@ -116,18 +162,13 @@ int32_t AuthSrcDataSyncState::Action(std::shared_ptr context) context->accesser.deviceName = context->softbusConnector->GetLocalDeviceName(); // Save this acl SetAclInfo(context); + UpdateCredInfo(context); context->authMessageProcessor->PutAccessControlList(context, context->accesser, context->accessee.deviceId); // Synchronize the local SP information, the format is uncertain, not done for now } std::string peerDeviceId = ""; - peerDeviceId = context->accesser.aclProfiles[DM_IDENTICAL_ACCOUNT].GetAccessee().GetAccesseeDeviceId(); - if (peerDeviceId.empty()) { - peerDeviceId = context->accesser.aclProfiles[DM_SHARE].GetAccessee().GetAccesseeDeviceId(); - } - if (peerDeviceId.empty()) { - peerDeviceId = context->accesser.aclProfiles[DM_POINT_TO_POINT].GetAccessee().GetAccesseeDeviceId(); - } + GetPeerDeviceId(context, peerDeviceId); bool isNeedJoinLnn = context->softbusConnector->CheckIsNeedJoinLnn(peerDeviceId, context->accessee.addr); // Trigger networking if ((!context->accesser.isOnline || isNeedJoinLnn) && context->isNeedJoinLnn) { @@ -159,6 +200,50 @@ DmAuthStateType AuthSrcDataSyncState::GetStateType() return DmAuthStateType::AUTH_SRC_DATA_SYNC_STATE; } +void AuthSrcDataSyncState::GetPeerDeviceId(std::shared_ptr context, std::string &peerDeviceId) +{ + CHECK_NULL_VOID(context); + if (context->accesser.aclProfiles.find(DM_IDENTICAL_ACCOUNT) != context->accesser.aclProfiles.end()) { + peerDeviceId = context->accesser.aclProfiles[DM_IDENTICAL_ACCOUNT].GetAccessee().GetAccesseeDeviceId(); + if (!peerDeviceId.empty()) { + return; + } + } + if (context->accesser.aclProfiles.find(DM_SHARE) != context->accesser.aclProfiles.end()) { + peerDeviceId = context->accesser.aclProfiles[DM_SHARE].GetAccessee().GetAccesseeDeviceId(); + if (peerDeviceId == context->accesser.deviceId) { + peerDeviceId = context->accesser.aclProfiles[DM_SHARE].GetAccesser().GetAccesserDeviceId(); + } + if (!peerDeviceId.empty()) { + return; + } + } + if (context->accesser.aclProfiles.find(DM_POINT_TO_POINT) != context->accesser.aclProfiles.end()) { + peerDeviceId = context->accesser.aclProfiles[DM_POINT_TO_POINT].GetAccessee().GetAccesseeDeviceId(); + if (peerDeviceId == context->accesser.deviceId) { + peerDeviceId = context->accesser.aclProfiles[DM_POINT_TO_POINT].GetAccesser().GetAccesserDeviceId(); + } + if (!peerDeviceId.empty()) { + return; + } + } + if (!context->IsProxyBind || context->subjectProxyOnes.empty()) { + return; + } + for (auto &app : context->subjectProxyOnes) { + if (app.proxyAccesser.aclProfiles.find(DM_POINT_TO_POINT) != app.proxyAccesser.aclProfiles.end()) { + peerDeviceId = app.proxyAccesser.aclProfiles[DM_POINT_TO_POINT].GetAccessee().GetAccesseeDeviceId(); + if (peerDeviceId == context->accesser.deviceId) { + peerDeviceId = app.proxyAccesser.aclProfiles[DM_POINT_TO_POINT].GetAccesser().GetAccesserDeviceId(); + } + if (!peerDeviceId.empty()) { + return; + } + } + } + LOGE("failed"); +} + // Received 200 end message, send 201 int32_t AuthSinkFinishState::Action(std::shared_ptr context) { diff --git a/services/implementation/src/authentication_v2/auth_stages/auth_confirm.cpp b/services/implementation/src/authentication_v2/auth_stages/auth_confirm.cpp index f9b71d6ebc3c827a52f112cf5dcc8c58a15ec7bc..dba71a330efa41b8f66f8a755cb55a5fb67b30e0 100644 --- a/services/implementation/src/authentication_v2/auth_stages/auth_confirm.cpp +++ b/services/implementation/src/authentication_v2/auth_stages/auth_confirm.cpp @@ -12,6 +12,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +#include "bundle_mgr_interface.h" +#include "bundle_mgr_proxy.h" +#include "iservice_registry.h" +#include "system_ability_definition.h" #include "auth_manager.h" #include "access_control_profile.h" @@ -83,6 +87,35 @@ void AuthSrcConfirmState::NegotiateCredential(std::shared_ptr con } } +void AuthSrcConfirmState::NegotiateProxyCredential(std::shared_ptr context) +{ + CHECK_NULL_VOID(context); + if (!context->IsProxyBind) { + return; + } + if (context->subjectProxyOnes.empty()) { + return; + } + for (auto item = context->subjectProxyOnes.begin(); item != context->subjectProxyOnes.end(); ++item) { + JsonObject credTypeNegoResult; + JsonObject accesseeCredTypeList; + accesseeCredTypeList.Parse(item->proxyAccessee.credTypeList); + JsonObject accesserCredTypeList; + accesserCredTypeList.Parse(item->proxyAccesser.credTypeList); + if (accesseeCredTypeList.IsDiscarded() || accesserCredTypeList.IsDiscarded()) { + item->proxyAccesser.credTypeList = credTypeNegoResult.Dump(); + continue; + } + if (accesseeCredTypeList.Contains("pointTopointCredType") && + accesserCredTypeList.Contains("pointTopointCredType")) { + credTypeNegoResult["pointTopointCredType"] = DM_POINT_TO_POINT; + item->proxyAccesser.credTypeList = credTypeNegoResult.Dump(); + continue; + } + item->proxyAccesser.credTypeList = credTypeNegoResult.Dump(); + } +} + void AuthSrcConfirmState::NegotiateAcl(std::shared_ptr context, JsonObject &aclNegoResult) { CHECK_NULL_VOID(context); @@ -98,12 +131,14 @@ void AuthSrcConfirmState::NegotiateAcl(std::shared_ptr context, J LOGI("have identical acl."); aclNegoResult["identicalAcl"] = DM_IDENTICAL_ACCOUNT; context->accesser.isAuthed = true; + context->accesser.isUserLevelAuthed = true; context->accesser.isPutLnnAcl = false; } if (accesseeAclList.Contains("shareAcl") && accesserAclList.Contains("shareAcl")) { LOGI("have share acl."); aclNegoResult["shareAcl"] = DM_SHARE; context->accesser.isAuthed = true; + context->accesser.isUserLevelAuthed = true; context->accesser.isPutLnnAcl = false; } if (accesseeAclList.Contains("pointTopointAcl") && accesserAclList.Contains("pointTopointAcl")) { @@ -118,6 +153,40 @@ void AuthSrcConfirmState::NegotiateAcl(std::shared_ptr context, J } } +void AuthSrcConfirmState::NegotiateProxyAcl(std::shared_ptr context) +{ + CHECK_NULL_VOID(context); + if (!context->IsProxyBind) { + return; + } + if (context->subjectProxyOnes.empty()) { + return; + } + for (auto item = context->subjectProxyOnes.begin(); item != context->subjectProxyOnes.end(); ++item) { + JsonObject aclNegoResult; + JsonObject accesseeAclList; + if (!item->proxyAccessee.aclTypeList.empty()) { + accesseeAclList.Parse(item->proxyAccessee.aclTypeList); + } + JsonObject accesserAclList; + if (!item->proxyAccesser.aclTypeList.empty()) { + accesserAclList.Parse(item->proxyAccesser.aclTypeList); + } + if (accesseeAclList.IsDiscarded() || accesserAclList.IsDiscarded()) { + item->proxyAccesser.aclTypeList = aclNegoResult.Dump(); + continue; + } + if (accesseeAclList.Contains("pointTopointAcl") && accesserAclList.Contains("pointTopointAcl")) { + LOGI("have point_to_point acl bundleName: %{public}s.", item->proxyAccesser.bundleName.c_str()); + aclNegoResult["pointTopointAcl"] = DM_POINT_TO_POINT; + item->proxyAccesser.aclTypeList = aclNegoResult.Dump(); + item->proxyAccesser.isAuthed = true; + continue; + } + item->proxyAccesser.aclTypeList = aclNegoResult.Dump(); + } +} + void AuthSrcConfirmState::GetSrcCredType(std::shared_ptr context, JsonObject &credInfo, JsonObject &aclInfo, JsonObject &credTypeJson) { @@ -127,6 +196,7 @@ void AuthSrcConfirmState::GetSrcCredType(std::shared_ptr context, if (!item.Contains(FILED_CRED_TYPE) || !item[FILED_CRED_TYPE].IsNumberInteger() || !item.Contains(FILED_CRED_ID) || !item[FILED_CRED_ID].IsString()) { deleteCredInfo.push_back(item[FILED_CRED_ID].Get()); + DirectlyDeleteCredential(context, context->accesser.userId, item); continue; } int32_t credType = item[FILED_CRED_TYPE].Get(); @@ -150,6 +220,7 @@ void AuthSrcConfirmState::GetSrcCredType(std::shared_ptr context, context->accesser.aclProfiles[DM_LNN].GetAccessee().GetAccesseeCredentialIdStr() != item[FILED_CRED_ID].Get())) { deleteCredInfo.push_back(item[FILED_CRED_ID].Get()); + DirectlyDeleteCredential(context, context->accesser.userId, item); } else { credTypeJson["lnnCredType"] = credType; context->accesser.credentialInfos[credType] = item.Dump(); @@ -160,9 +231,9 @@ void AuthSrcConfirmState::GetSrcCredType(std::shared_ptr context, break; } } + GetSrcProxyCredTypeForP2P(context, deleteCredInfo); for (const auto &item : deleteCredInfo) { credInfo.Erase(item); - context->hiChainAuthConnector->DeleteCredential(context->accesser.userId, item); } } @@ -176,12 +247,65 @@ void AuthSrcConfirmState::GetSrcCredTypeForP2P(std::shared_ptr co context->accesser.aclProfiles[DM_POINT_TO_POINT].GetAccessee().GetAccesseeCredentialIdStr() != credObj[FILED_CRED_ID].Get())) { deleteCredInfo.push_back(credObj[FILED_CRED_ID].Get()); + DeleteCredential(context, context->accesser.userId, credObj, context->accesser.aclProfiles[DM_POINT_TO_POINT]); } else { credTypeJson["pointTopointCredType"] = credType; context->accesser.credentialInfos[credType] = credObj.Dump(); } } +void AuthSrcConfirmState::GetSrcProxyCredTypeForP2P(std::shared_ptr context, + std::vector &deleteCredInfo) +{ + CHECK_NULL_VOID(context); + if (!context->IsProxyBind || context->subjectProxyOnes.empty()) { + return; + } + for (auto item = context->subjectProxyOnes.begin(); item != context->subjectProxyOnes.end(); ++item) { + JsonObject credInfoJson; + if (!item->proxyAccesser.credInfoJson.empty()) { + credInfoJson.Parse(item->proxyAccesser.credInfoJson); + } + for (const auto &credItem : credInfoJson.Items()) { + if (!credItem.Contains(FILED_CRED_ID) || !credItem[FILED_CRED_ID].IsString()) { + continue; + } + if (!credItem.Contains(FILED_CRED_TYPE) || !credItem[FILED_CRED_TYPE].IsNumberInteger()) { + deleteCredInfo.push_back(credItem[FILED_CRED_ID].Get()); + DirectlyDeleteCredential(context, context->accesser.userId, credItem); + continue; + } + int32_t credType = credItem[FILED_CRED_TYPE].Get(); + if (credType != static_cast(DM_POINT_TO_POINT)) { + continue; + } + std::string credId = credItem[FILED_CRED_ID].Get(); + JsonObject aclTypeJson; + if (!item->proxyAccesser.aclTypeList.empty()) { + aclTypeJson.Parse(item->proxyAccesser.aclTypeList); + } + if (!aclTypeJson.Contains("pointTopointAcl") || + item->proxyAccesser.aclProfiles.find(DM_POINT_TO_POINT) == item->proxyAccesser.aclProfiles.end() || + (item->proxyAccesser.aclProfiles[DM_POINT_TO_POINT].GetAccessee().GetAccesseeCredentialIdStr() != + credItem[FILED_CRED_ID].Get() && + item->proxyAccesser.aclProfiles[DM_POINT_TO_POINT].GetAccesser().GetAccesserCredentialIdStr() != + credItem[FILED_CRED_ID].Get())) { + deleteCredInfo.push_back(credItem[FILED_CRED_ID].Get()); + DeleteCredential(context, context->accesser.userId, credItem, + item->proxyAccesser.aclProfiles[DM_POINT_TO_POINT]); + continue; + } + JsonObject validCredInfoJson; + if (!item->proxyAccesser.credTypeList.empty()) { + validCredInfoJson.Parse(item->proxyAccesser.credTypeList); + } + validCredInfoJson["pointTopointCredType"] = credType; + item->proxyAccesser.credTypeList = validCredInfoJson.Dump(); + item->proxyAccesser.credentialInfos[credType] = credItem.Dump(); + } + } +} + void AuthSrcConfirmState::GetSrcAclInfo(std::shared_ptr context, JsonObject &credInfo, JsonObject &aclInfo) { @@ -242,6 +366,50 @@ void AuthSrcConfirmState::GetSrcAclInfoForP2P(std::shared_ptr con aclInfo["lnnAcl"] = DM_LNN; context->accesser.aclProfiles[DM_LNN] = profile; } + GetSrcProxyAclInfoForP2P(context, profile); +} + +void AuthSrcConfirmState::GetSrcProxyAclInfoForP2P(std::shared_ptr context, + const DistributedDeviceProfile::AccessControlProfile &profile) +{ + CHECK_NULL_VOID(context); + if (!context->IsProxyBind || context->subjectProxyOnes.empty()) { + return; + } + for (auto &app : context->subjectProxyOnes) { + if ((profile.GetAccesser().GetAccesserTokenId() == app.proxyAccesser.tokenId && + Crypto::GetTokenIdHash(std::to_string(profile.GetAccessee().GetAccesseeTokenId())) == + app.proxyAccessee.tokenIdHash) || + (profile.GetAccessee().GetAccesseeTokenId() == app.proxyAccesser.tokenId && + Crypto::GetTokenIdHash(std::to_string(profile.GetAccesser().GetAccesserTokenId())) == + app.proxyAccessee.tokenIdHash)) { + std::string credId; + if (!IsAclHasCredential(profile, app.proxyAccesser.credInfoJson, credId)) { + continue; + } + std::vector appList; + JsonObject credInfoJsonObj; + if (!app.proxyAccesser.credInfoJson.empty()) { + credInfoJsonObj.Parse(app.proxyAccesser.credInfoJson); + } + credInfoJsonObj[credId][FILED_AUTHORIZED_APP_LIST].Get(appList); + const size_t APP_LIST_SIZE = 2; + if (appList.size() < APP_LIST_SIZE || + std::find(appList.begin(), appList.end(), std::to_string(profile.GetAccesser().GetAccesserTokenId())) + == appList.end() || + std::find(appList.begin(), appList.end(), std::to_string(profile.GetAccessee().GetAccesseeTokenId())) + == appList.end()) { + continue; + } + JsonObject aclTypeJson; + if (!app.proxyAccesser.aclTypeList.empty()) { + aclTypeJson.Parse(app.proxyAccesser.aclTypeList); + } + aclTypeJson["pointTopointAcl"] = DM_POINT_TO_POINT; + app.proxyAccesser.aclTypeList = aclTypeJson.Dump(); + app.proxyAccesser.aclProfiles[DM_POINT_TO_POINT] = profile; + } + } } bool AuthSrcConfirmState::CheckCredIdInAcl(std::shared_ptr context, @@ -253,7 +421,7 @@ bool AuthSrcConfirmState::CheckCredIdInAcl(std::shared_ptr contex credId = profile.GetAccessee().GetAccesseeCredentialIdStr(); if (!credInfo.Contains(credId)) { LOGE("credInfoJson not contain credId %{public}s.", GetAnonyString(credId).c_str()); - DeleteAcl(context, profile); + DeleteAclAndSk(context, profile); return false; } } @@ -300,7 +468,7 @@ void AuthSrcConfirmState::CheckCredIdInAclForP2P(std::shared_ptr std::to_string(profile.GetAccessee().GetAccesseeTokenId()) == appList[0]))) { checkResult = true; } else { - DeleteAcl(context, profile); + DeleteAclAndSk(context, profile); } } } @@ -443,6 +611,7 @@ int32_t AuthSrcConfirmState::Action(std::shared_ptr context) LOGI("start."); CHECK_NULL_RETURN(context, ERR_DM_POINT_NULL); context->timer->DeleteTimer(std::string(NEGOTIATE_TIMEOUT_TASK)); + ResetBindLevel(context); GetCustomDescBySinkLanguage(context); context->accessee.isOnline = SoftbusCache::GetInstance().CheckIsOnline(context->accessee.deviceIdHash); JsonObject credInfo; @@ -457,11 +626,12 @@ int32_t AuthSrcConfirmState::Action(std::shared_ptr context) JsonObject credTypeNegoResult; NegotiateCredential(context, credTypeNegoResult); context->accesser.credTypeList = credTypeNegoResult.Dump(); + NegotiateProxyCredential(context); // update acl negotiate result JsonObject aclNegoResult; NegotiateAcl(context, aclNegoResult); context->accesser.aclTypeList = aclNegoResult.Dump(); - + NegotiateProxyAcl(context); context->authMessageProcessor->CreateAndSendMsg(MSG_TYPE_REQ_USER_CONFIRM, context); context->listener->OnAuthResult(context->processInfo, context->peerTargetId.deviceId, context->accessee.tokenIdHash, static_cast(STATUS_DM_SHOW_AUTHORIZE_UI), DM_OK); @@ -475,6 +645,15 @@ int32_t AuthSrcConfirmState::Action(std::shared_ptr context) return DM_OK; } +void AuthSrcConfirmState::ResetBindLevel(std::shared_ptr context) +{ + CHECK_NULL_VOID(context); + if (context->accesser.bindLevel != DmRole::DM_ROLE_USER || !context->IsProxyBind) { + return; + } + context->accesser.bindLevel = DmRole::DM_ROLE_SA; +} + void AuthSrcConfirmState::GetCustomDescBySinkLanguage(std::shared_ptr context) { if (context == nullptr || context->customData.empty()) { @@ -519,14 +698,14 @@ int32_t AuthSinkConfirmState::ShowConfigDialog(std::shared_ptr co 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; // Reserved jsonObj[TAG_HOST_PKGLABEL] = context->pkgLabel; - + GetBundleLabel(context); + CreateProxyData(context, jsonObj); const std::string params = jsonObj.Dump(); DmDialogManager::GetInstance().ShowConfirmDialog(params); @@ -534,6 +713,66 @@ int32_t AuthSinkConfirmState::ShowConfigDialog(std::shared_ptr co return DM_OK; } +void AuthSinkConfirmState::GetBundleLabel(std::shared_ptr context) +{ + CHECK_NULL_VOID(context); + if (!context->IsProxyBind || context->subjectProxyOnes.empty()) { + return; + } + auto samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); + if (samgr == nullptr) { + LOGE("Get ability manager failed"); + return; + } + + sptr object = samgr->GetSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID); + if (object == nullptr) { + LOGE("object is NULL."); + return; + } + + sptr bms = iface_cast(object); + if (bms == nullptr) { + LOGE("bundle manager service is NULL."); + return; + } + + auto bundleResourceProxy = bms->GetBundleResourceProxy(); + if (bundleResourceProxy == nullptr) { + LOGE("GetBundleResourceProxy fail"); + return; + } + for (auto &app : context->subjectProxyOnes) { + AppExecFwk::BundleResourceInfo resourceInfo; + auto result = bundleResourceProxy->GetBundleResourceInfo(app.proxyAccessee.bundleName, + static_cast(OHOS::AppExecFwk::ResourceFlag::GET_RESOURCE_INFO_ALL), resourceInfo); + if (result == ERR_OK) { + app.proxyAccessee.pkgLabel = resourceInfo.label; + } + } +} + +int32_t AuthSinkConfirmState::CreateProxyData(std::shared_ptr context, JsonObject &jsonObj) +{ + CHECK_NULL_RETURN(context, ERR_DM_POINT_NULL); + if (!context->IsProxyBind || context->subjectProxyOnes.empty()) { + jsonObj[PARAM_KEY_IS_PROXY_BIND] = false; + return DM_OK; + } + jsonObj[PARAM_KEY_IS_PROXY_BIND] = context->IsProxyBind; + JsonObject allProxyObj(JsonCreateType::JSON_CREATE_TYPE_ARRAY); + for (const auto &app : context->subjectProxyOnes) { + JsonObject object; + object[TAG_HOST_PKGLABEL] = !app.proxyAccessee.pkgLabel.empty() ? app.proxyAccessee.pkgLabel : + app.proxyAccessee.bundleName; + object[TAG_BUNDLE_NAME] = app.proxyAccessee.bundleName; + object[BUNDLE_INFO] = app.proxyAccessee.bundleInfo; + allProxyObj.PushBack(object); + } + jsonObj[APP_USER_DATA] = allProxyObj.Dump(); + return DM_OK; +} + void AuthSinkConfirmState::NegotiateCredential(std::shared_ptr context, JsonObject &credTypeNegoResult) { CHECK_NULL_VOID(context); @@ -568,6 +807,32 @@ void AuthSinkConfirmState::NegotiateCredential(std::shared_ptr co return; } +void AuthSinkConfirmState::NegotiateProxyCredential(std::shared_ptr context) +{ + CHECK_NULL_VOID(context); + if (!context->IsProxyBind || context->subjectProxyOnes.empty()) { + return; + } + for (auto item = context->subjectProxyOnes.begin(); item != context->subjectProxyOnes.end(); ++item) { + JsonObject credTypeNegoResult; + JsonObject accesseeCredTypeList; + accesseeCredTypeList.Parse(item->proxyAccessee.credTypeList); + JsonObject accesserCredTypeList; + accesserCredTypeList.Parse(item->proxyAccesser.credTypeList); + if (accesseeCredTypeList.IsDiscarded() || accesserCredTypeList.IsDiscarded()) { + item->proxyAccessee.credTypeList = credTypeNegoResult.Dump(); + continue; + } + if (accesseeCredTypeList.Contains("pointTopointCredType") && + accesserCredTypeList.Contains("pointTopointCredType")) { + credTypeNegoResult["pointTopointCredType"] = DM_POINT_TO_POINT; + item->proxyAccessee.credTypeList = credTypeNegoResult.Dump(); + continue; + } + item->proxyAccessee.credTypeList = credTypeNegoResult.Dump(); + } +} + void AuthSinkConfirmState::NegotiateAcl(std::shared_ptr context, JsonObject &aclNegoResult) { CHECK_NULL_VOID(context); @@ -584,12 +849,14 @@ void AuthSinkConfirmState::NegotiateAcl(std::shared_ptr context, aclNegoResult["identicalAcl"] = DM_IDENTICAL_ACCOUNT; context->accessee.isPutLnnAcl = false; context->accessee.isAuthed = true; + context->accessee.isUserLevelAuthed = true; } if (accesseeAclList.Contains("shareCredType") && accesserAclList.Contains("shareCredType")) { LOGI("have share acl."); aclNegoResult["shareAcl"] = DM_SHARE; context->accessee.isPutLnnAcl = false; context->accessee.isAuthed = true; + context->accessee.isUserLevelAuthed = true; } if (accesseeAclList.Contains("pointTopointAcl") && accesserAclList.Contains("pointTopointAcl")) { LOGI("have point_to_point acl."); @@ -603,6 +870,37 @@ void AuthSinkConfirmState::NegotiateAcl(std::shared_ptr context, } } +void AuthSinkConfirmState::NegotiateProxyAcl(std::shared_ptr context) +{ + CHECK_NULL_VOID(context); + if (!context->IsProxyBind || context->subjectProxyOnes.empty()) { + return; + } + for (auto item = context->subjectProxyOnes.begin(); item != context->subjectProxyOnes.end(); ++item) { + JsonObject aclNegoResult; + JsonObject accesseeAclList; + if (!item->proxyAccessee.aclTypeList.empty()) { + accesseeAclList.Parse(item->proxyAccessee.aclTypeList); + } + JsonObject accesserAclList; + if (!item->proxyAccesser.aclTypeList.empty()) { + accesserAclList.Parse(item->proxyAccesser.aclTypeList); + } + if (accesseeAclList.IsDiscarded() || accesserAclList.IsDiscarded()) { + item->proxyAccessee.aclTypeList = aclNegoResult.Dump(); + continue; + } + if (accesseeAclList.Contains("pointTopointAcl") && accesserAclList.Contains("pointTopointAcl")) { + LOGI("have point_to_point acl bundleName: %{public}s.", item->proxyAccesser.bundleName.c_str()); + aclNegoResult["pointTopointAcl"] = DM_POINT_TO_POINT; + item->proxyAccessee.aclTypeList = aclNegoResult.Dump(); + item->proxyAccessee.isAuthed = true; + continue; + } + item->proxyAccessee.aclTypeList = aclNegoResult.Dump(); + } +} + void AuthSinkConfirmState::MatchFallBackCandidateList( std::shared_ptr context, DmAuthType authType) { @@ -650,6 +948,7 @@ void AuthSinkConfirmState::ReadServiceInfo(std::shared_ptr contex } } context->customData = srvInfo.GetDescription(); // read customData + context->srvExtarInfo = srvInfo.GetExtraInfo(); } else if (DmAuthState::IsImportAuthCodeCompatibility(context->authType) && AuthSinkStatePinAuthComm::IsAuthCodeReady(context)) { // only special scenarios can import pincode @@ -669,21 +968,28 @@ int32_t AuthSinkConfirmState::Action(std::shared_ptr context) JsonObject aclNegoResult; NegotiateCredential(context, credTypeNegoResult); context->accessee.credTypeList = credTypeNegoResult.Dump(); + NegotiateProxyCredential(context); NegotiateAcl(context, aclNegoResult); context->accessee.aclTypeList = aclNegoResult.Dump(); + NegotiateProxyAcl(context); if (credTypeNegoResult.Dump() != context->accesser.credTypeList || aclNegoResult.Dump() != context->accesser.aclTypeList) { LOGE("compability negotiate not match."); context->reason = ERR_DM_CAPABILITY_NEGOTIATE_FAILED; return ERR_DM_FAILED; } + if (!ProcessServerAuthorize(context)) { + LOGE("no srvExtarInfo"); + context->reason = ERR_DM_AUTH_PEER_REJECT; + return ERR_DM_FAILED; + } int32_t ret = NegotiateProcess::GetInstance().HandleNegotiateResult(context); if (ret != DM_OK) { LOGE("HandleNegotiateResult failed ret %{public}d.", ret); - context->reason = ERR_DM_CAPABILITY_NEGOTIATE_FAILED; + context->reason = ret; return ret; } - if (context->needBind) { + if (IsNeedBind(context)) { return ProcessBindAuthorize(context); } else { return ProcessNoBindAuthorize(context); @@ -702,7 +1008,8 @@ int32_t AuthSinkConfirmState::ProcessBindAuthorize(std::shared_ptrauthType); } - if (DmAuthState::IsImportAuthCodeCompatibility(context->authType) && + if ((DmAuthState::IsImportAuthCodeCompatibility(context->authType) || + context->authType == DmAuthType::AUTH_TYPE_PIN_ULTRASONIC) && (context->serviceInfoFound || AuthSinkStatePinAuthComm::IsAuthCodeReady(context)) && context->authBoxType == DMLocalServiceInfoAuthBoxType::SKIP_CONFIRM) { context->authMessageProcessor->CreateAndSendMsg(MSG_TYPE_RESP_USER_CONFIRM, context); @@ -712,28 +1019,135 @@ int32_t AuthSinkConfirmState::ProcessBindAuthorize(std::shared_ptrauthType == DmAuthType::AUTH_TYPE_PIN || context->authType == DmAuthType::AUTH_TYPE_NFC || context->authType == DmAuthType::AUTH_TYPE_PIN_ULTRASONIC) && context->authBoxType == DMLocalServiceInfoAuthBoxType::STATE3) { - context->timer->DeleteTimer(std::string(WAIT_REQUEST_TIMEOUT_TASK)); - if (ShowConfigDialog(context) != DM_OK) { - LOGE("ShowConfigDialog failed"); - context->reason = ERR_DM_SHOW_CONFIRM_FAILED; - return ERR_DM_FAILED; + return ProcessUserAuthorize(context); + } + context->confirmOperation = UiAction::USER_OPERATION_TYPE_CANCEL_AUTH; + return ERR_DM_FAILED; +} + +int32_t AuthSinkConfirmState::ProcessUserAuthorize(std::shared_ptr context) +{ + CHECK_NULL_RETURN(context, ERR_DM_POINT_NULL); + context->timer->DeleteTimer(std::string(WAIT_REQUEST_TIMEOUT_TASK)); + if (ShowConfigDialog(context) != DM_OK) { + LOGE("ShowConfigDialog failed"); + context->reason = ERR_DM_SHOW_CONFIRM_FAILED; + return ERR_DM_FAILED; + } + if (DmEventType::ON_USER_OPERATION != + context->authStateMachine->WaitExpectEvent(DmEventType::ON_USER_OPERATION)) { + LOGE("AuthSinkConfirmState::Action ON_USER_OPERATION err"); + return ERR_DM_FAILED; + } + if (context->confirmOperation == USER_OPERATION_TYPE_CANCEL_AUTH) { + LOGE("AuthSinkConfirmState::Action USER_OPERATION_TYPE_CANCEL_AUTH"); + context->reason = ERR_DM_AUTH_PEER_REJECT; + return ERR_DM_FAILED; + } + if (!ProcessUserOption(context, context->userOperationParam)) { + LOGE("user reject"); + context->reason = ERR_DM_AUTH_PEER_REJECT; + return ERR_DM_FAILED; + } + context->authMessageProcessor->CreateAndSendMsg(MSG_TYPE_RESP_USER_CONFIRM, context); + context->authStateMachine->TransitionTo(std::make_shared()); + return DM_OK; +} + +bool AuthSinkConfirmState::ProcessUserOption(std::shared_ptr context, + const std::string &authorizeInfo) +{ + if (context == nullptr) { + return false; + } + if (!context->IsProxyBind) { + return true; + } + if (authorizeInfo.empty() && !context->IsCallingProxyAsSubject) { + LOGE("no proxy data"); + context->subjectProxyOnes.clear(); + return false; + } + JsonObject jsonObj; + jsonObj.Parse(authorizeInfo); + if (jsonObj.IsDiscarded() || !jsonObj.Contains(APP_USER_DATA) || + !IsArray(jsonObj, APP_USER_DATA)) { + context->subjectProxyOnes.clear(); + LOGE("no subject proxy data"); + return context->IsCallingProxyAsSubject; + } + JsonObject appDataObj; + std::string appDataStr = jsonObj[APP_USER_DATA].Dump(); + appDataObj.Parse(appDataStr); + for (auto item = context->subjectProxyOnes.begin(); item != context->subjectProxyOnes.end();) { + if (IsUserAuthorize(appDataObj, item->proxyAccessee)) { + item++; + } else { + item = context->subjectProxyOnes.erase(item); + } + } + return context->subjectProxyOnes.size() > 0 || context->IsCallingProxyAsSubject; +} + +bool AuthSinkConfirmState::ProcessServerAuthorize(std::shared_ptr context) +{ + if (context == nullptr) { + return false; + } + if (!context->IsProxyBind) { + return true; + } + OHOS::DistributedDeviceProfile::LocalServiceInfo srvInfo; + auto ret = DeviceProfileConnector::GetInstance().GetLocalServiceInfoByBundleNameAndPinExchangeType( + context->accessee.pkgName, context->authType, srvInfo); + if (ret != OHOS::DistributedDeviceProfile::DP_SUCCESS) { + LOGE("ReadServiceInfo not found"); + return false; + } + std::string srvExtarInfo = srvInfo.GetExtraInfo(); + if (srvExtarInfo.empty()) { + LOGE("no proxy data"); + context->subjectProxyOnes.clear(); + return false; + } + JsonObject jsonObj; + jsonObj.Parse(srvExtarInfo); + if (jsonObj.IsDiscarded() || !jsonObj.Contains(APP_USER_DATA) || + !IsArray(jsonObj, APP_USER_DATA)) { + context->subjectProxyOnes.clear(); + LOGE("no subject proxy data"); + return false; + } + JsonObject appDataObj; + std::string appDataStr = jsonObj[APP_USER_DATA].Dump(); + appDataObj.Parse(appDataStr); + for (auto item = context->subjectProxyOnes.begin(); item != context->subjectProxyOnes.end();) { + if (IsUserAuthorize(appDataObj, item->proxyAccessee)) { + item++; + } else { + item = context->subjectProxyOnes.erase(item); } - if (DmEventType::ON_USER_OPERATION != - context->authStateMachine->WaitExpectEvent(DmEventType::ON_USER_OPERATION)) { - LOGE("AuthSinkConfirmState::Action ON_USER_OPERATION err"); - return ERR_DM_FAILED; + } + return context->subjectProxyOnes.size() > 0; +} + +bool AuthSinkConfirmState::IsUserAuthorize(JsonObject ¶mObj, DmProxyAccess &access) +{ + if (paramObj.IsDiscarded()) { + return false; + } + for (auto const &item : paramObj.Items()) { + if (!item.Contains(TAG_BUNDLE_NAME) || !IsString(item, TAG_BUNDLE_NAME)) { + continue; } - if (context->confirmOperation == USER_OPERATION_TYPE_CANCEL_AUTH) { - LOGE("AuthSinkConfirmState::Action USER_OPERATION_TYPE_CANCEL_AUTH"); - context->reason = ERR_DM_AUTH_PEER_REJECT; - return ERR_DM_FAILED; + if (access.bundleName == item[TAG_BUNDLE_NAME].Get()) { + if (item.Contains(BUNDLE_INFO) && IsString(item, BUNDLE_INFO)) { + access.bundleInfo = item[BUNDLE_INFO].Get(); + } + return true; } - context->authMessageProcessor->CreateAndSendMsg(MSG_TYPE_RESP_USER_CONFIRM, context); - context->authStateMachine->TransitionTo(std::make_shared()); - return DM_OK; } - context->confirmOperation = UiAction::USER_OPERATION_TYPE_CANCEL_AUTH; - return ERR_DM_FAILED; + return false; } int32_t AuthSinkConfirmState::ProcessNoBindAuthorize(std::shared_ptr context) diff --git a/services/implementation/src/authentication_v2/auth_stages/auth_credential.cpp b/services/implementation/src/authentication_v2/auth_stages/auth_credential.cpp index 363cb393f40f142ab1941233e917d723f723ab23..3caf69e22f2077bb346f814c73567103f4c7704c 100644 --- a/services/implementation/src/authentication_v2/auth_stages/auth_credential.cpp +++ b/services/implementation/src/authentication_v2/auth_stages/auth_credential.cpp @@ -135,28 +135,31 @@ std::string AuthSrcCredentialAuthDoneState::GenerateCertificate(std::shared_ptr< int32_t AuthSrcCredentialAuthDoneState::Action(std::shared_ptr context) { + CHECK_NULL_RETURN(context, ERR_DM_POINT_NULL); + if (GetSessionKey(context)) { + DerivativeSessionKey(context); + context->accesser.cert = GenerateCertificate(context); + context->authMessageProcessor->CreateAndSendMsg(MSG_TYPE_REQ_DATA_SYNC, context); + return DM_OK; + } // decrypt and transmit transmitData int32_t ret = g_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(context->accesser.userId, skId); - if (ret != DM_OK) { - LOGE("AuthSrcCredentialAuthDoneState::Action DP save user session key failed"); - return ret; - } + // first time joinLnn, auth lnnCredential if (context->accesser.isGenerateLnnCredential == true && context->isAppCredentialVerified == false && context->accesser.bindLevel != USER) { context->isAppCredentialVerified = true; - SetAuthContext(skId, context->accesser.transmitSkTimeStamp, context->accesser.transmitSessionKeyId); + DerivativeSessionKey(context); msgType = MSG_TYPE_REQ_CREDENTIAL_AUTH_START; ret = context->hiChainAuthConnector->AuthCredential(context->accesser.userId, context->requestId, context->accesser.lnnCredentialId, std::string("")); @@ -164,6 +167,7 @@ int32_t AuthSrcCredentialAuthDoneState::Action(std::shared_ptr co 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."); @@ -171,16 +175,29 @@ int32_t AuthSrcCredentialAuthDoneState::Action(std::shared_ptr co } // First-time authentication and Lnn credential process } else if (context->accesser.isGenerateLnnCredential == true && context->accesser.bindLevel != USER) { + int32_t skId = 0; + int32_t ret = context->authMessageProcessor->SaveSessionKeyToDP(context->accesser.userId, skId); + if (ret != DM_OK) { + LOGE("DP save user session key failed %{public}d", ret); + return ret; + } SetAuthContext(skId, context->accesser.lnnSkTimeStamp, context->accesser.lnnSessionKeyId); context->accesser.cert = GenerateCertificate(context); msgType = MSG_TYPE_REQ_DATA_SYNC; } else { // Non-first-time authentication transport credential process - SetAuthContext(skId, context->accesser.transmitSkTimeStamp, context->accesser.transmitSessionKeyId); + DerivativeSessionKey(context); context->accesser.cert = GenerateCertificate(context); msgType = MSG_TYPE_REQ_DATA_SYNC; } - std::string message = - context->authMessageProcessor->CreateMessage(msgType, context); + return SendCredentialAuthMessage(context, msgType); +} + +int32_t AuthSrcCredentialAuthDoneState::SendCredentialAuthMessage(std::shared_ptr context, + DmMessageType &msgType) +{ + CHECK_NULL_RETURN(context, ERR_DM_POINT_NULL); + CHECK_NULL_RETURN(context->authMessageProcessor, ERR_DM_POINT_NULL); + std::string message = context->authMessageProcessor->CreateMessage(msgType, context); if (message.empty()) { LOGE("AuthSrcCredentialAuthDoneState::Action CreateMessage failed"); return ERR_DM_FAILED; @@ -188,6 +205,69 @@ int32_t AuthSrcCredentialAuthDoneState::Action(std::shared_ptr co return context->softbusConnector->GetSoftbusSession()->SendData(context->sessionId, message); } +int32_t AuthSrcCredentialAuthDoneState::DerivativeSessionKey(std::shared_ptr context) +{ + CHECK_NULL_RETURN(context, ERR_DM_POINT_NULL); + if (!context->IsProxyBind || context->subjectProxyOnes.empty()) { + int32_t skId = 0; + int32_t ret = context->authMessageProcessor->SaveSessionKeyToDP(context->accesser.userId, skId); + if (ret != DM_OK) { + LOGE("AuthSrcCredentialAuthDoneState::Action DP save user session key failed"); + return ret; + } + SetAuthContext(skId, context->accesser.transmitSkTimeStamp, context->accesser.transmitSessionKeyId); + return DM_OK; + } + return DerivativeProxySessionKey(context); +} + +int32_t AuthSrcCredentialAuthDoneState::DerivativeProxySessionKey(std::shared_ptr context) +{ + CHECK_NULL_RETURN(context, ERR_DM_POINT_NULL); + if (!context->reUseCreId.empty()) { + context->accesser.transmitCredentialId = context->reUseCreId; + } + if (context->IsCallingProxyAsSubject && !context->accesser.isAuthed) { + int32_t skId = 0; + int32_t ret = 0; + if (!context->reUseCreId.empty()) { + std::string suffix = context->accesser.deviceIdHash + context->accessee.deviceIdHash + + context->accesser.tokenIdHash + context->accessee.tokenIdHash; + ret = context->authMessageProcessor->SaveDerivativeSessionKeyToDP(context->accesser.userId, suffix, skId); + context->accesser.transmitCredentialId = context->reUseCreId; + } else { + ret = context->authMessageProcessor->SaveSessionKeyToDP(context->accesser.userId, skId); + } + if (ret != DM_OK) { + LOGE("AuthSrcCredentialAuthDoneState::Action DP save user session key failed"); + return ret; + } + SetAuthContext(skId, context->accesser.transmitSkTimeStamp, context->accesser.transmitSessionKeyId); + } + for (auto &app : context->subjectProxyOnes) { + if (app.proxyAccesser.isAuthed) { + continue; + } + int32_t skId = 0; + std::string suffix = context->accesser.deviceIdHash + context->accessee.deviceIdHash + + app.proxyAccesser.tokenIdHash + app.proxyAccessee.tokenIdHash; + int32_t ret = + context->authMessageProcessor->SaveDerivativeSessionKeyToDP(context->accesser.userId, suffix, skId); + if (ret != DM_OK) { + LOGE("AuthSrcCredentialAuthDoneState::Action DP save user session key failed"); + return ret; + } + app.proxyAccesser.skTimeStamp = static_cast(DmAuthState::GetSysTimeMs()); + app.proxyAccesser.transmitSessionKeyId = skId; + if (!context->reUseCreId.empty()) { + app.proxyAccesser.transmitCredentialId = context->reUseCreId; + continue; + } + app.proxyAccesser.transmitCredentialId = context->accesser.transmitCredentialId; + } + return DM_OK; +} + DmAuthStateType AuthSinkCredentialAuthStartState::GetStateType() { return DmAuthStateType::AUTH_SINK_CREDENTIAL_AUTH_START_STATE; @@ -233,21 +313,60 @@ int32_t AuthSinkCredentialAuthNegotiateState::Action(std::shared_ptrauthMessageProcessor->SaveSessionKeyToDP(context->accessee.userId, 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->accessee.isGenerateLnnCredential == true && context->accessee.bindLevel != USER && context->isAppCredentialVerified == true) { + ret = context->authMessageProcessor->SaveSessionKeyToDP(context->accessee.userId, skId); + if (ret != DM_OK) { + LOGE("AuthSinkCredentialAuthNegotiateState::Action DP save user session key failed"); + return ret; + } context->accessee.lnnSkTimeStamp = static_cast(GetSysTimeMs()); context->accessee.lnnSessionKeyId = skId; } else { // Twice transport cred auth context->isAppCredentialVerified = true; - context->accessee.transmitSkTimeStamp = static_cast(GetSysTimeMs()); - context->accessee.transmitSessionKeyId = skId; + if (!context->IsProxyBind || context->subjectProxyOnes.empty() || + (context->IsCallingProxyAsSubject && !context->accessee.isAuthed)) { + ret = context->authMessageProcessor->SaveSessionKeyToDP(context->accessee.userId, skId); + if (ret != DM_OK) { + LOGE("DP save user session key failed %{public}d", ret); + return ret; + } + context->accessee.transmitSkTimeStamp = static_cast(GetSysTimeMs()); + context->accessee.transmitSessionKeyId = skId; + } + DerivativeSessionKey(context); + } + return DM_OK; +} + +int32_t AuthSinkCredentialAuthNegotiateState::DerivativeSessionKey(std::shared_ptr context) +{ + CHECK_NULL_RETURN(context, ERR_DM_POINT_NULL); + if (!context->IsProxyBind || context->subjectProxyOnes.empty()) { + return DM_OK; + } + for (auto &app : context->subjectProxyOnes) { + if (app.proxyAccessee.isAuthed) { + continue; + } + int32_t skId = 0; + std::string suffix = context->accesser.deviceIdHash + context->accessee.deviceIdHash + + app.proxyAccesser.tokenIdHash + app.proxyAccessee.tokenIdHash; + int32_t ret = + context->authMessageProcessor->SaveDerivativeSessionKeyToDP(context->accessee.userId, suffix, skId); + if (ret != DM_OK) { + LOGE("AuthSinkCredentialAuthNegotiateState::Action DP save user session key failed %{public}d", ret); + return ret; + } + app.proxyAccessee.skTimeStamp = static_cast(DmAuthState::GetSysTimeMs()); + app.proxyAccessee.transmitSessionKeyId = skId; + if (!context->reUseCreId.empty()) { + app.proxyAccessee.transmitCredentialId = context->reUseCreId; + continue; + } + app.proxyAccessee.transmitCredentialId = context->accessee.transmitCredentialId; } return DM_OK; } @@ -291,9 +410,7 @@ std::string AuthCredentialAgreeState::CreateAuthParamsString(DmAuthScope authori jsonObj[TAG_AUTHORIZED_SCOPE] = authorizedScope; } if (authorizedScope == DM_AUTH_SCOPE_APP || authorizedScope == DM_AUTH_SCOPE_USER) { - std::vector tokenIds = {std::to_string(authContext->accesser.tokenId), - std::to_string(authContext->accessee.tokenId)}; - jsonObj[TAG_AUTHORIZED_APP_LIST] = tokenIds; + GenerateTokenIds(authContext, jsonObj); } jsonObj[TAG_CREDENTIAL_OWNER] = DM_AUTH_CREDENTIAL_OWNER; @@ -301,6 +418,32 @@ std::string AuthCredentialAgreeState::CreateAuthParamsString(DmAuthScope authori return jsonObj.Dump(); } +void AuthCredentialAgreeState::GenerateTokenIds(const std::shared_ptr &context, + JsonObject &jsonObj) +{ + CHECK_NULL_VOID(context); + std::vector tokenIds; + if (!context->IsProxyBind || context->subjectProxyOnes.empty()) { + tokenIds.push_back(std::to_string(context->accesser.tokenId)); + tokenIds.push_back(std::to_string(context->accessee.tokenId)); + jsonObj[TAG_AUTHORIZED_APP_LIST] = tokenIds; + return; + } + if (context->IsCallingProxyAsSubject) { + tokenIds.push_back(std::to_string(context->accesser.tokenId)); + tokenIds.push_back(std::to_string(context->accessee.tokenId)); + } + for (auto &app : context->subjectProxyOnes) { + tokenIds.push_back(std::to_string(app.proxyAccesser.tokenId)); + tokenIds.push_back(std::to_string(app.proxyAccessee.tokenId)); + } + if (tokenIds.empty()) { + LOGE("no tokenId."); + return; + } + jsonObj[TAG_AUTHORIZED_APP_LIST] = tokenIds; +} + // Generate credential ID and public key int32_t AuthCredentialAgreeState::GenerateCredIdAndPublicKey(DmAuthScope authorizedScope, std::shared_ptr &authContext) @@ -389,17 +532,19 @@ int32_t AuthSrcCredentialExchangeState::Action(std::shared_ptr co LOGI("AuthSrcCredentialExchangeState::Action() start."); int32_t ret = ERR_DM_FAILED; context->isAppCredentialVerified = false; - if (!NeedAgreeAcl(context)) { - context->authStateMachine->TransitionTo(std::make_shared()); + context->authStateMachine->TransitionTo(std::make_shared()); + return DM_OK; + } + if (GetSessionKey(context)) { + context->authStateMachine->TransitionTo(std::make_shared()); return DM_OK; } - if (!NeedAgreeCredential(context)) { + if (!IsNeedAgreeCredential(context)) { context->authStateMachine->TransitionTo(std::make_shared()); return DM_OK; } - // First authentication, generate LNN credentials and public key if (context->accesser.isGenerateLnnCredential && context->accesser.bindLevel != USER) { ret = GenerateCredIdAndPublicKey(DM_AUTH_SCOPE_LNN, context); @@ -440,7 +585,6 @@ int32_t AuthSinkCredentialExchangeState::Action(std::shared_ptr c 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; @@ -469,7 +613,6 @@ int32_t AuthSinkCredentialExchangeState::Action(std::shared_ptr c context->hiChainAuthConnector->DeleteCredential(osAccountId, tmpCredId); } - // DmAuthScope authorizedScope = DM_AUTH_SCOPE_INVALID; if (context->accessee.bindLevel == APP || context->accessee.bindLevel == SERVICE) { authorizedScope = DM_AUTH_SCOPE_APP; @@ -518,7 +661,7 @@ int32_t AuthSrcCredentialAuthStartState::Action(std::shared_ptr c return ret; } - if (NeedAgreeCredential(context)) { + if (IsNeedAgreeCredential(context)) { // First authentication if (context->accesser.isGenerateLnnCredential && context->accesser.bindLevel != USER) { // Agree lnn credentials and public key diff --git a/services/implementation/src/authentication_v2/auth_stages/auth_negotiate.cpp b/services/implementation/src/authentication_v2/auth_stages/auth_negotiate.cpp index eae7d17263c2756a3842fbfde38b41dffdd5169c..aef232c30323b5e3fc918c96e3bdf523fbb479ef 100644 --- a/services/implementation/src/authentication_v2/auth_stages/auth_negotiate.cpp +++ b/services/implementation/src/authentication_v2/auth_stages/auth_negotiate.cpp @@ -155,7 +155,7 @@ int32_t AuthSinkNegotiateStateMachine::RespQueryAcceseeIds(std::shared_ptraccessee.bundleName.c_str()); return ERR_DM_GET_TOKENID_FAILED; } - if (AuthManagerBase::CheckProcessNameInWhiteList(context->accessee.bundleName)) { + if (!context->IsProxyBind && AuthManagerBase::CheckProcessNameInWhiteList(context->accessee.bundleName)) { context->accessee.bindLevel = DmRole::DM_ROLE_USER; } context->accessee.tokenIdHash = Crypto::GetTokenIdHash(std::to_string(context->accessee.tokenId)); @@ -163,6 +163,31 @@ int32_t AuthSinkNegotiateStateMachine::RespQueryAcceseeIds(std::shared_ptraccessee.language = DmLanguageManager::GetInstance().GetSystemLanguage(); context->accessee.deviceName = context->listener->GetLocalDisplayDeviceNameForPrivacy(); context->accessee.networkId = context->softbusConnector->GetLocalDeviceNetworkId(); + return RespQueryProxyAcceseeIds(context); +} + +int32_t AuthSinkNegotiateStateMachine::RespQueryProxyAcceseeIds(std::shared_ptr context) +{ + CHECK_NULL_RETURN(context, ERR_DM_POINT_NULL); + if (!context->IsProxyBind) { + return DM_OK; + } + if (context->subjectProxyOnes.empty()) { + return ERR_DM_INPUT_PARA_INVALID; + } + for (auto item = context->subjectProxyOnes.begin(); item != context->subjectProxyOnes.end(); ++item) { + if (AppManager::GetInstance().GetNativeTokenIdByName(item->proxyAccessee.bundleName, + item->proxyAccessee.tokenId) == DM_OK) { + item->proxyAccessee.bindLevel = DmRole::DM_ROLE_SA; + } else if (AppManager::GetInstance().GetHapTokenIdByName(context->accessee.userId, + item->proxyAccessee.bundleName, 0, item->proxyAccessee.tokenId) == DM_OK) { + item->proxyAccessee.bindLevel = DmRole::DM_ROLE_FA; + } else { + LOGE("sink not contain the bundlename %{public}s.", item->proxyAccessee.bundleName.c_str()); + return ERR_DM_GET_TOKENID_FAILED; + } + item->proxyAccessee.tokenIdHash = Crypto::GetTokenIdHash(std::to_string(item->proxyAccessee.tokenId)); + } return DM_OK; } @@ -238,6 +263,7 @@ void AuthSinkNegotiateStateMachine::GetSinkCredType(std::shared_ptr()); + DirectlyDeleteCredential(context, context->accessee.userId, item); continue; } int32_t credType = item[FILED_CRED_TYPE].Get(); @@ -261,6 +287,7 @@ void AuthSinkNegotiateStateMachine::GetSinkCredType(std::shared_ptraccessee.aclProfiles[DM_LNN].GetAccesser().GetAccesserCredentialIdStr() != item[FILED_CRED_ID].Get())) { deleteCredInfo.push_back(item[FILED_CRED_ID].Get()); + DirectlyDeleteCredential(context, context->accessee.userId, item); } else { credTypeJson["lnnCredType"] = credType; context->accessee.credentialInfos[credType] = item.Dump(); @@ -271,10 +298,10 @@ void AuthSinkNegotiateStateMachine::GetSinkCredType(std::shared_ptrhiChainAuthConnector->DeleteCredential(context->accessee.userId, item); - } + GetSinkProxyCredTypeForP2P(context, deleteCredInfo); + for (const auto &item : deleteCredInfo) { + credInfo.Erase(item); + } } void AuthSinkNegotiateStateMachine::GetSinkCredTypeForP2P(std::shared_ptr context, @@ -288,12 +315,63 @@ void AuthSinkNegotiateStateMachine::GetSinkCredTypeForP2P(std::shared_ptraccessee.aclProfiles[DM_POINT_TO_POINT].GetAccesser().GetAccesserCredentialIdStr() != credObj[FILED_CRED_ID].Get())) { deleteCredInfo.push_back(credObj[FILED_CRED_ID].Get()); + DeleteCredential(context, context->accessee.userId, credObj, context->accessee.aclProfiles[DM_POINT_TO_POINT]); } else { credTypeJson["pointTopointCredType"] = credType; context->accessee.credentialInfos[credType] = credObj.Dump(); } } +void AuthSinkNegotiateStateMachine::GetSinkProxyCredTypeForP2P(std::shared_ptr context, + std::vector &deleteCredInfo) +{ + CHECK_NULL_VOID(context); + if (!context->IsProxyBind || context->subjectProxyOnes.empty()) { + return; + } + for (auto item = context->subjectProxyOnes.begin(); item != context->subjectProxyOnes.end(); ++item) { + JsonObject credInfoJson; + if (!item->proxyAccessee.credInfoJson.empty()) { + credInfoJson.Parse(item->proxyAccessee.credInfoJson); + } + for (const auto &credItem : credInfoJson.Items()) { + if (!credItem.Contains(FILED_CRED_TYPE) || !credItem[FILED_CRED_TYPE].IsNumberInteger() || + !credItem.Contains(FILED_CRED_ID) || !credItem[FILED_CRED_ID].IsString()) { + deleteCredInfo.push_back(credItem[FILED_CRED_ID].Get()); + DirectlyDeleteCredential(context, context->accessee.userId, credItem); + continue; + } + int32_t credType = credItem[FILED_CRED_TYPE].Get(); + if (credType != static_cast(DM_POINT_TO_POINT)) { + continue; + } + std::string credId = credItem[FILED_CRED_ID].Get(); + JsonObject aclTypeJson; + if (!item->proxyAccessee.aclTypeList.empty()) { + aclTypeJson.Parse(item->proxyAccessee.aclTypeList); + } + if (!aclTypeJson.Contains("pointTopointAcl") || + item->proxyAccessee.aclProfiles.find(DM_POINT_TO_POINT) == item->proxyAccessee.aclProfiles.end() || + (item->proxyAccessee.aclProfiles[DM_POINT_TO_POINT].GetAccessee().GetAccesseeCredentialIdStr() != + credItem[FILED_CRED_ID].Get() && + item->proxyAccessee.aclProfiles[DM_POINT_TO_POINT].GetAccesser().GetAccesserCredentialIdStr() != + credItem[FILED_CRED_ID].Get())) { + deleteCredInfo.push_back(credItem[FILED_CRED_ID].Get()); + DeleteCredential(context, context->accessee.userId, credItem, + item->proxyAccessee.aclProfiles[DM_POINT_TO_POINT]); + continue; + } + JsonObject validCredInfoJson; + if (!item->proxyAccessee.credTypeList.empty()) { + validCredInfoJson.Parse(item->proxyAccessee.credTypeList); + } + validCredInfoJson["pointTopointCredType"] = credType; + item->proxyAccessee.credTypeList = validCredInfoJson.Dump(); + item->proxyAccessee.credentialInfos[credType] = credItem.Dump(); + } + } +} + void AuthSinkNegotiateStateMachine::GetSinkAclInfo(std::shared_ptr context, JsonObject &credInfo, JsonObject &aclInfo) { @@ -354,6 +432,52 @@ void AuthSinkNegotiateStateMachine::GetSinkAclInfoForP2P(std::shared_ptraccessee.aclProfiles[DM_LNN] = profile; } + GetSinkProxyAclInfoForP2P(context, profile); +} + +void AuthSinkNegotiateStateMachine::GetSinkProxyAclInfoForP2P(std::shared_ptr context, + const DistributedDeviceProfile::AccessControlProfile &profile) +{ + CHECK_NULL_VOID(context); + if (!context->IsProxyBind || context->subjectProxyOnes.empty()) { + return; + } + for (auto &app : context->subjectProxyOnes) { + if ((profile.GetAccessee().GetAccesseeTokenId() == app.proxyAccessee.tokenId && + Crypto::GetTokenIdHash(std::to_string(profile.GetAccesser().GetAccesserTokenId())) == + app.proxyAccesser.tokenIdHash) || + (profile.GetAccesser().GetAccesserTokenId() == app.proxyAccessee.tokenId && + Crypto::GetTokenIdHash(std::to_string(profile.GetAccessee().GetAccesseeTokenId())) == + app.proxyAccesser.tokenIdHash)) { + std::string credId; + if (!IsAclHasCredential(profile, app.proxyAccessee.credInfoJson, credId)) { + DeleteAclAndSk(context, profile); + continue; + } + std::vector appList; + JsonObject credInfoJsonObj; + if (!app.proxyAccessee.credInfoJson.empty()) { + credInfoJsonObj.Parse(app.proxyAccessee.credInfoJson); + } + credInfoJsonObj[credId][FILED_AUTHORIZED_APP_LIST].Get(appList); + const size_t APP_LIST_SIZE = 2; + if (appList.size() < APP_LIST_SIZE || + std::find(appList.begin(), appList.end(), + std::to_string(profile.GetAccesser().GetAccesserTokenId())) == appList.end() || + std::find(appList.begin(), appList.end(), + std::to_string(profile.GetAccessee().GetAccesseeTokenId())) == appList.end()) { + DeleteAclAndSk(context, profile); + continue; + } + JsonObject aclTypeJson; + if (!app.proxyAccessee.aclTypeList.empty()) { + aclTypeJson.Parse(app.proxyAccessee.aclTypeList); + } + aclTypeJson["pointTopointAcl"] = DM_POINT_TO_POINT; + app.proxyAccessee.aclTypeList = aclTypeJson.Dump(); + app.proxyAccessee.aclProfiles[DM_POINT_TO_POINT] = profile; + } + } } bool AuthSinkNegotiateStateMachine::CheckCredIdInAcl(std::shared_ptr context, @@ -364,7 +488,7 @@ bool AuthSinkNegotiateStateMachine::CheckCredIdInAcl(std::shared_ptr= APP_LIST_SIZE && - ((std::to_string(profile.GetAccesser().GetAccesserTokenId()) == appList[0] && - std::to_string(profile.GetAccessee().GetAccesseeTokenId()) == appList[1]) || - (std::to_string(profile.GetAccessee().GetAccesseeTokenId()) == appList[0] && - std::to_string(profile.GetAccesser().GetAccesserTokenId()) == appList[1]))) { + std::find(appList.begin(), appList.end(), + std::to_string(profile.GetAccesser().GetAccesserTokenId())) != appList.end() && + std::find(appList.begin(), appList.end(), + std::to_string(profile.GetAccessee().GetAccesseeTokenId())) != appList.end()) { checkResult = true; } else { - DeleteAcl(context, profile); + DeleteAclAndSk(context, profile); } } else { DeleteAcl(context, profile); 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 index 9c11a753a803e120074c1016d7b76dbfdba51eea..d7d9ced4420486a4fc632508e83fc1c5812604fe 100644 --- a/services/implementation/src/authentication_v2/auth_stages/auth_pin_auth.cpp +++ b/services/implementation/src/authentication_v2/auth_stages/auth_pin_auth.cpp @@ -114,7 +114,7 @@ bool AuthSinkStatePinAuthComm::IsAuthCodeReady(std::shared_ptr co return false; } if (context->pkgName != context->importPkgName) { - LOGE("AuthSinkNegotiateStateMachine::IsAuthCodeReady pkgName %{public}s not supported with " + LOGE("AuthSinkStatePinAuthComm::IsAuthCodeReady pkgName %{public}s not supported with " "import pkgName %{public}s.", context->pkgName.c_str(), context->importPkgName.c_str()); return false; } @@ -268,7 +268,6 @@ int32_t AuthSinkPinAuthMsgNegotiateState::Action(std::shared_ptr LOGI("AuthSinkPinAuthMsgNegotiateState::AuthDevice WAIT ON_SESSION_KEY_RETURNED ON_ERROR failed, maybe retry."); return DM_OK; } - LOGE("AuthSinkPinAuthMsgNegotiateState::AuthDevice failed."); return STOP_BIND; } @@ -281,6 +280,7 @@ DmAuthStateType AuthSinkPinAuthDoneState::GetStateType() int32_t AuthSinkPinAuthDoneState::Action(std::shared_ptr context) { LOGI("AuthSinkPinAuthDoneState Action"); + GetSessionKey(context); return DM_OK; } @@ -390,17 +390,17 @@ int32_t AuthSrcPinNegotiateStartState::Action(std::shared_ptr con int32_t ret = NegotiateProcess::GetInstance().HandleNegotiateResult(context); if (ret != DM_OK) { LOGE("HandleNegotiateResult failed ret %{public}d", ret); - context->reason = ERR_DM_CAPABILITY_NEGOTIATE_FAILED; + context->reason = ret; return ret; } } - if (!context->needBind && !context->needAgreeCredential && context->needAuth) { + if (!IsNeedBind(context) && !IsNeedAgreeCredential(context) && IsNeedAuth(context)) { return ProcessCredAuth(context); } - if (context->needBind) { + if (IsNeedBind(context)) { return ProcessPinBind(context); } - if (!context->needBind && !context->needAgreeCredential && !context->needAuth) { + if (!IsNeedBind(context) && !IsNeedAgreeCredential(context) && !IsNeedAuth(context)) { context->reason = ERR_DM_BIND_TRUST_TARGET; context->authStateMachine->TransitionTo(std::make_shared()); return DM_OK; diff --git a/services/implementation/src/authentication_v2/dm_auth_manager_base.cpp b/services/implementation/src/authentication_v2/dm_auth_manager_base.cpp index f2d4fd466207eb05a16d562b45dae89683a78c78..80d4aca64d709d7e9ae77a77328a855a6c2dbf95 100644 --- a/services/implementation/src/authentication_v2/dm_auth_manager_base.cpp +++ b/services/implementation/src/authentication_v2/dm_auth_manager_base.cpp @@ -57,6 +57,7 @@ const char* TAG_TOKENID = "tokenId"; const char* TAG_HOST_PKGLABEL = "hostPkgLabel"; const char* TAG_REMOTE_DEVICE_NAME = "REMOTE_DEVICE_NAME"; const char* TAG_HOST = "HOST"; +const char* TAG_PROXY_CONTEXT_ID = "proxyContextId"; const char* APP_OPERATION_KEY = "appOperation"; const char* TARGET_PKG_NAME_KEY = "targetPkgName"; 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 820a997d7c7a647e21883dbc05afbbf508accab5..4e6b859472f10e7f8c96c05114e0a527566c26fa 100644 --- a/services/implementation/src/authentication_v2/dm_auth_message_processor.cpp +++ b/services/implementation/src/authentication_v2/dm_auth_message_processor.cpp @@ -107,6 +107,7 @@ constexpr const int32_t DM_HASH_LEN = 32; const char* TAG_DEVICE_TYPE = "DEVICETYPE"; constexpr int32_t DM_ULTRASONIC_FORWARD = 0; constexpr int32_t DM_ULTRASONIC_REVERSE = 1; +constexpr uint32_t MAX_SESSION_KEY_LENGTH = 512; void ParseDmAccessToSync(const std::string &jsonString, DmAccess &access, bool isUseDeviceFullName) { @@ -193,7 +194,6 @@ bool IsMessageValid(const JsonItemObject &jsonObject) } return true; } - } int32_t DmAuthMessageProcessor::SaveSessionKey(const uint8_t *sessionKey, const uint32_t keyLen) @@ -214,6 +214,60 @@ int32_t DmAuthMessageProcessor::SaveSessionKeyToDP(int32_t userId, int32_t &skId return DeviceProfileConnector::GetInstance().PutSessionKey(userId, cryptoMgr_->GetSessionKey(), skId); } +int32_t DmAuthMessageProcessor::SaveDerivativeSessionKeyToDP(int32_t userId, const std::string &suffix, int32_t &skId) +{ + if (cryptoMgr_ == nullptr) { + LOGE("DmAuthMessageProcessor::SaveSessionKeyToDP failed, cryptoMgr_ is nullptr."); + return ERR_DM_FAILED; + } + std::vector sessionKey = cryptoMgr_->GetSessionKey(); + size_t keyLen = sessionKey.size(); + std::string keyStr; + for (size_t i = 0; i < sessionKey.size(); ++i) { + keyStr = keyStr + (char)sessionKey.data()[i]; + } + std::string newKeyStr = Crypto::Sha256(keyStr + suffix); + DMSessionKey newSessionKey; + size_t newKeyLen = std::min(keyLen, newKeyStr.size()); + if (newKeyLen == 0 || newKeyLen > MAX_SESSION_KEY_LENGTH) { + LOGE("newKeyLen invaild, cannot allocate memory."); + return ERR_DM_FAILED; + } + newSessionKey.key = (uint8_t*)calloc(newKeyLen, sizeof(uint8_t)); + if (memcpy_s(newSessionKey.key, newKeyLen, newKeyStr.c_str(), newKeyLen) != DM_OK) { + LOGE("copy key data failed."); + if (newSessionKey.key != nullptr) { + (void)memset_s(newSessionKey.key, newKeyLen, 0, newKeyLen); + free(newSessionKey.key); + newSessionKey.key = nullptr; + newSessionKey.keyLen = 0; + } + return ERR_DM_FAILED; + } + newSessionKey.keyLen = newKeyLen; + int ret = DeviceProfileConnector::GetInstance().PutSessionKey(userId, + std::vector(newSessionKey.key, newSessionKey.key + newSessionKey.keyLen), skId); + if (newSessionKey.key != nullptr) { + (void)memset_s(newSessionKey.key, newSessionKey.keyLen, 0, newSessionKey.keyLen); + free(newSessionKey.key); + newSessionKey.key = nullptr; + newSessionKey.keyLen = 0; + } + return ret; +} + +int32_t DmAuthMessageProcessor::GetSessionKey(int32_t userId, int32_t &skId) +{ + std::vector sessionKey; + int32_t ret = DeviceProfileConnector::GetInstance().GetSessionKey(userId, skId, sessionKey); + if (ret != DM_OK) { + LOGE("failed: %{public}d", ret); + return ret; + } + CHECK_NULL_RETURN(cryptoMgr_, ERR_DM_POINT_NULL); + return cryptoMgr_->ProcessSessionKey(sessionKey.data(), sessionKey.size()); +} + int32_t DmAuthMessageProcessor::DeleteSessionKeyToDP(int32_t userId, int32_t skId) { return DeviceProfileConnector::GetInstance().DeleteSessionKey(userId, skId); @@ -307,21 +361,93 @@ int32_t DmAuthMessageProcessor::PutAccessControlList(std::shared_ptrdirection == DM_AUTH_SOURCE) ? context->accesser.isAuthed : context->accessee.isAuthed; + if (!context->IsProxyBind || context->subjectProxyOnes.empty() || (context->IsCallingProxyAsSubject && !isAuthed)) { + std::string isLnnAclFalse = std::string(ACL_IS_LNN_ACL_VAL_FALSE); + extraData[ACL_IS_LNN_ACL_KEY] = isLnnAclFalse; + profile.SetExtraData(extraData.Dump()); + profile.SetBindLevel(access.bindLevel); + SetTransmitAccessControlList(context, accesser, accessee); + profile.SetBindLevel(access.bindLevel); + profile.SetBindType(access.transmitBindType); + profile.SetAccessee(accessee); + profile.SetAccesser(accesser); + int32_t ret = + DistributedDeviceProfile::DistributedDeviceProfileClient::GetInstance().PutAccessControlProfile(profile); + if (ret != DM_OK) { + LOGE("PutAccessControlProfile failed."); + } } - return ret; + return PutProxyAccessControlList(context, profile, accesser, accessee); +} + +int32_t DmAuthMessageProcessor::SetProxyAccess(std::shared_ptr context, + DmProxyAuthContext &proxyAuthContext, DistributedDeviceProfile::Accesser &accesser, + DistributedDeviceProfile::Accessee &accessee) +{ + CHECK_NULL_RETURN(context, ERR_DM_POINT_NULL); + accesser.SetAccesserTokenId(proxyAuthContext.proxyAccesser.tokenId); + accesser.SetAccesserBundleName(proxyAuthContext.proxyAccesser.bundleName); + accesser.SetAccesserCredentialIdStr(proxyAuthContext.proxyAccesser.transmitCredentialId); + accesser.SetAccesserSessionKeyId(proxyAuthContext.proxyAccesser.transmitSessionKeyId); + accesser.SetAccesserSKTimeStamp(proxyAuthContext.proxyAccesser.skTimeStamp); + JsonObject accesserProxyObj(JsonCreateType::JSON_CREATE_TYPE_ARRAY); + accesserProxyObj.PushBack(context->accesser.tokenId); + JsonObject accesserExtObj; + if (!context->accesser.extraInfo.empty()) { + accesserExtObj.Parse(context->accesser.extraInfo); + } + accesserExtObj[TAG_PROXY] = accesserProxyObj.Dump(); + accesser.SetAccesserExtraData(accesserExtObj.Dump()); + + accessee.SetAccesseeTokenId(proxyAuthContext.proxyAccessee.tokenId); + accessee.SetAccesseeBundleName(proxyAuthContext.proxyAccessee.bundleName); + accessee.SetAccesseeCredentialIdStr(proxyAuthContext.proxyAccessee.transmitCredentialId); + accessee.SetAccesseeSessionKeyId(proxyAuthContext.proxyAccessee.transmitSessionKeyId); + accessee.SetAccesseeSKTimeStamp(proxyAuthContext.proxyAccessee.skTimeStamp); + JsonObject accesseeProxyObj(JsonCreateType::JSON_CREATE_TYPE_ARRAY); + accesseeProxyObj.PushBack(context->accessee.tokenId); + JsonObject accesseeExtObj; + if (!context->accessee.extraInfo.empty()) { + accesseeExtObj.Parse(context->accessee.extraInfo); + } + accesseeExtObj[TAG_PROXY] = accesseeProxyObj.Dump(); + accessee.SetAccesseeExtraData(accesseeExtObj.Dump()); + return DM_OK; +} + +int32_t DmAuthMessageProcessor::PutProxyAccessControlList(std::shared_ptr context, + DistributedDeviceProfile::AccessControlProfile &profile, DistributedDeviceProfile::Accesser &accesser, + DistributedDeviceProfile::Accessee &accessee) +{ + CHECK_NULL_RETURN(context, ERR_DM_POINT_NULL); + if (!context->IsProxyBind || context->subjectProxyOnes.empty()) { + return DM_OK; + } + for (auto &app : context->subjectProxyOnes) { + if (context->direction == DM_AUTH_SOURCE ? app.proxyAccesser.isAuthed : app.proxyAccessee.isAuthed) { + continue; + } + SetProxyAccess(context, app, accesser, accessee); + JsonObject extraData; + std::string isLnnAclFalse = std::string(ACL_IS_LNN_ACL_VAL_FALSE); + extraData[ACL_IS_LNN_ACL_KEY] = isLnnAclFalse; + profile.SetExtraData(extraData.Dump()); + profile.SetBindLevel(context->direction == DM_AUTH_SOURCE ? app.proxyAccesser.bindLevel : + app.proxyAccessee.bindLevel); + profile.SetBindType(context->direction == DM_AUTH_SOURCE ? context->accesser.transmitBindType : + context->accessee.transmitBindType); + profile.SetAccessee(accessee); + profile.SetAccesser(accesser); + int32_t ret = + DistributedDeviceProfile::DistributedDeviceProfileClient::GetInstance().PutAccessControlProfile(profile); + if (ret != DM_OK) { + LOGE("PutAccessControlProfile failed. %{public}d", ret); + return ret; + } + } + SetAclProxyRelate(context); + return DM_OK; } DmAuthMessageProcessor::DmAuthMessageProcessor() @@ -527,6 +653,7 @@ int32_t DmAuthMessageProcessor::ParseMessageReqCredExchange(const JsonObject &js 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(); + ParseProxyCredExchangeToSync(context, jsonData); context->authStateMachine->TransitionTo(std::make_shared()); return DM_OK; } @@ -572,11 +699,44 @@ int32_t DmAuthMessageProcessor::ParseMessageRspCredExchange(const JsonObject &js 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(); - + ParseProxyCredExchangeToSync(context, jsonData); context->authStateMachine->TransitionTo(std::make_shared()); return DM_OK; } +int32_t DmAuthMessageProcessor::ParseProxyCredExchangeToSync(std::shared_ptr &context, + JsonObject &jsonObject) +{ + CHECK_NULL_RETURN(context, ERR_DM_POINT_NULL); + if (!context->IsProxyBind || context->subjectProxyOnes.empty()) { + return DM_OK; + } + if (!IsString(jsonObject, PARAM_KEY_SUBJECT_PROXYED_SUBJECTS)) { + LOGE("no subjectProxyOnes"); + return ERR_DM_FAILED; + } + std::string subjectProxyOnesStr = jsonObject[PARAM_KEY_SUBJECT_PROXYED_SUBJECTS].Get(); + JsonObject allProxyObj; + allProxyObj.Parse(subjectProxyOnesStr); + for (auto const &item : allProxyObj.Items()) { + if (!IsString(item, TAG_PROXY_CONTEXT_ID)) { + continue; + } + DmProxyAuthContext proxyAuthContext; + proxyAuthContext.proxyContextId = item[TAG_PROXY_CONTEXT_ID].Get(); + auto it = std::find(context->subjectProxyOnes.begin(), context->subjectProxyOnes.end(), proxyAuthContext); + if (it != context->subjectProxyOnes.end()) { + if (!IsInt64(item, TAG_TOKEN_ID)) { + LOGE("no tokenId"); + return ERR_DM_FAILED; + } + DmProxyAccess &access = (context->direction == DM_AUTH_SOURCE) ? it->proxyAccessee : it->proxyAccesser; + access.tokenId = item[TAG_TOKEN_ID].Get(); + } + } + return DM_OK; +} + std::string DmAuthMessageProcessor::CreateMessage(DmMessageType msgType, std::shared_ptr context) { LOGI("DmAuthMessageProcessor::CreateMessage start. msgType is %{public}d", msgType); @@ -656,6 +816,29 @@ int32_t DmAuthMessageProcessor::CreateNegotiateMessage(std::shared_ptrbusinessId.empty()) { jsonObject[DM_BUSINESS_ID] = context->businessId; } + CreateProxyNegotiateMessage(context, jsonObject); + return DM_OK; +} + +int32_t DmAuthMessageProcessor::CreateProxyNegotiateMessage(std::shared_ptr context, + JsonObject &jsonObject) +{ + CHECK_NULL_RETURN(context, ERR_DM_POINT_NULL); + jsonObject[PARAM_KEY_IS_PROXY_BIND] = context->IsProxyBind; + jsonObject[PARAM_KEY_IS_CALLING_PROXY_AS_SUBJECT] = context->IsCallingProxyAsSubject; + if (context != nullptr && context->IsProxyBind && !context->subjectProxyOnes.empty()) { + JsonObject allProxyObj(JsonCreateType::JSON_CREATE_TYPE_ARRAY); + for (const auto &app : context->subjectProxyOnes) { + JsonObject object; + object[TAG_PROXY_CONTEXT_ID] = app.proxyContextId; + object[TAG_HOST_PKGLABEL] = app.pkgLabel; + object[TAG_BUNDLE_NAME] = app.proxyAccesser.bundleName; + object[TAG_PEER_BUNDLE_NAME] = app.proxyAccessee.bundleName; + object[TAG_TOKEN_ID_HASH] = app.proxyAccesser.tokenIdHash; + allProxyObj.PushBack(object); + } + jsonObject[PARAM_KEY_SUBJECT_PROXYED_SUBJECTS] = allProxyObj.Dump(); + } return DM_OK; } @@ -677,7 +860,27 @@ int32_t DmAuthMessageProcessor::CreateRespNegotiateMessage(std::shared_ptraccessee.networkId; jsonObject[TAG_IS_ONLINE] = context->accesser.isOnline; + CreateProxyRespNegotiateMessage(context, jsonObject); + return DM_OK; +} +int32_t DmAuthMessageProcessor::CreateProxyRespNegotiateMessage(std::shared_ptr context, + JsonObject &jsonObject) +{ + CHECK_NULL_RETURN(context, ERR_DM_POINT_NULL); + jsonObject[PARAM_KEY_IS_PROXY_BIND] = context->IsProxyBind; + if (context != nullptr && context->IsProxyBind && !context->subjectProxyOnes.empty()) { + JsonObject allProxyObj(JsonCreateType::JSON_CREATE_TYPE_ARRAY); + for (const auto &app : context->subjectProxyOnes) { + JsonObject object; + object[TAG_PROXY_CONTEXT_ID] = app.proxyContextId; + object[TAG_TOKEN_ID_HASH] = app.proxyAccessee.tokenIdHash; + object[TAG_ACL_TYPE_LIST] = app.proxyAccessee.aclTypeList; + object[TAG_CERT_TYPE_LIST] = app.proxyAccessee.credTypeList; + allProxyObj.PushBack(object); + } + jsonObject[PARAM_KEY_SUBJECT_PROXYED_SUBJECTS] = allProxyObj.Dump(); + } return DM_OK; } @@ -693,7 +896,7 @@ int32_t DmAuthMessageProcessor::CreateMessageReqCredExchange(std::shared_ptraccesser.deviceId; jsonData[TAG_PEER_USER_SPACE_ID] = context->accesser.userId; jsonData[TAG_TOKEN_ID] = context->accesser.tokenId; - + CreateProxyCredExchangeMessage(context, jsonData); std::string plainText = jsonData.Dump(); std::string cipherText; int32_t ret = cryptoMgr_->EncryptMessage(plainText, cipherText); @@ -718,7 +921,7 @@ int32_t DmAuthMessageProcessor::CreateMessageRspCredExchange(std::shared_ptraccessee.deviceId; jsonData[TAG_PEER_USER_SPACE_ID] = context->accessee.userId; jsonData[TAG_TOKEN_ID] = context->accessee.tokenId; - + CreateProxyCredExchangeMessage(context, jsonData); std::string plainText = jsonData.Dump(); std::string cipherText; LOGI("plainText=%{public}s", GetAnonyJsonString(plainText).c_str()); @@ -731,6 +934,25 @@ int32_t DmAuthMessageProcessor::CreateMessageRspCredExchange(std::shared_ptr &context, + JsonObject &jsonData) +{ + CHECK_NULL_RETURN(context, ERR_DM_POINT_NULL); + if (!context->IsProxyBind || context->subjectProxyOnes.empty()) { + return DM_OK; + } + JsonObject allProxyObj(JsonCreateType::JSON_CREATE_TYPE_ARRAY); + for (const auto &app : context->subjectProxyOnes) { + const DmProxyAccess &access = (context->direction == DM_AUTH_SOURCE) ? app.proxyAccesser : app.proxyAccessee; + JsonObject object; + object[TAG_PROXY_CONTEXT_ID] = app.proxyContextId; + object[TAG_TOKEN_ID] = access.tokenId; + allProxyObj.PushBack(object); + } + jsonData[PARAM_KEY_SUBJECT_PROXYED_SUBJECTS] = allProxyObj.Dump(); + return DM_OK; +} + // Create 160 message. int32_t DmAuthMessageProcessor::CreateMessageReqCredAuthStart(std::shared_ptr context, JsonObject &jsonObject) @@ -793,6 +1015,7 @@ bool DmAuthMessageProcessor::CheckAccessValidityAndAssign(std::shared_ptr // Parse into access ParseDmAccessToSync(srcAccessStr, accessTmp, false); // check access validity + if (ParseProxyAccessToSync(context, jsonObject) != DM_OK) { + LOGE("ParseProxyAccessToSync error, stop auth."); + return ERR_DM_FAILED; + } if (!CheckAccessValidityAndAssign(context, access, accessTmp)) { LOGE("ParseSyncMessage CheckAccessValidityAndAssign error, data between two stages different, stop auth."); return ERR_DM_FAILED; @@ -824,7 +1051,6 @@ int32_t DmAuthMessageProcessor::ParseSyncMessage(std::shared_ptr return ERR_DM_FAILED; } access.aclStrList = jsonObject[TAG_ACL_CHECKSUM].Get(); - if (context->direction == DmAuthDirection::DM_AUTH_SOURCE) { LOGI("Source parse sink user confirm opt"); int32_t userConfirmOpt = static_cast(USER_OPERATION_TYPE_CANCEL_AUTH); @@ -840,27 +1066,78 @@ int32_t DmAuthMessageProcessor::ParseSyncMessage(std::shared_ptr return DM_OK; } +int32_t DmAuthMessageProcessor::ParseProxyAccessToSync(std::shared_ptr &context, + JsonObject &jsonObject) +{ + CHECK_NULL_RETURN(context, ERR_DM_POINT_NULL); + if (!context->IsProxyBind || context->subjectProxyOnes.empty()) { + return DM_OK; + } + if (!IsString(jsonObject, PARAM_KEY_SUBJECT_PROXYED_SUBJECTS)) { + LOGE("no subjectProxyOnes"); + return ERR_DM_FAILED; + } + std::string subjectProxyOnesStr = jsonObject[PARAM_KEY_SUBJECT_PROXYED_SUBJECTS].Get(); + JsonObject allProxyObj; + allProxyObj.Parse(subjectProxyOnesStr); + for (auto const &item : allProxyObj.Items()) { + if (!IsString(item, TAG_PROXY_CONTEXT_ID)) { + LOGE("no proxyContextId"); + return ERR_DM_FAILED; + } + DmProxyAuthContext proxyAuthContext; + proxyAuthContext.proxyContextId = item[TAG_PROXY_CONTEXT_ID].Get(); + auto it = std::find(context->subjectProxyOnes.begin(), context->subjectProxyOnes.end(), proxyAuthContext); + if (it != context->subjectProxyOnes.end()) { + if (!IsInt64(item, TAG_TOKEN_ID) || !IsString(item, TAG_TRANSMIT_SK_ID) || + !IsInt32(item, TAG_BIND_LEVEL) || !IsInt64(item, TAG_TRANSMIT_SK_TIMESTAMP) || + !IsString(item, TAG_TRANSMIT_CREDENTIAL_ID)) { + LOGE("proxyContext format error"); + return ERR_DM_FAILED; + } + + DmProxyAccess &access = (context->direction == DM_AUTH_SOURCE) ? it->proxyAccessee : it->proxyAccesser; + DmProxyAccess &selfAccess = (context->direction == DM_AUTH_SOURCE) ? it->proxyAccesser : it->proxyAccessee; + if (Crypto::GetTokenIdHash(std::to_string(item[TAG_TOKEN_ID].Get())) == access.tokenIdHash && + item[TAG_BIND_LEVEL].Get() == selfAccess.bindLevel) { + access.tokenId = item[TAG_TOKEN_ID].Get(); + access.bindLevel = item[TAG_BIND_LEVEL].Get(); + access.transmitSessionKeyId = std::atoi(item[TAG_TRANSMIT_SK_ID].Get().c_str()); + access.skTimeStamp = item[TAG_TRANSMIT_SK_TIMESTAMP].Get(); + access.transmitCredentialId = item[TAG_TRANSMIT_CREDENTIAL_ID].Get(); + } else { + LOGE("tokenId or bindLevel invaild"); + return ERR_DM_FAILED; + } + } else { + LOGE("proxyContextId not exist"); + return ERR_DM_FAILED; + } + } + return DM_OK; +} + 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"); + LOGE("syncMsg error"); return ret; } JsonObject plainJson(syncMsgCompress); if (plainJson.IsDiscarded()) { - LOGE("DecryptSyncMessage plainJson error"); + LOGE("plainJson error"); return ERR_DM_FAILED; } if (!plainJson[TAG_COMPRESS_ORI_LEN].IsNumberInteger()) { - LOGE("DecryptSyncMessage TAG_COMPRESS_ORI_LEN json error"); + LOGE("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"); + LOGE("TAG_COMPRESS_ORI_LEN json error"); return ERR_DM_FAILED; } std::string compressMsg = plainJson[TAG_COMPRESS].Get(); @@ -868,13 +1145,13 @@ int32_t DmAuthMessageProcessor::DecryptSyncMessage(std::shared_ptrauthStateMachine->TransitionTo(std::make_shared()); return DM_OK; } @@ -1040,6 +1318,46 @@ void DmAuthMessageProcessor::ParseCert(const JsonObject &jsonObject, } } +int32_t DmAuthMessageProcessor::ParseProxyNegotiateMessage( + const JsonObject &jsonObject, std::shared_ptr context) +{ + CHECK_NULL_RETURN(context, ERR_DM_POINT_NULL); + context->IsProxyBind = false; + //accesser dmVersion greater than DM_VERSION_5_1_1 + if (CompareVersion(context->accesser.dmVersion, DM_VERSION_5_1_1) && IsBool(jsonObject, PARAM_KEY_IS_PROXY_BIND)) { + context->IsProxyBind = jsonObject[PARAM_KEY_IS_PROXY_BIND].Get(); + } + if (!context->IsProxyBind) { + return DM_OK; + } + if (IsBool(jsonObject, PARAM_KEY_IS_CALLING_PROXY_AS_SUBJECT)) { + context->IsCallingProxyAsSubject = jsonObject[PARAM_KEY_IS_CALLING_PROXY_AS_SUBJECT].Get(); + } + + if (!IsString(jsonObject, PARAM_KEY_SUBJECT_PROXYED_SUBJECTS)) { + return ERR_DM_INPUT_PARA_INVALID; + } + std::string subjectProxyOnesStr = jsonObject[PARAM_KEY_SUBJECT_PROXYED_SUBJECTS].Get(); + JsonObject allProxyObj; + allProxyObj.Parse(subjectProxyOnesStr); + for (auto const &item : allProxyObj.Items()) { + if (!IsString(item, TAG_PROXY_CONTEXT_ID) || !IsString(item, TAG_BUNDLE_NAME) || + !IsString(item, TAG_PEER_BUNDLE_NAME) || !IsString(item, TAG_TOKEN_ID_HASH)) { + continue; + } + DmProxyAuthContext proxyAuthContext; + proxyAuthContext.proxyContextId = item[TAG_PROXY_CONTEXT_ID].Get(); + proxyAuthContext.proxyAccesser.bundleName = item[TAG_BUNDLE_NAME].Get(); + proxyAuthContext.proxyAccessee.bundleName = item[TAG_PEER_BUNDLE_NAME].Get(); + proxyAuthContext.proxyAccesser.tokenIdHash = item[TAG_TOKEN_ID_HASH].Get(); + if (IsString(item, TAG_HOST_PKGLABEL)) { + proxyAuthContext.pkgLabel = item[TAG_HOST_PKGLABEL].Get(); + } + context->subjectProxyOnes.push_back(proxyAuthContext); + } + return DM_OK; +} + void DmAuthMessageProcessor::ParseUltrasonicSide( const JsonObject &jsonObject, std::shared_ptr context) { @@ -1107,10 +1425,47 @@ int32_t DmAuthMessageProcessor::ParseMessageRespAclNegotiate(const JsonObject &j if (jsonObject[TAG_EXTRA_INFO].IsString()) { context->accessee.extraInfo = jsonObject[TAG_EXTRA_INFO].Get(); } + ParseMessageProxyRespAclNegotiate(jsonObject, context); context->authStateMachine->TransitionTo(std::make_shared()); return DM_OK; } +int32_t DmAuthMessageProcessor::ParseMessageProxyRespAclNegotiate(const JsonObject &jsonObject, + std::shared_ptr context) +{ + CHECK_NULL_RETURN(context, ERR_DM_POINT_NULL); + //sink not support proxy + if (!CompareVersion(context->accessee.dmVersion, DM_VERSION_5_1_1)) { + context->IsProxyBind = false; + LOGE("sink does not support proxy"); + return DM_OK; + } + if (!context->IsProxyBind) { + return DM_OK; + } + if (!IsString(jsonObject, PARAM_KEY_SUBJECT_PROXYED_SUBJECTS)) { + return ERR_DM_INPUT_PARA_INVALID; + } + std::string subjectProxyOnesStr = jsonObject[PARAM_KEY_SUBJECT_PROXYED_SUBJECTS].Get(); + JsonObject allProxyObj; + allProxyObj.Parse(subjectProxyOnesStr); + for (auto const &item : allProxyObj.Items()) { + if (!IsString(item, TAG_PROXY_CONTEXT_ID) || !IsString(item, TAG_TOKEN_ID_HASH) || + !IsString(item, TAG_ACL_TYPE_LIST) || !IsString(item, TAG_CERT_TYPE_LIST)) { + continue; + } + DmProxyAuthContext proxyAuthContext; + proxyAuthContext.proxyContextId = item[TAG_PROXY_CONTEXT_ID].Get(); + auto it = std::find(context->subjectProxyOnes.begin(), context->subjectProxyOnes.end(), proxyAuthContext); + if (it != context->subjectProxyOnes.end()) { + it->proxyAccessee.tokenIdHash = item[TAG_TOKEN_ID_HASH].Get(); + it->proxyAccessee.aclTypeList = item[TAG_ACL_TYPE_LIST].Get(); + it->proxyAccessee.credTypeList = item[TAG_CERT_TYPE_LIST].Get(); + } + } + return DM_OK; +} + int32_t DmAuthMessageProcessor::ParseMessageReqUserConfirm(const JsonObject &json, std::shared_ptr context) { @@ -1135,10 +1490,40 @@ int32_t DmAuthMessageProcessor::ParseMessageReqUserConfirm(const JsonObject &jso if (IsString(json, TAG_CUSTOM_DESCRIPTION)) { context->customData = json[TAG_CUSTOM_DESCRIPTION].Get(); } + ParseMessageProxyReqUserConfirm(json, context); context->authStateMachine->TransitionTo(std::make_shared()); return DM_OK; } +int32_t DmAuthMessageProcessor::ParseMessageProxyReqUserConfirm(const JsonObject &json, + std::shared_ptr context) +{ + CHECK_NULL_RETURN(context, ERR_DM_POINT_NULL); + if (!context->IsProxyBind) { + return DM_OK; + } + if (!IsString(json, PARAM_KEY_SUBJECT_PROXYED_SUBJECTS)) { + return ERR_DM_INPUT_PARA_INVALID; + } + std::string subjectProxyOnesStr = json[PARAM_KEY_SUBJECT_PROXYED_SUBJECTS].Get(); + JsonObject allProxyObj; + allProxyObj.Parse(subjectProxyOnesStr); + for (auto const &item : allProxyObj.Items()) { + if (!IsString(item, TAG_PROXY_CONTEXT_ID) || !IsString(item, TAG_ACL_TYPE_LIST) || + !IsString(item, TAG_CERT_TYPE_LIST)) { + continue; + } + DmProxyAuthContext proxyAuthContext; + proxyAuthContext.proxyContextId = item[TAG_PROXY_CONTEXT_ID].Get(); + auto it = std::find(context->subjectProxyOnes.begin(), context->subjectProxyOnes.end(), proxyAuthContext); + if (it != context->subjectProxyOnes.end()) { + it->proxyAccesser.aclTypeList = item[TAG_ACL_TYPE_LIST].Get(); + it->proxyAccesser.credTypeList = item[TAG_CERT_TYPE_LIST].Get(); + } + } + return DM_OK; +} + int32_t DmAuthMessageProcessor::ParseMessageRespUserConfirm(const JsonObject &json, std::shared_ptr context) { @@ -1149,10 +1534,47 @@ int32_t DmAuthMessageProcessor::ParseMessageRespUserConfirm(const JsonObject &js if (json[TAG_EXTRA_INFO].IsString()) { context->accessee.extraInfo = json[TAG_EXTRA_INFO].Get(); } + ParseMessageProxyRespUserConfirm(json, context); context->authStateMachine->TransitionTo(std::make_shared()); return DM_OK; } +int32_t DmAuthMessageProcessor::ParseMessageProxyRespUserConfirm(const JsonObject &json, + std::shared_ptr context) +{ + if (!context->IsProxyBind) { + return DM_OK; + } + if (!IsString(json, PARAM_KEY_SUBJECT_PROXYED_SUBJECTS)) { + context->subjectProxyOnes.clear(); + return ERR_DM_INPUT_PARA_INVALID; + } + std::string subjectProxyOnesStr = json[PARAM_KEY_SUBJECT_PROXYED_SUBJECTS].Get(); + JsonObject allProxyObj; + allProxyObj.Parse(subjectProxyOnesStr); + if (allProxyObj.IsDiscarded()) { + context->subjectProxyOnes.clear(); + return ERR_DM_INPUT_PARA_INVALID; + } + std::vector sinksubjectProxyOnes; + for (auto const &item : allProxyObj.Items()) { + if (!IsString(item, TAG_PROXY_CONTEXT_ID)) { + continue; + } + DmProxyAuthContext proxyAuthContext; + proxyAuthContext.proxyContextId = item[TAG_PROXY_CONTEXT_ID].Get(); + sinksubjectProxyOnes.push_back(proxyAuthContext); + } + for (auto item = context->subjectProxyOnes.begin(); item != context->subjectProxyOnes.end();) { + if (std::find(sinksubjectProxyOnes.begin(), sinksubjectProxyOnes.end(), *item) != sinksubjectProxyOnes.end()) { + item++; + } else { + item = context->subjectProxyOnes.erase(item); + } + } + return DM_OK; +} + int32_t DmAuthMessageProcessor::ParseMessageReqPinAuthStart(const JsonObject &json, std::shared_ptr context) { @@ -1231,7 +1653,24 @@ int32_t DmAuthMessageProcessor::CreateMessageReqUserConfirm(std::shared_ptraccesser.deviceName; json[TAG_EXTRA_INFO] = context->accesser.extraInfo; json[TAG_CUSTOM_DESCRIPTION] = context->customData; + CreateMessageProxyReqUserConfirm(context, json); + return DM_OK; +} +int32_t DmAuthMessageProcessor::CreateMessageProxyReqUserConfirm(std::shared_ptr context, + JsonObject &json) +{ + if (context != nullptr && context->IsProxyBind && !context->subjectProxyOnes.empty()) { + JsonObject allProxyObj(JsonCreateType::JSON_CREATE_TYPE_ARRAY); + for (const auto &app : context->subjectProxyOnes) { + JsonObject object; + object[TAG_PROXY_CONTEXT_ID] = app.proxyContextId; + object[TAG_ACL_TYPE_LIST] = app.proxyAccesser.aclTypeList; + object[TAG_CERT_TYPE_LIST] = app.proxyAccesser.credTypeList; + allProxyObj.PushBack(object); + } + json[PARAM_KEY_SUBJECT_PROXYED_SUBJECTS] = allProxyObj.Dump(); + } return DM_OK; } @@ -1239,6 +1678,15 @@ int32_t DmAuthMessageProcessor::CreateMessageRespUserConfirm(std::shared_ptrauthTypeList); json[TAG_EXTRA_INFO] = context->accessee.extraInfo; + if (context != nullptr && context->IsProxyBind && !context->subjectProxyOnes.empty()) { + JsonObject allProxyObj(JsonCreateType::JSON_CREATE_TYPE_ARRAY); + for (const auto &app : context->subjectProxyOnes) { + JsonObject object; + object[TAG_PROXY_CONTEXT_ID] = app.proxyContextId; + allProxyObj.PushBack(object); + } + json[PARAM_KEY_SUBJECT_PROXYED_SUBJECTS] = allProxyObj.Dump(); + } return DM_OK; } @@ -1431,6 +1879,7 @@ int32_t DmAuthMessageProcessor::EncryptSyncMessage(std::shared_ptraccesser.isCommonFlag; syncMsgJson[TAG_DM_CERT_CHAIN] = context->accesser.cert; + CreateProxyAccessMessage(context, syncMsgJson); std::string syncMsg = syncMsgJson.Dump(); std::string compressMsg = CompressSyncMsg(syncMsg); if (compressMsg.empty()) { @@ -1443,6 +1892,39 @@ int32_t DmAuthMessageProcessor::EncryptSyncMessage(std::shared_ptrEncryptMessage(plainJson.Dump(), encSyncMsg); } +int32_t DmAuthMessageProcessor::CreateProxyAccessMessage(std::shared_ptr &context, + JsonObject &syncMsgJson) +{ + CHECK_NULL_RETURN(context, ERR_DM_POINT_NULL); + if (!context->IsProxyBind || context->subjectProxyOnes.empty()) { + return DM_OK; + } + JsonObject allProxyObj(JsonCreateType::JSON_CREATE_TYPE_ARRAY); + for (const auto &app : context->subjectProxyOnes) { + DmProxyAccess access; + if (context->direction == DM_AUTH_SOURCE) { + access = app.proxyAccesser; + } else { + access = app.proxyAccessee; + } + if (access.isAuthed) { + continue; + } + JsonObject object; + object[TAG_PROXY_CONTEXT_ID] = app.proxyContextId; + object[TAG_TOKEN_ID] = access.tokenId; + object[TAG_BUNDLE_NAME] = access.bundleName; + object[TAG_BIND_LEVEL] = access.bindLevel; + object[TAG_PKG_NAME] = access.pkgName; + object[TAG_TRANSMIT_SK_ID] = std::to_string(access.transmitSessionKeyId); + object[TAG_TRANSMIT_SK_TIMESTAMP] = access.skTimeStamp; + object[TAG_TRANSMIT_CREDENTIAL_ID] = access.transmitCredentialId; + allProxyObj.PushBack(object); + } + syncMsgJson[PARAM_KEY_SUBJECT_PROXYED_SUBJECTS] = allProxyObj.Dump(); + return DM_OK; +} + int32_t DmAuthMessageProcessor::ACLToStr(DistributedDeviceProfile::AccessControlProfile acl, std::string aclStr) { DmAccessControlTable dmAcl; @@ -1501,6 +1983,85 @@ int32_t DmAuthMessageProcessor::ParseAuthStartMessage(const JsonObject &jsonObje return DM_OK; } +bool DmAuthMessageProcessor::IsExistTheToken(JsonObject &proxyObj, int64_t tokenId) +{ + if (proxyObj.IsDiscarded()) { + return false; + } + for (auto const &item : proxyObj.Items()) { + if (tokenId == item.Get()) { + return true; + } + } + return false; +} + +void DmAuthMessageProcessor::SetAclProxyRelate(std::shared_ptr context) +{ + CHECK_NULL_VOID(context); + if (!context->IsProxyBind || context->subjectProxyOnes.empty()) { + return; + } + DmAccess &access = (context->direction == DM_AUTH_SOURCE) ? context->accesser : context->accessee; + DmAccess &remoteAccess = (context->direction == DM_AUTH_SOURCE) ? context->accessee : context->accesser; + for (auto &app : context->subjectProxyOnes) { + DmProxyAccess &proxyAccess = (context->direction == DM_AUTH_SOURCE) ? app.proxyAccesser : app.proxyAccessee; + if (!proxyAccess.isAuthed || proxyAccess.aclProfiles.find(DM_POINT_TO_POINT) == + proxyAccess.aclProfiles.end()) { + continue; + } + SetAclProxyRelate(context, proxyAccess.aclProfiles[DM_POINT_TO_POINT]); + } +} + +void DmAuthMessageProcessor::SetAclProxyRelate(std::shared_ptr context, + DistributedDeviceProfile::AccessControlProfile &profile) +{ + DmAccess &access = (context->direction == DM_AUTH_SOURCE) ? context->accesser : context->accessee; + DmAccess &remoteAccess = (context->direction == DM_AUTH_SOURCE) ? context->accessee : context->accesser; + bool isNeedUpdateProxy = false; + JsonObject accesserExtObj; + if (!profile.GetAccesser().GetAccesserExtraData().empty()) { + accesserExtObj.Parse(profile.GetAccesser().GetAccesserExtraData()); + } + JsonObject accesserProxyObj(JsonCreateType::JSON_CREATE_TYPE_ARRAY); + if (IsString(accesserExtObj, TAG_PROXY)) { + std::string proxyStr = accesserExtObj[TAG_PROXY].Get(); + accesserProxyObj.Parse(proxyStr); + } + int64_t tokenId = access.deviceId == profile.GetAccesser().GetAccesserDeviceId() ? access.tokenId : + remoteAccess.tokenId; + if (!IsExistTheToken(accesserProxyObj, tokenId)) { + isNeedUpdateProxy = true; + accesserProxyObj.PushBack(tokenId); + accesserExtObj[TAG_PROXY] = accesserProxyObj.Dump(); + DistributedDeviceProfile::Accesser accesser = profile.GetAccesser(); + accesser.SetAccesserExtraData(accesserExtObj.Dump()); + profile.SetAccesser(accesser); + } + + JsonObject accesseeExtObj; + if (!profile.GetAccessee().GetAccesseeExtraData().empty()) { + accesseeExtObj.Parse(profile.GetAccessee().GetAccesseeExtraData()); + } + JsonObject accesseeProxyObj(JsonCreateType::JSON_CREATE_TYPE_ARRAY); + if (IsString(accesseeExtObj, TAG_PROXY)) { + std::string proxyStr = accesseeExtObj[TAG_PROXY].Get(); + accesseeProxyObj.Parse(proxyStr); + } + tokenId = access.deviceId == profile.GetAccesser().GetAccesserDeviceId() ? remoteAccess.tokenId : access.tokenId; + if (!IsExistTheToken(accesseeProxyObj, tokenId)) { + isNeedUpdateProxy = true; + accesseeProxyObj.PushBack(tokenId); + accesseeExtObj[TAG_PROXY] = accesseeProxyObj.Dump(); + DistributedDeviceProfile::Accessee accessee = profile.GetAccessee(); + accessee.SetAccesseeExtraData(accesseeExtObj.Dump()); + profile.SetAccessee(accessee); + } + if (isNeedUpdateProxy) { + DistributedDeviceProfile::DistributedDeviceProfileClient::GetInstance().UpdateAccessControlProfile(profile); + } +} void ToJson(JsonItemObject &itemObject, const DmAccessControlTable &table) { diff --git a/services/implementation/src/authentication_v2/dm_auth_state.cpp b/services/implementation/src/authentication_v2/dm_auth_state.cpp index 7ab8d7a8cda4cca04c3270a42e9d0aef58bf54ed..9a63c3f00ed5dd2a7e8aabdc7f706ad6e07d7f37 100644 --- a/services/implementation/src/authentication_v2/dm_auth_state.cpp +++ b/services/implementation/src/authentication_v2/dm_auth_state.cpp @@ -119,7 +119,7 @@ void DmAuthState::SourceFinish(std::shared_ptr context) GetOutputState(context->state), GenerateBindResultContent(context)); context->successFinished = true; - if (context->reason != DM_OK && context->reason != DM_ALREADY_AUTHED) { + if (context->reason != DM_OK && context->reason != DM_ALREADY_AUTHED && context->reUseCreId.empty()) { // 根据凭据id 删除sink端多余的凭据 context->hiChainAuthConnector->DeleteCredential(context->accesser.userId, context->accesser.lnnCredentialId); @@ -153,7 +153,7 @@ void DmAuthState::SinkFinish(std::shared_ptr context) GetOutputReplay(context->accessee.bundleName, context->reason), GetOutputState(context->state), GenerateBindResultContent(context)); context->successFinished = true; - if (context->reason != DM_OK) { + if (context->reason != DM_OK && context->reUseCreId.empty()) { // 根据凭据id 删除sink端多余的凭据 context->hiChainAuthConnector->DeleteCredential(context->accessee.userId, context->accessee.lnnCredentialId); @@ -167,6 +167,7 @@ void DmAuthState::SinkFinish(std::shared_ptr context) } else { SetAclInfo(context); if (NeedAgreeAcl(context)) { + UpdateCredInfo(context); context->authMessageProcessor->PutAccessControlList(context, context->accessee, context->accesser.deviceId); } @@ -223,14 +224,131 @@ bool DmAuthState::NeedReqUserConfirm(std::shared_ptr context) return true; } -bool DmAuthState::NeedAgreeCredential(std::shared_ptr context) +bool DmAuthState::NeedAgreeAcl(std::shared_ptr context) { - return context->needAgreeCredential; + if (context == nullptr) { + return true; + } + if (context->direction == DM_AUTH_SOURCE) { + if (context->accesser.isUserLevelAuthed) { + LOGI("accesser user level authed"); + return false; + } + if (!context->IsProxyBind || context->subjectProxyOnes.empty()) { + LOGI("accesser is authed"); + return !context->accesser.isAuthed; + } + if (context->IsCallingProxyAsSubject && !context->accesser.isAuthed) { + LOGI("accesser is not authed"); + return true; + } + return ProxyNeedAgreeAcl(context); + } + if (context->accessee.isUserLevelAuthed) { + LOGI("accessee user level authed"); + return false; + } + if (!context->IsProxyBind || context->subjectProxyOnes.empty()) { + LOGI("accessee is authed"); + return !context->accessee.isAuthed; + } + if (context->IsCallingProxyAsSubject && !context->accessee.isAuthed) { + LOGI("accessee is not authed"); + return true; + } + return ProxyNeedAgreeAcl(context); } -bool DmAuthState::NeedAgreeAcl(std::shared_ptr context) +bool DmAuthState::ProxyNeedAgreeAcl(std::shared_ptr context) { - return (context->direction == DM_AUTH_SOURCE) ? !context->accesser.isAuthed : !context->accessee.isAuthed; + CHECK_NULL_RETURN(context, ERR_DM_POINT_NULL); + if (!context->IsProxyBind || context->subjectProxyOnes.empty()) { + return false; + } + if (context->direction == DM_AUTH_SOURCE) { + for (const auto &app : context->subjectProxyOnes) { + if (!app.proxyAccesser.isAuthed) { + return true; + } + } + return false; + } + for (const auto &app : context->subjectProxyOnes) { + if (!app.proxyAccessee.isAuthed) { + return true; + } + } + return false; +} + +bool DmAuthState::GetReuseSkId(std::shared_ptr context, int32_t &skId) +{ + CHECK_NULL_RETURN(context, ERR_DM_POINT_NULL); + DistributedDeviceProfile::AccessControlProfile profile; + GetReuseACL(context, profile); + if (!profile.GetAccesser().GetAccesserCredentialIdStr().empty() && + !profile.GetAccessee().GetAccesseeCredentialIdStr().empty()) { + if (context->direction == DM_AUTH_SOURCE) { + if (context->accesser.deviceId == profile.GetAccesser().GetAccesserDeviceId()) { + skId = profile.GetAccesser().GetAccesserSessionKeyId(); + context->reUseCreId = profile.GetAccesser().GetAccesserCredentialIdStr(); + context->accessee.deviceId = profile.GetAccessee().GetAccesseeDeviceId(); + return true; + } + skId = profile.GetAccessee().GetAccesseeSessionKeyId(); + context->reUseCreId = profile.GetAccessee().GetAccesseeCredentialIdStr(); + context->accessee.deviceId = profile.GetAccesser().GetAccesserDeviceId(); + return true; + } + if (context->accessee.deviceId == profile.GetAccessee().GetAccesseeDeviceId()) { + skId = profile.GetAccessee().GetAccesseeSessionKeyId(); + context->reUseCreId = profile.GetAccessee().GetAccesseeCredentialIdStr(); + context->accesser.deviceId = profile.GetAccesser().GetAccesserDeviceId(); + return true; + } + skId = profile.GetAccesser().GetAccesserSessionKeyId(); + context->reUseCreId = profile.GetAccesser().GetAccesserCredentialIdStr(); + context->accesser.deviceId = profile.GetAccessee().GetAccesseeDeviceId(); + return true; + } + return false; +} + +void DmAuthState::GetReuseACL(std::shared_ptr context, + DistributedDeviceProfile::AccessControlProfile &profile) +{ + if (context == nullptr) { + return; + } + if (!context->IsProxyBind || context->subjectProxyOnes.empty()) { + return; + } + DmAccess &access = (context->direction == DM_AUTH_SOURCE) ? context->accesser : context->accessee; + if (!access.aclTypeList.empty()) { + JsonObject aclTypeListJson; + aclTypeListJson.Parse(access.aclTypeList); + if (!aclTypeListJson.IsDiscarded() && aclTypeListJson.Contains("pointTopointAcl") && + access.aclProfiles.find(DM_POINT_TO_POINT) != access.aclProfiles.end() && + !access.aclProfiles[DM_POINT_TO_POINT].GetAccessee().GetAccesseeCredentialIdStr().empty() && + !access.aclProfiles[DM_POINT_TO_POINT].GetAccesser().GetAccesserCredentialIdStr().empty()) { + profile = access.aclProfiles[DM_POINT_TO_POINT]; + return; + } + } + for (auto &app : context->subjectProxyOnes) { + DmProxyAccess &proxyAccess = context->direction == DM_AUTH_SOURCE ? app.proxyAccesser : app.proxyAccessee; + JsonObject aclList; + if (!proxyAccess.aclTypeList.empty()) { + aclList.Parse(proxyAccess.aclTypeList); + } + if (!aclList.IsDiscarded() && aclList.Contains("pointTopointAcl") && + proxyAccess.aclProfiles.find(DM_POINT_TO_POINT) != proxyAccess.aclProfiles.end() && + !proxyAccess.aclProfiles[DM_POINT_TO_POINT].GetAccessee().GetAccesseeCredentialIdStr().empty() && + !proxyAccess.aclProfiles[DM_POINT_TO_POINT].GetAccesser().GetAccesserCredentialIdStr().empty()) { + profile = proxyAccess.aclProfiles[DM_POINT_TO_POINT]; + return; + } + } } bool DmAuthState::IsImportAuthCodeCompatibility(DmAuthType authType) @@ -308,9 +426,15 @@ uint32_t DmAuthState::GetCredType(std::shared_ptr context, const context->direction == DM_AUTH_SINK && subject == SUBJECT_SECONDARY) { return DM_SHARE; } - if (credType == ACCOUNT_UNRELATED && (authorizedScope == SCOPE_APP || authorizedScope == SCOPE_USER) && - HaveSameTokenId(context, appList)) { - return DM_POINT_TO_POINT; + if (credType == ACCOUNT_UNRELATED && (authorizedScope == SCOPE_APP || authorizedScope == SCOPE_USER)) { + std::vector tokenIdHashList; + for (std::string tokenId : appList) { + tokenIdHashList.push_back(Crypto::GetTokenIdHash(tokenId)); + } + GetProxyCredInfo(context, credInfo, tokenIdHashList); + if (HaveSameTokenId(context, tokenIdHashList)) { + return DM_POINT_TO_POINT; + } } if (credType == ACCOUNT_UNRELATED && authorizedScope == SCOPE_USER && appList.empty()) { return DM_LNN; @@ -318,6 +442,43 @@ uint32_t DmAuthState::GetCredType(std::shared_ptr context, const return DM_INVALIED_TYPE; } +int32_t DmAuthState::GetProxyCredInfo(std::shared_ptr context, const JsonItemObject &credInfo, + const std::vector &tokenIdHashList) +{ + CHECK_NULL_RETURN(context, ERR_DM_POINT_NULL); + if (!context->IsProxyBind) { + return DM_OK; + } + if (context->subjectProxyOnes.empty()) { + return ERR_DM_INPUT_PARA_INVALID; + } + if (!credInfo.Contains(FILED_CRED_ID) || !credInfo[FILED_CRED_ID].IsString()) { + return static_cast(DM_INVALIED_TYPE); + } + for (auto &app : context->subjectProxyOnes) { + if (std::find(tokenIdHashList.begin(), tokenIdHashList.end(), app.proxyAccesser.tokenIdHash) + != tokenIdHashList.end() && + std::find(tokenIdHashList.begin(), tokenIdHashList.end(), app.proxyAccessee.tokenIdHash) + != tokenIdHashList.end()) { + JsonObject appCredInfo(credInfo.Dump()); + appCredInfo[FILED_CRED_TYPE] = DM_POINT_TO_POINT; + JsonObject credInfoJson; + std::string credInfoJsonStr = context->direction == DM_AUTH_SOURCE ? app.proxyAccesser.credInfoJson : + app.proxyAccessee.credInfoJson; + if (!credInfoJsonStr.empty()) { + credInfoJson.Parse(credInfoJsonStr); + } + credInfoJson.Insert(credInfo[FILED_CRED_ID].Get(), appCredInfo); + if (context->direction == DM_AUTH_SOURCE) { + app.proxyAccesser.credInfoJson = credInfoJson.Dump(); + } else { + app.proxyAccessee.credInfoJson = credInfoJson.Dump(); + } + } + } + return DM_OK; +} + uint32_t DmAuthState::GetCredentialType(std::shared_ptr context, const JsonItemObject &credInfo) { CHECK_NULL_RETURN(context, DM_INVALIED_TYPE); @@ -330,22 +491,18 @@ uint32_t DmAuthState::GetCredentialType(std::shared_ptr context, return GetCredType(context, credInfo); } -bool DmAuthState::HaveSameTokenId(std::shared_ptr context, const std::vector &tokenList) +bool DmAuthState::HaveSameTokenId(std::shared_ptr context, + const std::vector &tokenIdHashList) { - // Store the token of src and sink. The size must be 2. - if (tokenList.size() != 2) { + // Store the token of src and sink. The size must be greater than or equal to 2. + if (tokenIdHashList.size() < 2) { LOGE("HaveSameTokenId invalid tokenList size."); return false; } - - // tokenIdList = [srcTokenId, sinkTokenId] - std::string srcTokenIdHash = Crypto::GetTokenIdHash(tokenList[0]); - std::string sinkTokenIdHash = Crypto::GetTokenIdHash(tokenList[1]); - - return ((srcTokenIdHash == context->accesser.tokenIdHash) && - (sinkTokenIdHash == context->accessee.tokenIdHash)) || - ((sinkTokenIdHash == context->accesser.tokenIdHash) && - (srcTokenIdHash == context->accessee.tokenIdHash)); + return std::find(tokenIdHashList.begin(), tokenIdHashList.end(), + context->accesser.tokenIdHash) != tokenIdHashList.end() && + std::find(tokenIdHashList.begin(), tokenIdHashList.end(), + context->accessee.tokenIdHash) != tokenIdHashList.end(); } int32_t DmAuthState::GetOutputState(int32_t state) @@ -402,15 +559,18 @@ void DmAuthState::DeleteAcl(std::shared_ptr context, LOGI("direction %{public}d.", static_cast(context->direction)); CHECK_NULL_VOID(context->authMessageProcessor); CHECK_NULL_VOID(context->hiChainAuthConnector); - int32_t userId = context->direction == DmAuthDirection::DM_AUTH_SOURCE ? - profile.GetAccesser().GetAccesserUserId() : profile.GetAccessee().GetAccesseeUserId(); - int32_t sessionKeyId = context->direction == DmAuthDirection::DM_AUTH_SOURCE ? + DmAccess &access = context->direction == DmAuthDirection::DM_AUTH_SOURCE ? context->accesser : context->accessee; + int32_t userId = access.userId; + int32_t sessionKeyId = access.deviceId == profile.GetAccesser().GetAccesserDeviceId() ? profile.GetAccesser().GetAccesserSessionKeyId() : profile.GetAccessee().GetAccesseeSessionKeyId(); - std::string credId = context->direction == DmAuthDirection::DM_AUTH_SOURCE ? + std::string credId = access.deviceId == profile.GetAccesser().GetAccesserDeviceId() ? profile.GetAccesser().GetAccesserCredentialIdStr() : profile.GetAccessee().GetAccesseeCredentialIdStr(); - context->authMessageProcessor->DeleteSessionKeyToDP(userId, sessionKeyId); - context->hiChainAuthConnector->DeleteCredential(userId, credId); + JsonObject credJson; + context->hiChainAuthConnector->QueryCredInfoByCredId(userId, credId, credJson); + if (credJson.Contains(credId)) { + DeleteCredential(context, userId, credJson[credId], profile); + } DeviceProfileConnector::GetInstance().DeleteAccessControlById(profile.GetAccessControlId()); } @@ -419,6 +579,7 @@ void DmAuthState::SetProcessInfo(std::shared_ptr context) CHECK_NULL_VOID(context); DmAccess localAccess = context->direction == DmAuthDirection::DM_AUTH_SOURCE ? context->accesser : context->accessee; + std::vector processInfoVec; ProcessInfo processInfo; processInfo.userId = localAccess.userId; uint32_t bindLevel = static_cast(localAccess.bindLevel); @@ -430,7 +591,17 @@ void DmAuthState::SetProcessInfo(std::shared_ptr context) LOGE("bindlevel error %{public}d.", bindLevel); return; } - context->softbusConnector->SetProcessInfo(processInfo); + processInfoVec.push_back(processInfo); + if (context->IsProxyBind && !context->subjectProxyOnes.empty()) { + for (const auto &app : context->subjectProxyOnes) { + ProcessInfo processInfo; + processInfo.userId = localAccess.userId; + processInfo.pkgName = context->direction == DmAuthDirection::DM_AUTH_SOURCE ? app.proxyAccesser.bundleName : + app.proxyAccessee.bundleName; + processInfoVec.push_back(processInfo); + } + } + context->softbusConnector->SetProcessInfoVec(processInfoVec); } void DmAuthState::FilterProfilesByContext( @@ -455,5 +626,181 @@ void DmAuthState::FilterProfilesByContext( profiles.clear(); profiles.assign(aclProfilesVec.begin(), aclProfilesVec.end()); } + +bool DmAuthState::GetSessionKey(std::shared_ptr context) +{ + int32_t skId = 0; + if (!GetReuseSkId(context, skId)) { + return false; + } + return context->authMessageProcessor->GetSessionKey(context->accesser.userId, skId) == DM_OK; +} + +bool DmAuthState::IsAclHasCredential(const DistributedDeviceProfile::AccessControlProfile &profile, + const std::string &credInfoJson, std::string &credId) +{ + JsonObject credInfoJsonObj; + if (!credInfoJson.empty()) { + credInfoJsonObj.Parse(credInfoJson); + } + credId = profile.GetAccesser().GetAccesserCredentialIdStr(); + if (credInfoJsonObj.Contains(credId)) { + return true; + } + credId = profile.GetAccessee().GetAccesseeCredentialIdStr(); + if (credInfoJsonObj.Contains(credId)) { + return true; + } + return false; +} + +void DmAuthState::UpdateCredInfo(std::shared_ptr context) +{ + CHECK_NULL_VOID(context); + if (!context->IsProxyBind || context->subjectProxyOnes.empty() || context->reUseCreId.empty()) { + return; + } + std::vector tokenIds; + bool isAuthed = context->direction == DM_AUTH_SOURCE ? context->accesser.isAuthed : context->accessee.isAuthed; + if (context->IsCallingProxyAsSubject && !isAuthed) { + tokenIds.push_back(std::to_string(context->accesser.tokenId)); + tokenIds.push_back(std::to_string(context->accessee.tokenId)); + } + for (auto &app : context->subjectProxyOnes) { + if (context->direction == DM_AUTH_SOURCE ? app.proxyAccesser.isAuthed : app.proxyAccessee.isAuthed) { + continue; + } + tokenIds.push_back(std::to_string(app.proxyAccesser.tokenId)); + tokenIds.push_back(std::to_string(app.proxyAccessee.tokenId)); + } + if (tokenIds.empty()) { + return; + } + context->hiChainAuthConnector->AddTokensToCredential(context->reUseCreId, context->direction == DM_AUTH_SOURCE ? + context->accesser.userId : context->accessee.userId, tokenIds); +} + +bool DmAuthState::IsNeedBind(std::shared_ptr context) +{ + if (context == nullptr) { + return true; + } + if (!context->IsProxyBind || context->subjectProxyOnes.empty()) { + LOGI("no proxy"); + return context->needBind; + } + if (context->authType == DmAuthType::AUTH_TYPE_IMPORT_AUTH_CODE) { + LOGI("authType is import pin code"); + return true; + } + if (context->needBind && context->needAgreeCredential && context->IsCallingProxyAsSubject) { + LOGI("subject need bind"); + return context->needBind; + } + for (const auto &app : context->subjectProxyOnes) { + if (app.needBind || app.IsNeedSetProxyRelationShip) { + LOGI("proxy need bind"); + return true; + } + } + return false; +} + +bool DmAuthState::IsNeedAgreeCredential(std::shared_ptr context) +{ + if (context == nullptr) { + return true; + } + if (!context->IsProxyBind || context->subjectProxyOnes.empty()) { + LOGI("no proxy"); + return context->needAgreeCredential; + } + if (!context->needAgreeCredential) { + LOGI("subject not need agree credential"); + return context->needAgreeCredential; + } + for (const auto &app : context->subjectProxyOnes) { + if (!app.needAgreeCredential) { + LOGI("proxy not need agree credential"); + return app.needAgreeCredential; + } + } + return true; +} + +bool DmAuthState::IsNeedAuth(std::shared_ptr context) +{ + if (context == nullptr) { + return true; + } + if (!context->IsProxyBind || context->subjectProxyOnes.empty()) { + LOGI("no proxy"); + return context->needAuth; + } + if (!context->needAuth) { + LOGI("subject not need auth"); + return context->needAuth; + } + for (const auto &app : context->subjectProxyOnes) { + if (!app.needAuth) { + LOGI("proxy not need auth"); + return app.needAuth; + } + } + return true; +} + +void DmAuthState::DeleteCredential(std::shared_ptr context, int32_t userId, + const JsonItemObject &credInfo, const DistributedDeviceProfile::AccessControlProfile &profile) +{ + CHECK_NULL_VOID(context); + CHECK_NULL_VOID(context->hiChainAuthConnector); + if (!credInfo.Contains(FILED_CRED_ID) || !credInfo[FILED_CRED_ID].IsString()) { + return; + } + if (!credInfo.Contains(FILED_AUTHORIZED_APP_LIST)) { + context->hiChainAuthConnector->DeleteCredential(userId, credInfo[FILED_CRED_ID].Get()); + return; + } + std::vector appList; + credInfo[FILED_AUTHORIZED_APP_LIST].Get(appList); + auto erIt = std::find(appList.begin(), appList.end(), std::to_string(profile.GetAccesser().GetAccesserTokenId())); + if (erIt != appList.end()) { + appList.erase(erIt); + } + auto eeIt = std::find(appList.begin(), appList.end(), std::to_string(profile.GetAccessee().GetAccesseeTokenId())); + if (eeIt != appList.end()) { + appList.erase(eeIt); + } + if (appList.size() == 0) { + context->hiChainAuthConnector->DeleteCredential(userId, credInfo[FILED_CRED_ID].Get()); + return; + } + context->hiChainAuthConnector->UpdateCredential(credInfo[FILED_CRED_ID].Get(), userId, appList); +} + +void DmAuthState::DirectlyDeleteCredential(std::shared_ptr context, int32_t userId, + const JsonItemObject &credInfo) +{ + CHECK_NULL_VOID(context); + CHECK_NULL_VOID(context->hiChainAuthConnector); + if (!credInfo.Contains(FILED_CRED_ID) || !credInfo[FILED_CRED_ID].IsString()) { + return; + } + context->hiChainAuthConnector->DeleteCredential(userId, credInfo[FILED_CRED_ID].Get()); +} + +void DmAuthState::DeleteAclAndSk(std::shared_ptr context, + const DistributedDeviceProfile::AccessControlProfile &profile) +{ + CHECK_NULL_VOID(context); + CHECK_NULL_VOID(context->authMessageProcessor); + DmAccess &access = context->direction == DmAuthDirection::DM_AUTH_SOURCE ? context->accesser : context->accessee; + int32_t userId = access.userId; + int32_t sessionKeyId = access.deviceId == profile.GetAccesser().GetAccesserDeviceId() ? + profile.GetAccesser().GetAccesserSessionKeyId() : profile.GetAccessee().GetAccesseeSessionKeyId(); + context->authMessageProcessor->DeleteSessionKeyToDP(userId, sessionKeyId); + DeviceProfileConnector::GetInstance().DeleteAccessControlById(profile.GetAccessControlId()); +} } // 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 index 74bba53bb67a377c515e9edb1541b0eb6a904926..231bf6690088a532d790daa4121b6a5b888798ed 100644 --- a/services/implementation/src/authentication_v2/dm_auth_state_machine.cpp +++ b/services/implementation/src/authentication_v2/dm_auth_state_machine.cpp @@ -68,6 +68,7 @@ void DmAuthStateMachine::InsertSrcTransTable() DmAuthStateType::AUTH_SRC_REVERSE_ULTRASONIC_START_STATE, DmAuthStateType::AUTH_SRC_FORWARD_ULTRASONIC_START_STATE, DmAuthStateType::AUTH_SRC_PIN_AUTH_START_STATE, + DmAuthStateType::AUTH_SRC_DATA_SYNC_STATE, }}, {DmAuthStateType::AUTH_SRC_PIN_INPUT_STATE, { DmAuthStateType::AUTH_SRC_PIN_AUTH_START_STATE, @@ -87,6 +88,7 @@ void DmAuthStateMachine::InsertSrcTransTable() {DmAuthStateType::AUTH_SRC_CREDENTIAL_EXCHANGE_STATE, { DmAuthStateType::AUTH_SRC_CREDENTIAL_AUTH_START_STATE, DmAuthStateType::AUTH_SRC_DATA_SYNC_STATE, + DmAuthStateType::AUTH_SRC_CREDENTIAL_AUTH_DONE_STATE, }}, {DmAuthStateType::AUTH_SRC_CREDENTIAL_AUTH_START_STATE, {DmAuthStateType::AUTH_SRC_CREDENTIAL_AUTH_NEGOTIATE_STATE}}, @@ -165,10 +167,12 @@ void DmAuthStateMachine::InsertSinkTransTable() {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_FINISH_STATE, }}, {DmAuthStateType::AUTH_SINK_PIN_AUTH_DONE_STATE, { DmAuthStateType::AUTH_SINK_CREDENTIAL_EXCHANGE_STATE, DmAuthStateType::AUTH_SINK_CREDENTIAL_AUTH_START_STATE, + DmAuthStateType::AUTH_SINK_DATA_SYNC_STATE, DmAuthStateType::AUTH_SINK_FINISH_STATE, }}, {DmAuthStateType::AUTH_SINK_CREDENTIAL_EXCHANGE_STATE, { diff --git a/services/implementation/src/authentication_v2/dm_negotiate_process.cpp b/services/implementation/src/authentication_v2/dm_negotiate_process.cpp index f882e584a3a7266d81e081ccea8aecd24ef5e761..1d0e5af647070204c3341df466a446acf01555a4 100644 --- a/services/implementation/src/authentication_v2/dm_negotiate_process.cpp +++ b/services/implementation/src/authentication_v2/dm_negotiate_process.cpp @@ -12,6 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +#include "dm_crypto.h" #include "dm_negotiate_process.h" namespace OHOS { @@ -108,12 +109,89 @@ int32_t NegotiateProcess::HandleNegotiateResult(std::shared_ptr c AuthType authType = ConvertAuthType(context->authType); LOGI("credType %{public}d, aclType %{public}d, authType %{public}d.", static_cast(credType), static_cast(aclType), static_cast(authType)); + int32_t ret = ERR_DM_CAPABILITY_NEGOTIATE_FAILED; NegotiateSpec negotiateSpec(credType, aclType, authType); auto handler = handlers_.find(negotiateSpec); - if (handler != handlers_.end()) { - return handler->second->NegotiateHandle(context); + if (handler != handlers_.end() && handler->second != nullptr) { + ret = handler->second->NegotiateHandle(context); + } else { + return ret; + } + if (!context->IsProxyBind || context->subjectProxyOnes.empty() || + (credType == CredType::DM_IDENTICAL_CREDTYPE && aclType == AclType::DM_IDENTICAL_ACL) || + (credType == CredType::DM_SHARE_CREDTYPE && aclType == AclType::DM_SHARE_ACL)) { + return ret; + } + return HandleProxyNegotiateResult(context, ret); +} + +int32_t NegotiateProcess::HandleProxyNegotiateResult(std::shared_ptr context, int32_t result) +{ + CHECK_NULL_RETURN(context, ERR_DM_POINT_NULL); + if (!context->IsProxyBind || context->subjectProxyOnes.empty()) { + return DM_OK; + } + bool isTrust = true; + for (auto &app : context->subjectProxyOnes) { + std::string credTypeList = context->direction == DmAuthDirection::DM_AUTH_SOURCE ? + app.proxyAccesser.credTypeList : app.proxyAccessee.credTypeList; + std::string aclTypeList = context->direction == DmAuthDirection::DM_AUTH_SOURCE ? + app.proxyAccesser.aclTypeList : app.proxyAccessee.aclTypeList; + CredType credType = ConvertCredType(credTypeList); + AclType aclType = ConvertAclType(aclTypeList); + if (credType == CredType::DM_P2P_CREDTYPE && aclType == AclType::DM_P2P_ACL) { + app.needBind = false; + app.needAgreeCredential = false; + app.needAuth = false; + app.IsNeedSetProxyRelationShip = IsNeedSetProxyRelationShip(context, app); + } + } + return DM_OK; +} + +bool NegotiateProcess::IsNeedSetProxyRelationShip(std::shared_ptr context, + DmProxyAuthContext &proxyContext) +{ + DmProxyAccess &access = context->direction == DmAuthDirection::DM_AUTH_SOURCE ? + proxyContext.proxyAccesser : proxyContext.proxyAccessee; + if (access.aclProfiles.find(DM_POINT_TO_POINT) == access.aclProfiles.end()) { + return true; + } + std::string accesserExtraData = access.aclProfiles[DM_POINT_TO_POINT].GetAccesser().GetAccesserExtraData(); + std::string accesseeExtraData = access.aclProfiles[DM_POINT_TO_POINT].GetAccessee().GetAccesseeExtraData(); + if ((IsExistTheTokenId(accesserExtraData, proxyContext.proxyAccesser.tokenIdHash) && + IsExistTheTokenId(accesseeExtraData, proxyContext.proxyAccessee.tokenIdHash)) || + (IsExistTheTokenId(accesserExtraData, proxyContext.proxyAccessee.tokenIdHash) && + IsExistTheTokenId(accesseeExtraData, proxyContext.proxyAccesser.tokenIdHash))) { + return false; } - return ERR_DM_CAPABILITY_NEGOTIATE_FAILED; + return true; +} + +bool NegotiateProcess::IsExistTheTokenId(const std::string extraData, const std::string tokenIdHash) +{ + if (extraData.empty()) { + return false; + } + JsonObject extObj; + extObj.Parse(extraData); + if (extObj.IsDiscarded()) { + return false; + } + JsonObject proxyObj; + if (IsString(extObj, TAG_PROXY)) { + std::string proxyStr = extObj[TAG_PROXY].Get(); + proxyObj.Parse(proxyStr); + } + if (proxyObj.IsDiscarded()) { + return false; + } + for (auto const &item : proxyObj.Items()) { + if (item.IsNumber() && tokenIdHash == Crypto::GetTokenIdHash(std::to_string(item.Get()))) { + return true; + } + } + return false; } CredType NegotiateProcess::ConvertCredType(const std::string &credType) @@ -131,10 +209,13 @@ CredType NegotiateProcess::ConvertCredType(const std::string &credType) } if (credTypeJson.Contains("identicalCredType")) { credTypeTemp = CredType::DM_IDENTICAL_CREDTYPE; + return credTypeTemp; } else if (credTypeJson.Contains("shareCredType")) { credTypeTemp = CredType::DM_SHARE_CREDTYPE; + return credTypeTemp; } else if (credTypeJson.Contains("pointTopointCredType")) { credTypeTemp = CredType::DM_P2P_CREDTYPE; + return credTypeTemp; } else { credTypeTemp = CredType::DM_NO_CRED; } @@ -156,10 +237,13 @@ AclType NegotiateProcess::ConvertAclType(const std::string &aclType) } if (aclTypeJson.Contains("identicalAcl")) { aclTypeTemp = AclType::DM_IDENTICAL_ACL; + return aclTypeTemp; } else if (aclTypeJson.Contains("shareAcl")) { aclTypeTemp = AclType::DM_SHARE_ACL; + return aclTypeTemp; } else if (aclTypeJson.Contains("pointTopointAcl")) { aclTypeTemp = AclType::DM_P2P_ACL; + return aclTypeTemp; } else { aclTypeTemp = AclType::DM_NO_ACL; } diff --git a/services/implementation/src/dependency/hichain/hichain_auth_connector.cpp b/services/implementation/src/dependency/hichain/hichain_auth_connector.cpp index 28759e22ccc46f9744215405d9a5787012705ddd..b659af1ad6bbbb4a698c506b6583ff02aeb21386 100644 --- a/services/implementation/src/dependency/hichain/hichain_auth_connector.cpp +++ b/services/implementation/src/dependency/hichain/hichain_auth_connector.cpp @@ -38,6 +38,14 @@ void HiChainAuthConnector::FreeJsonString(char *jsonStr) } } +void HiChainAuthConnector::FreeCharArray(char *charArray) +{ + if (charArray != nullptr) { + free(charArray); + charArray = nullptr; + } +} + HiChainAuthConnector::HiChainAuthConnector() { deviceAuthCallback_ = {.onTransmit = HiChainAuthConnector::onTransmit, @@ -530,5 +538,72 @@ int32_t HiChainAuthConnector::DeleteCredential(const std::string &deviceId, int3 FreeJsonString(returnData); return DM_OK; } + +int32_t HiChainAuthConnector::AddTokensToCredential(const std::string &credId, int32_t userId, + std::vector &tokenIds) +{ + const CredManager *cm = GetCredMgrInstance(); + if (cm == nullptr) { + LOGE("cm is null."); + return ERR_DM_FAILED; + } + char *returnCredInfo = nullptr; + int32_t ret = cm->queryCredInfoByCredId(userId, credId.c_str(), &returnCredInfo); + if (ret != DM_OK) { + FreeCharArray(returnCredInfo); + LOGE("[HICHAIN]::QueryCredInfoByCredId failed, ret: %{public}d.", ret); + return ret; + } + JsonObject credInfoJson(returnCredInfo); + FreeCharArray(returnCredInfo); + if (credInfoJson.IsDiscarded()) { + LOGE("QueryCredInfoByCredId credential info jsonStr error"); + return ERR_DM_FAILED; + } + std::vector appList; + if (credInfoJson.Contains(FIELD_AUTHORIZED_APP_LIST)) { + credInfoJson[FIELD_AUTHORIZED_APP_LIST].Get(appList); + } + appList.insert(appList.end(), tokenIds.begin(), tokenIds.end()); + JsonObject jsonObj; + jsonObj[FIELD_AUTHORIZED_APP_LIST] = appList; + ret = cm->updateCredInfo(userId, credId.c_str(), jsonObj.Dump().c_str()); + if (ret != DM_OK) { + LOGE("[HICHAIN]::updateCredInfo failed, ret: %{public}d.", ret); + return ret; + } + return DM_OK; +} + +int32_t HiChainAuthConnector::UpdateCredential(const std::string &credId, int32_t userId, + std::vector &tokenIds) +{ + const CredManager *cm = GetCredMgrInstance(); + if (cm == nullptr) { + LOGE("cm is null."); + return ERR_DM_FAILED; + } + char *returnCredInfo = nullptr; + int32_t ret = cm->queryCredInfoByCredId(userId, credId.c_str(), &returnCredInfo); + if (ret != DM_OK) { + FreeCharArray(returnCredInfo); + LOGE("[HICHAIN]::QueryCredInfoByCredId failed, ret: %{public}d.", ret); + return ret; + } + JsonObject credInfoJson(returnCredInfo); + FreeCharArray(returnCredInfo); + if (credInfoJson.IsDiscarded()) { + LOGE("QueryCredInfoByCredId credential info jsonStr error"); + return ERR_DM_FAILED; + } + JsonObject jsonObj; + jsonObj[FIELD_AUTHORIZED_APP_LIST] = tokenIds; + ret = cm->updateCredInfo(userId, credId.c_str(), jsonObj.Dump().c_str()); + if (ret != DM_OK) { + LOGE("[HICHAIN]::updateCredInfo failed, ret: %{public}d.", ret); + return ret; + } + return DM_OK; +} } // namespace DistributedHardware } // namespace OHOS