Subject: [kitten] OpenID SASL interop server available

From: Simon Josefsson <[email-masked]>
Date: Wed, 28 Mar 2012 21:10:40 +0200

Hello,

Version 1.7.2 of GNU SASL (announcement in [1]) supports the OPENID20
mechanism and contains a example server which is running on
"interop.josefsson.org" port 2000 using the SMTP protocol.

The server accepts any OpenID URLs and will happily redirect you to its
IdP and accept its authentication decision.  Real servers would probably
have some pre-filtering of acceptable OpenID URLs before proceeding with
the redirect (i.e., the URL must match some identity in the database of
authorized users).  There are hints on how to test the server here:

https://lists.gnu.org/archive/html/help-gsasl/2012-03/msg00004.html

In the post you can see a step-by-step example of a succesful OpenID
authenticated login to interop.josefsson.org.

What is unusual about this mechanism compared to all other SASL
mechanisms I have implemented is that it is variable-roundtrip.  It can
complete successfully after the second roundtrip (i.e., openid url,
redirect url, dummy '=' response) or after the third roundtrip (i.e.,
openid url, redirect url, dummy '=' response, sreg, empty response).
This caused some complexity in my implementation, but not significant.

The document is a bit terse with examples, and there may be room for
different interpretation of the SREG vs non-SREG cases, and also when
the authentication fails.  To get other people's feedback with the hope
of improving interoperability, I wanted to give examples of the variants
I could think of.  (The output below is actually from my self-tests.)

Running successful authentication without SREG:

S: `' (0) GSASL_NEEDS_MORE
C: `biwsaHR0cDovL3VzZXIuZXhhbXBsZS5vcmcv' (36) GSASL_NEEDS_MORE
S: `aHR0cDovL2lkcC5leGFtcGxlL05PTkNFLz9vcGVuaWQuZm9vPWJhcg==' (56) GSASL_NEEDS_MORE
C: `PQ==' (4) GSASL_OK
S: `' (0) GSASL_OK
C: `' (0) GSASL_OK
S: GSASL_MECHANISM_CALLED_TOO_MANY_TIMES
C: GSASL_MECHANISM_CALLED_TOO_MANY_TIMES

Running successful authentication with SREG:

S: `' (0) GSASL_NEEDS_MORE
C: `biwsaHR0cDovL3VzZXIuZXhhbXBsZS5vcmcv' (36) GSASL_NEEDS_MORE
S: `aHR0cDovL2lkcC5leGFtcGxlL05PTkNFLz9vcGVuaWQuZm9vPWJhcg==' (56) GSASL_NEEDS_MORE
C: `PQ==' (4) GSASL_OK
S: `bmlja25hbWU9amFz' (16) GSASL_OK
C: `' (0) GSASL_OK
S: GSASL_MECHANISM_CALLED_TOO_MANY_TIMES
C: GSASL_MECHANISM_CALLED_TOO_MANY_TIMES

Running successful authentication without SREG with authzid:

S: `' (0) GSASL_NEEDS_MORE
C: `bixhPXVzZXIsaHR0cDovL3VzZXIuZXhhbXBsZS5vcmcv' (44) GSASL_NEEDS_MORE
S: `aHR0cDovL2lkcC5leGFtcGxlL05PTkNFLz9vcGVuaWQuZm9vPWJhcg==' (56) GSASL_NEEDS_MORE
C: `PQ==' (4) GSASL_OK
S: `bmlja25hbWU9amFz' (16) GSASL_OK
C: `' (0) GSASL_OK
S: GSASL_MECHANISM_CALLED_TOO_MANY_TIMES
C: GSASL_MECHANISM_CALLED_TOO_MANY_TIMES

Running successful authentication with SREG with authzid:

S: `' (0) GSASL_NEEDS_MORE
C: `bixhPXVzZXIsaHR0cDovL3VzZXIuZXhhbXBsZS5vcmcv' (44) GSASL_NEEDS_MORE
S: `aHR0cDovL2lkcC5leGFtcGxlL05PTkNFLz9vcGVuaWQuZm9vPWJhcg==' (56) GSASL_NEEDS_MORE
C: `PQ==' (4) GSASL_OK
S: `bmlja25hbWU9amFz' (16) GSASL_OK
C: `' (0) GSASL_OK
S: GSASL_MECHANISM_CALLED_TOO_MANY_TIMES
C: GSASL_MECHANISM_CALLED_TOO_MANY_TIMES

Running failed authentication:

S: `' (0) GSASL_NEEDS_MORE
C: `bixhPXVzZXIsaHR0cDovL3VzZXIuZXhhbXBsZS5vcmcv' (44) GSASL_NEEDS_MORE
S: `aHR0cDovL2lkcC5leGFtcGxlL05PTkNFLz9vcGVuaWQuZm9vPWJhcg==' (56) GSASL_NEEDS_MORE
C: `PQ==' (4) GSASL_OK
S: `b3BlbmlkLmVycm9yPWZhaWw=' (24) GSASL_NEEDS_MORE
C: `PQ==' (4) GSASL_NEEDS_MORE
S: GSASL_AUTHENTICATION_ERROR
C: GSASL_MECHANISM_CALLED_TOO_MANY_TIMES

Does anyone have different interpretation of how the round-trips should
look like?

Finally, I I noticed a nit in section 2.1:

      The nonce value MUST be at least 2^32 large and large enough to
      handle well in excess of the number of concurrent transactions a
      SASL server shall see.

Presumably the intention is not to use 2^32 = 4GB large nonces.  I used
a 32 byte nonce, but possibly the intention was that the minimum
required length should be 4 bytes?  That is reinforced by the examples
using 4 bytes.

/Simon

[1] https://lists.gnu.org/archive/html/help-gsasl/2012-03/msg00003.html