Add UCI support to Openswan
[packages.git] / net / openswan / files / ipsec.init
index 68ad359..b0961b3 100755 (executable)
 
 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" <<ENDHEADER
+# $IPSEC_UCI_CONF - UCI IPsec configuration file
+#
+# This file is automatically generated by the ipsec init script from
+# configuration information stored in UCI.  DO NOT EDIT THIS FILE BY HAND.
+ENDHEADER
+}
+
+ipsec_config_print_header_secret() {
+       cat > "$IPSEC_SEC_UCI_CONF" <<ENDHEADER
+# $IPSEC_SEC_UCI_CONF - UCI IPsec sensitive configuration file
+#
+# This file is automatically generated by the ipsec init script from
+# configuration information stored in UCI.  DO NOT EDIT THIS FILE BY HAND.
+ENDHEADER
+}
+
+ipsec_config_add_secret_cs() {
+       local SECTNAME="$1"
+
+       config_get "FILE" "$SECTNAME" "file"
+       config_get "SECRET" "$SECTNAME" "secret"
+
+       FILE="\"$FILE\""
+       if [ "$SECRET" != "%prompt" ] ; then
+               SECRET="\"$SECRET\""
+       fi
+
+       echo ": RSA $FILE $SECRET" >> "$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 "$@"