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

📄 eapol.cpp

📁 source_code 实现无线局域网中的802.1x功能
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// This function is defined by the standard (8.5.10.1.3(d)), and sends an
// EAP Response Authentication frame.
int txRspAuth(int prevId, int revId)
{
  const int mac_header_size = 14;
  u_char *resp_out=NULL;
  int resp_out_size=0, i=0;
  u_char *src_mac = NULL;
  u_char *tmp = NULL;

  resp_out = (u_char *)malloc(1514);  // Again, this is the largest frame we can send.
  memcpy(resp_out, eapol_dst, 6);
	
  src_mac = get_src_mac();
  memcpy(&resp_out[6], src_mac, 6);
  resp_out[12] = 0x88;                       // 0x888e for EAPOL
  resp_out[13] = 0x8e;
  free(src_mac);
  src_mac = NULL;

  tmp = get_working_frame();                 // This should be the request frame.
  i = (((u_char) tmp[16] << 8) | (u_char)tmp[17]);

  // Pass in the frame, minus the header.
  if (eap_build_auth_response(&tmp[14], i, resp_out, &resp_out_size) == -1)
  {
      resp_out = NULL;
      return -1;
  } 
  else 
  {
      send_frame(resp_out, resp_out_size);
      free(resp_out);
      resp_out = NULL;
  }
  return 0;
}

void eapol_pae_set_state(EapolStates newState)
{
  // Set the last state to the current state
  eapol_last_state = eapol_current_state;
  
  //Set the current state to a new state
  eapol_current_state = newState;
}

int eapol_pae_do_state()
{
  int retVal = 0;

  if (get_initialize()) 
  {
    eapol_pae_set_state(DISCONNECTED);
  }
  else if (get_eapSuccess() && !get_initialize()) 
  {
    eapol_pae_set_state(AUTHENTICATED);
    xsupplicant_run_auth = 1;
  }
  else if(get_eapFail() && !get_initialize() && !get_userLogoff() && !get_logoffSent()) 
  {
    eapol_pae_set_state(HELD);
  }
  else if((get_userLogoff() && !get_logoffSent()) && !(get_initialize())) 
  {
    eapol_pae_set_state(LOGOFF);
  }

  switch(eapol_get_current_state()) {

  case CONNECTING:
	// If we just transitioned to Connecting, we need to set the variables.
    // otherwise, we need to decrement, and possibly send an EAPOL-Start.
    if (eapol_get_last_state() != CONNECTING)
		{
			set_startWhen(startPeriod);
			set_startCount(0);
			set_reqId(FALSE);
			txStart();
		} 
	else 
		{
            set_startWhen(get_startWhen() - 1);
			if (get_startWhen() <= 0)
			{
				set_startCount(get_startCount() + 1);
				set_startWhen(startPeriod);

				if ((get_startCount() < 3))
				{
					txStart();
				} 
				else 
				{
				
					eapol_pae_set_state(AUTHENTICATED);
					xsupplicant_run_auth = 1;
					eapol_pae_transition_state(); // This may not be needed.
				}
			}
		}
    break;

  case AUTHENTICATED:
    set_eapSuccess(FALSE);
    set_eapFail(FALSE);
    set_suppStatus(AUTHORIZED);
    break;
  case ACQUIRED:
	if (get_reqId() == TRUE)  // Do we have an ID request?
    {
		txRspId(get_previousId(), get_receivedId());
        set_authWhile(authPeriod);
        set_startCount(0);
        set_reqId(FALSE);
        set_reqAuth(FALSE);
    }
    if (get_authWhile() <= 0)
    {
        set_authWhile(authPeriod);
        txRspId(get_previousId(), get_receivedId());
    } 
	else 
	{
        set_authWhile(get_authWhile() - 1);
    }
    
    set_previousId(get_receivedId());


    break;

  case AUTHENTICATING:
	if (get_reqAuth())
    {
	    set_authWhile(authPeriod);
        set_reqAuth(FALSE);
        if (txRspAuth(get_previousId(), get_receivedId()) < 0)
		{ 
			return -1;
		}
    } 
    if (get_authWhile() <= 0)
    {
        set_authWhile(authPeriod);
        if (txRspAuth(get_previousId(), get_receivedId()) < 0) return -1;
    }

    set_previousId(get_receivedId());

    break;

  case HELD:
	if(eapol_get_current_state() != eapol_get_last_state())
    {
		set_heldWhile(heldPeriod);
		set_eapFail(FALSE);
		set_eapSuccess(FALSE);
		set_suppStatus(UNAUTHORIZED);
	
    }
    else
    {
		if (get_heldWhile() <= 0)  // We need to transition back to CONNECTING
		{
			eapol_pae_set_state(CONNECTING);
		} 
		else 
		{
			set_heldWhile(get_heldWhile() - 1);
		}
    }
    break;
  case LOGOFF:
    //Send a logoff
    txLogoff();
    set_logoffSent(TRUE);
    set_suppStatus(UNAUTHORIZED);
    break;
  case DISCONNECTED:
    /* The 802.1x spec calls for an unconditional transition to CONNECTING from DISCONNECTED state */
	set_eapSuccess(FALSE);
    set_eapFail(FALSE);
    set_startCount(0);
    set_logoffSent(FALSE);
    set_previousId(256);
    set_suppStatus(UNAUTHORIZED);
    set_initialize(0);
    eapol_pae_set_state(CONNECTING); /* automatic transition because
					We already setup link */
    /* xsupplicant-specifc stuff */
    set_haveKey(FALSE);
   
    break;
  default:

    retVal = -1;
    break;
  }

  if(eapol_get_current_state() != eapol_last_state)
    {
      eapol_last_state = eapol_get_current_state();
    }

  set_tick(FALSE);     //Set our tick to false as the last thing we do. 
                                 // Section (8.5.3.1.1)
  return retVal;
}

