• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "legacy/softbus_adapter_hitrace.h"
17 #include "trans_auth_negotiation.h"
18 
19 #include <securec.h>
20 
21 #include "softbus_adapter_mem.h"
22 #include "softbus_error_code.h"
23 #include "softbus_utils.h"
24 #include "trans_log.h"
25 
26 #include "softbus_proxychannel_manager.h"
27 #include "softbus_proxychannel_transceiver.h"
28 
29 #define AUTH_NEGOTIATION_TIMEOUT_MS 10000 // Generate auth key timeout period, unit ms
30 #define AUTH_NEGOTIATION_CHECK_INTERVAL 100 // Auth status check interval, unit ms
31 
32 static SoftBusList *g_reqAuthPendingList = NULL;
33 
34 typedef struct {
35     ListNode node;
36     uint32_t authRequestId;
37     uint32_t cnt;
38     int32_t errCode;
39     bool isFinished;
40 } TransReqAuthItem;
41 
TransReqAuthPendingInit(void)42 int32_t TransReqAuthPendingInit(void)
43 {
44     TRANS_CHECK_AND_RETURN_RET_LOGW(g_reqAuthPendingList == NULL, SOFTBUS_OK, TRANS_SVC, "auth pending already init");
45 
46     g_reqAuthPendingList = CreateSoftBusList();
47     TRANS_CHECK_AND_RETURN_RET_LOGE(
48         g_reqAuthPendingList != NULL, SOFTBUS_TRANS_LIST_INIT_FAILED, TRANS_SVC, "auth pending list init failed");
49 
50     return SOFTBUS_OK;
51 }
52 
TransReqAuthPendingDeinit(void)53 void TransReqAuthPendingDeinit(void)
54 {
55     TRANS_LOGW(TRANS_SVC, "deinit auth request pending list");
56     TRANS_CHECK_AND_RETURN_LOGW(g_reqAuthPendingList != NULL, TRANS_SVC, "auth pending already deinit");
57 
58     int32_t ret = SoftBusMutexLock(&g_reqAuthPendingList->lock);
59     TRANS_CHECK_AND_RETURN_LOGE(ret == SOFTBUS_OK, TRANS_SVC, "lock auth pending list failed");
60 
61     TransReqAuthItem *item = NULL;
62     TransReqAuthItem *next = NULL;
63     LIST_FOR_EACH_ENTRY_SAFE(item, next, &g_reqAuthPendingList->list, TransReqAuthItem, node) {
64         ListDelete(&item->node);
65         SoftBusFree(item);
66     }
67     (void)SoftBusMutexUnlock(&g_reqAuthPendingList->lock);
68     DestroySoftBusList(g_reqAuthPendingList);
69     g_reqAuthPendingList = NULL;
70 }
71 
TransAddAuthReqToPendingList(uint32_t authRequestId)72 static int32_t TransAddAuthReqToPendingList(uint32_t authRequestId)
73 {
74     TRANS_CHECK_AND_RETURN_RET_LOGE(authRequestId != 0, SOFTBUS_INVALID_PARAM, TRANS_SVC, "invalid auth requestId");
75     TRANS_CHECK_AND_RETURN_RET_LOGE(
76         g_reqAuthPendingList != NULL, SOFTBUS_NO_INIT, TRANS_SVC, "auth pending list no init");
77 
78     TransReqAuthItem *item = (TransReqAuthItem *)SoftBusCalloc(sizeof(TransReqAuthItem));
79     TRANS_CHECK_AND_RETURN_RET_LOGE(item != NULL, SOFTBUS_MALLOC_ERR, TRANS_SVC, "malloc auth request item failed");
80     item->authRequestId = authRequestId;
81     item->cnt = 0;
82     item->errCode = SOFTBUS_TRANS_AUTH_REQUEST_NOT_FOUND;
83     item->isFinished = false;
84 
85     if (SoftBusMutexLock(&g_reqAuthPendingList->lock) != SOFTBUS_OK) {
86         TRANS_LOGE(TRANS_SVC, "lock auth pending list failed");
87         SoftBusFree(item);
88         return SOFTBUS_LOCK_ERR;
89     }
90     ListInit(&item->node);
91     ListAdd(&g_reqAuthPendingList->list, &item->node);
92     g_reqAuthPendingList->cnt++;
93     (void)SoftBusMutexUnlock(&g_reqAuthPendingList->lock);
94     TRANS_LOGI(TRANS_SVC, "add auth request to pending success, authRequestId=%{public}u", authRequestId);
95     return SOFTBUS_OK;
96 }
97 
TransDelAuthReqFromPendingList(uint32_t authRequestId)98 static void TransDelAuthReqFromPendingList(uint32_t authRequestId)
99 {
100     TRANS_CHECK_AND_RETURN_LOGE(authRequestId != 0, TRANS_SVC, "invalid auth requestId");
101     TRANS_CHECK_AND_RETURN_LOGE(g_reqAuthPendingList != NULL, TRANS_SVC, "auth pending list no init");
102 
103     int32_t ret = SoftBusMutexLock(&g_reqAuthPendingList->lock);
104     TRANS_CHECK_AND_RETURN_LOGE(ret == SOFTBUS_OK, TRANS_SVC, "lock auth pending list failed");
105     TransReqAuthItem *item = NULL;
106     TransReqAuthItem *next = NULL;
107     LIST_FOR_EACH_ENTRY_SAFE(item, next, &g_reqAuthPendingList->list, TransReqAuthItem, node) {
108         if (item->authRequestId == authRequestId) {
109             ListDelete(&item->node);
110             SoftBusFree(item);
111             g_reqAuthPendingList->cnt--;
112             (void)SoftBusMutexUnlock(&g_reqAuthPendingList->lock);
113             TRANS_LOGI(TRANS_SVC, "delete auth request by authRequestId=%{public}u", authRequestId);
114             return;
115         }
116     }
117     (void)SoftBusMutexUnlock(&g_reqAuthPendingList->lock);
118     TRANS_LOGW(TRANS_SVC, "auth request not found by authRequestId=%{public}u", authRequestId);
119 }
120 
TransUpdateAuthInfo(uint32_t authRequestId,int32_t errCode)121 static int32_t TransUpdateAuthInfo(uint32_t authRequestId, int32_t errCode)
122 {
123     TRANS_CHECK_AND_RETURN_RET_LOGE(authRequestId != 0, SOFTBUS_INVALID_PARAM, TRANS_SVC, "invalid auth requestId");
124     TRANS_CHECK_AND_RETURN_RET_LOGE(
125         g_reqAuthPendingList != NULL, SOFTBUS_NO_INIT, TRANS_SVC, "auth pending list no init");
126 
127     int32_t ret = SoftBusMutexLock(&g_reqAuthPendingList->lock);
128     TRANS_CHECK_AND_RETURN_RET_LOGE(ret == SOFTBUS_OK, SOFTBUS_LOCK_ERR, TRANS_SVC, "lock auth pending list failed");
129     TransReqAuthItem *item = NULL;
130     LIST_FOR_EACH_ENTRY(item, &g_reqAuthPendingList->list, TransReqAuthItem, node) {
131         if (item->authRequestId == authRequestId) {
132             item->errCode = errCode;
133             item->isFinished = true;
134             (void)SoftBusMutexUnlock(&g_reqAuthPendingList->lock);
135             return SOFTBUS_OK;
136         }
137     }
138     (void)SoftBusMutexUnlock(&g_reqAuthPendingList->lock);
139     TRANS_LOGE(TRANS_SVC, "auth request not found by authRequestId=%{public}u", authRequestId);
140     return SOFTBUS_TRANS_AUTH_REQUEST_NOT_FOUND;
141 }
142 
TransCheckAuthNegoStatusByReqId(uint32_t authRequestId,bool * isFinished,int32_t * errCode,int32_t * cnt)143 static int32_t TransCheckAuthNegoStatusByReqId(uint32_t authRequestId, bool *isFinished, int32_t *errCode, int32_t *cnt)
144 {
145     TRANS_CHECK_AND_RETURN_RET_LOGE(
146         g_reqAuthPendingList != NULL, SOFTBUS_NO_INIT, TRANS_SVC, "auth pending list no init");
147 
148     int32_t ret = SoftBusMutexLock(&g_reqAuthPendingList->lock);
149     TRANS_CHECK_AND_RETURN_RET_LOGE(ret == SOFTBUS_OK, SOFTBUS_LOCK_ERR, TRANS_SVC, "lock auth pending list failed");
150     TransReqAuthItem *item = NULL;
151     LIST_FOR_EACH_ENTRY(item, &g_reqAuthPendingList->list, TransReqAuthItem, node) {
152         if (item->authRequestId == authRequestId) {
153             *isFinished = item->isFinished;
154             *errCode = item->errCode;
155             *cnt = ++item->cnt;
156             (void)SoftBusMutexUnlock(&g_reqAuthPendingList->lock);
157             return SOFTBUS_OK;
158         }
159     }
160     (void)SoftBusMutexUnlock(&g_reqAuthPendingList->lock);
161     TRANS_LOGE(TRANS_SVC, "auth request not found by authRequestId=%{public}u", authRequestId);
162     return SOFTBUS_TRANS_AUTH_REQUEST_NOT_FOUND;
163 }
164 
WaitingForAuthNegoToBeDone(uint32_t authRequestId,int32_t channelId)165 static int32_t WaitingForAuthNegoToBeDone(uint32_t authRequestId, int32_t channelId)
166 {
167     int32_t ret = TransAddAuthReqToPendingList(authRequestId);
168     if (ret != SOFTBUS_OK) {
169         TRANS_LOGE(TRANS_SVC, "channelId=%{public}d add authRequestId=%{public}u to pending fail, ret=%{public}d",
170             channelId, authRequestId, ret);
171         return ret;
172     }
173     TransProxyPostAuthNegoMsgToLooperDelay(authRequestId, channelId, AUTH_NEGOTIATION_CHECK_INTERVAL);
174     return SOFTBUS_OK;
175 }
176 
OnAuthSessionKeyGenSucc(uint32_t authRequestId,AuthHandle authHandle)177 static void OnAuthSessionKeyGenSucc(uint32_t authRequestId, AuthHandle authHandle)
178 {
179     (void)authHandle;
180     TRANS_LOGI(TRANS_SVC, "authKey gen success, authRequestId=%{public}u", authRequestId);
181     TransUpdateAuthInfo(authRequestId, SOFTBUS_OK);
182 }
183 
OnAuthSessionKeyGenFail(uint32_t authRequestId,int32_t errCode)184 static void OnAuthSessionKeyGenFail(uint32_t authRequestId, int32_t errCode)
185 {
186     TRANS_LOGE(TRANS_SVC, "authKey gen failure, authRequestId=%{public}u errCode=%{public}d", authRequestId, errCode);
187     TransUpdateAuthInfo(authRequestId, errCode);
188 }
189 
190 // update session key, no need to notify request
OnUpdateSessionKeySucc(uint32_t authRequestId,AuthHandle authHandle)191 static void OnUpdateSessionKeySucc(uint32_t authRequestId, AuthHandle authHandle)
192 {
193     (void)authRequestId;
194     (void)authHandle;
195     TRANS_LOGI(TRANS_SVC, "update success, authRequestId=%{public}u", authRequestId);
196 }
197 
198 // update session key, no need to notify request
OnUpdateSessionKeyFail(uint32_t authRequestId,int32_t errCode)199 static void OnUpdateSessionKeyFail(uint32_t authRequestId, int32_t errCode)
200 {
201     (void)authRequestId;
202     (void)errCode;
203     TRANS_LOGE(TRANS_SVC, "update failure, authRequestId=%{public}u errCode=%{public}d", authRequestId, errCode);
204 }
205 
TransNegotiateSessionKey(const AuthConnInfo * authConnInfo,int32_t channelId,const char * peerNetworkId)206 int32_t TransNegotiateSessionKey(const AuthConnInfo *authConnInfo, int32_t channelId, const char *peerNetworkId)
207 {
208     TRANS_CHECK_AND_RETURN_RET_LOGE((authConnInfo != NULL && peerNetworkId != NULL),
209         SOFTBUS_INVALID_PARAM, TRANS_SVC, "invalid param");
210 
211     // Meta's peerNetworkId is empty in dSoftBus, and meta no need to negotiate, just skip
212     if (strlen(peerNetworkId) == 0) {
213         TRANS_LOGI(TRANS_SVC, "channelId=%{public}d peerNetworkId is empty, skip negotiate", channelId);
214         TransProxyNegoSessionKeySucc(channelId);
215         return SOFTBUS_OK;
216     }
217 
218     int32_t ret = AuthCheckSessionKeyValidByConnInfo(peerNetworkId, authConnInfo);
219     if (ret == SOFTBUS_AUTH_SESSION_KEY_INVALID || ret == SOFTBUS_AUTH_SESSION_KEY_TOO_OLD) {
220         uint32_t authRequestId = AuthGenRequestId();
221         bool isFastAuth = true;
222         if (ret == SOFTBUS_AUTH_SESSION_KEY_TOO_OLD) {
223             TRANS_LOGI(TRANS_SVC, "sessionKey older, update it, authRequestId=%{public}u", authRequestId);
224             TransProxyNegoSessionKeySucc(channelId); // if sessionKey older, use old key to handshake first
225             AuthConnCallback authCallback = {
226                 .onConnOpened = OnUpdateSessionKeySucc,
227                 .onConnOpenFailed = OnUpdateSessionKeyFail,
228             };
229             AuthStartConnVerify(authConnInfo, authRequestId, &authCallback, AUTH_MODULE_TRANS, isFastAuth);
230             return SOFTBUS_OK;
231         }
232         TRANS_LOGI(TRANS_SVC, "no session key, start generation, authRequestId=%{public}u", authRequestId);
233         AuthConnCallback authCallback = {
234             .onConnOpened = OnAuthSessionKeyGenSucc,
235             .onConnOpenFailed = OnAuthSessionKeyGenFail,
236         };
237         AuthStartConnVerify(authConnInfo, authRequestId, &authCallback, AUTH_MODULE_TRANS, isFastAuth);
238         return WaitingForAuthNegoToBeDone(authRequestId, channelId);
239     }
240     TransProxyNegoSessionKeySucc(channelId);
241     return SOFTBUS_OK;
242 }
243 
TransReNegotiateSessionKey(const AuthConnInfo * authConnInfo,int32_t channelId)244 int32_t TransReNegotiateSessionKey(const AuthConnInfo *authConnInfo, int32_t channelId)
245 {
246     TRANS_CHECK_AND_RETURN_RET_LOGE(authConnInfo != NULL, SOFTBUS_INVALID_PARAM, TRANS_SVC, "invalid param");
247 
248     uint32_t authRequestId = AuthGenRequestId();
249     bool isFastAuth = true;
250     TRANS_LOGI(TRANS_SVC, "server side no session key, renegotiate, authRequestId=%{public}u", authRequestId);
251     AuthConnCallback authCallback = {
252         .onConnOpened = OnAuthSessionKeyGenSucc,
253         .onConnOpenFailed = OnAuthSessionKeyGenFail,
254     };
255     AuthStartConnVerify(authConnInfo, authRequestId, &authCallback, AUTH_MODULE_TRANS, isFastAuth);
256     return WaitingForAuthNegoToBeDone(authRequestId, channelId);
257 }
258 
SetWlanAuthConnInfo(const struct ConnSocketInfo * socketInfo,AuthConnInfo * authConnInfo)259 static int32_t SetWlanAuthConnInfo(const struct ConnSocketInfo *socketInfo, AuthConnInfo *authConnInfo)
260 {
261     if (socketInfo->protocol != LNN_PROTOCOL_IP) {
262         TRANS_LOGE(TRANS_SVC, "tcp protocol=%{public}d not support", socketInfo->protocol);
263         return SOFTBUS_FUNC_NOT_SUPPORT;
264     }
265 
266     authConnInfo->type = AUTH_LINK_TYPE_WIFI;
267     if (strcpy_s(authConnInfo->info.ipInfo.ip, IP_LEN, socketInfo->addr) != EOK) {
268         TRANS_LOGE(TRANS_SVC, "strcpy_s ip addr failed");
269         return SOFTBUS_STRCPY_ERR;
270     }
271     authConnInfo->info.ipInfo.port = socketInfo->port;
272     authConnInfo->info.ipInfo.moduleId = (ListenerModule)socketInfo->moduleId;
273 
274     return SOFTBUS_OK;
275 }
276 
SetBrAuthConnInfo(const struct BrInfo * brInfo,AuthConnInfo * authConnInfo)277 static int32_t SetBrAuthConnInfo(const struct BrInfo *brInfo, AuthConnInfo *authConnInfo)
278 {
279     authConnInfo->type = AUTH_LINK_TYPE_BR;
280     if (strcpy_s(authConnInfo->info.brInfo.brMac, BT_MAC_LEN, brInfo->brMac) != EOK) {
281         TRANS_LOGE(TRANS_SVC, "strcpy_s br mac failed");
282         return SOFTBUS_STRCPY_ERR;
283     }
284 
285     return SOFTBUS_OK;
286 }
287 
SetBleAuthConnInfo(const struct BleInfo * bleInfo,AuthConnInfo * authConnInfo)288 static int32_t SetBleAuthConnInfo(const struct BleInfo *bleInfo, AuthConnInfo *authConnInfo)
289 {
290     authConnInfo->type = AUTH_LINK_TYPE_BLE;
291     if (strcpy_s(authConnInfo->info.bleInfo.bleMac, BT_MAC_LEN, bleInfo->bleMac) != EOK ||
292         memcpy_s(authConnInfo->info.bleInfo.deviceIdHash,
293             UDID_HASH_LEN,
294             bleInfo->deviceIdHash,
295             UDID_HASH_LEN) != EOK) {
296         TRANS_LOGE(TRANS_SVC, "copy ble mac or deviceId hash failed");
297         return SOFTBUS_MEM_ERR;
298     }
299     authConnInfo->info.bleInfo.protocol = bleInfo->protocol;
300     authConnInfo->info.bleInfo.psm = bleInfo->psm;
301 
302     return SOFTBUS_OK;
303 }
304 
SetSleAuthConnInfo(const struct SleInfo * sleInfo,AuthConnInfo * authConnInfo)305 static int32_t SetSleAuthConnInfo(const struct SleInfo *sleInfo, AuthConnInfo *authConnInfo)
306 {
307     authConnInfo->type = AUTH_LINK_TYPE_SLE;
308     if (memcpy_s(authConnInfo->info.sleInfo.sleMac, BT_MAC_LEN, sleInfo->address, BT_MAC_LEN) != EOK) {
309         TRANS_LOGE(TRANS_SVC, "memcpy_s sle mac failed.");
310         return SOFTBUS_MEM_ERR;
311     }
312     authConnInfo->info.sleInfo.protocol = sleInfo->protocol;
313     return SOFTBUS_OK;
314 }
315 
ConvertConnInfoToAuthConnInfo(const ConnectionInfo * connInfo,AuthConnInfo * authConnInfo)316 static int32_t ConvertConnInfoToAuthConnInfo(const ConnectionInfo *connInfo, AuthConnInfo *authConnInfo)
317 {
318     switch (connInfo->type) {
319         case CONNECT_TCP:
320             return SetWlanAuthConnInfo(&(connInfo->socketInfo), authConnInfo);
321         case CONNECT_BR:
322             return SetBrAuthConnInfo(&(connInfo->brInfo), authConnInfo);
323         case CONNECT_BLE:
324             return SetBleAuthConnInfo(&(connInfo->bleInfo), authConnInfo);
325         case CONNECT_SLE:
326             return SetSleAuthConnInfo(&(connInfo->sleInfo), authConnInfo);
327         default:
328             TRANS_LOGE(TRANS_SVC, "not support connection type=%{public}d", connInfo->type);
329             return SOFTBUS_FUNC_NOT_SUPPORT;
330     }
331 }
332 
GetAuthConnInfoByConnId(uint32_t connectionId,AuthConnInfo * authConnInfo)333 int32_t GetAuthConnInfoByConnId(uint32_t connectionId, AuthConnInfo *authConnInfo)
334 {
335     TRANS_CHECK_AND_RETURN_RET_LOGE(authConnInfo != NULL, SOFTBUS_INVALID_PARAM, TRANS_SVC, "invalid param");
336 
337     ConnectionInfo connInfo;
338     (void)memset_s(&connInfo, sizeof(ConnectionInfo), 0, sizeof(ConnectionInfo));
339     int32_t ret = ConnGetConnectionInfo(connectionId, &connInfo);
340     if (ret != SOFTBUS_OK) {
341         TRANS_LOGE(TRANS_CTRL, "get ConnectionInfo by connId=%{public}u failed, ret=%{public}d", connectionId, ret);
342         return ret;
343     }
344 
345     ret = ConvertConnInfoToAuthConnInfo(&connInfo, authConnInfo);
346     if (ret != SOFTBUS_OK) {
347         TRANS_LOGE(TRANS_CTRL, "convert connInfo to authConnInfo failed, ret=%{public}d", ret);
348         return ret;
349     }
350 
351     return SOFTBUS_OK;
352 }
353 
TransAuthNegoTaskManager(uint32_t authRequestId,int32_t channelId)354 void TransAuthNegoTaskManager(uint32_t authRequestId, int32_t channelId)
355 {
356     SoftBusHitraceChainBegin("TransAuthNegoTaskManager");
357     if (authRequestId == 0) {
358         TRANS_LOGE(TRANS_SVC, "invalid param");
359         SoftBusHitraceChainEnd();
360         return;
361     }
362     bool isFinished = false;
363     int32_t errCode = SOFTBUS_TRANS_AUTH_NEGO_TASK_NOT_FOUND;
364     int32_t cnt = 0;
365     int32_t ret = TransCheckAuthNegoStatusByReqId(authRequestId, &isFinished, &errCode, &cnt);
366     if (ret != SOFTBUS_OK) {
367         TRANS_LOGE(TRANS_SVC, "check auth status by authRequestId=%{public}u failed", authRequestId);
368         SoftBusHitraceChainEnd();
369         return;
370     }
371 
372     if (!isFinished) {
373         int32_t timeoutCnt = AUTH_NEGOTIATION_TIMEOUT_MS / AUTH_NEGOTIATION_CHECK_INTERVAL;
374         if (cnt >= timeoutCnt) {
375             TRANS_LOGE(TRANS_SVC, "authRequestId=%{public}u timeout, cnt=%{public}d", authRequestId, cnt);
376             TransProxyNegoSessionKeyFail(channelId, SOFTBUS_TRANS_AUTH_NEGOTIATE_SK_TIMEOUT);
377             TransDelAuthReqFromPendingList(authRequestId);
378             SoftBusHitraceChainEnd();
379             return;
380         }
381         TRANS_LOGD(TRANS_SVC, "authRequestId=%{public}u not finished, generate new task and waiting", authRequestId);
382         TransProxyPostAuthNegoMsgToLooperDelay(authRequestId, channelId, AUTH_NEGOTIATION_CHECK_INTERVAL);
383         SoftBusHitraceChainEnd();
384         return;
385     }
386 
387     if (errCode != SOFTBUS_OK) {
388         TRANS_LOGE(TRANS_SVC, "authRequestId=%{public}u negotiate failed, errCode=%{public}d", authRequestId, errCode);
389         TransProxyNegoSessionKeyFail(channelId, errCode);
390         TransDelAuthReqFromPendingList(authRequestId);
391         SoftBusHitraceChainEnd();
392         return;
393     }
394 
395     TransProxyNegoSessionKeySucc(channelId);
396     TransDelAuthReqFromPendingList(authRequestId);
397     SoftBusHitraceChainEnd();
398 }
399