Re: bug#58985: 29.0.50; Have auth-source-pass behave more like other back ends

Akib Azmain Turja <[email protected]>
Newsgroups gmane.emacs.erc.general
Message-ID <[email protected]>
"J.P." <[email protected]> writes:

>>> +    (if (eq auth-source-pass-extra-query-keywords 'test)
>>> +        (reverse rv)
>>
>> The value `test' is not documented.  Is it used in tests?  If it is, I
>> think an internal variable would be better.
>
> I got rid of the `test' stuff completely, so this function now always
> wraps secrets.

That looks good.

>
>
> From 8870cb62be1ad3ac5b9e5553e52a7f6ed7533c2f Mon Sep 17 00:00:00 2001
> From: "F. Jason Park" <[email protected]>
> Date: Tue, 1 Nov 2022 22:46:24 -0700
> Subject: [PATCH 1/2] [POC] Make auth-source-pass behave more like other
>  backends
>
> * lisp/auth-source-pass.el (auth-source-pass-extra-query-keywords): Add
> new option to bring search behavior more in line with other backends.
> (auth-source-pass-search): Add new keyword params `max' and `require'
> and consider new option `auth-source-pass-extra-query-keywords' for
> dispatch.
> (auth-source-pass--match-regexp, auth-source-pass--retrieve-parsed,
> auth-source-pass--match-parts): Add supporting variable and helpers.
> (auth-source-pass--build-result-many,
> auth-source-pass--find-match-many): Add "-many" variants for existing
> workhorse functions.
> * test/lisp/auth-source-pass-tests.el
> (auth-source-pass-extra-query-keywords--wild-port-miss-netrc,
> auth-source-pass-extra-query-keywords--wild-port-miss,
> auth-source-pass-extra-query-keywords--wild-port-hit-netrc,
> auth-source-pass-extra-query-keywords--wild-port-hit,
> auth-source-pass-extra-query-keywords--wild-port-req-miss-netrc,
> auth-source-pass-extra-query-keywords--wild-port-req-miss,
> auth-source-pass-extra-query-keywords--netrc-akib,
> auth-source-pass-extra-query-keywords--akib,
> auth-source-pass-extra-query-keywords--netrc-host,
> auth-source-pass-extra-query-keywords--host,
> auth-source-pass-extra-query-keywords--baseline,
> auth-source-pass-extra-query-keywords--port-type,
> auth-source-pass-extra-query-keywords--hosts-first): Add juxtaposed
> netrc and extra-query-keywords pairs to demo optional extra-compliant
> behavior.
> * doc/misc/auth.texi: Add option
> `auth-source-pass-extra-query-keywords' to auth-source-pass section.
> * etc/NEWS: Mention `auth-source-pass-extra-query-keywords' in Emacs
> 29.1 package changes section.  Bug#58985.
> ---
>  doc/misc/auth.texi                  |  11 ++
>  etc/NEWS                            |   8 ++
>  lisp/auth-source-pass.el            | 105 +++++++++++++++-
>  test/lisp/auth-source-pass-tests.el | 184 ++++++++++++++++++++++++++++
>  4 files changed, 307 insertions(+), 1 deletion(-)
>

[...]

> +(defun auth-source-pass--build-result-many (hosts ports users require max)
> +  "Return multiple `auth-source-pass--build-result' values."
> +  (unless (listp hosts) (setq hosts (list hosts)))
> +  (unless (listp users) (setq users (list users)))
> +  (unless (listp ports) (setq ports (list ports)))
> +  (let* ((auth-source-pass--match-regexp (auth-source-pass--match-regexp
> +                                          auth-source-pass-port-separator))
> +         (rv (auth-source-pass--find-match-many hosts users ports
> +                                                require (or max 1))))
> +    (when auth-source-debug
> +      (auth-source-pass--do-debug "final result: %S" rv))
> +    (let (out)
> +      (dolist (e rv out)
> +        (when-let* ((s (plist-get e :secret)) ; s not captured by closure
> +                    (v (auth-source--obfuscate s)))
> +          (setf (plist-get e :secret)
> +                (lambda () (auth-source--deobfuscate v))))

Why the closure doesn't capture "s"?  For me, the following code
captures "s" (obviously with lexical binding): (just let-wrapped version
of your code)

--8<---------------cut here---------------start------------->8---
(let ((e '(:secret "topsecret")))
  (when-let* ((s (plist-get e :secret)) ; s not captured by closure
              (v (auth-source--obfuscate s)))
    (setf (plist-get e :secret)
          (lambda () (auth-source--deobfuscate v))))
  e)
;; => (:secret
;;     (closure
;;         ((p #1)
;;          (v . "XIcHKKIKtavKgK8J6zXP1w==-N/XAaAOqAtGcCzKGKX71og==")
;;          (s . "topsecret") ;; LEAKED!!!
;;          (e :secret #1)
;;          t)
;;         nil
;;       (auth-source--deobfuscate v)))
--8<---------------cut here---------------end--------------->8---

> +        (push e out)))))

[...]

> +(defun auth-source-pass--retrieve-parsed (seen path port-number-p)
> +  (when-let ((m (string-match auth-source-pass--match-regexp path)))

Why do you let-bound "m"?  I can't find any use of it in the body.

> +    (puthash path
> +             (list :host (or (match-string 10 path) (match-string 11 path))
> +                   :user (or (match-string 20 path) (match-string 21 path))
> +                   :port (and-let* ((p (or (match-string 30 path)
> +                                           (match-string 31 path)))
> +                                    (n (string-to-number p)))
> +                           (if (or (zerop n) (not port-number-p))
> +                               (format "%s" p)
> +                             n)))
> +             seen)))

[...]

> +(defun auth-source-pass--find-match-many (hosts users ports require max)
> +  "Return plists for valid combinations of HOSTS, USERS, PORTS.
> +Each plist contains, at the very least, a host and a secret."
> +  (let ((seen (make-hash-table :test #'equal))
> +        (entries (auth-source-pass-entries))
> +        out)
> +    (catch 'done
> +      (dolist (host hosts out)
> +        (pcase-let ((`(,_ ,u ,p) (auth-source-pass--disambiguate host)))
> +          (unless (or (not (equal "443" p)) (string-prefix-p "https://" host))
> +            (setq p nil))
> +          (dolist (user (or users (list u)))
> +            (dolist (port (or ports (list p)))
> +              (dolist (e entries)
> +                (when-let*
> +                    ((m (or (gethash e seen) (auth-source-pass--retrieve-parsed
> +                                              seen e (integerp port))))
> +                     ((equal host (plist-get m :host)))
> +                     ((auth-source-pass--match-parts m :port port require))
> +                     ((auth-source-pass--match-parts m :user user require))
> +                     (parsed (auth-source-pass-parse-entry e))
> +                     ;; For now, ignore body-content pairs, if any,
> +                     ;; from `auth-source-pass--parse-data'.
> +                     (secret (or (auth-source-pass--get-attr 'secret parsed)
> +                                 (not (memq :secret require)))))
> +                  (push
> +                   `( :host ,host ; prefer user-provided :host over h
> +                      ,@(and-let* ((u (plist-get m :user))) (list :user u))
> +                      ,@(and-let* ((p (plist-get m :port))) (list :port p))
> +                      ,@(and secret (not (eq secret t)) (list :secret secret)))
> +                   out)
> +                  (when (or (zerop (cl-decf max))
> +                            (null (setq entries (remove e entries))))

Remove will create a lot of garbage, e.g. (let ((x '(1 2 3 4 5)))
(eq (remove 6 x) x)) and (let ((x '(1 2 3 4 5))) (eq (remove 1 x)
(cdr x))) both returns nil.

If you think delete is OK, go ahead and use it.  If you think remove is
better, keep it.  Do whatever you think right.

> +                    (throw 'done out)))))))))))
> +

[...]

-- 
Akib Azmain Turja, GPG key: 70018CE5819F17A3BBA666AFE74F0EFA922AE7F5
Fediverse: [email protected]
Codeberg: akib
emailselfdefense.fsf.org | "Nothing can be secure without encryption."
signature.asc (application/pgp-signature, 832 B)
-----BEGIN PGP SIGNATURE-----

iQIzBAEBCAAdFiEEyVTKmrtL6kNBe3FRVTX89U2IYWsFAmNuYCIACgkQVTX89U2I
YWs9KBAAlrXAXpWRUi15waWQG0opGBOPpCiluhKzn7RzYAYhV3T6AIHhIFpBFT20
SlPLDfcyhLcGPyBRSDxxCEA2BtLztkCJGV9KNSRZXky0y/zVYU9NE/NYc0uOZevN
vNHAQZH6Kspds2EIy0QinS7gOpo2ct++77/Ns3k8R4fejL8J2dB3Rddx7yCE4i+j
BX+aOFzUrlNq5V0AgGVD22uIjZUoK+vGPEJxZBVD5+YOocKFXPGTvdGlJzh0VPNb
x1jkoxEs+0t5jzTbS6l+C3SzYLL3puVIgIZp07hGtj55ErRrn/ODAG7NaWUKM90s
BASutyCkibtUhENWP5ze91aLbYaE4qvnTnTGI8+hIfVKj5Im51GwDLW64KB2IEcz
8nqKnFKEpWHMjQFOpA/Kvd0446FZaIDh4M6+VzzbGgyejvXJTCpd3tZUU0NtLoVj
Jvm2Ylg2ZSIgRo8UN8f4tI/S0UokwUeXo2RfTYIrz8YwufLxyx/yejHb2hX4VkTE
RxbkcZMH3aPtw2qN9lfgK7NA31Y4mb74ZSsdLFLbRxq5d8hsxdw2IKjx/sRGeYUZ
o3/kC9MXuUIoi2tmRjjIkGC1y/z32msqmtyOMySu0A7YjtODIQgaMZxBVZ7YQ2Qe
QtU9r8woXU/npOzBUq1rgdZ3JGnNoahGEhcgmXtMmxZvQUF6aCw=
=RBav
-----END PGP SIGNATURE-----
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.