int eapol_pae_transition_state()
{
  int retVal = 0;
  
  switch(eapol_get_current_state()) 
  {
	case CONNECTING:
		if (get_reqId() == TRUE) 
		{
			eapol_pae_set_state(ACQUIRED);
		}
	break;
	case ACQUIRED:
		if (get_reqId() == TRUE) 
		{
			eapol_pae_set_state(ACQUIRED);
		}
		else if (get_reqAuth() == TRUE) 
		{
			eapol_pae_set_state(AUTHENTICATING);
		}
		else if (get_authWhile() == 0) 
		{
			eapol_pae_set_state(CONNECTING);
		}
    break;
	case AUTHENTICATING:
		if (get_reqId() == TRUE) 
		{
			eapol_pae_set_state(ACQUIRED);
		}
		else if (get_reqAuth() == TRUE) 
		{
			eapol_pae_set_state(AUTHENTICATING);
		}
		else if (get_authWhile() == 0) 
		{
			eapol_pae_set_state(CONNECTING);
		}
    break;
	case HELD:
		if (get_heldWhile() == 0) 
		{
			eapol_pae_set_state(CONNECTING);
		}
		if (get_reqId() == TRUE) 
		{
			eapol_pae_set_state(ACQUIRED);
		}
    break;
	case AUTHENTICATED:
		if (get_reqId() == TRUE) 
		{
			eapol_pae_set_state(ACQUIRED);
		}
    break;
	case LOGOFF:
		if(!get_userLogoff()) 
		{
			eapol_pae_set_state(DISCONNECTED);
		}
    break;
	case DISCONNECTED:
    /* 802.1x specifies that you must unconditionally transition from
       DISCONNECTED to CONNECTED, but we handle this in eap_pae_do_state()
       in the DISCONNECTED case.  */
    break;
  }
  return retVal;
}

u_char *
eapol_create_start_stop_frame(char stst)
{
  u_char *eapol_start;
  u_char *src_addr;

  eapol_start = (u_char *)malloc(18);  // An eapol start frame is 18 bytes.

  memcpy(eapol_start, eapol_dst, 6);  // Copy the destination address.

  src_addr = get_src_mac();
  memcpy(&eapol_start[6], src_addr, 6);  // Copy the source address.
  free(src_addr);
  src_addr = NULL;

  eapol_start[12] = 0x88;                // 0x888e is EAPOL frame type.
  eapol_start[13] = 0x8e;
  eapol_start[14] = 1;                   // EAPOL_Version
  eapol_start[15] = stst;                // Start or Stop
  eapol_start[16] = 0;                   // No payload.
  eapol_start[17] = 0;

  return eapol_start;
}

