diff options
| author | Damien Cassou | 2017-11-09 10:40:19 +0100 |
|---|---|---|
| committer | Nicolas Petton | 2018-06-05 15:51:14 +0200 |
| commit | b43ed61ef985e01975b90d7e0ec3cac70d0afefa (patch) | |
| tree | bc4414f8595bc6ddee73cb4822062fb34b8a9cef /lisp/auth-source-pass.el | |
| parent | a52661b58bc9cffa13cb5f0749cdb3a4c24fbf74 (diff) | |
| download | emacs-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/auth-source-pass.el')
| -rw-r--r-- | lisp/auth-source-pass.el | 68 |
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. | ||
| 159 | Return 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. |
| 235 | If many matches are found, return the first one. If no match is | 215 | |
| 236 | found, return nil." | 216 | Disambiguate between user provided inside HOST (e.g., user@server.com) and |
| 217 | inside 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. | ||
| 229 | If many matches are found, return the first one. If no match is found, | ||
| 230 | return nil. | ||
| 231 | |||
| 232 | HOSTNAME 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 |