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

📄 eapol.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 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 <pcap.h>
#include <libnet.h>#include <unistd.h>#include <errno.h>#include <stdlib.h>
#include <signal.h>#include "dot1x_globals.h"
#include "eapol.h"#include "os_frame_funcs.h"#include "os_wireless_ext.h"#include "userconf.h"#ifndef EAPOL_DEBUG#define EAPOL_DEBUG 0#endif #define NAK_SUPPORT    // FreeRadius doesn't support this!/** GLOBAL VARS **/// moved to 802.1x spec. globals to dot1x_globals.hunsigned int successCount = 0;unsigned int failCount    = 0;/* IEEE 802.1x default recommendations *//* Note that these don't need to be strict consts *//* IEEE 802.1x specifies that the state machine shouldn't *//* modify these values, so in that way, they are const, but not otherwise */const int authPeriod = 30;const int heldPeriod = 60;const int startPeriod = 30;const int maxStart = 3;/* Globals for this specific implementation */u_char *eapol_src = NULL;   /* MAC address of interface */
u_char ETH_HDR_LEN = 14 ;
u_char eapol_dst[ETH_ADDR_LEN] ; //addu_char bssid[ETH_ADDR_LEN] = {0x01, 0x80, 0xc2, 0x00, 0x00, 0x03};  /* MAC address of authenticator */
char * eapol_device = NULL; /* Interface name */char * eapol_config = "1x.conf"; /* Configuration File */char eapol_ssid[100] = "";  /* network name */int xsupplicant_first_auth = 0;int xsupplicant_run_auth = 0;int xsupplicant_auth_command_pid = 0;  // pid could never be 0EapolStates eapol_current_state = DISCONNECTED;EapolStates eapol_last_state    = DISCONNECTED;KeyReceiveStates eapol_key_receive_state;
unsigned char is_wired = FALSE;
//Return the current state of the state machine.
EapolStates eapol_get_current_state()
{
  return eapol_current_state;
}

CString get_current_state() //for GUI
{
	CString text;

	if (eapol_current_state == 0)
		text="LOGOFF";
	else if (eapol_current_state == 1)
		text="DISCONNECTED";
	else if (eapol_current_state == 2)
		text="CONNECTING";
	else if (eapol_current_state == 3)
		text="ACQUIRED";
	else if (eapol_current_state == 4)
		text="AUTHENTICATING";
	else if (eapol_current_state == 5)
		text="HELD\n(You fail the authentication!)";
	else if (eapol_current_state == 6)
		text="AUTHENTICATED\n(You are authenticated successfully!)";

	return text;

}

//Return the last state of the state machine.
EapolStates eapol_get_last_state()
{
	return eapol_last_state;
}

int getFailCount()
{
    return failCount;
}

int getSuccessCount()
{
    return successCount;
}

int init_eapol(char *device, char *netid, u_char *auth_addr, 
	       char *config)
{
  int retVal = 0; /* default to success */
  char *reterr;   // Pointer to hold an error return code.
  char *temp_char;
  char *wired_type = "WIRED";

  // Initalize the frame functions.
  reterr = initalize_frame_funcs(device, 1700, 0);
  eapol_device = get_dev_name();
  if (eapol_device == NULL) return -1;   //If we can't get an address name, die
  printf("Setup on device %s complete\n", eapol_device);
  
  /* setup config file */
  if (config != NULL) {

  }

  /* set authenticator address */
  if (auth_addr != NULL) 
  {
       printf("Setting destination to : %x:%x:%x:%x:%x:%x\n", auth_addr[0],
	   auth_addr[1], auth_addr[2], auth_addr[3], auth_addr[4],
	   auth_addr[5]);
       //memcpy(eapol_dst, auth_addr, ETH_ADDR_LEN);
	   memcpy(eapol_dst, bssid, ETH_ADDR_LEN);      //Nov.27
  }
  else 
  {
      temp_char = get_client_type();
	  if (temp_char == NULL || (strncmp(temp_char, "WIRELESS", strlen(temp_char))==0))
	  {
		if (eapol_wireless_get_bssid(eapol_device, eapol_dst)==-1) 
		{
			printf("Specific Wireless Authenticator MAC not found, using default destination\n");
		}

	  /* determine network name */
		if (netid != NULL) 
		{
			strncpy(eapol_ssid, netid, 99);
			if (strlen(netid) >= 100) 
			{
				printf("Network ID too long\n");
				return -1;
			}
		}
     
		else if (eapol_wireless_get_ssid(eapol_device, eapol_ssid) == -1) 
		{ 
			strncpy(eapol_ssid,"default\0",8);
		}
	  } 
	  else 
	  {
		printf("This connection has been forced to a wired connection!  The network name will be 'default'\n");
		strncpy(eapol_ssid,"default\0",8);
		is_wired=TRUE;
      }
  }

  /* Establish our global variables. */
  set_initialize(1);
  eapol_pae_transition_state();  // We need to transition to the correct state

  /* initialize lower layer */
  if (init_eap(eapol_config, eapol_ssid) != 0)
    {
      printf("Problems initalizing EAP methods!\n");
      return -1;
    }

  printf("Done with init.\n");
  return retVal;
}

