]> git.ipfire.org Git - people/stevee/network.git/blobdiff - src/functions/functions.ipsec
network fix parameter passing when using ""
[people/stevee/network.git] / src / functions / functions.ipsec
index 03aefcdde2e184c8c35ce1888f868d35f002daf9..038ed879c345913f11aba3cfaf529696a44f51ec 100644 (file)
@@ -30,20 +30,31 @@ IPSEC_CONNECTION_CONFIG_SETTINGS="\
        LOCAL_PREFIX \
        MODE \
        PEER \
+       POOLS \
        PSK \
        REMOTE_ID \
        REMOTE_PREFIX \
-       SECURITY_POLICY"
+       SECURITY_POLICY \
+       START_ACTION \
+       TYPE \
+       ENABLED"
+
+IPSEC_POOL_CONFIG_SETTINGS="\
+       DNS_SERVER \
+       NETWORK \
+       TYPE"
 
 # Default values
 IPSEC_DEFAULT_AUTH_MODE="PSK"
 IPSEC_DEFAULT_DPD_ACTION="restart"
 IPSEC_DEFAULT_DPD_DELAY="30"
 IPSEC_DEFAULT_DPD_TIMEOUT="120"
+IPSEC_DEFAULT_ENABLED="true"
 IPSEC_DEFAULT_INACTIVITY_TIMEOUT="0"
 IPSEC_DEFAULT_MODE="tunnel"
 IPSEC_DEFAULT_SECURITY_POLICY="system"
 IPSEC_DEFAULT_START_ACTION="on-demand"
+IPSEC_DEFAULT_TYPE="net-to-net"
 
 IPSEC_VALID_MODES="gre-transport tunnel vti"
 IPSEC_VALID_AUTH_MODES="PSK"
@@ -54,7 +65,10 @@ cli_ipsec() {
 
        case "${action}" in
                connection)
-                       cli_ipsec_connection $@
+                       cli_ipsec_connection "$@"
+                       ;;
+               pool)
+                       cli_ipsec_pool "$@"
                        ;;
                *)
                        error "Unrecognized argument: ${action}"
@@ -71,8 +85,8 @@ cli_ipsec_connection() {
                shift 2
 
                case "${key}" in
-                       authentication|down|dpd|inactivity_timeout|local|mode|peer|remote|security_policy|start_action|up)
-                               ipsec_connection_${key} ${connection} $@
+                       authentication|down|disable|dpd|enable|inactivity_timeout|local|mode|peer|pool|remote|security_policy|start_action|up)
+                               ipsec_connection_${key} ${connection} "$@"
                                ;;
                        show)
                                cli_ipsec_connection_show "${connection}"
@@ -89,10 +103,10 @@ cli_ipsec_connection() {
 
                case "${action}" in
                        new)
-                               ipsec_connection_new $@
+                               ipsec_connection_new "$@"
                                ;;
                        destroy)
-                               ipsec_connection_destroy $@
+                               cli_ipsec_connection_destroy "$@"
                                ;;
                        ""|*)
                                if [ -n "${action}" ]; then
@@ -104,6 +118,61 @@ cli_ipsec_connection() {
        fi
 }
 
