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

📄 eapmschapv2.c

📁 linux下可以用来通过802.1x认证
💻 C
📖 第 1 页 / 共 2 页
字号:
/** * 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 + -