From 72c19d0f395e8883c65689c86e79905a34d36586 Mon Sep 17 00:00:00 2001 From: Michael Albinus Date: Mon, 15 Sep 2025 11:43:52 +0200 Subject: [PATCH] Improve check for netrc tokens * doc/misc/auth.texi (Help for users): Mention also "#" inside tokens. * lisp/auth-source.el (auth-source-netrc-create): Better check for token format. * test/lisp/auth-source-tests.el (auth-source-backend-parse-json): New test. (auth-source-test-netrc-create-secret): Extend test. --- doc/misc/auth.texi | 4 ++-- lisp/auth-source.el | 13 +++++++++---- test/lisp/auth-source-tests.el | 17 +++++++++++++++-- 3 files changed, 26 insertions(+), 8 deletions(-) diff --git a/doc/misc/auth.texi b/doc/misc/auth.texi index cc6fc0c3396..1fd232a697e 100644 --- a/doc/misc/auth.texi +++ b/doc/misc/auth.texi @@ -132,8 +132,8 @@ use them automatically, either pass @code{:client-certificate t} to @code{open-network-stream}, or customize @code{network-stream-use-client-certificates} to @code{t}. -You can use spaces inside a password or other token by surrounding the -token with either single or double quotes. +You can use spaces or number signs (@t{"#"}) inside a password or other +token by surrounding the token with either single or double quotes. You can use apostrophes inside a password or other token by surrounding it with double quotes, e.g., @t{"he'llo"}. Similarly you diff --git a/lisp/auth-source.el b/lisp/auth-source.el index 442fe2fc1e3..e7c8f43b7f9 100644 --- a/lisp/auth-source.el +++ b/lisp/auth-source.el @@ -1468,7 +1468,9 @@ See `auth-source-search' for details on SPEC." (when (and (stringp data) (< 0 (length data))) (when (eq r 'secret) - (setq save-function t)) + (setq save-function + (not (and (string-match-p "\"" data) + (string-match-p "'" data))))) ;; this function is not strictly necessary but I think it ;; makes the code clearer -tzz (let ((printer (lambda () @@ -1484,9 +1486,12 @@ See `auth-source-search' for details on SPEC." (secret "password") (port "port") ; redundant but clearer (t (symbol-name r))) - (if (string-match "[\"# ]" data) - (format "%S" data) - data))))) + (cond + ((string-match-p "\"" data) + (format "'%s'" data)) + ((string-match-p "['# ]" data) + (format "%S" data)) + (t data)))))) (setq add (concat add (funcall printer))))))) (when save-function diff --git a/test/lisp/auth-source-tests.el b/test/lisp/auth-source-tests.el index b4bc0f5a7f6..d6845b0af37 100644 --- a/test/lisp/auth-source-tests.el +++ b/test/lisp/auth-source-tests.el @@ -119,6 +119,16 @@ (create-function . auth-source-netrc-create)))) +(ert-deftest auth-source-backend-parse-json () + (auth-source-validate-backend '(:source "foo.json") + '((source . "foo.json") + (type . json) + (search-function . auth-source-json-search) + (create-function + ;; To be implemented: + ;; . auth-source-json-create)))) + . ignore)))) + (ert-deftest auth-source-backend-parse-secrets () (provide 'secrets) ; simulates the presence of the `secrets' package (let ((secrets-enabled t)) @@ -383,7 +393,8 @@ (auth-source-save-behavior t) (auth-source-ignore-non-existing-file t) host auth-info auth-passwd) - (dolist (passwd '("foo" "" nil)) + (dolist (passwd `("foo" "bar baz" "bar'baz" "bar\"baz" + "foo'bar\"baz" "" nil)) ;; Redefine `read-*' in order to avoid interactive input. (cl-letf (((symbol-function 'read-passwd) (lambda (_) passwd)) ((symbol-function 'read-string) @@ -409,7 +420,9 @@ auth-passwd (auth-info-password auth-info)) (with-temp-buffer (insert-file-contents netrc-file) - (if (zerop (length passwd)) + (if (or (zerop (length passwd)) + (and (string-match-p "\"" passwd) + (string-match-p "'" passwd))) (progn (should-not (plist-get auth-info :user)) (should-not (plist-get auth-info :host))