18e745fdaSopenharmony_ci/*
28e745fdaSopenharmony_ci * Copyright (c) 2024 Huawei Device Co., Ltd.
38e745fdaSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
48e745fdaSopenharmony_ci * you may not use this file except in compliance with the License.
58e745fdaSopenharmony_ci * You may obtain a copy of the License at
68e745fdaSopenharmony_ci *
78e745fdaSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
88e745fdaSopenharmony_ci *
98e745fdaSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
108e745fdaSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
118e745fdaSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
128e745fdaSopenharmony_ci * See the License for the specific language governing permissions and
138e745fdaSopenharmony_ci * limitations under the License.
148e745fdaSopenharmony_ci */
158e745fdaSopenharmony_ci
168e745fdaSopenharmony_ci#include "ipsec_vpn_ctl.h"
178e745fdaSopenharmony_ci
188e745fdaSopenharmony_ci#include <string>
198e745fdaSopenharmony_ci
208e745fdaSopenharmony_ci#include "base64_utils.h"
218e745fdaSopenharmony_ci#include "netmgr_ext_log_wrapper.h"
228e745fdaSopenharmony_ci#include "netmanager_base_common_utils.h"
238e745fdaSopenharmony_ci#include "net_manager_ext_constants.h"
248e745fdaSopenharmony_ci
258e745fdaSopenharmony_cinamespace OHOS {
268e745fdaSopenharmony_cinamespace NetManagerStandard {
278e745fdaSopenharmony_ciIpsecVpnCtl::IpsecVpnCtl(sptr<VpnConfig> config, const std::string &pkg, int32_t userId,
288e745fdaSopenharmony_ci    std::vector<int32_t> &activeUserIds)
298e745fdaSopenharmony_ci    : NetVpnImpl(config, pkg, userId, activeUserIds)
308e745fdaSopenharmony_ci{}
318e745fdaSopenharmony_ci
328e745fdaSopenharmony_ciIpsecVpnCtl::~IpsecVpnCtl()
338e745fdaSopenharmony_ci{
348e745fdaSopenharmony_ci    NETMGR_EXT_LOG_I("~IpsecVpnCtl");
358e745fdaSopenharmony_ci}
368e745fdaSopenharmony_ci
378e745fdaSopenharmony_ciint32_t IpsecVpnCtl::SetUp()
388e745fdaSopenharmony_ci{
398e745fdaSopenharmony_ci    return StartSysVpn();
408e745fdaSopenharmony_ci}
418e745fdaSopenharmony_ci
428e745fdaSopenharmony_ciint32_t IpsecVpnCtl::Destroy()
438e745fdaSopenharmony_ci{
448e745fdaSopenharmony_ci    return StopSysVpn();
458e745fdaSopenharmony_ci}
468e745fdaSopenharmony_ci
478e745fdaSopenharmony_ciint32_t IpsecVpnCtl::StopSysVpn()
488e745fdaSopenharmony_ci{
498e745fdaSopenharmony_ci    NETMGR_EXT_LOG_I("stop ipsec vpn");
508e745fdaSopenharmony_ci    state_ = IpsecVpnStateCode::STATE_DISCONNECTED;
518e745fdaSopenharmony_ci    NetsysController::GetInstance().ProcessVpnStage(SysVpnStageCode::VPN_STAGE_DOWN_HOME);
528e745fdaSopenharmony_ci    NetsysController::GetInstance().ProcessVpnStage(SysVpnStageCode::VPN_STAGE_STOP);
538e745fdaSopenharmony_ci    NotifyConnectState(VpnConnectState::VPN_DISCONNECTED);
548e745fdaSopenharmony_ci    return NETMANAGER_EXT_SUCCESS;
558e745fdaSopenharmony_ci}
568e745fdaSopenharmony_ci
578e745fdaSopenharmony_ciint32_t IpsecVpnCtl::StartSysVpn()
588e745fdaSopenharmony_ci{
598e745fdaSopenharmony_ci    NETMGR_EXT_LOG_I("start ipsec vpn");
608e745fdaSopenharmony_ci    state_ = IpsecVpnStateCode::STATE_INIT;
618e745fdaSopenharmony_ci    InitConfigFile();
628e745fdaSopenharmony_ci    NetsysController::GetInstance().ProcessVpnStage(SysVpnStageCode::VPN_STAGE_RESTART);
638e745fdaSopenharmony_ci    return NETMANAGER_EXT_SUCCESS;
648e745fdaSopenharmony_ci}
658e745fdaSopenharmony_ci
668e745fdaSopenharmony_ciint32_t IpsecVpnCtl::InitConfigFile()
678e745fdaSopenharmony_ci{
688e745fdaSopenharmony_ci    CleanTempFiles();
698e745fdaSopenharmony_ci    if (ipsecVpnConfig_ == nullptr) {
708e745fdaSopenharmony_ci        NETMGR_EXT_LOG_E("InitConfigFile ipsecVpnConfig is null");
718e745fdaSopenharmony_ci        return NETMANAGER_EXT_ERR_INTERNAL;
728e745fdaSopenharmony_ci    }
738e745fdaSopenharmony_ci
748e745fdaSopenharmony_ci    if (!ipsecVpnConfig_->swanctlConf_.empty()) {
758e745fdaSopenharmony_ci        std::string swanctlCfg = Base64::Decode(ipsecVpnConfig_->swanctlConf_);
768e745fdaSopenharmony_ci        if (!swanctlCfg.empty()) {
778e745fdaSopenharmony_ci            CommonUtils::WriteFile(SWAN_CTL_FILE, swanctlCfg);
788e745fdaSopenharmony_ci        }
798e745fdaSopenharmony_ci    }
808e745fdaSopenharmony_ci    if (!ipsecVpnConfig_->strongswanConf_.empty()) {
818e745fdaSopenharmony_ci        std::string strongswanCfg = Base64::Decode(ipsecVpnConfig_->strongswanConf_);
828e745fdaSopenharmony_ci        if (!strongswanCfg.empty()) {
838e745fdaSopenharmony_ci            CommonUtils::WriteFile(SWAN_CONFIG_FILE, strongswanCfg);
848e745fdaSopenharmony_ci        }
858e745fdaSopenharmony_ci    }
868e745fdaSopenharmony_ci    return NETMANAGER_EXT_SUCCESS;
878e745fdaSopenharmony_ci}
888e745fdaSopenharmony_ci
898e745fdaSopenharmony_civoid IpsecVpnCtl::CleanTempFiles()
908e745fdaSopenharmony_ci{
918e745fdaSopenharmony_ci    DeleteTempFile(SWAN_CTL_FILE);
928e745fdaSopenharmony_ci    DeleteTempFile(SWAN_CONFIG_FILE);
938e745fdaSopenharmony_ci    DeleteTempFile(L2TP_CFG);
948e745fdaSopenharmony_ci    DeleteTempFile(L2TP_IPSEC_CFG);
958e745fdaSopenharmony_ci    DeleteTempFile(L2TP_IPSEC_SECRETS_CFG);
968e745fdaSopenharmony_ci    DeleteTempFile(OPTIONS_L2TP_CLIENT);
978e745fdaSopenharmony_ci}
988e745fdaSopenharmony_ci
998e745fdaSopenharmony_civoid IpsecVpnCtl::DeleteTempFile(const std::string &fileName)
1008e745fdaSopenharmony_ci{
1018e745fdaSopenharmony_ci    if (std::filesystem::exists(fileName)) {
1028e745fdaSopenharmony_ci        if (!std::filesystem::remove(fileName)) {
1038e745fdaSopenharmony_ci            NETMGR_EXT_LOG_E("remove old cache file failed");
1048e745fdaSopenharmony_ci        }
1058e745fdaSopenharmony_ci    }
1068e745fdaSopenharmony_ci}
1078e745fdaSopenharmony_ci
1088e745fdaSopenharmony_ciint32_t IpsecVpnCtl::NotifyConnectStage(const std::string &stage, const int32_t &result)
1098e745fdaSopenharmony_ci{
1108e745fdaSopenharmony_ci    if (stage.empty()) {
1118e745fdaSopenharmony_ci        NETMGR_EXT_LOG_E("stage is empty");
1128e745fdaSopenharmony_ci        return NETMANAGER_EXT_ERR_PARAMETER_ERROR;
1138e745fdaSopenharmony_ci    }
1148e745fdaSopenharmony_ci    if (result != NETMANAGER_EXT_SUCCESS) {
1158e745fdaSopenharmony_ci        NETMGR_EXT_LOG_E("vpn stage: %{public}s failed, result: %{public}d", stage.c_str(), result);
1168e745fdaSopenharmony_ci        return NETMANAGER_EXT_ERR_INTERNAL;
1178e745fdaSopenharmony_ci    }
1188e745fdaSopenharmony_ci    switch (state_) {
1198e745fdaSopenharmony_ci        case IpsecVpnStateCode::STATE_INIT:
1208e745fdaSopenharmony_ci            if (stage.compare(IPSEC_START_TAG) == 0) {
1218e745fdaSopenharmony_ci                // 1. start strongswan
1228e745fdaSopenharmony_ci                NETMGR_EXT_LOG_I("ipsec vpn setup step 1: start strongswan");
1238e745fdaSopenharmony_ci                state_ = IpsecVpnStateCode::STATE_STARTED;
1248e745fdaSopenharmony_ci                NetsysController::GetInstance().ProcessVpnStage(SysVpnStageCode::VPN_STAGE_SWANCTL_LOAD);
1258e745fdaSopenharmony_ci            }
1268e745fdaSopenharmony_ci            break;
1278e745fdaSopenharmony_ci        case IpsecVpnStateCode::STATE_STARTED:
1288e745fdaSopenharmony_ci            if (stage.compare(SWANCTL_START_TAG) == 0) {
1298e745fdaSopenharmony_ci                // 2. start connect
1308e745fdaSopenharmony_ci                NETMGR_EXT_LOG_I("ipsec vpn setup step 2: start connect");
1318e745fdaSopenharmony_ci                state_ = IpsecVpnStateCode::STATE_CONFIGED;
1328e745fdaSopenharmony_ci                NetsysController::GetInstance().ProcessVpnStage(SysVpnStageCode::VPN_STAGE_UP_HOME);
1338e745fdaSopenharmony_ci            }
1348e745fdaSopenharmony_ci            break;
1358e745fdaSopenharmony_ci        case IpsecVpnStateCode::STATE_CONFIGED:
1368e745fdaSopenharmony_ci            if (stage.compare(IPSEC_CONNECT_TAG) == 0) {
1378e745fdaSopenharmony_ci                // 3. is connected
1388e745fdaSopenharmony_ci                NETMGR_EXT_LOG_I("ipsec vpn setup step 3: is connected");
1398e745fdaSopenharmony_ci                state_ = IpsecVpnStateCode::STATE_CONNECTED;
1408e745fdaSopenharmony_ci                NotifyConnectState(VpnConnectState::VPN_CONNECTED);
1418e745fdaSopenharmony_ci            }
1428e745fdaSopenharmony_ci            break;
1438e745fdaSopenharmony_ci        default:
1448e745fdaSopenharmony_ci            NETMGR_EXT_LOG_E("invalid state: %{public}d", state_);
1458e745fdaSopenharmony_ci            return NETMANAGER_EXT_ERR_INTERNAL;
1468e745fdaSopenharmony_ci    }
1478e745fdaSopenharmony_ci    return NETMANAGER_EXT_SUCCESS;
1488e745fdaSopenharmony_ci}
1498e745fdaSopenharmony_ci
1508e745fdaSopenharmony_ciint32_t IpsecVpnCtl::GetSysVpnCertUri(const int32_t certType, std::string &certUri)
1518e745fdaSopenharmony_ci{
1528e745fdaSopenharmony_ci    if (ipsecVpnConfig_ == nullptr) {
1538e745fdaSopenharmony_ci        NETMGR_EXT_LOG_E("GetSysVpnCertUri ipsecVpnConfig is null");
1548e745fdaSopenharmony_ci        return NETMANAGER_EXT_ERR_INTERNAL;
1558e745fdaSopenharmony_ci    }
1568e745fdaSopenharmony_ci    switch (certType) {
1578e745fdaSopenharmony_ci        case IpsecVpnCertType::CA_CERT:
1588e745fdaSopenharmony_ci            certUri = ipsecVpnConfig_->ipsecCaCertConf_;
1598e745fdaSopenharmony_ci            break;
1608e745fdaSopenharmony_ci        case IpsecVpnCertType::USER_CERT:
1618e745fdaSopenharmony_ci            certUri = ipsecVpnConfig_->ipsecPublicUserCertConf_;
1628e745fdaSopenharmony_ci            break;
1638e745fdaSopenharmony_ci        case IpsecVpnCertType::SERVER_CERT:
1648e745fdaSopenharmony_ci            certUri = ipsecVpnConfig_->ipsecPublicServerCertConf_;
1658e745fdaSopenharmony_ci            break;
1668e745fdaSopenharmony_ci        default:
1678e745fdaSopenharmony_ci            NETMGR_EXT_LOG_E("invalid certType: %{public}d", certType);
1688e745fdaSopenharmony_ci            break;
1698e745fdaSopenharmony_ci    }
1708e745fdaSopenharmony_ci    return NETMANAGER_EXT_SUCCESS;
1718e745fdaSopenharmony_ci}
1728e745fdaSopenharmony_ci
1738e745fdaSopenharmony_ciint32_t IpsecVpnCtl::GetConnectedSysVpnConfig(sptr<SysVpnConfig> &sysVpnConfig)
1748e745fdaSopenharmony_ci{
1758e745fdaSopenharmony_ci    if (state_ == IpsecVpnStateCode::STATE_CONNECTED && ipsecVpnConfig_ != nullptr) {
1768e745fdaSopenharmony_ci        NETMGR_EXT_LOG_I("GetConnectedSysVpnConfig success");
1778e745fdaSopenharmony_ci        sysVpnConfig = ipsecVpnConfig_;
1788e745fdaSopenharmony_ci    }
1798e745fdaSopenharmony_ci    return NETMANAGER_EXT_SUCCESS;
1808e745fdaSopenharmony_ci}
1818e745fdaSopenharmony_ci
1828e745fdaSopenharmony_cibool IpsecVpnCtl::IsInternalVpn()
1838e745fdaSopenharmony_ci{
1848e745fdaSopenharmony_ci    return true;
1858e745fdaSopenharmony_ci}
1868e745fdaSopenharmony_ci} // namespace NetManagerStandard
1878e745fdaSopenharmony_ci} // namespace OHOS