From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 7597 invoked from network); 22 Nov 2005 09:47:20 -0000 X-Spam-Checker-Version: SpamAssassin 3.1.0 (2005-09-13) on f.primenet.com.au X-Spam-Level: X-Spam-Status: No, score=-2.5 required=5.0 tests=AWL,BAYES_00, FORGED_RCVD_HELO autolearn=ham version=3.1.0 Received: from news.dotsrc.org (HELO a.mx.sunsite.dk) (130.225.247.88) by ns1.primenet.com.au with SMTP; 22 Nov 2005 09:47:20 -0000 Received: (qmail 94168 invoked from network); 22 Nov 2005 09:47:14 -0000 Received: from sunsite.dk (130.225.247.90) by a.mx.sunsite.dk with SMTP; 22 Nov 2005 09:47:14 -0000 Received: (qmail 383 invoked by alias); 22 Nov 2005 09:47:06 -0000 Mailing-List: contact zsh-users-help@sunsite.dk; run by ezmlm Precedence: bulk X-No-Archive: yes X-Seq: 9706 Received: (qmail 373 invoked from network); 22 Nov 2005 09:47:05 -0000 Received: from news.dotsrc.org (HELO a.mx.sunsite.dk) (130.225.247.88) by sunsite.dk with SMTP; 22 Nov 2005 09:47:05 -0000 Received: (qmail 93092 invoked from network); 22 Nov 2005 09:47:05 -0000 Received: from vinc17.net4.nerim.net (HELO ay.vinc17.org) (62.212.121.106) by a.mx.sunsite.dk with SMTP; 22 Nov 2005 09:47:03 -0000 Received: from lefevre by ay.vinc17.org with local (Exim 4.54) id 1EeUjs-0004Xt-BW; Tue, 22 Nov 2005 10:47:00 +0100 Date: Tue, 22 Nov 2005 10:47:00 +0100 From: Vincent Lefevre To: zsh-users@sunsite.dk Subject: Re: Is zsh buggy in connection with screen? Message-ID: <20051122094700.GP24980@ay.vinc17.org> Mail-Followup-To: zsh-users@sunsite.dk References: <20051108130233.GA6146@hpfsc.de> <20051108141317.GQ27583@ay.vinc17.org> <20051108174411.GH24349@dot.blorf.net> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="8t9RHnE3ZwKMSgU+" Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: X-Mailer-Info: http://www.vinc17.org/mutt/ User-Agent: Mutt/1.5.11-vl-20051120 --8t9RHnE3ZwKMSgU+ Content-Type: text/plain; charset=iso-8859-1 Content-Disposition: inline Content-Transfer-Encoding: 8bit On 2005-11-08 17:09:42 -0500, Ian Langworth wrote: > I have a similar problem with ssh-agent. New screen windows > automatically get the updated environment when I've shelled freshly > into the machine, but existing shells in windows need to run > "latestssh." [...] I have my own solution for ssh, which is not related to screen, since I sometimes have several shells on a machine, but without necessarily using screen. This solution also supports connection sharing. See the attached message. -- Vincent Lefèvre - Web: 100% accessible validated (X)HTML - Blog: Work: CR INRIA - computer arithmetic / SPACES project at LORIA --8t9RHnE3ZwKMSgU+ Content-Type: message/rfc822 Content-Disposition: inline Content-Transfer-Encoding: 8bit Date: Fri, 28 Oct 2005 16:15:45 +0200 From: Vincent Lefevre Subject: Re: SSH connection caching MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="61jdw2sOBCFtR2d/" Content-Disposition: inline Content-Transfer-Encoding: 8bit --61jdw2sOBCFtR2d/ Content-Type: text/plain; charset=iso-8859-1 Content-Disposition: inline Content-Transfer-Encoding: 8bit This isn't a command, but a set of zsh scripts I've written. I've attached them. If you want to use them, you basically need to put these files somewhere in your $fpath, autoload the corresponding functions with autoload -U _call_sshagent _call_sshadd kill_sshmasters call _call_sshagent from your .zlogin and add the following to your .zlogout: # 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 and use the following wrappers: ssh() { _call_sshadd "$@" command ssh "$@" } slogin() { _call_sshadd "$@" command slogin "$@" } scp() { _call_sshadd "$@" command scp "$@" } sftp() { _call_sshadd "$@" command sftp "$@" } Note: here, these wrappers are defined in .zalias (so is the autoload line I've mentioned above), sourced by my .zshrc file. Also, I've set SVN_SSH to $HOME/scripts/ssh; this script contains: source ~/.zshenv source ~/.zalias unset DISPLAY ssh -C "$@" Note that $HOME/scripts must not be in $path to avoid an infinite recursion. In fact, it would be more robust to dynamically remove $HOME/scripts from $path before calling ssh, after resolving hard and symbolic links. But there should be no problem if you do not have '.' in your $path or if you have it at the end (having '.' earlier in $path is a security problem anyway). This way, one no longer needs to call ssh-agent and/or ssh-add manually. The passphrase is automatically asked at the first connection attempt and remembered until the last login shell exits. However, one still needs to execute ssh -fMN manually for ssh connection caching. You can add lines to some ssh wrapper to do that automatically, but you need to check for the corresponding ControlSocket file first, otherwise there will be no benefit; unfortunately this is not easy... About these problems, you can see my bug report and followup here: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=335697 Also, note that lsof is used to find the ssh master connection. If you do not have lsof, the ssh master connection will not be killed. The kill_sshmasters script has an echo line to let you know that this connection is killed. So, you know what happens. Standard disclaimer: use these scripts at your own risks. I've written them with security in mind, but they haven't be reviewed by anyone else. Also, I've written them for my config on various machines, and I'm not sure they work correctly everywhere. You can still check that ssh-agent is killed when you completely logout with a ssh host ps -aef | grep ssh-agent ^^^^ or other options depending on your system, and things like that. -- Vincent Lefèvre - Web: 100% accessible validated (X)HTML - Blog: Work: CR INRIA - computer arithmetic / SPACES project at LORIA --61jdw2sOBCFtR2d/ Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=_call_sshadd #!/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 2770 2004-03-17 22:39:32Z lefevre $ --61jdw2sOBCFtR2d/ Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=_call_sshagent #!/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=0 until (ln -s /dev/null $link.lock 2> /dev/null) do [[ $i -eq 0 ]] && echo "$0: waiting for lock" if [[ $((++i)) -eq 4 ]] 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 kill_sshmasters 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 9482 2005-10-25 15:49:48Z lefevre $ --61jdw2sOBCFtR2d/ Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=kill_sshmasters #!/usr/bin/env zsh # Kill the ssh master connections having no slaves. emulate -LR zsh local file pid pids for file in /tmp/ssh-*(=N) do pids=($(lsof -F f -U -a -c ssh -a "$file" 2>/dev/null)) if [[ $#pids == 2 ]] then pid=${pids[1]#p} echo "kill $pid (socket $file)" kill -TERM $pid fi done # Never fail. true # $Id: kill_sshmasters 9485 2005-10-25 16:08:12Z lefevre $ --61jdw2sOBCFtR2d/-- --8t9RHnE3ZwKMSgU+--