Passwordless SSH messes with escaped spaces

Jannes Faber jannes.faber at gmail.com
Thu Aug 24 22:41:42 GMT 2006


Hi,

Thanks for your answer.

Yes that's what I want to do. Well luckily I can tell normal spaces 
apart from escaped ones because the \ is still there (unless there are 
really weird file names that screw that up).

I thought I had actually tried exec "${arr[@]}" (you think enjoy typing 
all those lines? :)  ) but I guess not: works like a charm. Thanks !

Anyway, hoping it might be useful to someone else, here's the version I 
have now (any comments on mistakes or omissions are very welcome!) :

#!/bin/sh
# v0.2  2006-08-25    jannes.faber at gmail.com
#
# Drops any command with any "special" character in it.
#    < > | & ; $ `
#
# Then only allows "rsync --server --sender ..." but retains any
# escaped spaces in the arguments.
#

cmd="$SSH_ORIGINAL_COMMAND"

myself=${0##*/}
logfile="/var/log/${myself}.log"

# Log the command
echo "$(date '+%F %T') $cmd" >> $logfile

# Clean up string
cmd="${cmd/</}"
cmd="${cmd/>/}"
cmd="${cmd/|/}"
cmd="${cmd/&/}"
cmd="${cmd/;/}"
cmd="${cmd/\$/}"
cmd="${cmd/'`'/}"

# Is it still the same? If there were any illegal
# characters, log it and quit directly
[ ! "$cmd" = "$SSH_ORIGINAL_COMMAND" ] && {
  echo "WARNING: previous command contains ILLEGAL characters!" >> $logfile
  exit 1
}

[ ! "${cmd:0:24}" = "rsync --server --sender " ] && exit 1

# ok, seems the command passed all tests. Now fix it so we preserve
# any escaped spaces.
set $cmd
declare -a arr

i=0
for a in $*; do
  arr[$i]="${arr[$i]:+${arr[$i]} }$1"
  if [ "${1%\\}" = "$1" ]; then
    i=$(($i+1))
  else
    arr[$i]="${arr[$i]%\\}"
  fi
  shift 1
done

# Finally, we're ready to run the command!
exec "${arr[@]}"


Jannes Faber

Matt McCutchen wrote:
> So really, your goal is to somehow get back from $SSH_ORIGINAL_COMMAND
> the original arguments, check that the first three are what they
> should be, and then execute the command line without further
> expansion.  Since $SSH_ORIGINAL_COMMAND doesn't give you any way to
> tell spaces between arguments from spaces inside arguments, one can't
> do much better than your approach.
>
> For the final exec, you could just use exec "${arr[@]}" .  Since bash
> does not re-expand the contents of variables when they are used,
> backquotes and other shell constructs in ${arr[@]} will not take
> effect, i.e., you're safe.
>
> Matt
>
> .
>


More information about the rsync mailing list