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