int ibss_rsn_rx_eapol(struct ibss_rsn *ibss_rsn, const u8 *src_addr, const u8 *buf, size_t len) { struct ibss_rsn_peer *peer; if (ibss_rsn == NULL) return -1; peer = ibss_rsn_get_peer(ibss_rsn, src_addr); if (peer) return ibss_rsn_process_rx_eapol(ibss_rsn, peer, buf, len); if (ibss_rsn_eapol_dst_supp(buf, len) > 0) { /* * Create new IBSS peer based on an EAPOL message from the peer * Authenticator. */ peer = ibss_rsn_peer_init(ibss_rsn, src_addr); if (peer == NULL) return -1; /* assume the peer is authenticated already */ wpa_printf(MSG_DEBUG, "RSN: IBSS Not using IBSS Auth for peer " MACSTR, MAC2STR(src_addr)); ibss_rsn_peer_authenticated(ibss_rsn, peer, IBSS_RSN_AUTH_EAPOL_BY_US); return ibss_rsn_process_rx_eapol(ibss_rsn, ibss_rsn->peers, buf, len); } return 0; }
static void ibss_rsn_handle_auth_1_of_2(struct ibss_rsn *ibss_rsn, struct ibss_rsn_peer *peer, const u8* addr) { wpa_printf(MSG_DEBUG, "RSN: IBSS RX Auth frame (SEQ 1) from " MACSTR, MAC2STR(addr)); if (peer && peer->authentication_status & (IBSS_RSN_SET_PTK_SUPP | IBSS_RSN_SET_PTK_AUTH)) { /* Clear the TK for this pair to allow recovery from the case * where the peer STA has restarted and lost its key while we * still have a pairwise key configured. */ wpa_printf(MSG_DEBUG, "RSN: Clear pairwise key for peer " MACSTR, MAC2STR(addr)); wpa_drv_set_key(ibss_rsn->wpa_s, WPA_ALG_NONE, addr, 0, 0, NULL, 0, NULL, 0); } if (peer && peer->authentication_status & IBSS_RSN_AUTH_EAPOL_BY_PEER) { if (peer->own_auth_tx.sec) { struct os_reltime now, diff; os_get_reltime(&now); os_reltime_sub(&now, &peer->own_auth_tx, &diff); if (diff.sec == 0 && diff.usec < 500000) { wpa_printf(MSG_DEBUG, "RSN: Skip IBSS reinit since only %u usec from own Auth frame TX", (int) diff.usec); goto skip_reinit; } } /* * A peer sent us an Authentication frame even though it already * started an EAPOL session. We should reinit state machines * here, but it's much more complicated than just deleting and * recreating the state machine */ wpa_printf(MSG_DEBUG, "RSN: IBSS Reinitializing station " MACSTR, MAC2STR(addr)); ibss_rsn_stop(ibss_rsn, addr); peer = NULL; } if (!peer) { peer = ibss_rsn_peer_init(ibss_rsn, addr); if (!peer) return; wpa_printf(MSG_DEBUG, "RSN: IBSS Auth started by peer " MACSTR, MAC2STR(addr)); } skip_reinit: /* reply with an Authentication frame now, before sending an EAPOL */ ibss_rsn_send_auth(ibss_rsn, addr, 2); /* no need to start another AUTH challenge in the other way.. */ ibss_rsn_peer_authenticated(ibss_rsn, peer, IBSS_RSN_AUTH_EAPOL_BY_US); }
static void ibss_rsn_handle_auth_1_of_2(struct ibss_rsn *ibss_rsn, struct ibss_rsn_peer *peer, const u8* addr) { wpa_printf(MSG_DEBUG, "RSN: IBSS RX Auth frame (SEQ 1) from " MACSTR, MAC2STR(addr)); if (peer && peer->authentication_status & IBSS_RSN_AUTH_EAPOL_BY_PEER) { if (peer->own_auth_tx.sec) { struct os_reltime now, diff; os_get_reltime(&now); os_reltime_sub(&now, &peer->own_auth_tx, &diff); if (diff.sec == 0 && diff.usec < 500000) { wpa_printf(MSG_DEBUG, "RSN: Skip IBSS reinit since only %u usec from own Auth frame TX", (int) diff.usec); goto skip_reinit; } } /* * A peer sent us an Authentication frame even though it already * started an EAPOL session. We should reinit state machines * here, but it's much more complicated than just deleting and * recreating the state machine */ wpa_printf(MSG_DEBUG, "RSN: IBSS Reinitializing station " MACSTR, MAC2STR(addr)); ibss_rsn_stop(ibss_rsn, addr); peer = NULL; } if (!peer) { peer = ibss_rsn_peer_init(ibss_rsn, addr); if (!peer) return; wpa_printf(MSG_DEBUG, "RSN: IBSS Auth started by peer " MACSTR, MAC2STR(addr)); } skip_reinit: /* reply with an Authentication frame now, before sending an EAPOL */ ibss_rsn_send_auth(ibss_rsn, addr, 2); /* no need to start another AUTH challenge in the other way.. */ ibss_rsn_peer_authenticated(ibss_rsn, peer, IBSS_RSN_AUTH_EAPOL_BY_US); }
void ibss_rsn_handle_auth(struct ibss_rsn *ibss_rsn, const u8 *auth_frame, size_t len) { const struct ieee80211_mgmt *header; struct ibss_rsn_peer *peer; size_t auth_length; header = (const struct ieee80211_mgmt *) auth_frame; auth_length = IEEE80211_HDRLEN + sizeof(header->u.auth); if (ibss_rsn == NULL || len < auth_length) return; if (le_to_host16(header->u.auth.auth_alg) != WLAN_AUTH_OPEN || le_to_host16(header->u.auth.status_code) != WLAN_STATUS_SUCCESS) return; peer = ibss_rsn_get_peer(ibss_rsn, header->sa); switch (le_to_host16(header->u.auth.auth_transaction)) { case 1: ibss_rsn_handle_auth_1_of_2(ibss_rsn, peer, header->sa); break; case 2: wpa_printf(MSG_DEBUG, "RSN: IBSS RX Auth frame (SEQ 2) from " MACSTR, MAC2STR(header->sa)); if (!peer) { wpa_printf(MSG_DEBUG, "RSN: Received Auth seq 2 from " "unknown STA " MACSTR, MAC2STR(header->sa)); break; } /* authentication has been completed */ eloop_cancel_timeout(ibss_rsn_auth_timeout, peer, NULL); wpa_printf(MSG_DEBUG, "RSN: IBSS Auth completed with " MACSTR, MAC2STR(header->sa)); ibss_rsn_peer_authenticated(ibss_rsn, peer, IBSS_RSN_AUTH_BY_US); break; } }