+cli_ipsec_pool() {
+       if ipsec_pool_exists ${1}; then
+               local pool=${1}
+               local key=${2}
+               key=${key//-/_}
+               shift 2
+
+               case "${key}" in
+                       dns_server|network)
+                               ipsec_pool_${key} ${pool} "$@"
+                               ;;
+                       show)
+                               cli_ipsec_pool_show "${pool}"
+                               exit $?
+                               ;;
+                       *)
+                               error "Unrecognized argument: ${key}"
+                               exit ${EXIT_ERROR}
+                               ;;
+               esac
+       else
+               local action=${1}
+               shift
+
+               case "${action}" in
+                       new)
+                               ipsec_pool_new "$@"
+                               ;;
+                       destroy)
+                               ipsec_pool_destroy "$@"
+                               ;;
+                       ""|*)
+                               if [ -n "${action}" ]; then
+                                       error "Unrecognized argument: '${action}'"
+                               fi
+                               exit ${EXIT_ERROR}
+                               ;;
+               esac
+       fi
+}
+
+cli_ipsec_connection_destroy() {
+       local connection="${1}"
+
+       if ! ipsec_connection_destroy "${connection}"; then
+               return ${EXIT_ERROR}
+       fi
+
+       # Inform strongswan about the changes
+       ipsec_strongswan_load
+
+       # Configure strongswan autostart
+       ipsec_strongswan_autostart
+}
+
 cli_ipsec_connection_show() {
        local connection="${1}"
 
@@ -198,6 +267,30 @@ cli_ipsec_connection_show() {
        return ${EXIT_OK}
 }
 
+ipsec_connection_disable() {
+       local connection=${1}
+
+       if ! ipsec_connection_write_config_key "${connection}" "ENABLED" "false"; then
+               log ERROR "Could not write configuration settings"
+               return ${EXIT_ERROR}
+       fi
+
+       # Configure strongswan autostart
+       ipsec_strongswan_autostart
+}
+
+ipsec_connection_enable() {
+       local connection=${1}
+
+       if ! ipsec_connection_write_config_key "${connection}" "ENABLED" "true"; then
+               log ERROR "Could not write configuration settings"
+               return ${EXIT_ERROR}
+       fi
+
+       # Configure strongswan autostart
+       ipsec_strongswan_autostart
+}
+
 # This function writes all values to a via ${connection} specificated VPN IPsec configuration file
 ipsec_connection_write_config() {
        assert [ $# -ge 1 ]
@@ -270,7 +363,7 @@ ipsec_connection_read_config() {
        if [ $# -eq 0 ] && [ -n "${IPSEC_CONNECTION_CONFIG_SETTINGS}" ]; then
                list_append args ${IPSEC_CONNECTION_CONFIG_SETTINGS}
        else
-               list_append args $@
+               list_append args "$@"
        fi
 
        local path="${NETWORK_IPSEC_CONNS_DIR}/${connection}/settings"
@@ -293,9 +386,82 @@ ipsec_connection_exists() {
        [ -d "${path}" ] && return ${EXIT_TRUE} || return ${EXIT_FALSE}
 }
 
+# Determines if strongswan should be automatically started
+# when the system boots up.
+ipsec_strongswan_autostart() {
+       local autostart_needed="false"
+
+       local connection
+       for connection in $(ipsec_list_connections); do
+               local ENABLED
+
+               if ! ipsec_connection_read_config "${connection}" "ENABLED"; then
+                       log WARNING "Could not read configuation"
+                       continue
+               fi
+
+               if enabled ENABLED; then
+                       autostart_needed="true"
+                       break
+               fi
+       done
+
+       # Start strongswan when we need it and when it is not yet enabled
+       if ${autostart_needed}; then
+               if ! service_is_enabled "strongswan"; then
+                       service_enable "strongswan"
+               fi
+
+               if ! service_is_active "strongswan"; then
+                       service_start "strongswan"
+               fi
+
+       # Disable strongswan when we do not need it but it is enabled
+       elif ! ${autostart_needed}; then
+               if service_is_enabled "strongswan"; then
+                       service_disable "strongswan"
+               fi
+
+               if service_is_active "strongswan"; then
+                       service_stop "strongswan"
+               fi
+       fi
+}
+
+ipsec_strongswan_load() {
+       # Do nothing if strongswan is not running
+       if ! service_is_active "strongswan"; then
+               return ${EXIT_OK}
+       fi
+
+       if ! cmd swanctl --load-all; then
+               log ERROR "Could not reload strongswan config"
+               return ${EXIT_ERROR}
+       fi
+}
+
 # Reloads the connection after config changes
 ipsec_reload() {
-       return ${EXIT_TRUE}
+       local connection=${1}
+
+       local ENABLED
+
+       if ! ipsec_connection_read_config "${connection}" "ENABLED"; then
+               log ERROR "Could not read configuration for IPsec connection ${connection}"
+               return ${EXIT_ERROR}
+       fi
+
+       if enabled ENABLED; then
+               if ! ipsec_connection_to_strongswan ${connection}; then
+                       log ERROR "Could not generate strongswan config for ${connnection}"
+                       return ${EXIT_ERROR}
+               fi
+       else
+               log DEBUG "Deleting strongswan config ${NETWORK_IPSEC_SWANCTL_CONNECTIONS_DIR}/${connection}.conf"
+               unlink "${NETWORK_IPSEC_SWANCTL_CONNECTIONS_DIR}/${connection}.conf"
+       fi
+
+       ipsec_strongswan_load
 }
 
 # Handle the cli after authentification
@@ -311,10 +477,10 @@ ipsec_connection_authentication() {
 
        case ${cmd} in
                mode)
-                       ipsec_connection_authentication_mode "${connection}" $@
+                       ipsec_connection_authentication_mode "${connection}" "$@"
                        ;;
                pre-shared-key)
-                       ipsec_connection_authentication_psk "${connection}" $@
+                       ipsec_connection_authentication_psk "${connection}" "$@"
                        ;;
                *)
                        log ERROR "Unrecognized argument: ${cmd}"
@@ -408,13 +574,13 @@ ipsec_connection_dpd() {
 
        case ${cmd} in
                action)
-                       ipsec_connection_dpd_action "${connection}" $@
+                       ipsec_connection_dpd_action "${connection}" "$@"
                        ;;
                delay)
-                       ipsec_connection_dpd_delay "${connection}" $@
+                       ipsec_connection_dpd_delay "${connection}" "$@"
                        ;;
                timeout)
-                       ipsec_connection_dpd_timeout "${connection}" $@
+                       ipsec_connection_dpd_timeout "${connection}" "$@"
                        ;;
                *)
                        log ERROR "Unrecognized argument: ${cmd}"
