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

📄 eapleap.c

📁 Linux dot1x认证的实现
💻 C
📖 第 1 页 / 共 2 页
字号:
/***************************************************************************** * LEAP implementation. * * Licensed under a dual GPL/BSD license.  (See LICENSE file for more info.) * * File: eapleap.c * * Authors: Marios Karagiannopoulos (marios@master.math.upatras.gr) * * Modified to support dynamic keying by Chris Hessing, with help from * Gilbert Goodwill. * ****************************************************************************/#include <string.h>#include <stdlib.h>#include <stdio.h>#include "xsup_debug.h"#include "xsup_err.h"#include "frame_structs.h"#include "xsupconfig.h"#include "profile.h"#include "eap.h"#include "eapleap.h"#include "leapmd4.h"#include "eap_types/mschapv2/mschapv2.h"#ifdef USE_EFENCE#include <efence.h>#endif#define LEAP_LENGTH    0x08struct leap_requests *leaprequest;struct leap_responses *leapresponse;struct leap_challenges *leapchallenges;static void ntPwdHash(unsigned char *MD4Hash, char *password) {    char unicodePass[513];    char passLen;    int i;    if (!xsup_assert((MD4Hash != NULL), "MD4Hash != NULL", FALSE))      return;    if (!xsup_assert((password != NULL), "password != NULL", FALSE))      return;    /* Microsoft passwords are unicode.  Convert plain text password       to unicode by inserting a zero every other byte */    passLen = strlen(password);    for (i = 0; i < passLen; i++) {        unicodePass[2 * i] = password[i];        unicodePass[2 * i + 1] = 0;    }    /* Encrypt plain text password to a 16-byte MD4 hash */    md4_calc(MD4Hash, (uint8_t *) unicodePass, passLen * 2);}void leap_mschap(char * password, char * response) {    unsigned char MD4Hash[16], MD4HashHash[16];    if (!xsup_assert((password != NULL), "password != NULL", FALSE))      return;    if (!xsup_assert((response != NULL), "response != NULL", FALSE))      return;    ntPwdHash(MD4Hash, password);    md4_calc(MD4HashHash, MD4Hash, 16);    ChallengeResponse((char *) leapchallenges->apc, (char *) MD4HashHash, response);}/***************************************************** * * Setup to handle LEAP EAP requests * * This function is called each time we receive a packet of the EAP type LEAP. * At a minimum, it should check to make sure it's stub in the structure * exists, and if not, set up any variables it may need.  Since LEAP doesn't * have any state that needs to survive successive calls, we don't need to * do anything here. * *****************************************************/int eapleap_setup(struct generic_eap_data *thisint){  struct leap_data *mydata;  if (!xsup_assert((thisint != NULL), "thisint != NULL", FALSE))    return XEMALLOC;  mydata = (struct leap_data *)malloc(sizeof(struct leap_data));  if (mydata == NULL)     {      debug_printf(DEBUG_NORMAL, "Cannot allocate memory in eapleap_setup()!\n");      return XEMALLOC;    }  mydata->keyingMaterial = NULL;  mydata->eapsuccess = FALSE;  thisint->eap_data = mydata;   return XENONE;}/*************************************************************  leap_decode_packet - decode an LEAP challenge, and answer it  	Cisco LEAP authenticates users to the wireless access point via apassword.  This password is authenticated against a back-end radius servervia a Challenge-Response protocol.  The protocol is such:	1.) The Wireless client sends an authentication request;	2.) The AP Acknowledges request with an 8 byte challenge;	3.) The Wireless client computes the response by:		a.) MD4 Hashing the password producing a 16 byte hash;		b.) Padding the hash with 5 nulls producing 21 bytes;		c.) Splitting the resulting 21 bytes into 7 byte chunks;		d.) Iterating through the 7 byte chunks, des encrypting			the challenge as plain-text with the 7-byte chunk			as the key.		e.) Concatenating the resulting cipher text producing 24			bytes	4.) The client then sends the resulting 24 bytes as the challenge		response;	5.) The back-end systems iterate through the same processes and		check for a match; then	6.) If the two match, authentication has been accomplished.************************************************************/int eapleap_process(struct generic_eap_data *thisint, uint8_t *dataoffs,		   int insize, uint8_t *outframe, int *outsize){  struct eap_header *eapheader;  char *answer = NULL;  char *data, *username;  unsigned char chall_response[24];  int total_length;  unsigned char MD4Hash[16], MD4HashHash[16];  char MasterKey[16];  struct config_eap_leap *userdata;  struct leap_data *mydata;  unsigned char challenge_response_expected[24];  unsigned char *challenge_response_got;  if (!xsup_assert((thisint != NULL), "thisint != NULL", FALSE))    return XEMALLOC;  if (!xsup_assert((dataoffs != NULL), "dataoffs != NULL", FALSE))    return XEMALLOC;  if (!xsup_assert((outframe != NULL), "outframe != NULL", FALSE))    return XEMALLOC;  if (!xsup_assert((outsize != NULL), "outsize != NULL", FALSE))    return XEMALLOC;  debug_printf(DEBUG_EVERYTHING, "Processing LEAP\n");  if (!xsup_assert((thisint->eap_conf_data != NULL), 		   "thisint->eap_conf_data != NULL", FALSE))    return XEMALLOC;  userdata = (struct config_eap_leap *)thisint->eap_conf_data;  if (!xsup_assert((userdata != NULL), "userdata != NULL", FALSE))    return XEMALLOC;  if (!xsup_assert((thisint->eap_data != NULL), "thisint->eap_data != NULL",		   FALSE))    return XEMALLOC;  mydata = (struct leap_data *)thisint->eap_data;  if ((thisint->tempPwd == NULL) && (userdata->password == NULL))    {      thisint->need_password = 1;      thisint->eaptype = strdup("LEAP");      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;    }  // Actually process, and respond to challenges.  // LEAP shouldn't be used as an inner type, so we should be able to get  // away with this.  data = (char *) dataoffs-5;  eapheader = (struct eap_header *)data;  switch (eapheader->eap_code) {  case EAP_REQUEST:      // ***********************************************************************************************    mydata->eapsuccess = FALSE;    leapchallenges = (struct leap_challenges *)malloc(sizeof(struct leap_challenges));    leaprequest = (struct leap_requests *)malloc(sizeof(struct leap_requests));    // extract the payload received    memcpy((struct leap_requests *)leaprequest, (struct leap_requests *)dataoffs, 16);    // store Peer Challenge    memcpy((uint8_t *)leapchallenges->pc, (char *)leaprequest->randval, 8);    if (leaprequest->count != LEAP_LENGTH)  {      debug_printf(DEBUG_NORMAL, "(EAP-LEAP) Incorrect length value for LEAP random value.\n");      return XELEAP;    }    memset(chall_response, 0x0, 24);    // Get our username and password out of our configuration structure in memory    debug_printf(DEBUG_AUTHTYPES, "(EAP-LEAP) ID : %d\n",eapheader->eap_identifier);    debug_printf(DEBUG_AUTHTYPES, "(EAP-LEAP) Username = %s   --   Password = %s\n", username,userdata->password);    debug_printf(DEBUG_AUTHTYPES, "(EAP-LEAP) Incoming Peer Challenge Random Value (Length = %d) : ",leaprequest->count);    debug_hex_printf(DEBUG_AUTHTYPES,(uint8_t *)leaprequest->randval, leaprequest->count);    NtChallengeResponse((char *)leapchallenges->pc, userdata->password, 			(char *)&chall_response, 0);    debug_printf(DEBUG_AUTHTYPES, "MSCHAP Response Calculated : ");    debug_hex_printf(DEBUG_AUTHTYPES, (uint8_t *)&chall_response, 24);     // store Peer Response    memcpy((uint8_t *)leapchallenges->pr, (char *)chall_response, 24);    total_length = 24+3+strlen(username)+1;    answer = (char *)malloc(total_length);    if (answer == NULL) {        debug_printf(DEBUG_NORMAL, "(EAP-LEAP) Couldn't allocate memory for building hash source!\n");        return XEMALLOC;    }    // Construct the LEAP response sub fields packet    // let's start with the version number (LEAP subfield)    // byte 0: Version    // byte 1: Unused - Reserved    // byte 2: Count    // byte 3..26: MS-CHAP Challenge Response    // byte 27..m: username    answer[0] = 0x01;    answer[1] = 0x00; // Reserved - Unused    answer[2] = 24; // Count    // Include MSCHAP Challenge response in the built packet    memcpy(&answer[3],&chall_response,24);    // Include username in the built packet    memcpy(&answer[24+3],username,strlen(username)+1);    // be sure that the username (last field) will be NUL terminated!    answer[strlen(answer)] = '\0';

⌨️ 快捷键说明

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