Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # FILE: ~/.bash_profile
- export SUCCESS=0
- export FAILURE=1
- #
- # ... SNIP ...
- #
- have() { type "$@" > /dev/null 2>&1; }
- eval2() { echo "$*"; eval "$@"; }
- : ${UNAME_S:=$(uname -s)}
- #
- # ... SNIP ...
- #
- DIALOG_MENU_TAGS="123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
- # dialog_menutag
- #
- # Obtain the menutag chosen by the user from the most recently displayed
- # dialog(1) menu and clean up any temporary files.
- #
- dialog_menutag()
- {
- local tmpfile="$DIALOG_TMPDIR/dialog.menu.$$"
- [ -f "$tmpfile" ] || return $FAILURE
- cat "$tmpfile" 2> /dev/null
- quietly rm -f "$tmpfile"
- return $SUCCESS
- }
- # dialog_menutag2help $tag_chosen $tag1 $item1 $help1 \
- # $tag2 $item2 $help2
- #
- # To use the `--menu' option of dialog(1) with the `--item-help' option, you
- # must pass an ordered list of tag/item/help triplets on the command-line. When
- # the user selects a menu option the tag for that item is printed to stderr.
- #
- # This function allows you to dereference the tag chosen by the user back into
- # the help associated with said tag (item is discarded/ignored).
- #
- # Pass the tag chosen by the user as the first argument, followed by the
- # ordered list of tag/item/help triplets (HINT: use the same tag/item/help list
- # as was passed to dialog(1) for consistency).
- #
- # If the tag cannot be found, NULL is returned.
- #
- dialog_menutag2help()
- {
- local tag="$1" tagn help
- shift 1 # tag
- while [ $# -gt 0 ]; do
- tagn="$1"
- help="$3"
- shift 3 # tagn/item/help
- if [ "$tag" = "$tagn" ]; then
- echo "$help"
- return $SUCCESS
- fi
- done
- return $FAILURE
- }
- #
- # ... SNIP ...
- #
- # ssh-agent-dup [-a]
- #
- # Provide a menu list of open/active ssh-agent sessions available to the
- # currently authenticated user. Allows the user to quickly duplicate access
- # to an ssh-agent launched in another interactive session on the same machine.
- #
- # This allows you to, for example:
- #
- # (in shell session A)
- # ssh-agent
- # (in shell session B)
- # ssh-agent-dup
- # (now both sessions A and B can use the same agent)
- #
- # No menu is presented if only a single agent session is available (the open
- # session is duplicated for the active shell session). If more than one agent
- # is available, a menu is presented. The menu choice becomes the active agent.
- #
- # If `-a' is present, list all readable agent sockets, not just those owned by
- # the currently logged-in user.
- #
- ssh-agent-dup()
- {
- local function=ssh-agent-dup
- local list_all=
- local sockets=
- local owner socket socket_owner pid current_user
- local OPTIND=1 OPTARG flag
- while getopts "a" flag; do
- case "$flag" in
- a) list_all=1 ;;
- \?|*)
- echo "$function [-a]" >&2
- return $FAILURE
- esac
- done
- shift $(( $OPTIND - 1 ))
- case "$UNAME_S" in
- *BSD) owner="-f%Su" ;;
- *) owner="-c%U"
- esac
- current_user=$( id -nu )
- for socket in /tmp/ssh-*/agent.[0-9]*; do
- # Must exist as a socket
- [ -S "$socket" ] || continue
- # Must end in numbers-only (after trailing dot)
- pid="${socket##*.}"
- [ "$pid" -a "$pid" = "${pid#*[!0-9]}" ] || continue
- pid=$(( $pid + 1 )) # socket num is one below agent PID
- # Must be a running pid and an ssh-agent
- kill -0 $pid || continue
- [ "$( ps -p $pid -o ucomm= )" = "ssh-agent" ] || continue
- # Must be owned by the current user unless `-a' is used
- # NB: When `-a' is used, the socket still has to be readable
- if [ ! "$list_all" ]; then
- socket_owner=$( stat $owner "$socket" ) || continue
- [ "$socket_owner" = "$current_user" ] || continue
- fi
- sockets="$sockets $socket"
- done
- sockets="${sockets# }"
- if [ ! "$sockets" ]; then
- echo "$function: No agent sockets available" >&2
- return $FAILURE
- fi
- if [ "${sockets}" = "${sockets%% *}" ]; then
- # Only one socket found
- eval2 export SSH_AUTH_SOCK="$sockets" \
- SSH_AGENT_PID="$(( ${sockets##*.} + 1 ))"
- return $SUCCESS
- fi
- #
- # If we don't have dialog(1), just print the possible values
- #
- if ! have dialog; then
- local prefix="%3s"
- local fmt="$prefix %-16s %3s %s\n"
- local num=0 choice
- local identities nloaded
- sockets=$( ls -tr $sockets ) # ascending order by age
- printf "$fmt" "" USER CNT COMMAND
- for socket in $sockets; do
- num=$(( $num + 1 ))
- pid=$(( ${socket##*.} + 1 ))
- nkeys=0
- identities=$( SSH_AUTH_SOCK="$socket" ssh-add -l ) &&
- nkeys=$( echo "$identities" | grep -c . )
- printf "$fmt" $num: "$( ps -p $pid -o user= )" \
- "$nkeys" "$( ps -p $pid -o command= )"
- printf "$prefix export %s %s\n" "" \
- SSH_AUTH_SOCK="$socket" \
- SSH_AGENT_PID="$pid"
- done
- echo
- read -p "Select a number [$num]: " choice
- : ${choice:=$num}
- case "$choice" in
- ""|*[!0-9]*)
- echo "$function: Invalid choice [$choice]" >&2
- return $FAILURE ;;
- esac
- if [ $choice -gt $num -o $choice -lt 1 ]; then
- echo "$function: Choice out of range [$choice]" >&2
- return $FAILURE
- fi
- set -- $sockets
- eval socket=\"\${$choice}\"
- pid=$(( ${socket##*.} + 1 ))
- eval2 export SSH_AUTH_SOCK="$socket" SSH_AGENT_PID="$pid"
- else
- local menu_list=
- sockets=$( ls -1t $sockets ) # descending order by age
- menu_list=$(
- echo "$sockets" | awk -v tags="$DIALOG_MENU_TAGS" '
- {
- if (++tagn > length(tags)) exit
- if (!match($0, /[[:digit:]]+$/)) next
- pid = substr($0, RSTART, RLENGTH) + 1
- cmd = sprintf("ps -p %u -o user=", pid)
- cmd | getline user
- close(cmd)
- cmd = sprintf("ps -p %u -o command=", pid)
- cmd | getline command
- close(cmd)
- nloaded = 0
- cmd = "SSH_AUTH_SOCK=" $0 " ssh-add -l"
- while (cmd | getline identity) {
- nloaded += identity ~ /^[[:digit:]]/
- }
- close(cmd)
- printf "'\'%s\'\ \'%s\'\ \'%s\''\n",
- substr(tags, tagn, 1),
- sprintf("pid %u %s+%u %s",
- pid, user, nloaded, command),
- sprintf("export %s %s",
- "SSH_AUTH_SOCK=" $0,
- "SSH_AGENT_PID=" pid)
- }'
- )
- eval dialog \
- --clear --title "'$function'" --item-help \
- --menu "'Pick an ssh-agent to duplicate:'" 17 55 9 \
- $menu_list \
- 2> "$DIALOG_TMPDIR/dialog.menu.$$"
- local retval=$?
- # Return if "Cancel" was chosen (-1) or ESC was pressed (255)
- [ $retval -eq $SUCCESS ] || return $retval
- local tag="$( dialog_menutag )"
- eval2 $( eval dialog_menutag2help "'$tag'" $menu_list )
- fi
- # Attempt to dump fingerprints from newly configured agent
- ssh-add -l
- }
- #
- # ... SNIP ...
- #
- # ssh-agent [ssh-agent options]
- #
- # Override ``ssh-agent'' to call a function (you can always call the real
- # binary by executing /usr/bin/ssh-agent) that launches a background ssh-agent
- # that times-out in 30 minutes.
- #
- # Will evaluate the output of /usr/bin/ssh-agent (the real ssh-agent) called
- # with either a known-secure set of arguments (if none are provided) or the
- # unmodified arguments to this functin.
- #
- # Purpose is to prevent memorizing something like ``eval "$( ssh-agent ... )"''
- # but instead simply ``ssh-agent [...]''.
- #
- # This allows you to, for example:
- #
- # ssh-agent
- # : do some ssh-add
- # : do some commits
- # ssh-agent -k
- # : or instead of ``ssh-agent -k'' just wait 30m for it to die
- #
- ssh-agent()
- {
- [ $# -gt 0 ] || set -- -t 1800
- eval "$( /usr/bin/ssh-agent "$@" )"
- }
- #
- # ... SNIP ...
- #
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement