Improve escaping of arguments passed to ejabberdctl

This fixes issue #804
This commit is contained in:
Paweł Chmielowski 2016-01-04 12:13:18 +01:00
parent fb8a511365
commit 98bad73d56
1 changed files with 81 additions and 69 deletions

View File

@ -1,4 +1,4 @@
#!/bin/sh #!/bin/bash
# define default configuration # define default configuration
POLL=true POLL=true
@ -42,9 +42,9 @@ else
fi fi
# parse command line parameters # parse command line parameters
ARGS="" declare -a ARGS=()
while [ $# -ne 0 ] ; do while [ $# -ne 0 ] ; do
PARAM=$1 PARAM="$1"
shift shift
case $PARAM in case $PARAM in
--) break ;; --) break ;;
@ -55,7 +55,7 @@ while [ $# -ne 0 ] ; do
--ctl-config) EJABBERDCTL_CONFIG_PATH="$1" ; shift ;; --ctl-config) EJABBERDCTL_CONFIG_PATH="$1" ; shift ;;
--logs) LOGS_DIR="$1" ; shift ;; --logs) LOGS_DIR="$1" ; shift ;;
--spool) SPOOL_DIR="$1" ; shift ;; --spool) SPOOL_DIR="$1" ; shift ;;
*) ARGS="$ARGS $PARAM" ;; *) ARGS=("${ARGS[@]}" "$PARAM") ;;
esac esac
done done
@ -160,18 +160,27 @@ export CONTRIB_MODULES_PATH
export CONTRIB_MODULES_CONF_DIR export CONTRIB_MODULES_CONF_DIR
export ERL_LIBS export ERL_LIBS
shell_escape()
{
local RES=()
for i in "$@"; do
printf '%q ' "$i"
done
}
# start server # start server
start() start()
{ {
check_start check_start
$EXEC_CMD "$ERL \ CMD="`shell_escape \"$ERL\" \"$NAME\" \"$ERLANG_NODE\"` \
$NAME $ERLANG_NODE \ -noinput -detached \
-noinput -detached \ $MNESIA_OPTS \
$MNESIA_OPTS \ $KERNEL_OPTS \
$KERNEL_OPTS \ $EJABBERD_OPTS \
$EJABBERD_OPTS \ -s ejabberd \
-s ejabberd \ $ERLANG_OPTS \
$ERLANG_OPTS $ARGS \"$@\"" `shell_escape \"${ARGS[@]}\" \"$@\"`"
$EXEC_CMD "$CMD"
} }
# attach to server # attach to server
@ -179,12 +188,13 @@ debug()
{ {
debugwarning debugwarning
TTY=`tty | sed -e 's/.*\///g'` TTY=`tty | sed -e 's/.*\///g'`
$EXEC_CMD "$ERL \ CMD="`shell_escape \"$ERL\" \"$NAME\" \"debug-${TTY}-${ERLANG_NODE}\"` \
$NAME debug-${TTY}-${ERLANG_NODE} \ -remsh $ERLANG_NODE \
-remsh $ERLANG_NODE \ -hidden \
-hidden \ $KERNEL_OPTS \
$KERNEL_OPTS \ $ERLANG_OPTS \
$ERLANG_OPTS $ARGS \"$@\"" `shell_escape \"${ARGS[@]}\" \"$@\"`"
$EXEC_CMD "$CMD"
} }
# attach to server using Elixir # attach to server using Elixir
@ -193,51 +203,57 @@ iexdebug()
debugwarning debugwarning
TTY=`tty | sed -e 's/.*\///g'` TTY=`tty | sed -e 's/.*\///g'`
# Elixir shell is hidden as default # Elixir shell is hidden as default
$EXEC_CMD "$IEX \ CMD="`shell_escape \"$IEX\" \"$IEXNAME\" \"debug-${TTY}-${ERLANG_NODE}\"` \
$IEXNAME debug-${TTY}-${ERLANG_NODE} \ -remsh $ERLANG_NODE \
--remsh $ERLANG_NODE \ --erl \"`shell_escape \"$KERNEL_OPTS\"\" \
--erl \"$KERNEL_OPTS\" \ --erl \"`shell_escape \"$ERLANG_OPTS\"\" \
--erl \"$ERLANG_OPTS\" --erl \"$ARGS\" --erl \"$@\"" --erl \"`shell_escape \"${ARGS[@]}\"\" \
--erl \"`shell_escape \"$@\"\""
$EXEC_CMD "$CMD"
} }
# start interactive server # start interactive server
live() live()
{ {
livewarning livewarning
$EXEC_CMD "$ERL \ CMD="`shell_escape \"$ERL\" \"$NAME\" \"${ERLANG_NODE}\"` \
$NAME $ERLANG_NODE \ $MNESIA_OPTS \
$MNESIA_OPTS \ $KERNEL_OPTS \
$KERNEL_OPTS \ $EJABBERD_OPTS \
$EJABBERD_OPTS \ -s ejabberd \
-s ejabberd \ $ERLANG_OPTS \
$ERLANG_OPTS $ARGS \"$@\"" `shell_escape \"${ARGS[@]}\" \"$@\"`"
$EXEC_CMD "$CMD"
} }
# start interactive server with Elixir # start interactive server with Elixir
iexlive() iexlive()
{ {
livewarning livewarning
$EXEC_CMD "$IEX \ CMD="`shell_escape \"$IEX\" \"$IEXNAME\" \"${ERLANG_NODE}\"` \
$IEXNAME $ERLANG_NODE \ --erl \"-mnesia dir \\\"$SPOOL_DIR\\\"\" \
--erl \"-mnesia dir \\\"$SPOOL_DIR\\\"\" \ --erl \"`shell_escape \"$KERNEL_OPTS\"`\" \
--erl \"$KERNEL_OPTS\" \ --erl \"`shell_escape \"$EJABBERD_OPTS\"`\" \
--erl \"$EJABBERD_OPTS\" \ --app ejabberd \
--app ejabberd \ --erl \"`shell_escape \"$ERLANG_OPTS\"`\" \
--erl \"$ERLANG_OPTS\" --erl $ARGS --erl \"$@\"" --erl \"`shell_escape \"${ARGS[@]}\"`\" \
--erl \"`shell_escape \"$@\"`\""
$EXEC_CMD "$CMD"
} }
# start server in the foreground # start server in the foreground
foreground() foreground()
{ {
check_start check_start
$EXEC_CMD "$ERL \ CMD="`shell_escape \"$ERL\" \"$NAME\" \"$ERLANG_NODE\"` \
$NAME $ERLANG_NODE \ -noinput \
-noinput \ $MNESIA_OPTS \
$MNESIA_OPTS \ $KERNEL_OPTS \
$KERNEL_OPTS \ $EJABBERD_OPTS \
$EJABBERD_OPTS \ -s ejabberd \
-s ejabberd \ $ERLANG_OPTS \
$ERLANG_OPTS $ARGS \"$@\"" `shell_escape \"${ARGS[@]}\" \"$@\"`"
$EXEC_CMD "$CMD"
} }
debugwarning() debugwarning()
@ -331,8 +347,6 @@ help()
# common control function # common control function
ctl() ctl()
{ {
COMMAND=$@
# Control number of connections identifiers # Control number of connections identifiers
# using flock if available. Expects a linux-style # using flock if available. Expects a linux-style
# flock that can lock a file descriptor. # flock that can lock a file descriptor.
@ -344,13 +358,13 @@ ctl()
if [ ! -x "$JOT" ] ; then if [ ! -x "$JOT" ] ; then
# no flock or jot, simply invoke ctlexec() # no flock or jot, simply invoke ctlexec()
CTL_CONN="ctl-${ERLANG_NODE}" CTL_CONN="ctl-${ERLANG_NODE}"
ctlexec $CTL_CONN $COMMAND ctlexec $CTL_CONN "$@"
result=$? result=$?
else else
# no flock, but at least there is jot # no flock, but at least there is jot
RAND=`jot -r 1 0 $MAXCONNID` RAND=`jot -r 1 0 $MAXCONNID`
CTL_CONN="ctl-${RAND}-${ERLANG_NODE}" CTL_CONN="ctl-${RAND}-${ERLANG_NODE}"
ctlexec $CTL_CONN $COMMAND ctlexec $CTL_CONN "$@"
result=$? result=$?
fi fi
else else
@ -365,7 +379,7 @@ ctl()
( (
exec 8>"$CTL_LOCKFILE" exec 8>"$CTL_LOCKFILE"
if flock --nb 8; then if flock --nb 8; then
ctlexec $CTL_CONN $COMMAND ctlexec $CTL_CONN "$@"
ssresult=$? ssresult=$?
# segregate from possible flock exit(1) # segregate from possible flock exit(1)
ssresult=`expr $ssresult \* 10` ssresult=`expr $ssresult \* 10`
@ -407,13 +421,11 @@ ctl()
ctlexec() ctlexec()
{ {
CONN_NAME=$1; shift CONN_NAME=$1; shift
COMMAND=$(echo $@ | sed 's/["&$;\|<>()]/\\&/g') CMD="`shell_escape \"$ERL\" \"$NAME\" \"$CONN_NAME\"` \
$EXEC_CMD "$ERL \ -noinput -hidden $KERNEL_OPTS -s ejabberd_ctl \
$NAME ${CONN_NAME} \ -extra `shell_escape \"$ERLANG_NODE\"` $EJABBERD_NO_TIMEOUT \
-noinput \ `shell_escape \"$@\"`"
-hidden \ $EXEC_CMD "$CMD"
$KERNEL_OPTS \
-s ejabberd_ctl -extra $ERLANG_NODE $EJABBERD_NO_TIMEOUT $COMMAND"
} }
# stop epmd if there is no other running node # stop epmd if there is no other running node
@ -463,16 +475,16 @@ wait_for_status()
} }
# main handler # main handler
case $ARGS in case "${ARGS[0]}" in
' start') start;; 'start') start;;
' debug') debug;; 'debug') debug;;
' iexdebug') iexdebug;; 'iexdebug') iexdebug;;
' live') live;; 'live') live;;
' iexlive') iexlive;; 'iexlive') iexlive;;
' foreground') foreground;; 'foreground') foreground;;
' ping'*) ping ${ARGS# ping};; 'ping'*) ping ${ARGS# ping};;
' etop') etop;; 'etop') etop;;
' started') wait_for_status 0 30 2;; # wait 30x2s before timeout 'started') wait_for_status 0 30 2;; # wait 30x2s before timeout
' stopped') wait_for_status 3 15 2 && stop_epmd;; # wait 15x2s before timeout 'stopped') wait_for_status 3 15 2 && stop_epmd;; # wait 15x2s before timeout
*) ctl $ARGS;; *) ctl "${ARGS[@]}";;
esac esac