add -t option to specify the target path

Allow the default target path (.ssh/authorized_files) to be over-riden

This was inspired by this MR from Panagiotis Cheilaris <philaris@cs.ntua.gr>

 https://gitlab.com/phil_hands/ssh-copy-id/-/merge_requests/8

SSH-Copy-ID-Upstream: a942a0e076874adb6d8b2f0fb76d6c7918190fcd
This commit is contained in:
Philip Hands 2023-05-23 16:46:42 +02:00 committed by Darren Tucker
parent 914f4ad138
commit b79e7b88ed
No known key found for this signature in database
2 changed files with 26 additions and 20 deletions

View File

@ -64,10 +64,11 @@ fi
# shellcheck disable=SC2010
DEFAULT_PUB_ID_FILE=$(ls -t "${HOME}"/.ssh/id*.pub 2>/dev/null | grep -v -- '-cert.pub$' | head -n 1)
SSH="ssh -a -x"
TARGET_PATH=".ssh/authorized_keys"
umask 0177
usage () {
printf 'Usage: %s [-h|-?|-f|-n|-s|-x] [-i [identity_file]] [-p port] [-F alternative ssh_config file] [[-o <ssh -o options>] ...] [user@]hostname\n' "$0" >&2
printf 'Usage: %s [-h|-?|-f|-n|-s|-x] [-i [identity_file]] [-p port] [-F alternative ssh_config file] [-t target_path] [[-o <ssh -o options>] ...] [user@]hostname\n' "$0" >&2
printf '\t-f: force mode -- copy keys without trying to check if they are already installed\n' >&2
printf '\t-n: dry run -- no keys are actually copied\n' >&2
printf '\t-s: use sftp -- use sftp instead of executing remote-commands. Can be useful if the remote only allows sftp\n' >&2
@ -114,7 +115,7 @@ if [ -n "$SSH_AUTH_SOCK" ] && ssh-add -L >/dev/null 2>&1 ; then
GET_ID="ssh-add -L"
fi
while getopts "i:o:p:F:fnsxh?" OPT
while getopts "i:o:p:F:t:fnsxh?" OPT
do
case "$OPT" in
i)
@ -137,6 +138,9 @@ do
s)
SFTP=sftp
;;
t)
TARGET_PATH="${OPTARG}"
;;
x)
set -x
;;
@ -238,11 +242,8 @@ populate_new_ids() {
}
# installkey_sh [target_path]
# produce a one-liner to add the keys to remote authorized_keys file
# optionally takes an alternative path for authorized_keys
# produce a one-liner to add the keys to remote $TARGET_PATH
installkeys_sh() {
AUTH_KEY_FILE=${1:-.ssh/authorized_keys}
# In setting INSTALLKEYS_SH:
# the tr puts it all on one line (to placate tcsh)
# (hence the excessive use of semi-colons (;) )
@ -255,7 +256,7 @@ installkeys_sh() {
INSTALLKEYS_SH=$(tr '\t\n' ' ' <<-EOF
cd;
umask 077;
AUTH_KEY_FILE="${AUTH_KEY_FILE}";
AUTH_KEY_FILE="${TARGET_PATH}";
[ -f /etc/openwrt_release ] && [ "\$LOGNAME" = "root" ] &&
AUTH_KEY_FILE=/etc/dropbear/authorized_keys;
AUTH_KEY_DIR=\`dirname "\${AUTH_KEY_FILE}"\`;
@ -275,6 +276,8 @@ installkeys_sh() {
#shellcheck disable=SC2120 # the 'eval set' confuses this
installkeys_via_sftp() {
AUTH_KEY_FILE=${TARGET_PATH}
AUTH_KEY_DIR=$(dirname "${AUTH_KEY_FILE}")
# repopulate "$@" inside this function
eval set -- "$SSH_OPTS"
@ -286,17 +289,17 @@ installkeys_via_sftp() {
#shellcheck disable=SC2064
trap "$L_CLEANUP" EXIT TERM INT QUIT
sftp -b - -o "ControlPath=$L_SHARED_CON" "ignored" <<-EOF || return 1
-get .ssh/authorized_keys $L_KEYS
-get "$AUTH_KEY_FILE" "$L_KEYS"
EOF
# add a newline or create file if it's missing, same like above
[ -z "$(tail -1c "$L_KEYS" 2>/dev/null)" ] || echo >> "$L_KEYS"
# append the keys being piped in here
cat >> "$L_KEYS"
sftp -b - -o "ControlPath=$L_SHARED_CON" "ignored" <<-EOF || return 1
-mkdir .ssh
chmod 700 .ssh
put $L_KEYS .ssh/authorized_keys
chmod 600 .ssh/authorized_keys
-mkdir "$AUTH_KEY_DIR"
chmod 700 "$AUTH_KEY_DIR"
put $L_KEYS "$AUTH_KEY_FILE"
chmod 600 "$AUTH_KEY_FILE"
EOF
#shellcheck disable=SC2064
eval "$L_CLEANUP" && trap "$SCRATCH_CLEANUP" EXIT TERM INT QUIT
@ -341,7 +344,7 @@ case "$REMOTE_VERSION" in
fi
;;
*)
# Assuming that the remote host treats ~/.ssh/authorized_keys as one might expect
# Assuming that the remote host treats $TARGET_PATH as one might expect
populate_new_ids 0
if ! [ "$DRY_RUN" ] ; then
printf '%s\n' "$NEW_IDS" | \

View File

@ -36,6 +36,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.Op Fl i Op Ar identity_file
.Op Fl p Ar port
.Op Fl o Ar ssh_option
.Op Fl t Ar target_path
.Op Ar user Ns @ Ns
.Ar hostname
.Nm
@ -92,13 +93,8 @@ With this option the user's
.Pa ~/.ssh/authorized_keys
file will be downloaded, modified locally and uploaded with sftp.
This option is useful if the server has restrictions on commands which can be used on the remote side.
.It Fl x
This option is for debugging the
.Nm
script itself.
It sets the shell's -x flag, so that you can see the commands being run.
.It Fl h , Fl ?
Print Usage summary
.It Fl t Ar target_path
the path on the target system where the keys should be added (defaults to ".ssh/authorized_keys")
.It Fl p Ar port , Fl o Ar ssh_option
These two options are simply passed through untouched, along with their
argument, to allow one to set the port or other
@ -109,6 +105,13 @@ Rather than specifying these as command line options, it is often better to use
.Xr ssh 1 Ns 's
configuration file:
.Xr ssh_config 5 .
.It Fl x
This option is for debugging the
.Nm
script itself.
It sets the shell's -x flag, so that you can see the commands being run.
.It Fl h , Fl ?
Print Usage summary
.El
.Pp
Default behaviour without