@@ -455,7 +621,7 @@ ipsec_connection_dpd_delay() {
        local value=$@
 
        if ! isinteger value; then
-               value=$(parse_time $@)
+               value=$(parse_time "$@")
                if [ ! $? -eq 0 ]; then
                        log ERROR "Parsing the passed time was not sucessful please check the passed values."
                        return ${EXIT_ERROR}
@@ -487,7 +653,7 @@ ipsec_connection_dpd_timeout() {
        local value=$@
 
        if ! isinteger value; then
-               value=$(parse_time $@)
+               value=$(parse_time "$@")
                if [ ! $? -eq 0 ]; then
                        log ERROR "Parsing the passed time was not sucessful please check the passed values."
                        return ${EXIT_ERROR}
@@ -520,13 +686,13 @@ ipsec_connection_local() {
 
        case ${cmd} in
                address)
-                       ipsec_connection_local_address "${connection}" $@
+                       ipsec_connection_local_address "${connection}" "$@"
                        ;;
                id)
-                       ipsec_connection_id "${connection}" "LOCAL" $@
+                       ipsec_connection_id "${connection}" "LOCAL" "$@"
                        ;;
                prefix)
-                       ipsec_connection_prefix "${connection}" "LOCAL" $@
+                       ipsec_connection_prefix "${connection}" "LOCAL" "$@"
                        ;;
                *)
                        log ERROR "Unrecognized argument: ${cmd}"
@@ -617,16 +783,16 @@ ipsec_connection_id() {
                log ERROR "Id '${id}' is invalid"
                return ${EXIT_ERROR}
        fi
-       
+
        if ! ipsec_connection_write_config_key "${connection}" "${type}_ID" ${id}; then
                log ERROR "Could not write configuration settings"
                return ${EXIT_ERROR}
        fi
-       
+
        return ${EXIT_OK}
 }
 
