1 /*
2  * Copyright (c) 2021-2023 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 "trans_session_manager.h"
17 
18 #include "anonymizer.h"
19 #include "lnn_lane_link.h"
20 #include "permission_entry.h"
21 #include "securec.h"
22 #include "softbus_adapter_mem.h"
23 #include "softbus_adapter_thread.h"
24 #include "softbus_def.h"
25 #include "softbus_errcode.h"
26 #include "softbus_utils.h"
27 #include "softbus_hidumper_trans.h"
28 #include "trans_channel_callback.h"
29 #include "trans_client_proxy.h"
30 #include "trans_log.h"
31 
32 #define MAX_SESSION_SERVER_NUM 100
33 #define CMD_REGISTED_SESSION_LIST "registed_sessionlist"
34 #define GET_ROUTE_TYPE(type) ((uint32_t)(type) & 0xff)
35 #define GET_CONN_TYPE(type) (((uint32_t)(type) >> 8) & 0xff)
36 
37 static SoftBusList *g_sessionServerList = NULL;
38 
TransSessionForEachShowInfo(int32_t fd)39 static int32_t TransSessionForEachShowInfo(int32_t fd)
40 {
41     if (g_sessionServerList == NULL) {
42         TRANS_LOGE(TRANS_CTRL, "session server list is empty");
43         return SOFTBUS_NO_INIT;
44     }
45     if (SoftBusMutexLock(&g_sessionServerList->lock) != SOFTBUS_OK) {
46         TRANS_LOGE(TRANS_CTRL, "lock mutex failed");
47         return SOFTBUS_LOCK_ERR;
48     }
49 
50     SessionServer *pos = NULL;
51     LIST_FOR_EACH_ENTRY(pos, &g_sessionServerList->list, SessionServer, node) {
52         SoftBusTransDumpRegisterSession(fd, pos->pkgName, pos->sessionName, pos->uid, pos->pid);
53     }
54 
55     (void)SoftBusMutexUnlock(&g_sessionServerList->lock);
56     return SOFTBUS_OK;
57 }
58 
TransSessionMgrInit(void)59 int32_t TransSessionMgrInit(void)
60 {
61     if (g_sessionServerList != NULL) {
62         return SOFTBUS_OK;
63     }
64     g_sessionServerList = CreateSoftBusList();
65     if (g_sessionServerList == NULL) {
66         TRANS_LOGE(TRANS_CTRL, "session manager init fail");
67         return SOFTBUS_MALLOC_ERR;
68     }
69 
70     return SoftBusRegTransVarDump(CMD_REGISTED_SESSION_LIST, TransSessionForEachShowInfo);
71 }
72 
TransSessionMgrDeinit(void)73 void TransSessionMgrDeinit(void)
74 {
75     if (g_sessionServerList != NULL) {
76         DestroySoftBusList(g_sessionServerList);
77         g_sessionServerList = NULL;
78     }
79 }
80 
TransSessionServerIsExist(const char * sessionName)81 bool TransSessionServerIsExist(const char *sessionName)
82 {
83     if (sessionName == NULL) {
84         return false;
85     }
86     if (g_sessionServerList == NULL) {
87         TRANS_LOGE(TRANS_CTRL, "sessionServerList not init");
88         return false;
89     }
90 
91     SessionServer *pos = NULL;
92     SessionServer *tmp = NULL;
93     if (SoftBusMutexLock(&g_sessionServerList->lock) != SOFTBUS_OK) {
94         TRANS_LOGE(TRANS_CTRL, "lock mutex failed");
95         return false;
96     }
97 
98     LIST_FOR_EACH_ENTRY_SAFE(pos, tmp, &g_sessionServerList->list, SessionServer, node) {
99         if (strcmp(pos->sessionName, sessionName) == 0) {
100             (void)SoftBusMutexUnlock(&g_sessionServerList->lock);
101             return true;
102         }
103     }
104     (void)SoftBusMutexUnlock(&g_sessionServerList->lock);
105     char *tmpSessionName = NULL;
106     Anonymize(sessionName, &tmpSessionName);
107     TRANS_LOGE(TRANS_CTRL, "session server not exist, sessionName=%{public}s", AnonymizeWrapper(tmpSessionName));
108     AnonymizeFree(tmpSessionName);
109     return false;
110 }
111 
ShowSessionServer(void)112 static void ShowSessionServer(void)
113 {
114     SessionServer *pos = NULL;
115     SessionServer *tmp = NULL;
116     int32_t count = 0;
117     char *tmpName = NULL;
118     LIST_FOR_EACH_ENTRY_SAFE(pos, tmp, &g_sessionServerList->list, SessionServer, node) {
119         Anonymize(pos->sessionName, &tmpName);
120         TRANS_LOGI(TRANS_CTRL,
121             "session server is exist. count=%{public}d, sessionName=%{public}s", count, tmpName);
122         AnonymizeFree(tmpName);
123         count++;
124     }
125 }
126 
TransSessionServerAddItem(SessionServer * newNode)127 int32_t TransSessionServerAddItem(SessionServer *newNode)
128 {
129     TRANS_CHECK_AND_RETURN_RET_LOGE(newNode != NULL, SOFTBUS_INVALID_PARAM, TRANS_CTRL, "param invalid");
130     TRANS_CHECK_AND_RETURN_RET_LOGE(g_sessionServerList != NULL, SOFTBUS_NO_INIT, TRANS_CTRL, "not init");
131     if (SoftBusMutexLock(&g_sessionServerList->lock) != SOFTBUS_OK) {
132         TRANS_LOGE(TRANS_CTRL, "lock mutex failed");
133         return SOFTBUS_LOCK_ERR;
134     }
135     if (g_sessionServerList->cnt >= MAX_SESSION_SERVER_NUM) {
136         (void)ShowSessionServer();
137         (void)SoftBusMutexUnlock(&g_sessionServerList->lock);
138         TRANS_LOGE(TRANS_CTRL, "session server num reach max");
139         return SOFTBUS_INVALID_NUM;
140     }
141 
142     SessionServer *pos = NULL;
143     SessionServer *tmp = NULL;
144     char *tmpName = NULL;
145     LIST_FOR_EACH_ENTRY_SAFE(pos, tmp, &g_sessionServerList->list, SessionServer, node) {
146         if (strcmp(pos->sessionName, newNode->sessionName) == 0) {
147             Anonymize(newNode->sessionName, &tmpName);
148             if ((pos->uid == newNode->uid) && (pos->pid == newNode->pid)) {
149                 TRANS_LOGI(TRANS_CTRL, "session server is exist, sessionName=%{public}s", AnonymizeWrapper(tmpName));
150                 (void)SoftBusMutexUnlock(&g_sessionServerList->lock);
151                 AnonymizeFree(tmpName);
152                 return SOFTBUS_SERVER_NAME_REPEATED;
153             }
154             if (CheckServiceIsRegistered(pos->pkgName, pos->pid) == SOFTBUS_OK) {
155                 TRANS_LOGI(TRANS_CTRL,
156                     "sessionName=%{public}s has been used by other processes, old Pid=%{public}d, new pid=%{public}d",
157                     AnonymizeWrapper(tmpName), pos->pid, newNode->pid);
158                 (void)SoftBusMutexUnlock(&g_sessionServerList->lock);
159                 AnonymizeFree(tmpName);
160                 return SOFTBUS_SERVER_NAME_USED;
161             }
162             pos->pid = newNode->pid;
163             TRANS_LOGI(TRANS_CTRL, "sessionName=%{public}s is exist. old pid=%{public}d, new pid=%{public}d",
164                 AnonymizeWrapper(tmpName), pos->pid, newNode->pid);
165             (void)SoftBusMutexUnlock(&g_sessionServerList->lock);
166             AnonymizeFree(tmpName);
167             SoftBusFree(newNode);
168             return SOFTBUS_OK;
169         }
170     }
171 
172     Anonymize(newNode->sessionName, &tmpName);
173     ListAdd(&(g_sessionServerList->list), &(newNode->node));
174     TRANS_LOGI(TRANS_CTRL, "add sessionName=%{public}s", AnonymizeWrapper(tmpName));
175     g_sessionServerList->cnt++;
176     (void)SoftBusMutexUnlock(&g_sessionServerList->lock);
177     AnonymizeFree(tmpName);
178     return SOFTBUS_OK;
179 }
180 
TransSessionServerDelItem(const char * sessionName)181 int32_t TransSessionServerDelItem(const char *sessionName)
182 {
183     if (sessionName == NULL) {
184         return SOFTBUS_INVALID_PARAM;
185     }
186     if (g_sessionServerList == NULL) {
187         return SOFTBUS_NO_INIT;
188     }
189 
190     bool isFind = false;
191     SessionServer *pos = NULL;
192     SessionServer *tmp = NULL;
193     if (SoftBusMutexLock(&g_sessionServerList->lock) != SOFTBUS_OK) {
194         TRANS_LOGE(TRANS_CTRL, "lock mutex failed");
195         return SOFTBUS_LOCK_ERR;
196     }
197     LIST_FOR_EACH_ENTRY_SAFE(pos, tmp, &g_sessionServerList->list, SessionServer, node) {
198         if (strcmp(pos->sessionName, sessionName) == 0) {
199             isFind = true;
200             break;
201         }
202     }
203     if (isFind) {
204         ListDelete(&pos->node);
205         SoftBusFree(pos);
206         g_sessionServerList->cnt--;
207         char *tmpName = NULL;
208         Anonymize(sessionName, &tmpName);
209         TRANS_LOGI(TRANS_CTRL, "destroy session server sessionName=%{public}s", tmpName);
210         AnonymizeFree(tmpName);
211     }
212     (void)SoftBusMutexUnlock(&g_sessionServerList->lock);
213     return SOFTBUS_OK;
214 }
215 
CheckUidAndPid(const char * sessionName,pid_t callingUid,pid_t callingPid)216 bool CheckUidAndPid(const char *sessionName, pid_t callingUid, pid_t callingPid)
217 {
218     if (sessionName == NULL) {
219         TRANS_LOGE(TRANS_CTRL, "Parameter sessionName is empty");
220         return false;
221     }
222     if (g_sessionServerList == NULL) {
223         TRANS_LOGE(TRANS_CTRL, "sessionServer is empty");
224         return false;
225     }
226     if (SoftBusMutexLock(&g_sessionServerList->lock) != SOFTBUS_OK) {
227         TRANS_LOGE(TRANS_CTRL, "Lock failure");
228         return false;
229     }
230 
231     SessionServer *pos = NULL;
232     LIST_FOR_EACH_ENTRY(pos, &g_sessionServerList->list, SessionServer, node) {
233         if (strcmp(pos->sessionName, sessionName) == 0 &&
234             pos->uid == callingUid && pos->pid == callingPid) {
235             (void)SoftBusMutexUnlock(&g_sessionServerList->lock);
236             return true;
237         }
238     }
239 
240     (void)SoftBusMutexUnlock(&g_sessionServerList->lock);
241     return false;
242 }
243 
TransDelItemByPackageName(const char * pkgName,int32_t pid)244 void TransDelItemByPackageName(const char *pkgName, int32_t pid)
245 {
246     if (pkgName == NULL || g_sessionServerList == NULL) {
247         return;
248     }
249 
250     SessionServer *pos = NULL;
251     SessionServer *tmp = NULL;
252     if (SoftBusMutexLock(&g_sessionServerList->lock) != SOFTBUS_OK) {
253         TRANS_LOGE(TRANS_CTRL, "lock mutex failed");
254         return;
255     }
256     LIST_FOR_EACH_ENTRY_SAFE(pos, tmp, &g_sessionServerList->list, SessionServer, node) {
257         if ((strcmp(pos->pkgName, pkgName) == 0) && (pos->pid == pid)) {
258             if (CheckDBinder(pos->sessionName)) {
259                 // Remove RPC Permission when Client Process Exit
260                 (void)DeleteDynamicPermission(pos->sessionName);
261             }
262             ListDelete(&pos->node);
263             g_sessionServerList->cnt--;
264             SoftBusFree(pos);
265             pos = NULL;
266         }
267     }
268     (void)SoftBusMutexUnlock(&g_sessionServerList->lock);
269     TRANS_LOGI(TRANS_CTRL, "del pkgName=%{public}s", pkgName);
270 }
271 
TransGetPkgNameBySessionName(const char * sessionName,char * pkgName,uint16_t len)272 int32_t TransGetPkgNameBySessionName(const char *sessionName, char *pkgName, uint16_t len)
273 {
274     if (sessionName == NULL || pkgName == NULL || len == 0) {
275         TRANS_LOGE(TRANS_CTRL, "param error");
276         return SOFTBUS_INVALID_PARAM;
277     }
278     if (g_sessionServerList == NULL) {
279         TRANS_LOGE(TRANS_CTRL, "session server list not init");
280         return SOFTBUS_NO_INIT;
281     }
282 
283     SessionServer *pos = NULL;
284     SessionServer *tmp = NULL;
285     if (SoftBusMutexLock(&g_sessionServerList->lock) != SOFTBUS_OK) {
286         TRANS_LOGE(TRANS_CTRL, "lock mutex failed");
287         return SOFTBUS_LOCK_ERR;
288     }
289     LIST_FOR_EACH_ENTRY_SAFE(pos, tmp, &g_sessionServerList->list, SessionServer, node) {
290         if (strcmp(pos->sessionName, sessionName) == 0) {
291             int32_t ret = strcpy_s(pkgName, len, pos->pkgName);
292             (void)SoftBusMutexUnlock(&g_sessionServerList->lock);
293             if (ret != EOK) {
294                 TRANS_LOGE(TRANS_CTRL, "strcpy_s error ret, ret=%{public}d", ret);
295                 return SOFTBUS_STRCPY_ERR;
296             }
297             return SOFTBUS_OK;
298         }
299     }
300 
301     (void)SoftBusMutexUnlock(&g_sessionServerList->lock);
302     char *tmpName = NULL;
303     Anonymize(sessionName, &tmpName);
304     TRANS_LOGE(TRANS_CTRL, "not found sessionName=%{public}s.", tmpName);
305     AnonymizeFree(tmpName);
306     return SOFTBUS_TRANS_SESSION_NAME_NO_EXIST;
307 }
308 
TransGetUidAndPid(const char * sessionName,int32_t * uid,int32_t * pid)309 int32_t TransGetUidAndPid(const char *sessionName, int32_t *uid, int32_t *pid)
310 {
311     if (sessionName == NULL || uid == NULL || pid == NULL) {
312         return SOFTBUS_INVALID_PARAM;
313     }
314     if (g_sessionServerList == NULL) {
315         TRANS_LOGE(TRANS_CTRL, "not init");
316         return SOFTBUS_NO_INIT;
317     }
318 
319     if (SoftBusMutexLock(&g_sessionServerList->lock) != SOFTBUS_OK) {
320         TRANS_LOGE(TRANS_CTRL, "lock mutex failed");
321         return SOFTBUS_LOCK_ERR;
322     }
323 
324     SessionServer *pos = NULL;
325     SessionServer *tmp = NULL;
326     char *tmpName = NULL;
327     Anonymize(sessionName, &tmpName);
328     LIST_FOR_EACH_ENTRY_SAFE(pos, tmp, &g_sessionServerList->list, SessionServer, node) {
329         if (strcmp(pos->sessionName, sessionName) == 0) {
330             *uid = pos->uid;
331             *pid = pos->pid;
332             TRANS_LOGD(TRANS_CTRL, "sessionName=%{public}s, uid=%{public}d, pid=%{public}d",
333                 tmpName, pos->uid, pos->pid);
334             (void)SoftBusMutexUnlock(&g_sessionServerList->lock);
335             AnonymizeFree(tmpName);
336             return SOFTBUS_OK;
337         }
338     }
339 
340     (void)SoftBusMutexUnlock(&g_sessionServerList->lock);
341     TRANS_LOGE(TRANS_CTRL, "err: sessionName=%{public}s", tmpName);
342     AnonymizeFree(tmpName);
343     return SOFTBUS_TRANS_GET_PID_FAILED;
344 }
345 
TransListDelete(ListNode * sessionServerList)346 static void TransListDelete(ListNode *sessionServerList)
347 {
348     SessionServer *pos = NULL;
349     SessionServer *tmp = NULL;
350 
351     LIST_FOR_EACH_ENTRY_SAFE(pos, tmp, sessionServerList, SessionServer, node) {
352         ListDelete(&pos->node);
353         SoftBusFree(pos);
354     }
355 }
356 
TransListCopy(ListNode * sessionServerList)357 static int32_t TransListCopy(ListNode *sessionServerList)
358 {
359     TRANS_LOGD(TRANS_CTRL, "enter.");
360     if (sessionServerList == NULL) {
361         return SOFTBUS_NO_INIT;
362     }
363 
364     SessionServer *pos = NULL;
365     SessionServer *tmp = NULL;
366     if (SoftBusMutexLock(&g_sessionServerList->lock) != SOFTBUS_OK) {
367         TRANS_LOGE(TRANS_CTRL, "lock mutex failed");
368         return SOFTBUS_LOCK_ERR;
369     }
370     LIST_FOR_EACH_ENTRY_SAFE(pos, tmp, &g_sessionServerList->list, SessionServer, node) {
371         SessionServer *newPos = (SessionServer *)SoftBusMalloc(sizeof(SessionServer));
372         if (newPos == NULL) {
373             TransListDelete(sessionServerList);
374             TRANS_LOGE(TRANS_CTRL, "SoftBusMalloc failed");
375             (void)SoftBusMutexUnlock(&g_sessionServerList->lock);
376             return SOFTBUS_MALLOC_ERR;
377         }
378         *newPos = *pos;
379         ListAdd(sessionServerList, &newPos->node);
380     }
381     (void)SoftBusMutexUnlock(&g_sessionServerList->lock);
382     return SOFTBUS_OK;
383 }
384 
TransOnLinkDown(const char * networkId,const char * uuid,const char * udid,const char * peerIp,int32_t type)385 void TransOnLinkDown(const char *networkId, const char *uuid, const char *udid, const char *peerIp, int32_t type)
386 {
387     if (networkId == NULL || g_sessionServerList == NULL) {
388         return;
389     }
390     int32_t routeType = (int32_t)GET_ROUTE_TYPE(type);
391     int32_t connType = (int32_t)GET_CONN_TYPE(type);
392     char *anonyNetworkId = NULL;
393     Anonymize(networkId, &anonyNetworkId);
394     TRANS_LOGI(TRANS_CTRL,
395         "routeType=%{public}d, networkId=%{public}s connType=%{public}d", routeType, anonyNetworkId, connType);
396     AnonymizeFree(anonyNetworkId);
397 
398     ListNode sessionServerList = {0};
399     ListInit(&sessionServerList);
400     int32_t ret = TransListCopy(&sessionServerList);
401     if (ret != SOFTBUS_OK) {
402         TRANS_LOGE(TRANS_CTRL, "copy list failed");
403         return;
404     }
405 
406     SessionServer *pos = NULL;
407     SessionServer *tmp = NULL;
408     LinkDownInfo info = {
409         .uuid = uuid,
410         .udid = udid,
411         .peerIp = peerIp,
412         .networkId = networkId,
413         .routeType = type
414     };
415 
416     LIST_FOR_EACH_ENTRY_SAFE(pos, tmp, &sessionServerList, SessionServer, node) {
417         (void)TransServerOnChannelLinkDown(pos->pkgName, pos->pid, &info);
418     }
419 
420     if (routeType == WIFI_P2P) {
421         LaneDeleteP2pAddress(networkId, true);
422     }
423     TransListDelete(&sessionServerList);
424 }
425