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

📄 ttlsphase2.c

📁 Linux上的802.1x 的supplicant的实现。很多supplicant程序都是基于它开发的
💻 C
📖 第 1 页 / 共 3 页
字号:
/******************************************************************* * EAPTTLS Phase 2 Function implementations * * Licensed under a dual GPL/BSD license.  (See LICENSE file for more info.) * * File: ttlsphase2.c * * Authors: Chris.Hessing@utah.edu * * $Id: ttlsphase2.c,v 1.41 2006/08/25 23:37:18 chessing Exp $ * $Date: 2006/08/25 23:37:18 $ * $Log: ttlsphase2.c,v $ * Revision 1.41  2006/08/25 23:37:18  chessing * Numerous patches that have come in over the last month or two. * * Revision 1.40  2006/06/13 21:16:28  chessing * Updates to the new EAP-TNC code. * * Revision 1.39  2006/06/05 23:27:36  chessing * Fixed a couple bugs introduced in the TTLS-EAP-MD5 code.  Cleaned up some other bugs introduced in this morning's commit. * * Revision 1.38  2006/06/05 01:40:41  chessing * Various small cleanups. * * Revision 1.37  2006/06/01 22:49:51  galimorerpg * Converted all instances of u_char to uint8_t * Fixed a bad #include in the generic frame handler. * * Revision 1.36  2006/06/01 04:03:04  chessing * Fixed a problem where we would segfault on a reauth.  (We probably need to get this fixed up a bit and release 1.2.6 quickly as a bug fix release.)  Added support for TTLS-EAP-MD5 * * Revision 1.35  2006/05/31 05:10:51  chessing * Beginnings of EAP-TTLS-EAP-MD5, and added internet draft for EAP-TTLS to doc/standards. * * Revision 1.34  2006/05/29 04:17:58  chessing * Fixes for some memory leaks. * * Revision 1.33  2006/05/13 03:44:46  chessing * Huge patch as a result of the downtime with SourceForge.  Fixed issues with WPA/WPA2.  Fixed a segfault when a scan returned a NULL.  Changed event handleing to use select() instead of older sleep/non-blocking socket resulting in a faster authentication.  Fixed a stack smashing bug that would cause random failures with WPA/WPA2.  Added status messages so that when we run in non-debug mode we have some idea of what is going on.  Various other code cleanups, bug fixes. * * Revision 1.31  2006/04/25 01:17:44  chessing * LOTS of code cleanups, new error checking/debugging code added, and other misc. fixes/changes. * * Revision 1.30  2006/04/17 03:56:24  chessing * Added some support to enable/disable TNC support both via the configuration file, and via IPC. * * Revision 1.29  2006/04/16 21:20:43  chessing * Added initial TNC support via patch from Mike McCauley.  Requires libtnc in order to work, which isn't yet available to the public. * * Revision 1.28  2006/01/03 04:02:36  chessing * Added the ability to store the PEAP password in a hashed format.  (Basically, an MS-CHAPv1 hash.)  Also added an 'ntpwdhash' program to the tools directory that will convert a cleartext password in to a hash that can be copied to the configuration file. * * Revision 1.27  2005/10/17 03:56:55  chessing * Updates to the libxsupconfig library.  It no longer relies on other source from the main tree, so it can be used safely in other code with problems. * * Revision 1.26  2005/10/14 02:26:18  shaftoe * - cleanup gcc 4 warnings * - (re)add support for a pid in the form of /var/run/xsupplicant.<iface>.pid * * -- Eric Evans <eevans@sym-link.com> * * Revision 1.25  2005/08/09 01:39:18  chessing * Cleaned out old commit notes from the released version.  Added a few small features including the ability to disable the friendly warnings that are spit out.  (Such as the warning that is displayed when keys aren't rotated after 10 minutes.)  We should also be able to start when the interface is down.  Last, but not least, we can handle empty network configs.  (This may be useful for situations where there isn't a good reason to have a default network defined.) * * *******************************************************************/#include <inttypes.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <stdio.h>#include <ctype.h>#include <netinet/in.h>#include <openssl/ssl.h>#include "xsupconfig.h"#include "profile.h"#include "eap.h"#include "../tls/tls_crypt.h"#include "xsup_debug.h"#include "xsup_err.h"#include "../mschapv2/mschapv2.h"#include "ttlsphase2.h"#ifdef HAVE_TNC#include <libtnctncc.h>#endif#ifdef USE_EFENCE#include <efence.h>#endif// A few numbers from the radius dictionary. 8-)#define USER_NAME_AVP        1#define USER_PASSWORD_AVP    2#define CHAP_PASSWORD_AVP    3#define CHAP_CHALLENGE_AVP   60#define EAP_MESSAGE          79// Defines for MS-CHAP values also from the dictionary.#define MS_VENDOR_ATTR       311#define MS_CHAP_RESPONSE     1#define MS_CHAP_CHALLENGE    11#define MS_CHAP2_RESPONSE    25// Defines for TNC Integrity Checking// Integrity Messages are passed between IMC modules in the client and IMV modules// in the server through OSC-Integrity-Message AVPs, which are tunnelled // through the TTLS tunnel.#define OSC_VENDOR_ATTR       9048#define OSC_INTEGRITY_MESSAGE 5#define MANDITORY_FLAG       0x40#define VENDOR_FLAG          0x80#define TTLS_CHALLENGE       "ttls challenge"    // Need to generate implied challenge.#define TTLS_CHALLENGE_SIZE  14#define TTLS_PHASE2_DEBUG    1uint32_t avp_code;uint32_t bitmask_avp_len;struct phase2_handler {  char *phase2name;  void (*phase2handler)(struct generic_eap_data *, char *, int, char *, int *);  ttls_phase2_type phase2type;};struct phase2_handler phase2types[] = {  {"UNDEFINED", ttls_do_bogus, TTLS_PHASE2_UNDEFINED},  {"PAP", ttls_do_pap, TTLS_PHASE2_PAP},  {"CHAP", ttls_do_chap, TTLS_PHASE2_CHAP},  {"MSCHAP", ttls_do_mschap, TTLS_PHASE2_MSCHAP},  {"MSCHAPV2", ttls_do_mschapv2, TTLS_PHASE2_MSCHAPV2},  {"EAP_MD5", ttls_do_eap_md5, TTLS_PHASE2_EAP_MD5},  {NULL, ttls_do_bogus, -1}};// This is from section 10.1 of the TTLS RFC.char *implicit_challenge(struct generic_eap_data *thisint){  if (!xsup_assert((thisint != NULL), "thisint != NULL", FALSE))    return NULL;  return tls_crypt_gen_keyblock(thisint, TTLS_CHALLENGE, TTLS_CHALLENGE_SIZE);}void build_avp(uint32_t avp_value, uint32_t avp_vendor, uint64_t avp_flags, 	       uint8_t *in_value, uint64_t in_value_len, uint8_t *out_value, 	       int *out_size){  int avp_padded;  uint32_t avp_vendor_stuff;  if (!xsup_assert((out_size != NULL), "out_size != NULL", FALSE))    return;  *out_size = 0;  if (!xsup_assert((in_value != NULL), "in_value != NULL", FALSE))    return;  if (!xsup_assert((out_value != NULL), "out_value != NULL", FALSE))    return;  avp_code = htonl(avp_value);  avp_vendor_stuff = htonl(avp_vendor);  if (avp_vendor != 0)     {      in_value_len = in_value_len +4;    }  if ((in_value_len % 4) != 0)    {      avp_padded = (in_value_len + (4 - (in_value_len % 4)));    } else {      avp_padded = in_value_len;    }  bitmask_avp_len = htonl((avp_flags << 24) + in_value_len + 8);  bzero(out_value, avp_padded+12);  memcpy(&out_value[0], &avp_code, 4);  memcpy(&out_value[4], &bitmask_avp_len, 4);  if (avp_vendor != 0)    {      memcpy(&out_value[8], &avp_vendor_stuff, 4);      memcpy(&out_value[12], in_value, in_value_len);      *out_size = avp_padded+8;    } else {      memcpy(&out_value[8], in_value, in_value_len);      *out_size = avp_padded+8;    }}#ifdef HAVE_TNC// global variables to hold destination buffer and lengths// for sending messages. Since there is only ever one network// connection being created in a single instance of xsupplicant, we do  not use// the TNC connection ID to find out what connection we are talking about.static uint8_t *dest_buf;static size_t  *dest_size;void ttls_tnc_start(uint8_t *out_value, size_t *out_size){    // When the handshake starts, the IMC may try to send message(s) to the IMV    // by calling TNC_TNCC_SendBatch    // Remember the destination output buffer for when TNC_TNCC_SendBatch    // is called    dest_buf = out_value;    dest_size = out_size;    if (libtnc_tncc_BeginSession(0) != TNC_RESULT_SUCCESS)    {	debug_printf(DEBUG_NORMAL, "libtnc_tncc_BeginSession failed\n");	return;    }    debug_printf(DEBUG_NORMAL, "Started IMC handshake\n");}// Process incoming decrypted inner message, looking for TNC IMC messages// and pass each one to the IMCsvoid ttls_tnc_process(uint8_t *in_value, size_t in_size, uint8_t *out_value, 		      size_t *out_size){    int i = 0;    while (i < in_size - 8) // AVP must be at least 8 octets    {	int      avpcode = ntohl(*(uint32_t*)(in_value + i));	int      avplength = ntohl(*(uint32_t*)(in_value + i + 4));	int      avpflags = (avplength >> 24) & 0xff; 	uint8_t *avpdata;	int      avpdatalength;	// Make sure we cant be fooled by silly sizes	avplength &= 0xffffff;	if (i + avplength > in_size)	    break;	if (avpflags & 0x80)	{	    // Vendor ID is present	    int avpvendor = ntohl(*(uint32_t*)(in_value + i + 8));	    avpdata = in_value + i + 12;	    avpdatalength = avplength - 12;	    if (   avpvendor == OSC_VENDOR_ATTR		   && avpcode == OSC_INTEGRITY_MESSAGE)	    {		// Its an OSC-Integrity-Message, which contains a TNCCS-Batch		// and has to be		// Given to the IMC. This call may result in a call to TNC_TNCC_SendBatch		// to send another batch of messages to the IMV at the server		dest_buf = out_value;		dest_size = out_size;		debug_printf(DEBUG_NORMAL, "Received an OSC-Integrity-Message\n");		libtnc_tncc_ReceiveBatch(0, (const char*)avpdata, avpdatalength);	    }	}	else	{	    avpdata = in_value + i + 8;	    avpdatalength = avplength - 8;	}	i += avplength;	// Pad up to multiple of 4:	if (i % 4)	    i += 4 - (i % 4);    }}// Called by TNCC when a finished batch is ready to sendTNC_Result TNC_TNCC_SendBatch(    /*in*/ TNC_ConnectionID connectionID,    /*in*/ const char* messageBuffer,    /*in*/ size_t messageLength){    int avp_out_size;    // Append an OSC-Integrity-Message to the current output buffer    build_avp(OSC_INTEGRITY_MESSAGE, OSC_VENDOR_ATTR, VENDOR_FLAG, 	      (uint8_t *)messageBuffer, messageLength, 	      dest_buf + *dest_size, &avp_out_size);    *dest_size += avp_out_size;    return TNC_RESULT_SUCCESS;}#endif/************************************************************** * * Do an EAP-MD5 authentication.  This could easily be converted to a  * generic EAP authentication handler, with little effort.  (There would * be more effort involved in the configuration parse code. ;) * **************************************************************/void ttls_do_eap_md5(struct generic_eap_data *thisint, char *indata, 		     int insize, char *out_data, int *out_size){  int eapid = 1;  char eapdata[1500];  // Temporary buffer to store EAP response.  int eapsize = 0;  char *identity;  struct config_eap_md5 *md5data;  struct config_eap_ttls *ttlsdata;  struct config_ttls_phase2 *phase2data;  struct config_eap_method eapmethod;  ttlsdata = (struct config_eap_ttls *)thisint->eap_conf_data;  if (!ttlsdata)    {      debug_printf(DEBUG_NORMAL, "Error gathering TTLS data.\n");      return;    }  phase2data = (struct config_ttls_phase2 *)ttlsdata->phase2;  if (phase2data == NULL)    {      debug_printf(DEBUG_NORMAL, "No phase 2 data available!\n");      return;    }  while ((phase2data != NULL) && 	 (phase2data->phase2_type != TTLS_PHASE2_EAP_MD5))    {      phase2data = phase2data->next;    }  if (!phase2data->phase2_data)    {      debug_printf(DEBUG_NORMAL, "Invalid phase 2 config in MS-CHAPv2!\n");      return;    }  md5data = (struct config_eap_md5 *)phase2data->phase2_data;  if (!md5data)    {      debug_printf(DEBUG_NORMAL, "Error gathering MD5 data.\n");      return;    }  // DO NOT free *identity!  It points to memory that will be freed  // later.  if (md5data->username)    {      identity = md5data->username;    }  else    {      identity = thisint->identity;    }  if (identity == NULL)    {      debug_printf(DEBUG_NORMAL, "Invalid phase 2 username found.  (You may"		   " need to populate the phase 2 username data field.)\n");      return;    }  if (insize == 0)    {      eap_request_id(identity, eapid, (char *) &eapdata, &eapsize);      debug_printf(DEBUG_INT, "EAP Identity dump (%d) : \n", eapsize);      debug_hex_dump(DEBUG_INT, eapdata, eapsize);

⌨️ 快捷键说明

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