rlm_krb5 hardware preauth
fcusack at fcusack.com
Thu Nov 24 06:33:51 CET 2005
On November 20, 2005 2:37:44 AM -0500 Benjamin Bennett <ben at psc.edu> wrote:
> I posted a patch to bugzilla
> (http://bugs.freeradius.org/show_bug.cgi?id=296) which adds kerberos
> hardware preauthentication support to rlm_krb5 when using MIT krb5 libs.
> Also pasted below.
> Any feedback from people involved with rlm_krb5 or other modules which
> use challenge-response would be appreciated. This patch takes advantage
> of the krb5 libs (and hence rlm_krb5) being thread-unsafe already, but
> could be changed if that bothers people.
Yes, very bothersome. Steady progress has been made on making krb5 libs
thread-safe (and on Solaris they will be thread-safe when they are exposed).
Use the data arg to the prompter, that's what it's there for, and it's
trivial to use.
Fix the style -- line length (there's a radlog() call in the prompter
that needs to have the last arg on a new line; if (foo) not if(foo); etc).
There's other stuff, but the existing code doesn't have the greatest
style to begin with so I won't belabor it.
The part where you copy the password into prompts.reply looks broken.
Maybe I'm wrong; it's been a long time since I've written krb5 code.
Does the library allocate reply->data for you? Looks that way. In
which case your copy of the password is incorrect, you are copying
as much space as is allocated in the reply, which could be greater
(or less) than the length of the password. If reply->length is greater
than strlen(password->strvalue), you'll run off of the password buffer
and possibly segfault. If lesser, you'll truncate the password.
Null termination of reply->data seems incorrect as well.
In the new request case, you should set reply->code just before you
set r, for readability (move the 2 free() statements up).
You should have a lot more comments, eg, why 'pass' and password get
switched up. More important, why you save the password in the State AVP.
I guess it's because you fail the krb5 part of the auth because it's too
difficult to issue the challenge to the user via RADIUS while staying
inside the prompte function.
Which brings me to my last point, the state isn't adequately protected.
If I can sit between the NAS and the RADIUS server, and insert packets,
I can authenticate as another user by waiting for him to authenticate
and then stealing the State AVP. Now, I login to the NAS as that user,
get a challenge from krb5 via RADIUS and when the NAS sends the response
back, I remove the state and insert the one I stole (from long ago).
You simply decode the state and accept it as valid. This allows me to
login as a user and only have to guess the SAD, without having to know
the long term password. Since the SAD data can be trivial to guess,
(e.g. it is commonly a 6 digit decimal number without any PIN), if
the krb5 server (or at least this specific user) operates in the modes
where the password is used along with the SAD (say, because the SAD is
exceptionally weak), then you've significantly broken things. If the
use-sad-as-key mode is used, well then you're fine, but since rlm_krb5
should be usable for any configuration, it should be fixed.
Oh, also you'll want to note that the failing of the krb5 auth in order
to escape the prompter function alters the kdc logs. There will always
be at least 2 auth requests for a single TGT return.
More information about the Freeradius-Devel