int
eapol_decode_packet(u_char *in)
{
  struct eth_hdr * ethHeader = (struct eth_hdr *)in;
  /* The eapol header portion */
  struct eapol_hdr * theHeader = (struct eapol_hdr *)(in + ETH_HDR_LEN);

  /* Just the payload */
  u_char * payload = in + ETH_HDR_LEN + sizeof(struct eapol_hdr);
  
  int receive_packet_size;
  struct eap_type_hdr *theTypeHeader = (struct eap_type_hdr *)payload;
  /* The payload size */
  int retVal = 0;  /* default to success */
  int eap_return = 0;
  u_char *my_src = NULL;
#ifdef NAK_SUPPORT
  char *temp = NULL;
#endif
   

  /* Major confusion going on here --- figure out this packet len crap */
  receive_packet_size = (int)ntohs(theHeader->len) + 
    sizeof(struct eapol_hdr);
  
  my_src = get_src_mac();

    if (memcmp(&in[6], my_src, ETH_ADDR_LEN) == 0)
    {
      free(my_src);
      my_src = NULL;
      return 0;
    }

  free(my_src);
  my_src = NULL;

  if (memcmp(eapol_dst, &ethHeader->eth_src, ETH_ADDR_LEN) != 0) 
  {

      // If the destination host from the authenticator isn't us, then
      // don't change it.
      if (memcmp(eapol_dst, &ethHeader->eth_dst, ETH_ADDR_LEN) != 0)
	  {
		  memcpy(eapol_dst, bssid, ETH_ADDR_LEN);
	  }
      /* need to update what network we are on */
  }
  else
  {
      set_initialize(0);
  }
	
  /* first set flags based on the incoming PDU */
  switch (theHeader ->eaptype) 
  {
  case EAP_PACK_TYPE:

    /* See what EAP thinks about the packet-
       EAP knows whether or not to send a respId so the state machine will
       remain consistent, but this isn't really necessary */
    set_receivedId(theTypeHeader->id);

    eap_return = eap_decode_packet(in);

    switch (eap_return) 
	{
    case -1:
		retVal = -1;
		goto eapol_decode_packet_END;
    break;
    case 0:  // Here, we need to check and see if the EAP type we want is being used.
		set_reqAuth(TRUE);
    break;
    case 1:
		set_reqId(TRUE);
    break;
    case 3:
        set_eapSuccess(TRUE);
    break;
    case 4:
        set_eapFail(TRUE);      
        eapol_pae_set_state(HELD);
    break;
    }
    /* DO the stuff here to put together the return packet, given the 
       payload from eap_decode */
  break;
  case EAPOL_START:
    //We will probably see EAPOL-Start messages from other clients in a 
    // shared media configuration.  (Such as wireless)  We should just
    // ignore them.
      retVal = 0;
      goto eapol_decode_packet_END;
  break;
  case EAPOL_LOGOFF:
    //We will probably see EAPOL-Logoff messages from other clients in a 
    // shared media configuration.  (Such as wireless)  We should just
    // ignore them.
    retVal = 0;
    goto eapol_decode_packet_END;
  break;
  case EAPOL_KEY:
    set_rxKey(TRUE);
  break;
  case EAPOL_ASF_ALERT:
  break;
  default:
	return -1;
  }
  
  eapol_decode_packet_END:
  return retVal;

}


int eapol_wireless_get_ssid(char *devname, char *retssid)
{
  retssid = NULL;
  return -1;
}


int
eapol_wireless_get_bssid(char *device, u_char *bssid)
{
  int skfd;            /* the socket */
  struct iwreq wrq;

  /* Get a socket */
  skfd = socket(AF_INET, SOCK_DGRAM, 0);
  
  strncpy(wrq.ifr_name, device, IFNAMSIZ);
  memcpy(bssid, wrq.u.ap_addr.sa_data, 6);
  close(skfd);
  return 0;
}

⌨️ 快捷键说明

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