1 /*
2 * Copyright (c) 2021-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 "trans_udp_negotiation_exchange.h"
17
18 #include "regex.h"
19 #include <securec.h>
20 #include "softbus_message_open_channel.h"
21 #include "softbus_adapter_crypto.h"
22 #include "softbus_def.h"
23 #include "softbus_errcode.h"
24 #include "softbus_json_utils.h"
25 #include "trans_log.h"
26 #include "trans_udp_channel_manager.h"
27
28 #define BASE64_SESSION_KEY_LEN 45
29 typedef enum {
30 CODE_EXCHANGE_UDP_INFO = 6,
31 CODE_FILE_TRANS_UDP = 0x602
32 } CodeType;
33
34 #define ISHARE_SESSION_NAME "IShare*"
35
IsIShareSession(const char * sessionName)36 bool IsIShareSession(const char *sessionName)
37 {
38 if (sessionName == NULL) {
39 TRANS_LOGE(TRANS_CTRL, "invalid sessionName.");
40 return false;
41 }
42 regex_t regComp;
43 if (regcomp(®Comp, ISHARE_SESSION_NAME, REG_EXTENDED | REG_NOSUB) != 0) {
44 TRANS_LOGE(TRANS_CTRL, "regcomp failed.");
45 return false;
46 }
47 bool compare = regexec(®Comp, sessionName, 0, NULL, 0) == 0;
48 regfree(®Comp);
49 return compare;
50 }
51
getCodeType(const AppInfo * appInfo)52 static inline CodeType getCodeType(const AppInfo *appInfo)
53 {
54 return ((appInfo->udpConnType == UDP_CONN_TYPE_P2P) &&
55 IsIShareSession(appInfo->myData.sessionName) && (IsIShareSession(appInfo->peerData.sessionName))) ?
56 CODE_FILE_TRANS_UDP : CODE_EXCHANGE_UDP_INFO;
57 }
58
TransUnpackReplyErrInfo(const cJSON * msg,int32_t * errCode)59 int32_t TransUnpackReplyErrInfo(const cJSON *msg, int32_t *errCode)
60 {
61 if ((msg == NULL) && (errCode == NULL)) {
62 TRANS_LOGW(TRANS_CTRL, "invalid param.");
63 return SOFTBUS_INVALID_PARAM;
64 }
65 if (!GetJsonObjectInt32Item(msg, ERR_CODE, errCode)) {
66 return SOFTBUS_PARSE_JSON_ERR;
67 }
68 return SOFTBUS_OK;
69 }
70
TransUnpackReplyUdpInfo(const cJSON * msg,AppInfo * appInfo)71 int32_t TransUnpackReplyUdpInfo(const cJSON *msg, AppInfo *appInfo)
72 {
73 TRANS_LOGI(TRANS_CTRL, "unpack reply udp info in negotiation.");
74 if (msg == NULL || appInfo == NULL) {
75 TRANS_LOGW(TRANS_CTRL, "invalid param.");
76 return SOFTBUS_INVALID_PARAM;
77 }
78
79 (void)GetJsonObjectStringItem(msg, "PKG_NAME", appInfo->peerData.pkgName, PKG_NAME_SIZE_MAX);
80 (void)GetJsonObjectNumberItem(msg, "UID", &(appInfo->peerData.uid));
81 (void)GetJsonObjectNumberItem(msg, "PID", &(appInfo->peerData.pid));
82 (void)GetJsonObjectNumberItem(msg, "BUSINESS_TYPE", (int*)&(appInfo->businessType));
83
84 int code = CODE_EXCHANGE_UDP_INFO;
85 (void)GetJsonObjectNumberItem(msg, "CODE", &code);
86 if ((code == CODE_FILE_TRANS_UDP) && (getCodeType(appInfo) == CODE_FILE_TRANS_UDP)) {
87 appInfo->fileProtocol = APP_INFO_UDP_FILE_PROTOCOL;
88 }
89
90 switch (appInfo->udpChannelOptType) {
91 case TYPE_UDP_CHANNEL_OPEN:
92 (void)GetJsonObjectNumber64Item(msg, "MY_CHANNEL_ID", &(appInfo->peerData.channelId));
93 (void)GetJsonObjectNumberItem(msg, "MY_PORT", &(appInfo->peerData.port));
94 (void)GetJsonObjectStringItem(msg, "MY_IP", appInfo->peerData.addr, sizeof(appInfo->peerData.addr));
95 break;
96 case TYPE_UDP_CHANNEL_CLOSE:
97 break;
98 default:
99 TRANS_LOGE(TRANS_CTRL, "invalid udp channel type.");
100 return SOFTBUS_TRANS_INVALID_CHANNEL_TYPE;
101 }
102 return SOFTBUS_OK;
103 }
104
TransGetCommonUdpInfoFromJson(const cJSON * msg,AppInfo * appInfo)105 static void TransGetCommonUdpInfoFromJson(const cJSON *msg, AppInfo *appInfo)
106 {
107 (void)GetJsonObjectStringItem(msg, "PKG_NAME", appInfo->peerData.pkgName, PKG_NAME_SIZE_MAX);
108 (void)GetJsonObjectStringItem(msg, "BUS_NAME", appInfo->myData.sessionName, SESSION_NAME_SIZE_MAX);
109 (void)GetJsonObjectStringItem(msg, "CLIENT_BUS_NAME", appInfo->peerData.sessionName, SESSION_NAME_SIZE_MAX);
110 (void)GetJsonObjectStringItem(msg, "GROUP_ID", appInfo->groupId, GROUP_ID_SIZE_MAX);
111
112 (void)GetJsonObjectNumberItem(msg, "API_VERSION", (int32_t *)&(appInfo->peerData.apiVersion));
113 (void)GetJsonObjectNumberItem(msg, "PID", &(appInfo->peerData.pid));
114 (void)GetJsonObjectNumberItem(msg, "UID", &(appInfo->peerData.uid));
115 (void)GetJsonObjectNumberItem(msg, "BUSINESS_TYPE", (int32_t *)&(appInfo->businessType));
116 (void)GetJsonObjectNumberItem(msg, "STREAM_TYPE", (int32_t *)&(appInfo->streamType));
117 (void)GetJsonObjectNumberItem(msg, "CHANNEL_TYPE", (int32_t *)&(appInfo->udpChannelOptType));
118 (void)GetJsonObjectNumberItem(msg, "UDP_CONN_TYPE", (int32_t *)&(appInfo->udpConnType));
119 }
120
TransUnpackRequestUdpInfo(const cJSON * msg,AppInfo * appInfo)121 int32_t TransUnpackRequestUdpInfo(const cJSON *msg, AppInfo *appInfo)
122 {
123 TRANS_LOGI(TRANS_CTRL, "unpack request udp info in negotiation.");
124 TRANS_CHECK_AND_RETURN_RET_LOGW(msg != NULL, SOFTBUS_INVALID_PARAM, TRANS_CTRL, "Invalid param");
125 TRANS_CHECK_AND_RETURN_RET_LOGW(appInfo != NULL, SOFTBUS_INVALID_PARAM, TRANS_CTRL, "Invalid param");
126 unsigned char encodeSessionKey[BASE64_SESSION_KEY_LEN] = {0};
127 size_t len = 0;
128 (void)GetJsonObjectStringItem(msg, "SESSION_KEY", (char*)encodeSessionKey, BASE64_SESSION_KEY_LEN);
129 int32_t ret = SoftBusBase64Decode((unsigned char*)appInfo->sessionKey, sizeof(appInfo->sessionKey), &len,
130 (unsigned char*)encodeSessionKey, strlen((char*)encodeSessionKey));
131 (void)memset_s(encodeSessionKey, sizeof(encodeSessionKey), 0, sizeof(encodeSessionKey));
132 TRANS_CHECK_AND_RETURN_RET_LOGE(len == sizeof(appInfo->sessionKey),
133 SOFTBUS_DECRYPT_ERR, TRANS_CTRL, "mbedtls decode failed.");
134 TRANS_CHECK_AND_RETURN_RET_LOGE(ret == 0, SOFTBUS_DECRYPT_ERR, TRANS_CTRL, "mbedtls decode failed.");
135
136 TransGetCommonUdpInfoFromJson(msg, appInfo);
137
138 int code = CODE_EXCHANGE_UDP_INFO;
139 (void)GetJsonObjectNumberItem(msg, "CODE", &code);
140 if ((code == CODE_FILE_TRANS_UDP) && (getCodeType(appInfo) == CODE_FILE_TRANS_UDP)) {
141 appInfo->fileProtocol = APP_INFO_UDP_FILE_PROTOCOL;
142 }
143
144 switch (appInfo->udpChannelOptType) {
145 case TYPE_UDP_CHANNEL_OPEN:
146 (void)GetJsonObjectNumber64Item(msg, "MY_CHANNEL_ID", &(appInfo->peerData.channelId));
147 (void)GetJsonObjectStringItem(msg, "MY_IP", appInfo->peerData.addr, sizeof(appInfo->peerData.addr));
148 if (!GetJsonObjectNumberItem(msg, "CALLING_TOKEN_ID", (int32_t *)&appInfo->callingTokenId)) {
149 appInfo->callingTokenId = TOKENID_NOT_SET;
150 }
151 (void)GetJsonObjectNumberItem(msg, "LINK_TYPE", &appInfo->linkType);
152 break;
153 case TYPE_UDP_CHANNEL_CLOSE:
154 (void)GetJsonObjectNumber64Item(msg, "PEER_CHANNEL_ID", &(appInfo->myData.channelId));
155 (void)GetJsonObjectNumber64Item(msg, "MY_CHANNEL_ID", &(appInfo->peerData.channelId));
156 (void)GetJsonObjectStringItem(msg, "MY_IP", appInfo->peerData.addr, sizeof(appInfo->peerData.addr));
157 if (appInfo->myData.channelId == INVALID_CHANNEL_ID) {
158 (void)TransUdpGetChannelIdByAddr(appInfo);
159 }
160 break;
161 default:
162 TRANS_LOGE(TRANS_CTRL, "invalid udp channel type.");
163 return SOFTBUS_TRANS_INVALID_CHANNEL_TYPE;
164 }
165 return SOFTBUS_OK;
166 }
167
TransPackRequestUdpInfo(cJSON * msg,const AppInfo * appInfo)168 int32_t TransPackRequestUdpInfo(cJSON *msg, const AppInfo *appInfo)
169 {
170 TRANS_LOGI(TRANS_CTRL, "pack request udp info in negotiation.");
171 if (msg == NULL || appInfo == NULL) {
172 TRANS_LOGW(TRANS_CTRL, "invalid param.");
173 return SOFTBUS_INVALID_PARAM;
174 }
175
176 switch (appInfo->udpChannelOptType) {
177 case TYPE_UDP_CHANNEL_OPEN:
178 (void)AddNumber64ToJsonObject(msg, "MY_CHANNEL_ID", appInfo->myData.channelId);
179 (void)AddStringToJsonObject(msg, "MY_IP", appInfo->myData.addr);
180 (void)AddNumberToJsonObject(msg, "CALLING_TOKEN_ID", (int32_t)appInfo->callingTokenId);
181 (void)AddNumberToJsonObject(msg, "LINK_TYPE", appInfo->linkType);
182 break;
183 case TYPE_UDP_CHANNEL_CLOSE:
184 (void)AddNumber64ToJsonObject(msg, "PEER_CHANNEL_ID", appInfo->peerData.channelId);
185 (void)AddNumber64ToJsonObject(msg, "MY_CHANNEL_ID", appInfo->myData.channelId);
186 (void)AddStringToJsonObject(msg, "MY_IP", appInfo->myData.addr);
187 break;
188 default:
189 TRANS_LOGE(TRANS_CTRL, "invalid udp channel type.");
190 return SOFTBUS_TRANS_INVALID_CHANNEL_TYPE;
191 }
192 char encodeSessionKey[BASE64_SESSION_KEY_LEN] = {0};
193 size_t len = 0;
194 int32_t ret = SoftBusBase64Encode((unsigned char*)encodeSessionKey, BASE64_SESSION_KEY_LEN, &len,
195 (unsigned char*)appInfo->sessionKey, sizeof(appInfo->sessionKey));
196 if (ret != SOFTBUS_OK) {
197 TRANS_LOGE(TRANS_CTRL, "mbedtls base64 encode failed.");
198 return SOFTBUS_DECRYPT_ERR;
199 }
200 (void)AddStringToJsonObject(msg, "SESSION_KEY", encodeSessionKey);
201
202 (void)AddNumberToJsonObject(msg, "CODE", getCodeType(appInfo));
203 (void)AddNumberToJsonObject(msg, "API_VERSION", appInfo->myData.apiVersion);
204 (void)AddNumberToJsonObject(msg, "UID", appInfo->myData.uid);
205 (void)AddNumberToJsonObject(msg, "PID", appInfo->myData.pid);
206 (void)AddNumberToJsonObject(msg, "BUSINESS_TYPE", appInfo->businessType);
207 (void)AddNumberToJsonObject(msg, "STREAM_TYPE", appInfo->streamType);
208 (void)AddNumberToJsonObject(msg, "CHANNEL_TYPE", appInfo->udpChannelOptType);
209 (void)AddNumberToJsonObject(msg, "UDP_CONN_TYPE", appInfo->udpConnType);
210
211 (void)AddStringToJsonObject(msg, "BUS_NAME", appInfo->peerData.sessionName);
212 (void)AddStringToJsonObject(msg, "CLIENT_BUS_NAME", appInfo->myData.sessionName);
213 (void)AddStringToJsonObject(msg, "GROUP_ID", appInfo->groupId);
214 (void)AddStringToJsonObject(msg, "PKG_NAME", appInfo->myData.pkgName);
215 (void)memset_s(encodeSessionKey, sizeof(encodeSessionKey), 0, sizeof(encodeSessionKey));
216 return SOFTBUS_OK;
217 }
218
TransPackReplyUdpInfo(cJSON * msg,const AppInfo * appInfo)219 int32_t TransPackReplyUdpInfo(cJSON *msg, const AppInfo *appInfo)
220 {
221 TRANS_LOGI(TRANS_CTRL, "pack reply udp info in negotiation.");
222 if (msg == NULL || appInfo == NULL) {
223 TRANS_LOGW(TRANS_CTRL, "invalid param.");
224 return SOFTBUS_INVALID_PARAM;
225 }
226
227 switch (appInfo->udpChannelOptType) {
228 case TYPE_UDP_CHANNEL_OPEN:
229 (void)AddNumber64ToJsonObject(msg, "MY_CHANNEL_ID", appInfo->myData.channelId);
230 (void)AddNumberToJsonObject(msg, "MY_PORT", appInfo->myData.port);
231 (void)AddStringToJsonObject(msg, "MY_IP", appInfo->myData.addr);
232 break;
233 case TYPE_UDP_CHANNEL_CLOSE:
234 break;
235 default:
236 TRANS_LOGE(TRANS_CTRL, "invalid udp channel type.");
237 return SOFTBUS_TRANS_INVALID_CHANNEL_TYPE;
238 }
239
240 (void)AddNumberToJsonObject(msg, "CODE", getCodeType(appInfo));
241 (void)AddStringToJsonObject(msg, "PKG_NAME", appInfo->myData.pkgName);
242 (void)AddNumberToJsonObject(msg, "UID", appInfo->myData.uid);
243 (void)AddNumberToJsonObject(msg, "PID", appInfo->myData.pid);
244 (void)AddNumberToJsonObject(msg, "BUSINESS_TYPE", appInfo->businessType);
245 (void)AddNumberToJsonObject(msg, "STREAM_TYPE", appInfo->streamType);
246
247 return SOFTBUS_OK;
248 }
249
TransPackReplyErrInfo(cJSON * msg,int errCode,const char * errDesc)250 int32_t TransPackReplyErrInfo(cJSON *msg, int errCode, const char* errDesc)
251 {
252 TRANS_LOGI(TRANS_CTRL, "pack reply error info in negotiation.");
253 if (msg == NULL || errDesc == NULL) {
254 TRANS_LOGW(TRANS_CTRL, "invalid param.");
255 return SOFTBUS_INVALID_PARAM;
256 }
257
258 (void)AddNumberToJsonObject(msg, CODE, CODE_EXCHANGE_UDP_INFO);
259 (void)AddStringToJsonObject(msg, ERR_DESC, errDesc);
260 (void)AddNumberToJsonObject(msg, ERR_CODE, errCode);
261
262 return SOFTBUS_OK;
263 }