ieee802_11_auth.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643
  1. /*
  2. * hostapd / IEEE 802.11 authentication (ACL)
  3. * Copyright (c) 2003-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. * Access control list for IEEE 802.11 authentication can uses statically
  9. * configured ACL from configuration files or an external RADIUS server.
  10. * Results from external RADIUS queries are cached to allow faster
  11. * authentication frame processing.
  12. */
  13. #include "utils/includes.h"
  14. #include "utils/common.h"
  15. #include "utils/eloop.h"
  16. #include "crypto/sha1.h"
  17. #include "radius/radius.h"
  18. #include "radius/radius_client.h"
  19. #include "hostapd.h"
  20. #include "ap_config.h"
  21. #include "ap_drv_ops.h"
  22. #include "ieee802_11.h"
  23. #include "ieee802_1x.h"
  24. #include "ieee802_11_auth.h"
  25. #define RADIUS_ACL_TIMEOUT 30
  26. struct hostapd_cached_radius_acl {
  27. struct os_reltime timestamp;
  28. macaddr addr;
  29. int accepted; /* HOSTAPD_ACL_* */
  30. struct hostapd_cached_radius_acl *next;
  31. u32 session_timeout;
  32. u32 acct_interim_interval;
  33. int vlan_id;
  34. struct hostapd_sta_wpa_psk_short *psk;
  35. char *identity;
  36. char *radius_cui;
  37. };
  38. struct hostapd_acl_query_data {
  39. struct os_reltime timestamp;
  40. u8 radius_id;
  41. macaddr addr;
  42. u8 *auth_msg; /* IEEE 802.11 authentication frame from station */
  43. size_t auth_msg_len;
  44. struct hostapd_acl_query_data *next;
  45. };
  46. #ifndef CONFIG_NO_RADIUS
  47. static void hostapd_acl_cache_free_entry(struct hostapd_cached_radius_acl *e)
  48. {
  49. os_free(e->identity);
  50. os_free(e->radius_cui);
  51. hostapd_free_psk_list(e->psk);
  52. os_free(e);
  53. }
  54. static void hostapd_acl_cache_free(struct hostapd_cached_radius_acl *acl_cache)
  55. {
  56. struct hostapd_cached_radius_acl *prev;
  57. while (acl_cache) {
  58. prev = acl_cache;
  59. acl_cache = acl_cache->next;
  60. hostapd_acl_cache_free_entry(prev);
  61. }
  62. }
  63. static void copy_psk_list(struct hostapd_sta_wpa_psk_short **psk,
  64. struct hostapd_sta_wpa_psk_short *src)
  65. {
  66. struct hostapd_sta_wpa_psk_short **copy_to;
  67. struct hostapd_sta_wpa_psk_short *copy_from;
  68. /* Copy PSK linked list */
  69. copy_to = psk;
  70. copy_from = src;
  71. while (copy_from && copy_to) {
  72. *copy_to = os_zalloc(sizeof(struct hostapd_sta_wpa_psk_short));
  73. if (*copy_to == NULL)
  74. break;
  75. os_memcpy(*copy_to, copy_from,
  76. sizeof(struct hostapd_sta_wpa_psk_short));
  77. copy_from = copy_from->next;
  78. copy_to = &((*copy_to)->next);
  79. }
  80. if (copy_to)
  81. *copy_to = NULL;
  82. }
  83. static int hostapd_acl_cache_get(struct hostapd_data *hapd, const u8 *addr,
  84. u32 *session_timeout,
  85. u32 *acct_interim_interval, int *vlan_id,
  86. struct hostapd_sta_wpa_psk_short **psk,
  87. char **identity, char **radius_cui)
  88. {
  89. struct hostapd_cached_radius_acl *entry;
  90. struct os_reltime now;
  91. os_get_reltime(&now);
  92. for (entry = hapd->acl_cache; entry; entry = entry->next) {
  93. if (os_memcmp(entry->addr, addr, ETH_ALEN) != 0)
  94. continue;
  95. if (os_reltime_expired(&now, &entry->timestamp,
  96. RADIUS_ACL_TIMEOUT))
  97. return -1; /* entry has expired */
  98. if (entry->accepted == HOSTAPD_ACL_ACCEPT_TIMEOUT)
  99. if (session_timeout)
  100. *session_timeout = entry->session_timeout;
  101. if (acct_interim_interval)
  102. *acct_interim_interval =
  103. entry->acct_interim_interval;
  104. if (vlan_id)
  105. *vlan_id = entry->vlan_id;
  106. copy_psk_list(psk, entry->psk);
  107. if (identity) {
  108. if (entry->identity)
  109. *identity = os_strdup(entry->identity);
  110. else
  111. *identity = NULL;
  112. }
  113. if (radius_cui) {
  114. if (entry->radius_cui)
  115. *radius_cui = os_strdup(entry->radius_cui);
  116. else
  117. *radius_cui = NULL;
  118. }
  119. return entry->accepted;
  120. }
  121. return -1;
  122. }
  123. #endif /* CONFIG_NO_RADIUS */
  124. static void hostapd_acl_query_free(struct hostapd_acl_query_data *query)
  125. {
  126. if (query == NULL)
  127. return;
  128. os_free(query->auth_msg);
  129. os_free(query);
  130. }
  131. #ifndef CONFIG_NO_RADIUS
  132. static int hostapd_radius_acl_query(struct hostapd_data *hapd, const u8 *addr,
  133. struct hostapd_acl_query_data *query)
  134. {
  135. struct radius_msg *msg;
  136. char buf[128];
  137. query->radius_id = radius_client_get_id(hapd->radius);
  138. msg = radius_msg_new(RADIUS_CODE_ACCESS_REQUEST, query->radius_id);
  139. if (msg == NULL)
  140. return -1;
  141. radius_msg_make_authenticator(msg, addr, ETH_ALEN);
  142. os_snprintf(buf, sizeof(buf), RADIUS_ADDR_FORMAT, MAC2STR(addr));
  143. if (!radius_msg_add_attr(msg, RADIUS_ATTR_USER_NAME, (u8 *) buf,
  144. os_strlen(buf))) {
  145. wpa_printf(MSG_DEBUG, "Could not add User-Name");
  146. goto fail;
  147. }
  148. if (!radius_msg_add_attr_user_password(
  149. msg, (u8 *) buf, os_strlen(buf),
  150. hapd->conf->radius->auth_server->shared_secret,
  151. hapd->conf->radius->auth_server->shared_secret_len)) {
  152. wpa_printf(MSG_DEBUG, "Could not add User-Password");
  153. goto fail;
  154. }
  155. if (add_common_radius_attr(hapd, hapd->conf->radius_auth_req_attr,
  156. NULL, msg) < 0)
  157. goto fail;
  158. os_snprintf(buf, sizeof(buf), RADIUS_802_1X_ADDR_FORMAT,
  159. MAC2STR(addr));
  160. if (!radius_msg_add_attr(msg, RADIUS_ATTR_CALLING_STATION_ID,
  161. (u8 *) buf, os_strlen(buf))) {
  162. wpa_printf(MSG_DEBUG, "Could not add Calling-Station-Id");
  163. goto fail;
  164. }
  165. os_snprintf(buf, sizeof(buf), "CONNECT 11Mbps 802.11b");
  166. if (!radius_msg_add_attr(msg, RADIUS_ATTR_CONNECT_INFO,
  167. (u8 *) buf, os_strlen(buf))) {
  168. wpa_printf(MSG_DEBUG, "Could not add Connect-Info");
  169. goto fail;
  170. }
  171. if (radius_client_send(hapd->radius, msg, RADIUS_AUTH, addr) < 0)
  172. goto fail;
  173. return 0;
  174. fail:
  175. radius_msg_free(msg);
  176. return -1;
  177. }
  178. #endif /* CONFIG_NO_RADIUS */
  179. /**
  180. * hostapd_allowed_address - Check whether a specified STA can be authenticated
  181. * @hapd: hostapd BSS data
  182. * @addr: MAC address of the STA
  183. * @msg: Authentication message
  184. * @len: Length of msg in octets
  185. * @session_timeout: Buffer for returning session timeout (from RADIUS)
  186. * @acct_interim_interval: Buffer for returning account interval (from RADIUS)
  187. * @vlan_id: Buffer for returning VLAN ID
  188. * @psk: Linked list buffer for returning WPA PSK
  189. * @identity: Buffer for returning identity (from RADIUS)
  190. * @radius_cui: Buffer for returning CUI (from RADIUS)
  191. * Returns: HOSTAPD_ACL_ACCEPT, HOSTAPD_ACL_REJECT, or HOSTAPD_ACL_PENDING
  192. *
  193. * The caller is responsible for freeing the returned *identity and *radius_cui
  194. * values with os_free().
  195. */
  196. int hostapd_allowed_address(struct hostapd_data *hapd, const u8 *addr,
  197. const u8 *msg, size_t len, u32 *session_timeout,
  198. u32 *acct_interim_interval, int *vlan_id,
  199. struct hostapd_sta_wpa_psk_short **psk,
  200. char **identity, char **radius_cui)
  201. {
  202. if (session_timeout)
  203. *session_timeout = 0;
  204. if (acct_interim_interval)
  205. *acct_interim_interval = 0;
  206. if (vlan_id)
  207. *vlan_id = 0;
  208. if (psk)
  209. *psk = NULL;
  210. if (identity)
  211. *identity = NULL;
  212. if (radius_cui)
  213. *radius_cui = NULL;
  214. if (hostapd_maclist_found(hapd->conf->accept_mac,
  215. hapd->conf->num_accept_mac, addr, vlan_id))
  216. return HOSTAPD_ACL_ACCEPT;
  217. if (hostapd_maclist_found(hapd->conf->deny_mac,
  218. hapd->conf->num_deny_mac, addr, vlan_id))
  219. return HOSTAPD_ACL_REJECT;
  220. if (hapd->conf->macaddr_acl == ACCEPT_UNLESS_DENIED)
  221. return HOSTAPD_ACL_ACCEPT;
  222. if (hapd->conf->macaddr_acl == DENY_UNLESS_ACCEPTED)
  223. return HOSTAPD_ACL_REJECT;
  224. if (hapd->conf->macaddr_acl == USE_EXTERNAL_RADIUS_AUTH) {
  225. #ifdef CONFIG_NO_RADIUS
  226. return HOSTAPD_ACL_REJECT;
  227. #else /* CONFIG_NO_RADIUS */
  228. struct hostapd_acl_query_data *query;
  229. /* Check whether ACL cache has an entry for this station */
  230. int res = hostapd_acl_cache_get(hapd, addr, session_timeout,
  231. acct_interim_interval,
  232. vlan_id, psk,
  233. identity, radius_cui);
  234. if (res == HOSTAPD_ACL_ACCEPT ||
  235. res == HOSTAPD_ACL_ACCEPT_TIMEOUT)
  236. return res;
  237. if (res == HOSTAPD_ACL_REJECT)
  238. return HOSTAPD_ACL_REJECT;
  239. query = hapd->acl_queries;
  240. while (query) {
  241. if (os_memcmp(query->addr, addr, ETH_ALEN) == 0) {
  242. /* pending query in RADIUS retransmit queue;
  243. * do not generate a new one */
  244. if (identity) {
  245. os_free(*identity);
  246. *identity = NULL;
  247. }
  248. if (radius_cui) {
  249. os_free(*radius_cui);
  250. *radius_cui = NULL;
  251. }
  252. return HOSTAPD_ACL_PENDING;
  253. }
  254. query = query->next;
  255. }
  256. if (!hapd->conf->radius->auth_server)
  257. return HOSTAPD_ACL_REJECT;
  258. /* No entry in the cache - query external RADIUS server */
  259. query = os_zalloc(sizeof(*query));
  260. if (query == NULL) {
  261. wpa_printf(MSG_ERROR, "malloc for query data failed");
  262. return HOSTAPD_ACL_REJECT;
  263. }
  264. os_get_reltime(&query->timestamp);
  265. os_memcpy(query->addr, addr, ETH_ALEN);
  266. if (hostapd_radius_acl_query(hapd, addr, query)) {
  267. wpa_printf(MSG_DEBUG, "Failed to send Access-Request "
  268. "for ACL query.");
  269. hostapd_acl_query_free(query);
  270. return HOSTAPD_ACL_REJECT;
  271. }
  272. query->auth_msg = os_malloc(len);
  273. if (query->auth_msg == NULL) {
  274. wpa_printf(MSG_ERROR, "Failed to allocate memory for "
  275. "auth frame.");
  276. hostapd_acl_query_free(query);
  277. return HOSTAPD_ACL_REJECT;
  278. }
  279. os_memcpy(query->auth_msg, msg, len);
  280. query->auth_msg_len = len;
  281. query->next = hapd->acl_queries;
  282. hapd->acl_queries = query;
  283. /* Queued data will be processed in hostapd_acl_recv_radius()
  284. * when RADIUS server replies to the sent Access-Request. */
  285. return HOSTAPD_ACL_PENDING;
  286. #endif /* CONFIG_NO_RADIUS */
  287. }
  288. return HOSTAPD_ACL_REJECT;
  289. }
  290. #ifndef CONFIG_NO_RADIUS
  291. static void hostapd_acl_expire_cache(struct hostapd_data *hapd,
  292. struct os_reltime *now)
  293. {
  294. struct hostapd_cached_radius_acl *prev, *entry, *tmp;
  295. prev = NULL;
  296. entry = hapd->acl_cache;
  297. while (entry) {
  298. if (os_reltime_expired(now, &entry->timestamp,
  299. RADIUS_ACL_TIMEOUT)) {
  300. wpa_printf(MSG_DEBUG, "Cached ACL entry for " MACSTR
  301. " has expired.", MAC2STR(entry->addr));
  302. if (prev)
  303. prev->next = entry->next;
  304. else
  305. hapd->acl_cache = entry->next;
  306. hostapd_drv_set_radius_acl_expire(hapd, entry->addr);
  307. tmp = entry;
  308. entry = entry->next;
  309. hostapd_acl_cache_free_entry(tmp);
  310. continue;
  311. }
  312. prev = entry;
  313. entry = entry->next;
  314. }
  315. }
  316. static void hostapd_acl_expire_queries(struct hostapd_data *hapd,
  317. struct os_reltime *now)
  318. {
  319. struct hostapd_acl_query_data *prev, *entry, *tmp;
  320. prev = NULL;
  321. entry = hapd->acl_queries;
  322. while (entry) {
  323. if (os_reltime_expired(now, &entry->timestamp,
  324. RADIUS_ACL_TIMEOUT)) {
  325. wpa_printf(MSG_DEBUG, "ACL query for " MACSTR
  326. " has expired.", MAC2STR(entry->addr));
  327. if (prev)
  328. prev->next = entry->next;
  329. else
  330. hapd->acl_queries = entry->next;
  331. tmp = entry;
  332. entry = entry->next;
  333. hostapd_acl_query_free(tmp);
  334. continue;
  335. }
  336. prev = entry;
  337. entry = entry->next;
  338. }
  339. }
  340. /**
  341. * hostapd_acl_expire - ACL cache expiration callback
  342. * @eloop_ctx: struct hostapd_data *
  343. * @timeout_ctx: Not used
  344. */
  345. static void hostapd_acl_expire(void *eloop_ctx, void *timeout_ctx)
  346. {
  347. struct hostapd_data *hapd = eloop_ctx;
  348. struct os_reltime now;
  349. os_get_reltime(&now);
  350. hostapd_acl_expire_cache(hapd, &now);
  351. hostapd_acl_expire_queries(hapd, &now);
  352. eloop_register_timeout(10, 0, hostapd_acl_expire, hapd, NULL);
  353. }
  354. static void decode_tunnel_passwords(struct hostapd_data *hapd,
  355. const u8 *shared_secret,
  356. size_t shared_secret_len,
  357. struct radius_msg *msg,
  358. struct radius_msg *req,
  359. struct hostapd_cached_radius_acl *cache)
  360. {
  361. int passphraselen;
  362. char *passphrase, *strpassphrase;
  363. size_t i;
  364. struct hostapd_sta_wpa_psk_short *psk;
  365. /*
  366. * Decode all tunnel passwords as PSK and save them into a linked list.
  367. */
  368. for (i = 0; ; i++) {
  369. passphrase = radius_msg_get_tunnel_password(
  370. msg, &passphraselen, shared_secret, shared_secret_len,
  371. req, i);
  372. /*
  373. * Passphrase is NULL iff there is no i-th Tunnel-Password
  374. * attribute in msg.
  375. */
  376. if (passphrase == NULL)
  377. break;
  378. /*
  379. * passphrase does not contain the NULL termination.
  380. * Add it here as pbkdf2_sha1() requires it.
  381. */
  382. strpassphrase = os_zalloc(passphraselen + 1);
  383. psk = os_zalloc(sizeof(struct hostapd_sta_wpa_psk_short));
  384. if (strpassphrase && psk) {
  385. os_memcpy(strpassphrase, passphrase, passphraselen);
  386. pbkdf2_sha1(strpassphrase,
  387. hapd->conf->ssid.ssid,
  388. hapd->conf->ssid.ssid_len, 4096,
  389. psk->psk, PMK_LEN);
  390. psk->next = cache->psk;
  391. cache->psk = psk;
  392. psk = NULL;
  393. }
  394. os_free(strpassphrase);
  395. os_free(psk);
  396. os_free(passphrase);
  397. }
  398. }
  399. /**
  400. * hostapd_acl_recv_radius - Process incoming RADIUS Authentication messages
  401. * @msg: RADIUS response message
  402. * @req: RADIUS request message
  403. * @shared_secret: RADIUS shared secret
  404. * @shared_secret_len: Length of shared_secret in octets
  405. * @data: Context data (struct hostapd_data *)
  406. * Returns: RADIUS_RX_PROCESSED if RADIUS message was a reply to ACL query (and
  407. * was processed here) or RADIUS_RX_UNKNOWN if not.
  408. */
  409. static RadiusRxResult
  410. hostapd_acl_recv_radius(struct radius_msg *msg, struct radius_msg *req,
  411. const u8 *shared_secret, size_t shared_secret_len,
  412. void *data)
  413. {
  414. struct hostapd_data *hapd = data;
  415. struct hostapd_acl_query_data *query, *prev;
  416. struct hostapd_cached_radius_acl *cache;
  417. struct radius_hdr *hdr = radius_msg_get_hdr(msg);
  418. query = hapd->acl_queries;
  419. prev = NULL;
  420. while (query) {
  421. if (query->radius_id == hdr->identifier)
  422. break;
  423. prev = query;
  424. query = query->next;
  425. }
  426. if (query == NULL)
  427. return RADIUS_RX_UNKNOWN;
  428. wpa_printf(MSG_DEBUG, "Found matching Access-Request for RADIUS "
  429. "message (id=%d)", query->radius_id);
  430. if (radius_msg_verify(msg, shared_secret, shared_secret_len, req, 0)) {
  431. wpa_printf(MSG_INFO, "Incoming RADIUS packet did not have "
  432. "correct authenticator - dropped\n");
  433. return RADIUS_RX_INVALID_AUTHENTICATOR;
  434. }
  435. if (hdr->code != RADIUS_CODE_ACCESS_ACCEPT &&
  436. hdr->code != RADIUS_CODE_ACCESS_REJECT) {
  437. wpa_printf(MSG_DEBUG, "Unknown RADIUS message code %d to ACL "
  438. "query", hdr->code);
  439. return RADIUS_RX_UNKNOWN;
  440. }
  441. /* Insert Accept/Reject info into ACL cache */
  442. cache = os_zalloc(sizeof(*cache));
  443. if (cache == NULL) {
  444. wpa_printf(MSG_DEBUG, "Failed to add ACL cache entry");
  445. goto done;
  446. }
  447. os_get_reltime(&cache->timestamp);
  448. os_memcpy(cache->addr, query->addr, sizeof(cache->addr));
  449. if (hdr->code == RADIUS_CODE_ACCESS_ACCEPT) {
  450. u8 *buf;
  451. size_t len;
  452. if (radius_msg_get_attr_int32(msg, RADIUS_ATTR_SESSION_TIMEOUT,
  453. &cache->session_timeout) == 0)
  454. cache->accepted = HOSTAPD_ACL_ACCEPT_TIMEOUT;
  455. else
  456. cache->accepted = HOSTAPD_ACL_ACCEPT;
  457. if (radius_msg_get_attr_int32(
  458. msg, RADIUS_ATTR_ACCT_INTERIM_INTERVAL,
  459. &cache->acct_interim_interval) == 0 &&
  460. cache->acct_interim_interval < 60) {
  461. wpa_printf(MSG_DEBUG, "Ignored too small "
  462. "Acct-Interim-Interval %d for STA " MACSTR,
  463. cache->acct_interim_interval,
  464. MAC2STR(query->addr));
  465. cache->acct_interim_interval = 0;
  466. }
  467. cache->vlan_id = radius_msg_get_vlanid(msg);
  468. decode_tunnel_passwords(hapd, shared_secret, shared_secret_len,
  469. msg, req, cache);
  470. if (radius_msg_get_attr_ptr(msg, RADIUS_ATTR_USER_NAME,
  471. &buf, &len, NULL) == 0) {
  472. cache->identity = os_zalloc(len + 1);
  473. if (cache->identity)
  474. os_memcpy(cache->identity, buf, len);
  475. }
  476. if (radius_msg_get_attr_ptr(
  477. msg, RADIUS_ATTR_CHARGEABLE_USER_IDENTITY,
  478. &buf, &len, NULL) == 0) {
  479. cache->radius_cui = os_zalloc(len + 1);
  480. if (cache->radius_cui)
  481. os_memcpy(cache->radius_cui, buf, len);
  482. }
  483. if (hapd->conf->wpa_psk_radius == PSK_RADIUS_REQUIRED &&
  484. !cache->psk)
  485. cache->accepted = HOSTAPD_ACL_REJECT;
  486. } else
  487. cache->accepted = HOSTAPD_ACL_REJECT;
  488. cache->next = hapd->acl_cache;
  489. hapd->acl_cache = cache;
  490. #ifdef CONFIG_DRIVER_RADIUS_ACL
  491. hostapd_drv_set_radius_acl_auth(hapd, query->addr, cache->accepted,
  492. cache->session_timeout);
  493. #else /* CONFIG_DRIVER_RADIUS_ACL */
  494. #ifdef NEED_AP_MLME
  495. /* Re-send original authentication frame for 802.11 processing */
  496. wpa_printf(MSG_DEBUG, "Re-sending authentication frame after "
  497. "successful RADIUS ACL query");
  498. ieee802_11_mgmt(hapd, query->auth_msg, query->auth_msg_len, NULL);
  499. #endif /* NEED_AP_MLME */
  500. #endif /* CONFIG_DRIVER_RADIUS_ACL */
  501. done:
  502. if (prev == NULL)
  503. hapd->acl_queries = query->next;
  504. else
  505. prev->next = query->next;
  506. hostapd_acl_query_free(query);
  507. return RADIUS_RX_PROCESSED;
  508. }
  509. #endif /* CONFIG_NO_RADIUS */
  510. /**
  511. * hostapd_acl_init: Initialize IEEE 802.11 ACL
  512. * @hapd: hostapd BSS data
  513. * Returns: 0 on success, -1 on failure
  514. */
  515. int hostapd_acl_init(struct hostapd_data *hapd)
  516. {
  517. #ifndef CONFIG_NO_RADIUS
  518. if (radius_client_register(hapd->radius, RADIUS_AUTH,
  519. hostapd_acl_recv_radius, hapd))
  520. return -1;
  521. eloop_register_timeout(10, 0, hostapd_acl_expire, hapd, NULL);
  522. #endif /* CONFIG_NO_RADIUS */
  523. return 0;
  524. }
  525. /**
  526. * hostapd_acl_deinit - Deinitialize IEEE 802.11 ACL
  527. * @hapd: hostapd BSS data
  528. */
  529. void hostapd_acl_deinit(struct hostapd_data *hapd)
  530. {
  531. struct hostapd_acl_query_data *query, *prev;
  532. #ifndef CONFIG_NO_RADIUS
  533. eloop_cancel_timeout(hostapd_acl_expire, hapd, NULL);
  534. hostapd_acl_cache_free(hapd->acl_cache);
  535. #endif /* CONFIG_NO_RADIUS */
  536. query = hapd->acl_queries;
  537. while (query) {
  538. prev = query;
  539. query = query->next;
  540. hostapd_acl_query_free(prev);
  541. }
  542. }
  543. void hostapd_free_psk_list(struct hostapd_sta_wpa_psk_short *psk)
  544. {
  545. while (psk) {
  546. struct hostapd_sta_wpa_psk_short *prev = psk;
  547. psk = psk->next;
  548. os_free(prev);
  549. }
  550. }