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 "l2tp_vpn_ctl.h"
17
18 #include <string>
19 #include <sys/stat.h>
20
21 #include "netmgr_ext_log_wrapper.h"
22 #include "netmanager_base_common_utils.h"
23 #include "net_manager_ext_constants.h"
24
25 namespace OHOS {
26 namespace NetManagerStandard {
L2tpVpnCtl(sptr<VpnConfig> config,const std::string & pkg,int32_t userId,std::vector<int32_t> & activeUserIds)27 L2tpVpnCtl::L2tpVpnCtl(sptr<VpnConfig> config, const std::string &pkg, int32_t userId,
28 std::vector<int32_t> &activeUserIds)
29 : IpsecVpnCtl(config, pkg, userId, activeUserIds)
30 {}
31
StopSysVpn()32 int32_t L2tpVpnCtl::StopSysVpn()
33 {
34 NETMGR_EXT_LOG_I("stop l2tp vpn");
35 state_ = IpsecVpnStateCode::STATE_DISCONNECTED;
36 std::string connectName = L2TP_CONNECT_NAME;
37 std::string ipsecName = IPSEC_CONNECT_NAME;
38 if (multiVpnInfo_ != nullptr) {
39 int32_t id = multiVpnInfo_->ifNameId;
40 connectName = connectName + std::to_string(id);
41 ipsecName = ipsecName + std::to_string(id);
42 }
43 if (l2tpVpnConfig_ != nullptr && l2tpVpnConfig_->vpnType_ != VpnType::L2TP) {
44 NetsysController::GetInstance().ProcessVpnStage(
45 SysVpnStageCode::VPN_STAGE_DOWN_HOME, ipsecName);
46 MultiVpnHelper::GetInstance().StopIpsec();
47 }
48 NetsysController::GetInstance().ProcessVpnStage(SysVpnStageCode::VPN_STAGE_L2TP_STOP, connectName);
49 MultiVpnHelper::GetInstance().StopL2tp();
50 NotifyConnectState(VpnConnectState::VPN_DISCONNECTED);
51 return NETMANAGER_EXT_SUCCESS;
52 }
53
StartSysVpn()54 int32_t L2tpVpnCtl::StartSysVpn()
55 {
56 NETMGR_EXT_LOG_I("start l2tp vpn");
57 state_ = IpsecVpnStateCode::STATE_INIT;
58 InitConfigFile();
59 if (multiVpnInfo_ != nullptr) {
60 NetsysController::GetInstance().ProcessVpnStage(
61 SysVpnStageCode::VPN_STAGE_CREATE_PPP_FD, multiVpnInfo_->ifName);
62 }
63 if (l2tpVpnConfig_ != nullptr && l2tpVpnConfig_->vpnType_ == VpnType::L2TP) {
64 state_ = IpsecVpnStateCode::STATE_CONFIGED;
65 if (!MultiVpnHelper::GetInstance().StartL2tp()) {
66 AddConfigToL2tpdConf();
67 }
68 } else {
69 if (!MultiVpnHelper::GetInstance().StartIpsec()) {
70 state_ = IpsecVpnStateCode::STATE_STARTED;
71 NetsysController::GetInstance().ProcessVpnStage(SysVpnStageCode::VPN_STAGE_SWANCTL_LOAD);
72 }
73 }
74 return NETMANAGER_EXT_SUCCESS;
75 }
76
InitConfigFile()77 int32_t L2tpVpnCtl::InitConfigFile()
78 {
79 CleanTempFiles();
80 if (l2tpVpnConfig_ == nullptr) {
81 NETMGR_EXT_LOG_E("InitConfigFile failed, l2tpVpnConfig_ is null");
82 return NETMANAGER_EXT_ERR_INTERNAL;
83 }
84 if (!l2tpVpnConfig_->strongswanConf_.empty()) {
85 CommonUtils::WriteFile(SWAN_CONFIG_FILE, l2tpVpnConfig_->strongswanConf_);
86 chmod(SWAN_CONFIG_FILE, S_IRUSR | S_IWUSR | S_IRGRP);
87 }
88 if (!l2tpVpnConfig_->xl2tpdConf_.empty()) {
89 CommonUtils::WriteFile(L2TP_CFG, l2tpVpnConfig_->xl2tpdConf_);
90 chmod(L2TP_CFG, S_IRUSR | S_IWUSR | S_IRGRP);
91 }
92 return NETMANAGER_EXT_SUCCESS;
93 }
94
NotifyConnectStage(const std::string & stage,const int32_t & result)95 int32_t L2tpVpnCtl::NotifyConnectStage(const std::string &stage, const int32_t &result)
96 {
97 if (stage.empty()) {
98 NETMGR_EXT_LOG_E("stage is empty");
99 return NETMANAGER_EXT_ERR_PARAMETER_ERROR;
100 }
101 if (result != NETMANAGER_EXT_SUCCESS) {
102 NETMGR_EXT_LOG_E("l2tp vpn connect failed");
103 HandleConnectFailed(result);
104 return NETMANAGER_EXT_ERR_INTERNAL;
105 }
106 switch (state_) {
107 case IpsecVpnStateCode::STATE_INIT:
108 if (stage.compare(IPSEC_START_TAG) == 0) {
109 HandleIpdecStarted();
110 }
111 break;
112 case IpsecVpnStateCode::STATE_STARTED:
113 if (stage.compare(SWANCTL_START_TAG) == 0) {
114 HandleSwanCtlLoaded();
115 }
116 break;
117 case IpsecVpnStateCode::STATE_CONFIGED:
118 if (stage.compare(L2TP_IPSEC_CONFIGURED_TAG) == 0) {
119 HandleL2tpConfiged();
120 }
121 break;
122 case IpsecVpnStateCode::STATE_L2TP_STARTED:
123 if (stage.compare(IPSEC_CONNECT_TAG) == 0) {
124 HandleL2tpdCtl();
125 }
126 break;
127 case IpsecVpnStateCode::STATE_CONTROLLED:
128 if (stage.compare(L2TP_IPSEC_CONNECTED_TAG) == 0) {
129 HandleL2tpConnected();
130 }
131 break;
132 case IpsecVpnStateCode::STATE_CONNECTED:
133 if (stage.find(IPSEC_NODE_UPDATE_CONFIG) != std::string::npos) {
134 if (ProcessUpdateConfig(stage) != NETMANAGER_EXT_SUCCESS) {
135 return NETMANAGER_EXT_ERR_INTERNAL;
136 }
137 }
138 break;
139 default:
140 NETMGR_EXT_LOG_E("invalid state: %{public}d", state_);
141 return NETMANAGER_EXT_ERR_INTERNAL;
142 }
143 return NETMANAGER_EXT_SUCCESS;
144 }
145
GetSysVpnCertUri(const int32_t certType,std::string & certUri)146 int32_t L2tpVpnCtl::GetSysVpnCertUri(const int32_t certType, std::string &certUri)
147 {
148 if (l2tpVpnConfig_ == nullptr) {
149 NETMGR_EXT_LOG_E("GetSysVpnCertUri l2tpVpnConfig_ is null");
150 return NETMANAGER_EXT_ERR_INTERNAL;
151 }
152 switch (certType) {
153 case IpsecVpnCertType::CA_CERT:
154 certUri = l2tpVpnConfig_->ipsecCaCertConf_;
155 break;
156 case IpsecVpnCertType::USER_CERT:
157 certUri = l2tpVpnConfig_->ipsecPublicUserCertConf_;
158 break;
159 case IpsecVpnCertType::SERVER_CERT:
160 certUri = l2tpVpnConfig_->ipsecPublicServerCertConf_;
161 break;
162 case IpsecVpnCertType::OPTIONS_L2TP_CLIENT_CONF:
163 certUri = l2tpVpnConfig_->optionsL2tpdClient_;
164 break;
165 case IpsecVpnCertType::L2TP_IPSEC_SECRETS_CONF:
166 certUri = l2tpVpnConfig_->ipsecSecrets_;
167 break;
168 case IpsecVpnCertType::SWAN_CTL_CONF:
169 certUri = l2tpVpnConfig_->ipsecConf_;
170 break;
171 default:
172 NETMGR_EXT_LOG_E("invalid certType: %{public}d", certType);
173 break;
174 }
175 return NETMANAGER_EXT_SUCCESS;
176 }
177
GetVpnCertData(const int32_t certType,std::vector<int8_t> & certData)178 int32_t L2tpVpnCtl::GetVpnCertData(const int32_t certType, std::vector<int8_t> &certData)
179 {
180 if (l2tpVpnConfig_ == nullptr) {
181 NETMGR_EXT_LOG_E("GetVpnCertData ipsecVpnConfig is null");
182 return NETMANAGER_EXT_ERR_INTERNAL;
183 }
184 switch (certType) {
185 case IpsecVpnCertType::PKCS12_PASSWD: {
186 if (!l2tpVpnConfig_->pkcs12Password_.empty()) {
187 certData.assign(l2tpVpnConfig_->pkcs12Password_.begin(),
188 l2tpVpnConfig_->pkcs12Password_.end());
189 } else {
190 NETMGR_EXT_LOG_D("GetVpnCertData pkcs12 password is empty");
191 }
192 break;
193 }
194 case IpsecVpnCertType::PKCS12_DATA: {
195 if (!l2tpVpnConfig_->pkcs12FileData_.empty()) {
196 certData.assign(l2tpVpnConfig_->pkcs12FileData_.begin(),
197 l2tpVpnConfig_->pkcs12FileData_.end());
198 } else {
199 NETMGR_EXT_LOG_D("GetVpnCertData pkcs12 data is empty");
200 }
201 break;
202 }
203 default:
204 NETMGR_EXT_LOG_E("invalid certType: %{public}d", certType);
205 break;
206 }
207 return NETMANAGER_EXT_SUCCESS;
208 }
209
GetConnectedSysVpnConfig(sptr<SysVpnConfig> & sysVpnConfig)210 int32_t L2tpVpnCtl::GetConnectedSysVpnConfig(sptr<SysVpnConfig> &sysVpnConfig)
211 {
212 if (state_ == IpsecVpnStateCode::STATE_CONNECTED && l2tpVpnConfig_ != nullptr) {
213 NETMGR_EXT_LOG_I("GetConnectedSysVpnConfig success");
214 sysVpnConfig = l2tpVpnConfig_;
215 }
216 return NETMANAGER_EXT_SUCCESS;
217 }
218
GetXl2tpdConfig()219 std::string L2tpVpnCtl::GetXl2tpdConfig()
220 {
221 std::string templateContent;
222 if (l2tpVpnConfig_ != nullptr && multiVpnInfo_ != nullptr && !l2tpVpnConfig_->addresses_.empty()) {
223 templateContent.append(VPN_NAME_KEY).append(std::to_string(multiVpnInfo_->ifNameId))
224 .append(SINGLE_XL2TP_CONFIG_LNS).append(l2tpVpnConfig_->addresses_[0].address_)
225 .append(SINGLE_XL2TP_CONFIG_PPP).append(VPN_CLIENT_CONFIG_NAME_KEY)
226 .append(std::to_string(multiVpnInfo_->ifNameId))
227 .append(SINGLE_XL2TP_CONFIG_LENGTH);
228 }
229 templateContent = "\"" + templateContent + "\"";
230 return templateContent;
231 }
232
AddConfigToL2tpdConf()233 void L2tpVpnCtl::AddConfigToL2tpdConf()
234 {
235 std::string tempConfig = GetXl2tpdConfig();
236 NetsysController::GetInstance().ProcessVpnStage(SysVpnStageCode::VPN_STAGE_SET_L2TP_CONF, tempConfig);
237 }
238
HandleIpdecStarted()239 void L2tpVpnCtl::HandleIpdecStarted()
240 {
241 NETMGR_EXT_LOG_I("1:ipsec started, process load swanctl config");
242 state_ = IpsecVpnStateCode::STATE_STARTED;
243 NetsysController::GetInstance().ProcessVpnStage(SysVpnStageCode::VPN_STAGE_SWANCTL_LOAD);
244 }
245
HandleSwanCtlLoaded()246 void L2tpVpnCtl::HandleSwanCtlLoaded()
247 {
248 NETMGR_EXT_LOG_I("2:swanctl loaded, process start l2tp or add l2tp config");
249 state_ = IpsecVpnStateCode::STATE_CONFIGED;
250 if (!MultiVpnHelper::GetInstance().StartL2tp()) {
251 AddConfigToL2tpdConf();
252 }
253 }
254
HandleL2tpConfiged()255 void L2tpVpnCtl::HandleL2tpConfiged()
256 {
257 NETMGR_EXT_LOG_I("3:l2tpd started or configed, process ipsec up");
258 if (l2tpVpnConfig_->vpnType_ == VpnType::L2TP) {
259 state_ = IpsecVpnStateCode::STATE_CONTROLLED;
260 if (multiVpnInfo_ != nullptr) {
261 NetsysController::GetInstance().ProcessVpnStage(SysVpnStageCode::VPN_STAGE_L2TP_CTL,
262 std::string(L2TP_CONNECT_NAME) + std::to_string(multiVpnInfo_->ifNameId));
263 } else {
264 NetsysController::GetInstance().ProcessVpnStage(SysVpnStageCode::VPN_STAGE_L2TP_CTL);
265 }
266 } else {
267 state_ = IpsecVpnStateCode::STATE_L2TP_STARTED;
268 std::string baseConnectName = IPSEC_CONNECT_NAME;
269 std::string connectName = multiVpnInfo_ == nullptr ? baseConnectName :
270 baseConnectName + std::to_string(multiVpnInfo_->ifNameId);
271 NetsysController::GetInstance().ProcessVpnStage(
272 SysVpnStageCode::VPN_STAGE_UP_HOME, connectName);
273 }
274 }
275
HandleL2tpdCtl()276 void L2tpVpnCtl::HandleL2tpdCtl()
277 {
278 NETMGR_EXT_LOG_I("4:set stage IPSEC_L2TP_CTL, process echo c");
279 state_ = IpsecVpnStateCode::STATE_CONTROLLED;
280 if (multiVpnInfo_ != nullptr) {
281 NetsysController::GetInstance().ProcessVpnStage(SysVpnStageCode::VPN_STAGE_L2TP_CTL,
282 std::string(L2TP_CONNECT_NAME) + std::to_string(multiVpnInfo_->ifNameId));
283 } else {
284 NetsysController::GetInstance().ProcessVpnStage(SysVpnStageCode::VPN_STAGE_L2TP_CTL);
285 }
286 }
287
HandleL2tpConnected()288 void L2tpVpnCtl::HandleL2tpConnected()
289 {
290 NETMGR_EXT_LOG_I("5:l2tp vpn is connected");
291 state_ = IpsecVpnStateCode::STATE_CONNECTED;
292 NotifyConnectState(VpnConnectState::VPN_CONNECTED);
293 }
294
ProcessUpdateConfig(const std::string & config)295 int32_t L2tpVpnCtl::ProcessUpdateConfig(const std::string &config)
296 {
297 NETMGR_EXT_LOG_I("6:l2tp vpn config update");
298 if (UpdateConfig(config) != NETMANAGER_EXT_SUCCESS) {
299 NETMGR_EXT_LOG_I("l2tp vpn config update failed");
300 return NETMANAGER_EXT_ERR_INTERNAL;
301 }
302 if (SetUpVpnTun() != NETMANAGER_EXT_SUCCESS) {
303 NETMGR_EXT_LOG_I("set up l2tp vpn failed");
304 return NETMANAGER_EXT_ERR_INTERNAL;
305 }
306 return NETMANAGER_EXT_SUCCESS;
307 }
308
HandleConnectFailed(const int32_t result)309 void L2tpVpnCtl::HandleConnectFailed(const int32_t result)
310 {
311 if (state_ == IpsecVpnStateCode::STATE_DISCONNECTED) {
312 NETMGR_EXT_LOG_I("l2tp already destroyed");
313 return;
314 }
315 if (multiVpnInfo_ != nullptr && l2tpVpnConfig_ != nullptr) {
316 VpnOperatorErrorType errorType;
317 switch (result) {
318 case VpnErrorCode::CONNECT_TIME_OUT:
319 errorType = VpnOperatorErrorType::ERROR_PEER_NO_RESPONSE;
320 break;
321 case VpnErrorCode::PASSWORD_ERROR:
322 errorType = VpnOperatorErrorType::ERROR_PASSWORD_INCORRECT;
323 break;
324 case VpnErrorCode::IKEV1_KEY_ERROR:
325 errorType = VpnOperatorErrorType::ERROR_IKEV1_KEY_INCORRECT;
326 break;
327 default:
328 Destroy();
329 return;
330 }
331 VpnHisysEvent::SetFaultVpnEvent(multiVpnInfo_->userId, multiVpnInfo_->bundleName,
332 VpnOperatorType::OPERATION_SETUP_VPN,
333 errorType, l2tpVpnConfig_->vpnType_);
334 }
335 Destroy();
336 }
337 } // namespace NetManagerStandard
338 } // namespace OHOS
339