ieee802_11_auth.c 18 KB

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