Home
| Calendar
| Mail Lists
| List Archives
| Desktop SIG
| Hardware Hacking SIG
Wiki | Flickr | PicasaWeb | Video | Maps & Directions | Installfests | Keysignings Linux Cafe | Meeting Notes | Linux Links | Bling | About BLU |
No, this keychain is an open source shell script available from Gentoo that utilizes ssh-agent in such a manner that it is possible to start mutiple shells with out multiple instances of ssh-agent being generated each time. My earlier post was inaccurate as far as the symptoms I am experiencing. I have been experimenting with both keychain and ssh-agent over the past week but not every day, so I unfortunately described the behavior of ssh-agent in my post. And that behavior is what you should experience with ssh-agent. Keychain is not working yet for me it gives me the following output when I first start a cygwin bash shell: KeyChain 2.0.1; http://www.gentoo.org/projects/keychain Copyright 2002 Gentoo Technologies, Inc.; Distributed under the GPL * All previously running ssh-agent(s) have been stopped. * Initializing /home/jim/.keychain/KELLY-RAND-sh file... * Initializing /home/jim/.keychain/KELLY-RAND-csh file... * Starting new ssh-agent * 1 more keys to add... Enter passphrase for /home/jim/.ssh/id_dsa: Identity added: /home/jim/.ssh/id_dsa (/home/jim/.ssh/id_dsa) bash: /home/jim/.ssh-agent: No such file or directory ############################################## below is the script keychain ############################################# #!/bin/sh # Copyright 1999-2002 Gentoo Technologies, Inc. # Distributed under the terms of the GNU General Public License v2 # Author: Daniel Robbins <drobbins at gentoo.org> # $Header: /home/cvsroot/gentoo-src/keychain/keychain,v 1.25 2002/08/26 20:25:24 drobbins Exp $ version=2.0.1 PATH="/sbin:/usr/sbin:${PATH}:/usr/ucb"; export PATH; myaction="" myactionarg="" noaskopt="" quietopt="" nocolopt="" clearopt="" mykeys="" keydir="${HOME}/.keychain" while [ -n "$1" ] do case $1 in -h|--help|--stop|-k) #action specified if [ -z "$myaction" ] then case $1 in -h|--help) myaction="help" ;; --stop|-k) myaction="stop" ;; esac myactionarg="$1" else echo "$0: you can't specify $myactionarg and $1 at the same time; exiting." exit 1 fi ;; --dir) shift keydir="${1}/.keychain" ;; --clear) clearopt="yes" ;; --noask) noaskopt="yes" ;; -q|--quiet) quietopt="yes" ;; --nocolor) nocolopt="yes" ;; *) mykeys="${mykeys} $1" ;; esac shift done #first, handle help. if [ "$myaction" = "help" ] then echo $E Usage: ${CYAN}${0}${OFF} [ ${GREEN}options${OFF} ] ${CYAN}sshkey${OFF} ... cat <<EOHELP Description: Keychain is an OpenSSH key manager, typically run from ~/.bash_profile. When run, it will make sure ssh-agent is running; if not, it will start ssh-agent. It will redirect ssh-agent's output to ~/.keychain/[hostname]-sh, so that cron jobs that need to use ssh-agent keys can simply source this file and make the necessary passwordless ssh connections. In addition, when keychain runs, it will check with ssh-agent and make sure that the ssh RSA/DSA keys that you specified on the keychain command line have actually been added to ssh-agent. If not, you are prompted for the appropriate passphrases so that they can be added by keychain. Typically, one uses keychain by adding the following to the top of their ~/.bash_profile (or ~/.zlogin, in case of zsh): EOHELP echo $E " ${CYAN}keychain ~/.ssh/id_rsa ~/.ssh/id_dsa" echo $E " . ~/.keychain/\${HOSTNAME}-sh${OFF}" echo echo $E " # alt. syntax: . ~/.keychain/\`uname -n\`-sh" echo $E " # note the use of back-quotes (\`) rather than single-quotes (') above." echo $E " # We now include the hostname (\`uname -n\`) in the keychain filename" echo $E " # for NFS-compatibility." echo echo " You can make keychain work with your csh-compatible shell by adding the" echo " following to your .cshrc:" echo echo $E " ${CYAN}keychain ~/.ssh/id_rsa ~/.ssh/id_dsa" echo $E " source ~/.keychain/\${HOSTNAME}-csh${OFF}" echo cat <<EOHELP Keychain allows all your apps and cron jobs to use a single ssh-agent process as an authentication agent. By default, the ssh-agent started by keychain is long-running and will continue to run, even after you have logged out from the system. If you'd like to tighten up security a bit, take a look at the EOHELP echo $E " ${GREEN}--clear${OFF} option, described below." echo echo Options: echo echo $E " ${GREEN}--clear${OFF}" echo cat <<EOHELP Tells keychain to delete all of ssh-agent's host keys. Typically, This is used in the ~/.bash_profile. The theory behind this is that keychain should assume that you are an intruder until proven otherwise. However, while this option increases security, it still allows your cron jobs to use your ssh keys when you're logged out. EOHELP echo echo $E " ${GREEN}--dir [directoryname]${OFF}" echo cat <<EOHELP Keychain will look in [directoryname] for the .keychain file, rather than your home directory. EOHELP echo echo $E " ${GREEN}--noask${OFF}" echo cat <<EOHELP This option tells keychain do everything it normally does (ensure ssh-agent is running, set up the ~/.keychain/[hostname]-{c}sh files) except that it will not prompt you to add any of the keys you specified if they haven't yet been added to ssh-agent. EOHELP echo echo $E " ${GREEN}--nocolor${OFF}" echo echo " This option disables color highlighting for non vt-100-compatible terms." echo echo $E " ${GREEN}--stop | -k${OFF}" echo cat <<EOHELP This option tells keychain to stop all running ssh-agent processes, and then exit. EOHELP echo echo $E " ${GREEN}--quiet | -q${OFF}" echo cat <<EOHELP This option tells keychain to turn off verbose mode and only print error messages and interactive messages. This is useful for login scripts etc. EOHELP echo #' this line is a simple fix for vim syntax highlighting rm -f "$lockf" 2> /dev/null exit 1 fi # Query local host for operating system. cygwin="no" hpux="no" myuname=`uname -s` if [ -n "`echo $myuname | grep CYGWIN`" ] then cygwin="yes" elif [ -n "`echo $myuname | grep HP-UX`" ] then hpux="yes" fi # Query local host for SSH application, presently supporting only # OpenSSH (see http://www.openssh.org) when openssh="yes" and # SSH2 (see http://www.ssh.com) when openssh="no". openssh="no" if [ -n "`ssh -V 2>&1 | grep OpenSSH`" ] then openssh="yes" fi # Avoid trapping on signal names with Cygwin. trapint="INT" if [ "$cygwin" = "yes" ] then trapint=2 fi # Disallow ^C abortion, since keys may be in interim, unsafe states. trap "" $trapint # pidf holds the specific name of the keychain .ssh-agent-myhostname file. # We use the new hostname extension for NFS compatibility. cshpidf is the # .ssh-agent file with csh-compatible syntax. lockf is the lockfile, used # to serialize the execution of multiple ssh-agent processes started # simultaneously (only works if lockfile from the procmail package is # available. hostname=`uname -n` pidf="${keydir}/${hostname}-sh" cshpidf="${keydir}/${hostname}-csh" lockf="${keydir}/${hostname}-lock" if [ -f ${keydir} ] then echo "$0: ${keydir} is a file (it should be a directory;) please fix." exit 1 #Solaris 9 doesn't have -e; using -d.... elif [ ! -d ${keydir} ] then mkdir ${keydir} || exit 1 chmod 0700 ${keydir} fi # perform lock if we have lockfile available if type lockfile >/dev/null 2>&1; then lockfile -1 -r 30 -l 35 -s 2 "$lockf" if [ $? != 0 ]; then echo "$0: Couldn't get lock" >&2 exit 1 fi fi #auto-detect whether echo -e works. unset BLUE GREEN OFF CYAN E if [ -z "`echo -e`" ] then E="-e" # color variables won't be defined if --nocolor is present fi if [ -z "$nocolopt" ] then BLUE="\033[34;01m" GREEN="\033[32;01m" OFF="\033[0m" CYAN="\033[36;01m" fi if [ -z "$quietopt" ] then echo echo $E "${GREEN}KeyChain ${version}; ${BLUE}http://www.gentoo.org/projects/keychain${OFF}" echo $E " Copyright 2002 Gentoo Technologies, Inc.; Distributed under the GPL" fi me=`whoami` if [ "$cygwin" = "yes" ] then #for cygwin psopts="-e -u $me -f" elif [ "$hpux" = "yes" ] then #for hp-ux psopts="-u $me -f" else psopts="FAIL" #-x option needed on MacOS X, but just in case it doesn't work on other arches we have a "-u $me -f" #at the end. "-uxw" works on modern Linux systems. for x in "-x -u $me -f" "-uxw" "-u $me -f" do ps $x >/dev/null 2>&1 if [ $? -eq 0 ] then psopts="$x" break fi done if [ "$psopts" = "FAIL" ] then echo "$0: unable to use \"ps\" to scan for ssh-agent processes. Report keychain version and" echo "system configuration to drobbins at gentoo.org." rm -f "${lockf}" 2> /dev/null exit 1 fi fi mypids=`ps $psopts 2>/dev/null | grep "[s]sh-agent"` > /dev/null 2>&1 #extract the second item from mypids: if [ -n "$mypids" ] then set $mypids mypids=$2 fi if [ "$myaction" = "stop" ] then # --stop tells keychain to kill the existing ssh-agent(s), then exit kill $mypids > /dev/null 2>&1 rm -f "${pidf}" "${cshpidf}" "$lockf" 2> /dev/null #`whoami` (rather than the $LOGNAME var) gives us the euid rather than the uid (what we want) if [ -z "$quietopt" ] then echo $E " ${GREEN}*${OFF} All ssh-agent(s) started by" `whoami` "are now stopped." echo fi exit 0 fi SSH_AGENT_PID="NULL" if [ -f $pidf ] then . $pidf fi # Copy application-specific environment variables into generic local variables. SSH_AUTH_SOCK_NAME="SSH_AUTH_SOCK" SSH_AGENT_PID_NAME="SSH_AGENT_PID" if [ "$openssh" = "no" ] then SSH_AUTH_SOCK=${SSH2_AUTH_SOCK} SSH_AGENT_PID=${SSH2_AGENT_PID} SSH_AUTH_SOCK_NAME="SSH2_AUTH_SOCK" SSH_AGENT_PID_NAME="SSH2_AGENT_PID" fi match="no" for x in $mypids do if [ "$x" = "$SSH_AGENT_PID" ] then if [ -z "$quietopt" ] then echo $E " ${GREEN}*${OFF} Found existing ssh-agent at PID ${x}" fi match="yes" break fi done if [ "$match" = "no" ] then if [ -n "$mypids" ] then kill $mypids > /dev/null 2>&1 fi if [ -z "$quietopt" ] then echo $E " ${GREEN}*${OFF} All previously running ssh-agent(s) have been stopped." echo $E " ${GREEN}*${OFF} Initializing ${pidf} file..." fi # "> pidf" doesn't work ash. But it should work with any sh-compatible shell > "$pidf" || { echo "$0: Cannot create ${pidf}; exiting." 1>&2; rm -f "$pidf" "$cshpidf" "$lockf" 2> /dev/null; exit 1; } [ -z "$quietopt" ] && echo $E " ${GREEN}*${OFF} Initializing ${cshpidf} file..." > "$cshpidf" || { echo "$0: Cannot create ${cshpidf}; exiting." 1>&2; rm -f "$pidf" "$cshpidf" "$lockf" 2> /dev/null; exit 1; } chmod 0600 "$pidf" "$cshpidf" [ -z "$quietopt" ] && echo $E " ${GREEN}*${OFF} Starting new ssh-agent" nohup ssh-agent -s | grep -v 'Agent pid' > "$pidf" . "$pidf" echo "setenv $SSH_AUTH_SOCK_NAME $SSH_AUTH_SOCK;" > "$cshpidf" echo "setenv $SSH_AGENT_PID_NAME $SSH_AGENT_PID;" >> "$cshpidf" fi if [ -n "$clearopt" ] then echo $E " ${GREEN}*${OFF} \c" ssh-add -D fi #now that keys are potentially cleared, it's safe to be aborted by ^C trap - $trapint if [ -n "$noaskopt" ] then # --noask means "don't ask for keys", so skip this next part echo rm -f "$lockf" 2> /dev/null exit 0 fi # hook in to existing agent . "$pidf" missingkeys="START" #below, previous count of missing keys, and count of missing keys, respectively. #when the difference between these two numbers does not abort after three tries, #we abort the loop (using $countdown) pmcount=0 mcount=0 countdown=3 while [ $countdown -gt 1 ] && [ "$missingkeys" != "" ] do pmcount=$mcount mcount=0 myfail=0 missingkeys="" # Generate and parse verbose listing of already added keys. if [ "$openssh" = "no" ] then myavail=`ssh-add -l 2>&1 | tail +2 | awk '{ sub(/:.*/, ""); print }'` else myavail=`ssh-add -l 2>&1 | cut -f2 -d " "` fi if [ $? -ne 0 ] then echo $E " ${CYAN}*${OFF} Problems listing keys; exiting..." exit 1 fi for x in $mykeys do if [ ! -f "$x" ] then echo $E " ${CYAN}*${OFF} Can't find ${x}; skipping..." continue fi # Extract relevant metadata from current user-specified key. if [ "$openssh" = "no" ] then myfing=`basename ${x} 2>&1 | cut -f2 -d " "` else if [ -f "${x}.pub" ] then myfing=`ssh-keygen -l -f ${x}.pub 2>&1` else myfing=`ssh-keygen -l -f ${x} 2>&1` if [ $? -ne 0 ] then echo $E " ${CYAN}*${OFF} Warning: ${x}.pub missing; can't tell if key ${x} already loaded." myfail=3 fi fi myfing=`echo ${myfing} | cut -f2 -d " "` fi skip=0 for y in $myavail do if [ "$y" = "$myfing" ] then skip=1 break fi done if [ $skip -ne 1 ] then missingkeys="$missingkeys $x" mcount=`expr $mcount + 1` fi done if [ "$missingkeys" = "" ] then break fi if [ `expr $pmcount - $mcount` -eq 0 ] then countdown=`expr $countdown - 1` else countdown=3 fi if [ -z "$quietopt" ] then echo $E " ${GREEN}*${OFF} ${BLUE}${mcount}${OFF} more keys to add..." fi if [ -n "$SSH_ASKPASS" ] then ssh-add ${missingkeys} < /dev/null else ssh-add ${missingkeys} fi if [ $? -ne 0 ] then myfail=`expr $myfail + 1` echo $E " ${CYAN}*${OFF} Problem adding key${OFF}..." fi done if [ -z "$quietopt" ] then echo fi #remove lockfile if it exists rm -f "$lockf" 2> /dev/null #end of keychain till next Jim Kelly-Rand
BLU is a member of BostonUserGroups | |
We also thank MIT for the use of their facilities. |