Subject: Re: [kitten] SASL OAuth: Next Steps

From: Tim Showalter <[email-masked]>
Date: Wed, 04 Jan 2012 15:44:02 -0800

On 12/20/11 1:36 AM, Tschofenig, Hannes (NSN - FI/Espoo) wrote:
> I would need your feedback on the following important design decision.
> Currently, the OAuth messages are encoded as HTTP headers and Leif had
> suggested to instead use a JSON encoding.

> ---------------
>     GET / HTTP/1.1
>     Host: imap.example.com
>     Authorization: BEARER "vF9dft4qmTc2Nvb3RlckBhbHRhdmlzdGEuY29tCg=="
> ---------------
>
> A possible JSON based representation would be:
> ---------------
>     {"token-type":" BEARER",
>      "token":" vF9dft4qmTc2Nvb3RlckBhbHRhdmlzdGEuY29tCg=="}
> ---------------
> In my made-up example I define two attributes: a token container and a
> token type attribute. The accessed resource is most likely in the
> protected token itself and is additionally carried in the underlying
> transport mechanism and therefore not needed again.

I much prefer to leverage the HTTP headers as the format is already 
defined and additional fields map naturally into the SASL profile.  But 
if we're going down that route, I would suggest that the JSON fields be 
mapped identically to the header fields, like this:

{"authorization":["BEARER" "vF9dft4qmTc2Nvb3RlckBhbHRhdmlzdGEuY29tCg=="]}

The "user" and "host" arguments are omitted from your JSON examples, but 
are helpful for discovery cases, like the IMAP server that is speaking 
to unconfigured clients, where the authentication credentials can come 
from multiple "realms" depending on the user involved.  In your JSON 
notation, the equivalent thing might be

{"user":"[email-masked]",
  "host":"imap.example.com",
  "authorization":{"token-type":"BEARER"
                   "token":"........."}}

Anyway, I still like just putting an HTTP thing in there.  The parser 
isn't that hard to write, and it means one fewer mapping in the world. 
It's not as pretty, but I think it's much less work to specify it, and 
to maintain the links between the specs.

I'm afraid that I have not followed discussions on discovery.  I would 
prefer to not make SASL any more different from HTTP OAuth 2 than is 
required to get the job done.  If we can steal others' discovery work, 
great!

Tim

---

From: Chris Newman <[email-masked]>
Date: Wed, 04 Jan 2012 17:55:22 -0800

We attempted to use HTTP syntax for the DIGEST-MD5 SASL mechanism. I 
believe it was one of the reasons that mechanism was a failure. While 
there's nothing apparently wrong with HTTP headers as normally used, the 
legal syntactic variations for semantically identical headers are 
unbounded. Not only is white-space variable, but line folding can get 
complex, especially when combined with 2047 encoding. Also, charsets are a 
mess (iso8859-1 or UTF-8 or RFC 2047?). And then there's the hidden 
side-effects of the legacy ABNF "#" operator used by HTTP syntax.

Having a SASL parser call out to a header parser would be poor security 
design, because every line of code is an additional potential security 
vulnerability (especially prior to authentication) and a lot of code is 
needed for a 100% correct header parser. So I think it's actually important 
for a SASL mechanism to not accept arbitrary header syntax.

It's probably easier to specify a constrained JSON syntax than a 
constrained subset of header syntax (disallowing all the unnecessary syntax 
variations so a strict parser is very simple), but either of those options 
would address the syntax problems encountered by the DIGEST-MD5 SASL 
mechanism.

I concur with Tim's point that if we do a JSON syntax it ought to be 
algorithmically mapped from HTTP header fields.

		- Chris

--On January 4, 2012 15:44:02 -0800 Tim Showalter <[email-masked]> 
wrote:

> are helpful for discovery cases, like the IMAP server that is speaking to
> unconfigured clients, where the authentication credentials can come from
> multiple "realms" depending on the user involved.  In your JSON notation,
> the equivalent thing might be
>
> It's not as pretty, but I think it's much less work to specify it, and to
> maintain the links between the specs.
>
> _______________________________________________
> Kitten mailing list
> [email-masked]
> https://www.ietf.org/mailman/listinfo/kitten
>

---

From: Russ Allbery <[email-masked]>
Date: Wed, 04 Jan 2012 18:34:11 -0800

Chris Newman <[email-masked]> writes:

> complex, especially when combined with 2047 encoding. Also, charsets are
> a mess (iso8859-1 or UTF-8 or RFC 2047?). And then there's the hidden

