• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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