preauth.c 6.6 KB

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