?? eapmschapv2.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 Chris Hessing & Terry Simons * 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: eapmschap.c * * Authors: Chris.Hessing@utah.edu, Terry.Simons@utah.edu * *******************************************************************//* TODO: Change DES routines to use OpenSSL Return MS-CHAP failure if server isn't authentic Use xlogf instead of printf. Clean up warnings! Look at implementing MPPE for dynamic keying. Break MS-CHAPv2 code into it's own file, to be used with PEAP and TTLS.*/#include <inttypes.h>#include <openssl/ssl.h>#include <openssl/rand.h>#include <string.h>#include <unistd.h>#include <stdlib.h>#include <ctype.h>#include "eapmschapv2.h"#include "../../configparse.h"#include "dot1x_globals.h"#include "eap.h"#include "userconf.h"#include "logging.h"#include "auth_methods/auth_tools.h"#include "des.h"#ifndef MSCHAP_DEBUG#define MSCHAP_DEBUG 0#endifchar *eapmschap_netid;char *eapmschap_config;struct mschap_vars { char NtResponse[24]; char PeerChallenge[16]; char AuthenticatorChallenge[16];};static struct mschap_vars savedvars;int init_eapmschap(char *config, char *netid){#ifdef MSCHAP_DEBUG xlogf(DEBUG_AUTHTYPES, "(EAPMS-CHAP) Initalized\n");#endif eapmschap_netid = netid; eapmschap_config = config; return 0;}void ntpasswordhash(char *uni_password, int len, char *out){ EVP_MD_CTX *cntx; char retVal[16]; int i; cntx = (EVP_MD_CTX *)malloc(sizeof(EVP_MD_CTX)); // We should fix this, so that we are using only OpenSSL, rather than other types of hash routines. EVP_DigestInit(cntx, EVP_md4()); EVP_DigestUpdate(cntx, uni_password, len); EVP_DigestFinal(cntx, (char *)&retVal, (int *)&i); if (i != 16) printf("Returned hash wasn't 16! ACK! (It was %d)\n",i); #if MSCHAP_DEBUG printf("Hash : "); for (i=0; i<16; i++) { printf("%02x",(uint8_t)retVal[i]); }#endif memcpy(out, &retVal, 16);}void HashNtPasswordHash(char *inhash, char *outhash){ EVP_MD_CTX cntx; int i; EVP_DigestInit(&cntx, EVP_md4()); EVP_DigestUpdate(&cntx, inhash, 16); EVP_DigestFinal(&cntx, outhash, &i);}void challenge_hash(char *peer_chal, char *auth_chal, char *username, char *chal){ EVP_MD_CTX *cntx; // The context needed for the hashing. char pre_digest[30]; // The originally returned digest. int retLen; cntx = (EVP_MD_CTX *)malloc(sizeof(EVP_MD_CTX)); EVP_DigestInit(cntx, EVP_sha1()); EVP_DigestUpdate(cntx, peer_chal, 16); EVP_DigestUpdate(cntx, auth_chal, 16); EVP_DigestUpdate(cntx, username, strlen(username)); EVP_DigestFinal(cntx, (char *)&pre_digest, &retLen); if (cntx != NULL) free(cntx); memcpy(chal, &pre_digest, 8);#if MSCHAP_DEBUG printf("Challenge Hash : "); print_hex(chal, 8);#endif}// Taken from FreeRADIUSstatic void parity_key(char * szOut, const char * szIn){ int i; unsigned char cNext = 0; unsigned char cWorking = 0; for (i = 0; i < 7; i++) { /* Shift operator works in place. Copy the char out */ cWorking = szIn[i]; szOut[i] = (cWorking >> i) | cNext | 1; cWorking = szIn[i]; cNext = (cWorking << (7 - i)); } szOut[i] = cNext | 1;}//Taken from FreeRADIUSstatic void des_encrypt(const char *szClear, const char *szKey, char *szOut){ char szParityKey[9]; unsigned long ulK[16][2]; parity_key(szParityKey, szKey); /* Insert parity bits */#if MSCHAP_DEBUG printf("Parity Key : "); print_hex(szParityKey, 9);#endif strncpy(szOut, szClear, 8); /* des encrypts in place */ deskey(ulK, (unsigned char *) szParityKey, 0); /* generate keypair */ des(ulK, szOut); /* encrypt */}//Taken from FreeRADIUSstatic void mschap(const char *szChallenge, unsigned char * smbPasswd, char *szResponse) { char szMD4[21]; /* initialize hash string */ memset(szMD4, 0, 21); memcpy(szMD4, smbPasswd, 16); /* * * challenge_response takes an 8-byte challenge string and a * 21-byte hash (16-byte hash padded to 21 bytes with zeros) and * returns a 24-byte response in szResponse */ des_encrypt(szChallenge, szMD4, szResponse); des_encrypt(szChallenge, szMD4 + 7, szResponse + 8); des_encrypt(szChallenge, szMD4 + 14, szResponse + 16);}char ctonibble(char cnib){ char retVal=0x00; char testval=0x00; if ((cnib>='0') && (cnib<='9')) { retVal = cnib - '0'; } else { testval = toupper(cnib); if ((testval>='A') && (testval<='F')) { retVal = ((testval - 'A') +10); } else { printf("Error in conversion! (Check ctonibble()) -- %02x\n",testval); } } return retVal;}// Convert an ASCII string to a binary version of it.void process_hex(char *instr, int size, char *outstr){ int i; // Make sure we don't try to convert something that isn't byte aligned. if ((size % 2) != 0) { printf("Hex string isn't an even number of chars!!!\n"); return; } for (i=0;i<=(size/2);i++) { if (instr[i*2] != 0x00) { outstr[i] = (ctonibble(instr[i*2]) << 4) + ctonibble(instr[(i*2)+1]);#if MSCHAP_DEBUG printf("%02x", (uint8_t)outstr[i]);#endif } }#if MSCHAP_DEBUG printf("\n");#endif}// This routine decodes the MSCHAPv2 success message, and returns it// as a couple of char *'s to be more useful. Return -1 if we were passed// a string that doesn't look like a success string.int decode_success(char *instr, int instr_size, char *authstr, char *msg){ char *temp; int i; // The success string passed in should look like this : // S=<auth string> M=<message> if (instr[0] != 'S') return -1; // We shouldn't have a return code more than 40 hex digits, but just to be // safe. temp = (char *)malloc(50); i=2; //Start beyond the S= while (instr[i] != ' ') { temp[i-2] = instr[i]; i++; } temp[i-2] = 0x00; // Make it so we can print the string correctly.#if MSCHAP_DEBUG printf("Processing string : %s\n", temp);#endif process_hex(temp, i-2, authstr); free(temp);#if MSCHAP_DEBUG printf("Returned : "); print_hex(authstr, 20); // 40 chars, boils down to 20 bytes. printf("\n");#endif // Skip to the next character. while (instr[i] != ' ') i++; // Make sure we have a message here. if (instr[i] != 'M') return -1; i+=2; // Skip to the first character in the message. memcpy(msg, &instr[i], (instr_size - i)); return 0;}void decode_error(char *instr, int *err, int *retry, char *challenge, int *pchange, char *msg){ char *err_blk=NULL, *retry_blk=NULL, *chal_blk=NULL, *pchange_blk=NULL; char *msg_blk = NULL; char *junk, *temp_store; if (instr[0] != 'E') // Then we don't have an error. { printf("The returned message isn't formatted correctly!\n"); return; } sprintf(instr, "%s %s %s %s %s", err_blk, retry_blk, chal_blk, pchange_blk, msg_blk); // Now, process each block. err = (int)strtod(&err_blk[2], &junk);#if MSCHAP_DEBUG printf("Error number : %d\n", err);#endif retry = (int)strtod(&retry_blk[2], &junk);#if MSCHAP_DEBUG
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -