From 56d0dc57f470e9ee2b53d749279be213f3581f88 Mon Sep 17 00:00:00 2001 From: Stephen Larew Date: Sat, 22 Jul 2017 12:07:16 -0400 Subject: [PATCH 1/3] ssh: remove persistent socket; use macOS Keychain * Remove persistent SSH auth socket. * Make ps|grep more robust and POSIX compliant. * On macOS, use `-A` switch to "add identities to the agent using any passphrase stored in the user's keychain." --- modules/ssh/init.zsh | 26 +++++++++++--------------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/modules/ssh/init.zsh b/modules/ssh/init.zsh index 08edce5772..b8943b9f41 100644 --- a/modules/ssh/init.zsh +++ b/modules/ssh/init.zsh @@ -16,26 +16,19 @@ _ssh_dir="$HOME/.ssh" # Set the path to the environment file if not set by another module. _ssh_agent_env="${_ssh_agent_env:-${TMPDIR:-/tmp}/ssh-agent.env.$UID}" -# Set the path to the persistent authentication socket. -_ssh_agent_sock="${TMPDIR:-/tmp}/ssh-agent.sock.$UID" - -# Start ssh-agent if not started. +# If a socket exists at SSH_AUTH_SOCK, assume ssh-agent is already running and +# skip starting it. if [[ ! -S "$SSH_AUTH_SOCK" ]]; then - # Export environment variables. + # Try to grab previously exported environment variables. source "$_ssh_agent_env" 2> /dev/null - # Start ssh-agent if not started. - if ! ps -U "$LOGNAME" -o pid,ucomm | grep -q -- "${SSH_AGENT_PID:--1} ssh-agent"; then + # Do not start ssh-agent if the PID from the last start of ssh-agent exists and + # corresponds to a running ssh-agent under the current user. + if ! ps -U "$LOGNAME" -o pid,comm | grep -E -q -e "^[[:blank:]]*${SSH_AGENT_PID:--1}[[:blank:]].*ssh-agent$"; then eval "$(ssh-agent | sed '/^echo /d' | tee "$_ssh_agent_env")" fi fi -# Create a persistent SSH authentication socket. -if [[ -S "$SSH_AUTH_SOCK" && "$SSH_AUTH_SOCK" != "$_ssh_agent_sock" ]]; then - ln -sf "$SSH_AUTH_SOCK" "$_ssh_agent_sock" - export SSH_AUTH_SOCK="$_ssh_agent_sock" -fi - # Load identities. if ssh-add -l 2>&1 | grep -q 'The agent has no identities'; then zstyle -a ':prezto:module:ssh:load' identities '_ssh_identities' @@ -50,11 +43,14 @@ if ssh-add -l 2>&1 | grep -q 'The agent has no identities'; then # program specified by SSH_ASKPASS and open an X11 window to read the # passphrase. if [[ -n "$DISPLAY" && -x "$SSH_ASKPASS" ]]; then - ssh-add ${_ssh_identities:+$_ssh_dir/${^_ssh_identities[@]}} < /dev/null 2> /dev/null + ssh-add "${_ssh_identities:+$_ssh_dir/${^_ssh_identities[@]}}" < /dev/null 2> /dev/null + elif [[ "$OSTYPE" == darwin* ]]; then + # macOS: `ssh-add -A` will load all identities defined in Keychain + ssh-add -A 2> /dev/null else ssh-add ${_ssh_identities:+$_ssh_dir/${^_ssh_identities[@]}} 2> /dev/null fi fi # Clean up. -unset _ssh_{dir,identities} _ssh_agent_{env,sock} +unset _ssh_{dir,identities,agent_env} From 3f8dace325fca0b5e35f17fea5fa4e8daf4ce182 Mon Sep 17 00:00:00 2001 From: Stephen Larew Date: Fri, 6 Oct 2017 11:01:06 -0400 Subject: [PATCH 2/3] Load :prezto:module:ssh:load identities on macOS If the user defines identities in `:prezto:module:ssh:load`, always try to load them, even on macOS. On macOS, also try to load Keychain managed identities. (Assume if a user adds an identity to Keychain then the use would want those identities automatically loaded.) --- modules/ssh/init.zsh | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/modules/ssh/init.zsh b/modules/ssh/init.zsh index b8943b9f41..051bfe4020 100644 --- a/modules/ssh/init.zsh +++ b/modules/ssh/init.zsh @@ -44,12 +44,16 @@ if ssh-add -l 2>&1 | grep -q 'The agent has no identities'; then # passphrase. if [[ -n "$DISPLAY" && -x "$SSH_ASKPASS" ]]; then ssh-add "${_ssh_identities:+$_ssh_dir/${^_ssh_identities[@]}}" < /dev/null 2> /dev/null - elif [[ "$OSTYPE" == darwin* ]]; then - # macOS: `ssh-add -A` will load all identities defined in Keychain - ssh-add -A 2> /dev/null else ssh-add ${_ssh_identities:+$_ssh_dir/${^_ssh_identities[@]}} 2> /dev/null fi + + if [[ "$OSTYPE" == darwin* ]]; then + # macOS: `ssh-add -A` will load all identities defined in Keychain. + # Assume `/usr/bin/ssh-add` is Apple customized version that understands + # the `-A` switch. + /usr/bin/ssh-add -A + fi fi # Clean up. From 84ad1f36df90b4820bc923915f79a74a762d41db Mon Sep 17 00:00:00 2001 From: Stephen Larew Date: Sat, 22 Jul 2017 12:15:51 -0400 Subject: [PATCH 3/3] ssh: add trust checks before sourcing env vars --- modules/ssh/init.zsh | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/modules/ssh/init.zsh b/modules/ssh/init.zsh index 051bfe4020..55209da65c 100644 --- a/modules/ssh/init.zsh +++ b/modules/ssh/init.zsh @@ -16,6 +16,19 @@ _ssh_dir="$HOME/.ssh" # Set the path to the environment file if not set by another module. _ssh_agent_env="${_ssh_agent_env:-${TMPDIR:-/tmp}/ssh-agent.env.$UID}" +# Due to the predictability of the env file, check the env file exists and is +# owned by current EUID before trusting it. +if [[ -f "$_ssh_agent_env" && ! -O "$_ssh_agent_env" ]]; then + cat 1>&2 <<-EOF + ERROR: Cannot trust the SSH agent environment variables persistence + file because it is owned by another user. + The ssh-agent will not be started. + $_ssh_agent_env + EOF + unset _ssh_{dir,agent_env} + return 1 +fi + # If a socket exists at SSH_AUTH_SOCK, assume ssh-agent is already running and # skip starting it. if [[ ! -S "$SSH_AUTH_SOCK" ]]; then