1 /*
2  * Copyright (c) 2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "auth_normalize_request.h"
17 
18 #include <securec.h>
19 
20 #include "anonymizer.h"
21 #include "auth_common.h"
22 #include "auth_manager.h"
23 #include "auth_log.h"
24 #include "softbus_adapter_mem.h"
25 #include "softbus_def.h"
26 
27 #define UDID_SHORT_HASH_STR 16
28 
29 static ListNode g_normalizeRequestList = {&g_normalizeRequestList, &g_normalizeRequestList};
30 
GetSameRequestNum(char * udidHash)31 static uint32_t GetSameRequestNum(char *udidHash)
32 {
33     uint32_t num = 0;
34     NormalizeRequest *item = NULL;
35     char *anonyUdidHash = NULL;
36     Anonymize(udidHash, &anonyUdidHash);
37     AUTH_LOGI(AUTH_HICHAIN, "udidHash=%{public}s", anonyUdidHash);
38     AnonymizeFree(anonyUdidHash);
39     LIST_FOR_EACH_ENTRY(item, &g_normalizeRequestList, NormalizeRequest, node) {
40         if (strncmp(item->udidHash, udidHash, UDID_SHORT_HASH_STR) != 0) {
41             continue;
42         }
43         num++;
44     }
45     return num;
46 }
47 
GetRequestListByUdidHash(char * udidHash,bool isNeedClear,NormalizeRequest ** requests,uint32_t * num)48 static int32_t GetRequestListByUdidHash(char *udidHash, bool isNeedClear,
49     NormalizeRequest **requests, uint32_t *num)
50 {
51     if (udidHash == NULL) {
52         AUTH_LOGE(AUTH_HICHAIN, "udidHash is null");
53         return SOFTBUS_INVALID_PARAM;
54     }
55     *num = GetSameRequestNum(udidHash);
56     if ((*num) == 0) {
57         AUTH_LOGI(AUTH_HICHAIN, "no other requests exist.");
58         return SOFTBUS_OK;
59     }
60     *requests = (NormalizeRequest *)SoftBusCalloc(sizeof(NormalizeRequest) * (*num));
61     if (*requests == NULL) {
62         AUTH_LOGE(AUTH_HICHAIN, "malloc fail.");
63         return SOFTBUS_MEM_ERR;
64     }
65     NormalizeRequest *item = NULL;
66     NormalizeRequest *next = NULL;
67     uint32_t index = 0;
68     LIST_FOR_EACH_ENTRY_SAFE(item, next, &g_normalizeRequestList, NormalizeRequest, node) {
69         if (strncmp(item->udidHash, udidHash, UDID_SHORT_HASH_STR) != 0 || index >= (*num)) {
70             continue;
71         }
72         (*requests)[index++] = *item;
73         if (!isNeedClear) {
74             continue;
75         }
76         ListDelete(&item->node);
77         SoftBusFree(item);
78     }
79     return SOFTBUS_OK;
80 }
81 
FindAndDelNormalizeRequest(int64_t authSeq,NormalizeRequest * request)82 static int32_t FindAndDelNormalizeRequest(int64_t authSeq, NormalizeRequest *request)
83 {
84     if (request == NULL) {
85         return SOFTBUS_INVALID_PARAM;
86     }
87     NormalizeRequest *item = NULL;
88     LIST_FOR_EACH_ENTRY(item, &g_normalizeRequestList, NormalizeRequest, node) {
89         if (item->authSeq == authSeq) {
90             *request = *item;
91             ListDelete(&item->node);
92             SoftBusFree(item);
93             return SOFTBUS_OK;
94         }
95     }
96     return SOFTBUS_ERR;
97 }
98 
GetNormalizeRequestList(int64_t authSeq,bool isNeedClear,NormalizeRequest * request,NormalizeRequest ** requests,uint32_t * num)99 static int32_t GetNormalizeRequestList(int64_t authSeq, bool isNeedClear, NormalizeRequest *request,
100     NormalizeRequest **requests, uint32_t *num)
101 {
102     if (num == NULL) {
103         return SOFTBUS_INVALID_PARAM;
104     }
105     if (!RequireAuthLock()) {
106         AUTH_LOGE(AUTH_HICHAIN, "RequireAuthLock fail");
107         return SOFTBUS_ERR;
108     }
109     if (FindAndDelNormalizeRequest(authSeq, request) != SOFTBUS_OK) {
110         AUTH_LOGE(AUTH_HICHAIN, "not found normalize request");
111         ReleaseAuthLock();
112         return SOFTBUS_AUTH_INNER_ERR;
113     }
114     int32_t ret = GetRequestListByUdidHash(request->udidHash, isNeedClear, requests, num);
115     ReleaseAuthLock();
116     return ret;
117 }
118 
DelAuthNormalizeRequest(int64_t authSeq)119 void DelAuthNormalizeRequest(int64_t authSeq)
120 {
121     if (!RequireAuthLock()) {
122         AUTH_LOGE(AUTH_HICHAIN, "RequireAuthLock fail");
123         return;
124     }
125     NormalizeRequest *item = NULL;
126     LIST_FOR_EACH_ENTRY(item, &g_normalizeRequestList, NormalizeRequest, node) {
127         if (item->authSeq == authSeq) {
128             ListDelete(&item->node);
129             SoftBusFree(item);
130             AUTH_LOGI(AUTH_HICHAIN, "del normalize request authSeq=%{public}" PRId64, authSeq);
131             break;
132         }
133     }
134     ReleaseAuthLock();
135 }
136 
AuthIsRepeatedAuthRequest(int64_t authSeq)137 bool AuthIsRepeatedAuthRequest(int64_t authSeq)
138 {
139     if (!RequireAuthLock()) {
140         AUTH_LOGE(AUTH_HICHAIN, "RequireAuthLock fail");
141         return false;
142     }
143     NormalizeRequest *item = NULL;
144     LIST_FOR_EACH_ENTRY(item, &g_normalizeRequestList, NormalizeRequest, node) {
145         if (item->authSeq == authSeq) {
146             ReleaseAuthLock();
147             return true;
148         }
149     }
150     ReleaseAuthLock();
151     return false;
152 }
153 
AddNormalizeRequest(const NormalizeRequest * request)154 uint32_t AddNormalizeRequest(const NormalizeRequest *request)
155 {
156     CHECK_NULL_PTR_RETURN_VALUE(request, 0);
157     NormalizeRequest *newRequest = SoftBusCalloc(sizeof(NormalizeRequest));
158     if (newRequest == NULL) {
159         AUTH_LOGE(AUTH_CONN, "malloc AuthRequest fail");
160         return 0;
161     }
162     *newRequest = *request;
163     if (!RequireAuthLock()) {
164         AUTH_LOGE(AUTH_CONN, "lock fail");
165         SoftBusFree(newRequest);
166         return 0;
167     }
168     ListTailInsert(&g_normalizeRequestList, &newRequest->node);
169     uint32_t waitNum = GetSameRequestNum(newRequest->udidHash);
170     ReleaseAuthLock();
171     return waitNum;
172 }
173 
NotifyNormalizeRequestSuccess(int64_t authSeq,bool isSupportNego)174 void NotifyNormalizeRequestSuccess(int64_t authSeq, bool isSupportNego)
175 {
176     NormalizeRequest *requests = NULL;
177     NormalizeRequest request = { 0 };
178     uint32_t num = 0;
179     if (GetNormalizeRequestList(authSeq, true, &request, &requests, &num) != SOFTBUS_OK) {
180         AUTH_LOGI(AUTH_HICHAIN, "get hichain request fail: authSeq=%{public}" PRId64, authSeq);
181         return;
182     }
183     if (num == 0 || requests == NULL) {
184         AUTH_LOGE(AUTH_HICHAIN, "requests is NULL");
185         return;
186     }
187     AUTH_LOGI(AUTH_HICHAIN, "request num=%{public}d", num);
188     for (uint32_t i = 0; i < num; i++) {
189         if (isSupportNego && requests[i].connInfo.type == request.connInfo.type) {
190             continue;
191         }
192         AUTH_LOGI(AUTH_HICHAIN, "notify AuthSessionSaveSessionKey: authSeq=%{public}" PRId64,
193             requests[i].authSeq);
194         (void)AuthNotifyRequestVerify(requests[i].authSeq);
195     }
196     SoftBusFree(requests);
197 }
198 
NotifyNormalizeRequestFail(int64_t authSeq,int32_t ret)199 void NotifyNormalizeRequestFail(int64_t authSeq, int32_t ret)
200 {
201     (void)ret;
202     NormalizeRequest *requests = NULL;
203     NormalizeRequest request = { 0 };
204     uint32_t num = 0;
205     if (GetNormalizeRequestList(authSeq, false, &request, &requests, &num) != SOFTBUS_OK) {
206         AUTH_LOGI(AUTH_HICHAIN, "get hichain request fail: authSeq=%{public}" PRId64, authSeq);
207         return;
208     }
209     if (num == 0 || requests == NULL) {
210         return;
211     }
212     for (uint32_t i = 0; i < num; i++) {
213         if (AuthNotifyRequestVerify(requests[i].authSeq) == SOFTBUS_OK) {
214             AUTH_LOGI(AUTH_HICHAIN, "continue auth, authSeq=%{public}" PRId64, requests[i].authSeq);
215             break;
216         }
217     }
218     SoftBusFree(requests);
219 }