$search
00001 /* 00002 * hostapd - Authenticator for IEEE 802.11i RSN pre-authentication 00003 * Copyright (c) 2004-2007, Jouni Malinen <j@w1.fi> 00004 * 00005 * This program is free software; you can redistribute it and/or modify 00006 * it under the terms of the GNU General Public License version 2 as 00007 * published by the Free Software Foundation. 00008 * 00009 * Alternatively, this software may be distributed under the terms of BSD 00010 * license. 00011 * 00012 * See README and COPYING for more details. 00013 */ 00014 00015 #include "utils/includes.h" 00016 00017 #ifdef CONFIG_RSN_PREAUTH 00018 00019 #include "utils/common.h" 00020 #include "utils/eloop.h" 00021 #include "l2_packet/l2_packet.h" 00022 #include "common/wpa_common.h" 00023 #include "eapol_auth/eapol_auth_sm.h" 00024 #include "eapol_auth/eapol_auth_sm_i.h" 00025 #include "hostapd.h" 00026 #include "ap_config.h" 00027 #include "ieee802_1x.h" 00028 #include "sta_info.h" 00029 #include "wpa_auth.h" 00030 #include "preauth_auth.h" 00031 00032 #ifndef ETH_P_PREAUTH 00033 #define ETH_P_PREAUTH 0x88C7 /* IEEE 802.11i pre-authentication */ 00034 #endif /* ETH_P_PREAUTH */ 00035 00036 static const int dot11RSNAConfigPMKLifetime = 43200; 00037 00038 struct rsn_preauth_interface { 00039 struct rsn_preauth_interface *next; 00040 struct hostapd_data *hapd; 00041 struct l2_packet_data *l2; 00042 char *ifname; 00043 int ifindex; 00044 }; 00045 00046 00047 static void rsn_preauth_receive(void *ctx, const u8 *src_addr, 00048 const u8 *buf, size_t len) 00049 { 00050 struct rsn_preauth_interface *piface = ctx; 00051 struct hostapd_data *hapd = piface->hapd; 00052 struct ieee802_1x_hdr *hdr; 00053 struct sta_info *sta; 00054 struct l2_ethhdr *ethhdr; 00055 00056 wpa_printf(MSG_DEBUG, "RSN: receive pre-auth packet " 00057 "from interface '%s'", piface->ifname); 00058 if (len < sizeof(*ethhdr) + sizeof(*hdr)) { 00059 wpa_printf(MSG_DEBUG, "RSN: too short pre-auth packet " 00060 "(len=%lu)", (unsigned long) len); 00061 return; 00062 } 00063 00064 ethhdr = (struct l2_ethhdr *) buf; 00065 hdr = (struct ieee802_1x_hdr *) (ethhdr + 1); 00066 00067 if (os_memcmp(ethhdr->h_dest, hapd->own_addr, ETH_ALEN) != 0) { 00068 wpa_printf(MSG_DEBUG, "RSN: pre-auth for foreign address " 00069 MACSTR, MAC2STR(ethhdr->h_dest)); 00070 return; 00071 } 00072 00073 sta = ap_get_sta(hapd, ethhdr->h_source); 00074 if (sta && (sta->flags & WLAN_STA_ASSOC)) { 00075 wpa_printf(MSG_DEBUG, "RSN: pre-auth for already association " 00076 "STA " MACSTR, MAC2STR(sta->addr)); 00077 return; 00078 } 00079 if (!sta && hdr->type == IEEE802_1X_TYPE_EAPOL_START) { 00080 sta = ap_sta_add(hapd, ethhdr->h_source); 00081 if (sta == NULL) 00082 return; 00083 sta->flags = WLAN_STA_PREAUTH; 00084 00085 ieee802_1x_new_station(hapd, sta); 00086 if (sta->eapol_sm == NULL) { 00087 ap_free_sta(hapd, sta); 00088 sta = NULL; 00089 } else { 00090 sta->eapol_sm->radius_identifier = -1; 00091 sta->eapol_sm->portValid = TRUE; 00092 sta->eapol_sm->flags |= EAPOL_SM_PREAUTH; 00093 } 00094 } 00095 if (sta == NULL) 00096 return; 00097 sta->preauth_iface = piface; 00098 ieee802_1x_receive(hapd, ethhdr->h_source, (u8 *) (ethhdr + 1), 00099 len - sizeof(*ethhdr)); 00100 } 00101 00102 00103 static int rsn_preauth_iface_add(struct hostapd_data *hapd, const char *ifname) 00104 { 00105 struct rsn_preauth_interface *piface; 00106 00107 wpa_printf(MSG_DEBUG, "RSN pre-auth interface '%s'", ifname); 00108 00109 piface = os_zalloc(sizeof(*piface)); 00110 if (piface == NULL) 00111 return -1; 00112 piface->hapd = hapd; 00113 00114 piface->ifname = os_strdup(ifname); 00115 if (piface->ifname == NULL) { 00116 goto fail1; 00117 } 00118 00119 piface->l2 = l2_packet_init(piface->ifname, NULL, ETH_P_PREAUTH, 00120 rsn_preauth_receive, piface, 1); 00121 if (piface->l2 == NULL) { 00122 wpa_printf(MSG_ERROR, "Failed to open register layer 2 access " 00123 "to ETH_P_PREAUTH"); 00124 goto fail2; 00125 } 00126 00127 piface->next = hapd->preauth_iface; 00128 hapd->preauth_iface = piface; 00129 return 0; 00130 00131 fail2: 00132 os_free(piface->ifname); 00133 fail1: 00134 os_free(piface); 00135 return -1; 00136 } 00137 00138 00139 void rsn_preauth_iface_deinit(struct hostapd_data *hapd) 00140 { 00141 struct rsn_preauth_interface *piface, *prev; 00142 00143 piface = hapd->preauth_iface; 00144 hapd->preauth_iface = NULL; 00145 while (piface) { 00146 prev = piface; 00147 piface = piface->next; 00148 l2_packet_deinit(prev->l2); 00149 os_free(prev->ifname); 00150 os_free(prev); 00151 } 00152 } 00153 00154 00155 int rsn_preauth_iface_init(struct hostapd_data *hapd) 00156 { 00157 char *tmp, *start, *end; 00158 00159 if (hapd->conf->rsn_preauth_interfaces == NULL) 00160 return 0; 00161 00162 tmp = os_strdup(hapd->conf->rsn_preauth_interfaces); 00163 if (tmp == NULL) 00164 return -1; 00165 start = tmp; 00166 for (;;) { 00167 while (*start == ' ') 00168 start++; 00169 if (*start == '\0') 00170 break; 00171 end = os_strchr(start, ' '); 00172 if (end) 00173 *end = '\0'; 00174 00175 if (rsn_preauth_iface_add(hapd, start)) { 00176 rsn_preauth_iface_deinit(hapd); 00177 os_free(tmp); 00178 return -1; 00179 } 00180 00181 if (end) 00182 start = end + 1; 00183 else 00184 break; 00185 } 00186 os_free(tmp); 00187 return 0; 00188 } 00189 00190 00191 static void rsn_preauth_finished_cb(void *eloop_ctx, void *timeout_ctx) 00192 { 00193 struct hostapd_data *hapd = eloop_ctx; 00194 struct sta_info *sta = timeout_ctx; 00195 wpa_printf(MSG_DEBUG, "RSN: Removing pre-authentication STA entry for " 00196 MACSTR, MAC2STR(sta->addr)); 00197 ap_free_sta(hapd, sta); 00198 } 00199 00200 00201 void rsn_preauth_finished(struct hostapd_data *hapd, struct sta_info *sta, 00202 int success) 00203 { 00204 const u8 *key; 00205 size_t len; 00206 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_WPA, 00207 HOSTAPD_LEVEL_INFO, "pre-authentication %s", 00208 success ? "succeeded" : "failed"); 00209 00210 key = ieee802_1x_get_key(sta->eapol_sm, &len); 00211 if (len > PMK_LEN) 00212 len = PMK_LEN; 00213 if (success && key) { 00214 if (wpa_auth_pmksa_add_preauth(hapd->wpa_auth, key, len, 00215 sta->addr, 00216 dot11RSNAConfigPMKLifetime, 00217 sta->eapol_sm) == 0) { 00218 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_WPA, 00219 HOSTAPD_LEVEL_DEBUG, 00220 "added PMKSA cache entry (pre-auth)"); 00221 } else { 00222 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_WPA, 00223 HOSTAPD_LEVEL_DEBUG, 00224 "failed to add PMKSA cache entry " 00225 "(pre-auth)"); 00226 } 00227 } 00228 00229 /* 00230 * Finish STA entry removal from timeout in order to avoid freeing 00231 * STA data before the caller has finished processing. 00232 */ 00233 eloop_register_timeout(0, 0, rsn_preauth_finished_cb, hapd, sta); 00234 } 00235 00236 00237 void rsn_preauth_send(struct hostapd_data *hapd, struct sta_info *sta, 00238 u8 *buf, size_t len) 00239 { 00240 struct rsn_preauth_interface *piface; 00241 struct l2_ethhdr *ethhdr; 00242 00243 piface = hapd->preauth_iface; 00244 while (piface) { 00245 if (piface == sta->preauth_iface) 00246 break; 00247 piface = piface->next; 00248 } 00249 00250 if (piface == NULL) { 00251 wpa_printf(MSG_DEBUG, "RSN: Could not find pre-authentication " 00252 "interface for " MACSTR, MAC2STR(sta->addr)); 00253 return; 00254 } 00255 00256 ethhdr = os_malloc(sizeof(*ethhdr) + len); 00257 if (ethhdr == NULL) 00258 return; 00259 00260 os_memcpy(ethhdr->h_dest, sta->addr, ETH_ALEN); 00261 os_memcpy(ethhdr->h_source, hapd->own_addr, ETH_ALEN); 00262 ethhdr->h_proto = host_to_be16(ETH_P_PREAUTH); 00263 os_memcpy(ethhdr + 1, buf, len); 00264 00265 if (l2_packet_send(piface->l2, sta->addr, ETH_P_PREAUTH, (u8 *) ethhdr, 00266 sizeof(*ethhdr) + len) < 0) { 00267 wpa_printf(MSG_ERROR, "Failed to send preauth packet using " 00268 "l2_packet_send\n"); 00269 } 00270 os_free(ethhdr); 00271 } 00272 00273 00274 void rsn_preauth_free_station(struct hostapd_data *hapd, struct sta_info *sta) 00275 { 00276 eloop_cancel_timeout(rsn_preauth_finished_cb, hapd, sta); 00277 } 00278 00279 #endif /* CONFIG_RSN_PREAUTH */