#!/bin/bash #Copyright 2001, William Stearns #Copyleft: # ssh-keyinstall helps an ssh user set up the keys at both ends of an ssh connection. # Copyright (C) 2001 William Stearns # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. # # The author can also be reached at: # William Stearns #email: wstearns@pobox.com (preferred) #web: http://www.pobox.com/~wstearns #snail: 544 Winchester Place # Colchester VT, 05446, USA #FIXME Reinstate the following and remove the static require-util and wrap #functions once sam is released. #if [ -f /usr/lib/sam/samlib ]; then # . /usr/lib/sam/samlib #else # echo "/usr/lib/sam/samlib is missing - please get it from" >&2 # echo "http://www.pobox.com/~wstearns/" >&2 # echo "Exiting." >&2 # exit 1 #fi #FIXME Static versions require-util () { while [ -n "$1" ]; do if ! type -path "$1" >/dev/null 2>/dev/null ; then echo Missing utility "$1". Please install it. >&2 return 1 #False, app is not available. fi shift done return 0 #True, app is there. } #End of require-util if type -path sed >/dev/null 2>/dev/null && type -path wc >/dev/null 2>/dev/null ; then wrap () { if [ -n "$LINELENGTH" ]; then LINELENGTH_INT=$[ $LINELENGTH - `echo -n "$WRAPHEADER" | wc -c` ] else LINELENGTH_INT=$[ 72 - `echo -n "$WRAPHEADER" | wc -c` ] fi if [ $[ $LINELENGTH_INT ] -lt 20 ]; then LINELENGTH_INT=20 fi if [ $# -eq 0 ]; then #Double sed is required as the first sed only thinks there's one ^, even after we've stuck in newlines. sed -e "s/\(.\{1,$LINELENGTH_INT\}\)[[:space:]]\+/\1!!LINEFEED!!/g" -e 's/!!LINEFEED!!/\ /g' | sed -e "s/^/$WRAPHEADER/" else echo $ENH -n "$* " | sed -e "s/\(.\{1,$LINELENGTH_INT\}\)[[:space:]]\+/\1!!LINEFEED!!/g" -e 's/!!LINEFEED!!/\ /g' | sed -e "s/^/$WRAPHEADER/" fi } #End of wrap else #Fall back on alternate form of the function that doesnt need sed or wc. wrap () { if [ $# -eq 0 ]; then while read LINE ; do echo $LINE ; done else echo $ENH $* fi } #End of wrap fi if type -path basename >/dev/null 2>/dev/null ; then SCRIPTNAME=`basename $0` else SCRIPTNAME=$0 fi wrap $SCRIPTNAME, version 1.0.0 wrap ' ' wrap Please report any successes or failures to wstearns@pobox.com . \ Please note the client and server ssh versions, type of key used \ \(rsa=ssh protocol 1 or dsa=ssh protocol 2\), whether you created a \ new key or used an existing key, and whether you forced a particular \ remote command and send that information to William at the above \ address as he is hoping to test every combination. #Client-Server (O=openssh, 1=ssh1/datafellows 1, 2=ssh2/datafellows 2) #1=rsa/2=dsa keys #e=existing key used/n=new key created. c=tested with forced remote command. #Initials show who verified that it works, version reported working. #non-listed combinations are invalid. #WLS=William Stearns #O-O, 1, e WLS, 0.0.1 #O-O, 1, e, c WLS, 0.0.5 #O-O, 2, e WLS, 0.0.1 #O-O, 2, e, c WLS, 0.0.5 #O-O, 1, n #O-O, 1, n, c #O-O, 2, n Jason Piterak, 0.1.3/0.1.4 #O-O, 2, n, c #O-1, 1, e #O-1, 1, e, c #O-1, 1, n #O-1, 1, n, c #O-2, 2, e WLS, 0.1.1 #O-2, 2, e, c WLS, 0.1.2-test: (in 0.1.1, 2.0.13 server didn't force command with an "=") #O-2, 2, n #O-2, 2, n, c #1-O, 1, e #1-O, 1, e, c #1-O, 1, n #1-O, 1, n, c #1-1, 1, e #1-1, 1, e, c #1-1, 1, n #1-1, 1, n, c #2-O, 2, e WLS: 0.1.2-test #2-O, 2, e, c WLS: 0.1.2-test #2-O, 2, n WLS: 0.1.2-test #2-O, 2, n, c WLS: 0.1.2-test #2-2, 2, e WLS: 0.1.2-test #2-2, 2, e, c WLS: 0.1.2-test #2-2, 2, n #2-2, 2, n, c WLS: 0.1.2-test #TODO #askfirst/log to shell script. #Carry over nice comments in ssh-keygen conversions (2->O leaves null comment) debug () { if [ "$VERBOSE" = "YES" ]; then wrap $* fi } showhelp () { wrap ' ' >&2 wrap Usage: >&2 WRAPHEADER=' ' wrap $SCRIPTNAME '-s RemoteServerName [-u UserNameOnTheRemoteServer] [-p RemoteServerPort] [-c RemoteCommand] [-t OPENSSH|COMSSH2|COMSSH1] [-h]' >&2 wrap For example, if I want to ssh to megabox.mydomain.com where I have user account gparker and the server runs on port 2222, I\'d type: >&2 wrap $SCRIPTNAME -s megabox.mydomain.com -u gparker -p 2222 >&2 wrap This will set up the necessary keys to connect from this machine to the given ssh server and account. >&2 wrap The RemoteUserName and port number are optional - if omitted, the value of \$USER and 22/tcp are used, respectively. >&2 wrap The RemoteCommand option allows you to specify a single command which is the only command that can be run when this key is used to authenticate. For example, if gparker was only allowed to run /usr/sbin/rsync-backup-server: >&2 wrap $SCRIPTNAME -s megabox.mydomain.com -u gparker -p 2222 -c /usr/sbin/rsync-backup-server >&2 wrap '-h shows this help.' >&2 wrap '-v runs verbosely.' >&2 wrap '-t forces the remote server type to OPENSSH, COMSSH1 (commercial ssh 1), or COMSSH2. Use this if the autodetect fails.' >&2 exit 1 } require-util require-util wrap nc head ssh scp debug showhelp mkdir chmod cat grep || exit 1 #We do ssh-keygen on a case-by-case basis if needed. if [ $# -eq 0 ]; then showhelp fi unset REMOTECOMMAND REMPORT SERVERNAME REMUSERNAME VERBOSE while [ -n "$1" ]; do case $1 in -c|--remote-command) if [ -n "$2" ]; then REMOTECOMMAND="$2" shift 2 else wrap Remote command option requested, but no remote command specified. Exiting. >&2 exit 1 fi ;; -p|--remote-port) if [ -n "$2" ]; then REMPORT="$2" shift 2 else wrap Remote port option requested, but no remote port specified. Exiting. >&2 exit 1 fi ;; -s|--remote-server) if [ -n "$2" ]; then SERVERNAME="$2" shift 2 else wrap Remote server option requested, but no remote server specified. Exiting. >&2 exit 1 fi ;; -u|--remote-user) if [ -n "$2" ]; then REMUSERNAME="$2" shift 2 else wrap Remote user option requested, but no remote user specified. Exiting. >&2 exit 1 fi ;; -t|--server-type) if [ -n "$2" ]; then case "$2" in [Oo][Pp][Ee][Nn][Ss][Ss][Hh]) SERVER_SSH1=YES SERVER_SSH2=YES #FIXME; Older versions may not... SERVERTYPE="OPENSSH" shift 2 ;; [Cc][Oo][Mm][Ss][Ss][Hh]1) SERVER_SSH1=YES SERVER_SSH2=NO SERVERTYPE="COMSSH1" shift 2 ;; [Cc][Oo][Mm][Ss][Ss][Hh]2) SERVER_SSH1=NO #FIXME - It may be there is a backward compatibility handoff; how to tell? SERVER_SSH2=YES SERVERTYPE="COMSSH2" shift 2 ;; *) wrap Remote server type option requested, but invalid remote server type specified. Please choose one of OPENSSH COMSSH2 or COMSSH1 .Exiting. >&2 ;; esac else wrap Remote server type option requested, but no remote server type specified. Exiting. >&2 exit 1 fi ;; -h|--help) showhelp shift ;; -v|--verbose) VERBOSE="YES" shift ;; *) wrap Unrecognized option \"$1\". Exiting. >&2 exit 1 ;; esac done if [ -z "$REMUSERNAME" ]; then REMUSERNAME=$USER fi if [ -z "$REMPORT" ]; then REMPORT=22 SSHCommand="ssh" SCPCommand="scp" else SSHCommand="ssh -p $REMPORT" SCPCommand="scp -P $REMPORT" fi CLIENT_SSH1=NO CLIENT_SSH2=NO if type -path ssh1 >/dev/null 2>/dev/null ; then debug ssh1 binary detected, assuming ssh1 client support. CLIENT_SSH1=YES CLIENTTYPE=COMMSSH1 fi if type -path ssh2 >/dev/null 2>/dev/null ; then debug ssh2 binary detected, assuming ssh2 client support. CLIENT_SSH2=YES CLIENTTYPE=COMMSSH2 fi if [ "$CLIENT_SSH1" = "NO" ] && [ "$CLIENT_SSH2" = "NO" ]; then CLIENTSTRING=`ssh -V 2>&1 | sed -e 's/^[^ ]*: //' | head -1` case $CLIENTSTRING in #OpenSSH_2.5.1p2, SSH protocols 1.5/2.0, OpenSSL 0x0090581f -> openssh-2.5.1p2 #SSH Version OpenSSH_2.2.0p1, protocol versions 1.5/2.0. -> openssh-2.2.0. OpenSSH*|SSH\ Version\ OpenSSH_2*) debug OpenSSH client detected, assuming support for protocols 1 and 2. CLIENT_SSH1=YES CLIENT_SSH2=YES CLIENTTYPE=OPENSSH ;; #SSH Version OpenSSH-1.2.3, protocol version 1.5. -> openssh 1.2.3 SSH\ Version\ OpenSSH-1*) debug OpenSSH 1.x client detected, assuming support for protocol 1 only. CLIENT_SSH1=YES CLIENT_SSH2=NO CLIENTTYPE=OPENSSH ;; #OK, big risk. I'm going to assume that fsecure ssh1 and ssh.com ssh1 use the same command line syntax. #FIXME # #F-SECURE SSH Version 1.3.6 [i686-unknown-linux], protocol version 1.5. # #Standard version. Does not use RSAREF. # F-SECURE\ SSH\ Version\ 1*) # CLIENT_SSH1=YES # CLIENTTYPE=FSECURESSH1 # ;; #SSH Version 1.2.26 [i686-unknown-linux], protocol version 1.5. #Standard version. Does not use RSAREF. -> commssh 1.2.26 SSH\ Version\ 1*|F-SECURE\ SSH\ Version\ 1*) debug Commercial ssh1 client detected, assuming support for protocol 1 only. CLIENT_SSH1=YES CLIENTTYPE=COMMSSH1 ;; #executable_name: SSH Version 2.0.13 -> commssh 2.0.13 SSH\ Version\ 2*) #FIXME - fsecure ssh2? debug Commercial ssh2 client detected, assuming support for protocol 2 only. CLIENT_SSH2=YES CLIENTTYPE=COMMSSH2 ;; *) wrap Unable to recognize the version string returned from this client: wrap \"$CLIENTSTRING\" wrap Please contact William Stearns \ with this description and the type and version number of the ssh client on this machine. Exiting. exit 1 ;; esac fi if [ -z "$SERVERTYPE" ]; then SERVERSTRING=`( echo 'SSH-2.0' ; sleep 5 ) | nc $SERVERNAME $REMPORT 2>/dev/null | head -1` #Using 1.0 or 1.5 in the above probe returns "Protocol mismatch" from ssh2 servers - not useful. #2.0 gives descriptive output from ssh1, openssh, and ssh2. case $SERVERSTRING in '') wrap It does not appear that any ssh server is running on port $REMPORT at $SERVERNAME . Exiting. exit 1 ;; #SSH-1.99-OpenSSH_2.5.1p2 #Openssh #SSH-2.0-OpenSSH_3.0.2p1 #Openssh SSH-1.99-OpenSSH*|SSH-2.0-OpenSSH*) #OpenSSH debug It appears the $SERVERNAME server is an OpenSSH server. Assuming it supports ssh1 and ssh2. SERVER_SSH1=YES SERVER_SSH2=YES #FIXME; Older versions may not... SERVERTYPE=OPENSSH ;; #FIXME If ssh2 is listening on port 22, it may hand off to sshd1. #SSH-1.99-2.0.13 (non-commercial) #ssh.com ssh2 #SSH-2.0-2.2.0 SSH Secure Shell (non-commercial) #ssh.com ssh2 SSH-1.99*|SSH-2.0-2*) #SSH2 from SSH Comm. Sec. debug It appears the $SERVERNAME server is an SSH2 server from SSH.com. Assuming it supports ssh2 only. SERVER_SSH1=NO #FIXME - It may be there is a backward compatibility handoff; how to tell? SERVER_SSH2=YES SERVERTYPE=COMMSSH2 ;; #SSH-2.0-3.1.2 SSH Secure Shell (non-commercial) SSH-2.0-3.*) #ssh-3.0.1 noncommerical SERVER_SSH1=NO SERVER_SSH2=YES SERVERTYPE=COMMSSH2 ;; #SSH-1.5-1.2.26 #ssh.com ssh1 #SSH-1.5-1.3.6 F-SECURE SSH #Datafellows ssh1 SSH-1.5*) #SSH1 from SSH Comm. Sec. or Datafellows debug It appears the $SERVERNAME server is an SSH1 server from SSH.com or Datafellows. Assuming it supports ssh1 only. SERVER_SSH1=YES SERVER_SSH2=NO SERVERTYPE=COMMSSH1 ;; *) wrap Unable to recognize the version string returned from the server: wrap \"$SERVERSTRING\" wrap Please contact William Stearns \ with this description and the type and version number of the ssh server at $SERVERNAME , port $REMPORT. If you know the remote server is one of OPENSSH , COMSSH1 , or COMSSH2, you can specify those on the command line with \"-t OPENSSH\", for example. Exiting. exit 1 ;; esac fi debug Summary: if [ "$CLIENT_SSH1" = "YES" ]; then debug Client supports SSH protocol 1. else debug Client does NOT support SSH protocol 1. fi if [ "$CLIENT_SSH2" = "YES" ]; then debug Client supports SSH protocol 2. else debug Client does NOT support SSH protocol 2. fi if [ "$SERVER_SSH1" = "YES" ]; then debug Server supports SSH protocol 1. else debug Server does NOT support SSH protocol 1. fi if [ "$SERVER_SSH2" = "YES" ]; then debug Server supports SSH protocol 2. else debug Server does NOT support SSH protocol 2. fi if [ "$CLIENT_SSH2" = "YES" ] && [ "$SERVER_SSH2" = "YES" ]; then debug Both client and server support protocol 2, good, we\'ll use that. #Set up ssh2 keys here. if [ "$CLIENTTYPE" = "COMMSSH1" ] || [ "$SERVERTYPE" = "COMMSSH1" ]; then wrap Ugh. We chose to use protocol 2, but either the client or server turned out to be ssh1 from SSH Communications Security or Datafellows. Please report this to the developer William Stearns \ as a bug. Please note the names and versions of the ssh client and ssh server. Thanks. exit 1 fi mkdir -p ~/.ssh ~/.ssh2 #We may not need both, but feel free to bill me for the lost 4K. chmod 700 ~ ~/.ssh ~/.ssh2 case $CLIENTTYPE in OPENSSH) if [ -f ~/.ssh/id_dsa ] && [ -f ~/.ssh/id_dsa.pub ]; then debug Existing id_dsa and id_dsa.pub files, using those. elif [ ! -f ~/.ssh/id_dsa ] && [ ! -f ~/.ssh/id_dsa.pub ]; then debug No identity file, making one. if [ -n "$REMOTECOMMAND" ]; then wrap You have specified a single allowed remote command. This _may_ be an appropriate situation to use a passphrase-less key, if so press enter twice when prompted to assign a blank passphrase. Otherwise please enter a truly hard to guess passphrase. else wrap Please enter a truly hard to guess passphrase. fi if type -path ssh-keygen >/dev/null 2>/dev/null ; then ssh-keygen -b 1024 -d -C "${USER}@$HOSTNAME" -f ~/.ssh/id_dsa else wrap Missing ssh-keygen from this openssh client. Exiting. exit 1 fi else wrap You have ~/.ssh/id_dsa or ~/.ssh/id_dsa.pub, but not both, oops. Please fix. Exiting. exit 1 fi PRIVATEKEY=~/.ssh/id_dsa #Don't quote the tilde's; they need to be expanded by the shell OPENSSHDSAPUBKEY=~/.ssh/id_dsa.pub if [ -f ~/.ssh/id_dsa.commsshformat.pub ]; then SSH2DSAPUBKEY=~/.ssh/id_dsa.commsshformat.pub elif [ ! -f ~/.ssh/id_dsa.commsshformat.pub ] && [ "$SERVERTYPE" = "COMMSSH2" ]; then wrap We do not have a public key in commercial ssh2 format but will need one in a minute. Converting now. This requires you to enter your passphrase as part of the conversion. if type -path ssh-keygen >/dev/null 2>/dev/null ; then ssh-keygen -f ~/.ssh/id_dsa -x >>~/.ssh/id_dsa.commsshformat.pub else wrap Missing ssh-keygen from this openssh client. Exiting. exit 1 fi SSH2DSAPUBKEY=~/.ssh/id_dsa.commsshformat.pub fi ;; #COMMSSH1 was disqualified, above. COMMSSH2) if [ -f ~/.ssh2/id_dsa_1024_a ] && [ -f ~/.ssh2/id_dsa_1024_a.pub ]; then debug Existing id_dsa_1024_a and id_dsa_1024_a.pub files, using those. elif [ ! -f ~/.ssh2/id_dsa_1024_a ] && [ ! -f ~/.ssh2/id_dsa_1024_a.pub ]; then debug No identity file, making one. if [ -n "$REMOTECOMMAND" ]; then wrap You have specified a single allowed remote command. This _may_ be an appropriate situation to use a passphrase-less key, if so press enter twice when prompted to assign a blank passphrase. Otherwise please enter a truly hard to guess passphrase. else wrap Please enter a truly hard to guess passphrase. fi if type -path ssh-keygen2 >/dev/null 2>/dev/null ; then ssh-keygen2 -b 1024 -t DSS -c "${USER}@$HOSTNAME" ~/.ssh2/id_dsa_1024_a #"-o" not needed for ssh2, at least elif type -path ssh-keygen >/dev/null 2>/dev/null ; then ssh-keygen -b 1024 -t DSS -c "${USER}@$HOSTNAME" ~/.ssh2/id_dsa_1024_a #"-o" not needed for ssh2, at least else wrap Missing ssh-keygen2/ssh-keygen from this ssh2 client. Exiting. exit 1 fi else wrap You have ~/.ssh2/id_dsa_1024_a or ~/.ssh2/id_dsa_1024_a.pub, but not both, oops. Please fix. Exiting. exit 1 fi PRIVATEKEY=~/.ssh2/id_dsa_1024_a OPENSSHDSAPUBKEY="" SSH2DSAPUBKEY=~/.ssh2/id_dsa_1024_a.pub if [ -z "`cat ~/.ssh2/identification 2>/dev/null | grep '^IdKey id_dsa_1024_a$'`" ]; then echo "IdKey id_dsa_1024_a" >>~/.ssh2/identification fi ;; esac SSH1PUBKEY="" #keys exist chmod 600 $PRIVATEKEY case $SERVERTYPE in OPENSSH) wrap You will be asked to enter your remote password for each of the following commands. If you disagree with a particular command, or simply wish to perform it yourself, enter an incorrect password. set -x #FIXME - do password only on each of these; if a remote command is #being forced, the commands we're spcecifying won't be run. Do for all server sections. # PASSONLY='-o "RSAAuthentication no" -o "PubkeyAuthentication no"' perhaps? good for openssh 2 client. #FIXME set PASSONLY in each of the client tests above and user below. $SSHCommand ${REMUSERNAME}@${SERVERNAME} 'chmod 700 ~ ; mkdir -p ~/.ssh ; chmod 700 ~/.ssh ; rm -f ~/.ssh/newpubkey ~/.ssh/authorized_keys2.temp ; [ -f ~/.ssh/authorized_keys2 ] && cat ~/.ssh/authorized_keys2 >~/.ssh/authorized_keys2.temp' if [ -n "$REMOTECOMMAND" ]; then $SSHCommand ${REMUSERNAME}@${SERVERNAME} "echo -n command=\\\"$REMOTECOMMAND\\\" ' ' >>~/.ssh/authorized_keys2.temp" fi if [ -n "$OPENSSHDSAPUBKEY" ]; then #Don't use ~/.ssh....; local and remote may not agree on what "~" is. $SCPCommand $OPENSSHDSAPUBKEY ${REMUSERNAME}@${SERVERNAME}:.ssh/newpubkey $SSHCommand ${REMUSERNAME}@${SERVERNAME} 'cat ~/.ssh/newpubkey >>~/.ssh/authorized_keys2.temp' else $SCPCommand $SSH2DSAPUBKEY ${REMUSERNAME}@${SERVERNAME}:.ssh/newpubkey $SSHCommand ${REMUSERNAME}@${SERVERNAME} 'ssh-keygen -f ~/.ssh/newpubkey -X >>~/.ssh/authorized_keys2.temp' fi $SSHCommand ${REMUSERNAME}@${SERVERNAME} 'chmod 600 ~/.ssh/authorized_keys2.temp ; rm -f ~/.ssh/newpubkey ; mv -f ~/.ssh/authorized_keys2.temp ~/.ssh/authorized_keys2' #The mv must be last step on server. set +x ;; COMMSSH2) #FIXME - temp auth file (we could get away without one because the Command= append is the last step #but it leaves a two command window where the new key can run any command; specially bad if #this script is interrupted). wrap You will be asked to enter your remote password for each of the following commands. If you disagree with a particular command, or simply wish to perform it yourself, enter an incorrect password. REMKEYNAME=${SSH2DSAPUBKEY##*/} set -x $SSHCommand ${REMUSERNAME}@${SERVERNAME} 'chmod 700 ~ ; mkdir -p ~/.ssh2 ; chmod 700 ~/.ssh2' set +x wrap I need to check if the remote key name is already in use. set -x while $SSHCommand ${REMUSERNAME}@${SERVERNAME} "[ -f .ssh2/${REMKEYNAME} ]" ; do set +x wrap ~/.ssh2/$REMKEYNAME is already in use on $SERVERNAME . Please suggest another filename to use. Enter only the filename. For example, if you know ~/.ssh2/goober.pub is available, enter only \"goober.pub\" read REMKEYNAME set -x done $SCPCommand $SSH2DSAPUBKEY ${REMUSERNAME}@${SERVERNAME}:.ssh2/$REMKEYNAME if [ -n "$REMOTECOMMAND" ]; then $SSHCommand ${REMUSERNAME}@${SERVERNAME} "echo Key $REMKEYNAME >>~/.ssh2/authorization" ' ; chmod 600 ~/.ssh2/authorization' " ; echo Command \\\"$REMOTECOMMAND\\\">>~/.ssh2/authorization" else $SSHCommand ${REMUSERNAME}@${SERVERNAME} "echo Key $REMKEYNAME >>~/.ssh2/authorization" ' ; chmod 600 ~/.ssh2/authorization' fi set +x ;; esac if [ "$CLIENTTYPE" = "OPENSSH" ]; then if [ ! -f ~/.ssh/config ]; then touch ~/.ssh/config chmod 600 ~/.ssh/config fi if [ -z "`cat ~/.ssh/config 2>/dev/null | grep ^Host\ $SERVERNAME$`" ]; then echo "Host $SERVERNAME" >>~/.ssh/config echo " IdentityFile $PRIVATEKEY" >>~/.ssh/config if [ "$CLIENT_SSH1" = "YES" ] && [ "$CLIENT_SSH2" = "YES" ]; then echo " Protocol 2" >>~/.ssh/config fi echo " User $REMUSERNAME" >>~/.ssh/config fi fi elif [ "$CLIENT_SSH1" = "YES" ] && [ "$SERVER_SSH1" = "YES" ]; then debug Both client and server support protocol 1, good, we\'ll use that. #Set up ssh1 keys here. if [ "$CLIENTTYPE" = "COMMSSH2" ] || [ "$SERVERTYPE" = "COMMSSH2" ]; then wrap Ugh. We chose to use protocol 1, but either the client or server turned out to be ssh2 from SSH Communications Security or Datafellows. Please report this to the developer William Stearns \ as a bug. Please note the names and versions of the ssh client and ssh server. Thanks. exit 1 fi mkdir -p ~/.ssh chmod 700 ~ ~/.ssh if [ -f ~/.ssh/identity ] && [ -f ~/.ssh/identity.pub ]; then debug Existing identity and identity.pub files, using those. PRIVATEKEY=~/.ssh/identity #Don't quote the tilde's; they need to be expanded by the shell SSH1PUBKEY=~/.ssh/identity.pub OPENSSHDSAPUBKEY="" SSH2DSAPUBKEY="" elif [ ! -f ~/.ssh/identity ] && [ ! -f ~/.ssh/identity.pub ]; then debug No identity file, making one. if [ -n "$REMOTECOMMAND" ]; then wrap You have specified a single allowed remote command. This _may_ be an appropriate situation to use a passphrase-less key, if so press enter twice when prompted to assign a blank passphrase. Otherwise please enter a truly hard to guess passphrase. else wrap Please enter a truly hard to guess passphrase. fi case $CLIENTTYPE in OPENSSH) if type -path ssh-keygen >/dev/null 2>/dev/null ; then if [ "$CLIENT_SSH2" = "YES" ]; then ssh-keygen -b 1024 -t rsa1 -C "${USER}@$HOSTNAME" -f ~/.ssh/identity else ssh-keygen -b 1024 -C "${USER}@$HOSTNAME" -f ~/.ssh/identity fi else wrap Missing ssh-keygen from this openssh client. Exiting. exit 1 fi ;; COMMSSH1) if type -path ssh-keygen1 >/dev/null 2>/dev/null ; then ssh-keygen1 -b 1024 -C "${USER}@$HOSTNAME" -f ~/.ssh/identity elif type -path ssh-keygen >/dev/null 2>/dev/null ; then ssh-keygen -b 1024 -C "${USER}@$HOSTNAME" -f ~/.ssh/identity else wrap Missing ssh-keygen1/ssh-keygen from this ssh1 client. Exiting. exit 1 fi ;; #disqualified above #COMMSSH2) # ssh-keygen2 -b 1024 -t DSS -c "${USER}@$HOSTNAME" -o ~/.ssh/identity # ;; esac PRIVATEKEY=~/.ssh/identity SSH1PUBKEY=~/.ssh/identity.pub OPENSSHDSAPUBKEY="" SSH2DSAPUBKEY="" else wrap You have ~/.ssh/identity or ~/.ssh/identity.pub, but not both, oops. Please fix. Exiting. exit 1 fi #keys exist chmod 600 $PRIVATEKEY #FIXME - temp auth file wrap You will be asked to enter your remote password for each of the following commands. If you disagree with a particular command, or simply wish to perform it yourself, enter an incorrect password. set -x $SSHCommand ${REMUSERNAME}@${SERVERNAME} 'chmod 700 ~ ; mkdir -p ~/.ssh ; chmod 700 ~/.ssh ; rm -f ~/.ssh/newpubkey' $SCPCommand $SSH1PUBKEY ${REMUSERNAME}@${SERVERNAME}:.ssh/newpubkey if [ -n "$REMOTECOMMAND" ]; then $SSHCommand ${REMUSERNAME}@${SERVERNAME} "echo -n command=\\\"$REMOTECOMMAND\\\" ' ' >>~/.ssh/authorized_keys" ' ; cat ~/.ssh/newpubkey >>~/.ssh/authorized_keys ; chmod 600 ~/.ssh/authorized_keys ; rm -f ~/.ssh/newpubkey' else $SSHCommand ${REMUSERNAME}@${SERVERNAME} 'cat ~/.ssh/newpubkey >>~/.ssh/authorized_keys ; chmod 600 ~/.ssh/authorized_keys ; rm -f ~/.ssh/newpubkey' fi set +x if [ "$CLIENTTYPE" = "OPENSSH" ]; then if [ ! -f ~/.ssh/config ]; then touch ~/.ssh/config chmod 600 ~/.ssh/config fi if [ -z "`cat ~/.ssh/config | grep ^Host\ $SERVERNAME$`" ]; then echo "Host $SERVERNAME" >>~/.ssh/config echo " IdentityFile $PRIVATEKEY" >>~/.ssh/config if [ "$CLIENT_SSH1" = "YES" ] && [ "$CLIENT_SSH2" = "YES" ]; then echo " Protocol 1" >>~/.ssh/config fi echo " User $REMUSERNAME" >>~/.ssh/config fi fi else wrap Cannot find a protocol they agree on, exiting. exit 1 fi if [ -n "$REMOTECOMMAND" ]; then wrap The public key has been installed on $SERVERNAME . \ At this point, if you ssh to $SERVERNAME as user \ $REMUSERNAME , you should be prompted for your passphrase \ and the remote server should run $REMOTECOMMAND . echo ' ' $SSHCommand -l $REMUSERNAME $SERVERNAME else wrap The public key has been installed on $SERVERNAME . \ If you wish to test this, you can run the following command, which \ should prompt you for your passphrase and return the string HI. echo ' ' $SSHCommand -l $REMUSERNAME $SERVERNAME \'/bin/echo HI\' fi wrap If you are prompted for your remote pass_word_, the key installation did not work. \ In this case, please let William Stearns \ know of the failure. \ Please include the ssh client and server versions and the exact command you just ran.