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