Multiple-Mechanism Sample Code?

Ken Hornstein kenh at cmf.nrl.navy.mil
Mon Jan 1 00:41:34 EST 2007


>>> The client starts iterating through the ordered list, starting from 
>>> the strongest mechanism. It tries the mechanism. If authentication 
>>> succeeds - success. If not, the client may retry the mechanism (e.g. 
>>> if the server returned an indication that the password is incorrect) 
>>> several times, say 3 times. After that the client should move on to 
>>> the next strongest SASL mechanism and so on.

I wasn't able to reply to your original note, but since it got brought up
again ... I just wanted to offer my $0.02.  I personally think this advice
is wrong.  I am speaking from the perspective of someone who uses (or at
least tries to use) the SASL GSSAPI mechanism as much as possible, and
I've written code that uses the Cyrus-SASL library as well as my own
lightweight GSSAPI-SASL library code (I had my reasons for not using
Cyrus-SASL for that one).  Here are my reasons:

- Doing this is complicated.

  As people have already noted, doing this right is a lot of work.  If you
  try to use the Cyrus-SASL library, you have to duplicate the list
  parsing yourself, which just increases the complexity.  Complexity means
  more bugs, and it also decreases the likelihood people will even bother
  to implement SASL in their products (other than the default CRAM-MD5
  mechanism).

  If you want to do this _right_, it also requires mechanism-specific
  knowledge.  Maybe redoing CRAM-MD5 attempts is correct, because
  the user's password could be wrong.  But redoing GSSAPI is almost
  certainly wrong (although I guess retrying it isn't harmful).
  But I recall one recent app (I want to say Thunderbird, but I
  could be wrong) that if GSSAPI failed, it prompted you for a
  password ... THAT everyone would agree is wrong, and is just
  confusing for users.

- It makes things more complicated for users.

  In your scenario, what kind of error message should be returned to
  a user?  All of the errors from all of the mechanisms?  Just the
  last one?  None?  I ask because getting the error message back from
  a failed SASL-GSSAPI authentication exchange is _crucial_ to debugging
  users problems.  Like I said above, at least one recent SASL app just
  gave you a new password prompt for every error, even with GSSAPI.
  Debugging THAT issue was a whole lot of fun (I think I ended up using
  a system call tracer; I could have saved myself an hour's worth of
  work if the damn program just spit out a useful message).

  Also, it's sometimes rather difficult to determine if an application
  supports the mechanism I am interested in.  I don't mean to bash on
  Simon's fine work at GSSAPI-ing the world; I've had many chats with
  him and I know the problems he's faced.  It's just that it's not always
  clear to me with some of the programs I've run into how you're supposed
  to turn GSSAPI authentication on.  I guess the idea is that it's
  "magically" supposed to work ... but when it doesn't, I'm sitting
  around scratching my head going, "Well, does this version even
  _support_ it?  Do I need to enable some wacky registry key?"  I
  like to consider myself pretty Kerberos savvy, but _none_ of these
  automagic SASL-GSSAPI programs ever work for me on the first try.

  I will contrast this with Apple's Mail.app.  It has a very clear
  UI element to select between different SASL mechanisms, and one
  of them is "Kerberos V (GSSAPI)".  I know that when I select that,
  it's going to use the mechanism I want, and none of the others.
  I will confess that I don't know if it returns useful error messages,
  because it's always worked on the first try for me.

- Not all mechanisms are created the same.

  Aside from the issue of attacks, in general don't want my users to
  be using any random mechanism; I want them to be using GSSAPI in all
  but a few cases.  If we get other SASL mechanisms that use some
  kind of infrastructure, I imagine the users of those mechanisms will
  feel the same way.  If GSSAPI is failing, I consider that a serious
  problem and I want to know about it, _now_.  I don't want users falling
  back to CRAM-MD5 (okay, I prevent that on the server, but I can't
  think of a situation where trying a bunch of mechanisms is preferrable
  to explicit mechanism selection on the client).

Now, my suggestions?  I think a SASL client should do the following:

- Allow (and perhaps even enforce) the selection of a specific SASL
  mechanism.
- If a mechanism is not specifically selected, pick the "best" one
  (I'm sure we could get into massive arguments about what the "best"
  mechanism is).  You could use some intelligence here; if you don't
  have a Kerberos credential cache, for example, don't try GSSAPI.
- If authentication fails with the chosen mechanism, error out and
  return the error text to the user.

--Ken


More information about the Cyrus-sasl mailing list