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  }