1 /*
2 * Copyright (c) 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_apply_key_manager.h"
17
18 #include <dirent.h>
19 #include <errno.h>
20 #include <securec.h>
21 #include <sys/stat.h>
22 #include <sys/types.h>
23
24 #include "anonymizer.h"
25 #include "auth_apply_key_process.h"
26 #include "auth_log.h"
27 #include "bus_center_event.h"
28 #include "g_enhance_lnn_func_pack.h"
29 #include "lnn_async_callback_utils.h"
30 #include "lnn_decision_db.h"
31 #include "lnn_map.h"
32 #include "lnn_ohos_account_adapter.h"
33 #include "softbus_adapter_file.h"
34 #include "softbus_adapter_mem.h"
35 #include "softbus_init_common.h"
36 #include "softbus_json_utils.h"
37
38 #define DEFAULT_FILE_PATH "/data/service/el1/public/dsoftbus/applykey"
39 #define KEY_LEN 100
40 #define MAP_KEY "mapKey"
41
42 #define VALUE_APPLY_KEY "applyKey"
43 #define VALUE_USER_ID "userId"
44 #define VALUE_TIME "time"
45 #define VALUE_ACCOUNT_HASH "accountHash"
46
47 typedef struct {
48 uint8_t applyKey[D2D_APPLY_KEY_LEN];
49 int32_t userId;
50 uint64_t time;
51 char accountHash[SHA_256_HEX_HASH_LEN];
52 } AuthApplyMapValue;
53
54 typedef struct {
55 char mapKey[KEY_LEN];
56 AuthApplyMapValue value;
57 } AuthApplyMap;
58
59 static Map g_authApplyMap;
60 static SoftBusMutex g_authApplyMutex;
61 static bool g_isInit = false;
62
AuthApplyMapInit(void)63 static int32_t AuthApplyMapInit(void)
64 {
65 if (SoftBusMutexInit(&g_authApplyMutex, NULL) != SOFTBUS_OK) {
66 AUTH_LOGE(AUTH_CONN, "g_authApplyMutex mutex init fail");
67 return SOFTBUS_LOCK_ERR;
68 }
69 LnnMapInit(&g_authApplyMap);
70 g_isInit = true;
71 return SOFTBUS_OK;
72 }
73
InsertToAuthApplyMap(const char * applyMapKey,const uint8_t * applyKey,int32_t userId,uint64_t time,char * accountHash)74 static int32_t InsertToAuthApplyMap(
75 const char *applyMapKey, const uint8_t *applyKey, int32_t userId, uint64_t time, char *accountHash)
76 {
77 if (!g_isInit) {
78 AUTH_LOGE(AUTH_INIT, "apply map init fail");
79 return SOFTBUS_NO_INIT;
80 }
81 if (applyMapKey == NULL || applyKey == NULL || accountHash == NULL) {
82 AUTH_LOGE(AUTH_INIT, "input is invalid param");
83 return SOFTBUS_INVALID_PARAM;
84 }
85
86 AuthApplyMapValue value = { .userId = userId, .time = time };
87 if (memcpy_s(value.applyKey, D2D_APPLY_KEY_LEN, applyKey, D2D_APPLY_KEY_LEN) != EOK) {
88 AUTH_LOGE(AUTH_CONN, "memcpy fail");
89 return SOFTBUS_MEM_ERR;
90 }
91 if (strcpy_s(value.accountHash, SHA_256_HEX_HASH_LEN, accountHash) != EOK) {
92 AUTH_LOGE(AUTH_CONN, "strcpy accountHash fail");
93 return SOFTBUS_STRCPY_ERR;
94 }
95 if (SoftBusMutexLock(&g_authApplyMutex) != SOFTBUS_OK) {
96 (void)memset_s(&value, sizeof(AuthApplyMapValue), 0, sizeof(AuthApplyMapValue));
97 AUTH_LOGE(AUTH_CONN, "SoftBusMutexLock fail");
98 return SOFTBUS_LOCK_ERR;
99 }
100 int32_t ret = LnnMapSet(&g_authApplyMap, applyMapKey, (const void *)&value, sizeof(AuthApplyMapValue));
101 if (ret != SOFTBUS_OK) {
102 (void)memset_s(&value, sizeof(AuthApplyMapValue), 0, sizeof(AuthApplyMapValue));
103 (void)SoftBusMutexUnlock(&g_authApplyMutex);
104 AUTH_LOGE(AUTH_CONN, "LnnMapSet fail");
105 return ret;
106 }
107 (void)memset_s(&value, sizeof(AuthApplyMapValue), 0, sizeof(AuthApplyMapValue));
108 (void)SoftBusMutexUnlock(&g_authApplyMutex);
109 return SOFTBUS_OK;
110 }
111
GetNodeFromAuthApplyMap(const char * applyMapKey,AuthApplyMapValue ** value)112 static int32_t GetNodeFromAuthApplyMap(const char *applyMapKey, AuthApplyMapValue **value)
113 {
114 if (!g_isInit) {
115 AUTH_LOGE(AUTH_INIT, "apply map init fail");
116 return SOFTBUS_NO_INIT;
117 }
118 if (applyMapKey == NULL) {
119 AUTH_LOGE(AUTH_INIT, "input is invalid param");
120 return SOFTBUS_INVALID_PARAM;
121 }
122
123 if (SoftBusMutexLock(&g_authApplyMutex) != SOFTBUS_OK) {
124 AUTH_LOGE(AUTH_CONN, "SoftBusMutexLock fail");
125 return SOFTBUS_LOCK_ERR;
126 }
127 uint64_t *ptr = (uint64_t *)LnnMapGet(&g_authApplyMap, applyMapKey);
128 if (ptr == NULL) {
129 AUTH_LOGE(AUTH_CONN, "LnnMapGet fail");
130 (void)SoftBusMutexUnlock(&g_authApplyMutex);
131 return SOFTBUS_AUTH_APPLY_KEY_NOT_FOUND;
132 }
133 *value = (AuthApplyMapValue *)ptr;
134 (void)SoftBusMutexUnlock(&g_authApplyMutex);
135 return SOFTBUS_OK;
136 }
137
DeleteToAuthApplyMap(const char * applyMapKey)138 static int32_t DeleteToAuthApplyMap(const char *applyMapKey)
139 {
140 if (!g_isInit) {
141 AUTH_LOGE(AUTH_INIT, "apply map init fail");
142 return SOFTBUS_NO_INIT;
143 }
144 if (applyMapKey == NULL) {
145 AUTH_LOGE(AUTH_INIT, "input is invalid param");
146 return SOFTBUS_INVALID_PARAM;
147 }
148
149 if (SoftBusMutexLock(&g_authApplyMutex) != SOFTBUS_OK) {
150 AUTH_LOGE(AUTH_CONN, "SoftBusMutexLock fail");
151 return SOFTBUS_LOCK_ERR;
152 }
153 int32_t ret = LnnMapErase(&g_authApplyMap, applyMapKey);
154 if (ret != SOFTBUS_OK) {
155 AUTH_LOGE(AUTH_CONN, "delete item fail, ret=%{public}d", ret);
156 (void)SoftBusMutexUnlock(&g_authApplyMutex);
157 return ret;
158 }
159 (void)SoftBusMutexUnlock(&g_authApplyMutex);
160 return SOFTBUS_OK;
161 }
162
ClearAuthApplyMap(void)163 static void ClearAuthApplyMap(void)
164 {
165 if (!g_isInit) {
166 AUTH_LOGE(AUTH_INIT, "apply map init fail");
167 return;
168 }
169
170 if (SoftBusMutexLock(&g_authApplyMutex) != SOFTBUS_OK) {
171 AUTH_LOGE(AUTH_CONN, "SoftBusMutexLock fail");
172 return;
173 }
174 LnnMapDelete(&g_authApplyMap);
175 AUTH_LOGI(AUTH_CONN, "ClearAuthApplyMap succ");
176 (void)SoftBusMutexUnlock(&g_authApplyMutex);
177 }
178
GetApplyKeyByBusinessInfo(const RequestBusinessInfo * info,uint8_t * uk,uint32_t ukLen,char * accountHash,uint32_t accountHashLen)179 int32_t GetApplyKeyByBusinessInfo(
180 const RequestBusinessInfo *info, uint8_t *uk, uint32_t ukLen, char *accountHash, uint32_t accountHashLen)
181 {
182 if (info == NULL || uk == NULL || accountHash == NULL || accountHashLen != SHA_256_HEX_HASH_LEN) {
183 AUTH_LOGE(AUTH_CONN, "invalid param");
184 return SOFTBUS_INVALID_PARAM;
185 }
186 char key[KEY_LEN];
187 int32_t userId = GetActiveOsAccountIds();
188 if (sprintf_s(key, sizeof(key), "%s_%s_%d_%d", info->udidHash, info->accountHash, userId, info->type) < 0) {
189 AUTH_LOGE(AUTH_CONN, "sprintf_s key fail");
190 return SOFTBUS_SPRINTF_ERR;
191 }
192 char *anonyAccountHash = NULL;
193 Anonymize(info->accountHash, &anonyAccountHash);
194 char *anonyUdidHash = NULL;
195 Anonymize(info->udidHash, &anonyUdidHash);
196 AUTH_LOGI(AUTH_CONN, "map key udidHash=%{public}s, accountHash=%{public}s, userId=%{public}d, type=%{public}d",
197 AnonymizeWrapper(anonyUdidHash), AnonymizeWrapper(anonyAccountHash), userId, info->type);
198 AnonymizeFree(anonyAccountHash);
199 AnonymizeFree(anonyUdidHash);
200 AuthApplyMapValue *value = NULL;
201 int32_t ret = GetNodeFromAuthApplyMap(key, &value);
202 if (ret != SOFTBUS_OK) {
203 AUTH_LOGE(AUTH_CONN, "GetNodeFromAuthApplyMap fail");
204 return ret;
205 }
206 if (memcpy_s(uk, ukLen, value->applyKey, D2D_APPLY_KEY_LEN) != EOK) {
207 AUTH_LOGE(AUTH_CONN, "memcpy key fail");
208 return SOFTBUS_MEM_ERR;
209 }
210 if (strcpy_s(accountHash, SHA_256_HEX_HASH_LEN, value->accountHash) != EOK) {
211 AUTH_LOGE(AUTH_CONN, "strcpy accountHash fail");
212 return SOFTBUS_STRCPY_ERR;
213 }
214 return SOFTBUS_OK;
215 }
216
PackAllApplyKey(void)217 static char *PackAllApplyKey(void)
218 {
219 cJSON *jsonArray = cJSON_CreateArray();
220 if (jsonArray == NULL) {
221 AUTH_LOGE(AUTH_CONN, "jsonArray is null");
222 return NULL;
223 }
224 if (SoftBusMutexLock(&g_authApplyMutex) != SOFTBUS_OK) {
225 AUTH_LOGE(AUTH_CONN, "SoftBusMutexLock fail");
226 cJSON_Delete(jsonArray);
227 return NULL;
228 }
229 MapIterator *it = LnnMapInitIterator(&g_authApplyMap);
230 if (it == NULL) {
231 AUTH_LOGE(AUTH_CONN, "map is empty");
232 (void)SoftBusMutexUnlock(&g_authApplyMutex);
233 cJSON_Delete(jsonArray);
234 return NULL;
235 }
236 while (LnnMapHasNext(it)) {
237 it = LnnMapNext(it);
238 if (it == NULL || it->node->value == NULL) {
239 break;
240 }
241 cJSON *obj = cJSON_CreateObject();
242 if (obj == NULL) {
243 AUTH_LOGE(AUTH_CONN, "create json fail");
244 break;
245 }
246 if (!AddStringToJsonObject(obj, MAP_KEY, it->node->key) ||
247 !AddStringToJsonObject(obj, VALUE_APPLY_KEY, (char *)((AuthApplyMapValue *)it->node->value)->applyKey) ||
248 !AddStringToJsonObject(obj, VALUE_ACCOUNT_HASH, ((AuthApplyMapValue *)it->node->value)->accountHash) ||
249 !AddNumberToJsonObject(obj, VALUE_USER_ID, ((AuthApplyMapValue *)it->node->value)->userId) ||
250 !AddNumber64ToJsonObject(obj, VALUE_TIME, ((AuthApplyMapValue *)it->node->value)->time)) {
251 AUTH_LOGE(AUTH_CONN, "add json object fail");
252 cJSON_Delete(obj);
253 break;
254 }
255 cJSON_AddItemToArray(jsonArray, obj);
256 }
257 LnnMapDeinitIterator(it);
258 char *msg = cJSON_PrintUnformatted(jsonArray);
259 if (msg == NULL) {
260 AUTH_LOGE(AUTH_CONN, "cJSON_PrintUnformatted fail");
261 }
262 (void)SoftBusMutexUnlock(&g_authApplyMutex);
263 cJSON_Delete(jsonArray);
264 return msg;
265 }
266
AuthAsyncSaveApplyMapFile(void)267 static void AuthAsyncSaveApplyMapFile(void)
268 {
269 char *dataStr = PackAllApplyKey();
270 if (dataStr == NULL) {
271 AUTH_LOGE(AUTH_CONN, "PackAllApplyKey fail");
272 }
273 if (LnnAsyncSaveDeviceDataPacked((const char *)dataStr, LNN_DATA_TYPE_APPLY_KEY) != SOFTBUS_OK) {
274 AUTH_LOGE(AUTH_CONN, "save apply key fail");
275 }
276 (void)memset_s(&dataStr, strlen(dataStr), 0, strlen(dataStr));
277 cJSON_free(dataStr);
278 return;
279 }
280
AuthUnpackApplyKey(const cJSON * json,AuthApplyMap * node)281 static bool AuthUnpackApplyKey(const cJSON *json, AuthApplyMap *node)
282 {
283 if (json == NULL || node == NULL) {
284 AUTH_LOGE(AUTH_CONN, "invalid param");
285 return false;
286 }
287 if (!GetJsonObjectNumber64Item(json, VALUE_TIME, (int64_t *)&node->value.time) ||
288 !GetJsonObjectNumberItem(json, VALUE_USER_ID, &node->value.userId) ||
289 !GetJsonObjectStringItem(json, MAP_KEY, node->mapKey, KEY_LEN) ||
290 !GetJsonObjectStringItem(json, VALUE_APPLY_KEY, (char *)node->value.applyKey, D2D_APPLY_KEY_LEN) ||
291 !GetJsonObjectStringItem(json, VALUE_ACCOUNT_HASH, node->value.accountHash, SHA_256_HEX_HASH_LEN)) {
292 AUTH_LOGE(AUTH_CONN, "unpack apply key fail");
293 return false;
294 }
295 return true;
296 }
297
AuthPraseApplyKey(const char * applyKey)298 static bool AuthPraseApplyKey(const char *applyKey)
299 {
300 if (applyKey == NULL) {
301 AUTH_LOGE(AUTH_CONN, "invalid param");
302 return false;
303 }
304
305 cJSON *json = cJSON_Parse(applyKey);
306 if (json == NULL) {
307 AUTH_LOGE(AUTH_CONN, "prase json fail");
308 return false;
309 }
310 int32_t arraySize = cJSON_GetArraySize(json);
311 AuthApplyMap node = { 0 };
312 for (int32_t i = 0; i < arraySize; i++) {
313 cJSON *item = cJSON_GetArrayItem(json, i);
314 (void)memset_s(&node, sizeof(AuthApplyMap), 0, sizeof(AuthApplyMap));
315 if (!AuthUnpackApplyKey(item, &node)) {
316 cJSON_Delete(json);
317 (void)memset_s(&node, sizeof(AuthApplyMap), 0, sizeof(AuthApplyMap));
318 }
319 if (AuthIsApplyKeyExpired(node.value.time)) {
320 if (InsertToAuthApplyMap(node.mapKey, node.value.applyKey, node.value.userId,
321 node.value.time, node.value.accountHash) != SOFTBUS_OK) {
322 AUTH_LOGE(AUTH_CONN, "insert apply key fail");
323 cJSON_Delete(json);
324 (void)memset_s(&node, sizeof(AuthApplyMap), 0, sizeof(AuthApplyMap));
325 return false;
326 }
327 } else {
328 AUTH_LOGE(AUTH_CONN, "get invalid apply key");
329 }
330 }
331 cJSON_Delete(json);
332 (void)memset_s(&node, sizeof(AuthApplyMap), 0, sizeof(AuthApplyMap));
333 return true;
334 }
335
AuthRecoveryApplyKey(void)336 void AuthRecoveryApplyKey(void)
337 {
338 char *applyKey = NULL;
339 uint32_t applyKeyLen = 0;
340 if (LnnRetrieveDeviceDataPacked(LNN_DATA_TYPE_APPLY_KEY, &applyKey, &applyKeyLen) != SOFTBUS_OK) {
341 AUTH_LOGE(AUTH_CONN, "retrieve device fail");
342 return;
343 }
344 if (applyKey == NULL) {
345 AUTH_LOGE(AUTH_CONN, "applyKey is empty");
346 return;
347 }
348 if (applyKeyLen == 0) {
349 AUTH_LOGE(AUTH_CONN, "applyKeyLen is zero");
350 (void)memset_s(applyKey, applyKeyLen, 0, applyKeyLen);
351 SoftBusFree(applyKey);
352 return;
353 }
354 if (!AuthPraseApplyKey(applyKey)) {
355 AUTH_LOGE(AUTH_CONN, "prase applyKey fail");
356 (void)LnnDeleteDeviceDataPacked((LnnDataType)LNN_DATA_TYPE_APPLY_KEY);
357 }
358 (void)memset_s(applyKey, applyKeyLen, 0, applyKeyLen);
359 SoftBusFree(applyKey);
360 }
361
AuthInsertApplyKey(const RequestBusinessInfo * info,const uint8_t * uk,uint32_t ukLen,uint64_t time,char * accountHash)362 int32_t AuthInsertApplyKey(
363 const RequestBusinessInfo *info, const uint8_t *uk, uint32_t ukLen, uint64_t time, char *accountHash)
364 {
365 if (info == NULL || uk == NULL || ukLen != D2D_APPLY_KEY_LEN || accountHash == NULL) {
366 AUTH_LOGE(AUTH_CONN, "invalid param");
367 return SOFTBUS_INVALID_PARAM;
368 }
369 char key[KEY_LEN];
370 int32_t userId = GetActiveOsAccountIds();
371 (void)memset_s(key, KEY_LEN, 0, KEY_LEN);
372 if (sprintf_s(key, sizeof(key), "%s_%s_%d_%d", info->udidHash, info->accountHash, userId, info->type) < 0) {
373 AUTH_LOGE(AUTH_CONN, "sprintf_s key fail");
374 return SOFTBUS_SPRINTF_ERR;
375 }
376 char *anonyAccountHash = NULL;
377 Anonymize(info->accountHash, &anonyAccountHash);
378 char *anonyUdidHash = NULL;
379 Anonymize(info->udidHash, &anonyUdidHash);
380 AUTH_LOGI(AUTH_CONN, "map key udidHash=%{public}s, accountHash=%{public}s, userId=%{public}d, type=%{public}d",
381 AnonymizeWrapper(anonyUdidHash), AnonymizeWrapper(anonyAccountHash), userId, info->type);
382 AnonymizeFree(anonyAccountHash);
383 AnonymizeFree(anonyUdidHash);
384 int32_t ret = InsertToAuthApplyMap(key, (const uint8_t *)uk, userId, time, accountHash);
385 if (ret != SOFTBUS_OK) {
386 AUTH_LOGE(AUTH_CONN, "insert apply key fail");
387 return ret;
388 }
389 AuthAsyncSaveApplyMapFile();
390 return ret;
391 }
392
AuthDeleteApplyKey(const RequestBusinessInfo * info)393 int32_t AuthDeleteApplyKey(const RequestBusinessInfo *info)
394 {
395 if (info == NULL) {
396 AUTH_LOGE(AUTH_CONN, "invalid param");
397 return SOFTBUS_INVALID_PARAM;
398 }
399 char key[KEY_LEN];
400 (void)memset_s(key, KEY_LEN, 0, KEY_LEN);
401 if (sprintf_s(key, sizeof(key), "%s_%s_%d_%d", info->udidHash, info->accountHash, GetActiveOsAccountIds(),
402 info->type) < 0) {
403 AUTH_LOGE(AUTH_CONN, "sprintf_s key fail");
404 return SOFTBUS_SPRINTF_ERR;
405 }
406 int32_t ret = DeleteToAuthApplyMap(key);
407 if (ret != SOFTBUS_OK) {
408 AUTH_LOGE(AUTH_CONN, "delete apply key fail");
409 return ret;
410 }
411 AuthAsyncSaveApplyMapFile();
412 return ret;
413 }
414
AuthRemoveApplyKeyFile()415 static int32_t AuthRemoveApplyKeyFile()
416 {
417 char *filename = DEFAULT_FILE_PATH;
418 return remove(filename);
419 }
420
AuthClearAccountApplyKey(void)421 void AuthClearAccountApplyKey(void)
422 {
423 ClearAuthApplyMap();
424 AuthRemoveApplyKeyFile();
425 }
426
ManagerAccountStateChangeEventHandler(const LnnEventBasicInfo * info)427 static void ManagerAccountStateChangeEventHandler(const LnnEventBasicInfo *info)
428 {
429 if (info == NULL || info->event != LNN_EVENT_ACCOUNT_CHANGED) {
430 AUTH_LOGE(AUTH_CONN, "sle state change evt handler get invalid event");
431 return;
432 }
433
434 const LnnMonitorSleStateChangedEvent *event = (const LnnMonitorSleStateChangedEvent *)info;
435 SoftBusAccountState accountState = (SoftBusAccountState)event->status;
436 switch (accountState) {
437 case SOFTBUS_ACCOUNT_LOG_IN:
438 AUTH_LOGI(AUTH_CONN, "(ignored)HB handle SOFTBUS_ACCOUNT_LOG_IN");
439 break;
440 case SOFTBUS_ACCOUNT_LOG_OUT:
441 AUTH_LOGI(AUTH_CONN, "HB handle SOFTBUS_ACCOUNT_LOG_OUT");
442 ClearAuthApplyMap();
443 AuthRemoveApplyKeyFile();
444 break;
445 default:
446 return;
447 }
448 }
449
InitApplyKeyManager(void)450 int32_t InitApplyKeyManager(void)
451 {
452 int32_t ret = AuthApplyMapInit();
453 if (ret != SOFTBUS_OK) {
454 AUTH_LOGE(AUTH_CONN, "AuthApplyMapInit failed");
455 return ret;
456 }
457 AuthRecoveryApplyKey();
458 if (LnnRegisterEventHandler(LNN_EVENT_ACCOUNT_CHANGED, ManagerAccountStateChangeEventHandler) != SOFTBUS_OK) {
459 AUTH_LOGE(AUTH_CONN, "regist account change evt handler fail");
460 return SOFTBUS_NETWORK_REG_EVENT_HANDLER_ERR;
461 }
462 return SOFTBUS_OK;
463 }
464
DeInitApplyKeyManager(void)465 void DeInitApplyKeyManager(void)
466 {
467 ClearAuthApplyMap();
468 (void)SoftBusMutexDestroy(&g_authApplyMutex);
469 }