• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 }