Last active
March 25, 2022 23:23
-
-
Save Ralnoc/e894708bac2ff1083b49 to your computer and use it in GitHub Desktop.
SSH Agent Management Bash Command
This file contains hidden or 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
## SSH-Agent Manager | |
# Command list: | |
# sagent new - Generate new ssh-agent instance | |
# sagent [list] - List all ssh-agent instances along with keys they have loaded | |
# sagent <number> - Select ssh-agent instance based on number shown in sagent list | |
# sagent add </path/to/keyfile> - Add ssh key to currently selected ssh-agent | |
# sagent purgedead - Remove files related to dead ssh-agent instances | |
# Find existing sockets and store them in file_list | |
function sshagent_findsockets { | |
file_list=() | |
while IFS= read -r file ; do | |
file_list=("${file_list[@]}" "$file") | |
done < <(find /tmp -uid $(id -u) -type s -name agent.\* -printf "%T@ %Tc %p\n" 2>/dev/null | sort -n | awk '{print $9}') | |
} | |
# Print details of each socket in file_list | |
function sshagent_socketdetails { | |
for agentsocket in ${!file_list[@]} ; do | |
sshagent_testsocket ${file_list[$agentsocket]} | |
if [ "$?" -eq "0" ]; then | |
export SSH_AUTH_SOCK=${file_list[$agentsocket]} | |
if [ "$SSH_AUTH_SOCK" == "$TMP_SSH_AUTH_SOCK" ]; then | |
printf " *%s) SSH Agent [%s]: \n" "$agentsocket" "${file_list[$agentsocket]}" | |
else | |
printf " %s) SSH Agent [%s]: \n" "$agentsocket" "${file_list[$agentsocket]}" | |
fi | |
while read -r ssh_key ; do | |
printf " %s\n" "$ssh_key" | |
done <<< $(ssh-add -L | cut -d' ' -f 1,3) | |
unset SSH_AUTH_SOCK | |
unset ssh_key | |
fi | |
done | |
} | |
# Delete dead sockets in file_list | |
function sshagent_purgesockets { | |
for agentsocket in ${!file_list[@]} ; do | |
sshagent_testsocket ${file_list[$agentsocket]} | |
if [ "$?" -eq "4" ]; then | |
rm -rf ${file_list[$agentsocket]} | |
printf "Deleted Agent [%s]: \n" "${file_list[$agentsocket]}" | |
fi | |
done | |
} | |
# Select socket from file_list or explicitly | |
function sshagent_selectsocket { | |
IS_NUM='^[0-9]+$' | |
if [ ! -x "$(which ssh-add)" ] ; then | |
echo "ssh-add is not available; agent testing aborted" | |
return 1 | |
fi | |
if [[ "$1" =~ $IS_NUM ]] ; then | |
export SSH_AUTH_SOCK=${file_list[$1]} | |
else | |
if [ X"$1" != X ] ; then | |
export SSH_AUTH_SOCK=$1 | |
fi | |
fi | |
if [ X"$SSH_AUTH_SOCK" = X ] ; then | |
return 2 | |
fi | |
if [ -S $SSH_AUTH_SOCK ] ; then | |
ssh-add -l > /dev/null | |
if [ $? = 2 ] ; then | |
echo "Socket $SSH_AUTH_SOCK is dead! Deleting!" | |
rm -f $SSH_AUTH_SOCK | |
unset SSH_AGENT_PID | |
unset SSH_AUTH_SOCK | |
return 4 | |
else | |
echo "ssh-agent $SSH_AUTH_SOCK" | |
return 0 | |
fi | |
else | |
echo "$SSH_AUTH_SOCK is not a socket!" | |
rm -f $SSH_AUTH_SOCK | |
unset SSH_AGENT_PID | |
unset SSH_AUTH_SOCK | |
return 3 | |
fi | |
} | |
# Test if actually an active socket | |
function sshagent_testsocket { | |
if [ ! -x "$(which ssh-add)" ] ; then | |
echo "ssh-add is not available; agent testing aborted" | |
return 1 | |
fi | |
if [ X"$1" != X ] ; then | |
export SSH_AUTH_SOCK=$1 | |
fi | |
if [ X"$SSH_AUTH_SOCK" = X ] ; then | |
return 2 | |
fi | |
if [ -S $SSH_AUTH_SOCK ] ; then | |
ssh-add -l > /dev/null | |
if [ $? = 2 ] ; then | |
echo "Socket $SSH_AUTH_SOCK is dead!" | |
unset SSH_AGENT_PID | |
unset SSH_AUTH_SOCK | |
return 4 | |
else | |
unset SSH_AGENT_PID | |
unset SSH_AUTH_SOCK | |
return 0 | |
fi | |
else | |
echo "$SSH_AUTH_SOCK is not a socket!" | |
unset SSH_AGENT_PID | |
unset SSH_AUTH_SOCK | |
return 3 | |
fi | |
} | |
# Primary command function | |
function sshagent_init { | |
IS_NUM='^[0-9]+$' | |
SSH_CHOICE=$1 | |
TMP_SSH_AUTH_SOCK=$SSH_AUTH_SOCK | |
unset SSH_AUTH_SOCK | |
# ssh agent sockets can be attached to a ssh daemon process or an | |
# ssh-agent process. | |
AGENTFOUND=0 | |
if [ "${SSH_CHOICE,,}" = "new" ]; then | |
exec ssh-agent $SHELL | |
unset TMP_SSH_AUTH_SOCK | |
return | |
fi | |
if [ "${SSH_CHOICE,,}" = "add" ]; then | |
if [ -n "$TMP_SSH_AUTH_SOCK" ]; then export SSH_AUTH_SOCK=$TMP_SSH_AUTH_SOCK ; fi | |
ssh-add $2 | |
return | |
fi | |
if [ "${SSH_CHOICE,,}" = "list" ]; then | |
sshagent_findsockets | |
echo "SSH Agents Found:" | |
sshagent_socketdetails | |
if [ -n "$TMP_SSH_AUTH_SOCK" ]; then export SSH_AUTH_SOCK=$TMP_SSH_AUTH_SOCK ; fi | |
return | |
fi | |
if [ "${SSH_CHOICE,,}" = "purgedead" ]; then | |
sshagent_findsockets | |
sshagent_purgesockets | |
return | |
fi | |
if [[ -n "${SSH_CHOICE}" ]] && ! [[ "${SSH_CHOICE}" =~ $IS_NUM ]]; then | |
echo "ERROR: ${SSH_CHOICE} is not a valid option." | |
return | |
fi | |
if [[ -z "${SSH_CHOICE}" ]]; then | |
sshagent_findsockets | |
echo "SSH Agents Found:" | |
sshagent_socketdetails | |
if [ -n "$TMP_SSH_AUTH_SOCK" ]; then export SSH_AUTH_SOCK=$TMP_SSH_AUTH_SOCK ; fi | |
return | |
fi | |
# If there is no agent in the environment, search /tmp for | |
# possible agents to reuse before starting a fresh ssh-agent | |
# process. | |
if [ $AGENTFOUND = 0 ] ; then | |
sshagent_findsockets | |
if [ -n "${SSH_CHOICE}" ]; then | |
if sshagent_selectsocket ${SSH_CHOICE} ; then AGENTFOUND=1 ; fi | |
fi | |
if [ -z "${SSH_CHOICE}" ] ; then | |
echo "SSH Agents Found:" | |
sshagent_socketdetails | |
fi | |
fi | |
if [ -n "$TMP_SSH_AUTH_SOCK" ] && [ -z "$SSH_AUTH_SOCK" ]; then | |
export SSH_AUTH_SOCK=$TMP_SSH_AUTH_SOCK | |
fi | |
# Finally, show what keys are currently in the agent | |
if [ $AGENTFOUND = 1 ] ; then | |
ssh-add -L | cut -d' ' -f 1,3 | |
else | |
echo "No SSH agent selected." | |
fi | |
# Clean up | |
unset agentsocket | |
unset file_list | |
unset TMP_SSH_AUTH_SOCK | |
unset AGENTFOUND | |
unset SSH_CHOICE | |
} | |
alias sagent="sshagent_init" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment