aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLdBeth2023-08-13 18:31:47 +0200
committerMichael Albinus2023-08-13 18:31:47 +0200
commit14cd2a058e56d63bab08190826559521083a7d05 (patch)
tree0c0205ece2e3083be905983bcc246056a6e3d133
parentba914bd9c953c3157390a5b535e042ae42cd0179 (diff)
downloademacs-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.el106
-rw-r--r--test/lisp/auth-source-tests.el20
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