summaryrefslogtreecommitdiff
path: root/tramp-auto-auth.el
blob: 48c2893462fbb6cf59f8c1e6f6c7700cae329561 (about) (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
;;; tramp-auto-auth.el --- TRAMP automatic authentication library

;; Copyright (C) 2019 Bruno Félix Rezende Ribeiro <oitofelix@gnu.org>

;; Author: Bruno Félix Rezende Ribeiro <oitofelix@gnu.org>
;; Maintainer: Bruno Félix Rezende Ribeiro <oitofelix@gnu.org>
;; Keywords: comm, processes
;; Package: tramp-auto-auth

;; Package-Requires: (tramp)

;; This program is free software: you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.

;; This program is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;; GNU General Public License for more details.

;; You should have received a copy of the GNU General Public License
;; along with this program.  If not, see <https://www.gnu.org/licenses/>.

;;; Commentary:

;; This library provides ‘tramp-auto-auth-mode’: a global minor mode
;; whose purpose is to automatically feed TRAMP sub-processes with
;; passwords for paths matching regexps.  This is useful in situations
;; where interactive user input is not desirable or feasible.  For
;; instance, in sub-nets with large number of hosts or whose hosts
;; have dynamic IPs assigned to them.  In those cases it’s not
;; practical to query passwords using the ‘auth-source’ library, since
;; this would require each host to be listed explicitly and immutably
;; in a Netrc file.  Another scenario where this mode is useful are
;; non-interactive Emacs sessions (like those used for batch
;; processing or by evaluating ‘:async’ Org Babel source blocks) in
;; which it’s impossible for the user to answer a password-asking
;; prompt.
;;
;; To make use of the automatic authentication feature, the variable
;; ‘tramp-auto-auth-alist’ must be customized to hold the path regexps
;; and their respective passwords, and then ‘tramp-auto-auth-mode’
;; must be enabled.  For example:
;;
;; (require ’tramp-auto-auth)
;; (add-to-list 'tramp-auto-auth-alist '("root@10\\.0\\." . "$r00tPasWD!"))
;; (tramp-auto-auth-mode)

;;; Code:


(require 'tramp)


(defcustom tramp-auto-auth-alist
  nil
  "Alist of TRAMP paths regexps and their respective passwords.
Each element has the form (PATH-REGEXP . PASSWORD), where
PATH-REGEXP is a regular expression to be matched against TRAMP
paths and PASSWORD is the respective password to be sent to the
TRAMP’s sub-process in case a match does occur."
  :type '(alist
	  :key-type
	  (string :tag "Path Regexp"
		  :help-echo "Regexp which matches the desired TRAMP path")
	  :value-type
	  (string :tag "Password"
		  :help-echo "Password for the TRAMP path resource"))
  :group 'tramp
  :require 'tramp-auto-auth)

;;;###autoload
(define-minor-mode tramp-auto-auth-mode
  "Toggle Tramp-Auto-Auth global minor mode on or off.
With a prefix argument ARG, enable Tramp-Auto-Auth mode if ARG is
positive, and disable it otherwise.  If called from Lisp, enable
the mode if ARG is omitted or nil, and toggle it if ARG is ‘toggle’.

When enabled ‘tramp-auto-auth-alist’ is used to automatically
authenticate to remote servers."
  :group 'tramp
  :global t
  :require 'tramp-auto-auth
  (if tramp-auto-auth-mode
      (progn
	(advice-add #'tramp-action-password :around
		    (lambda (tramp-action-password proc vec)
		      (pcase (or (car (last vec)) "")
			((and (app (lambda (expval)
				     (assoc-default expval tramp-auto-auth-alist
						    #'string-match-p))
				   passwd)
			      (guard passwd))
			 (process-send-string proc (concat passwd tramp-local-end-of-line)))
			(_ (funcall tramp-action-password proc vec))))
		    '((name . tramp-auto-auth-mode)))
	(advice-add #'tramp-action-yesno :around
		    (lambda (tramp-action-yesno proc vec)
		      (pcase (or (car (last vec)) "")
			((pred (lambda (expval)
				 (assoc-default expval tramp-auto-auth-alist
						#'string-match-p)))
			 (tramp-send-string vec (concat "yes" tramp-local-end-of-line)))
			(_ (funcall tramp-action-yesno proc vec))))
		    '((name . tramp-auto-auth-mode))))
    (advice-remove #'tramp-action-password 'tramp-auto-auth-mode)
    (advice-remove #'tramp-action-yesno 'tramp-auto-auth-mode)))


(provide 'tramp-auto-auth)

;;; tramp-auto-auth.el ends here