nmh-workers
[Top] [All Lists]

[Nmh-workers] Big patch: Add XOAUTH2 support for SMTP and POP

2014-12-05 20:08:35
Background: 
http://googleappsdeveloper.blogspot.com/2014/10/updates-on-authentication-for-gmail.html

Unless you use two-step verification and create an app password
(https://support.google.com/accounts/answer/185833), or are
willing to enable these risky logins, you can no longer use nmh
with Gmail for POP and SMTP.

I guess this is a bit of a distraction from the current focus on
improving MIME support and such, and I'm not helping with that
at all.  Sorry; this is a blocker for me, that's not :(

Disclosure: I work at Google in the same group that works on
Google OAuth support, though I work on other parts of the
identity infrastructure.  Aside from the only hinted at POP
support, this is all thoroughly covered by public documentation;
I don't have any insider OAuth knowledge.

OAuth is a very modern thing to bring into nmh.  You need to be
able to make HTTP requests and process JSON resonses.  Luckily,
curl is nearly ubiquitous.  This does not seem to be the case for
any JSON library, nor does there even seem to be one obvious
implementation to go with.  I picked jsmn because it has a
liberal license and is tiny (only 312 lines).

I enable a libcurl dependency only when configured with
--with-oauth which is off by default.  But practically no one has
jsmn installed, so I'm suggesting we include it directly.
I think that might be unprecedented for nmh.  But I hope it's not
too controversial.

I updated the man pages for send, inc, and msgchk, but it's
probably not good enough; suggestions welcome.

Quick overview:

% mhlogin -oauth gmail
Load the following URL in your browser and authorize nmh to access Gmail:

https://accounts.google.com/o/oauth2/auth?response_type=code&client_id=91584523849-8lv9kgp1rvp8ahta6fa4b125tn2polcg.apps.googleusercontent.com&redirect_uri=urn%3Aietf%3Awg%3Aoauth%3A2.0%3Aoob&scope=https%3A%2F%2Fmail.google.com%2F

Enter the authorization code: 
4/SJ-cCVsTYuRYXg9hHnzNJ8lRQbhNx-h8N6K0hr8ZM1o.8mV7QHLMqOAbEnp6UAPFm0Hc5WAelAI

% msgchk
eric(_dot_)gillespie(_at_)gmail(_dot_)com has 1 message (5661 bytes) on 
localhost

% grep oauth .mh_profile
send: -server smtp.gmail.com -tls -oauth gmail -user 
eric(_dot_)gillespie(_at_)gmail(_dot_)com
inc: -oauth gmail -host localhost -port 995 -user 
eric(_dot_)gillespie(_at_)gmail(_dot_)com
msgchk: -oauth gmail -host localhost -port 995 -user 
eric(_dot_)gillespie(_at_)gmail(_dot_)com

You have to use inc/msgchk -proxy because Gmail requires TLS.
For future reference: libcurl can handle POP and SMTP with TLS
for us too... :)

Tested with AddressSanitizer:
CFLAGS='-g -fno-omit-frame-pointer -fsanitize=address -static-libasan'

Unresolved issues:

- mhlogin name / flag names

  Naming is hard :).  I picked this on the theory that it's not
  terribly confusing as is, and if there were to be some other
  kind of system users might need to login to, expanding mhlogin
  to have more than just -oauth would make sense.

- Repeating -user for each command is possibly odd.  Maybe put
  -user on mhlogin and save it in the cred file.  Arguably easier
  -for the user this way, arguably not.  Changing it would
  -complicate the code slightly.  I don't really care either way.

- I have a lot of test cases in only a few broadly categorized
  test scripts, and they print descriptions as they go so it's
  easy to see what broke.  This messes up the test suite output.
  Does this make sense, should I change this only to print only
  if some environment variable is set, or should I just break
  these up into one test case per script?  I'd kinda prefer the
  latter, but I don't know if anyone objects to a big pile of
  test scripts in there.

- Owning the Google client credentials.  I took the liberty of
  creating a Google developer project for nmh already.  I'm happy
  to share ownership, or just give it away, or dispose of mine in
  favor of another.  I would suggest that the Google project have
  at least two owners.

Of course, I welcome criticism on all other aspects too:  API,
documentation, organization, whatever.

Thanks!



<Prev in Thread] Current Thread [Next in Thread>