#! /bin/bash # Make old ssh connections that forward the AUTH_SOCK work by # symbolically linking old ssh auth sockets used by ssh clients to the # currently active socket. # Usage: # ssh host 'ssh_auth_shuffle && screen -d -r; rm ~/.ssh_auth_sock/$$' # to clean up pid file immediately or # ssh host 'ssh_auth_shuffle && exec screen -d -r' # Useful aliases/functions for Bourne like shells are: # auth '. ~/.auth_ssh' -- refreshes SSH variables to current settings # ssh '. ~/.auth_ssh; ssh ' -- refreshes SSH variables and invokes ssh # scp '. ~/.auth_ssh; ssh ' -- refreshes SSH variables and invokes scp # at the end of your shell startup script put: # . ~/.auth_ssh # for bourne like shells # Support for multiple screen sessions not yet complete, but that is # why there are independent files to store the SSH auth vars in. # require globbing for non-existant files to be null. shopt -s nullglob # make files/directories created below private umask 077 # make directory [ -d ~/.ssh/auth_sock_info ] || mkdir -p ~/.ssh/auth_sock_info # clean up old links to sockets we have done in the past if [ -f ~/.ssh/auth_sock_info/old ]; then for i in `cat ~/.ssh/auth_sock_info/old` do rm -rf `dirname $i` done rm -f ~/.ssh/auth_sock_info/old fi # clean up socket info for old shells for i in ~/.ssh/auth_sock_info/[0-9]* do # use ps -p to see if process exists. # exit 1 if not and 0 if it does. # it's ok if it's not our process at some point the process will # not exist and the pid file will be reaped. /bin/ps -p `basename $i` > /dev/null || rm -f $i done # make sure we have an active sshd process to link to. pid=`echo $SSH_AUTH_SOCK | sed -e 's/.*\.\([0-9]*\)$/\1/'` if ps -p $pid -f | grep "$USER.*sshd.*@.*[0-9]" > /dev/null; then # store the current SSH variables set | sed -ne '/[S]SH/s/^/export /p' > ~/.ssh/auth_sock_info/$PPID # store the current DISPLAY variable set | sed -ne '/DISPLAY/s/^/export /p' >> ~/.ssh/auth_sock_info/$PPID # Create a statically named link that points to the current # info rm -f ~/.auth_ssh; ln -s ~/.ssh/auth_sock_info/$PPID ~/.auth_ssh else echo "Current SSH_AUTH_SOCK is invalid. Pid $pid not a valid sshd." exit 2 fi # run through processes for this user looking for ssh processes # with SSH_AUTH_SOCK set in their environments. USER=`whoami` for i in `pgrep -u $USER 'ssh$'` do SOCK=`ps ewwp $i | sed -ne 's/.*SSH_AUTH_SOCK=\([^ ]*\).*/\1/p'` OLD_SOCK="$OLD_SOCK $SOCK" done if [ -n "$OLD_SOCK" ]; then for i in $OLD_SOCK do # see if the old sshd process is running and if it is not # connected to a tty it's orphaned. Kill it and set up to # forward the socket. pid=`echo $i | sed -e 's/.*\.\([0-9]*\)$/\1/'` if ps -p $pid -f | grep "$USER.*sshd.*@.*[0-9]" > /dev/null; then echo "Prior sshd process $pid still connected to tty not resetting socket" else # make sure it is orphaned. It could be reused by another # non-sshd process. if ps -p $pid -f | grep "$USER.*sshd.*notty" > /dev/null ; then kill $pid fi # remove the old socket in case ssh didn't clean up rm -f $i OLD_DEAD_SOCK="$OLD_DEAD_SOCK $i" fi done fi if [ -n "$OLD_DEAD_SOCK" ]; then for i in $OLD_DEAD_SOCK do # in case ssh exited on it's own it might have cleaned up and # removed the socket and the directory, so we need to check # and remake directory. [ -d "`dirname $i`" ] || mkdir "`dirname $i`" # link old location to new active socket. ln -s "$SSH_AUTH_SOCK" "$i" # record for later cleanup echo "$i" >> ~/.ssh/auth_sock_info/old done fi exit 0