Created
April 16, 2009 09:32
-
-
Save baseonmars/96333 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/sh | |
# AUTHOR: Matt Simerson ([email protected]) | |
# | |
# VERSIONS: | |
# 1.02 - Dec 16, 2007 | |
# - adjusted ps invocation for reliable detection when multiple | |
# - users run ssh-agent on a single system | |
# 1.01 - Oct 9, 2007 | |
# - when cleaning up stale agent, remove stale sock file | |
# 1.0 - July, 2007 | |
# - initial release | |
# | |
# INSTRUCTIONS | |
# 1. Install this script in your ~/.ssh directory as agent.sh | |
# | |
# curl -o .ssh/agent.sh http://www.tnpi.net/computing/mac/agent.sh.txt | |
# chmod 755 .ssh/agent.sh | |
# | |
# 2. Configure it to run when a new terminal window opens | |
# | |
# echo 'source .ssh/agent.sh' >> ~/.bash_profile | |
# | |
# 3. Open new terminal/shell sessions | |
# | |
# 4. Enjoy | |
# | |
# GUI APPLICATIONS | |
# | |
# If you use GUI apps that are ssh-agent aware, you will need to run the | |
# script once and then log out and back in. Then your GUI apps will be | |
# ssh-agent aware. | |
unset _sockfile | |
### begin SSH-AGENT SOCKET NOTES | |
# | |
# Setting _sockfile is an efficiency improvement. Rather than storing the | |
# ssh socket file in /tmp/ssh-XXXXXXXXXX/agent.<ppid> and having to glob | |
# to find it, we can store it in a fixed location so this script can find | |
# it more efficiently. Since all our shell/terminal windows will share the | |
# first ssh-agent process, there is no need for the random location. | |
# | |
# If you decide to alter the location, keep security in mind. You do not want | |
# others to have access to this socket. Your ~/.ssh directory is a great | |
# choice because its default permissions (600) are readable only by you. | |
# | |
# If you wish to keep the default /tmp behavior, simply comment out this | |
# setting | |
# | |
_sockfile="${HOME}/.ssh/agent.sock" | |
# | |
### end SSH-AGENT SOCKET NOTES | |
if [ "$0" != "-bash" ]; | |
then | |
echo ' | |
OOPS! Did you mean to source this script? Try this: | |
source ~/.ssh/agent.sh | |
' | |
fi | |
main() | |
{ | |
# There are three states we check for | |
# | |
# 1. ssh-agent not running. | |
# | |
# a) clean up any stale environment variables | |
# b) launch the agent | |
# c) configure our environment to use it | |
# d) add our ssh keys | |
# | |
# 2. ssh-agent is running, but our environment variables are outdated. | |
# (SSH_AGENT_PID is set but different than running ssh-agent pid) | |
# | |
# a) clean up the stale environment variables | |
# b) configure our environment to use the existing ssh-agent | |
# | |
# 3. ssh-agent is running | |
# | |
# a) configure our environment to use the existing ssh-agent | |
set_agent_pid | |
if [ -z "${_agent_pid}" ]; # 1 | |
then | |
cleanup_stale_agent | |
start_ssh_agent | |
elif [ ! -z $SSH_AGENT_PID ] && [ "${_agent_pid}" -ne $SSH_AGENT_PID ]; | |
then # 2 | |
cleanup_stale_agent | |
discover_ssh_agent $_agent_pid | |
else # 3 | |
discover_ssh_agent $_agent_pid | |
fi | |
} | |
set_agent_pid() | |
{ | |
# this is expensive but reliable | |
#echo "checking for ssh-agent process" | |
_agent_pid=`ps uwwxU $USER | grep ssh-agent | grep -v grep | awk '{ print $2 }' | tail -n1` | |
} | |
discover_ssh_agent() | |
{ | |
if [ -z "$1" ]; | |
then | |
set_agent_pid | |
fi | |
if [ ! -z $_agent_pid ]; | |
then | |
echo "ssh agent for $USER found at pid ${_agent_pid}." | |
export SSH_AGENT_PID=${_agent_pid} | |
# if _sockfile is not defined we must figure it out | |
if [ -z "$_sockfile" ] || [ ! -e "$_sockfile" ]; | |
then | |
_sock_pid=`echo "${_agent_pid} - 1" | bc` | |
_sockfile=`/bin/ls /tmp/ssh-*/agent.${_sock_pid}` | |
fi | |
if [ ! -e "$_sockfile" ]; | |
then | |
echo "ERROR: could not determine ssh-agent socket file for pid: $SSH_AGENT_PID" | |
else | |
export SSH_AUTH_SOCK=$_sockfile | |
# make sure the Mac Login environment is configured | |
if [ "`uname`" == "Darwin" ]; then | |
setup_plist | |
fi | |
fi | |
fi | |
} | |
start_ssh_agent() | |
{ | |
if [ -z "$_sockfile" ]; | |
then | |
echo "starting ssh-agent" | |
ssh-agent > /dev/null | |
else | |
echo "starting ssh-agent -a $_sockfile" | |
ssh-agent -a $_sockfile > /dev/null | |
fi | |
discover_ssh_agent | |
if [ ! -z $SSH_AUTH_SOCK ]; | |
then | |
# this will prompt the user to authenticate their ssh key(s) | |
echo "adding ssh key(s) to agent" | |
ssh-add | |
fi | |
} | |
setup_plist() | |
{ | |
_envdir="$HOME/.MacOSX" | |
if [ ! -d $_envdir ]; then | |
mkdir $_envdir | |
fi | |
_plist="$_envdir/environment.plist" | |
if [ -e $_plist ]; | |
then | |
if [ ! `grep "$_sockfile" $_plist` ]; then | |
set +o noclobber | |
write_plist # check and update | |
fi | |
else | |
write_plist # create | |
fi | |
} | |
write_plist() | |
{ | |
echo "updating Mac OS X environment" | |
( | |
cat <<EOXML | |
<?xml version="1.0" encoding="UTF-8"?> | |
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" | |
"http://www.apple.com/DTDs/PropertyList-1.0.dtd"> | |
<plist version="1.0"> | |
<dict> | |
<key>SSH_AUTH_SOCK</key> | |
<string>${_sockfile}</string> | |
</dict> | |
</plist> | |
EOXML | |
) > $_plist | |
} | |
cleanup_stale_agent() | |
{ | |
echo "cleaning up stale ssh agent" | |
# check the environment variable SSH_AGENT_PID as it could be set | |
# despite the ssh-agent process being missing. | |
if [ ! -z $SSH_AGENT_PID ]; | |
then | |
#echo "cleaning up stale ssh agent pid: $SSH_AGENT_PID" | |
unset SSH_AGENT_PID | |
fi | |
if [ ! -z $SSH_AUTH_SOCK ]; | |
then | |
unset SSH_AUTH_SOCK | |
fi | |
if [ -e $_sockfile ]; | |
then | |
echo "cleaning up stale agent socket file: $_sockfile" | |
unlink $_sockfile | |
fi | |
} | |
print_agent_info() { | |
echo "pid : $_agent_pid" | |
echo "sock: $_sockfile" | |
} | |
main | |
#print_agent_info |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment