Home | History | Annotate | Download | only in ap
      1 /*
      2  * hostapd / TKIP countermeasures
      3  * Copyright (c) 2002-2011, Jouni Malinen <j (at) w1.fi>
      4  *
      5  * This software may be distributed under the terms of the BSD license.
      6  * See README for more details.
      7  */
      8 
      9 #include "utils/includes.h"
     10 
     11 #include "utils/common.h"
     12 #include "utils/eloop.h"
     13 #include "common/ieee802_11_defs.h"
     14 #include "hostapd.h"
     15 #include "sta_info.h"
     16 #include "ap_mlme.h"
     17 #include "wpa_auth.h"
     18 #include "ap_drv_ops.h"
     19 #include "tkip_countermeasures.h"
     20 
     21 
     22 static void ieee80211_tkip_countermeasures_stop(void *eloop_ctx,
     23 						void *timeout_ctx)
     24 {
     25 	struct hostapd_data *hapd = eloop_ctx;
     26 	hapd->tkip_countermeasures = 0;
     27 	hostapd_drv_set_countermeasures(hapd, 0);
     28 	hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE80211,
     29 		       HOSTAPD_LEVEL_INFO, "TKIP countermeasures ended");
     30 }
     31 
     32 
     33 static void ieee80211_tkip_countermeasures_start(struct hostapd_data *hapd)
     34 {
     35 	struct sta_info *sta;
     36 
     37 	hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE80211,
     38 		       HOSTAPD_LEVEL_INFO, "TKIP countermeasures initiated");
     39 
     40 	wpa_auth_countermeasures_start(hapd->wpa_auth);
     41 	hapd->tkip_countermeasures = 1;
     42 	hostapd_drv_set_countermeasures(hapd, 1);
     43 	wpa_gtk_rekey(hapd->wpa_auth);
     44 	eloop_cancel_timeout(ieee80211_tkip_countermeasures_stop, hapd, NULL);
     45 	eloop_register_timeout(60, 0, ieee80211_tkip_countermeasures_stop,
     46 			       hapd, NULL);
     47 	for (sta = hapd->sta_list; sta != NULL; sta = sta->next) {
     48 		hostapd_drv_sta_deauth(hapd, sta->addr,
     49 				       WLAN_REASON_MICHAEL_MIC_FAILURE);
     50 		ap_sta_set_authorized(hapd, sta, 0);
     51 		sta->flags &= ~(WLAN_STA_AUTH | WLAN_STA_ASSOC);
     52 		hostapd_drv_sta_remove(hapd, sta->addr);
     53 	}
     54 }
     55 
     56 
     57 void ieee80211_tkip_countermeasures_deinit(struct hostapd_data *hapd)
     58 {
     59 	eloop_cancel_timeout(ieee80211_tkip_countermeasures_stop, hapd, NULL);
     60 }
     61 
     62 
     63 void michael_mic_failure(struct hostapd_data *hapd, const u8 *addr, int local)
     64 {
     65 	struct os_time now;
     66 
     67 	if (addr && local) {
     68 		struct sta_info *sta = ap_get_sta(hapd, addr);
     69 		if (sta != NULL) {
     70 			wpa_auth_sta_local_mic_failure_report(sta->wpa_sm);
     71 			hostapd_logger(hapd, addr, HOSTAPD_MODULE_IEEE80211,
     72 				       HOSTAPD_LEVEL_INFO,
     73 				       "Michael MIC failure detected in "
     74 				       "received frame");
     75 			mlme_michaelmicfailure_indication(hapd, addr);
     76 		} else {
     77 			wpa_printf(MSG_DEBUG,
     78 				   "MLME-MICHAELMICFAILURE.indication "
     79 				   "for not associated STA (" MACSTR
     80 				   ") ignored", MAC2STR(addr));
     81 			return;
     82 		}
     83 	}
     84 
     85 	os_get_time(&now);
     86 	if (now.sec > hapd->michael_mic_failure + 60) {
     87 		hapd->michael_mic_failures = 1;
     88 	} else {
     89 		hapd->michael_mic_failures++;
     90 		if (hapd->michael_mic_failures > 1)
     91 			ieee80211_tkip_countermeasures_start(hapd);
     92 	}
     93 	hapd->michael_mic_failure = now.sec;
     94 }
     95