Hi Alan We did the following changes in code 1. File: src/modules/rlm_eap/types/rlm_eap_gtc/rlm_eap_gtc.c In function gtc_initiate(void *type_data, EAP_HANDLER *handler) Added following lines with reference to the src/modules/rlm_eap/types/rlm_eap_mschapv2/rlm_eap_mschapv2.c file #ifdef WITH_PROXY /* * The EAP session doesn't have enough information to * proxy the "inside EAP" protocol. Disable EAP proxying. */ handler->request->options &= ~RAD_REQUEST_OPTION_PROXY_EAP; #endif
2. We also added the following functions in rlm_eap_gtc file static int gtc_postproxy(EAP_HANDLER *handler, void *tunnel_data) 3. If we try to add callback for post proxy in gtc_authenticate() function its start crashing. If we assign the callback function as NULL then we are able to set the User-Password in Proxy EAP-PEAP_GTC. But the access challenge thrown by Radius server is never sent back to client. The modified rlm_eap_gtc.c is attached for your reference. We want to forward the access challenge thrown by server back to client. Can someone help what more changes are required to achieve this? Thanks n regards Sankalp Dubey -----Original Message----- From: freeradius-users-bounces+sankalp_dubey=symantec....@lists.freeradius.org [mailto:freeradius-users-bounces+sankalp_dubey=symantec....@lists.freeradius.org] On Behalf Of Alan DeKok Sent: Wednesday, May 08, 2013 6:53 PM To: FreeRadius users mailing list Subject: Re: Free radius as Proxy EAP-PEAP-GTC User-Password is never set Sankalp Dubey wrote: > Can you please provide some pointers on where to carry out code change to > achieve this. Well... looking at the EAP-GTC code would be a good start. Alan DeKok. - List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html
/* * rlm_eap_gtc.c Handles that are called from eap * * Version: $Id$ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA * * Copyright 2003,2006 The FreeRADIUS server project */ #include <freeradius-devel/ident.h> RCSID("$Id$") #include <freeradius-devel/autoconf.h> #include <stdio.h> #include <stdlib.h> #include "eap.h" #include <freeradius-devel/rad_assert.h> /* * EAP-GTC is just ASCII data carried inside of the EAP session. * The length of the data is indicated by the encapsulating EAP * protocol. */ typedef struct rlm_eap_gtc_t { const char *challenge; const char *auth_type_name; int auth_type; } rlm_eap_gtc_t; static CONF_PARSER module_config[] = { { "challenge", PW_TYPE_STRING_PTR, offsetof(rlm_eap_gtc_t, challenge), NULL, "Password: " }, { "auth_type", PW_TYPE_STRING_PTR, offsetof(rlm_eap_gtc_t, auth_type_name), NULL, "PAP" }, { NULL, -1, 0, NULL, NULL } /* end the list */ }; /* * Detach the module. */ static int gtc_detach(void *arg) { rlm_eap_gtc_t *inst = (rlm_eap_gtc_t *) arg; free(inst); return 0; } /* * Attach the module. */ static int gtc_attach(CONF_SECTION *cs, void **instance) { rlm_eap_gtc_t *inst; DICT_VALUE *dval; inst = malloc(sizeof(*inst)); if (!inst) { radlog(L_ERR, "rlm_eap_gtc: out of memory"); return -1; } memset(inst, 0, sizeof(*inst)); /* * Parse the configuration attributes. */ if (cf_section_parse(cs, inst, module_config) < 0) { gtc_detach(inst); return -1; } dval = dict_valbyname(PW_AUTH_TYPE, inst->auth_type_name); if (!dval) { radlog(L_ERR, "rlm_eap_gtc: Unknown Auth-Type %s", inst->auth_type_name); gtc_detach(inst); return -1; } inst->auth_type = dval->value; *instance = inst; return 0; } /* * Initiate the EAP-GTC session by sending a challenge to the peer. */ static int gtc_initiate(void *type_data, EAP_HANDLER *handler) { char challenge_str[1024] = {0}; int length; EAP_DS *eap_ds = handler->eap_ds; rlm_eap_gtc_t *inst = (rlm_eap_gtc_t *) type_data; if (!radius_xlat(challenge_str, sizeof(challenge_str), inst->challenge, handler->request, NULL)) { radlog(L_ERR, "rlm_eap_gtc: xlat of \"%s\" failed", inst->challenge); return 0; } length = strlen(challenge_str); /* * We're sending a request... */ eap_ds->request->code = PW_EAP_REQUEST; eap_ds->request->type.data = malloc(length); if (eap_ds->request->type.data == NULL) { radlog(L_ERR, "rlm_eap_gtc: out of memory"); return 0; } memcpy(eap_ds->request->type.data, challenge_str, length); eap_ds->request->type.length = length; #ifdef WITH_PROXY /* * The EAP session doesn't have enough information to * proxy the "inside EAP" protocol. Disable EAP proxying. */ handler->request->options &= ~RAD_REQUEST_OPTION_PROXY_EAP; #endif /* * We don't need to authorize the user at this point. * * We also don't need to keep the challenge, as it's * stored in 'handler->eap_ds', which will be given back * to us... */ handler->stage = AUTHENTICATE; return 1; } #ifdef WITH_PROXY /* * Do post-proxy processing, * 0 = fail * 1 = OK. * * Called from rlm_eap.c, eap_postproxy(). */ static int gtc_postproxy(EAP_HANDLER *handler, void *tunnel_data) { VALUE_PAIR *response = NULL; mschapv2_opaque_t *data; tunnel_data = tunnel_data; /* -Wunused */ DEBUG2(" rlm_eap_gtc: Passing reply from proxy back into the tunnel %p %d.", handler->request, handler->request->reply->code); /* * Done doing EAP proxy stuff. */ handler->request->options &= ~RAD_REQUEST_OPTION_PROXY_EAP; /* * save any other attributes for re-use in the final * access-accept e.g. vlan, etc. This lets the PEAP * use_tunneled_reply code work */ data->reply = paircopy(handler->request->reply->vps); /* * And we need to challenge the user, not ack/reject them, * so we re-write the ACK to a challenge. Yuck. */ handler->request->reply->code = PW_ACCESS_CHALLENGE; return 1; } #endif /* * Authenticate a previously sent challenge. */ static int gtc_authenticate(void *type_data, EAP_HANDLER *handler) { VALUE_PAIR *vp; EAP_DS *eap_ds = handler->eap_ds; rlm_eap_gtc_t *inst = (rlm_eap_gtc_t *) type_data; /* * Get the Cleartext-Password for this user. */ rad_assert(handler->request != NULL); rad_assert(handler->stage == AUTHENTICATE); /* * Sanity check the response. We need at least one byte * of data. */ if (eap_ds->response->length <= 4) { radlog(L_ERR, "rlm_eap_gtc: corrupted data"); eap_ds->request->code = PW_EAP_FAILURE; return 0; } #if 0 if ((debug_flag > 2) && fr_log_fp) { int i; for (i = 0; i < eap_ds->response->length - 4; i++) { if ((i & 0x0f) == 0) fprintf(fr_log_fp, "%d: ", i); fprintf(fr_log_fp, "%02x ", eap_ds->response->type.data[i]); if ((i & 0x0f) == 0x0f) fprintf(fr_log_fp, "\n"); } } #endif /* * Handle passwords here. */ if (inst->auth_type == PW_AUTHTYPE_LOCAL) { /* * For now, do clear-text password authentication. */ vp = pairfind(handler->request->config_items, PW_CLEARTEXT_PASSWORD); if (!vp) { DEBUG2(" rlm_eap_gtc: ERROR: Cleartext-Password is required for authentication."); eap_ds->request->code = PW_EAP_FAILURE; return 0; } if (eap_ds->response->type.length != vp->length) { DEBUG2(" rlm_eap_gtc: ERROR: Passwords are of different length. %u %u", (unsigned) eap_ds->response->type.length, (unsigned) vp->length); eap_ds->request->code = PW_EAP_FAILURE; return 0; } if (memcmp(eap_ds->response->type.data, vp->vp_strvalue, vp->length) != 0) { DEBUG2(" rlm_eap_gtc: ERROR: Passwords are different"); eap_ds->request->code = PW_EAP_FAILURE; return 0; } /* * EAP packets can be ~64k long maximum, and * we don't like that. */ } else if (eap_ds->response->type.length <= 128) { int rcode; /* * If there was a User-Password in the request, * why the heck are they using EAP-GTC? */ pairdelete(&handler->request->packet->vps, PW_USER_PASSWORD); vp = pairmake("User-Password", "", T_OP_EQ); if (!vp) { radlog(L_ERR, "rlm_eap_gtc: out of memory"); return 0; } vp->length = eap_ds->response->type.length; memcpy(vp->vp_strvalue, eap_ds->response->type.data, vp->length); vp->vp_strvalue[vp->length] = 0; /* * Add the password to the request, and allow * another module to do the work of authenticating it. */ pairadd(&handler->request->packet->vps, vp); handler->request->password = vp; #ifdef WITH_PROXY /* * If this options is set, then we do NOT authenticate the * user here. Instead, now that we've added the MS-CHAP * attributes to the request, we STOP, and let the outer * tunnel code handle it. * * This means that the outer tunnel code will DELETE the * EAP attributes, and proxy the MS-CHAP attributes to a * home server. */ if (handler->request->options & RAD_REQUEST_OPTION_PROXY_EAP) { /* * Set up the callbacks for the tunnel eap_tunnel_data_t *tunnel; tunnel = rad_malloc(sizeof(*tunnel)); memset(tunnel, 0, sizeof(*tunnel)); tunnel->tls_session = type_data; tunnel->callback = gtc_postproxy; */ /* * Associate the callback with the request. rcode = request_data_add(handler->request, handler->request->proxy, REQUEST_DATA_EAP_TUNNEL_CALLBACK, tunnel, free); rad_assert(rcode == 0); */ /* * The State attribute is NOT supposed to * go into the proxied packet, it will confuse * other RADIUS servers, and they will discard * the request. * * The PEAP module will take care of adding * the State attribute back, before passing * the handler & request back into the tunnel. */ pairdelete(&handler->request->packet->vps, PW_STATE); /* * Remember that in the post-proxy stage, we've got * to do the work below, AFTER the call to MS-CHAP * authentication... */ return 1; } #endif /* * This is a wild & crazy hack. */ rcode = module_authenticate(inst->auth_type, handler->request); if (rcode != RLM_MODULE_OK) { eap_ds->request->code = PW_EAP_FAILURE; return 0; } } else { radlog(L_ERR, "rlm_eap_gtc: Response is too large to understand"); eap_ds->request->code = PW_EAP_FAILURE; return 0; } DEBUG2(" rlm_eap_gtc: Everything is OK."); eap_ds->request->code = PW_EAP_SUCCESS; return 1; } /* * The module name should be the only globally exported symbol. * That is, everything else should be 'static'. */ EAP_TYPE rlm_eap_gtc = { "eap_gtc", gtc_attach, /* attach */ gtc_initiate, /* Start the initial request */ NULL, /* authorization */ gtc_authenticate, /* authentication */ gtc_detach /* detach */ };
- List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html