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