]> git.ipfire.org Git - people/ms/network.git/blame - src/functions/functions.ipsec
Introduce list_directory
[people/ms/network.git] / src / functions / functions.ipsec
CommitLineData
917a1aa0
JS
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
33944dfb
MT
22IPSEC_CONNECTION_CONFIG_SETTINGS="\
23 AUTH_MODE \
24 DPD_ACTION \
25 DPD_DELAY \
26 DPD_TIMEOUT \
27 INACTIVITY_TIMEOUT \
28 LOCAL_ADDRESS \
29 LOCAL_ID \
30 LOCAL_PREFIX \
31 MODE \
32 PEER \
96fdb077 33 POOLS \
33944dfb
MT
34 PSK \
35 REMOTE_ID \
36 REMOTE_PREFIX \
5601f4f5 37 SECURITY_POLICY \
eb6fa666 38 START_ACTION \
89d71d08 39 TYPE \
5601f4f5 40 ENABLED"
917a1aa0
JS
41
42# Default values
ab589039 43IPSEC_DEFAULT_AUTH_MODE="PSK"
bb9fccaf
JS
44IPSEC_DEFAULT_DPD_ACTION="restart"
45IPSEC_DEFAULT_DPD_DELAY="30"
46IPSEC_DEFAULT_DPD_TIMEOUT="120"
5601f4f5 47IPSEC_DEFAULT_ENABLED="true"
917a1aa0 48IPSEC_DEFAULT_INACTIVITY_TIMEOUT="0"
bb9fccaf 49IPSEC_DEFAULT_MODE="tunnel"
917a1aa0 50IPSEC_DEFAULT_SECURITY_POLICY="system"
bb9fccaf 51IPSEC_DEFAULT_START_ACTION="on-demand"
89d71d08 52IPSEC_DEFAULT_TYPE="net-to-net"
917a1aa0
JS
53
54IPSEC_VALID_MODES="gre-transport tunnel vti"
ab589039 55IPSEC_VALID_AUTH_MODES="PSK"
917a1aa0 56
2da98f56
MT
57cli_ipsec() {
58 local action=${1}
59 shift 1
60
61 case "${action}" in
62 connection)
2212045f 63 cli_ipsec_connection "$@"
2da98f56 64 ;;
7c623df2 65 pool)
2212045f 66 cli_ipsec_pool "$@"
7c623df2 67 ;;
2da98f56
MT
68 *)
69 error "Unrecognized argument: ${action}"
70 exit ${EXIT_ERROR}
71 ;;
72 esac
73}
74
75cli_ipsec_connection() {
76 if ipsec_connection_exists ${1}; then
77 local connection=${1}
78 local key=${2}
79 key=${key//-/_}
80 shift 2
81
82 case "${key}" in
96fdb077 83 authentication|down|disable|dpd|enable|inactivity_timeout|local|mode|peer|pool|remote|security_policy|start_action|up)
2212045f 84 ipsec_connection_${key} ${connection} "$@"
2da98f56 85 ;;
5bcadc60
JS
86 color)
87 color_cli "ipsec-connection" "${connection}" "$@"
88 ;;
dc5dcfaf
JS
89 description)
90 description_cli "ipsec-connection" ${connection} $@
91 ;;
c1e76e97
MT
92 show)
93 cli_ipsec_connection_show "${connection}"
94 exit $?
95 ;;
2da98f56
MT
96 *)
97 error "Unrecognized argument: ${key}"
98 exit ${EXIT_ERROR}
99 ;;
100 esac
101 else
102 local action=${1}
103 shift
104
105 case "${action}" in
106 new)
2212045f 107 ipsec_connection_new "$@"
2da98f56
MT
108 ;;
109 destroy)
2212045f 110 cli_ipsec_connection_destroy "$@"
2da98f56
MT
111 ;;
112 ""|*)
113 if [ -n "${action}" ]; then
114 error "Unrecognized argument: '${action}'"
115 fi
116 exit ${EXIT_ERROR}
117 ;;
118 esac
119 fi
120}
121
fa33d830
MT
122cli_ipsec_connection_destroy() {
123 local connection="${1}"
124
125 if ! ipsec_connection_destroy "${connection}"; then
126 return ${EXIT_ERROR}
127 fi
128
129 # Inform strongswan about the changes
130 ipsec_strongswan_load
131
132 # Configure strongswan autostart
133 ipsec_strongswan_autostart
134}
135
5bcadc60
JS
136ipsec_connection_get_color() {
137 # This function return the color of a zone
138 assert [ $# -eq 1 ]
139
140 local name=${1}
141 color_read "ipsec-connection" ${name}
142}
143
dc5dcfaf
JS
144ipsec_connection_get_description_title() {
145 assert [ $# -eq 1 ]
146
147 local name=${1}
148 description_title_read $(description_format_filename "ipsec-connection" "${name}")
149}
150
c1e76e97
MT
151cli_ipsec_connection_show() {
152 local connection="${1}"
153
154 # Read the config settings
155 local ${IPSEC_CONNECTION_CONFIG_SETTINGS}
156 if ! ipsec_connection_read_config "${connection}"; then
157 error "Could not read the connection configuration"
158 return ${EXIT_ERROR}
159 fi
160
161 cli_headline 0 "IPsec VPN Connection: ${connection}"
162 cli_space
163
5bcadc60 164 cli_print_fmt1 1 "Color" "$(cli_color_bar $(ipsec_connection_get_color ${connection}))"
dc5dcfaf 165 cli_print_fmt1 1 "Description" "$(ipsec_connection_get_description_title ${connection})"
5bcadc60
JS
166 cli_space
167
c1e76e97
MT
168 # Peer
169 if isset PEER; then
170 cli_print_fmt1 1 "Peer" "${PEER}"
171 fi
172
173 # Security Policy
174 cli_print_fmt1 1 "Security Policy" "${SECURITY_POLICY-${IPSEC_DEFAULT_SECURITY_POLICY}}"
175 cli_space
176
177 cli_headline 2 "Authentication"
178 case "${AUTH_MODE^^}" in
179 PSK)
180 cli_print_fmt1 2 "Mode" "Pre-Shared-Key"
181
182 if isset PSK; then
183 cli_print_fmt1 2 "Pre-Shared-Key" "****"
184 else
185 cli_print_fmt1 2 "Pre-Shared-Key" "- is not set -"
186 fi
187 ;;
188 X509)
189 : # TODO
190 ;;
191 esac
192 cli_space
193
194 local i
195 for i in LOCAL REMOTE; do
196 case "${i}" in
197 LOCAL)
198 cli_headline 2 "Local"
199 ;;
200 REMOTE)
201 cli_headline 2 "Remote"
202 ;;
203 esac
204
205 local id_var="${i}_ID"
206 if [ -n "${!id_var}" ]; then
207 cli_print_fmt1 2 "ID" "${!id_var}"
208 fi
209
210 local prefix_var="${i}_PREFIX"
211 if isset ${prefix_var}; then
212 cli_headline 3 "Prefix(es)"
213
214 local prefix
215 for prefix in ${!prefix_var}; do
216 cli_print_fmt1 3 "${prefix}"
217 done
218 fi
219
220 cli_space
221 done
222
223 cli_headline 2 "Misc."
224
225 case "${MODE}" in
226 gre-transport)
227 cli_print_fmt1 2 "Transport Mode" "GRE Transport"
228 ;;
229 tunnel)
230 cli_print_fmt1 2 "Transport Mode" "Tunnel"
231 ;;
232 vti)
233 cli_print_fmt1 2 "Transport Mode" "Virtual Tunnel Interface"
234 ;;
235 *)
236 cli_print_fmt1 2 "Transport Mode" "- Unknown -"
237 ;;
238 esac
239
240 # Inactivity timeout
241 if isset INACTIVITY_TIMEOUT && [ ${INACTIVITY_TIMEOUT} -gt 0 ]; then
242 cli_print_fmt1 2 "Inactivity Timeout" "$(format_time ${INACTIVITY_TIMEOUT})"
243 fi
244 cli_space
245
246 return ${EXIT_OK}
247}
248
5601f4f5
JS
249ipsec_connection_disable() {
250 local connection=${1}
251
252 if ! ipsec_connection_write_config_key "${connection}" "ENABLED" "false"; then
253 log ERROR "Could not write configuration settings"
254 return ${EXIT_ERROR}
255 fi
256
c3f31173
MT
257 # Configure strongswan autostart
258 ipsec_strongswan_autostart
5601f4f5
JS
259}
260
261ipsec_connection_enable() {
262 local connection=${1}
263
264 if ! ipsec_connection_write_config_key "${connection}" "ENABLED" "true"; then
265 log ERROR "Could not write configuration settings"
266 return ${EXIT_ERROR}
267 fi
268
c3f31173
MT
269 # Configure strongswan autostart
270 ipsec_strongswan_autostart
5601f4f5
JS
271}
272
917a1aa0
JS
273# This function writes all values to a via ${connection} specificated VPN IPsec configuration file
274ipsec_connection_write_config() {
275 assert [ $# -ge 1 ]
276
277 local connection="${1}"
278
279 if ! ipsec_connection_exists "${connection}"; then
280 log ERROR "No such VPN IPsec connection: ${connection}"
281 return ${EXIT_ERROR}
282 fi
283
cf8685a1 284 local path="${NETWORK_IPSEC_CONNS_DIR}/${connection}/settings"
917a1aa0
JS
285
286 if ! settings_write "${path}" ${IPSEC_CONNECTION_CONFIG_SETTINGS}; then
287 log ERROR "Could not write configuration settings for VPN IPsec connection ${connection}"
288 return ${EXIT_ERROR}
289 fi
290
291 ipsec_reload ${connection}
292}
293
294# This funtion writes the value for one key to a via ${connection} specificated VPN IPsec connection configuration file
295ipsec_connection_write_config_key() {
296 assert [ $# -ge 3 ]
297
298 local connection=${1}
299 local key=${2}
300 shift 2
301
302 local value="$@"
303
304 if ! ipsec_connection_exists "${connection}"; then
305 log ERROR "No such VPN ipsec connection: ${connection}"
306 return ${EXIT_ERROR}
307 fi
308
309 log DEBUG "Set '${key}' to new value '${value}' in VPN ipsec connection '${connection}'"
310
311 local ${IPSEC_CONNECTION_CONFIG_SETTINGS}
312
313 # Read the config settings
314 if ! ipsec_connection_read_config "${connection}"; then
315 return ${EXIT_ERROR}
316 fi
317
318 # Set the key to a new value
319 assign "${key}" "${value}"
320
321 if ! ipsec_connection_write_config "${connection}"; then
322 return ${EXIT_ERROR}
323 fi
324
325 return ${EXIT_TRUE}
326}
327
328# Reads one or more keys out of a settings file or all if no key is provided.
329ipsec_connection_read_config() {
330 assert [ $# -ge 1 ]
331
332 local connection="${1}"
333 shift 1
334
335 if ! ipsec_connection_exists "${connection}"; then
336 log ERROR "No such VPN IPsec connection : ${connection}"
337 return ${EXIT_ERROR}
338 fi
339
340
341 local args
342 if [ $# -eq 0 ] && [ -n "${IPSEC_CONNECTION_CONFIG_SETTINGS}" ]; then
343 list_append args ${IPSEC_CONNECTION_CONFIG_SETTINGS}
344 else
2212045f 345 list_append args "$@"
917a1aa0
JS
346 fi
347
cf8685a1 348 local path="${NETWORK_IPSEC_CONNS_DIR}/${connection}/settings"
917a1aa0
JS
349
350 if ! settings_read "${path}" ${args}; then
351 log ERROR "Could not read settings for VPN IPsec connection ${connection}"
352 return ${EXIT_ERROR}
353 fi
354}
355
917a1aa0
JS
356# This function checks if a vpn ipsec connection exists
357# Returns True when yes and false when not
358ipsec_connection_exists() {
359 assert [ $# -eq 1 ]
360
361 local connection=${1}
362
cf8685a1 363 local path="${NETWORK_IPSEC_CONNS_DIR}/${connection}"
917a1aa0
JS
364
365 [ -d "${path}" ] && return ${EXIT_TRUE} || return ${EXIT_FALSE}
366}
367
c3f31173
MT
368# Determines if strongswan should be automatically started
369# when the system boots up.
370ipsec_strongswan_autostart() {
371 local autostart_needed="false"
372
373 local connection
374 for connection in $(ipsec_list_connections); do
375 local ENABLED
376
377 if ! ipsec_connection_read_config "${connection}" "ENABLED"; then
378 log WARNING "Could not read configuation"
379 continue
380 fi
381
382 if enabled ENABLED; then
383 autostart_needed="true"
384 break
385 fi
386 done
387
388 # Start strongswan when we need it and when it is not yet enabled
b863fe52
MT
389 if ${autostart_needed}; then
390 if ! service_is_enabled "strongswan"; then
391 service_enable "strongswan"
392 fi
393
394 if ! service_is_active "strongswan"; then
395 service_start "strongswan"
396 fi
c3f31173
MT
397
398 # Disable strongswan when we do not need it but it is enabled
b863fe52
MT
399 elif ! ${autostart_needed}; then
400 if service_is_enabled "strongswan"; then
401 service_disable "strongswan"
402 fi
403
404 if service_is_active "strongswan"; then
405 service_stop "strongswan"
406 fi
c3f31173
MT
407 fi
408}
409
f0e91d26 410ipsec_strongswan_load() {
7fc57ebc
MT
411 # Do nothing if strongswan is not running
412 if ! service_is_active "strongswan"; then
413 return ${EXIT_OK}
414 fi
415
f0e91d26
JS
416 if ! cmd swanctl --load-all; then
417 log ERROR "Could not reload strongswan config"
418 return ${EXIT_ERROR}
419 fi
420}
421
917a1aa0
JS
422# Reloads the connection after config changes
423ipsec_reload() {
39d87f20
JS
424 local connection=${1}
425
5601f4f5
JS
426 local ENABLED
427
428 if ! ipsec_connection_read_config "${connection}" "ENABLED"; then
429 log ERROR "Could not read configuration for IPsec connection ${connection}"
39d87f20
JS
430 return ${EXIT_ERROR}
431 fi
432
471f16bc 433 if enabled ENABLED; then
5601f4f5
JS
434 if ! ipsec_connection_to_strongswan ${connection}; then
435 log ERROR "Could not generate strongswan config for ${connnection}"
436 return ${EXIT_ERROR}
437 fi
438 else
ad482897 439 log DEBUG "Deleting strongswan config ${NETWORK_IPSEC_SWANCTL_CONNECTIONS_DIR}/${connection}.conf"
5601f4f5
JS
440 unlink "${NETWORK_IPSEC_SWANCTL_CONNECTIONS_DIR}/${connection}.conf"
441 fi
442
f0e91d26 443 ipsec_strongswan_load
917a1aa0
JS
444}
445
446# Handle the cli after authentification
447ipsec_connection_authentication() {
448 if [ ! $# -gt 1 ]; then
449 log ERROR "Not enough arguments"
450 return ${EXIT_ERROR}
451 fi
452
453 local connection=${1}
454 local cmd=${2}
455 shift 2
456
457 case ${cmd} in
458 mode)
2212045f 459 ipsec_connection_authentication_mode "${connection}" "$@"
917a1aa0
JS
460 ;;
461 pre-shared-key)
2212045f 462 ipsec_connection_authentication_psk "${connection}" "$@"
917a1aa0
JS
463 ;;
464 *)
465 log ERROR "Unrecognized argument: ${cmd}"
466 return ${EXIT_ERROR}
467 ;;
468 esac
469}
470
471# Set the authentification mode
472ipsec_connection_authentication_mode() {
473 if [ ! $# -eq 2 ]; then
474 log ERROR "Not enough arguments"
475 return ${EXIT_ERROR}
476 fi
477 local connection=${1}
478 local mode=${2}
479
480 if ! isoneof mode ${IPSEC_VALID_AUTH_MODES}; then
481 log ERROR "Auth mode '${mode}' is invalid"
482 return ${EXIT_ERROR}
483 fi
484
ab589039 485 if ! ipsec_connection_write_config_key "${connection}" "AUTH_MODE" ${mode^^}; then
917a1aa0
JS
486 log ERROR "Could not write configuration settings"
487 return ${EXIT_ERROR}
488 fi
489}
490
491# Set the psk
492ipsec_connection_authentication_psk() {
db491d1d 493 if [ ! $# -eq 2 ]; then
917a1aa0
JS
494 log ERROR "Not enough arguments"
495 return ${EXIT_ERROR}
496 fi
1bfc4f56 497
917a1aa0
JS
498 local connection=${1}
499 local psk=${2}
500
1bfc4f56
MT
501 local length=${#psk}
502
503 if [ ${length} -lt 4 ]; then
504 error "The PSK must be longer than four characters"
505 return ${EXIT_ERROR}
506 fi
507
508 if [ ${length} -gt 128 ]; then
509 error "The PSK cannot be longer than 128 characters"
510 return ${EXIT_ERROR}
511 fi
917a1aa0 512
1bfc4f56 513 if ! ipsec_connection_write_config_key "${connection}" "PSK" "${psk}"; then
917a1aa0
JS
514 log ERROR "Could not write configuration settings"
515 return ${EXIT_ERROR}
516 fi
517
518 return ${EXIT_OK}
519}
520
3cde31b9
MT
521ipsec_connection_up() {
522 local connection="${1}"
523
524 if ! ipsec_connection_exists "${connection}"; then
525 error "No such VPN IPsec connection: ${connection}"
526 return ${EXIT_ERROR}
527 fi
528
529 cmd swanctl --initiate --child "${connection}"
530}
531
532ipsec_connection_down() {
533 local connection="${1}"
534
535 if ! ipsec_connection_exists "${connection}"; then
536 error "No such VPN IPsec connection: ${connection}"
537 return ${EXIT_ERROR}
538 fi
539
540 cmd swanctl --terminate --ike "${connection}"
541}
bb9fccaf
JS
542
543# Handle the cli after authentification
544ipsec_connection_dpd() {
545 if [ ! $# -gt 1 ]; then
546 log ERROR "Not enough arguments"
547 return ${EXIT_ERROR}
548 fi
549
550 local connection=${1}
551 local cmd=${2}
552 shift 2
553
554 case ${cmd} in
555 action)
2212045f 556 ipsec_connection_dpd_action "${connection}" "$@"
bb9fccaf
JS
557 ;;
558 delay)
2212045f 559 ipsec_connection_dpd_delay "${connection}" "$@"
bb9fccaf
JS
560 ;;
561 timeout)
2212045f 562 ipsec_connection_dpd_timeout "${connection}" "$@"
bb9fccaf
JS
563 ;;
564 *)
565 log ERROR "Unrecognized argument: ${cmd}"
566 return ${EXIT_ERROR}
567 ;;
568 esac
569}
570
571# Set the default dpd action
572ipsec_connection_dpd_action() {
573 if [ ! $# -eq 2 ]; then
574 log ERROR "Not enough arguments"
575 return ${EXIT_ERROR}
576 fi
577 local connection=${1}
578 local action=${2}
579
580 if ! isoneof action "restart" "clear"; then
581 log ERROR "dpd action '${action}' is invalid"
582 return ${EXIT_ERROR}
583 fi
584
585 if ! ipsec_connection_write_config_key "${connection}" "DPD_ACTION" ${action}; then
586 log ERROR "Could not write configuration settings"
587 return ${EXIT_ERROR}
588 fi
589}
590
591# Set the dpd delay
592ipsec_connection_dpd_delay() {
593 if [ ! $# -ge 2 ]; then
594 log ERROR "Not enough arguments"
595 return ${EXIT_ERROR}
596 fi
597
598 local connection=${1}
599 shift 1
600 local value=$@
601
602 if ! isinteger value; then
2212045f 603 value=$(parse_time "$@")
bb9fccaf
JS
604 if [ ! $? -eq 0 ]; then
605 log ERROR "Parsing the passed time was not sucessful please check the passed values."
606 return ${EXIT_ERROR}
607 fi
608 fi
609
610 if [ ${value} -lt 0 ]; then
611 log ERROR "The passed time value must be in the sum greater or equal zero seconds."
612 return ${EXIT_ERROR}
613 fi
614
615 if ! ipsec_connection_write_config_key "${connection}" "DPD_DELAY" ${value}; then
616 log ERROR "Could not write configuration settings"
617 return ${EXIT_ERROR}
618 fi
619
620 return ${EXIT_OK}
621}
622
623# Set the dpd timeout
624ipsec_connection_dpd_timeout() {
625 if [ ! $# -ge 2 ]; then
626 log ERROR "Not enough arguments"
627 return ${EXIT_ERROR}
628 fi
629
630 local connection=${1}
631 shift 1
632 local value=$@
633
634 if ! isinteger value; then
2212045f 635 value=$(parse_time "$@")
bb9fccaf
JS
636 if [ ! $? -eq 0 ]; then
637 log ERROR "Parsing the passed time was not sucessful please check the passed values."
638 return ${EXIT_ERROR}
639 fi
640 fi
641
642 if [ ${value} -le 0 ]; then
643 log ERROR "The passed time value must be in the sum greater or equal zero seconds."
644 return ${EXIT_ERROR}
645 fi
646
647 if ! ipsec_connection_write_config_key "${connection}" "DPD_TIMEOUT" ${value}; then
648 log ERROR "Could not write configuration settings"
649 return ${EXIT_ERROR}
650 fi
651
652 return ${EXIT_OK}
653}
654
917a1aa0
JS
655# Handle the cli after local
656ipsec_connection_local() {
657 if [ ! $# -ge 2 ]; then
658 log ERROR "Not enough arguments"
659 return ${EXIT_ERROR}
660 fi
661
662 local connection=${1}
663 local cmd=${2}
664 shift 2
665
666 case ${cmd} in
bb9fccaf 667 address)
2212045f 668 ipsec_connection_local_address "${connection}" "$@"
bb9fccaf 669 ;;
917a1aa0 670 id)
2212045f 671 ipsec_connection_id "${connection}" "LOCAL" "$@"
917a1aa0
JS
672 ;;
673 prefix)
2212045f 674 ipsec_connection_prefix "${connection}" "LOCAL" "$@"
917a1aa0
JS
675 ;;
676 *)
677 log ERROR "Unrecognized argument: ${cmd}"
678 return ${EXIT_ERROR}
679 ;;
680 esac
681
682 return ${EXIT_OK}
683}
684
685# Set the connection mode
686ipsec_connection_mode() {
5bdbc2ee 687 if [ ! $# -eq 2 ]; then
917a1aa0
JS
688 log ERROR "Not enough arguments"
689 return ${EXIT_ERROR}
690 fi
691 local connection=${1}
692 local mode=${2}
693
694 if ! isoneof mode ${IPSEC_VALID_MODES}; then
695 log ERROR "Mode '${mode}' is invalid"
696 return ${EXIT_ERROR}
697 fi
698
699 if ! ipsec_connection_write_config_key "${connection}" "MODE" ${mode}; then
700 log ERROR "Could not write configuration settings"
701 return ${EXIT_ERROR}
702 fi
703
704 return ${EXIT_OK}
705}
706
bb9fccaf
JS
707# Set the local address
708ipsec_connection_local_address() {
709 if [ ! $# -eq 2 ]; then
710 log ERROR "Not enough arguments"
711 return ${EXIT_ERROR}
712 fi
713 local connection=${1}
714 local local_address=${2}
715
716 if ! ipsec_connection_check_peer ${local_address}; then
717 log ERROR "Local address '${local_address}' is invalid"
718 return ${EXIT_ERROR}
719 fi
720
721 if ! ipsec_connection_write_config_key "${connection}" "LOCAL_ADDRESS" ${local_address}; then
722 log ERROR "Could not write configuration settings"
723 return ${EXIT_ERROR}
724 fi
725
726 return ${EXIT_OK}
727}
728
917a1aa0
JS
729# Set the peer to connect to
730ipsec_connection_peer() {
0b962a64 731 if [ ! $# -eq 2 ]; then
917a1aa0
JS
732 log ERROR "Not enough arguments"
733 return ${EXIT_ERROR}
734 fi
735 local connection=${1}
736 local peer=${2}
737
738 if ! ipsec_connection_check_peer ${peer}; then
739 log ERROR "Peer '${peer}' is invalid"
740 return ${EXIT_ERROR}
741 fi
742
743 if ! ipsec_connection_write_config_key "${connection}" "PEER" ${peer}; then
744 log ERROR "Could not write configuration settings"
745 return ${EXIT_ERROR}
746 fi
747
748 return ${EXIT_OK}
749}
750
751#Set the local or remote id
752ipsec_connection_id() {
753 if [ ! $# -eq 3 ]; then
754 log ERROR "Not enough arguments"
755 return ${EXIT_ERROR}
756 fi
757 local connection=${1}
758 local type=${2}
759 local id=${3}
760
761 if ! ipsec_connection_check_id ${id}; then
762 log ERROR "Id '${id}' is invalid"
763 return ${EXIT_ERROR}
764 fi
aaa72eef 765
917a1aa0
JS
766 if ! ipsec_connection_write_config_key "${connection}" "${type}_ID" ${id}; then
767 log ERROR "Could not write configuration settings"
768 return ${EXIT_ERROR}
769 fi
aaa72eef 770
917a1aa0
JS
771 return ${EXIT_OK}
772}
773
aaa72eef 774# Set the local or remote prefix
917a1aa0
JS
775ipsec_connection_prefix() {
776 if [ ! $# -ge 3 ]; then
777 log ERROR "Not enough arguments"
778 return ${EXIT_ERROR}
779 fi
780 local connection=${1}
781 local type=${2}
782 shift 2
aaa72eef 783
917a1aa0
JS
784 local _prefix="${type}_PREFIX"
785 local "${_prefix}"
786 if ! ipsec_connection_read_config "${connection}" "${_prefix}"; then
787 return ${EXIT_ERROR}
788 fi
789
790 # Remove duplicated entries to proceed the list safely
791 assign "${_prefix}" "$(list_unique ${!_prefix} )"
792
793 local prefixes_added
794 local prefixes_removed
795 local prefixes_set
796
797 while [ $# -gt 0 ]; do
798 local arg="${1}"
799
800 case "${arg}" in
801 +*)
802 list_append prefixes_added "${arg:1}"
803 ;;
804 -*)
805 list_append prefixes_removed "${arg:1}"
806 ;;
807 [A-Fa-f0-9]*)
808 list_append prefixes_set "${arg}"
809 ;;
810 *)
811 error "Invalid argument: ${arg}"
812 return ${EXIT_ERROR}
813 ;;
814 esac
815 shift
816 done
817
818 # Check if the user is trying a mixed operation
819 if ! list_is_empty prefixes_set && (! list_is_empty prefixes_added || ! list_is_empty prefixes_removed); then
820 error "You cannot reset the prefix list and add or remove prefixes at the same time"
821 return ${EXIT_ERROR}
822 fi
823
824 # Set new prefix list
825 if ! list_is_empty prefixes_set; then
826 # Check if all prefixes are valid
827 local prefix
828 for prefix in ${prefixes_set}; do
829 if ! ip_net_is_valid ${prefix}; then
830 error "Unsupported prefix: ${prefix}"
831 return ${EXIT_ERROR}
832 fi
833 done
834
835 assign "${_prefix}" "${prefixes_set}"
836
837 # Perform incremental updates
838 else
839 local prefix
840
841 # Perform all removals
842 for prefix in ${prefixes_removed}; do
843 if ! list_remove "${_prefix}" ${prefix}; then
844 warning "${prefix} was not on the list and could not be removed"
845 fi
846 done
847
848
849 for prefix in ${prefixes_added}; do
850 if ip_net_is_valid ${prefix}; then
851 if ! list_append_unique "${_prefix}" ${prefix}; then
852 warning "${prefix} is already on the prefix list"
853 fi
854 else
f03f29b7 855 warning "${prefix} is not a valid IP network and could not be added"
917a1aa0
JS
856 fi
857 done
858 fi
859
860 # Check if the list contain at least one valid prefix
861 if list_is_empty ${_prefix}; then
862 error "Cannot save an empty prefix list"
863 return ${EXIT_ERROR}
864 fi
865
866 # Save everything
867 if ! ipsec_connection_write_config_key "${connection}" "${_prefix}" ${!_prefix}; then
868 log ERROR "Could not write configuration settings"
869 fi
870
871 return ${EXIT_OK}
872}
873
96fdb077
JS
874# Set the pools to use
875ipsec_connection_pool() {
876 if [ ! $# -ge 2 ]; then
877 log ERROR "Not enough arguments"
878 return ${EXIT_ERROR}
879 fi
880 local connection=${1}
881 shift
882
883 local POOLS
884 if ! ipsec_connection_read_config "${connection}" "POOLS"; then
885 return ${EXIT_ERROR}
886 fi
887
888 # Remove duplicated entries to proceed the list safely
889 assign "POOLS" "$(list_unique ${POOLS})"
890
891 local pools_added
892 local pools_removed
893 local pools_set
894
895 while [ $# -gt 0 ]; do
896 local arg="${1}"
897
898 case "${arg}" in
899 +*)
900 list_append pools_added "${arg:1}"
901 ;;
902 -*)
903 list_append pools_removed "${arg:1}"
904 ;;
905 [A-Za-z0-9]*)
906 list_append pools_set "${arg}"
907 ;;
908 *)
909 error "Invalid argument: ${arg}"
910 return ${EXIT_ERROR}
911 ;;
912 esac
913 shift
914 done
915
916 # Check if the user is trying a mixed operation
917 if ! list_is_empty pools_set && (! list_is_empty pools_added || ! list_is_empty pools_removed); then
918 error "You cannot reset the pools list and add or remove pools at the same time"
919 return ${EXIT_ERROR}
920 fi
921
922 # Set new pools list
923 if ! list_is_empty pools_set; then
924 # Check if all pools are valid
925 local pool
926 for pool in ${pools_set}; do
927 if ! ipsec_pool_exists ${pool} || ! ipsec_pool_check_config ${pool}; then
928 error "Pool ${pool} is not valid"
929 return ${EXIT_ERROR}
930 fi
931 done
932
933 assign "POOLS" "${pools_set}"
934
935 # Perform incremental updates
936 else
937 local pool
938
939 # Perform all removals
940 for pool in ${pools_removed}; do
941 if ! list_remove "POOLS" ${pool}; then
942 warning "${pool} was not on the list and could not be removed"
943 fi
944 done
945
946
947 for pool in ${pools_added}; do
beb0ebbb 948 if ipsec_pool_exists ${pool} && ipsec_pool_check_config ${pool}; then
96fdb077
JS
949 if ! list_append_unique "POOLS" ${pool}; then
950 warning "${pool} is already on the prefix list"
951 fi
952 else
953 warning "${pool} is not a valid pool"
954 fi
955 done
956 fi
957
958 # Check if the list contain at least one valid pool
959 if list_is_empty POOLS; then
960 error "Cannot save an empty pool list"
961 return ${EXIT_ERROR}
962 fi
963
964 # Save everything
965 if ! ipsec_connection_write_config_key "${connection}" "POOLS" ${POOLS}; then
966 log ERROR "Could not write configuration settings"
967 fi
968
969 return ${EXIT_OK}
970}
971
917a1aa0
JS
972# Handle the cli after remote
973ipsec_connection_remote() {
974 if [ ! $# -ge 2 ]; then
975 log ERROR "Not enough arguments"
976 return ${EXIT_ERROR}
977 fi
978
979 local connection=${1}
980 local cmd=${2}
981 shift 2
982
983 case ${cmd} in
984 id)
2212045f 985 ipsec_connection_id "${connection}" "REMOTE" "$@"
917a1aa0
JS
986 ;;
987
988 prefix)
2212045f 989 ipsec_connection_prefix "${connection}" "REMOTE" "$@"
917a1aa0
JS
990 ;;
991 *)
992 log ERROR "Unrecognized argument: ${cmd}"
993 return ${EXIT_ERROR}
994 ;;
995 esac
996
997 return ${EXIT_OK}
998}
999
1000# Set the inactivity timeout
1001ipsec_connection_inactivity_timeout() {
1002 if [ ! $# -ge 2 ]; then
1003 log ERROR "Not enough arguments"
1004 return ${EXIT_ERROR}
1005 fi
1006
1007 local connection=${1}
1008 shift 1
1009 local value=$@
1010
1011 if ! isinteger value; then
2212045f 1012 value=$(parse_time "$@")
917a1aa0
JS
1013 if [ ! $? -eq 0 ]; then
1014 log ERROR "Parsing the passed time was not sucessful please check the passed values."
1015 return ${EXIT_ERROR}
1016 fi
1017 fi
1018
1019 if [ ${value} -le 0 ]; then
1020 log ERROR "The passed time value must be in the sum greater zero seconds."
1021 return ${EXIT_ERROR}
1022 fi
1023
1024 if ! ipsec_connection_write_config_key "${connection}" "INACTIVITY_TIMEOUT" ${value}; then
1025 log ERROR "Could not write configuration settings"
1026 return ${EXIT_ERROR}
1027 fi
1028
1029 return ${EXIT_OK}
1030}
1031
bb9fccaf
JS
1032# Set the default start action
1033ipsec_connection_start_action() {
1034 if [ ! $# -eq 2 ]; then
1035 log ERROR "Not enough arguments"
1036 return ${EXIT_ERROR}
1037 fi
1038 local connection=${1}
1039 local action=${2}
1040
1041 if ! isoneof action "on-demand" "always-on"; then
1042 log ERROR "Start action '${action}' is invalid"
1043 return ${EXIT_ERROR}
1044 fi
1045
1046 if ! ipsec_connection_write_config_key "${connection}" "START_ACTION" ${action}; then
1047 log ERROR "Could not write configuration settings"
1048 return ${EXIT_ERROR}
1049 fi
1050}
917a1aa0
JS
1051
1052# Set the security policy to use
1053ipsec_connection_security_policy() {
1054 if [ ! $# -eq 2 ]; then
1055 log ERROR "Not enough arguments"
1056 return ${EXIT_ERROR}
1057 fi
1058 local connection=${1}
1059 local security_policy=${2}
1060
1061 if ! vpn_security_policy_exists ${security_policy}; then
1062 log ERROR "No such vpn security policy '${security_policy}'"
1063 return ${EXIT_ERROR}
1064 fi
1065
1066 if ! ipsec_connection_write_config_key "${connection}" "SECURITY_POLICY" ${security_policy}; then
1067 log ERROR "Could not write configuration settings"
1068 return ${EXIT_ERROR}
1069 fi
1070}
1071
1072# Check if a id is valid
1073ipsec_connection_check_id() {
1074 assert [ $# -eq 1 ]
1075 local id=${1}
1076
1077 if [[ ${id} =~ ^@[[:alnum:]]+$ ]] || ip_is_valid ${id}; then
1078 return ${EXIT_TRUE}
1079 else
1080 return ${EXIT_FALSE}
1081 fi
1082}
1083
1084# Checks if a peer is valid
1085ipsec_connection_check_peer() {
1086 assert [ $# -eq 1 ]
1087 local peer=${1}
1088
1089 # TODO Accept also FQDNs
1090 if ip_is_valid ${peer}; then
1091 return ${EXIT_TRUE}
1092 else
1093 return ${EXIT_FALSE}
1094 fi
1095}
1096
1097# This function checks if a VPN IPsec connection name is valid
1098# Allowed are only A-Za-z0-9
1099ipsec_connection_check_name() {
1100 assert [ $# -eq 1 ]
1101
1102 local connection=${1}
1103
1104 [[ "${connection}" =~ [^[:alnum:]$] ]]
1105}
1106
1107# Function that creates one VPN IPsec connection
1108ipsec_connection_new() {
89d71d08 1109 if [ $# -gt 2 ]; then
917a1aa0
JS
1110 error "Too many arguments"
1111 return ${EXIT_ERROR}
1112 fi
1113
1114 local connection="${1}"
89d71d08
JS
1115 local type="${2}"
1116
917a1aa0
JS
1117 if ! isset connection; then
1118 error "Please provide a connection name"
1119 return ${EXIT_ERROR}
1120 fi
1121
1122 # Check for duplicates
1123 if ipsec_connection_exists "${connection}"; then
1124 error "The VPN IPsec connection ${connection} already exists"
1125 return ${EXIT_ERROR}
1126 fi
1127
1128 # Check if the name of the connection is valid
1129 if ipsec_connection_check_name "${connection}"; then
1130 error "'${connection}' contains illegal characters"
1131 return ${EXIT_ERROR}
1132 fi
1133
89d71d08
JS
1134 # Set TYPE to default if not set by the user
1135 if ! isset type; then
1136 type="${IPSEC_DEFAULT_TYPE}"
1137 fi
1138
1139 if ! isoneof "type" "net-to-net" "host-to-net"; then
1140 error "Type is invalid"
1141 return ${EXIT_ERROR}
1142 fi
1143
917a1aa0
JS
1144 log DEBUG "Creating VPN IPsec connection ${connection}"
1145
cf8685a1 1146 if ! mkdir -p "${NETWORK_IPSEC_CONNS_DIR}/${connection}"; then
917a1aa0
JS
1147 log ERROR "Could not create config directory for ${connection}"
1148 return ${EXIT_ERROR}
1149 fi
1150
1151 local ${IPSEC_CONNECTION_CONFIG_SETTINGS}
1152
917a1aa0 1153 AUTH_MODE=${IPSEC_DEFAULT_AUTH_MODE}
bb9fccaf
JS
1154 DPD_ACTION=${IPSEC_DEFAULT_DPD_ACTION}
1155 DPD_DELAY=${IPSEC_DEFAULT_DPD_DELAY}
1156 DPD_TIMEOUT=${IPSEC_DEFAULT_DPD_TIMEOUT}
5601f4f5 1157 ENABLED=${IPSEC_DEFAULT_ENABLED}
bb9fccaf
JS
1158 MODE=${IPSEC_DEFAULT_MODE}
1159 START_ACTION=${IPSEC_DEFAULT_START_ACTION}
89d71d08 1160 TYPE="${type}"
bb9fccaf 1161
917a1aa0
JS
1162 INACTIVITY_TIMEOUT=${IPSEC_DEFAULT_INACTIVITY_TIMEOUT}
1163 SECURITY_POLICY=${IPSEC_DEFAULT_SECURITY_POLICY}
1164
1165 if ! ipsec_connection_write_config "${connection}"; then
1166 log ERROR "Could not write new config file"
1167 return ${EXIT_ERROR}
1168 fi
c3f31173
MT
1169
1170 # Configure strongswan autostart
1171 ipsec_strongswan_autostart
917a1aa0
JS
1172}
1173
1174# Function that deletes based on the passed parameters one ore more vpn security policies
1175ipsec_connection_destroy() {
1176 local connection
2212045f 1177 for connection in "$@"; do
917a1aa0
JS
1178 if ! ipsec_connection_exists "${connection}"; then
1179 log ERROR "The VPN IPsec connection ${connection} does not exist."
1180 continue
1181 fi
1182
1183 log DEBUG "Deleting VPN IPsec connection ${connection}"
fa33d830
MT
1184
1185 # Delete strongswan configuration file
1186 file_delete "${NETWORK_IPSEC_SWANCTL_CONNECTIONS_DIR}/${connection}.conf"
1187
cf8685a1 1188 if ! rm -rf "${NETWORK_IPSEC_CONNS_DIR}/${connection}"; then
917a1aa0
JS
1189 log ERROR "Deleting the VPN IPsec connection ${connection} was not sucessful"
1190 return ${EXIT_ERROR}
1191 fi
c3f31173 1192
fa33d830 1193 done
917a1aa0 1194}
d6c852b8
JS
1195
1196# List all ipsec connections
1197ipsec_list_connections() {
60b1f378 1198 list_directory "${NETWORK_IPSEC_CONNS_DIR}"
d6c852b8 1199}
67baa452
MT
1200
1201ipsec_connection_to_strongswan() {
1202 local connection="${1}"
aaa72eef 1203 log DEBUG "Generating IPsec configuration for ${connection}"
67baa452
MT
1204
1205 # Read the config settings
1206 local ${IPSEC_CONNECTION_CONFIG_SETTINGS}
1207 if ! ipsec_connection_read_config "${connection}"; then
1208 error "Could not read the connection ${connection}"
1209 return ${EXIT_ERROR}
1210 fi
1211
1212 local path="${NETWORK_IPSEC_SWANCTL_CONNECTIONS_DIR}/${connection}.conf"
1213
1214 (
1215 # Write the connection section
1216 _ipsec_connection_to_strongswan_connection "${connection}"
1217
1218 # Write the secrets section
1219 _ipsec_connection_to_strongswan_secrets "${connection}"
1220
1221 ) > ${path}
1222}
1223
1224_ipsec_connection_to_strongswan_connection() {
1225 local connection="${1}"
1226
1227 # Read the security policy
1228 local ${VPN_SECURITY_POLICIES_CONFIG_SETTINGS}
1229 if ! vpn_security_policies_read_config "${SECURITY_POLICY}"; then
1230 return ${EXIT_ERROR}
1231 fi
1232
4e271faa
MT
1233 # Is DPD enabled?
1234 local dpd="false"
1235 if isset DPD_DELAY && isinteger DPD_DELAY && [ ${DPD_DELAY} -gt 0 ]; then
1236 dpd="true"
1237 fi
1238
b21fb175
MT
1239 # Write configuration header
1240 config_header "strongSwan configuration for ${connection}"
1241
67baa452
MT
1242 print_indent 0 "connections {"
1243 print_indent 1 "${connection} {"
1244
1245 # IKE Version
1246 print_indent 2 "# IKE Version"
1247 case "${KEY_EXCHANGE^^}" in
1248 IKEV1)
1249 print_indent 2 "version = 1"
1250 ;;
1251
1252 # Fall back to IKEv2 for any random values
1253 IKEV2|*)
1254 print_indent 2 "version = 2"
1255 ;;
1256 esac
1257 print # empty line
1258
4609d6b4
MT
1259 # Always only keep one connection open at a time
1260 print_indent 2 "# Unique IDs"
1261 print_indent 2 "unique = replace"
1262 print
1263
3e8ad776
MT
1264 # Local Address
1265 print_indent 2 "# Local Address"
1266 if isset LOCAL_ADDRESS; then
1267 print_indent 2 "local_addrs = ${LOCAL_ADDRESS}"
1268 else
1269 print_indent 2 "local_addrs = %any"
1270 fi
1271 print
67baa452
MT
1272
1273 # Remote Address
1274 print_indent 2 "# Remote Address"
1275 if isset PEER; then
1276 print_indent 2 "remote_addrs = ${PEER}"
1277 else
1278 print_indent 2 "remote_addrs = %any"
1279 fi
1280 print
1281
1282 # IKE Proposals
1283 print_indent 2 "# IKE Proposals"
e3ffacf7 1284 print_indent 2 "proposals = $(vpn_security_policies_make_ike_proposal ${SECURITY_POLICY})"
67baa452
MT
1285 print
1286
117278c3 1287 # DPD Settings
4e271faa 1288 if enabled dpd; then
117278c3 1289 print_indent 2 "# Dead Peer Detection"
117278c3
MT
1290 print_indent 2 "dpd_delay = ${DPD_DELAY}"
1291
1292 if isset DPD_TIMEOUT; then
1293 print_indent 2 "dpd_timeout = ${DPD_TIMEOUT}"
1294 fi
1295
1296 print
1297 fi
67baa452
MT
1298
1299 # Fragmentation
1300 print_indent 2 "# Fragmentation"
1301 print_indent 2 "fragmentation = yes"
1302 print
1303
dd66c192
MT
1304
1305 # Host-to-Net specific settings
1306 case "${TYPE}" in
1307 host-to-net)
1308 # Pools
1309 if isset POOLS; then
1310 print_indent 2 "# Pools"
1311 print_indent 2 "pools = $(list_join POOLS ", ")"
1312 print
1313 fi
1314 ;;
1315 esac
96fdb077 1316
67baa452
MT
1317 # Local
1318 print_indent 2 "local {"
1319
1320 # Local ID
1321 if isset LOCAL_ID; then
1322 print_indent 3 "id = ${LOCAL_ID}"
1323 fi
1324
1325 # Authentication
1326 case "${AUTH_MODE}" in
1327 PSK)
1328 print_indent 3 "auth = psk"
1329 ;;
1330 esac
1331
1332 print_indent 2 "}"
1333 print
1334
1335 # Remote
1336 print_indent 2 "remote {"
1337
1338 # Remote ID
1339 if isset REMOTE_ID; then
1340 print_indent 3 "id = ${REMOTE_ID}"
1341 fi
1342
1343 # Authentication
1344 case "${AUTH_MODE}" in
1345 PSK)
1346 print_indent 3 "auth = psk"
1347 ;;
1348 esac
1349
1350 print_indent 2 "}"
1351 print
1352
1353 # Children
1354
1355 print_indent 2 "children {"
1356 print_indent 3 "${connection} {"
1357
1358 print_indent 4 "# ESP Proposals"
e3d8f3f6 1359 print_indent 4 "esp_proposals = $(vpn_security_policies_make_esp_proposal ${SECURITY_POLICY})"
67baa452
MT
1360 print
1361
1362 # Traffic Selectors
1363
95835d23
MT
1364 case "${MODE}" in
1365 gre-*)
1366 print_indent 4 "local_ts = dynamic[gre]"
1367 print_indent 4 "remote_ts = dynamic[gre]"
1368 ;;
1369 *)
1370 # Local Prefixes
1371 if isset LOCAL_PREFIX; then
1372 print_indent 4 "local_ts = $(list_join LOCAL_PREFIX ,)"
1373 else
1374 print_indent 4 "local_ts = dynamic"
1375 fi
67baa452 1376
95835d23
MT
1377 # Remote Prefixes
1378 if isset REMOTE_PREFIX; then
1379 print_indent 4 "remote_ts = $(list_join REMOTE_PREFIX ,)"
1380 else
1381 print_indent 4 "remote_ts = dynamic"
1382 fi
1383 ;;
1384 esac
67baa452
MT
1385 print
1386
82fac748 1387 # Netfilter Marks
8af22236
MT
1388 case "${MODE}" in
1389 vti)
1390 print_indent 4 "# Netfilter Marks"
1391 print_indent 4 "mark_in = %unique"
1392 print_indent 4 "mark_out = %unique"
1393 print
1394 ;;
1395 esac
82fac748 1396
4e271faa
MT
1397 # Dead Peer Detection
1398 if enabled dpd; then
1399 print_indent 4 "# Dead Peer Detection"
1400 print_indent 4 "dpd_action = ${DPD_ACTION}"
1401 print
1402 fi
1403
67baa452
MT
1404 # Rekeying
1405 if isset LIFETIME; then
1406 print_indent 4 "# Rekey Time"
1407 print_indent 4 "rekey_time = ${LIFETIME}"
1408 print
1409 fi
1410
1411 # Updown Script
1412 print_indent 4 "updown = ${NETWORK_HELPERS_DIR}/ipsec-updown"
1413 print
1414
1415 # Mode
1416 print_indent 4 "# Mode"
1417 case "${MODE}" in
1418 gre-transport)
1419 print_indent 4 "mode = transport"
1420 ;;
1421 tunnel|vti|*)
1422 print_indent 4 "mode = tunnel"
1423 ;;
1424 esac
1425 print
1426
1427 # Compression
1428 print_indent 4 "# Compression"
1429 if enabled COMPRESSION; then
1430 print_indent 4 "ipcomp = yes"
1431 else
1432 print_indent 4 "ipcomp = no"
1433 fi
1434 print
1435
1436 # Inactivity Timeout
1437 if isset INACTIVITY_TIMEOUT; then
1438 print_indent 4 "# Inactivity Timeout"
1439 print_indent 4 "inactivity = ${INACTIVITY_TIMEOUT}"
1440 print
1441 fi
1442
dd66c192
MT
1443 # Net-to-Net specific settings
1444 case "${TYPE}" in
1445 net-to-net)
1446 # Start Action
1447 print_indent 4 "# Start Action"
1448 case "${START_ACTION}" in
1449 on-demand)
1450 print_indent 4 "start_action = trap"
1451 print_indent 4 "close_action = trap"
1452 ;;
1453 wait)
1454 print_indent 4 "start_action = none"
1455 print_indent 4 "close_action = none"
1456 ;;
1457 always-on|*)
1458 print_indent 4 "start_action = start"
1459 print_indent 4 "close_action = start"
1460 ;;
1461 esac
1462 print
37317b3e
MT
1463 ;;
1464 esac
67baa452
MT
1465
1466 print_indent 3 "}"
1467 print_indent 2 "}"
1468 print
1469
1470 print_indent 1 "}"
1471 print_indent 0 "}"
1472 print
1473}
1474
1475_ipsec_connection_to_strongswan_secrets() {
1476 local connection="${1}"
1477
1478 print_indent 0 "secrets {"
1479
1480 case "${AUTH_MODE}" in
1481 PSK)
1482 print_indent 1 "ike {"
1483
1484 # Secret
1485 print_indent 2 "secret = ${PSK}"
1486
1487 # ID
1488 if isset REMOTE_ID; then
1489 print_indent 2 "id = ${REMOTE_ID}"
1490 fi
1491
1492 print_indent 1 "}"
1493 ;;
1494 esac
1495
1496 print_indent 0 "}"
1497}