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