diff --git a/net/openswan/Makefile b/net/openswan/Makefile index 6920a714a..29d58ad86 100644 --- a/net/openswan/Makefile +++ b/net/openswan/Makefile @@ -86,12 +86,17 @@ endef define Package/openswan/conffiles /etc/ipsec.conf /etc/ipsec.secrets +/etc/config/ipsec endef define Package/openswan/install $(CP) $(PKG_INSTALL_DIR)/* $(1) $(INSTALL_DIR) $(1)/etc/init.d $(CP) ./files/ipsec.init $(1)/etc/init.d/ipsec + $(CP) ./files/ipsec.conf $(1)/etc/ipsec.conf + $(CP) ./files/ipsec.secrets $(1)/etc/ipsec.secrets + $(INSTALL_DIR) $(1)/etc/config + $(INSTALL_CONF) ./files/ipsec.config $(1)/etc/config/ipsec rm -rf $(1)/usr/share rm -rf $(1)/usr/man rm -rf $(1)/var diff --git a/net/openswan/files/ipsec.conf b/net/openswan/files/ipsec.conf new file mode 100644 index 000000000..b214bac08 --- /dev/null +++ b/net/openswan/files/ipsec.conf @@ -0,0 +1,8 @@ +# /etc/ipsec.conf - IPsec configuration file + +version 2.0 + +include /etc/ipsec.uci.conf + +# Include non-UCI connections here +# They will be preserved across restarts/upgrades diff --git a/net/openswan/files/ipsec.config b/net/openswan/files/ipsec.config new file mode 100644 index 000000000..6469e9898 --- /dev/null +++ b/net/openswan/files/ipsec.config @@ -0,0 +1,2 @@ +config ipsec_config setup + option nat_traversal yes diff --git a/net/openswan/files/ipsec.init b/net/openswan/files/ipsec.init index 68ad35929..b0961b3ec 100755 --- a/net/openswan/files/ipsec.init +++ b/net/openswan/files/ipsec.init @@ -32,7 +32,187 @@ START=60 EXTRA_COMMANDS=status -EXTRA_HELP=" status Show the status of the service" +EXTRA_HELP=" status Show the status of the service" + +# Format a list into a delimited string and print it +config_list_delimit() { + local SECTION="$1" + local OPTION="$2" + local DELIMITER="${3:- }" + + config_list_foreach "$SECTION" "$OPTION" "printf \"%s%s\"" "$DELIMITER" | sed "s/.\{${#DELIMITER}\}$//" +} + +# Callback for each ipsec configuration section +# Converts list options from UCI to ipsec format and writes ipsec section headers +CUR_SECTION_NAME= +CUR_SECTION_TYPE= +config_cb() { + local TYPE="$1" + local NAME="$2" + + # Handle list options from previous section + if [ "$CUR_SECTION_TYPE" = "ipsec_conn" ] ; then + local IKE="$(config_list_delimit "$CUR_SECTION_NAME" "ike" ", ")" + if [ -n "$IKE" ] ; then + printf "\tike=\"%s\"\n" "$IKE" >> "$IPSEC_UCI_CONF" + fi + + local SUBNETS + local SPACE_PAT="* *" + config_get "SUBNETS" "$CUR_SECTION_NAME" "leftsubnets" + case "$SUBNETS" in + $SPACE_PAT) + printf "\tleftsubnets={ %s }\n" "$SUBNETS" >> "$IPSEC_UCI_CONF" + ;; + ?*) + printf "\tleftsubnet=%s\n" "$SUBNETS" >> "$IPSEC_UCI_CONF" + ;; + esac + + config_get "SUBNETS" "$CUR_SECTION_NAME" "rightsubnets" + case "$SUBNETS" in + $SPACE_PAT) + printf "\trightsubnets={ %s }\n" "$SUBNETS" >> "$IPSEC_UCI_CONF" + ;; + ?*) + printf "\trightsubnet=%s\n" "$SUBNETS" >> "$IPSEC_UCI_CONF" + ;; + esac + elif [ "$CUR_SECTION_TYPE" = "ipsec_config" ] ; then + local VPRIV="$(config_list_delimit "$CUR_SECTION_NAME" "virtual_private" ",")" + if [ -n "$VPRIV" ] ; then + printf "\tvirtual_private=%s\n" "$VPRIV" >> "$IPSEC_UCI_CONF" + fi + fi + + CUR_SECTION_NAME="$NAME" + CUR_SECTION_TYPE="$TYPE" + + case "$CUR_SECTION_TYPE" in + ipsec_config|ipsec_conn) + # Handled in option_cb + echo >> "$IPSEC_UCI_CONF" + echo "${TYPE#ipsec_} $NAME" >> "$IPSEC_UCI_CONF" + ;; + *) + # Not handled in option_cb + ;; + esac + + return 0 +} + +# Callback for each ipsec configuration option +# Prints each UCI option to $IPSEC_UCI_CONF in ipsec.conf format +option_cb() { + local NAME="$1" + local VALUE="$2" + + case "$CUR_SECTION_TYPE" in + ipsec_config|ipsec_conn) + # Handle option in these sections + ;; + *) + # Ignore options in all other sections + return 0 + ;; + esac + + case "$NAME" in + modecfgdns_ITEM[0-9]*) + printf "\tmodecfgdns%d=%s\n" "${NAME##modecfgdns_ITEM}" "$VALUE" >> "$IPSEC_UCI_CONF" + ;; + modecfgwins_ITEM[0-9]*) + printf "\tmodecfgwins%d=%s\n" "${NAME##modecfgwins_ITEM}" "$VALUE" >> "$IPSEC_UCI_CONF" + ;; + *_ITEM[0-9]*|*_LENGTH) + # Ignore list items and length updates + ;; + [!a-zA-Z]*) + # Ignore non-ipsec.conf parameters + ;; + *) + # Quote values with characers which require quoting + if echo "$VALUE" | grep -q '^[[:alnum:]_%.]*$' ; then + printf "\t%s=%s\n" "$NAME" "$VALUE" >> "$IPSEC_UCI_CONF" + else + printf "\t%s=\"%s\"\n" "$NAME" "$VALUE" >> "$IPSEC_UCI_CONF" + fi + ;; + esac + + return 0 +} + +ipsec_config_convert() { + IPSEC_UCI_CONF="${IPSEC_UCI_CONF:-${IPSEC_CONFS:-/etc}/ipsec.uci.conf}" + ipsec_config_print_header + config_load "ipsec" + # Conversion for $IPSEC_UCI_CONF handled in section_cb and option_cb + + IPSEC_SEC_UCI_CONF="${IPSEC_SEC_UCI_CONF:-${IPSEC_CONFS:-/etc}/ipsec.uci.secrets}" + ipsec_config_print_header_secret + echo >> "$IPSEC_SEC_UCI_CONF" + echo "# Certificate Secrets" >> "$IPSEC_SEC_UCI_CONF" + config_foreach "ipsec_config_add_secret_cs" "ipsec_secret_cs" + echo >> "$IPSEC_SEC_UCI_CONF" + echo "# Shared Secrets" >> "$IPSEC_SEC_UCI_CONF" + config_foreach "ipsec_config_add_secret_ss" "ipsec_secret_ss" + echo >> "$IPSEC_SEC_UCI_CONF" + echo "# XAUTH Secrets" >> "$IPSEC_SEC_UCI_CONF" + config_foreach "ipsec_config_add_secret_xs" "ipsec_secret_xs" +} + +ipsec_config_print_header() { + cat > "$IPSEC_UCI_CONF" < "$IPSEC_SEC_UCI_CONF" <> "$IPSEC_SEC_UCI_CONF" +} + +ipsec_config_add_secret_ss() { + local SECTNAME="$1" + + config_get "INDICES" "$SECTNAME" "indices" + config_get "SECRET" "$SECTNAME" "secret" + + echo "$INDICES : PSK \"$SECRET\"" >> "$IPSEC_SEC_UCI_CONF" +} + +ipsec_config_add_secret_xs() { + local SECTNAME="$1" + + config_get "USERNAME" "$SECTNAME" "username" + config_get "SECRET" "$SECTNAME" "secret" + + echo "@$USERNAME : XAUTH \"$SECRET\"" >> "$IPSEC_SEC_UCI_CONF" +} script_init() { me='ipsec setup' # for messages @@ -189,6 +369,7 @@ script_command() { esac } start() { + ipsec_config_convert script_init start "$@" script_command start "$@" } @@ -199,6 +380,7 @@ stop() { } restart() { + ipsec_config_convert script_init stop "$@" script_command stop "$@" script_command start "$@" diff --git a/net/openswan/files/ipsec.secrets b/net/openswan/files/ipsec.secrets new file mode 100644 index 000000000..138468387 --- /dev/null +++ b/net/openswan/files/ipsec.secrets @@ -0,0 +1,7 @@ +# /etc/ipsec.secrets - IPsec sensitive configuration file + +# Include configuration information from UCI +include /etc/ipsec.uci.secrets + +# Add non-UCI secrets below +# This file will be preserved across restarts/upgrades