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