void eapol_handle_logoff()
{
  /* This is a kludge.  We should really be checking to see
     if we have an interface to pass frames to, otherwise we segfault. */
  
  if(eapol_get_current_state() == AUTHENTICATED)
    {
      set_userLogoff(1);
      eapol_pae_transition_state();
      eapol_pae_do_state();
      set_userLogoff(0);
    }
}

// Clean up
int eapol_shutdown()
{
  eapol_handle_logoff();
  shutdown_frame_funcs();
  return 0;
}


int 
eapol_authenticate()
{
  /* general setup */
  u_char *frame_ptr = NULL;
  int retVal = 0; /* default to success */

    /* if we have a different bssid than previously, inititialize */
  if (eapol_pae_do_state() < 0) { return -1;}
    /* get the next frame */
    while (frame_ptr == NULL)
    {
        //Check for logoff
		if(get_userLogoff())
		{
			if(eapol_get_current_state() == LOGOFF) // We're trying to logoff... return -1 
			{
				return -1;
			}
		}


	// If the sleep value for get_frame is too high, we will miss frames
	// and may fail the next authentication request.  If the value is
	// too low, we will waste a lot of processor time, and eat laptop
	// batteries.
		if (more_frames() == 1)   // We have more frames, so don't wait before
		{                       // checking.
			frame_ptr = get_frame(0);   
		} 
		else 
		{
			frame_ptr = get_frame(1000);  // Wait 1/4th of a second.            
		}
	
		if (get_tick()==TRUE) 
		{
			if (eapol_pae_do_state() < 0) return -1;
		}

	// We need to keep the event loop in 1xdriver.c going.
	// If we get this far, and the frame_ptr is NULL, we should return 0;
		if(frame_ptr == NULL)
		{
			return 0;
		}
	}

    if (frame_ptr != NULL)
      /* decode the packet and get the next response back*/
		if((retVal = eapol_decode_packet(frame_ptr)) == -1)
		{
			return retVal;
		}
    /* Based on the received packet, go to the next state of each machine */
    eapol_pae_transition_state();

    done_with_current_frame();   // This should destroy the frame in memory.
    if (frame_ptr != NULL) 
    {
		frame_ptr = NULL;
    }
    
	return retVal;
}
void xsupplicant_shutdown_auth()
{
   xsupplicant_auth_command_pid = 0;
}

void xsupplicant_post_auth()
{
	char *command = NULL;
  // if it's the first transition to auth
  /** XXX Use something other than popen here, we really want it to die
      when we close it */
	if (xsupplicant_run_auth && !xsupplicant_first_auth) 
	{
		if ((command = get_first_auth()) != NULL) 
		{
			if (xsupplicant_auth_command_pid)
			xsupplicant_shutdown_auth();
			if (xsupplicant_auth_command_pid == 0 )
			{
 				exit(0);
			}
			else if (xsupplicant_auth_command_pid == -1) 
			{
			}
		}
		// never do that again
		xsupplicant_first_auth = 1;
	}
  // all other transitions to auth
	else if(xsupplicant_run_auth) 
	{
		if ((command = get_after_auth()) != NULL) 
		{
			if (xsupplicant_auth_command_pid)
			xsupplicant_shutdown_auth();
			if (xsupplicant_auth_command_pid == 0 )
			{
				exit(0);
			}
			else if (xsupplicant_auth_command_pid == -1) 
			{

			}
		}
	}
	if (command) free(command);
	// unconditionally say we have done something
	xsupplicant_run_auth = 0;
  
}

/**** LOW LEVEL FUNCTIONS****/
/* Only Functions defined in EAPOL should call these */

// This function is defined by the standard (8.5.10.1.3(a)), and sends an 
// EAPOL-Start frame.
void txStart()
{
  u_char *temp;
  temp = eapol_create_start_stop_frame(EAPOL_START);
  send_frame(temp, 18);
  if (send_frame(temp, 18) == NULL)
  free(temp);
  temp = NULL;
}

// This function is defined by the standard (8.5.10.1.3(b)), and sends an
// EAPOL-Logoff frame.
void txLogoff()
{
  u_char *temp;
  temp = eapol_create_start_stop_frame(EAPOL_LOGOFF);
  send_frame(temp, 18);
  free(temp);
  temp = NULL;
}

// This function is defined by the standard (8.5.10.1.3(c)), and sends an
// EAP Response, Identity frame.
void txRspId(int prevId, int revId)
{
  const int mac_header_bytes = 14;
  u_char *resp_out = NULL;
  int resp_out_size = 0;
  u_char *src_mac = NULL;

  resp_out = (u_char *)malloc(1514);   // 1514 is the largest frame we could send.
  memcpy(resp_out, eapol_dst, 6);
  src_mac = get_src_mac();

  if(src_mac == NULL)
    {
      printf("ACK! src_mac is NULL in txRspId! (We're going to crash.)\n");
    }

  memcpy(&resp_out[6], src_mac, 6); 
  free(src_mac);
  src_mac = NULL;
  resp_out[12] = 0x88;   // 0x888e is an EAPOL frame
  resp_out[13] = 0x8e;

  if (eap_build_responseId(resp_out, &resp_out_size) == -1) 
  {
	free(resp_out);
    resp_out = NULL;
  } 
  else 
  {
	send_frame(resp_out, resp_out_size);  
    free(resp_out);
    resp_out = NULL;
  }
}

⌨️ 快捷键说明

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