File: //dev/shm/.local/sbin/blitz
#!/usr/bin/env bash
# A wrapper script to do this (esentially):
# Server:
# $ gs-memew -s MySecret -l -e "/usr/bin/rsync --server -vlogDtpr --partial ."
# Client:
# $ rsync -aP -e "gs-memew -s MySecret --" test4k.dat 127.1:.
GS_MEMEW_BIN="gs-memew"
RSYNC_SERVER_DEFAULTS="--server -logtprR --safe-links --partial"
# -D special devices
# -g preserver group (may need root)
# -p preserve permissions
# -r recursive into directories
# -R use relative path names
# If client uses '-a' then server must use '-g'
# If client uses '-R' then server must use '-R'
# RSYNC_SERVER_DEFAULTS="--server -lotpr --partial"
# RSYNC_SERVER_DEFAULTS="--server -lotpr --partial"
# RSYNC_SERVER_DEFAULTS="--server -logDtprRe.iLsfxCIvu --partial"
RSYNC_CLIENT_DEFAULTS="-ahPRv"
# Try to use the gs-memew that's in the same path as this binary first.
BIN="$(cd "$(dirname "${0}")" || exit; pwd)/${GS_MEMEW_BIN}"
[[ -f "${BIN}" ]] && GS_MEMEW_BIN="${BIN}"
command -v "${GS_MEMEW_BIN}" >/dev/null 2>&1 || { echo >&2 "${GS_MEMEW_BIN} not found. Check PATH=?"; exit 1; }
command -v rsync >/dev/null 2>&1 || { echo >&2 "rsync not found. Try 'apt-get install rsync' or check PATH=?"; exit 1; }
usage()
{
echo "blitz [-k file] [-s password] [-l] [FILES ...]
-l Server Mode.
-s <secret> Secret (e.g. password).
-k <file> Read Secret from file.
-f <list> Read list of file names from FILE [or - for stdin]
-o RSOPT=val Options passed to rsync.
Example:
$ blitz -s MySecret -l # Server
$ blitz -s MySecret *.dat # Client
...limiting transfer rate to 10kB/sec
$ blitz -s MySecret -o 'RSOPT=--bwlimit=10 -v' /etc/*.conf *.dat
...reading the file list from standard-in
$ cd /etc
$ find . -name '*.mp3' | blitz -s MySecret -f -
...limit the amount of path information by inserting a dot and slash
$ blitz -s MySecret ~/tools/./upx/mp3
See 'man gs-memew' and 'man rsync' for more options."
exit 0
}
read_password()
{
printf >&2 "Enter Secret (or press Enter to generate): "
read -r password
if [[ -z "${password}" ]]; then
password=$(${GS_MEMEW_BIN} -g)
fi
echo "${password}" | tr -d "[:space:]"
}
# remove -o from parameter list.
# Remove -s/-k from parameter list
# Copy all other
OPTERR=0
FL_NEED_PASSWORD=1
# Check if -s or -k is already supplied in environment and dont ask again.
[[ "$TOKET_ARGS" =~ ^'-s' ]] && unset FL_NEED_PASSWORD
[[ "$TOKET_ARGS" =~ ' -s' ]] && unset FL_NEED_PASSWORD
[[ "$TOKET_ARGS" =~ ^'-k' ]] && unset FL_NEED_PASSWORD
[[ "$TOKET_ARGS" =~ ' -k' ]] && unset FL_NEED_PASSWORD
# Current options are options for gs-memew followed by a list of files. We
# need to split off the gs-memew options (all but -o/-s/-k) without the
# files. To do so we need to know which gs-memew options takes an argument
# at add those to getopts's optstring (such as -L <logfile>).
# These are caught by '*'.
# All single options (e.g. -w etc) are caught by '\?'.
# shellcheck disable=SC2220 # Invalid flags are not handled. Add a *) case.
while getopts ":hgls:k:o:L:f:" opt; do
case ${opt} in
o )
RSYNC_ARGS+=${OPTARG//RSOPT=/}
RSYNC_ARGS+=" "
;;
s )
GSNC_ENV_ARGS[${#GSNC_ENV_ARGS[@]}]="-s" # Add to end of array
GSNC_ENV_ARGS[${#GSNC_ENV_ARGS[@]}]="$OPTARG" # Add to end of array
unset FL_NEED_PASSWORD
;;
k )
GSNC_ENV_ARGS[${#GSNC_ENV_ARGS[@]}]="-k" # Add to end of array
KFILE=$(cd "$(dirname "$OPTARG")" && pwd)/$(basename "$OPTARG")
[[ -f "${KFILE}" ]] || { echo >&2 "File not found: ${KFILE}"; exit 255; }
GSNC_ENV_ARGS[${#GSNC_ENV_ARGS[@]}]="${KFILE}" # Add to end of array
unset FL_NEED_PASSWORD
;;
g )
"${GS_MEMEW_BIN}" -g
exit
;;
h )
usage
;;
f )
RSYNC_ARGS+="--files-from=${OPTARG} . "
IS_FILES_FROM=1
;;
l )
IS_SERVER=1
ARGS_NEW[${#ARGS_NEW[@]}]="-l" # Add to end of array
;;
\? )
# UNKNOWN option. Handle before '*' (e.g. -l)
ARGS_NEW[${#ARGS_NEW[@]}]="-${OPTARG}" # Add to end of array
;;
* )
# Other (known opts from opstring) w parameters (e.g. -L <file>)
ARGS_NEW[${#ARGS_NEW[@]}]="-${opt}" # Add to end of array
ARGS_NEW[${#ARGS_NEW[@]}]="${OPTARG}" # Add to end of array
;;
esac
done
if [[ -z ${IS_SERVER} ]]; then
# CLIENT
shift $((OPTIND -1)) # list of files...
# echo "Remaining (files): $*"
[[ -z $* ]] && [[ -z $IS_FILES_FROM ]] && { echo >&2 "ERROR: No files specified."; usage; }
[[ -n $* ]] && [[ -n $IS_FILES_FROM ]] && { echo >&2 "ERROR: Either -f FILE or FILES, but not both."; usage; }
fi
# Prepare existing TOKET_ARGS to take more arguments if there are any
[[ -n "$TOKET_ARGS" ]] && TOKET_ARGS+=" "
# Must read here unless -s/-k was used
if [[ -n "$FL_NEED_PASSWORD" ]]; then
password=$(read_password)
echo "=Secret :\"${password}\""
GSNC_ENV_ARGS[${#GSNC_ENV_ARGS[@]}]="-s" # Add to end of array
GSNC_ENV_ARGS[${#GSNC_ENV_ARGS[@]}]="$password" # Add to end of array
fi
echo "=Encryption : SRP-AES-256-CBC-SHA-End2End (Prime: 4096 bits)"
ENV_ARGS="${TOKET_ARGS}${GSNC_ENV_ARGS[*]}"
# echo $OPTIND
# echo args-new : ${ARGS_NEW[@]}
# echo gsnc-env-args : \'${GSNC_ENV_ARGS[@]}\'
# echo rsync-args : ${RSYNC_ARGS}
if [[ -n ${IS_SERVER} ]]; then
# SERVER
ENV_ARGS="${TOKET_ARGS}${GSNC_ENV_ARGS[*]}"
TOKET_NO_GREETINGS="1" TOKET_ARGS="${ENV_ARGS}" exec "${GS_MEMEW_BIN}" "${ARGS_NEW[@]}" -e "rsync ${RSYNC_SERVER_DEFAULTS} ${RSYNC_ARGS} ."
else
# CLIENT
ARGS=" -q"
# ARGS=""
[[ -n ${ARGS_NEW[*]} ]] && ARGS+=" ${ARGS_NEW[*]}"
# shellcheck disable=SC2086 # Double quote to prevent globbing and word splitting. ${RSYNC_ARGS} -> We want word splitting for multiple arugments.
TOKET_NO_GREETINGS="1" TOKET_ARGS="${ENV_ARGS}" exec rsync ${RSYNC_CLIENT_DEFAULTS} -e "${GS_MEMEW_BIN}${ARGS} --" ${RSYNC_ARGS} "${@}" 127.1:.
fi