#!/bin/sh - # # Copyright (c) 1998-2002 Daniel J. Gregor, Jr., All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # 1. Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # 2. Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # 3. All advertising materials mentioning features or use of this software # must display the following acknowledgement: # This product includes software developed by Daniel J. Gregor, Jr. # 4. The name of Daniel J. Gregor, Jr. may not be used to endorse or promote # products derived from this software without specific prior written # permission. # # THIS SOFTWARE IS PROVIDED BY DANIEL J. GREGOR, JR. ``AS IS'' AND # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL DANIEL J. GREGOR, JR. BE LIABLE # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF # SUCH DAMAGE. # usage="usage: `basename $0` [-h] [-v] [-l ] [-i ] [-I ] [-k ] [-o] [-1] [-2] " overwrite="" inst_identity="" auth_keys="" versions="" basename="`basename $0`" die() { echo "${basename}: $*" >&2 exit 1 } while getopts hvl:i:I:k:o12 c do case $c in h) cat << EOF $usage This script is used for installing SSH public keys onto remote servers. Options: -v Verbose. -h Show this help information. -l Login to remote server as and install SSH key for -o Replace the entirety of the remote authorized keys file with this key, instead of appending the key (default). -i Identity file to pass to SSH for authenticating to the remote server. -I Identity file to copy to remote server (the default is $HOME/.ssh/identity.pub for version 1 keys, and $HOME/.ssh/id_[rd]sa.pub for version 2 keys). -k Location of the remote authorized keys file (the default is $HOME/.ssh/authorized_key for version 1 keys, or $HOME/.ssh/authorized_keys2 for version 2 keys). -1 Use version 1 default file locations (identity.pub, authorized_keys). Default is both 1 and 2, if they exist. -2 Use version 2 default file locations (id_[rd]sa.pub, authorized_keys2). Default is both 1 and 2, if they exist. EOF exit 0 ;; v) verbose="-v" ;; l) remote_user="-l $OPTARG" ;; i) identity="-i $OPTARG" ;; I) inst_identity="$OPTARG" ;; k) auth_keys="$OPTARG" ;; o) overwrite="yes" ;; 1|2) versions="$versions $c" ;; \?) echo "$usage" >&2 exit 1 ;; esac done shift `expr $OPTIND - 1` if [ $# -ne 1 ] then echo "$usage" >&2 exit 2 fi host="$1"; shift # Check these problem cases: # - inst_identity or auth_keys are set and multiple versions are specified # - inst_identity and not auth_keys are set and not a single version # - not inst_identity and auth_keys are set and not a single version if [ \( X"$inst_identity" != X"" -o X"$auth_keys" != X"" \) -a \ `echo "$versions" | wc -w` -ne 1 ]; then die "-I or -k options require a single version to be specified (-1, -2)" fi if [ X"$versions" = X"" ]; then if [ -r $HOME/.ssh/identity.pub ]; then versions="$versions 1" fi if [ -r $HOME/.ssh/id_dsa.pub -o -r $HOME/.ssh/id_rsa.pub ]; then versions="$versions 2 2-in-1" fi fi for version in $versions do if [ X"$inst_identity" = X"" ]; then if [ X"$version" = X"1" ]; then inst_identities=$HOME/.ssh/identity.pub else inst_identities="$HOME/.ssh/id_dsa.pub $HOME/.ssh/id_rsa.pub" fi else inst_identities="$inst_identity" fi found_one="" for this_identity in $inst_identities do test -r $this_identity || continue if [ X"$auth_keys" = X"" ]; then if [ X"$version" = X"1" -o X"$version" = X"2-in-1" ] then auth_keys=\$HOME/.ssh/authorized_keys else auth_keys=\$HOME/.ssh/authorized_keys2 fi fi if [ X"$version" = X"1" ]; then identity_comment="`cat $this_identity | \ awk '{ print $4 }'`" else identity_comment="`cat $this_identity | \ awk '{ print $3 }'`" fi if [ X"$overwrite" != X"" ]; then ssh $verbose $remote_user $identity "$host" '\ test -d $HOME/.ssh || \ mkdir -m 755 $HOME/.ssh ; \ chmod go-w $HOME/.ssh ; \ touch '"$auth_keys"' ; \ chmod 600 '"$auth_keys"' ; \ cat > '"$auth_keys" < $this_identity else ssh $verbose $remote_user $identity "$host" '\ test -d $HOME/.ssh || \ mkdir -m 755 $HOME/.ssh ; \ chmod go-w $HOME/.ssh ; \ touch '"$auth_keys"' ; \ chmod 600 '"$auth_keys"' ; \ grep '"\"$identity_comment\"" "$auth_keys"' \ > /dev/null || \ cat >> '"$auth_keys" < $this_identity fi done if [ x"$found_one" != x"" ] then die "Cannot read any identity files" fi inst_identity="" auth_keys="" done