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

📄 eapol.cpp

📁 source_code 实现无线局域网中的802.1x功能
💻 CPP
📖 第 1 页 / 共 2 页
字号:
		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()) {
	  printf("initialize\n");
    eapol_pae_set_state(DISCONNECTED);
  }
  else if (get_eapSuccess() && !get_initialize()) {
    printf("eapSuccess\n");
	  eapol_pae_set_state(AUTHENTICATED);
    xsupplicant_run_auth = 1;
  }
  else if(get_eapFail() && !get_initialize() && !get_userLogoff() && !get_logoffSent()) {
    printf("eapFail\n");
	  eapol_pae_set_state(HELD);
  }
  else if((get_userLogoff() && !get_logoffSent()) && !(get_initialize())) {
    printf("userLogoff\n");
	  eapol_pae_set_state(LOGOFF);
  }

  switch(eapol_get_current_state()) {

  case CONNECTING:
	printf("enter CONNECTING\n");
    // 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))
	    {
			printf("Sending EAPOL-Start #%d\n",get_startCount());
		    txStart();
	    } else {
			printf("No authenticator found! Assuming the port is authorized!\n");
			eapol_pae_set_state(AUTHENTICATED);
			xsupplicant_run_auth = 1;
			eapol_pae_transition_state(); // This may not be needed.
	    }
	  }
      }
    break;

  case AUTHENTICATED:
    printf("enter AUTHENTICATED\n");
    set_eapSuccess(FALSE);
    set_eapFail(FALSE);
    set_suppStatus(AUTHORIZED);
    break;
  case ACQUIRED:
	  printf("enter ACQUIRED\n");
    if (get_reqId() == TRUE)  // Do we have an ID request?
      {
		printf("Connection Established, authenticating...\n");
        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:
	  printf("enter AUTHENTICATING\n");
    if (get_reqAuth())
      {
		printf("authenticating\n");
        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:
	  printf("enter HELD\n");
    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:
	  printf("enter LOGOFF\n");
        //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 */
	printf("enter DISCONNECTED\n");
    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);
		  memcpy(eapol_dst, &ethHeader->eth_src, 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.
	printf("EAP-reqAuth\n");         
		set_reqAuth(TRUE);

      break;
    case 1:
      printf("EAP-reqId\n");
		set_reqId(TRUE);

      break;
    case 3:
	  printf("Authentication Succeeded\n");
      set_eapSuccess(TRUE);

      break;
    case 4:
	  printf("Failed to Authenticate\n");
      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;
}

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;

}

⌨️ 快捷键说明

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