P2P: Select PSK based on Device Address instead of Interface Address

When using per-device PSKs, select the PSK based on the P2P Device
Address of the connecting client if that client is a P2P Device. This
allows the P2P Interface Address to be changed between P2P group
connections which may happen especially when using persistent groups.

Signed-hostap: Jouni Malinen <j@w1.fi>
This commit is contained in:
Jouni Malinen 2013-09-01 11:30:26 +03:00
parent 94ddef3e72
commit 759fd76b7f
6 changed files with 38 additions and 12 deletions

View file

@ -1,6 +1,6 @@
/* /*
* hostapd / Configuration helper functions * hostapd / Configuration helper functions
* Copyright (c) 2003-2012, Jouni Malinen <j@w1.fi> * Copyright (c) 2003-2013, Jouni Malinen <j@w1.fi>
* *
* This software may be distributed under the terms of the BSD license. * This software may be distributed under the terms of the BSD license.
* See README for more details. * See README for more details.
@ -625,14 +625,31 @@ const char * hostapd_get_vlan_id_ifname(struct hostapd_vlan *vlan, int vlan_id)
const u8 * hostapd_get_psk(const struct hostapd_bss_config *conf, const u8 * hostapd_get_psk(const struct hostapd_bss_config *conf,
const u8 *addr, const u8 *prev_psk) const u8 *addr, const u8 *p2p_dev_addr,
const u8 *prev_psk)
{ {
struct hostapd_wpa_psk *psk; struct hostapd_wpa_psk *psk;
int next_ok = prev_psk == NULL; int next_ok = prev_psk == NULL;
if (p2p_dev_addr) {
wpa_printf(MSG_DEBUG, "Searching a PSK for " MACSTR
" p2p_dev_addr=" MACSTR " prev_psk=%p",
MAC2STR(addr), MAC2STR(p2p_dev_addr), prev_psk);
if (!is_zero_ether_addr(p2p_dev_addr))
addr = NULL; /* Use P2P Device Address for matching */
} else {
wpa_printf(MSG_DEBUG, "Searching a PSK for " MACSTR
" prev_psk=%p",
MAC2STR(addr), prev_psk);
}
for (psk = conf->ssid.wpa_psk; psk != NULL; psk = psk->next) { for (psk = conf->ssid.wpa_psk; psk != NULL; psk = psk->next) {
if (next_ok && if (next_ok &&
(psk->group || os_memcmp(psk->addr, addr, ETH_ALEN) == 0)) (psk->group ||
(addr && os_memcmp(psk->addr, addr, ETH_ALEN) == 0) ||
(!addr && p2p_dev_addr &&
os_memcmp(psk->p2p_dev_addr, p2p_dev_addr, ETH_ALEN) ==
0)))
return psk->psk; return psk->psk;
if (psk->psk == prev_psk) if (psk->psk == prev_psk)

View file

@ -552,7 +552,8 @@ int hostapd_rate_found(int *list, int rate);
int hostapd_wep_key_cmp(struct hostapd_wep_keys *a, int hostapd_wep_key_cmp(struct hostapd_wep_keys *a,
struct hostapd_wep_keys *b); struct hostapd_wep_keys *b);
const u8 * hostapd_get_psk(const struct hostapd_bss_config *conf, const u8 * hostapd_get_psk(const struct hostapd_bss_config *conf,
const u8 *addr, const u8 *prev_psk); const u8 *addr, const u8 *p2p_dev_addr,
const u8 *prev_psk);
int hostapd_setup_wpa_psk(struct hostapd_bss_config *conf); int hostapd_setup_wpa_psk(struct hostapd_bss_config *conf);
int hostapd_vlan_id_valid(struct hostapd_vlan *vlan, int vlan_id); int hostapd_vlan_id_valid(struct hostapd_vlan *vlan, int vlan_id);
const char * hostapd_get_vlan_id_ifname(struct hostapd_vlan *vlan, const char * hostapd_get_vlan_id_ifname(struct hostapd_vlan *vlan,

View file

@ -82,11 +82,14 @@ static inline int wpa_auth_get_eapol(struct wpa_authenticator *wpa_auth,
static inline const u8 * wpa_auth_get_psk(struct wpa_authenticator *wpa_auth, static inline const u8 * wpa_auth_get_psk(struct wpa_authenticator *wpa_auth,
const u8 *addr, const u8 *prev_psk) const u8 *addr,
const u8 *p2p_dev_addr,
const u8 *prev_psk)
{ {
if (wpa_auth->cb.get_psk == NULL) if (wpa_auth->cb.get_psk == NULL)
return NULL; return NULL;
return wpa_auth->cb.get_psk(wpa_auth->cb.ctx, addr, prev_psk); return wpa_auth->cb.get_psk(wpa_auth->cb.ctx, addr, p2p_dev_addr,
prev_psk);
} }
@ -1681,7 +1684,7 @@ SM_STATE(WPA_PTK, INITPSK)
{ {
const u8 *psk; const u8 *psk;
SM_ENTRY_MA(WPA_PTK, INITPSK, wpa_ptk); SM_ENTRY_MA(WPA_PTK, INITPSK, wpa_ptk);
psk = wpa_auth_get_psk(sm->wpa_auth, sm->addr, NULL); psk = wpa_auth_get_psk(sm->wpa_auth, sm->addr, sm->p2p_dev_addr, NULL);
if (psk) { if (psk) {
os_memcpy(sm->PMK, psk, PMK_LEN); os_memcpy(sm->PMK, psk, PMK_LEN);
#ifdef CONFIG_IEEE80211R #ifdef CONFIG_IEEE80211R
@ -1774,7 +1777,8 @@ SM_STATE(WPA_PTK, PTKCALCNEGOTIATING)
* the packet */ * the packet */
for (;;) { for (;;) {
if (wpa_key_mgmt_wpa_psk(sm->wpa_key_mgmt)) { if (wpa_key_mgmt_wpa_psk(sm->wpa_key_mgmt)) {
pmk = wpa_auth_get_psk(sm->wpa_auth, sm->addr, pmk); pmk = wpa_auth_get_psk(sm->wpa_auth, sm->addr,
sm->p2p_dev_addr, pmk);
if (pmk == NULL) if (pmk == NULL)
break; break;
} else } else
@ -2161,7 +2165,8 @@ SM_STEP(WPA_PTK)
} }
break; break;
case WPA_PTK_INITPSK: case WPA_PTK_INITPSK:
if (wpa_auth_get_psk(sm->wpa_auth, sm->addr, NULL)) if (wpa_auth_get_psk(sm->wpa_auth, sm->addr, sm->p2p_dev_addr,
NULL))
SM_ENTER(WPA_PTK, PTKSTART); SM_ENTER(WPA_PTK, PTKSTART);
else { else {
wpa_auth_logger(sm->wpa_auth, sm->addr, LOGGER_INFO, wpa_auth_logger(sm->wpa_auth, sm->addr, LOGGER_INFO,

View file

@ -184,7 +184,8 @@ struct wpa_auth_callbacks {
void (*set_eapol)(void *ctx, const u8 *addr, wpa_eapol_variable var, void (*set_eapol)(void *ctx, const u8 *addr, wpa_eapol_variable var,
int value); int value);
int (*get_eapol)(void *ctx, const u8 *addr, wpa_eapol_variable var); int (*get_eapol)(void *ctx, const u8 *addr, wpa_eapol_variable var);
const u8 * (*get_psk)(void *ctx, const u8 *addr, const u8 *prev_psk); const u8 * (*get_psk)(void *ctx, const u8 *addr, const u8 *p2p_dev_addr,
const u8 *prev_psk);
int (*get_msk)(void *ctx, const u8 *addr, u8 *msk, size_t *len); int (*get_msk)(void *ctx, const u8 *addr, u8 *msk, size_t *len);
int (*set_key)(void *ctx, int vlan_id, enum wpa_alg alg, int (*set_key)(void *ctx, int vlan_id, enum wpa_alg alg,
const u8 *addr, int idx, u8 *key, size_t key_len); const u8 *addr, int idx, u8 *key, size_t key_len);

View file

@ -186,6 +186,7 @@ static int hostapd_wpa_auth_get_eapol(void *ctx, const u8 *addr,
static const u8 * hostapd_wpa_auth_get_psk(void *ctx, const u8 *addr, static const u8 * hostapd_wpa_auth_get_psk(void *ctx, const u8 *addr,
const u8 *p2p_dev_addr,
const u8 *prev_psk) const u8 *prev_psk)
{ {
struct hostapd_data *hapd = ctx; struct hostapd_data *hapd = ctx;
@ -200,7 +201,7 @@ static const u8 * hostapd_wpa_auth_get_psk(void *ctx, const u8 *addr,
} }
#endif /* CONFIG_SAE */ #endif /* CONFIG_SAE */
psk = hostapd_get_psk(hapd->conf, addr, prev_psk); psk = hostapd_get_psk(hapd->conf, addr, p2p_dev_addr, prev_psk);
/* /*
* This is about to iterate over all psks, prev_psk gives the last * This is about to iterate over all psks, prev_psk gives the last
* returned psk which should not be returned again. * returned psk which should not be returned again.

View file

@ -257,7 +257,8 @@ static void auth_logger(void *ctx, const u8 *addr, logger_level level,
} }
static const u8 * auth_get_psk(void *ctx, const u8 *addr, const u8 *prev_psk) static const u8 * auth_get_psk(void *ctx, const u8 *addr,
const u8 *p2p_dev_addr, const u8 *prev_psk)
{ {
struct ibss_rsn *ibss_rsn = ctx; struct ibss_rsn *ibss_rsn = ctx;
wpa_printf(MSG_DEBUG, "AUTH: %s (addr=" MACSTR " prev_psk=%p)", wpa_printf(MSG_DEBUG, "AUTH: %s (addr=" MACSTR " prev_psk=%p)",