Hi,
I'm trying to use rsync through ssh to pull files from PCs that need to be
backup up. I set up the passwordless authentication and things work fine
there.
However there's a problem when I try to seal off the SSH access to restrict
it to limited rsync only using the "command=" in authorized_keys. That
by
itself works, however not in combination with spaces in the file names.
I found several example scripts, but they all give me the same problem:
paths with spaces in them get split up into 2 separate source file names
(spaces are properly escaped of course and things work fine without
"command=").
After endlessly trying all kinds of combinations I "solved" it using
this
kludge, however this doesn't even fully restrict all dangerous things yet
(like back quotes). Someone please tell me there is a really simple thing
I'm missing here, before I waste more time to finish this script:
#!/bin/sh
# v0.1 2006-08-17
# Only allows "rsync --server --sender" but retains any escaped spaces
in
the arguments.
#
cmd="${SSH_ORIGINAL_COMMAND}"
[ ! "${cmd:0:24}" = "rsync --server --sender " ] &&
exit 127
myself=${0##*/}
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
echo "$(date '+%F %T') ${arr[@]}" >>
/var/log/${myself}.log
exec \
${arr[0]:+"${arr[0]}"} ${arr[1]:+"${arr[1]}"}
${arr[2]:+"${arr[2]}"}
${arr[3]:+"${arr[3]}"} \
${arr[4]:+"${arr[4]}"} ${arr[5]:+"${arr[5]}"}
${arr[6]:+"${arr[6]}"}
${arr[7]:+"${arr[7]}"} \
${arr[8]:+"${arr[8]}"} ${arr[9]:+"${arr[9]}"}
${arr[10]:+"${arr[10]}"}
${arr[11]:+"${arr[11]}"} \
${arr[12]:+"${arr[12]}"} ${arr[13]:+"${arr[13]}"}
${arr[14]:+"${arr[14]}"}
${arr[15]:+"${arr[15]}"} \
${arr[16]:+"${arr[16]}"} ${arr[17]:+"${arr[17]}"}
${arr[18]:+"${arr[18]}"}
${arr[19]:+"${arr[19]}"} \
${arr[20]:+"${arr[20]}"} ${arr[21]:+"${arr[21]}"}
${arr[22]:+"${arr[22]}"}
${arr[23]:+"${arr[23]}"} \
${arr[24]:+"${arr[24]}"} ${arr[25]:+"${arr[25]}"}
${arr[26]:+"${arr[26]}"}
${arr[27]:+"${arr[27]}"}
If this really is "the only way" to fix this problem, let me know and
I'll
finish it and post the end result as well.
Thanks
Jannes Faber
-------------- next part --------------
HTML attachment scrubbed and removed
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
On Thu, Aug 24, 2006 at 06:24:58PM +0200, Jannes Faber wrote:> I found several example scripts, but they all give me the same problem: > paths with spaces in them get split up into 2 separate source file names > (spaces are properly escaped of course and things work fine without > "command=").Note that the script "rrsync" in the "support" dir is a perl script that validates a restricted rsync command. It lets you specify a subdir that the user's command should not exit (and it also makes a pass through the command-line arts to reject args that it doesn't like). Matt's suggestion to switch over to a single-instance daemon is also a good way to go. ..wayne..
Maybe Matching Threads
- files-from and filter from one file?
- [Bug 2253] New: No "$@"-like SSH_ORIGINAL_COMMAND leads to escaping, arg-sep and metachar issues
- Logging with ForceCommand and SCP
- Make SSH_ORIGINAL_COMMAND available in AuthorizedKeysCommand context
- setup git in my godaddy server