wpa_supplicant disconnect bug
Chris Zimmermann
cbzimmermann
Thu Aug 17 22:01:02 PDT 2006
In wpa_supplicant version 0.5.4,
the file events.c,
the function wpa_supplicant_event_disassoc()
static void wpa_supplicant_event_disassoc(struct wpa_supplicant *wpa_s)
{
const u8 *bssid;
if (wpa_s->key_mgmt == WPA_KEY_MGMT_WPA_NONE) {
/*
* At least Host AP driver and a Prism3 card seemed to be
* generating streams of disconnected events when configuring
* IBSS for WPA-None. Ignore them for now.
*/
wpa_printf(MSG_DEBUG, "Disconnect event - ignore in "
"IBSS/WPA-None mode");
return;
}
if (wpa_s->wpa_state == WPA_4WAY_HANDSHAKE &&
wpa_s->key_mgmt == WPA_KEY_MGMT_PSK) {
wpa_msg(wpa_s, MSG_INFO, "WPA: 4-Way Handshake failed - "
"pre-shared key may be incorrect");
}
if (wpa_s->wpa_state >= WPA_ASSOCIATED)
wpa_supplicant_req_scan(wpa_s, 0, 100000);
bssid = wpa_s->bssid;
if (memcmp(bssid, "\x00\x00\x00\x00\x00\x00", ETH_ALEN) == 0)
bssid = wpa_s->pending_bssid;
wpa_blacklist_add(wpa_s, bssid);
wpa_sm_notify_disassoc(wpa_s->wpa);
wpa_supplicant_mark_disassoc(wpa_s);
wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_DISCONNECTED "- Disconnect event - "
"remove keys");
if (wpa_supplicant_dynamic_keys(wpa_s)) {
wpa_s->keys_cleared = 0;
wpa_clear_keys(wpa_s, wpa_s->bssid);
}
}
However, the function, wpa_supplicant_mark_disassoc() ends up setting
the field wpa_s->bssid to all zeros (00:00:00:00:00:00). When you
call wpa_clear_keys() after this, the PTK is not really cleared.
This leads to the inability to renegotiate WPA PTK, because the
message 2/4 will go out encrypted and the authenticator will never
get the message.
Changing the call to use a cached version of the BSSID held by
wpa_supplicant_event_disassoc() corrects this issue.
static void wpa_supplicant_event_disassoc(struct wpa_supplicant *wpa_s)
{
- const u8 *bssid;
+ u8 bssid[ETH_ALEN];
if (wpa_s->key_mgmt == WPA_KEY_MGMT_WPA_NONE) {
/*
* At least Host AP driver and a Prism3 card seemed to be
* generating streams of disconnected events when configuring
* IBSS for WPA-None. Ignore them for now.
*/
wpa_printf(MSG_DEBUG, "Disconnect event - ignore in "
"IBSS/WPA-None mode");
return;
}
if (wpa_s->wpa_state == WPA_4WAY_HANDSHAKE &&
wpa_s->key_mgmt == WPA_KEY_MGMT_PSK) {
wpa_msg(wpa_s, MSG_INFO, "WPA: 4-Way Handshake failed - "
"pre-shared key may be incorrect");
}
if (wpa_s->wpa_state >= WPA_ASSOCIATED)
wpa_supplicant_req_scan(wpa_s, 0, 100000);
- bssid = wpa_s->bssid;
+ memcpy( bssid, wpa_s->bssid, ETH_ALEN);
if (memcmp(bssid, "\x00\x00\x00\x00\x00\x00", ETH_ALEN) == 0)
- bssid = wpa_s->pending_bssid;
+ memcpy( bssid, wpa_s->pending_bssid, ETH_ALEN);
wpa_blacklist_add(wpa_s, bssid);
wpa_sm_notify_disassoc(wpa_s->wpa);
wpa_supplicant_mark_disassoc(wpa_s);
wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_DISCONNECTED "- Disconnect event - "
"remove keys");
if (wpa_supplicant_dynamic_keys(wpa_s)) {
wpa_s->keys_cleared = 0;
- wpa_clear_keys(wpa_s, wpa_s->bssid);
+ wpa_clear_keys(wpa_s, bssid);
}
}
I also think it would be more optimal to do this;
if (memcmp(wpa_s->bssid, "\x00\x00\x00\x00\x00\x00", ETH_ALEN) == 0)
memcpy( bssid, wpa_s->pending_bssid, ETH_ALEN);
else
memcpy( bssid, wpa_s->bssid, ETH_ALEN);
rather than this
memcpy( bssid, wpa_s->bssid, ETH_ALEN);
if (memcmp(bssid, "\x00\x00\x00\x00\x00\x00", ETH_ALEN) == 0)
memcpy( bssid, wpa_s->pending_bssid, ETH_ALEN);
Thanks,
Chris
--
Chris Zimmermann
cbzimmermann at mac.com
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.shmoo.com/pipermail/hostap/attachments/20060817/c18646d7/attachment.htm
More information about the Hostap
mailing list