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

📄 eap.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                                                    */
/**************************************************************************/

/**
 * 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 Bryan D. Payne & Nick L. Petroni Jr.
 * 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.
 */

/***
 *** Specifics for EAPOL can be found in Section 7 of 
 *** IEEE Draft P802.1X/D11,
 ***/
#include <stdafx.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <winsock2.h>
#include "dot1x_globals.h"
#include "os_frame_funcs.h"
#include "eap.h"
#include "eapmd5.h"    
#include "userconf.h"

#ifndef EAP_DEBUG
#define EAP_DEBUG 0
#endif

/** GLOBAL VARS **/
int eap_auth_types[] = {
  EAP_TYPE_MD5,
  NO_EAP_AUTH
};

char *eap_auth_names[] = {
  "MD5",
};

int (*eap_auth_inits[])(char *, char *) = {
  init_eapmd5,
};

int (*eap_auth_challenge[])() = {
  eapmd5_auth_challenge,
};

int (*eap_auth_handlers[])(u_char *, int, u_char *, int *) = {
  eapmd5_decode_packet,
};

int (*eap_auth_cleanup[])() = {
  eapmd5_shutdown,
}; 

char *eap_config;
char *eap_netid;

/** FUNCTION DEFINITIONS **/
int init_eap(char *config, char *netid)
{
  int auth = 0;
  eap_config = config;
  eap_netid = netid;

  /* Initialize Auth types */
  while (eap_auth_types[auth] != NO_EAP_AUTH) 
  {
    if ((*eap_auth_inits[auth++])(config, netid) != 0)
    {
		printf("Couldn't initalize eap type : %s\n", eap_auth_names[auth]);
		printf("If you are trying to use this authentication method, it probably won't work!\n");
    }
  }
  return 0;
}

//Check to see if we have a valid EAP type.  (If so, return the auth index.)
int is_valid_eap(char *in_eap)
{
  int auth=0;

  while ((strncmp(eap_auth_names[auth], in_eap, strlen(in_eap) != 0)) &&
	 (eap_auth_types[auth] != NO_EAP_AUTH))
  {
    // We don't have a match.  Check the next one.
    auth++;
  }

  if (eap_auth_types[auth] != NO_EAP_AUTH)
    {
      return eap_auth_types[auth];
    }

  return -1;   // We didn't find a match.
}

// Return a list of known EAP types.
char *return_known_eap_types()
{
  int auth = 0;
  char *eap_types;
  int eap_size=0;
  int num_types=0;
  char *comma_space = ", ";
  char *period = ".";

  while (eap_auth_types[auth] != NO_EAP_AUTH)
    {
      eap_size+=strlen(eap_auth_names[auth]);
      eap_size+=2;  // for a comma and space.
      auth++;
      num_types++;
    }

  auth = 0;
  eap_types = (char *)malloc(eap_size);  // Build a string big enough.
  eap_types[0] = 0x00;  // Set the first character to a NULL.

  while (eap_auth_types[auth] != NO_EAP_AUTH)
    {
		strcat(eap_types, eap_auth_names[auth]);
		if (auth < (num_types-1))
		{
			strcat(eap_types, comma_space);
		} 
		else 
		{
			strcat(eap_types, period);
		}
		auth++;
    }
  
  return eap_types;
}

// Call the shutdown routines for all of the authentication types.
int shutdown_eap()
{
  int auth = 0;

  while (eap_auth_types[auth] != NO_EAP_AUTH) 
  {
    (* eap_auth_cleanup[auth++])();
  }

  return 0;
}

