• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023-2025 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 permission and
13  * limitations under the License.
14  */
15 
16 #include "auth_deviceprofile.h"
17 
18 #include <cstring>
19 #include <securec.h>
20 
21 #include "anonymizer.h"
22 #include "bus_center_manager.h"
23 #include "distributed_device_profile_client.h"
24 #include "lnn_distributed_net_ledger.h"
25 #include "lnn_log.h"
26 #include "lnn_ohos_account.h"
27 #include "ohos_account_kits.h"
28 #include "softbus_adapter_crypto.h"
29 #include "softbus_adapter_mem.h"
30 #include "softbus_utils.h"
31 
32 #define DEFAULT_ACCOUNT_UID         "ohosAnonymousUid"
33 #define DEFAULT_ACCOUNT_VALUE       "0"
34 #define DEFAULT_USER_KEY_INDEX      (-1)
35 #define DEFAULT_UKID_TIME           (-1)
36 #define DEFAULT_USERID              (-1)
37 #define MAX_BUNDLE_NAME_LEN         200
38 
39 using DpClient = OHOS::DistributedDeviceProfile::DistributedDeviceProfileClient;
40 static std::set<std::string> g_notTrustedDevices;
41 static std::mutex g_mutex;
42 static constexpr const int32_t LONG_TO_STRING_MAX_LEN = 21;
43 
44 typedef struct {
45     std::string localUdid;
46     std::string peerUdid;
47     int32_t peerUserId;
48     int32_t sessionKeyId;
49     uint64_t time;
50 } AclParams;
51 
IsNotTrustDevice(std::string deviceIdHash)52 static bool IsNotTrustDevice(std::string deviceIdHash)
53 {
54     std::lock_guard<std::mutex> autoLock(g_mutex);
55     if (g_notTrustedDevices.find(deviceIdHash) != g_notTrustedDevices.end()) {
56         return true;
57     }
58     return false;
59 }
60 
InsertNotTrustDevice(std::string deviceIdHash)61 static void InsertNotTrustDevice(std::string deviceIdHash)
62 {
63     std::lock_guard<std::mutex> autoLock(g_mutex);
64     g_notTrustedDevices.insert(deviceIdHash);
65 }
66 
DelNotTrustDevice(const char * udid)67 void DelNotTrustDevice(const char *udid)
68 {
69     if (udid == nullptr) {
70         LNN_LOGE(LNN_STATE, "udid is null");
71         return;
72     }
73     uint8_t udidHash[SHA_256_HASH_LEN] = { 0 };
74     char hashStr[CUST_UDID_LEN + 1] = { 0 };
75     if (SoftBusGenerateStrHash((const unsigned char *)udid, strlen(udid), udidHash) != SOFTBUS_OK) {
76         LNN_LOGE(LNN_STATE, "generate udidhash fail");
77         return;
78     }
79     if (ConvertBytesToHexString(hashStr, CUST_UDID_LEN + 1, udidHash, CUST_UDID_LEN / HEXIFY_UNIT_LEN) != SOFTBUS_OK) {
80         LNN_LOGE(LNN_STATE, "convert udidhash hex string fail");
81         return;
82     }
83     std::lock_guard<std::mutex> autoLock(g_mutex);
84     if (g_notTrustedDevices.find(hashStr) != g_notTrustedDevices.end()) {
85         LNN_LOGI(LNN_STATE, "remove not trust device");
86         g_notTrustedDevices.erase(hashStr);
87         return;
88     }
89     LNN_LOGI(LNN_STATE, "not need remove");
90 }
91 
GetAclLocalUserId(const OHOS::DistributedDeviceProfile::AccessControlProfile & trustDevice)92 static int32_t GetAclLocalUserId(const OHOS::DistributedDeviceProfile::AccessControlProfile &trustDevice)
93 {
94     if (trustDevice.GetTrustDeviceId() == trustDevice.GetAccessee().GetAccesseeDeviceId()) {
95         return trustDevice.GetAccesser().GetAccesserUserId();
96     }
97     return trustDevice.GetAccessee().GetAccesseeUserId();
98 }
99 
GetAclPeerUserId(const OHOS::DistributedDeviceProfile::AccessControlProfile & trustDevice)100 static int32_t GetAclPeerUserId(const OHOS::DistributedDeviceProfile::AccessControlProfile &trustDevice)
101 {
102     if (trustDevice.GetTrustDeviceId() == trustDevice.GetAccessee().GetAccesseeDeviceId()) {
103         return trustDevice.GetAccessee().GetAccesseeUserId();
104     }
105     return trustDevice.GetAccesser().GetAccesserUserId();
106 }
107 
GetStringHash(std::string str,char * hashStrBuf,int32_t len)108 static int32_t GetStringHash(std::string str, char *hashStrBuf, int32_t len)
109 {
110     uint8_t hash[SHA_256_HASH_LEN] = { 0 };
111     if (SoftBusGenerateStrHash((const unsigned char *)str.c_str(), str.length(), hash) != SOFTBUS_OK) {
112         LNN_LOGE(LNN_STATE, "generate hash fail");
113         return SOFTBUS_NETWORK_GENERATE_STR_HASH_ERR;
114     }
115     if (ConvertBytesToHexString(hashStrBuf, len + 1, hash, len / HEXIFY_UNIT_LEN) != SOFTBUS_OK) {
116         LNN_LOGE(LNN_STATE, "convert hash hex string fail");
117         return SOFTBUS_NETWORK_BYTES_TO_HEX_STR_ERR;
118     }
119     return SOFTBUS_OK;
120 }
121 
IsTrustDevice(std::vector<OHOS::DistributedDeviceProfile::AccessControlProfile> & trustDevices,const char * deviceIdHash,const char * anonyDeviceIdHash,bool isOnlyPointToPoint)122 static bool IsTrustDevice(std::vector<OHOS::DistributedDeviceProfile::AccessControlProfile> &trustDevices,
123     const char *deviceIdHash, const char *anonyDeviceIdHash, bool isOnlyPointToPoint)
124 {
125     int32_t localUserId = GetActiveOsAccountIds();
126     for (const auto &trustDevice : trustDevices) {
127         if (isOnlyPointToPoint &&
128             trustDevice.GetBindType() == (uint32_t)OHOS::DistributedDeviceProfile::BindType::SAME_ACCOUNT) {
129             continue;
130         }
131         if (trustDevice.GetDeviceIdType() != (uint32_t)OHOS::DistributedDeviceProfile::DeviceIdType::UDID ||
132             trustDevice.GetTrustDeviceId().empty() ||
133             trustDevice.GetStatus() == (uint32_t)OHOS::DistributedDeviceProfile::Status::INACTIVE ||
134             localUserId != GetAclLocalUserId(trustDevice)) {
135             continue;
136         }
137         char *anonyUdid = nullptr;
138         Anonymize(trustDevice.GetTrustDeviceId().c_str(), &anonyUdid);
139         LNN_LOGI(LNN_STATE, "udid=%{public}s, deviceIdHash=%{public}s", AnonymizeWrapper(anonyUdid),
140             AnonymizeWrapper(anonyDeviceIdHash));
141         AnonymizeFree(anonyUdid);
142         uint8_t udidHash[SHA_256_HASH_LEN] = { 0 };
143         char hashStr[CUST_UDID_LEN + 1] = { 0 };
144         if (SoftBusGenerateStrHash((const unsigned char *)trustDevice.GetTrustDeviceId().c_str(),
145             trustDevice.GetTrustDeviceId().length(), udidHash) != SOFTBUS_OK) {
146             LNN_LOGE(LNN_STATE, "generate udidhash fail");
147             continue;
148         }
149         if (ConvertBytesToHexString(hashStr, CUST_UDID_LEN + 1, udidHash, CUST_UDID_LEN / HEXIFY_UNIT_LEN) !=
150             SOFTBUS_OK) {
151             LNN_LOGE(LNN_STATE, "convert udidhash hex string fail");
152             continue;
153         }
154         if (strncmp(hashStr, deviceIdHash, strlen(deviceIdHash)) == 0) {
155             LNN_LOGI(LNN_STATE, "device trusted in dp continue verify, deviceIdHash=%{public}s", anonyDeviceIdHash);
156             return true;
157         }
158     }
159     return false;
160 }
161 
CompareAclWithPeerDeviceInfo(const OHOS::DistributedDeviceProfile::AccessControlProfile & aclProfile,const char * peerAccountHash,const char * peerUdid,int32_t peerUserId)162 static bool CompareAclWithPeerDeviceInfo(const OHOS::DistributedDeviceProfile::AccessControlProfile &aclProfile,
163     const char *peerAccountHash, const char *peerUdid, int32_t peerUserId)
164 {
165     int32_t localUserId = GetActiveOsAccountIds();
166     char udid[UDID_BUF_LEN] = { 0 };
167     uint8_t localAccountHash[SHA_256_HASH_LEN] = { 0 };
168     char localAccountString[SHA_256_HEX_HASH_LEN] = { 0 };
169     if (LnnGetLocalStrInfo(STRING_KEY_DEV_UDID, udid, UDID_BUF_LEN) != SOFTBUS_OK) {
170         LNN_LOGE(LNN_STATE, "get local udid fail");
171         return false;
172     }
173     if (LnnGetLocalByteInfo(BYTE_KEY_ACCOUNT_HASH, localAccountHash, SHA_256_HASH_LEN) != SOFTBUS_OK) {
174         LNN_LOGE(LNN_STATE, "get local account hash fail");
175         return false;
176     }
177     if (ConvertBytesToHexString(
178         localAccountString, SHA_256_HEX_HASH_LEN, (unsigned char *)localAccountHash, SHA_256_HASH_LEN) != SOFTBUS_OK) {
179         LNN_LOGE(LNN_STATE, "convert account to string fail");
180         return false;
181     }
182     std::string localUdid(udid);
183     std::string sourceAccountId = aclProfile.GetAccesser().GetAccesserAccountId();
184     std::string sinkAccountId = aclProfile.GetAccessee().GetAccesseeAccountId();
185     if (strcmp(DEFAULT_ACCOUNT_UID, sourceAccountId.c_str()) != 0) {
186         if (StrCmpIgnoreCase(sourceAccountId.c_str(), peerAccountHash) != 0 &&
187             StrCmpIgnoreCase(sourceAccountId.c_str(), localAccountString) != 0) {
188             return false;
189         }
190     }
191     if (strcmp(DEFAULT_ACCOUNT_UID, sinkAccountId.c_str()) != 0) {
192         if (StrCmpIgnoreCase(sinkAccountId.c_str(), peerAccountHash) != 0 &&
193             StrCmpIgnoreCase(sinkAccountId.c_str(), localAccountString) != 0) {
194             return false;
195         }
196     }
197     if (((aclProfile.GetAccessee().GetAccesseeDeviceId() != peerUdid ||
198         aclProfile.GetAccesser().GetAccesserDeviceId() != localUdid) &&
199         (aclProfile.GetAccesser().GetAccesserDeviceId() != peerUdid ||
200         aclProfile.GetAccessee().GetAccesseeDeviceId() != localUdid)) ||
201         GetAclLocalUserId(aclProfile) != localUserId || GetAclPeerUserId(aclProfile) != peerUserId) {
202         return false;
203     }
204     return true;
205 }
206 
IsTrustedDeviceFromAccess(const char * peerAccountHash,const char * peerUdid,int32_t peerUserId)207 bool IsTrustedDeviceFromAccess(const char *peerAccountHash, const char *peerUdid, int32_t peerUserId)
208 {
209     if (peerAccountHash == nullptr || peerUdid == nullptr) {
210         LNN_LOGE(LNN_STATE, "peerUdid is null");
211         return false;
212     }
213     std::vector<OHOS::DistributedDeviceProfile::AccessControlProfile> aclProfiles;
214     int32_t ret = DpClient::GetInstance().GetAllAccessControlProfile(aclProfiles);
215     if (ret != OHOS::DistributedDeviceProfile::DP_NOT_FIND_DATA && ret != OHOS::DistributedDeviceProfile::DP_SUCCESS) {
216         LNN_LOGE(LNN_STATE, "GetAllAccessControlProfile ret=%{public}d", ret);
217         return false;
218     }
219     if (aclProfiles.empty()) {
220         LNN_LOGE(LNN_STATE, "aclProfiles is empty");
221         return false;
222     }
223     for (auto &aclProfile : aclProfiles) {
224         LNN_LOGI(LNN_STATE, "GetAccesser=%{public}s, GetAccessee=%{public}s", aclProfile.GetAccesser().dump().c_str(),
225             aclProfile.GetAccessee().dump().c_str());
226         if (aclProfile.GetDeviceIdType() != (uint32_t)OHOS::DistributedDeviceProfile::DeviceIdType::UDID ||
227             aclProfile.GetTrustDeviceId().empty() || aclProfile.GetTrustDeviceId() != peerUdid) {
228             continue;
229         }
230         if (!CompareAclWithPeerDeviceInfo(aclProfile, peerAccountHash, peerUdid, peerUserId)) {
231             continue;
232         }
233         return true;
234     }
235     return false;
236 }
237 
IsPotentialTrustedDeviceDp(const char * deviceIdHash,bool isOnlyPointToPoint)238 bool IsPotentialTrustedDeviceDp(const char *deviceIdHash, bool isOnlyPointToPoint)
239 {
240     if (deviceIdHash == nullptr) {
241         LNN_LOGE(LNN_STATE, "deviceIdHash is null");
242         return false;
243     }
244     if (IsNotTrustDevice(deviceIdHash)) {
245         LNN_LOGD(LNN_STATE, "device not trusted");
246         return false;
247     }
248     std::vector<OHOS::DistributedDeviceProfile::AccessControlProfile> aclProfiles;
249     int32_t ret = DpClient::GetInstance().GetAllAccessControlProfile(aclProfiles);
250     if (ret != OHOS::DistributedDeviceProfile::DP_NOT_FIND_DATA && ret != OHOS::DistributedDeviceProfile::DP_SUCCESS) {
251         LNN_LOGE(LNN_STATE, "GetAllAccessControlProfile ret=%{public}d", ret);
252         return false;
253     }
254     if (aclProfiles.empty()) {
255         LNN_LOGE(LNN_STATE, "aclProfiles is empty");
256         InsertNotTrustDevice(deviceIdHash);
257         return false;
258     }
259     char *anonyDeviceIdHash = nullptr;
260     Anonymize(deviceIdHash, &anonyDeviceIdHash);
261     static uint32_t callCount = 0;
262     if (IsTrustDevice(aclProfiles, deviceIdHash, anonyDeviceIdHash, isOnlyPointToPoint)) {
263         AnonymizeFree(anonyDeviceIdHash);
264         return true;
265     }
266     InsertNotTrustDevice(deviceIdHash);
267     LNN_LOGI(LNN_STATE, "device is not trusted in dp, deviceIdHash=%{public}s, callCount=%{public}u",
268         AnonymizeWrapper(anonyDeviceIdHash), callCount++);
269     AnonymizeFree(anonyDeviceIdHash);
270     return false;
271 }
272 
DpHasAccessControlProfile(const char * udid,bool isNeedUserId,int32_t localUserId)273 bool DpHasAccessControlProfile(const char *udid, bool isNeedUserId, int32_t localUserId)
274 {
275     if (udid == nullptr) {
276         LNN_LOGE(LNN_STATE, "udid is null");
277         return false;
278     }
279 
280     char *anonyUdid = nullptr;
281     Anonymize(udid, &anonyUdid);
282     LNN_LOGI(LNN_STATE, "udid=%{public}s, isNeedUserId=%{public}d, localUserId=%{public}d", AnonymizeWrapper(anonyUdid),
283         isNeedUserId, localUserId);
284     AnonymizeFree(anonyUdid);
285     std::vector<OHOS::DistributedDeviceProfile::AccessControlProfile> aclProfiles;
286     int32_t ret = DpClient::GetInstance().GetAllAccessControlProfile(aclProfiles);
287     if (ret != OHOS::DistributedDeviceProfile::DP_NOT_FIND_DATA && ret != OHOS::DistributedDeviceProfile::DP_SUCCESS) {
288         LNN_LOGE(LNN_STATE, "GetAllAccessControlProfile ret=%{public}d", ret);
289         return false;
290     }
291     if (aclProfiles.empty()) {
292         LNN_LOGE(LNN_STATE, "aclProfiles is empty");
293         return false;
294     }
295     for (const auto &trustDevice : aclProfiles) {
296         if (trustDevice.GetDeviceIdType() != (uint32_t)OHOS::DistributedDeviceProfile::DeviceIdType::UDID ||
297             trustDevice.GetTrustDeviceId().empty() || trustDevice.GetTrustDeviceId() != udid) {
298             continue;
299         }
300         if (isNeedUserId && GetAclLocalUserId(trustDevice) != localUserId) {
301             continue;
302         }
303 
304         LNN_LOGI(LNN_STATE, "dp has accessControlProfile");
305         return true;
306     }
307     LNN_LOGI(LNN_STATE, "dp not has accessControlProfile");
308     return false;
309 }
310 
DumpAccountId(int64_t localAccountId,int64_t peerAccountId)311 static void DumpAccountId(int64_t localAccountId, int64_t peerAccountId)
312 {
313     char localAccountString[LONG_TO_STRING_MAX_LEN] = { 0 };
314     if (sprintf_s(localAccountString, LONG_TO_STRING_MAX_LEN, "%" PRId64, localAccountId) == -1) {
315         LNN_LOGE(LNN_STATE, "long to string fail");
316         return;
317     }
318 
319     char peerAccountString[LONG_TO_STRING_MAX_LEN] = { 0 };
320     if (sprintf_s(peerAccountString, LONG_TO_STRING_MAX_LEN, "%" PRId64, peerAccountId) == -1) {
321         LNN_LOGE(LNN_STATE, "long to string fail");
322         return;
323     }
324 
325     char *anonyLocalAccountId = nullptr;
326     char *anonyPeerAccountId = nullptr;
327     Anonymize(localAccountString, &anonyLocalAccountId);
328     Anonymize(peerAccountString, &anonyPeerAccountId);
329     LNN_LOGI(LNN_STATE, "localAccountId=%{public}s, peerAccountId=%{public}s", AnonymizeWrapper(anonyLocalAccountId),
330         AnonymizeWrapper(anonyPeerAccountId));
331     AnonymizeFree(anonyLocalAccountId);
332     AnonymizeFree(anonyPeerAccountId);
333 }
334 
IsSameAccount(int64_t accountId)335 static bool IsSameAccount(int64_t accountId)
336 {
337     int64_t localAccountId = 0;
338     int32_t ret = LnnGetLocalNum64Info(NUM_KEY_ACCOUNT_LONG, &localAccountId);
339     if (ret != SOFTBUS_OK) {
340         LNN_LOGE(LNN_STATE, "get local accountId fail");
341         return false;
342     }
343     DumpAccountId(localAccountId, accountId);
344     if (localAccountId == accountId && !LnnIsDefaultOhosAccount()) {
345         return true;
346     }
347     return false;
348 }
349 
DumpDpAclInfo(const std::string peerUdid,int32_t localUserId,int32_t peerUserId,const OHOS::DistributedDeviceProfile::AccessControlProfile & aclProfile)350 static void DumpDpAclInfo(const std::string peerUdid, int32_t localUserId, int32_t peerUserId,
351     const OHOS::DistributedDeviceProfile::AccessControlProfile &aclProfile)
352 {
353     char *anonyUdid = nullptr;
354     Anonymize(peerUdid.c_str(), &anonyUdid);
355     LNN_LOGI(LNN_STATE,
356         "dp has acl. udid=%{public}s, localUserId=%{public}d, peerUserId=%{public}d, "
357         "Status=%{public}d",
358         AnonymizeWrapper(anonyUdid), localUserId, peerUserId, aclProfile.GetStatus());
359     AnonymizeFree(anonyUdid);
360 }
361 
UpdateDpSameAccountAcl(const std::string & peerUdid,int32_t peerUserId,int32_t sessionKeyId)362 static UpdateDpAclResult UpdateDpSameAccountAcl(const std::string &peerUdid, int32_t peerUserId, int32_t sessionKeyId)
363 {
364     peerUserId = peerUserId == 0 ? DEFAULT_USERID : peerUserId;
365     std::vector<OHOS::DistributedDeviceProfile::AccessControlProfile> aclProfiles;
366     int32_t ret = DpClient::GetInstance().GetAllAccessControlProfile(aclProfiles);
367     LNN_CHECK_AND_RETURN_RET_LOGE(ret == OHOS::DistributedDeviceProfile::DP_SUCCESS, GET_ALL_ACL_FAIL, LNN_STATE,
368         "GetAllAccessControlProfile ret=%{public}d", ret);
369     LNN_CHECK_AND_RETURN_RET_LOGE(!aclProfiles.empty(), GET_ALL_ACL_IS_EMPTY, LNN_STATE, "aclProfiles is empty");
370     UpdateDpAclResult updateResult = UPDATE_ACL_NOT_MATCH;
371     int32_t localUserId = GetActiveOsAccountIds();
372     char udid[UDID_BUF_LEN] = {0};
373     if (LnnGetLocalStrInfo(STRING_KEY_DEV_UDID, udid, UDID_BUF_LEN) != SOFTBUS_OK) {
374         LNN_LOGE(LNN_STATE, "get local udid fail");
375     }
376     std::string localUdid(udid);
377     for (auto &aclProfile : aclProfiles) {
378         if (aclProfile.GetDeviceIdType() != (uint32_t)OHOS::DistributedDeviceProfile::DeviceIdType::UDID ||
379             aclProfile.GetTrustDeviceId().empty() || aclProfile.GetTrustDeviceId() != peerUdid ||
380             aclProfile.GetBindType() != (uint32_t)OHOS::DistributedDeviceProfile::BindType::SAME_ACCOUNT ||
381             aclProfile.GetAccesser().GetAccesserUserId() != localUserId ||
382             ((aclProfile.GetAccessee().GetAccesseeUserId() != peerUserId) &&
383             (aclProfile.GetAccessee().GetAccesseeUserId() != DEFAULT_USERID))) {
384             continue;
385         }
386         OHOS::DistributedDeviceProfile::Accesser accesser(aclProfile.GetAccesser());
387         if (sessionKeyId != DEFAULT_USER_KEY_INDEX) {
388             accesser.SetAccesserSessionKeyId(sessionKeyId);
389             accesser.SetAccesserSKTimeStamp(SoftBusGetSysTimeMs());
390         }
391         aclProfile.SetAccesser(accesser);
392         OHOS::DistributedDeviceProfile::Accessee accessee(aclProfile.GetAccessee());
393         if (accessee.GetAccesseeUserId() == DEFAULT_USERID && peerUserId != DEFAULT_USERID) {
394             accessee.SetAccesseeUserId(peerUserId);
395             aclProfile.SetAccessee(accessee);
396         }
397         if (aclProfile.GetAccessee().GetAccesseeDeviceId() == peerUdid &&
398             aclProfile.GetAccesser().GetAccesserDeviceId() != localUdid) {
399             continue;
400         }
401         DumpDpAclInfo(peerUdid, localUserId, peerUserId, aclProfile);
402         if (aclProfile.GetStatus() != (int32_t)OHOS::DistributedDeviceProfile::Status::ACTIVE) {
403             aclProfile.SetStatus((int32_t)OHOS::DistributedDeviceProfile::Status::ACTIVE);
404         }
405         ret = DpClient::GetInstance().UpdateAccessControlProfile(aclProfile);
406         LNN_LOGI(LNN_STATE, "UpdateAccessControlProfile ret=%{public}d", ret);
407         updateResult = UPDATE_ACL_SUCC;
408     }
409     return updateResult;
410 }
411 
GenerateDsoftbusBundleName(const char * peerUdid,const char * localUdid,int32_t localUserId,char * bundleName)412 static int32_t GenerateDsoftbusBundleName(
413     const char *peerUdid, const char *localUdid, int32_t localUserId, char *bundleName)
414 {
415     if (peerUdid == NULL || localUdid == NULL || bundleName == NULL) {
416         LNN_LOGE(LNN_STATE, "invalid param");
417         return SOFTBUS_INVALID_PARAM;
418     }
419 
420     char localShortUdid[SHORT_UDID_HASH_HEX_LEN + 1] = { 0 };
421     char peerShortUdid[SHORT_UDID_HASH_HEX_LEN + 1] = { 0 };
422     if (strncpy_s(localShortUdid, SHORT_UDID_HASH_HEX_LEN + 1, localUdid, SHORT_UDID_HASH_HEX_LEN) != EOK) {
423         LNN_LOGE(LNN_STATE, "strncpy_s localUdid fail");
424         return SOFTBUS_STRCPY_ERR;
425     }
426     if (strncpy_s(peerShortUdid, SHORT_UDID_HASH_HEX_LEN + 1, peerUdid, SHORT_UDID_HASH_HEX_LEN) != EOK) {
427         LNN_LOGE(LNN_STATE, "strncpy_s peerUdid fail");
428         return SOFTBUS_STRCPY_ERR;
429     }
430     if (sprintf_s(bundleName, MAX_BUNDLE_NAME_LEN, "dsoftbus_%d_%s_%s", localUserId, localShortUdid,
431         peerShortUdid) < 0) {
432         LNN_LOGE(LNN_STATE, "sprintf_s bundleName fail");
433         return SOFTBUS_SPRINTF_ERR;
434     }
435     return SOFTBUS_OK;
436 }
437 
InsertDpSameAccountAcl(const std::string & peerUdid,int32_t peerUserId,int32_t sessionKeyId)438 static void InsertDpSameAccountAcl(const std::string &peerUdid, int32_t peerUserId, int32_t sessionKeyId)
439 {
440     OHOS::DistributedDeviceProfile::AccessControlProfile accessControlProfile;
441     OHOS::DistributedDeviceProfile::Accesser accesser;
442     OHOS::DistributedDeviceProfile::Accessee accessee;
443     char udid[UDID_BUF_LEN] = { 0 };
444     if (LnnGetLocalStrInfo(STRING_KEY_DEV_UDID, udid, UDID_BUF_LEN) != SOFTBUS_OK) {
445         LNN_LOGE(LNN_STATE, "get local udid fail");
446         return;
447     }
448     uint64_t currentTime = SoftBusGetSysTimeMs();
449     std::string localUdid(udid);
450     accesser.SetAccesserDeviceId(localUdid);
451     accesser.SetAccesserUserId(GetActiveOsAccountIds());
452     OHOS::AccountSA::OhosAccountInfo accountInfo;
453     OHOS::ErrCode ret = OHOS::AccountSA::OhosAccountKits::GetInstance().GetOhosAccountInfo(accountInfo);
454     if (ret != OHOS::ERR_OK || accountInfo.uid_.empty()) {
455         LNN_LOGE(LNN_STATE, "GetOhosAccountInfo fail ret=%{public}d", ret);
456         return;
457     }
458     accesser.SetAccesserAccountId(accountInfo.uid_);
459     if (sessionKeyId != DEFAULT_USER_KEY_INDEX) {
460         accesser.SetAccesserSessionKeyId(sessionKeyId);
461         accesser.SetAccesserSKTimeStamp(currentTime);
462     }
463     char bundleName[MAX_BUNDLE_NAME_LEN] = { 0 };
464     if (GenerateDsoftbusBundleName(peerUdid.c_str(), udid, GetActiveOsAccountIds(), bundleName) != SOFTBUS_OK) {
465         LNN_LOGE(LNN_STATE, "generate dsoftbus bundle name fail.");
466         return;
467     }
468     accesser.SetAccesserBundleName(std::string(bundleName));
469     accessee.SetAccesseeDeviceId(peerUdid);
470     if (peerUserId != 0) {
471         accessee.SetAccesseeUserId(peerUserId);
472     }
473     accessee.SetAccesseeAccountId(accountInfo.uid_);
474     accessControlProfile.SetBindType((uint32_t)OHOS::DistributedDeviceProfile::BindType::SAME_ACCOUNT);
475     accessControlProfile.SetDeviceIdType((uint32_t)OHOS::DistributedDeviceProfile::DeviceIdType::UDID);
476     accessControlProfile.SetStatus((uint32_t)OHOS::DistributedDeviceProfile::Status::ACTIVE);
477     accessControlProfile.SetAuthenticationType((uint32_t)OHOS::DistributedDeviceProfile::AuthenticationType::PERMANENT);
478     accessControlProfile.SetTrustDeviceId(peerUdid);
479     accessControlProfile.SetAccesser(accesser);
480     accessControlProfile.SetAccessee(accessee);
481     ret = DpClient::GetInstance().PutAccessControlProfile(accessControlProfile);
482     if (ret != OHOS::DistributedDeviceProfile::DP_SUCCESS) {
483         LNN_LOGE(LNN_STATE, "PutAccessControlProfile failed, ret=%{public}d", ret);
484         return;
485     }
486     LNN_LOGI(LNN_STATE, "insert dp same account succ, GetAccesser=%{public}s, GetAccessee=%{public}s",
487         accesser.dump().c_str(), accessee.dump().c_str());
488 }
489 
PutDpAclUkByUserId(int32_t userId,const uint8_t * sessionKey,uint32_t sessionKeyLen,int32_t * sessionKeyId)490 static UpdateDpAclResult PutDpAclUkByUserId(
491     int32_t userId, const uint8_t *sessionKey, uint32_t sessionKeyLen, int32_t *sessionKeyId)
492 {
493     if (sessionKey == nullptr || sessionKeyId == nullptr) {
494         LNN_LOGE(LNN_STATE, "put uk info is invalid param");
495         return GET_ALL_ACL_FAIL;
496     }
497     std::vector<uint8_t> aclSessionKey;
498     std::copy(sessionKey, sessionKey + sizeof(uint8_t) * sessionKeyLen, std::back_inserter(aclSessionKey));
499     int32_t ret = DpClient::GetInstance().PutSessionKey(userId, aclSessionKey, *sessionKeyId);
500     if (ret != OHOS::ERR_OK) {
501         LNN_LOGE(LNN_STATE, "put session key fail, ret=%{public}d", ret);
502         return UPDATE_ACL_NOT_MATCH;
503     }
504     LNN_LOGI(
505         LNN_STATE, "set sessionKey for acl succ, sessionKeyId=%{public}d, userId=%{public}d", *sessionKeyId, userId);
506     return UPDATE_ACL_SUCC;
507 }
508 
UpdateDpSameAccount(UpdateDpAclParams * aclParams,SessionKey sessionKey,bool isNeedUpdateDk,AclWriteState aclState)509 void UpdateDpSameAccount(UpdateDpAclParams *aclParams, SessionKey sessionKey, bool isNeedUpdateDk,
510     AclWriteState aclState)
511 {
512     if (aclParams == nullptr || aclParams->deviceId == nullptr) {
513         LNN_LOGE(LNN_STATE, "deviceId is null");
514         return;
515     }
516     if (aclState == ACL_NOT_WRITE) {
517         LNN_LOGE(LNN_STATE, "no need write acl");
518         return;
519     }
520     int32_t sessionKeyId = DEFAULT_USER_KEY_INDEX;
521     std::string peerUdid(aclParams->deviceId);
522     UpdateDpAclResult ret = UPDATE_ACL_SUCC;
523 
524     if (isNeedUpdateDk) {
525         ret = PutDpAclUkByUserId(GetActiveOsAccountIds(), sessionKey.value, sessionKey.len, &sessionKeyId);
526         if (ret != UPDATE_ACL_SUCC) {
527             LNN_LOGW(LNN_STATE, "not need update uk for acl");
528         }
529     }
530     if (isNeedUpdateDk || IsSameAccount(aclParams->accountId) || (aclState == ACL_CAN_WRITE)) {
531         ret = UpdateDpSameAccountAcl(peerUdid, aclParams->peerUserId, sessionKeyId);
532         if (ret != UPDATE_ACL_SUCC) {
533             InsertDpSameAccountAcl(peerUdid, aclParams->peerUserId, sessionKeyId);
534         }
535     }
536 }
537 
GetSessionKeyProfile(int32_t sessionKeyId,uint8_t * sessionKey,uint32_t * length)538 bool GetSessionKeyProfile(int32_t sessionKeyId, uint8_t *sessionKey, uint32_t *length)
539 {
540     LNN_CHECK_AND_RETURN_RET_LOGE(sessionKey != NULL, false, LNN_EVENT, "sessionKey is null");
541     LNN_CHECK_AND_RETURN_RET_LOGE(length != NULL, false, LNN_EVENT, "length is null");
542     std::vector<uint8_t> vecSessionKey;
543     int32_t localUserId = GetActiveOsAccountIds();
544     if (localUserId < 0) {
545         LNN_LOGE(LNN_STATE, "GetUserId failed");
546         return false;
547     }
548     int32_t rc = DpClient::GetInstance().GetSessionKey(localUserId, sessionKeyId, vecSessionKey);
549     if (rc != OHOS::DistributedDeviceProfile::DP_SUCCESS) {
550         LNN_LOGE(LNN_STATE, "GetSessionKey failed, ret=%{public}d", rc);
551         return false;
552     }
553     std::copy(vecSessionKey.begin(), vecSessionKey.end(), sessionKey);
554     *length = vecSessionKey.size();
555     return true;
556 }
557 
DelSessionKeyProfile(int32_t sessionKeyId)558 void DelSessionKeyProfile(int32_t sessionKeyId)
559 {
560     int32_t localUserId = GetActiveOsAccountIds();
561     if (localUserId < 0) {
562         LNN_LOGE(LNN_STATE, "GetUserId failed");
563         return;
564     }
565     int32_t rc = DpClient::GetInstance().DeleteSessionKey(localUserId, sessionKeyId);
566     if (rc != OHOS::DistributedDeviceProfile::DP_SUCCESS) {
567         LNN_LOGE(LNN_STATE, "DelSessionKey failed, ret=%{public}d", rc);
568     }
569 }
570 
CompareAssetAclSameAccount(OHOS::DistributedDeviceProfile::AccessControlProfile aclProfile,const AuthACLInfo * acl,bool isSameSide)571 static bool CompareAssetAclSameAccount(
572     OHOS::DistributedDeviceProfile::AccessControlProfile aclProfile, const AuthACLInfo *acl, bool isSameSide)
573 {
574     std::string itemSourceDeviceId = aclProfile.GetAccesser().GetAccesserDeviceId();
575     std::string itemSinkDeviceId = aclProfile.GetAccessee().GetAccesseeDeviceId();
576     std::string itemSourceAccountId = aclProfile.GetAccesser().GetAccesserAccountId();
577     std::string itemSinkAccountId = aclProfile.GetAccessee().GetAccesseeAccountId();
578     if (aclProfile.GetBindType() != (uint32_t)OHOS::DistributedDeviceProfile::BindType::SAME_ACCOUNT) {
579         LNN_LOGE(LNN_STATE, "not same account");
580         return false;
581     }
582     if (isSameSide) {
583         if (itemSourceDeviceId.compare(std::string(acl->sourceUdid)) != 0 ||
584             itemSinkDeviceId.compare(std::string(acl->sinkUdid)) != 0 ||
585             itemSourceAccountId.compare(std::string(acl->sourceAccountId)) != 0 ||
586             itemSinkAccountId.compare(std::string(acl->sinkAccountId)) != 0 ||
587             strcmp(DEFAULT_ACCOUNT_UID, itemSourceAccountId.c_str()) == 0 ||
588             strcmp(DEFAULT_ACCOUNT_UID, itemSinkAccountId.c_str()) == 0 ||
589             aclProfile.GetAccesser().GetAccesserUserId() != acl->sourceUserId ||
590             aclProfile.GetAccessee().GetAccesseeUserId() != acl->sinkUserId) {
591             LNN_LOGE(LNN_STATE, "same side compare fail");
592             return false;
593         }
594         return true;
595     } else {
596         if (itemSourceDeviceId.compare(std::string(acl->sinkUdid)) != 0 ||
597             itemSinkDeviceId.compare(std::string(acl->sourceUdid)) != 0 ||
598             itemSourceAccountId.compare(std::string(acl->sinkAccountId)) != 0 ||
599             itemSinkAccountId.compare(std::string(acl->sourceAccountId)) != 0 ||
600             strcmp(DEFAULT_ACCOUNT_UID, itemSourceAccountId.c_str()) == 0 ||
601             strcmp(DEFAULT_ACCOUNT_UID, itemSinkAccountId.c_str()) == 0 ||
602             aclProfile.GetAccesser().GetAccesserUserId() != acl->sinkUserId ||
603             aclProfile.GetAccessee().GetAccesseeUserId() != acl->sourceUserId) {
604             LNN_LOGE(LNN_STATE, "diff side compare fail");
605             return false;
606         }
607         return true;
608     }
609 }
610 
CompareAssetAclDiffAccountWithUserLevel(OHOS::DistributedDeviceProfile::AccessControlProfile aclProfile,const AuthACLInfo * acl,bool isSameSide)611 static bool CompareAssetAclDiffAccountWithUserLevel(
612     OHOS::DistributedDeviceProfile::AccessControlProfile aclProfile, const AuthACLInfo *acl, bool isSameSide)
613 {
614     std::string itemSourceDeviceId = aclProfile.GetAccesser().GetAccesserDeviceId();
615     std::string itemSinkDeviceId = aclProfile.GetAccessee().GetAccesseeDeviceId();
616     if (aclProfile.GetBindLevel() != (uint32_t)OHOS::DistributedDeviceProfile::BindLevel::USER) {
617         LNN_LOGE(LNN_STATE, "bind level is no user");
618         return false;
619     }
620     if (isSameSide) {
621         if (itemSourceDeviceId.compare(std::string(acl->sourceUdid)) != 0 ||
622             itemSinkDeviceId.compare(std::string(acl->sinkUdid)) != 0 ||
623             aclProfile.GetAccesser().GetAccesserUserId() != acl->sourceUserId ||
624             aclProfile.GetAccessee().GetAccesseeUserId() != acl->sinkUserId) {
625             LNN_LOGE(LNN_STATE, "same side compare fail");
626             return false;
627         }
628         return true;
629     } else {
630         if (itemSourceDeviceId.compare(std::string(acl->sinkUdid)) != 0 ||
631             itemSinkDeviceId.compare(std::string(acl->sourceUdid)) != 0 ||
632             aclProfile.GetAccesser().GetAccesserUserId() != acl->sinkUserId ||
633             aclProfile.GetAccessee().GetAccesseeUserId() != acl->sourceUserId) {
634             LNN_LOGE(LNN_STATE, "diff side compare fail");
635             return false;
636         }
637         return true;
638     }
639 }
640 
CompareAssetAclDiffAccount(OHOS::DistributedDeviceProfile::AccessControlProfile aclProfile,const AuthACLInfo * acl,bool isSameSide)641 static bool CompareAssetAclDiffAccount(
642     OHOS::DistributedDeviceProfile::AccessControlProfile aclProfile, const AuthACLInfo *acl, bool isSameSide)
643 {
644     std::string itemSourceDeviceId = aclProfile.GetAccesser().GetAccesserDeviceId();
645     std::string itemSinkDeviceId = aclProfile.GetAccessee().GetAccesseeDeviceId();
646     if (aclProfile.GetBindType() == (uint32_t)OHOS::DistributedDeviceProfile::BindType::SAME_ACCOUNT ||
647         aclProfile.GetBindLevel() == (uint32_t)OHOS::DistributedDeviceProfile::BindLevel::USER) {
648         LNN_LOGE(LNN_STATE, "is same account or user bind level");
649         return false;
650     }
651     if (isSameSide) {
652         if (itemSourceDeviceId.compare(std::string(acl->sourceUdid)) != 0 ||
653             itemSinkDeviceId.compare(std::string(acl->sinkUdid)) != 0 ||
654             aclProfile.GetAccesser().GetAccesserUserId() != acl->sourceUserId ||
655             aclProfile.GetAccessee().GetAccesseeUserId() != acl->sinkUserId ||
656             (int32_t)aclProfile.GetAccesser().GetAccesserTokenId() != (int32_t)acl->sourceTokenId ||
657             (int32_t)aclProfile.GetAccessee().GetAccesseeTokenId() != (int32_t)acl->sinkTokenId) {
658             LNN_LOGE(LNN_STATE, "same side compare fail");
659             return false;
660         }
661         return true;
662     } else {
663         if (itemSourceDeviceId.compare(std::string(acl->sinkUdid)) != 0 ||
664             itemSinkDeviceId.compare(std::string(acl->sourceUdid)) != 0 ||
665             aclProfile.GetAccesser().GetAccesserUserId() != acl->sinkUserId ||
666             aclProfile.GetAccessee().GetAccesseeUserId() != acl->sourceUserId ||
667             (int32_t)aclProfile.GetAccesser().GetAccesserTokenId() != (int32_t)acl->sinkTokenId ||
668             (int32_t)aclProfile.GetAccessee().GetAccesseeTokenId() != (int32_t)acl->sourceTokenId) {
669             LNN_LOGE(LNN_STATE, "diff side compare fail");
670             return false;
671         }
672         return true;
673     }
674 }
675 
CompareAssetAllAcl(OHOS::DistributedDeviceProfile::AccessControlProfile aclProfile,const AuthACLInfo * acl,bool isSameSide,bool isSameAccount)676 static bool CompareAssetAllAcl(OHOS::DistributedDeviceProfile::AccessControlProfile aclProfile, const AuthACLInfo *acl,
677     bool isSameSide, bool isSameAccount)
678 {
679     if (isSameAccount) {
680         return CompareAssetAclSameAccount(aclProfile, acl, isSameSide);
681     }
682     return CompareAssetAclDiffAccountWithUserLevel(aclProfile, acl, isSameSide) ||
683         CompareAssetAclDiffAccount(aclProfile, acl, isSameSide);
684 }
685 
InsertUserKeyToUKCache(const AuthACLInfo * acl,int32_t ukId,uint64_t time,bool isUserBindLevel)686 static void InsertUserKeyToUKCache(const AuthACLInfo *acl, int32_t ukId, uint64_t time, bool isUserBindLevel)
687 {
688     AuthUserKeyInfo userKeyInfo = {};
689     AuthACLInfo info = {};
690     (void)memset_s(&userKeyInfo, sizeof(AuthUserKeyInfo), 0, sizeof(AuthUserKeyInfo));
691     (void)memset_s(&info, sizeof(AuthACLInfo), 0, sizeof(AuthACLInfo));
692     if (!acl->isServer) {
693         info.isServer = !acl->isServer;
694         if (strcpy_s(info.sourceUdid, UDID_BUF_LEN, acl->sinkUdid) != EOK ||
695             strcpy_s(info.sinkUdid, UDID_BUF_LEN, acl->sourceUdid) != EOK ||
696             strcpy_s(info.sourceAccountId, ACCOUNT_ID_BUF_LEN, acl->sinkAccountId) != EOK ||
697             strcpy_s(info.sinkAccountId, ACCOUNT_ID_BUF_LEN, acl->sourceAccountId) != EOK) {
698             LNN_LOGE(LNN_STATE, "copy info fail");
699             return;
700         }
701         info.sourceUserId = acl->sinkUserId;
702         info.sinkUserId = acl->sourceUserId;
703         info.sourceTokenId = acl->sinkTokenId;
704         info.sinkTokenId = acl->sourceTokenId;
705     } else {
706         info = *acl;
707     }
708     userKeyInfo.time = time;
709     userKeyInfo.keyIndex = ukId;
710     userKeyInfo.keyLen = SESSION_KEY_LENGTH;
711     if (GetUserKeyByUkId(ukId, userKeyInfo.deviceKey, SESSION_KEY_LENGTH) != SOFTBUS_OK) {
712         std::vector<uint8_t> sessionKey;
713         if (DpClient::GetInstance().GetSessionKey(info.sourceUserId, ukId, sessionKey) != OHOS::ERR_OK) {
714             LNN_LOGE(LNN_STATE, "getOhosAccountInfo fail");
715             return;
716         }
717         if (SESSION_KEY_LENGTH < sessionKey.size()) {
718             LNN_LOGE(LNN_STATE, "cannot memcpy uk, sessionKeyLen=%{public}u", (uint32_t)sessionKey.size());
719             sessionKey.clear();
720             return;
721         }
722         for (size_t i = 0; i < sessionKey.size(); ++i) {
723             userKeyInfo.deviceKey[i] = sessionKey[i];
724         }
725         userKeyInfo.keyLen = sessionKey.size();
726         sessionKey.clear();
727     }
728     (void)AuthInsertUserKey(&info, &userKeyInfo, isUserBindLevel);
729     (void)memset_s(userKeyInfo.deviceKey, sizeof(userKeyInfo.deviceKey), 0, sizeof(userKeyInfo.deviceKey));
730 }
731 
GetLocalUkIdFromAccess(OHOS::DistributedDeviceProfile::AccessControlProfile aclProfile,const AuthACLInfo * acl,int32_t * ukId,uint64_t * time)732 static void GetLocalUkIdFromAccess(OHOS::DistributedDeviceProfile::AccessControlProfile aclProfile,
733     const AuthACLInfo *acl, int32_t *ukId, uint64_t *time)
734 {
735     std::string accesserDeviceId = aclProfile.GetAccesser().GetAccesserDeviceId();
736     std::string accesseeDeviceId = aclProfile.GetAccessee().GetAccesseeDeviceId();
737     std::string localDeviceId = acl->isServer ? std::string(acl->sourceUdid) : std::string(acl->sinkUdid);
738     if (accesserDeviceId.compare(localDeviceId) == 0) {
739         *ukId = aclProfile.GetAccesser().GetAccesserSessionKeyId();
740         *time = aclProfile.GetAccesser().GetAccesserSKTimeStamp();
741     } else if (accesseeDeviceId.compare(localDeviceId) == 0) {
742         *ukId = aclProfile.GetAccessee().GetAccesseeSessionKeyId();
743         *time = aclProfile.GetAccessee().GetAccesseeSKTimeStamp();
744     }
745 }
746 
UpdateAccessProfileSessionKeyId(OHOS::DistributedDeviceProfile::AccessControlProfile aclProfile,int32_t * ukId)747 static void UpdateAccessProfileSessionKeyId(
748     OHOS::DistributedDeviceProfile::AccessControlProfile aclProfile, int32_t *ukId)
749 {
750     *ukId = DEFAULT_USER_KEY_INDEX;
751     OHOS::DistributedDeviceProfile::Accesser accesser(aclProfile.GetAccesser());
752     accesser.SetAccesserSessionKeyId(*ukId);
753     aclProfile.SetAccesser(accesser);
754     OHOS::DistributedDeviceProfile::Accessee accessee(aclProfile.GetAccessee());
755     accessee.SetAccesseeSessionKeyId(*ukId);
756     aclProfile.SetAccessee(accessee);
757     int32_t ret = DpClient::GetInstance().UpdateAccessControlProfile(aclProfile);
758     LNN_LOGI(LNN_STATE, "sessionKey is invalid, UpdateAccessControlProfile ret=%{public}d", ret);
759 }
760 
GetAccessUkIdSameAccount(const AuthACLInfo * acl,int32_t * ukId,uint64_t * time)761 int32_t GetAccessUkIdSameAccount(const AuthACLInfo *acl, int32_t *ukId, uint64_t *time)
762 {
763     if (acl == nullptr || ukId == nullptr || time == nullptr) {
764         LNN_LOGE(LNN_STATE, "find uk acl is invalid param");
765         return SOFTBUS_INVALID_PARAM;
766     }
767     std::vector<OHOS::DistributedDeviceProfile::AccessControlProfile> aclProfiles;
768     int32_t ret = DpClient::GetInstance().GetAllAccessControlProfile(aclProfiles);
769     if (ret != OHOS::DistributedDeviceProfile::DP_SUCCESS) {
770         LNN_LOGE(LNN_STATE, "GetAllAccessControlProfile ret=%{public}d", ret);
771         return SOFTBUS_AUTH_ACL_NOT_FOUND;
772     }
773     if (aclProfiles.empty()) {
774         LNN_LOGE(LNN_STATE, "aclProfiles is empty");
775         return SOFTBUS_AUTH_ACL_NOT_FOUND;
776     }
777     for (auto &aclProfile : aclProfiles) {
778         LNN_LOGI(LNN_STATE, "GetAccesser=%{public}s, GetAccessee=%{public}s",
779             aclProfile.GetAccesser().dump().c_str(), aclProfile.GetAccessee().dump().c_str());
780         if (!CompareAssetAclSameAccount(aclProfile, acl, acl->isServer)) {
781             continue;
782         }
783         GetLocalUkIdFromAccess(aclProfile, acl, ukId, time);
784         if (!AuthIsUkExpired(*time)) {
785             UpdateAccessProfileSessionKeyId(aclProfile, ukId);
786         } else {
787             InsertUserKeyToUKCache(acl, *ukId, *time,
788                 aclProfile.GetBindLevel() == (uint32_t)OHOS::DistributedDeviceProfile::BindLevel::USER);
789         }
790         return SOFTBUS_OK;
791     }
792     LNN_LOGE(LNN_STATE, "not find uk");
793     return SOFTBUS_AUTH_ACL_NOT_FOUND;
794 }
795 
GetAccessUkIdDiffAccountWithUserLevel(const AuthACLInfo * acl,int32_t * ukId,uint64_t * time)796 int32_t GetAccessUkIdDiffAccountWithUserLevel(const AuthACLInfo *acl, int32_t *ukId, uint64_t *time)
797 {
798     if (acl == nullptr || ukId == nullptr || time == nullptr) {
799         LNN_LOGE(LNN_STATE, "find uk info is invalid param");
800         return SOFTBUS_INVALID_PARAM;
801     }
802     std::vector<OHOS::DistributedDeviceProfile::AccessControlProfile> aclProfiles;
803     int32_t ret = DpClient::GetInstance().GetAllAccessControlProfile(aclProfiles);
804     if (ret != OHOS::DistributedDeviceProfile::DP_SUCCESS) {
805         LNN_LOGE(LNN_STATE, "GetAllAccessControlProfile ret=%{public}d", ret);
806         return SOFTBUS_AUTH_ACL_NOT_FOUND;
807     }
808     if (aclProfiles.empty()) {
809         LNN_LOGE(LNN_STATE, "aclProfiles is empty");
810         return SOFTBUS_AUTH_ACL_NOT_FOUND;
811     }
812     for (auto &aclProfile : aclProfiles) {
813         LNN_LOGI(LNN_STATE, "GetAccesser=%{public}s, GetAccessee=%{public}s",
814             aclProfile.GetAccesser().dump().c_str(), aclProfile.GetAccessee().dump().c_str());
815         if (!CompareAssetAclDiffAccountWithUserLevel(aclProfile, acl, true) &&
816             !CompareAssetAclDiffAccountWithUserLevel(aclProfile, acl, false)) {
817             continue;
818         }
819         GetLocalUkIdFromAccess(aclProfile, acl, ukId, time);
820         if (!AuthIsUkExpired(*time)) {
821             UpdateAccessProfileSessionKeyId(aclProfile, ukId);
822         } else {
823             InsertUserKeyToUKCache(acl, *ukId, *time,
824                 aclProfile.GetBindLevel() == (uint32_t)OHOS::DistributedDeviceProfile::BindLevel::USER);
825         }
826         return SOFTBUS_OK;
827     }
828     LNN_LOGE(LNN_STATE, "not find uk");
829     return SOFTBUS_AUTH_ACL_NOT_FOUND;
830 }
831 
GetAccessUkIdDiffAccount(const AuthACLInfo * acl,int32_t * ukId,uint64_t * time)832 int32_t GetAccessUkIdDiffAccount(const AuthACLInfo *acl, int32_t *ukId, uint64_t *time)
833 {
834     if (acl == nullptr || ukId == nullptr || time == nullptr) {
835         LNN_LOGE(LNN_STATE, "find uk info is invalid param");
836         return SOFTBUS_INVALID_PARAM;
837     }
838     std::vector<OHOS::DistributedDeviceProfile::AccessControlProfile> aclProfiles;
839     int32_t ret = DpClient::GetInstance().GetAllAccessControlProfile(aclProfiles);
840     if (ret != OHOS::DistributedDeviceProfile::DP_SUCCESS) {
841         LNN_LOGE(LNN_STATE, "GetAllAccessControlProfile ret=%{public}d", ret);
842         return SOFTBUS_AUTH_ACL_NOT_FOUND;
843     }
844     if (aclProfiles.empty()) {
845         LNN_LOGE(LNN_STATE, "aclProfiles is empty");
846         return SOFTBUS_AUTH_ACL_NOT_FOUND;
847     }
848     for (auto &aclProfile : aclProfiles) {
849         LNN_LOGI(LNN_STATE, "GetAccesser=%{public}s, GetAccessee=%{public}s",
850             aclProfile.GetAccesser().dump().c_str(), aclProfile.GetAccessee().dump().c_str());
851         if (!CompareAssetAclDiffAccount(aclProfile, acl, true) && !CompareAssetAclDiffAccount(aclProfile, acl, false)) {
852             continue;
853         }
854         GetLocalUkIdFromAccess(aclProfile, acl, ukId, time);
855         if (!AuthIsUkExpired(*time)) {
856             UpdateAccessProfileSessionKeyId(aclProfile, ukId);
857         } else {
858             InsertUserKeyToUKCache(acl, *ukId, *time,
859                 aclProfile.GetBindLevel() == (uint32_t)OHOS::DistributedDeviceProfile::BindLevel::USER);
860         }
861         return SOFTBUS_OK;
862     }
863     LNN_LOGE(LNN_STATE, "not find uk");
864     return SOFTBUS_AUTH_ACL_NOT_FOUND;
865 }
866 
GetAccessUkByUkId(int32_t sessionKeyId,uint8_t * uk,uint32_t ukLen)867 int32_t GetAccessUkByUkId(int32_t sessionKeyId, uint8_t *uk, uint32_t ukLen)
868 {
869     if (uk == nullptr) {
870         LNN_LOGE(LNN_STATE, "uk is invalid param");
871         return SOFTBUS_INVALID_PARAM;
872     }
873     std::vector<OHOS::DistributedDeviceProfile::AccessControlProfile> aclProfiles;
874     int32_t ret = DpClient::GetInstance().GetAllAccessControlProfile(aclProfiles);
875     if (ret != OHOS::DistributedDeviceProfile::DP_SUCCESS) {
876         LNN_LOGE(LNN_STATE, "GetAllAccessControlProfile ret=%{public}d", ret);
877         return SOFTBUS_AUTH_ACL_NOT_FOUND;
878     }
879     if (aclProfiles.empty()) {
880         LNN_LOGE(LNN_STATE, "aclProfiles is empty");
881         return SOFTBUS_AUTH_ACL_NOT_FOUND;
882     }
883     std::vector<uint8_t> sessionKey;
884     int32_t accesserSessionKeyId = 0;
885     int32_t accesseeSessionKeyId = 0;
886     for (auto &aclProfile : aclProfiles) {
887         LNN_LOGI(LNN_STATE, "GetAccesser=%{public}s, GetAccessee=%{public}s",
888             aclProfile.GetAccesser().dump().c_str(), aclProfile.GetAccessee().dump().c_str());
889         accesserSessionKeyId = aclProfile.GetAccesser().GetAccesserSessionKeyId();
890         accesseeSessionKeyId = aclProfile.GetAccessee().GetAccesseeSessionKeyId();
891         if (accesserSessionKeyId != sessionKeyId && accesseeSessionKeyId != sessionKeyId) {
892             continue;
893         }
894         uint32_t localUserId = aclProfile.GetAccesser().GetAccesserUserId();
895         if (DpClient::GetInstance().GetSessionKey(localUserId, sessionKeyId, sessionKey) != OHOS::ERR_OK) {
896             LNN_LOGE(LNN_STATE, "getOhosAccountInfo fail");
897             return SOFTBUS_AUTH_ACL_NOT_FOUND;
898         }
899         if (ukLen < sessionKey.size()) {
900             LNN_LOGE(LNN_STATE, "cannot memcpy uk, sessionKeyLen=%{public}u", (uint32_t)sessionKey.size());
901             return SOFTBUS_MEM_ERR;
902         }
903         for (size_t i = 0; i < sessionKey.size(); ++i) {
904             uk[i] = sessionKey[i];
905         }
906         sessionKey.clear();
907         LNN_LOGI(LNN_STATE, "user key find");
908         return SOFTBUS_OK;
909     }
910     LNN_LOGE(LNN_STATE, "user key not found");
911     return SOFTBUS_AUTH_ACL_NOT_FOUND;
912 }
913 
UpdateDpAclByAuthAcl(AuthACLInfo * info,int32_t sessionKeyId,uint64_t currentTime,bool isSameAccount)914 static UpdateDpAclResult UpdateDpAclByAuthAcl(
915     AuthACLInfo *info, int32_t sessionKeyId, uint64_t currentTime, bool isSameAccount)
916 {
917     std::vector<OHOS::DistributedDeviceProfile::AccessControlProfile> aclProfiles;
918     int32_t ret = DpClient::GetInstance().GetAllAccessControlProfile(aclProfiles);
919     if (ret != OHOS::DistributedDeviceProfile::DP_SUCCESS) {
920         LNN_LOGE(LNN_STATE, "GetAllAccessControlProfile ret=%{public}d", ret);
921         return GET_ALL_ACL_FAIL;
922     }
923     if (aclProfiles.empty()) {
924         LNN_LOGE(LNN_STATE, "aclProfiles is empty");
925         return GET_ALL_ACL_IS_EMPTY;
926     }
927     UpdateDpAclResult updateResult = UPDATE_ACL_NOT_MATCH;
928     for (auto &aclProfile : aclProfiles) {
929         LNN_LOGI(LNN_STATE, "GetAccesser=%{public}s, GetAccessee=%{public}s", aclProfile.GetAccesser().dump().c_str(),
930             aclProfile.GetAccessee().dump().c_str());
931         if ((CompareAssetAllAcl(aclProfile, info, true, isSameAccount) && info->isServer) ||
932             (CompareAssetAllAcl(aclProfile, info, false, isSameAccount) && !info->isServer)) {
933             OHOS::DistributedDeviceProfile::Accesser accesser(aclProfile.GetAccesser());
934             accesser.SetAccesserSessionKeyId(sessionKeyId);
935             accesser.SetAccesserSKTimeStamp(currentTime);
936             aclProfile.SetAccesser(accesser);
937             ret = DpClient::GetInstance().UpdateAccessControlProfile(aclProfile);
938             LNN_LOGI(LNN_STATE, "UpdateAccessControlProfile set accesser ret=%{public}d", ret);
939             updateResult = UPDATE_ACL_SUCC;
940         } else if ((CompareAssetAllAcl(aclProfile, info, true, isSameAccount) && !info->isServer) ||
941             (CompareAssetAllAcl(aclProfile, info, false, isSameAccount) && info->isServer)) {
942             OHOS::DistributedDeviceProfile::Accessee accessee(aclProfile.GetAccessee());
943             accessee.SetAccesseeSessionKeyId(sessionKeyId);
944             accessee.SetAccesseeSKTimeStamp(currentTime);
945             aclProfile.SetAccessee(accessee);
946             ret = DpClient::GetInstance().UpdateAccessControlProfile(aclProfile);
947             LNN_LOGI(LNN_STATE, "UpdateAccessControlProfile set accessee ret=%{public}d", ret);
948             updateResult = UPDATE_ACL_SUCC;
949         } else {
950             continue;
951         }
952         InsertUserKeyToUKCache(info, sessionKeyId, currentTime,
953             aclProfile.GetBindLevel() == (uint32_t)OHOS::DistributedDeviceProfile::BindLevel::USER);
954         LNN_LOGI(LNN_STATE, "find acl");
955     }
956     return updateResult;
957 }
958 
UpdateAssetSessionKeyByAcl(AuthACLInfo * info,const uint8_t * sessionKey,uint32_t sessionKeyLen,int32_t * sessionKeyId,bool isSameAccount)959 void UpdateAssetSessionKeyByAcl(
960     AuthACLInfo *info, const uint8_t *sessionKey, uint32_t sessionKeyLen, int32_t *sessionKeyId, bool isSameAccount)
961 {
962     if (info == nullptr) {
963         LNN_LOGE(LNN_STATE, "acl info is null");
964         return;
965     }
966     UpdateDpAclResult ret = UPDATE_ACL_SUCC;
967     uint64_t currentTime = SoftBusGetSysTimeMs();
968 
969     if (!info->isServer) {
970         ret = PutDpAclUkByUserId(info->sinkUserId, sessionKey, sessionKeyLen, sessionKeyId);
971     } else {
972         ret = PutDpAclUkByUserId(info->sourceUserId, sessionKey, sessionKeyLen, sessionKeyId);
973     }
974     if (ret != UPDATE_ACL_SUCC) {
975         LNN_LOGW(LNN_STATE, "PutDpAclUkByUserId failed, ret=%{public}d", ret);
976         //fall-through: Possible failure, do not handle abnormal scenarios.
977     }
978     ret = UpdateDpAclByAuthAcl(info, *sessionKeyId, currentTime, isSameAccount);
979     LNN_LOGW(LNN_STATE, "UpdateDpAclByAuthAcl result ret=%{public}d", ret);
980     return;
981 }
982 
IsSKIdInvalidInner(int32_t sessionKeyId,const char * accountHash,const char * udidShortHash,int32_t userId,OHOS::DistributedDeviceProfile::AccessControlProfile & aclProfile)983 static bool IsSKIdInvalidInner(int32_t sessionKeyId, const char *accountHash, const char *udidShortHash,
984     int32_t userId, OHOS::DistributedDeviceProfile::AccessControlProfile &aclProfile)
985 {
986     std::string sourceDeviceId = aclProfile.GetAccesser().GetAccesserDeviceId();
987     std::string sourceAccountId = aclProfile.GetAccesser().GetAccesserAccountId();
988     std::string sinkDeviceId = aclProfile.GetAccessee().GetAccesseeDeviceId();
989     std::string sinkAccountId = aclProfile.GetAccessee().GetAccesseeAccountId();
990     char aclUdidShortHash[SHA_256_HEX_HASH_LEN] = { 0 };
991     char aclAccountHash[SHA_256_HEX_HASH_LEN] = { 0 };
992     if (strcmp(DEFAULT_ACCOUNT_UID, sourceAccountId.c_str()) == 0) {
993         (void)GetStringHash(DEFAULT_ACCOUNT_VALUE, aclAccountHash, SHA_256_HEX_HASH_LEN - 1);
994         sourceAccountId = aclAccountHash;
995     }
996     if (strcmp(DEFAULT_ACCOUNT_UID, sinkAccountId.c_str()) == 0) {
997         (void)GetStringHash(DEFAULT_ACCOUNT_VALUE, aclAccountHash, SHA_256_HEX_HASH_LEN - 1);
998         sinkAccountId = aclAccountHash;
999     }
1000     if (aclProfile.GetAccesser().GetAccesserSessionKeyId() == sessionKeyId) {
1001         if (GetStringHash(sinkDeviceId, aclUdidShortHash, CUST_UDID_LEN) != SOFTBUS_OK) {
1002             LNN_LOGE(LNN_STATE, "GetStringHash fail");
1003             return false;
1004         }
1005         if (StrCmpIgnoreCase(aclUdidShortHash, udidShortHash) != 0 ||
1006             StrCmpIgnoreCase(sinkAccountId.c_str(), accountHash) != 0 ||
1007             userId != aclProfile.GetAccessee().GetAccesseeUserId()) {
1008             LNN_LOGE(LNN_STATE, "accountId/udid/userId error");
1009             return true;
1010         }
1011         return false;
1012     } else if (aclProfile.GetAccessee().GetAccesseeSessionKeyId() == sessionKeyId) {
1013         if (GetStringHash(sourceDeviceId, aclUdidShortHash, CUST_UDID_LEN) != SOFTBUS_OK) {
1014             LNN_LOGE(LNN_STATE, "GetStringHash fail");
1015             return false;
1016         }
1017         if (StrCmpIgnoreCase(aclUdidShortHash, udidShortHash) != 0 ||
1018             StrCmpIgnoreCase(sourceAccountId.c_str(), accountHash) != 0 ||
1019             userId != aclProfile.GetAccesser().GetAccesserUserId()) {
1020             LNN_LOGE(LNN_STATE, "accountId/udid/userId error");
1021             return true;
1022         }
1023         return false;
1024     }
1025     LNN_LOGE(LNN_STATE, "skId not match!");
1026     return true;
1027 }
1028 
IsSKIdInvalid(int32_t sessionKeyId,const char * accountHash,const char * udidShortHash,int32_t userId)1029 bool IsSKIdInvalid(int32_t sessionKeyId, const char *accountHash, const char *udidShortHash, int32_t userId)
1030 {
1031     if (accountHash == nullptr || udidShortHash == nullptr || strlen(udidShortHash) < CUST_UDID_LEN ||
1032         strlen(accountHash) < SHA_256_HEX_HASH_LEN - 1) {
1033         LNN_LOGE(LNN_STATE, "param error");
1034         return false;
1035     }
1036 
1037     std::vector<OHOS::DistributedDeviceProfile::AccessControlProfile> aclProfiles;
1038     int32_t ret = DpClient::GetInstance().GetAllAccessControlProfile(aclProfiles);
1039     if (ret != OHOS::DistributedDeviceProfile::DP_SUCCESS) {
1040         LNN_LOGE(LNN_STATE, "GetAllAccessControlProfile ret=%{public}d", ret);
1041         return false;
1042     }
1043     if (aclProfiles.empty()) {
1044         LNN_LOGE(LNN_STATE, "aclProfiles is empty");
1045         return true;
1046     }
1047     int32_t accesserSessionKeyId = 0;
1048     int32_t accesseeSessionKeyId = 0;
1049     for (auto &aclProfile : aclProfiles) {
1050         LNN_LOGI(LNN_STATE, "GetAccesser=%{public}s, GetAccessee=%{public}s",
1051             aclProfile.GetAccesser().dump().c_str(), aclProfile.GetAccessee().dump().c_str());
1052         accesserSessionKeyId = aclProfile.GetAccesser().GetAccesserSessionKeyId();
1053         accesseeSessionKeyId = aclProfile.GetAccessee().GetAccesseeSessionKeyId();
1054         if (accesserSessionKeyId != sessionKeyId && accesseeSessionKeyId != sessionKeyId) {
1055             continue;
1056         }
1057         return IsSKIdInvalidInner(sessionKeyId, accountHash, udidShortHash, userId, aclProfile);
1058     }
1059     LNN_LOGE(LNN_STATE, "key not found");
1060     return true;
1061 }
1062 
SelectAllAcl(TrustedInfo ** trustedInfoArray,uint32_t * num)1063 int32_t SelectAllAcl(TrustedInfo **trustedInfoArray, uint32_t *num)
1064 {
1065     if (num == nullptr || trustedInfoArray == nullptr) {
1066         LNN_LOGE(LNN_LEDGER, "invalid param");
1067         return SOFTBUS_INVALID_PARAM;
1068     }
1069     std::vector<OHOS::DistributedDeviceProfile::AccessControlProfile> aclProfiles;
1070     int32_t ret = DpClient::GetInstance().GetAllAccessControlProfile(aclProfiles);
1071     if (ret != OHOS::DistributedDeviceProfile::DP_SUCCESS) {
1072         LNN_LOGE(LNN_STATE, "GetAllAccessControlProfile ret=%{public}d", ret);
1073         return SOFTBUS_AUTH_ACL_NOT_FOUND;
1074     }
1075     if (aclProfiles.empty()) {
1076         LNN_LOGI(LNN_STATE, "aclProfiles is empty");
1077         return SOFTBUS_OK;
1078     }
1079     int32_t localUserId = GetActiveOsAccountIds();
1080     std::unordered_set<std::string> matchAcl;
1081     for (auto &aclProfile : aclProfiles) {
1082         if (aclProfile.GetDeviceIdType() != (uint32_t)OHOS::DistributedDeviceProfile::DeviceIdType::UDID ||
1083             aclProfile.GetTrustDeviceId().empty() || GetAclLocalUserId(aclProfile) != localUserId ||
1084             aclProfile.GetBindType() == (uint32_t)OHOS::DistributedDeviceProfile::BindType::SAME_ACCOUNT) {
1085             continue;
1086         }
1087         char *anonyUdid = nullptr;
1088         Anonymize(aclProfile.GetTrustDeviceId().c_str(), &anonyUdid);
1089         LNN_LOGI(LNN_STATE, "trusted dev info, udid=%{public}s, localUserId=%{public}d",
1090             AnonymizeWrapper(anonyUdid), GetAclLocalUserId(aclProfile));
1091         AnonymizeFree(anonyUdid);
1092         matchAcl.insert(aclProfile.GetTrustDeviceId());
1093     }
1094     if (matchAcl.empty()) {
1095         LNN_LOGI(LNN_STATE, "matchAcl is empty");
1096         return SOFTBUS_OK;
1097     }
1098     *trustedInfoArray = (TrustedInfo *)SoftBusCalloc(matchAcl.size() * sizeof(TrustedInfo));
1099     if (*trustedInfoArray == nullptr) {
1100         LNN_LOGE(LNN_STATE, "malloc fail.");
1101         return SOFTBUS_MALLOC_ERR;
1102     }
1103     for (auto item : matchAcl)  {
1104         if (strcpy_s(((*trustedInfoArray) + (*num))->udid, UDID_BUF_LEN, item.c_str()) != EOK) {
1105             LNN_LOGE(LNN_STATE, "udid str cpy fail");
1106             SoftBusFree(*trustedInfoArray);
1107             return SOFTBUS_STRCPY_ERR;
1108         }
1109         ((*trustedInfoArray) + (*num))->userId = localUserId;
1110         (*num)++;
1111     }
1112     return SOFTBUS_OK;
1113 }
1114