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

📄 ttlsphase2.cpp

📁 source_code 实现无线局域网中的802.1x功能
💻 CPP
字号:
/**************************************************************************/
/* 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                                                    */
/**************************************************************************/
/*
 * --- 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 <stdlib.h>#include <string.h>#include <unistd.h>#include <stdio.h>#include <ctype.h>#include <assert.h>#include <winsock.h>
#include <openssl/ssl.h>#include "eapcrypt.h"#include "userconf.h"#include "ttlsphase2.h"#include "eapmschapv2.h"#ifndef TTLS_PHASE2_DEBUG#define TTLS_PHASE2_DEBUG  0#endif//*********************************************
//for uint32_t
typedef unsigned int uint32_t;
//for uint8_t
typedef unsigned char uint8_t;
//not sure
typedef unsigned long uint64_t;
//**********************************************// A few numbers from the radius dictionary. 8-)#define USER_NAME_AVP        1#define USER_PASSWORD_AVP    2#define CHAP_PASSWORD_AVP    3#define CHAP_CHALLENGE_AVP   60// Defines for MS-CHAP values also from the dictionary.#define MS_VENDOR_ATTR       311#define MS_CHAP_RESPONSE     1#define MS_CHAP_CHALLENGE    11#define MS_CHAP2_RESPONSE    25#define MANDITORY_FLAG       0x40#define VENDOR_FLAG          0x80#define TTLS_CHALLENGE       "ttls challenge"    // Need to generate implied challenge.#define TTLS_CHALLENGE_SIZE  14uint32_t avp_code;uint32_t bitmask_avp_len;// If we add a new phase 2 type, it needs to be defined here.char *phase2_auth_types[] = {  "PAP",  "CHAP",  "MSCHAP",  "MSCHAPV2",  NULL};void (*phase2_method[])(char *, int *) = {  ttls_do_pap,  ttls_do_chap,  ttls_do_mschap,  ttls_do_mschapv2};// This is from section 10.1 of the TTLS RFC.char *implicit_challenge(){  return (char *)eapcrypt_gen_keyblock((u_char *)TTLS_CHALLENGE, TTLS_CHALLENGE_SIZE);}void build_avp(uint32_t avp_value, uint32_t avp_vendor, uint64_t avp_flags, uint8_t *in_value, uint64_t in_value_len, uint8_t *out_value, int *out_size){  int avp_padded;  uint32_t avp_vendor_stuff;  avp_code = htonl(avp_value);  avp_vendor_stuff = htonl(avp_vendor);  if (avp_vendor != 0)     {      in_value_len = in_value_len +4;    }  if ((in_value_len % 4) != 0)    {      avp_padded = (in_value_len + (4 - (in_value_len % 4)));    } else {      avp_padded = in_value_len;    }  bitmask_avp_len = htonl((avp_flags << 24) + in_value_len + 8);  memset(out_value, 0, avp_padded+12);  memcpy(&out_value[0], &avp_code, 4);  memcpy(&out_value[4], &bitmask_avp_len, 4);  if (avp_vendor != 0)    {      memcpy(&out_value[8], &avp_vendor_stuff, 4);      memcpy(&out_value[12], in_value, in_value_len);      *out_size = avp_padded+8;    } else {      memcpy(&out_value[8], in_value, in_value_len);      *out_size = avp_padded+8;    }}void ttls_do_mschapv2(char *out_data, int *out_size){  u_char mschap_challenge[16], mschap_answer[50];  u_char mschap_result[24];  char *username = NULL, *password = NULL, *challenge = NULL;  int avp_offset, avp_out_size, username_size, id;  username = get_phase2id();  username_size = strlen(username);  // Send the Username AVP  build_avp(USER_NAME_AVP, 0, MANDITORY_FLAG, (u_char *)username, username_size, (u_char *)out_data, &avp_out_size);  avp_offset = avp_out_size;  challenge = implicit_challenge();  memcpy(&mschap_challenge, challenge, 16);  id = challenge[17];  // Send the MS-CHAP AVP  build_avp(MS_CHAP_CHALLENGE, MS_VENDOR_ATTR, (MANDITORY_FLAG | VENDOR_FLAG), (u_char *)&mschap_challenge, 16, (u_char *)&out_data[avp_offset], &avp_out_size);  avp_offset+=avp_out_size;  memset(&mschap_answer, 0, 50);
  memcpy(&mschap_answer, &mschap_challenge, 16);  // The first 24 bytes should be left as 0s.  password = get_password();    // Get our password.  GenerateNTResponse((char *)&mschap_challenge, (char *)&mschap_challenge, username, password, (char *)&mschap_result);  mschap_answer[0] = id;  mschap_answer[1] = 0;  memcpy(&mschap_answer[2], &mschap_challenge, 16);  memcpy(&mschap_answer[26], &mschap_result, 24);  build_avp(MS_CHAP2_RESPONSE, MS_VENDOR_ATTR, (MANDITORY_FLAG | VENDOR_FLAG), (u_char *)&mschap_answer, 50, (u_char *)&out_data[avp_offset], &avp_out_size);  avp_offset+=avp_out_size;  *out_size = avp_offset;  if (username != NULL)    {      free(username);      username = NULL;    }  if (password != NULL)    {      free(password);      password = NULL;    }}// For phase 2 MS-CHAP, we get 8 bytes implicit challenge, and 1 byte for ID.void ttls_do_mschap(char *out_data, int *out_size){  u_char mschap_challenge[8], mschap_answer[49];  u_char mschap_result[24];  char *username = NULL, *password = NULL, *challenge = NULL;  int avp_offset, avp_out_size, username_size, id;  username = get_phase2id();  username_size = strlen(username);  // Send the Username AVP  build_avp(USER_NAME_AVP, 0, MANDITORY_FLAG, (u_char *)username, username_size, (u_char *)out_data, &avp_out_size);  avp_offset = avp_out_size;  challenge = implicit_challenge();  memcpy((char *)&mschap_challenge[0], challenge, 8);  id = challenge[9];  // Send the MS-CHAP AVP  build_avp(MS_CHAP_CHALLENGE, MS_VENDOR_ATTR, (MANDITORY_FLAG | VENDOR_FLAG), (u_char *)&mschap_challenge, 8, (u_char *)&out_data[avp_offset], &avp_out_size);  avp_offset+=avp_out_size;  memset((char *)&mschap_answer[0], 0, 49);  password = get_password();    // Get our password.  NtChallengeResponse((char *)&mschap_challenge, password, (char *)&mschap_result);  mschap_answer[0] = id;  mschap_answer[1] = 1; // Use NT Style Passwords.  memcpy((char *)&mschap_answer[26], (char *)&mschap_result, 24);  build_avp(MS_CHAP_RESPONSE, MS_VENDOR_ATTR, (MANDITORY_FLAG | VENDOR_FLAG), (u_char *)&mschap_answer, 50, (u_char *)&out_data[avp_offset], &avp_out_size);  avp_offset+=avp_out_size;  *out_size = avp_offset;  if (username != NULL)    {      free(username);      username = NULL;    }  if (password != NULL)    {      free(password);      password = NULL;    }}// For phase 2 CHAP, we need to get an implicit_challenge from the phase 1,// and use the first 16 bytes for challenge, and the 17th byte as the ID.// Then, to find the CHAP password hash, we find MD5(id + password + // challenge).  Then, we need to send 3 AVPs back to the authenticator.// The username, challenge, and password AVPs.  Where the challenge is the// 16 bytes from the implicit challenge.  void ttls_do_chap(char *out_data, int *out_size){  u_char *challenge = NULL, *tohash = NULL;  u_char *user_passwd = NULL;  u_char chap_challenge[18], chap_hash[17];  uint8_t session_id;  int username_size, avp_out_size;  int avp_offset, md5_length, hashlen;  EVP_MD_CTX *ctx=NULL;  char *username = NULL;  username = get_phase2id();  username_size = strlen(username);  build_avp(USER_NAME_AVP, 0, MANDITORY_FLAG, (u_char *)username, username_size, (u_char *)out_data, &avp_out_size);  avp_offset = avp_out_size;  // Get the implicit challenge.  challenge = (u_char *)implicit_challenge();  assert(challenge != NULL);  memcpy(&chap_challenge, challenge, 16);  session_id = challenge[16];  // Build the password hash.  ctx = (EVP_MD_CTX *)malloc(sizeof(EVP_MD_CTX));  if (ctx == NULL)    {      return;    }  user_passwd = (u_char *)get_password();  if(username!=NULL)    {      free(username);      username = NULL;    }  tohash = (u_char *)malloc(1+16+strlen((char *)user_passwd));  if (tohash == NULL)    {      return;    }  tohash[0] = session_id;  memcpy(&tohash[1], user_passwd, strlen((char *)user_passwd));  memcpy(&tohash[1+strlen((char *)user_passwd)], &chap_challenge, 16);  hashlen = 1+strlen((char *)user_passwd)+16;  free(user_passwd);   // We are done with it.  user_passwd = NULL;    EVP_DigestInit(ctx, EVP_md5());  EVP_DigestUpdate(ctx, tohash, hashlen);  EVP_DigestFinal(ctx, (u_char *)&chap_hash[1], (uint32_t *)&md5_length);    if (md5_length != 16)  // We didn't get back a valid hash!    {    }  chap_hash[0]=session_id;  build_avp(CHAP_PASSWORD_AVP, 0, MANDITORY_FLAG, (u_char *)chap_hash, 17, (u_char *)&out_data[avp_offset], &avp_out_size);  avp_offset += avp_out_size;  build_avp(CHAP_CHALLENGE_AVP, 0, MANDITORY_FLAG, (u_char *)&chap_challenge, 16, (u_char *)&out_data[avp_offset], &avp_out_size);  if (tohash != NULL)    {      free(tohash);      tohash = NULL;    }  if (ctx != NULL)    {      free(ctx);      ctx = NULL;    }  if (user_passwd != NULL) free(user_passwd);  *out_size = avp_offset+avp_out_size;}void ttls_do_pap(char *out_data, int *out_size){  char *username, *password, *tempbuf;  int username_size, passwd_size, avp_out_size, avp_offset;  // Get the username from our configuration.  (We should probably change this  // to allow a different username in phase 2... But, for now use the phase  // one name.)  username = get_phase2id();  password = get_password();  avp_offset = 0;  username_size = strlen(username);  build_avp(USER_NAME_AVP, 0, MANDITORY_FLAG, (u_char *)username, username_size, (u_char *)out_data, &avp_out_size);  avp_offset += avp_out_size;  // We have the username AVP loaded, so it's time to build the password AVP.  passwd_size = (strlen(password) + (16-(strlen(password) % 16)));  tempbuf = (char *)malloc(passwd_size);  if (tempbuf == NULL)    {      return;    }  memset(tempbuf, 0, passwd_size);
  memcpy(tempbuf, password, strlen(password));  build_avp(USER_PASSWORD_AVP, 0, MANDITORY_FLAG, (u_char *)tempbuf, passwd_size, (u_char *)&out_data[avp_offset], &avp_out_size);  *out_size = avp_offset + avp_out_size;    if (password != NULL)     {      free(password);      password=NULL;    }  if (username != NULL)    {      free(username);      username=NULL;    }  if (tempbuf != NULL)    {      free(tempbuf);      tempbuf = NULL;    }}// We don't do anything with the "in" stuff for now..void ttls_do_phase2(char *in, int in_size, char *out, int *out_size){  int i;  char *phase2name=NULL;  // We need to see what phase 2 method we should use.  // First, make sure that the method name is in all caps.  phase2name = get_phase2auth();  if (phase2name != NULL)    {      for (i=0;i<strlen(phase2name);i++)	{	  phase2name[i] = toupper(phase2name[i]);	}      i = 0;      while ((phase2_auth_types[i]!=NULL) && (strncmp(phase2name, phase2_auth_types[i], strlen(phase2name)) != 0))	{	  i++;	}      if (phase2_auth_types[i] == NULL)	{	  ttls_do_pap(out, out_size);	} else {	  (*phase2_method[i])(out, out_size);	}    } else {      ttls_do_pap(out, out_size);    }
  if (phase2name != NULL)     {      free(phase2name);      phase2name = NULL;    }

}

⌨️ 快捷键说明

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