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 "softbus_proxychannel_control.h"
17 
18 #include <securec.h>
19 #include <string.h>
20 
21 #include "auth_interface.h"
22 #include "cJSON.h"
23 #include "softbus_def.h"
24 #include "softbus_errcode.h"
25 #include "softbus_proxychannel_manager.h"
26 #include "softbus_proxychannel_message.h"
27 #include "softbus_proxychannel_transceiver.h"
28 #include "trans_log.h"
29 #include "trans_event.h"
30 
TransProxySendInnerMessage(ProxyChannelInfo * info,const char * payLoad,uint32_t payLoadLen,int32_t priority)31 int32_t TransProxySendInnerMessage(ProxyChannelInfo *info, const char *payLoad,
32     uint32_t payLoadLen, int32_t priority)
33 {
34     if (info == NULL) {
35         TRANS_LOGW(TRANS_CTRL, "invalid param.");
36         return SOFTBUS_INVALID_PARAM;
37     }
38 
39     ProxyDataInfo dataInfo = {0};
40     ProxyMessageHead msgHead = {0};
41     msgHead.type = (PROXYCHANNEL_MSG_TYPE_NORMAL & FOUR_BIT_MASK) | (VERSION << VERSION_SHIFT);
42     msgHead.cipher = (msgHead.cipher | ENCRYPTED);
43     msgHead.myId = info->myId;
44     msgHead.peerId = info->peerId;
45 
46     dataInfo.inData = (uint8_t *)payLoad;
47     dataInfo.inLen = payLoadLen;
48     if (TransProxyPackMessage(&msgHead, info->authHandle, &dataInfo) != SOFTBUS_OK) {
49         TRANS_LOGE(TRANS_CTRL, "pack msg error");
50         return SOFTBUS_TRANS_PROXY_PACKMSG_ERR;
51     }
52     return TransProxyTransSendMsg(info->connId, dataInfo.outData, dataInfo.outLen,
53         priority, info->appInfo.myData.pid);
54 }
55 
ConvertConnectType2AuthLinkType(ConnectType type)56 static inline AuthLinkType ConvertConnectType2AuthLinkType(ConnectType type)
57 {
58     if (type == CONNECT_TCP) {
59         return AUTH_LINK_TYPE_WIFI;
60     } else if ((type == CONNECT_BLE) || (type == CONNECT_BLE_DIRECT)) {
61         return AUTH_LINK_TYPE_BLE;
62     } else if (type == CONNECT_BR) {
63         return AUTH_LINK_TYPE_BR;
64     } else {
65         return AUTH_LINK_TYPE_P2P;
66     }
67 }
68 
SetCipherOfHandshakeMsg(ProxyChannelInfo * info,uint8_t * cipher)69 static int32_t SetCipherOfHandshakeMsg(ProxyChannelInfo *info, uint8_t *cipher)
70 {
71     AuthGetLatestIdByUuid(info->appInfo.peerData.deviceId, ConvertConnectType2AuthLinkType(info->type),
72                           false, &info->authHandle);
73     if (info->authHandle.authId == AUTH_INVALID_ID) {
74         TRANS_LOGE(TRANS_CTRL, "get authId for cipher err");
75         return SOFTBUS_TRANS_PROXY_GET_AUTH_ID_FAILED;
76     }
77 
78     int32_t ret = TransProxySetAuthHandleByChanId((int32_t)info->channelId, info->authHandle);
79     if (ret != SOFTBUS_OK) {
80         TRANS_LOGE(TRANS_CTRL, "set authHandle fail, ret=%{public}d", ret);
81         return ret;
82     }
83     AuthConnInfo connInfo;
84     (void)memset_s(&connInfo, sizeof(AuthConnInfo), 0, sizeof(AuthConnInfo));
85     ret = AuthGetConnInfo(info->authHandle, &connInfo);
86     if (ret != SOFTBUS_OK) {
87         TRANS_LOGE(TRANS_CTRL, "get auth connInfo fail");
88         return ret;
89     }
90     bool isAuthServer = false;
91     ret = AuthGetServerSide(info->authHandle.authId, &isAuthServer);
92     if (ret != SOFTBUS_OK) {
93         TRANS_LOGE(TRANS_CTRL, "get auth server side fail");
94         return ret;
95     }
96 
97     *cipher |= ENCRYPTED;
98     if (isAuthServer) {
99         *cipher |= AUTH_SERVER_SIDE;
100     }
101     if (connInfo.type == AUTH_LINK_TYPE_BLE) {
102         *cipher |= USE_BLE_CIPHER;
103     }
104     return SOFTBUS_OK;
105 }
106 
TransProxyHandshake(ProxyChannelInfo * info)107 int32_t TransProxyHandshake(ProxyChannelInfo *info)
108 {
109     if (info == NULL) {
110         TRANS_LOGW(TRANS_CTRL, "invalid param.");
111         return SOFTBUS_INVALID_PARAM;
112     }
113     char *payLoad = NULL;
114     ProxyDataInfo dataInfo = {0};
115     ProxyMessageHead msgHead = {0};
116     msgHead.type = (PROXYCHANNEL_MSG_TYPE_HANDSHAKE & FOUR_BIT_MASK) | (VERSION << VERSION_SHIFT);
117     msgHead.cipher = CS_MODE;
118     if (info->appInfo.appType != APP_TYPE_AUTH) {
119         if (SetCipherOfHandshakeMsg(info, &msgHead.cipher) != SOFTBUS_OK) {
120             TRANS_LOGE(TRANS_CTRL, "set cipher fail");
121             return SOFTBUS_TRANS_PROXY_SET_CIPHER_FAILED;
122         }
123     }
124     msgHead.myId = info->myId;
125     msgHead.peerId = INVALID_CHANNEL_ID;
126     TRANS_LOGI(TRANS_CTRL, "handshake myChannelId=%{public}d, cipher=0x%{public}02x", msgHead.myId, msgHead.cipher);
127     payLoad = TransProxyPackHandshakeMsg(info);
128     if (payLoad == NULL) {
129         TRANS_LOGE(TRANS_CTRL, "pack handshake fail");
130         return SOFTBUS_TRANS_PROXY_PACK_HANDSHAKE_ERR;
131     }
132     dataInfo.inData = (uint8_t *)payLoad;
133     dataInfo.inLen = strlen(payLoad) + 1;
134     if (TransProxyPackMessage(&msgHead, info->authHandle, &dataInfo) != SOFTBUS_OK) {
135         TRANS_LOGE(TRANS_CTRL, "pack handshake head fail");
136         cJSON_free(payLoad);
137         return SOFTBUS_TRANS_PROXY_PACK_HANDSHAKE_HEAD_ERR;
138     }
139     cJSON_free(payLoad);
140     dataInfo.inData = NULL;
141     int32_t ret = TransProxyTransSendMsg(info->connId, dataInfo.outData, dataInfo.outLen,
142         CONN_HIGH, info->appInfo.myData.pid);
143     if (ret != SOFTBUS_OK) {
144         TRANS_LOGE(TRANS_CTRL, "send handshake buf fail");
145         return ret;
146     }
147     TransEventExtra extra = {
148         .channelId = info->myId,
149         .connectionId = (int32_t)info->connId,
150         .result = EVENT_STAGE_RESULT_OK
151     };
152     TRANS_EVENT(EVENT_SCENE_OPEN_CHANNEL, EVENT_STAGE_HANDSHAKE_START, extra);
153     return SOFTBUS_OK;
154 }
155 
TransProxyAckHandshake(uint32_t connId,ProxyChannelInfo * chan,int32_t retCode)156 int32_t TransProxyAckHandshake(uint32_t connId, ProxyChannelInfo *chan, int32_t retCode)
157 {
158     if (chan == NULL) {
159         TRANS_LOGW(TRANS_CTRL, "invalid param.");
160         return SOFTBUS_INVALID_PARAM;
161     }
162     char *payLoad = NULL;
163     ProxyDataInfo dataInfo = {0};
164     ProxyMessageHead msgHead = {0};
165 
166     msgHead.type = (PROXYCHANNEL_MSG_TYPE_HANDSHAKE_ACK & FOUR_BIT_MASK) | (VERSION << VERSION_SHIFT);
167     if (chan->appInfo.appType != APP_TYPE_AUTH) {
168         msgHead.cipher = (msgHead.cipher | ENCRYPTED);
169     }
170     msgHead.myId = chan->myId;
171     msgHead.peerId = chan->peerId;
172 
173     if (retCode != SOFTBUS_OK) {
174         TRANS_LOGI(TRANS_CTRL,
175             "send handshake error msg errCode=%{public}d, myChannelId=%{public}d, peerChannelId=%{public}d",
176             retCode, chan->myId, chan->peerId);
177         payLoad = TransProxyPackHandshakeErrMsg(retCode);
178     } else {
179         TRANS_LOGI(TRANS_CTRL, "send handshake ack msg myChannelId=%{public}d, peerChannelId=%{public}d",
180             chan->myId, chan->peerId);
181         payLoad = TransProxyPackHandshakeAckMsg(chan);
182     }
183     if (payLoad == NULL) {
184         TRANS_LOGE(TRANS_CTRL, "pack handshake ack fail");
185         return SOFTBUS_TRANS_PROXY_PACKMSG_ERR;
186     }
187     dataInfo.inData = (uint8_t *)payLoad;
188     dataInfo.inLen = strlen(payLoad) + 1;
189     if (TransProxyPackMessage(&msgHead, chan->authHandle, &dataInfo) != SOFTBUS_OK) {
190         TRANS_LOGE(TRANS_CTRL, "pack handshake ack head fail");
191         cJSON_free(payLoad);
192         return SOFTBUS_TRANS_PROXY_PACKMSG_ERR;
193     }
194     cJSON_free(payLoad);
195     int32_t ret = TransProxyTransSendMsg(connId, dataInfo.outData, dataInfo.outLen,
196         CONN_HIGH, chan->appInfo.myData.pid);
197     TRANS_CHECK_AND_RETURN_RET_LOGE(ret == SOFTBUS_OK, ret, TRANS_CTRL, "send handshakeack buf fail");
198     return SOFTBUS_OK;
199 }
200 
TransProxyKeepalive(uint32_t connId,const ProxyChannelInfo * info)201 void TransProxyKeepalive(uint32_t connId, const ProxyChannelInfo *info)
202 {
203     if (info == NULL) {
204         TRANS_LOGW(TRANS_CTRL, "invalid param.");
205         return;
206     }
207 
208     char *payLoad = NULL;
209     ProxyDataInfo dataInfo = {0};
210     ProxyMessageHead msgHead = {0};
211     msgHead.type = (PROXYCHANNEL_MSG_TYPE_KEEPALIVE & FOUR_BIT_MASK) | (VERSION << VERSION_SHIFT);
212     msgHead.myId = info->myId;
213     msgHead.peerId = info->peerId;
214     if (info->appInfo.appType != APP_TYPE_AUTH) {
215         msgHead.cipher = (msgHead.cipher | ENCRYPTED);
216     }
217 
218     payLoad = TransProxyPackIdentity(info->identity);
219     if (payLoad == NULL) {
220         TRANS_LOGE(TRANS_CTRL, "pack keepalive fail");
221         return;
222     }
223     dataInfo.inData = (uint8_t *)payLoad;
224     dataInfo.inLen = strlen(payLoad) + 1;
225     if (TransProxyPackMessage(&msgHead, info->authHandle, &dataInfo) != SOFTBUS_OK) {
226         TRANS_LOGE(TRANS_CTRL, "pack keepalive head fail");
227         cJSON_free(payLoad);
228         return;
229     }
230     cJSON_free(payLoad);
231     if (TransProxyTransSendMsg(connId, dataInfo.outData, dataInfo.outLen,
232         CONN_HIGH, info->appInfo.myData.pid) != SOFTBUS_OK) {
233         TRANS_LOGE(TRANS_CTRL, "send keepalive buf fail");
234         return;
235     }
236 }
237 
TransProxyAckKeepalive(ProxyChannelInfo * info)238 int32_t TransProxyAckKeepalive(ProxyChannelInfo *info)
239 {
240     if (info == NULL) {
241         TRANS_LOGW(TRANS_CTRL, "invalid param.");
242         return SOFTBUS_INVALID_PARAM;
243     }
244     char *payLoad = NULL;
245     ProxyDataInfo dataInfo = {0};
246     ProxyMessageHead msgHead = {0};
247     msgHead.type = (PROXYCHANNEL_MSG_TYPE_KEEPALIVE_ACK & FOUR_BIT_MASK) | (VERSION << VERSION_SHIFT);
248     msgHead.myId = info->myId;
249     msgHead.peerId = info->peerId;
250     if (info->appInfo.appType != APP_TYPE_AUTH) {
251         msgHead.cipher = (msgHead.cipher | ENCRYPTED);
252     }
253 
254     payLoad = TransProxyPackIdentity(info->identity);
255     if (payLoad == NULL) {
256         TRANS_LOGE(TRANS_CTRL, "pack keepalive ack fail");
257         return SOFTBUS_TRANS_PACK_LEEPALIVE_ACK_FAILED;
258     }
259     dataInfo.inData = (uint8_t *)payLoad;
260     dataInfo.inLen = strlen(payLoad) + 1;
261     int32_t ret = TransProxyPackMessage(&msgHead, info->authHandle, &dataInfo);
262     if (ret != SOFTBUS_OK) {
263         TRANS_LOGE(TRANS_CTRL, "pack keepalive ack head fail");
264         cJSON_free(payLoad);
265         return ret;
266     }
267     cJSON_free(payLoad);
268     ret = TransProxyTransSendMsg(info->connId, dataInfo.outData, dataInfo.outLen, CONN_HIGH, info->appInfo.myData.pid);
269     if (ret != SOFTBUS_OK) {
270         TRANS_LOGE(TRANS_CTRL, "send keepalive ack buf fail");
271         return ret;
272     }
273     return SOFTBUS_OK;
274 }
275 
TransProxyResetPeer(ProxyChannelInfo * info)276 int32_t TransProxyResetPeer(ProxyChannelInfo *info)
277 {
278     if (info == NULL) {
279         TRANS_LOGW(TRANS_CTRL, "invalid param.");
280         return SOFTBUS_INVALID_PARAM;
281     }
282 
283     char *payLoad = NULL;
284     ProxyDataInfo dataInfo = {0};
285     ProxyMessageHead msgHead = {0};
286     TRANS_LOGI(TRANS_CTRL, "send reset msg myChannelId=%{public}d, peerChannelId=%{public}d", info->myId, info->peerId);
287     msgHead.type = (PROXYCHANNEL_MSG_TYPE_RESET & FOUR_BIT_MASK) | (VERSION << VERSION_SHIFT);
288     msgHead.myId = info->myId;
289     msgHead.peerId = info->peerId;
290     if (info->appInfo.appType != APP_TYPE_AUTH) {
291         msgHead.cipher = (msgHead.cipher | ENCRYPTED);
292     }
293 
294     payLoad = TransProxyPackIdentity(info->identity);
295     if (payLoad == NULL) {
296         TRANS_LOGE(TRANS_CTRL, "pack reset fail");
297         return SOFTBUS_TRANS_PACK_LEEPALIVE_ACK_FAILED;
298     }
299     dataInfo.inData = (uint8_t *)payLoad;
300     dataInfo.inLen = strlen(payLoad) + 1;
301     int32_t ret = TransProxyPackMessage(&msgHead, info->authHandle, &dataInfo);
302     if (ret != SOFTBUS_OK) {
303         TRANS_LOGE(TRANS_CTRL, "pack reset head fail");
304         cJSON_free(payLoad);
305         return ret;
306     }
307     cJSON_free(payLoad);
308     ret = TransProxyTransSendMsg(info->connId, dataInfo.outData, dataInfo.outLen, CONN_LOW, info->appInfo.myData.pid);
309     TransEventExtra extra = {
310         .socketName = info->appInfo.myData.sessionName,
311         .channelId = info->channelId,
312         .errcode = ret,
313         .result = EVENT_STAGE_RESULT_OK
314     };
315     if (ret != SOFTBUS_OK) {
316         TRANS_LOGE(TRANS_CTRL, "send reset buf fail");
317         extra.result = EVENT_STAGE_RESULT_FAILED;
318         TRANS_EVENT(EVENT_SCENE_TRANS_PROXY_RESET_PEER, EVENT_STAGE_TRANS_COMMON_ONE, extra);
319         return ret;
320     }
321     TRANS_EVENT(EVENT_SCENE_TRANS_PROXY_RESET_PEER, EVENT_STAGE_TRANS_COMMON_ONE, extra);
322     return SOFTBUS_OK;
323 }
324