> needed for a 100% correct header parser. So I think it's actually
> important for a SASL mechanism to not accept arbitrary header syntax.

Based on my experience writing netnews implementations, which use RFC 5322
header field syntax very akin to the HTTP header field syntax, I
completely concur with Chris's reaction.  The header field syntax is
surprisingly complex, particularly in the presence of encoding and
character set issues, and most implementors do not implement it properly.

-- 
Russ Allbery ([email-masked])             <http://www.eyrie.org/~eagle/>

---

From: Tim Showalter <[email-masked]>
Date: Thu, 05 Jan 2012 13:38:03 -0800

On 1/4/12 6:34 PM, Russ Allbery wrote:
> Chris Newman<[email-masked]>  writes:

I'm really sorry to hear that -- I suspect you're right, and I don't 
like it.  I think trying to constrain JSON and define the mappings is 
going to be a lot of work.

Is there a simple way to specify a general mapping?  Or are we going to 
have to do this on a per-header basis?

Tim

---

From: William Mills <[email-masked]>
Date: Thu, 5 Jan 2012 16:01:24 -0800 (PST)

Yeah, I really hate this.

There's stuff in the MAC token spec for example that requires knowing the URL path, fragments, hostname, etc., and so we have to include every element form HTTP that might be required for any OAuth (HTTP based itself) authorization scheme.  This means we have to write an entire mapping grammar for an entire HTTP payload into JSON.

While I agree that HTTP is non-trivial to parse, I don't think it's compelling enough for me to like the change to JSON because there are enough HTTP parsing libraries out there that an implementer should not have to do their own, they should pull one in.
As I said before, designing this in a vacuum HTTP is far down the list, but I think in light of the fact that we're bridging from something that *is* HTTP it is less complex overall to stay consistent.

-bill

________________________________
 From: Tim Showalter <[email-masked]>
To: Russ Allbery <[email-masked]> 
Cc: "[email-masked]" <[email-masked]> 
Sent: Thursday, January 5, 2012 1:38 PM
Subject: Re: [kitten] SASL OAuth: Next Steps
 
> character set issues, and most implementors do not implement it properly.

I'm really sorry to hear that -- I suspect you're right, and I don't like it.  I think trying to constrain JSON and define the mappings is going to be a lot of work.

Is there a simple way to specify a general mapping?  Or are we going to have to do this on a per-header basis?

Tim

---

From: William Mills <[email-masked]>
Date: Mon, 23 Jan 2012 23:10:00 -0800 (PST)

I've been thinking about this quite a bit, and Tim's rebuke to me privately that I really should think about JSON seriously before dismissing the idea because HTTP really is harder to parse than I think it is struck home.

I'm still stuck on the fact that I think the HTTP we have to parse in the client for the mechanism to work is all OAuth 2 protocol 
or defined in the mechanims (discovery) so it's more limited.  On the server side it's very limited, only enough to figure out the discovery.  So I don't think the HTTP here is that scary. The actual HTTP we have to parse for the mechanism to work on the server side is mimimal, and well defined.  Am I wrong?

SO.... I'm trying to figure out how this would work and what we'd need to do in order to make JSON work instead of HTTP as the authentication message format.  My assumptions are:

-    We're passing the Auth header in to a library, the SASL mechanism itself doesn't need to parse it.

We need to support right now for the profiles I know about:

-    The user name and host name for discovery
-    The port number for things like MAC authentication
-    the Authorization header payload
-    discovery information for return to the client

It's possible we'll also need to pass in:

-    The HTTP POST payload for profiles that require it (though I was assuming GET only initially)
-    Something else I'm forgetting about... or for extension flexibility?

In the end I'm presuming we're passing all the real HTTP into a library that will understand it anyway (which is how my initial implementation is working) so we don't need to dive down into the header and POST body payload in the JSON. If this is right then the JSON doesn't look that hard, but then again if what I have above is correct then we're not talking about a general use HTTP parser either.

The OAuth 1.0a library I was playing with for this consumes and gives back the entire Auth header, but I don't know if that design pattern is common.

Where do we go from here?

-bill

________________________________
 From: William Mills <[email-masked]>
To: Tim Showalter <[email-masked]>; Russ Allbery <[email-masked]> 
Cc: "[email-masked]" <[email-masked]> 
Sent: Thursday, January 5, 2012 4:01 PM
Subject: Re: [kitten] SASL OAuth: Next Steps

-bill

On 1/4/12 6:34 PM, Russ Allbery wrote:
> character set issues, and most
 implementors do not implement it properly.

Tim