preauth_auth.c 6.5 KB

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