-# Set the local or remote prefix 
+# Set the local or remote prefix
 ipsec_connection_prefix() {
        if [ ! $# -ge 3 ]; then
                log ERROR "Not enough arguments"
@@ -635,7 +801,7 @@ ipsec_connection_prefix() {
        local connection=${1}
        local type=${2}
        shift 2
-       
+
        local _prefix="${type}_PREFIX"
        local "${_prefix}"
        if ! ipsec_connection_read_config "${connection}" "${_prefix}"; then
@@ -726,6 +892,104 @@ ipsec_connection_prefix() {
        return ${EXIT_OK}
 }
 
+# Set the pools to use
+ipsec_connection_pool() {
+       if [ ! $# -ge 2 ]; then
+               log ERROR "Not enough arguments"
+               return ${EXIT_ERROR}
+       fi
+       local connection=${1}
+       shift
+
+       local POOLS
+       if ! ipsec_connection_read_config "${connection}" "POOLS"; then
+               return ${EXIT_ERROR}
+       fi
+
+       # Remove duplicated entries to proceed the list safely
+       assign "POOLS" "$(list_unique ${POOLS})"
+
+       local pools_added
+       local pools_removed
+       local pools_set
+
+       while [ $# -gt 0 ]; do
+               local arg="${1}"
+
+               case "${arg}" in
+                       +*)
+                               list_append pools_added "${arg:1}"
+                               ;;
+                       -*)
+                               list_append pools_removed "${arg:1}"
+                               ;;
+                       [A-Za-z0-9]*)
+                               list_append pools_set "${arg}"
+                               ;;
+                       *)
+                               error "Invalid argument: ${arg}"
+                               return ${EXIT_ERROR}
+                               ;;
+               esac
+               shift
+       done
+
+       # Check if the user is trying a mixed operation
+       if ! list_is_empty pools_set && (! list_is_empty pools_added || ! list_is_empty pools_removed); then
+               error "You cannot reset the pools list and add or remove pools at the same time"
+               return ${EXIT_ERROR}
+       fi
+
+       # Set new pools list
+       if ! list_is_empty pools_set; then
+               # Check if all pools are valid
+               local pool
+               for pool in ${pools_set}; do
+                       if ! ipsec_pool_exists ${pool} || ! ipsec_pool_check_config ${pool}; then
+                               error "Pool ${pool} is not valid"
+                               return ${EXIT_ERROR}
+                       fi
+               done
+
+               assign "POOLS" "${pools_set}"
+
+       # Perform incremental updates
+       else
+               local pool
+
+               # Perform all removals
+               for pool in ${pools_removed}; do
+                       if ! list_remove "POOLS" ${pool}; then
+                               warning "${pool} was not on the list and could not be removed"
+                       fi
+               done
+
+
+               for pool in ${pools_added}; do
+                       if ipsec_pool_exists ${pool} && ipsec_pool_check_config ${pool}; then
+                               if ! list_append_unique "POOLS" ${pool}; then
+                                       warning "${pool} is already on the prefix list"
+                               fi
+                       else
+                               warning "${pool} is not a valid pool"
+                       fi
+               done
+       fi
+
+       # Check if the list contain at least one valid pool
+       if list_is_empty POOLS; then
+               error "Cannot save an empty pool list"
+               return ${EXIT_ERROR}
+       fi
+
+       # Save everything
+       if ! ipsec_connection_write_config_key "${connection}" "POOLS" ${POOLS}; then
+               log ERROR "Could not write configuration settings"
+       fi
+
+       return ${EXIT_OK}
+}
+
 # Handle the cli after remote
 ipsec_connection_remote() {
        if [ ! $# -ge 2 ]; then
@@ -739,11 +1003,11 @@ ipsec_connection_remote() {
 
        case ${cmd} in
                id)
-                       ipsec_connection_id "${connection}" "REMOTE" $@
+                       ipsec_connection_id "${connection}" "REMOTE" "$@"
                        ;;
 
                prefix)
-                       ipsec_connection_prefix "${connection}" "REMOTE" $@
+                       ipsec_connection_prefix "${connection}" "REMOTE" "$@"
                        ;;
                *)
                        log ERROR "Unrecognized argument: ${cmd}"
@@ -766,7 +1030,7 @@ ipsec_connection_inactivity_timeout() {
        local value=$@
 
        if ! isinteger value; then
-               value=$(parse_time $@)
+               value=$(parse_time "$@")
                if [ ! $? -eq 0 ]; then
                        log ERROR "Parsing the passed time was not sucessful please check the passed values."
                        return ${EXIT_ERROR}
@@ -863,12 +1127,14 @@ ipsec_connection_check_name() {
 
 # Function that creates one VPN IPsec connection
 ipsec_connection_new() {
-       if [ $# -gt 1 ]; then
+       if [ $# -gt 2 ]; then
                error "Too many arguments"
                return ${EXIT_ERROR}
        fi
 
        local connection="${1}"
+       local type="${2}"
+
        if ! isset connection; then
                error "Please provide a connection name"
                return ${EXIT_ERROR}
@@ -886,6 +1152,16 @@ ipsec_connection_new() {
                return ${EXIT_ERROR}
        fi
 
+       # Set TYPE to default if not set by the user
+       if ! isset type; then
+               type="${IPSEC_DEFAULT_TYPE}"
+       fi
+
+       if ! isoneof "type" "net-to-net" "host-to-net"; then
+               error "Type is invalid"
+               return ${EXIT_ERROR}
+       fi
+
        log DEBUG "Creating VPN IPsec connection ${connection}"
 
        if ! mkdir -p "${NETWORK_IPSEC_CONNS_DIR}/${connection}"; then
@@ -899,8 +1175,10 @@ ipsec_connection_new() {
        DPD_ACTION=${IPSEC_DEFAULT_DPD_ACTION}
        DPD_DELAY=${IPSEC_DEFAULT_DPD_DELAY}
        DPD_TIMEOUT=${IPSEC_DEFAULT_DPD_TIMEOUT}
+       ENABLED=${IPSEC_DEFAULT_ENABLED}
        MODE=${IPSEC_DEFAULT_MODE}
        START_ACTION=${IPSEC_DEFAULT_START_ACTION}
+       TYPE="${type}"
 
        INACTIVITY_TIMEOUT=${IPSEC_DEFAULT_INACTIVITY_TIMEOUT}
        SECURITY_POLICY=${IPSEC_DEFAULT_SECURITY_POLICY}
@@ -909,22 +1187,30 @@ ipsec_connection_new() {
                log ERROR "Could not write new config file"
                return ${EXIT_ERROR}
        fi
+
+       # Configure strongswan autostart
+       ipsec_strongswan_autostart
 }
 
 # Function that deletes based on the passed parameters one ore more vpn security policies
 ipsec_connection_destroy() {
        local connection
-       for connection in $@; do
+       for connection in "$@"; do
                if ! ipsec_connection_exists "${connection}"; then
                        log ERROR "The VPN IPsec connection ${connection} does not exist."
                        continue
                fi
 
                log DEBUG "Deleting VPN IPsec connection ${connection}"
+
+               # Delete strongswan configuration file
+               file_delete "${NETWORK_IPSEC_SWANCTL_CONNECTIONS_DIR}/${connection}.conf"
+
                if ! rm -rf "${NETWORK_IPSEC_CONNS_DIR}/${connection}"; then
                        log ERROR "Deleting the VPN IPsec connection ${connection} was not sucessful"
                        return ${EXIT_ERROR}
                fi
+
        done
 }
 
@@ -939,6 +1225,7 @@ ipsec_list_connections() {
 
 ipsec_connection_to_strongswan() {
        local connection="${1}"
+       log DEBUG "Generating IPsec configuration for ${connection}"
 
        # Read the config settings
        local ${IPSEC_CONNECTION_CONFIG_SETTINGS}
@@ -974,6 +1261,9 @@ _ipsec_connection_to_strongswan_connection() {
                dpd="true"
        fi
 
+       # Write configuration header
+       config_header "strongSwan configuration for ${connection}"
+
        print_indent 0 "connections {"
        print_indent 1 "${connection} {"
 
@@ -991,6 +1281,11 @@ _ipsec_connection_to_strongswan_connection() {
        esac
        print # empty line
 
+       # Always only keep one connection open at a time
+       print_indent 2 "# Unique IDs"
+       print_indent 2 "unique = replace"
+       print
+
        # Local Address
        print_indent 2 "# Local Address"
        if isset LOCAL_ADDRESS; then
@@ -1011,7 +1306,7 @@ _ipsec_connection_to_strongswan_connection() {
 
        # IKE Proposals
        print_indent 2 "# IKE Proposals"
-       print_indent 2 "proposals = $(vpn_security_policies_make_ah_proposal ${SECURITY_POLICY})"
+       print_indent 2 "proposals = $(vpn_security_policies_make_ike_proposal ${SECURITY_POLICY})"
        print
 
        # DPD Settings
@@ -1031,6 +1326,19 @@ _ipsec_connection_to_strongswan_connection() {
        print_indent 2 "fragmentation = yes"
        print
 
+
+       # Host-to-Net specific settings
+       case "${TYPE}" in
+               host-to-net)
+                       # Pools
+                       if isset POOLS; then
+                               print_indent 2 "# Pools"
+                               print_indent 2 "pools = $(list_join POOLS ", ")"
+                               print
+                       fi
+                       ;;
+       esac
+
        # Local
        print_indent 2 "local {"
 
@@ -1102,10 +1410,14 @@ _ipsec_connection_to_strongswan_connection() {
        print
 
        # Netfilter Marks
-       print_indent 4 "# Netfilter Marks"
-       print_indent 4 "mark_in = %unique"
-       print_indent 4 "mark_out = %unique"
-       print
+       case "${MODE}" in
+               vti)
+                       print_indent 4 "# Netfilter Marks"
+                       print_indent 4 "mark_in = %unique"
+                       print_indent 4 "mark_out = %unique"
+                       print
+                       ;;
+       esac
 
        # Dead Peer Detection
        if enabled dpd; then
@@ -1153,23 +1465,28 @@ _ipsec_connection_to_strongswan_connection() {
                print
        fi
 
-       # Start Action
-       print_indent 4 "# Start Action"
-       case "${START_ACTION}" in
-               on-demand)
-                       print_indent 4 "start_action = trap"
-                       print_indent 4 "close_action = trap"
-                       ;;
-               wait)
-                       print_indent 4 "start_action = none"
-                       print_indent 4 "close_action = none"
-                       ;;
-               always-on|*)
-                       print_indent 4 "start_action = start"
-                       print_indent 4 "close_action = start"
+       # Net-to-Net specific settings
+       case "${TYPE}" in
+               net-to-net)
+                       # Start Action
+                       print_indent 4 "# Start Action"
+                       case "${START_ACTION}" in
+                               on-demand)
+                                       print_indent 4 "start_action = trap"
+                                       print_indent 4 "close_action = trap"
+                                       ;;
+                               wait)
+                                       print_indent 4 "start_action = none"
+                                       print_indent 4 "close_action = none"
+                                       ;;
+                               always-on|*)
+                                       print_indent 4 "start_action = start"
+                                       print_indent 4 "close_action = start"
+                                       ;;
+                       esac
+                       print
                        ;;
        esac
-       print
 
        print_indent 3 "}"
        print_indent 2 "}"
@@ -1203,3 +1520,359 @@ _ipsec_connection_to_strongswan_secrets() {
 
        print_indent 0 "}"
 }
+
+# This function writes all values to a via ${pool} specificated VPN IPsec pool configuration file
+ipsec_pool_write_config() {
+       assert [ $# -ge 1 ]
+
+       local pool="${1}"
+
+       if ! ipsec_pool_exists "${pool}"; then
+               log ERROR "No such VPN IPsec pool: ${pool}"
+               return ${EXIT_ERROR}
+       fi
+
+       local path="${NETWORK_IPSEC_POOLS_DIR}/${pool}/settings"
+
+       if ! settings_write "${path}" ${IPSEC_POOL_CONFIG_SETTINGS}; then
+               log ERROR "Could not write configuration settings for VPN IPsec pool ${pool}"
+               return ${EXIT_ERROR}
+       fi
+
+       if ! ipsec_pool_reload ${pool}; then
+               log WARNING "Could not reload IPsec pool ${pool}"
+       fi
+
+       # When we get here the writing of the config file was successful
+       return ${EXIT_OK}
+}
+
+# This funtion writes the value for one key to a via ${connection} specificated
+# VPN IPsec pool configuration file
+ipsec_pool_write_config_key() {
+       assert [ $# -ge 3 ]
+
+       local pool=${1}
+       local key=${2}
+       shift 2
+
+       local value="$@"
+
+       if ! ipsec_pool_exists "${pool}"; then
+               log ERROR "No such VPN IPsec pool: ${pool}"
+               return ${EXIT_ERROR}
+       fi
+
+       log DEBUG "Set '${key}' to new value '${value}' in VPN IPsec pool '${pool}'"
+
+       local ${IPSEC_POOL_CONFIG_SETTINGS}
+
+       # Read the config settings
+       if ! ipsec_pool_read_config "${pool}"; then
+               return ${EXIT_ERROR}
+       fi
+
+       # Set the key to a new value
+       assign "${key}" "${value}"
+
+       if ! ipsec_pool_write_config "${pool}"; then
+               return ${EXIT_ERROR}
+       fi
+
+       return ${EXIT_TRUE}
+}
+
+# Reads one or more keys out of a settings file or all if no key is provided.
+ipsec_pool_read_config() {
+       assert [ $# -ge 1 ]
+
+       local pool="${1}"
+       shift 1
+
+       if ! ipsec_pool_exists "${pool}"; then
+               log ERROR "No such VPN IPsec pool : ${pool}"
+               return ${EXIT_ERROR}
+       fi
+
+       local args
+       if [ $# -eq 0 ] && [ -n "${IPSEC_POOL_CONFIG_SETTINGS}" ]; then
+               list_append args ${IPSEC_POOL_CONFIG_SETTINGS}
+       else
+               list_append args "$@"
+       fi
+
+       local path="${NETWORK_IPSEC_POOLS_DIR}/${pool}/settings"
+
+       if ! settings_read "${path}" ${args}; then
+               log ERROR "Could not read settings for VPN IPsec pool ${pool}"
+               return ${EXIT_ERROR}
+       fi
+}
+
+# This function checks if a vpn IPsec pool exists
+# Returns True when yes and false when not
+ipsec_pool_exists() {
+       assert [ $# -eq 1 ]
+
+       local pool=${1}
+
+       local path="${NETWORK_IPSEC_POOLS_DIR}/${pool}"
+
+       [ -d "${path}" ] && return ${EXIT_TRUE} || return ${EXIT_FALSE}
+}
+
+# This function checks if a VPN IPsec pool name is valid
+# Allowed are only A-Za-z0-9
+ipsec_pool_check_name() {
+       assert [ $# -eq 1 ]
+
+       local pool=${1}
+
+       # These are special words in strongswan
+       if isoneof pool dhcp radius; then
+               return ${EXIT_ERROR}
+       fi
+
+       [[ "${pool}" =~ [^[:alnum:]$] ]]
+}
+
+ipsec_pool_new() {
+       if [ $# -gt 1 ]; then
+               error "Too many arguments"
+               return ${EXIT_ERROR}
+       fi
+
+       local pool="${1}"
+       if ! isset pool; then
+               error "Please provide a pool name"
+               return ${EXIT_ERROR}
+       fi
+
+       # Check for duplicates
+       if ipsec_pool_exists "${pool}"; then
+               error "The VPN IPsec pool ${pool} already exists"
+               return ${EXIT_ERROR}
+       fi
+
+       # Check if the name of the connection is valid
+       if  ipsec_pool_check_name "${pool}"; then
+               error "'${pool}' contains illegal characters"
+               return ${EXIT_ERROR}
+       fi
+
+       log DEBUG "Creating VPN IPsec pool ${pool}"
+
+       if ! mkdir -p "${NETWORK_IPSEC_POOLS_DIR}/${pool}"; then
+               log ERROR "Could not create config directory for ${pool}"
+               return ${EXIT_ERROR}
+       fi
+
+       local ${IPSEC_POOL_CONFIG_SETTINGS}
+
+       if ! ipsec_pool_write_config "${pool}"; then
+               log ERROR "Could not write new config file"
+               return ${EXIT_ERROR}
+       fi
+}
+
+# Function that deletes based on the passed parameters
+# one ore more vpn ipsec pools
+ipsec_pool_destroy() {
+       local pool
+       for pool in "$@"; do
+               if ! ipsec_pool_exists "${pool}"; then
+                       log ERROR "The VPN IPsec pool ${pool} does not exist."
+                       continue
+               fi
+
+               log DEBUG "Deleting VPN IPsec pool ${pool}"
+
+               if ! rm -rf "${NETWORK_IPSEC_POOLS_DIR}/${pool}"; then
+                       log ERROR "Deleting the VPN IPsec pool ${pool} was not sucessful"
+                       return ${EXIT_ERROR}
+               fi
+       done
+}
+
+ipsec_pool_set_type() {
+       local pool=${1}
+       local ip=${2}
+       assert isset pool
+       assert isset ip
+
+       local type=$(ip_detect_protocol ${ip})
+
+       if ! isset type; then
+               error "Cannot detect IP protocol of ${ip}"
+               return ${EXIT_ERROR}
+       else
+               log DEBUG "IP protocol of ${ip} is ${type}"
+               if ! ipsec_pool_write_config_key "${pool}" "TYPE" ${type}; then
+                       log ERROR "Could not write configuration settings"
+                       return ${EXIT_ERROR}
+               fi
+       fi
+}
+
+ipsec_pool_network() {
+       if [ ! $# -eq 2 ]; then
+               log ERROR "Not enough arguments"
+               return ${EXIT_ERROR}
+       fi
+       local pool=${1}
+       local network=${2}
+
+       local TYPE
+       if ! ipsec_pool_read_config ${pool} "TYPE"; then
+               error "Failed to read configuration settings for pool '${pool}'"
+               return ${EXIT_ERROR}
+       fi
+
+       if ! isset TYPE; then
+               if ! ip_net_is_valid ${network}; then
+                       log ERROR "Network '${network}' is invalid"
+                       return ${EXIT_ERROR}
+               fi
+
+               if ! ipsec_pool_set_type ${pool} ${network}; then
+                       log ERROR "Could not set type for IPsec pool ${pool}"
+                       return ${EXIT_ERROR}
+               fi
+       else
+               if ! ${TYPE}_net_is_valid ${network}; then
+                       log ERROR "Network '${network}' is invalid"
+                       return ${EXIT_ERROR}
+               fi
+       fi
+
+       if ! ipsec_pool_write_config_key "${pool}" "NETWORK" ${network}; then
+               log ERROR "Could not write configuration settings"
+               return ${EXIT_ERROR}
+       fi
+}
+
+ipsec_pool_dns_server() {
+       if [ ! $# -eq 2 ]; then
+               log ERROR "Not enough arguments"
+               return ${EXIT_ERROR}
+       fi
+       local pool=${1}
+       local dns_server=${2}
+
+       local TYPE
+       if ! ipsec_pool_read_config ${pool} "TYPE"; then
+               error "Failed to read configuration settings for pool '${pool}'"
+               return ${EXIT_ERROR}
+       fi
+
+       if ! isset TYPE; then
+               if ! ip_is_valid ${dns_server}; then
+                       log ERROR "DNS server '${dns_server}' is invalid"
+                       return ${EXIT_ERROR}
+               fi
+
+               if ! ipsec_pool_set_type ${pool} ${dns_server}; then
+                       log ERROR "Could not set type for IPsec pool ${pool}"
+                       return ${EXIT_ERROR}
+               fi
+       else
+               if ! ${TYPE}_is_valid ${dns_server}; then
+                       log ERROR "DNS server '${dns_server}' is invalid"
+                       return ${EXIT_ERROR}
+               fi
+       fi
+
+       if ! ipsec_pool_write_config_key "${pool}" "DNS_SERVER" ${dns_server}; then
+               log ERROR "Could not write configuration settings"
+               return ${EXIT_ERROR}
+       fi
+}
+
+ipsec_pool_check_config() {
+       local pool=${1}
+       assert isset pool
+
+       local ${IPSEC_POOL_CONFIG_SETTINGS}
+       if ! ipsec_pool_read_config "${pool}"; then
+               log ERROR "Could not read configuration settings"
+               return ${EXIT_ERROR}
+       fi
+
+       if ! isset NETWORK; then
+               log ERROR "Network for IPSec pool ${pool} is not set"
+               return ${EXIT_ERROR}
+       fi
+
+       if ! isset TYPE; then
+               TYPE=$(ip_detect_protocol ${NETWORK})
+               log DEBUG "IP protocol of ${NETWORK} is ${TYPE}"
+               if ! isset TYPE; then
+                       error "Cannot detect IP protocol of ${NETWORK}"
+                       return ${EXIT_ERROR}
+               else
+                       if ! ipsec_pool_write_config_key "${pool}" "TYPE" ${TYPE}; then
+                               log ERROR "Could not write configuration settings"
+                               return ${EXIT_ERROR}
+                       fi
+               fi
+       else
+               if ! ${TYPE}_net_is_valid ${NETWORK}; then
+                       log ERROR "NETWORK '${NETWORK}' is invalid"
+                       return ${EXIT_ERROR}
+               fi
+
+               if isset DNS_SERVER && ! ${TYPE}_is_valid ${DNS_SERVER}; then
+                       log ERROR "DNS server '${DNS_SERVER}' is invalid"
+                       return ${EXIT_ERROR}
+               fi
+       fi
+
+       return ${EXIT_OK}
+}
+
+ipsec_pool_reload() {
+       local pool=${1}
+
+       if ! ipsec_pool_to_strongswan ${pool}; then
+               log ERROR "Could not generate strongswan config for ${pool}"
+               return ${EXIT_ERROR}
+       fi
+
+       ipsec_strongswan_load
+}
+
+ipsec_pool_to_strongswan() {
+       local pool=${1}
+
+       log DEBUG "Generating IPsec pool config for ${pool}"
+
+       local ${IPSEC_POOL_CONFIG_SETTINGS}
+       if ! ipsec_pool_read_config "${pool}"; then
+               return ${EXIT_ERROR}
+       fi
+
+       if isset NETWORK && ! ipsec_pool_check_config "${pool}"; then
+               log ERROR "Configuration of ${pool} seems to be invalid"
+               return ${EXIT_ERROR}
+       fi
+
+       local path="${NETWORK_IPSEC_SWANCTL_POOLS_DIR}/${pool}.conf"
+
+       (
+               config_header "strongSwan pool configuration"
+
+               if isset NETWORK; then
+                       print_indent 0 "pools {"
+
+                       print_indent 1 "${pool} {"
+                       print_indent 2 "addrs = ${NETWORK}"
+
+                       if isset DNS_SERVER; then
+                               print_indent 2 "dns = ${DNS_SERVER}"
+                       fi
+
+                       print_indent 1 "}"
+                       print_indent 0 "}"
+               fi
+       ) > ${path}
+}