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(&regComp, ISHARE_SESSION_NAME, REG_EXTENDED | REG_NOSUB) != 0) {
44         TRANS_LOGE(TRANS_CTRL, "regcomp failed.");
45         return false;
46     }
47     bool compare = regexec(&regComp, sessionName, 0, NULL, 0) == 0;
48     regfree(&regComp);
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 }