[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Modifying Emacs to use the Mac OS X Keychain Services

From: Ted Zlatanov
Subject: Re: Modifying Emacs to use the Mac OS X Keychain Services
Date: Sun, 29 Jul 2012 18:05:22 -0400
User-agent: Gnus/5.130006 (Ma Gnus v0.6) Emacs/24.1.50 (gnu/linux)

On Fri, 27 Jul 2012 11:20:17 -0400 Dave Abrahams <address@hidden> wrote: 

DA> Did anything come of this?  I am really tired of typing in my GPG key
DA> every time I start Gnus.  I'd be more than happy to have a solution that
DA> just used /usr/bin/security to look up the password; I don't need more
DA> security than that.

DA> I looked a bit at the "secrets" API but could understand it easily
DA> enough to code something up.  I just want Emacs to run

DA>    /usr/bin/security --find-internet-password -gs <hostname> <username>

DA> to get the password for my mail server.

I don't think I knew about this utility :)  Thanks!

I haven't heard from Ben Key (CC-ed on this post) in a year so I figured
it's simpler to implement this myself.  I've pushed something into the
Gnus repo, which you can test.  It doesn't support creation or deletion,
but searching works.

The fundamental problem was that internet (I've spelled it with a
lowercase 'i' to be consistent with Apple) and generic keychains behave
very differently.  So I chose to make the user decide which one he
wants; the following are valid entries in `auth-sources':

#+begin_src lisp
(auth-source-backend-parse 'macos-keychain-internet)
(auth-source-backend-parse 'macos-keychain-generic)
(auth-source-backend-parse "macos-keychain-internet:/path/here.keychain")
(auth-source-backend-parse "macos-keychain-generic:/path/here.keychain")
(auth-source-backend-parse '(:source (:macos-keychain-internet default)))
(auth-source-backend-parse '(:source (:macos-keychain-generic 

...and here you can see the very first entry in each of your default
internet and generic keychains:

#+begin_src lisp
(let ((auth-sources '(macos-keychain-internet))) (auth-source-search :max 1))
(let ((auth-sources '(macos-keychain-generic))) (auth-source-search :max 1))

The hardest part was mapping internet and generic keychains into the
common auth-source format for searching and for providing results.  For
searching, I chose to map them as explained in the docstring of
`auth-source-macos-keychain-search', using the various /usr/bin/security
parameters.  For results, the logic is simple enough to show here:

#+begin_src lisp
(defun auth-source-macos-keychain-result-append (result generic k v)
  (push v result)
  (setq k (cond
           ((equal k "acct") "user")
           ;; for generic keychains, creator is host, service is port
           ((and generic (equal k "crtr")) "host")
           ((and generic (equal k "svce")) "port")
           ;; for internet keychains, protocol is port, server is host
           ((and (not generic) (equal k "ptcl")) "port")
           ((and (not generic) (equal k "srvr")) "host")
           (t k)))

  (push (intern (format ":%s" k)) result))

At most one result is returned, ever.  This is due to the way
/usr/bin/security works.  If I dump the whole keychain, the user would
get a thousand popup dialogs.

It should be pretty trivial to use the native keychain calls on Mac OS X
within this framework.  Ben, if you're still interested, please let us

I am far from expert on Mac OS X; this worked for me and I hope it works
for you.  Patches welcome to improve it.


reply via email to

[Prev in Thread] Current Thread [Next in Thread]