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