preauth.c 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275
  1. /*
  2. * hostapd - Authenticator for IEEE 802.11i RSN pre-authentication
  3. * Copyright (c) 2004-2007, Jouni Malinen <j@w1.fi>
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License version 2 as
  7. * published by the Free Software Foundation.
  8. *
  9. * Alternatively, this software may be distributed under the terms of BSD
  10. * license.
  11. *
  12. * See README and COPYING for more details.
  13. */
  14. #include "includes.h"
  15. #ifdef CONFIG_RSN_PREAUTH
  16. #include "hostapd.h"
  17. #include "l2_packet/l2_packet.h"
  18. #include "ieee802_1x.h"
  19. #include "eloop.h"
  20. #include "sta_info.h"
  21. #include "wpa_common.h"
  22. #include "eapol_sm.h"
  23. #include "wpa.h"
  24. #include "preauth.h"
  25. #ifndef ETH_P_PREAUTH
  26. #define ETH_P_PREAUTH 0x88C7 /* IEEE 802.11i pre-authentication */
  27. #endif /* ETH_P_PREAUTH */
  28. static const int dot11RSNAConfigPMKLifetime = 43200;
  29. struct rsn_preauth_interface {
  30. struct rsn_preauth_interface *next;
  31. struct hostapd_data *hapd;
  32. struct l2_packet_data *l2;
  33. char *ifname;
  34. int ifindex;
  35. };
  36. static void rsn_preauth_receive(void *ctx, const u8 *src_addr,
  37. const u8 *buf, size_t len)
  38. {
  39. struct rsn_preauth_interface *piface = ctx;
  40. struct hostapd_data *hapd = piface->hapd;
  41. struct ieee802_1x_hdr *hdr;
  42. struct sta_info *sta;
  43. struct l2_ethhdr *ethhdr;
  44. wpa_printf(MSG_DEBUG, "RSN: receive pre-auth packet "
  45. "from interface '%s'", piface->ifname);
  46. if (len < sizeof(*ethhdr) + sizeof(*hdr)) {
  47. wpa_printf(MSG_DEBUG, "RSN: too short pre-auth packet "
  48. "(len=%lu)", (unsigned long) len);
  49. return;
  50. }
  51. ethhdr = (struct l2_ethhdr *) buf;
  52. hdr = (struct ieee802_1x_hdr *) (ethhdr + 1);
  53. if (os_memcmp(ethhdr->h_dest, hapd->own_addr, ETH_ALEN) != 0) {
  54. wpa_printf(MSG_DEBUG, "RSN: pre-auth for foreign address "
  55. MACSTR, MAC2STR(ethhdr->h_dest));
  56. return;
  57. }
  58. sta = ap_get_sta(hapd, ethhdr->h_source);
  59. if (sta && (sta->flags & WLAN_STA_ASSOC)) {
  60. wpa_printf(MSG_DEBUG, "RSN: pre-auth for already association "
  61. "STA " MACSTR, MAC2STR(sta->addr));
  62. return;
  63. }
  64. if (!sta && hdr->type == IEEE802_1X_TYPE_EAPOL_START) {
  65. sta = ap_sta_add(hapd, ethhdr->h_source);
  66. if (sta == NULL)
  67. return;
  68. sta->flags = WLAN_STA_PREAUTH;
  69. ieee802_1x_new_station(hapd, sta);
  70. if (sta->eapol_sm == NULL) {
  71. ap_free_sta(hapd, sta);
  72. sta = NULL;
  73. } else {
  74. sta->eapol_sm->radius_identifier = -1;
  75. sta->eapol_sm->portValid = TRUE;
  76. sta->eapol_sm->flags |= EAPOL_SM_PREAUTH;
  77. }
  78. }
  79. if (sta == NULL)
  80. return;
  81. sta->preauth_iface = piface;
  82. ieee802_1x_receive(hapd, ethhdr->h_source, (u8 *) (ethhdr + 1),
  83. len - sizeof(*ethhdr));
  84. }
  85. static int rsn_preauth_iface_add(struct hostapd_data *hapd, const char *ifname)
  86. {
  87. struct rsn_preauth_interface *piface;
  88. wpa_printf(MSG_DEBUG, "RSN pre-auth interface '%s'", ifname);
  89. piface = os_zalloc(sizeof(*piface));
  90. if (piface == NULL)
  91. return -1;
  92. piface->hapd = hapd;
  93. piface->ifname = os_strdup(ifname);
  94. if (piface->ifname == NULL) {
  95. goto fail1;
  96. }
  97. piface->l2 = l2_packet_init(piface->ifname, NULL, ETH_P_PREAUTH,
  98. rsn_preauth_receive, piface, 1);
  99. if (piface->l2 == NULL) {
  100. wpa_printf(MSG_ERROR, "Failed to open register layer 2 access "
  101. "to ETH_P_PREAUTH");
  102. goto fail2;
  103. }
  104. piface->next = hapd->preauth_iface;
  105. hapd->preauth_iface = piface;
  106. return 0;
  107. fail2:
  108. os_free(piface->ifname);
  109. fail1:
  110. os_free(piface);
  111. return -1;
  112. }
  113. void rsn_preauth_iface_deinit(struct hostapd_data *hapd)
  114. {
  115. struct rsn_preauth_interface *piface, *prev;
  116. piface = hapd->preauth_iface;
  117. hapd->preauth_iface = NULL;
  118. while (piface) {
  119. prev = piface;
  120. piface = piface->next;
  121. l2_packet_deinit(prev->l2);
  122. os_free(prev->ifname);
  123. os_free(prev);
  124. }
  125. }
  126. int rsn_preauth_iface_init(struct hostapd_data *hapd)
  127. {
  128. char *tmp, *start, *end;
  129. if (hapd->conf->rsn_preauth_interfaces == NULL)
  130. return 0;
  131. tmp = os_strdup(hapd->conf->rsn_preauth_interfaces);
  132. if (tmp == NULL)
  133. return -1;
  134. start = tmp;
  135. for (;;) {
  136. while (*start == ' ')
  137. start++;
  138. if (*start == '\0')
  139. break;
  140. end = os_strchr(start, ' ');
  141. if (end)
  142. *end = '\0';
  143. if (rsn_preauth_iface_add(hapd, start)) {
  144. rsn_preauth_iface_deinit(hapd);
  145. return -1;
  146. }
  147. if (end)
  148. start = end + 1;
  149. else
  150. break;
  151. }
  152. os_free(tmp);
  153. return 0;
  154. }
  155. static void rsn_preauth_finished_cb(void *eloop_ctx, void *timeout_ctx)
  156. {
  157. struct hostapd_data *hapd = eloop_ctx;
  158. struct sta_info *sta = timeout_ctx;
  159. wpa_printf(MSG_DEBUG, "RSN: Removing pre-authentication STA entry for "
  160. MACSTR, MAC2STR(sta->addr));
  161. ap_free_sta(hapd, sta);
  162. }
  163. void rsn_preauth_finished(struct hostapd_data *hapd, struct sta_info *sta,
  164. int success)
  165. {
  166. const u8 *key;
  167. size_t len;
  168. hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_WPA,
  169. HOSTAPD_LEVEL_INFO, "pre-authentication %s",
  170. success ? "succeeded" : "failed");
  171. key = ieee802_1x_get_key(sta->eapol_sm, &len);
  172. if (len > PMK_LEN)
  173. len = PMK_LEN;
  174. if (success && key) {
  175. if (wpa_auth_pmksa_add_preauth(hapd->wpa_auth, key, len,
  176. sta->addr,
  177. dot11RSNAConfigPMKLifetime,
  178. sta->eapol_sm) == 0) {
  179. hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_WPA,
  180. HOSTAPD_LEVEL_DEBUG,
  181. "added PMKSA cache entry (pre-auth)");
  182. } else {
  183. hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_WPA,
  184. HOSTAPD_LEVEL_DEBUG,
  185. "failed to add PMKSA cache entry "
  186. "(pre-auth)");
  187. }
  188. }
  189. /*
  190. * Finish STA entry removal from timeout in order to avoid freeing
  191. * STA data before the caller has finished processing.
  192. */
  193. eloop_register_timeout(0, 0, rsn_preauth_finished_cb, hapd, sta);
  194. }
  195. void rsn_preauth_send(struct hostapd_data *hapd, struct sta_info *sta,
  196. u8 *buf, size_t len)
  197. {
  198. struct rsn_preauth_interface *piface;
  199. struct l2_ethhdr *ethhdr;
  200. piface = hapd->preauth_iface;
  201. while (piface) {
  202. if (piface == sta->preauth_iface)
  203. break;
  204. piface = piface->next;
  205. }
  206. if (piface == NULL) {
  207. wpa_printf(MSG_DEBUG, "RSN: Could not find pre-authentication "
  208. "interface for " MACSTR, MAC2STR(sta->addr));
  209. return;
  210. }
  211. ethhdr = os_malloc(sizeof(*ethhdr) + len);
  212. if (ethhdr == NULL)
  213. return;
  214. os_memcpy(ethhdr->h_dest, sta->addr, ETH_ALEN);
  215. os_memcpy(ethhdr->h_source, hapd->own_addr, ETH_ALEN);
  216. ethhdr->h_proto = htons(ETH_P_PREAUTH);
  217. os_memcpy(ethhdr + 1, buf, len);
  218. if (l2_packet_send(piface->l2, sta->addr, ETH_P_PREAUTH, (u8 *) ethhdr,
  219. sizeof(*ethhdr) + len) < 0) {
  220. wpa_printf(MSG_ERROR, "Failed to send preauth packet using "
  221. "l2_packet_send\n");
  222. }
  223. os_free(ethhdr);
  224. }
  225. void rsn_preauth_free_station(struct hostapd_data *hapd, struct sta_info *sta)
  226. {
  227. eloop_cancel_timeout(rsn_preauth_finished_cb, hapd, sta);
  228. }
  229. #endif /* CONFIG_RSN_PREAUTH */