?? eapleap.c
字號:
/** * A client-side 802.1x implementation supporting EAP/LEAP * * 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) 2003 Marios Karagiannopoulos * 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. *//***************************************************************************** * EAPOL Function implementations for supplicant * * File: eapleap.c * * Authors: Marios Karagiannopoulos (marios@master.math.upatras.gr) * ****************************************************************************/#include <string.h>#include <stdlib.h>#include <stdio.h>#include "xsup_debug.h"#include "xsup_err.h"#include "frame_structs.h"#include "config.h"#include "profile.h"#include "eap.h"#include "eapleap.h"#include "leapmd4.h"#include "eap_types/mschapv2/mschapv2.h"#include "interactive.h"#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 ((!MD4Hash) || (!password)) { debug_printf(DEBUG_NORMAL, "Invalid data passed in to ntPwdHash!\n"); 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, unicodePass, passLen * 2);}void leap_mschap(char * password, char * response) { unsigned char MD4Hash[16], MD4HashHash[16]; if ((!password) || (!response)) { debug_printf(DEBUG_NORMAL, "Invalid data passed in to leap_mschap()!\n"); return; } ntPwdHash(MD4Hash, password); md4_calc(MD4HashHash, MD4Hash, 16); ChallengeResponse(leapchallenges->apc, 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 (!thisint) { debug_printf(DEBUG_NORMAL, "Invalid interface structure passed to eapleap_setup()!\n"); 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; debug_printf(DEBUG_EVERYTHING, "Initalized EAP-LEAP!\n"); 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, u_char *dataoffs, int insize, u_char *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], mppeSend[16], mppeRecv[16]; struct config_eap_leap *userdata; struct leap_data *mydata; unsigned char challenge_response_expected[24]; unsigned char *challenge_response_got; if (!thisint) { debug_printf(DEBUG_NORMAL, "Invalid interface struct passed in to eapleap_process()!\n"); return XEMALLOC; } if (!thisint->eap_conf_data) { debug_printf(DEBUG_NORMAL, "No valid configuration information for LEAP!\n"); return XEMALLOC; } if (!outframe) { debug_printf(DEBUG_NORMAL, "Invalid out frame buffer in eapleap_process()!\n"); return XEMALLOC; } userdata = (struct config_eap_leap *)thisint->eap_conf_data; if (!thisint->eap_data) { debug_printf(DEBUG_NORMAL, "No valid state information in eapleap_proces()!\n"); 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; } debug_printf(DEBUG_AUTHTYPES, "(EAP-LEAP) Processing.\n"); // 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 = dataoffs-5; eapheader = (struct eap_header *)data; switch (eapheader->eap_code) { case EAP_REQUEST: // *********************************************************************************************** debug_printf(DEBUG_AUTHTYPES, "(EAP-LEAP) Got EAP-REQUEST\n"); 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); 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+2+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
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -