1 /*
2  * Copyright (c) 2023-2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "deviceprofile_connector.h"
17 #include "dm_anonymous.h"
18 #include "dm_constants.h"
19 #include "dm_crypto.h"
20 #include "dm_log.h"
21 #include "multiple_user_connector.h"
22 #include "distributed_device_profile_client.h"
23 
24 using namespace OHOS::DistributedDeviceProfile;
25 
26 namespace OHOS {
27 namespace DistributedHardware {
28 DM_IMPLEMENT_SINGLE_INSTANCE(DeviceProfileConnector);
GetAccessControlProfile()29 std::vector<AccessControlProfile> DeviceProfileConnector::GetAccessControlProfile()
30 {
31     std::vector<AccessControlProfile> profiles;
32     std::map<std::string, std::string> queryParams;
33     int32_t userId = MultipleUserConnector::GetCurrentAccountUserID();
34     queryParams["userId"] = std::to_string(userId);
35     if (DistributedDeviceProfileClient::GetInstance().GetAccessControlProfile(queryParams, profiles) != DM_OK) {
36         LOGE("DP GetAccessControlProfile failed.");
37     }
38     return profiles;
39 }
40 
GetAccessControlProfileByUserId(int32_t userId)41 std::vector<AccessControlProfile> DeviceProfileConnector::GetAccessControlProfileByUserId(int32_t userId)
42 {
43     std::vector<AccessControlProfile> profiles;
44     std::map<std::string, std::string> queryParams;
45     queryParams[USERID] = std::to_string(userId);
46     if (DistributedDeviceProfileClient::GetInstance().GetAccessControlProfile(queryParams, profiles) != DM_OK) {
47         LOGE("DP GetAccessControlProfileByUserId failed.");
48     }
49     return profiles;
50 }
51 
GetAppTrustDeviceList(const std::string & pkgName,const std::string & deviceId)52 std::unordered_map<std::string, DmAuthForm> DeviceProfileConnector::GetAppTrustDeviceList(const std::string &pkgName,
53     const std::string &deviceId)
54 {
55     std::vector<AccessControlProfile> profiles = GetAccessControlProfile();
56     std::unordered_map<std::string, DmAuthForm> deviceIdMap;
57     for (auto &item : profiles) {
58         std::string trustDeviceId = item.GetTrustDeviceId();
59         if (trustDeviceId == deviceId || item.GetStatus() != ACTIVE) {
60             continue;
61         }
62         DmDiscoveryInfo discoveryInfo = {pkgName, deviceId};
63         int32_t bindType = HandleDmAuthForm(item, discoveryInfo);
64         LOGI("The udid %{public}s in ACL authForm is %{public}d.", GetAnonyString(trustDeviceId).c_str(), bindType);
65         if (bindType == DmAuthForm::INVALID_TYPE) {
66             continue;
67         }
68         if (deviceIdMap.find(trustDeviceId) == deviceIdMap.end()) {
69             deviceIdMap[trustDeviceId] = static_cast<DmAuthForm>(bindType);
70             continue;
71         }
72         DmAuthForm authForm = deviceIdMap.at(trustDeviceId);
73         if (bindType == authForm) {
74             continue;
75         }
76         if (bindType == DmAuthForm::IDENTICAL_ACCOUNT) {
77             deviceIdMap[trustDeviceId] = DmAuthForm::IDENTICAL_ACCOUNT;
78             continue;
79         }
80         if (bindType == DmAuthForm::PEER_TO_PEER && authForm == DmAuthForm::ACROSS_ACCOUNT) {
81             deviceIdMap[trustDeviceId] = DmAuthForm::PEER_TO_PEER;
82             continue;
83         }
84     }
85     return deviceIdMap;
86 }
87 
GetDeviceAclParam(DmDiscoveryInfo discoveryInfo,bool & isOnline,int32_t & authForm)88 int32_t DeviceProfileConnector::GetDeviceAclParam(DmDiscoveryInfo discoveryInfo, bool &isOnline, int32_t &authForm)
89 {
90     std::vector<AccessControlProfile> profiles = GetAccessControlProfile();
91     if (profiles.size() == 0) {
92         return DM_OK;
93     }
94     std::vector<int32_t> bindTypes;
95     for (auto &item : profiles) {
96         char deviceIdHash[DM_MAX_DEVICE_ID_LEN] = {0};
97         if (Crypto::GetUdidHash(item.GetTrustDeviceId(), reinterpret_cast<uint8_t *>(deviceIdHash)) != DM_OK) {
98             LOGE("get deviceIdHash by deviceId: %{public}s failed.", GetAnonyString(deviceIdHash).c_str());
99             return ERR_DM_FAILED;
100         }
101         if (static_cast<std::string>(deviceIdHash) != discoveryInfo.remoteDeviceIdHash || item.GetStatus() != ACTIVE) {
102             continue;
103         }
104         int32_t bindType = HandleDmAuthForm(item, discoveryInfo);
105         if (bindType == DmAuthForm::INVALID_TYPE) {
106             continue;
107         }
108         bindTypes.push_back(bindType);
109     }
110     if (std::count(bindTypes.begin(), bindTypes.end(), DmAuthForm::IDENTICAL_ACCOUNT) > 0) {
111         isOnline = true;
112         authForm = DmAuthForm::IDENTICAL_ACCOUNT;
113         LOGI("The found device is identical account device bind type.");
114         return DM_OK;
115     }
116     if (std::count(bindTypes.begin(), bindTypes.end(), DmAuthForm::PEER_TO_PEER) > 0) {
117         isOnline = true;
118         authForm = DmAuthForm::PEER_TO_PEER;
119         LOGI("The found device is peer-to-peer device bind-level.");
120         return DM_OK;
121     }
122     if (std::count(bindTypes.begin(), bindTypes.end(), DmAuthForm::ACROSS_ACCOUNT) > 0) {
123         isOnline = true;
124         authForm = DmAuthForm::ACROSS_ACCOUNT;
125         LOGI("The found device is across-account device bind-level.");
126         return DM_OK;
127     }
128     authForm = DmAuthForm::INVALID_TYPE;
129     return DM_OK;
130 }
131 
CheckAuthForm(DmAuthForm form,AccessControlProfile profiles,DmDiscoveryInfo discoveryInfo)132 int32_t DeviceProfileConnector::CheckAuthForm(DmAuthForm form, AccessControlProfile profiles,
133     DmDiscoveryInfo discoveryInfo)
134 {
135     if (profiles.GetBindLevel() == DEVICE || (profiles.GetBindLevel() == APP && discoveryInfo.pkgname == "")) {
136         return form;
137     }
138     if (profiles.GetBindLevel() == APP) {
139         if (discoveryInfo.pkgname == profiles.GetAccesser().GetAccesserBundleName() &&
140             discoveryInfo.localDeviceId == profiles.GetAccesser().GetAccesserDeviceId()) {
141             return form;
142         }
143         if (discoveryInfo.pkgname == profiles.GetAccessee().GetAccesseeBundleName() &&
144             discoveryInfo.localDeviceId == profiles.GetAccessee().GetAccesseeDeviceId()) {
145             return form;
146         }
147     }
148     return DmAuthForm::INVALID_TYPE;
149 }
150 
HandleDmAuthForm(AccessControlProfile profiles,DmDiscoveryInfo discoveryInfo)151 int32_t DeviceProfileConnector::HandleDmAuthForm(AccessControlProfile profiles, DmDiscoveryInfo discoveryInfo)
152 {
153     if (profiles.GetBindType() == DM_IDENTICAL_ACCOUNT) {
154         return DmAuthForm::IDENTICAL_ACCOUNT;
155     }
156     if (profiles.GetBindType() == DM_POINT_TO_POINT) {
157         return CheckAuthForm(DmAuthForm::PEER_TO_PEER, profiles, discoveryInfo);
158     }
159     if (profiles.GetBindType() == DM_ACROSS_ACCOUNT) {
160         return CheckAuthForm(DmAuthForm::ACROSS_ACCOUNT, profiles, discoveryInfo);
161     }
162     return DmAuthForm::INVALID_TYPE;
163 }
164 
CheckBindType(std::string trustDeviceId,std::string requestDeviceId)165 uint32_t DeviceProfileConnector::CheckBindType(std::string trustDeviceId, std::string requestDeviceId)
166 {
167     LOGI("Start.");
168     std::vector<AccessControlProfile> profiles = GetAccessControlProfile();
169     LOGI("AccessControlProfile size is %{public}zu", profiles.size());
170     uint32_t highestPriority = INVALIED_TYPE;
171     for (auto &item : profiles) {
172         if (trustDeviceId != item.GetTrustDeviceId() || item.GetStatus() != ACTIVE) {
173             continue;
174         }
175         uint32_t priority = static_cast<uint32_t>(GetAuthForm(item, trustDeviceId, requestDeviceId));
176         if (priority > highestPriority) {
177             highestPriority = priority;
178         }
179     }
180     return highestPriority;
181 }
182 
GetAuthForm(DistributedDeviceProfile::AccessControlProfile profiles,const std::string & trustDev,const std::string & reqDev)183 int32_t DeviceProfileConnector::GetAuthForm(DistributedDeviceProfile::AccessControlProfile profiles,
184     const std::string &trustDev, const std::string &reqDev)
185 {
186     LOGI("BindType %{public}d, bindLevel %{public}d",
187         profiles.GetBindType(), profiles.GetBindLevel());
188     uint32_t priority = INVALIED_TYPE;
189     uint32_t bindType = profiles.GetBindType();
190     switch (bindType) {
191         case DM_IDENTICAL_ACCOUNT:
192             priority = IDENTICAL_ACCOUNT_TYPE;
193             break;
194         case DM_POINT_TO_POINT:
195             if (profiles.GetBindLevel() == DEVICE) {
196                 priority = DEVICE_PEER_TO_PEER_TYPE;
197             } else if (profiles.GetBindLevel() == APP && profiles.GetAccesser().GetAccesserDeviceId() == reqDev &&
198                 profiles.GetAccessee().GetAccesseeDeviceId() == trustDev) {
199                 priority = APP_PEER_TO_PEER_TYPE;
200             } else if (profiles.GetBindLevel() == APP && profiles.GetAccessee().GetAccesseeDeviceId() == reqDev &&
201                 profiles.GetAccesser().GetAccesserDeviceId() == trustDev) {
202                 priority = APP_PEER_TO_PEER_TYPE;
203             }
204             break;
205         case DM_ACROSS_ACCOUNT:
206             if (profiles.GetBindLevel() == DEVICE) {
207                 priority = DEVICE_ACROSS_ACCOUNT_TYPE;
208             } else if (profiles.GetBindLevel() == APP && profiles.GetAccesser().GetAccesserDeviceId() == reqDev &&
209                 profiles.GetAccessee().GetAccesseeDeviceId() == trustDev) {
210                 priority = APP_ACROSS_ACCOUNT_TYPE;
211             } else if (profiles.GetBindLevel() == APP && profiles.GetAccessee().GetAccesseeDeviceId() == reqDev &&
212                 profiles.GetAccesser().GetAccesserDeviceId() == trustDev) {
213                 priority = APP_ACROSS_ACCOUNT_TYPE;
214             }
215             break;
216         default:
217             LOGE("unknown bind type %{public}d.", bindType);
218             break;
219     }
220     return priority;
221 }
222 
GetBindTypeByPkgName(std::string pkgName,std::string requestDeviceId,std::string trustUdid)223 std::vector<int32_t> DeviceProfileConnector::GetBindTypeByPkgName(std::string pkgName, std::string requestDeviceId,
224     std::string trustUdid)
225 {
226     LOGI("Start.");
227     std::vector<AccessControlProfile> profiles = GetAccessControlProfile();
228     LOGI("AccessControlProfile size is %{public}zu", profiles.size());
229     std::vector<int32_t> bindTypeVec;
230     for (auto &item : profiles) {
231         if (trustUdid != item.GetTrustDeviceId() || item.GetStatus() != ACTIVE) {
232             continue;
233         }
234         GetParamBindTypeVec(item, pkgName, requestDeviceId, bindTypeVec);
235     }
236     return bindTypeVec;
237 }
238 
GetParamBindTypeVec(AccessControlProfile profiles,std::string pkgName,std::string requestDeviceId,std::vector<int32_t> & bindTypeVec)239 void DeviceProfileConnector::GetParamBindTypeVec(AccessControlProfile profiles, std::string pkgName,
240     std::string requestDeviceId, std::vector<int32_t> &bindTypeVec)
241 {
242     if (profiles.GetBindType() == DM_IDENTICAL_ACCOUNT) {
243         bindTypeVec.push_back(IDENTICAL_ACCOUNT_TYPE);
244     }
245     if (profiles.GetBindType() == DM_POINT_TO_POINT) {
246         if (profiles.GetBindLevel() == DEVICE) {
247             bindTypeVec.push_back(DEVICE_PEER_TO_PEER_TYPE);
248         }
249         if (profiles.GetBindLevel() == APP) {
250             if (profiles.GetAccesser().GetAccesserBundleName() == pkgName &&
251                 profiles.GetAccesser().GetAccesserDeviceId() == requestDeviceId) {
252                 bindTypeVec.push_back(APP_PEER_TO_PEER_TYPE);
253             }
254             if ((profiles.GetAccessee().GetAccesseeBundleName() == pkgName &&
255                 profiles.GetAccessee().GetAccesseeDeviceId() == requestDeviceId)) {
256                 bindTypeVec.push_back(APP_PEER_TO_PEER_TYPE);
257             }
258         }
259     }
260     if (profiles.GetBindType() == DM_ACROSS_ACCOUNT) {
261         if (profiles.GetBindLevel() == DEVICE) {
262             bindTypeVec.push_back(DEVICE_ACROSS_ACCOUNT_TYPE);
263         }
264         if (profiles.GetBindLevel() == APP) {
265             if (profiles.GetAccesser().GetAccesserBundleName() == pkgName &&
266                 profiles.GetAccesser().GetAccesserDeviceId() == requestDeviceId) {
267                 bindTypeVec.push_back(APP_ACROSS_ACCOUNT_TYPE);
268             }
269             if ((profiles.GetAccessee().GetAccesseeBundleName() == pkgName &&
270                 profiles.GetAccessee().GetAccesseeDeviceId() == requestDeviceId)) {
271                 bindTypeVec.push_back(APP_ACROSS_ACCOUNT_TYPE);
272             }
273         }
274     }
275 }
276 
CompareBindType(std::vector<AccessControlProfile> profiles,std::string pkgName,std::vector<int32_t> & sinkBindType,std::string localDeviceId,std::string targetDeviceId)277 std::vector<int32_t> DeviceProfileConnector::CompareBindType(std::vector<AccessControlProfile> profiles,
278     std::string pkgName, std::vector<int32_t> &sinkBindType, std::string localDeviceId, std::string targetDeviceId)
279 {
280     std::vector<int32_t> bindTypeIndex;
281     for (uint32_t index = 0; index < profiles.size(); index++) {
282         if (profiles[index].GetTrustDeviceId() != targetDeviceId || profiles[index].GetStatus() != ACTIVE) {
283             continue;
284         }
285         DmDiscoveryInfo paramInfo = {
286             .pkgname = pkgName,
287             .localDeviceId = localDeviceId,
288         };
289         ProcessBindType(profiles[index], paramInfo, sinkBindType, bindTypeIndex, index);
290     }
291     return bindTypeIndex;
292 }
293 
ProcessBindType(AccessControlProfile profiles,DmDiscoveryInfo paramInfo,std::vector<int32_t> & sinkBindType,std::vector<int32_t> & bindTypeIndex,uint32_t index)294 void DeviceProfileConnector::ProcessBindType(AccessControlProfile profiles, DmDiscoveryInfo paramInfo,
295     std::vector<int32_t> &sinkBindType, std::vector<int32_t> &bindTypeIndex, uint32_t index)
296 {
297     if (profiles.GetBindType() == DM_IDENTICAL_ACCOUNT) {
298         sinkBindType.push_back(IDENTICAL_ACCOUNT_TYPE);
299         bindTypeIndex.push_back(index);
300     }
301     if (profiles.GetBindType() == DM_POINT_TO_POINT) {
302         if (profiles.GetBindLevel() == DEVICE) {
303             sinkBindType.push_back(DEVICE_PEER_TO_PEER_TYPE);
304             bindTypeIndex.push_back(index);
305         }
306         if (profiles.GetBindLevel() == APP) {
307             if (profiles.GetAccesser().GetAccesserBundleName() == paramInfo.pkgname &&
308                 profiles.GetAccesser().GetAccesserDeviceId() == paramInfo.localDeviceId) {
309                 sinkBindType.push_back(APP_PEER_TO_PEER_TYPE);
310                 bindTypeIndex.push_back(index);
311             }
312             if (profiles.GetAccessee().GetAccesseeBundleName() == paramInfo.pkgname &&
313                 profiles.GetAccessee().GetAccesseeDeviceId() == paramInfo.localDeviceId) {
314                 sinkBindType.push_back(APP_PEER_TO_PEER_TYPE);
315                 bindTypeIndex.push_back(index);
316             }
317         }
318     }
319     if (profiles.GetBindType() == DM_ACROSS_ACCOUNT) {
320         if (profiles.GetBindLevel() == DEVICE) {
321             sinkBindType.push_back(DEVICE_ACROSS_ACCOUNT_TYPE);
322             bindTypeIndex.push_back(index);
323         }
324         if (profiles.GetBindLevel() == APP) {
325             if (profiles.GetAccesser().GetAccesserBundleName() == paramInfo.pkgname &&
326                 profiles.GetAccesser().GetAccesserDeviceId() == paramInfo.localDeviceId) {
327                 sinkBindType.push_back(APP_ACROSS_ACCOUNT_TYPE);
328                 bindTypeIndex.push_back(index);
329             }
330             if (profiles.GetAccessee().GetAccesseeBundleName() == paramInfo.pkgname &&
331                 profiles.GetAccessee().GetAccesseeDeviceId() == paramInfo.localDeviceId) {
332                 sinkBindType.push_back(APP_ACROSS_ACCOUNT_TYPE);
333                 bindTypeIndex.push_back(index);
334             }
335         }
336     }
337 }
338 
SyncAclByBindType(std::string pkgName,std::vector<int32_t> bindTypeVec,std::string localDeviceId,std::string targetDeviceId)339 std::vector<int32_t> DeviceProfileConnector::SyncAclByBindType(std::string pkgName, std::vector<int32_t> bindTypeVec,
340     std::string localDeviceId, std::string targetDeviceId)
341 {
342     std::vector<AccessControlProfile> profiles = GetAccessControlProfile();
343     LOGI("AccessControlProfile size is %{public}zu", profiles.size());
344     std::vector<int32_t> sinkBindType;
345     std::vector<int32_t> bindType;
346     std::vector<int32_t> bindTypeIndex =
347         CompareBindType(profiles, pkgName, sinkBindType, localDeviceId, targetDeviceId);
348     for (uint32_t sinkIndex = 0; sinkIndex < sinkBindType.size(); sinkIndex++) {
349         bool deleteAclFlag = true;
350         for (uint32_t srcIndex = 0; srcIndex < bindTypeVec.size(); srcIndex++) {
351             if (sinkBindType[sinkIndex] == bindTypeVec[srcIndex]) {
352                 deleteAclFlag = false;
353                 bindType.push_back(bindTypeVec[sinkIndex]);
354             }
355         }
356         if (deleteAclFlag) {
357             int32_t deleteIndex = profiles[bindTypeIndex[sinkIndex]].GetAccessControlId();
358             DistributedDeviceProfileClient::GetInstance().DeleteAccessControlProfile(deleteIndex);
359         }
360     }
361     return bindType;
362 }
363 
GetPkgNameFromAcl(std::string & localDeviceId,std::string & targetDeviceId)364 std::vector<std::string> DeviceProfileConnector::GetPkgNameFromAcl(std::string &localDeviceId,
365     std::string &targetDeviceId)
366 {
367     LOGI("Start.");
368     std::vector<AccessControlProfile> profiles = GetAccessControlProfile();
369     LOGI("AccessControlProfile size is %{public}zu", profiles.size());
370     std::vector<std::string> pkgNameVec;
371     for (auto &item : profiles) {
372         if (item.GetTrustDeviceId() != targetDeviceId || item.GetStatus() != ACTIVE) {
373             continue;
374         }
375         if ((item.GetAccesser().GetAccesserDeviceId() == localDeviceId &&
376             item.GetAccessee().GetAccesseeDeviceId() == targetDeviceId) ||
377             (item.GetAccesser().GetAccesserDeviceId() == targetDeviceId &&
378             item.GetAccessee().GetAccesseeDeviceId() == localDeviceId)) {
379             pkgNameVec.push_back(item.GetAccesser().GetAccesserBundleName());
380         }
381     }
382     return pkgNameVec;
383 }
384 
GetOfflineParamFromAcl(std::string trustDeviceId,std::string requestDeviceId)385 DmOfflineParam DeviceProfileConnector::GetOfflineParamFromAcl(std::string trustDeviceId, std::string requestDeviceId)
386 {
387     LOGI("TrustDeviceId = %{public}s and requestDeviceId = %{public}s",
388          GetAnonyString(trustDeviceId).c_str(), GetAnonyString(requestDeviceId).c_str());
389     std::vector<AccessControlProfile> profiles = GetAccessControlProfile();
390     LOGI("AccessControlProfile size is %{public}zu", profiles.size());
391     DmOfflineParam offlineParam;
392     offlineParam.leftAclNumber = 0;
393     offlineParam.bindType = INVALIED_TYPE;
394     for (auto &item : profiles) {
395         if (item.GetTrustDeviceId() != trustDeviceId || item.GetStatus() != ACTIVE) {
396             continue;
397         }
398         offlineParam.leftAclNumber++;
399         uint32_t priority = INVALIED_TYPE;
400         if (item.GetBindType() == DM_IDENTICAL_ACCOUNT) {
401             priority = IDENTICAL_ACCOUNT_TYPE;
402         } else if (item.GetBindLevel() == DEVICE && item.GetAuthenticationType() == ALLOW_AUTH_ALWAYS) {
403             priority = DEVICE_PEER_TO_PEER_TYPE;
404         } else if (item.GetBindLevel() == DEVICE && item.GetAuthenticationType() == ALLOW_AUTH_ONCE) {
405             priority = DEVICE_PEER_TO_PEER_TYPE;
406             offlineParam.pkgNameVec.push_back(item.GetAccesser().GetAccesserBundleName());
407         } else if ((item.GetAccesser().GetAccesserDeviceId() == requestDeviceId &&
408             item.GetAccessee().GetAccesseeDeviceId() == trustDeviceId) ||
409             (item.GetAccesser().GetAccesserDeviceId() == trustDeviceId &&
410             item.GetAccessee().GetAccesseeDeviceId() == requestDeviceId)) {
411             priority = APP_PEER_TO_PEER_TYPE;
412             offlineParam.pkgNameVec.push_back(item.GetAccesser().GetAccesserBundleName());
413         }
414         if (priority > offlineParam.bindType) {
415             offlineParam.bindType = priority;
416         }
417     }
418     return offlineParam;
419 }
420 
PutAccessControlList(DmAclInfo aclInfo,DmAccesser dmAccesser,DmAccessee dmAccessee)421 int32_t DeviceProfileConnector::PutAccessControlList(DmAclInfo aclInfo, DmAccesser dmAccesser, DmAccessee dmAccessee)
422 {
423     LOGI("Start.");
424     Accesser accesser;
425     accesser.SetAccesserDeviceId(dmAccesser.requestDeviceId);
426     accesser.SetAccesserUserId(dmAccesser.requestUserId);
427     accesser.SetAccesserAccountId(dmAccesser.requestAccountId);
428     accesser.SetAccesserTokenId(dmAccesser.requestTokenId);
429     accesser.SetAccesserBundleName(dmAccesser.requestBundleName);
430     Accessee accessee;
431     accessee.SetAccesseeDeviceId(dmAccessee.trustDeviceId);
432     accessee.SetAccesseeUserId(dmAccessee.trustUserId);
433     accessee.SetAccesseeAccountId(dmAccessee.trustAccountId);
434     accessee.SetAccesseeTokenId(dmAccessee.trustTokenId);
435     accessee.SetAccesseeBundleName(dmAccessee.trustBundleName);
436     AccessControlProfile profile;
437     profile.SetBindType(aclInfo.bindType);
438     profile.SetBindLevel(aclInfo.bindLevel);
439     profile.SetStatus(ACTIVE);
440     profile.SetTrustDeviceId(aclInfo.trustDeviceId);
441     profile.SetDeviceIdType((int32_t)DeviceIdType::UDID);
442     profile.SetDeviceIdHash(aclInfo.deviceIdHash);
443     profile.SetAuthenticationType(aclInfo.authenticationType);
444     profile.SetAccessee(accessee);
445     profile.SetAccesser(accesser);
446     int32_t ret = DistributedDeviceProfileClient::GetInstance().PutAccessControlProfile(profile);
447     if (ret != DM_OK) {
448         LOGE("PutAccessControlProfile failed.");
449     }
450     return ret;
451 }
452 
DeleteAccessControlList(int32_t userId,std::string & accountId)453 int32_t DeviceProfileConnector::DeleteAccessControlList(int32_t userId, std::string &accountId)
454 {
455     LOGI("Start.");
456     std::vector<AccessControlProfile> profiles;
457     std::map<std::string, std::string> queryParams;
458     queryParams["userId"] = std::to_string(userId);
459     if (DistributedDeviceProfileClient::GetInstance().GetAccessControlProfile(queryParams, profiles) != DM_OK) {
460         LOGE("DP GetAccessControlProfile failed.");
461     }
462     LOGI("Size is %{public}zu", profiles.size());
463     for (auto &item : profiles) {
464         LOGI("BindType is : %{public}d.", item.GetBindType());
465         DistributedDeviceProfileClient::GetInstance().DeleteAccessControlProfile(item.GetAccessControlId());
466     }
467     return DM_OK;
468 }
469 
DeleteAccessControlList(const std::string & udid)470 void DeviceProfileConnector::DeleteAccessControlList(const std::string &udid)
471 {
472     LOGI("Udid: %{public}s.", GetAnonyString(udid).c_str());
473     if (udid.empty()) {
474         LOGE("DeleteAccessControlList udid is empty.");
475         return;
476     }
477     std::vector<AccessControlProfile> profiles = GetAccessControlProfile();
478     LOGI("Size is %{public}zu", profiles.size());
479     for (const auto &item : profiles) {
480         if (item.GetTrustDeviceId() == udid) {
481             DistributedDeviceProfileClient::GetInstance().DeleteAccessControlProfile(item.GetAccessControlId());
482         }
483     }
484 }
485 
DeleteAclForAccountLogOut(const std::string & localUdid,int32_t userId,const std::string & remoteUdid)486 void DeviceProfileConnector::DeleteAclForAccountLogOut(const std::string &localUdid, int32_t userId,
487     const std::string &remoteUdid)
488 {
489     LOGI("localUdid %{public}s, userId %{public}d, remoteUdid %{public}s.", GetAnonyString(localUdid).c_str(), userId,
490         GetAnonyString(remoteUdid).c_str());
491     std::vector<AccessControlProfile> profiles = GetAccessControlProfileByUserId(userId);
492     for (const auto &item : profiles) {
493         if (item.GetTrustDeviceId() == remoteUdid) {
494             DistributedDeviceProfileClient::GetInstance().DeleteAccessControlProfile(item.GetAccessControlId());
495         }
496     }
497 }
498 
DeleteAclForUserRemoved(int32_t userId)499 void DeviceProfileConnector::DeleteAclForUserRemoved(int32_t userId)
500 {
501     LOGI("DeleteAclForUserRemoved userId %{public}d.", userId);
502     std::vector<AccessControlProfile> profiles = GetAccessControlProfileByUserId(userId);
503     for (const auto &item : profiles) {
504         if (item.GetAccesser().GetAccesserUserId() == userId || item.GetAccessee().GetAccesseeUserId() == userId) {
505             DistributedDeviceProfileClient::GetInstance().DeleteAccessControlProfile(item.GetAccessControlId());
506         }
507     }
508 }
509 
GetDeviceIdAndBindType(int32_t userId,const std::string & accountId,const std::string & localUdid)510 std::map<std::string, int32_t> DeviceProfileConnector::GetDeviceIdAndBindType(int32_t userId,
511     const std::string &accountId, const std::string &localUdid)
512 {
513     LOGI("userId %{public}d, accountId %{public}s.", userId, GetAnonyString(accountId).c_str());
514     std::vector<AccessControlProfile> profiles = GetAccessControlProfileByUserId(userId);
515     std::map<std::string, int32_t> deviceIdMap;
516     for (const auto &item : profiles) {
517         if (item.GetAccesser().GetAccesserUserId() == userId &&
518             item.GetAccesser().GetAccesserAccountId() == accountId &&
519             item.GetAccesser().GetAccesserDeviceId() == localUdid) {
520             LOGI("Account logout localUdid %{public}s is src.", GetAnonyString(localUdid).c_str());
521             UpdateBindType(item.GetTrustDeviceId(), item.GetBindType(), deviceIdMap);
522             continue;
523         }
524         if (item.GetAccessee().GetAccesseeUserId() == userId &&
525             item.GetAccessee().GetAccesseeAccountId() == accountId &&
526             item.GetAccessee().GetAccesseeDeviceId() == localUdid) {
527             LOGI("Account logout localUdid %{public}s is sink.", GetAnonyString(localUdid).c_str());
528             UpdateBindType(item.GetTrustDeviceId(), item.GetBindType(), deviceIdMap);
529             continue;
530         }
531     }
532     return deviceIdMap;
533 }
534 
UpdateBindType(const std::string & udid,int32_t bindType,std::map<std::string,int32_t> & deviceMap)535 void DeviceProfileConnector::UpdateBindType(const std::string &udid, int32_t bindType,
536     std::map<std::string, int32_t> &deviceMap)
537 {
538     LOGI("BindType %{public}d.", bindType);
539     if (deviceMap.find(udid) == deviceMap.end()) {
540         deviceMap[udid] = bindType;
541     } else {
542         deviceMap[udid] = std::min(deviceMap[udid], bindType);
543     }
544 }
545 
DeleteAccessControlList(std::string pkgName,std::string localDeviceId,std::string remoteDeviceId)546 DmOfflineParam DeviceProfileConnector::DeleteAccessControlList(std::string pkgName, std::string localDeviceId,
547     std::string remoteDeviceId)
548 {
549     LOGI("DeleteAccessControlList by pkgName %{public}s, localDeviceId %{public}s, remoteDeviceId %{public}s.",
550         pkgName.c_str(), GetAnonyString(localDeviceId).c_str(), GetAnonyString(remoteDeviceId).c_str());
551     std::vector<AccessControlProfile> profiles = GetAccessControlProfile();
552     LOGI("Size is %{public}zu", profiles.size());
553     DmOfflineParam offlineParam;
554     offlineParam.bindType = INVALIED_TYPE;
555     offlineParam.leftAclNumber = 0;
556     for (auto &item : profiles) {
557         if (item.GetTrustDeviceId() != remoteDeviceId || item.GetStatus() != ACTIVE) {
558             continue;
559         }
560         if (item.GetBindType() == DM_IDENTICAL_ACCOUNT) {
561             LOGE("Identical account forbid unbind.");
562             offlineParam.bindType = INVALIED_TYPE;
563             return offlineParam;
564         }
565         if (item.GetTrustDeviceId() == remoteDeviceId) {
566             offlineParam.leftAclNumber++;
567             if (item.GetBindLevel() == DEVICE && item.GetBindType() != DM_IDENTICAL_ACCOUNT &&
568                 (item.GetAccesser().GetAccesserBundleName() == pkgName ||
569                 item.GetAccesser().GetAccesserBundleName() == "")) {
570                 LOGI("DeleteAccessControlList device unbind.");
571                 offlineParam.bindType = DEVICE_PEER_TO_PEER_TYPE;
572             }
573         }
574     }
575     for (auto &item : profiles) {
576         if (item.GetTrustDeviceId() != remoteDeviceId || item.GetStatus() != ACTIVE) {
577             continue;
578         }
579         if ((item.GetAccesser().GetAccesserDeviceId() == localDeviceId &&
580             item.GetAccessee().GetAccesseeDeviceId() == remoteDeviceId) ||
581             (item.GetAccessee().GetAccesseeDeviceId() == localDeviceId &&
582             item.GetAccesser().GetAccesserDeviceId() == remoteDeviceId)) {
583             if (offlineParam.bindType == DEVICE_PEER_TO_PEER_TYPE) {
584                 DistributedDeviceProfileClient::GetInstance().DeleteAccessControlProfile(item.GetAccessControlId());
585                 offlineParam.leftAclNumber--;
586             } else if (item.GetAccesser().GetAccesserBundleName() == pkgName &&
587                 item.GetAccessee().GetAccesseeBundleName() == pkgName) {
588                 offlineParam.bindType = APP_PEER_TO_PEER_TYPE;
589                 DistributedDeviceProfileClient::GetInstance().DeleteAccessControlProfile(item.GetAccessControlId());
590                 offlineParam.leftAclNumber--;
591                 break;
592             }
593         }
594     }
595     return offlineParam;
596 }
597 
UpdateAccessControlList(int32_t userId,std::string & oldAccountId,std::string & newAccountId)598 int32_t DeviceProfileConnector::UpdateAccessControlList(int32_t userId, std::string &oldAccountId,
599     std::string &newAccountId)
600 {
601     LOGI("Start.");
602     std::vector<AccessControlProfile> profiles = GetAccessControlProfile();
603     LOGI("AccessControlProfile size is %{public}zu", profiles.size());
604     for (auto &item : profiles) {
605         if ((item.GetAccesser().GetAccesserUserId() == userId &&
606             item.GetAccesser().GetAccesserAccountId() == oldAccountId) ||
607             (item.GetAccessee().GetAccesseeUserId() == userId &&
608             item.GetAccessee().GetAccesseeAccountId() == oldAccountId)) {
609             item.SetStatus(INACTIVE);
610             DistributedDeviceProfileClient::GetInstance().UpdateAccessControlProfile(item);
611         }
612         if ((item.GetAccesser().GetAccesserUserId() == userId &&
613             item.GetAccesser().GetAccesserAccountId() == newAccountId) ||
614             (item.GetAccessee().GetAccesseeUserId() == userId &&
615             item.GetAccessee().GetAccesseeAccountId() == newAccountId)) {
616             item.SetStatus(ACTIVE);
617             DistributedDeviceProfileClient::GetInstance().UpdateAccessControlProfile(item);
618         }
619     }
620     return DM_OK;
621 }
622 
CheckIdenticalAccount(int32_t userId,const std::string & accountId)623 bool DeviceProfileConnector::CheckIdenticalAccount(int32_t userId, const std::string &accountId)
624 {
625     LOGI("Start");
626     std::vector<AccessControlProfile> profiles;
627     std::map<std::string, std::string> queryParams;
628     queryParams["userId"] = std::to_string(userId);
629     queryParams["accountId"] = accountId;
630     if (DistributedDeviceProfileClient::GetInstance().GetAccessControlProfile(queryParams, profiles) != DM_OK) {
631         LOGE("DP GetAccessControlProfile failed.");
632     }
633     for (auto &item : profiles) {
634         if (item.GetBindType() == DM_IDENTICAL_ACCOUNT && item.GetStatus() == ACTIVE) {
635             return true;
636         }
637     }
638     return false;
639 }
DeleteP2PAccessControlList(int32_t userId,std::string & accountId)640 int32_t DeviceProfileConnector::DeleteP2PAccessControlList(int32_t userId, std::string &accountId)
641 {
642     LOGI("Start");
643     std::vector<AccessControlProfile> profiles;
644     std::map<std::string, std::string> queryParams;
645     queryParams["userId"] = std::to_string(userId);
646     queryParams["accountId"] = accountId;
647     if (DistributedDeviceProfileClient::GetInstance().GetAccessControlProfile(queryParams, profiles) != DM_OK) {
648         LOGE("DP GetAccessControlProfile failed.");
649     }
650     for (auto &item : profiles) {
651         if (item.GetBindType() == DM_IDENTICAL_ACCOUNT || item.GetStatus() != ACTIVE) {
652             continue;
653         }
654         if ((item.GetAccesser().GetAccesserUserId() == userId &&
655             item.GetAccesser().GetAccesserAccountId() == accountId) ||
656             (item.GetAccessee().GetAccesseeUserId() == userId &&
657             item.GetAccessee().GetAccesseeAccountId() == accountId)) {
658             DistributedDeviceProfileClient::GetInstance().DeleteAccessControlProfile(item.GetAccessControlId());
659         }
660     }
661     return DM_OK;
662 }
663 
CheckSrcDevIdInAclForDevBind(const std::string & pkgName,const std::string & deviceId)664 bool DeviceProfileConnector::CheckSrcDevIdInAclForDevBind(const std::string &pkgName, const std::string &deviceId)
665 {
666     LOGI("Start");
667     std::vector<AccessControlProfile> profiles = GetAccessControlProfile();
668     LOGI("AccessControlProfile size is %{public}zu", profiles.size());
669     for (auto &item : profiles) {
670         if (item.GetTrustDeviceId() == deviceId && item.GetStatus() == ACTIVE &&
671             item.GetBindLevel() == DEVICE && (item.GetAccessee().GetAccesseeBundleName() == pkgName ||
672             item.GetAccesser().GetAccesserBundleName() == "") && item.GetAccessee().GetAccesseeUserId() == 0 &&
673             item.GetAccessee().GetAccesseeAccountId() == "") {
674             return true;
675         }
676     }
677     return false;
678 }
679 
CheckSinkDevIdInAclForDevBind(const std::string & pkgName,const std::string & deviceId)680 bool DeviceProfileConnector::CheckSinkDevIdInAclForDevBind(const std::string &pkgName, const std::string &deviceId)
681 {
682     LOGI("Start");
683     std::vector<AccessControlProfile> profiles = GetAccessControlProfile();
684     LOGI("AccessControlProfile size is %{public}zu", profiles.size());
685     for (auto &item : profiles) {
686         if (item.GetTrustDeviceId() == deviceId && item.GetStatus() == ACTIVE &&
687             item.GetBindLevel() == DEVICE && (item.GetAccesser().GetAccesserBundleName() == pkgName ||
688             item.GetAccesser().GetAccesserBundleName() == "") && item.GetAccesser().GetAccesserUserId() == 0 &&
689             item.GetAccesser().GetAccesserAccountId() == "") {
690             return true;
691         }
692     }
693     return false;
694 }
695 
CheckDevIdInAclForDevBind(const std::string & pkgName,const std::string & deviceId)696 bool DeviceProfileConnector::CheckDevIdInAclForDevBind(const std::string &pkgName, const std::string &deviceId)
697 {
698     return (CheckSinkDevIdInAclForDevBind(pkgName, deviceId) || CheckSrcDevIdInAclForDevBind(pkgName, deviceId));
699 }
700 
DeleteTimeOutAcl(const std::string & deviceId)701 uint32_t DeviceProfileConnector::DeleteTimeOutAcl(const std::string &deviceId)
702 {
703     LOGI("Start");
704     std::vector<AccessControlProfile> profiles = GetAccessControlProfile();
705     LOGI("AccessControlProfile size is %{public}zu", profiles.size());
706     uint32_t res = 0;
707     for (auto &item : profiles) {
708         if (item.GetTrustDeviceId() != deviceId || item.GetStatus() != ACTIVE) {
709             continue;
710         }
711         res++;
712         if (item.GetAuthenticationType() == ALLOW_AUTH_ONCE) {
713             res--;
714             DistributedDeviceProfileClient::GetInstance().DeleteAccessControlProfile(item.GetAccessControlId());
715         }
716     }
717     return res;
718 }
719 
GetTrustNumber(const std::string & deviceId)720 int32_t DeviceProfileConnector::GetTrustNumber(const std::string &deviceId)
721 {
722     LOGI("Start");
723     std::vector<AccessControlProfile> profiles = GetAccessControlProfile();
724     LOGI("AccessControlProfile size is %{public}zu", profiles.size());
725     int32_t trustNumber = 0;
726     for (auto &item : profiles) {
727         if (item.GetTrustDeviceId() == deviceId && item.GetStatus() == ACTIVE) {
728             trustNumber++;
729         }
730     }
731     return trustNumber;
732 }
733 
CheckPkgnameInAcl(std::string pkgName,std::string localDeviceId,std::string remoteDeviceId)734 bool DeviceProfileConnector::CheckPkgnameInAcl(std::string pkgName, std::string localDeviceId,
735     std::string remoteDeviceId)
736 {
737     LOGI("Start");
738     std::vector<AccessControlProfile> profiles = GetAccessControlProfile();
739     LOGI("AccessControlProfile size is %{public}zu", profiles.size());
740     for (auto &item : profiles) {
741         if (item.GetTrustDeviceId() != remoteDeviceId || item.GetStatus() != ACTIVE ||
742             item.GetBindType() == DM_IDENTICAL_ACCOUNT) {
743             continue;
744         }
745         if (item.GetBindLevel() == DEVICE && (item.GetAccesser().GetAccesserBundleName() == pkgName ||
746             item.GetAccessee().GetAccesseeBundleName() == pkgName ||
747             item.GetAccesser().GetAccesserBundleName() == "" || item.GetAccessee().GetAccesseeBundleName() == "")) {
748             LOGI("The pkgname %{public}s is peer-to-peer device unbind.", pkgName.c_str());
749             return true;
750         } else if (item.GetBindLevel() == APP && item.GetAccesser().GetAccesserBundleName() == pkgName &&
751             item.GetAccesser().GetAccesserDeviceId() == localDeviceId) {
752             LOGI("The accesser pkgname %{public}s is peer-to-peer app unbind.", pkgName.c_str());
753             return true;
754         } else if (item.GetBindLevel() == APP && item.GetAccessee().GetAccesseeBundleName() == pkgName &&
755             item.GetAccessee().GetAccesseeDeviceId() == localDeviceId) {
756             LOGI("The accessee pkgname %{public}s is peer-to-peer app unbind.", pkgName.c_str());
757             return true;
758         }
759     }
760     return false;
761 }
762 
IsSameAccount(const std::string & udid)763 int32_t DeviceProfileConnector::IsSameAccount(const std::string &udid)
764 {
765     LOGI("Start.");
766     std::vector<AccessControlProfile> profiles = GetAccessControlProfile();
767     for (auto &item : profiles) {
768         if (item.GetTrustDeviceId() == udid && item.GetStatus() == ACTIVE) {
769             if (item.GetBindType() == DM_IDENTICAL_ACCOUNT) {  // 同账号
770                 LOGI("The udid %{public}s is identical bind.", GetAnonyString(udid).c_str());
771                 return DM_OK;
772             }
773         }
774     }
775     return ERR_DM_FAILED;
776 }
777 
CheckAccessControl(const DmAccessCaller & caller,const std::string & srcUdid,const DmAccessCallee & callee,const std::string & sinkUdid)778 int32_t DeviceProfileConnector::CheckAccessControl(const DmAccessCaller &caller, const std::string &srcUdid,
779     const DmAccessCallee &callee, const std::string &sinkUdid)
780 {
781     LOGI("PkgName %{public}s, srcUdid %{public}s, sinkUdid %{public}s",
782         caller.pkgName.c_str(), GetAnonyString(srcUdid).c_str(), GetAnonyString(sinkUdid).c_str());
783     std::vector<AccessControlProfile> profiles = GetAccessControlProfile();
784     for (auto &item : profiles) {
785         if (item.GetStatus() != ACTIVE || (item.GetTrustDeviceId() != sinkUdid &&
786             item.GetTrustDeviceId() != srcUdid)) {
787             continue;
788         }
789         if (SingleUserProcess(item, caller, callee)) {
790             return DM_OK;
791         }
792     }
793     return ERR_DM_FAILED;
794 }
795 
SingleUserProcess(const DistributedDeviceProfile::AccessControlProfile & profile,const DmAccessCaller & caller,const DmAccessCallee & callee)796 bool DeviceProfileConnector::SingleUserProcess(const DistributedDeviceProfile::AccessControlProfile &profile,
797     const DmAccessCaller &caller, const DmAccessCallee &callee)
798 {
799     LOGI("BindType %{public}d, bindLevel %{public}d.",
800         profile.GetBindType(), profile.GetBindLevel());
801     uint32_t bindType = profile.GetBindType();
802     bool ret = false;
803     switch (bindType) {
804         case DM_IDENTICAL_ACCOUNT:
805             ret = true;
806             break;
807         case DM_POINT_TO_POINT:
808             if (profile.GetBindLevel() == DEVICE || profile.GetBindLevel() == SERVICE) {
809                 ret = true;
810             } else if (profile.GetBindLevel() == APP &&
811                 profile.GetAccesser().GetAccesserBundleName() == caller.pkgName) {
812                 ret = true;
813             }
814             break;
815         case DM_ACROSS_ACCOUNT:
816             if (profile.GetBindLevel() == DEVICE || profile.GetBindLevel() == SERVICE) {
817                 ret = true;
818             } else if (profile.GetBindLevel() == APP &&
819                 profile.GetAccesser().GetAccesserBundleName() == caller.pkgName) {
820                 ret = true;
821             }
822             break;
823         default:
824             LOGE("unknown bind type %{public}d.", bindType);
825             break;
826     }
827     return ret;
828 }
829 
CheckIsSameAccount(const DmAccessCaller & caller,const std::string & srcUdid,const DmAccessCallee & callee,const std::string & sinkUdid)830 int32_t DeviceProfileConnector::CheckIsSameAccount(const DmAccessCaller &caller, const std::string &srcUdid,
831     const DmAccessCallee &callee, const std::string &sinkUdid)
832 {
833     LOGI(" DeviceProfileConnector::CheckIsSameAccount pkgName %{public}s, srcUdid %{public}s, sinkUdid %{public}s",
834         caller.pkgName.c_str(), GetAnonyString(srcUdid).c_str(), GetAnonyString(sinkUdid).c_str());
835     std::vector<AccessControlProfile> profiles = GetAccessControlProfile();
836     for (auto &item : profiles) {
837         if (item.GetStatus() != ACTIVE || (item.GetTrustDeviceId() != sinkUdid &&
838             item.GetTrustDeviceId() != srcUdid)) {
839             continue;
840         }
841         if (item.GetBindType() == DM_IDENTICAL_ACCOUNT) {
842             LOGI("The udid %{public}s is identical bind.", GetAnonyString(item.GetTrustDeviceId()).c_str());
843             return DM_OK;
844         }
845     }
846     return ERR_DM_FAILED;
847 }
848 
CreateDpConnectorInstance()849 IDeviceProfileConnector *CreateDpConnectorInstance()
850 {
851     return &DeviceProfileConnector::GetInstance();
852 }
853 } // namespace DistributedHardware
854 } // namespace OHOS
855