* Copyright (c) 2023-2025 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <cstdio>
#include "deviceprofile_connector.h"
#include "crypto_mgr.h"
#include "dm_anonymous.h"
#include "dm_constants.h"
#include "dm_crypto.h"
#include "dm_device_info.h"
#include "dm_log.h"
#include "multiple_user_connector.h"
#include "distributed_device_profile_client.h"
#include "system_ability_definition.h"
#include "ipc_skeleton.h"
#include "dm_jsonstr_handle.h"
#include "app_manager.h"
using namespace OHOS::DistributedDeviceProfile;
const uint32_t INVALIED_TYPE = 0;
const uint32_t APP_PEER_TO_PEER_TYPE = 1;
const uint32_t APP_ACROSS_ACCOUNT_TYPE = 2;
const uint32_t SERVICE_PEER_TO_PEER_TYPE = 3;
const uint32_t SERVICE_ACROSS_ACCOUNT_TYPE = 4;
const uint32_t SHARE_TYPE = 5;
const uint32_t DEVICE_PEER_TO_PEER_TYPE = 6;
const uint32_t DEVICE_ACROSS_ACCOUNT_TYPE = 7;
const uint32_t IDENTICAL_ACCOUNT_TYPE = 8;
const uint32_t DM_INVALIED_TYPE = 2048;
const uint32_t SERVICE = 2;
const uint32_t APP = 3;
const uint32_t USER = 1;
const int64_t DM_DEFAULT_SERVICE_ID = 0;
constexpr uint32_t MAX_SESSION_KEY_LENGTH = 512;
const char* TAG_PEER_BUNDLE_NAME = "peerBundleName";
const char* TAG_PEER_TOKENID = "peerTokenId";
const char* TAG_ACL = "accessControlTable";
const char* TAG_DMVERSION = "dmVersion";
const char* TAG_ACL_HASH_KEY_VERSION = "aclVersion";
const char* TAG_ACL_HASH_KEY_ACLHASHLIST = "aclHashList";
namespace OHOS {
namespace DistributedHardware {
namespace {
const int32_t DM_SUPPORT_ACL_AGING_VERSION_NUM = 1;
const std::string DM_VERSION_STR_5_1_0 = DM_VERSION_5_1_0;
const std::vector<std::string> DM_SUPPORT_ACL_AGING_VERSIONS = {DM_VERSION_STR_5_1_0};
constexpr uint32_t AUTH_EXT_WHITE_LIST_NUM = 1;
constexpr const static char* g_extWhiteList[AUTH_EXT_WHITE_LIST_NUM] = {
"CastEngineService",
};
enum DmDevBindType : int32_t {
DEVICE_PEER_TO_PEER_BIND_TYPE = 3,
DEVICE_ACROSS_ACCOUNT_BIND_TYPE = 4,
IDENTICAL_ACCOUNT_BIND_TYPE = 5
};
constexpr int32_t INVALID_PROFILE_STATUS = -1;
}
IMPLEMENT_SINGLE_INSTANCE(DeviceProfileConnector);
void PrintProfile(const AccessControlProfile &profile)
{
uint32_t bindType = profile.GetBindType();
uint32_t bindLevel = profile.GetBindLevel();
std::string acerDeviceId = profile.GetAccesser().GetAccesserDeviceId();
int32_t acerUserId = profile.GetAccesser().GetAccesserUserId();
std::string acerAccountId = profile.GetAccesser().GetAccesserAccountId();
std::string acerPkgName = profile.GetAccesser().GetAccesserBundleName();
std::string acerCredId = profile.GetAccesser().GetAccesserCredentialIdStr();
int32_t acerSkId = profile.GetAccesser().GetAccesserSessionKeyId();
int64_t acerTokenId = profile.GetAccesser().GetAccesserTokenId();
std::string aceeDeviceId = profile.GetAccessee().GetAccesseeDeviceId();
int32_t aceeUserId = profile.GetAccessee().GetAccesseeUserId();
std::string aceeAccountId = profile.GetAccessee().GetAccesseeAccountId();
std::string aceePkgName = profile.GetAccessee().GetAccesseeBundleName();
std::string aceeCredId = profile.GetAccessee().GetAccesseeCredentialIdStr();
int32_t aceeSkId = profile.GetAccessee().GetAccesseeSessionKeyId();
int64_t aceeTokenId = profile.GetAccessee().GetAccesseeTokenId();
LOGI("bindType %{public}d, bindLevel %{public}d, status %{public}d, acerDeviceId %{public}s, acerUserId %{public}d,"
"acerAccountId %{public}s, acerPkgName %{public}s, acerCredId %{public}s,"
"acerSkId %{public}d, aceeDeviceId %{public}s, aceeUserId %{public}d, aceeAccountId %{public}s,"
"aceePkgName %{public}s, aceeCredId %{public}s, aceeSkId %{public}d,"
"acerTokenId %{public}s, aceeTokenId %{public}s.",
bindType, bindLevel, profile.GetStatus(), GetAnonyString(acerDeviceId).c_str(), acerUserId,
GetAnonyString(acerAccountId).c_str(), acerPkgName.c_str(), GetAnonyString(acerCredId).c_str(), acerSkId,
GetAnonyString(aceeDeviceId).c_str(), aceeUserId, GetAnonyString(aceeAccountId).c_str(),
aceePkgName.c_str(), GetAnonyString(aceeCredId).c_str(), aceeSkId,
GetAnonyInt64(acerTokenId).c_str(), GetAnonyInt64(aceeTokenId).c_str());
}
std::string GetLocalDeviceId()
{
char localDeviceId[DEVICE_UUID_LENGTH] = {0};
GetDevUdid(localDeviceId, DEVICE_UUID_LENGTH);
return std::string(localDeviceId);
}
DM_EXPORT int32_t DeviceProfileConnector::GetVersionByExtra(std::string &extraInfo, std::string &dmVersion)
{
JsonObject extraInfoJson(extraInfo);
if (extraInfoJson.IsDiscarded()) {
LOGE("extraInfoJson error");
return ERR_DM_FAILED;
}
if (!extraInfoJson[TAG_DMVERSION].IsString()) {
LOGE("PARAM_KEY_OS_VERSION error");
return ERR_DM_FAILED;
}
dmVersion = extraInfoJson[TAG_DMVERSION].Get<std::string>();
return DM_OK;
}
DM_EXPORT void DeviceProfileConnector::GetAllVerionAclMap(DistributedDeviceProfile::AccessControlProfile &acl,
std::map<std::string, std::vector<std::string>> &aclMap, std::string dmVersion)
{
std::vector<std::string> needGenVersions = {};
if (dmVersion.empty()) {
for (int32_t idx = 0; idx < DM_SUPPORT_ACL_AGING_VERSION_NUM; idx++) {
needGenVersions.push_back(DM_SUPPORT_ACL_AGING_VERSIONS[idx]);
}
} else if (std::find(DM_SUPPORT_ACL_AGING_VERSIONS.begin(), DM_SUPPORT_ACL_AGING_VERSIONS.end(), dmVersion) !=
DM_SUPPORT_ACL_AGING_VERSIONS.end()) {
needGenVersions.push_back(dmVersion);
} else {
LOGE("dmVersion invalid, %{public}s", dmVersion.c_str());
return;
}
for (auto const &version : needGenVersions) {
GenerateAclHash(acl, aclMap, version);
}
}
void DeviceProfileConnector::GenerateAclHash(DistributedDeviceProfile::AccessControlProfile &acl,
std::map<std::string, std::vector<std::string>> &aclMap, const std::string &dmVersion)
{
int32_t versionNum = 0;
if (!GetVersionNumber(dmVersion, versionNum)) {
LOGE("GetAllVerionAclMap GetVersionNumber error");
return;
}
std::string aclStr;
switch (versionNum) {
case DM_VERSION_INT_5_1_0:
aclStr = AccessToStr(acl);
break;
default:
LOGE("versionNum is invaild, ver: %{public}d", versionNum);
break;
}
if (aclStr.empty()) {
return;
}
auto iter = aclMap.find(dmVersion);
if (iter != aclMap.end()) {
aclMap[dmVersion].push_back(Crypto::Sha256(aclStr));
} else {
std::vector<std::string> aclStrVec;
aclStrVec.push_back(Crypto::Sha256(aclStr));
aclMap[dmVersion] = aclStrVec;
}
}
DM_EXPORT int32_t DeviceProfileConnector::GetAclListHashStr(const DevUserInfo &localDevUserInfo,
const DevUserInfo &remoteDevUserInfo, std::string &aclListHash, std::string dmVersion)
{
std::map<std::string, std::vector<std::string>> aclMap;
std::vector<DistributedDeviceProfile::AccessControlProfile> profiles =
DeviceProfileConnector::GetInstance().GetAllAclIncludeLnnAcl();
for (auto &item : profiles) {
if (item.GetAccesser().GetAccesserDeviceId() == localDevUserInfo.deviceId &&
item.GetAccesser().GetAccesserUserId() == localDevUserInfo.userId &&
item.GetAccessee().GetAccesseeDeviceId() == remoteDevUserInfo.deviceId &&
item.GetAccessee().GetAccesseeUserId() == remoteDevUserInfo.userId) {
GetAllVerionAclMap(item, aclMap, dmVersion);
continue;
}
if (item.GetAccesser().GetAccesserDeviceId() == remoteDevUserInfo.deviceId &&
item.GetAccesser().GetAccesserUserId() == remoteDevUserInfo.userId &&
item.GetAccessee().GetAccesseeDeviceId() == localDevUserInfo.deviceId &&
item.GetAccessee().GetAccesseeUserId() == localDevUserInfo.userId) {
GetAllVerionAclMap(item, aclMap, dmVersion);
continue;
}
}
if (aclMap.empty()) {
LOGI("acl list is empty");
}
std::vector<AclHashItem> aclStrVec;
for (auto &item : aclMap) {
aclStrVec.push_back({item.first, item.second});
}
JsonObject allAclObj(JsonCreateType::JSON_CREATE_TYPE_ARRAY);
AclHashVecToJson(allAclObj, aclStrVec);
aclListHash = allAclObj.Dump();
return DM_OK;
}
DM_EXPORT void DeviceProfileConnector::AclHashItemToJson(JsonItemObject &itemObject, const AclHashItem &value)
{
itemObject[TAG_ACL_HASH_KEY_VERSION] = value.version;
JsonObject hashList(JsonCreateType::JSON_CREATE_TYPE_ARRAY);
for (const auto &val : value.aclHashList) {
hashList.PushBack(val);
}
itemObject[TAG_ACL_HASH_KEY_ACLHASHLIST] = hashList.Dump();
}
DM_EXPORT void DeviceProfileConnector::AclHashVecToJson(JsonItemObject &itemObject,
const std::vector<AclHashItem> &values)
{
for (const auto &val : values) {
JsonObject object;
AclHashItemToJson(object, val);
itemObject.PushBack(object.Dump());
}
}
DM_EXPORT void DeviceProfileConnector::AclHashItemFromJson(const JsonItemObject &itemObject, AclHashItem &value)
{
if (itemObject.IsDiscarded() || !IsString(itemObject, TAG_ACL_HASH_KEY_VERSION) ||
!IsString(itemObject, TAG_ACL_HASH_KEY_ACLHASHLIST)) {
LOGE("Invalid JSON structure for ACL hash item");
return;
}
value.version = itemObject[TAG_ACL_HASH_KEY_VERSION].Get<std::string>();
std::string hashListStr = itemObject[TAG_ACL_HASH_KEY_ACLHASHLIST].Get<std::string>();
JsonObject hashList;
hashList.Parse(hashListStr);
for (auto const &item : hashList.Items()) {
if (item.IsDiscarded() || !item.IsString()) {
LOGE("ACL hash list contains invalid element");
continue;
}
value.aclHashList.push_back(item.Get<std::string>());
}
}
DM_EXPORT void DeviceProfileConnector::AclHashVecFromJson(const JsonItemObject &itemObject,
std::vector<AclHashItem> &values)
{
for (auto const &item : itemObject.Items()) {
JsonObject object;
AclHashItem aclItem;
if (item.IsDiscarded() || !item.IsString()) {
LOGE("ItemObject contains invalid element");
continue;
}
object.Parse(item.Get<std::string>());
AclHashItemFromJson(object, aclItem);
values.push_back(aclItem);
}
}
DM_EXPORT bool DeviceProfileConnector::ChecksumAcl(DistributedDeviceProfile::AccessControlProfile &acl,
std::vector<std::string> &acLStrList)
{
std::string aclStr = AccessToStr(acl);
auto aclIter = find(acLStrList.begin(), acLStrList.end(), Crypto::Sha256(aclStr));
return (aclIter != acLStrList.end());
}
DM_EXPORT std::string DeviceProfileConnector::AccessToStr(DistributedDeviceProfile::AccessControlProfile acl)
{
std::string aclStr = "";
DistributedDeviceProfile::Accesser accesser = acl.GetAccesser();
aclStr += accesser.GetAccesserDeviceId();
aclStr += std::to_string(accesser.GetAccesserUserId());
aclStr += accesser.GetAccesserAccountId();
aclStr += std::to_string(accesser.GetAccesserTokenId());
aclStr += accesser.GetAccesserBundleName();
aclStr += accesser.GetAccesserHapSignature();
aclStr += std::to_string(accesser.GetAccesserBindLevel());
aclStr += accesser.GetAccesserCredentialIdStr();
aclStr += std::to_string(accesser.GetAccesserStatus());
aclStr += std::to_string(accesser.GetAccesserSKTimeStamp());
DistributedDeviceProfile::Accessee accessee = acl.GetAccessee();
aclStr += accessee.GetAccesseeDeviceId();
aclStr += std::to_string(accessee.GetAccesseeUserId());
aclStr += accessee.GetAccesseeAccountId();
aclStr += std::to_string(accessee.GetAccesseeTokenId());
aclStr += accessee.GetAccesseeBundleName();
aclStr += accessee.GetAccesseeHapSignature();
aclStr += std::to_string(accessee.GetAccesseeBindLevel());
aclStr += accessee.GetAccesseeCredentialIdStr();
aclStr += std::to_string(accessee.GetAccesseeStatus());
aclStr += std::to_string(accessee.GetAccesseeSKTimeStamp());
return aclStr;
}
DM_EXPORT std::vector<DistributedDeviceProfile::AccessControlProfile> DeviceProfileConnector::GetAclList(
const std::string localUdid, int32_t localUserId, const std::string remoteUdid, int32_t remoteUserId)
{
std::vector<DistributedDeviceProfile::AccessControlProfile> profiles =
DeviceProfileConnector::GetInstance().GetAllAclIncludeLnnAcl();
std::vector<DistributedDeviceProfile::AccessControlProfile> aclList;
for (auto &item : profiles) {
if (item.GetAccesser().GetAccesserDeviceId() == localUdid &&
item.GetAccesser().GetAccesserUserId() == localUserId &&
item.GetAccessee().GetAccesseeDeviceId() == remoteUdid &&
item.GetAccessee().GetAccesseeUserId() == remoteUserId) {
aclList.push_back(item);
continue;
}
if (item.GetAccesser().GetAccesserDeviceId() == remoteUdid &&
item.GetAccesser().GetAccesserUserId() == remoteUserId &&
item.GetAccessee().GetAccesseeDeviceId() == localUdid &&
item.GetAccessee().GetAccesseeUserId() == localUserId) {
aclList.push_back(item);
continue;
}
}
if (aclList.empty()) {
LOGI("acl is empty");
}
return aclList;
}
DM_EXPORT std::string DeviceProfileConnector::IsAuthNewVersion(int32_t bindLevel, std::string localUdid,
std::string remoteUdid, int32_t tokenId, int32_t userId)
{
LOGI("localUdid %{public}s, remoteUdid %{public}s, bindLevel %{public}d.",
GetAnonyString(localUdid).c_str(), GetAnonyString(remoteUdid).c_str(), bindLevel);
if (static_cast<uint32_t>(bindLevel) > APP || static_cast<uint32_t>(bindLevel) < USER) {
LOGE("Invalied bindlevel bindLevel=%{public}u.", bindLevel);
return "";
}
std::vector<AccessControlProfile> profiles = GetAclProfileByDeviceIdAndUserId(localUdid, userId);
if (profiles.empty()) {
LOGE("Acl is empty.");
return "";
}
switch (bindLevel) {
case APP:
case SERVICE:
return GetAppServiceAuthVersionInfo(localUdid, remoteUdid, tokenId, userId, profiles);
case USER:
return GetDeviceAuthVersionInfo(localUdid, remoteUdid, profiles);
default:
break;
}
return "";
}
std::string DeviceProfileConnector::GetAppServiceAuthVersionInfo(std::string localUdid, std::string remoteUdid,
int32_t tokenId, int32_t userId, std::vector<DistributedDeviceProfile::AccessControlProfile> profiles)
{
for (auto &item : profiles) {
if (item.GetBindType() == DM_IDENTICAL_ACCOUNT ||
(item.GetBindLevel() != APP && item.GetBindLevel() != SERVICE)) {
continue;
}
int32_t acerUserId = item.GetAccesser().GetAccesserUserId();
int32_t aceeUserId = item.GetAccessee().GetAccesseeUserId();
std::string acerDeviceId = item.GetAccesser().GetAccesserDeviceId();
std::string aceeDeviceId = item.GetAccessee().GetAccesseeDeviceId();
int32_t acerTokenId = static_cast<int32_t>(item.GetAccesser().GetAccesserTokenId());
int32_t aceeTokenId = static_cast<int32_t>(item.GetAccessee().GetAccesseeTokenId());
if (acerUserId == userId && acerTokenId == tokenId &&
acerDeviceId == localUdid && aceeDeviceId == remoteUdid) {
return item.GetAccesser().GetAccesserExtraData();
}
if (aceeUserId == userId && aceeTokenId == tokenId &&
aceeDeviceId == localUdid && acerDeviceId == remoteUdid) {
return item.GetAccessee().GetAccesseeExtraData();
}
}
return "";
}
std::string DeviceProfileConnector::GetDeviceAuthVersionInfo(std::string localUdid, std::string remoteUdid,
std::vector<DistributedDeviceProfile::AccessControlProfile> profiles)
{
for (auto &item : profiles) {
if (item.GetBindType() == DM_IDENTICAL_ACCOUNT || item.GetBindLevel() != USER || IsLnnAcl(item)) {
continue;
}
std::string acerDeviceId = item.GetAccesser().GetAccesserDeviceId();
std::string aceeDeviceId = item.GetAccessee().GetAccesseeDeviceId();
if (acerDeviceId == localUdid && aceeDeviceId == remoteUdid) {
return item.GetAccesser().GetAccesserExtraData();
}
if (aceeDeviceId == localUdid && acerDeviceId == remoteUdid) {
return item.GetAccessee().GetAccesseeExtraData();
}
}
return "";
}
std::string DeviceProfileConnector::GetAclVersionInfo(const std::string localUdid, const std::string remoteUdid,
const DistributedDeviceProfile::AccessControlProfile &acl)
{
std::string acerDeviceId = acl.GetAccesser().GetAccesserDeviceId();
std::string aceeDeviceId = acl.GetAccessee().GetAccesseeDeviceId();
if (acerDeviceId == localUdid && aceeDeviceId == remoteUdid) {
return acl.GetAccesser().GetAccesserExtraData();
}
if (aceeDeviceId == localUdid && acerDeviceId == remoteUdid) {
return acl.GetAccessee().GetAccesseeExtraData();
}
return "";
}
DM_EXPORT DmOfflineParam DeviceProfileConnector::FilterNeedDeleteACL(const std::string &localDeviceId,
uint32_t localTokenId, const std::string &remoteDeviceId, const std::string &extra)
{
LOGI("localDeviceId %{public}s, remoteDeviceId %{public}s",
GetAnonyString(localDeviceId).c_str(), GetAnonyString(remoteDeviceId).c_str());
DmOfflineParam offlineParam = {};
int32_t userId = MultipleUserConnector::GetCurrentAccountUserID();
std::vector<AccessControlProfile> profiles = GetAclProfileByDeviceIdAndUserId(localDeviceId, userId,
remoteDeviceId);
if (profiles.empty()) {
LOGE("Acl is empty.");
return offlineParam;
}
FilterNeedDeleteACLInfos(profiles, localDeviceId, localTokenId, remoteDeviceId, extra, offlineParam);
return offlineParam;
}
void DeviceProfileConnector::CheckLastLnnAcl(const std::string &localDeviceId, int32_t localUserId,
const std::string &remoteDeviceId, DmOfflineParam &offlineParam,
std::vector<DistributedDeviceProfile::AccessControlProfile> &profiles)
{
LOGI("profiles size: %{public}zu", profiles.size());
if (profiles.size() == 1 && IsLnnAcl(profiles[0])) {
if (profiles[0].GetAccesser().GetAccesserDeviceId() == localDeviceId) {
CacheAcerAclId(profiles[0], offlineParam.needDelAclInfos);
}
if (profiles[0].GetAccessee().GetAccesseeDeviceId() == localDeviceId) {
CacheAceeAclId(profiles[0], offlineParam.needDelAclInfos);
}
offlineParam.hasLnnAcl = true;
}
}
void DeviceProfileConnector::DeleteCacheAcl(std::vector<int64_t> delAclIdVec,
std::vector<DistributedDeviceProfile::AccessControlProfile> &profiles)
{
for (auto delAclId : delAclIdVec) {
for (auto item = profiles.begin(); item != profiles.end();) {
if (delAclId == item->GetAccessControlId()) {
item = profiles.erase(item);
} else {
item++;
}
}
}
}
bool DeviceProfileConnector::FindTargetAcl(const DistributedDeviceProfile::AccessControlProfile &acl,
const std::string &localUdid, const uint32_t localTokenId,
const std::string &remoteUdid, const uint32_t peerTokenId,
DmOfflineParam &offlineParam)
{
bool isMatch = false;
int64_t acerTokenId = acl.GetAccesser().GetAccesserTokenId();
int64_t aceeTokenId = acl.GetAccessee().GetAccesseeTokenId();
std::string acerDeviceId = acl.GetAccesser().GetAccesserDeviceId();
std::string aceeDeviceId = acl.GetAccessee().GetAccesseeDeviceId();
if ((acerTokenId == static_cast<int64_t>(localTokenId)) &&
(acerDeviceId == localUdid) && (aceeDeviceId == remoteUdid) &&
(peerTokenId == 0 || (peerTokenId != 0 && aceeTokenId == static_cast<int64_t>(peerTokenId)))) {
ProcessInfo processInfo;
processInfo.pkgName = acl.GetAccesser().GetAccesserBundleName();
processInfo.userId = acl.GetAccesser().GetAccesserUserId();
processInfo.tokenId = acl.GetAccesser().GetAccesserTokenId();
if ((acl.GetBindLevel() == USER || acl.GetBindType() == DM_IDENTICAL_ACCOUNT)) {
offlineParam.hasUserAcl = true;
processInfo.tokenId = 0;
}
offlineParam.processVec.push_back(processInfo);
CacheAcerAclId(acl, offlineParam.needDelAclInfos);
LOGI("Src del acl aclId: %{public}" PRId64 ", localUdid: %{public}s, remoteUdid: %{public}s"
", bindType: %{public}d, bindLevel: %{public}d", acl.GetAccessControlId(),
GetAnonyString(localUdid).c_str(), GetAnonyString(remoteUdid).c_str(), acl.GetBindType(),
acl.GetBindLevel());
isMatch = true;
}
if ((aceeTokenId == static_cast<int64_t>(localTokenId)) &&
(aceeDeviceId == localUdid) && (acerDeviceId == remoteUdid) &&
(peerTokenId == 0 || (peerTokenId != 0 && acerTokenId == static_cast<int64_t>(peerTokenId)))) {
ProcessInfo processInfo;
processInfo.pkgName = acl.GetAccessee().GetAccesseeBundleName();
processInfo.userId = acl.GetAccessee().GetAccesseeUserId();
processInfo.tokenId = acl.GetAccessee().GetAccesseeTokenId();
if ((acl.GetBindLevel() == USER || acl.GetBindType() == DM_IDENTICAL_ACCOUNT)) {
offlineParam.hasUserAcl = true;
processInfo.tokenId = 0;
}
offlineParam.processVec.push_back(processInfo);
CacheAceeAclId(acl, offlineParam.needDelAclInfos);
LOGI("Sink del acl aclId: %{public}" PRId64 ", localUdid: %{public}s, remoteUdid: %{public}s"
", bindType: %{public}d, bindLevel: %{public}d", acl.GetAccessControlId(),
GetAnonyString(localUdid).c_str(), GetAnonyString(remoteUdid).c_str(), acl.GetBindType(),
acl.GetBindLevel());
isMatch = true;
}
return isMatch;
}
bool DeviceProfileConnector::FindLnnAcl(const DistributedDeviceProfile::AccessControlProfile &acl,
const std::string &localUdid, const std::string &remoteUdid, DmOfflineParam &offlineParam)
{
bool isMatch = false;
std::string acerDeviceId = acl.GetAccesser().GetAccesserDeviceId();
std::string aceeDeviceId = acl.GetAccessee().GetAccesseeDeviceId();
if (IsLnnAcl(acl) && acl.GetTrustDeviceId() == remoteUdid) {
if (acerDeviceId == localUdid && aceeDeviceId == remoteUdid) {
LOGI("Src lnn acl aclId: %{public}" PRId64 ", localUdid %{public}s, remoteUdid %{public}s"
", bindType %{public}d, bindLevel: %{public}d", acl.GetAccessControlId(),
GetAnonyString(localUdid).c_str(),
GetAnonyString(remoteUdid).c_str(), acl.GetBindType(), acl.GetBindLevel());
CacheAcerAclId(acl, offlineParam.allLnnAclInfos);
}
if (aceeDeviceId == localUdid && acerDeviceId == remoteUdid) {
LOGI("Sink lnn acl aclId: %{public}" PRId64 ", localUdid %{public}s, remoteUdid %{public}s"
", bindType %{public}d, bindLevel: %{public}d", acl.GetAccessControlId(),
GetAnonyString(localUdid).c_str(), GetAnonyString(remoteUdid).c_str(), acl.GetBindType(),
acl.GetBindLevel());
CacheAceeAclId(acl, offlineParam.allLnnAclInfos);
}
isMatch = true;
}
return isMatch;
}
bool DeviceProfileConnector::FindUserAcl(const DistributedDeviceProfile::AccessControlProfile &acl,
const std::string &localUdid, const std::string &remoteUdid, DmOfflineParam &offlineParam)
{
bool isMatch = false;
std::string acerDeviceId = acl.GetAccesser().GetAccesserDeviceId();
std::string aceeDeviceId = acl.GetAccessee().GetAccesseeDeviceId();
if (acl.GetBindLevel() == USER || acl.GetBindType() == DM_IDENTICAL_ACCOUNT) {
if (acerDeviceId == localUdid && aceeDeviceId == remoteUdid) {
LOGI("Src User acl aclId: %{public}" PRId64 ", localUdid %{public}s, remoteUdid %{public}s"
", bindType %{public}d, bindLevel: %{public}d", acl.GetAccessControlId(),
GetAnonyString(localUdid).c_str(), GetAnonyString(remoteUdid).c_str(), acl.GetBindType(),
acl.GetBindLevel());
CacheAcerAclId(acl, offlineParam.allUserAclInfos);
}
if (aceeDeviceId == localUdid && acerDeviceId == remoteUdid) {
LOGI("Sink User acl aclId: %{public}" PRId64 ", localUdid %{public}s, remoteUdid %{public}s"
", bindType %{public}d, bindLevel: %{public}d", acl.GetAccessControlId(),
GetAnonyString(localUdid).c_str(), GetAnonyString(remoteUdid).c_str(), acl.GetBindType(),
acl.GetBindLevel());
CacheAceeAclId(acl, offlineParam.allUserAclInfos);
}
isMatch = true;
}
return isMatch;
}
bool DeviceProfileConnector::FindLeftAcl(const DistributedDeviceProfile::AccessControlProfile &acl,
const std::string &localUdid, const std::string &remoteUdid, DmOfflineParam &offlineParam)
{
bool isMatch = false;
std::string acerDeviceId = acl.GetAccesser().GetAccesserDeviceId();
std::string aceeDeviceId = acl.GetAccessee().GetAccesseeDeviceId();
if (acl.GetBindLevel() == SERVICE || acl.GetBindLevel() == APP) {
if (acerDeviceId == localUdid && aceeDeviceId == remoteUdid) {
LOGI("Src Left acl aclId: %{public}" PRId64 ", localUdid %{public}s, remoteUdid %{public}s"
", bindType %{public}d, bindLevel: %{public}d", acl.GetAccessControlId(),
GetAnonyString(localUdid).c_str(), GetAnonyString(remoteUdid).c_str(), acl.GetBindType(),
acl.GetBindLevel());
CacheAcerAclId(acl, offlineParam.allLeftAppOrSvrAclInfos);
}
if (aceeDeviceId == localUdid && acerDeviceId == remoteUdid) {
LOGI("Sink Left acl aclId: %{public}" PRId64 ", localUdid %{public}s, remoteUdid %{public}s"
", bindType %{public}d, bindLevel: %{public}d", acl.GetAccessControlId(),
GetAnonyString(localUdid).c_str(), GetAnonyString(remoteUdid).c_str(), acl.GetBindType(),
acl.GetBindLevel());
CacheAceeAclId(acl, offlineParam.allLeftAppOrSvrAclInfos);
}
isMatch = true;
}
return isMatch;
}
void DeviceProfileConnector::FilterNeedDeleteACLInfos(
std::vector<DistributedDeviceProfile::AccessControlProfile> &profiles,
const std::string &localUdid, const uint32_t localTokenId,
const std::string &remoteUdid, const std::string &extra, DmOfflineParam &offlineParam)
{
uint64_t peerTokenId = 0;
std::string peerBundleName = "";
JsonStrHandle::GetInstance().GetPeerAppInfoParseExtra(extra, peerTokenId, peerBundleName);
for (auto &item : profiles) {
if (item.GetTrustDeviceId() != remoteUdid) {
continue;
}
if (FindTargetAcl(item, localUdid, localTokenId, remoteUdid, peerTokenId, offlineParam)) {
continue;
}
if (FindLnnAcl(item, localUdid, remoteUdid, offlineParam)) {
continue;
}
if (FindUserAcl(item, localUdid, remoteUdid, offlineParam)) {
continue;
}
if (FindLeftAcl(item, localUdid, remoteUdid, offlineParam)) {
continue;
}
}
}
DM_EXPORT std::vector<AccessControlProfile> DeviceProfileConnector::GetAccessControlProfile()
{
int32_t userId = MultipleUserConnector::GetCurrentAccountUserID();
return GetAccessControlProfileByUserId(userId);
}
std::vector<AccessControlProfile> DeviceProfileConnector::GetAccessControlProfileByUserId(int32_t userId)
{
std::vector<AccessControlProfile> profiles;
std::map<std::string, std::string> queryParams;
queryParams[USERID] = std::to_string(userId);
if (DistributedDeviceProfileClient::GetInstance().GetAccessControlProfile(queryParams, profiles) != DM_OK) {
LOGE("DP GetAccessControlProfileByUserId failed.");
}
return profiles;
}
DM_EXPORT std::vector<AccessControlProfile> DeviceProfileConnector::GetAclProfileByDeviceIdAndUserId(
const std::string &deviceId, int32_t userId)
{
std::vector<AccessControlProfile> profiles = GetAccessControlProfileByUserId(userId);
std::vector<AccessControlProfile> aclProfileVec;
for (auto &item : profiles) {
if ((item.GetAccesser().GetAccesserDeviceId() == deviceId &&
item.GetAccesser().GetAccesserUserId() == userId) ||
(item.GetAccessee().GetAccesseeDeviceId() == deviceId &&
item.GetAccessee().GetAccesseeUserId() == userId)) {
aclProfileVec.push_back(item);
}
}
return aclProfileVec;
}
DM_EXPORT std::vector<AccessControlProfile> DeviceProfileConnector::GetAclProfileByDeviceIdAndUserId(
const std::string &deviceId, int32_t userId, const std::string &remoteDeviceId)
{
std::vector<AccessControlProfile> aclProfileVec;
std::vector<AccessControlProfile> profiles = GetAllAclIncludeLnnAcl();
for (auto &item : profiles) {
if ((item.GetAccesser().GetAccesserDeviceId() == deviceId &&
item.GetAccesser().GetAccesserUserId() == userId &&
item.GetAccessee().GetAccesseeDeviceId() == remoteDeviceId) ||
(item.GetAccessee().GetAccesseeDeviceId() == deviceId &&
item.GetAccessee().GetAccesseeUserId() == userId &&
item.GetAccesser().GetAccesserDeviceId() == remoteDeviceId)) {
aclProfileVec.push_back(item);
}
}
return aclProfileVec;
}
DM_EXPORT std::unordered_map<std::string, DmAuthForm> DeviceProfileConnector::GetAppTrustDeviceList(
const std::string &pkgName, const std::string &deviceId)
{
int32_t userId = MultipleUserConnector::GetCurrentAccountUserID();
LOGI("localDeviceId: %{public}s, userId: %{public}d", GetAnonyString(deviceId).c_str(), userId);
std::vector<AccessControlProfile> profiles = GetAllAclIncludeLnnAcl();
std::vector<AccessControlProfile> profilesFilter = {};
for (auto &item : profiles) {
if (!IsLnnAcl(item) && ((item.GetAccesser().GetAccesserUserId() == userId &&
item.GetAccesser().GetAccesserDeviceId() == deviceId) ||
(item.GetAccessee().GetAccesseeUserId() == userId &&
item.GetAccessee().GetAccesseeDeviceId() == deviceId))) {
profilesFilter.push_back(item);
}
}
return GetAuthFormMap(pkgName, deviceId, profilesFilter, userId);
}
std::unordered_map<std::string, DmAuthForm> DeviceProfileConnector::GetAuthFormMap(const std::string &pkgName,
const std::string &deviceId, const std::vector<DistributedDeviceProfile::AccessControlProfile> &profilesFilter,
const int32_t &userId)
{
std::unordered_map<std::string, DmAuthForm> deviceIdMap;
for (auto &item : profilesFilter) {
std::string trustDeviceId = item.GetTrustDeviceId();
LOGI("trustDeviceId: %{public}s, status: %{public}d, acerUserId: %{public}d, aceeUserId: %{public}d",
GetAnonyString(trustDeviceId).c_str(), item.GetStatus(), item.GetAccesser().GetAccesserUserId(),
item.GetAccessee().GetAccesseeUserId());
if (trustDeviceId == deviceId || item.GetStatus() != ACTIVE) {
continue;
}
DmDiscoveryInfo discoveryInfo = {pkgName, deviceId};
int32_t bindType = HandleDmAuthForm(item, discoveryInfo);
LOGI("The udid %{public}s in ACL authForm is %{public}d.", GetAnonyString(trustDeviceId).c_str(), bindType);
if (bindType == DmAuthForm::INVALID_TYPE) {
continue;
}
if (deviceIdMap.find(trustDeviceId) == deviceIdMap.end()) {
if (CheckSinkShareType(item, userId, deviceId, trustDeviceId, bindType)) {
LOGI("CheckSinkShareType true.");
continue;
}
deviceIdMap[trustDeviceId] = static_cast<DmAuthForm>(bindType);
continue;
}
DmAuthForm authForm = deviceIdMap.at(trustDeviceId);
if (bindType == authForm) {
continue;
}
uint32_t highestBindType = CheckBindType(trustDeviceId, deviceId);
if (highestBindType == IDENTICAL_ACCOUNT_TYPE) {
deviceIdMap[trustDeviceId] = DmAuthForm::IDENTICAL_ACCOUNT;
continue;
} else if (highestBindType == SHARE_TYPE) {
if (CheckSinkShareType(item, userId, deviceId, trustDeviceId, DmAuthForm::SHARE)) {
continue;
}
deviceIdMap[trustDeviceId] = DmAuthForm::SHARE;
continue;
} else if (highestBindType == DEVICE_PEER_TO_PEER_TYPE || highestBindType == APP_PEER_TO_PEER_TYPE ||
highestBindType == SERVICE_PEER_TO_PEER_TYPE) {
deviceIdMap[trustDeviceId] = DmAuthForm::PEER_TO_PEER;
continue;
} else if (highestBindType == APP_ACROSS_ACCOUNT_TYPE ||
highestBindType == DEVICE_ACROSS_ACCOUNT_TYPE || highestBindType == SERVICE_ACROSS_ACCOUNT_TYPE) {
deviceIdMap[trustDeviceId] = DmAuthForm::ACROSS_ACCOUNT;
continue;
} else {
LOGE("highestBindType match failed.");
continue;
}
}
return deviceIdMap;
}
bool DeviceProfileConnector::CheckSinkShareType(const DistributedDeviceProfile::AccessControlProfile &profile,
const int32_t &userId, const std::string &deviceId, const std::string &trustDeviceId, const int32_t &bindType)
{
if (profile.GetAccessee().GetAccesseeUserId() == userId &&
profile.GetAccessee().GetAccesseeDeviceId() == deviceId &&
profile.GetAccesser().GetAccesserDeviceId() == trustDeviceId &&
bindType == DmAuthForm::SHARE) {
return true;
}
return false;
}
int32_t DeviceProfileConnector::GetDeviceAclParam(DmDiscoveryInfo discoveryInfo, bool &isOnline, int32_t &authForm)
{
std::vector<AccessControlProfile> profiles = GetAccessControlProfileByUserId(discoveryInfo.userId);
std::vector<int32_t> bindTypes;
for (auto &item : profiles) {
char deviceIdHash[DM_MAX_DEVICE_ID_LEN] = {0};
if (Crypto::GetUdidHash(item.GetTrustDeviceId(), reinterpret_cast<uint8_t *>(deviceIdHash)) != DM_OK) {
LOGE("get deviceIdHash by deviceId: %{public}s failed.", GetAnonyString(deviceIdHash).c_str());
continue;
}
if (IsLnnAcl(item) || static_cast<std::string>(deviceIdHash) != discoveryInfo.remoteDeviceIdHash ||
(discoveryInfo.localDeviceId == item.GetAccesser().GetAccesserDeviceId() &&
discoveryInfo.userId != item.GetAccesser().GetAccesserUserId()) ||
(discoveryInfo.localDeviceId == item.GetAccessee().GetAccesseeDeviceId() &&
discoveryInfo.userId != item.GetAccessee().GetAccesseeUserId())) {
continue;
}
int32_t bindType = HandleDmAuthForm(item, discoveryInfo);
if (bindType == DmAuthForm::INVALID_TYPE) {
continue;
}
bindTypes.push_back(bindType);
}
if (std::count(bindTypes.begin(), bindTypes.end(), DmAuthForm::IDENTICAL_ACCOUNT) > 0) {
isOnline = true;
authForm = DmAuthForm::IDENTICAL_ACCOUNT;
LOGI("The found device is identical account device bind type.");
return DM_OK;
}
if (std::count(bindTypes.begin(), bindTypes.end(), DmAuthForm::PEER_TO_PEER) > 0) {
isOnline = true;
authForm = DmAuthForm::PEER_TO_PEER;
LOGI("The found device is peer-to-peer device bind-level.");
return DM_OK;
}
if (std::count(bindTypes.begin(), bindTypes.end(), DmAuthForm::ACROSS_ACCOUNT) > 0) {
isOnline = true;
authForm = DmAuthForm::ACROSS_ACCOUNT;
LOGI("The found device is across-account device bind-level.");
return DM_OK;
}
authForm = DmAuthForm::INVALID_TYPE;
return DM_OK;
}
bool DeviceProfileConnector::CheckAuthFormProxyTokenId(const std::string pkgName, const std::string &extraStr)
{
std::vector<int64_t> proxyTokenIdVec = JsonStrHandle::GetInstance().GetProxyTokenIdByExtra(extraStr);
int64_t callingTokenId = static_cast<int64_t>(IPCSkeleton::GetCallingTokenID());
for (auto &proxyTokenId : proxyTokenIdVec) {
std::string proxyBundleName;
if (AppManager::GetInstance().GetBundleNameByTokenId(proxyTokenId, proxyBundleName) != DM_OK) {
continue;
}
if (callingTokenId == proxyTokenId && pkgName == proxyBundleName) {
return true;
}
}
return false;
}
bool DeviceProfileConnector::CheckAuthFormForAccesser(DmAuthForm form, const std::string &pkgName,
const DistributedDeviceProfile::AccessControlProfile &profile, bool isSystemSA, uint32_t callingTokenId)
{
const auto &accesser = profile.GetAccesser();
if (isSystemSA) {
if (pkgName == accesser.GetAccesserBundleName() ||
CheckAuthFormProxyTokenId(pkgName, accesser.GetAccesserExtraData())) {
return true;
}
} else {
if (pkgName == accesser.GetAccesserBundleName() &&
static_cast<uint64_t>(accesser.GetAccesserTokenId()) == callingTokenId) {
LOGI("Non-systemSA matched: pkgName and tokenId as accesser.");
return true;
}
}
return false;
}
bool DeviceProfileConnector::CheckAuthFormForAccessee(DmAuthForm form, const std::string &pkgName,
const DistributedDeviceProfile::AccessControlProfile &profile, bool isSystemSA, uint32_t callingTokenId)
{
const auto &accessee = profile.GetAccessee();
if (isSystemSA) {
if (pkgName == accessee.GetAccesseeBundleName() ||
CheckAuthFormProxyTokenId(pkgName, accessee.GetAccesseeExtraData())) {
return true;
}
} else {
if (pkgName == accessee.GetAccesseeBundleName() &&
static_cast<uint64_t>(accessee.GetAccesseeTokenId()) == callingTokenId) {
LOGI("Non-systemSA matched: pkgName and tokenId as accessee.");
return true;
}
}
return false;
}
int32_t DeviceProfileConnector::CheckAuthForm(DmAuthForm form, AccessControlProfile profiles,
DmDiscoveryInfo discoveryInfo)
{
if (IsLnnAcl(profiles)) {
return DmAuthForm::INVALID_TYPE;
}
if (profiles.GetBindLevel() == USER || ((profiles.GetBindLevel() == APP ||
profiles.GetBindLevel() == SERVICE) && discoveryInfo.pkgname == "")) {
return form;
}
if (profiles.GetBindLevel() != APP && profiles.GetBindLevel() != SERVICE) {
return DmAuthForm::INVALID_TYPE;
}
bool isSystemSA = AppManager::GetInstance().IsSystemSA();
uint32_t callingTokenId = 0;
if (!isSystemSA) {
callingTokenId = IPCSkeleton::GetCallingTokenID();
if (callingTokenId == 0) {
LOGE("GetCallingTokenID error.");
return DmAuthForm::INVALID_TYPE;
}
}
if (discoveryInfo.localDeviceId == profiles.GetAccesser().GetAccesserDeviceId()) {
if (CheckAuthFormForAccesser(form, discoveryInfo.pkgname, profiles, isSystemSA, callingTokenId)) {
return form;
}
}
if (discoveryInfo.localDeviceId == profiles.GetAccessee().GetAccesseeDeviceId()) {
if (CheckAuthFormForAccessee(form, discoveryInfo.pkgname, profiles, isSystemSA, callingTokenId)) {
return form;
}
}
return DmAuthForm::INVALID_TYPE;
}
int32_t DeviceProfileConnector::HandleDmAuthForm(AccessControlProfile profiles, DmDiscoveryInfo discoveryInfo)
{
if (profiles.GetBindType() == DM_IDENTICAL_ACCOUNT) {
return DmAuthForm::IDENTICAL_ACCOUNT;
}
if (profiles.GetBindType() == DM_POINT_TO_POINT) {
return CheckAuthForm(DmAuthForm::PEER_TO_PEER, profiles, discoveryInfo);
}
if (profiles.GetBindType() == DM_ACROSS_ACCOUNT) {
return CheckAuthForm(DmAuthForm::PEER_TO_PEER, profiles, discoveryInfo);
}
if (profiles.GetBindType() == DM_SHARE) {
return CheckAuthForm(DmAuthForm::SHARE, profiles, discoveryInfo);
}
return DmAuthForm::INVALID_TYPE;
}
DM_EXPORT uint32_t DeviceProfileConnector::CheckBindType(std::string peerUdid,
std::string localUdid)
{
std::vector<AccessControlProfile> filterProfiles = GetAclProfileByUserId(localUdid,
MultipleUserConnector::GetFirstForegroundUserId(), peerUdid);
LOGI("filterProfiles size is %{public}zu", filterProfiles.size());
uint32_t highestPriority = INVALIED_TYPE;
for (auto &item : filterProfiles) {
if (IsLnnAcl(item) || peerUdid != item.GetTrustDeviceId()) {
continue;
}
uint32_t priority = static_cast<uint32_t>(GetAuthForm(item, peerUdid, localUdid));
if (priority > highestPriority) {
highestPriority = priority;
}
}
return highestPriority;
}
int32_t DeviceProfileConnector::GetAuthForm(DistributedDeviceProfile::AccessControlProfile profiles,
const std::string &trustDev, const std::string &reqDev)
{
LOGI("BindType %{public}d, bindLevel %{public}d", profiles.GetBindType(), profiles.GetBindLevel());
uint32_t priority = INVALIED_TYPE;
uint32_t bindType = profiles.GetBindType();
switch (bindType) {
case DM_IDENTICAL_ACCOUNT:
priority = IDENTICAL_ACCOUNT_TYPE;
break;
case DM_SHARE:
priority = SHARE_TYPE;
break;
case DM_POINT_TO_POINT:
if (profiles.GetBindLevel() == USER) {
priority = DEVICE_PEER_TO_PEER_TYPE;
}
if (profiles.GetBindLevel() == SERVICE) {
priority = SERVICE_PEER_TO_PEER_TYPE;
}
if (profiles.GetBindLevel() == APP) {
priority = APP_PEER_TO_PEER_TYPE;
}
break;
case DM_ACROSS_ACCOUNT:
if (profiles.GetBindLevel() == USER) {
priority = DEVICE_ACROSS_ACCOUNT_TYPE;
}
if (profiles.GetBindLevel() == SERVICE) {
priority = SERVICE_ACROSS_ACCOUNT_TYPE;
}
if (profiles.GetBindLevel() == APP) {
priority = APP_ACROSS_ACCOUNT_TYPE;
}
break;
default:
LOGE("unknown bind type %{public}d.", bindType);
break;
}
return priority;
}
DM_EXPORT std::vector<int32_t> DeviceProfileConnector::GetBindTypeByPkgName(
std::string pkgName, std::string requestDeviceId, std::string trustUdid)
{
LOGI("Start requestDeviceId %{public}s, trustUdid %{public}s.", GetAnonyString(requestDeviceId).c_str(),
GetAnonyString(trustUdid).c_str());
std::vector<int32_t> bindTypeVec;
if (requestDeviceId.empty() || trustUdid.empty() || requestDeviceId == trustUdid) {
LOGE("Input udid param invalied.");
return bindTypeVec;
}
std::vector<AccessControlProfile> profiles =
GetAccessControlProfileByUserId(MultipleUserConnector::GetFirstForegroundUserId());
LOGI("AccessControlProfile size is %{public}zu", profiles.size());
for (auto &item : profiles) {
if (IsLnnAcl(item) || trustUdid != item.GetTrustDeviceId() || item.GetStatus() != ACTIVE) {
continue;
}
GetParamBindTypeVec(item, requestDeviceId, bindTypeVec, trustUdid);
}
return bindTypeVec;
}
DM_EXPORT uint64_t DeviceProfileConnector::GetTokenIdByNameAndDeviceId(std::string extra, std::string requestDeviceId)
{
uint64_t peerTokenId = 0;
std::string pkgName = "";
JsonStrHandle::GetInstance().GetPeerAppInfoParseExtra(extra, peerTokenId, pkgName);
std::vector<AccessControlProfile> profiles = GetAccessControlProfile();
for (auto &item : profiles) {
if (item.GetAccesser().GetAccesserBundleName() == pkgName &&
item.GetAccesser().GetAccesserDeviceId() == requestDeviceId) {
peerTokenId = static_cast<uint64_t>(item.GetAccesser().GetAccesserTokenId());
break;
}
if (item.GetAccessee().GetAccesseeBundleName() == pkgName &&
item.GetAccessee().GetAccesseeDeviceId() == requestDeviceId) {
peerTokenId = static_cast<uint64_t>(item.GetAccessee().GetAccesseeTokenId());
break;
}
}
return peerTokenId;
}
void DeviceProfileConnector::GetParamBindTypeVec(AccessControlProfile profile, std::string requestDeviceId,
std::vector<int32_t> &bindTypeVec, std::string trustUdid)
{
if (!(profile.GetAccesser().GetAccesserDeviceId() == trustUdid &&
profile.GetAccessee().GetAccesseeDeviceId() == requestDeviceId) &&
!(profile.GetAccessee().GetAccesseeDeviceId() == trustUdid &&
profile.GetAccesser().GetAccesserDeviceId() == requestDeviceId)) {
LOGE("input udid param invalied.");
return;
}
uint32_t bindType = profile.GetBindType();
switch (bindType) {
case DM_IDENTICAL_ACCOUNT:
bindTypeVec.push_back(DmDevBindType::IDENTICAL_ACCOUNT_BIND_TYPE);
break;
case DM_POINT_TO_POINT:
if (profile.GetBindLevel() == USER) {
bindTypeVec.push_back(DmDevBindType::DEVICE_PEER_TO_PEER_BIND_TYPE);
}
if (profile.GetBindLevel() == APP) {
bindTypeVec.push_back(APP_PEER_TO_PEER_TYPE);
}
break;
case DM_ACROSS_ACCOUNT:
if (profile.GetBindLevel() == USER) {
bindTypeVec.push_back(DmDevBindType::DEVICE_ACROSS_ACCOUNT_BIND_TYPE);
}
if (profile.GetBindLevel() == APP) {
bindTypeVec.push_back(APP_ACROSS_ACCOUNT_TYPE);
}
break;
default:
LOGE("unknown bind type %{public}d.", bindType);
break;
}
}
std::vector<int32_t> DeviceProfileConnector::CompareBindType(std::vector<AccessControlProfile> profiles,
std::string pkgName, std::vector<int32_t> &sinkBindType, std::string localDeviceId, std::string targetDeviceId)
{
std::vector<int32_t> bindTypeIndex;
for (uint32_t index = 0; index < profiles.size(); index++) {
if (IsLnnAcl(profiles[index]) || profiles[index].GetTrustDeviceId() != targetDeviceId ||
profiles[index].GetStatus() != ACTIVE) {
continue;
}
DmDiscoveryInfo paramInfo = {
.pkgname = pkgName,
.localDeviceId = localDeviceId,
};
ProcessBindType(profiles[index], localDeviceId, sinkBindType, bindTypeIndex, index, targetDeviceId);
}
return bindTypeIndex;
}
void DeviceProfileConnector::ProcessBindType(AccessControlProfile profiles, std::string localDeviceId,
std::vector<int32_t> &sinkBindType, std::vector<int32_t> &bindTypeIndex,
uint32_t index, std::string targetDeviceId)
{
if (profiles.GetBindType() == DM_IDENTICAL_ACCOUNT) {
sinkBindType.push_back(DmDevBindType::IDENTICAL_ACCOUNT_BIND_TYPE);
bindTypeIndex.push_back(index);
}
if (profiles.GetBindType() == DM_POINT_TO_POINT) {
if (profiles.GetBindLevel() == USER) {
sinkBindType.push_back(DmDevBindType::DEVICE_PEER_TO_PEER_BIND_TYPE);
bindTypeIndex.push_back(index);
}
if (profiles.GetBindLevel() == APP) {
if (profiles.GetAccesser().GetAccesserDeviceId() == targetDeviceId &&
profiles.GetAccessee().GetAccesseeDeviceId() == localDeviceId) {
sinkBindType.push_back(APP_PEER_TO_PEER_TYPE);
bindTypeIndex.push_back(index);
}
if (profiles.GetAccessee().GetAccesseeDeviceId() == targetDeviceId &&
profiles.GetAccesser().GetAccesserDeviceId() == localDeviceId) {
sinkBindType.push_back(APP_PEER_TO_PEER_TYPE);
bindTypeIndex.push_back(index);
}
}
}
if (profiles.GetBindType() == DM_ACROSS_ACCOUNT) {
if (profiles.GetBindLevel() == USER) {
sinkBindType.push_back(DmDevBindType::DEVICE_ACROSS_ACCOUNT_BIND_TYPE);
bindTypeIndex.push_back(index);
}
if (profiles.GetBindLevel() == APP) {
if (profiles.GetAccesser().GetAccesserDeviceId() == targetDeviceId &&
profiles.GetAccessee().GetAccesseeDeviceId() == localDeviceId) {
sinkBindType.push_back(APP_ACROSS_ACCOUNT_TYPE);
bindTypeIndex.push_back(index);
}
if (profiles.GetAccessee().GetAccesseeDeviceId() == targetDeviceId &&
profiles.GetAccesser().GetAccesserDeviceId() == localDeviceId) {
sinkBindType.push_back(APP_ACROSS_ACCOUNT_TYPE);
bindTypeIndex.push_back(index);
}
}
}
}
DM_EXPORT std::vector<int32_t> DeviceProfileConnector::SyncAclByBindType(
std::string pkgName, std::vector<int32_t> bindTypeVec, std::string localDeviceId, std::string targetDeviceId)
{
std::vector<AccessControlProfile> profiles =
GetAccessControlProfileByUserId(MultipleUserConnector::GetFirstForegroundUserId());
LOGI("AccessControlProfile size is %{public}zu", profiles.size());
std::vector<int32_t> sinkBindType;
std::vector<int32_t> bindType;
std::vector<int32_t> bindTypeIndex =
CompareBindType(profiles, pkgName, sinkBindType, localDeviceId, targetDeviceId);
LOGI("sinkBindType size is %{public}zu", sinkBindType.size());
for (uint32_t sinkIndex = 0; sinkIndex < sinkBindType.size(); sinkIndex++) {
bool deleteAclFlag = true;
for (uint32_t srcIndex = 0; srcIndex < bindTypeVec.size(); srcIndex++) {
if (sinkBindType[sinkIndex] == bindTypeVec[srcIndex]) {
deleteAclFlag = false;
bindType.push_back(bindTypeVec[srcIndex]);
}
}
if (deleteAclFlag) {
int32_t deleteIndex = profiles[bindTypeIndex[sinkIndex]].GetAccessControlId();
DistributedDeviceProfileClient::GetInstance().DeleteAccessControlProfile(deleteIndex);
LOGI("deleteAcl index is %{public}d", deleteIndex);
}
}
return bindType;
}
DM_EXPORT std::vector<OHOS::DistributedHardware::ProcessInfo> DeviceProfileConnector::GetProcessInfoFromAclByUserId(
const std::string &localDeviceId, const std::string &targetDeviceId, int32_t userId)
{
std::vector<AccessControlProfile> filterProfiles = GetAclProfileByUserId(localDeviceId,
userId, targetDeviceId);
LOGI("filterProfiles size is %{public}zu", filterProfiles.size());
std::vector<OHOS::DistributedHardware::ProcessInfo> processInfoVec;
for (auto &item : filterProfiles) {
if (IsLnnAcl(item) || item.GetTrustDeviceId() != targetDeviceId) {
continue;
}
std::string accesserUdid = item.GetAccesser().GetAccesserDeviceId();
std::string accesseeUdid = item.GetAccessee().GetAccesseeDeviceId();
OHOS::DistributedHardware::ProcessInfo processInfo;
std::string extraStr;
if (accesserUdid == localDeviceId) {
processInfo.pkgName = item.GetAccesser().GetAccesserBundleName();
processInfo.userId = item.GetAccesser().GetAccesserUserId();
processInfo.tokenId = static_cast<uint32_t>(item.GetAccesser().GetAccesserTokenId());
processInfoVec.push_back(processInfo);
extraStr = item.GetAccesser().GetAccesserExtraData();
} else if (accesseeUdid == localDeviceId) {
processInfo.pkgName = item.GetAccessee().GetAccesseeBundleName();
processInfo.userId = item.GetAccessee().GetAccesseeUserId();
processInfo.tokenId = static_cast<uint32_t>(item.GetAccessee().GetAccesseeTokenId());
processInfoVec.push_back(processInfo);
extraStr = item.GetAccessee().GetAccesseeExtraData();
} else {
continue;
}
std::vector<int64_t> proxyTokenIdVec = JsonStrHandle::GetInstance().GetProxyTokenIdByExtra(extraStr);
for (auto &proxyTokenId : proxyTokenIdVec) {
std::string proxyBundleName;
if (AppManager::GetInstance().GetBundleNameByTokenId(proxyTokenId, proxyBundleName) != DM_OK) {
continue;
}
processInfo.pkgName = proxyBundleName;
processInfoVec.push_back(processInfo);
}
}
return processInfoVec;
}
DM_EXPORT AccessControlProfile DeviceProfileConnector::GetAccessControlProfileByAccessControlId(
int64_t accessControlId)
{
AccessControlProfile profile;
profile.SetAccessControlId(0);
std::vector<AccessControlProfile> profiles = GetAllAclIncludeLnnAcl();
for (auto &item : profiles) {
if (item.GetAccessControlId() == accessControlId) {
return item;
}
}
return profile;
}
DM_EXPORT std::vector<std::pair<int64_t, int64_t>> DeviceProfileConnector::GetAgentToProxyVecFromAclByUserId(
const std::string &localDeviceId, const std::string &targetDeviceId, int32_t userId)
{
std::vector<AccessControlProfile> filterProfiles = GetAclProfileByUserId(localDeviceId,
userId, targetDeviceId);
LOGI("filterProfiles size is %{public}zu", filterProfiles.size());
std::vector<std::pair<int64_t, int64_t>> agentToProxyVec;
for (auto &item : filterProfiles) {
if (IsLnnAcl(item) || item.GetTrustDeviceId() != targetDeviceId) {
continue;
}
std::string accesserUdid = item.GetAccesser().GetAccesserDeviceId();
std::string accesseeUdid = item.GetAccessee().GetAccesseeDeviceId();
int64_t agentTokenId;
std::string extraStr;
if (accesserUdid == localDeviceId) {
agentTokenId = item.GetAccesser().GetAccesserTokenId();
extraStr = item.GetAccesser().GetAccesserExtraData();
} else if (accesseeUdid == localDeviceId) {
agentTokenId = item.GetAccessee().GetAccesseeTokenId();
extraStr = item.GetAccessee().GetAccesseeExtraData();
} else {
continue;
}
std::vector<int64_t> proxyTokenIdVec = JsonStrHandle::GetInstance().GetProxyTokenIdByExtra(extraStr);
for (auto &proxyTokenId : proxyTokenIdVec) {
agentToProxyVec.push_back(std::pair<int64_t, int64_t>(agentTokenId, proxyTokenId));
}
}
return agentToProxyVec;
}
int32_t DeviceProfileConnector::PutAccessControlList(DmAclInfo aclInfo, DmAccesser dmAccesser, DmAccessee dmAccessee)
{
LOGI("Start.");
Accesser accesser;
accesser.SetAccesserDeviceId(dmAccesser.requestDeviceId);
accesser.SetAccesserUserId(dmAccesser.requestUserId);
accesser.SetAccesserAccountId(dmAccesser.requestAccountId);
accesser.SetAccesserTokenId(dmAccesser.requestTokenId);
accesser.SetAccesserBundleName(dmAccesser.requestBundleName);
accesser.SetAccesserDeviceName(dmAccesser.requestDeviceName);
Accessee accessee;
accessee.SetAccesseeDeviceId(dmAccessee.trustDeviceId);
accessee.SetAccesseeUserId(dmAccessee.trustUserId);
accessee.SetAccesseeAccountId(dmAccessee.trustAccountId);
accessee.SetAccesseeTokenId(dmAccessee.trustTokenId);
accessee.SetAccesseeBundleName(dmAccessee.trustBundleName);
accessee.SetAccesseeDeviceName(dmAccessee.trustDeviceName);
AccessControlProfile profile;
profile.SetBindType(aclInfo.bindType);
profile.SetBindLevel(aclInfo.bindLevel);
profile.SetStatus(ACTIVE);
profile.SetTrustDeviceId(aclInfo.trustDeviceId);
profile.SetDeviceIdType((int32_t)DeviceIdType::UDID);
profile.SetDeviceIdHash(aclInfo.deviceIdHash);
profile.SetAuthenticationType(aclInfo.authenticationType);
profile.SetAccessee(accessee);
profile.SetAccesser(accesser);
int32_t ret = DistributedDeviceProfileClient::GetInstance().PutAccessControlProfile(profile);
if (ret != DM_OK) {
LOGE("PutAccessControlProfile failed.");
}
return ret;
}
DM_EXPORT bool DeviceProfileConnector::DeleteAclForAccountLogOut(
const DMAclQuadInfo &info, const std::string &accountId, DmOfflineParam &offlineParam,
std::vector<DmUserRemovedServiceInfo> &serviceInfos)
{
LOGI("localUdid %{public}s, localUserId %{public}d, peerUdid %{public}s, peerUserId %{public}d.",
GetAnonyString(info.localUdid).c_str(), info.localUserId, GetAnonyString(info.peerUdid).c_str(),
info.peerUserId);
std::vector<AccessControlProfile> profiles = GetAllAclIncludeLnnAcl();
bool notifyOffline = false;
for (const auto &item : profiles) {
if (item.GetTrustDeviceId() != info.peerUdid) {
continue;
}
std::string accesserUdid = item.GetAccesser().GetAccesserDeviceId();
int32_t accesserUserId = item.GetAccesser().GetAccesserUserId();
std::string accesseeUdid = item.GetAccessee().GetAccesseeDeviceId();
int32_t accesseeUserId = item.GetAccessee().GetAccesseeUserId();
std::string accesserAccountId = item.GetAccesser().GetAccesserAccountId();
std::string accesseeAccountId = item.GetAccessee().GetAccesseeAccountId();
if (accesserUdid == info.localUdid && accesserUserId == info.localUserId &&
accesseeUdid == info.peerUdid && accesseeUserId == info.peerUserId &&
accesserAccountId == accountId) {
ProcessLocalAccessRemote(item, info, accountId, offlineParam, serviceInfos, notifyOffline);
continue;
}
if (accesserUdid == info.peerUdid && accesserUserId == info.peerUserId &&
accesseeUdid == info.localUdid && accesseeUserId == info.localUserId &&
accesseeAccountId == accountId) {
ProcessRemoteAccessLocal(item, info, accountId, offlineParam, serviceInfos, notifyOffline);
continue;
}
}
return notifyOffline;
}
void DeviceProfileConnector::ProcessLocalAccessRemote(
const AccessControlProfile &item, const DMAclQuadInfo &info, const std::string &accountId,
DmOfflineParam &offlineParam, std::vector<DmUserRemovedServiceInfo> &serviceInfos, bool ¬ifyOffline)
{
offlineParam.bindType = item.GetBindType();
SetProcessInfoPkgName(item, offlineParam.processVec, true);
notifyOffline = (item.GetStatus() == ACTIVE);
CacheAcerAclId(item, offlineParam.needDelAclInfos);
if (IsLnnAcl(item)) {
return;
}
if (FillDmUserRemovedServiceInfoRemote(item, serviceInfos) != DM_OK) {
return;
}
}
void DeviceProfileConnector::ProcessRemoteAccessLocal(
const AccessControlProfile &item, const DMAclQuadInfo &info, const std::string &accountId,
DmOfflineParam &offlineParam, std::vector<DmUserRemovedServiceInfo> &serviceInfos, bool ¬ifyOffline)
{
offlineParam.bindType = item.GetBindType();
SetProcessInfoPkgName(item, offlineParam.processVec, false);
notifyOffline = (item.GetStatus() == ACTIVE);
CacheAceeAclId(item, offlineParam.needDelAclInfos);
if (IsLnnAcl(item)) {
return;
}
FillDmUserRemovedServiceInfoLocal(item, serviceInfos);
}
DM_EXPORT bool DeviceProfileConnector::DeleteAclByActhash(
const DMAclQuadInfo &info, const std::string &accountIdHash, DmOfflineParam &offlineParam,
std::vector<DmUserRemovedServiceInfo> &serviceInfos)
{
LOGI("localUdid %{public}s, localUserId %{public}d, peerUdid %{public}s, peerUserId %{public}d.",
GetAnonyString(info.localUdid).c_str(), info.localUserId, GetAnonyString(info.peerUdid).c_str(),
info.peerUserId);
std::vector<AccessControlProfile> profiles = GetAllAclIncludeLnnAcl();
bool notifyOffline = false;
for (const auto &item : profiles) {
if (item.GetTrustDeviceId() != info.peerUdid) {
continue;
}
DmCacheOfflineInputParam inputParam;
inputParam.profile = item;
inputParam.info = info;
inputParam.accountIdHash = accountIdHash;
CacheOfflineParam(inputParam, offlineParam, notifyOffline, serviceInfos);
}
return notifyOffline;
}
void DeviceProfileConnector::CacheOfflineParam(const DmCacheOfflineInputParam &inputParam,
DmOfflineParam &offlineParam, bool ¬ifyOffline, std::vector<DmUserRemovedServiceInfo> &serviceInfos)
{
LOGI("start.");
DistributedDeviceProfile::AccessControlProfile profile = inputParam.profile;
DMAclQuadInfo info = inputParam.info;
std::string accountIdHash = inputParam.accountIdHash;
std::string accesserUdid = profile.GetAccesser().GetAccesserDeviceId();
std::string accesseeUdid = profile.GetAccessee().GetAccesseeDeviceId();
int32_t accesserUserId = profile.GetAccesser().GetAccesserUserId();
int32_t accesseeUserId = profile.GetAccessee().GetAccesseeUserId();
std::string accesserAccountId = profile.GetAccesser().GetAccesserAccountId();
std::string accesseeAccountId = profile.GetAccessee().GetAccesseeAccountId();
char accesserAccountIdHash[DM_MAX_DEVICE_ID_LEN] = {0};
if (Crypto::GetAccountIdHash(accesserAccountId, reinterpret_cast<uint8_t *>(accesserAccountIdHash)) != DM_OK) {
LOGE("GetAccountHash failed.");
return;
}
char accesseeAccountIdHash[DM_MAX_DEVICE_ID_LEN] = {0};
if (Crypto::GetAccountIdHash(accesseeAccountId, reinterpret_cast<uint8_t *>(accesseeAccountIdHash)) != DM_OK) {
LOGE("GetAccountHash failed.");
return;
}
if (accesserUdid == info.localUdid && accesserUserId == info.localUserId &&
accesseeUdid == info.peerUdid && accesseeUserId == info.peerUserId &&
std::string(accesseeAccountIdHash) == accountIdHash) {
ProcessLocalToPeer(profile, info, accountIdHash, offlineParam, notifyOffline, serviceInfos);
return;
}
if (accesserUdid == info.peerUdid && accesserUserId == info.peerUserId &&
accesseeUdid == info.localUdid && accesseeUserId == info.localUserId &&
std::string(accesserAccountIdHash) == accountIdHash) {
ProcessPeerToLocal(profile, info, accountIdHash, offlineParam, notifyOffline, serviceInfos);
return;
}
}
void DeviceProfileConnector::ProcessLocalToPeer(
const DistributedDeviceProfile::AccessControlProfile &profile, const DMAclQuadInfo &info,
const std::string &accountIdHash, DmOfflineParam &offlineParam, bool ¬ifyOffline,
std::vector<DmUserRemovedServiceInfo> &serviceInfos)
{
offlineParam.bindType = profile.GetBindType();
SetProcessInfoPkgName(profile, offlineParam.processVec, true);
notifyOffline = (profile.GetStatus() == ACTIVE);
CacheAcerAclId(profile, offlineParam.needDelAclInfos);
if (IsLnnAcl(profile)) {
return;
}
if (FillDmUserRemovedServiceInfoRemote(profile, serviceInfos) != DM_OK) {
return;
}
}
void DeviceProfileConnector::ProcessPeerToLocal(
const DistributedDeviceProfile::AccessControlProfile &profile, const DMAclQuadInfo &info,
const std::string &accountIdHash, DmOfflineParam &offlineParam, bool ¬ifyOffline,
std::vector<DmUserRemovedServiceInfo> &serviceInfos)
{
offlineParam.bindType = profile.GetBindType();
SetProcessInfoPkgName(profile, offlineParam.processVec, false);
notifyOffline = (profile.GetStatus() == ACTIVE);
CacheAceeAclId(profile, offlineParam.needDelAclInfos);
if (IsLnnAcl(profile)) {
return;
}
FillDmUserRemovedServiceInfoLocal(profile, serviceInfos);
}
void DeviceProfileConnector::SaveInvalidSkIdAcl(const DistributedDeviceProfile::AccessControlProfile &acl,
std::map<std::string, DmOfflineParam> &invalidAclMap, bool isLocalAccer, DmOfflineParam &dmParam)
{
std::string acerUdid = acl.GetAccesser().GetAccesserDeviceId();
std::string aceeUdid = acl.GetAccessee().GetAccesseeDeviceId();
if (isLocalAccer) {
if (invalidAclMap.find(aceeUdid) != invalidAclMap.end()) {
CacheAcerAclId(acl, invalidAclMap[aceeUdid].needDelAclInfos);
FindLeftAcl(acl, acerUdid, aceeUdid, invalidAclMap[aceeUdid]);
FindUserAcl(acl, acerUdid, aceeUdid, invalidAclMap[aceeUdid]);
FindLnnAcl(acl, acerUdid, aceeUdid, invalidAclMap[aceeUdid]);
} else {
CacheAcerAclId(acl, dmParam.needDelAclInfos);
FindLeftAcl(acl, acerUdid, aceeUdid, dmParam);
FindUserAcl(acl, acerUdid, aceeUdid, dmParam);
FindLnnAcl(acl, acerUdid, aceeUdid, dmParam);
invalidAclMap.insert(std::pair<std::string, DmOfflineParam>(aceeUdid, dmParam));
}
} else {
if (invalidAclMap.find(acerUdid) != invalidAclMap.end()) {
CacheAceeAclId(acl, invalidAclMap[acerUdid].needDelAclInfos);
FindLeftAcl(acl, aceeUdid, acerUdid, invalidAclMap[acerUdid]);
FindUserAcl(acl, aceeUdid, acerUdid, invalidAclMap[acerUdid]);
FindLnnAcl(acl, aceeUdid, acerUdid, invalidAclMap[acerUdid]);
} else {
CacheAceeAclId(acl, dmParam.needDelAclInfos);
FindLeftAcl(acl, aceeUdid, acerUdid, dmParam);
FindUserAcl(acl, aceeUdid, acerUdid, dmParam);
FindLnnAcl(acl, aceeUdid, acerUdid, dmParam);
invalidAclMap.insert(std::pair<std::string, DmOfflineParam>(acerUdid, dmParam));
}
}
}
bool DeviceProfileConnector::SaveInvalidAclMap(const DistributedDeviceProfile::AccessControlProfile &acl,
bool isLocalAccer, DmOfflineParam &dmParam, std::set<int32_t> &invalidSkIdSet,
std::map<std::string, DmOfflineParam> &invalidAclMap)
{
int32_t skId = -1;
int32_t userId = -1;
if (isLocalAccer) {
skId = acl.GetAccesser().GetAccesserSessionKeyId();
userId = acl.GetAccesser().GetAccesserUserId();
} else {
skId = acl.GetAccessee().GetAccesseeSessionKeyId();
userId = acl.GetAccessee().GetAccesseeUserId();
}
if (invalidSkIdSet.find(skId) != invalidSkIdSet.end()) {
PrintProfile(acl);
SaveInvalidSkIdAcl(acl, invalidAclMap, isLocalAccer, dmParam);
return true;
}
std::vector<unsigned char> sessionKey;
int32_t ret = GetSessionKey(userId, skId, sessionKey);
if (ret != DM_OK || sessionKey.empty()) {
LOGE("GetSessionKey failed ret:%{public}d", ret);
PrintProfile(acl);
SaveInvalidSkIdAcl(acl, invalidAclMap, isLocalAccer, dmParam);
invalidSkIdSet.insert(skId);
return true;
}
return false;
}
DM_EXPORT void DeviceProfileConnector::GetInvalidSkIdAcl(std::map<std::string, DmOfflineParam> &invalidAclMap)
{
std::vector<AccessControlProfile> profiles = GetAllAclIncludeLnnAcl();
std::set<int32_t> invalidSkIdSet;
int32_t localUserId = MultipleUserConnector::TryGetCurrentAccountUserID();
if (localUserId == -1) {
LOGE("get current userId failed");
return;
}
std::string localUdid = GetLocalDeviceId();
for (auto &item : profiles) {
if (item.GetBindType() == DM_IDENTICAL_ACCOUNT) {
continue;
}
DmOfflineParam dmParam;
std::string acerUdid = item.GetAccesser().GetAccesserDeviceId();
int32_t acerUserId = item.GetAccesser().GetAccesserUserId();
if (acerUdid == localUdid && localUserId == acerUserId) {
LOGI("is src");
if (SaveInvalidAclMap(item, true, dmParam, invalidSkIdSet, invalidAclMap)) {
continue;
}
}
std::string aceeUdid = item.GetAccessee().GetAccesseeDeviceId();
int32_t aceeUserId = item.GetAccessee().GetAccesseeUserId();
if (aceeUdid == localUdid && localUserId == aceeUserId) {
LOGI("is sink");
if (SaveInvalidAclMap(item, false, dmParam, invalidSkIdSet, invalidAclMap)) {
continue;
}
}
}
}
DM_EXPORT void DeviceProfileConnector::DeleteAclForUserRemoved(const DmLocalUserRemovedInfo &userRemovedInfo,
std::multimap<std::string, int32_t> &peerUserIdMap, DmOfflineParam &offlineParam,
std::vector<DmUserRemovedServiceInfo> &serviceInfos)
{
std::vector<AccessControlProfile> profiles = GetAllAclIncludeLnnAcl();
for (const auto &item : profiles) {
if (find(userRemovedInfo.peerUdids.begin(), userRemovedInfo.peerUdids.end(),
item.GetTrustDeviceId()) == userRemovedInfo.peerUdids.end()) {
continue;
}
std::string accesserUdid = item.GetAccesser().GetAccesserDeviceId();
std::string accesseeUdid = item.GetAccessee().GetAccesseeDeviceId();
int32_t accesserUserId = item.GetAccesser().GetAccesserUserId();
int32_t accesseeUserId = item.GetAccessee().GetAccesseeUserId();
if (accesserUdid == userRemovedInfo.localUdid && accesserUserId == userRemovedInfo.preUserId) {
if (!IsValueExist(peerUserIdMap, accesseeUdid, accesseeUserId)) {
peerUserIdMap.insert(std::pair<std::string, int32_t>(accesseeUdid, accesseeUserId));
}
CacheAcerAclId(item, offlineParam.needDelAclInfos);
if (IsLnnAcl(item)) {
continue;
}
if (FillDmUserRemovedServiceInfoRemote(item, serviceInfos) != DM_OK) {
continue;
}
continue;
}
if (accesseeUdid == userRemovedInfo.localUdid && accesseeUserId == userRemovedInfo.preUserId) {
if (!IsValueExist(peerUserIdMap, accesserUdid, accesserUserId)) {
peerUserIdMap.insert(std::pair<std::string, int32_t>(accesserUdid, accesserUserId));
}
CacheAceeAclId(item, offlineParam.needDelAclInfos);
if (IsLnnAcl(item)) {
continue;
}
FillDmUserRemovedServiceInfoLocal(item, serviceInfos);
continue;
}
}
}
DM_EXPORT void DeviceProfileConnector::DeleteAclForRemoteUserRemoved(
DmRemoteUserRemovedInfo &userRemovedInfo, DmOfflineParam &offlineParam,
std::vector<DmUserRemovedServiceInfo> &serviceInfos)
{
LOGI("peerUdid %{public}s, peerUserId %{public}d.", GetAnonyString(userRemovedInfo.peerUdid).c_str(),
userRemovedInfo.peerUserId);
std::vector<AccessControlProfile> profiles = GetAllAclIncludeLnnAcl();
for (const auto &item : profiles) {
std::string accesserUdid = item.GetAccesser().GetAccesserDeviceId();
std::string accesseeUdid = item.GetAccessee().GetAccesseeDeviceId();
int32_t accesserUserId = item.GetAccesser().GetAccesserUserId();
int32_t accesseeUserId = item.GetAccessee().GetAccesseeUserId();
if (accesserUdid == userRemovedInfo.peerUdid && accesserUserId == userRemovedInfo.peerUserId) {
if (item.GetBindLevel() == USER) {
userRemovedInfo.localUserIds.push_back(accesseeUserId);
}
CacheAceeAclId(item, offlineParam.needDelAclInfos);
if (IsLnnAcl(item)) {
continue;
}
FillDmUserRemovedServiceInfoLocal(item, serviceInfos);
continue;
}
if (accesseeUdid == userRemovedInfo.peerUdid && accesseeUserId == userRemovedInfo.peerUserId) {
if (item.GetBindLevel() == USER) {
userRemovedInfo.localUserIds.push_back(accesserUserId);
}
CacheAcerAclId(item, offlineParam.needDelAclInfos);
if (IsLnnAcl(item)) {
continue;
}
if (FillDmUserRemovedServiceInfoRemote(item, serviceInfos) != DM_OK) {
continue;
}
}
}
}
DM_EXPORT void DeviceProfileConnector::DeleteAccessControlList(const std::string &udid)
{
LOGI("Udid: %{public}s.", GetAnonyString(udid).c_str());
if (udid.empty()) {
LOGE("udid is empty.");
return;
}
std::vector<AccessControlProfile> profiles = GetAccessControlProfile();
LOGI("Size is %{public}zu", profiles.size());
for (const auto &item : profiles) {
if (item.GetTrustDeviceId() == udid) {
DistributedDeviceProfileClient::GetInstance().DeleteAccessControlProfile(item.GetAccessControlId());
}
}
}
DM_EXPORT DmOfflineParam DeviceProfileConnector::FilterNeedDeleteACL(const std::string &peerUdid)
{
std::string localUdid = GetLocalDeviceId();
LOGI("localUdid %{public}s, peerUdid %{public}s",
GetAnonyString(localUdid).c_str(), GetAnonyString(peerUdid).c_str());
DmOfflineParam offlineParam;
int32_t userId = MultipleUserConnector::GetCurrentAccountUserID();
std::vector<AccessControlProfile> profiles = GetAclProfileByDeviceIdAndUserId(localUdid, userId,
peerUdid);
if (profiles.empty()) {
LOGE("Acl is empty.");
return offlineParam;
}
FilterNeedDeleteACLInfos(profiles, localUdid, peerUdid, offlineParam);
return offlineParam;
}
bool DeviceProfileConnector::IsAuthNewVersion(const DistributedDeviceProfile::AccessControlProfile &acl,
const std::string localUdid, const std::string remoteUdid)
{
std::string extraInfo = GetAclVersionInfo(localUdid, remoteUdid, acl);
JsonObject extraInfoJson(extraInfo);
if (extraInfoJson.IsDiscarded()) {
LOGE("extraInfoJson error");
return false;
}
if (!extraInfoJson[TAG_DMVERSION].IsString()) {
LOGE("PARAM_KEY_OS_VERSION error");
return false;
}
std::string dmVersion = extraInfoJson[TAG_DMVERSION].Get<std::string>();
if (CompareVersion(dmVersion, std::string(DM_VERSION_5_1_0)) || dmVersion == std::string(DM_VERSION_5_1_0)) {
return true;
}
return false;
}
void DeviceProfileConnector::FilterNeedDeleteACLInfos(
std::vector<DistributedDeviceProfile::AccessControlProfile> &profiles,
const std::string &localUdid, const std::string &peerUdid, DmOfflineParam &offlineParam)
{
for (auto &item : profiles) {
if (item.GetTrustDeviceId() != peerUdid) {
continue;
}
bool isNewVersion = IsAuthNewVersion(item, localUdid, peerUdid);
offlineParam.isNewVersion = isNewVersion;
if (isNewVersion && FindTargetAclIncludeLnn(item, localUdid, peerUdid, offlineParam)) {
continue;
}
if (!isNewVersion && FindTargetAclIncludeLnnOld(item, localUdid, peerUdid, offlineParam)) {
continue;
}
}
}
bool DeviceProfileConnector::FindTargetAclIncludeLnn(const DistributedDeviceProfile::AccessControlProfile &acl,
const std::string &localUdid, const std::string &remoteUdid, DmOfflineParam &offlineParam)
{
bool isMatch = false;
if (acl.GetAccesser().GetAccesserDeviceId() == remoteUdid &&
acl.GetAccessee().GetAccesseeDeviceId() == localUdid) {
if (!IsLnnAcl(acl) && (acl.GetBindLevel() == USER || acl.GetBindType() == DM_IDENTICAL_ACCOUNT)) {
offlineParam.hasUserAcl = true;
}
if (!IsLnnAcl(acl)) {
ProcessInfo processInfo;
processInfo.pkgName = acl.GetAccessee().GetAccesseeBundleName();
processInfo.userId = acl.GetAccessee().GetAccesseeUserId();
offlineParam.processVec.push_back(processInfo);
}
CacheAceeAclId(acl, offlineParam.needDelAclInfos);
LOGI("Src del acl aclId: %{public}" PRId64 ", localUdid %{public}s, remoteUdid %{public}s"
", bindType %{public}d, bindLevel: %{public}d", acl.GetAccessControlId(),
GetAnonyString(localUdid).c_str(), GetAnonyString(remoteUdid).c_str(), acl.GetBindType(),
acl.GetBindLevel());
isMatch = true;
}
if (acl.GetAccessee().GetAccesseeDeviceId() == remoteUdid &&
acl.GetAccesser().GetAccesserDeviceId() == localUdid) {
if (!IsLnnAcl(acl) && (acl.GetBindLevel() == USER || acl.GetBindType() == DM_IDENTICAL_ACCOUNT)) {
offlineParam.hasUserAcl = true;
}
if (!IsLnnAcl(acl)) {
ProcessInfo processInfo;
processInfo.pkgName = acl.GetAccesser().GetAccesserBundleName();
processInfo.userId = acl.GetAccesser().GetAccesserUserId();
offlineParam.processVec.push_back(processInfo);
}
CacheAcerAclId(acl, offlineParam.needDelAclInfos);
LOGI("Sink del acl aclId: %{public}" PRId64 ", localUdid %{public}s, remoteUdid %{public}s"
", bindType %{public}d, bindLevel: %{public}d", acl.GetAccessControlId(),
GetAnonyString(localUdid).c_str(), GetAnonyString(remoteUdid).c_str(), acl.GetBindType(),
acl.GetBindLevel());
isMatch = true;
}
return isMatch;
}
bool DeviceProfileConnector::FindTargetAclIncludeLnnOld(const DistributedDeviceProfile::AccessControlProfile &acl,
const std::string &localUdid, const std::string &remoteUdid, DmOfflineParam &offlineParam)
{
bool isMatch = false;
if (acl.GetAccesser().GetAccesserDeviceId() == remoteUdid &&
acl.GetAccessee().GetAccesseeDeviceId() == localUdid) {
if ((acl.GetBindLevel() == USER || acl.GetBindType() == DM_IDENTICAL_ACCOUNT)) {
offlineParam.hasUserAcl = true;
}
ProcessInfo processInfo;
processInfo.pkgName = acl.GetAccessee().GetAccesseeBundleName();
processInfo.userId = acl.GetAccessee().GetAccesseeUserId();
offlineParam.processVec.push_back(processInfo);
offlineParam.peerUserId = acl.GetAccesser().GetAccesserUserId();
CacheAceeAclId(acl, offlineParam.needDelAclInfos);
LOGI("Src del acl aclId: %{public}" PRId64 ", localUdid %{public}s, remoteUdid %{public}s"
", bindType %{public}d, bindLevel: %{public}d", acl.GetAccessControlId(),
GetAnonyString(localUdid).c_str(), GetAnonyString(remoteUdid).c_str(), acl.GetBindType(),
acl.GetBindLevel());
isMatch = true;
}
if (acl.GetAccessee().GetAccesseeDeviceId() == remoteUdid &&
acl.GetAccesser().GetAccesserDeviceId() == localUdid) {
if ((acl.GetBindLevel() == USER || acl.GetBindType() == DM_IDENTICAL_ACCOUNT)) {
offlineParam.hasUserAcl = true;
}
ProcessInfo processInfo;
processInfo.pkgName = acl.GetAccesser().GetAccesserBundleName();
processInfo.userId = acl.GetAccesser().GetAccesserUserId();
offlineParam.processVec.push_back(processInfo);
offlineParam.peerUserId = acl.GetAccessee().GetAccesseeUserId();
CacheAcerAclId(acl, offlineParam.needDelAclInfos);
LOGI("Sink del acl aclId: %{public}" PRId64 ", localUdid %{public}s, remoteUdid %{public}s"
", bindType %{public}d, bindLevel: %{public}d", acl.GetAccessControlId(),
GetAnonyString(localUdid).c_str(), GetAnonyString(remoteUdid).c_str(), acl.GetBindType(),
acl.GetBindLevel());
isMatch = true;
}
return isMatch;
}
DmOfflineParam DeviceProfileConnector::DeleteAccessControlList(const std::string &pkgName,
const std::string &localDeviceId, const std::string &remoteDeviceId,
int32_t bindLevel, const std::string &extra)
{
LOGI("pkgName %{public}s, localDeviceId %{public}s, remoteDeviceId %{public}s, bindLevel %{public}d.",
pkgName.c_str(), GetAnonyString(localDeviceId).c_str(), GetAnonyString(remoteDeviceId).c_str(), bindLevel);
DmOfflineParam offlineParam;
offlineParam.bindType = INVALIED_TYPE;
if (static_cast<uint32_t>(bindLevel) > APP || static_cast<uint32_t>(bindLevel) < USER) {
LOGE("Invalied bindlevel.");
return offlineParam;
}
std::vector<AccessControlProfile> profiles = GetAclProfileByDeviceIdAndUserId(localDeviceId,
MultipleUserConnector::GetFirstForegroundUserId());
if (profiles.empty()) {
LOGE("Acl is empty.");
return offlineParam;
}
switch (bindLevel) {
case APP:
if (extra == "") {
DeleteAppBindLevel(offlineParam, pkgName, profiles, localDeviceId, remoteDeviceId);
} else {
DeleteAppBindLevel(offlineParam, pkgName, profiles, localDeviceId, remoteDeviceId, extra);
}
break;
case SERVICE:
DeleteServiceBindLevel(offlineParam, pkgName, profiles, localDeviceId, remoteDeviceId);
break;
case USER:
DeleteDeviceBindLevel(offlineParam, profiles, localDeviceId, remoteDeviceId);
break;
default:
break;
}
return offlineParam;
}
void DeviceProfileConnector::DeleteAppBindLevel(DmOfflineParam &offlineParam, const std::string &pkgName,
const std::vector<AccessControlProfile> &profiles, const std::string &localUdid, const std::string &remoteUdid)
{
int32_t bindNums = 0;
int32_t deleteNums = 0;
for (auto &item : profiles) {
if (item.GetTrustDeviceId() != remoteUdid || item.GetBindType() == DM_IDENTICAL_ACCOUNT ||
item.GetBindLevel() != APP) {
continue;
}
bindNums++;
if (item.GetAccesser().GetAccesserBundleName() == pkgName &&
item.GetAccesser().GetAccesserDeviceId() == localUdid &&
item.GetAccessee().GetAccesseeDeviceId() == remoteUdid) {
DistributedDeviceProfileClient::GetInstance().DeleteAccessControlProfile(item.GetAccessControlId());
deleteNums++;
offlineParam.bindType = APP;
ProcessInfo processInfo;
processInfo.pkgName = item.GetAccesser().GetAccesserBundleName();
processInfo.userId = item.GetAccesser().GetAccesserUserId();
offlineParam.processVec.push_back(processInfo);
offlineParam.peerUserId = item.GetAccessee().GetAccesseeUserId();
LOGI("Src delete acl pkgName %{public}s, bindType %{public}d, localUdid %{public}s, remoteUdid %{public}s",
pkgName.c_str(), item.GetBindType(), GetAnonyString(localUdid).c_str(),
GetAnonyString(remoteUdid).c_str());
continue;
}
if (item.GetAccessee().GetAccesseeBundleName() == pkgName &&
item.GetAccessee().GetAccesseeDeviceId() == localUdid &&
item.GetAccesser().GetAccesserDeviceId() == remoteUdid) {
DistributedDeviceProfileClient::GetInstance().DeleteAccessControlProfile(item.GetAccessControlId());
deleteNums++;
offlineParam.bindType = APP;
ProcessInfo processInfo;
processInfo.pkgName = item.GetAccessee().GetAccesseeBundleName();
processInfo.userId = item.GetAccessee().GetAccesseeUserId();
offlineParam.processVec.push_back(processInfo);
offlineParam.peerUserId = item.GetAccesser().GetAccesserUserId();
LOGI("Sink delete acl pkgName %{public}s, bindType %{public}u, localUdid %{public}s, remoteUdid %{public}s",
pkgName.c_str(), item.GetBindType(), GetAnonyString(localUdid).c_str(),
GetAnonyString(remoteUdid).c_str());
continue;
}
}
offlineParam.leftAclNumber = bindNums - deleteNums;
}
void DeviceProfileConnector::DeleteAppBindLevel(DmOfflineParam &offlineParam, const std::string &pkgName,
const std::vector<AccessControlProfile> &profiles, const std::string &localUdid,
const std::string &remoteUdid, const std::string &extra)
{
int32_t bindNums = 0;
int32_t deleteNums = 0;
uint64_t peerTokenId = 0;
std::string peerBundleName;
JsonStrHandle::GetInstance().GetPeerAppInfoParseExtra(extra, peerTokenId, peerBundleName);
LOGI("peerBundleName %{public}s", peerBundleName.c_str());
for (auto &item : profiles) {
if (item.GetTrustDeviceId() != remoteUdid || item.GetBindType() == DM_IDENTICAL_ACCOUNT ||
item.GetBindLevel() != APP) {
continue;
}
bindNums++;
if (item.GetAccesser().GetAccesserBundleName() == pkgName &&
item.GetAccessee().GetAccesseeBundleName() == peerBundleName &&
item.GetAccesser().GetAccesserDeviceId() == localUdid &&
item.GetAccessee().GetAccesseeDeviceId() == remoteUdid) {
DistributedDeviceProfileClient::GetInstance().DeleteAccessControlProfile(item.GetAccessControlId());
deleteNums++;
offlineParam.bindType = APP;
ProcessInfo processInfo;
processInfo.pkgName = item.GetAccesser().GetAccesserBundleName();
processInfo.userId = item.GetAccesser().GetAccesserUserId();
offlineParam.processVec.push_back(processInfo);
offlineParam.peerUserId = item.GetAccessee().GetAccesseeUserId();
LOGI("Src delete acl pkgName %{public}s, bindType %{public}d, localUdid %{public}s, remoteUdid %{public}s",
pkgName.c_str(), item.GetBindType(), GetAnonyString(localUdid).c_str(),
GetAnonyString(remoteUdid).c_str());
continue;
}
if (item.GetAccessee().GetAccesseeBundleName() == pkgName &&
item.GetAccesser().GetAccesserBundleName() == peerBundleName &&
item.GetAccessee().GetAccesseeDeviceId() == localUdid &&
item.GetAccesser().GetAccesserDeviceId() == remoteUdid) {
DistributedDeviceProfileClient::GetInstance().DeleteAccessControlProfile(item.GetAccessControlId());
deleteNums++;
offlineParam.bindType = APP;
ProcessInfo processInfo;
processInfo.pkgName = item.GetAccessee().GetAccesseeBundleName();
processInfo.userId = item.GetAccessee().GetAccesseeUserId();
offlineParam.processVec.push_back(processInfo);
offlineParam.peerUserId = item.GetAccesser().GetAccesserUserId();
LOGI("Sink delete acl pkgName %{public}s, bindType %{public}u, localUdid %{public}s, remoteUdid %{public}s",
pkgName.c_str(), item.GetBindType(), GetAnonyString(localUdid).c_str(),
GetAnonyString(remoteUdid).c_str());
continue;
}
}
offlineParam.leftAclNumber = bindNums - deleteNums;
}
void DeviceProfileConnector::DeleteDeviceBindLevel(DmOfflineParam &offlineParam,
const std::vector<AccessControlProfile> &profiles, const std::string &localUdid, const std::string &remoteUdid)
{
int32_t bindNums = 0;
int32_t deleteNums = 0;
for (auto &item : profiles) {
if (item.GetTrustDeviceId() != remoteUdid || item.GetBindType() == DM_IDENTICAL_ACCOUNT) {
continue;
}
bindNums++;
if (item.GetAccesser().GetAccesserDeviceId() == localUdid &&
item.GetAccessee().GetAccesseeDeviceId() == remoteUdid) {
DistributedDeviceProfileClient::GetInstance().DeleteAccessControlProfile(item.GetAccessControlId());
deleteNums++;
offlineParam.bindType = USER;
LOGI("Src delete acl bindType %{public}d, localUdid %{public}s, remoteUdid %{public}s", item.GetBindType(),
GetAnonyString(localUdid).c_str(), GetAnonyString(remoteUdid).c_str());
continue;
}
if (item.GetAccessee().GetAccesseeDeviceId() == localUdid &&
item.GetAccesser().GetAccesserDeviceId() == remoteUdid) {
DistributedDeviceProfileClient::GetInstance().DeleteAccessControlProfile(item.GetAccessControlId());
deleteNums++;
offlineParam.bindType = USER;
LOGI("Sink delete acl bindType %{public}u, localUdid %{public}s, remoteUdid %{public}s", item.GetBindType(),
GetAnonyString(localUdid).c_str(), GetAnonyString(remoteUdid).c_str());
continue;
}
}
offlineParam.leftAclNumber = bindNums - deleteNums;
}
void DeviceProfileConnector::DeleteServiceBindLevel(DmOfflineParam &offlineParam, const std::string &pkgName,
const std::vector<AccessControlProfile> &profiles, const std::string &localUdid, const std::string &remoteUdid)
{
int32_t bindNums = 0;
int32_t deleteNums = 0;
for (auto &item : profiles) {
if (item.GetTrustDeviceId() != remoteUdid || item.GetBindType() == DM_IDENTICAL_ACCOUNT ||
item.GetBindLevel() != SERVICE) {
continue;
}
bindNums++;
if (item.GetAccesser().GetAccesserBundleName() == pkgName &&
item.GetAccesser().GetAccesserDeviceId() == localUdid &&
item.GetAccessee().GetAccesseeDeviceId() == remoteUdid) {
DistributedDeviceProfileClient::GetInstance().DeleteAccessControlProfile(item.GetAccessControlId());
deleteNums++;
offlineParam.bindType = SERVICE;
LOGI("Src delete acl pkgName %{public}s, bindType %{public}d, localUdid %{public}s, remoteUdid %{public}s",
pkgName.c_str(), item.GetBindType(), GetAnonyString(localUdid).c_str(),
GetAnonyString(remoteUdid).c_str());
continue;
}
if (item.GetAccessee().GetAccesseeBundleName() == pkgName &&
item.GetAccessee().GetAccesseeDeviceId() == localUdid &&
item.GetAccesser().GetAccesserDeviceId() == remoteUdid) {
DistributedDeviceProfileClient::GetInstance().DeleteAccessControlProfile(item.GetAccessControlId());
deleteNums++;
offlineParam.bindType = SERVICE;
LOGI("Sink delete acl pkgName %{public}s, bindType %{public}u, localUdid %{public}s, remoteUdid %{public}s",
pkgName.c_str(), item.GetBindType(), GetAnonyString(localUdid).c_str(),
GetAnonyString(remoteUdid).c_str());
continue;
}
}
offlineParam.leftAclNumber = bindNums - deleteNums;
}
DM_EXPORT void DeviceProfileConnector::UpdateAclStatus(const DistributedDeviceProfile::AccessControlProfile &profile)
{
DistributedDeviceProfileClient::GetInstance().UpdateAccessControlProfile(profile);
}
int32_t DeviceProfileConnector::UpdateAccessControlList(int32_t userId, std::string &oldAccountId,
std::string &newAccountId)
{
std::vector<AccessControlProfile> profiles = GetAccessControlProfile();
LOGI("AccessControlProfile size is %{public}zu", profiles.size());
for (auto &item : profiles) {
if ((item.GetAccesser().GetAccesserUserId() == userId &&
item.GetAccesser().GetAccesserAccountId() == oldAccountId) ||
(item.GetAccessee().GetAccesseeUserId() == userId &&
item.GetAccessee().GetAccesseeAccountId() == oldAccountId)) {
item.SetStatus(INACTIVE);
DistributedDeviceProfileClient::GetInstance().UpdateAccessControlProfile(item);
}
if ((item.GetAccesser().GetAccesserUserId() == userId &&
item.GetAccesser().GetAccesserAccountId() == newAccountId) ||
(item.GetAccessee().GetAccesseeUserId() == userId &&
item.GetAccessee().GetAccesseeAccountId() == newAccountId)) {
item.SetStatus(ACTIVE);
DistributedDeviceProfileClient::GetInstance().UpdateAccessControlProfile(item);
}
}
return DM_OK;
}
DM_EXPORT bool DeviceProfileConnector::CheckSrcDevIdInAclForDevBind(
const std::string &pkgName, const std::string &deviceId)
{
std::vector<AccessControlProfile> profiles = GetAccessControlProfile();
LOGI("AccessControlProfile size is %{public}zu", profiles.size());
for (auto &item : profiles) {
if (item.GetTrustDeviceId() == deviceId && item.GetStatus() == ACTIVE &&
item.GetBindLevel() == USER && (item.GetAccessee().GetAccesseeBundleName() == pkgName ||
item.GetAccesser().GetAccesserBundleName() == "") && item.GetAccessee().GetAccesseeUserId() == 0 &&
item.GetAccessee().GetAccesseeAccountId() == "") {
return true;
}
}
return false;
}
bool DeviceProfileConnector::CheckSinkDevIdInAclForDevBind(const std::string &pkgName, const std::string &deviceId)
{
std::vector<AccessControlProfile> profiles = GetAccessControlProfile();
LOGI("AccessControlProfile size is %{public}zu", profiles.size());
for (auto &item : profiles) {
if (item.GetTrustDeviceId() == deviceId && item.GetStatus() == ACTIVE &&
item.GetBindLevel() == USER && (item.GetAccesser().GetAccesserBundleName() == pkgName ||
item.GetAccesser().GetAccesserBundleName() == "") && item.GetAccesser().GetAccesserUserId() == 0 &&
item.GetAccesser().GetAccesserAccountId() == "") {
return true;
}
}
return false;
}
bool DeviceProfileConnector::CheckDevIdInAclForDevBind(const std::string &pkgName, const std::string &deviceId)
{
return (CheckSinkDevIdInAclForDevBind(pkgName, deviceId) || CheckSrcDevIdInAclForDevBind(pkgName, deviceId));
}
bool DeviceProfileConnector::MatchAccesseeByBothUserIdAndPeerUdid(const std::string &peerUdid, int32_t peerUserId,
int32_t localUserId, const AccessControlProfile &aclProfile)
{
auto accesser = aclProfile.GetAccesser();
auto accessee = aclProfile.GetAccessee();
if (accessee.GetAccesseeDeviceId() == peerUdid && accessee.GetAccesseeUserId() == peerUserId &&
accesser.GetAccesserUserId() == localUserId) {
return true;
}
return false;
}
bool DeviceProfileConnector::MatchAccesserByBothUserIdAndPeerUdid(const std::string &peerUdid, int32_t peerUserId,
int32_t localUserId, const AccessControlProfile &aclProfile)
{
auto accesser = aclProfile.GetAccesser();
auto accessee = aclProfile.GetAccessee();
if (accesser.GetAccesserDeviceId() == peerUdid && accesser.GetAccesserUserId() == peerUserId &&
accessee.GetAccesseeUserId() == localUserId) {
return true;
}
return false;
}
DM_EXPORT uint32_t DeviceProfileConnector::DeleteTimeOutAcl(const std::string &peerUdid, int32_t peerUserId,
int32_t localUserId, DmOfflineParam &offlineParam)
{
std::vector<AccessControlProfile> profiles = GetAllAclIncludeLnnAcl();
LOGI("AccessControlProfile size is %{public}zu", profiles.size());
uint32_t allAclCnt = 0;
uint32_t noLnnAclCnt = 0;
DmAclIdParam lnnDmAclIdParam;
for (auto &item : profiles) {
if (item.GetTrustDeviceId() != peerUdid ||
!(item.GetBindType() == DM_POINT_TO_POINT || item.GetBindType() == DM_ACROSS_ACCOUNT)) {
continue;
}
allAclCnt++;
if (!(MatchAccesseeByBothUserIdAndPeerUdid(peerUdid, peerUserId, localUserId, item) ||
MatchAccesserByBothUserIdAndPeerUdid(peerUdid, peerUserId, localUserId, item))) {
continue;
}
if (CacheLnnAcl(item, peerUdid, peerUserId, localUserId, lnnDmAclIdParam)) {
continue;
}
noLnnAclCnt++;
if (item.GetAuthenticationType() != ALLOW_AUTH_ONCE) {
continue;
}
if (MatchAccesserByBothUserIdAndPeerUdid(peerUdid, peerUserId, localUserId, item)) {
CacheAceeAclId(item, offlineParam.needDelAclInfos);
}
if (MatchAccesseeByBothUserIdAndPeerUdid(peerUdid, peerUserId, localUserId, item)) {
CacheAcerAclId(item, offlineParam.needDelAclInfos);
}
}
LOGI("allAclCnt:%{public}u, noLnnAclCnt:%{public}u, needDelAclInfos.size:%{public}zu, lnnAclId:%{public}" PRId64,
allAclCnt, noLnnAclCnt, offlineParam.needDelAclInfos.size(), lnnDmAclIdParam.accessControlId);
if (noLnnAclCnt > 0 && noLnnAclCnt == static_cast<uint32_t>(offlineParam.needDelAclInfos.size()) &&
lnnDmAclIdParam.accessControlId > 0) {
offlineParam.needDelAclInfos.push_back(lnnDmAclIdParam);
}
offlineParam.peerUserId = peerUserId;
return allAclCnt;
}
bool DeviceProfileConnector::CacheLnnAcl(const AccessControlProfile &profile, const std::string &peerUdid,
int32_t peerUserId, int32_t localUserId, DmAclIdParam &dmAclIdParam)
{
if (IsLnnAcl(profile)) {
auto accesser = profile.GetAccesser();
auto accessee = profile.GetAccessee();
if (accesser.GetAccesserDeviceId() != peerUdid && accesser.GetAccesserUserId() == localUserId &&
accessee.GetAccesseeUserId() == peerUserId) {
dmAclIdParam.udid = accesser.GetAccesserDeviceId();
dmAclIdParam.userId = localUserId;
dmAclIdParam.skId = accesser.GetAccesserSessionKeyId();
dmAclIdParam.credId = accesser.GetAccesserCredentialIdStr();
dmAclIdParam.tokenIds.insert(accessee.GetAccesseeTokenId());
dmAclIdParam.tokenIds.insert(accesser.GetAccesserTokenId());
dmAclIdParam.accessControlId = profile.GetAccessControlId();
}
if (accessee.GetAccesseeDeviceId() != peerUdid && accessee.GetAccesseeUserId() == localUserId &&
accesser.GetAccesserUserId() == peerUserId) {
dmAclIdParam.udid = accessee.GetAccesseeDeviceId();
dmAclIdParam.userId = localUserId;
dmAclIdParam.skId = accessee.GetAccesseeSessionKeyId();
dmAclIdParam.credId = accessee.GetAccesseeCredentialIdStr();
dmAclIdParam.tokenIds.insert(accessee.GetAccesseeTokenId());
dmAclIdParam.tokenIds.insert(accesser.GetAccesserTokenId());
dmAclIdParam.accessControlId = profile.GetAccessControlId();
}
return true;
}
return false;
}
DM_EXPORT int32_t DeviceProfileConnector::GetTrustNumber(const std::string &deviceId)
{
std::vector<AccessControlProfile> profiles = GetAccessControlProfile();
LOGI("AccessControlProfile size is %{public}zu", profiles.size());
int32_t trustNumber = 0;
for (auto &item : profiles) {
if (item.GetTrustDeviceId() == deviceId && item.GetStatus() == ACTIVE) {
trustNumber++;
}
}
return trustNumber;
}
DM_EXPORT int32_t DeviceProfileConnector::IsSameAccount(const std::string &udid)
{
std::vector<AccessControlProfile> profiles = GetAccessControlProfile();
for (auto &item : profiles) {
if (item.GetTrustDeviceId() == udid && item.GetStatus() == ACTIVE) {
if (item.GetBindType() == DM_IDENTICAL_ACCOUNT) {
LOGI("The udid %{public}s is identical bind.", GetAnonyString(udid).c_str());
return DM_OK;
}
}
}
return ERR_DM_FAILED;
}
DM_EXPORT int32_t DeviceProfileConnector::CheckIsSameAccountByUdidHash(const std::string &udidHash)
{
if (udidHash.empty()) {
LOGE("udidHash is empty!");
return ERR_DM_INPUT_PARA_INVALID;
}
std::vector<AccessControlProfile> profiles = GetAccessControlProfile();
for (auto &item : profiles) {
if (Crypto::GetUdidHash(item.GetTrustDeviceId()) == udidHash) {
if (item.GetBindType() == DM_IDENTICAL_ACCOUNT) {
LOGI("The udidHash %{public}s is identical bind.", GetAnonyString(udidHash).c_str());
return DM_OK;
}
}
}
return ERR_DM_VERIFY_SAME_ACCOUNT_FAILED;
}
bool checkAccesserACL(AccessControlProfile& profile, const DmAccessCaller &caller,
const std::string &srcUdid, const DmAccessCallee &callee, const std::string &sinkUdid)
{
if ((profile.GetAccesser().GetAccesserUserId() == caller.userId ||
profile.GetAccesser().GetAccesserUserId() == 0 ||
profile.GetAccesser().GetAccesserUserId() == -1) &&
profile.GetAccesser().GetAccesserDeviceId() == srcUdid &&
profile.GetAccessee().GetAccesseeDeviceId() == sinkUdid) {
if (callee.userId != 0 && callee.userId == profile.GetAccessee().GetAccesseeUserId()) {
LOGI("accesser success add, callee userId not null!");
return true;
} else if (callee.userId == 0 ||
profile.GetAccessee().GetAccesseeUserId() == -1 ||
profile.GetAccessee().GetAccesseeUserId() == 0) {
LOGI("accesser success add!");
return true;
}
}
return false;
}
bool checkAccesseeACL(AccessControlProfile& profile, const DmAccessCaller &caller,
const std::string &srcUdid, const DmAccessCallee &callee, const std::string &sinkUdid)
{
if ((profile.GetAccessee().GetAccesseeUserId() == caller.userId ||
profile.GetAccessee().GetAccesseeUserId() == 0 ||
profile.GetAccessee().GetAccesseeUserId() == -1) &&
profile.GetAccessee().GetAccesseeDeviceId() == srcUdid &&
profile.GetAccesser().GetAccesserDeviceId() == sinkUdid) {
if (callee.userId != 0 && callee.userId == profile.GetAccesser().GetAccesserUserId()) {
LOGI("accessee success add, callee userId not null!");
return true;
} else if (callee.userId == 0 ||
profile.GetAccesser().GetAccesserUserId() == -1 ||
profile.GetAccesser().GetAccesserUserId() == 0) {
LOGI("accessee success add!");
return true;
}
}
return false;
}
std::vector<AccessControlProfile> GetACLByDeviceIdAndUserId(std::vector<AccessControlProfile> profiles,
const DmAccessCaller &caller, const std::string &srcUdid, const DmAccessCallee &callee, const std::string &sinkUdid)
{
LOGI("srcUdid = %{public}s, caller.userId = %{public}s, sinkUdid = %{public}s, callee.userId = %{public}s",
GetAnonyString(srcUdid).c_str(), GetAnonyInt32(caller.userId).c_str(),
GetAnonyString(sinkUdid).c_str(), GetAnonyInt32(callee.userId).c_str());
std::vector<AccessControlProfile> profilesFilter;
for (auto &item : profiles) {
if (checkAccesserACL(item, caller, srcUdid, callee, sinkUdid) ||
checkAccesseeACL(item, caller, srcUdid, callee, sinkUdid)) {
profilesFilter.push_back(item);
}
}
return profilesFilter;
}
DM_EXPORT bool DeviceProfileConnector::CheckAccessControl(
const DmAccessCaller &caller, const std::string &srcUdid,
const DmAccessCallee &callee, const std::string &sinkUdid)
{
LOGI("srcUdid %{public}s, srcUserId %{public}d, srcPkgName %{public}s, srcAccountId %{public}s,"
"sinkUdid %{public}s, sinkUserId %{public}d, sinkPkgName %{public}s, sinkAccountId %{public}s"
"callerTokenId %{public}s, calleeTokenId %{public}s.", GetAnonyString(srcUdid).c_str(), caller.userId,
caller.pkgName.c_str(), GetAnonyString(caller.accountId).c_str(),
GetAnonyString(sinkUdid).c_str(), callee.userId, callee.pkgName.c_str(),
GetAnonyString(callee.accountId).c_str(), GetAnonyUint64(caller.tokenId).c_str(),
GetAnonyUint64(callee.tokenId).c_str());
std::vector<AccessControlProfile> profiles = GetAllAccessControlProfile();
std::vector<AccessControlProfile> profilesFilter =
GetACLByDeviceIdAndUserId(profiles, caller, srcUdid, callee, sinkUdid);
for (auto &item : profilesFilter) {
if (item.GetStatus() != ACTIVE || (item.GetTrustDeviceId() != sinkUdid &&
item.GetTrustDeviceId() != srcUdid)) {
continue;
}
if (SingleUserProcess(item, caller, callee)) {
return true;
}
}
return false;
}
bool DeviceProfileConnector::SingleUserProcess(const DistributedDeviceProfile::AccessControlProfile &profile,
const DmAccessCaller &caller, const DmAccessCallee &callee)
{
LOGI("BindType %{public}d, bindLevel %{public}d.",
profile.GetBindType(), profile.GetBindLevel());
uint32_t bindType = profile.GetBindType();
bool ret = false;
switch (bindType) {
case DM_IDENTICAL_ACCOUNT:
ret = true;
break;
case DM_POINT_TO_POINT:
if (profile.GetBindLevel() == USER && !IsLnnAcl(profile)) {
ret = true;
} else if ((profile.GetBindLevel() == APP || profile.GetBindLevel() == SERVICE) &&
(profile.GetAccesser().GetAccesserBundleName() == caller.pkgName ||
profile.GetAccessee().GetAccesseeBundleName() == caller.pkgName)) {
ret = CheckAppLevelAccess(profile, caller, callee);
}
break;
case DM_ACROSS_ACCOUNT:
if (profile.GetBindLevel() == USER && !IsLnnAcl(profile)) {
ret = true;
} else if ((profile.GetBindLevel() == APP || profile.GetBindLevel() == SERVICE) &&
(profile.GetAccesser().GetAccesserBundleName() == caller.pkgName ||
profile.GetAccessee().GetAccesseeBundleName() == caller.pkgName)) {
ret = CheckAppLevelAccess(profile, caller, callee);
}
break;
default:
LOGE("unknown bind type %{public}d.", bindType);
break;
}
return ret;
}
bool DeviceProfileConnector::CheckAppLevelAccess(const DistributedDeviceProfile::AccessControlProfile &profile,
const DmAccessCaller &caller, const DmAccessCallee &callee)
{
if (caller.tokenId == 0 || callee.tokenId == 0) {
return true;
} else {
if ((static_cast<uint64_t>(profile.GetAccesser().GetAccesserTokenId()) == caller.tokenId &&
static_cast<uint64_t>(profile.GetAccessee().GetAccesseeTokenId()) == callee.tokenId) ||
(static_cast<uint64_t>(profile.GetAccesser().GetAccesserTokenId()) == callee.tokenId &&
static_cast<uint64_t>(profile.GetAccessee().GetAccesseeTokenId()) == caller.tokenId)) {
return true;
} else {
return false;
}
}
}
DM_EXPORT bool DeviceProfileConnector::CheckIsSameAccount(
const DmAccessCaller &caller, const std::string &srcUdid,
const DmAccessCallee &callee, const std::string &sinkUdid)
{
LOGI("srcUdid %{public}s, srcUserId %{public}d, srcPkgName %{public}s,"
"srcAccountId %{public}s, sinkUdid %{public}s, sinkUserId %{public}d, sinkPkgName %{public}s,"
"sinkAccountId %{public}s, callerTokenId %{public}s, calleeTokenId %{public}s.",
GetAnonyString(srcUdid).c_str(), caller.userId,
caller.pkgName.c_str(), GetAnonyString(caller.accountId).c_str(),
GetAnonyString(sinkUdid).c_str(), callee.userId, callee.pkgName.c_str(),
GetAnonyString(callee.accountId).c_str(), GetAnonyUint64(caller.tokenId).c_str(),
GetAnonyUint64(callee.tokenId).c_str());
std::vector<AccessControlProfile> profiles = GetAllAccessControlProfile();
std::vector<AccessControlProfile> profilesFilter
= GetACLByDeviceIdAndUserId(profiles, caller, srcUdid, callee, sinkUdid);
for (auto &item : profilesFilter) {
if (item.GetStatus() != ACTIVE || (item.GetTrustDeviceId() != sinkUdid &&
item.GetTrustDeviceId() != srcUdid)) {
continue;
}
if (item.GetBindType() == DM_IDENTICAL_ACCOUNT) {
LOGI("The udid %{public}s is identical bind.", GetAnonyString(item.GetTrustDeviceId()).c_str());
return true;
}
}
return false;
}
DM_EXPORT int32_t DeviceProfileConnector::GetBindLevel(const std::string &pkgName,
const std::string &localUdid, const std::string &udid, uint64_t &tokenId)
{
LOGI("pkgName %{public}s, udid %{public}s.", pkgName.c_str(), GetAnonyString(udid).c_str());
std::vector<AccessControlProfile> profiles = GetAclProfileByDeviceIdAndUserId(localUdid,
MultipleUserConnector::GetFirstForegroundUserId());
int32_t bindLevel = INVALIED_TYPE;
for (auto &item : profiles) {
if (item.GetTrustDeviceId() != udid) {
continue;
}
if (item.GetAccesser().GetAccesserBundleName() == pkgName &&
item.GetAccesser().GetAccesserDeviceId() == localUdid &&
item.GetAccessee().GetAccesseeDeviceId() == udid) {
tokenId = static_cast<uint64_t>(item.GetAccesser().GetAccesserTokenId());
bindLevel = static_cast<int32_t>(item.GetBindLevel());
LOGI("Src get bindLevel %{public}d.", bindLevel);
continue;
}
if (item.GetAccessee().GetAccesseeBundleName() == pkgName &&
item.GetAccessee().GetAccesseeDeviceId() == localUdid &&
item.GetAccesser().GetAccesserDeviceId() == udid) {
tokenId = static_cast<uint64_t>(item.GetAccessee().GetAccesseeTokenId());
bindLevel = static_cast<int32_t>(item.GetBindLevel());
LOGI("Sink get bindLevel %{public}d.", bindLevel);
continue;
}
}
return bindLevel;
}
std::map<std::string, int32_t> DeviceProfileConnector::GetDeviceIdAndBindLevel(std::vector<int32_t> userIds,
const std::string &localUdid)
{
std::vector<AccessControlProfile> profiles = GetAllAccessControlProfile();
std::map<std::string, int32_t> deviceIdMap;
for (const auto &item : profiles) {
if (IsLnnAcl(item)) {
continue;
}
if (find(userIds.begin(), userIds.end(), item.GetAccesser().GetAccesserUserId()) != userIds.end() &&
item.GetAccesser().GetAccesserDeviceId() == localUdid) {
LOGI("Get Device Bind type localUdid %{public}s is src.", GetAnonyString(localUdid).c_str());
UpdateBindType(item.GetTrustDeviceId(), item.GetBindLevel(), deviceIdMap);
continue;
}
if (find(userIds.begin(), userIds.end(), item.GetAccessee().GetAccesseeUserId()) != userIds.end() &&
item.GetAccessee().GetAccesseeDeviceId() == localUdid) {
LOGI("Get Device Bind type localUdid %{public}s is sink.", GetAnonyString(localUdid).c_str());
UpdateBindType(item.GetTrustDeviceId(), item.GetBindLevel(), deviceIdMap);
continue;
}
}
return deviceIdMap;
}
bool DeviceProfileConnector::CheckAccessControlProfileByTokenId(int32_t tokenId)
{
if (tokenId < 0) {
LOGE("tokenId error.");
return false;
}
std::string localUdid = GetLocalDeviceId();
int32_t userId = MultipleUserConnector::GetCurrentAccountUserID();
std::vector<AccessControlProfile> profiles = GetAllAccessControlProfile();
for (const auto &item : profiles) {
if (IsLnnAcl(item)) {
continue;
}
if (item.GetAccesser().GetAccesserDeviceId() == localUdid &&
item.GetAccesser().GetAccesserUserId() == userId &&
static_cast<int32_t>(item.GetAccesser().GetAccesserTokenId()) == tokenId) {
return true;
}
if (item.GetAccessee().GetAccesseeDeviceId() == localUdid &&
item.GetAccessee().GetAccesseeUserId() == userId &&
static_cast<int32_t>(item.GetAccessee().GetAccesseeTokenId()) == tokenId) {
return true;
}
}
return false;
}
std::vector<std::string> DeviceProfileConnector::GetDeviceIdAndUdidListByTokenId(const std::vector<int32_t> &userIds,
const std::string &localUdid, int32_t tokenId)
{
if (userIds.empty() || localUdid.empty()) {
LOGE("userIds or localUdid is empty.");
return {};
}
std::vector<AccessControlProfile> profiles = GetAllAccessControlProfile();
std::map<std::string, int32_t> deviceIdMap;
std::vector<std::string> udidList;
for (const auto &item : profiles) {
if (IsLnnAcl(item)) {
continue;
}
if (find(userIds.begin(), userIds.end(), item.GetAccesser().GetAccesserUserId()) != userIds.end() &&
item.GetAccesser().GetAccesserDeviceId() == localUdid &&
static_cast<int32_t>(item.GetAccesser().GetAccesserTokenId()) == tokenId) {
LOGI("Get Device Bind type localUdid %{public}s is src, tokenId %{public}s.",
GetAnonyString(localUdid).c_str(), GetAnonyInt32(tokenId).c_str());
UpdateBindType(item.GetTrustDeviceId(), item.GetBindLevel(), deviceIdMap);
continue;
}
if (find(userIds.begin(), userIds.end(), item.GetAccessee().GetAccesseeUserId()) != userIds.end() &&
item.GetAccessee().GetAccesseeDeviceId() == localUdid &&
static_cast<int32_t>(item.GetAccessee().GetAccesseeTokenId()) == tokenId) {
LOGI("Get Device Bind type localUdid %{public}s is sink, tokenId %{public}s.",
GetAnonyString(localUdid).c_str(), GetAnonyInt32(tokenId).c_str());
UpdateBindType(item.GetTrustDeviceId(), item.GetBindLevel(), deviceIdMap);
continue;
}
}
for (const auto &item : deviceIdMap) {
udidList.push_back(item.first);
}
return udidList;
}
DM_EXPORT std::multimap<std::string, int32_t> DeviceProfileConnector::GetDeviceIdAndUserId(
int32_t userId, const std::string &accountId, const std::string &localUdid)
{
LOGI("localUdid %{public}s, userId %{public}d, accountId %{public}s.", GetAnonyString(localUdid).c_str(),
userId, GetAnonyString(accountId).c_str());
std::vector<AccessControlProfile> profiles = GetAllAclIncludeLnnAcl();
std::multimap<std::string, int32_t> deviceIdMap;
for (const auto &item : profiles) {
std::string accesserUdid = item.GetAccesser().GetAccesserDeviceId();
std::string accesseeUdid = item.GetAccessee().GetAccesseeDeviceId();
int32_t accesserUserId = item.GetAccesser().GetAccesserUserId();
int32_t accesseeUserId = item.GetAccessee().GetAccesseeUserId();
std::string accesserAccountId = item.GetAccesser().GetAccesserAccountId();
std::string accesseeAccountId = item.GetAccessee().GetAccesseeAccountId();
if (accesserUdid == localUdid && accesserUserId == userId && accesserAccountId == accountId) {
LOGI("Account logout trust udid %{public}s userid %{public}d is src.",
GetAnonyString(accesseeUdid).c_str(), accesseeUserId);
deviceIdMap.insert(std::pair<std::string, int32_t>(accesseeUdid, accesseeUserId));
continue;
}
if (accesseeUdid == localUdid && accesseeUserId == userId && accesseeAccountId == accountId) {
LOGI("Account logout trust udid %{public}s userid %{public}d is sink.",
GetAnonyString(accesserUdid).c_str(), accesserUserId);
deviceIdMap.insert(std::pair<std::string, int32_t>(accesserUdid, accesserUserId));
continue;
}
}
return deviceIdMap;
}
void DeviceProfileConnector::UpdateBindType(const std::string &udid, int32_t compareParam,
std::map<std::string, int32_t> &deviceMap)
{
LOGI("BindType %{public}d.", compareParam);
if (deviceMap.find(udid) == deviceMap.end()) {
deviceMap[udid] = compareParam;
} else {
deviceMap[udid] = std::min(deviceMap[udid], compareParam);
}
}
int32_t DeviceProfileConnector::HandleAccountLogoutEvent(int32_t remoteUserId,
const std::string &remoteAccountHash, const std::string &remoteUdid, const std::string &localUdid)
{
LOGI("RemoteUserId %{public}d, remoteAccountHash %{public}s, remoteUdid %{public}s, localUdid %{public}s.",
remoteUserId, GetAnonyString(remoteAccountHash).c_str(), GetAnonyString(remoteUdid).c_str(),
GetAnonyString(localUdid).c_str());
std::vector<AccessControlProfile> profiles = GetAccessControlProfileByUserId(remoteUserId);
int32_t bindType = DM_INVALIED_TYPE;
for (const auto &item : profiles) {
if (item.GetTrustDeviceId() != remoteUdid) {
continue;
}
std::string accesserUdid = item.GetAccesser().GetAccesserDeviceId();
std::string accesseeUdid = item.GetAccessee().GetAccesseeDeviceId();
int32_t accesserUserId = item.GetAccesser().GetAccesserUserId();
int32_t accesseeUserId = item.GetAccessee().GetAccesseeUserId();
if (accesserUdid == localUdid && accesseeUdid == remoteUdid && accesseeUserId == remoteUserId) {
DistributedDeviceProfileClient::GetInstance().DeleteAccessControlProfile(item.GetAccessControlId());
bindType = DM_IDENTICAL_ACCOUNT;
continue;
}
if (accesseeUdid == localUdid && accesserUdid == remoteUdid && accesserUserId == remoteUserId) {
DistributedDeviceProfileClient::GetInstance().DeleteAccessControlProfile(item.GetAccessControlId());
bindType = DM_IDENTICAL_ACCOUNT;
continue;
}
}
return bindType;
}
DM_EXPORT int32_t DeviceProfileConnector::HandleDevUnBindEvent(int32_t remoteUserId, const std::string &remoteUdid,
const std::string &localUdid, DmOfflineParam &offlineParam, int32_t tokenId)
{
LOGI("RemoteUserId %{public}d, remoteUdid %{public}s, localUdid %{public}s, tokenId %{public}s.", remoteUserId,
GetAnonyString(remoteUdid).c_str(), GetAnonyString(localUdid).c_str(), GetAnonyInt32(tokenId).c_str());
std::vector<AccessControlProfile> profiles = GetAclProfileByDeviceIdAndUserId(remoteUdid, remoteUserId, localUdid);
int32_t bindType = DM_INVALIED_TYPE;
for (const auto &item : profiles) {
if (item.GetTrustDeviceId() != remoteUdid) {
continue;
}
if (item.GetBindType() == DM_IDENTICAL_ACCOUNT) {
bindType = DM_IDENTICAL_ACCOUNT;
continue;
}
if (item.GetAccesser().GetAccesserDeviceId() == localUdid &&
item.GetAccessee().GetAccesseeDeviceId() == remoteUdid &&
item.GetAccessee().GetAccesseeTokenId() == tokenId) {
offlineParam.bindType = USER;
CacheAcerAclId(item, offlineParam.needDelAclInfos);
LOGI("Src delete acl bindType %{public}d, localUdid %{public}s, remoteUdid %{public}s", item.GetBindType(),
GetAnonyString(localUdid).c_str(), GetAnonyString(remoteUdid).c_str());
bindType = std::min(bindType, static_cast<int32_t>(item.GetBindType()));
continue;
}
if (item.GetAccessee().GetAccesseeDeviceId() == localUdid &&
item.GetAccesser().GetAccesserDeviceId() == remoteUdid &&
item.GetAccesser().GetAccesserTokenId() == tokenId) {
offlineParam.bindType = USER;
CacheAceeAclId(item, offlineParam.needDelAclInfos);
LOGI("Sink delete acl bindType %{public}u, localUdid %{public}s, remoteUdid %{public}s", item.GetBindType(),
GetAnonyString(localUdid).c_str(), GetAnonyString(remoteUdid).c_str());
bindType = std::min(bindType, static_cast<int32_t>(item.GetBindType()));
continue;
}
}
return bindType;
}
DM_EXPORT DmOfflineParam DeviceProfileConnector::HandleAppUnBindEvent(int32_t remoteUserId,
const std::string &remoteUdid, int32_t tokenId, const std::string &localUdid)
{
LOGI("RemoteUserId %{public}d, remoteUdid %{public}s, localUdid %{public}s.",
remoteUserId, GetAnonyString(remoteUdid).c_str(), GetAnonyString(localUdid).c_str());
std::vector<AccessControlProfile> profiles = GetAclProfileByDeviceIdAndUserId(remoteUdid, remoteUserId, localUdid);
DmOfflineParam offlineParam;
if (profiles.empty()) {
LOGE("Acl is empty.");
return offlineParam;
}
for (auto &item : profiles) {
if (item.GetTrustDeviceId() != remoteUdid) {
continue;
}
if (FindTargetAcl(item, localUdid, remoteUserId, remoteUdid, tokenId, offlineParam)) {
continue;
}
if (FindLnnAcl(item, localUdid, remoteUdid, offlineParam)) {
continue;
}
if (FindUserAcl(item, localUdid, remoteUdid, offlineParam)) {
continue;
}
if (FindLeftAcl(item, localUdid, remoteUdid, offlineParam)) {
continue;
}
}
return offlineParam;
}
bool DeviceProfileConnector::FindTargetAcl(const DistributedDeviceProfile::AccessControlProfile &acl,
const std::string &localUdid, const int32_t remoteUserId, const std::string &remoteUdid,
const int32_t tokenId, const int32_t peerTokenId, DmOfflineParam &offlineParam)
{
bool isMatch = false;
std::string acerDeviceId = acl.GetAccesser().GetAccesserDeviceId();
std::string aceeDeviceId = acl.GetAccessee().GetAccesseeDeviceId();
int32_t acerTokenId = static_cast<int32_t>(acl.GetAccesser().GetAccesserTokenId());
int32_t aceeTokenId = static_cast<int32_t>(acl.GetAccessee().GetAccesseeTokenId());
if (acl.GetAccesser().GetAccesserUserId() == remoteUserId && acerDeviceId == remoteUdid &&
aceeDeviceId == localUdid && (acerTokenId == peerTokenId) && (aceeTokenId == tokenId)) {
if ((acl.GetBindLevel() == USER || acl.GetBindType() == DM_IDENTICAL_ACCOUNT)) {
offlineParam.hasUserAcl = true;
}
ProcessInfo processInfo;
processInfo.pkgName = acl.GetAccessee().GetAccesseeBundleName();
processInfo.userId = acl.GetAccessee().GetAccesseeUserId();
offlineParam.processVec.push_back(processInfo);
CacheAceeAclId(acl, offlineParam.needDelAclInfos);
LOGI("Src del acl aclId: %{public}" PRId64 ", localUdid %{public}s, remoteUdid %{public}s"
", bindType %{public}d, bindLevel: %{public}d", acl.GetAccessControlId(),
GetAnonyString(localUdid).c_str(), GetAnonyString(remoteUdid).c_str(), acl.GetBindType(),
acl.GetBindLevel());
isMatch = true;
}
if (acl.GetAccessee().GetAccesseeUserId() == remoteUserId && aceeDeviceId == remoteUdid &&
acerDeviceId == localUdid && (aceeTokenId == peerTokenId) && (acerTokenId == tokenId)) {
if ((acl.GetBindLevel() == USER || acl.GetBindType() == DM_IDENTICAL_ACCOUNT)) {
offlineParam.hasUserAcl = true;
}
ProcessInfo processInfo;
processInfo.pkgName = acl.GetAccesser().GetAccesserBundleName();
processInfo.userId = acl.GetAccesser().GetAccesserUserId();
offlineParam.processVec.push_back(processInfo);
CacheAcerAclId(acl, offlineParam.needDelAclInfos);
LOGI("Sink del acl aclId: %{public}" PRId64 ", localUdid %{public}s, remoteUdid %{public}s"
", bindType %{public}d, bindLevel: %{public}d", acl.GetAccessControlId(),
GetAnonyString(localUdid).c_str(), GetAnonyString(remoteUdid).c_str(), acl.GetBindType(),
acl.GetBindLevel());
isMatch = true;
}
return isMatch;
}
DM_EXPORT DmOfflineParam DeviceProfileConnector::HandleAppUnBindEvent(int32_t remoteUserId,
const std::string &remoteUdid, int32_t tokenId, const std::string &localUdid, int32_t peerTokenId)
{
LOGI("RemoteUserId %{public}d, remoteUdid %{public}s, localUdid %{public}s.",
remoteUserId, GetAnonyString(remoteUdid).c_str(), GetAnonyString(localUdid).c_str());
std::vector<AccessControlProfile> profiles = GetAclProfileByDeviceIdAndUserId(remoteUdid, remoteUserId, localUdid);
DmOfflineParam offlineParam;
if (profiles.empty()) {
LOGE("Acl is empty.");
return offlineParam;
}
for (auto &item : profiles) {
if (item.GetTrustDeviceId() != remoteUdid) {
continue;
}
if (FindTargetAcl(item, localUdid, remoteUserId, remoteUdid, tokenId, peerTokenId, offlineParam)) {
continue;
}
if (FindLnnAcl(item, localUdid, remoteUdid, offlineParam)) {
continue;
}
if (FindUserAcl(item, localUdid, remoteUdid, offlineParam)) {
continue;
}
if (FindLeftAcl(item, localUdid, remoteUdid, offlineParam)) {
continue;
}
}
return offlineParam;
}
bool DeviceProfileConnector::FindTargetAcl(const DistributedDeviceProfile::AccessControlProfile &acl,
const std::string &localUdid, const int32_t remoteUserId, const std::string &remoteUdid,
const int32_t remoteTokenId, DmOfflineParam &offlineParam)
{
bool isMatch = false;
if (acl.GetAccesser().GetAccesserUserId() == remoteUserId &&
acl.GetAccesser().GetAccesserDeviceId() == remoteUdid &&
(static_cast<int32_t>(acl.GetAccesser().GetAccesserTokenId()) == remoteTokenId) &&
acl.GetAccessee().GetAccesseeDeviceId() == localUdid) {
ProcessInfo processInfo;
processInfo.pkgName = acl.GetAccessee().GetAccesseeBundleName();
processInfo.userId = acl.GetAccessee().GetAccesseeUserId();
processInfo.tokenId = acl.GetAccessee().GetAccesseeTokenId();
if ((acl.GetBindLevel() == USER || acl.GetBindType() == DM_IDENTICAL_ACCOUNT)) {
offlineParam.hasUserAcl = true;
processInfo.tokenId = 0;
}
offlineParam.processVec.push_back(processInfo);
CacheAceeAclId(acl, offlineParam.needDelAclInfos);
LOGI("Src del acl aclId: %{public}" PRId64 ", localUdid %{public}s, remoteUdid %{public}s"
", bindType %{public}d, bindLevel: %{public}d", acl.GetAccessControlId(),
GetAnonyString(localUdid).c_str(), GetAnonyString(remoteUdid).c_str(), acl.GetBindType(),
acl.GetBindLevel());
isMatch = true;
}
if (acl.GetAccessee().GetAccesseeUserId() == remoteUserId &&
acl.GetAccessee().GetAccesseeDeviceId() == remoteUdid &&
(static_cast<int32_t>(acl.GetAccessee().GetAccesseeTokenId()) == remoteTokenId) &&
acl.GetAccesser().GetAccesserDeviceId() == localUdid) {
ProcessInfo processInfo;
processInfo.pkgName = acl.GetAccesser().GetAccesserBundleName();
processInfo.userId = acl.GetAccesser().GetAccesserUserId();
processInfo.tokenId = acl.GetAccesser().GetAccesserTokenId();
if ((acl.GetBindLevel() == USER || acl.GetBindType() == DM_IDENTICAL_ACCOUNT)) {
offlineParam.hasUserAcl = true;
processInfo.tokenId = 0;
}
offlineParam.processVec.push_back(processInfo);
CacheAcerAclId(acl, offlineParam.needDelAclInfos);
LOGI("Sink del acl aclId: %{public}" PRId64 ", localUdid %{public}s, remoteUdid %{public}s"
", bindType %{public}d, bindLevel: %{public}d", acl.GetAccessControlId(),
GetAnonyString(localUdid).c_str(), GetAnonyString(remoteUdid).c_str(), acl.GetBindType(),
acl.GetBindLevel());
isMatch = true;
}
return isMatch;
}
DmOfflineParam DeviceProfileConnector::HandleServiceUnBindEvent(int32_t remoteUserId,
const std::string &remoteUdid, const std::string &localUdid, int32_t tokenId)
{
LOGI("RemoteUserId %{public}d, remoteUdid %{public}s, localUdid %{public}s.",
remoteUserId, GetAnonyString(remoteUdid).c_str(), GetAnonyString(localUdid).c_str());
std::vector<AccessControlProfile> profiles = GetAclProfileByDeviceIdAndUserId(remoteUdid, remoteUserId, localUdid);
DmOfflineParam offlineParam;
if (profiles.empty()) {
LOGE("Acl is empty.");
return offlineParam;
}
for (auto &item : profiles) {
if (item.GetTrustDeviceId() != remoteUdid) {
continue;
}
if (FindTargetAcl(item, localUdid, remoteUserId, remoteUdid, tokenId, offlineParam)) {
continue;
}
if (FindLnnAcl(item, localUdid, remoteUdid, offlineParam)) {
continue;
}
if (FindUserAcl(item, localUdid, remoteUdid, offlineParam)) {
continue;
}
if (FindLeftAcl(item, localUdid, remoteUdid, offlineParam)) {
continue;
}
}
return offlineParam;
}
DM_EXPORT std::vector<AccessControlProfile> DeviceProfileConnector::GetAllAccessControlProfile()
{
std::vector<AccessControlProfile> profiles;
int32_t ret = DistributedDeviceProfileClient::GetInstance().GetAllAccessControlProfile(profiles);
if (ret != DM_OK) {
LOGE("DP failed, ret = %{public}d", ret);
}
return profiles;
}
DM_EXPORT std::vector<AccessControlProfile> DeviceProfileConnector::GetAllAclIncludeLnnAcl()
{
std::vector<AccessControlProfile> profiles;
int32_t ret = DistributedDeviceProfileClient::GetInstance().GetAllAclIncludeLnnAcl(profiles);
if (ret != DM_OK) {
LOGE("DP failed, ret = %{public}d", ret);
}
return profiles;
}
DM_EXPORT void DeviceProfileConnector::DeleteAccessControlById(
int64_t accessControlId)
{
DistributedDeviceProfileClient::GetInstance().DeleteAccessControlProfile(accessControlId);
}
DM_EXPORT int32_t DeviceProfileConnector::HandleUserSwitched(
const std::string &localUdid, const std::vector<std::string> &deviceVec, int32_t currentUserId,
int32_t beforeUserId)
{
if (deviceVec.empty()) {
LOGI("no remote device.");
return DM_OK;
}
std::vector<AccessControlProfile> profiles = GetAllAclIncludeLnnAcl();
std::vector<AccessControlProfile> activeProfiles;
std::vector<AccessControlProfile> inActiveProfiles;
for (auto &item : profiles) {
if (std::find(deviceVec.begin(), deviceVec.end(), item.GetTrustDeviceId()) == deviceVec.end()) {
continue;
}
if ((item.GetAccesser().GetAccesserDeviceId() == localUdid &&
item.GetAccesser().GetAccesserUserId() == beforeUserId) ||
(item.GetAccessee().GetAccesseeDeviceId() == localUdid &&
item.GetAccessee().GetAccesseeUserId() == beforeUserId)) {
if (item.GetStatus() == ACTIVE) {
item.SetStatus(INACTIVE);
inActiveProfiles.push_back(item);
}
continue;
}
if ((item.GetAccesser().GetAccesserDeviceId() == localUdid &&
item.GetAccesser().GetAccesserUserId() == currentUserId && item.GetStatus() == INACTIVE) || (
item.GetAccessee().GetAccesseeDeviceId() == localUdid &&
item.GetAccessee().GetAccesseeUserId() == currentUserId && item.GetStatus() == INACTIVE)) {
item.SetStatus(ACTIVE);
activeProfiles.push_back(item);
continue;
}
}
HandleUserSwitched(activeProfiles, inActiveProfiles);
return DM_OK;
}
DM_EXPORT void DeviceProfileConnector::HandleUserSwitched(
const std::vector<AccessControlProfile> &activeProfiles,
const std::vector<AccessControlProfile> &inActiveProfiles)
{
for (auto &item : inActiveProfiles) {
DistributedDeviceProfileClient::GetInstance().UpdateAccessControlProfile(item);
}
for (auto &item : activeProfiles) {
DistributedDeviceProfileClient::GetInstance().UpdateAccessControlProfile(item);
}
}
std::vector<AccessControlProfile> DeviceProfileConnector::GetAclProfileByUserId(const std::string &localUdid,
int32_t userId, const std::string &remoteUdid)
{
LOGI("localUdid %{public}s, localUserId %{public}d, remoteUdid %{public}s.", GetAnonyString(localUdid).c_str(),
userId, GetAnonyString(remoteUdid).c_str());
std::vector<AccessControlProfile> profiles = GetAllAccessControlProfile();
std::vector<AccessControlProfile> profilesTemp;
for (const auto &item : profiles) {
if (item.GetAccesser().GetAccesserDeviceId() == localUdid &&
item.GetAccesser().GetAccesserUserId() == userId &&
item.GetAccessee().GetAccesseeDeviceId() == remoteUdid) {
profilesTemp.push_back(item);
} else if (item.GetAccessee().GetAccesseeDeviceId() == localUdid &&
item.GetAccessee().GetAccesseeUserId() == userId &&
item.GetAccesser().GetAccesserDeviceId() == remoteUdid) {
profilesTemp.push_back(item);
}
}
return profilesTemp;
}
DM_EXPORT void DeviceProfileConnector::HandleSyncForegroundUserIdEvent(
const std::vector<int32_t> &remoteUserIds, const std::string &remoteUdid,
const std::vector<int32_t> &localUserIds, std::string &localUdid,
std::vector<DmUserRemovedServiceInfo> &serviceInfos)
{
LOGI("localUdid %{public}s, remoteUdid %{public}s.", GetAnonyString(localUdid).c_str(),
GetAnonyString(remoteUdid).c_str());
std::vector<AccessControlProfile> profiles = GetAllAclIncludeLnnAcl();
for (auto &item : profiles) {
if (item.GetAccesser().GetAccesserDeviceId() == localUdid &&
item.GetAccessee().GetAccesseeDeviceId() == remoteUdid &&
find(localUserIds.begin(), localUserIds.end(),
item.GetAccesser().GetAccesserUserId()) != localUserIds.end() &&
find(remoteUserIds.begin(), remoteUserIds.end(),
item.GetAccessee().GetAccesseeUserId()) != remoteUserIds.end() && item.GetStatus() == INACTIVE) {
item.SetStatus(ACTIVE);
DistributedDeviceProfileClient::GetInstance().UpdateAccessControlProfile(item);
if (IsLnnAcl(item)) {
continue;
}
DmUserRemovedServiceInfo serviceInfo;
std::string aceeExtraData = item.GetAccessee().GetAccesseeExtraData();
if (aceeExtraData.empty()) {
LOGE("CheckAclByUdidAndTokenIdAndServiceId aceeExtraData is empty.");
continue;
}
JsonObject aceeExtJson(aceeExtraData);
if (aceeExtJson.IsDiscarded() || !IsArray(aceeExtJson, "serviceId")) {
LOGE("serviceId is not exist.");
continue;
}
JsonItemObject serviceIdItem = aceeExtJson["serviceId"];
serviceIdItem.Get(serviceInfo.serviceIds);
serviceInfo.localTokenId = item.GetAccesser().GetAccesserTokenId();
serviceInfo.localPkgName = item.GetAccesser().GetAccesserBundleName();
serviceInfo.bindType = item.GetBindType();
serviceInfo.peerUdid = item.GetAccessee().GetAccesseeDeviceId();
serviceInfo.peerUserId = item.GetAccessee().GetAccesseeUserId();
serviceInfo.isActive = true;
serviceInfos.push_back(serviceInfo);
} else if (item.GetAccessee().GetAccesseeDeviceId() == localUdid &&
item.GetAccesser().GetAccesserDeviceId() == remoteUdid &&
find(localUserIds.begin(), localUserIds.end(),
item.GetAccessee().GetAccesseeUserId()) != localUserIds.end() &&
find(remoteUserIds.begin(), remoteUserIds.end(),
item.GetAccesser().GetAccesserUserId()) != remoteUserIds.end() && item.GetStatus() == INACTIVE) {
item.SetStatus(ACTIVE);
DistributedDeviceProfileClient::GetInstance().UpdateAccessControlProfile(item);
}
}
}
std::vector<ProcessInfo> DeviceProfileConnector::GetOfflineProcessInfo(std::string &localUdid,
const std::vector<int32_t> &localUserIds, const std::string &remoteUdid, const std::vector<int32_t> &remoteUserIds)
{
LOGI("localUdid %{public}s, remoteUdid %{public}s.", GetAnonyString(localUdid).c_str(),
GetAnonyString(remoteUdid).c_str());
std::vector<AccessControlProfile> profiles = GetAllAccessControlProfile();
std::vector<ProcessInfo> processInfos;
int32_t bindLevel = 100;
for (const auto &item : profiles) {
if (IsLnnAcl(item)) {
continue;
}
ProcessInfo processInfo;
std::string accesserUdid = item.GetAccesser().GetAccesserDeviceId();
std::string accesseeUdid = item.GetAccessee().GetAccesseeDeviceId();
int32_t accesserUserId = item.GetAccesser().GetAccesserUserId();
int32_t accesseeUserId = item.GetAccessee().GetAccesseeUserId();
if (accesserUdid == localUdid && accesseeUdid == remoteUdid &&
find(localUserIds.begin(), localUserIds.end(), accesserUserId) != localUserIds.end() &&
find(remoteUserIds.begin(), remoteUserIds.end(), accesseeUserId) != remoteUserIds.end() &&
item.GetStatus() == ACTIVE) {
processInfo.pkgName = item.GetAccesser().GetAccesserBundleName();
processInfo.userId = item.GetAccesser().GetAccesserUserId();
bindLevel = std::min(bindLevel, static_cast<int32_t>(item.GetBindLevel()));
processInfos.push_back(processInfo);
} else if (accesseeUdid == localUdid && accesserUdid == remoteUdid &&
find(localUserIds.begin(), localUserIds.end(), accesseeUserId) != localUserIds.end() &&
find(remoteUserIds.begin(), remoteUserIds.end(), accesserUserId) != remoteUserIds.end() &&
item.GetStatus() == ACTIVE) {
processInfo.pkgName = item.GetAccessee().GetAccesseeBundleName();
processInfo.userId = item.GetAccessee().GetAccesseeUserId();
bindLevel = std::min(bindLevel, static_cast<int32_t>(item.GetBindLevel()));
processInfos.push_back(processInfo);
}
}
if (bindLevel == INVALIED_TYPE || bindLevel == USER) {
processInfos.clear();
for (const auto &item : localUserIds) {
ProcessInfo processInfo;
processInfo.pkgName = std::string(DM_PKG_NAME);
processInfo.userId = item;
processInfos.push_back(processInfo);
}
}
return processInfos;
}
DM_EXPORT std::map<int32_t, int32_t> DeviceProfileConnector::GetUserIdAndBindLevel(
const std::string &localUdid, const std::string &peerUdid)
{
LOGI("localUdid %{public}s, peerUdid %{public}s.", GetAnonyString(localUdid).c_str(),
GetAnonyString(peerUdid).c_str());
std::vector<AccessControlProfile> profiles = GetAllAccessControlProfile();
std::map<int32_t, int32_t> userIdAndBindLevel;
for (const auto &item : profiles) {
if (IsLnnAcl(item)) {
continue;
}
std::string accesserUdid = item.GetAccesser().GetAccesserDeviceId();
std::string accesseeUdid = item.GetAccessee().GetAccesseeDeviceId();
int32_t accesserUserid = item.GetAccesser().GetAccesserUserId();
int32_t accesseeUserid = item.GetAccessee().GetAccesseeUserId();
if (accesserUdid == localUdid && accesseeUdid == peerUdid) {
if (userIdAndBindLevel.find(accesserUserid) == userIdAndBindLevel.end()) {
userIdAndBindLevel[accesserUserid] = static_cast<int32_t>(item.GetBindLevel());
} else {
userIdAndBindLevel[accesserUserid] =
std::min(static_cast<int32_t>(item.GetBindLevel()), userIdAndBindLevel[accesserUserid]);
}
} else if (accesseeUdid == localUdid && accesserUdid == peerUdid) {
if (userIdAndBindLevel.find(accesseeUserid) == userIdAndBindLevel.end()) {
userIdAndBindLevel[accesseeUserid] = static_cast<int32_t>(item.GetBindLevel());
} else {
userIdAndBindLevel[accesseeUserid] =
std::min(static_cast<int32_t>(item.GetBindLevel()), userIdAndBindLevel[accesseeUserid]);
}
}
}
return userIdAndBindLevel;
}
DM_EXPORT void DeviceProfileConnector::UpdateACL(std::string &localUdid,
const std::vector<int32_t> &localUserIds, const std::string &remoteUdid,
const std::vector<int32_t> &remoteFrontUserIds, const std::vector<int32_t> &remoteBackUserIds,
DmOfflineParam &offlineParam)
{
LOGI("localUdid %{public}s, remoteUdid %{public}s.", GetAnonyString(localUdid).c_str(),
GetAnonyString(remoteUdid).c_str());
std::vector<AccessControlProfile> profiles = GetAllAclIncludeLnnAcl();
for (auto item : profiles) {
DeleteSigTrustACL(item, remoteUdid, remoteFrontUserIds, remoteBackUserIds, offlineParam);
UpdatePeerUserId(item, localUdid, localUserIds, remoteUdid, remoteFrontUserIds);
}
}
void DeviceProfileConnector::DeleteSigTrustACL(AccessControlProfile profile, const std::string &remoteUdid,
const std::vector<int32_t> &remoteFrontUserIds, const std::vector<int32_t> &remoteBackUserIds,
DmOfflineParam &offlineParam)
{
LOGI("start.");
std::string accesserUdid = profile.GetAccesser().GetAccesserDeviceId();
std::string accesseeUdid = profile.GetAccessee().GetAccesseeDeviceId();
int32_t accesserUserid = profile.GetAccesser().GetAccesserUserId();
int32_t accesseeUserid = profile.GetAccessee().GetAccesseeUserId();
if (accesserUdid == remoteUdid && accesserUserid != 0 && accesserUserid != -1 &&
find(remoteFrontUserIds.begin(), remoteFrontUserIds.end(), accesserUserid) == remoteFrontUserIds.end() &&
find(remoteBackUserIds.begin(), remoteBackUserIds.end(), accesserUserid) == remoteBackUserIds.end()) {
CacheAcerAclId(profile, offlineParam.needDelAclInfos);
return;
}
if (accesseeUdid == remoteUdid && accesseeUserid != 0 && accesseeUserid != -1 &&
find(remoteFrontUserIds.begin(), remoteFrontUserIds.end(), accesseeUserid) == remoteFrontUserIds.end() &&
find(remoteBackUserIds.begin(), remoteBackUserIds.end(), accesseeUserid) == remoteBackUserIds.end()) {
CacheAceeAclId(profile, offlineParam.needDelAclInfos);
return;
}
}
void DeviceProfileConnector::UpdatePeerUserId(AccessControlProfile profile, std::string &localUdid,
const std::vector<int32_t> &localUserIds, const std::string &remoteUdid,
const std::vector<int32_t> &remoteFrontUserIds)
{
LOGI("start.");
if (remoteFrontUserIds.empty() || localUserIds.empty()) {
LOGI("remoteFrontUserIds or localUserIds is empty.");
return;
}
std::string accesserUdid = profile.GetAccesser().GetAccesserDeviceId();
std::string accesseeUdid = profile.GetAccessee().GetAccesseeDeviceId();
int32_t accesserUserid = profile.GetAccesser().GetAccesserUserId();
int32_t accesseeUserid = profile.GetAccessee().GetAccesseeUserId();
uint32_t bindType = profile.GetBindType();
if (accesserUdid == localUdid && accesseeUdid == remoteUdid && bindType == DM_IDENTICAL_ACCOUNT &&
find(localUserIds.begin(), localUserIds.end(), accesserUserid) != localUserIds.end() &&
(accesseeUserid == 0 || accesseeUserid == -1)) {
Accessee accessee = profile.GetAccessee();
accessee.SetAccesseeUserId(remoteFrontUserIds[0]);
profile.SetAccessee(accessee);
DistributedDeviceProfileClient::GetInstance().UpdateAccessControlProfile(profile);
return;
}
}
void DeviceProfileConnector::SetProcessInfoPkgName(const DistributedDeviceProfile::AccessControlProfile &acl,
std::vector<OHOS::DistributedHardware::ProcessInfo> &processInfoVec, bool isAccer)
{
if (IsLnnAcl(acl)) {
return;
}
OHOS::DistributedHardware::ProcessInfo processInfo;
if (isAccer) {
if (acl.GetBindType() == DM_IDENTICAL_ACCOUNT || acl.GetBindLevel() == USER) {
processInfo.pkgName = std::string(DM_PKG_NAME);
} else {
processInfo.pkgName = acl.GetAccesser().GetAccesserBundleName();
processInfo.tokenId = static_cast<uint32_t>(acl.GetAccesser().GetAccesserTokenId());
}
processInfo.userId = acl.GetAccesser().GetAccesserUserId();
} else {
if (acl.GetBindType() == DM_IDENTICAL_ACCOUNT || acl.GetBindLevel() == USER) {
processInfo.pkgName = std::string(DM_PKG_NAME);
} else {
processInfo.pkgName = acl.GetAccessee().GetAccesseeBundleName();
processInfo.tokenId = static_cast<uint32_t>(acl.GetAccessee().GetAccesseeTokenId());
}
processInfo.userId = acl.GetAccessee().GetAccesseeUserId();
}
auto check = [&processInfo](const OHOS::DistributedHardware::ProcessInfo &info) {
return info.pkgName == processInfo.pkgName;
};
if (find_if(processInfoVec.begin(), processInfoVec.end(), check) != processInfoVec.end()) {
return;
}
processInfoVec.emplace_back(processInfo);
}
DM_EXPORT std::multimap<std::string, int32_t> DeviceProfileConnector::GetDevIdAndUserIdByActHash(
const std::string &localUdid, const std::string &peerUdid,
int32_t peerUserId, const std::string &peerAccountHash)
{
LOGI("localUdid %{public}s, peerUdid %{public}s, peerUserId %{public}d, peerAccountHash %{public}s.",
GetAnonyString(localUdid).c_str(), GetAnonyString(peerUdid).c_str(), peerUserId, peerAccountHash.c_str());
std::vector<AccessControlProfile> profiles = GetAllAccessControlProfile();
std::multimap<std::string, int32_t> deviceIdMap;
for (const auto &item : profiles) {
std::string accesserAccountId = item.GetAccesser().GetAccesserAccountId();
std::string accesseeAccountId = item.GetAccessee().GetAccesseeAccountId();
char accesserAccountIdHash[DM_MAX_DEVICE_ID_LEN] = {0};
if (Crypto::GetAccountIdHash(accesserAccountId, reinterpret_cast<uint8_t *>(accesserAccountIdHash)) != DM_OK) {
LOGE("GetAccountHash failed.");
return deviceIdMap;
}
char accesseeAccountIdHash[DM_MAX_DEVICE_ID_LEN] = {0};
if (Crypto::GetAccountIdHash(accesseeAccountId, reinterpret_cast<uint8_t *>(accesseeAccountIdHash)) != DM_OK) {
LOGE("GetAccountHash failed.");
return deviceIdMap;
}
LOGI("accesserAccountIdHash %{public}s, accesseeAccountIdHash %{public}s", accesserAccountIdHash,
accesseeAccountIdHash);
std::string accesserUdid = item.GetAccesser().GetAccesserDeviceId();
std::string accesseeUdid = item.GetAccessee().GetAccesseeDeviceId();
int32_t accesserUserid = item.GetAccesser().GetAccesserUserId();
int32_t accesseeUserid = item.GetAccessee().GetAccesseeUserId();
if (accesserUdid == localUdid && accesseeUdid == peerUdid && accesseeUserid == peerUserId &&
std::string(accesseeAccountIdHash) == peerAccountHash) {
deviceIdMap.insert(std::pair<std::string, int32_t>(accesserUdid, accesserUserid));
continue;
}
if (accesseeUdid == localUdid && accesserUdid == peerUdid && accesserUserid == peerUserId &&
std::string(accesserAccountIdHash) == peerAccountHash) {
deviceIdMap.insert(std::pair<std::string, int32_t>(accesseeUdid, accesseeUserid));
continue;
}
}
return deviceIdMap;
}
DM_EXPORT std::multimap<std::string, int32_t> DeviceProfileConnector::GetDeviceIdAndUserId(
const std::string &localUdid, int32_t localUserId)
{
LOGI("localUdid %{public}s, userId %{public}d.", GetAnonyString(localUdid).c_str(), localUserId);
std::vector<AccessControlProfile> profiles = GetAllAccessControlProfile();
std::multimap<std::string, int32_t> deviceIdMap;
for (const auto &item : profiles) {
std::string accesserDeviceId = item.GetAccesser().GetAccesserDeviceId();
int32_t accesserUserId = item.GetAccesser().GetAccesserUserId();
std::string accesseeDeviceId = item.GetAccessee().GetAccesseeDeviceId();
int32_t accesseeUserId = item.GetAccessee().GetAccesseeUserId();
if (accesserDeviceId == localUdid && accesserUserId == localUserId) {
if (!IsValueExist(deviceIdMap, accesseeDeviceId, accesseeUserId)) {
deviceIdMap.insert(std::pair<std::string, int32_t>(accesseeDeviceId, accesseeUserId));
}
continue;
}
if (accesseeDeviceId == localUdid && accesseeUserId == localUserId) {
if (!IsValueExist(deviceIdMap, accesserDeviceId, accesserUserId)) {
deviceIdMap.insert(std::pair<std::string, int32_t>(accesserDeviceId, accesserUserId));
}
continue;
}
}
return deviceIdMap;
}
void DeviceProfileConnector::HandleSyncBackgroundUserIdEventInner(AccessControlProfile &item,
std::vector<DmUserRemovedServiceInfo> &serviceInfos)
{
if (item.GetStatus() == ACTIVE) {
item.SetStatus(INACTIVE);
DistributedDeviceProfileClient::GetInstance().UpdateAccessControlProfile(item);
if (IsLnnAcl(item)) {
return;
}
DmUserRemovedServiceInfo serviceInfo;
std::string aceeExtraData = item.GetAccessee().GetAccesseeExtraData();
if (aceeExtraData.empty()) {
LOGE("CheckAclByUdidAndTokenIdAndServiceId aceeExtraData is empty.");
return;
}
JsonObject aceeExtJson(aceeExtraData);
if (aceeExtJson.IsDiscarded() || !IsArray(aceeExtJson, "serviceId")) {
LOGE("serviceId is not exist.");
return;
}
JsonItemObject serviceIdItem = aceeExtJson["serviceId"];
serviceIdItem.Get(serviceInfo.serviceIds);
serviceInfo.localTokenId = item.GetAccesser().GetAccesserTokenId();
serviceInfo.localPkgName = item.GetAccesser().GetAccesserBundleName();
serviceInfo.bindType = item.GetBindType();
serviceInfo.peerUdid = item.GetAccessee().GetAccesseeDeviceId();
serviceInfo.peerUserId = item.GetAccessee().GetAccesseeUserId();
serviceInfos.push_back(serviceInfo);
}
}
DM_EXPORT void DeviceProfileConnector::HandleSyncBackgroundUserIdEvent(
const std::vector<int32_t> &remoteUserIds, const std::string &remoteUdid,
const std::vector<int32_t> &localUserIds, std::string &localUdid,
std::vector<DmUserRemovedServiceInfo> &serviceInfos)
{
LOGI("localUdid %{public}s, remoteUdid %{public}s.", GetAnonyString(localUdid).c_str(),
GetAnonyString(remoteUdid).c_str());
std::vector<AccessControlProfile> profiles = GetAllAclIncludeLnnAcl();
for (auto &item : profiles) {
std::string accesserDeviceId = item.GetAccesser().GetAccesserDeviceId();
std::string accesseeDeviceId = item.GetAccessee().GetAccesseeDeviceId();
int32_t accesserUserId = item.GetAccesser().GetAccesserUserId();
int32_t accesseeUserId = item.GetAccessee().GetAccesseeUserId();
if (accesserDeviceId == localUdid && accesseeDeviceId == remoteUdid &&
(find(remoteUserIds.begin(), remoteUserIds.end(), accesseeUserId) != remoteUserIds.end() ||
find(localUserIds.begin(), localUserIds.end(), accesserUserId) == localUserIds.end())) {
HandleSyncBackgroundUserIdEventInner(item, serviceInfos);
} else if ((accesseeDeviceId == localUdid && accesserDeviceId == remoteUdid) &&
(find(remoteUserIds.begin(), remoteUserIds.end(), accesserUserId) != remoteUserIds.end() ||
find(localUserIds.begin(), localUserIds.end(), accesseeUserId) == localUserIds.end())) {
if (item.GetStatus() == ACTIVE) {
item.SetStatus(INACTIVE);
DistributedDeviceProfileClient::GetInstance().UpdateAccessControlProfile(item);
}
}
}
}
DM_EXPORT void DeviceProfileConnector::HandleDeviceUnBind(int32_t bindType,
const std::string &peerUdid, const std::string &localUdid, int32_t localUserId, const std::string &localAccountId)
{
std::vector<DistributedDeviceProfile::AccessControlProfile> profiles =
DeviceProfileConnector::GetInstance().GetAllAccessControlProfile();
if (profiles.empty()) {
LOGI("profiles is empty");
return;
}
for (auto &item : profiles) {
if ((item.GetBindType() == static_cast<uint32_t>(bindType)) &&
item.GetTrustDeviceId() == peerUdid &&
item.GetAccesser().GetAccesserDeviceId() == localUdid &&
item.GetAccesser().GetAccesserUserId() == localUserId &&
item.GetAccesser().GetAccesserAccountId() == localAccountId) {
DeviceProfileConnector::GetInstance().DeleteAccessControlById(item.GetAccessControlId());
}
}
}
DM_EXPORT int32_t DeviceProfileConnector::SubscribeDeviceProfileInited(
sptr<DistributedDeviceProfile::IDpInitedCallback> dpInitedCallback)
{
LOGI("In");
if (dpInitedCallback == nullptr) {
LOGE("dpInitedCallback is nullptr");
return ERR_DM_INPUT_PARA_INVALID;
}
int32_t ret = DistributedDeviceProfileClient::GetInstance().SubscribeDeviceProfileInited(
DISTRIBUTED_HARDWARE_DEVICEMANAGER_SA_ID, dpInitedCallback);
if (ret != DM_OK) {
LOGE("failed: %{public}d", ret);
return ret;
}
return DM_OK;
}
DM_EXPORT int32_t DeviceProfileConnector::UnSubscribeDeviceProfileInited()
{
LOGI("In");
int32_t ret = DistributedDeviceProfileClient::GetInstance().UnSubscribeDeviceProfileInited(
DISTRIBUTED_HARDWARE_DEVICEMANAGER_SA_ID);
if (ret != DM_OK) {
LOGE("failed: %{public}d", ret);
return ret;
}
return DM_OK;
}
DM_EXPORT int32_t DeviceProfileConnector::PutAllTrustedDevices(
const std::vector<DistributedDeviceProfile::TrustedDeviceInfo> &deviceInfos)
{
LOGI("In deviceInfos.size:%{public}zu", deviceInfos.size());
int32_t ret = DistributedDeviceProfileClient::GetInstance().PutAllTrustedDevices(deviceInfos);
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<int32_t> &foregroundUserIds,
const std::vector<int32_t> &backgroundUserIds)
{
if ((profile.GetAccesser().GetAccesserDeviceId() == localUdid &&
(find(backgroundUserIds.begin(), backgroundUserIds.end(), profile.GetAccesser().GetAccesserUserId()) !=
backgroundUserIds.end()) && (profile.GetStatus() == ACTIVE)) ||
(profile.GetAccessee().GetAccesseeDeviceId() == localUdid &&
(find(backgroundUserIds.begin(), backgroundUserIds.end(), profile.GetAccessee().GetAccesseeUserId()) !=
backgroundUserIds.end()) && (profile.GetStatus() == ACTIVE))) {
return true;
}
if ((profile.GetAccesser().GetAccesserDeviceId() == localUdid &&
(find(foregroundUserIds.begin(), foregroundUserIds.end(), profile.GetAccesser().GetAccesserUserId()) !=
foregroundUserIds.end()) && profile.GetStatus() == INACTIVE) ||
(profile.GetAccessee().GetAccesseeDeviceId() == localUdid &&
(find(foregroundUserIds.begin(), foregroundUserIds.end(), profile.GetAccessee().GetAccesseeUserId()) !=
foregroundUserIds.end()) && profile.GetStatus() == INACTIVE)) {
return true;
}
return false;
}
bool DeviceProfileConnector::CheckAclStatusAndForegroundNotMatch(const std::string &localUdid,
const std::vector<int32_t> &foregroundUserIds, const std::vector<int32_t> &backgroundUserIds)
{
std::vector<AccessControlProfile> profiles = GetAllAclIncludeLnnAcl();
LOGI("profiles size is %{public}zu", profiles.size());
for (auto &item : profiles) {
if (CheckAclStatusNotMatch(item, localUdid, foregroundUserIds, backgroundUserIds)) {
return true;
}
}
return false;
}
DM_EXPORT int32_t DeviceProfileConnector::HandleUserSwitched(
const std::string &localUdid, const std::vector<std::string> &deviceVec,
const std::vector<int32_t> &foregroundUserIds, const std::vector<int32_t> &backgroundUserIds)
{
LOGI("OnStart HandleUserSwitched");
if (deviceVec.empty()) {
LOGI("no remote device.");
return DM_OK;
}
std::vector<AccessControlProfile> profiles = GetAllAclIncludeLnnAcl();
std::vector<AccessControlProfile> activeProfiles;
std::vector<AccessControlProfile> inActiveProfiles;
for (auto &item : profiles) {
if (std::find(deviceVec.begin(), deviceVec.end(), item.GetTrustDeviceId()) == deviceVec.end()) {
continue;
}
if ((item.GetAccesser().GetAccesserDeviceId() == localUdid &&
(find(backgroundUserIds.begin(), backgroundUserIds.end(),
item.GetAccesser().GetAccesserUserId()) != backgroundUserIds.end())) ||
(item.GetAccessee().GetAccesseeDeviceId() == localUdid &&
(find(backgroundUserIds.begin(), backgroundUserIds.end(),
item.GetAccessee().GetAccesseeUserId()) != backgroundUserIds.end()))) {
if (item.GetStatus() == ACTIVE) {
item.SetStatus(INACTIVE);
inActiveProfiles.push_back(item);
}
continue;
}
if ((item.GetAccesser().GetAccesserDeviceId() == localUdid &&
(find(foregroundUserIds.begin(), foregroundUserIds.end(),
item.GetAccesser().GetAccesserUserId()) != foregroundUserIds.end()) && item.GetStatus() == INACTIVE) || (
item.GetAccessee().GetAccesseeDeviceId() == localUdid &&
(find(foregroundUserIds.begin(), foregroundUserIds.end(),
item.GetAccessee().GetAccesseeUserId()) != foregroundUserIds.end()) && item.GetStatus() == INACTIVE)) {
item.SetStatus(ACTIVE);
activeProfiles.push_back(item);
continue;
}
}
HandleUserSwitched(activeProfiles, inActiveProfiles);
return DM_OK;
}
int32_t DeviceProfileConnector::HandleUserStop(int32_t stopUserId, const std::string &stopEventUdid)
{
std::vector<AccessControlProfile> profiles = GetAllAclIncludeLnnAcl();
for (auto &item : profiles) {
if ((item.GetAccesser().GetAccesserDeviceId() == stopEventUdid &&
item.GetAccesser().GetAccesserUserId() == stopUserId && item.GetStatus() == ACTIVE) ||
(item.GetAccessee().GetAccesseeDeviceId() == stopEventUdid &&
item.GetAccessee().GetAccesseeUserId() == stopUserId && item.GetStatus() == ACTIVE)) {
item.SetStatus(INACTIVE);
DistributedDeviceProfileClient::GetInstance().UpdateAccessControlProfile(item);
}
}
return DM_OK;
}
int32_t DeviceProfileConnector::HandleUserStop(int32_t stopUserId, const std::string &stopEventUdid,
const std::vector<std::string> &acceptEventUdids)
{
if (acceptEventUdids.empty()) {
LOGI("no remote device.");
return DM_OK;
}
std::vector<AccessControlProfile> profiles = GetAllAclIncludeLnnAcl();
for (auto &item : profiles) {
if (std::find(acceptEventUdids.begin(), acceptEventUdids.end(), item.GetTrustDeviceId()) ==
acceptEventUdids.end()) {
continue;
}
if ((item.GetAccesser().GetAccesserDeviceId() == stopEventUdid &&
item.GetAccesser().GetAccesserUserId() == stopUserId && item.GetStatus() == ACTIVE) ||
(item.GetAccessee().GetAccesseeDeviceId() == stopEventUdid &&
item.GetAccessee().GetAccesseeUserId() == stopUserId && item.GetStatus() == ACTIVE)) {
item.SetStatus(INACTIVE);
DistributedDeviceProfileClient::GetInstance().UpdateAccessControlProfile(item);
}
}
return DM_OK;
}
DM_EXPORT int32_t DeviceProfileConnector::UpdateAclDeviceName(const std::string &udid,
const std::string &newDeviceName, bool isLocal)
{
std::vector<AccessControlProfile> allProfile =
DeviceProfileConnector::GetInstance().GetAllAccessControlProfile();
int32_t localUserId = MultipleUserConnector::GetCurrentAccountUserID();
for (AccessControlProfile profile : allProfile) {
if (!isLocal && profile.GetTrustDeviceId() != udid) {
continue;
}
if (profile.GetStatus() != ACTIVE) {
continue;
}
Accessee acee = profile.GetAccessee();
Accesser acer = profile.GetAccesser();
if (acee.GetAccesseeDeviceId() == udid && ((!isLocal && acer.GetAccesserUserId() == localUserId) ||
(isLocal && acee.GetAccesseeUserId() == localUserId))) {
acee.SetAccesseeDeviceName(newDeviceName);
profile.SetAccessee(acee);
DistributedDeviceProfileClient::GetInstance().UpdateAccessControlProfile(profile);
continue;
}
if (acer.GetAccesserDeviceId() == udid && ((!isLocal && acee.GetAccesseeUserId() == localUserId) ||
(isLocal && acer.GetAccesserUserId() == localUserId))) {
acer.SetAccesserDeviceName(newDeviceName);
profile.SetAccesser(acer);
DistributedDeviceProfileClient::GetInstance().UpdateAccessControlProfile(profile);
continue;
}
}
return DM_OK;
}
DM_EXPORT int32_t DeviceProfileConnector::CheckDeviceInfoPermission(const std::string &localUdid,
const std::string &peerDeviceId)
{
LOGI("Start.");
int32_t localUserId = 0;
uint32_t tempLocalTokenId = 0;
MultipleUserConnector::GetTokenIdAndForegroundUserId(tempLocalTokenId, localUserId);
int64_t localTokenId = static_cast<int64_t>(tempLocalTokenId);
std::string localAccountId = MultipleUserConnector::GetOhosAccountIdByUserId(localUserId);
std::vector<AccessControlProfile> profiles = GetAccessControlProfileByUserId(localUserId);
for (auto &item : profiles) {
if (IsLnnAcl(item)) {
continue;
}
if (item.GetTrustDeviceId() == peerDeviceId) {
if (item.GetBindType() == DM_IDENTICAL_ACCOUNT || item.GetBindLevel() == USER) {
return DM_OK;
}
}
int32_t profileUserId = item.GetAccesser().GetAccesserUserId();
if (item.GetAccesser().GetAccesserDeviceId() == localUdid &&
(profileUserId == localUserId || profileUserId == -1 || profileUserId == 0) &&
item.GetAccesser().GetAccesserTokenId() == localTokenId &&
item.GetAccessee().GetAccesseeDeviceId() == peerDeviceId) {
return DM_OK;
}
profileUserId = item.GetAccessee().GetAccesseeUserId();
if (item.GetAccessee().GetAccesseeDeviceId() == localUdid &&
(profileUserId == localUserId || profileUserId == -1 || profileUserId == 0) &&
item.GetAccessee().GetAccesseeTokenId() == localTokenId &&
item.GetAccesser().GetAccesserDeviceId() == peerDeviceId) {
return DM_OK;
}
}
return ERR_DM_NO_PERMISSION;
}
DM_EXPORT int32_t DeviceProfileConnector::PutLocalServiceInfo(
const DistributedDeviceProfile::LocalServiceInfo &localServiceInfo)
{
int32_t ret = DistributedDeviceProfileClient::GetInstance().PutLocalServiceInfo(localServiceInfo);
if (ret != DM_OK) {
LOGE("failed: %{public}d", ret);
return ret;
}
return DM_OK;
}
DM_EXPORT int32_t DeviceProfileConnector::DeleteLocalServiceInfo(const std::string &bundleName, int32_t pinExchangeType)
{
int32_t ret = DistributedDeviceProfileClient::GetInstance().DeleteLocalServiceInfo(bundleName, pinExchangeType);
if (ret != DM_OK) {
LOGE("failed: %{public}d", ret);
return ret;
}
return DM_OK;
}
DM_EXPORT int32_t DeviceProfileConnector::UpdateLocalServiceInfo(
const DistributedDeviceProfile::LocalServiceInfo &localServiceInfo)
{
int32_t ret = DistributedDeviceProfileClient::GetInstance().UpdateLocalServiceInfo(localServiceInfo);
if (ret != DM_OK) {
LOGE("failed: %{public}d", ret);
return ret;
}
return DM_OK;
}
DM_EXPORT int32_t DeviceProfileConnector::GetLocalServiceInfoByBundleNameAndPinExchangeType(
const std::string &bundleName, int32_t pinExchangeType,
DistributedDeviceProfile::LocalServiceInfo &localServiceInfo)
{
LOGI("getLocalServiceInfo bundleName = %{public}s, pinExchangeType = %{public}d",
bundleName.c_str(), pinExchangeType);
int32_t ret = DistributedDeviceProfileClient::GetInstance().GetLocalServiceInfoByBundleAndPinType(bundleName,
pinExchangeType, localServiceInfo);
if (ret != DM_OK) {
LOGE("failed: %{public}d", ret);
return ret;
}
return DM_OK;
}
int32_t DeviceProfileConnector::PutSessionKey(int32_t userId, const std::vector<unsigned char> &sessionKeyArray,
int32_t &sessionKeyId)
{
if (sessionKeyArray.empty() || sessionKeyArray.size() > MAX_SESSION_KEY_LENGTH) {
LOGE("SessionKey size invalid");
return ERR_DM_FAILED;
}
int32_t ret = DistributedDeviceProfileClient::GetInstance().PutSessionKey(static_cast<uint32_t>(userId),
sessionKeyArray, sessionKeyId);
if (ret != DM_OK) {
LOGE("failed: %{public}d", ret);
return ret;
}
return DM_OK;
}
int32_t DeviceProfileConnector::DeleteSessionKey(int32_t userId, int32_t sessionKeyId)
{
int32_t ret =
DistributedDeviceProfileClient::GetInstance().DeleteSessionKey(static_cast<uint32_t>(userId), sessionKeyId);
if (ret != DM_OK) {
LOGE("failed: %{public}d", ret);
return ret;
}
return DM_OK;
}
int32_t DeviceProfileConnector::GetSessionKey(int32_t userId, int32_t sessionKeyId,
std::vector<unsigned char> &sessionKeyArray)
{
int32_t ret = DistributedDeviceProfileClient::GetInstance().GetSessionKey(static_cast<uint32_t>(userId),
sessionKeyId, sessionKeyArray);
if (ret != DM_OK) {
LOGE("failed: %{public}d", ret);
return ret;
}
return DM_OK;
}
DM_EXPORT bool DeviceProfileConnector::IsLnnAcl(const DistributedDeviceProfile::AccessControlProfile &profile)
{
std::string extraData = profile.GetExtraData();
if (extraData.empty()) {
return false;
}
JsonObject extJson(extraData);
if (extJson.IsDiscarded() || !IsString(extJson, ACL_IS_LNN_ACL_KEY)) {
return false;
}
std::string isLnnAclStr = extJson[ACL_IS_LNN_ACL_KEY].Get<std::string>();
std::string isLnnAclTrue = std::string(ACL_IS_LNN_ACL_VAL_TRUE);
return isLnnAclStr == isLnnAclTrue;
}
DM_EXPORT void DeviceProfileConnector::CacheAcerAclId(const DistributedDeviceProfile::AccessControlProfile &profile,
std::vector<DmAclIdParam> &aclInfos)
{
DmAclIdParam dmAclIdParam;
dmAclIdParam.udid = profile.GetAccesser().GetAccesserDeviceId();
dmAclIdParam.userId = profile.GetAccesser().GetAccesserUserId();
dmAclIdParam.skId = profile.GetAccesser().GetAccesserSessionKeyId();
dmAclIdParam.credId = profile.GetAccesser().GetAccesserCredentialIdStr();
dmAclIdParam.tokenIds.insert(profile.GetAccessee().GetAccesseeTokenId());
dmAclIdParam.tokenIds.insert(profile.GetAccesser().GetAccesserTokenId());
dmAclIdParam.pkgName = profile.GetAccesser().GetAccesserBundleName();
dmAclIdParam.accessControlId = profile.GetAccessControlId();
aclInfos.push_back(dmAclIdParam);
}
DM_EXPORT void DeviceProfileConnector::CacheAceeAclId(const DistributedDeviceProfile::AccessControlProfile &profile,
std::vector<DmAclIdParam> &aclInfos)
{
DmAclIdParam dmAclIdParam;
dmAclIdParam.udid = profile.GetAccessee().GetAccesseeDeviceId();
dmAclIdParam.userId = profile.GetAccessee().GetAccesseeUserId();
dmAclIdParam.skId = profile.GetAccessee().GetAccesseeSessionKeyId();
dmAclIdParam.credId = profile.GetAccessee().GetAccesseeCredentialIdStr();
dmAclIdParam.tokenIds.insert(profile.GetAccessee().GetAccesseeTokenId());
dmAclIdParam.tokenIds.insert(profile.GetAccesser().GetAccesserTokenId());
dmAclIdParam.accessControlId = profile.GetAccessControlId();
dmAclIdParam.pkgName = profile.GetAccessee().GetAccesseeBundleName();
aclInfos.push_back(dmAclIdParam);
}
DmUserRemovedServiceInfo ParseServiceInfoForProfile(const AccessControlProfile &item, bool isActive)
{
DmUserRemovedServiceInfo serviceInfo;
std::string aceeExtraData = item.GetAccessee().GetAccesseeExtraData();
if (aceeExtraData.empty()) {
LOGE("CheckAclByUdidAndTokenIdAndServiceId aceeExtraData is empty.");
return serviceInfo;
}
JsonObject aceeExtJson(aceeExtraData);
if (aceeExtJson.IsDiscarded() || !IsArray(aceeExtJson, "serviceId")) {
LOGE("serviceId is not exist.");
return serviceInfo;
}
JsonItemObject serviceIdItem = aceeExtJson["serviceId"];
serviceIdItem.Get(serviceInfo.serviceIds);
serviceInfo.localTokenId = item.GetAccesser().GetAccesserTokenId();
serviceInfo.localPkgName = item.GetAccesser().GetAccesserBundleName();
serviceInfo.bindType = item.GetBindType();
serviceInfo.peerUdid = item.GetAccessee().GetAccesseeDeviceId();
serviceInfo.peerUserId = item.GetAccessee().GetAccesseeUserId();
serviceInfo.isActive = isActive;
return serviceInfo;
}
bool IsProfileForBackgroundUser(const AccessControlProfile &item, const std::string &localUdid,
const std::vector<int32_t> &foregroundUserIds)
{
if (item.GetAccesser().GetAccesserDeviceId() == localUdid &&
std::find(foregroundUserIds.begin(), foregroundUserIds.end(), item.GetAccesser().GetAccesserUserId()) ==
foregroundUserIds.end()) {
return true;
}
if (item.GetAccessee().GetAccesseeDeviceId() == localUdid &&
std::find(foregroundUserIds.begin(), foregroundUserIds.end(), item.GetAccessee().GetAccesseeUserId()) ==
foregroundUserIds.end()) {
return true;
}
return false;
}
bool IsProfileForForegroundUser(const AccessControlProfile &item, const std::string &localUdid,
const std::vector<int32_t> &foregroundUserIds)
{
if (item.GetAccesser().GetAccesserDeviceId() == localUdid &&
std::find(foregroundUserIds.begin(), foregroundUserIds.end(), item.GetAccesser().GetAccesserUserId()) !=
foregroundUserIds.end()) {
return true;
}
if (item.GetAccessee().GetAccesseeDeviceId() == localUdid &&
std::find(foregroundUserIds.begin(), foregroundUserIds.end(), item.GetAccessee().GetAccesseeUserId()) !=
foregroundUserIds.end()) {
return true;
}
return false;
}
DM_EXPORT int32_t DeviceProfileConnector::HandleAccountCommonEvent(const std::string &localUdid,
const std::vector<std::string> &deviceVec, const std::vector<int32_t> &foregroundUserIds,
const std::vector<int32_t> &backgroundUserIds, std::vector<DmUserRemovedServiceInfo> &serviceInfos)
{
LOGI("start, foregroundUserIds: %{public}s, backgroundUserIds: %{public}s",
GetIntegerList(foregroundUserIds).c_str(), GetIntegerList(backgroundUserIds).c_str());
if (deviceVec.empty()) {
LOGI("no remote device.");
return DM_OK;
}
std::vector<AccessControlProfile> profiles = GetAllAclIncludeLnnAcl();
std::vector<AccessControlProfile> activeProfiles;
std::vector<AccessControlProfile> inActiveProfiles;
for (auto &item : profiles) {
if (std::find(deviceVec.begin(), deviceVec.end(), item.GetTrustDeviceId()) == deviceVec.end()) {
continue;
}
if (IsProfileForBackgroundUser(item, localUdid, foregroundUserIds) && item.GetStatus() == ACTIVE) {
item.SetStatus(INACTIVE);
inActiveProfiles.push_back(item);
if (item.GetAccesser().GetAccesserDeviceId() != localUdid || IsLnnAcl(item)) {
continue;
}
serviceInfos.push_back(ParseServiceInfoForProfile(item, false));
continue;
}
if (IsProfileForForegroundUser(item, localUdid, foregroundUserIds) && item.GetStatus() == INACTIVE) {
item.SetStatus(ACTIVE);
activeProfiles.push_back(item);
if (item.GetAccesser().GetAccesserDeviceId() != localUdid || IsLnnAcl(item)) {
continue;
}
serviceInfos.push_back(ParseServiceInfoForProfile(item, true));
continue;
}
}
for (auto &item : inActiveProfiles) {
DistributedDeviceProfileClient::GetInstance().UpdateAccessControlProfile(item);
}
for (auto &item : activeProfiles) {
DistributedDeviceProfileClient::GetInstance().UpdateAccessControlProfile(item);
}
return DM_OK;
}
DM_EXPORT bool DeviceProfileConnector::CheckSrcAccessControl(const DmAccessCaller &caller, const std::string &srcUdid,
const DmAccessCallee &callee, const std::string &sinkUdid)
{
LOGI("srcUdid %{public}s, srcUserId %{public}d, srcPkgName %{public}s,"
"srcAccountId %{public}s, sinkUdid %{public}s, sinkUserId %{public}d, sinkPkgName %{public}s,"
"sinkAccountId %{public}s, callerTokenId %{public}s, calleeTokenId %{public}s.",
GetAnonyString(srcUdid).c_str(), caller.userId,
caller.pkgName.c_str(), GetAnonyString(caller.accountId).c_str(),
GetAnonyString(sinkUdid).c_str(), callee.userId, callee.pkgName.c_str(),
GetAnonyString(callee.accountId).c_str(), GetAnonyUint64(caller.tokenId).c_str(),
GetAnonyUint64(callee.tokenId).c_str());
if (!CheckUserIdIsForegroundUserId(caller.userId)) {
LOGI("srcUserId = %{public}d is not foregroundUserId", caller.userId);
return false;
}
std::vector<AccessControlProfile> profiles = GetAllAccessControlProfile();
std::string localUdid = GetLocalDeviceId();
std::string trustUdid = (localUdid == srcUdid ? sinkUdid : srcUdid);
for (const auto &item : profiles) {
PrintProfile(item);
if (item.GetTrustDeviceId() != trustUdid) {
continue;
}
switch (item.GetBindType()) {
case DM_IDENTICAL_ACCOUNT:
if (CheckSrcAcuntAccessControl(item, caller, srcUdid, callee, sinkUdid)) {
return true;
}
break;
case DM_SHARE:
if (CheckSrcShareAccessControl(item, caller, srcUdid, callee, sinkUdid)) {
return true;
}
break;
case DM_POINT_TO_POINT:
case DM_ACROSS_ACCOUNT:
if (CheckSrcP2PAccessControl(item, caller, srcUdid, callee, sinkUdid)) {
return true;
}
break;
default:
break;
}
}
return false;
}
bool DeviceProfileConnector::CheckSrcAcuntAccessControl(const DistributedDeviceProfile::AccessControlProfile &profile,
const DmAccessCaller &caller, const std::string &srcUdid, const DmAccessCallee &callee, const std::string &sinkUdid)
{
std::string acerDeviceId = profile.GetAccesser().GetAccesserDeviceId();
int32_t acerUserId = profile.GetAccesser().GetAccesserUserId();
std::string aceeDeviceId = profile.GetAccessee().GetAccesseeDeviceId();
int32_t aceeUserId = profile.GetAccessee().GetAccesseeUserId();
if (srcUdid == acerDeviceId && caller.userId == acerUserId && sinkUdid == aceeDeviceId) {
return true;
}
if (srcUdid == aceeDeviceId && caller.userId == aceeUserId && sinkUdid == acerDeviceId) {
return true;
}
return false;
}
bool DeviceProfileConnector::CheckSrcShareAccessControl(const DistributedDeviceProfile::AccessControlProfile &profile,
const DmAccessCaller &caller, const std::string &srcUdid, const DmAccessCallee &callee, const std::string &sinkUdid)
{
std::string acerDeviceId = profile.GetAccesser().GetAccesserDeviceId();
int32_t acerUserId = profile.GetAccesser().GetAccesserUserId();
std::string acerAccountId = profile.GetAccesser().GetAccesserAccountId();
std::string aceeDeviceId = profile.GetAccessee().GetAccesseeDeviceId();
if (srcUdid == acerDeviceId && caller.userId == acerUserId && caller.accountId == acerAccountId &&
sinkUdid == aceeDeviceId) {
return true;
}
return false;
}
bool DeviceProfileConnector::CheckSrcP2PAccessControl(const DistributedDeviceProfile::AccessControlProfile &profile,
const DmAccessCaller &caller, const std::string &srcUdid, const DmAccessCallee &callee, const std::string &sinkUdid)
{
std::string acerDeviceId = profile.GetAccesser().GetAccesserDeviceId();
int32_t acerUserId = profile.GetAccesser().GetAccesserUserId();
int32_t acerTokenId = static_cast<int32_t>(profile.GetAccesser().GetAccesserTokenId());
std::string acerPkgName = profile.GetAccesser().GetAccesserBundleName();
std::string aceeDeviceId = profile.GetAccessee().GetAccesseeDeviceId();
int32_t aceeUserId = profile.GetAccessee().GetAccesseeUserId();
int32_t aceeTokenId = static_cast<int32_t>(profile.GetAccessee().GetAccesseeTokenId());
std::string aceePkgName = profile.GetAccessee().GetAccesseeBundleName();
uint32_t bindLevel = profile.GetBindLevel();
switch (bindLevel) {
case USER:
if (srcUdid == acerDeviceId && caller.userId == acerUserId && sinkUdid == aceeDeviceId) {
return true;
}
if (srcUdid == aceeDeviceId && caller.userId == aceeUserId && sinkUdid == acerDeviceId) {
return true;
}
break;
case SERVICE:
case APP:
if (srcUdid == acerDeviceId && caller.userId == acerUserId &&
static_cast<int32_t>(caller.tokenId) == acerTokenId && sinkUdid == aceeDeviceId) {
return true;
}
if (srcUdid == aceeDeviceId && caller.userId == aceeUserId &&
static_cast<int32_t>(caller.tokenId) == aceeTokenId && sinkUdid == acerDeviceId) {
return true;
}
break;
default:
LOGE("invalid bindLevel %{public}d.", bindLevel);
break;
}
return false;
}
DM_EXPORT bool DeviceProfileConnector::CheckSinkAccessControl(const DmAccessCaller &caller, const std::string &srcUdid,
const DmAccessCallee &callee, const std::string &sinkUdid)
{
LOGI("srcUdid %{public}s, srcUserId %{public}d, srcPkgName %{public}s,"
"srcAccountId %{public}s, sinkUdid %{public}s, sinkUserId %{public}d, sinkPkgName %{public}s,"
"sinkAccountId %{public}s.", GetAnonyString(srcUdid).c_str(), caller.userId,
caller.pkgName.c_str(), GetAnonyString(caller.accountId).c_str(),
GetAnonyString(sinkUdid).c_str(), callee.userId, callee.pkgName.c_str(),
GetAnonyString(callee.accountId).c_str());
if (!CheckUserIdIsForegroundUserId(callee.userId)) {
LOGI("sinkUserId = %{public}d is not ForegroundUserId", callee.userId);
return false;
}
std::vector<AccessControlProfile> profiles = GetAllAccessControlProfile();
std::string localUdid = GetLocalDeviceId();
std::string trustUdid = (localUdid == srcUdid ? sinkUdid : srcUdid);
for (const auto &item : profiles) {
PrintProfile(item);
if (item.GetTrustDeviceId() != trustUdid) {
continue;
}
switch (item.GetBindType()) {
case DM_IDENTICAL_ACCOUNT:
if (CheckSinkAcuntAccessControl(item, caller, srcUdid, callee, sinkUdid)) {
return true;
}
break;
case DM_SHARE:
if (CheckSinkShareAccessControl(item, caller, srcUdid, callee, sinkUdid)) {
return true;
}
break;
case DM_POINT_TO_POINT:
case DM_ACROSS_ACCOUNT:
if (CheckSinkP2PAccessControl(item, caller, srcUdid, callee, sinkUdid)) {
return true;
}
break;
default:
break;
}
}
return false;
}
bool DeviceProfileConnector::CheckSinkAcuntAccessControl(const DistributedDeviceProfile::AccessControlProfile &profile,
const DmAccessCaller &caller, const std::string &srcUdid, const DmAccessCallee &callee, const std::string &sinkUdid)
{
std::string acerDeviceId = profile.GetAccesser().GetAccesserDeviceId();
int32_t acerUserId = profile.GetAccesser().GetAccesserUserId();
std::string aceeDeviceId = profile.GetAccessee().GetAccesseeDeviceId();
int32_t aceeUserId = profile.GetAccessee().GetAccesseeUserId();
if (srcUdid == acerDeviceId && caller.userId == acerUserId &&
sinkUdid == aceeDeviceId && callee.userId == aceeUserId && caller.accountId == callee.accountId) {
return true;
}
if (srcUdid == aceeDeviceId && caller.userId == aceeUserId &&
sinkUdid == acerDeviceId && callee.userId == acerUserId && caller.accountId == callee.accountId) {
return true;
}
return false;
}
bool DeviceProfileConnector::CheckSinkShareAccessControl(const DistributedDeviceProfile::AccessControlProfile &profile,
const DmAccessCaller &caller, const std::string &srcUdid, const DmAccessCallee &callee, const std::string &sinkUdid)
{
std::string acerDeviceId = profile.GetAccesser().GetAccesserDeviceId();
int32_t acerUserId = profile.GetAccesser().GetAccesserUserId();
std::string acerAccountId = profile.GetAccesser().GetAccesserAccountId();
std::string aceeDeviceId = profile.GetAccessee().GetAccesseeDeviceId();
int32_t aceeUserId = profile.GetAccessee().GetAccesseeUserId();
std::string aceeAccountId = profile.GetAccessee().GetAccesseeAccountId();
if (srcUdid == acerDeviceId && caller.userId == acerUserId && caller.accountId == acerAccountId &&
sinkUdid == aceeDeviceId && callee.userId == aceeUserId && callee.accountId == aceeAccountId) {
return true;
}
return false;
}
bool DeviceProfileConnector::CheckSinkP2PAccessControl(const DistributedDeviceProfile::AccessControlProfile &profile,
const DmAccessCaller &caller, const std::string &srcUdid, const DmAccessCallee &callee, const std::string &sinkUdid)
{
uint32_t bindLevel = profile.GetBindLevel();
switch (bindLevel) {
case USER:
if (CheckSinkUserP2PAcl(profile, caller, srcUdid, callee, sinkUdid)) {
return true;
}
break;
case SERVICE:
case APP:
if (CheckSinkAppOrServiceP2PAcl(profile, caller, srcUdid, callee, sinkUdid)) {
return true;
}
break;
default:
LOGE("invalid bindLevel %{public}d.", bindLevel);
break;
}
return false;
}
bool DeviceProfileConnector::CheckSinkUserP2PAcl(const DistributedDeviceProfile::AccessControlProfile &profile,
const DmAccessCaller &caller, const std::string &srcUdid, const DmAccessCallee &callee,
const std::string &sinkUdid)
{
std::string acerDeviceId = profile.GetAccesser().GetAccesserDeviceId();
int32_t acerUserId = profile.GetAccesser().GetAccesserUserId();
std::string aceeDeviceId = profile.GetAccessee().GetAccesseeDeviceId();
int32_t aceeUserId = profile.GetAccessee().GetAccesseeUserId();
if (srcUdid == acerDeviceId && caller.userId == acerUserId && sinkUdid == aceeDeviceId &&
callee.userId == aceeUserId) {
return true;
}
if (srcUdid == aceeDeviceId && caller.userId == aceeUserId && sinkUdid == acerDeviceId &&
callee.userId == acerUserId) {
return true;
}
return false;
}
bool DeviceProfileConnector::CheckSinkAppOrServiceP2PAcl(const DistributedDeviceProfile::AccessControlProfile &profile,
const DmAccessCaller &caller, const std::string &srcUdid, const DmAccessCallee &callee,
const std::string &sinkUdid)
{
std::string acerDeviceId = profile.GetAccesser().GetAccesserDeviceId();
int32_t acerUserId = profile.GetAccesser().GetAccesserUserId();
int32_t acerTokenId = static_cast<int32_t>(profile.GetAccesser().GetAccesserTokenId());
std::string aceeDeviceId = profile.GetAccessee().GetAccesseeDeviceId();
int32_t aceeUserId = profile.GetAccessee().GetAccesseeUserId();
int32_t aceeTokenId = static_cast<int32_t>(profile.GetAccessee().GetAccesseeTokenId());
if (srcUdid == acerDeviceId && caller.userId == acerUserId &&
static_cast<int32_t>(caller.tokenId) == acerTokenId && sinkUdid == aceeDeviceId &&
callee.userId == aceeUserId && static_cast<int32_t>(callee.tokenId) == aceeTokenId) {
return true;
}
if (srcUdid == aceeDeviceId && caller.userId == aceeUserId &&
static_cast<int32_t>(caller.tokenId) == aceeTokenId && sinkUdid == acerDeviceId &&
callee.userId == acerUserId && static_cast<int32_t>(callee.tokenId) == acerTokenId) {
return true;
}
return false;
}
DM_EXPORT bool DeviceProfileConnector::CheckSrcIsSameAccount(const DmAccessCaller &caller, const std::string &srcUdid,
const DmAccessCallee &callee, const std::string &sinkUdid)
{
LOGI("srcUdid %{public}s, srcUserId %{public}d, srcPkgName %{public}s,"
"srcAccountId %{public}s, sinkUdid %{public}s, sinkUserId %{public}d, sinkPkgName %{public}s,"
"sinkAccountId %{public}s, callerTokenId %{public}s, calleeTokenId %{public}s.",
GetAnonyString(srcUdid).c_str(), caller.userId,
caller.pkgName.c_str(), GetAnonyString(caller.accountId).c_str(),
GetAnonyString(sinkUdid).c_str(), callee.userId, callee.pkgName.c_str(),
GetAnonyString(callee.accountId).c_str(), GetAnonyUint64(caller.tokenId).c_str(),
GetAnonyUint64(callee.tokenId).c_str());
if (!CheckUserIdIsForegroundUserId(caller.userId)) {
LOGI("srcUserId = %{public}d is not ForegroundUserId", caller.userId);
return false;
}
std::vector<AccessControlProfile> profiles = GetAllAccessControlProfile();
std::string localUdid = GetLocalDeviceId();
std::string trustUdid = (localUdid == srcUdid ? sinkUdid : srcUdid);
for (const auto &item : profiles) {
PrintProfile(item);
if (item.GetTrustDeviceId() != trustUdid || item.GetBindType() != DM_IDENTICAL_ACCOUNT) {
continue;
}
if (CheckSrcAcuntAccessControl(item, caller, srcUdid, callee, sinkUdid)) {
return true;
}
}
return false;
}
DM_EXPORT bool DeviceProfileConnector::CheckSinkIsSameAccount(const DmAccessCaller &caller, const std::string &srcUdid,
const DmAccessCallee &callee, const std::string &sinkUdid)
{
LOGI("srcUdid %{public}s, srcUserId %{public}d, srcPkgName %{public}s,"
"srcAccountId %{public}s, sinkUdid %{public}s, sinkUserId %{public}d, sinkPkgName %{public}s,"
"sinkAccountId %{public}s, callerTokenId %{public}s, calleeTokenId %{public}s.",
GetAnonyString(srcUdid).c_str(), caller.userId,
caller.pkgName.c_str(), GetAnonyString(caller.accountId).c_str(),
GetAnonyString(sinkUdid).c_str(), callee.userId, callee.pkgName.c_str(),
GetAnonyString(callee.accountId).c_str(), GetAnonyUint64(caller.tokenId).c_str(),
GetAnonyUint64(callee.tokenId).c_str());
if (!CheckUserIdIsForegroundUserId(callee.userId)) {
LOGI("sinkUserId = %{public}d is not ForegroundUserId", callee.userId);
return false;
}
std::vector<AccessControlProfile> profiles = GetAllAccessControlProfile();
std::string localUdid = GetLocalDeviceId();
std::string trustUdid = (localUdid == srcUdid ? sinkUdid : srcUdid);
for (const auto &item : profiles) {
PrintProfile(item);
if (item.GetTrustDeviceId() != trustUdid || item.GetBindType() != DM_IDENTICAL_ACCOUNT) {
continue;
}
if (CheckSinkAcuntAccessControl(item, caller, srcUdid, callee, sinkUdid)) {
return true;
}
}
return false;
}
DM_EXPORT bool DeviceProfileConnector::CheckUserIdIsForegroundUserId(const int32_t userId)
{
std::vector<int32_t> userVec;
int32_t ret = MultipleUserConnector::GetForegroundUserIds(userVec);
if (ret != DM_OK) {
LOGE("GetForegroundUserIds failed, ret = %{public}d", ret);
return false;
}
if (std::find(userVec.begin(), userVec.end(), userId) != userVec.end()) {
return true;
}
LOGE("userId = %{public}d is not foregroundUserId.", userId);
return false;
}
DM_EXPORT void DeviceProfileConnector::DeleteHoDevice(const std::string &peerUdid,
const std::vector<int32_t> &foreGroundUserIds, const std::vector<int32_t> &backGroundUserIds)
{
if (peerUdid.empty() || foreGroundUserIds.empty() || backGroundUserIds.empty()) {
LOGE("invalid input param.");
return;
}
std::vector<int32_t> localUserIds(foreGroundUserIds.begin(), foreGroundUserIds.end());
std::copy(backGroundUserIds.begin(), backGroundUserIds.end(), std::back_inserter(localUserIds));
std::vector<AccessControlProfile> profiles = GetAllAccessControlProfile();
std::string localUdid = GetLocalDeviceId();
for (const auto &item : profiles) {
if (peerUdid != item.GetTrustDeviceId() || item.GetBindType() == DM_IDENTICAL_ACCOUNT) {
continue;
}
std::string acerDeviceId = item.GetAccesser().GetAccesserDeviceId();
int32_t acerUserId = item.GetAccesser().GetAccesserUserId();
std::string acerPkgName = item.GetAccesser().GetAccesserBundleName();
std::string aceeDeviceId = item.GetAccessee().GetAccesseeDeviceId();
int32_t aceeUserId = item.GetAccessee().GetAccesseeUserId();
std::string aceePkgName = item.GetAccessee().GetAccesseeBundleName();
if (localUdid == acerDeviceId && peerUdid == aceeDeviceId && !CheckExtWhiteList(acerPkgName) &&
std::find(localUserIds.begin(), localUserIds.end(), acerUserId) != localUserIds.end()) {
DistributedDeviceProfileClient::GetInstance().DeleteAccessControlProfile(item.GetAccessControlId());
continue;
}
if (peerUdid == acerDeviceId && localUdid == aceeDeviceId && !CheckExtWhiteList(aceePkgName) &&
std::find(localUserIds.begin(), localUserIds.end(), aceeUserId) != localUserIds.end()) {
DistributedDeviceProfileClient::GetInstance().DeleteAccessControlProfile(item.GetAccessControlId());
continue;
}
}
}
DM_EXPORT void DeviceProfileConnector::GetRemoteTokenIds(const std::string &localUdid,
const std::string &udid, std::unordered_set<int64_t> &remoteTokenIds)
{
if (udid.empty() || localUdid.empty() || localUdid == udid) {
LOGE("udid error.");
return;
}
int32_t userId = MultipleUserConnector::GetCurrentAccountUserID();
std::vector<AccessControlProfile> profiles = GetAclProfileByDeviceIdAndUserId(localUdid, userId);
uint64_t peerToken = 0;
for (auto &item : profiles) {
if (item.GetStatus() != ACTIVE) {
continue;
}
if (item.GetAccessee().GetAccesseeDeviceId() == localUdid &&
item.GetAccesser().GetAccesserDeviceId() == udid) {
peerToken = static_cast<uint64_t>(item.GetAccesser().GetAccesserTokenId());
remoteTokenIds.insert(peerToken);
}
if (item.GetAccessee().GetAccesseeDeviceId()== udid &&
item.GetAccesser().GetAccesserDeviceId() == localUdid) {
peerToken = static_cast<uint64_t>(item.GetAccessee().GetAccesseeTokenId());
remoteTokenIds.insert(peerToken);
}
}
}
bool DeviceProfileConnector::CheckExtWhiteList(const std::string &pkgName)
{
LOGI("start pkgName %{public}s.", pkgName.c_str());
if (pkgName.empty()) {
LOGE("bundleName empty.");
return false;
}
for (uint32_t index = 0 ; index < AUTH_EXT_WHITE_LIST_NUM ; index++) {
if (pkgName == g_extWhiteList[index]) {
return true;
}
}
return false;
}
bool DeviceProfileConnector::IsAllowAuthAlways(const std::string &localUdid, int32_t userId,
const std::string &peerUdid, const std::string &pkgName, int64_t tokenId)
{
auto acls = GetAclProfileByDeviceIdAndUserId(localUdid, userId, peerUdid);
for (const auto &item : acls) {
auto accesser = item.GetAccesser();
auto accessee = item.GetAccessee();
if (item.GetAuthenticationType() == ALLOW_AUTH_ALWAYS &&
((accesser.GetAccesserBundleName() == pkgName && accesser.GetAccesserTokenId() == tokenId) ||
(accessee.GetAccesseeBundleName() == pkgName && accessee.GetAccesseeTokenId() == tokenId))) {
return true;
}
}
return false;
}
int32_t DeviceProfileConnector::GetAllAuthOnceAclInfos(
std::unordered_set<AuthOnceAclInfo, AuthOnceAclInfoHash> &aclInfos)
{
std::vector<AccessControlProfile> profiles = GetAllAclIncludeLnnAcl();
for (auto &item : profiles) {
if (item.GetAuthenticationType() != ALLOW_AUTH_ONCE) {
continue;
}
AuthOnceAclInfo aclInfo = { .peerUdid = item.GetTrustDeviceId() };
auto accesser = item.GetAccesser();
auto accessee = item.GetAccessee();
if (accesser.GetAccesserDeviceId() == item.GetTrustDeviceId()) {
aclInfo.peerUserId = accesser.GetAccesserUserId();
aclInfo.localUserId = accessee.GetAccesseeUserId();
aclInfos.insert(aclInfo);
}
if (accessee.GetAccesseeDeviceId() == item.GetTrustDeviceId()) {
aclInfo.peerUserId = accessee.GetAccesseeUserId();
aclInfo.localUserId = accesser.GetAccesserUserId();
aclInfos.insert(aclInfo);
}
}
return DM_OK;
}
void DeviceProfileConnector::DeleteDpInvalidAcl()
{
std::vector<AccessControlProfile> profiles;
int32_t ret = DistributedDeviceProfileClient::GetInstance().GetAllAclIncludeLnnAcl(profiles);
if (ret != DM_OK) {
LOGE("DP failed, ret = %{public}d", ret);
return;
}
for (auto item = profiles.begin(); item != profiles.end(); item++) {
std::string acerAccountId = item->GetAccesser().GetAccesserAccountId();
std::string aceeAccountId = item->GetAccessee().GetAccesseeAccountId();
if (item->GetBindType() == DM_IDENTICAL_ACCOUNT && (acerAccountId == "ohosAnonymousUid" ||
aceeAccountId == "ohosAnonymousUid")) {
PrintProfile(*item);
DistributedDeviceProfileClient::GetInstance().DeleteAccessControlProfile(item->GetAccessControlId());
}
}
}
DM_EXPORT void DeviceProfileConnector::GetAuthTypeByUdidHash(const std::string &udidHash, const std::string &pkgName,
DMLocalServiceInfoAuthType &authType)
{
authType = DMLocalServiceInfoAuthType::CANCEL;
std::vector<AccessControlProfile> acls = GetAccessControlProfile();
for (const auto &acl : acls) {
if (Crypto::GetUdidHash(acl.GetTrustDeviceId()) != udidHash) {
continue;
}
if (acl.GetBindType() == DM_IDENTICAL_ACCOUNT || acl.GetBindType() == DM_SHARE) {
authType = DMLocalServiceInfoAuthType::TRUST_ALWAYS;
return;
}
if ((acl.GetBindType() == DM_POINT_TO_POINT || acl.GetBindType() == DM_ACROSS_ACCOUNT) &&
(acl.GetBindLevel() == USER || acl.GetAccesser().GetAccesserBundleName() == pkgName ||
acl.GetAccessee().GetAccesseeBundleName() == pkgName)) {
if (acl.GetAuthenticationType() == ALLOW_AUTH_ALWAYS) {
authType = DMLocalServiceInfoAuthType::TRUST_ALWAYS;
return;
}
authType = DMLocalServiceInfoAuthType::TRUST_ONETIME;
}
}
}
DM_EXPORT std::unordered_set<int32_t> DeviceProfileConnector::GetActiveAuthOncePeerUserId(const std::string &peerUdid,
int32_t localUserId)
{
std::unordered_set<int32_t> peerUserIds;
std::vector<AccessControlProfile> profiles = GetAccessControlProfileByUserId(localUserId);
for (auto &item : profiles) {
if (item.GetTrustDeviceId() != peerUdid || item.GetStatus() != ACTIVE ||
item.GetAuthenticationType() != ALLOW_AUTH_ONCE) {
continue;
}
auto accesser = item.GetAccesser();
auto accessee = item.GetAccessee();
if (accesser.GetAccesserDeviceId() == peerUdid && accessee.GetAccesseeUserId() == localUserId) {
peerUserIds.insert(accesser.GetAccesserUserId());
}
if (accessee.GetAccesseeDeviceId() == peerUdid && accesser.GetAccesserUserId() == localUserId) {
peerUserIds.insert(accessee.GetAccesseeUserId());
}
}
return peerUserIds;
}
DM_EXPORT std::unordered_set<AuthOnceAclInfo, AuthOnceAclInfoHash> DeviceProfileConnector::GetAuthOnceAclInfos(
const std::string &peerUdid)
{
std::unordered_set<AuthOnceAclInfo, AuthOnceAclInfoHash> authOnceAclInfos;
std::vector<AccessControlProfile> profiles = GetAllAccessControlProfile();
for (auto &item : profiles) {
if (item.GetTrustDeviceId() != peerUdid || item.GetAuthenticationType() != ALLOW_AUTH_ONCE) {
continue;
}
auto accesser = item.GetAccesser();
auto accessee = item.GetAccessee();
int32_t localUserId = 0;
int32_t peerUserId = 0;
if (accesser.GetAccesserDeviceId() == peerUdid) {
localUserId = accessee.GetAccesseeUserId();
peerUserId = accesser.GetAccesserUserId();
}
if (accessee.GetAccesseeDeviceId() == peerUdid) {
localUserId = accesser.GetAccesserUserId();
peerUserId = accessee.GetAccesseeUserId();
}
if (localUserId != 0 && peerUserId != 0) {
authOnceAclInfos.insert({ .peerUdid = peerUdid, .peerUserId = peerUserId, .localUserId = localUserId });
}
}
return authOnceAclInfos;
}
DM_EXPORT bool DeviceProfileConnector::AuthOnceAclIsActive(const std::string &peerUdid, int32_t peerUserId,
int32_t localUserId)
{
std::vector<AccessControlProfile> profiles = GetAccessControlProfileByUserId(localUserId);
for (auto &item : profiles) {
if (item.GetTrustDeviceId() != peerUdid || item.GetAuthenticationType() != ALLOW_AUTH_ONCE) {
continue;
}
if (MatchAccesserByBothUserIdAndPeerUdid(peerUdid, peerUserId, localUserId, item) ||
MatchAccesseeByBothUserIdAndPeerUdid(peerUdid, peerUserId, localUserId, item)) {
return item.GetStatus() == ACTIVE;
}
}
return false;
}
DM_EXPORT int32_t DeviceProfileConnector::GetServiceInfoByUdidAndServiceId(const std::string &udid, int64_t serviceId,
DistributedDeviceProfile::ServiceInfo &serviceInfo)
{
LOGI("start");
DistributedDeviceProfile::UserInfo userInfo;
userInfo.udid = udid;
std::vector<DistributedDeviceProfile::ServiceInfo> dpServiceInfos;
int32_t ret = DistributedDeviceProfileClient::GetInstance().GetServiceInfosByUserInfo(
userInfo, dpServiceInfos);
if (ret != DM_OK) {
LOGE("GetServiceInfosByUdidAndServiceId failed, result: %{public}d", ret);
if (ret == DP_NOT_FIND_DATA) {
ret = ERR_DM_SERVICE_INFO_NOT_EXIST;
}
return ret;
}
for (auto &dpServiceInfo : dpServiceInfos) {
if (dpServiceInfo.GetServiceId() == serviceId) {
serviceInfo = dpServiceInfo;
return DM_OK;
}
}
LOGE("GetServiceInfosByUdidAndServiceId failed, udid not match");
return ERR_DM_SERVICE_INFO_NOT_EXIST;
}
DM_EXPORT int32_t DeviceProfileConnector::GetServiceInfosByUdidAndUserId(const std::string &udid, int32_t userId,
std::vector<DistributedDeviceProfile::ServiceInfo> &serviceInfos)
{
LOGI("start");
DistributedDeviceProfile::UserInfo userInfo;
userInfo.udid = udid;
userInfo.userId = userId;
int32_t ret = DistributedDeviceProfileClient::GetInstance().GetServiceInfosByUserInfo(
userInfo, serviceInfos);
if (ret != DM_OK) {
LOGE("ret: %{public}d", ret);
if (ret == DP_NOT_FIND_DATA) {
ret = ERR_DM_SERVICE_INFO_NOT_EXIST;
}
return ret;
}
return DM_OK;
}
DM_EXPORT int32_t DeviceProfileConnector::PutServiceInfo(const DistributedDeviceProfile::ServiceInfo &serviceInfo)
{
LOGI("start");
int32_t ret = DistributedDeviceProfileClient::GetInstance().PutServiceInfo(serviceInfo);
if (ret != DM_OK) {
LOGE("result: %{public}d", ret);
return ret;
}
LOGI("success");
return DM_OK;
}
DM_EXPORT int32_t DeviceProfileConnector::DeleteServiceInfo(const DistributedDeviceProfile::ServiceInfo &serviceInfo)
{
LOGI("start");
DistributedDeviceProfile::UserInfo userInfo;
userInfo.udid = serviceInfo.GetUdid();
userInfo.userId = serviceInfo.GetUserId();
userInfo.serviceId = serviceInfo.GetServiceId();
int32_t ret = DistributedDeviceProfileClient::GetInstance().DeleteServiceInfo(userInfo);
if (ret != DM_OK) {
LOGE("result: %{public}d", ret);
return ret;
}
LOGI("success");
return DM_OK;
}
DM_EXPORT int32_t DeviceProfileConnector::GetServiceInfosByUdid(const std::string &udid,
std::vector<DistributedDeviceProfile::ServiceInfo> &serviceInfos)
{
DistributedDeviceProfile::UserInfo userInfo;
userInfo.udid = udid;
int32_t ret = DistributedDeviceProfileClient::GetInstance().GetServiceInfosByUserInfo(
userInfo, serviceInfos);
if (ret != DM_OK) {
LOGE("result: %{public}d", ret);
return ret;
}
LOGI("success");
return DM_OK;
}
DM_EXPORT void DeviceProfileConnector::GetPeerTokenIdForServiceProxyUnbind(int32_t userId, uint64_t localTokenId,
const std::string &peerUdid, int64_t serviceId, std::vector<uint64_t> &peerTokenId)
{
char localUdid[DEVICE_UUID_LENGTH] = {0};
GetDevUdid(localUdid, DEVICE_UUID_LENGTH);
std::vector<DistributedDeviceProfile::AccessControlProfile> profiles = GetAllAccessControlProfile();
for (const auto& profile : profiles) {
if (profile.GetAccesser().GetAccesserUserId() == userId &&
static_cast<uint64_t>(profile.GetAccesser().GetAccesserTokenId()) == localTokenId &&
profile.GetAccesser().GetAccesserDeviceId() == std::string(localUdid) &&
profile.GetAccessee().GetAccesseeDeviceId() == peerUdid &&
HasServiceId(profile, serviceId)) {
peerTokenId.push_back(static_cast<uint64_t>(profile.GetAccessee().GetAccesseeTokenId()));
break;
}
if (profile.GetAccessee().GetAccesseeUserId() == userId &&
static_cast<uint64_t>(profile.GetAccessee().GetAccesseeTokenId()) == localTokenId &&
profile.GetAccessee().GetAccesseeDeviceId() == std::string(localUdid) &&
profile.GetAccesser().GetAccesserDeviceId() == peerUdid &&
HasServiceId(profile, serviceId)) {
peerTokenId.push_back(static_cast<uint64_t>(profile.GetAccesser().GetAccesserTokenId()));
break;
}
}
}
bool DeviceProfileConnector::HasServiceId(const DistributedDeviceProfile::AccessControlProfile &profile,
int64_t serviceId)
{
LOGI("start.");
std::string aceeExtraData = profile.GetAccessee().GetAccesseeExtraData();
if (aceeExtraData.empty()) {
LOGE("CheckAclByUdidAndTokenIdAndServiceId aceeExtraData is empty.");
return false;
}
JsonObject aceeExtJson(aceeExtraData);
if (aceeExtJson.IsDiscarded() || !IsArray(aceeExtJson, "serviceId")) {
LOGE("serviceId is not exist.");
return false;
}
JsonItemObject serviceIdItem = aceeExtJson["serviceId"];
std::vector<int64_t> aceeServiceId;
serviceIdItem.Get(aceeServiceId);
auto it = std::find(aceeServiceId.begin(), aceeServiceId.end(), serviceId);
if (it != aceeServiceId.end()) {
return true;
}
return false;
}
int32_t DeviceProfileConnector::FillDmUserRemovedServiceInfoRemote(
const DistributedDeviceProfile::AccessControlProfile &item,
std::vector<DmUserRemovedServiceInfo> &serviceInfos)
{
LOGI("start.");
DmUserRemovedServiceInfo serviceInfo;
serviceInfo.localTokenId = item.GetAccesser().GetAccesserTokenId();
serviceInfo.localPkgName = item.GetAccesser().GetAccesserBundleName();
serviceInfo.bindType = item.GetBindType();
serviceInfo.peerUdid = item.GetAccessee().GetAccesseeDeviceId();
serviceInfo.peerUserId = item.GetAccessee().GetAccesseeUserId();
if (item.GetBindType() == DM_POINT_TO_POINT) {
std::string aceeExtraData = item.GetAccessee().GetAccesseeExtraData();
if (aceeExtraData.empty()) {
LOGE("aceeExtraData is empty.");
return ERR_DM_FAILED;
}
JsonObject aceeExtJson(aceeExtraData);
if (aceeExtJson.IsDiscarded() || !IsArray(aceeExtJson, "serviceId")) {
LOGE("serviceId is not exist.");
return ERR_DM_FAILED;
}
JsonItemObject serviceIdItem = aceeExtJson["serviceId"];
serviceIdItem.Get(serviceInfo.serviceIds);
} else if (item.GetBindType() == DM_IDENTICAL_ACCOUNT) {
serviceInfo.serviceIds = {DM_DEFAULT_SERVICE_ID};
}
serviceInfos.push_back(serviceInfo);
return DM_OK;
}
void DeviceProfileConnector::FillDmUserRemovedServiceInfoLocal(
const DistributedDeviceProfile::AccessControlProfile &item,
std::vector<DmUserRemovedServiceInfo> &serviceInfos)
{
if (item.GetBindType() == DM_IDENTICAL_ACCOUNT) {
DmUserRemovedServiceInfo serviceInfo;
serviceInfo.localTokenId = item.GetAccesser().GetAccesserTokenId();
serviceInfo.localPkgName = item.GetAccesser().GetAccesserBundleName();
serviceInfo.bindType = item.GetBindType();
serviceInfo.peerUdid = item.GetAccessee().GetAccesseeDeviceId();
serviceInfo.peerUserId = item.GetAccessee().GetAccesseeUserId();
serviceInfo.serviceIds = {DM_DEFAULT_SERVICE_ID};
serviceInfos.push_back(serviceInfo);
}
}
IDeviceProfileConnector *CreateDpConnectorInstance()
{
return &DeviceProfileConnector::GetInstance();
}
void DeviceProfileConnector::HandleDistributedAccountLogin(const std::string &localUdid, int32_t userId,
const std::string &accountId)
{
LOGI("HandleDistributedAccountLogin: localUdid %{public}s, userId %{public}d, accountId %{public}s",
GetAnonyString(localUdid).c_str(), userId, GetAnonyString(accountId).c_str());
UpdateAclStatusByAccountId(localUdid, userId, accountId, ACTIVE);
}
void DeviceProfileConnector::HandleDistributedAccountUnbound(const std::string &localUdid, int32_t userId,
const std::string &accountId)
{
LOGI("HandleDistributedAccountUnbound: localUdid %{public}s, userId %{public}d, accountId %{public}s",
GetAnonyString(localUdid).c_str(), userId, GetAnonyString(accountId).c_str());
DeleteAclByAccountId(localUdid, userId, accountId);
}
void DeviceProfileConnector::HandleDistributedAccountLogout(const std::string &localUdid, int32_t userId,
const std::string &accountId)
{
LOGI("HandleDistributedAccountLogout: localUdid %{public}s, userId %{public}d, accountId %{public}s",
GetAnonyString(localUdid).c_str(), userId, GetAnonyString(accountId).c_str());
UpdateAclStatusByAccountId(localUdid, userId, accountId, INACTIVE);
}
void DeviceProfileConnector::HandleDistributedAccountLogout(const std::string &localUdid, int32_t userId,
const std::string &accountId, const std::string &peerUdid)
{
LOGI("HandleDistributedAccountLogout: localUdid %{public}s, userId %{public}d, accountId %{public}s,"
"peerUdid %{public}s", GetAnonyString(localUdid).c_str(), userId, GetAnonyString(accountId).c_str(),
GetAnonyString(peerUdid).c_str());
std::vector<AccessControlProfile> profiles = GetAllAclIncludeLnnAcl();
for (const auto &profile : profiles) {
if (CheckAclMatchByAccountId(profile, localUdid, userId, accountId, peerUdid)) {
AccessControlProfile updateProfile = profile;
updateProfile.SetStatus(INACTIVE);
int32_t ret = DistributedDeviceProfileClient::GetInstance().UpdateAccessControlProfile(updateProfile);
if (ret != DM_OK) {
LOGE("UpdateAccessControlProfile failed for accountId %{public}s, peerUdid %{public}s, ret %{public}d",
GetAnonyString(accountId).c_str(), GetAnonyString(peerUdid).c_str(), ret);
}
}
}
}
void DeviceProfileConnector::HandleSubProfileSwitched(const std::string &localUdid, int32_t userId,
int32_t currentSubProfileId, int32_t previousSubProfileId)
{
LOGI("localUdid %{public}s, userId %{public}d, currentSubProfileId %{public}d, "
"previousSubProfileId %{public}d", GetAnonyString(localUdid).c_str(), userId,
currentSubProfileId, previousSubProfileId);
std::string previousAccountId = MultipleUserConnector::GetAccountIdBySubProfileId(userId, previousSubProfileId);
std::string currentAccountId = MultipleUserConnector::GetAccountIdBySubProfileId(userId, currentSubProfileId);
UpdateAclStatusByAccountId(localUdid, userId, previousAccountId, INACTIVE);
UpdateAclStatusByAccountId(localUdid, userId, currentAccountId, ACTIVE);
}
bool DeviceProfileConnector::IsAccountInForeground(int32_t userId, const std::string &accountIdHash,
const std::vector<ForegroundAccountInfo> &foregroundAccounts)
{
for (const auto &account : foregroundAccounts) {
if (account.userId == userId && account.accountId == accountIdHash) {
return true;
}
}
return false;
}
bool DeviceProfileConnector::IsAccountInForegroundByUserId(int32_t userId,
const std::vector<ForegroundAccountInfo> &foregroundAccounts)
{
for (const auto &account : foregroundAccounts) {
if (account.userId == userId) {
return true;
}
}
return false;
}
int32_t DeviceProfileConnector::GetDeviceTypeFromExtraData(const std::string &extraData)
{
if (extraData.empty()) {
return DEVICE_TYPE_UNKNOWN;
}
JsonObject extJson(extraData);
if (!extJson.IsDiscarded() && extJson["deviceType"].IsNumber()) {
return extJson["deviceType"].Get<int32_t>();
}
return DEVICE_TYPE_UNKNOWN;
}
int32_t DeviceProfileConnector::CalculateProfileTargetStatus(const AccessControlProfile &profile,
const std::string &localUdid, const std::string &peerUdid,
const std::vector<ForegroundAccountInfo> &localForegroundAccounts,
const std::vector<ForegroundAccountInfo> &peerForegroundAccounts)
{
std::string accesserUdid = profile.GetAccesser().GetAccesserDeviceId();
std::string accesseeUdid = profile.GetAccessee().GetAccesseeDeviceId();
if ((accesserUdid != localUdid || accesseeUdid != peerUdid) &&
(accesserUdid != peerUdid || accesseeUdid != localUdid)) {
return INVALID_PROFILE_STATUS;
}
char accesserAccountIdHash[DM_MAX_DEVICE_ID_LEN] = {0};
char accesseeAccountIdHash[DM_MAX_DEVICE_ID_LEN] = {0};
if (Crypto::GetAccountIdHash7(profile.GetAccesser().GetAccesserAccountId(),
reinterpret_cast<uint8_t *>(accesserAccountIdHash)) != DM_OK ||
Crypto::GetAccountIdHash7(profile.GetAccessee().GetAccesseeAccountId(),
reinterpret_cast<uint8_t *>(accesseeAccountIdHash)) != DM_OK) {
return INVALID_PROFILE_STATUS;
}
bool localNeedCheckAccountId = true;
bool peerNeedCheckAccountId = true;
bool isP2P = (profile.GetBindType() == DM_POINT_TO_POINT || profile.GetBindType() == DM_ACROSS_ACCOUNT);
if (isP2P) {
int32_t accesserDeviceType = GetDeviceTypeFromExtraData(profile.GetAccesser().GetAccesserExtraData());
int32_t accesseeDeviceType = GetDeviceTypeFromExtraData(profile.GetAccessee().GetAccesseeExtraData());
localNeedCheckAccountId = (accesserUdid == localUdid) ?
(accesserDeviceType == DEVICE_TYPE_CAR) : (accesseeDeviceType == DEVICE_TYPE_CAR);
peerNeedCheckAccountId = (accesserUdid == localUdid) ?
(accesseeDeviceType == DEVICE_TYPE_CAR) : (accesserDeviceType == DEVICE_TYPE_CAR);
}
int32_t accesserUserId = profile.GetAccesser().GetAccesserUserId();
int32_t accesseeUserId = profile.GetAccessee().GetAccesseeUserId();
auto localCheck = [&](int32_t userId, const std::string &accountIdHash) {
return localNeedCheckAccountId ? IsAccountInForeground(userId, accountIdHash, localForegroundAccounts) :
IsAccountInForegroundByUserId(userId, localForegroundAccounts);
};
auto peerCheck = [&](int32_t userId, const std::string &accountIdHash) {
return peerNeedCheckAccountId ? IsAccountInForeground(userId, accountIdHash, peerForegroundAccounts) :
IsAccountInForegroundByUserId(userId, peerForegroundAccounts);
};
bool localInForeground = (accesserUdid == localUdid) ?
localCheck(accesserUserId, accesserAccountIdHash) : localCheck(accesseeUserId, accesseeAccountIdHash);
bool peerInForeground = (accesserUdid == localUdid) ?
peerCheck(accesseeUserId, accesseeAccountIdHash) : peerCheck(accesserUserId, accesserAccountIdHash);
return (localInForeground && peerInForeground) ? ACTIVE : INACTIVE;
}
int32_t DeviceProfileConnector::UpdateAclByDualForegroundAccountHash(const std::string &localUdid,
const std::string &peerUdid, const std::vector<ForegroundAccountInfo> &localForegroundAccounts,
const std::vector<ForegroundAccountInfo> &peerForegroundAccounts)
{
LOGI("localUdid %{public}s, peerUdid %{public}s, localAccounts %{public}zu, peerAccounts %{public}zu",
GetAnonyString(localUdid).c_str(), GetAnonyString(peerUdid).c_str(),
localForegroundAccounts.size(), peerForegroundAccounts.size());
std::vector<AccessControlProfile> profiles = GetAllAclIncludeLnnAcl();
std::vector<AccessControlProfile> inactiveProfiles;
std::vector<AccessControlProfile> activeProfiles;
for (const auto &profile : profiles) {
int32_t targetStatus = CalculateProfileTargetStatus(profile, localUdid, peerUdid,
localForegroundAccounts, peerForegroundAccounts);
if (targetStatus < 0 || profile.GetStatus() == targetStatus) {
continue;
}
AccessControlProfile updateProfile = profile;
updateProfile.SetStatus(targetStatus);
if (targetStatus == INACTIVE) {
inactiveProfiles.push_back(updateProfile);
} else {
activeProfiles.push_back(updateProfile);
}
}
for (const auto &profile : inactiveProfiles) {
int32_t ret = DistributedDeviceProfileClient::GetInstance().UpdateAccessControlProfile(profile);
if (ret != DM_OK) {
LOGE("Update inactive profile failed, ret %{public}d", ret);
return ret;
}
}
for (const auto &profile : activeProfiles) {
int32_t ret = DistributedDeviceProfileClient::GetInstance().UpdateAccessControlProfile(profile);
if (ret != DM_OK) {
LOGE("Update active profile failed, ret %{public}d", ret);
return ret;
}
}
return DM_OK;
}
bool DeviceProfileConnector::CheckAclMatchByAccountId(const AccessControlProfile &profile,
const std::string &localUdid, int32_t userId, const std::string &accountId)
{
return CheckAclMatchByAccountId(profile, localUdid, userId, accountId, "");
}
bool DeviceProfileConnector::CheckAclMatchByAccountId(const AccessControlProfile &profile,
const std::string &localUdid, int32_t userId, const std::string &accountId, const std::string &peerUdid)
{
return CheckAclMatchAccesser(profile, localUdid, userId, accountId, peerUdid) ||
CheckAclMatchAccessee(profile, localUdid, userId, accountId, peerUdid);
}
bool DeviceProfileConnector::CheckAclMatchAccesser(const AccessControlProfile &profile,
const std::string &localUdid, int32_t userId, const std::string &accountId, const std::string &peerUdid)
{
std::string accesserUdid = profile.GetAccesser().GetAccesserDeviceId();
int32_t accesserUserId = profile.GetAccesser().GetAccesserUserId();
std::string accesserAccountId = profile.GetAccesser().GetAccesserAccountId();
std::string accesseeUdid = profile.GetAccessee().GetAccesseeDeviceId();
if (accesserUdid != localUdid || accesserUserId != userId) {
return false;
}
if (accesserAccountId != accountId) {
return false;
}
if (!peerUdid.empty() && accesseeUdid != peerUdid) {
return false;
}
return true;
}
bool DeviceProfileConnector::CheckAclMatchAccessee(const AccessControlProfile &profile,
const std::string &localUdid, int32_t userId, const std::string &accountId, const std::string &peerUdid)
{
std::string accesseeUdid = profile.GetAccessee().GetAccesseeDeviceId();
int32_t accesseeUserId = profile.GetAccessee().GetAccesseeUserId();
std::string accesseeAccountId = profile.GetAccessee().GetAccesseeAccountId();
std::string accesserUdid = profile.GetAccesser().GetAccesserDeviceId();
if (accesseeUdid != localUdid || accesseeUserId != userId) {
return false;
}
if (accesseeAccountId != accountId) {
return false;
}
if (!peerUdid.empty() && accesserUdid != peerUdid) {
return false;
}
return true;
}
bool DeviceProfileConnector::CheckAclMatchByAccountIdHash(const AccessControlProfile &profile,
const std::string &peerUdid, int32_t userId, const std::string &accountIdHash)
{
return CheckAclMatchAccesserByAccountIdHash(profile, peerUdid, userId, accountIdHash) ||
CheckAclMatchAccesseeByAccountIdHash(profile, peerUdid, userId, accountIdHash);
}
bool DeviceProfileConnector::CheckAclMatchAccesserByAccountIdHash(const AccessControlProfile &profile,
const std::string &peerUdid, int32_t userId, const std::string &accountIdHash)
{
std::string accesserUdid = profile.GetAccesser().GetAccesserDeviceId();
int32_t accesserUserId = profile.GetAccesser().GetAccesserUserId();
std::string accesserAccountId = profile.GetAccesser().GetAccesserAccountId();
char accesserAccountIdHash[DM_MAX_DEVICE_ID_LEN] = {0};
if (Crypto::GetAccountIdHash7(accesserAccountId, reinterpret_cast<uint8_t *>(accesserAccountIdHash)) != DM_OK) {
return false;
}
return (accesserUdid == peerUdid && accesserUserId == userId &&
std::string(accesserAccountIdHash) == accountIdHash);
}
bool DeviceProfileConnector::CheckAclMatchAccesseeByAccountIdHash(const AccessControlProfile &profile,
const std::string &peerUdid, int32_t userId, const std::string &accountIdHash)
{
std::string accesseeUdid = profile.GetAccessee().GetAccesseeDeviceId();
int32_t accesseeUserId = profile.GetAccessee().GetAccesseeUserId();
std::string accesseeAccountId = profile.GetAccessee().GetAccesseeAccountId();
char accesseeAccountIdHash[DM_MAX_DEVICE_ID_LEN] = {0};
if (Crypto::GetAccountIdHash7(accesseeAccountId, reinterpret_cast<uint8_t *>(accesseeAccountIdHash)) != DM_OK) {
return false;
}
return (accesseeUdid == peerUdid && accesseeUserId == userId &&
std::string(accesseeAccountIdHash) == accountIdHash);
}
std::vector<AccessControlProfile> DeviceProfileConnector::GetAclByAccountId(
const std::string &localUdid, int32_t userId, const std::string &accountId)
{
std::vector<AccessControlProfile> result;
std::vector<AccessControlProfile> profiles = GetAllAclIncludeLnnAcl();
for (const auto &profile : profiles) {
if (CheckAclMatchByAccountId(profile, localUdid, userId, accountId)) {
result.push_back(profile);
}
}
LOGI("GetAclByAccountId: found %{public}zu ACLs for accountId %{public}s",
result.size(), GetAnonyString(accountId).c_str());
return result;
}
int32_t DeviceProfileConnector::UpdateAclStatusByAccountId(const std::string &localUdid, int32_t userId,
const std::string &accountId, int32_t newStatus)
{
LOGI("localUdid %{public}s, userId %{public}d, accountId %{public}s, newStatus %{public}d",
GetAnonyString(localUdid).c_str(), userId, GetAnonyString(accountId).c_str(), newStatus);
std::vector<AccessControlProfile> profiles = GetAllAclIncludeLnnAcl();
int32_t updateCount = 0;
for (const auto &profile : profiles) {
if (CheckAclMatchByAccountId(profile, localUdid, userId, accountId) && profile.GetStatus() != newStatus) {
AccessControlProfile updateProfile = profile;
updateProfile.SetStatus(newStatus);
int32_t ret = DistributedDeviceProfileClient::GetInstance().UpdateAccessControlProfile(updateProfile);
if (ret == DM_OK) {
updateCount++;
} else {
LOGE("UpdateAccessControlProfile failed, ret %{public}d", ret);
}
}
}
LOGI("Updated %{public}d ACLs", updateCount);
return DM_OK;
}
int32_t DeviceProfileConnector::UpdateAclStatusByAccountIdHash(const std::string &localUdid, int32_t userId,
const std::string &accountIdHash, int32_t newStatus, const std::string &peerUdid)
{
LOGI("localUdid %{public}s, userId %{public}d, accountIdHash %{public}s, newStatus %{public}d, peerUdid %{public}s",
GetAnonyString(localUdid).c_str(), userId, GetAnonyString(accountIdHash).c_str(), newStatus,
GetAnonyString(peerUdid).c_str());
std::vector<AccessControlProfile> profiles = GetAllAclIncludeLnnAcl();
int32_t updateCount = 0;
for (const auto &profile : profiles) {
if (CheckAclMatchByAccountIdHash(profile, peerUdid, userId, accountIdHash) &&
profile.GetStatus() != newStatus) {
AccessControlProfile updateProfile = profile;
updateProfile.SetStatus(newStatus);
int32_t ret = DistributedDeviceProfileClient::GetInstance().UpdateAccessControlProfile(updateProfile);
if (ret == DM_OK) {
updateCount++;
} else {
LOGE("UpdateAccessControlProfile failed (accesser), ret %{public}d", ret);
}
}
}
LOGI("Updated %{public}d ACLs by accountIdHash", updateCount);
return DM_OK;
}
int32_t DeviceProfileConnector::DeleteAclByAccountId(const std::string &localUdid, int32_t userId,
const std::string &accountId)
{
return DeleteAclByAccountId(localUdid, userId, accountId, "");
}
int32_t DeviceProfileConnector::DeleteAclByAccountId(const std::string &localUdid, int32_t userId,
const std::string &accountId, const std::string &peerUdid)
{
LOGI("localUdid %{public}s, userId %{public}d, accountId %{public}s, peerUdid %{public}s",
GetAnonyString(localUdid).c_str(), userId, GetAnonyString(accountId).c_str(),
GetAnonyString(peerUdid).c_str());
std::vector<AccessControlProfile> profiles = GetAllAclIncludeLnnAcl();
int32_t deleteCount = 0;
for (const auto &profile : profiles) {
if (CheckAclMatchByAccountId(profile, localUdid, userId, accountId, peerUdid)) {
DeleteAccessControlById(profile.GetAccessControlId());
deleteCount++;
}
}
LOGI("Deleted %{public}d ACLs", deleteCount);
return DM_OK;
}
int32_t DeviceProfileConnector::DeleteAclByAccountIdHash(const std::string &localUdid, int32_t userId,
const std::string &accountIdHash, const std::string &peerUdid)
{
LOGI("localUdid %{public}s, userId %{public}d, accountIdHash %{public}s, peerUdid %{public}s",
GetAnonyString(localUdid).c_str(), userId, GetAnonyString(accountIdHash).c_str(),
GetAnonyString(peerUdid).c_str());
std::vector<AccessControlProfile> profiles = GetAllAclIncludeLnnAcl();
int32_t deleteCount = 0;
for (const auto &profile : profiles) {
if (CheckAclMatchByAccountIdHash(profile, peerUdid, userId, accountIdHash)) {
DeleteAccessControlById(profile.GetAccessControlId());
deleteCount++;
}
}
LOGI("Deleted %{public}d ACLs by accountIdHash", deleteCount);
return DM_OK;
}
}
}