aboutsummaryrefslogtreecommitdiffstats
path: root/lisp
diff options
context:
space:
mode:
authorDamien Cassou2017-11-09 10:40:19 +0100
committerNicolas Petton2018-06-05 15:51:14 +0200
commitb43ed61ef985e01975b90d7e0ec3cac70d0afefa (patch)
treebc4414f8595bc6ddee73cb4822062fb34b8a9cef /lisp
parenta52661b58bc9cffa13cb5f0749cdb3a4c24fbf74 (diff)
downloademacs-b43ed61ef985e01975b90d7e0ec3cac70d0afefa.tar.gz
emacs-b43ed61ef985e01975b90d7e0ec3cac70d0afefa.zip
auth-source-pass: Take care of matching hosts when port is provided
* lisp/auth-source-pass.el (auth-source-pass--find-match): Add PORT parameter and reorganize code by extracting `find-match-unambiguous'. (auth-source-pass--find-match-unambiguous): New function. (auth-source-pass--build-result): Fix the call to `find-match'. (auth-source-pass--hostname, auth-source-pass--hostname-with-user, auth-source-pass--user): Remove functions. * test/lisp/auth-source-pass-tests.el: Fix the calls to `find-match'. (auth-source-pass-find-host-without-port) Add corresponding test.
Diffstat (limited to 'lisp')
-rw-r--r--lisp/auth-source-pass.el68
1 files changed, 30 insertions, 38 deletions
diff --git a/lisp/auth-source-pass.el b/lisp/auth-source-pass.el
index 1785ca32550..96aefc8dd7e 100644
--- a/lisp/auth-source-pass.el
+++ b/lisp/auth-source-pass.el
@@ -52,7 +52,7 @@ See `auth-source-search' for details on SPEC."
52 52
53(defun auth-source-pass--build-result (host port user) 53(defun auth-source-pass--build-result (host port user)
54 "Build auth-source-pass entry matching HOST, PORT and USER." 54 "Build auth-source-pass entry matching HOST, PORT and USER."
55 (let ((entry (auth-source-pass--find-match host user))) 55 (let ((entry (auth-source-pass--find-match host user port)))
56 (when entry 56 (when entry
57 (let ((retval (list 57 (let ((retval (list
58 :host host 58 :host host
@@ -139,26 +139,6 @@ CONTENTS is the contents of a password-store formatted file."
139 (mapconcat #'identity (cdr pair) ":"))))) 139 (mapconcat #'identity (cdr pair) ":")))))
140 (cdr lines))))) 140 (cdr lines)))))
141 141
142(defun auth-source-pass--hostname (host)
143 "Extract hostname from HOST."
144 (let ((url (url-generic-parse-url host)))
145 (or (url-host url) host)))
146
147(defun auth-source-pass--hostname-with-user (host)
148 "Extract hostname and user from HOST."
149 (let* ((url (url-generic-parse-url host))
150 (user (url-user url))
151 (hostname (url-host url)))
152 (cond
153 ((and user hostname) (format "%s@%s" user hostname))
154 (hostname hostname)
155 (t host))))
156
157(defun auth-source-pass--user (host)
158 "Extract user from HOST and return it.
159Return nil if no match was found."
160 (url-user (url-generic-parse-url host)))
161
162(defun auth-source-pass--do-debug (&rest msg) 142(defun auth-source-pass--do-debug (&rest msg)
163 "Call `auth-source-do-debug` with MSG and a prefix." 143 "Call `auth-source-do-debug` with MSG and a prefix."
164 (apply #'auth-source-do-debug 144 (apply #'auth-source-do-debug
@@ -230,27 +210,39 @@ matching USER."
230 (car matching-entries)) 210 (car matching-entries))
231 (_ (auth-source-pass--select-one-entry matching-entries user))))) 211 (_ (auth-source-pass--select-one-entry matching-entries user)))))
232 212
233(defun auth-source-pass--find-match (host user) 213(defun auth-source-pass--find-match (host user port)
234 "Return a password-store entry name matching HOST and USER. 214 "Return a password-store entry name matching HOST, USER and PORT.
235If many matches are found, return the first one. If no match is 215
236found, return nil." 216Disambiguate between user provided inside HOST (e.g., user@server.com) and
217inside USER by giving priority to USER. Same for PORT."
218 (let* ((url (url-generic-parse-url (if (string-match-p ".*://" host)
219 host
220 (format "https://%s" host)))))
221 (auth-source-pass--find-match-unambiguous
222 (or (url-host url) host)
223 (or user (url-user url))
224 ;; url-port returns 443 (because of the https:// above) by default
225 (or port (number-to-string (url-port url))))))
226
227(defun auth-source-pass--find-match-unambiguous (hostname user port)
228 "Return a password-store entry name matching HOSTNAME, USER and PORT.
229If many matches are found, return the first one. If no match is found,
230return nil.
231
232HOSTNAME should not contain any username or port number."
237 (or 233 (or
238 (if (auth-source-pass--user host) 234 (and user port (auth-source-pass--find-one-by-entry-name (format "%s@%s:%s" user hostname port) user))
239 ;; if HOST contains a user (e.g., "user@host.com"), <HOST> 235 (and user (auth-source-pass--find-one-by-entry-name (format "%s@%s" user hostname) user))
240 (auth-source-pass--find-one-by-entry-name (auth-source-pass--hostname-with-user host) user) 236 (and port (auth-source-pass--find-one-by-entry-name (format "%s:%s" hostname port) nil))
241 ;; otherwise, if USER is provided, search for <USER>@<HOST> 237 (auth-source-pass--find-one-by-entry-name hostname user)
242 (when (stringp user)
243 (auth-source-pass--find-one-by-entry-name (concat user "@" (auth-source-pass--hostname host)) user)))
244 ;; if that didn't work, search for HOST without its user component, if any
245 (auth-source-pass--find-one-by-entry-name (auth-source-pass--hostname host) user)
246 ;; if that didn't work, search for HOST with user extracted from it
247 (auth-source-pass--find-one-by-entry-name
248 (auth-source-pass--hostname host) (auth-source-pass--user host))
249 ;; if that didn't work, remove subdomain: foo.bar.com -> bar.com 238 ;; if that didn't work, remove subdomain: foo.bar.com -> bar.com
250 (let ((components (split-string host "\\."))) 239 (let ((components (split-string hostname "\\.")))
251 (when (= (length components) 3) 240 (when (= (length components) 3)
252 ;; start from scratch 241 ;; start from scratch
253 (auth-source-pass--find-match (mapconcat 'identity (cdr components) ".") user))))) 242 (auth-source-pass--find-match-unambiguous
243 (mapconcat 'identity (cdr components) ".")
244 user
245 port)))))
254 246
255(provide 'auth-source-pass) 247(provide 'auth-source-pass)
256;;; auth-source-pass.el ends here 248;;; auth-source-pass.el ends here