1214501Srpaulo/* 2214501Srpaulo * hostapd / TKIP countermeasures 3214501Srpaulo * Copyright (c) 2002-2009, Jouni Malinen <j@w1.fi> 4214501Srpaulo * 5214501Srpaulo * This program is free software; you can redistribute it and/or modify 6214501Srpaulo * it under the terms of the GNU General Public License version 2 as 7214501Srpaulo * published by the Free Software Foundation. 8214501Srpaulo * 9214501Srpaulo * Alternatively, this software may be distributed under the terms of BSD 10214501Srpaulo * license. 11214501Srpaulo * 12214501Srpaulo * See README and COPYING for more details. 13214501Srpaulo */ 14214501Srpaulo 15214501Srpaulo#include "utils/includes.h" 16214501Srpaulo 17214501Srpaulo#include "utils/common.h" 18214501Srpaulo#include "utils/eloop.h" 19214501Srpaulo#include "common/ieee802_11_defs.h" 20214501Srpaulo#include "hostapd.h" 21214501Srpaulo#include "sta_info.h" 22214501Srpaulo#include "ap_mlme.h" 23214501Srpaulo#include "wpa_auth.h" 24214501Srpaulo#include "tkip_countermeasures.h" 25214501Srpaulo 26214501Srpaulo 27214501Srpaulostatic void ieee80211_tkip_countermeasures_stop(void *eloop_ctx, 28214501Srpaulo void *timeout_ctx) 29214501Srpaulo{ 30214501Srpaulo struct hostapd_data *hapd = eloop_ctx; 31214501Srpaulo hapd->tkip_countermeasures = 0; 32214501Srpaulo hapd->drv.set_countermeasures(hapd, 0); 33214501Srpaulo hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE80211, 34214501Srpaulo HOSTAPD_LEVEL_INFO, "TKIP countermeasures ended"); 35214501Srpaulo} 36214501Srpaulo 37214501Srpaulo 38214501Srpaulostatic void ieee80211_tkip_countermeasures_start(struct hostapd_data *hapd) 39214501Srpaulo{ 40214501Srpaulo struct sta_info *sta; 41214501Srpaulo 42214501Srpaulo hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE80211, 43214501Srpaulo HOSTAPD_LEVEL_INFO, "TKIP countermeasures initiated"); 44214501Srpaulo 45214501Srpaulo wpa_auth_countermeasures_start(hapd->wpa_auth); 46214501Srpaulo hapd->tkip_countermeasures = 1; 47214501Srpaulo hapd->drv.set_countermeasures(hapd, 1); 48214501Srpaulo wpa_gtk_rekey(hapd->wpa_auth); 49214501Srpaulo eloop_cancel_timeout(ieee80211_tkip_countermeasures_stop, hapd, NULL); 50214501Srpaulo eloop_register_timeout(60, 0, ieee80211_tkip_countermeasures_stop, 51214501Srpaulo hapd, NULL); 52214501Srpaulo for (sta = hapd->sta_list; sta != NULL; sta = sta->next) { 53214501Srpaulo hapd->drv.sta_deauth(hapd, sta->addr, 54214501Srpaulo WLAN_REASON_MICHAEL_MIC_FAILURE); 55214501Srpaulo sta->flags &= ~(WLAN_STA_AUTH | WLAN_STA_ASSOC | 56214501Srpaulo WLAN_STA_AUTHORIZED); 57214501Srpaulo hapd->drv.sta_remove(hapd, sta->addr); 58214501Srpaulo } 59214501Srpaulo} 60214501Srpaulo 61214501Srpaulo 62214501Srpaulovoid michael_mic_failure(struct hostapd_data *hapd, const u8 *addr, int local) 63214501Srpaulo{ 64214501Srpaulo time_t now; 65214501Srpaulo 66214501Srpaulo if (addr && local) { 67214501Srpaulo struct sta_info *sta = ap_get_sta(hapd, addr); 68214501Srpaulo if (sta != NULL) { 69214501Srpaulo wpa_auth_sta_local_mic_failure_report(sta->wpa_sm); 70214501Srpaulo hostapd_logger(hapd, addr, HOSTAPD_MODULE_IEEE80211, 71214501Srpaulo HOSTAPD_LEVEL_INFO, 72214501Srpaulo "Michael MIC failure detected in " 73214501Srpaulo "received frame"); 74214501Srpaulo mlme_michaelmicfailure_indication(hapd, addr); 75214501Srpaulo } else { 76214501Srpaulo wpa_printf(MSG_DEBUG, 77214501Srpaulo "MLME-MICHAELMICFAILURE.indication " 78214501Srpaulo "for not associated STA (" MACSTR 79214501Srpaulo ") ignored", MAC2STR(addr)); 80214501Srpaulo return; 81214501Srpaulo } 82214501Srpaulo } 83214501Srpaulo 84214501Srpaulo time(&now); 85214501Srpaulo if (now > hapd->michael_mic_failure + 60) { 86214501Srpaulo hapd->michael_mic_failures = 1; 87214501Srpaulo } else { 88214501Srpaulo hapd->michael_mic_failures++; 89214501Srpaulo if (hapd->michael_mic_failures > 1) 90214501Srpaulo ieee80211_tkip_countermeasures_start(hapd); 91214501Srpaulo } 92214501Srpaulo hapd->michael_mic_failure = now; 93214501Srpaulo} 94