1 /* 2 * hostapd / IEEE 802.11 authentication (ACL) 3 * Copyright (c) 2003-2022, 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 14 #include "utils/includes.h" 15 16 #include "utils/common.h" 17 #include "utils/eloop.h" 18 #include "radius/radius.h" 19 #include "radius/radius_client.h" 20 #include "hostapd.h" 21 #include "ap_config.h" 22 #include "ap_drv_ops.h" 23 #include "sta_info.h" 24 #include "wpa_auth.h" 25 #include "ieee802_11.h" 26 #include "ieee802_1x.h" 27 #include "ieee802_11_auth.h" 28 29 #define RADIUS_ACL_TIMEOUT 30 30 31 32 struct hostapd_cached_radius_acl { 33 struct os_reltime timestamp; 34 macaddr addr; 35 int accepted; /* HOSTAPD_ACL_* */ 36 struct hostapd_cached_radius_acl *next; 37 struct radius_sta info; 38 }; 39 40 41 struct hostapd_acl_query_data { 42 struct os_reltime timestamp; 43 u8 radius_id; 44 macaddr addr; 45 u8 *auth_msg; /* IEEE 802.11 authentication frame from station */ 46 size_t auth_msg_len; 47 struct hostapd_acl_query_data *next; 48 bool radius_psk; 49 int akm; 50 u8 *anonce; 51 u8 *eapol; 52 size_t eapol_len; 53 }; 54 55 56 #ifndef CONFIG_NO_RADIUS 57 static void hostapd_acl_cache_free_entry(struct hostapd_cached_radius_acl *e) 58 { 59 os_free(e->info.identity); 60 os_free(e->info.radius_cui); 61 hostapd_free_psk_list(e->info.psk); 62 os_free(e); 63 } 64 65 66 static void hostapd_acl_cache_free(struct hostapd_cached_radius_acl *acl_cache) 67 { 68 struct hostapd_cached_radius_acl *prev; 69 70 while (acl_cache) { 71 prev = acl_cache; 72 acl_cache = acl_cache->next; 73 hostapd_acl_cache_free_entry(prev); 74 } 75 } 76 77 78 static int hostapd_acl_cache_get(struct hostapd_data *hapd, const u8 *addr, 79 struct radius_sta *out) 80 { 81 struct hostapd_cached_radius_acl *entry; 82 struct os_reltime now; 83 84 os_get_reltime(&now); 85 86 for (entry = hapd->acl_cache; entry; entry = entry->next) { 87 if (!ether_addr_equal(entry->addr, addr)) 88 continue; 89 90 if (os_reltime_expired(&now, &entry->timestamp, 91 RADIUS_ACL_TIMEOUT)) 92 return -1; /* entry has expired */ 93 *out = entry->info; 94 95 return entry->accepted; 96 } 97 98 return -1; 99 } 100 #endif /* CONFIG_NO_RADIUS */ 101 102 103 static void hostapd_acl_query_free(struct hostapd_acl_query_data *query) 104 { 105 if (!query) 106 return; 107 os_free(query->auth_msg); 108 os_free(query->anonce); 109 os_free(query->eapol); 110 os_free(query); 111 } 112 113 114 #ifndef CONFIG_NO_RADIUS 115 static int hostapd_radius_acl_query(struct hostapd_data *hapd, const u8 *addr, 116 struct hostapd_acl_query_data *query) 117 { 118 struct radius_msg *msg; 119 char buf[128]; 120 121 query->radius_id = radius_client_get_id(hapd->radius); 122 msg = radius_msg_new(RADIUS_CODE_ACCESS_REQUEST, query->radius_id); 123 if (!msg) 124 return -1; 125 126 if (radius_msg_make_authenticator(msg) < 0) { 127 wpa_printf(MSG_INFO, "Could not make Request Authenticator"); 128 goto fail; 129 } 130 131 if (!radius_msg_add_msg_auth(msg)) 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 141 if (!radius_msg_add_attr_user_password( 142 msg, (u8 *) buf, os_strlen(buf), 143 hapd->conf->radius->auth_server->shared_secret, 144 hapd->conf->radius->auth_server->shared_secret_len)) { 145 wpa_printf(MSG_DEBUG, "Could not add User-Password"); 146 goto fail; 147 } 148 149 if (add_common_radius_attr(hapd, hapd->conf->radius_auth_req_attr, 150 NULL, msg) < 0) 151 goto fail; 152 153 os_snprintf(buf, sizeof(buf), RADIUS_802_1X_ADDR_FORMAT, 154 MAC2STR(addr)); 155 if (!radius_msg_add_attr(msg, RADIUS_ATTR_CALLING_STATION_ID, 156 (u8 *) buf, os_strlen(buf))) { 157 wpa_printf(MSG_DEBUG, "Could not add Calling-Station-Id"); 158 goto fail; 159 } 160 161 os_snprintf(buf, sizeof(buf), "CONNECT 11Mbps 802.11b"); 162 if (!radius_msg_add_attr(msg, RADIUS_ATTR_CONNECT_INFO, 163 (u8 *) buf, os_strlen(buf))) { 164 wpa_printf(MSG_DEBUG, "Could not add Connect-Info"); 165 goto fail; 166 } 167 168 if (query->akm && 169 !radius_msg_add_attr_int32(msg, RADIUS_ATTR_WLAN_AKM_SUITE, 170 wpa_akm_to_suite(query->akm))) { 171 wpa_printf(MSG_DEBUG, "Could not add WLAN-AKM-Suite"); 172 goto fail; 173 } 174 175 if (query->anonce && 176 !radius_msg_add_ext_vs(msg, RADIUS_ATTR_EXT_VENDOR_SPECIFIC_5, 177 RADIUS_VENDOR_ID_FREERADIUS, 178 RADIUS_VENDOR_ATTR_FREERADIUS_802_1X_ANONCE, 179 query->anonce, WPA_NONCE_LEN)) { 180 wpa_printf(MSG_DEBUG, "Could not add FreeRADIUS-802.1X-Anonce"); 181 goto fail; 182 } 183 184 if (query->eapol && 185 !radius_msg_add_ext_vs(msg, RADIUS_ATTR_EXT_VENDOR_SPECIFIC_5, 186 RADIUS_VENDOR_ID_FREERADIUS, 187 RADIUS_VENDOR_ATTR_FREERADIUS_802_1X_EAPOL_KEY_MSG, 188 query->eapol, query->eapol_len)) { 189 wpa_printf(MSG_DEBUG, "Could not add FreeRADIUS-802.1X-EAPoL-Key-Msg"); 190 goto fail; 191 } 192 193 if (radius_client_send(hapd->radius, msg, RADIUS_AUTH, addr) < 0) 194 goto fail; 195 return 0; 196 197 fail: 198 radius_msg_free(msg); 199 return -1; 200 } 201 #endif /* CONFIG_NO_RADIUS */ 202 203 204 /** 205 * hostapd_check_acl - Check a specified STA against accept/deny ACLs 206 * @hapd: hostapd BSS data 207 * @addr: MAC address of the STA 208 * @vlan_id: Buffer for returning VLAN ID 209 * Returns: HOSTAPD_ACL_ACCEPT, HOSTAPD_ACL_REJECT, or HOSTAPD_ACL_PENDING 210 */ 211 int hostapd_check_acl(struct hostapd_data *hapd, const u8 *addr, 212 struct vlan_description *vlan_id) 213 { 214 if (hostapd_maclist_found(hapd->conf->accept_mac, 215 hapd->conf->num_accept_mac, addr, vlan_id)) 216 return HOSTAPD_ACL_ACCEPT; 217 218 if (hostapd_maclist_found(hapd->conf->deny_mac, 219 hapd->conf->num_deny_mac, addr, vlan_id)) 220 return HOSTAPD_ACL_REJECT; 221 222 if (hapd->conf->macaddr_acl == ACCEPT_UNLESS_DENIED) 223 return HOSTAPD_ACL_ACCEPT; 224 if (hapd->conf->macaddr_acl == DENY_UNLESS_ACCEPTED) 225 return HOSTAPD_ACL_REJECT; 226 227 return HOSTAPD_ACL_PENDING; 228 } 229 230 231 /** 232 * hostapd_allowed_address - Check whether a specified STA can be authenticated 233 * @hapd: hostapd BSS data 234 * @addr: MAC address of the STA 235 * @msg: Authentication message 236 * @len: Length of msg in octets 237 * @out.session_timeout: Buffer for returning session timeout (from RADIUS) 238 * @out.acct_interim_interval: Buffer for returning account interval (from 239 * RADIUS) 240 * @out.vlan_id: Buffer for returning VLAN ID 241 * @out.psk: Linked list buffer for returning WPA PSK 242 * @out.identity: Buffer for returning identity (from RADIUS) 243 * @out.radius_cui: Buffer for returning CUI (from RADIUS) 244 * @is_probe_req: Whether this query for a Probe Request frame 245 * Returns: HOSTAPD_ACL_ACCEPT, HOSTAPD_ACL_REJECT, or HOSTAPD_ACL_PENDING 246 * 247 * The caller is responsible for properly cloning the returned out->identity and 248 * out->radius_cui and out->psk values. 249 */ 250 int hostapd_allowed_address(struct hostapd_data *hapd, const u8 *addr, 251 const u8 *msg, size_t len, struct radius_sta *out, 252 int is_probe_req) 253 { 254 int res; 255 256 os_memset(out, 0, sizeof(*out)); 257 258 res = hostapd_check_acl(hapd, addr, &out->vlan_id); 259 if (res != HOSTAPD_ACL_PENDING) 260 return res; 261 262 if (hapd->conf->macaddr_acl == USE_EXTERNAL_RADIUS_AUTH) { 263 #ifdef CONFIG_NO_RADIUS 264 return HOSTAPD_ACL_REJECT; 265 #else /* CONFIG_NO_RADIUS */ 266 struct hostapd_acl_query_data *query; 267 268 if (is_probe_req) { 269 /* Skip RADIUS queries for Probe Request frames to avoid 270 * excessive load on the authentication server. */ 271 return HOSTAPD_ACL_ACCEPT; 272 }; 273 274 if (hapd->conf->ssid.dynamic_vlan == DYNAMIC_VLAN_DISABLED) 275 os_memset(&out->vlan_id, 0, sizeof(out->vlan_id)); 276 277 /* Check whether ACL cache has an entry for this station */ 278 res = hostapd_acl_cache_get(hapd, addr, out); 279 if (res == HOSTAPD_ACL_ACCEPT || 280 res == HOSTAPD_ACL_ACCEPT_TIMEOUT) 281 return res; 282 if (res == HOSTAPD_ACL_REJECT) 283 return HOSTAPD_ACL_REJECT; 284 285 query = hapd->acl_queries; 286 while (query) { 287 if (ether_addr_equal(query->addr, addr)) { 288 /* pending query in RADIUS retransmit queue; 289 * do not generate a new one */ 290 return HOSTAPD_ACL_PENDING; 291 } 292 query = query->next; 293 } 294 295 if (!hapd->conf->radius->auth_server) 296 return HOSTAPD_ACL_REJECT; 297 298 /* No entry in the cache - query external RADIUS server */ 299 query = os_zalloc(sizeof(*query)); 300 if (!query) { 301 wpa_printf(MSG_ERROR, "malloc for query data failed"); 302 return HOSTAPD_ACL_REJECT; 303 } 304 os_get_reltime(&query->timestamp); 305 os_memcpy(query->addr, addr, ETH_ALEN); 306 if (hostapd_radius_acl_query(hapd, addr, query)) { 307 wpa_printf(MSG_DEBUG, 308 "Failed to send Access-Request for ACL query."); 309 hostapd_acl_query_free(query); 310 return HOSTAPD_ACL_REJECT; 311 } 312 313 query->auth_msg = os_memdup(msg, len); 314 if (!query->auth_msg) { 315 wpa_printf(MSG_ERROR, 316 "Failed to allocate memory for auth frame."); 317 hostapd_acl_query_free(query); 318 return HOSTAPD_ACL_REJECT; 319 } 320 query->auth_msg_len = len; 321 query->next = hapd->acl_queries; 322 hapd->acl_queries = query; 323 324 /* Queued data will be processed in hostapd_acl_recv_radius() 325 * when RADIUS server replies to the sent Access-Request. */ 326 return HOSTAPD_ACL_PENDING; 327 #endif /* CONFIG_NO_RADIUS */ 328 } 329 330 return HOSTAPD_ACL_REJECT; 331 } 332 333 334 #ifndef CONFIG_NO_RADIUS 335 static void hostapd_acl_expire_cache(struct hostapd_data *hapd, 336 struct os_reltime *now) 337 { 338 struct hostapd_cached_radius_acl *prev, *entry, *tmp; 339 340 prev = NULL; 341 entry = hapd->acl_cache; 342 343 while (entry) { 344 if (os_reltime_expired(now, &entry->timestamp, 345 RADIUS_ACL_TIMEOUT)) { 346 wpa_printf(MSG_DEBUG, "Cached ACL entry for " MACSTR 347 " has expired.", MAC2STR(entry->addr)); 348 if (prev) 349 prev->next = entry->next; 350 else 351 hapd->acl_cache = entry->next; 352 hostapd_drv_set_radius_acl_expire(hapd, entry->addr); 353 tmp = entry; 354 entry = entry->next; 355 hostapd_acl_cache_free_entry(tmp); 356 continue; 357 } 358 359 prev = entry; 360 entry = entry->next; 361 } 362 } 363 364 365 static void hostapd_acl_expire_queries(struct hostapd_data *hapd, 366 struct os_reltime *now) 367 { 368 struct hostapd_acl_query_data *prev, *entry, *tmp; 369 370 prev = NULL; 371 entry = hapd->acl_queries; 372 373 while (entry) { 374 if (os_reltime_expired(now, &entry->timestamp, 375 RADIUS_ACL_TIMEOUT)) { 376 wpa_printf(MSG_DEBUG, "ACL query for " MACSTR 377 " has expired.", MAC2STR(entry->addr)); 378 if (prev) 379 prev->next = entry->next; 380 else 381 hapd->acl_queries = entry->next; 382 383 tmp = entry; 384 entry = entry->next; 385 hostapd_acl_query_free(tmp); 386 continue; 387 } 388 389 prev = entry; 390 entry = entry->next; 391 } 392 } 393 394 395 /** 396 * hostapd_acl_expire - ACL cache expiration callback 397 * @hapd: struct hostapd_data * 398 */ 399 void hostapd_acl_expire(struct hostapd_data *hapd) 400 { 401 struct os_reltime now; 402 403 os_get_reltime(&now); 404 hostapd_acl_expire_cache(hapd, &now); 405 hostapd_acl_expire_queries(hapd, &now); 406 } 407 408 409 static void decode_tunnel_passwords(struct hostapd_data *hapd, 410 const u8 *shared_secret, 411 size_t shared_secret_len, 412 struct radius_msg *msg, 413 struct radius_msg *req, 414 struct hostapd_cached_radius_acl *cache) 415 { 416 int passphraselen; 417 char *passphrase; 418 size_t i; 419 struct hostapd_sta_wpa_psk_short *psk; 420 421 /* 422 * Decode all tunnel passwords as PSK and save them into a linked list. 423 */ 424 for (i = 0; ; i++) { 425 passphrase = radius_msg_get_tunnel_password( 426 msg, &passphraselen, shared_secret, shared_secret_len, 427 req, i); 428 /* 429 * Passphrase is NULL iff there is no i-th Tunnel-Password 430 * attribute in msg. 431 */ 432 if (!passphrase) 433 break; 434 435 /* 436 * Passphase should be 8..63 chars (to be hashed with SSID) 437 * or 64 chars hex string (no separate hashing with SSID). 438 */ 439 440 if (passphraselen < MIN_PASSPHRASE_LEN || 441 passphraselen > MAX_PASSPHRASE_LEN + 1) 442 goto free_pass; 443 444 /* 445 * passphrase does not contain the NULL termination. 446 * Add it here as pbkdf2_sha1() requires it. 447 */ 448 psk = os_zalloc(sizeof(struct hostapd_sta_wpa_psk_short)); 449 if (psk) { 450 if ((passphraselen == MAX_PASSPHRASE_LEN + 1) && 451 (hexstr2bin(passphrase, psk->psk, PMK_LEN) < 0)) { 452 hostapd_logger(hapd, cache->addr, 453 HOSTAPD_MODULE_RADIUS, 454 HOSTAPD_LEVEL_WARNING, 455 "invalid hex string (%d chars) in Tunnel-Password", 456 passphraselen); 457 goto skip; 458 } else if (passphraselen <= MAX_PASSPHRASE_LEN) { 459 os_memcpy(psk->passphrase, passphrase, 460 passphraselen); 461 psk->is_passphrase = 1; 462 } 463 psk->next = cache->info.psk; 464 cache->info.psk = psk; 465 psk = NULL; 466 } 467 skip: 468 os_free(psk); 469 free_pass: 470 os_free(passphrase); 471 } 472 } 473 474 475 /** 476 * hostapd_acl_recv_radius - Process incoming RADIUS Authentication messages 477 * @msg: RADIUS response message 478 * @req: RADIUS request message 479 * @shared_secret: RADIUS shared secret 480 * @shared_secret_len: Length of shared_secret in octets 481 * @data: Context data (struct hostapd_data *) 482 * Returns: RADIUS_RX_PROCESSED if RADIUS message was a reply to ACL query (and 483 * was processed here) or RADIUS_RX_UNKNOWN if not. 484 */ 485 static RadiusRxResult 486 hostapd_acl_recv_radius(struct radius_msg *msg, struct radius_msg *req, 487 const u8 *shared_secret, size_t shared_secret_len, 488 void *data) 489 { 490 struct hostapd_data *hapd = data; 491 struct hostapd_acl_query_data *query, *prev; 492 struct hostapd_cached_radius_acl *cache; 493 struct radius_sta *info; 494 struct radius_hdr *hdr = radius_msg_get_hdr(msg); 495 496 query = hapd->acl_queries; 497 prev = NULL; 498 while (query) { 499 if (query->radius_id == hdr->identifier) 500 break; 501 prev = query; 502 query = query->next; 503 } 504 if (!query) 505 return RADIUS_RX_UNKNOWN; 506 507 wpa_printf(MSG_DEBUG, 508 "Found matching Access-Request for RADIUS message (id=%d)", 509 query->radius_id); 510 511 if (radius_msg_verify( 512 msg, shared_secret, shared_secret_len, req, 513 hapd->conf->radius_require_message_authenticator)) { 514 wpa_printf(MSG_INFO, 515 "Incoming RADIUS packet did not have correct authenticator - dropped"); 516 return RADIUS_RX_INVALID_AUTHENTICATOR; 517 } 518 519 if (hdr->code != RADIUS_CODE_ACCESS_ACCEPT && 520 hdr->code != RADIUS_CODE_ACCESS_REJECT) { 521 wpa_printf(MSG_DEBUG, 522 "Unknown RADIUS message code %d to ACL query", 523 hdr->code); 524 return RADIUS_RX_UNKNOWN; 525 } 526 527 /* Insert Accept/Reject info into ACL cache */ 528 cache = os_zalloc(sizeof(*cache)); 529 if (!cache) { 530 wpa_printf(MSG_DEBUG, "Failed to add ACL cache entry"); 531 goto done; 532 } 533 os_get_reltime(&cache->timestamp); 534 os_memcpy(cache->addr, query->addr, sizeof(cache->addr)); 535 info = &cache->info; 536 if (hdr->code == RADIUS_CODE_ACCESS_ACCEPT) { 537 u8 *buf; 538 size_t len; 539 540 if (radius_msg_get_attr_int32(msg, RADIUS_ATTR_SESSION_TIMEOUT, 541 &info->session_timeout) == 0) 542 cache->accepted = HOSTAPD_ACL_ACCEPT_TIMEOUT; 543 else 544 cache->accepted = HOSTAPD_ACL_ACCEPT; 545 546 if (radius_msg_get_attr_int32( 547 msg, RADIUS_ATTR_ACCT_INTERIM_INTERVAL, 548 &info->acct_interim_interval) == 0 && 549 info->acct_interim_interval < 60) { 550 wpa_printf(MSG_DEBUG, 551 "Ignored too small Acct-Interim-Interval %d for STA " 552 MACSTR, 553 info->acct_interim_interval, 554 MAC2STR(query->addr)); 555 info->acct_interim_interval = 0; 556 } 557 558 if (hapd->conf->ssid.dynamic_vlan != DYNAMIC_VLAN_DISABLED) 559 info->vlan_id.notempty = !!radius_msg_get_vlanid( 560 msg, &info->vlan_id.untagged, 561 MAX_NUM_TAGGED_VLAN, info->vlan_id.tagged); 562 563 decode_tunnel_passwords(hapd, shared_secret, shared_secret_len, 564 msg, req, cache); 565 566 if (radius_msg_get_attr_ptr(msg, RADIUS_ATTR_USER_NAME, 567 &buf, &len, NULL) == 0) { 568 info->identity = os_zalloc(len + 1); 569 if (info->identity) 570 os_memcpy(info->identity, buf, len); 571 } 572 if (radius_msg_get_attr_ptr( 573 msg, RADIUS_ATTR_CHARGEABLE_USER_IDENTITY, 574 &buf, &len, NULL) == 0) { 575 info->radius_cui = os_zalloc(len + 1); 576 if (info->radius_cui) 577 os_memcpy(info->radius_cui, buf, len); 578 } 579 580 if (hapd->conf->wpa_psk_radius == PSK_RADIUS_REQUIRED && 581 !info->psk) 582 cache->accepted = HOSTAPD_ACL_REJECT; 583 584 if (info->vlan_id.notempty && 585 !hostapd_vlan_valid(hapd->conf->vlan, &info->vlan_id)) { 586 hostapd_logger(hapd, query->addr, 587 HOSTAPD_MODULE_RADIUS, 588 HOSTAPD_LEVEL_INFO, 589 "Invalid VLAN %d%s received from RADIUS server", 590 info->vlan_id.untagged, 591 info->vlan_id.tagged[0] ? "+" : ""); 592 os_memset(&info->vlan_id, 0, sizeof(info->vlan_id)); 593 } 594 if (hapd->conf->ssid.dynamic_vlan == DYNAMIC_VLAN_REQUIRED && 595 !info->vlan_id.notempty) 596 cache->accepted = HOSTAPD_ACL_REJECT; 597 } else 598 cache->accepted = HOSTAPD_ACL_REJECT; 599 cache->next = hapd->acl_cache; 600 hapd->acl_cache = cache; 601 602 if (query->radius_psk) { 603 struct sta_info *sta; 604 bool success = cache->accepted == HOSTAPD_ACL_ACCEPT || 605 cache->accepted == HOSTAPD_ACL_ACCEPT_TIMEOUT; 606 607 sta = ap_get_sta(hapd, query->addr); 608 if (!sta || !sta->wpa_sm) { 609 wpa_printf(MSG_DEBUG, 610 "No STA/SM entry found for the RADIUS PSK response"); 611 goto done; 612 } 613 #ifdef NEED_AP_MLME 614 if (success && 615 (ieee802_11_set_radius_info(hapd, sta, cache->accepted, 616 info) < 0 || 617 ap_sta_bind_vlan(hapd, sta) < 0)) 618 success = false; 619 #endif /* NEED_AP_MLME */ 620 wpa_auth_sta_radius_psk_resp(sta->wpa_sm, success); 621 } else { 622 #ifdef CONFIG_DRIVER_RADIUS_ACL 623 hostapd_drv_set_radius_acl_auth(hapd, query->addr, 624 cache->accepted, 625 info->session_timeout); 626 #else /* CONFIG_DRIVER_RADIUS_ACL */ 627 #ifdef NEED_AP_MLME 628 /* Re-send original authentication frame for 802.11 processing 629 */ 630 wpa_printf(MSG_DEBUG, 631 "Re-sending authentication frame after successful RADIUS ACL query"); 632 ieee802_11_mgmt(hapd, query->auth_msg, query->auth_msg_len, 633 NULL); 634 #endif /* NEED_AP_MLME */ 635 #endif /* CONFIG_DRIVER_RADIUS_ACL */ 636 } 637 638 done: 639 if (!prev) 640 hapd->acl_queries = query->next; 641 else 642 prev->next = query->next; 643 644 hostapd_acl_query_free(query); 645 646 return RADIUS_RX_PROCESSED; 647 } 648 #endif /* CONFIG_NO_RADIUS */ 649 650 651 /** 652 * hostapd_acl_init: Initialize IEEE 802.11 ACL 653 * @hapd: hostapd BSS data 654 * Returns: 0 on success, -1 on failure 655 */ 656 int hostapd_acl_init(struct hostapd_data *hapd) 657 { 658 #ifndef CONFIG_NO_RADIUS 659 if (radius_client_register(hapd->radius, RADIUS_AUTH, 660 hostapd_acl_recv_radius, hapd)) 661 return -1; 662 #endif /* CONFIG_NO_RADIUS */ 663 664 return 0; 665 } 666 667 668 /** 669 * hostapd_acl_deinit - Deinitialize IEEE 802.11 ACL 670 * @hapd: hostapd BSS data 671 */ 672 void hostapd_acl_deinit(struct hostapd_data *hapd) 673 { 674 struct hostapd_acl_query_data *query, *prev; 675 676 #ifndef CONFIG_NO_RADIUS 677 hostapd_acl_cache_free(hapd->acl_cache); 678 hapd->acl_cache = NULL; 679 #endif /* CONFIG_NO_RADIUS */ 680 681 query = hapd->acl_queries; 682 hapd->acl_queries = NULL; 683 while (query) { 684 prev = query; 685 query = query->next; 686 hostapd_acl_query_free(prev); 687 } 688 } 689 690 691 void hostapd_copy_psk_list(struct hostapd_sta_wpa_psk_short **psk, 692 struct hostapd_sta_wpa_psk_short *src) 693 { 694 if (!psk) 695 return; 696 697 if (src) 698 src->ref++; 699 700 *psk = src; 701 } 702 703 704 void hostapd_free_psk_list(struct hostapd_sta_wpa_psk_short *psk) 705 { 706 if (psk && psk->ref) { 707 /* This will be freed when the last reference is dropped. */ 708 psk->ref--; 709 return; 710 } 711 712 while (psk) { 713 struct hostapd_sta_wpa_psk_short *prev = psk; 714 psk = psk->next; 715 bin_clear_free(prev, sizeof(*prev)); 716 } 717 } 718 719 720 #ifndef CONFIG_NO_RADIUS 721 void hostapd_acl_req_radius_psk(struct hostapd_data *hapd, const u8 *addr, 722 int key_mgmt, const u8 *anonce, 723 const u8 *eapol, size_t eapol_len) 724 { 725 struct hostapd_acl_query_data *query; 726 727 query = os_zalloc(sizeof(*query)); 728 if (!query) 729 return; 730 731 query->radius_psk = true; 732 query->akm = key_mgmt; 733 os_get_reltime(&query->timestamp); 734 os_memcpy(query->addr, addr, ETH_ALEN); 735 if (anonce) 736 query->anonce = os_memdup(anonce, WPA_NONCE_LEN); 737 if (eapol) { 738 query->eapol = os_memdup(eapol, eapol_len); 739 query->eapol_len = eapol_len; 740 } 741 if (hostapd_radius_acl_query(hapd, addr, query)) { 742 wpa_printf(MSG_DEBUG, 743 "Failed to send Access-Request for RADIUS PSK/ACL query"); 744 hostapd_acl_query_free(query); 745 return; 746 } 747 748 query->next = hapd->acl_queries; 749 hapd->acl_queries = query; 750 } 751 #endif /* CONFIG_NO_RADIUS */ 752