1 /*
2 * Copyright (c) 2022 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_common.h"
17
18 #include <securec.h>
19
20 #include "bus_center_manager.h"
21 #include "message_handler.h"
22 #include "softbus_base_listener.h"
23 #include "softbus_adapter_crypto.h"
24 #include "softbus_adapter_mem.h"
25 #include "softbus_adapter_timer.h"
26 #include "softbus_feature_config.h"
27
28 #define TIME_SEC_TO_MSEC 1000L
29 #define TIME_MSEC_TO_USEC 1000L
30
31 #define SEQ_NETWORK_ID_BITS 32
32 #define SEQ_TIME_STAMP_BITS 8
33 #define SEQ_TIME_STAMP_MASK 0xFFL
34 #define SEQ_INTEGER_BITS 24
35 #define SEQ_INTEGER_MAX 0xFFFFFF
36
37 #define AUTH_SUPPORT_AS_SERVER_MASK 0x01
38
39 typedef struct {
40 EventType event;
41 RemoveCompareFunc cmpFunc;
42 void *param;
43 } EventRemoveInfo;
44
45 static uint64_t g_uniqueId = 0;
46 static SoftBusMutex g_authLock;
47 static SoftBusHandler g_authHandler = { NULL, NULL, NULL };
48
49 /* auth handler */
IsAuthHandlerInit(void)50 static bool IsAuthHandlerInit(void)
51 {
52 if (g_authHandler.looper == NULL ||
53 g_authHandler.looper->PostMessage == NULL ||
54 g_authHandler.looper->PostMessageDelay == NULL ||
55 g_authHandler.looper->RemoveMessageCustom == NULL) {
56 SoftBusLog(SOFTBUS_LOG_AUTH, SOFTBUS_LOG_ERROR, "auth handler not init.");
57 return false;
58 }
59 return true;
60 }
61
DelAuthMessage(SoftBusMessage * msg)62 static void DelAuthMessage(SoftBusMessage *msg)
63 {
64 CHECK_NULL_PTR_RETURN_VOID(msg);
65 if (msg->obj != NULL) {
66 SoftBusFree(msg->obj);
67 msg->obj = NULL;
68 }
69 SoftBusFree(msg);
70 }
71
NewAuthMessage(const uint8_t * obj,uint32_t size)72 static SoftBusMessage *NewAuthMessage(const uint8_t *obj, uint32_t size)
73 {
74 SoftBusMessage *msg = MallocMessage();
75 if (msg == NULL) {
76 SoftBusLog(SOFTBUS_LOG_AUTH, SOFTBUS_LOG_ERROR, "malloc message fail.");
77 return NULL;
78 }
79 msg->obj = NULL;
80 if (obj != NULL && size > 0) {
81 msg->obj = DupMemBuffer(obj, size);
82 if (msg->obj == NULL) {
83 SoftBusLog(SOFTBUS_LOG_AUTH, SOFTBUS_LOG_ERROR, "dup data fail.");
84 SoftBusFree(msg);
85 return NULL;
86 }
87 }
88 msg->handler = &g_authHandler;
89 msg->FreeMessage = DelAuthMessage;
90 return msg;
91 }
92
HandleAuthMessage(SoftBusMessage * msg)93 static void HandleAuthMessage(SoftBusMessage *msg)
94 {
95 CHECK_NULL_PTR_RETURN_VOID(msg);
96 EventHandler handler = (EventHandler)msg->arg1;
97 if (handler == NULL) {
98 SoftBusLog(SOFTBUS_LOG_AUTH, SOFTBUS_LOG_ERROR,
99 "invalid event handler, event: %d", msg->what);
100 return;
101 }
102 handler(msg->obj);
103 }
104
PostAuthEvent(EventType event,EventHandler handler,const void * obj,uint32_t size,uint64_t delayMs)105 int32_t PostAuthEvent(EventType event, EventHandler handler,
106 const void *obj, uint32_t size, uint64_t delayMs)
107 {
108 if (!IsAuthHandlerInit()) {
109 return SOFTBUS_NO_INIT;
110 }
111 SoftBusMessage *msg = NewAuthMessage(obj, size);
112 if (msg == NULL) {
113 SoftBusLog(SOFTBUS_LOG_AUTH, SOFTBUS_LOG_ERROR, "malloc fail, event: %d", event);
114 return SOFTBUS_MALLOC_ERR;
115 }
116 msg->what = (int32_t)event;
117 msg->arg1 = (uint64_t)handler;
118 if (delayMs == 0) {
119 g_authHandler.looper->PostMessage(g_authHandler.looper, msg);
120 } else {
121 g_authHandler.looper->PostMessageDelay(g_authHandler.looper, msg, delayMs);
122 }
123 return SOFTBUS_OK;
124 }
125
CustomFunc(const SoftBusMessage * msg,void * param)126 static int32_t CustomFunc(const SoftBusMessage *msg, void *param)
127 {
128 CHECK_NULL_PTR_RETURN_VALUE(msg, SOFTBUS_ERR);
129 CHECK_NULL_PTR_RETURN_VALUE(param, SOFTBUS_ERR);
130 EventRemoveInfo *info = (EventRemoveInfo *)param;
131 if (msg->what != (int32_t)info->event) {
132 return SOFTBUS_ERR;
133 }
134 if (info->cmpFunc == NULL) {
135 return SOFTBUS_ERR;
136 }
137 return info->cmpFunc(msg->obj, info->param);
138 }
139
RemoveAuthEvent(EventType event,RemoveCompareFunc func,void * param)140 int32_t RemoveAuthEvent(EventType event, RemoveCompareFunc func, void *param)
141 {
142 if (!IsAuthHandlerInit()) {
143 return SOFTBUS_NO_INIT;
144 }
145 EventRemoveInfo info = {
146 .event = event,
147 .cmpFunc = func,
148 .param = param,
149 };
150 g_authHandler.looper->RemoveMessageCustom(g_authHandler.looper, &g_authHandler, CustomFunc, &info);
151 return SOFTBUS_OK;
152 }
153
154 /* auth lock */
RequireAuthLock(void)155 bool RequireAuthLock(void)
156 {
157 if (SoftBusMutexLock(&g_authLock) != SOFTBUS_OK) {
158 SoftBusLog(SOFTBUS_LOG_AUTH, SOFTBUS_LOG_ERROR, "auth lock fail.");
159 return false;
160 }
161 return true;
162 }
163
ReleaseAuthLock(void)164 void ReleaseAuthLock(void)
165 {
166 if (SoftBusMutexUnlock(&g_authLock) != SOFTBUS_OK) {
167 SoftBusLog(SOFTBUS_LOG_AUTH, SOFTBUS_LOG_ERROR, "auth unlock fail.");
168 }
169 }
170
171 /* auth config */
GetConfigSupportAsServer(void)172 bool GetConfigSupportAsServer(void)
173 {
174 uint32_t ability = 0;
175 if (SoftbusGetConfig(SOFTBUS_INT_AUTH_ABILITY_COLLECTION,
176 (uint8_t *)(&ability), sizeof(ability)) != SOFTBUS_OK) {
177 SoftBusLog(SOFTBUS_LOG_AUTH, SOFTBUS_LOG_ERROR, "get auth ability from config file fail.");
178 }
179 SoftBusLog(SOFTBUS_LOG_AUTH, SOFTBUS_LOG_INFO, "auth ability: %u", ability);
180 return ((ability & AUTH_SUPPORT_AS_SERVER_MASK) != 0);
181 }
182
183 /* auth common function */
DupMemBuffer(const uint8_t * buf,uint32_t size)184 uint8_t *DupMemBuffer(const uint8_t *buf, uint32_t size)
185 {
186 if (buf == NULL || size == 0) {
187 return NULL;
188 }
189 uint8_t *dup = (uint8_t *)SoftBusMalloc(size);
190 if (dup == NULL) {
191 return NULL;
192 }
193 if (memcpy_s(dup, size, buf, size) != EOK) {
194 SoftBusFree(dup);
195 return NULL;
196 }
197 return dup;
198 }
199
UpdateUniqueId(void)200 static void UpdateUniqueId(void)
201 {
202 char networkId[NETWORK_ID_BUF_LEN] = {0};
203 if (LnnGetLocalStrInfo(STRING_KEY_NETWORKID, networkId, sizeof(networkId)) != SOFTBUS_OK) {
204 SoftBusLog(SOFTBUS_LOG_AUTH, SOFTBUS_LOG_ERROR, "get local networkId fail.");
205 return;
206 }
207 uint8_t hashId[SHA_256_HASH_LEN] = {0};
208 if (SoftBusGenerateStrHash((uint8_t *)networkId, strlen(networkId), hashId) != SOFTBUS_OK) {
209 SoftBusLog(SOFTBUS_LOG_DISC, SOFTBUS_LOG_ERROR, "GenerateStrHash fail.");
210 return;
211 }
212 for (uint32_t i = 0; i < SEQ_NETWORK_ID_BITS / BYTES_BIT_NUM; i++) {
213 g_uniqueId = (g_uniqueId << BYTES_BIT_NUM) | hashId[i];
214 }
215 uint64_t timeStamp = GetCurrentTimeMs();
216 g_uniqueId = (g_uniqueId << SEQ_TIME_STAMP_BITS) | (SEQ_TIME_STAMP_MASK & timeStamp);
217 }
218
GenSeq(bool isServer)219 int64_t GenSeq(bool isServer)
220 {
221 static uint32_t integer = 0;
222 if (integer >= SEQ_INTEGER_MAX) {
223 integer = 0;
224 }
225 if (integer == 0) {
226 UpdateUniqueId();
227 }
228 integer += SEQ_INTERVAL;
229 uint64_t seq = isServer ? (integer + 1) : integer;
230 /* |----NetworkIdHash(32)----|-----timeStamp(8)----|----AtomicInteger(24)----| */
231 seq = (g_uniqueId << SEQ_INTEGER_BITS) | (seq & SEQ_INTEGER_MAX);
232 return (int64_t)seq;
233 }
234
GetCurrentTimeMs(void)235 uint64_t GetCurrentTimeMs(void)
236 {
237 SoftBusSysTime now = {0};
238 if (SoftBusGetTime(&now) != SOFTBUS_OK) {
239 SoftBusLog(SOFTBUS_LOG_AUTH, SOFTBUS_LOG_ERROR, "SoftBusGetTime fail.");
240 return 0;
241 }
242 return (uint64_t)now.sec * TIME_SEC_TO_MSEC + (uint64_t)now.usec / TIME_MSEC_TO_USEC;
243 }
244
GetAuthSideStr(bool isServer)245 const char *GetAuthSideStr(bool isServer)
246 {
247 return isServer ? "server" : "client";
248 }
249
CompareConnInfo(const AuthConnInfo * info1,const AuthConnInfo * info2)250 bool CompareConnInfo(const AuthConnInfo *info1, const AuthConnInfo *info2)
251 {
252 CHECK_NULL_PTR_RETURN_VALUE(info1, false);
253 CHECK_NULL_PTR_RETURN_VALUE(info2, false);
254 switch (info1->type) {
255 case AUTH_LINK_TYPE_WIFI:
256 if (info2->type == AUTH_LINK_TYPE_WIFI &&
257 strcmp(info1->info.ipInfo.ip, info2->info.ipInfo.ip) == 0) {
258 return true;
259 }
260 break;
261 case AUTH_LINK_TYPE_BR:
262 if (info2->type == AUTH_LINK_TYPE_BR &&
263 StrCmpIgnoreCase(info1->info.brInfo.brMac, info2->info.brInfo.brMac) == 0) {
264 return true;
265 }
266 break;
267 case AUTH_LINK_TYPE_BLE:
268 if (info2->type == AUTH_LINK_TYPE_BLE &&
269 memcmp(info1->info.bleInfo.deviceIdHash, info2->info.bleInfo.deviceIdHash, UDID_HASH_LEN) == 0) {
270 return true;
271 }
272 break;
273 case AUTH_LINK_TYPE_P2P:
274 if (info2->type == AUTH_LINK_TYPE_P2P &&
275 info1->info.ipInfo.port == info2->info.ipInfo.port &&
276 strcmp(info1->info.ipInfo.ip, info2->info.ipInfo.ip) == 0) {
277 return true;
278 }
279 break;
280 default:
281 SoftBusLog(SOFTBUS_LOG_AUTH, SOFTBUS_LOG_ERROR, "unexpected connInfo, type = %d.", info1->type);
282 return false;
283 }
284 return false;
285 }
286
ConvertToConnectOption(const AuthConnInfo * connInfo,ConnectOption * option)287 int32_t ConvertToConnectOption(const AuthConnInfo *connInfo, ConnectOption *option)
288 {
289 CHECK_NULL_PTR_RETURN_VALUE(connInfo, SOFTBUS_INVALID_PARAM);
290 CHECK_NULL_PTR_RETURN_VALUE(option, SOFTBUS_INVALID_PARAM);
291 switch (connInfo->type) {
292 case AUTH_LINK_TYPE_BR:
293 option->type = CONNECT_BR;
294 if (strcpy_s(option->brOption.brMac, BT_MAC_LEN, connInfo->info.brInfo.brMac) != EOK) {
295 SoftBusLog(SOFTBUS_LOG_AUTH, SOFTBUS_LOG_ERROR, "copy brMac fail.");
296 return SOFTBUS_MEM_ERR;
297 }
298 break;
299 case AUTH_LINK_TYPE_BLE:
300 option->type = CONNECT_BLE;
301 if (strcpy_s(option->bleOption.bleMac, BT_MAC_LEN, connInfo->info.bleInfo.bleMac) != EOK ||
302 memcpy_s(option->bleOption.deviceIdHash, UDID_HASH_LEN,
303 connInfo->info.bleInfo.deviceIdHash, UDID_HASH_LEN) != EOK) {
304 SoftBusLog(SOFTBUS_LOG_AUTH, SOFTBUS_LOG_ERROR, "copy bleMac/deviceIdHash fail.");
305 return SOFTBUS_MEM_ERR;
306 }
307 option->bleOption.fastestConnectEnable = true;
308 break;
309 case AUTH_LINK_TYPE_P2P:
310 option->type = CONNECT_TCP;
311 if (strcpy_s(option->socketOption.addr, sizeof(option->socketOption.addr),
312 connInfo->info.ipInfo.ip) != EOK) {
313 SoftBusLog(SOFTBUS_LOG_AUTH, SOFTBUS_LOG_ERROR, "copy ip fail.");
314 return SOFTBUS_MEM_ERR;
315 }
316 option->socketOption.port = connInfo->info.ipInfo.port;
317 option->socketOption.moduleId = AUTH_P2P;
318 option->socketOption.protocol = LNN_PROTOCOL_IP;
319 option->socketOption.keepAlive = 1;
320 break;
321 default:
322 SoftBusLog(SOFTBUS_LOG_AUTH, SOFTBUS_LOG_ERROR, "unexpected connType=%d.", connInfo->type);
323 return SOFTBUS_ERR;
324 }
325 return SOFTBUS_OK;
326 }
327
ConvertToAuthConnInfo(const ConnectionInfo * info,AuthConnInfo * connInfo)328 int32_t ConvertToAuthConnInfo(const ConnectionInfo *info, AuthConnInfo *connInfo)
329 {
330 CHECK_NULL_PTR_RETURN_VALUE(info, SOFTBUS_INVALID_PARAM);
331 CHECK_NULL_PTR_RETURN_VALUE(connInfo, SOFTBUS_INVALID_PARAM);
332 switch (info->type) {
333 case CONNECT_TCP:
334 if (info->socketInfo.protocol != LNN_PROTOCOL_IP) {
335 SoftBusLog(SOFTBUS_LOG_AUTH, SOFTBUS_LOG_WARN, "only support LNN_PROTOCOL_IP.");
336 return SOFTBUS_ERR;
337 }
338 connInfo->type = AUTH_LINK_TYPE_P2P;
339 connInfo->info.ipInfo.port = info->socketInfo.port;
340 if (strcpy_s(connInfo->info.ipInfo.ip, IP_LEN, info->socketInfo.addr) != EOK) {
341 SoftBusLog(SOFTBUS_LOG_AUTH, SOFTBUS_LOG_ERROR, "copy ip fail.");
342 return SOFTBUS_MEM_ERR;
343 }
344 break;
345 case CONNECT_BR:
346 connInfo->type = AUTH_LINK_TYPE_BR;
347 if (strcpy_s(connInfo->info.brInfo.brMac, BT_MAC_LEN, info->brInfo.brMac) != EOK) {
348 SoftBusLog(SOFTBUS_LOG_AUTH, SOFTBUS_LOG_ERROR, "copy brMac fail.");
349 return SOFTBUS_MEM_ERR;
350 }
351 break;
352 case CONNECT_BLE:
353 connInfo->type = AUTH_LINK_TYPE_BLE;
354 if (strcpy_s(connInfo->info.bleInfo.bleMac, BT_MAC_LEN, info->bleInfo.bleMac) != EOK ||
355 memcpy_s(connInfo->info.bleInfo.deviceIdHash, UDID_HASH_LEN,
356 info->bleInfo.deviceIdHash, UDID_HASH_LEN) != EOK) {
357 SoftBusLog(SOFTBUS_LOG_AUTH, SOFTBUS_LOG_ERROR, "copy bleMac/deviceIdHash fail.");
358 return SOFTBUS_MEM_ERR;
359 }
360 break;
361 default:
362 SoftBusLog(SOFTBUS_LOG_AUTH, SOFTBUS_LOG_ERROR, "unexpected connectionInfo, type=%d.", info->type);
363 return SOFTBUS_ERR;
364 }
365 return SOFTBUS_OK;
366 }
367
AuthCommonInit(void)368 int32_t AuthCommonInit(void)
369 {
370 g_authHandler.name = "AuthHandler";
371 g_authHandler.HandleMessage = HandleAuthMessage;
372 g_authHandler.looper = GetLooper(LOOP_TYPE_DEFAULT);
373
374 if (SoftBusMutexInit(&g_authLock, NULL) != SOFTBUS_OK) {
375 SoftBusLog(SOFTBUS_LOG_AUTH, SOFTBUS_LOG_ERROR, "auth mutex init fail.");
376 return SOFTBUS_ERR;
377 }
378 return SOFTBUS_OK;
379 }
380
AuthCommonDeinit(void)381 void AuthCommonDeinit(void)
382 {
383 g_authHandler.looper = NULL;
384 g_authHandler.HandleMessage = NULL;
385
386 if (SoftBusMutexDestroy(&g_authLock) != SOFTBUS_OK) {
387 SoftBusLog(SOFTBUS_LOG_AUTH, SOFTBUS_LOG_ERROR, "auth mutex destroy fail.");
388 }
389 }
390