// Here, we want to actually build a responseId.
int eap_build_responseId(u_char *out, int *out_size)
{
  const int eap_header_size = 5;
  char *temp_buf = NULL;
  int temp_size;
  struct my_eapol_header *eapol_header = (struct my_eapol_header *)out;
  struct my_eapol_packet *eapol_packet = (struct my_eapol_packet *)out;

  /* XXX Really, I would like to see us reparse here for the right network,
     but for now I am just checking to see we dont' segfault */
  temp_buf = get_username();
  if (temp_buf == NULL) 
	 return -1;
  temp_size = strlen(temp_buf);     // The username is appended to the frame.
                                    // So, we need to know how long it is.

  // Set up the EAP values needed for the frame.
  eapol_header->eapol_version = 1;
  eapol_header->eapol_type = EAPOL_PACKET;

  // The length value that is reported in the frame is the length of the EAP
	  // portion only.  So, the actual size of the frame will be 18 bytes larger.
  //  12 (src/dst MAC) + 2 (EAPOL Frame Type) + 4 (EAPOL Header)
  eapol_header->eapol_length = htons(eap_header_size+temp_size);
  eapol_packet->code = EAP_RESPONSE;
  eapol_packet->identifier = get_receivedId();
  eapol_packet->length = eapol_header->eapol_length;
  eapol_packet->type = EAP_TYPE_ID;

  // At offset 23 in to the frame, we should have non-header data, such as
  // the username.  Copy the username in to the frame.
  memcpy(&out[EAP_PAYLOAD_OFFSET], temp_buf, temp_size);

  // out_size should be the size of the data we created here.  Ignore the 
  // additional MAC header bytes, as they will be added by the calling function
  *out_size = EAP_PAYLOAD_OFFSET+temp_size;

  return 0;
}

// Build the frame that will carry our authentication response.
//
int eap_build_auth_response(u_char *in, int in_size, u_char *out, int *out_size)
{
  const int eapol_header_size = 5;
  int auth=0;
  u_char *temp_buf=NULL;
  u_char *payload = in + 9; // This is the first byte in the payload.
  struct my_eapol_header *eapol_header = (struct my_eapol_header *)out;
  struct my_eapol_packet *eapol_packet = (struct my_eapol_packet *)out;

  // This is the offset to get past the MAC header.
  int payload_size = in_size - 9;  // This is the payload size, minus all headers.
  int temp_size;

  // First, see if we have a handler for this case.
  while ((eap_auth_types[auth] != get_authType()) && (eap_auth_types[auth] != NO_EAP_AUTH))
    auth++;

  if (eap_auth_types[auth] == NO_EAP_AUTH)
  {
      return -1;
  }

  // Now, determine if this is our first authentication, or if we are
  // reauthenticating.
  if (get_suppStatus() != AUTHORIZED)
  {
      // We need to get a password, or some other authentication information.
      if ((eap_auth_challenge[auth])() < 0)
	  {
			return -1;
	  }
  }

  // Now, build the authentication answer.  (Allocate 1500 bytes, since our
  // ethernet MTU is 1514, but we aren't dealing with the 14 bytes for header.)
  temp_buf = (u_char *)malloc(1500);
  if ((* eap_auth_handlers[auth])(payload, payload_size, temp_buf, &temp_size) == -1) {
	return -1;
  }

  eapol_header->eapol_version = 1;
  eapol_header->eapol_type = EAPOL_PACKET;
  eapol_header->eapol_length = htons(eapol_header_size+temp_size);  //Make sure we have the correct byte order.
  eapol_packet->code = EAP_RESPONSE;
  eapol_packet->identifier = get_receivedId();
  eapol_packet->length = eapol_header->eapol_length;
  eapol_packet->type = eap_auth_types[auth];

  memcpy(&out[EAP_PAYLOAD_OFFSET], temp_buf, temp_size);

  free(temp_buf);  //We no longer need temp_buf

  *out_size = EAP_PAYLOAD_OFFSET+temp_size;

  return 0;
}


int eap_decode_packet(u_char *in)
{
  struct my_eapol_packet * mypacket = (struct my_eapol_packet *)(in);
  int retVal = 0;
  /* USE #defines here because the struct is not the same size as the
     actual header (padding) */

  /* decode based on the EAP code */
  switch(mypacket->code) {
   case EAP_REQUEST:
    switch(mypacket->type) {
    case EAP_TYPE_ID:
      retVal = 1;
      break;
    case EAP_TYPE_NOTIFY:
      printf("Received EAP Notify\n");
      break;
    case EAP_TYPE_NAK:
      printf("Received EAP NAK\n");
      break;
    default:
      set_authType(mypacket->type);
      retVal = 0;
    }
  
    break;

  case EAP_RESPONSE:
    printf("received EAP_RESPONSE packet -- error\n");
    retVal = 0;  // We should return an error here, but if we do the current code will cause the supplicant to die.
    break;

  case EAP_SUCCESS:
    retVal = 3;
    break;

  case EAP_FAILURE:
    retVal = 4;
    break;

  default:
    printf("Unknown EAP code type\n");
  }
  
  return retVal;
}

/*** EOF ***/

⌨️ 快捷键说明

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