Add UCI support to Openswan

The Openswan and UCI configuration file formats are very similar.
Implement the conversion from UCI to IPsec configuration file format in
the ipsec init script and store the converted information in
/etc/ipsec.uci.{conf,secrets} then reference these files from
/etc/ipsec.{conf,secrets}.  This scheme allows for
backwards-compatibility during upgrades (since the original
configuration is preserved) and allows for users to implement any exotic
configurations that they require without conflicting with the
configuration in UCI.

Also add a nearly empty ipsec config file which enables nat_traversal.
This option should be safe in all configurations and is required in
many, which makes it a good default.

Signed-off-by: Kevin Locke <kevin@kevinlocke.name>

git-svn-id: svn://svn.openwrt.org/openwrt/packages@29585 3c298f89-4303-0410-b956-a3cf2f4a3e73
This commit is contained in:
jow 2011-12-20 04:36:42 +00:00
parent 6d1726c72d
commit 52cf8701e7
5 changed files with 205 additions and 1 deletions

View File

@ -86,12 +86,17 @@ endef
define Package/openswan/conffiles define Package/openswan/conffiles
/etc/ipsec.conf /etc/ipsec.conf
/etc/ipsec.secrets /etc/ipsec.secrets
/etc/config/ipsec
endef endef
define Package/openswan/install define Package/openswan/install
$(CP) $(PKG_INSTALL_DIR)/* $(1) $(CP) $(PKG_INSTALL_DIR)/* $(1)
$(INSTALL_DIR) $(1)/etc/init.d $(INSTALL_DIR) $(1)/etc/init.d
$(CP) ./files/ipsec.init $(1)/etc/init.d/ipsec $(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/share
rm -rf $(1)/usr/man rm -rf $(1)/usr/man
rm -rf $(1)/var rm -rf $(1)/var

View File

@ -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

View File

@ -0,0 +1,2 @@
config ipsec_config setup
option nat_traversal yes

View File

@ -32,7 +32,187 @@
START=60 START=60
EXTRA_COMMANDS=status 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() { script_init() {
me='ipsec setup' # for messages me='ipsec setup' # for messages
@ -189,6 +369,7 @@ script_command() {
esac esac
} }
start() { start() {
ipsec_config_convert
script_init start "$@" script_init start "$@"
script_command start "$@" script_command start "$@"
} }
@ -199,6 +380,7 @@ stop() {
} }
restart() { restart() {
ipsec_config_convert
script_init stop "$@" script_init stop "$@"
script_command stop "$@" script_command stop "$@"
script_command start "$@" script_command start "$@"

View File

@ -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