Re: [RFC] Initialisation of ssh-agent
On Fri, Jul 18, 2003 at 20:20:58 -0500, Jesse Meyer wrote:
> On Fri, 18 Jul 2003, Vincent Lefevre wrote:
> > I wrote some zsh scripts to start ssh-agent if one is not running,
> > and call ssh-add only when needed (ssh, slogin and scp are wrappers).
> > The ssh-agent is killed when it isn't needed any longer (but this
> > doesn't work very well with screen, perhaps unless one chooses to
> > make all shells login shells).
>
> I'm curious - mind showing us the scripts?
I've attached the two ssh functions _call_sshagent and _call_sshadd
(put them in your fpath). Use these scripts at your own risks. I tried
to avoid race conditions but there may still be something I forgot.
The .zlogin should contain a call to _call_sshagent. The .zlogout
should contain something like:
# Unregister from ssh-agent and kill it if need be.
if [[ -n $SSH_AUTH_SOCK ]] then
if [[ `whence -w _call_sshagent` == '_call_sshagent: function' ]] then
_call_sshagent -r
elif [[ -n $SSH_AGENT_PID ]] then
eval `ssh-agent -k`
fi
fi
Alternativement, if you use programs like screen, you could put the
call to _call_sshagent into the .zshrc and use a trap to clean up.
And wrappers to automatically call ssh-add if need be:
ssh()
{
_call_sshadd "$@"
command ssh "$@"
}
slogin()
{
_call_sshadd "$@"
command slogin "$@"
}
scp()
{
_call_sshadd "$@"
command scp "$@"
}
I also have a wrapper scripts/ssh that contains:
#!/usr/bin/env zsh
# Note: put this script in ~/scripts (not in path)
source ~/.zshenv
source ~/.zalias
unset DISPLAY
ssh "$@"
# $Id: ssh 11 2003-06-18 19:30:04Z lefevre $
(the .zalias file contains the definitions of the above 3 functions).
This is useful for some programs like cvs or svn:
export CVS_RSH=$HOME/scripts/ssh
export SVN_SSH=$HOME/scripts/ssh
--
Vincent Lefèvre <vincent@vinc17.org> - Web: <http://www.vinc17.org/> - 100%
validated (X)HTML - Acorn Risc PC, Yellow Pig 17, Championnat International
des Jeux Mathématiques et Logiques, TETRHEX, etc.
Work: CR INRIA - computer arithmetic / SPACES project at LORIA
#!/usr/bin/env zsh
# Usage: _call_sshagent [ -l | -r ]
# -l: try to use an existing ssh-agent and change SSH_AUTH_SOCK
# accordingly. This is useful for some non-login shells (no
# possible clean-up by the .zlogout).
# -r: remove the socket associated with the current process and
# kill ssh-agent if there are no sockets any longer.
emulate -LR zsh
local link=/tmp/ssh-agent-$USER
local i=4
until (ln -s /dev/null $link.lock)
do
if [[ $((--i)) -eq 0 ]] then
echo "$0: can't lock $link"
return
fi
sleep 2
done
local dir=`readlink $link`
if [[ $1 == -r ]] then
if [[ -O $link && -d $dir && -O $dir && $SSH_AUTH_SOCK == $link/* ]] then
local others
rm -f $SSH_AUTH_SOCK
unset SSH_AUTH_SOCK
others=($dir/agent.*(N=))
if [[ -z $others ]] then
local pid=$(<$dir/ssh-agent.pid)
rm -f $link $dir/ssh-agent.pid
kill -TERM $pid
fi
else
# Inconsistent data, try to kill ssh-agent in the standard way
eval `ssh-agent -k`
fi
elif [[ $1 == -l ]] then
if [[ -O $link && -d $dir && -O $dir ]] then
local old
old=($link/agent.*(N=[1]))
if [[ -S $old ]] then
SSH_AUTH_SOCK=$old ssh-add -l >& /dev/null
if [[ $? -ne 2 ]] then
export SSH_AUTH_SOCK=$old
unset SSH_AGENT_PID
fi
else
echo "$0: $old isn't a socket"
fi
fi
else
if [[ -O $link && -d $dir && -O $dir ]] then
local old
old=($link/agent.*(N=[1]))
if [[ -S $old ]] then
SSH_AUTH_SOCK=$old ssh-add -l >& /dev/null
if [[ $? -eq 2 ]] then
# The agent could not be contacted, assume that it has died
rm -f $dir/agent.*(N) $dir/ssh-agent.pid && rmdir $dir
rm -f $link
rm -f $link.lock
$0
return
fi
local new=$link/agent.$$
if [[ $new == $old ]] || ln -f $old $new; then
export SSH_AUTH_SOCK=$new
unset SSH_AGENT_PID
else
echo "$0: can't link $new -> $old"
fi
else
echo "$0: $old isn't a socket"
fi
elif eval `ssh-agent`; then
if ln -fs $SSH_AUTH_SOCK:h $link; then
local old=$SSH_AUTH_SOCK
echo $SSH_AGENT_PID > $link/ssh-agent.pid
rm -f $link.lock
$0 && rm -f $old
return
else
echo "$0: can't symlink $dir -> $SSH_AUTH_SOCK:h"
fi
else
echo "$0: can't call ssh-agent"
fi
fi
rm -f $link.lock
# $Id: _call_sshagent 11 2003-06-18 19:30:04Z lefevre $
#!/usr/bin/env zsh
emulate -LR zsh
ssh-add -l >& /dev/null
local err=$?
if [[ $err -eq 2 ]] then
_call_sshagent -l
ssh-add -l >& /dev/null
err=$?
fi
if [[ $err -eq 1 ]] then
local file i
file=()
for i in id_rsa id_rsa-internal identity
do
[[ -f $HOME/.ssh/$i ]] && file=($file $HOME/.ssh/$i)
done
ssh-add $file
fi
true
# $Id: _call_sshadd 11 2003-06-18 19:30:04Z lefevre $
Reply to: