diff options
| author | LdBeth | 2023-08-13 18:31:47 +0200 |
|---|---|---|
| committer | Michael Albinus | 2023-08-13 18:31:47 +0200 |
| commit | 14cd2a058e56d63bab08190826559521083a7d05 (patch) | |
| tree | 0c0205ece2e3083be905983bcc246056a6e3d133 | |
| parent | ba914bd9c953c3157390a5b535e042ae42cd0179 (diff) | |
| download | emacs-14cd2a058e56d63bab08190826559521083a7d05.tar.gz emacs-14cd2a058e56d63bab08190826559521083a7d05.zip | |
Fix auth-source-macos-keychain (bug#64977)
* lisp/auth-source.el (auth-source-macos-keychain-search)
(auth-source-macos-keychain-search-items): Fix handling of user
and port.
* test/lisp/auth-source-tests.el (test-macos-keychain-search): New test.
| -rw-r--r-- | lisp/auth-source.el | 106 | ||||
| -rw-r--r-- | test/lisp/auth-source-tests.el | 20 |
2 files changed, 76 insertions, 50 deletions
diff --git a/lisp/auth-source.el b/lisp/auth-source.el index e51fc02724a..66de763f671 100644 --- a/lisp/auth-source.el +++ b/lisp/auth-source.el | |||
| @@ -1958,20 +1958,23 @@ entries for git.gnus.org: | |||
| 1958 | (hosts (if (and hosts (listp hosts)) hosts `(,hosts))) | 1958 | (hosts (if (and hosts (listp hosts)) hosts `(,hosts))) |
| 1959 | (ports (plist-get spec :port)) | 1959 | (ports (plist-get spec :port)) |
| 1960 | (ports (if (and ports (listp ports)) ports `(,ports))) | 1960 | (ports (if (and ports (listp ports)) ports `(,ports))) |
| 1961 | (users (plist-get spec :user)) | ||
| 1962 | (users (if (and users (listp users)) users `(,users))) | ||
| 1961 | ;; Loop through all combinations of host/port and pass each of these to | 1963 | ;; Loop through all combinations of host/port and pass each of these to |
| 1962 | ;; auth-source-macos-keychain-search-items | 1964 | ;; auth-source-macos-keychain-search-items |
| 1963 | (items (catch 'match | 1965 | (items (catch 'match |
| 1964 | (dolist (host hosts) | 1966 | (dolist (host hosts) |
| 1965 | (dolist (port ports) | 1967 | (dolist (port ports) |
| 1966 | (let* ((port (if port (format "%S" port))) | 1968 | (dolist (user users) |
| 1967 | (items (apply #'auth-source-macos-keychain-search-items | 1969 | (let ((items (apply |
| 1968 | coll | 1970 | #'auth-source-macos-keychain-search-items |
| 1969 | type | 1971 | coll |
| 1970 | max | 1972 | type |
| 1971 | host port | 1973 | max |
| 1972 | search-spec))) | 1974 | host port user |
| 1973 | (when items | 1975 | search-spec))) |
| 1974 | (throw 'match items))))))) | 1976 | (when items |
| 1977 | (throw 'match items)))))))) | ||
| 1975 | 1978 | ||
| 1976 | ;; ensure each item has each key in `returned-keys' | 1979 | ;; ensure each item has each key in `returned-keys' |
| 1977 | (items (mapcar (lambda (plist) | 1980 | (items (mapcar (lambda (plist) |
| @@ -2003,8 +2006,9 @@ entries for git.gnus.org: | |||
| 2003 | collect var)) | 2006 | collect var)) |
| 2004 | 'utf-8))) | 2007 | 'utf-8))) |
| 2005 | 2008 | ||
| 2006 | (cl-defun auth-source-macos-keychain-search-items (coll _type _max host port | 2009 | (cl-defun auth-source-macos-keychain-search-items (coll _type _max |
| 2007 | &key label type user | 2010 | host port user |
| 2011 | &key label type | ||
| 2008 | &allow-other-keys) | 2012 | &allow-other-keys) |
| 2009 | (let* ((keychain-generic (eq type 'macos-keychain-generic)) | 2013 | (let* ((keychain-generic (eq type 'macos-keychain-generic)) |
| 2010 | (args `(,(if keychain-generic | 2014 | (args `(,(if keychain-generic |
| @@ -2022,47 +2026,49 @@ entries for git.gnus.org: | |||
| 2022 | (when port | 2026 | (when port |
| 2023 | (if keychain-generic | 2027 | (if keychain-generic |
| 2024 | (setq args (append args (list "-s" port))) | 2028 | (setq args (append args (list "-s" port))) |
| 2025 | (setq args (append args (list | 2029 | (setq args (append args (if (string-match "[0-9]+" port) |
| 2026 | (if (string-match "[0-9]+" port) "-P" "-r") | 2030 | (list "-P" port) |
| 2027 | port))))) | 2031 | (list "-r" (substring |
| 2032 | (format "%-4s" port) | ||
| 2033 | 0 4))))))) | ||
| 2028 | 2034 | ||
| 2029 | (unless (equal coll "default") | 2035 | (unless (equal coll "default") |
| 2030 | (setq args (append args (list coll)))) | 2036 | (setq args (append args (list coll)))) |
| 2031 | 2037 | ||
| 2032 | (with-temp-buffer | 2038 | (with-temp-buffer |
| 2033 | (apply #'call-process "/usr/bin/security" nil t nil args) | 2039 | (apply #'call-process "/usr/bin/security" nil t nil args) |
| 2034 | (goto-char (point-min)) | 2040 | (goto-char (point-min)) |
| 2035 | (while (not (eobp)) | 2041 | (while (not (eobp)) |
| 2036 | (cond | 2042 | (cond |
| 2037 | ((looking-at "^password: \\(?:0x[0-9A-F]+\\)? *\"\\(.+\\)\"") | 2043 | ((looking-at "^password: \\(?:0x[0-9A-F]+\\)? *\"\\(.+\\)\"") |
| 2038 | (setq ret (auth-source-macos-keychain-result-append | 2044 | (setq ret (auth-source-macos-keychain-result-append |
| 2039 | ret | 2045 | ret |
| 2040 | keychain-generic | 2046 | keychain-generic |
| 2041 | "secret" | 2047 | "secret" |
| 2042 | (let ((v (auth-source--decode-octal-string | 2048 | (let ((v (auth-source--decode-octal-string |
| 2043 | (match-string 1)))) | 2049 | (match-string 1)))) |
| 2044 | (lambda () v))))) | 2050 | (lambda () v))))) |
| 2045 | ;; TODO: check if this is really the label | 2051 | ;; TODO: check if this is really the label |
| 2046 | ;; match 0x00000007 <blob>="AppleID" | 2052 | ;; match 0x00000007 <blob>="AppleID" |
| 2047 | ((looking-at | 2053 | ((looking-at |
| 2048 | "^[ ]+0x00000007 <blob>=\\(?:0x[0-9A-F]+\\)? *\"\\(.+\\)\"") | 2054 | "^[ ]+0x00000007 <blob>=\\(?:0x[0-9A-F]+\\)? *\"\\(.+\\)\"") |
| 2049 | (setq ret (auth-source-macos-keychain-result-append | 2055 | (setq ret (auth-source-macos-keychain-result-append |
| 2050 | ret | 2056 | ret |
| 2051 | keychain-generic | 2057 | keychain-generic |
| 2052 | "label" | 2058 | "label" |
| 2053 | (auth-source--decode-octal-string (match-string 1))))) | 2059 | (auth-source--decode-octal-string (match-string 1))))) |
| 2054 | ;; match "crtr"<uint32>="aapl" | 2060 | ;; match "crtr"<uint32>="aapl" |
| 2055 | ;; match "svce"<blob>="AppleID" | 2061 | ;; match "svce"<blob>="AppleID" |
| 2056 | ((looking-at | 2062 | ((looking-at |
| 2057 | "^[ ]+\"\\([a-z]+\\)\"[^=]+=\\(?:0x[0-9A-F]+\\)? *\"\\(.+\\)\"") | 2063 | "^[ ]+\"\\([a-z]+\\)\"[^=]+=\\(?:0x[0-9A-F]+\\)? *\"\\(.+\\)\"") |
| 2058 | (setq ret (auth-source-macos-keychain-result-append | 2064 | (setq ret (auth-source-macos-keychain-result-append |
| 2059 | ret | 2065 | ret |
| 2060 | keychain-generic | 2066 | keychain-generic |
| 2061 | (auth-source--decode-octal-string (match-string 1)) | 2067 | (auth-source--decode-octal-string (match-string 1)) |
| 2062 | (auth-source--decode-octal-string (match-string 2)))))) | 2068 | (auth-source--decode-octal-string (match-string 2)))))) |
| 2063 | (forward-line))) | 2069 | (forward-line))) |
| 2064 | ;; return `ret' iff it has the :secret key | 2070 | ;; return `ret' iff it has the :secret key |
| 2065 | (and (plist-get ret :secret) (list ret)))) | 2071 | (and (plist-get ret :secret) (list ret)))) |
| 2066 | 2072 | ||
| 2067 | (defun auth-source-macos-keychain-result-append (result generic k v) | 2073 | (defun auth-source-macos-keychain-result-append (result generic k v) |
| 2068 | (push v result) | 2074 | (push v result) |
diff --git a/test/lisp/auth-source-tests.el b/test/lisp/auth-source-tests.el index ef915e5fc5b..ab1a437b303 100644 --- a/test/lisp/auth-source-tests.el +++ b/test/lisp/auth-source-tests.el | |||
| @@ -435,5 +435,25 @@ machine c1 port c2 user c3 password c4\n" | |||
| 435 | '((("machine" . "XM") ("login" . "XL") ("password" . "XP")) | 435 | '((("machine" . "XM") ("login" . "XL") ("password" . "XP")) |
| 436 | (("machine" . "YM") ("login" . "YL") ("password" . "YP"))))))) | 436 | (("machine" . "YM") ("login" . "YL") ("password" . "YP"))))))) |
| 437 | 437 | ||
| 438 | (ert-deftest test-macos-keychain-search () | ||
| 439 | "Test if the constructed command line arglist is correct." | ||
| 440 | (let ((auth-sources '(macos-keychain-internet macos-keychain-generic))) | ||
| 441 | ;; Redefine `call-process' to check command line arguments. | ||
| 442 | (cl-letf (((symbol-function 'call-process) | ||
| 443 | (lambda (_program _infile _destination _display | ||
| 444 | &rest args) | ||
| 445 | ;; Arguments must be all strings | ||
| 446 | (should (cl-every #'stringp args)) | ||
| 447 | ;; Argument number should be even | ||
| 448 | (should (cl-evenp (length args))) | ||
| 449 | (should (cond ((string= (car args) "find-internet-password") | ||
| 450 | (let ((protocol (cl-member "-r" args :test #'string=))) | ||
| 451 | (if protocol | ||
| 452 | (= 4 (length (cadr protocol))) | ||
| 453 | t))) | ||
| 454 | ((string= (car args) "find-generic-password") | ||
| 455 | t)))))) | ||
| 456 | (auth-source-search :user '("a" "b") :host '("example.org") :port '("irc" "ftp" "https"))))) | ||
| 457 | |||
| 438 | (provide 'auth-source-tests) | 458 | (provide 'auth-source-tests) |
| 439 | ;;; auth-source-tests.el ends here | 459 | ;;; auth-source-tests.el ends here |