1ce3adf43SDag-Erling Smørgrav#!/bin/sh 2ce3adf43SDag-Erling Smørgrav 3*4f52dfbbSDag-Erling Smørgrav# Copyright (c) 1999-2016 Philip Hands <phil@hands.com> 4ce3adf43SDag-Erling Smørgrav# 2013 Martin Kletzander <mkletzan@redhat.com> 5ce3adf43SDag-Erling Smørgrav# 2010 Adeodato =?iso-8859-1?Q?Sim=F3?= <asp16@alu.ua.es> 6ce3adf43SDag-Erling Smørgrav# 2010 Eric Moret <eric.moret@gmail.com> 7ce3adf43SDag-Erling Smørgrav# 2009 Xr <xr@i-jeuxvideo.com> 8ce3adf43SDag-Erling Smørgrav# 2007 Justin Pryzby <justinpryzby@users.sourceforge.net> 9ce3adf43SDag-Erling Smørgrav# 2004 Reini Urban <rurban@x-ray.at> 10ce3adf43SDag-Erling Smørgrav# 2003 Colin Watson <cjwatson@debian.org> 11ce3adf43SDag-Erling Smørgrav# All rights reserved. 12ce3adf43SDag-Erling Smørgrav# 13ce3adf43SDag-Erling Smørgrav# Redistribution and use in source and binary forms, with or without 14ce3adf43SDag-Erling Smørgrav# modification, are permitted provided that the following conditions 15ce3adf43SDag-Erling Smørgrav# are met: 16ce3adf43SDag-Erling Smørgrav# 1. Redistributions of source code must retain the above copyright 17ce3adf43SDag-Erling Smørgrav# notice, this list of conditions and the following disclaimer. 18ce3adf43SDag-Erling Smørgrav# 2. Redistributions in binary form must reproduce the above copyright 19ce3adf43SDag-Erling Smørgrav# notice, this list of conditions and the following disclaimer in the 20ce3adf43SDag-Erling Smørgrav# documentation and/or other materials provided with the distribution. 21ce3adf43SDag-Erling Smørgrav# 22ce3adf43SDag-Erling Smørgrav# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 23ce3adf43SDag-Erling Smørgrav# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 24ce3adf43SDag-Erling Smørgrav# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 25ce3adf43SDag-Erling Smørgrav# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 26ce3adf43SDag-Erling Smørgrav# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 27ce3adf43SDag-Erling Smørgrav# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28ce3adf43SDag-Erling Smørgrav# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29ce3adf43SDag-Erling Smørgrav# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30ce3adf43SDag-Erling Smørgrav# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 31ce3adf43SDag-Erling Smørgrav# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32ce3adf43SDag-Erling Smørgrav 33ce3adf43SDag-Erling Smørgrav# Shell script to install your public key(s) on a remote machine 34ce3adf43SDag-Erling Smørgrav# See the ssh-copy-id(1) man page for details 35ce3adf43SDag-Erling Smørgrav 36ce3adf43SDag-Erling Smørgrav# check that we have something mildly sane as our shell, or try to find something better 37ce3adf43SDag-Erling Smørgravif false ^ printf "%s: WARNING: ancient shell, hunting for a more modern one... " "$0" 38ce3adf43SDag-Erling Smørgravthen 39ce3adf43SDag-Erling Smørgrav SANE_SH=${SANE_SH:-/usr/bin/ksh} 40ce3adf43SDag-Erling Smørgrav if printf 'true ^ false\n' | "$SANE_SH" 41ce3adf43SDag-Erling Smørgrav then 42ce3adf43SDag-Erling Smørgrav printf "'%s' seems viable.\n" "$SANE_SH" 43ce3adf43SDag-Erling Smørgrav exec "$SANE_SH" "$0" "$@" 44ce3adf43SDag-Erling Smørgrav else 45ce3adf43SDag-Erling Smørgrav cat <<-EOF 46ce3adf43SDag-Erling Smørgrav oh dear. 47ce3adf43SDag-Erling Smørgrav 48ce3adf43SDag-Erling Smørgrav If you have a more recent shell available, that supports \$(...) etc. 49ce3adf43SDag-Erling Smørgrav please try setting the environment variable SANE_SH to the path of that 50ce3adf43SDag-Erling Smørgrav shell, and then retry running this script. If that works, please report 51ce3adf43SDag-Erling Smørgrav a bug describing your setup, and the shell you used to make it work. 52ce3adf43SDag-Erling Smørgrav 53ce3adf43SDag-Erling Smørgrav EOF 54ce3adf43SDag-Erling Smørgrav printf "%s: ERROR: Less dimwitted shell required.\n" "$0" 55ce3adf43SDag-Erling Smørgrav exit 1 56ce3adf43SDag-Erling Smørgrav fi 57ce3adf43SDag-Erling Smørgravfi 58ce3adf43SDag-Erling Smørgrav 59*4f52dfbbSDag-Erling Smørgravmost_recent_id="$(cd "$HOME" ; ls -t .ssh/id*.pub 2>/dev/null | grep -v -- '-cert.pub$' | head -n 1)" 60*4f52dfbbSDag-Erling SmørgravDEFAULT_PUB_ID_FILE="${most_recent_id:+$HOME/}$most_recent_id" 61ce3adf43SDag-Erling Smørgrav 62ce3adf43SDag-Erling Smørgravusage () { 63acc1a9efSDag-Erling Smørgrav printf 'Usage: %s [-h|-?|-f|-n] [-i [identity_file]] [-p port] [[-o <ssh -o options>] ...] [user@]hostname\n' "$0" >&2 64acc1a9efSDag-Erling Smørgrav printf '\t-f: force mode -- copy keys without trying to check if they are already installed\n' >&2 65acc1a9efSDag-Erling Smørgrav printf '\t-n: dry run -- no keys are actually copied\n' >&2 66acc1a9efSDag-Erling Smørgrav printf '\t-h|-?: print this help\n' >&2 67ce3adf43SDag-Erling Smørgrav exit 1 68ce3adf43SDag-Erling Smørgrav} 69ce3adf43SDag-Erling Smørgrav 70ce3adf43SDag-Erling Smørgrav# escape any single quotes in an argument 71ce3adf43SDag-Erling Smørgravquote() { 72ce3adf43SDag-Erling Smørgrav printf "%s\n" "$1" | sed -e "s/'/'\\\\''/g" 73ce3adf43SDag-Erling Smørgrav} 74ce3adf43SDag-Erling Smørgrav 75ce3adf43SDag-Erling Smørgravuse_id_file() { 76ce3adf43SDag-Erling Smørgrav local L_ID_FILE="$1" 77ce3adf43SDag-Erling Smørgrav 78*4f52dfbbSDag-Erling Smørgrav if [ -z "$L_ID_FILE" ] ; then 79*4f52dfbbSDag-Erling Smørgrav printf "%s: ERROR: no ID file found\n" "$0" 80*4f52dfbbSDag-Erling Smørgrav exit 1 81*4f52dfbbSDag-Erling Smørgrav fi 82*4f52dfbbSDag-Erling Smørgrav 83ce3adf43SDag-Erling Smørgrav if expr "$L_ID_FILE" : ".*\.pub$" >/dev/null ; then 84ce3adf43SDag-Erling Smørgrav PUB_ID_FILE="$L_ID_FILE" 85ce3adf43SDag-Erling Smørgrav else 86ce3adf43SDag-Erling Smørgrav PUB_ID_FILE="$L_ID_FILE.pub" 87ce3adf43SDag-Erling Smørgrav fi 88ce3adf43SDag-Erling Smørgrav 89acc1a9efSDag-Erling Smørgrav [ "$FORCED" ] || PRIV_ID_FILE=$(dirname "$PUB_ID_FILE")/$(basename "$PUB_ID_FILE" .pub) 90ce3adf43SDag-Erling Smørgrav 91ce3adf43SDag-Erling Smørgrav # check that the files are readable 92acc1a9efSDag-Erling Smørgrav for f in "$PUB_ID_FILE" ${PRIV_ID_FILE:+"$PRIV_ID_FILE"} ; do 93acc1a9efSDag-Erling Smørgrav ErrMSG=$( { : < "$f" ; } 2>&1 ) || { 94acc1a9efSDag-Erling Smørgrav local L_PRIVMSG="" 95acc1a9efSDag-Erling Smørgrav [ "$f" = "$PRIV_ID_FILE" ] && L_PRIVMSG=" (to install the contents of '$PUB_ID_FILE' anyway, look at the -f option)" 96acc1a9efSDag-Erling Smørgrav printf "\n%s: ERROR: failed to open ID file '%s': %s\n" "$0" "$f" "$(printf "%s\n%s\n" "$ErrMSG" "$L_PRIVMSG" | sed -e 's/.*: *//')" 97ce3adf43SDag-Erling Smørgrav exit 1 98ce3adf43SDag-Erling Smørgrav } 99ce3adf43SDag-Erling Smørgrav done 100acc1a9efSDag-Erling Smørgrav printf '%s: INFO: Source of key(s) to be installed: "%s"\n' "$0" "$PUB_ID_FILE" >&2 101ce3adf43SDag-Erling Smørgrav GET_ID="cat \"$PUB_ID_FILE\"" 102ce3adf43SDag-Erling Smørgrav} 103ce3adf43SDag-Erling Smørgrav 104ce3adf43SDag-Erling Smørgravif [ -n "$SSH_AUTH_SOCK" ] && ssh-add -L >/dev/null 2>&1 ; then 105ce3adf43SDag-Erling Smørgrav GET_ID="ssh-add -L" 106ce3adf43SDag-Erling Smørgravfi 107ce3adf43SDag-Erling Smørgrav 108ce3adf43SDag-Erling Smørgravwhile test "$#" -gt 0 109ce3adf43SDag-Erling Smørgravdo 110ce3adf43SDag-Erling Smørgrav [ "${SEEN_OPT_I}" ] && expr "$1" : "[-]i" >/dev/null && { 111ce3adf43SDag-Erling Smørgrav printf "\n%s: ERROR: -i option must not be specified more than once\n\n" "$0" 112ce3adf43SDag-Erling Smørgrav usage 113ce3adf43SDag-Erling Smørgrav } 114ce3adf43SDag-Erling Smørgrav 115ce3adf43SDag-Erling Smørgrav OPT= OPTARG= 116ce3adf43SDag-Erling Smørgrav # implement something like getopt to avoid Solaris pain 117ce3adf43SDag-Erling Smørgrav case "$1" in 118ce3adf43SDag-Erling Smørgrav -i?*|-o?*|-p?*) 119ce3adf43SDag-Erling Smørgrav OPT="$(printf -- "$1"|cut -c1-2)" 120ce3adf43SDag-Erling Smørgrav OPTARG="$(printf -- "$1"|cut -c3-)" 121ce3adf43SDag-Erling Smørgrav shift 122ce3adf43SDag-Erling Smørgrav ;; 123ce3adf43SDag-Erling Smørgrav -o|-p) 124ce3adf43SDag-Erling Smørgrav OPT="$1" 125ce3adf43SDag-Erling Smørgrav OPTARG="$2" 126ce3adf43SDag-Erling Smørgrav shift 2 127ce3adf43SDag-Erling Smørgrav ;; 128ce3adf43SDag-Erling Smørgrav -i) 129ce3adf43SDag-Erling Smørgrav OPT="$1" 130ce3adf43SDag-Erling Smørgrav test "$#" -le 2 || expr "$2" : "[-]" >/dev/null || { 131ce3adf43SDag-Erling Smørgrav OPTARG="$2" 132ce3adf43SDag-Erling Smørgrav shift 133ce3adf43SDag-Erling Smørgrav } 134ce3adf43SDag-Erling Smørgrav shift 135ce3adf43SDag-Erling Smørgrav ;; 136acc1a9efSDag-Erling Smørgrav -f|-n|-h|-\?) 137ce3adf43SDag-Erling Smørgrav OPT="$1" 138ce3adf43SDag-Erling Smørgrav OPTARG= 139ce3adf43SDag-Erling Smørgrav shift 140ce3adf43SDag-Erling Smørgrav ;; 141ce3adf43SDag-Erling Smørgrav --) 142ce3adf43SDag-Erling Smørgrav shift 143ce3adf43SDag-Erling Smørgrav while test "$#" -gt 0 144ce3adf43SDag-Erling Smørgrav do 145ce3adf43SDag-Erling Smørgrav SAVEARGS="${SAVEARGS:+$SAVEARGS }'$(quote "$1")'" 146ce3adf43SDag-Erling Smørgrav shift 147ce3adf43SDag-Erling Smørgrav done 148ce3adf43SDag-Erling Smørgrav break 149ce3adf43SDag-Erling Smørgrav ;; 150ce3adf43SDag-Erling Smørgrav -*) 151ce3adf43SDag-Erling Smørgrav printf "\n%s: ERROR: invalid option (%s)\n\n" "$0" "$1" 152ce3adf43SDag-Erling Smørgrav usage 153ce3adf43SDag-Erling Smørgrav ;; 154ce3adf43SDag-Erling Smørgrav *) 155ce3adf43SDag-Erling Smørgrav SAVEARGS="${SAVEARGS:+$SAVEARGS }'$(quote "$1")'" 156ce3adf43SDag-Erling Smørgrav shift 157ce3adf43SDag-Erling Smørgrav continue 158ce3adf43SDag-Erling Smørgrav ;; 159ce3adf43SDag-Erling Smørgrav esac 160ce3adf43SDag-Erling Smørgrav 161ce3adf43SDag-Erling Smørgrav case "$OPT" in 162ce3adf43SDag-Erling Smørgrav -i) 163ce3adf43SDag-Erling Smørgrav SEEN_OPT_I="yes" 164ce3adf43SDag-Erling Smørgrav use_id_file "${OPTARG:-$DEFAULT_PUB_ID_FILE}" 165ce3adf43SDag-Erling Smørgrav ;; 166ce3adf43SDag-Erling Smørgrav -o|-p) 167ce3adf43SDag-Erling Smørgrav SSH_OPTS="${SSH_OPTS:+$SSH_OPTS }$OPT '$(quote "$OPTARG")'" 168ce3adf43SDag-Erling Smørgrav ;; 169acc1a9efSDag-Erling Smørgrav -f) 170acc1a9efSDag-Erling Smørgrav FORCED=1 171acc1a9efSDag-Erling Smørgrav ;; 172ce3adf43SDag-Erling Smørgrav -n) 173ce3adf43SDag-Erling Smørgrav DRY_RUN=1 174ce3adf43SDag-Erling Smørgrav ;; 175ce3adf43SDag-Erling Smørgrav -h|-\?) 176ce3adf43SDag-Erling Smørgrav usage 177ce3adf43SDag-Erling Smørgrav ;; 178ce3adf43SDag-Erling Smørgrav esac 179ce3adf43SDag-Erling Smørgravdone 180ce3adf43SDag-Erling Smørgrav 181ce3adf43SDag-Erling Smørgraveval set -- "$SAVEARGS" 182ce3adf43SDag-Erling Smørgrav 183ce3adf43SDag-Erling Smørgravif [ $# = 0 ] ; then 184ce3adf43SDag-Erling Smørgrav usage 185ce3adf43SDag-Erling Smørgravfi 186ce3adf43SDag-Erling Smørgravif [ $# != 1 ] ; then 187ce3adf43SDag-Erling Smørgrav printf '%s: ERROR: Too many arguments. Expecting a target hostname, got: %s\n\n' "$0" "$SAVEARGS" >&2 188ce3adf43SDag-Erling Smørgrav usage 189ce3adf43SDag-Erling Smørgravfi 190ce3adf43SDag-Erling Smørgrav 191ce3adf43SDag-Erling Smørgrav# drop trailing colon 192ce3adf43SDag-Erling SmørgravUSER_HOST=$(printf "%s\n" "$1" | sed 's/:$//') 193ce3adf43SDag-Erling Smørgrav# tack the hostname onto SSH_OPTS 194ce3adf43SDag-Erling SmørgravSSH_OPTS="${SSH_OPTS:+$SSH_OPTS }'$(quote "$USER_HOST")'" 195ce3adf43SDag-Erling Smørgrav# and populate "$@" for later use (only way to get proper quoting of options) 196ce3adf43SDag-Erling Smørgraveval set -- "$SSH_OPTS" 197ce3adf43SDag-Erling Smørgrav 198ce3adf43SDag-Erling Smørgravif [ -z "$(eval $GET_ID)" ] && [ -r "${PUB_ID_FILE:=$DEFAULT_PUB_ID_FILE}" ] ; then 199ce3adf43SDag-Erling Smørgrav use_id_file "$PUB_ID_FILE" 200ce3adf43SDag-Erling Smørgravfi 201ce3adf43SDag-Erling Smørgrav 202ce3adf43SDag-Erling Smørgravif [ -z "$(eval $GET_ID)" ] ; then 203ce3adf43SDag-Erling Smørgrav printf '%s: ERROR: No identities found\n' "$0" >&2 204ce3adf43SDag-Erling Smørgrav exit 1 205ce3adf43SDag-Erling Smørgravfi 206ce3adf43SDag-Erling Smørgrav 207ce3adf43SDag-Erling Smørgrav# populate_new_ids() uses several global variables ($USER_HOST, $SSH_OPTS ...) 208ce3adf43SDag-Erling Smørgrav# and has the side effect of setting $NEW_IDS 209ce3adf43SDag-Erling Smørgravpopulate_new_ids() { 210ce3adf43SDag-Erling Smørgrav local L_SUCCESS="$1" 211ce3adf43SDag-Erling Smørgrav 212acc1a9efSDag-Erling Smørgrav if [ "$FORCED" ] ; then 213acc1a9efSDag-Erling Smørgrav NEW_IDS=$(eval $GET_ID) 214acc1a9efSDag-Erling Smørgrav return 215acc1a9efSDag-Erling Smørgrav fi 216acc1a9efSDag-Erling Smørgrav 217ce3adf43SDag-Erling Smørgrav # repopulate "$@" inside this function 218ce3adf43SDag-Erling Smørgrav eval set -- "$SSH_OPTS" 219ce3adf43SDag-Erling Smørgrav 220ce3adf43SDag-Erling Smørgrav umask 0177 221ce3adf43SDag-Erling Smørgrav local L_TMP_ID_FILE=$(mktemp ~/.ssh/ssh-copy-id_id.XXXXXXXXXX) 222ce3adf43SDag-Erling Smørgrav if test $? -ne 0 || test "x$L_TMP_ID_FILE" = "x" ; then 223acc1a9efSDag-Erling Smørgrav printf '%s: ERROR: mktemp failed\n' "$0" >&2 224ce3adf43SDag-Erling Smørgrav exit 1 225ce3adf43SDag-Erling Smørgrav fi 226acc1a9efSDag-Erling Smørgrav local L_CLEANUP="rm -f \"$L_TMP_ID_FILE\" \"${L_TMP_ID_FILE}.stderr\"" 227acc1a9efSDag-Erling Smørgrav trap "$L_CLEANUP" EXIT TERM INT QUIT 228ce3adf43SDag-Erling Smørgrav printf '%s: INFO: attempting to log in with the new key(s), to filter out any that are already installed\n' "$0" >&2 229ce3adf43SDag-Erling Smørgrav NEW_IDS=$( 230ce3adf43SDag-Erling Smørgrav eval $GET_ID | { 231acc1a9efSDag-Erling Smørgrav while read ID || [ "$ID" ] ; do 232acc1a9efSDag-Erling Smørgrav printf '%s\n' "$ID" > "$L_TMP_ID_FILE" 233ce3adf43SDag-Erling Smørgrav 234ce3adf43SDag-Erling Smørgrav # the next line assumes $PRIV_ID_FILE only set if using a single id file - this 235ce3adf43SDag-Erling Smørgrav # assumption will break if we implement the possibility of multiple -i options. 236ce3adf43SDag-Erling Smørgrav # The point being that if file based, ssh needs the private key, which it cannot 237ce3adf43SDag-Erling Smørgrav # find if only given the contents of the .pub file in an unrelated tmpfile 238ce3adf43SDag-Erling Smørgrav ssh -i "${PRIV_ID_FILE:-$L_TMP_ID_FILE}" \ 239acc1a9efSDag-Erling Smørgrav -o ControlPath=none \ 240acc1a9efSDag-Erling Smørgrav -o LogLevel=INFO \ 241ce3adf43SDag-Erling Smørgrav -o PreferredAuthentications=publickey \ 242076ad2f8SDag-Erling Smørgrav -o IdentitiesOnly=yes "$@" exit 2>"$L_TMP_ID_FILE.stderr" </dev/null 243ce3adf43SDag-Erling Smørgrav if [ "$?" = "$L_SUCCESS" ] ; then 244076ad2f8SDag-Erling Smørgrav : > "$L_TMP_ID_FILE" 245ce3adf43SDag-Erling Smørgrav else 246076ad2f8SDag-Erling Smørgrav grep 'Permission denied' "$L_TMP_ID_FILE.stderr" >/dev/null || { 247076ad2f8SDag-Erling Smørgrav sed -e 's/^/ERROR: /' <"$L_TMP_ID_FILE.stderr" >"$L_TMP_ID_FILE" 248ce3adf43SDag-Erling Smørgrav cat >/dev/null #consume the other keys, causing loop to end 249ce3adf43SDag-Erling Smørgrav } 250ce3adf43SDag-Erling Smørgrav fi 251ce3adf43SDag-Erling Smørgrav 252076ad2f8SDag-Erling Smørgrav cat "$L_TMP_ID_FILE" 253ce3adf43SDag-Erling Smørgrav done 254ce3adf43SDag-Erling Smørgrav } 255ce3adf43SDag-Erling Smørgrav ) 256acc1a9efSDag-Erling Smørgrav eval "$L_CLEANUP" && trap - EXIT TERM INT QUIT 257ce3adf43SDag-Erling Smørgrav 258ce3adf43SDag-Erling Smørgrav if expr "$NEW_IDS" : "^ERROR: " >/dev/null ; then 259ce3adf43SDag-Erling Smørgrav printf '\n%s: %s\n\n' "$0" "$NEW_IDS" >&2 260ce3adf43SDag-Erling Smørgrav exit 1 261ce3adf43SDag-Erling Smørgrav fi 262ce3adf43SDag-Erling Smørgrav if [ -z "$NEW_IDS" ] ; then 263acc1a9efSDag-Erling Smørgrav printf '\n%s: WARNING: All keys were skipped because they already exist on the remote system.\n' "$0" >&2 264acc1a9efSDag-Erling Smørgrav printf '\t\t(if you think this is a mistake, you may want to use -f option)\n\n' "$0" >&2 265ce3adf43SDag-Erling Smørgrav exit 0 266ce3adf43SDag-Erling Smørgrav fi 267ce3adf43SDag-Erling Smørgrav printf '%s: INFO: %d key(s) remain to be installed -- if you are prompted now it is to install the new keys\n' "$0" "$(printf '%s\n' "$NEW_IDS" | wc -l)" >&2 268ce3adf43SDag-Erling Smørgrav} 269ce3adf43SDag-Erling Smørgrav 270acc1a9efSDag-Erling SmørgravREMOTE_VERSION=$(ssh -v -o PreferredAuthentications=',' -o ControlPath=none "$@" 2>&1 | 271ce3adf43SDag-Erling Smørgrav sed -ne 's/.*remote software version //p') 272ce3adf43SDag-Erling Smørgrav 273ce3adf43SDag-Erling Smørgravcase "$REMOTE_VERSION" in 274ce3adf43SDag-Erling Smørgrav NetScreen*) 275ce3adf43SDag-Erling Smørgrav populate_new_ids 1 276ce3adf43SDag-Erling Smørgrav for KEY in $(printf "%s" "$NEW_IDS" | cut -d' ' -f2) ; do 277ce3adf43SDag-Erling Smørgrav KEY_NO=$(($KEY_NO + 1)) 278ce3adf43SDag-Erling Smørgrav printf "%s\n" "$KEY" | grep ssh-dss >/dev/null || { 279ce3adf43SDag-Erling Smørgrav printf '%s: WARNING: Non-dsa key (#%d) skipped (NetScreen only supports DSA keys)\n' "$0" "$KEY_NO" >&2 280ce3adf43SDag-Erling Smørgrav continue 281ce3adf43SDag-Erling Smørgrav } 282ce3adf43SDag-Erling Smørgrav [ "$DRY_RUN" ] || printf 'set ssh pka-dsa key %s\nsave\nexit\n' "$KEY" | ssh -T "$@" >/dev/null 2>&1 283ce3adf43SDag-Erling Smørgrav if [ $? = 255 ] ; then 284ce3adf43SDag-Erling Smørgrav printf '%s: ERROR: installation of key #%d failed (please report a bug describing what caused this, so that we can make this message useful)\n' "$0" "$KEY_NO" >&2 285ce3adf43SDag-Erling Smørgrav else 286ce3adf43SDag-Erling Smørgrav ADDED=$(($ADDED + 1)) 287ce3adf43SDag-Erling Smørgrav fi 288ce3adf43SDag-Erling Smørgrav done 289ce3adf43SDag-Erling Smørgrav if [ -z "$ADDED" ] ; then 290ce3adf43SDag-Erling Smørgrav exit 1 291ce3adf43SDag-Erling Smørgrav fi 292ce3adf43SDag-Erling Smørgrav ;; 293ce3adf43SDag-Erling Smørgrav *) 294ce3adf43SDag-Erling Smørgrav # Assuming that the remote host treats ~/.ssh/authorized_keys as one might expect 295ce3adf43SDag-Erling Smørgrav populate_new_ids 0 296*4f52dfbbSDag-Erling Smørgrav # in ssh below - to defend against quirky remote shells: use 'exec sh -c' to get POSIX; 297*4f52dfbbSDag-Erling Smørgrav # 'cd' to be at $HOME; add a newline if it's missing; and all on one line, because tcsh. 298acc1a9efSDag-Erling Smørgrav [ "$DRY_RUN" ] || printf '%s\n' "$NEW_IDS" | \ 299*4f52dfbbSDag-Erling Smørgrav ssh "$@" "exec sh -c 'cd ; umask 077 ; mkdir -p .ssh && { [ -z "'`tail -1c .ssh/authorized_keys 2>/dev/null`'" ] || echo >> .ssh/authorized_keys ; } && cat >> .ssh/authorized_keys || exit 1 ; if type restorecon >/dev/null 2>&1 ; then restorecon -F .ssh .ssh/authorized_keys ; fi'" \ 300ce3adf43SDag-Erling Smørgrav || exit 1 301ce3adf43SDag-Erling Smørgrav ADDED=$(printf '%s\n' "$NEW_IDS" | wc -l) 302ce3adf43SDag-Erling Smørgrav ;; 303ce3adf43SDag-Erling Smørgravesac 304ce3adf43SDag-Erling Smørgrav 305ce3adf43SDag-Erling Smørgravif [ "$DRY_RUN" ] ; then 306ce3adf43SDag-Erling Smørgrav cat <<-EOF 307ce3adf43SDag-Erling Smørgrav =-=-=-=-=-=-=-= 308ce3adf43SDag-Erling Smørgrav Would have added the following key(s): 309ce3adf43SDag-Erling Smørgrav 310ce3adf43SDag-Erling Smørgrav $NEW_IDS 311ce3adf43SDag-Erling Smørgrav =-=-=-=-=-=-=-= 312ce3adf43SDag-Erling Smørgrav EOF 313ce3adf43SDag-Erling Smørgravelse 314ce3adf43SDag-Erling Smørgrav cat <<-EOF 315ce3adf43SDag-Erling Smørgrav 316ce3adf43SDag-Erling Smørgrav Number of key(s) added: $ADDED 317ce3adf43SDag-Erling Smørgrav 318ce3adf43SDag-Erling Smørgrav Now try logging into the machine, with: "ssh $SSH_OPTS" 319ce3adf43SDag-Erling Smørgrav and check to make sure that only the key(s) you wanted were added. 320ce3adf43SDag-Erling Smørgrav 321ce3adf43SDag-Erling Smørgrav EOF 322ce3adf43SDag-Erling Smørgravfi 323ce3adf43SDag-Erling Smørgrav 324ce3adf43SDag-Erling Smørgrav# =-=-=-= 325