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_log.h"
23 #include "auth_manager.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", AnonymizeWrapper(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, NormalizeRequest **requests, uint32_t *num)
49 {
50 if (udidHash == NULL) {
51 AUTH_LOGE(AUTH_HICHAIN, "udidHash is null");
52 return SOFTBUS_INVALID_PARAM;
53 }
54 *num = GetSameRequestNum(udidHash);
55 if ((*num) == 0) {
56 AUTH_LOGI(AUTH_HICHAIN, "no other requests exist.");
57 return SOFTBUS_OK;
58 }
59 *requests = (NormalizeRequest *)SoftBusCalloc(sizeof(NormalizeRequest) * (*num));
60 if (*requests == NULL) {
61 AUTH_LOGE(AUTH_HICHAIN, "malloc fail.");
62 return SOFTBUS_MEM_ERR;
63 }
64 NormalizeRequest *item = NULL;
65 NormalizeRequest *next = NULL;
66 uint32_t index = 0;
67 LIST_FOR_EACH_ENTRY_SAFE(item, next, &g_normalizeRequestList, NormalizeRequest, node) {
68 if (strncmp(item->udidHash, udidHash, UDID_SHORT_HASH_STR) != 0 || index >= (*num)) {
69 continue;
70 }
71 (*requests)[index++] = *item;
72 if (!isNeedClear) {
73 continue;
74 }
75 ListDelete(&item->node);
76 SoftBusFree(item);
77 }
78 return SOFTBUS_OK;
79 }
80
FindAndDelNormalizeRequest(int64_t authSeq,NormalizeRequest * request)81 static int32_t FindAndDelNormalizeRequest(int64_t authSeq, NormalizeRequest *request)
82 {
83 if (request == NULL) {
84 return SOFTBUS_INVALID_PARAM;
85 }
86 NormalizeRequest *item = NULL;
87 LIST_FOR_EACH_ENTRY(item, &g_normalizeRequestList, NormalizeRequest, node) {
88 if (item->authSeq == authSeq) {
89 *request = *item;
90 ListDelete(&item->node);
91 SoftBusFree(item);
92 return SOFTBUS_OK;
93 }
94 }
95 return SOFTBUS_AUTH_NOT_FOUND;
96 }
97
GetNormalizeRequestList(int64_t authSeq,bool isNeedClear,NormalizeRequest * request,NormalizeRequest ** requests,uint32_t * num)98 static int32_t GetNormalizeRequestList(
99 int64_t authSeq, bool isNeedClear, NormalizeRequest *request, NormalizeRequest **requests, uint32_t *num)
100 {
101 if (num == NULL) {
102 return SOFTBUS_INVALID_PARAM;
103 }
104 if (!RequireAuthLock()) {
105 AUTH_LOGE(AUTH_HICHAIN, "RequireAuthLock fail");
106 return SOFTBUS_LOCK_ERR;
107 }
108 if (FindAndDelNormalizeRequest(authSeq, request) != SOFTBUS_OK) {
109 AUTH_LOGE(AUTH_HICHAIN, "not found normalize request");
110 ReleaseAuthLock();
111 return SOFTBUS_AUTH_INNER_ERR;
112 }
113 int32_t ret = GetRequestListByUdidHash(request->udidHash, isNeedClear, requests, num);
114 ReleaseAuthLock();
115 return ret;
116 }
117
DelAuthNormalizeRequest(int64_t authSeq)118 void DelAuthNormalizeRequest(int64_t authSeq)
119 {
120 if (!RequireAuthLock()) {
121 AUTH_LOGE(AUTH_HICHAIN, "RequireAuthLock fail");
122 return;
123 }
124 NormalizeRequest *item = NULL;
125 LIST_FOR_EACH_ENTRY(item, &g_normalizeRequestList, NormalizeRequest, node) {
126 if (item->authSeq == authSeq) {
127 ListDelete(&item->node);
128 SoftBusFree(item);
129 AUTH_LOGI(AUTH_HICHAIN, "del normalize request authSeq=%{public}" PRId64, authSeq);
130 break;
131 }
132 }
133 ReleaseAuthLock();
134 }
135
AuthIsRepeatedAuthRequest(int64_t authSeq)136 bool AuthIsRepeatedAuthRequest(int64_t authSeq)
137 {
138 if (!RequireAuthLock()) {
139 AUTH_LOGE(AUTH_HICHAIN, "RequireAuthLock fail");
140 return false;
141 }
142 NormalizeRequest *item = NULL;
143 LIST_FOR_EACH_ENTRY(item, &g_normalizeRequestList, NormalizeRequest, node) {
144 if (item->authSeq == authSeq) {
145 ReleaseAuthLock();
146 return true;
147 }
148 }
149 ReleaseAuthLock();
150 return false;
151 }
152
AddNormalizeRequest(const NormalizeRequest * request)153 uint32_t AddNormalizeRequest(const NormalizeRequest *request)
154 {
155 CHECK_NULL_PTR_RETURN_VALUE(request, 0);
156 NormalizeRequest *newRequest = SoftBusCalloc(sizeof(NormalizeRequest));
157 if (newRequest == NULL) {
158 AUTH_LOGE(AUTH_CONN, "malloc AuthRequest fail");
159 return 0;
160 }
161 *newRequest = *request;
162 if (!RequireAuthLock()) {
163 AUTH_LOGE(AUTH_CONN, "lock fail");
164 SoftBusFree(newRequest);
165 return 0;
166 }
167 ListTailInsert(&g_normalizeRequestList, &newRequest->node);
168 uint32_t waitNum = GetSameRequestNum(newRequest->udidHash);
169 ReleaseAuthLock();
170 return waitNum;
171 }
172
NotifyNormalizeRequestSuccess(int64_t authSeq,bool isSupportNego)173 void NotifyNormalizeRequestSuccess(int64_t authSeq, bool isSupportNego)
174 {
175 NormalizeRequest *requests = NULL;
176 NormalizeRequest request = { 0 };
177 uint32_t num = 0;
178 if (GetNormalizeRequestList(authSeq, true, &request, &requests, &num) != SOFTBUS_OK) {
179 AUTH_LOGI(AUTH_HICHAIN, "get hichain request fail: authSeq=%{public}" PRId64, authSeq);
180 return;
181 }
182 if (num == 0 || requests == NULL) {
183 AUTH_LOGE(AUTH_HICHAIN, "requests is NULL");
184 return;
185 }
186 AUTH_LOGI(AUTH_HICHAIN, "request num=%{public}d", num);
187 for (uint32_t i = 0; i < num; i++) {
188 if (isSupportNego && requests[i].connInfo.type == request.connInfo.type) {
189 continue;
190 }
191 AUTH_LOGI(AUTH_HICHAIN, "notify AuthSessionSaveSessionKey: authSeq=%{public}" PRId64, requests[i].authSeq);
192 (void)AuthNotifyRequestVerify(requests[i].authSeq);
193 }
194 SoftBusFree(requests);
195 }
196
NotifyNormalizeRequestFail(int64_t authSeq,int32_t ret)197 void NotifyNormalizeRequestFail(int64_t authSeq, int32_t ret)
198 {
199 (void)ret;
200 NormalizeRequest *requests = NULL;
201 NormalizeRequest request = { 0 };
202 uint32_t num = 0;
203 if (GetNormalizeRequestList(authSeq, false, &request, &requests, &num) != SOFTBUS_OK) {
204 AUTH_LOGI(AUTH_HICHAIN, "get hichain request fail: authSeq=%{public}" PRId64, authSeq);
205 return;
206 }
207 if (num == 0 || requests == NULL) {
208 return;
209 }
210 for (uint32_t i = 0; i < num; i++) {
211 if (AuthNotifyRequestVerify(requests[i].authSeq) == SOFTBUS_OK) {
212 AUTH_LOGI(AUTH_HICHAIN, "continue auth, authSeq=%{public}" PRId64, requests[i].authSeq);
213 break;
214 }
215 }
216 SoftBusFree(requests);
217 }