📄 eapol.cpp
字号:
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:
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:
//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, ðHeader->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, ðHeader->eth_dst, ETH_ADDR_LEN) != 0)
{
memcpy(eapol_dst, bssid, ETH_ADDR_LEN);
//memcpy(eapol_dst, ðHeader->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 + -