xref: /dragonfly/contrib/wpa_supplicant/src/ap/tkip_countermeasures.c (revision 3a84a4273475ed07d0ab1c2dfeffdfedef35d9cd)
1 /*
2  * hostapd / TKIP countermeasures
3  * Copyright (c) 2002-2012, Jouni Malinen <j@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 "radius/radius.h"
15 #include "hostapd.h"
16 #include "sta_info.h"
17 #include "ap_mlme.h"
18 #include "wpa_auth.h"
19 #include "ap_drv_ops.h"
20 #include "tkip_countermeasures.h"
21 
22 
ieee80211_tkip_countermeasures_stop(void * eloop_ctx,void * timeout_ctx)23 static void ieee80211_tkip_countermeasures_stop(void *eloop_ctx,
24                                                             void *timeout_ctx)
25 {
26           struct hostapd_data *hapd = eloop_ctx;
27           hapd->tkip_countermeasures = 0;
28           hostapd_drv_set_countermeasures(hapd, 0);
29           hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE80211,
30                            HOSTAPD_LEVEL_INFO, "TKIP countermeasures ended");
31 }
32 
33 
ieee80211_tkip_countermeasures_start(struct hostapd_data * hapd)34 static void ieee80211_tkip_countermeasures_start(struct hostapd_data *hapd)
35 {
36           struct sta_info *sta;
37 
38           hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE80211,
39                            HOSTAPD_LEVEL_INFO, "TKIP countermeasures initiated");
40 
41           wpa_auth_countermeasures_start(hapd->wpa_auth);
42           hapd->tkip_countermeasures = 1;
43           hostapd_drv_set_countermeasures(hapd, 1);
44           wpa_gtk_rekey(hapd->wpa_auth);
45           eloop_cancel_timeout(ieee80211_tkip_countermeasures_stop, hapd, NULL);
46           eloop_register_timeout(60, 0, ieee80211_tkip_countermeasures_stop,
47                                      hapd, NULL);
48           while ((sta = hapd->sta_list)) {
49                     sta->acct_terminate_cause =
50                               RADIUS_ACCT_TERMINATE_CAUSE_ADMIN_RESET;
51                     if (sta->flags & WLAN_STA_AUTH) {
52                               mlme_deauthenticate_indication(
53                                         hapd, sta,
54                                         WLAN_REASON_MICHAEL_MIC_FAILURE);
55                     }
56                     hostapd_drv_sta_deauth(hapd, sta->addr,
57                                                WLAN_REASON_MICHAEL_MIC_FAILURE);
58                     ap_free_sta(hapd, sta);
59           }
60 }
61 
62 
ieee80211_tkip_countermeasures_deinit(struct hostapd_data * hapd)63 void ieee80211_tkip_countermeasures_deinit(struct hostapd_data *hapd)
64 {
65           eloop_cancel_timeout(ieee80211_tkip_countermeasures_stop, hapd, NULL);
66 }
67 
68 
michael_mic_failure(struct hostapd_data * hapd,const u8 * addr,int local)69 int michael_mic_failure(struct hostapd_data *hapd, const u8 *addr, int local)
70 {
71           struct os_reltime now;
72           int ret = 0;
73 
74           hostapd_logger(hapd, addr, HOSTAPD_MODULE_IEEE80211,
75                            HOSTAPD_LEVEL_INFO,
76                            "Michael MIC failure detected in received frame%s",
77                            local ? " (local)" : "");
78 
79           if (addr && local) {
80                     struct sta_info *sta = ap_get_sta(hapd, addr);
81                     if (sta != NULL) {
82                               wpa_auth_sta_local_mic_failure_report(sta->wpa_sm);
83                               hostapd_logger(hapd, addr, HOSTAPD_MODULE_IEEE80211,
84                                                HOSTAPD_LEVEL_INFO,
85                                                "Michael MIC failure detected in "
86                                                "received frame");
87                               mlme_michaelmicfailure_indication(hapd, addr);
88                     } else {
89                               wpa_printf(MSG_DEBUG,
90                                            "MLME-MICHAELMICFAILURE.indication "
91                                            "for not associated STA (" MACSTR
92                                            ") ignored", MAC2STR(addr));
93                               return ret;
94                     }
95           }
96 
97           os_get_reltime(&now);
98           if (os_reltime_expired(&now, &hapd->michael_mic_failure, 60)) {
99                     hapd->michael_mic_failures = 1;
100           } else {
101                     hapd->michael_mic_failures++;
102                     if (hapd->michael_mic_failures > 1) {
103                               ieee80211_tkip_countermeasures_start(hapd);
104                               ret = 1;
105                     }
106           }
107           hapd->michael_mic_failure = now;
108 
109           return ret;
110 }
111