示例#1
0
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.
		 */
		if (ibss_rsn_start(ibss_rsn, src_addr) < 0)
			return -1;
		return ibss_rsn_process_rx_eapol(ibss_rsn, ibss_rsn->peers,
						 buf, len);
	}

	return 0;
}
示例#2
0
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;
}
示例#3
0
int ibss_rsn_start(struct ibss_rsn *ibss_rsn, const u8 *addr)
{
	struct ibss_rsn_peer *peer;
	int res;

	if (!ibss_rsn)
		return -1;

	/* if the peer already exists, exit immediately */
	peer = ibss_rsn_get_peer(ibss_rsn, addr);
	if (peer)
		return 0;

	peer = ibss_rsn_peer_init(ibss_rsn, addr);
	if (peer == NULL)
		return -1;

	/* Open Authentication: send first Authentication frame */
	res = ibss_rsn_send_auth(ibss_rsn, addr, 1);
	if (res) {
		/*
		 * The driver may not support Authentication frame exchange in
		 * IBSS. Ignore authentication and go through EAPOL exchange.
		 */
		peer->authentication_status |= IBSS_RSN_AUTH_BY_US;
		return ibss_rsn_auth_init(ibss_rsn, peer);
	} else {
		os_get_reltime(&peer->own_auth_tx);
		eloop_register_timeout(1, 0, ibss_rsn_auth_timeout, peer, NULL);
	}

	return 0;
}
示例#4
0
static void auth_set_eapol(void *ctx, const u8 *addr,
				       wpa_eapol_variable var, int value)
{
	struct ibss_rsn *ibss_rsn = ctx;
	struct ibss_rsn_peer *peer = ibss_rsn_get_peer(ibss_rsn, addr);

	if (peer == NULL)
		return;

	switch (var) {
	case WPA_EAPOL_authorized:
		ibss_set_sta_authorized(ibss_rsn, peer, value);
		break;
	default:
		/* do not handle any other event */
		wpa_printf(MSG_DEBUG, "AUTH: eapol event not handled %d", var);
		break;
	}
}
示例#5
0
static int auth_set_key(void *ctx, int vlan_id, enum wpa_alg alg,
			const u8 *addr, int idx, u8 *key, size_t key_len)
{
	struct ibss_rsn *ibss_rsn = ctx;
	u8 seq[6];

	os_memset(seq, 0, sizeof(seq));

	if (addr) {
		wpa_printf(MSG_DEBUG, "AUTH: %s(alg=%d addr=" MACSTR
			   " key_idx=%d)",
			   __func__, alg, MAC2STR(addr), idx);
	} else {
		wpa_printf(MSG_DEBUG, "AUTH: %s(alg=%d key_idx=%d)",
			   __func__, alg, idx);
	}
	wpa_hexdump_key(MSG_DEBUG, "AUTH: set_key - key", key, key_len);

	if (idx == 0) {
		if (addr) {
			struct ibss_rsn_peer *peer;
			peer = ibss_rsn_get_peer(ibss_rsn, addr);
			if (peer) {
				peer->authentication_status |=
					IBSS_RSN_SET_PTK_AUTH;
				ibss_check_rsn_completed(peer);
			}
		}
		/*
		 * In IBSS RSN, the pairwise key from the 4-way handshake
		 * initiated by the peer with highest MAC address is used.
		 */
		if (addr == NULL ||
		    os_memcmp(ibss_rsn->wpa_s->own_addr, addr, ETH_ALEN) < 0) {
			wpa_printf(MSG_DEBUG, "AUTH: Do not use this PTK");
			return 0;
		}
	}

	return wpa_drv_set_key(ibss_rsn->wpa_s, alg, addr, idx,
			       1, seq, 6, key, key_len);
}
示例#6
0
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;
	}
}
示例#7
0
int ibss_rsn_start(struct ibss_rsn *ibss_rsn, const u8 *addr)
{
	struct ibss_rsn_peer *peer;

	if (ibss_rsn == NULL)
		return -1;

	if (ibss_rsn_get_peer(ibss_rsn, addr)) {
		wpa_printf(MSG_DEBUG, "RSN: IBSS Authenticator and Supplicant "
			   "for peer " MACSTR " already running",
			   MAC2STR(addr));
		return 0;
	}

	wpa_printf(MSG_DEBUG, "RSN: Starting IBSS Authenticator and "
		   "Supplicant for peer " MACSTR, MAC2STR(addr));

	peer = os_zalloc(sizeof(*peer));
	if (peer == NULL)
		return -1;

	peer->ibss_rsn = ibss_rsn;
	os_memcpy(peer->addr, addr, ETH_ALEN);

	if (ibss_rsn_supp_init(peer, ibss_rsn->wpa_s->own_addr, ibss_rsn->psk)
	    < 0) {
		ibss_rsn_free(peer);
		return -1;
	}

	if (ibss_rsn_auth_init(ibss_rsn, peer) < 0) {
		ibss_rsn_free(peer);
		return -1;
	}

	peer->next = ibss_rsn->peers;
	ibss_rsn->peers = peer;

	return 0;
}
示例#8
0
static struct ibss_rsn_peer *
ibss_rsn_peer_init(struct ibss_rsn *ibss_rsn, const u8 *addr)
{
	struct ibss_rsn_peer *peer;
	if (ibss_rsn == NULL)
		return NULL;

	peer = ibss_rsn_get_peer(ibss_rsn, addr);
	if (peer) {
		wpa_printf(MSG_DEBUG, "RSN: IBSS Supplicant for peer "MACSTR
			   " already running", MAC2STR(addr));
		return peer;
	}

	wpa_printf(MSG_DEBUG, "RSN: Starting IBSS Supplicant for peer "MACSTR,
		   MAC2STR(addr));

	peer = os_zalloc(sizeof(*peer));
	if (peer == NULL) {
		wpa_printf(MSG_DEBUG, "RSN: Could not allocate memory.");
		return NULL;
	}

	peer->ibss_rsn = ibss_rsn;
	os_memcpy(peer->addr, addr, ETH_ALEN);
	peer->authentication_status = IBSS_RSN_AUTH_NOT_AUTHENTICATED;

	if (ibss_rsn_supp_init(peer, ibss_rsn->wpa_s->own_addr,
			       ibss_rsn->psk) < 0) {
		ibss_rsn_free(peer);
		return NULL;
	}

	peer->next = ibss_rsn->peers;
	ibss_rsn->peers = peer;

	return peer;
}