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 16import common from '@ohos.app.ability.common'; 17import HashMap from '@ohos.util.HashMap'; 18import { util } from '@kit.ArkTS'; 19import { IpsecVpnConfig } from './VpnConfig'; 20import { VpnConfigModel } from './VpnConfigModel'; 21import { VpnTypeModel } from '../../model/vpnImpl/VpnTypeModel'; 22import LogUtil from '../../../../../../../common/utils/src/main/ets/default/baseUtil/LogUtil'; 23 24const MODULE_TAG: string = 'setting_vpn:SwanCtlModel:'; 25//param 26const KEY_VPN_ADDRESS: string = 'vpn_address_value'; 27const KEY_VPN_USERNAME: string = 'vpn_username_value'; 28const KEY_VPN_IPSEC_IDENTIFIER: string = 'vpn_ipsec_identifier_value'; 29const KEY_VPN_PASSWORD: string = 'vpn_password_value'; 30const KEY_VPN_IPSEC_SHAREDKEY: string = 'vpn_ipsec_sharedKey_value'; 31 32//file path 33const SWANCTL_IKE2_IPSEC_MSCHAPV2_PATH: string = 'vpn/ike2_ipsec_mschapv2/swanctl.conf'; 34const STRONGSWAN_IKE2_IPSEC_MSCHAPV2_PATH: string = 'vpn/ike2_ipsec_mschapv2/strongswan.conf'; 35const SWANCTL_IKE2_IPSEC_RSA_PATH: string = 'vpn/ike2_ipsec_rsa/swanctl.conf'; 36const STRONGSWAN_IKE2_IPSEC_RSA_PATH: string = 'vpn/ike2_ipsec_rsa/strongswan.conf'; 37const SWANCTL_IKE2_IPSEC_PSK_PATH: string = 'vpn/ike2_ipsec_psk/swanctl.conf'; 38const STRONGSWAN_IKE2_IPSEC_PSK_PATH: string = 'vpn/ike2_ipsec_psk/strongswan.conf'; 39 40const SWANCTL_IPSEC_XAUTH_PSK_PATH: string = 'vpn/ipsec_xauth_psk/swanctl.conf'; 41const STRONGSWAN_IPSEC_XAUTH_PSK_PATH: string = 'vpn/ipsec_xauth_psk/strongswan.conf'; 42const SWANCTL_IPSEC_XAUTH_RSA_PATH: string = 'vpn/ipsec_xauth_rsa/swanctl.conf'; 43const STRONGSWAN_IPSEC_XAUTH_RSA_PATH: string = 'vpn/ipsec_xauth_rsa/strongswan.conf'; 44 45const STRONGSWAN_L2TP_IPSEC_RSA_PATH: string = 'vpn/l2tp_ipsec_rsa/strongswan.conf'; 46const STRONGSWAN_L2TP_IPSEC_PSK_PATH: string = 'vpn/l2tp_ipsec_psk/strongswan.conf'; 47 48const CLIENT_L2TP_IPSEC_PSK_PATH: string = 'vpn/l2tp_ipsec_psk/options.l2tpd.client.conf'; 49const CLIENT_L2TP_IPSEC_RSA_PATH: string = 'vpn/l2tp_ipsec_rsa/options.l2tpd.client.conf'; 50const XL2TPD_L2TP_IPSEC_PSK_PATH: string = 'vpn/l2tp_ipsec_psk/xl2tpd.conf'; 51const XL2TPD_L2TP_IPSEC_RSA_PATH: string = 'vpn/l2tp_ipsec_rsa/xl2tpd.conf'; 52 53const IPSECCONF_L2TP_IPSEC_PSK_PATH: string = 'vpn/l2tp_ipsec_psk/ipsec.conf'; 54const IPSECCONF_L2TP_IPSEC_RSA_PATH: string = 'vpn/l2tp_ipsec_rsa/ipsec.conf'; 55 56const IPSEC_SECRETS_L2TP_IPSEC_PSK_PATH: string = 'vpn/l2tp_ipsec_psk/ipsec.secrets.conf'; 57const IPSEC_SECRETS_L2TP_IPSEC_RSA_PATH: string = 'vpn/l2tp_ipsec_rsa/ipsec.secrets.conf'; 58 59const SWANCTL_IPSEC_HYBRID_RSA_PATH: string = 'vpn/ipsec_hybrid_rsa/swanctl.conf'; 60const STRONGSWAN_IPSEC_HYBRID_RSA_PATH: string = 'vpn/ipsec_hybrid_rsa/strongswan.conf'; 61 62export class SwanCtlModel { 63 private context: common.UIAbilityContext = undefined; 64 private swanCtlMap = new HashMap(); 65 private strongSwanMap = new HashMap(); 66 private l2tpdClientMap = new HashMap(); 67 private xl2tpdMap = new HashMap(); 68 private ipsecConfMap = new HashMap(); 69 private ipsecSecretsMap = new HashMap(); 70 71 private static instance: SwanCtlModel; 72 73 public static getInstance(): SwanCtlModel { 74 if (!this.instance) { 75 this.instance = new SwanCtlModel(); 76 } 77 return this.instance; 78 } 79 80 public async init(context: common.UIAbilityContext): Promise<void> { 81 this.context = context; 82 this.readTemplate(); 83 } 84 85 public buildConfig(ipsec: IpsecVpnConfig): IpsecVpnConfig { 86 let helper: util.Base64Helper = new util.Base64Helper(); 87 if (ipsec.vpnType !== VpnTypeModel.TYPE_L2TP_IPSEC_PSK && ipsec.vpnType !== VpnTypeModel.TYPE_L2TP_IPSEC_RSA) { 88 ipsec.swanctlConfig = helper.encodeToStringSync(this.ipsec2swanCtl(ipsec)); 89 } 90 ipsec.strongSwanConfig = helper.encodeToStringSync(this.ipsec2strongSwan(ipsec)); 91 if (ipsec.vpnType === VpnTypeModel.TYPE_L2TP_IPSEC_PSK || ipsec.vpnType === VpnTypeModel.TYPE_L2TP_IPSEC_RSA) { 92 ipsec.optionsL2tpdClient = helper.encodeToStringSync(this.ipsec2L2tpdClient(ipsec)); 93 ipsec.xl2tpdConfig = helper.encodeToStringSync(this.ipsec2Xl2tpd(ipsec)); 94 ipsec.ipsecConfig = helper.encodeToStringSync(this.ipsec2IpsecConf(ipsec)); 95 ipsec.ipsecSecrets = helper.encodeToStringSync(this.ipsec2IpsecSecrets(ipsec)); 96 } 97 return ipsec; 98 } 99 100 private ipsec2swanCtl(ipsec: IpsecVpnConfig): Uint8Array { 101 if (this.swanCtlMap.isEmpty()) { 102 this.readTemplate(); 103 } 104 let template = this.swanCtlMap.get(ipsec.vpnType); 105 let vpnTemplate = String(template); 106 vpnTemplate = this.replaceConfigParam(vpnTemplate, KEY_VPN_ADDRESS, VpnConfigModel.getInstance().getAddress(ipsec)); 107 vpnTemplate = this.replaceConfigParam(vpnTemplate, KEY_VPN_IPSEC_IDENTIFIER, ipsec.ipsecIdentifier); 108 vpnTemplate = this.replaceConfigParam(vpnTemplate, KEY_VPN_IPSEC_SHAREDKEY, ipsec.ipsecPreSharedKey); 109 vpnTemplate = this.replaceConfigParam(vpnTemplate, KEY_VPN_USERNAME, ipsec.userName); 110 vpnTemplate = this.replaceConfigParam(vpnTemplate, KEY_VPN_PASSWORD, ipsec.password); 111 112 let swanCtl = this.stringToUint8Array(vpnTemplate); 113 return swanCtl; 114 } 115 116 private ipsec2strongSwan(ipsec: IpsecVpnConfig): Uint8Array { 117 if (this.strongSwanMap.isEmpty()) { 118 this.readTemplate(); 119 } 120 let template = this.strongSwanMap.get(ipsec.vpnType); 121 let strongSwan = this.stringToUint8Array(String(template)); 122 return strongSwan; 123 } 124 125 private ipsec2Xl2tpd(ipsec: IpsecVpnConfig): Uint8Array { 126 if (this.xl2tpdMap.isEmpty()) { 127 this.readTemplate(); 128 } 129 let template = this.xl2tpdMap.get(ipsec.vpnType); 130 let vpnTemplate = String(template); 131 vpnTemplate = this.replaceConfigParam(vpnTemplate, KEY_VPN_ADDRESS, VpnConfigModel.getInstance().getAddress(ipsec)); 132 let xl2tpd = this.stringToUint8Array(vpnTemplate); 133 return xl2tpd; 134 } 135 136 private ipsec2L2tpdClient(ipsec: IpsecVpnConfig): Uint8Array { 137 if (this.l2tpdClientMap.isEmpty()) { 138 this.readTemplate(); 139 } 140 let template = this.l2tpdClientMap.get(ipsec.vpnType); 141 let vpnTemplate = String(template); 142 vpnTemplate = this.replaceConfigParam(vpnTemplate, KEY_VPN_USERNAME, ipsec.userName); 143 vpnTemplate = this.replaceConfigParam(vpnTemplate, KEY_VPN_PASSWORD, ipsec.password); 144 let xl2tpd = this.stringToUint8Array(vpnTemplate); 145 return xl2tpd; 146 } 147 148 private ipsec2IpsecConf(ipsec: IpsecVpnConfig): Uint8Array { 149 if (this.ipsecConfMap.isEmpty()) { 150 this.readTemplate(); 151 } 152 let template = this.ipsecConfMap.get(ipsec.vpnType); 153 let vpnTemplate = String(template); 154 vpnTemplate = this.replaceConfigParam(vpnTemplate, KEY_VPN_ADDRESS, VpnConfigModel.getInstance().getAddress(ipsec)); 155 let ipsecConf = this.stringToUint8Array(vpnTemplate); 156 return ipsecConf; 157 } 158 159 private ipsec2IpsecSecrets(ipsec: IpsecVpnConfig): Uint8Array { 160 if (this.ipsecSecretsMap.isEmpty()) { 161 this.readTemplate(); 162 } 163 let template = this.ipsecSecretsMap.get(ipsec.vpnType); 164 let vpnTemplate = String(template); 165 vpnTemplate = this.replaceConfigParam(vpnTemplate, KEY_VPN_IPSEC_SHAREDKEY, ipsec.ipsecPreSharedKey); 166 let ipsecSecrets = this.stringToUint8Array(vpnTemplate); 167 return ipsecSecrets; 168 } 169 170 private readTemplate(): void { 171 //swanctl.config 172 this.swanCtlMap.set(VpnTypeModel.TYPE_IKEV2_IPSEC_MSCHAPv2, SWANCTL_IKE2_IPSEC_MSCHAPV2_PATH); 173 this.swanCtlMap.set(VpnTypeModel.TYPE_IKEV2_IPSEC_RSA, SWANCTL_IKE2_IPSEC_RSA_PATH); 174 this.swanCtlMap.set(VpnTypeModel.TYPE_IKEV2_IPSEC_PSK, SWANCTL_IKE2_IPSEC_PSK_PATH); 175 this.swanCtlMap.set(VpnTypeModel.TYPE_IPSEC_XAUTH_PSK, SWANCTL_IPSEC_XAUTH_PSK_PATH); 176 this.swanCtlMap.set(VpnTypeModel.TYPE_IPSEC_XAUTH_RSA, SWANCTL_IPSEC_XAUTH_RSA_PATH); 177 this.swanCtlMap.set(VpnTypeModel.TYPE_IPSEC_HYBRID_RSA, SWANCTL_IPSEC_HYBRID_RSA_PATH); 178 this.swanCtlMap = this.readRawFile(this.swanCtlMap); 179 //strongSwan.config 180 this.strongSwanMap.set(VpnTypeModel.TYPE_IKEV2_IPSEC_MSCHAPv2, STRONGSWAN_IKE2_IPSEC_MSCHAPV2_PATH); 181 this.strongSwanMap.set(VpnTypeModel.TYPE_IKEV2_IPSEC_RSA, STRONGSWAN_IKE2_IPSEC_RSA_PATH); 182 this.strongSwanMap.set(VpnTypeModel.TYPE_IKEV2_IPSEC_PSK, STRONGSWAN_IKE2_IPSEC_PSK_PATH); 183 this.strongSwanMap.set(VpnTypeModel.TYPE_IPSEC_XAUTH_PSK, STRONGSWAN_IPSEC_XAUTH_PSK_PATH); 184 this.strongSwanMap.set(VpnTypeModel.TYPE_IPSEC_XAUTH_RSA, STRONGSWAN_IPSEC_XAUTH_RSA_PATH); 185 this.strongSwanMap.set(VpnTypeModel.TYPE_IPSEC_HYBRID_RSA, STRONGSWAN_IPSEC_HYBRID_RSA_PATH); 186 this.strongSwanMap.set(VpnTypeModel.TYPE_L2TP_IPSEC_PSK, STRONGSWAN_L2TP_IPSEC_PSK_PATH); 187 this.strongSwanMap.set(VpnTypeModel.TYPE_L2TP_IPSEC_RSA, STRONGSWAN_L2TP_IPSEC_RSA_PATH); 188 this.strongSwanMap = this.readRawFile(this.strongSwanMap); 189 //xl2tpd.conf 190 this.xl2tpdMap.set(VpnTypeModel.TYPE_L2TP_IPSEC_PSK, XL2TPD_L2TP_IPSEC_PSK_PATH); 191 this.xl2tpdMap.set(VpnTypeModel.TYPE_L2TP_IPSEC_RSA, XL2TPD_L2TP_IPSEC_RSA_PATH); 192 this.xl2tpdMap = this.readRawFile(this.xl2tpdMap); 193 //options.l2tpd.client.conf 194 this.l2tpdClientMap.set(VpnTypeModel.TYPE_L2TP_IPSEC_PSK, CLIENT_L2TP_IPSEC_PSK_PATH); 195 this.l2tpdClientMap.set(VpnTypeModel.TYPE_L2TP_IPSEC_RSA, CLIENT_L2TP_IPSEC_RSA_PATH); 196 this.l2tpdClientMap = this.readRawFile(this.l2tpdClientMap); 197 //ipsec.conf 198 this.ipsecConfMap.set(VpnTypeModel.TYPE_L2TP_IPSEC_PSK, IPSECCONF_L2TP_IPSEC_PSK_PATH); 199 this.ipsecConfMap.set(VpnTypeModel.TYPE_L2TP_IPSEC_RSA, IPSECCONF_L2TP_IPSEC_RSA_PATH); 200 this.ipsecConfMap = this.readRawFile(this.ipsecConfMap); 201 //ipsec.secrets.conf 202 this.ipsecSecretsMap.set(VpnTypeModel.TYPE_L2TP_IPSEC_PSK, IPSEC_SECRETS_L2TP_IPSEC_PSK_PATH); 203 this.ipsecSecretsMap.set(VpnTypeModel.TYPE_L2TP_IPSEC_RSA, IPSEC_SECRETS_L2TP_IPSEC_RSA_PATH); 204 this.ipsecSecretsMap = this.readRawFile(this.ipsecSecretsMap); 205 } 206 207 private readRawFile(pathMap): HashMap<number, string> { 208 try { 209 pathMap.forEach((path, key) => { 210 this.context.resourceManager.getRawFileContent(path as string, (error, value) => { 211 if (error !== null && error !== undefined) { 212 LogUtil.log(MODULE_TAG + 'readRawFile faile, error:' + error); 213 } else { 214 let valStr: string = this.uint8ArrayToString(value); 215 let contentStr: string = valStr.replace(/\r\n/g, '\n'); 216 pathMap.set(key, contentStr); 217 } 218 }); 219 }); 220 } catch (error) { 221 LogUtil.error(MODULE_TAG + 'callback getRawfileContent failed, error:' + error); 222 } 223 return pathMap; 224 } 225 226 private replaceConfigParam(vpnTemplate: string, key: string, value: string): string { 227 if (!value || !key) { 228 LogUtil.warn(MODULE_TAG + 'replaceConfigParam failed, params is null or undefined'); 229 return vpnTemplate; 230 } 231 while (vpnTemplate.indexOf(key) !== -1) { 232 vpnTemplate = vpnTemplate.replace(key, value.trim()); 233 } 234 return vpnTemplate; 235 } 236 237 private uint8ArrayToString(fileData): string { 238 let dataString = ''; 239 for (let i = 0; i < fileData.length; i++) { 240 dataString += String.fromCharCode(fileData[i]); 241 } 242 return dataString; 243 } 244 245 private stringToUint8Array(str: string): Uint8Array { 246 let arr: number[] = []; 247 for (let i = 0, j = str.length; i < j; ++i) { 248 arr.push(str.charCodeAt(i)); 249 } 250 return new Uint8Array(arr); 251 } 252}