c2aeff2a7bd54223bbcac494997f54d5dea57378
[openwrt-luci.git] /
1 'use strict';
2 'require view';
3 'require form';
4 'require uci';
5 'require tools.widgets as widgets';
6 'require strongswan_algorithms';
7
8 function addAlgorithms(o, algorithms) {
9         algorithms.forEach(function (algorithm) {
10                 if (strongswan_algorithms.isInsecure(algorithm)) {
11                         o.value(algorithm, '%s*'.format(algorithm));
12                 } else {
13                         o.value(algorithm);
14                 }
15         });
16 }
17
18 return view.extend({
19         render: function () {
20                 var m, s, o;
21
22                 m = new form.Map('ipsec', _('strongSwan Configuration'),
23                         _('Configure strongSwan for secure VPN connections.'));
24                 m.tabbed = true;
25
26                 // strongSwan General Settings
27                 s = m.section(form.TypedSection, 'ipsec', _('General Settings'));
28                 s.anonymous = true;
29
30                 o = s.option(widgets.ZoneSelect, 'zone', _('Zone'),
31                         _('Firewall zone that has to match the defined firewall zone'));
32                 o.default = 'lan';
33                 o.multiple = true;
34
35                 o = s.option(widgets.NetworkSelect, 'listen', _('Listening Interfaces'),
36                         _('Interfaces that accept VPN traffic'));
37                 o.datatype = 'interface';
38                 o.placeholder = _('Select an interface or leave empty for all interfaces');
39                 o.default = 'wan';
40                 o.multiple = true;
41                 o.rmempty = false;
42
43                 o = s.option(form.Value, 'debug', _('Debug Level'),
44                         _('Trace level: 0 is least verbose, 4 is most'));
45                 o.default = '0';
46                 o.datatype = 'range(0,4)';
47
48                 // Remote Configuration
49                 s = m.section(form.GridSection, 'remote', _('Remote Configuration'),
50                         _('Define Remote IKE Configurations.'));
51                 s.addremove = true;
52                 s.nodescriptions = true;
53
54                 o = s.option(form.Flag, 'enabled', _('Enabled'),
55                         _('Configuration is enabled or not'));
56                 o.rmempty = false;
57
58                 o = s.option(form.Value, 'gateway', _('Gateway (Remote Endpoint)'),
59                         _('IP address or FQDN name of the tunnel remote endpoint'));
60                 o.datatype = 'or(hostname,ipaddr)';
61                 o.rmempty = false;
62
63                 o = s.option(form.Value, 'local_gateway', _('Local Gateway'),
64                         _('IP address or FQDN of the tunnel local endpoint'));
65                 o.datatype = 'or(hostname,ipaddr)';
66                 o.modalonly = true;
67
68                 o = s.option(form.Value, 'local_sourceip', _('Local Source IP'),
69                         _('Virtual IP(s) to request in IKEv2 configuration payloads requests'));
70                 o.datatype = 'ipaddr';
71                 o.modalonly = true;
72
73                 o = s.option(form.Value, 'local_ip', _('Local IP'),
74                         _('Local address(es) to use in IKE negotiation'));
75                 o.datatype = 'ipaddr';
76                 o.modalonly = true;
77
78                 o = s.option(form.Value, 'local_identifier', _('Local Identifier'),
79                         _('Local identifier for IKE (phase 1)'));
80                 o.datatype = 'string';
81                 o.placeholder = 'C=US, O=Acme Corporation, CN=headquarters';
82                 o.modalonly = true;
83
84                 o = s.option(form.Value, 'remote_identifier', _('Remote Identifier'),
85                         _('Remote identifier for IKE (phase 1)'));
86                 o.datatype = 'string';
87                 o.placeholder = 'C=US, O=Acme Corporation, CN=soho';
88                 o.modalonly = true;
89
90                 o = s.option(form.ListValue, 'authentication_method',
91                         _('Authentication Method'), _('IKE authentication (phase 1)'));
92                 o.modalonly = true;
93                 o.value('psk', 'Pre-shared Key');
94                 o.value('pubkey', 'Public Key');
95
96                 o = s.option(form.Value, 'pre_shared_key', _('Pre-Shared Key'),
97                         _('The pre-shared key for the tunnel'));
98                 o.datatype = 'string';
99                 o.password = true;
100                 o.modalonly = true;
101                 o.depends('authentication_method', 'psk');
102
103                 o = s.option(form.Flag, 'mobike', _('MOBIKE'),
104                         _('MOBIKE (IKEv2 Mobility and Multihoming Protocol)'));
105                 o.default = '1';
106                 o.modalonly = true;
107
108                 o = s.option(form.ListValue, 'fragmentation', _('IKE Fragmentation'),
109                         _('Use IKE fragmentation'));
110                 o.value('yes');
111                 o.value('no');
112                 o.value('force');
113                 o.value('accept');
114                 o.default = 'yes';
115                 o.modalonly = true;
116
117                 o = s.option(form.MultiValue, 'crypto_proposal', _('Crypto Proposal'),
118                         _('List of IKE (phase 1) proposals to use for authentication'));
119                 o.load = function (section_id) {
120                         this.keylist = [];
121                         this.vallist = [];
122
123                         var sections = uci.sections('ipsec', 'crypto_proposal');
124                         if (sections.length == 0) {
125                                 this.value('', _('Please create a Proposal first'));
126                         } else {
127                                 sections.forEach(L.bind(function (section) {
128                                         if (section.is_esp != '1') {
129                                                 this.value(section['.name']);
130                                         }
131                                 }, this));
132                         }
133
134                         return this.super('load', [section_id]);
135                 };
136                 o.rmempty = false;
137
138                 o = s.option(form.MultiValue, 'tunnel', _('Tunnel'),
139                         _('Name of ESP (phase 2) section'));
140                 o.load = function (section_id) {
141                         this.keylist = [];
142                         this.vallist = [];
143
144                         var sections = uci.sections('ipsec', 'tunnel');
145                         if (sections.length == 0) {
146                                 this.value('', _('Please create a Tunnel first'));
147                         } else {
148                                 sections.forEach(L.bind(function (section) {
149                                         this.value(section['.name']);
150                                 }, this));
151                         }
152
153                         return this.super('load', [section_id]);
154                 };
155                 o.rmempty = false;
156
157                 // Tunnel Configuration
158                 s = m.section(form.GridSection, 'tunnel', _('Tunnel Configuration'),
159                         _('Define Connection Children to be used as Tunnels in Remote Configurations.'));
160                 s.addremove = true;
161                 s.nodescriptions = true;
162
163                 o = s.option(form.DynamicList, 'local_subnet', _('Local Subnet'),
164                         _('Local network(s)'));
165                 o.datatype = 'subnet';
166                 o.placeholder = '192.168.1.1/24';
167                 o.rmempty = false;
168
169                 o = s.option(form.DynamicList, 'remote_subnet', _('Remote Subnet'),
170                         _('Remote network(s)'));
171                 o.datatype = 'subnet';
172                 o.placeholder = '192.168.2.1/24';
173                 o.rmempty = false;
174
175                 o = s.option(form.Value, 'local_nat', _('Local NAT'),
176                         _('NAT range for tunnels with overlapping IP addresses'));
177                 o.datatype = 'subnet';
178                 o.modalonly = true;
179
180                 o = s.option(form.MultiValue, 'crypto_proposal',
181                         _('Crypto Proposal (Phase 2)'),
182                         _('List of ESP (phase two) proposals. Only Proposals with checked ESP flag are selectable'));
183                 o.load = function (section_id) {
184                         this.keylist = [];
185                         this.vallist = [];
186
187                         var sections = uci.sections('ipsec', 'crypto_proposal');
188                         if (sections.length == 0) {
189                                 this.value('', _('Please create an ESP Proposal first'));
190                         } else {
191                                 sections.forEach(L.bind(function (section) {
192                                         if (section.is_esp == '1') {
193                                                 this.value(section['.name']);
194                                         }
195                                 }, this));
196                         }
197
198                         return this.super('load', [section_id]);
199                 };
200                 o.rmempty = false;
201
202                 o = s.option(form.ListValue, 'startaction', _('Start Action'),
203                         _('Action on initial configuration load'));
204                 o.value('none');
205                 o.value('trap');
206                 o.value('start');
207                 o.default = 'trap';
208                 o.modalonly = true;
209
210                 o = s.option(form.Value, 'updown', _('Up/Down Script Path'),
211                         _('Path to script to run on CHILD_SA up/down events'));
212                 o.datatype = 'file';
213                 o.modalonly = true;
214
215                 // Crypto Proposals
216                 s = m.section(form.GridSection, 'crypto_proposal',
217                         _('Encryption Proposals'),
218                         _('Configure Cipher Suites to define IKE (Phase 1) or ESP (Phase 2) Proposals.'));
219                 s.addremove = true;
220                 s.nodescriptions = true;
221
222                 o = s.option(form.Flag, 'is_esp', _('ESP Proposal'),
223                         _('Whether this is an ESP (phase 2) proposal or not'));
224
225                 o = s.option(form.ListValue, 'encryption_algorithm',
226                         _('Encryption Algorithm'),
227                         _('Algorithms marked with * are considered insecure'));
228                 o.default = 'aes256gcm128';
229                 addAlgorithms(o, strongswan_algorithms.getEncryptionAlgorithms());
230                 addAlgorithms(o, strongswan_algorithms.getAuthenticatedEncryptionAlgorithms());
231
232
233                 o = s.option(form.ListValue, 'hash_algorithm', _('Hash Algorithm'),
234                         _('Algorithms marked with * are considered insecure'));
235                 strongswan_algorithms.getEncryptionAlgorithms().forEach(function (algorithm) {
236                         o.depends('encryption_algorithm', algorithm);
237                 });
238                 o.default = 'sha512';
239                 o.rmempty = false;
240                 addAlgorithms(o, strongswan_algorithms.getHashAlgorithms());
241
242                 o = s.option(form.ListValue, 'dh_group', _('Diffie-Hellman Group'),
243                         _('Algorithms marked with * are considered insecure'));
244                 o.default = 'modp3072';
245                 addAlgorithms(o, strongswan_algorithms.getDiffieHellmanAlgorithms());
246
247                 o = s.option(form.ListValue, 'prf_algorithm', _('PRF Algorithm'),
248                         _('Algorithms marked with * are considered insecure'));
249                 o.validate = function (section_id, value) {
250                         var encryptionAlgorithm = this.section.formvalue(section_id, 'encryption_algorithm');
251
252                         if (strongswan_algorithms.getAuthenticatedEncryptionAlgorithms().includes(
253                                         encryptionAlgorithm) && !value) {
254                                 return _('PRF Algorithm must be configured when using an Authenticated Encryption Algorithm');
255                         }
256
257                         return true;
258                 };
259                 o.optional = true;
260                 o.depends('is_esp', '0');
261                 addAlgorithms(o, strongswan_algorithms.getPrfAlgorithms());
262
263                 return m.render();
264         }
265 });
git clone https://git.99rst.org/PROJECT