⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rlm_eap_sim.c

📁 linux1.0内核的源代码,欢迎大家使用
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * rlm_eap_sim.c    Handles that are called from eap for SIM * * The development of the EAP/SIM support was funded by Internet Foundation * Austria (http://www.nic.at/ipa). * * Version:     $Id: rlm_eap_sim.c,v 1.12 2004/03/19 02:20:35 mcr Exp $ * *   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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA * * Copyright 2003  Michael Richardson <mcr@sandelman.ottawa.on.ca> * Copyright 2003  The FreeRADIUS server project * */#include "autoconf.h"#include <stdio.h>#include <stdlib.h>#include "../../eap.h"#include "eap_types.h"#include "eap_sim.h"#include <rad_assert.h>struct eap_sim_server_state {	enum eapsim_serverstates state;	struct eapsim_keys keys;	int  sim_id;};/* * Add value pair to reply */static void add_reply(VALUE_PAIR** vp,		      const char* name, const char* value, int len){	VALUE_PAIR *reply_attr;	reply_attr = pairmake(name, "", T_OP_EQ);	if (!reply_attr) {		DEBUG("rlm_eap_sim: "		      "add_reply failed to create attribute %s: %s\n",		      name, librad_errstr);		return;	}	memcpy(reply_attr->strvalue, value, len);	reply_attr->length = len;	pairadd(vp, reply_attr);}static void eap_sim_state_free(void *opaque){	struct eap_sim_server_state *ess = (struct eap_sim_server_state *)opaque;	if (!ess) return;	free(ess);}/* *	build a reply to be sent. */static int eap_sim_compose(EAP_HANDLER *handler){	/* we will set the ID on requests, since we have to HMAC it */	handler->eap_ds->set_request_id = 1;	return map_eapsim_basictypes(handler->request->reply,				     handler->eap_ds->request);}static int eap_sim_sendstart(EAP_HANDLER *handler){	VALUE_PAIR **vps, *newvp;	uint16_t *words;	struct eap_sim_server_state *ess;	rad_assert(handler->request != NULL);	rad_assert(handler->request->reply);	ess = (struct eap_sim_server_state *)handler->opaque;	/* these are the outgoing attributes */	vps = &handler->request->reply->vps;	rad_assert(vps != NULL);	/*	 * add appropriate TLVs for the EAP things we wish to send.	 */	/* the version list. We support only version 1. */	newvp = paircreate(ATTRIBUTE_EAP_SIM_BASE+PW_EAP_SIM_VERSION_LIST,			PW_TYPE_OCTETS);	words = (uint16_t *)newvp->strvalue;	newvp->length = 3*sizeof(uint16_t);	words[0] = htons(1*sizeof(uint16_t));	words[1] = htons(EAP_SIM_VERSION);	words[2] = 0;	pairadd(vps, newvp);	/* set the EAP_ID - new value */	newvp = paircreate(ATTRIBUTE_EAP_ID, PW_TYPE_INTEGER);	newvp->lvalue = ess->sim_id++;	pairreplace(vps, newvp);	/* record it in the ess */	ess->keys.versionlistlen = 2;	memcpy(ess->keys.versionlist, words+1, ess->keys.versionlistlen);	/* the ANY_ID attribute. We do not support re-auth or pseudonym */	newvp = paircreate(ATTRIBUTE_EAP_SIM_BASE+PW_EAP_SIM_FULLAUTH_ID_REQ,			   PW_TYPE_OCTETS);	newvp->length = 2;	newvp->strvalue[0]=0;	newvp->strvalue[0]=1;	pairadd(vps, newvp);	/* the SUBTYPE, set to start. */	newvp = paircreate(ATTRIBUTE_EAP_SIM_SUBTYPE, PW_TYPE_INTEGER);	newvp->lvalue = eapsim_start;	pairreplace(vps, newvp);	return 1;}static int eap_sim_getchalans(VALUE_PAIR *vps, int chalno,			      struct eap_sim_server_state *ess){	VALUE_PAIR *vp;	rad_assert(chalno >= 0 && chalno < 3);	vp = pairfind(vps, ATTRIBUTE_EAP_SIM_RAND1+chalno);	if(vp == NULL) {		/* bad, we can't find stuff! */		DEBUG2("   eap-sim can not find sim-challenge%d",chalno+1);		return 0;	}	if(vp->length != EAPSIM_RAND_SIZE) {		DEBUG2("   eap-sim chal%d is not 8-bytes: %d", chalno+1,		       vp->length);		return 0;	}	memcpy(ess->keys.rand[chalno], vp->strvalue, EAPSIM_RAND_SIZE);	vp = pairfind(vps, ATTRIBUTE_EAP_SIM_SRES1+chalno);	if(vp == NULL) {		/* bad, we can't find stuff! */		DEBUG2("   eap-sim can not find sim-sres%d",chalno+1);		return 0;	}	if(vp->length != EAPSIM_SRES_SIZE) {		DEBUG2("   eap-sim sres%d is not 16-bytes: %d", chalno+1,		       vp->length);		return 0;	}	memcpy(ess->keys.sres[chalno], vp->strvalue, EAPSIM_SRES_SIZE);	vp = pairfind(vps, ATTRIBUTE_EAP_SIM_KC1+chalno);	if(vp == NULL) {		/* bad, we can't find stuff! */		DEBUG2("   eap-sim can not find sim-kc%d",chalno+1);		return 0;	}	if(vp->length != EAPSIM_Kc_SIZE) {		DEBUG2("   eap-sim kc%d is not 8-bytes: %d", chalno+1,		       vp->length);		return 0;	}	memcpy(ess->keys.Kc[chalno], vp->strvalue, EAPSIM_Kc_SIZE);	return 1;}/* * this code sends the challenge itself. * * Challenges will come from one of three places eventually: * * 1  from attributes like ATTRIBUTE_EAP_SIM_RANDx *            (these might be retrived from a database) * * 2  from internally implemented SIM authenticators *            (a simple one based upon XOR will be provided) * * 3  from some kind of SS7 interface. * * For now, they only come from attributes. * It might be that the best way to do 2/3 will be with a different * module to generate/calculate things. * */static int eap_sim_sendchallenge(EAP_HANDLER *handler){	struct eap_sim_server_state *ess;	VALUE_PAIR **invps, **outvps, *newvp;	ess = (struct eap_sim_server_state *)handler->opaque;	rad_assert(handler->request != NULL);	rad_assert(handler->request->reply);	/* invps is the data from the client.	 * but, this is for non-protocol data here. We should	 * already have consumed any client originated data.	 */	invps = &handler->request->packet->vps;	/* outvps is the data to the client. */	outvps= &handler->request->reply->vps;	printf("+++> EAP-sim decoded packet:\n");	vp_printlist(stdout, *invps);	/* okay, we got the challenges! Put them into an attribute */	newvp = paircreate(ATTRIBUTE_EAP_SIM_BASE+PW_EAP_SIM_RAND,			   PW_TYPE_OCTETS);	memset(newvp->strvalue,    0, 2); /* clear reserved bytes */	memcpy(newvp->strvalue+2+EAPSIM_RAND_SIZE*0, ess->keys.rand[0], EAPSIM_RAND_SIZE);	memcpy(newvp->strvalue+2+EAPSIM_RAND_SIZE*1, ess->keys.rand[1], EAPSIM_RAND_SIZE);	memcpy(newvp->strvalue+2+EAPSIM_RAND_SIZE*2, ess->keys.rand[2], EAPSIM_RAND_SIZE);	newvp->length = 2+EAPSIM_RAND_SIZE*3;	pairadd(outvps, newvp);	/* set the EAP_ID - new value */	newvp = paircreate(ATTRIBUTE_EAP_ID, PW_TYPE_INTEGER);	newvp->lvalue = ess->sim_id++;	pairreplace(outvps, newvp);	/* make a copy of the identity */	ess->keys.identitylen = strlen(handler->identity);	memcpy(ess->keys.identity, handler->identity, ess->keys.identitylen);	/* all set, calculate keys! */	eapsim_calculate_keys(&ess->keys);#ifdef EAP_SIM_DEBUG_PRF	eapsim_dump_mk(&ess->keys);#endif	/*	 * need to include an AT_MAC attribute so that it will get	 * calculated. The NONCE_MT and the MAC are both 16 bytes, so	 * we store the NONCE_MT in the MAC for the encoder, which	 * will pull it out before it does the operation.	 */	newvp = paircreate(ATTRIBUTE_EAP_SIM_BASE+PW_EAP_SIM_MAC,			   PW_TYPE_OCTETS);	memcpy(newvp->strvalue, ess->keys.nonce_mt, 16);	newvp->length = 16;	pairreplace(outvps, newvp);	newvp = paircreate(ATTRIBUTE_EAP_SIM_KEY, PW_TYPE_OCTETS);	memcpy(newvp->strvalue, ess->keys.K_aut, 16);	newvp->length = 16;	pairreplace(outvps, newvp);	/* the SUBTYPE, set to challenge. */	newvp = paircreate(ATTRIBUTE_EAP_SIM_SUBTYPE, PW_TYPE_INTEGER);	newvp->lvalue = eapsim_challenge;	pairreplace(outvps, newvp);	return 1;}#ifndef EAPTLS_MPPE_KEY_LEN#define EAPTLS_MPPE_KEY_LEN     32#endif/* * this code sends the success message. * * the only work to be done is the add the appropriate SEND/RECV * radius attributes derived from the MSK. * */static int eap_sim_sendsuccess(EAP_HANDLER *handler){        unsigned char *p;	struct eap_sim_server_state *ess;	VALUE_PAIR **outvps;	VALUE_PAIR *newvp;	/* outvps is the data to the client. */	outvps= &handler->request->reply->vps;	ess = (struct eap_sim_server_state *)handler->opaque;	/* set the EAP_ID - new value */	newvp = paircreate(ATTRIBUTE_EAP_ID, PW_TYPE_INTEGER);	newvp->lvalue = ess->sim_id++;	pairreplace(outvps, newvp);	p = ess->keys.msk;	add_reply(outvps, "MS-MPPE-Recv-Key", p, EAPTLS_MPPE_KEY_LEN);	p += EAPTLS_MPPE_KEY_LEN;	add_reply(outvps, "MS-MPPE-Send-Key", p, EAPTLS_MPPE_KEY_LEN);	return 1;}/* * run the server state machine. */static void eap_sim_stateenter(EAP_HANDLER *handler,			       struct eap_sim_server_state *ess,			       enum eapsim_serverstates newstate){	switch(newstate) {	case eapsim_server_start:		/*		 * send the EAP-SIM Start message, listing the		 * versions that we support.		 */		eap_sim_sendstart(handler);		break;	case eapsim_server_challenge:		/*		 * send the EAP-SIM Challenge message.		 */		eap_sim_sendchallenge(handler);		break;	case eapsim_server_success:		/*

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -