security-policies: performance: Remove CBC ciphers
[people/ms/network.git] / src / functions / functions.vpn-security-policies
1 #!/bin/bash
2 ###############################################################################
3 #                                                                             #
4 # IPFire.org - A linux based firewall                                         #
5 # Copyright (C) 2017  IPFire Network Development Team                         #
6 #                                                                             #
7 # This program is free software: you can redistribute it and/or modify        #
8 # it under the terms of the GNU General Public License as published by        #
9 # the Free Software Foundation, either version 3 of the License, or           #
10 # (at your option) any later version.                                         #
11 #                                                                             #
12 # This program is distributed in the hope that it will be useful,             #
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of              #
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               #
15 # GNU General Public License for more details.                                #
16 #                                                                             #
17 # You should have received a copy of the GNU General Public License           #
18 # along with this program.  If not, see <http://www.gnu.org/licenses/>.       #
19 #                                                                             #
20 ###############################################################################
21
22 VPN_SECURITY_POLICIES_CONFIG_SETTINGS="CIPHERS COMPRESSION GROUP_TYPES \
23         INTEGRITIES PSEUDO_RANDOM_FUNCTIONS KEY_EXCHANGE LIFETIME PFS"
24 VPN_SECURITY_POLICIES_READONLY="system performance"
25
26 VPN_DEFAULT_SECURITY_POLICY="system"
27
28 declare -A VPN_SUPPORTED_CIPHERS=(
29         # 3DES-CBC
30         [3DES-CBC]="168 bit 3DES-EDE-CBC"
31
32         # AES-CBC
33         [AES256-CBC]="256 bit AES-CBC"
34         [AES192-CBC]="192 bit AES-CBC"
35         [AES128-CBC]="128 bit AES-CBC"
36
37         # AES-CTR
38         [AES256-CTR]="256 bit AES-COUNTER"
39         [AES192-CTR]="192 bit AES-COUNTER"
40         [AES128-CTR]="128 bit AES-COUNTER"
41
42         # AES-GCM
43         [AES256-GCM128]="256 bit AES-GCM with 128 bit ICV"
44         [AES192-GCM128]="192 bit AES-GCM with 128 bit ICV"
45         [AES128-GCM128]="128 bit AES-GCM with 128 bit ICV"
46         [AES256-GCM96]="256 bit AES-GCM with 96 bit ICV"
47         [AES192-GCM96]="192 bit AES-GCM with 96 bit ICV"
48         [AES128-GCM96]="128 bit AES-GCM with 96 bit ICV"
49         [AES256-GCM64]="256 bit AES-GCM with 64 bit ICV"
50         [AES192-GCM64]="192 bit AES-GCM with 64 bit ICV"
51         [AES128-GCM64]="128 bit AES-GCM with 64 bit ICV"
52
53         # AES-CCM
54         [AES256-CCM128]="256 bit AES-CCM with 128 bit ICV"
55         [AES192-CCM128]="192 bit AES-CCM with 128 bit ICV"
56         [AES128-CCM128]="128 bit AES-CCM with 128 bit ICV"
57         [AES256-CCM96]="256 bit AES-CCM with 96 bit ICV"
58         [AES192-CCM96]="192 bit AES-CCM with 96 bit ICV"
59         [AES128-CCM96]="128 bit AES-CCM with 96 bit ICV"
60         [AES256-CCM64]="256 bit AES-CCM with 64 bit ICV"
61         [AES192-CCM64]="192 bit AES-CCM with 64 bit ICV"
62         [AES128-CCM64]="128 bit AES-CCM with 64 bit ICV"
63
64         # CAMELLIA-CBC
65         [CAMELLIA256-CBC]="256 bit CAMELLIA-CBC"
66         [CAMELLIA192-CBC]="192 bit CAMELLIA-CBC"
67         [CAMELLIA128-CBC]="128 bit CAMELLIA-CBC"
68
69         # CAMELLIA-CTR
70         [CAMELLIA256-CTR]="256 bit CAMELLIA-COUNTER"
71         [CAMELLIA192-CTR]="192 bit CAMELLIA-COUNTER"
72         [CAMELLIA128-CTR]="128 bit CAMELLIA-COUNTER"
73
74         # CAMELLIA-GCM
75         [CAMELLIA256-GCM128]="256 bit CAMELLIA-GCM with 128 bit ICV"
76         [CAMELLIA192-GCM128]="192 bit CAMELLIA-GCM with 128 bit ICV"
77         [CAMELLIA128-GCM128]="128 bit CAMELLIA-GCM with 128 bit ICV"
78         [CAMELLIA256-GCM96]="256 bit CAMELLIA-GCM with 96 bit ICV"
79         [CAMELLIA192-GCM96]="192 bit CAMELLIA-GCM with 96 bit ICV"
80         [CAMELLIA128-GCM96]="128 bit CAMELLIA-GCM with 96 bit ICV"
81         [CAMELLIA256-GCM64]="256 bit CAMELLIA-GCM with 64 bit ICV"
82         [CAMELLIA192-GCM64]="192 bit CAMELLIA-GCM with 64 bit ICV"
83         [CAMELLIA128-GCM64]="128 bit CAMELLIA-GCM with 64 bit ICV"
84
85         # CAMELLIA-CCM
86         [CAMELLIA256-CCM128]="256 bit CAMELLIA-CCM with 128 bit ICV"
87         [CAMELLIA192-CCM128]="192 bit CAMELLIA-CCM with 128 bit ICV"
88         [CAMELLIA128-CCM128]="128 bit CAMELLIA-CCM with 128 bit ICV"
89         [CAMELLIA256-CCM96]="256 bit CAMELLIA-CCM with 96 bit ICV"
90         [CAMELLIA192-CCM96]="192 bit CAMELLIA-CCM with 96 bit ICV"
91         [CAMELLIA128-CCM96]="128 bit CAMELLIA-CCM with 96 bit ICV"
92         [CAMELLIA256-CCM64]="256 bit CAMELLIA-CCM with 64 bit ICV"
93         [CAMELLIA192-CCM64]="192 bit CAMELLIA-CCM with 64 bit ICV"
94         [CAMELLIA128-CCM64]="128 bit CAMELLIA-CCM with 64 bit ICV"
95
96         # DJB
97         [CHACHA20-POLY1305]="256 bit ChaCha20/Poly1305 with 128 bit ICV"
98
99         # No Encryption
100         [NULL]="No Encryption"
101 )
102
103 declare -A CIPHER_TO_STRONGSWAN=(
104         # 3DES-CBC
105         [3DES-CBC]="3des"
106
107         # AES-CBC
108         [AES256-CBC]="aes256"
109         [AES192-CBC]="aes192"
110         [AES128-CBC]="aes128"
111
112         # AES-CTR
113         [AES256-CTR]="aes256ctr"
114         [AES192-CTR]="aes192ctr"
115         [AES128-CTR]="aes128ctr"
116
117         # AES-GCM
118         [AES256-GCM128]="aes256gcm128"
119         [AES192-GCM128]="aes192gcm128"
120         [AES128-GCM128]="aes128gcm128"
121         [AES256-GCM96]="aes256gcm96"
122         [AES192-GCM96]="aes192gcm96"
123         [AES128-GCM96]="aes128gcm96"
124         [AES256-GCM64]="aes256gcm64"
125         [AES192-GCM64]="aes192gcm64"
126         [AES128-GCM64]="aes128gcm64"
127
128         # AES-CCM
129         [AES256-CCM128]="aes256ccm128"
130         [AES192-CCM128]="aes192ccm128"
131         [AES128-CCM128]="aes128ccm128"
132         [AES256-CCM96]="aes256ccm96"
133         [AES192-CCM96]="aes192ccm96"
134         [AES128-CCM96]="aes128ccm96"
135         [AES256-CCM64]="aes256ccm64"
136         [AES192-CCM64]="aes192ccm64"
137         [AES128-CCM64]="aes128ccm64"
138
139         # CAMELLIA-CBC
140         [CAMELLIA256-CBC]="camellia256"
141         [CAMELLIA192-CBC]="camellia192"
142         [CAMELLIA128-CBC]="camellia128"
143
144         # CAMELLIA-CTR
145         [CAMELLIA256-CTR]="camellia256ctr"
146         [CAMELLIA192-CTR]="camellia192ctr"
147         [CAMELLIA128-CTR]="camellia128ctr"
148
149         # CAMELLIA-GCM
150         [CAMELLIA256-GCM128]="camellia256gcm128"
151         [CAMELLIA192-GCM128]="camellia192gcm128"
152         [CAMELLIA128-GCM128]="camellia128gcm128"
153         [CAMELLIA256-GCM96]="camellia256gcm96"
154         [CAMELLIA192-GCM96]="camellia192gcm96"
155         [CAMELLIA128-GCM96]="camellia128gcm96"
156         [CAMELLIA256-GCM64]="camellia256gcm64"
157         [CAMELLIA192-GCM64]="camellia192gcm64"
158         [CAMELLIA128-GCM64]="camellia128gcm64"
159
160         # CAMELLIA-CCM
161         [CAMELLIA256-CCM128]="camellia256ccm128"
162         [CAMELLIA192-CCM128]="camellia192ccm128"
163         [CAMELLIA128-CCM128]="camellia128ccm128"
164         [CAMELLIA256-CCM96]="camellia256ccm96"
165         [CAMELLIA192-CCM96]="camellia192ccm96"
166         [CAMELLIA128-CCM96]="camellia128ccm96"
167         [CAMELLIA256-CCM64]="camellia256ccm64"
168         [CAMELLIA192-CCM64]="camellia192ccm64"
169         [CAMELLIA128-CCM64]="camellia128ccm64"
170
171         # DJB
172         [CHACHA20-POLY1305]="chacha20poly1305"
173
174         # No Encryption
175         [NULL]="null"
176 )
177
178 declare -A VPN_SUPPORTED_PSEUDO_RANDOM_FUNCTIONS=(
179         [MD5]="MD5"
180
181         # SHA
182         [SHA1]="SHA1"
183         [SHA256]="SHA256"
184         [SHA384]="SHA384"
185         [SHA512]="SHA512"
186
187         # AES
188         [AES-XCBC]="AES-XCBC"
189         [AES-CMAC]="AES-CMAC"
190 )
191
192 declare -A PSEUDO_RANDOM_FUNCTION_TO_STRONGSWAN=(
193         [MD5]="prfmd5"
194
195         # SHA
196         [SHA1]="prfsha1"
197         [SHA256]="prfsha256"
198         [SHA384]="prfsha384"
199         [SHA512]="prfsha512"
200
201         # AES
202         [AES-XCBC]="prfaesxcbc"
203         [AES-CMAC]="prfaescmac"
204 )
205
206 declare -A VPN_SUPPORTED_INTEGRITIES=(
207         [MD5]="MD5-HMAC"
208
209         # SHA
210         [SHA1]="SHA1-HMAC"
211         [SHA512]="512 bit SHA2-HMAC"
212         [SHA384]="384 bit SHA2-HMAC"
213         [SHA256]="256 bit SHA2-HMAC"
214
215         # AES
216         [AES-XCBC]="AES-XCBC"
217         [AES-CMAC]="AES-CMAC"
218         [AES256-GMAC]="256 bit AES-GMAC"
219         [AES192-GMAC]="192 bit AES-GMAC"
220         [AES128-GMAC]="128 bit AES-GMAC"
221 )
222
223 declare -A INTEGRITY_TO_STRONGSWAN=(
224         [MD5]="md5"
225
226         # SHA
227         [SHA1]="sha1"
228         [SHA512]="sha512"
229         [SHA384]="sha384"
230         [SHA256]="sha256"
231
232         # AES
233         [AES-XCBC]="aesxcbc"
234         [AES-CMAC]="aescmac"
235         [AES256-GMAC]="aes256gmac"
236         [AES192-GMAC]="aes192gmac"
237         [AES128-GMAC]="aes128gmac"
238 )
239
240 declare -A VPN_SUPPORTED_GROUP_TYPES=(
241         # Regular Groups
242         [MODP768]="768 bit Modulo Prime Group"
243         [MODP1024]="1024 bit Modulo Prime Group"
244         [MODP1536]="1536 bit Modulo Prime Group"
245         [MODP2048]="2048 bit Modulo Prime Group"
246         [MODP3072]="3072 bit Modulo Prime Group"
247         [MODP4096]="4096 bit Modulo Prime Group"
248         [MODP6144]="6144 bit Modulo Prime Group"
249         [MODP8192]="8192 bit Modulo Prime Group"
250
251         # NIST Elliptic Curve Groups
252         [ECP192]="192 bit NIST Elliptic Curve Group"
253         [ECP224]="224 bit NIST Elliptic Curve Group"
254         [ECP256]="256 bit NIST Elliptic Curve Group"
255         [ECP384]="384 bit NIST Elliptic Curve Group"
256         [ECP521]="521 bit NIST Elliptic Curve Group"
257
258         # Brainpool Elliptic Curve Groups
259         [ECP224BP]="224 bit Brainpool Elliptic Curve Group"
260         [ECP256BP]="256 bit Brainpool Elliptic Curve Group"
261         [ECP384BP]="384 bit Brainpool Elliptic Curve Group"
262         [ECP512BP]="512 bit Brainpool Elliptic Curve Group"
263
264         # Curve25519
265         [CURVE25519]="256 bit Elliptic Curve 25519"
266 )
267
268 declare -A GROUP_TYPE_TO_STRONGSWAN=(
269         # Regular Groups
270         [MODP768]="modp768"
271         [MODP1024]="modp1024"
272         [MODP1536]="modp1536"
273         [MODP2048]="modp2048"
274         [MODP3072]="modp3072"
275         [MODP4096]="modp4096"
276         [MODP6144]="modp6144"
277         [MODP8192]="modp8192"
278
279         # NIST Elliptic Curve Groups
280         [ECP192]="ecp192"
281         [ECP224]="ecp224"
282         [ECP256]="ecp256"
283         [ECP384]="ecp384"
284         [ECP521]="ecp521"
285
286         # Brainpool Elliptic Curve Groups
287         [ECP224BP]="ecp224bp"
288         [ECP256BP]="ecp256bp"
289         [ECP384BP]="ecp384bp"
290         [ECP512BP]="ecp512bp"
291
292         # Curve25519
293         [CURVE25519]="curve25519"
294 )
295
296 cli_vpn_security_policies() {
297         local action
298         local security_policy
299
300         if vpn_security_policy_exists ${1}; then
301                 security_policy=${1}
302                 key=${2}
303                 shift 2
304
305                 case "${key}" in
306                         ciphers|compression|integrities|lifetime|pfs|show)
307                                 vpn_security_policies_${key} ${security_policy} "$@"
308                                 ;;
309                         pseudo-random-functions)
310                                 vpn_security_policies_pseudo_random_functions "${security_policy}" "$@"
311                                 ;;
312                         group-types)
313                                 vpn_security_policies_group_types ${security_policy} "$@"
314                                 ;;
315                         key-exchange)
316                                 vpn_security_policies_key_exchange ${security_policy} "$@"
317                                 ;;
318                         *)
319                                 error "Unrecognized argument: ${key}"
320                                 exit ${EXIT_ERROR}
321                                 ;;
322                 esac
323         else
324                 action=${1}
325                 shift
326
327                 case "${action}" in
328                         new)
329                                 vpn_security_policies_new "$@"
330                                 ;;
331                         destroy)
332                                 vpn_security_policies_destroy "$@"
333                                 ;;
334                         ""|*)
335                                 if [ -n "${action}" ]; then
336                                         error "Unrecognized argument: '${action}'"
337                                 fi
338                                 exit ${EXIT_ERROR}
339                                 ;;
340                 esac
341         fi
342 }
343
344 # This functions checks if a policy is readonly
345 # returns true when yes and false when no
346 vpn_security_policies_check_readonly() {
347         if isoneof name ${VPN_SECURITY_POLICIES_READONLY}; then
348                 return ${EXIT_TRUE}
349         else
350                 return ${EXIT_FALSE}
351         fi
352 }
353
354 # This function writes all values to a via ${name} specificated vpn security policy configuration file
355 vpn_security_policies_write_config() {
356         assert [ $# -ge 1 ]
357
358         local name="${1}"
359
360         if ! vpn_security_policy_exists "${name}"; then
361                 log ERROR "No such vpn security policy: ${name}"
362                 return ${EXIT_ERROR}
363         fi
364
365         if vpn_security_policies_check_readonly "${name}"; then
366                 log ERROR "The ${name} vpn security policy cannot be changed."
367                 return ${EXIT_ERROR}
368         fi
369
370         local path="$(vpn_security_policies_path "${name}")"
371         if [ ! -w ${path} ]; then
372                 log ERROR "${path} is not writeable"
373                 return ${EXIT_ERROR}
374         fi
375
376         if ! settings_write "${path}" ${VPN_SECURITY_POLICIES_CONFIG_SETTINGS}; then
377                 log ERROR "Could not write configuration settings for vpn security policy ${name}"
378                 return ${EXIT_ERROR}
379         fi
380
381         if ! vpn_security_policies_reload ${name}; then
382                 log WARNING "Could not reload the IPsec connection using this security policy"
383                 return ${EXIT_ERROR}
384         fi
385 }
386
387 # reload IPsec connections using a special policy
388 vpn_security_policies_reload() {
389         local name=${1}
390
391         local connection
392         for connection in $(ipsec_list_connections); do
393                 local SECURITY_POLICY ENABLED
394
395                 if ! ipsec_connection_read_config "${connection}" "SECURITY_POLICY"; then
396                         continue
397                 fi
398
399                 if [[ "${SECURITY_POLICY}" = "${name}" ]] && enabled ENABLED; then
400                         if ! ipsec_connection_to_strongswan "${connection}"; then
401                                 log ERROR "Could not generate strongswan config for ${connnection}"
402                         fi
403                 fi
404         done
405
406         ipsec_strongswan_load
407 }
408
409 # This funtion writes the value for one key to a via ${name} specificated vpn security policy configuration file
410 vpn_security_policies_write_config_key() {
411         assert [ $# -ge 3 ]
412
413         local name=${1}
414         local key=${2}
415         shift 2
416
417         local value="$@"
418
419         if ! vpn_security_policy_exists "${name}"; then
420                 log ERROR "No such vpn security policy: ${name}"
421                 return ${EXIT_ERROR}
422         fi
423
424         log DEBUG "Set '${key}' to new value '${value}' in vpn security policy ${name}"
425
426         local ${VPN_SECURITY_POLICIES_CONFIG_SETTINGS}
427
428         # Read the config settings
429         if ! vpn_security_policies_read_config "${name}"; then
430                 return ${EXIT_ERROR}
431         fi
432
433         # Set the key to a new value
434         assign "${key}" "${value}"
435
436         if ! vpn_security_policies_write_config "${name}"; then
437                 return ${EXIT_ERROR}
438         fi
439
440         return ${EXIT_TRUE}
441 }
442
443 # Reads one or more keys out of a settings file or all if no key is provided.
444 vpn_security_policies_read_config() {
445         assert [ $# -ge 1 ]
446
447         local name="${1}"
448         shift 1
449
450         if ! vpn_security_policy_exists "${name}"; then
451                 log ERROR "No such vpn security policy: ${name}"
452                 return ${EXIT_ERROR}
453         fi
454
455
456         local args
457         if [ $# -eq 0 ] && [ -n "${VPN_SECURITY_POLICIES_CONFIG_SETTINGS}" ]; then
458                 list_append args ${VPN_SECURITY_POLICIES_CONFIG_SETTINGS}
459         else
460                 list_append args "$@"
461         fi
462
463         local path="$(vpn_security_policies_path ${name})"
464
465         if ! settings_read "${path}" ${args}; then
466                 log ERROR "Could not read settings for vpn security policy ${name}"
467                 return ${EXIT_ERROR}
468         fi
469 }
470
471 # Returns the path to a the configuration fora given name
472 vpn_security_policies_path() {
473         assert [ $# -eq 1 ]
474
475         local name=${1}
476
477         if vpn_security_policies_check_readonly "${name}"; then
478                 echo "${NETWORK_SHARE_DIR}/vpn/security-policies/${name}"
479         else
480                 echo "${NETWORK_CONFIG_DIR}/vpn/security-policies/${name}"
481         fi
482 }
483
484 # Print the content of a vpn security policy configuration file in a nice way
485 vpn_security_policies_show() {
486         assert [ $# -eq 1 ]
487
488         local name=${1}
489
490         local ${VPN_SECURITY_POLICIES_CONFIG_SETTINGS}
491         if ! vpn_security_policies_read_config ${name}; then
492                 return ${EXIT_ERROR}
493         fi
494
495         cli_print_fmt1 0 "Security Policy: ${name}"
496         cli_space
497
498         # This could be done in a loop but a loop is much more complicated
499         # because we print 'Group Types' but the variable is named 'GROUP_TYPES'
500         cli_print_fmt1 1 "Ciphers:"
501         local cipher
502         for cipher in ${CIPHERS}; do
503                 cli_print_fmt1 2 "${VPN_SUPPORTED_CIPHERS[${cipher}]-${cipher}}"
504         done
505         cli_space
506
507         cli_print_fmt1 1 "Integrity:"
508         local integrity
509         for integrity in ${INTEGRITIES}; do
510                 cli_print_fmt1 2 "${VPN_SUPPORTED_INTEGRITIES[${integrity}]-${integrity}}"
511         done
512         cli_space
513
514         cli_print_fmt1 1 "Pseudo Random Functions:"
515         local prf
516         for prf in ${PSEUDO_RANDOM_FUNCTIONS}; do
517                 cli_print_fmt1 2 "${VPN_SUPPORTED_PSEUDO_RANDOM_FUNCTIONS[${prf}]-${prf}}"
518         done
519         cli_space
520
521         cli_print_fmt1 1 "Group Types:"
522         local group_type
523         for group_type in ${GROUP_TYPES}; do
524                 cli_print_fmt1 2 "${VPN_SUPPORTED_GROUP_TYPES[${group_type}]-${group_type}}"
525         done
526         cli_space
527
528         cli_print_fmt1 1 "Key Exchange:" "${KEY_EXCHANGE}"
529
530         # Key Lifetime
531         if isinteger LIFETIME && [ ${LIFETIME} -gt 0 ]; then
532                 cli_print_fmt1 1 "Key Lifetime:" "$(format_time ${LIFETIME})"
533         else
534                 log ERROR "The value for Key Lifetime is not a valid integer greater zero."
535         fi
536
537         # PFS
538         if enabled PFS; then
539                 cli_print_fmt1 1 "Perfect Forward Secrecy:" "enabled"
540         else
541                 cli_print_fmt1 1 "Perfect Forward Secrecy:" "disabled"
542         fi
543         cli_space
544
545         # Compression
546         if enabled COMPRESSION; then
547                 cli_print_fmt1 1 "Compression:" "enabled"
548         else
549                 cli_print_fmt1 1 "Compression:" "disabled"
550         fi
551         cli_space
552 }
553
554 # This function checks if a vpn security policy exists
555 # Returns True when yes and false when not
556 vpn_security_policy_exists() {
557         assert [ $# -eq 1 ]
558
559         local name=${1}
560
561         local path=$(vpn_security_policies_path "${name}")
562
563         [ -f ${path} ] && return ${EXIT_TRUE} || return ${EXIT_FALSE}
564 }
565
566
567 # This function parses the parameters for the 'cipher' command
568 vpn_security_policies_ciphers() {
569         local name=${1}
570         shift
571
572         if [ $# -eq 0 ]; then
573                 log ERROR "You must pass at least one value after cipher"
574                 return ${EXIT_ERROR}
575         fi
576
577         local CIPHERS
578         if ! vpn_security_policies_read_config ${name} "CIPHERS"; then
579                 return ${EXIT_ERROR}
580         fi
581
582         # Remove duplicated entries to proceed the list safely
583         CIPHERS="$(list_unique ${CIPHERS})"
584
585         local ciphers_added
586         local ciphers_removed
587         local ciphers_set
588
589         while [ $# -gt 0 ]; do
590                 local arg="${1}"
591
592                 case "${arg}" in
593                         +*)
594                                 list_append ciphers_added "${arg:1}"
595                                 ;;
596                         -*)
597                                 list_append ciphers_removed "${arg:1}"
598                                 ;;
599                         [A-Z0-9]*)
600                                 list_append ciphers_set "${arg}"
601                                 ;;
602                         *)
603                                 error "Invalid argument: ${arg}"
604                                 return ${EXIT_ERROR}
605                                 ;;
606                 esac
607                 shift
608         done
609
610         # Check if the user is trying a mixed operation
611         if ! list_is_empty ciphers_set && (! list_is_empty ciphers_added || ! list_is_empty ciphers_removed); then
612                 error "You cannot reset the cipher list and add or remove ciphers at the same time"
613                 return ${EXIT_ERROR}
614         fi
615
616         # Set new cipher list
617         if ! list_is_empty ciphers_set; then
618                 # Check if all ciphers are valid
619                 local cipher
620                 for cipher in ${ciphers_set}; do
621                         if ! vpn_security_policies_cipher_supported ${cipher}; then
622                                 error "Unsupported cipher: ${cipher}"
623                                 return ${EXIT_ERROR}
624                         fi
625                 done
626
627                 CIPHERS="${ciphers_set}"
628
629         # Perform incremental updates
630         else
631                 local cipher
632
633                 # Perform all removals
634                 for cipher in ${ciphers_removed}; do
635                         if ! list_remove CIPHERS ${cipher}; then
636                                 warning "${cipher} was not on the list and could not be removed"
637                         fi
638                 done
639
640                 for cipher in ${ciphers_added}; do
641                         if vpn_security_policies_cipher_supported ${cipher}; then
642                                 if ! list_append_unique CIPHERS ${cipher}; then
643                                         warning "${cipher} is already on the cipher list"
644                                 fi
645                         else
646                                 warning "${cipher} is unknown or unsupported and could not be added"
647                         fi
648                 done
649         fi
650
651         # Check if the list contain at least one valid cipher
652         if list_is_empty CIPHERS; then
653                 error "Cannot save an empty cipher list"
654                 return ${EXIT_ERROR}
655         fi
656
657         # Save everything
658         if ! vpn_security_policies_write_config_key ${name} "CIPHERS" ${CIPHERS}; then
659                 log ERROR "The changes for the vpn security policy ${name} could not be written."
660         fi
661
662         cli_headline 1 "Current cipher list for ${name}:"
663         for cipher in ${CIPHERS}; do
664                 cli_print_fmt1 1 "${cipher}" "${VPN_SUPPORTED_CIPHERS[${cipher}]}"
665         done
666 }
667
668 # This function parses the parameters for the 'compression' command
669 vpn_security_policies_compression(){
670         local name=${1}
671         local value=${2}
672
673         # Check if we get only one argument after compression <name>
674         if [ ! $# -eq 2 ]; then
675                 log ERROR "The number of arguments do not match. Only one argument after compression is allowed."
676                 return ${EXIT_ERROR}
677         fi
678
679         if ! isbool value; then
680                 # We suggest only two values to avoid overburding the user.
681                 log ERROR "Invalid Argument ${value}"
682                 return ${EXIT_ERROR}
683         fi
684
685         vpn_security_policies_write_config_key "${name}" "COMPRESSION" "${value}"
686 }
687
688 # This function parses the parameters for the 'group-type' command
689 vpn_security_policies_group_types() {
690         local name=${1}
691         shift
692
693         if [ $# -eq 0 ]; then
694                 log ERROR "You must pass at least one value after group-type"
695                 return ${EXIT_ERROR}
696         fi
697
698         local GROUP_TYPES
699         if ! vpn_security_policies_read_config ${name} "GROUP_TYPES"; then
700                 return ${EXIT_ERROR}
701         fi
702
703         # Remove duplicated entries to proceed the list safely
704         GROUP_TYPES="$(list_unique ${GROUP_TYPES})"
705
706         local group_types_added
707         local group_types_removed
708         local group_types_set
709
710         while [ $# -gt 0 ]; do
711                 local arg="${1}"
712
713                 case "${arg}" in
714                         +*)
715                                 list_append group_types_added "${arg:1}"
716                                 ;;
717                         -*)
718                                 list_append group_types_removed "${arg:1}"
719                                 ;;
720                         [A-Z0-9]*)
721                                 list_append group_types_set "${arg}"
722                                 ;;
723                         *)
724                                 error "Invalid argument: ${arg}"
725                                 return ${EXIT_ERROR}
726                                 ;;
727                 esac
728                 shift
729         done
730
731         # Check if the user is trying a mixed operation
732         if ! list_is_empty group_types_set && (! list_is_empty group_types_added || ! list_is_empty group_types_removed); then
733                 error "You cannot reset the group type list and add or remove group types at the same time"
734                 return ${EXIT_ERROR}
735         fi
736
737         # Set new group type list
738         if ! list_is_empty group_types_set; then
739                 # Check if all group types are valid
740                 local group_type
741                 for group_type in ${group_types_set}; do
742                         if ! vpn_security_policies_group_type_supported ${group_type}; then
743                                 error "Unsupported group type: ${group_type}"
744                                 return ${EXIT_ERROR}
745                         fi
746                 done
747
748                 GROUP_TYPES="${group_types_set}"
749
750         # Perform incremental updates
751         else
752                 local group_type
753
754                 # Perform all removals
755                 for group_type in ${group_types_removed}; do
756                         if ! list_remove GROUP_TYPES ${group_type}; then
757                                 warning "${group_type} was not on the list and could not be removed"
758                         fi
759                 done
760
761                 for group_type in ${group_types_added}; do
762                         if vpn_security_policies_group_type_supported ${group_type}; then
763                                 if ! list_append_unique GROUP_TYPES ${group_type}; then
764                                         warning "${group_type} is already on the group type list"
765                                 fi
766                         else
767                                 warning "${group_type} is unknown or unsupported and could not be added"
768                         fi
769                 done
770         fi
771
772         # Check if the list contain at least one valid group_type
773         if list_is_empty GROUP_TYPES; then
774                 error "Cannot save an empty group type list"
775                 return ${EXIT_ERROR}
776         fi
777
778         # Save everything
779         if ! vpn_security_policies_write_config_key ${name} "GROUP_TYPES" ${GROUP_TYPES}; then
780                 log ERROR "The changes for the vpn security policy ${name} could not be written."
781         fi
782
783         cli_headline 1 "Current group type list for ${name}:"
784         for group_type in ${GROUP_TYPES}; do
785                 cli_print_fmt1 1 "${group_type}" "${VPN_SUPPORTED_GROUP_TYPES[${group_type}]}"
786         done
787 }
788
789 # This function parses the parameters for the 'integrity' command
790 vpn_security_policies_integrities() {
791         local name=${1}
792         shift
793
794         if [ $# -eq 0 ]; then
795                 log ERROR "You must pass at least one value"
796                 return ${EXIT_ERROR}
797         fi
798
799         local INTEGRITIES
800         if ! vpn_security_policies_read_config ${name} "INTEGRITIES"; then
801                 return ${EXIT_ERROR}
802         fi
803
804         # Remove duplicated entries to proceed the list safely
805         INTEGRITIES="$(list_unique ${INTEGRITIES})"
806
807         local integritys_added
808         local integritys_removed
809         local integritys_set
810
811         while [ $# -gt 0 ]; do
812                 local arg="${1}"
813
814                 case "${arg}" in
815                         +*)
816                                 list_append integritys_added "${arg:1}"
817                                 ;;
818                         -*)
819                                 list_append integritys_removed "${arg:1}"
820                                 ;;
821                         [A-Z0-9]*)
822                                 list_append integritys_set "${arg}"
823                                 ;;
824                         *)
825                                 error "Invalid argument: ${arg}"
826                                 return ${EXIT_ERROR}
827                                 ;;
828                 esac
829                 shift
830         done
831
832         # Check if the user is trying a mixed operation
833         if ! list_is_empty integritys_set && (! list_is_empty integritys_added || ! list_is_empty integritys_removed); then
834                 error "You cannot reset the integrity hashes list and add or remove integrity hashes at the same time"
835                 return ${EXIT_ERROR}
836         fi
837
838         # Set new integrity list
839         if ! list_is_empty integritys_set; then
840                 # Check if all integrity hashes are valid
841                 local integrity
842                 for integrity in ${integritys_set}; do
843                         if ! vpn_security_policies_integrity_supported ${integrity}; then
844                                 error "Unsupported integrity hash: ${integrity}"
845                                 return ${EXIT_ERROR}
846                         fi
847                 done
848
849                 INTEGRITIES="${integritys_set}"
850
851         # Perform incremental updates
852         else
853                 local integrity
854
855                 # Perform all removals
856                 for integrity in ${integritys_removed}; do
857                         if ! list_remove INTEGRITIES ${integrity}; then
858                                 warning "${integrity} was not on the list and could not be removed"
859                         fi
860                 done
861
862                 for integrity in ${integritys_added}; do
863                         if vpn_security_policies_integrity_supported ${integrity}; then
864                                 if ! list_append_unique INTEGRITIES ${integrity}; then
865                                         warning "${integrity} is already on the integrity list"
866                                 fi
867                         else
868                                 warning "${integrity} is unknown or unsupported and could not be added"
869                         fi
870                 done
871         fi
872
873         # Check if the list contain at least one valid integrity
874         if list_is_empty INTEGRITIES; then
875                 error "Cannot save an empty integrity hashes list"
876                 return ${EXIT_ERROR}
877         fi
878
879         # Save everything
880         if ! vpn_security_policies_write_config_key ${name} "INTEGRITIES" ${INTEGRITIES}; then
881                 log ERROR "The changes for the vpn security policy ${name} could not be written."
882         fi
883
884         cli_headline 1 "Current integrity hashes list for ${name}:"
885         for integrity in ${INTEGRITIES}; do
886                 cli_print_fmt1 1 "${integrity}" "${VPN_SUPPORTED_INTEGRITIES[${integrity}]}"
887         done
888 }
889
890 # This function parses the parameters for the 'pseudo-random-functions' command
891 vpn_security_policies_pseudo_random_functions() {
892         local name=${1}
893         shift
894
895         if [ $# -eq 0 ]; then
896                 log ERROR "You must pass at least one value"
897                 return ${EXIT_ERROR}
898         fi
899
900         local PSEUDO_RANDOM_FUNCTIONS
901         if ! vpn_security_policies_read_config ${name} "PSEUDO_RANDOM_FUNCTIONS"; then
902                 return ${EXIT_ERROR}
903         fi
904
905         # Remove duplicated entries to proceed the list safely
906         PSEUDO_RANDOM_FUNCTIONS="$(list_unique ${PSEUDO_RANDOM_FUNCTIONS})"
907
908         local prfs_added
909         local prfs_removed
910         local prfs_set
911
912         while [ $# -gt 0 ]; do
913                 local arg="${1}"
914
915                 case "${arg}" in
916                         +*)
917                                 list_append prfs_added "${arg:1}"
918                                 ;;
919                         -*)
920                                 list_append prfs_removed "${arg:1}"
921                                 ;;
922                         [A-Z0-9]*)
923                                 list_append prfs_set "${arg}"
924                                 ;;
925                         *)
926                                 error "Invalid argument: ${arg}"
927                                 return ${EXIT_ERROR}
928                                 ;;
929                 esac
930                 shift
931         done
932
933         # Check if the user is trying a mixed operation
934         if ! list_is_empty prfs_set && (! list_is_empty prfs_added || ! list_is_empty prfs_removed); then
935                 error "You cannot reset the pseudo random function list and add or remove functions at the same time"
936                 return ${EXIT_ERROR}
937         fi
938
939         # Set new psudo random function list
940         if ! list_is_empty prfs_set; then
941                 # Check if all PRFs are valid
942                 local prf
943                 for prf in ${prfs_set}; do
944                         if ! vpn_security_policies_pseudo_random_function_supported "${prf}"; then
945                                 error "Unsupported pseudo random function: ${prf}"
946                                 return ${EXIT_ERROR}
947                         fi
948                 done
949
950                 PSEUDO_RANDOM_FUNCTIONS="${prfs_set}"
951
952         # Perform incremental updates
953         else
954                 local prf
955
956                 # Perform all removals
957                 for prf in ${prfs_removed}; do
958                         if ! list_remove PSEUDO_RANDOM_FUNCTIONS "${prf}"; then
959                                 warning "${prf} was not on the list and could not be removed"
960                         fi
961                 done
962
963                 for prf in ${prfs_added}; do
964                         if vpn_security_policies_pseudo_random_function_supported "${prf}"; then
965                                 if ! list_append_unique PSEUDO_RANDOM_FUNCTIONS "${prf}"; then
966                                         warning "${prf} is already on the list"
967                                 fi
968                         else
969                                 warning "${prf} is unknown or unsupported and could not be added"
970                         fi
971                 done
972         fi
973
974         # Check if the list contain at least one valid value
975         if list_is_empty PSEUDO_RANDOM_FUNCTIONS; then
976                 error "Cannot save an empty list of pseudo random functions"
977                 return ${EXIT_ERROR}
978         fi
979
980         # Save everything
981         if ! vpn_security_policies_write_config_key "${name}" "PSEUDO_RANDOM_FUNCTIONS" "${PSEUDO_RANDOM_FUNCTIONS}"; then
982                 log ERROR "The changes for the VPN security policy ${name} could not be written"
983         fi
984
985         cli_headline 1 "Current pseudo random function list for ${name}:"
986         for prf in ${PSEUDO_RANDOM_FUNCTIONS}; do
987                 cli_print_fmt1 1 "${prf}" "${VPN_SUPPORTED_PSEUDO_RANDOM_FUNCTIONS[${prf}]}"
988         done
989 }
990
991 # This function parses the parameters for the 'key-exchange' command
992 vpn_security_policies_key_exchange() {
993         local name=${1}
994         local value=${2}
995
996         # Check if we get only one argument after key-exchange <name>
997         if [ ! $# -eq 2 ]; then
998                 log ERROR "The number of arguments do not match. Only argument after key-exchange is allowed."
999                 return ${EXIT_ERROR}
1000         fi
1001
1002         if ! isoneof value "ikev1" "ikev2" "IKEV1" "IKEV2"; then
1003                 log ERROR "Invalid Argument ${value}"
1004                 return ${EXIT_ERROR}
1005         fi
1006
1007         vpn_security_policies_write_config_key "${name}" "KEY_EXCHANGE" "${value,,}"
1008 }
1009
1010 # This function parses the parameters for the 'lifetime' command.
1011 vpn_security_policies_lifetime(){
1012         local name=${1}
1013         shift
1014
1015         local value=$@
1016
1017         # Check if we get only one argument after lifetime <name>
1018         if [ ! $# -ge 1 ]; then
1019                 log ERROR "The number of arguments do not match you must provide at least one integer value or a valid time with the format  <hours>h <minutes>m <seconds>s"
1020                 return ${EXIT_ERROR}
1021         fi
1022
1023         if ! isinteger value; then
1024                 value=$(parse_time "$@")
1025                 if [ ! $? -eq 0 ]; then
1026                         log ERROR "Parsing the passed time was not sucessful please check the passed values."
1027                         return ${EXIT_ERROR}
1028                 fi
1029         fi
1030
1031         if [ ${value} -le 0 ]; then
1032                 log ERROR "The passed time value must be in the sum greater zero seconds."
1033                 return ${EXIT_ERROR}
1034         fi
1035
1036         vpn_security_policies_write_config_key "${name}" "LIFETIME" "${value}"
1037 }
1038
1039 # This function parses the parameters for the 'pfs' command
1040 vpn_security_policies_pfs(){
1041         local name=${1}
1042         local value=${2}
1043
1044         # Check if we get only one argument after pfs <name>
1045         if [ ! $# -eq 2 ]; then
1046                 log ERROR "The number of arguments do not match. Only argument after pfs is allowed."
1047                 return ${EXIT_ERROR}
1048         fi
1049
1050         if [ ! $# -eq 2 ] || ! isbool value; then
1051                 # We suggest only two values to avoid overburding the user.
1052                 log ERROR "Invalid Argument ${value}"
1053                 return ${EXIT_ERROR}
1054         fi
1055
1056         vpn_security_policies_write_config_key "${name}" "PFS" "${value}"
1057 }
1058
1059 # This function checks if a vpn security policy name is valid
1060 # Allowed are only A-Za-z0-9
1061 vpn_security_policies_check_name() {
1062         assert [ $# -eq 1 ]
1063
1064         local name=${1}
1065
1066         [[ ${name} =~ [^[:alnum:]$] ]]
1067 }
1068
1069 # Function that creates based on the paramters one ore more new vpn security policies
1070 vpn_security_policies_new() {
1071         if [ $# -gt 1 ]; then
1072                 error "Too many arguments"
1073                 return ${EXIT_ERROR}
1074         fi
1075
1076         local name="${1}"
1077         if ! isset name; then
1078                 error "Please provide a name"
1079                 return ${EXIT_ERROR}
1080         fi
1081
1082         # Check for duplicates
1083         if vpn_security_policy_exists "${name}"; then
1084                 error "The VPN security policy with name ${name} already exists"
1085                 return ${EXIT_ERROR}
1086         fi
1087
1088         # Check if name is valid
1089         if  vpn_security_policies_check_name "${name}"; then
1090                 error "'${name}' contains illegal characters"
1091                 return ${EXIT_ERROR}
1092         fi
1093
1094         # Check if we have a read-only policy with the same name
1095         if vpn_security_policies_check_readonly "${name}"; then
1096                 error "The VPN security policy ${name} is read-only"
1097                 return ${EXIT_ERROR}
1098         fi
1099
1100         # Check if our source policy exists
1101         if ! vpn_security_policy_exists "${VPN_DEFAULT_SECURITY_POLICY}"; then
1102                 error "Default VPN Security Policy '${VPN_DEFAULT_SECURITY_POLICY}' does not exist"
1103                 return ${EXIT_ERROR}
1104         fi
1105
1106         log DEBUG "Creating VPN Security Policy ${name}"
1107
1108         if copy "$(vpn_security_policies_path "${VPN_DEFAULT_SECURITY_POLICY}")" \
1109                         "$(vpn_security_policies_path ${name})"; then
1110                 log INFO "VPN Security Policy ${name} successfully created"
1111         else
1112                 log ERROR "Could not create VPN Security Policy ${name}"
1113                 return ${EXIT_ERROR}
1114         fi
1115
1116         # Show the newly created policy
1117         vpn_security_policies_show "${name}"
1118 }
1119
1120 # Function that deletes based on the passed parameters one ore more vpn security policies
1121 vpn_security_policies_destroy() {
1122         local name
1123         for name in "$@"; do
1124                 if ! vpn_security_policy_exists ${name}; then
1125                         log ERROR "The vpn security policy ${name} does not exist."
1126                         continue
1127                 fi
1128
1129                 if vpn_security_policies_check_readonly ${name}; then
1130                         log ERROR "The vpn security policy ${name} cannot be deleted."
1131                         continue
1132                 fi
1133
1134                 log DEBUG "Deleting vpn security policy ${name}"
1135                 settings_remove $(vpn_security_policies_path ${name})
1136
1137                 # Delete cache
1138                 rm -rf "${NETWORK_CACHE_DIR}/vpn/security-policies/${name}"
1139         done
1140 }
1141
1142 vpn_security_policies_cipher_supported() {
1143         local cipher=${1}
1144
1145         list_match ${cipher} ${!VPN_SUPPORTED_CIPHERS[@]}
1146 }
1147
1148
1149 vpn_security_policies_group_type_supported() {
1150         local group_type=${1}
1151
1152         list_match ${group_type} ${!VPN_SUPPORTED_GROUP_TYPES[@]}
1153 }
1154
1155 vpn_security_policies_integrity_supported() {
1156         local integrity=${1}
1157
1158         list_match ${integrity} ${!VPN_SUPPORTED_INTEGRITIES[@]}
1159 }
1160
1161 vpn_security_policies_pseudo_random_function_supported() {
1162         local prf="${1}"
1163
1164         list_match "${prf}" ${!VPN_SUPPORTED_PSEUDO_RANDOM_FUNCTIONS[@]}
1165 }
1166
1167 vpn_security_policies_cipher_is_aead() {
1168         local cipher=${1}
1169
1170         # All CCM and GCM ciphers are AEAD
1171         if string_match "[CG]CM" "${cipher}"; then
1172                 return ${EXIT_TRUE}
1173         fi
1174
1175         # Poly1305 is AEAD
1176         if string_match "POLY1305" "${cipher}"; then
1177                 return ${EXIT_TRUE}
1178         fi
1179
1180         return ${EXIT_FALSE}
1181 }
1182
1183 vpn_security_policies_make_ike_proposal() {
1184         local name=${1}
1185
1186         if ! vpn_security_policy_exists ${name}; then
1187                 return ${EXIT_ERROR}
1188         fi
1189
1190         local config_path="$(vpn_security_policies_path ${name})"
1191         local cache_path="${NETWORK_CACHE_DIR}/vpn/security-policies/${name}/ike-proposal"
1192
1193         # Get data from cache if possible
1194         if file_exists "${cache_path}" && ! file_is_newer_than "${config_path}" "${cache_path}"; then
1195                 fread "${cache_path}"
1196                 return ${EXIT_OK}
1197         fi
1198
1199         # No or invalid cache data found
1200         local proposal=$(_vpn_security_policies_make_ike_proposal "${name}")
1201
1202         # Write proposal to cache
1203         if ! make_parent_directory "${cache_path}" || ! fwrite "${cache_path}" "${proposal}"; then
1204                 log WARNING "Could not write to cache: ${cache_path}"
1205         fi
1206
1207         print "${proposal}"
1208 }
1209
1210 _vpn_security_policies_make_ike_proposal() {
1211         local name=${1}
1212
1213         # Read the config settings
1214         local ${VPN_SECURITY_POLICIES_CONFIG_SETTINGS}
1215         if ! vpn_security_policies_read_config "${name}"; then
1216                 return ${EXIT_ERROR}
1217         fi
1218
1219         local proposals
1220
1221         local cipher
1222         for cipher in ${CIPHERS}; do
1223                 # Translate cipher
1224                 local _cipher=${CIPHER_TO_STRONGSWAN[${cipher}]}
1225
1226                 if ! isset _cipher; then
1227                         log WARN "Unsupported cipher: ${cipher}"
1228                         continue
1229                 fi
1230
1231                 if vpn_security_policies_cipher_is_aead "${cipher}"; then
1232                         local prf
1233                         for prf in ${PSEUDO_RANDOM_FUNCTIONS}; do
1234                                 local _prf="${PSEUDO_RANDOM_FUNCTION_TO_STRONGSWAN[${prf}]}"
1235
1236                                 if ! isset _prf; then
1237                                         log WARN "Unsupported pseudo random function: ${prf}"
1238                                         continue
1239                                 fi
1240
1241                                 local group_type
1242                                 for group_type in ${GROUP_TYPES}; do
1243                                         local _group_type=${GROUP_TYPE_TO_STRONGSWAN[${group_type}]}
1244
1245                                         if ! isset _group_type; then
1246                                                 log WARN "Unsupported group-type: ${group_type}"
1247                                                 continue
1248                                         fi
1249
1250                                         # Put everything together
1251                                         list_append proposals "${_cipher}-${_prf}-${_group_type}"
1252                                 done
1253                         done
1254                 else
1255                         local integrity
1256                         for integrity in ${INTEGRITIES}; do
1257                                 local _integrity=${INTEGRITY_TO_STRONGSWAN[${integrity}]}
1258
1259                                 if ! isset _integrity; then
1260                                         log WARN "Unsupported integrity: ${integrity}"
1261                                         continue
1262                                 fi
1263
1264                                 local group_type
1265                                 for group_type in ${GROUP_TYPES}; do
1266                                         local _group_type=${GROUP_TYPE_TO_STRONGSWAN[${group_type}]}
1267
1268                                         if ! isset _group_type; then
1269                                                 log WARN "Unsupported group-type: ${group_type}"
1270                                                 continue
1271                                         fi
1272
1273                                         # Put everything together
1274                                         list_append proposals "${_cipher}-${_integrity}-${_group_type}"
1275                                 done
1276                         done
1277                 fi
1278         done
1279
1280         # Returns as a comma-separated list
1281         list_join proposals ,
1282 }
1283
1284 vpn_security_policies_make_esp_proposal() {
1285         local name=${1}
1286
1287         if ! vpn_security_policy_exists ${name}; then
1288                 return ${EXIT_ERROR}
1289         fi
1290
1291         local config_path="$(vpn_security_policies_path ${name})"
1292         local cache_path="${NETWORK_CACHE_DIR}/vpn/security-policies/${name}/esp-proposal"
1293
1294         # Get data from cache if possible
1295         if file_exists "${cache_path}" && ! file_is_newer_than "${config_path}" "${cache_path}"; then
1296                 fread "${cache_path}"
1297                 return ${EXIT_OK}
1298         fi
1299
1300         # No or invalid cache data found
1301         local proposal=$(_vpn_security_policies_make_esp_proposal "${name}")
1302
1303         # Write proposal to cache
1304         if ! make_parent_directory "${cache_path}" || ! fwrite "${cache_path}" "${proposal}"; then
1305                 log WARNING "Could not write to cache: ${cache_path}"
1306         fi
1307
1308         print "${proposal}"
1309 }
1310
1311 _vpn_security_policies_make_esp_proposal() {
1312         local name=${1}
1313
1314         # Read the config settings
1315         local ${VPN_SECURITY_POLICIES_CONFIG_SETTINGS}
1316         if ! vpn_security_policies_read_config "${name}"; then
1317                 return ${EXIT_ERROR}
1318         fi
1319
1320         local proposals
1321
1322         local cipher
1323         for cipher in ${CIPHERS}; do
1324                 # Translate cipher
1325                 local _cipher=${CIPHER_TO_STRONGSWAN[${cipher}]}
1326
1327                 if ! isset _cipher; then
1328                         log WARN "Unsupported cipher: ${cipher}"
1329                         continue
1330                 fi
1331
1332                 if vpn_security_policies_cipher_is_aead ${cipher}; then
1333                         local group_type
1334                         for group_type in ${GROUP_TYPES}; do
1335                                 local _group_type=${GROUP_TYPE_TO_STRONGSWAN[${group_type}]}
1336
1337                                 if ! isset _group_type; then
1338                                         log WARN "Unsupported group-type: ${group_type}"
1339                                         continue
1340                                 fi
1341
1342                                 # Put everything together
1343                                 list_append proposals "${_cipher}-${_group_type}"
1344                         done
1345                 else
1346                         local integrity
1347                         for integrity in ${INTEGRITIES}; do
1348                                 local _integrity=${INTEGRITY_TO_STRONGSWAN[${integrity}]}
1349
1350                                 if ! isset _integrity; then
1351                                         log WARN "Unsupported integrity: ${integrity}"
1352                                         continue
1353                                 fi
1354
1355                                 local group_type
1356                                 for group_type in ${GROUP_TYPES}; do
1357                                         local _group_type=${GROUP_TYPE_TO_STRONGSWAN[${group_type}]}
1358
1359                                         if ! isset _group_type; then
1360                                                 log WARN "Unsupported group-type: ${group_type}"
1361                                                 continue
1362                                         fi
1363
1364                                         # Put everything together
1365                                         list_append proposals "${_cipher}-${_integrity}-${_group_type}"
1366                                 done
1367                         done
1368                 fi
1369         done
1370
1371         # Returns as a comma-separated list
1372         list_join proposals ,
1373 }
1374
1375 # List all security policies
1376 vpn_security_policies_list_all() {
1377         list_directory "${NETWORK_SHARE_DIR}/vpn/security-policies"
1378
1379         # Add all user-defined policies
1380         vpn_security_policies_list_user
1381 }
1382
1383 vpn_security_policies_list_user() {
1384         list_directory "${NETWORK_CONFIG_DIR}/vpn/security-policies"
1385 }