adding OAuth

Ken Hornstein kenh at cmf.nrl.navy.mil
Thu May 31 23:12:37 EDT 2018


>	I relay my mail through gmail.  sendmail uses cyrus sasl to
>authenticate.  gmail uses OAuth authentication.  If I could add OAuth
>to cyrus I could disable gmail requiring that I 'allow less secure
>apps'.  I think the authentication I use for my own messages is good
>enough; I worry about the vulnerability to which 'allow less secure
>apps' exposes my account from attack by others.  

So, I'm one of the people who work on nmh (the successor to good old
MH, and yes, it's still alive and kicking!), and our latest release
supports OAuth for POP and SMTP.  I didn't write the original OAuth
code, but I did do some of the integration work when we refactored our
networking code into a generic layer (nmh also supports Cyrus-SASL for
those protocols).  So I feel I can speak with some reasonable knowledge
on this topic.  But forgive me if I get some details wrong; it's been
a little bit since I looked at this, and a lot of the documentation is
very web-focused, so figuring out the bits that you need is a bit rough.

Adding OAuth support to Cyrus-SASL would be ... a large pain in the ass.
For the following reasons:

- The people who developed the XOAUTH2 SASL mechanism made some ... well,
  I would politely call them "non-optimal design choices".  Specifically,
  if there is a failure in the SASL protocol message exchange you have to
  be prepared to deal with that because you will get back an encoded JSON
  error message, and it wasn't all that clear to me you could do that in
  a generic SASL application because of the message flow (I'd have to look
  at the details again for this one, so if you are interested in more
  detail here let know).  The OAuth2 code in nmh is special-cased; if you
  request the XOAUTH2 mechanism it goes down the XOAUTH2 protocol exchange
  and doesn't call the Cyrus SASL library.

- To support OAuth2 for Gmail requires your project to register with Google
  and obtain a specific key (well, what you get is a "client_id" and a
  "client_secret"); we did that for nmh.  It's not clear to me how that
  would work for Cyrus-SASL; would every application have to register an
  API key?  That means you'd be limited to applications that did that (and
  there would have to be an API extension to pass that key into the library).
  Or would the Cyrus-SASL library get it's own key?  Tht might be better,
  but that presents it's own problems.

- You need some external utility to do the initial authorization; what
  we have is a new program (mhlogin) which will give you a URL to load
  into your web browser; you then login to Gmail, grant nmh access to
  your email, and you get an authorization code which you THEN use to
  get a "grant" in OAuth2 termology, and you need to keep that grant
  around to get a new bearer token (the bearer token is used to generate
  what actually gets sent during the XOAUTH2 SASL exchange).  This gets
  back to a problem I alluded to above; you are granting access to your
  email for specific applications, but if you got a client key for the
  Cyrus-SASL library then you'd be granting access to all applications
  that used the Cyrus-SASL library.  This may or may not be what you want
  (this wouldn't mean every Cyrus-SASL application could instantly
  read your email; you'd still need to get the grant into the application).

- The actual implementation requires you to parse JSON and speak HTTP
  to get a bearer token.  If you are doing a lot of requests you probably
  want to cache the bearer token (it has a limited lifetime); you use the
  grant you saved above to get a fresh bearer token.

Now, none of this is IMPOSSIBLE; I mean, we did it in nmh.  But it's a
lot more heavyweight than you might think.  I realize this is similar
in general scope to how Kerberos works, in that you need an extra
utility to get the Kerberos TGT, you have to talk to other servers to
get the actual tokens you send over the wire, the tokens have a limited
lifetime, etc etc.  But the key difference here is the GSSAPI library
and Kerberos utilities take care of all that for you; all you need to
do as an application programmer is make GSSAPI calls and you get the
necessary info back.  There is not, AFAIK, a comparable library in C
that is designed for this work; everything I've seen was web-focused and
really, I don't think we would have been able to do it if wasn't for the
main developer of the code who happens to work at Google.  So ... given
the current state of the art if you wanted to add that to Cyrus-SASL
you're going to have to write all of that code yourself.

There were objections to special-casing support for XOAUTH2 when the code
was first submitted; I agreed with them at first, but when I dug into it
a bit more I realized what was required and I knew it was not very likely
that OAuth2 would make it into Cyrus-SASL anytime soon.

>	gmail put both messages from this mailing list in my spam
>folder.

I think this is not a Cyrus-SASL issue?

--Ken


More information about the Cyrus-sasl mailing list