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 
20 #include "base64_utils.h"
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 {
IpsecVpnCtl(sptr<VpnConfig> config, const std::string &pkg, int32_t userId, std::vector<int32_t> &activeUserIds)27 IpsecVpnCtl::IpsecVpnCtl(sptr<VpnConfig> config, const std::string &pkg, int32_t userId,
28     std::vector<int32_t> &activeUserIds)
29     : NetVpnImpl(config, pkg, userId, activeUserIds)
30 {}
31 
~IpsecVpnCtl()32 IpsecVpnCtl::~IpsecVpnCtl()
33 {
34     NETMGR_EXT_LOG_I("~IpsecVpnCtl");
35 }
36 
SetUp()37 int32_t IpsecVpnCtl::SetUp()
38 {
39     return StartSysVpn();
40 }
41 
Destroy()42 int32_t IpsecVpnCtl::Destroy()
43 {
44     return StopSysVpn();
45 }
46 
StopSysVpn()47 int32_t IpsecVpnCtl::StopSysVpn()
48 {
49     NETMGR_EXT_LOG_I("stop ipsec vpn");
50     state_ = IpsecVpnStateCode::STATE_DISCONNECTED;
51     NetsysController::GetInstance().ProcessVpnStage(SysVpnStageCode::VPN_STAGE_DOWN_HOME);
52     NetsysController::GetInstance().ProcessVpnStage(SysVpnStageCode::VPN_STAGE_STOP);
53     NotifyConnectState(VpnConnectState::VPN_DISCONNECTED);
54     return NETMANAGER_EXT_SUCCESS;
55 }
56 
StartSysVpn()57 int32_t IpsecVpnCtl::StartSysVpn()
58 {
59     NETMGR_EXT_LOG_I("start ipsec vpn");
60     state_ = IpsecVpnStateCode::STATE_INIT;
61     InitConfigFile();
62     NetsysController::GetInstance().ProcessVpnStage(SysVpnStageCode::VPN_STAGE_RESTART);
63     return NETMANAGER_EXT_SUCCESS;
64 }
65 
InitConfigFile()66 int32_t IpsecVpnCtl::InitConfigFile()
67 {
68     CleanTempFiles();
69     if (ipsecVpnConfig_ == nullptr) {
70         NETMGR_EXT_LOG_E("InitConfigFile ipsecVpnConfig is null");
71         return NETMANAGER_EXT_ERR_INTERNAL;
72     }
73 
74     if (!ipsecVpnConfig_->swanctlConf_.empty()) {
75         std::string swanctlCfg = Base64::Decode(ipsecVpnConfig_->swanctlConf_);
76         if (!swanctlCfg.empty()) {
77             CommonUtils::WriteFile(SWAN_CTL_FILE, swanctlCfg);
78         }
79     }
80     if (!ipsecVpnConfig_->strongswanConf_.empty()) {
81         std::string strongswanCfg = Base64::Decode(ipsecVpnConfig_->strongswanConf_);
82         if (!strongswanCfg.empty()) {
83             CommonUtils::WriteFile(SWAN_CONFIG_FILE, strongswanCfg);
84         }
85     }
86     return NETMANAGER_EXT_SUCCESS;
87 }
88 
CleanTempFiles()89 void IpsecVpnCtl::CleanTempFiles()
90 {
91     DeleteTempFile(SWAN_CTL_FILE);
92     DeleteTempFile(SWAN_CONFIG_FILE);
93     DeleteTempFile(L2TP_CFG);
94     DeleteTempFile(L2TP_IPSEC_CFG);
95     DeleteTempFile(L2TP_IPSEC_SECRETS_CFG);
96     DeleteTempFile(OPTIONS_L2TP_CLIENT);
97 }
98 
DeleteTempFile(const std::string &fileName)99 void IpsecVpnCtl::DeleteTempFile(const std::string &fileName)
100 {
101     if (std::filesystem::exists(fileName)) {
102         if (!std::filesystem::remove(fileName)) {
103             NETMGR_EXT_LOG_E("remove old cache file failed");
104         }
105     }
106 }
107 
NotifyConnectStage(const std::string &stage, const int32_t &result)108 int32_t IpsecVpnCtl::NotifyConnectStage(const std::string &stage, const int32_t &result)
109 {
110     if (stage.empty()) {
111         NETMGR_EXT_LOG_E("stage is empty");
112         return NETMANAGER_EXT_ERR_PARAMETER_ERROR;
113     }
114     if (result != NETMANAGER_EXT_SUCCESS) {
115         NETMGR_EXT_LOG_E("vpn stage: %{public}s failed, result: %{public}d", stage.c_str(), result);
116         return NETMANAGER_EXT_ERR_INTERNAL;
117     }
118     switch (state_) {
119         case IpsecVpnStateCode::STATE_INIT:
120             if (stage.compare(IPSEC_START_TAG) == 0) {
121                 // 1. start strongswan
122                 NETMGR_EXT_LOG_I("ipsec vpn setup step 1: start strongswan");
123                 state_ = IpsecVpnStateCode::STATE_STARTED;
124                 NetsysController::GetInstance().ProcessVpnStage(SysVpnStageCode::VPN_STAGE_SWANCTL_LOAD);
125             }
126             break;
127         case IpsecVpnStateCode::STATE_STARTED:
128             if (stage.compare(SWANCTL_START_TAG) == 0) {
129                 // 2. start connect
130                 NETMGR_EXT_LOG_I("ipsec vpn setup step 2: start connect");
131                 state_ = IpsecVpnStateCode::STATE_CONFIGED;
132                 NetsysController::GetInstance().ProcessVpnStage(SysVpnStageCode::VPN_STAGE_UP_HOME);
133             }
134             break;
135         case IpsecVpnStateCode::STATE_CONFIGED:
136             if (stage.compare(IPSEC_CONNECT_TAG) == 0) {
137                 // 3. is connected
138                 NETMGR_EXT_LOG_I("ipsec vpn setup step 3: is connected");
139                 state_ = IpsecVpnStateCode::STATE_CONNECTED;
140                 NotifyConnectState(VpnConnectState::VPN_CONNECTED);
141             }
142             break;
143         default:
144             NETMGR_EXT_LOG_E("invalid state: %{public}d", state_);
145             return NETMANAGER_EXT_ERR_INTERNAL;
146     }
147     return NETMANAGER_EXT_SUCCESS;
148 }
149 
GetSysVpnCertUri(const int32_t certType, std::string &certUri)150 int32_t IpsecVpnCtl::GetSysVpnCertUri(const int32_t certType, std::string &certUri)
151 {
152     if (ipsecVpnConfig_ == nullptr) {
153         NETMGR_EXT_LOG_E("GetSysVpnCertUri ipsecVpnConfig is null");
154         return NETMANAGER_EXT_ERR_INTERNAL;
155     }
156     switch (certType) {
157         case IpsecVpnCertType::CA_CERT:
158             certUri = ipsecVpnConfig_->ipsecCaCertConf_;
159             break;
160         case IpsecVpnCertType::USER_CERT:
161             certUri = ipsecVpnConfig_->ipsecPublicUserCertConf_;
162             break;
163         case IpsecVpnCertType::SERVER_CERT:
164             certUri = ipsecVpnConfig_->ipsecPublicServerCertConf_;
165             break;
166         default:
167             NETMGR_EXT_LOG_E("invalid certType: %{public}d", certType);
168             break;
169     }
170     return NETMANAGER_EXT_SUCCESS;
171 }
172 
GetConnectedSysVpnConfig(sptr<SysVpnConfig> &sysVpnConfig)173 int32_t IpsecVpnCtl::GetConnectedSysVpnConfig(sptr<SysVpnConfig> &sysVpnConfig)
174 {
175     if (state_ == IpsecVpnStateCode::STATE_CONNECTED && ipsecVpnConfig_ != nullptr) {
176         NETMGR_EXT_LOG_I("GetConnectedSysVpnConfig success");
177         sysVpnConfig = ipsecVpnConfig_;
178     }
179     return NETMANAGER_EXT_SUCCESS;
180 }
181 
IsInternalVpn()182 bool IpsecVpnCtl::IsInternalVpn()
183 {
184     return true;
185 }
186 } // namespace NetManagerStandard
187 } // namespace OHOS