rlm_krb5 hardware preauth
Benjamin Bennett
ben at psc.edu
Sun Nov 20 08:37:44 CET 2005
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.
--ben
--- src/modules/rlm_krb5/rlm_krb5.c.dist 2005-11-18 18:06:03.000000000
-0500
+++ src/modules/rlm_krb5/rlm_krb5.c 2005-11-18 21:44:49.000000000 -0500
@@ -20,6 +20,7 @@
* Copyright 2000 The FreeRADIUS server project
* Copyright 2000 Nathan Neulinger <nneul at umr.edu>
* Copyright 2000 Alan DeKok <aland at ox.org>
+ * Copyright 2005 Benjamin Bennett <ben at psc.edu>
*/
@@ -39,6 +40,8 @@
#include <krb5.h>
#include <com_err.h>
+REQUEST *global_request;
+
typedef struct rlm_krb5_t {
const char *keytab;
const char *service_princ;
@@ -205,12 +208,83 @@
return 0;
}
+#ifndef HEIMDAL_KRB5
+static krb5_error_code KRB5_CALLCONV
+krb5_radius_prompter(krb5_context context, void *data, const char *name,
+ const char *banner, int num_prompts,
+ krb5_prompt prompts[])
+{
+ VALUE_PAIR *state;
+ VALUE_PAIR *reply;
+ char *challenge;
+ char *newstate;
+ int clen;
+ int r;
+
+ /* Squelch unused param warnings */
+ context = context;
+ data = data;
+
+ if(num_prompts != 1) {
+ radlog(L_DBG, "rlm_krb5: [%s] krb5_radius_prompter failed: num_prompts (%d) != 1", global_request->username->strvalue, num_prompts);
+ global_request->reply->code = PW_AUTHENTICATION_REJECT;
+ return KRB5_LIBOS_CANTREADPWD;
+ }
+
+ state = pairfind(global_request->packet->vps, PW_STATE);
+
+ if(!state) { /* NEW Request */
+ radlog(L_DBG, "rlm_krb5: [%s] krb5_radius_prompter: additional token required", global_request->username->strvalue);
+
+ /* Setup challenge prompt */
+ clen = strlen(name)+strlen(banner)+strlen(prompts[0].prompt)+5;
+ challenge = rad_malloc(clen);
+ snprintf(challenge, clen, "%s\n%s\n%s: ", name, banner,
+ prompts[0].prompt);
+
+ /* Re-encode User-Password to send back */
+ rad_pwencode((char *)global_request->password->strvalue,
+ &global_request->password->length,
+ global_request->secret,
+ (char *)global_request->packet->vector);
+
+ /* Setup State with current Authenticator and User-Password */
+ newstate = rad_malloc(AUTH_VECTOR_LEN+
+ global_request->password->length+1);
+ memcpy(newstate, global_request->packet->vector, AUTH_VECTOR_LEN);
+ memcpy(newstate+AUTH_VECTOR_LEN, global_request->password->strvalue,
+ global_request->password->length+1);
+
+ /* Put State into a challenge reply */
+ reply = pairmake("Reply-Message", challenge, T_OP_EQ);
+ pairadd(&global_request->reply->vps, reply);
+ state = pairmake("State", newstate, T_OP_EQ);
+ pairadd(&global_request->reply->vps, state);
+ global_request->reply->code = PW_ACCESS_CHALLENGE;
+ free(challenge);
+ free(newstate);
+ r = KRB5_LIBOS_CANTREADPWD;
+ } else { /* Challenge Response */
+ radlog(L_DBG, "rlm_krb5: [%s] krb5_radius_prompter: using additional token", global_request->username->strvalue);
+
+ strncpy(prompts[0].reply->data,
+ (char *)global_request->password->strvalue,
+ prompts[0].reply->length);
+ prompts[0].reply->data[(prompts[0].reply->length)-1] = '\0';
+ prompts[0].reply->length = strlen(prompts[0].reply->data);
+ r = 0;
+ }
+ return r;
+}
+#endif
+
/* validate userid/passwd */
/* MIT case */
#ifndef HEIMDAL_KRB5
static int krb5_auth(void *instance, REQUEST *request)
{
int r;
+ VALUE_PAIR *state;
krb5_data tgtname = {
0,
@@ -218,11 +292,13 @@
KRB5_TGS_NAME
};
krb5_creds kcreds;
+ krb5_get_init_creds_opt opts;
krb5_ccache ccache;
char cache_name[L_tmpnam + 8];
krb5_context context = *((rlm_krb5_t *)instance)->context; /* copy data */
- const char *user, *pass;
+ const char *user;
+ char *pass;
/*
* We can only authenticate user requests which HAVE
@@ -271,6 +347,8 @@
/*
* Actually perform the authentication
*/
+ krb5_get_init_creds_opt_init(&opts);
+
memset((char *)&kcreds, 0, sizeof(kcreds));
if ( (r = krb5_parse_name(context, user, &kcreds.client)) ) {
@@ -302,22 +380,40 @@
return RLM_MODULE_REJECT;
}
- if ( (r = krb5_get_in_tkt_with_password(context,
- 0, NULL, NULL, NULL, pass, ccache, &kcreds, 0)) ) {
- radlog(L_AUTH, "rlm_krb5: [%s] krb5_g_i_t_w_p failed: %s",
- user, error_message(r));
- krb5_free_cred_contents(context, &kcreds);
- krb5_cc_destroy(context, ccache);
- return RLM_MODULE_REJECT;
- } else {
+ global_request = request;
+ state = pairfind(request->packet->vps, PW_STATE);
+ if(state) {
+ radlog(L_DBG, "rlm_krb5: [%s] challenge response", user);
+ if(state->length <= AUTH_VECTOR_LEN) {
+ radlog(L_AUTH, "rlm_krb5: [%s] BAD State data", user);
+ return RLM_MODULE_REJECT;
+ }
+ pass = (char *)state->strvalue+AUTH_VECTOR_LEN;
+ rad_pwdecode(pass, state->length-AUTH_VECTOR_LEN,
+ request->secret, (char *)state->strvalue);
+ }
+
+ if(!(r = krb5_get_init_creds_password(context, &kcreds,
+ kcreds.client, pass, krb5_radius_prompter, NULL,
+ (krb5_deltat)0, NULL, &opts))) {
+ if( (r = krb5_cc_store_cred(context, ccache, &kcreds)) ) {
+ radlog(L_AUTH, "rlm_krb5: [%s] krb5_cc_store_cred failed: %s",
+ user, error_message(r));
+ return RLM_MODULE_REJECT;
+ }
/* Now verify the KDC's identity. */
r = verify_krb5_tgt(context, (rlm_krb5_t *)instance, user, ccache);
- krb5_free_cred_contents(context, &kcreds);
- krb5_cc_destroy(context, ccache);
- return r;
+ } else if(r == KRB5_LIBOS_CANTREADPWD) {
+ r = RLM_MODULE_HANDLED;
+ } else {
+ radlog(L_AUTH, "rlm_krb5: [%s] krb5_g_i_c_p failed: %s", user,
+ error_message(r));
+ r = RLM_MODULE_REJECT;
}
- return RLM_MODULE_REJECT;
+ krb5_free_cred_contents(context, &kcreds);
+ krb5_cc_destroy(context, ccache);
+ return r;
}
#else /* HEIMDAL_KRB5 */
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 189 bytes
Desc: This is a digitally signed message part
URL: <http://lists.freeradius.org/pipermail/freeradius-devel/attachments/20051120/a3bbd39a/attachment.pgp>
More information about the Freeradius-Devel
mailing list