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

📄 peap_phase2.c

📁 linux下 用来通过802.1x人证
💻 C
字号:
/** * A client-side 802.1x implementation  * * This code is released under both the GPL version 2 and BSD licenses. * Either license may be used.  The respective licenses are found below. * * Copyright (C) 2002 Bryan D. Payne & Nick L. Petroni Jr. * All Rights Reserved * * --- GPL Version 2 License --- * 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. * * --- BSD License --- * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * *  - Redistributions of source code must retain the above copyright notice, *    this list of conditions and the following disclaimer. *  - Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. *  - All advertising materials mentioning features or use of this software *    must display the following acknowledgement: *       This product includes software developed by the University of *       Maryland at College Park and its contributors. *  - Neither the name of the University nor the names of its contributors *    may be used to endorse or promote products derived from this software *    without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. *//******************************************************************* * The driver function for a Linux application layer EAPOL  * implementation * File: peap_phase2.c * * Authors: Chris.Hessing@utah.edu * * $Id: peap_phase2.c,v 1.19 2004/07/15 04:15:37 chessing Exp $ * $Date: 2004/07/15 04:15:37 $ * $Log: peap_phase2.c,v $ * Revision 1.19  2004/07/15 04:15:37  chessing * * True/false int values are now bit flags in a byte.  PEAP now calls back in to functions from eap.c for phase 2 methods.  This allows for any phase 1 EAP type to work.  This resulted in some major changes the functions in eap.c, and in peap_phase2.c.  PEAP has been tested using both MS-CHAPv2, and EAP-MD5 as inner types.  More types need to be tested, and enabled. * * Revision 1.18  2004/06/29 01:35:36  chessing * * Added credit to eapleap.c for Gilbert Goodwill (who gave me the clues I needed to figure out the keying piece for LEAP).  Added patch from Toby Collett to make PEAP work for broken implementations of IAS.  (New option ias_quirk has been added.) * * Revision 1.17  2004/06/15 03:22:31  chessing * * XSupplicant Release 1.0 * * *******************************************************************/#include <stdio.h>#include <stdlib.h>#include <string.h>#include <netinet/in.h>#include "config.h"#include "profile.h"#include "eap.h"#include "peap_phase2.h"#include "eappeap.h"#include "../tls/eaptls.h"#include "xsup_err.h"#include "xsup_debug.h"#include "../mschapv2/eapmschapv2.h"#include "../otp/eapotp.h"#include "../tls/tls_crypt.h"#define VALID_EAP_TYPE  EAP_TYPE_MSCHAP#define HIGHEST_PEAP_SUPPORTED   1int set_peap_version(struct phase2_data *p2d, int new_version){  if (!p2d)    {      debug_printf(DEBUG_NORMAL, "Invalid phase 2 data in set_peap_version()!\n");      return XEMALLOC;    }  if (new_version > HIGHEST_PEAP_SUPPORTED)     {      p2d->peap_version = HIGHEST_PEAP_SUPPORTED;      return HIGHEST_PEAP_SUPPORTED;    }  // Only change versions if we are changing to a higher one.  This will   // keep us from backing off to a lower version mid-communication, should the  // RADIUS server get confused.  if (p2d->peap_version < new_version)    {      debug_printf(DEBUG_AUTHTYPES, "PEAP Version changed to %d\n",new_version);      p2d->peap_version = new_version;    }  return p2d->peap_version;}// Remove the beginning 18 bytes.void peap_unpad_frame(u_char *in, int in_size, u_char *out, int *out_size){  int i;  if ((!in) || (!out))    {      debug_printf(DEBUG_NORMAL, "Invalid packet buffer in in or out at peap_unpad_frame()!\n");      return;    }  if (in_size > 1520)    {      debug_printf(DEBUG_NORMAL, "Packet too large in peap_unpad_frame()!\n");      return;    }  *out_size = in_size - 4;  for (i=0;i<=*out_size;i++)    {      out[i] = in[4+i];    }}// Pad out the beginning with 18 bytes.  (Probably 0s.)void peap_pad_frame(u_char *in, int in_size, u_char *out, int *out_size){  int i;  if ((!in) || (!out))    {      debug_printf(DEBUG_NORMAL, "Invalid packet buffer in in or out at peap_pad_frame()!\n");      return;    }  if (in_size > 1520)    {      debug_printf(DEBUG_NORMAL, "In packet size to large!  Ignoring!\n");      return;    }  *out_size = in_size + 4;  bzero(out, *out_size);  for (i=0;i<=in_size;i++)    {      out[4+i] = in[i];    }}void do_peap_version1(struct phase2_data *thisint, u_char *in, int in_size, 		      u_char *out, int *out_size){  char *new_frame = NULL;  int eapvalue, eapid;  struct tls_vars *mytls_vars;  if ((!thisint) || (!out) || (!out_size))    {      debug_printf(DEBUG_NORMAL, "Invalid data passed in to do_peap_version1()!\n");      if (out_size) *out_size = 0;      return;    }  if (in_size > 1520)    {      debug_printf(DEBUG_NORMAL, "Invalid frame passed in to do_peap_version1()!\n");      return;    }    *out_size = 0;  mytls_vars = (struct tls_vars *)thisint->eapdata->eap_data;  // mytls_vars may be NULL here!  This is okay, as long as we aren't in the  // middle of an inner authentication.  eapvalue = in[4];  eapid = in[5]; // Inner EAP id.  debug_printf(DEBUG_AUTHTYPES, "Inner packet : \n");  if (in_size < 1522)    {      debug_hex_dump(DEBUG_AUTHTYPES, in, in_size);    } else {      debug_printf(DEBUG_AUTHTYPES, "INVALID PACKET SIZE!\n");    }  new_frame = (char *)malloc(1024);  if (new_frame == NULL)    {      debug_printf(DEBUG_NORMAL, "Couldn't allocate memory for new_frame in do_peap_version1()!\n");      return;    }  bzero(new_frame, 1024);  switch ((uint8_t)eapvalue)    {    case EAP_REQUEST:      eap_request_id(thisint->eapdata->identity, eapid, out, out_size);       break;    case EAP_SUCCESS:      printf("Got a phase 2 success!\n");      break;      // If we catch the EAP_FAILURE, it has the same value as MD5.  Which      // is probably why PEAP-EAP-MD5 isn't allowed in XP. ;)      /*    case EAP_FAILURE:      printf("Got a phase 2 failure!\n");      break;      */    case PEAP_EAP_EXTENSION: // EAP Extension      debug_printf(DEBUG_AUTHTYPES, "Got an EAP extension frame!\n");      out[0] = EAP_RESPONSE;      memcpy(&out[1], &in[1], in_size-1);      *out_size = in_size;      break;    default:      if (eap_create_active_method(&thisint->activemethod,				   thisint->eapdata->identity,				   thisint->eapdata->tempPwd) != 0)	{	  debug_printf(DEBUG_NORMAL, "Couldn't build active method!  Phase 2 authentication will not happen!\n");	  return;	}      eap_request_auth(thisint->activemethod, thisint->eapdata->eap_conf_data,		       in, in_size, out, out_size);      break;    }  free(new_frame);}void do_peap_version0(struct phase2_data *thisint, u_char *in, int in_size, 		      u_char *out, int *out_size){  char *padded_frame, *new_frame;  int padded_size, new_frame_size, eframe = 0;  if ((!thisint) || (!out_size))    {      debug_printf(DEBUG_NORMAL, "Invalid data passed in to do_peap_version0()!\n");      if (out_size) *out_size = 0;      return;    }  *out_size = 0;  if (!in)    {      debug_printf(DEBUG_NORMAL, "Input frame was NULL!  Ignoring!\n");      return;    }  if (!out)    {      debug_printf(DEBUG_NORMAL, "Invalid return buffer!\n");      return;    }  if (in_size>1520)    {      debug_printf(DEBUG_NORMAL, "Input frame is too big! Ignoring!\n");      *out_size = 0;      return;    }  padded_size = in_size;  padded_frame = (char *)malloc(in_size+19);  // It is 19 bytes to pad out.  if (padded_frame == NULL)    {      debug_printf(DEBUG_NORMAL, "Unable to allocate memory for padded_frame in do_peap_version0()!\n");      return;    }  if ((in[4] == 0x21) && (in[5] = 0x80) && !(thisint->eapdata->ias_quirk == 1 && in[0] == EAP_TYPE_MSCHAPV2))      {      eframe = 1;      memcpy(padded_frame, in, in_size);    }  if (eframe != 1)     {      peap_pad_frame(in, in_size, padded_frame, &padded_size);    }  new_frame = (char *)malloc(1024);  if (new_frame == NULL)    {      debug_printf(DEBUG_NORMAL, "ACK!  We can't allocate memory!\n");      return;    }   do_peap_version1(thisint, padded_frame, padded_size, new_frame, 		   &new_frame_size);  free(padded_frame);  if (eframe !=1)     {      peap_unpad_frame(new_frame, new_frame_size, out, out_size);    } else {      memcpy(out, new_frame, new_frame_size);      *out_size = new_frame_size;    }  free(new_frame);  eframe = 0;}void peap_do_phase2(struct generic_eap_data *thisint, u_char *in, int in_size, 		    u_char *out, int *out_size){  struct tls_vars *mytls_vars;  struct phase2_data *p2d;  u_char *decr_data, *encr_data;  int encrsize, decrsize;  struct config_eap_peap *peapconf;  struct generic_eap_data *eapdata;  if ((!thisint) || (!in) || (!out))    {      debug_printf(DEBUG_NORMAL, "Invalid parameters passed in to peap_do_phase2()!\n");      return;    }  *out_size = 0;  mytls_vars = (struct tls_vars *)thisint->eap_data;  if (mytls_vars == NULL)    {      debug_printf(DEBUG_NORMAL, "mytls_vars (thisint->eap_data) == NULL!\n");      return;    }  peapconf = (struct config_eap_peap *)thisint->eap_conf_data;  if (peapconf == NULL)    {      debug_printf(DEBUG_NORMAL, "peapconf == NULL!\n");      return;    }  p2d = (struct phase2_data *)mytls_vars->phase2data;  if (p2d->eapdata == NULL)    {      p2d->eapdata = (struct generic_eap_data *)malloc(sizeof(struct generic_eap_data));      if (p2d->eapdata == NULL)	{	  *out_size = 0;	  return;	}      memset(p2d->eapdata, 0, sizeof(struct generic_eap_data));            p2d->eapdata->eap_data = NULL;    }  p2d->eapdata->eap_conf_data = peapconf->phase2;  p2d->eapdata->identity = thisint->identity;  p2d->eapdata->ias_quirk = peapconf->ias_quirk;  decr_data = (char *)malloc(1550);  if (decr_data == NULL)     {      debug_printf(DEBUG_NORMAL, "Couldn't allocate memory for decryption buffer!\n");      return;    }  encr_data = (char *)malloc(1550);  if (encr_data == NULL)     {      debug_printf(DEBUG_NORMAL, "Couldn't allocate memory for encryption buffer!\n");      free(decr_data);      return;    }  if (in_size > 0)    {      tls_crypt_decrypt(thisint, in, in_size, decr_data, &decrsize);      debug_printf(DEBUG_AUTHTYPES, "Decrypted dump : \n");      debug_hex_dump(DEBUG_AUTHTYPES, decr_data, decrsize);    } else {      free(decr_data);      decr_data = NULL;    }  // We need to check this.  I don't think it is needed anymore.  if (decrsize <=0)    {      debug_printf(DEBUG_AUTHTYPES, "Sending ACK!\n");      bzero(out,10);      *out_size = 1;      free(decr_data);      free(encr_data);      return;    }  debug_printf(DEBUG_AUTHTYPES, "Decrypted packet returned %d byte(s)\n", decrsize);  if (thisint->tempPwd != NULL)    {      eapdata = p2d->eapdata;      if (eapdata != NULL)	{	  eapdata->tempPwd = thisint->tempPwd;	}    }  bzero(out, 100);  switch (p2d->peap_version)    {    case 0:      debug_printf(DEBUG_AUTHTYPES, "Doing PEAP v0!\n");      do_peap_version0(p2d, decr_data, decrsize, encr_data, &encrsize);      break;    case 1:      debug_printf(DEBUG_AUTHTYPES, "Doing PEAP v1!\n");      do_peap_version1(p2d, decr_data, decrsize, encr_data, &encrsize);      break;    default:      debug_printf(DEBUG_NORMAL, "Unknown PEAP version!  (%d)\n",p2d->peap_version);      break;    }  eapdata = p2d->eapdata;    if (eapdata->need_password == 1)    {      thisint->need_password = 1;      thisint->eaptype = eapdata->eaptype;      thisint->eapchallenge = eapdata->eapchallenge;      *out_size = 0;    }  if (encrsize > 0)    {      debug_printf(DEBUG_AUTHTYPES, "Unencrypted return frame : \n");      debug_hex_dump(DEBUG_AUTHTYPES, encr_data, encrsize);      tls_crypt_encrypt_nolen(thisint, encr_data, encrsize, out, out_size);      debug_printf(DEBUG_AUTHTYPES, "Encrypted return frame : \n");      debug_hex_dump(DEBUG_AUTHTYPES, out, *out_size);    }  free(encr_data);  free(decr_data);}void peap_phase2_failed(struct generic_eap_data *thisint){  struct tls_vars *mytls_vars;  struct phase2_data *p2d;  if (!thisint)    {      debug_printf(DEBUG_NORMAL, "Invalid data passed to peap_phase2_failed()!\n");      return;    }  mytls_vars = (struct tls_vars *)thisint->eap_data;  if (mytls_vars == NULL)    {      debug_printf(DEBUG_NORMAL, "mytls_vars (thisint->eap_data) == NULL!\n");      return;    }  p2d = (struct phase2_data *)mytls_vars->phase2data;  if (p2d->eapdata == NULL)    {      // We didn't get to phase 2, so just bail.      return;    }  eap_do_fail(p2d->activemethod);}

⌨️ 快捷键说明

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