]> git.ipfire.org Git - thirdparty/openssh-portable.git/commitdiff
add -t option to specify the target path
authorPhilip Hands <phil@hands.com>
Tue, 23 May 2023 14:46:42 +0000 (16:46 +0200)
committerDarren Tucker <dtucker@dtucker.net>
Thu, 25 May 2023 08:24:45 +0000 (18:24 +1000)
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

contrib/ssh-copy-id
contrib/ssh-copy-id.1

index 171c4e06ccab7660edafe5a0b67e1cca1b2ece0d..23965b241d4eb65c6457f8b4ff0765b82a0290b1 100644 (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" | \
index 79d976c773c8b3c369f5a784ac59d5e4b2c15427..0cb47a33341a6cde83aef05a8f165f7a9715a6d6 100644 (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