Added initial step for IBSS RSN support
This commit adds a new build option, CONFIG_IBSS_RSN=y, that can be used to enable RSN support for IBSS. This links in RSN Authenticator code from hostapd and adds code for managing per-peer information for IBSS. A new wpa_cli command or driver event can be used to request RSN authentication with an IBSS peer. New RSN Authenticator and Supplicant will be allocated for each peer. The basic state machine setup code is included in this commit, but the state machines are not properly started yet. In addition, some of the callback functions are not yet complete.
This commit is contained in:
parent
4bb081f1b4
commit
11ef8d3578
9 changed files with 475 additions and 1 deletions
|
@ -1147,7 +1147,17 @@ typedef enum wpa_event_type {
|
||||||
* FT authentication sequence from the AP. The FT IEs are included in
|
* FT authentication sequence from the AP. The FT IEs are included in
|
||||||
* the extra information in union wpa_event_data::ft_ies.
|
* the extra information in union wpa_event_data::ft_ies.
|
||||||
*/
|
*/
|
||||||
EVENT_FT_RESPONSE
|
EVENT_FT_RESPONSE,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* EVENT_IBSS_RSN_START - Request RSN authentication in IBSS
|
||||||
|
*
|
||||||
|
* The driver can use this event to inform wpa_supplicant about a STA
|
||||||
|
* in an IBSS with which protected frames could be exchanged. This
|
||||||
|
* event starts RSN authentication with the other STA to authenticate
|
||||||
|
* the STA and set up encryption keys with it.
|
||||||
|
*/
|
||||||
|
EVENT_IBSS_RSN_START
|
||||||
} wpa_event_type;
|
} wpa_event_type;
|
||||||
|
|
||||||
|
|
||||||
|
@ -1274,6 +1284,13 @@ union wpa_event_data {
|
||||||
int ft_action;
|
int ft_action;
|
||||||
u8 target_ap[ETH_ALEN];
|
u8 target_ap[ETH_ALEN];
|
||||||
} ft_ies;
|
} ft_ies;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct ibss_rsn_start - Data for EVENT_IBSS_RSN_START
|
||||||
|
*/
|
||||||
|
struct ibss_rsn_start {
|
||||||
|
u8 peer[ETH_ALEN];
|
||||||
|
} ibss_rsn_start;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -941,6 +941,21 @@ else
|
||||||
CFLAGS += -DCONFIG_NO_WPA -DCONFIG_NO_WPA2
|
CFLAGS += -DCONFIG_NO_WPA -DCONFIG_NO_WPA2
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifdef CONFIG_IBSS_RSN
|
||||||
|
CFLAGS += -DCONFIG_IBSS_RSN
|
||||||
|
OBJS += ibss_rsn.o
|
||||||
|
OBJS += ../hostapd/wpa.o
|
||||||
|
OBJS += ../hostapd/wpa_auth_ie.o
|
||||||
|
OBJS += ../hostapd/pmksa_cache.o
|
||||||
|
OBJS += ../src/radius/radius.o
|
||||||
|
ifdef CONFIG_IEEE80211R
|
||||||
|
OBJS += ../hostapd/wpa_ft.o
|
||||||
|
endif
|
||||||
|
ifdef CONFIG_PEERKEY
|
||||||
|
OBJS += ../hostapd/peerkey.o
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
ifdef CONFIG_NO_WPA2
|
ifdef CONFIG_NO_WPA2
|
||||||
CFLAGS += -DCONFIG_NO_WPA2
|
CFLAGS += -DCONFIG_NO_WPA2
|
||||||
endif
|
endif
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
#include "ieee802_11_defs.h"
|
#include "ieee802_11_defs.h"
|
||||||
#include "wps_supplicant.h"
|
#include "wps_supplicant.h"
|
||||||
#include "wps/wps.h"
|
#include "wps/wps.h"
|
||||||
|
#include "ibss_rsn.h"
|
||||||
|
|
||||||
static int wpa_supplicant_global_iface_list(struct wpa_global *global,
|
static int wpa_supplicant_global_iface_list(struct wpa_global *global,
|
||||||
char *buf, int len);
|
char *buf, int len);
|
||||||
|
@ -227,6 +228,26 @@ static int wpa_supplicant_ctrl_iface_wps_reg(struct wpa_supplicant *wpa_s,
|
||||||
#endif /* CONFIG_WPS */
|
#endif /* CONFIG_WPS */
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef CONFIG_IBSS_RSN
|
||||||
|
static int wpa_supplicant_ctrl_iface_ibss_rsn(
|
||||||
|
struct wpa_supplicant *wpa_s, char *addr)
|
||||||
|
{
|
||||||
|
u8 peer[ETH_ALEN];
|
||||||
|
|
||||||
|
if (hwaddr_aton(addr, peer)) {
|
||||||
|
wpa_printf(MSG_DEBUG, "CTRL_IFACE IBSS_RSN: invalid "
|
||||||
|
"address '%s'", peer);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
wpa_printf(MSG_DEBUG, "CTRL_IFACE IBSS_RSN " MACSTR,
|
||||||
|
MAC2STR(peer));
|
||||||
|
|
||||||
|
return ibss_rsn_start(wpa_s->ibss_rsn, peer);
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_IBSS_RSN */
|
||||||
|
|
||||||
|
|
||||||
static int wpa_supplicant_ctrl_iface_ctrl_rsp(struct wpa_supplicant *wpa_s,
|
static int wpa_supplicant_ctrl_iface_ctrl_rsp(struct wpa_supplicant *wpa_s,
|
||||||
char *rsp)
|
char *rsp)
|
||||||
{
|
{
|
||||||
|
@ -1566,6 +1587,11 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s,
|
||||||
if (wpa_supplicant_ctrl_iface_wps_reg(wpa_s, buf + 8))
|
if (wpa_supplicant_ctrl_iface_wps_reg(wpa_s, buf + 8))
|
||||||
reply_len = -1;
|
reply_len = -1;
|
||||||
#endif /* CONFIG_WPS */
|
#endif /* CONFIG_WPS */
|
||||||
|
#ifdef CONFIG_IBSS_RSN
|
||||||
|
} else if (os_strncmp(buf, "IBSS_RSN ", 9) == 0) {
|
||||||
|
if (wpa_supplicant_ctrl_iface_ibss_rsn(wpa_s, buf + 9))
|
||||||
|
reply_len = -1;
|
||||||
|
#endif /* CONFIG_IBSS_RSN */
|
||||||
} else if (os_strncmp(buf, WPA_CTRL_RSP, os_strlen(WPA_CTRL_RSP)) == 0)
|
} else if (os_strncmp(buf, WPA_CTRL_RSP, os_strlen(WPA_CTRL_RSP)) == 0)
|
||||||
{
|
{
|
||||||
if (wpa_supplicant_ctrl_iface_ctrl_rsp(
|
if (wpa_supplicant_ctrl_iface_ctrl_rsp(
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
#include "blacklist.h"
|
#include "blacklist.h"
|
||||||
#include "wpas_glue.h"
|
#include "wpas_glue.h"
|
||||||
#include "wps_supplicant.h"
|
#include "wps_supplicant.h"
|
||||||
|
#include "ibss_rsn.h"
|
||||||
|
|
||||||
|
|
||||||
static int wpa_supplicant_select_config(struct wpa_supplicant *wpa_s)
|
static int wpa_supplicant_select_config(struct wpa_supplicant *wpa_s)
|
||||||
|
@ -1067,6 +1068,17 @@ wpa_supplicant_event_ft_response(struct wpa_supplicant *wpa_s,
|
||||||
#endif /* CONFIG_IEEE80211R */
|
#endif /* CONFIG_IEEE80211R */
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef CONFIG_IBSS_RSN
|
||||||
|
static void wpa_supplicant_event_ibss_rsn_start(struct wpa_supplicant *wpa_s,
|
||||||
|
union wpa_event_data *data)
|
||||||
|
{
|
||||||
|
if (data == NULL)
|
||||||
|
return;
|
||||||
|
ibss_rsn_start(wpa_s->ibss_rsn, data->ibss_rsn_start.peer);
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_IBSS_RSN */
|
||||||
|
|
||||||
|
|
||||||
void wpa_supplicant_event(void *ctx, wpa_event_type event,
|
void wpa_supplicant_event(void *ctx, wpa_event_type event,
|
||||||
union wpa_event_data *data)
|
union wpa_event_data *data)
|
||||||
{
|
{
|
||||||
|
@ -1106,6 +1118,11 @@ void wpa_supplicant_event(void *ctx, wpa_event_type event,
|
||||||
wpa_supplicant_event_ft_response(wpa_s, data);
|
wpa_supplicant_event_ft_response(wpa_s, data);
|
||||||
break;
|
break;
|
||||||
#endif /* CONFIG_IEEE80211R */
|
#endif /* CONFIG_IEEE80211R */
|
||||||
|
#ifdef CONFIG_IBSS_RSN
|
||||||
|
case EVENT_IBSS_RSN_START:
|
||||||
|
wpa_supplicant_event_ibss_rsn_start(wpa_s, data);
|
||||||
|
break;
|
||||||
|
#endif /* CONFIG_IBSS_RSN */
|
||||||
default:
|
default:
|
||||||
wpa_printf(MSG_INFO, "Unknown event %d", event);
|
wpa_printf(MSG_INFO, "Unknown event %d", event);
|
||||||
break;
|
break;
|
||||||
|
|
319
wpa_supplicant/ibss_rsn.c
Normal file
319
wpa_supplicant/ibss_rsn.c
Normal file
|
@ -0,0 +1,319 @@
|
||||||
|
/*
|
||||||
|
* wpa_supplicant - IBSS RSN
|
||||||
|
* Copyright (c) 2009, Jouni Malinen <j@w1.fi>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* Alternatively, this software may be distributed under the terms of BSD
|
||||||
|
* license.
|
||||||
|
*
|
||||||
|
* See README and COPYING for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "includes.h"
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
#include "wpa_supplicant_i.h"
|
||||||
|
#include "wpa.h"
|
||||||
|
#include "wpa_ie.h"
|
||||||
|
#include "../hostapd/wpa.h"
|
||||||
|
#include "ibss_rsn.h"
|
||||||
|
|
||||||
|
|
||||||
|
static void ibss_rsn_free(struct ibss_rsn_peer *peer)
|
||||||
|
{
|
||||||
|
wpa_auth_sta_deinit(peer->auth);
|
||||||
|
wpa_sm_deinit(peer->supp);
|
||||||
|
os_free(peer);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int supp_ether_send(void *ctx, const u8 *dest, u16 proto, const u8 *buf,
|
||||||
|
size_t len)
|
||||||
|
{
|
||||||
|
/* struct ibss_rsn_peer *peer = ctx; */
|
||||||
|
|
||||||
|
wpa_printf(MSG_DEBUG, "SUPP: %s(dest=" MACSTR " proto=0x%04x "
|
||||||
|
"len=%lu)",
|
||||||
|
__func__, MAC2STR(dest), proto, (unsigned long) len);
|
||||||
|
|
||||||
|
/* TODO: send EAPOL frame */
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static u8 * supp_alloc_eapol(void *ctx, u8 type, const void *data,
|
||||||
|
u16 data_len, size_t *msg_len, void **data_pos)
|
||||||
|
{
|
||||||
|
struct ieee802_1x_hdr *hdr;
|
||||||
|
|
||||||
|
wpa_printf(MSG_DEBUG, "SUPP: %s(type=%d data_len=%d)",
|
||||||
|
__func__, type, data_len);
|
||||||
|
|
||||||
|
*msg_len = sizeof(*hdr) + data_len;
|
||||||
|
hdr = os_malloc(*msg_len);
|
||||||
|
if (hdr == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
hdr->version = 2;
|
||||||
|
hdr->type = type;
|
||||||
|
hdr->length = host_to_be16(data_len);
|
||||||
|
|
||||||
|
if (data)
|
||||||
|
os_memcpy(hdr + 1, data, data_len);
|
||||||
|
else
|
||||||
|
os_memset(hdr + 1, 0, data_len);
|
||||||
|
|
||||||
|
if (data_pos)
|
||||||
|
*data_pos = hdr + 1;
|
||||||
|
|
||||||
|
return (u8 *) hdr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int supp_get_beacon_ie(void *ctx)
|
||||||
|
{
|
||||||
|
wpa_printf(MSG_DEBUG, "SUPP: %s", __func__);
|
||||||
|
/* TODO */
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int supp_set_key(void *ctx, wpa_alg alg,
|
||||||
|
const u8 *addr, int key_idx, int set_tx,
|
||||||
|
const u8 *seq, size_t seq_len,
|
||||||
|
const u8 *key, size_t key_len)
|
||||||
|
{
|
||||||
|
wpa_printf(MSG_DEBUG, "SUPP: %s(alg=%d addr=" MACSTR " key_idx=%d "
|
||||||
|
"set_tx=%d)",
|
||||||
|
__func__, alg, MAC2STR(addr), key_idx, set_tx);
|
||||||
|
wpa_hexdump(MSG_DEBUG, "SUPP: set_key - seq", seq, seq_len);
|
||||||
|
wpa_hexdump(MSG_DEBUG, "SUPP: set_key - key", key, key_len);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int supp_mlme_setprotection(void *ctx, const u8 *addr,
|
||||||
|
int protection_type, int key_type)
|
||||||
|
{
|
||||||
|
wpa_printf(MSG_DEBUG, "SUPP: %s(addr=" MACSTR " protection_type=%d "
|
||||||
|
"key_type=%d)",
|
||||||
|
__func__, MAC2STR(addr), protection_type, key_type);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void supp_cancel_auth_timeout(void *ctx)
|
||||||
|
{
|
||||||
|
wpa_printf(MSG_DEBUG, "SUPP: %s", __func__);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int ibss_rsn_supp_init(struct ibss_rsn_peer *peer, const u8 *own_addr,
|
||||||
|
const u8 *psk)
|
||||||
|
{
|
||||||
|
struct wpa_sm_ctx *ctx = os_zalloc(sizeof(*ctx));
|
||||||
|
if (ctx == NULL)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
ctx->ctx = peer;
|
||||||
|
ctx->ether_send = supp_ether_send;
|
||||||
|
ctx->get_beacon_ie = supp_get_beacon_ie;
|
||||||
|
ctx->alloc_eapol = supp_alloc_eapol;
|
||||||
|
ctx->set_key = supp_set_key;
|
||||||
|
ctx->mlme_setprotection = supp_mlme_setprotection;
|
||||||
|
ctx->cancel_auth_timeout = supp_cancel_auth_timeout;
|
||||||
|
peer->supp = wpa_sm_init(ctx);
|
||||||
|
if (peer->supp == NULL) {
|
||||||
|
wpa_printf(MSG_DEBUG, "SUPP: wpa_sm_init() failed");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
wpa_sm_set_own_addr(peer->supp, own_addr);
|
||||||
|
wpa_sm_set_param(peer->supp, WPA_PARAM_RSN_ENABLED, 1);
|
||||||
|
wpa_sm_set_param(peer->supp, WPA_PARAM_PROTO, WPA_PROTO_RSN);
|
||||||
|
wpa_sm_set_param(peer->supp, WPA_PARAM_PAIRWISE, WPA_CIPHER_CCMP);
|
||||||
|
wpa_sm_set_param(peer->supp, WPA_PARAM_GROUP, WPA_CIPHER_CCMP);
|
||||||
|
wpa_sm_set_param(peer->supp, WPA_PARAM_KEY_MGMT, WPA_KEY_MGMT_PSK);
|
||||||
|
wpa_sm_set_pmk(peer->supp, psk, PMK_LEN);
|
||||||
|
|
||||||
|
#if 0 /* TODO? */
|
||||||
|
peer->supp_ie_len = sizeof(peer->supp_ie);
|
||||||
|
if (wpa_sm_set_assoc_wpa_ie_default(peer->supp, peer->supp_ie,
|
||||||
|
&peer->supp_ie_len) < 0) {
|
||||||
|
wpa_printf(MSG_DEBUG, "SUPP: wpa_sm_set_assoc_wpa_ie_default()"
|
||||||
|
" failed");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
wpa_sm_notify_assoc(peer->supp, peer->addr);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void auth_logger(void *ctx, const u8 *addr, logger_level level,
|
||||||
|
const char *txt)
|
||||||
|
{
|
||||||
|
if (addr)
|
||||||
|
wpa_printf(MSG_DEBUG, "AUTH: " MACSTR " - %s",
|
||||||
|
MAC2STR(addr), txt);
|
||||||
|
else
|
||||||
|
wpa_printf(MSG_DEBUG, "AUTH: %s", txt);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static const u8 * auth_get_psk(void *ctx, const u8 *addr, const u8 *prev_psk)
|
||||||
|
{
|
||||||
|
struct ibss_rsn *ibss_rsn = ctx;
|
||||||
|
wpa_printf(MSG_DEBUG, "AUTH: %s (addr=" MACSTR " prev_psk=%p)",
|
||||||
|
__func__, MAC2STR(addr), prev_psk);
|
||||||
|
if (prev_psk)
|
||||||
|
return NULL;
|
||||||
|
return ibss_rsn->psk;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int auth_send_eapol(void *ctx, const u8 *addr, const u8 *data,
|
||||||
|
size_t data_len, int encrypt)
|
||||||
|
{
|
||||||
|
/* struct ibss_rsn *ibss_rsn = ctx; */
|
||||||
|
|
||||||
|
wpa_printf(MSG_DEBUG, "AUTH: %s(addr=" MACSTR " data_len=%lu "
|
||||||
|
"encrypt=%d)",
|
||||||
|
__func__, MAC2STR(addr), (unsigned long) data_len, encrypt);
|
||||||
|
|
||||||
|
/* TODO: send EAPOL frame */
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int ibss_rsn_auth_init_group(struct ibss_rsn *ibss_rsn,
|
||||||
|
const u8 *own_addr)
|
||||||
|
{
|
||||||
|
struct wpa_auth_config conf;
|
||||||
|
struct wpa_auth_callbacks cb;
|
||||||
|
|
||||||
|
wpa_printf(MSG_DEBUG, "AUTH: Initializing group state machine");
|
||||||
|
|
||||||
|
os_memset(&conf, 0, sizeof(conf));
|
||||||
|
conf.wpa = 2;
|
||||||
|
conf.wpa_key_mgmt = WPA_KEY_MGMT_PSK;
|
||||||
|
conf.wpa_pairwise = WPA_CIPHER_CCMP;
|
||||||
|
conf.rsn_pairwise = WPA_CIPHER_CCMP;
|
||||||
|
conf.wpa_group = WPA_CIPHER_CCMP;
|
||||||
|
conf.eapol_version = 2;
|
||||||
|
|
||||||
|
os_memset(&cb, 0, sizeof(cb));
|
||||||
|
cb.ctx = ibss_rsn;
|
||||||
|
cb.logger = auth_logger;
|
||||||
|
cb.send_eapol = auth_send_eapol;
|
||||||
|
cb.get_psk = auth_get_psk;
|
||||||
|
|
||||||
|
ibss_rsn->auth_group = wpa_init(own_addr, &conf, &cb);
|
||||||
|
if (ibss_rsn->auth_group == NULL) {
|
||||||
|
wpa_printf(MSG_DEBUG, "AUTH: wpa_init() failed");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int ibss_rsn_auth_init(struct ibss_rsn *ibss_rsn,
|
||||||
|
struct ibss_rsn_peer *peer)
|
||||||
|
{
|
||||||
|
peer->auth = wpa_auth_sta_init(ibss_rsn->auth_group, peer->addr);
|
||||||
|
if (peer->auth == NULL) {
|
||||||
|
wpa_printf(MSG_DEBUG, "AUTH: wpa_auth_sta_init() failed");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0 /* TODO: get peer RSN IE with Probe Request */
|
||||||
|
if (wpa_validate_wpa_ie(ibss_rsn->auth_group, peer->auth, PEER_IE,
|
||||||
|
PEER_IE_LEN, NULL, 0) != WPA_IE_OK) {
|
||||||
|
wpa_printf(MSG_DEBUG, "AUTH: wpa_validate_wpa_ie() failed");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
wpa_auth_sm_event(peer->auth, WPA_ASSOC);
|
||||||
|
|
||||||
|
wpa_auth_sta_associated(ibss_rsn->auth_group, peer->auth);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int ibss_rsn_start(struct ibss_rsn *ibss_rsn, const u8 *addr)
|
||||||
|
{
|
||||||
|
struct ibss_rsn_peer *peer;
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
struct ibss_rsn * ibss_rsn_init(struct wpa_supplicant *wpa_s)
|
||||||
|
{
|
||||||
|
struct ibss_rsn *ibss_rsn;
|
||||||
|
|
||||||
|
ibss_rsn = os_zalloc(sizeof(*ibss_rsn));
|
||||||
|
if (ibss_rsn == NULL)
|
||||||
|
return NULL;
|
||||||
|
ibss_rsn->wpa_s = wpa_s;
|
||||||
|
|
||||||
|
if (ibss_rsn_auth_init_group(ibss_rsn, wpa_s->own_addr) < 0) {
|
||||||
|
ibss_rsn_deinit(ibss_rsn);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ibss_rsn;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ibss_rsn_deinit(struct ibss_rsn *ibss_rsn)
|
||||||
|
{
|
||||||
|
struct ibss_rsn_peer *peer, *prev;
|
||||||
|
|
||||||
|
if (ibss_rsn == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
peer = ibss_rsn->peers;
|
||||||
|
while (peer) {
|
||||||
|
prev = peer;
|
||||||
|
peer = peer->next;
|
||||||
|
ibss_rsn_free(prev);
|
||||||
|
}
|
||||||
|
|
||||||
|
wpa_deinit(ibss_rsn->auth_group);
|
||||||
|
os_free(ibss_rsn);
|
||||||
|
|
||||||
|
}
|
40
wpa_supplicant/ibss_rsn.h
Normal file
40
wpa_supplicant/ibss_rsn.h
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
/*
|
||||||
|
* wpa_supplicant - IBSS RSN
|
||||||
|
* Copyright (c) 2009, Jouni Malinen <j@w1.fi>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* Alternatively, this software may be distributed under the terms of BSD
|
||||||
|
* license.
|
||||||
|
*
|
||||||
|
* See README and COPYING for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef IBSS_RSN_H
|
||||||
|
#define IBSS_RSN_H
|
||||||
|
|
||||||
|
struct ibss_rsn_peer {
|
||||||
|
struct ibss_rsn_peer *next;
|
||||||
|
|
||||||
|
u8 addr[ETH_ALEN];
|
||||||
|
|
||||||
|
struct wpa_sm *supp;
|
||||||
|
|
||||||
|
struct wpa_state_machine *auth;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ibss_rsn {
|
||||||
|
struct wpa_supplicant *wpa_s;
|
||||||
|
struct wpa_authenticator *auth_group;
|
||||||
|
struct ibss_rsn_peer *peers;
|
||||||
|
u8 psk[PMK_LEN];
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct ibss_rsn * ibss_rsn_init(struct wpa_supplicant *wpa_s);
|
||||||
|
void ibss_rsn_deinit(struct ibss_rsn *ibss_rsn);
|
||||||
|
int ibss_rsn_start(struct ibss_rsn *ibss_rsn, const u8 *addr);
|
||||||
|
|
||||||
|
#endif /* IBSS_RSN_H */
|
|
@ -465,6 +465,26 @@ static int wpa_cli_cmd_wps_reg(struct wpa_ctrl *ctrl, int argc, char *argv[])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int wpa_cli_cmd_ibss_rsn(struct wpa_ctrl *ctrl, int argc, char *argv[])
|
||||||
|
{
|
||||||
|
char cmd[256];
|
||||||
|
int res;
|
||||||
|
|
||||||
|
if (argc != 1) {
|
||||||
|
printf("Invalid IBSS_RSN command: needs one argument "
|
||||||
|
"(Peer STA MAC address)\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
res = os_snprintf(cmd, sizeof(cmd), "IBSS_RSN %s", argv[0]);
|
||||||
|
if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
|
||||||
|
printf("Too long IBSS_RSN command.\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return wpa_ctrl_command(ctrl, cmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int wpa_cli_cmd_level(struct wpa_ctrl *ctrl, int argc, char *argv[])
|
static int wpa_cli_cmd_level(struct wpa_ctrl *ctrl, int argc, char *argv[])
|
||||||
{
|
{
|
||||||
char cmd[256];
|
char cmd[256];
|
||||||
|
@ -1239,6 +1259,9 @@ static struct wpa_cli_cmd wpa_cli_commands[] = {
|
||||||
{ "wps_reg", wpa_cli_cmd_wps_reg,
|
{ "wps_reg", wpa_cli_cmd_wps_reg,
|
||||||
cli_cmd_flag_sensitive,
|
cli_cmd_flag_sensitive,
|
||||||
"<BSSID> <AP PIN> = start WPS Registrar to configure an AP" },
|
"<BSSID> <AP PIN> = start WPS Registrar to configure an AP" },
|
||||||
|
{ "ibss_rsn", wpa_cli_cmd_ibss_rsn,
|
||||||
|
cli_cmd_flag_none,
|
||||||
|
"<addr> = request RSN authentication with <addr> in IBSS" },
|
||||||
{ NULL, NULL, cli_cmd_flag_none, NULL }
|
{ NULL, NULL, cli_cmd_flag_none, NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -39,6 +39,7 @@
|
||||||
#include "blacklist.h"
|
#include "blacklist.h"
|
||||||
#include "wpas_glue.h"
|
#include "wpas_glue.h"
|
||||||
#include "wps_supplicant.h"
|
#include "wps_supplicant.h"
|
||||||
|
#include "ibss_rsn.h"
|
||||||
|
|
||||||
const char *wpa_supplicant_version =
|
const char *wpa_supplicant_version =
|
||||||
"wpa_supplicant v" VERSION_STR "\n"
|
"wpa_supplicant v" VERSION_STR "\n"
|
||||||
|
@ -385,6 +386,11 @@ static void wpa_supplicant_cleanup(struct wpa_supplicant *wpa_s)
|
||||||
ieee80211_sta_deinit(wpa_s);
|
ieee80211_sta_deinit(wpa_s);
|
||||||
|
|
||||||
wpas_wps_deinit(wpa_s);
|
wpas_wps_deinit(wpa_s);
|
||||||
|
|
||||||
|
#ifdef CONFIG_IBSS_RSN
|
||||||
|
ibss_rsn_deinit(wpa_s->ibss_rsn);
|
||||||
|
wpa_s->ibss_rsn = NULL;
|
||||||
|
#endif /* CONFIG_IBSS_RSN */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1859,6 +1865,14 @@ static int wpa_supplicant_init_iface2(struct wpa_supplicant *wpa_s)
|
||||||
wpa_s->driver_4way_handshake = 1;
|
wpa_s->driver_4way_handshake = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_IBSS_RSN
|
||||||
|
wpa_s->ibss_rsn = ibss_rsn_init(wpa_s);
|
||||||
|
if (!wpa_s->ibss_rsn) {
|
||||||
|
wpa_printf(MSG_DEBUG, "Failed to init IBSS RSN");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_IBSS_RSN */
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -33,6 +33,7 @@ extern struct wpa_driver_ops *wpa_supplicant_drivers[];
|
||||||
struct wpa_scan_result;
|
struct wpa_scan_result;
|
||||||
struct wpa_sm;
|
struct wpa_sm;
|
||||||
struct wpa_supplicant;
|
struct wpa_supplicant;
|
||||||
|
struct ibss_rsn;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Forward declarations of private structures used within the ctrl_iface
|
* Forward declarations of private structures used within the ctrl_iface
|
||||||
|
@ -355,6 +356,8 @@ struct wpa_supplicant {
|
||||||
int mic_errors_seen; /* Michael MIC errors with the current PTK */
|
int mic_errors_seen; /* Michael MIC errors with the current PTK */
|
||||||
|
|
||||||
struct wps_context *wps;
|
struct wps_context *wps;
|
||||||
|
|
||||||
|
struct ibss_rsn *ibss_rsn;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue