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