1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164
|
#!/usr/bin/env bash
# A wrapper script to do this (esentially):
# Server:
# $ gs-netcat -s MySecret -l -e "/usr/bin/rsync --server -vlogDtpr --partial ."
# Client:
# $ rsync -aP -e "gs-netcat -s MySecret --" test4k.dat 127.1:.
GS_NETCAT_BIN="gs-netcat"
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-netcat that's in the same path as this binary first.
BIN="$(cd "$(dirname "${0}")" || exit; pwd)/${GS_NETCAT_BIN}"
[[ -f "${BIN}" ]] && GS_NETCAT_BIN="${BIN}"
command -v "${GS_NETCAT_BIN}" >/dev/null 2>&1 || { echo >&2 "${GS_NETCAT_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-netcat' 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_NETCAT_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.
[[ "$GSOCKET_ARGS" =~ ^'-s' ]] && unset FL_NEED_PASSWORD
[[ "$GSOCKET_ARGS" =~ ' -s' ]] && unset FL_NEED_PASSWORD
[[ "$GSOCKET_ARGS" =~ ^'-k' ]] && unset FL_NEED_PASSWORD
[[ "$GSOCKET_ARGS" =~ ' -k' ]] && unset FL_NEED_PASSWORD
# Current options are options for gs-netcat followed by a list of files. We
# need to split off the gs-netcat options (all but -o/-s/-k) without the
# files. To do so we need to know which gs-netcat 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_NETCAT_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 GSOCKET_ARGS to take more arguments if there are any
[[ -n "$GSOCKET_ARGS" ]] && GSOCKET_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="${GSOCKET_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="${GSOCKET_ARGS}${GSNC_ENV_ARGS[*]}"
GSOCKET_NO_GREETINGS="1" GSOCKET_ARGS="${ENV_ARGS}" exec "${GS_NETCAT_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.
GSOCKET_NO_GREETINGS="1" GSOCKET_ARGS="${ENV_ARGS}" exec rsync ${RSYNC_CLIENT_DEFAULTS} -e "${GS_NETCAT_BIN}${ARGS} --" ${RSYNC_ARGS} "${@}" 127.1:.
fi
|