1 /*
2 * Copyright (c) 2025 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 #include "vpn_template_processor.h"
16 #include "net_manager_constants.h"
17 #include "netmgr_ext_log_wrapper.h"
18 #include "ipsec_vpn_ctl.h"
19 #include "netmanager_base_common_utils.h"
20
21 namespace OHOS {
22 namespace NetManagerStandard {
23 constexpr const char *MULTI_TUN_CARD_NAME = "multitun-vpn";
24 constexpr const char* STRONGSWAN_CONF_TEMPCONFIG = R"(charon {
25 i_dont_care_about_security_and_use_aggressive_mode_psk = yes
26 install_virtual_ip = no
27 plugins {
28 include /system/etc/strongswan/strongswan.d/charon/*.conf
29 kernel-libipsec {
30 load = no
31 }
32 kernel-netlink {
33 load = yes
34 }
35 }
36 }
37 include /system/etc/strongswan/strongswan.d/*.conf)";
38
BuildConfig(std::shared_ptr<NetVpnImpl> & vpnObj,std::map<std::string,std::shared_ptr<NetVpnImpl>> & vpnObjMap)39 int32_t VpnTemplateProcessor::BuildConfig(std::shared_ptr<NetVpnImpl> &vpnObj,
40 std::map<std::string, std::shared_ptr<NetVpnImpl>> &vpnObjMap)
41 {
42 if (vpnObj == nullptr) {
43 NETMGR_EXT_LOG_E("invalid vpnObj");
44 return NETMANAGER_EXT_ERR_INTERNAL;
45 }
46 std::shared_ptr<IpsecVpnCtl> sysVpnObj = std::static_pointer_cast<IpsecVpnCtl>(vpnObj);
47 if (sysVpnObj == nullptr || sysVpnObj->multiVpnInfo_ == nullptr) {
48 NETMGR_EXT_LOG_E("invalid sysVpnObj");
49 return NETMANAGER_EXT_ERR_INTERNAL;
50 }
51 int32_t ifNameId = sysVpnObj->multiVpnInfo_->ifNameId;
52 GenSwanctlOrIpsecConf(sysVpnObj->ipsecVpnConfig_, sysVpnObj->l2tpVpnConfig_, ifNameId, vpnObjMap);
53 if (sysVpnObj->ipsecVpnConfig_ != nullptr) {
54 sysVpnObj->ipsecVpnConfig_->strongswanConf_ = STRONGSWAN_CONF_TEMPCONFIG;
55 } else if (sysVpnObj->l2tpVpnConfig_ != nullptr) {
56 GenOptionsL2tpdClient(sysVpnObj->l2tpVpnConfig_);
57 GenXl2tpdConf(sysVpnObj->l2tpVpnConfig_, ifNameId, vpnObjMap);
58 GenIpsecSecrets(sysVpnObj->l2tpVpnConfig_);
59 sysVpnObj->l2tpVpnConfig_->strongswanConf_ = STRONGSWAN_CONF_TEMPCONFIG;
60 } else {
61 NETMGR_EXT_LOG_W("invalid config");
62 }
63 return NETMANAGER_EXT_SUCCESS;
64 }
65
GenSwanctlOrIpsecConf(sptr<IpsecVpnConfig> & ipsecConfig,sptr<L2tpVpnConfig> & l2tpConfig,int32_t ifNameId,std::map<std::string,std::shared_ptr<NetVpnImpl>> & vpnObjMap)66 void VpnTemplateProcessor::GenSwanctlOrIpsecConf(sptr<IpsecVpnConfig> &ipsecConfig, sptr<L2tpVpnConfig> &l2tpConfig,
67 int32_t ifNameId, std::map<std::string, std::shared_ptr<NetVpnImpl>> &vpnObjMap)
68 {
69 if (ipsecConfig == nullptr && l2tpConfig == nullptr) {
70 NETMGR_EXT_LOG_W("invalid config");
71 return;
72 }
73 std::string connects;
74 std::string secrets;
75 for (const auto& pair : vpnObjMap) {
76 if (pair.second == nullptr || pair.second->multiVpnInfo_ == nullptr) {
77 continue;
78 }
79 if (strstr(pair.second->multiVpnInfo_->ifName.c_str(), MULTI_TUN_CARD_NAME) != NULL) {
80 continue;
81 }
82 std::shared_ptr<IpsecVpnCtl> vpnObj = std::static_pointer_cast<IpsecVpnCtl>(pair.second);
83 if (vpnObj != nullptr && vpnObj->multiVpnInfo_ != nullptr) {
84 CreateConnectAndSecret(vpnObj->ipsecVpnConfig_, vpnObj->l2tpVpnConfig_,
85 vpnObj->multiVpnInfo_->ifNameId, connects, secrets);
86 }
87 }
88 CreateConnectAndSecret(ipsecConfig, l2tpConfig, ifNameId, connects, secrets);
89 std::string conf = "connections {\n" + connects + "\n}\nsecrets {\n" + secrets + "\n}";
90 if (ipsecConfig != nullptr) {
91 ipsecConfig->swanctlConf_ = conf;
92 }
93 if (l2tpConfig != nullptr) {
94 l2tpConfig->ipsecConf_ = conf;
95 }
96 }
97
GenXl2tpdConf(sptr<L2tpVpnConfig> & config,int32_t ifNameId,std::map<std::string,std::shared_ptr<NetVpnImpl>> & vpnObjMap)98 void VpnTemplateProcessor::GenXl2tpdConf(sptr<L2tpVpnConfig> &config, int32_t ifNameId,
99 std::map<std::string, std::shared_ptr<NetVpnImpl>> &vpnObjMap)
100 {
101 if (config == nullptr) {
102 NETMGR_EXT_LOG_W("invalid config");
103 return;
104 }
105 std::string conf;
106 for (const auto& pair : vpnObjMap) {
107 if (pair.second == nullptr || pair.second->multiVpnInfo_ == nullptr) {
108 continue;
109 }
110 if (strstr(pair.second->multiVpnInfo_->ifName.c_str(), MULTI_TUN_CARD_NAME) != NULL) {
111 continue;
112 }
113 std::shared_ptr<IpsecVpnCtl> vpnObj = std::static_pointer_cast<IpsecVpnCtl>(pair.second);
114 if (vpnObj != nullptr && vpnObj->multiVpnInfo_ != nullptr) {
115 CreateXl2tpdConf(vpnObj->l2tpVpnConfig_, vpnObj->multiVpnInfo_->ifNameId, conf);
116 }
117 }
118 CreateXl2tpdConf(config, ifNameId, conf);
119 config->xl2tpdConf_ = conf;
120 }
121
GenOptionsL2tpdClient(sptr<L2tpVpnConfig> & config)122 void VpnTemplateProcessor::GenOptionsL2tpdClient(sptr<L2tpVpnConfig> &config)
123 {
124 if (config == nullptr) {
125 NETMGR_EXT_LOG_W("invalid config");
126 return;
127 }
128 int32_t configType = config->vpnType_;
129 if (configType == VpnType::L2TP_IPSEC_PSK || configType == VpnType::L2TP_IPSEC_RSA
130 || configType == VpnType::L2TP) {
131 std::ostringstream oss;
132 oss << "ipcp-accept-local\nipcp-accept-remote\nrefuse-eap\nrequire-mschap-v2\n";
133 oss << "noccp\nnoauth\nidle 1800\nmtu 1410\nmru 1410\n";
134 oss << "defaultroute\nusepeerdns\ndebug\nconnect-delay 3000\n";
135 oss << "name " << config->userName_ << " \npassword " << config->password_;
136 config->optionsL2tpdClient_ = oss.str();
137 }
138 }
139
GenIpsecSecrets(sptr<L2tpVpnConfig> & config)140 void VpnTemplateProcessor::GenIpsecSecrets(sptr<L2tpVpnConfig> &config)
141 {
142 if (config != nullptr && config->vpnType_ == VpnType::L2TP_IPSEC_PSK) {
143 config->ipsecSecrets_ = ": PSK " + config->ipsecPreSharedKey_;
144 }
145 }
146
CreateXl2tpdConf(sptr<L2tpVpnConfig> & config,int32_t ifNameId,std::string & outConf)147 void VpnTemplateProcessor::CreateXl2tpdConf(sptr<L2tpVpnConfig> &config, int32_t ifNameId, std::string &outConf)
148 {
149 if (config == nullptr || config->addresses_.empty()) {
150 NETMGR_EXT_LOG_W("invalid config");
151 return;
152 }
153 std::ostringstream oss;
154 oss << "[lac l2tp" << ifNameId << "]" << std::endl;
155 oss << "lns = " << config->addresses_[0].address_ << std::endl;
156 oss << "ppp debug = yes" << std::endl;
157 oss << "pppoptfile = options.l2tpd.client.conf-" << ifNameId << std::endl;
158 oss << "length bit = yes" << std::endl;
159 outConf.append(oss.str());
160 }
161
GetSecret(sptr<IpsecVpnConfig> & ipsecConfig,int32_t ifNameId,std::string & outSecret)162 void VpnTemplateProcessor::GetSecret(sptr<IpsecVpnConfig> &ipsecConfig, int32_t ifNameId, std::string &outSecret)
163 {
164 if (ipsecConfig == nullptr) {
165 NETMGR_EXT_LOG_W("invalid config");
166 return;
167 }
168 std::string homeElement = "home" + std::to_string(ifNameId);
169 std::string ipsecId = ipsecConfig->ipsecIdentifier_.empty() ? "%any" : ipsecConfig->ipsecIdentifier_;
170 std::ostringstream oss;
171 switch (ipsecConfig->vpnType_) {
172 case VpnType::IKEV2_IPSEC_MSCHAPv2: {
173 oss << "eap-" << homeElement << " {\nid = " << ipsecConfig->userName_;
174 oss << "\nsecret = " << ipsecConfig->password_ << "\n}\n";
175 break;
176 }
177 case VpnType::IKEV2_IPSEC_PSK: {
178 oss << "ike-" << homeElement << " {\nid = " << ipsecId;
179 oss << "\nsecret = " << ipsecConfig->ipsecPreSharedKey_ << "\n}\n";
180 break;
181 }
182 case VpnType::IPSEC_XAUTH_PSK: {
183 oss << "ike-" << homeElement << " {\nid = " << ipsecId;
184 oss << "\nsecret = " << ipsecConfig->ipsecPreSharedKey_ << "\n}\n";
185 oss << "xauth-" << homeElement << " {\nid = " << ipsecConfig->userName_;
186 oss << "\nsecret = " << ipsecConfig->password_ << "\n}\n";
187 break;
188 }
189 case VpnType::IPSEC_XAUTH_RSA:
190 case VpnType::IPSEC_HYBRID_RSA: {
191 oss << "xauth-" << homeElement << " {id = " << ipsecConfig->userName_;
192 oss << "\nsecret = " << ipsecConfig->password_ << "\n}\n";
193 break;
194 }
195 default:
196 break;
197 }
198 outSecret.append(oss.str());
199 }
200
GetConnect(sptr<IpsecVpnConfig> & ipsecConfig,int32_t ifNameId,std::string & outConnect)201 void VpnTemplateProcessor::GetConnect(sptr<IpsecVpnConfig> &ipsecConfig, int32_t ifNameId, std::string &outConnect)
202 {
203 if (ipsecConfig == nullptr || ipsecConfig->addresses_.empty()) {
204 NETMGR_EXT_LOG_W("invalid config");
205 return;
206 }
207 std::string homeElement = "home" + std::to_string(ifNameId);
208 std::string ipsecId = ipsecConfig->ipsecIdentifier_.empty() ? "%any" : ipsecConfig->ipsecIdentifier_;
209 std::string children = "children {\n home {\n if_id_in=" + std::to_string(ifNameId) + "\n if_id_out="
210 + std::to_string(ifNameId) + "\nremote_ts=0.0.0.0/0\n esp_proposals = default\n}\n}";
211 outConnect = homeElement + " {\n remote_addrs = " + ipsecConfig->addresses_[0].address_ + "\n vips = 0.0.0.0\n";
212 std::ostringstream oss;
213 switch (ipsecConfig->vpnType_) {
214 case VpnType::IKEV2_IPSEC_MSCHAPv2:
215 oss << "local {\n auth = eap-mschapv2\n eap_id = " << ipsecConfig->userName_ << "\n}\n";
216 oss << "remote {\n auth = pubkey\n}\n" << children << "\nversion = 2\n proposals = default\n}\n";
217 break;
218 case VpnType::IKEV2_IPSEC_PSK:
219 oss << "local {\n auth = psk\n}\n remote {\n auth = psk\n id = " << ipsecId << "\n}\n";
220 oss << children << "\nversion = 2\n proposals = default\n}\n";
221 break;
222 case VpnType::IKEV2_IPSEC_RSA:
223 oss << "local {\n auth = pubkey\n id = " << ipsecId << "\n}\n";
224 oss << "remote {\n auth = pubkey\n}\n" << children << "\nversion = 2\n proposals = default\n}\n";
225 break;
226 case VpnType::IPSEC_XAUTH_PSK:
227 oss << "local {\n auth = psk\n id = " << ipsecId << "\n}\n";
228 oss << "local-xauth {\n auth = xauth\n xauth_id = " << ipsecConfig->userName_ << "\n}\n";
229 oss << "remote {\n auth = psk\n id = " << ipsecId << "\n}\n";
230 oss << children << "\n version = 1\n proposals = default\n aggressive=yes\n}\n";
231 break;
232 case VpnType::IPSEC_XAUTH_RSA:
233 oss << "local {\n auth = pubkey\n id = " << ipsecConfig->userName_ << "\n}\n";
234 oss << "local-xauth {\n auth = xauth\n}\n remote {\n auth = pubkey\n}\n";
235 oss << "children {\n home {\n remote_ts=0.0.0.0/0\n esp_proposals = default\n}\n}\n";
236 oss << "version = 1\n proposals = default\n}\n";
237 break;
238 case VpnType::IPSEC_HYBRID_RSA:
239 oss << "local {\n auth = xauth\n xauth_id = " << ipsecConfig->userName_ << "\n}\n";
240 oss << "remote {\n auth = pubkey\n}\n";
241 oss << children << "\n version = 1\n proposals = default\n}\n";
242 break;
243 default:
244 break;
245 }
246 outConnect.append(oss.str());
247 }
248
CreateConnectAndSecret(sptr<IpsecVpnConfig> & ipsecConfig,sptr<L2tpVpnConfig> & l2tpConfig,int32_t ifNameId,std::string & outConnect,std::string & outSecret)249 void VpnTemplateProcessor::CreateConnectAndSecret(sptr<IpsecVpnConfig> &ipsecConfig, sptr<L2tpVpnConfig> &l2tpConfig,
250 int32_t ifNameId, std::string &outConnect, std::string &outSecret)
251 {
252 if (ipsecConfig == nullptr && l2tpConfig == nullptr) {
253 NETMGR_EXT_LOG_W("invalid config");
254 return;
255 }
256 std::string connect;
257 std::string secret;
258 if (l2tpConfig != nullptr) {
259 if (l2tpConfig->vpnType_ == L2TP) {
260 return;
261 }
262 std::string homeElement = "home" + std::to_string(ifNameId);
263 std::string address = !l2tpConfig->addresses_.empty() ? l2tpConfig->addresses_[0].address_ : "";
264 std::string localId = !l2tpConfig->ipsecIdentifier_.empty() ? l2tpConfig->ipsecIdentifier_ :
265 (l2tpConfig->vpnType_ == L2TP_IPSEC_PSK) ? homeElement : l2tpConfig->userName_;
266 std::string remoteId = l2tpConfig->ipsecIdentifier_.empty() ? "%any" : l2tpConfig->ipsecIdentifier_;
267 std::string authType = (l2tpConfig->vpnType_ == L2TP_IPSEC_PSK) ? "psk" : "pubkey";
268
269 std::ostringstream connectOss;
270 std::ostringstream secretOss;
271 connectOss << "home" << ifNameId << " {\nremote_addrs = " << address << "\n";
272 connectOss << "local {\nid = " << localId << "\nauth = " << authType << "\n}\n";
273 connectOss << "remote {\nid = " << remoteId << "\nauth = " << authType << "\n}\n";
274 connectOss << "children {\nhomel2tp {\nmode=transport\nlocal_ts = 0.0.0.0/0[udp/1701]\n";
275 connectOss << "remote_ts = " << address << "/32[udp/1701]\n";
276 connectOss << "esp_proposals = aes256-sha1, aes128-sha1, 3des-sha1\n}\n}\nversion = 1\n";
277 connectOss << "proposals = 3des-sha1-modp1024, aes128-sha1-modp1024, aes256-sha1-modp1024\n}\n";
278
279 std::string l2tpId = l2tpConfig->ipsecIdentifier_.empty() ? homeElement : l2tpConfig->ipsecIdentifier_;
280 secretOss << "ike-" << homeElement << " {\nid-1 = " << l2tpId;
281 secretOss << "\nid-2 = " << l2tpId << "\nsecret = " << l2tpConfig->ipsecPreSharedKey_ << "\n}\n";
282
283 connect = connectOss.str();
284 secret = secretOss.str();
285 }
286 if (ipsecConfig != nullptr) {
287 GetConnect(ipsecConfig, ifNameId, connect);
288 GetSecret(ipsecConfig, ifNameId, secret);
289 }
290 outConnect.append(connect);
291 outSecret.append(secret);
292 }
293 } // namespace NetManagerStandard
294 } // namespace OHOS
295