-
-
Save lo48576/d120d139e091f2338d35e1de85f9315f to your computer and use it in GitHub Desktop.
#!/bin/sh | |
# Copyright (C) 2004 Joe Smith <[email protected]> | |
# Copyright (C) 2004-2015 Wayne Davison <[email protected]> | |
# Copyright (C) 2016-2018 YOSHIOKA Takuma <[email protected]> | |
# | |
# This program is free software: you can redistribute it and/or modify | |
# it under the terms of the GNU General Public License as published by | |
# the Free Software Foundation, either version 3 of the License, or | |
# (at your option) any later version. | |
# | |
# This program is distributed in the hope that it will be useful, | |
# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
# GNU General Public License for more details. | |
# | |
# You should have received a copy of the GNU General Public License | |
# along with this program. If not, see <http://www.gnu.org/licenses/>. | |
# This script is based on `support/rrsync` perl script in rsync-3.1.2. | |
USAGE="Use command=\"$0 [-ro|-wo] SUBDIR\" | |
in front of lines in ${HOME}/.ssh/authorized_keys" | |
LOGFILE="${HOME}/rrsync.log" | |
CMDNAME="$0" | |
# Log the given message. | |
die() { | |
DATETIME="$(LANG=C date '+%F %T')" | |
echo "[$DATETIME] $CMDNAME: $1" >>"$LOGFILE" | |
echo >>"$LOGFILE" | |
exit 2 | |
} | |
# Die with the given error message. | |
debug() { | |
DATETIME="$(LANG=C date '+%F %T')" | |
echo "[$DATETIME][DEBUG] $1" | tr '\n' '\0' | sed -e 's/\0/\n[DEBUG]'"$DATETIME"'/g' >>"$LOGFILE" | |
} | |
# Get "only" option. | |
# It would be "w" for `-wo` (write only), "r" for `-ro` (read only), or empty string (neither `-ro` nor `-wo`). | |
ONLY="" | |
while [ "x$1" = "x-ro" -o "x$1" = "x-wo" ] ; do | |
if [ "x$1" = "x-ro" ] ; then | |
if [ "x$ONLY" = "xw" ] ; then | |
die "the -ro and -wo options conflict." | |
fi | |
ONLY="r" | |
shift | |
else | |
if [ "x$ONLY" = "xr" ] ; then | |
die "the -ro and -wo options conflict." | |
fi | |
ONLY="w" | |
shift | |
fi | |
done | |
# Now "$ONLY" has "r", "w" or "". | |
# Ensure the subdirectory is given. | |
if [ $# -lt 1 ] ; then | |
die "No subdirectory specified.\n${USAGE}" | |
fi | |
ALLOWED_DIR="$1" | |
cd "$ALLOWED_DIR" || die 'Failed to change current directory' | |
# Ensure the rrsync is invoked via sshd. | |
if [ -z "$SSH_ORIGINAL_COMMAND" ] ; then | |
die "Not invoked via sshd.\n${USAGE}" | |
fi | |
# Ensure the rrsync is invoked in server mode via remote rsync. | |
if ! echo "$SSH_ORIGINAL_COMMAND" | grep -sqE '^rsync\s+--server' ; then | |
die "SSH_ORIGINAL_COMMAND='$SSH_ORIGINAL_COMMAND' is not 'rsync --server' or '--server' is not specified first." | |
fi | |
# Check whether the rsync server should be sender or receiver. | |
if echo "$SSH_ORIGINAL_COMMAND" | grep -sqE '^rsync\s+--server\s+--sender\s' ; then | |
# The local rsync is sender mode, i.e. files should be sent from local to remote. | |
if [ "x$ONLY" = "xw" ] ; then | |
die "Sending to read-only server not allowed." | |
fi | |
else | |
# The local rsync is receiver mode, i.e. files should be sent from remote to local. | |
if [ "x$ONLY" = "xr" ] ; then | |
die "Reading to write-only server not allowed." | |
fi | |
fi | |
# Command line sanity check. | |
set -f | |
set -- $SSH_ORIGINAL_COMMAND | |
# For each argument: | |
while [ $# -ge 1 ] ; do | |
# Collapse continuous slashes in the argument. | |
ARG="$(echo "$1" | sed -e 's!///*!/!g')" | |
# Ensure the argument has no ".." as path component. | |
if echo "$ARG" | grep -sqE '(^(-[a-zA-Z0-9-]+=?)?|/)\.\.(/|$)' ; then | |
debug "command line: ${SSH_ORIGINAL_COMMAND}\ndangerous argument: \`$1\`" | |
die "Do not use .. in option argument, anchor the path at the root of your restricted dir." | |
fi | |
# Ensure the argument has no absolute path. | |
if echo "$ARG" | grep -sq '^/' ; then | |
debug "command line: ${SSH_ORIGINAL_COMMAND}\ndangerous argument: \`$1\`" | |
die "Do not use absolute path in argument, anchor the path at the root of your restricted dir." | |
fi | |
shift | |
done | |
# Arguments are safe! | |
# Execute rsync. | |
exec $SSH_ORIGINAL_COMMAND |
@dbishop
This script is based on rrsync distributed in rsync package by samba project and it is licensed under GPLv3 (See rsync's license).
I don't understand GPLv3 very well, but I think rrsync.sh
script should inherit GPL license.
Sorry for my late reply.
Please note that this script is NOT safe without further modification. rsync 3 introduced the --protect-args (-s) parameter which would no longer send the path as part of the rsync command line arguments. With that parameter set this script would accept any path.
The original script explicitly disallows the -s parameter. See https://git.samba.org/?p=rsync.git;a=commitdiff;h=2e8259bb0bc5ffe64df9075ef8f1e8050caf951c.
It also ignores any of the long parameters.
Thank you, noted that the script is unmaintained (at least now).
I might try to fix the problem if I can understand the problem correctly, but it is not guaranteed...
The code is licensed under GPLv3, feel free to modify and distribute the script if you want!
Hi! I was wondering if this code was open source, and if so, under what license you like to share it?
Thanks!
Darrell