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

📄 eapmschapv2.c

📁 linux下 用来通过802.1x人证
💻 C
字号:
/** * A client-side 802.1x implementation supporting EAP/TLS * * 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. *//******************************************************************* * EAP-MSCHAPv2 Function implementations *  * File: eapmschapv2.c * * Authors: Chris.Hessing@utah.edu * * $Id: eapmschapv2.c,v 1.23 2004/06/29 01:35:35 chessing Exp $ * $Date: 2004/06/29 01:35:35 $ * $Log: eapmschapv2.c,v $ * Revision 1.23  2004/06/29 01:35:35  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.22  2004/06/15 03:35:20  chessing * * New updates including fixes to LEAP (keying now works with wireless) and adding EAP-AKA. * * Revision 1.21  2004/06/15 03:22:29  chessing * * XSupplicant Release 1.0 * * *******************************************************************/#include <openssl/rand.h>#include <string.h>#include <netinet/in.h>#include "profile.h"#include "config.h"#include "xsup_debug.h"#include "xsup_err.h"#include "frame_structs.h"#include "eapmschapv2.h"#include "mschapv2.h"#include "eap.h"#include "interactive.h"int eapmschapv2_setup(struct generic_eap_data *thisint){  struct mschapv2_vars *myvars;  if (!thisint)    {      debug_printf(DEBUG_NORMAL, "Invalid interface structure passed in to eapmschapv2_setup()!\n");      return XEMALLOC;    }  thisint->eap_data = (u_char *)malloc(sizeof(struct mschapv2_vars));  if (thisint->eap_data == NULL) return XEMALLOC;  memset(thisint->eap_data, 0, sizeof(struct mschapv2_vars));  myvars = thisint->eap_data;  myvars->AuthenticatorChallenge = NULL;  myvars->PeerChallenge = NULL;  myvars->NtResponse = NULL;  myvars->keyingMaterial = NULL;  return XENONE;}int eapmschapv2_process(struct generic_eap_data *thisint, u_char *dataoffs, 			int insize, u_char *outframe, int *outsize){  struct mschapv2_challenge *challenge;  struct mschapv2_response *response;  struct mschapv2_success_request *success;  struct mschapv2_vars *myvars;  char *username;  int respOk;  u_char recv[41];  u_char NtHash[16], NtHashHash[16], MasterKey[16];  u_char mppeSend[16], mppeRecv[16];  struct config_eap_mschapv2 *userdata;  if (!thisint)    {      debug_printf(DEBUG_NORMAL, "Invalid interface structure passed in to eapmschapv2_process()!\n");      return XEMALLOC;    }    if (!outframe)    {      debug_printf(DEBUG_NORMAL, "Invalid return buffer in eapmschapv2_process()!\n");      return XEMALLOC;    }  if (!thisint->eap_conf_data)    {      debug_printf(DEBUG_NORMAL, "No valid configuration data available for MSCHAP-V2!\n");      return XEMALLOC;    }  userdata = (struct config_eap_mschapv2 *)thisint->eap_conf_data;  if (!thisint->eap_data)    {      debug_printf(DEBUG_NORMAL, "Invalid state configuration in MSCHAP-V2!\n");      return XEMALLOC;    }  myvars = (struct mschapv2_vars *)thisint->eap_data;  if ((thisint->tempPwd == NULL) && (userdata->password == NULL))    {      thisint->need_password = 1;      thisint->eaptype = strdup("EAP-MS-CHAPv2");      thisint->eapchallenge = NULL;      *outsize = 0;      return XENONE;    }  // Make sure we have something to process...  if (dataoffs == NULL) return XENONE;  if (userdata->username == NULL)    {      username = thisint->identity;    } else {      username = userdata->username;    }  if ((userdata->password == NULL) && (thisint->tempPwd != NULL))    {      userdata->password = thisint->tempPwd;      thisint->tempPwd = NULL;    }  switch ((uint8_t)dataoffs[0])    {    case MS_CHAPV2_CHALLENGE:      debug_printf(DEBUG_AUTHTYPES, "(EAP-MSCHAPv2) Challenge\n");      challenge = (struct mschapv2_challenge *)dataoffs;      response = (struct mschapv2_response *)outframe;      debug_printf(DEBUG_AUTHTYPES, "(EAP-MS-CHAPv2) ID : %02X\n",		   challenge->MS_CHAPv2_ID);      // This value should *ALWAYS* be 16!      if (challenge->Value_Size != 0x10)	{	  if (thisint->ias_quirk == 1)	    {	      debug_printf(DEBUG_NORMAL, "(EAP-MS-CHAPv2) Invalid Value-Size! (%d), forced to 0x10 (ias_quirk=yes)\n", challenge->Value_Size);	      challenge->Value_Size = 0x10;	    }	  else 	    {	      debug_printf(DEBUG_NORMAL, "(EAP-MS-CHAPv2) Invalid Value-Size! (%d)\n", challenge->Value_Size);	      debug_printf(DEBUG_NORMAL, "(EAP-MS-CHAPv2) Should you enable ias_quirk?\n");	      return XEMSCHAPV2LEN;	    }	}      if (myvars->AuthenticatorChallenge != NULL)	{	  free(myvars->AuthenticatorChallenge);	  myvars->AuthenticatorChallenge = NULL;	}      myvars->AuthenticatorChallenge = (u_char *)malloc(16);      if (myvars->AuthenticatorChallenge == NULL) return XEMALLOC;      memcpy(myvars->AuthenticatorChallenge, &challenge->Challenge, 16);            debug_printf(DEBUG_AUTHTYPES, "Authenticator Challenge : ");      debug_hex_printf(DEBUG_AUTHTYPES, myvars->AuthenticatorChallenge, 16);      if (myvars->PeerChallenge != NULL)	{	  free(myvars->PeerChallenge);	  myvars->PeerChallenge = NULL;	}      // Ignore the RADIUS host, we probably don't care.      myvars->PeerChallenge = (u_char *)malloc(16);      if (myvars->PeerChallenge == NULL) return XEMALLOC;      RAND_bytes(myvars->PeerChallenge, 16);      debug_printf(DEBUG_AUTHTYPES, "Generated PeerChallenge : ");      debug_hex_printf(DEBUG_AUTHTYPES, myvars->PeerChallenge,16);      if (myvars->NtResponse != NULL)	{	  free(myvars->NtResponse);	  myvars->NtResponse = NULL;	}      myvars->NtResponse = (u_char *)malloc(24);      if (myvars->NtResponse == NULL) return XEMALLOC;      GenerateNTResponse(myvars->AuthenticatorChallenge, myvars->PeerChallenge,			 username, userdata->password, myvars->NtResponse);      debug_printf(DEBUG_AUTHTYPES, "myvars->NtResponse = ");      debug_hex_printf(DEBUG_AUTHTYPES, myvars->NtResponse, 24);      response->OpCode = MS_CHAPV2_RESPONSE;      response->MS_CHAPv2_ID = challenge->MS_CHAPv2_ID;      response->MS_Length = htons(54+strlen(username));         response->Value_Size = 49;      memcpy((u_char *)&response->Peer_Challenge, myvars->PeerChallenge, 16);      bzero((u_char *)&response->Reserved, 8);      memcpy((u_char *)&response->NT_Response, myvars->NtResponse, 24);      debug_printf(DEBUG_AUTHTYPES, "response->NT_Response = ");      debug_hex_printf(DEBUG_AUTHTYPES, response->NT_Response, 24);      response->Flags = 0;      memcpy(&outframe[54],username, strlen(username));      *outsize = (54 + strlen(username));      break;    case MS_CHAPV2_RESPONSE:      debug_printf(DEBUG_NORMAL, "Got an MS-CHAPv2 Response!?  Ignoring.\n");      *outsize = 0;      break;    case MS_CHAPV2_SUCCESS:      debug_printf(DEBUG_AUTHTYPES, "(EAP-MSCHAPv2) Success!\n");      success = (struct mschapv2_success_request *)dataoffs;      bzero((u_char *)&recv[0], 41);      memcpy((u_char *)&recv[0], (u_char *)&success->MsgField[2], 40);      CheckAuthenticatorResponse(userdata->password, 				 myvars->NtResponse, myvars->PeerChallenge,				 myvars->AuthenticatorChallenge,				 username, (u_char *)&recv[0], &respOk);      if (respOk == 1)	{	  debug_printf(DEBUG_AUTHTYPES, "Server authentication check success!  Sending phase 2 success!\n");	  outframe[0] = MS_CHAPV2_SUCCESS;	  	  // We were successful, so generate keying material.	  NtPasswordHash(userdata->password, (u_char *)&NtHash);	  HashNtPasswordHash((u_char *)&NtHash, (u_char *)&NtHashHash);	  GetMasterKey((u_char *)&NtHashHash, myvars->NtResponse, (u_char *)&MasterKey);	  	  // Now, get the send key.	  GetAsymetricStartKey((u_char *)&MasterKey, (u_char *)&mppeSend, 16, TRUE, FALSE);	  // And the recv key.	  GetAsymetricStartKey((u_char *)&MasterKey, (u_char *)&mppeRecv, 16, FALSE, FALSE);	  // Finally, populate our myvars->keyingMaterial.	  if (myvars->keyingMaterial != NULL)	    {	      free(myvars->keyingMaterial);	      myvars->keyingMaterial = NULL;	    }	  myvars->keyingMaterial = (u_char *)malloc(64);  // 32 bytes each.	  if (myvars->keyingMaterial == NULL) return XEMALLOC;	  bzero(myvars->keyingMaterial, 64);	  memcpy(&myvars->keyingMaterial[32], &mppeRecv, 16);	  memcpy(myvars->keyingMaterial, &mppeSend, 16);	} else {	  debug_printf(DEBUG_AUTHTYPES, "Server verification check failed!  Sending PHASE 2 FAILURE!\n");	  outframe[0] = MS_CHAPV2_FAILURE;	}      *outsize = 1;            break;    case MS_CHAPV2_FAILURE:      debug_printf(DEBUG_NORMAL, "MS-CHAPv2 Authentication Failure!\n");      *outsize = 0;      // We should probably process the failure info, and respond as needed,      // but, we really don't care if a failure is retryable, as 802.1x will      // just try again anyway. ;)      break;    case MS_CHAPV2_CHANGE_PWD:      debug_printf(DEBUG_NORMAL, "Password changing is not supported!\n");      break;    }  return XENONE;}int eapmschapv2_get_keys(struct interface_data *thisint){  struct mschapv2_vars *myconf;  if ((!thisint) || (!thisint->userdata) || (!thisint->userdata->activemethod) || (!thisint->userdata->activemethod->eap_data))      return XEMALLOC;  myconf = (struct mschapv2_vars *)thisint->userdata->activemethod->eap_data;  if (thisint->keyingMaterial != NULL)    {      free(thisint->keyingMaterial);    }  thisint->keyingMaterial = (char *)malloc(64);  if (thisint->keyingMaterial == NULL) return -1;  memcpy(thisint->keyingMaterial, myconf->keyingMaterial, 64);  thisint->keyingLength = 32;    return XENONE;}int eapmschapv2_failed(struct generic_eap_data *thisint){  struct config_eap_mschapv2 *userdata;  if ((!thisint) || (!thisint->eap_conf_data))    {      debug_printf(DEBUG_AUTHTYPES, "No EAP MS-CHAPv2 configuration data!  Nothing to do!\n");      return XEMALLOC;    }  userdata = (struct config_eap_mschapv2 *)thisint->eap_conf_data;#ifndef NO_PWD_RESET  /*  if (userdata->password != NULL)    {      free(userdata->password);      userdata->password = NULL;    }  */#endif  return XENONE;}int eapmschapv2_cleanup(struct generic_eap_data *thisint){  struct mschapv2_vars *myvars;  if (!thisint)    {      debug_printf(DEBUG_NORMAL, "Invalid interface structure in eapmschapv2_cleanup()!\n");      return XEMALLOC;    }  myvars = (struct mschapv2_vars *)thisint->eap_data;  if (thisint->eap_data != NULL)    {      if (myvars->AuthenticatorChallenge != NULL)	{	  free(myvars->AuthenticatorChallenge);	  myvars->AuthenticatorChallenge = NULL;	}      if (myvars->PeerChallenge != NULL)	{	  free(myvars->PeerChallenge);	  myvars->PeerChallenge = NULL;	}      if (myvars->NtResponse != NULL)	{	  free(myvars->NtResponse);	  myvars->NtResponse = NULL;	}            if (myvars->keyingMaterial != NULL)	{	  free(myvars->keyingMaterial);	  myvars->keyingMaterial = NULL;	}      free(thisint->eap_data);      thisint->eap_data = NULL;    }  return XENONE;}

⌨️ 快捷键说明

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