From 1d49567af0acaca79fe9047703a0d94ebaf31064 Mon Sep 17 00:00:00 2001 From: Jouke Witteveen Date: Mon, 18 Mar 2013 09:13:26 +0100 Subject: Proper systemd escaping This fixes the use of all sorts of characters in profile names/interface names. --- src/lib/8021x | 2 +- src/netctl | 32 +++++++++++++++++++++----------- 2 files changed, 22 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/lib/8021x b/src/lib/8021x index fa23dd3..7a841a4 100644 --- a/src/lib/8021x +++ b/src/lib/8021x @@ -2,7 +2,7 @@ ## Wrapper around wpa_cli to deal with supplicant configurations that set a -## non-standard control path. +## non-standard control path # $1: interface name # $2...: call to the supplicant wpa_call() { diff --git a/src/netctl b/src/netctl index aac0dac..9e14e55 100755 --- a/src/netctl +++ b/src/netctl @@ -14,7 +14,7 @@ Commands: list List available profiles store Save which profiles are active restore Load saved profiles - stop-all Stops all profiles. + stop-all Stops all profiles start [PROFILE] Start a profile stop [PROFILE] Stop a profile restart [PROFILE] Restart a profile @@ -26,12 +26,22 @@ Commands: END } -# Wrapper around systemctl to convert profile names to unit names. +sd_escape() { + local IFS='' + # Prevent a recursion loop on backspaces + set "${@//\\/\\x5c}" + while [[ "$*" =~ [^[:alnum:].:_/\\] ]]; do + set "${@//$BASH_REMATCH/$(printf '\\x%x' "'$BASH_REMATCH")}" + done + printf '%s\n' "${@//\//-}" +} + +# Wrapper around systemctl to convert profile names to unit names sd_call() { - local cmd=$1 units + local command=$1 shift - mapfile -t units < <(printf 'netctl@%s.service\n' "$@") - systemctl $cmd "${units[@]}" + set $(sd_escape "$@") + systemctl $command $(printf 'netctl@%s.service\n' "$@") } list() { @@ -90,7 +100,7 @@ switch_to() { } unit_enable() { - local unit="/etc/systemd/system/netctl@$1.service" + local unit="/etc/systemd/system/netctl@$(sd_escape "$1").service" if [[ -e $unit ]]; then report_error "A unit file for profile '$1' already exists" return 1 @@ -100,13 +110,13 @@ unit_enable() { echo -e "\n[Unit]" >> "$unit" [[ -n $Description ]] && echo "Description=$Description" >> "$unit" : ${BindsToInterfaces=$Interface} - BindsToInterfaces=( "${BindsToInterfaces[@]//-/\\x2d}" ) printf 'BindsTo=sys-subsystem-net-devices-%s.device\n' \ - "${BindsToInterfaces[@]}" >> "$unit" + $(sd_escape "${BindsToInterfaces[@]}") >> "$unit" printf 'After=sys-subsystem-net-devices-%s.device\n' \ - "${BindsToInterfaces[@]}" >> "$unit" + $(sd_escape "${BindsToInterfaces[@]}") >> "$unit" if [[ -n $After ]]; then - printf 'After="netctl@%s.service"\n' "${After[@]//\"/\\\"}" >> "$unit" + printf 'After="netctl@%s.service"\n' \ + $(sd_escape "${After[@]}") >> "$unit" fi echo "ln -s '$unit' '${unit/system\//system/multi-user.target.wants/}'" ln -s "$unit" "${unit/system\//system/multi-user.target.wants/}" @@ -114,7 +124,7 @@ unit_enable() { } unit_disable() { - local unit="/etc/systemd/system/netctl@$1.service" + local unit="/etc/systemd/system/netctl@$(sd_escape "$1").service" if sd_call "is-enabled --quiet" "$1" &> /dev/null; then sd_call disable "$1" fi -- cgit v1.2.3-24-g4f1b