Skip to content

Instantly share code, notes, and snippets.

@algal
Created February 20, 2020 01:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save algal/ceeb64692f96343f6e4f2f1dfe14d566 to your computer and use it in GitHub Desktop.
Save algal/ceeb64692f96343f6e4f2f1dfe14d566 to your computer and use it in GitHub Desktop.
Within emacs, fix ssh agent forwarding, which breaks in long-running tmux sessions
;; The purpose of this file is to define the function `fixssh-in-tmux`,
;; which attempts to fix ssh agent forwarding when it breaks within
;; a tmux session
;; from https://github.com/magnars/s.el/blob/master/s.el
(defun fixssh--s-match (regexp s &optional start)
"When the given expression matches the string, this function returns a list
of the whole matching string and a string for each matched subexpressions.
If it did not match the returned value is an empty list (nil).
When START is non-nil the search will start at that index."
(declare (side-effect-free t))
(save-match-data
(if (string-match regexp s start)
(let ((match-data-list (match-data))
result)
(while match-data-list
(let* ((beg (car match-data-list))
(end (cadr match-data-list))
(subs (if (and beg end) (substring s beg end) nil)))
(setq result (cons subs result))
(setq match-data-list
(cddr match-data-list))))
(nreverse result)))))
(defun fixssh--find-value (key string)
"Finds value for key in string, where string is output from running tmux show-env -s"
(let ((v (fixssh--s-match (concat key "=\"\\(.*\\)\";") string)))
(when v
(cadr v))))
(defun fixssh-in-tmux ()
"Attempts to fix broken SSH agent forwarding within tmux sessions
Does this running <tmux show-env -s> on the shell, parsing the output to
find the values for SSH_AUTH_SOCK and SSH_CONNECTION, and then
calling `setenv` to update those values within emacs."
(interactive)
(let* ((out (generate-new-buffer "tmuxoutput"))
(err (generate-new-buffer "err"))
(exit-code (shell-command "tmux show-env -s" out err))
(outString (with-current-buffer out
(buffer-string)))
(SSH_AUTH_SOCK (fixssh--find-value "SSH_AUTH_SOCK" outString))
(SSH_CONNECTION (fixssh--find-value "SSH_CONNECTION" outString)))
(when (and SSH_AUTH_SOCK SSH_CONNECTION (= exit-code 0)
(setenv "SSH_CONNECTION" SSH_CONNECTION)
(setenv "SSH_AUTH_SOCK" SSH_AUTH_SOCK)))))
;; TODO: enhance the above not to print output into the output buffer, by using make-process not shell-command
;; TODO; report success or failure in *Messages*
(provide 'fixssh-tmux)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment