• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 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 "ipsec_vpn_ctl.h"
17 
18 #include <string>
19 #include <sys/stat.h>
20 
21 #include "multi_vpn_helper.h"
22 #include "netmgr_ext_log_wrapper.h"
23 #include "netmanager_base_common_utils.h"
24 #include "net_manager_ext_constants.h"
25 
26 namespace OHOS {
27 namespace NetManagerStandard {
IpsecVpnCtl(sptr<VpnConfig> config,const std::string & pkg,int32_t userId,std::vector<int32_t> & activeUserIds)28 IpsecVpnCtl::IpsecVpnCtl(sptr<VpnConfig> config, const std::string &pkg, int32_t userId,
29     std::vector<int32_t> &activeUserIds)
30     : NetVpnImpl(config, pkg, userId, activeUserIds)
31 {}
32 
~IpsecVpnCtl()33 IpsecVpnCtl::~IpsecVpnCtl()
34 {
35     NETMGR_EXT_LOG_I("~IpsecVpnCtl");
36 }
37 
IsSystemVpn()38 bool IpsecVpnCtl::IsSystemVpn()
39 {
40     return true;
41 }
42 
SetUp()43 int32_t IpsecVpnCtl::SetUp()
44 {
45     return StartSysVpn();
46 }
47 
Destroy()48 int32_t IpsecVpnCtl::Destroy()
49 {
50     StopSysVpn();
51     if (multiVpnInfo_ != nullptr) {
52         NetsysController::GetInstance().ProcessVpnStage(SysVpnStageCode::VPN_STAGE_SET_VPN_CALL_MODE,
53             multiVpnInfo_->isVpnExtCall ? "0" : "1");
54     }
55     int result = NetVpnImpl::Destroy();
56     NETMGR_EXT_LOG_I("ipsec Destroy result %{public}d", result);
57     return result;
58 }
59 
StopSysVpn()60 int32_t IpsecVpnCtl::StopSysVpn()
61 {
62     NETMGR_EXT_LOG_I("stop ipsec vpn");
63     state_ = IpsecVpnStateCode::STATE_DISCONNECTED;
64     std::string baseConnectName = IPSEC_CONNECT_NAME;
65     std::string connectName = multiVpnInfo_ == nullptr ? baseConnectName :
66         baseConnectName + std::to_string(multiVpnInfo_->ifNameId);
67     NetsysController::GetInstance().ProcessVpnStage(
68         SysVpnStageCode::VPN_STAGE_DOWN_HOME, connectName);
69     MultiVpnHelper::GetInstance().StopIpsec();
70     NotifyConnectState(VpnConnectState::VPN_DISCONNECTED);
71     return NETMANAGER_EXT_SUCCESS;
72 }
73 
StartSysVpn()74 int32_t IpsecVpnCtl::StartSysVpn()
75 {
76     NETMGR_EXT_LOG_I("start ipsec vpn");
77     state_ = IpsecVpnStateCode::STATE_INIT;
78     InitConfigFile();
79     if (!MultiVpnHelper::GetInstance().StartIpsec()) {
80         state_ = IpsecVpnStateCode::STATE_STARTED;
81         NetsysController::GetInstance().ProcessVpnStage(SysVpnStageCode::VPN_STAGE_SWANCTL_LOAD);
82     };
83     return NETMANAGER_EXT_SUCCESS;
84 }
85 
InitConfigFile()86 int32_t IpsecVpnCtl::InitConfigFile()
87 {
88     CleanTempFiles();
89     if (ipsecVpnConfig_ == nullptr) {
90         NETMGR_EXT_LOG_E("InitConfigFile ipsecVpnConfig is null");
91         return NETMANAGER_EXT_ERR_INTERNAL;
92     }
93     if (!ipsecVpnConfig_->strongswanConf_.empty()) {
94         CommonUtils::WriteFile(SWAN_CONFIG_FILE, ipsecVpnConfig_->strongswanConf_);
95         chmod(SWAN_CONFIG_FILE, S_IRUSR | S_IWUSR | S_IRGRP);
96     }
97     return NETMANAGER_EXT_SUCCESS;
98 }
99 
CleanTempFiles()100 void IpsecVpnCtl::CleanTempFiles()
101 {
102     DeleteTempFile(SWAN_CONFIG_FILE);
103     DeleteTempFile(L2TP_CFG);
104 }
105 
DeleteTempFile(const std::string & fileName)106 void IpsecVpnCtl::DeleteTempFile(const std::string &fileName)
107 {
108     if (std::filesystem::exists(fileName)) {
109         if (!std::filesystem::remove(fileName)) {
110             NETMGR_EXT_LOG_E("remove old cache file failed");
111         }
112     }
113 }
114 
SetUpVpnTun()115 int32_t IpsecVpnCtl::SetUpVpnTun()
116 {
117     if (multiVpnInfo_ != nullptr) {
118         NetsysController::GetInstance().ProcessVpnStage(SysVpnStageCode::VPN_STAGE_SET_VPN_CALL_MODE,
119             multiVpnInfo_->isVpnExtCall ? "0" : "1");
120     }
121     if (NetVpnImpl::SetUp() != NETMANAGER_EXT_SUCCESS) {
122         StopSysVpn();
123         NETMGR_EXT_LOG_I("ipsec SetUp failed");
124         return NETMANAGER_EXT_ERR_INTERNAL;
125     }
126     if (multiVpnInfo_ != nullptr && vpnConfig_ != nullptr) {
127         multiVpnInfo_->localAddress = vpnConfig_->addresses_.empty() ?
128             "" : vpnConfig_->addresses_.back().address_;
129     }
130     NETMGR_EXT_LOG_I("ipsec SetUp success");
131     return NETMANAGER_EXT_SUCCESS;
132 }
133 
UpdateConfig(const std::string & msg)134 int32_t IpsecVpnCtl::UpdateConfig(const std::string &msg)
135 {
136     if (msg.empty()) {
137         NETMGR_EXT_LOG_E("msg is empty");
138         return NETMANAGER_EXT_ERR_PARAMETER_ERROR;
139     }
140     const char *ret = strstr(msg.c_str(), "{");
141     if (ret == nullptr) {
142         NETMGR_EXT_LOG_E("client rootJson format error");
143         return NETMANAGER_EXT_ERR_PARAMETER_ERROR;
144     }
145     cJSON* rootJson = cJSON_Parse(ret);
146     if (rootJson == nullptr) {
147         NETMGR_EXT_LOG_E("not json string");
148         return NETMANAGER_EXT_ERR_PARAMETER_ERROR;
149     }
150 
151     cJSON* jConfig = cJSON_GetObjectItem(rootJson, IPSEC_NODE_UPDATE_CONFIG);
152     if (!cJSON_IsObject(jConfig)) {
153         NETMGR_EXT_LOG_E("jConfig format error");
154         cJSON_Delete(rootJson);
155         return NETMANAGER_EXT_ERR_PARAMETER_ERROR;
156     }
157     ProcessUpdateConfig(jConfig);
158 
159     cJSON_Delete(rootJson);
160     rootJson = nullptr;
161     if (vpnConfig_ != nullptr) {
162         std::string addr = vpnConfig_->addresses_.empty() ? "" : vpnConfig_->addresses_.back().address_;
163         if (MultiVpnHelper::GetInstance().CheckAndCompareMultiVpnLocalAddress(addr) != NETMANAGER_EXT_SUCCESS) {
164             NETMGR_EXT_LOG_E("ipsec check ip address is same error.");
165             return NETMANAGER_EXT_ERR_INTERNAL;
166         }
167     }
168     return NETMANAGER_EXT_SUCCESS;
169 }
170 
171 
NotifyConnectStage(const std::string & stage,const int32_t & result)172 int32_t IpsecVpnCtl::NotifyConnectStage(const std::string &stage, const int32_t &result)
173 {
174     if (stage.empty()) {
175         NETMGR_EXT_LOG_E("stage is empty");
176         return NETMANAGER_EXT_ERR_PARAMETER_ERROR;
177     }
178     if (result != NETMANAGER_EXT_SUCCESS) {
179         NETMGR_EXT_LOG_E("ipsec vpn connect failed");
180         HandleIpsecConnectFailed(result);
181         return NETMANAGER_EXT_ERR_INTERNAL;
182     }
183     switch (state_) {
184         case IpsecVpnStateCode::STATE_INIT:
185             if (stage.compare(IPSEC_START_TAG) == 0) {
186                 ProcessSwanctlLoad();
187             }
188             break;
189         case IpsecVpnStateCode::STATE_STARTED:
190             if (stage.compare(SWANCTL_START_TAG) == 0) {
191                 ProcessIpsecUp();
192             }
193             break;
194         case IpsecVpnStateCode::STATE_CONFIGED:
195             if (stage.compare(IPSEC_CONNECT_TAG) == 0) {
196                 HandleConnected();
197             }
198             if (stage.find(IPSEC_NODE_UPDATE_CONFIG) != std::string::npos) {
199                 if (HandleUpdateConfig(stage) != NETMANAGER_EXT_SUCCESS) {
200                     return NETMANAGER_EXT_ERR_INTERNAL;
201                 }
202             }
203             break;
204         default:
205             NETMGR_EXT_LOG_E("invalid state: %{public}d", state_);
206             return NETMANAGER_EXT_ERR_INTERNAL;
207     }
208     return NETMANAGER_EXT_SUCCESS;
209 }
210 
GetSysVpnCertUri(const int32_t certType,std::string & certUri)211 int32_t IpsecVpnCtl::GetSysVpnCertUri(const int32_t certType, std::string &certUri)
212 {
213     if (ipsecVpnConfig_ == nullptr) {
214         NETMGR_EXT_LOG_E("GetSysVpnCertUri ipsecVpnConfig is null");
215         return NETMANAGER_EXT_ERR_INTERNAL;
216     }
217     switch (certType) {
218         case IpsecVpnCertType::CA_CERT:
219             certUri = ipsecVpnConfig_->ipsecCaCertConf_;
220             break;
221         case IpsecVpnCertType::USER_CERT:
222             certUri = ipsecVpnConfig_->ipsecPublicUserCertConf_;
223             break;
224         case IpsecVpnCertType::SERVER_CERT:
225             certUri = ipsecVpnConfig_->ipsecPublicServerCertConf_;
226             break;
227         case IpsecVpnCertType::SWAN_CTL_CONF:
228             certUri = ipsecVpnConfig_->swanctlConf_;
229             break;
230         default:
231             NETMGR_EXT_LOG_E("invalid certType: %{public}d", certType);
232             break;
233     }
234     return NETMANAGER_EXT_SUCCESS;
235 }
236 
GetVpnCertData(const int32_t certType,std::vector<int8_t> & certData)237 int32_t IpsecVpnCtl::GetVpnCertData(const int32_t certType, std::vector<int8_t> &certData)
238 {
239     if (ipsecVpnConfig_ == nullptr) {
240         NETMGR_EXT_LOG_E("GetSysVpnCertUri ipsecVpnConfig is null");
241         return NETMANAGER_EXT_ERR_INTERNAL;
242     }
243     switch (certType) {
244         case IpsecVpnCertType::PKCS12_PASSWD: {
245             if (!ipsecVpnConfig_->pkcs12Password_.empty()) {
246                 certData.assign(ipsecVpnConfig_->pkcs12Password_.begin(),
247                     ipsecVpnConfig_->pkcs12Password_.end());
248             } else {
249                 NETMGR_EXT_LOG_D("GetVpnCertData pkcs12 password is empty");
250             }
251             break;
252         }
253         case IpsecVpnCertType::PKCS12_DATA: {
254             if (!ipsecVpnConfig_->pkcs12FileData_.empty()) {
255                 certData.assign(ipsecVpnConfig_->pkcs12FileData_.begin(),
256                     ipsecVpnConfig_->pkcs12FileData_.end());
257             } else {
258                 NETMGR_EXT_LOG_D("GetVpnCertData pkcs12 data is empty");
259             }
260             break;
261         }
262         default:
263             NETMGR_EXT_LOG_E("invalid certType: %{public}d", certType);
264             break;
265     }
266     return NETMANAGER_EXT_SUCCESS;
267 }
268 
GetConnectedSysVpnConfig(sptr<SysVpnConfig> & sysVpnConfig)269 int32_t IpsecVpnCtl::GetConnectedSysVpnConfig(sptr<SysVpnConfig> &sysVpnConfig)
270 {
271     if (state_ == IpsecVpnStateCode::STATE_CONNECTED && ipsecVpnConfig_ != nullptr) {
272         NETMGR_EXT_LOG_I("GetConnectedSysVpnConfig success");
273         sysVpnConfig = ipsecVpnConfig_;
274     }
275     return NETMANAGER_EXT_SUCCESS;
276 }
277 
IsInternalVpn()278 bool IpsecVpnCtl::IsInternalVpn()
279 {
280     return true;
281 }
282 
ProcessUpdateConfig(cJSON * jConfig)283 void IpsecVpnCtl::ProcessUpdateConfig(cJSON* jConfig)
284 {
285     if (vpnConfig_ == nullptr) {
286         NETMGR_EXT_LOG_E("UpdateConfig vpnConfig_ is null");
287         return;
288     }
289     cJSON *mtu = cJSON_GetObjectItem(jConfig, IPSEC_NODE_MTU);
290     if (mtu != nullptr && cJSON_IsNumber(mtu)) {
291         int32_t ipsecVpnMtu = static_cast<int32_t>(cJSON_GetNumberValue(mtu));
292         vpnConfig_->mtu_ = ipsecVpnMtu;
293         NETMGR_EXT_LOG_I("UpdateConfig mtu %{public}d", ipsecVpnMtu);
294     }
295 
296     INetAddr iNetAddr;
297     INetAddr destination;
298     INetAddr gateway;
299     cJSON *address = cJSON_GetObjectItem(jConfig, IPSEC_NODE_ADDRESS);
300     if (address != nullptr && cJSON_IsString(address)) {
301         std::string ipsecVpnAddress = cJSON_GetStringValue(address);
302         iNetAddr.address_ = ipsecVpnAddress;
303         gateway.address_ = ipsecVpnAddress;
304         destination.address_ = ipsecVpnAddress;
305     }
306 
307     cJSON *netmask = cJSON_GetObjectItem(jConfig, IPSEC_NODE_NETMASK);
308     if (netmask != nullptr && cJSON_IsString(netmask)) {
309         std::string ipsecVpnNetmask = cJSON_GetStringValue(netmask);
310         iNetAddr.netMask_ = ipsecVpnNetmask;
311         destination.prefixlen_ = CommonUtils::GetMaskLength(ipsecVpnNetmask);
312     }
313 
314     cJSON *phyIfNameObj = cJSON_GetObjectItem(jConfig, IPSEC_NODE_PHY_NAME);
315     if (phyIfNameObj != nullptr && cJSON_IsString(phyIfNameObj)) {
316         std::string phyIfName = cJSON_GetStringValue(phyIfNameObj);
317         NETMGR_EXT_LOG_I("phyIfName:%{public}s", phyIfName.c_str());
318         NetsysController::GetInstance().ProcessVpnStage(SysVpnStageCode::VPN_STAGE_SET_XFRM_PHY_IFNAME, phyIfName);
319     }
320 
321     cJSON *dstIpObj = cJSON_GetObjectItem(jConfig, IPSEC_NODE_REMOTE_IP);
322     if (dstIpObj != nullptr && cJSON_IsString(dstIpObj)) {
323         std::string remoteIp = cJSON_GetStringValue(dstIpObj);
324         NetsysController::GetInstance().ProcessVpnStage(SysVpnStageCode::VPN_STAGE_SET_VPN_REMOTE_ADDRESS, remoteIp);
325     }
326     vpnConfig_->addresses_.emplace_back(iNetAddr);
327     ProcessDnsConfig(jConfig);
328 }
329 
ProcessDnsConfig(cJSON * jConfig)330 int32_t IpsecVpnCtl::ProcessDnsConfig(cJSON* jConfig)
331 {
332     if (vpnConfig_ == nullptr) {
333         NETMGR_EXT_LOG_E("ProcessDnsConfig vpnConfig_ is null");
334         return NETMANAGER_EXT_ERR_INTERNAL;
335     }
336 
337     for (auto it = vpnConfig_->dnsAddresses_.begin(); it != vpnConfig_->dnsAddresses_.end();) {
338         if (it->empty()) {
339             it = vpnConfig_->dnsAddresses_.erase(it);
340         } else {
341             ++it;
342         }
343     }
344     cJSON *primaryObj = cJSON_GetObjectItem(jConfig, PRIMARY_DNS);
345     if (primaryObj != nullptr && cJSON_IsString(primaryObj)) {
346         std::string dnsPrimary = cJSON_GetStringValue(primaryObj);
347         if (!dnsPrimary.empty()) {
348             vpnConfig_->dnsAddresses_.emplace_back(dnsPrimary);
349         }
350     }
351 
352     cJSON *secondaryObj = cJSON_GetObjectItem(jConfig, SECONDARY_DNS);
353     if (secondaryObj != nullptr && cJSON_IsString(secondaryObj)) {
354         std::string dnsSecondary = cJSON_GetStringValue(secondaryObj);
355         if (!dnsSecondary.empty()) {
356             vpnConfig_->dnsAddresses_.emplace_back(dnsSecondary);
357         }
358     }
359     return NETMANAGER_EXT_SUCCESS;
360 }
361 
ProcessSwanctlLoad()362 void IpsecVpnCtl::ProcessSwanctlLoad()
363 {
364     // 1. start strongswan
365     NETMGR_EXT_LOG_I("ipsec vpn setup step 1: start strongswan");
366     state_ = IpsecVpnStateCode::STATE_STARTED;
367     NetsysController::GetInstance().ProcessVpnStage(SysVpnStageCode::VPN_STAGE_SWANCTL_LOAD);
368 }
369 
ProcessIpsecUp()370 void IpsecVpnCtl::ProcessIpsecUp()
371 {
372     // 2. start connect
373     NETMGR_EXT_LOG_I("ipsec vpn setup step 2: start connect");
374     state_ = IpsecVpnStateCode::STATE_CONFIGED;
375     std::string baseConnectName = IPSEC_CONNECT_NAME;
376     std::string connectName = multiVpnInfo_ == nullptr ? baseConnectName :
377         baseConnectName + std::to_string(multiVpnInfo_->ifNameId);
378     NetsysController::GetInstance().ProcessVpnStage(
379         SysVpnStageCode::VPN_STAGE_UP_HOME, std::string(connectName));
380 }
381 
HandleConnected()382 void IpsecVpnCtl::HandleConnected()
383 {
384     // 3. is connected
385     NETMGR_EXT_LOG_I("ipsec vpn setup step 3: is connected");
386     state_ = IpsecVpnStateCode::STATE_CONNECTED;
387     NotifyConnectState(VpnConnectState::VPN_CONNECTED);
388 }
389 
HandleUpdateConfig(const std::string & config)390 int32_t IpsecVpnCtl::HandleUpdateConfig(const std::string &config)
391 {
392     if (UpdateConfig(config) != NETMANAGER_EXT_SUCCESS) {
393         NETMGR_EXT_LOG_I("ipsec vpn config update failed");
394         return NETMANAGER_EXT_ERR_INTERNAL;
395     }
396     if (SetUpVpnTun() != NETMANAGER_EXT_SUCCESS) {
397         NETMGR_EXT_LOG_I("set up l2tp vpn failed");
398         return NETMANAGER_EXT_ERR_INTERNAL;
399     }
400     return NETMANAGER_EXT_SUCCESS;
401 }
402 
HandleIpsecConnectFailed(const int32_t result)403 void IpsecVpnCtl::HandleIpsecConnectFailed(const int32_t result)
404 {
405     if (state_ == IpsecVpnStateCode::STATE_DISCONNECTED) {
406         NETMGR_EXT_LOG_I("ipsec already destroyed");
407         return;
408     }
409     if (multiVpnInfo_ != nullptr && ipsecVpnConfig_ != nullptr) {
410         VpnOperatorErrorType errorType;
411         switch (result) {
412             case VpnErrorCode::CONNECT_TIME_OUT:
413                 errorType = VpnOperatorErrorType::ERROR_PEER_NO_RESPONSE;
414                 break;
415             case VpnErrorCode::IKEV2_KEY_ERROR:
416                 errorType = VpnOperatorErrorType::ERROR_IKEV2_KEY_INCORRECT;
417                 break;
418             case VpnErrorCode::CA_ERROR:
419                 errorType = VpnOperatorErrorType::ERROR_CA_INCORRECT;
420                 break;
421             case VpnErrorCode::PASSWORD_ERROR:
422                 errorType = VpnOperatorErrorType::ERROR_PASSWORD_INCORRECT;
423                 break;
424             default:
425                 Destroy();
426                 return;
427         }
428         VpnHisysEvent::SetFaultVpnEvent(multiVpnInfo_->userId, multiVpnInfo_->bundleName,
429             VpnOperatorType::OPERATION_SETUP_VPN,
430             errorType, ipsecVpnConfig_->vpnType_);
431     }
432     Destroy();
433 }
434 } // namespace NetManagerStandard
435 } // namespace OHOS