diff --git a/services/distributeddataservice/adapter/communicator/src/device_manager_adapter.cpp b/services/distributeddataservice/adapter/communicator/src/device_manager_adapter.cpp index cd9f85c726f63758895f8fff8ef1d0d51de625f7..7fe1e98bedbd928c116745f6ef5812db16caa47a 100644 --- a/services/distributeddataservice/adapter/communicator/src/device_manager_adapter.cpp +++ b/services/distributeddataservice/adapter/communicator/src/device_manager_adapter.cpp @@ -757,4 +757,22 @@ bool DeviceManagerAdapter::IsSameAccount(const std::string &id) auto networkId = DeviceManagerAdapter::GetInstance().ToNetworkID(id); return DeviceManager::GetInstance().IsSameAccount(networkId); } + +bool DeviceManagerAdapter::CheckAccessControl(const AccessCaller &accCaller, const AccessCallee &accCallee) +{ + DmAccessCaller dmAccessCaller = { .accountId = accCaller.accountId, .pkgName = accCaller.bundleName, + .networkId = accCaller.networkId, .userId = accCaller.userId }; + DmAccessCallee dmAccessCallee = { .userId = accCallee.userId, .accountId = accCallee.accountId, + .networkId = accCallee.networkId }; + return DeviceManager::GetInstance().CheckAccessControl(dmAccessCaller, dmAccessCallee); +} + +bool DeviceManagerAdapter::IsSameAccount(const AccessCaller &accCaller, const AccessCallee &accCallee) +{ + DmAccessCaller dmAccessCaller = { .accountId = accCaller.accountId, .networkId = accCaller.networkId, + .userId = accCaller.userId }; + DmAccessCallee dmAccessCallee = { .userId = accCallee.userId, .accountId = accCallee.accountId, + .networkId = accCallee.networkId }; + return DeviceManager::GetInstance().CheckIsSameAccount(dmAccessCaller, dmAccessCallee); +} } // namespace OHOS::DistributedData diff --git a/services/distributeddataservice/adapter/include/communicator/commu_types.h b/services/distributeddataservice/adapter/include/communicator/commu_types.h index afe72286792aa0dce767a26f3c8f083fbb7a06b9..6b1f1af696dcb9482181dea2df903ce5f51913a8 100644 --- a/services/distributeddataservice/adapter/include/communicator/commu_types.h +++ b/services/distributeddataservice/adapter/include/communicator/commu_types.h @@ -30,6 +30,25 @@ struct API_EXPORT DeviceInfo { int32_t authForm; }; +struct API_EXPORT AccessCaller { + std::string accountId; + std::string bundleName; + std::string networkId; + int32_t userId; +}; + +struct API_EXPORT AccessCallee { + std::string accountId; + std::string networkId; + int32_t userId; +}; + +struct API_EXPORT AclParams { + AccessCaller accCaller; + AccessCallee accCallee; + int32_t authType = 0; +}; + enum RouteType : int32_t { INVALID_ROUTE_TYPE = -1, ROUTE_TYPE_ALL = 0, diff --git a/services/distributeddataservice/adapter/include/communicator/device_manager_adapter.h b/services/distributeddataservice/adapter/include/communicator/device_manager_adapter.h index 7c99f1fb99f8faed188f1b381f504d22f29e7917..7edbd0fd1a598c913b4eef55cf407578567dc8c9 100644 --- a/services/distributeddataservice/adapter/include/communicator/device_manager_adapter.h +++ b/services/distributeddataservice/adapter/include/communicator/device_manager_adapter.h @@ -50,6 +50,8 @@ public: using AppDeviceChangeListener = OHOS::AppDistributedKv::AppDeviceChangeListener; using Status = OHOS::DistributedKv::Status; using Time = std::chrono::steady_clock::time_point; + using AccessCaller = OHOS::AppDistributedKv::AccessCaller; + using AccessCallee = OHOS::AppDistributedKv::AccessCallee; static DeviceManagerAdapter &GetInstance(); static constexpr const char *CLOUD_DEVICE_UUID = "cloudDeviceUuid"; static constexpr const char *CLOUD_DEVICE_UDID = "cloudDeviceUdid"; @@ -78,6 +80,8 @@ public: NetworkType GetNetworkType(bool retrieve = false); int32_t GetAuthType(const std::string& id); bool IsSameAccount(const std::string &id); + bool IsSameAccount(const AccessCaller &accCaller, const AccessCallee &accCallee); + bool CheckAccessControl(const AccessCaller &accCaller, const AccessCallee &accCallee); friend class DataMgrDmStateCall; friend class NetConnCallbackObserver; diff --git a/services/distributeddataservice/app/src/session_manager/session_manager.cpp b/services/distributeddataservice/app/src/session_manager/session_manager.cpp index d46217a47b5211f88a7507c2285553ae4fa287d8..cc32580171ddc397c3a3c2b3e4969a75f0ff0d8e 100644 --- a/services/distributeddataservice/app/src/session_manager/session_manager.cpp +++ b/services/distributeddataservice/app/src/session_manager/session_manager.cpp @@ -28,8 +28,10 @@ #include "utils/anonymous.h" #include "utils/converter.h" #include "types.h" +#include "device_manager_adapter.h" namespace OHOS::DistributedData { using namespace OHOS::DistributedKv; +using DmAdapter = OHOS::DistributedData::DeviceManagerAdapter; SessionManager &SessionManager::GetInstance() { static SessionManager instance; @@ -58,58 +60,95 @@ Session SessionManager::GetSession(const SessionPoint &from, const std::string & } } - std::string bundleName = ""; - int32_t authType = static_cast(AuthType::DEFAULT); - if (!GetAuthParams(from, bundleName, authType)) { - ZLOGE("GetAuthParams failed"); + AclParams aclParams; + if (!GetSendAuthParams(from, targetDeviceId, aclParams)) { + ZLOGE("get send auth params failed:%{public}s", Anonymous::Change(targetDeviceId).c_str()); return session; } - for (const auto &user : users) { - bool isPermitted = AuthDelegate::GetInstance()->CheckAccess(from.userId, user.id, - targetDeviceId, authType); - ZLOGD("access to peer user %{public}d is %{public}d", user.id, isPermitted); + auto [isPermitted, isSameAccount] = AuthDelegate::GetInstance()->CheckAccess(from.userId, user.id, + targetDeviceId, aclParams); if (isPermitted) { auto it = std::find(session.targetUserIds.begin(), session.targetUserIds.end(), user.id); - if (it == session.targetUserIds.end()) { + if (it == session.targetUserIds.end() && isSameAccount) { + session.targetUserIds.insert(session.targetUserIds.begin(), user.id); + } + if (it == session.targetUserIds.end() && !isSameAccount) { session.targetUserIds.push_back(user.id); } } } - ZLOGD("end"); + ZLOGD("access to peer user:%{public}d", session.targetUserIds[0]); return session; } -bool SessionManager::GetAuthParams(const SessionPoint &from, std::string &bundleName, int32_t &auth) const +bool SessionManager::GetSendAuthParams(const SessionPoint &from, const std::string &targetDeviceId, + AclParams &aclParams) const { std::vector metaData; if (!MetaDataManager::GetInstance().LoadMeta(StoreMetaData::GetPrefix({ from.deviceId }), metaData)) { - ZLOGW("load meta failed, deviceId:%{public}s", Anonymous::Change(from.deviceId).c_str()); + ZLOGE("load meta failed, deviceId:%{public}s, user:%{public}d", Anonymous::Change(from.deviceId).c_str(), + from.userId); return false; } for (const auto &storeMeta : metaData) { - if (storeMeta.appId == from.appId) { - bundleName = storeMeta.bundleName; - auth = storeMeta.authType; - break; + if (storeMeta.appId == from.appId && storeMeta.storeId == from.storeId) { + aclParams.accCaller.bundleName = storeMeta.bundleName; + aclParams.accCaller.accountId = AccountDelegate::GetInstance()->GetCurrentAccountId(); + aclParams.accCaller.userId = from.userId; + aclParams.accCaller.networkId = DmAdapter::GetInstance().ToNetworkID(from.deviceId); + + aclParams.accCallee.networkId = DmAdapter::GetInstance().ToNetworkID(targetDeviceId); + aclParams.authType = storeMeta.authType; + return true; } } - if (bundleName.empty()) { - ZLOGE("not find bundleName"); + ZLOGE("get params failed,appId:%{public}s,localDevId:%{public}s,tarDevid:%{public}s,user:%{public}d,", + from.appId.c_str(), Anonymous::Change(from.deviceId).c_str(), + Anonymous::Change(targetDeviceId).c_str(), from.userId); + return false; +} + +bool SessionManager::GetRecvAuthParams(const SessionPoint &from, const std::string &targetDeviceId, + AclParams &aclParams, int32_t peerUser) const +{ + std::vector metaData; + if (!MetaDataManager::GetInstance().LoadMeta(StoreMetaData::GetPrefix({ targetDeviceId }), metaData)) { + ZLOGE("load meta failed, deviceId:%{public}s, user:%{public}d", Anonymous::Change(targetDeviceId).c_str(), + peerUser); return false; } - return true; + for (const auto &storeMeta : metaData) { + if (storeMeta.appId == from.appId) { + auto accountId = AccountDelegate::GetInstance()->GetCurrentAccountId(); + aclParams.accCaller.bundleName = storeMeta.bundleName; + aclParams.accCaller.accountId = accountId; + aclParams.accCaller.userId = from.userId; + aclParams.accCaller.networkId = DmAdapter::GetInstance().ToNetworkID(from.deviceId); + + aclParams.accCallee.accountId = accountId; + aclParams.accCallee.userId = peerUser; + aclParams.accCallee.networkId = DmAdapter::GetInstance().ToNetworkID(targetDeviceId); + aclParams.authType = storeMeta.authType; + return true; + } + } + + ZLOGE("get params failed,appId:%{public}s,tarDevid:%{public}s,user:%{public}d,peer:%{public}d", + from.appId.c_str(), Anonymous::Change(targetDeviceId).c_str(), from.userId, peerUser); + return false; } bool SessionManager::CheckSession(const SessionPoint &from, const SessionPoint &to) const { - std::string bundleName = ""; - int32_t authType = static_cast(AuthType::DEFAULT); - if (!GetAuthParams(from, bundleName, authType)) { - ZLOGE("GetAuthParams failed"); + AclParams aclParams; + if (!GetRecvAuthParams(from, to.deviceId, aclParams, to.userId)) { + ZLOGE("get recv auth params failed:%{public}s", Anonymous::Change(to.deviceId).c_str()); return false; } - return AuthDelegate::GetInstance()->CheckAccess(from.userId, to.userId, to.deviceId, authType, false); + auto [isPermitted, isSameAccount] = AuthDelegate::GetInstance()->CheckAccess(from.userId, + to.userId, to.deviceId, aclParams); + return isPermitted; } bool Session::Marshal(json &node) const diff --git a/services/distributeddataservice/app/src/session_manager/session_manager.h b/services/distributeddataservice/app/src/session_manager/session_manager.h index 43c6312f78e9db26872eaace711fecde048f96c6..df16d8598fc79f238707b11f94a4237c55f75fa6 100644 --- a/services/distributeddataservice/app/src/session_manager/session_manager.h +++ b/services/distributeddataservice/app/src/session_manager/session_manager.h @@ -20,8 +20,11 @@ #include #include "serializable/serializable.h" - +#include "commu_types.h" +#include "metadata/user_meta_data.h" namespace OHOS::DistributedData { +using AclParams = OHOS::AppDistributedKv::AclParams; +using DistributedData::UserStatus; struct SessionPoint { std::string deviceId; uint32_t userId; @@ -50,7 +53,10 @@ public: Session GetSession(const SessionPoint &from, const std::string &targetDeviceId) const; bool CheckSession(const SessionPoint &from, const SessionPoint &to) const; private: - bool GetAuthParams(const SessionPoint &from, std::string &bundleName, int32_t &auth) const; + bool GetSendAuthParams(const SessionPoint &from, const std::string &targetDeviceId, + AclParams &aclParams) const; + bool GetRecvAuthParams(const SessionPoint &from, const std::string &targetDeviceId, + AclParams &aclParams, int peerUser) const; }; } // namespace OHOS::DistributedData diff --git a/services/distributeddataservice/service/kvdb/auth_delegate.cpp b/services/distributeddataservice/service/kvdb/auth_delegate.cpp index fc72e1cfc6c4bcd37d5d8c26c80ab6a9124fc93d..234a1698c6933c52fd8be026350a34adc1703adf 100644 --- a/services/distributeddataservice/service/kvdb/auth_delegate.cpp +++ b/services/distributeddataservice/service/kvdb/auth_delegate.cpp @@ -30,16 +30,21 @@ using DmAdapter = OHOS::DistributedData::DeviceManagerAdapter; class AuthHandlerStub : public AuthHandler { public: // override for mock auth in current version, need remove in the future - bool CheckAccess( - int localUserId, int peerUserId, const std::string &peerDeviceId, - int32_t authType, bool isSend = true) override; + std::pair CheckAccess(int localUserId, int peerUserId, const std::string &peerDeviceId, + const AclParams &aclParams) override; private: bool IsUserActive(const std::vector &users, int32_t userId); bool CheckUsers(int localUserId, int peerUserId, const std::string &peerDeviceId); + bool IsSystemUser(int localUserId, int peerUserId); static constexpr pid_t UID_CAPACITY = 10000; static constexpr int SYSTEM_USER = 0; }; +bool AuthHandlerStub::IsSystemUser(int localUserId, int peerUserId) +{ + return localUserId == SYSTEM_USER && peerUserId == SYSTEM_USER; +} + bool AuthHandlerStub::CheckUsers(int localUserId, int peerUserId, const std::string &peerDeviceId) { if (localUserId == SYSTEM_USER) { @@ -51,15 +56,37 @@ bool AuthHandlerStub::CheckUsers(int localUserId, int peerUserId, const std::str return peerUserId != SYSTEM_USER && IsUserActive(localUsers, localUserId) && IsUserActive(peerUsers, peerUserId); } -bool AuthHandlerStub::CheckAccess( - int localUserId, int peerUserId, const std::string &peerDeviceId, int32_t authType, bool isSend) +std::pair AuthHandlerStub::CheckAccess(int localUserId, int peerUserId, const std::string &peerDeviceId, + const AclParams &aclParams) { - if (authType == static_cast(DistributedKv::AuthType::IDENTICAL_ACCOUNT) && - !DmAdapter::GetInstance().IsSameAccount(peerDeviceId)) { - ZLOGE("CheckAccess failed."); - return false; + if (IsSystemUser(localUserId, peerUserId)) { + return std::make_pair(true, false); + } + if (!CheckUsers(localUserId, peerUserId, peerDeviceId)) { + return std::make_pair(false, false); + } + if (!DmAdapter::GetInstance().IsOHOSType(peerDeviceId)) { + return std::make_pair(true, false); + } + if (aclParams.authType == static_cast(DistributedKv::AuthType::DEFAULT)) { + if (DmAdapter::GetInstance().IsSameAccount(aclParams.accCaller, aclParams.accCallee)) { + return std::make_pair(true, true); + } + if (DmAdapter::GetInstance().CheckAccessControl(aclParams.accCaller, aclParams.accCallee)) { + return std::make_pair(true, false); + } + ZLOGE("CheckAccess failed. bundleName:%{public}s, localUser:%{public}d, peerUser:%{public}d", + aclParams.accCaller.bundleName.c_str(), localUserId, peerUserId); + return std::make_pair(false, false); + } + + if (aclParams.authType == static_cast(DistributedKv::AuthType::IDENTICAL_ACCOUNT)) { + auto isSameAccount = DmAdapter::GetInstance().IsSameAccount(aclParams.accCaller, aclParams.accCallee); + return std::make_pair(isSameAccount, isSameAccount); } - return CheckUsers(localUserId, peerUserId, peerDeviceId); + ZLOGE("CheckAccess failed.bundleName:%{public}s,peerDeviceId:%{public}s,authtype:%{public}d", + aclParams.accCaller.bundleName.c_str(), Anonymous::Change(peerDeviceId).c_str(), aclParams.authType); + return std::make_pair(false, false); } bool AuthHandlerStub::IsUserActive(const std::vector &users, int32_t userId) diff --git a/services/distributeddataservice/service/kvdb/auth_delegate.h b/services/distributeddataservice/service/kvdb/auth_delegate.h index 11a931993306d0ad1a572a482b3a8844af107666..199b7e74599245cbd4f123389bfa89da1a534e75 100644 --- a/services/distributeddataservice/service/kvdb/auth_delegate.h +++ b/services/distributeddataservice/service/kvdb/auth_delegate.h @@ -20,7 +20,9 @@ #include "metadata/user_meta_data.h" #include "serializable/serializable.h" +#include "commu_types.h" namespace OHOS::DistributedData { +using AclParams = OHOS::AppDistributedKv::AclParams; enum AUTH_GROUP_TYPE { ALL_GROUP = 0, IDENTICAL_ACCOUNT_GROUP = 1, @@ -31,8 +33,8 @@ enum AUTH_GROUP_TYPE { class AuthHandler { public: - virtual bool CheckAccess( - int localUserId, int peerUserId, const std::string &peerDeviceId, int32_t authType, bool isSend = true); + virtual std::pair CheckAccess(int localUserId, int peerUserId, + const std::string &peerDeviceId, const AclParams &aclParams); }; class AuthDelegate { diff --git a/services/distributeddataservice/service/test/kvdb_service_test.cpp b/services/distributeddataservice/service/test/kvdb_service_test.cpp index 29eca7560d74ecb58540b6718a0950af271edfa1..edac1475e7dbdfdba31d8ffaf7b0bc247e69f6f7 100644 --- a/services/distributeddataservice/service/test/kvdb_service_test.cpp +++ b/services/distributeddataservice/service/test/kvdb_service_test.cpp @@ -657,30 +657,31 @@ HWTEST_F(AuthHandlerTest, AuthHandler, TestSize.Level0) int localUserId = 0; int peerUserId = 0; std::string peerDeviceId = ""; - int32_t authType = static_cast(DistributedKv::AuthType::IDENTICAL_ACCOUNT); - bool isSend = false; - auto result = AuthDelegate::GetInstance()->CheckAccess(localUserId, peerUserId, peerDeviceId, authType, isSend); - EXPECT_FALSE(result); - authType = static_cast(DistributedKv::AuthType::DEFAULT); - result = AuthDelegate::GetInstance()->CheckAccess(localUserId, peerUserId, peerDeviceId, authType, isSend); - EXPECT_TRUE(result); - - authType = static_cast(DistributedKv::AuthType::IDENTICAL_ACCOUNT); + AclParams aclParams; + aclParams.authType = static_cast(DistributedKv::AuthType::IDENTICAL_ACCOUNT); + auto result = AuthDelegate::GetInstance()->CheckAccess(localUserId, peerUserId, peerDeviceId, aclParams); + EXPECT_TRUE(result.first); + + aclParams.authType = static_cast(DistributedKv::AuthType::DEFAULT); + result = AuthDelegate::GetInstance()->CheckAccess(localUserId, peerUserId, peerDeviceId, aclParams); + EXPECT_TRUE(result.first); + + aclParams.authType = static_cast(DistributedKv::AuthType::IDENTICAL_ACCOUNT); peerDeviceId = "peerDeviceId"; - result = AuthDelegate::GetInstance()->CheckAccess(localUserId, peerUserId, peerDeviceId, authType, isSend); - EXPECT_FALSE(result); + result = AuthDelegate::GetInstance()->CheckAccess(localUserId, peerUserId, peerDeviceId, aclParams); + EXPECT_TRUE(result.first); - authType = static_cast(DistributedKv::AuthType::DEFAULT); - result = AuthDelegate::GetInstance()->CheckAccess(localUserId, peerUserId, peerDeviceId, authType, isSend); - EXPECT_TRUE(result); + aclParams.authType = static_cast(DistributedKv::AuthType::DEFAULT); + result = AuthDelegate::GetInstance()->CheckAccess(localUserId, peerUserId, peerDeviceId, aclParams); + EXPECT_TRUE(result.first); localUserId = 1; - result = AuthDelegate::GetInstance()->CheckAccess(localUserId, peerUserId, peerDeviceId, authType, isSend); - EXPECT_FALSE(result); + result = AuthDelegate::GetInstance()->CheckAccess(localUserId, peerUserId, peerDeviceId, aclParams); + EXPECT_FALSE(result.first); peerUserId = 1; - result = AuthDelegate::GetInstance()->CheckAccess(localUserId, peerUserId, peerDeviceId, authType, isSend); - EXPECT_FALSE(result); + result = AuthDelegate::GetInstance()->CheckAccess(localUserId, peerUserId, peerDeviceId, aclParams); + EXPECT_FALSE(result.first); } } // namespace DistributedDataTest } // namespace OHOS::Test \ No newline at end of file