On November 20, 2005 2:37:44 AM -0500 Benjamin Bennett <ben@psc.edu> wrote:
Hi,
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[0].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. -frank