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

📄 eapmschapv2.cpp

📁 source_code 实现无线局域网中的802.1x功能
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/**************************************************************************/
/* WIRE1x Version 1.0: A client-side 802.1x implementation                */
/* based on xsupplicant of Open1x for Windows XP, 2000, 98, and Me        */
/*                                                                        */
/* 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) 2004, WIRE Lab, National Tsing Hua Univ., Hsinchu, Taiwan*/
/* All Rights Reserved                                                    */
/**************************************************************************/
/** * 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. */#include <stdafx.h>
#include <openssl/ssl.h>#include <openssl/rand.h>#include <string.h>#include <unistd.h>#include <stdlib.h>#include <ctype.h>#include <winsock.h>#include "eapmschapv2.h"#include "eap.h"#include "userconf.h"#include "auth_tools.h"#include "des.h"char *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){  eapmschap_netid = netid;  eapmschap_config = config;  return 0;}//526void NtPasswordHash(char *Password, char *PasswordHash)
{
  EVP_MD_CTX cntx;
  char retVal[20];
  int i, len;
  char *uniPassword;

  if ((!Password) || (!PasswordHash))
    {
      return;
    }

  memset(retVal, 0, 20);
  uniPassword = to_unicode(Password);
  len = (strlen(Password))*2;

  EVP_DigestInit(&cntx, EVP_md4());
  EVP_DigestUpdate(&cntx, uniPassword, len);
  EVP_DigestFinal(&cntx, (u_char *)&retVal, (unsigned int *)&i);
  memcpy(PasswordHash, &retVal, 16);
  free(uniPassword);
}
//526
// Take from hostap code by Jouni Malinen, and modified to work with
// XSupplicant.
void ChallengeResponse(char *Challenge, char *PasswordHash, char *Response)
{
  uint8_t zpwd[7];

  if ((!Challenge) || (!PasswordHash) || (!Response))
    {
      return;
    }

  des_encrypt(Challenge, PasswordHash, Response);
  des_encrypt(Challenge, PasswordHash + 7, Response+8);
  zpwd[0] = PasswordHash[14];
  zpwd[1] = PasswordHash[15];
  memset(zpwd + 2, 0, 5);
  des_encrypt(Challenge, (char *)zpwd, Response+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, (u_char *)outhash, (uint32_t *)&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));  if (cntx == NULL)    {      return;    }  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, (u_char *)&pre_digest, (uint32_t *)&retLen);  if (cntx != NULL) free(cntx);  memcpy(chal, &pre_digest, 8);
}
//526
// Shamelessly take from the hostap code written by Jouni Malinen
void des_encrypt(char *clear, char *key, char *cypher)
{
  uint8_t pkey[8], next, tmp;
  int i;
  DES_key_schedule ks;

  if ((!clear) || (!key) || (!cypher))
    {
      return;
    }

  /* Add parity bits to key */
  next = 0;
  for (i=0; i<7; i++)
    {
      tmp = key[i];
      pkey[i] = (tmp >> i) | next | 1;
      next = tmp << (7-i);
    }
  pkey[i] = next | 1;

  DES_set_key(&pkey, &ks);
  DES_ecb_encrypt((DES_cblock *) clear, (DES_cblock *) cypher, &ks,
		  DES_ENCRYPT);
}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 {	}    }  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)    {      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]);
}// 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;  // The success string passed in should look like this :  // S=<auth string> M=<message>  if (instr[0] != 'S') return -1;  temp = &instr[2];  // Point past the S=
  process_hex(temp, 40, authstr);  // Here we could process the M= message, but since not all RADIUS servers  // return one, we will just ignore it.  /*  // 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.    {      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);  *retry = (int)strtod(&retry_blk[2], &junk);  temp_store = (char *)malloc(32);  // It shouldn't be more than 16 bytes.  if (temp_store == NULL)    {      return;    }  memcpy(temp_store, &chal_blk[2], 32);  process_hex(temp_store, 32, challenge);  free(temp_store);  *pchange = (int)strtod(&pchange_blk[2], &junk);  memcpy(msg, &msg_blk[2], (strlen(msg_blk)-2));
}// Convert a string to unicode(ish)char *to_uni(char *non_uni){  char *retUni;  int i;  retUni = (char *)malloc((strlen(non_uni)+1)*2);  if (retUni == NULL)    {      return NULL;    }  memset(retUni, 0, ((strlen(non_uni)+1)*2));  for (i=0; i<strlen(non_uni); i++)    {      retUni[(2*i)] = non_uni[i];    }  return retUni;}// Pass in the needed information, along with a non-unicode password.//   The spec calls for a unicode password, but we will pad it with 0s//   to make it work for now. ;)//527void GenerateNTResponse(char *AuthenticatorChallenge, char *PeerChallenge,
			char *UserName, char *Password, char *Response)
{
  char Challenge[8], PasswordHash[16];

  if ((!AuthenticatorChallenge) || (!PeerChallenge) || (!UserName) ||
      (!Password) || (!Response))
    {
      return;
    }
  
  ChallengeHash(PeerChallenge, AuthenticatorChallenge, UserName, (char *)&Challenge);
  NtPasswordHash(Password, (char *)&PasswordHash);
  ChallengeResponse(Challenge, (char *)&PasswordHash, Response);
}//526// Pass in the challenge information to *in_chal, the password (non-unicode)// in *password, and you will get an MS-CHAPv1 compatible response.void NtChallengeResponse(char *Challenge, char *Password, char *Response)
{

⌨️ 快捷键说明

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