1 /* 2 * RADIUS authentication server 3 * Copyright (c) 2005-2009, 2011-2014, Jouni Malinen <j (at) w1.fi> 4 * 5 * This software may be distributed under the terms of the BSD license. 6 * See README for more details. 7 */ 8 9 #include "includes.h" 10 #include <net/if.h> 11 #ifdef CONFIG_SQLITE 12 #include <sqlite3.h> 13 #endif /* CONFIG_SQLITE */ 14 15 #include "common.h" 16 #include "radius.h" 17 #include "eloop.h" 18 #include "eap_server/eap.h" 19 #include "ap/ap_config.h" 20 #include "crypto/tls.h" 21 #include "radius_server.h" 22 23 /** 24 * RADIUS_SESSION_TIMEOUT - Session timeout in seconds 25 */ 26 #define RADIUS_SESSION_TIMEOUT 60 27 28 /** 29 * RADIUS_SESSION_MAINTAIN - Completed session expiration timeout in seconds 30 */ 31 #define RADIUS_SESSION_MAINTAIN 5 32 33 /** 34 * RADIUS_MAX_SESSION - Maximum number of active sessions 35 */ 36 #define RADIUS_MAX_SESSION 1000 37 38 /** 39 * RADIUS_MAX_MSG_LEN - Maximum message length for incoming RADIUS messages 40 */ 41 #define RADIUS_MAX_MSG_LEN 3000 42 43 static const struct eapol_callbacks radius_server_eapol_cb; 44 45 struct radius_client; 46 struct radius_server_data; 47 48 /** 49 * struct radius_server_counters - RADIUS server statistics counters 50 */ 51 struct radius_server_counters { 52 u32 access_requests; 53 u32 invalid_requests; 54 u32 dup_access_requests; 55 u32 access_accepts; 56 u32 access_rejects; 57 u32 access_challenges; 58 u32 malformed_access_requests; 59 u32 bad_authenticators; 60 u32 packets_dropped; 61 u32 unknown_types; 62 63 u32 acct_requests; 64 u32 invalid_acct_requests; 65 u32 acct_responses; 66 u32 malformed_acct_requests; 67 u32 acct_bad_authenticators; 68 u32 unknown_acct_types; 69 }; 70 71 /** 72 * struct radius_session - Internal RADIUS server data for a session 73 */ 74 struct radius_session { 75 struct radius_session *next; 76 struct radius_client *client; 77 struct radius_server_data *server; 78 unsigned int sess_id; 79 struct eap_sm *eap; 80 struct eap_eapol_interface *eap_if; 81 char *username; /* from User-Name attribute */ 82 char *nas_ip; 83 84 struct radius_msg *last_msg; 85 char *last_from_addr; 86 int last_from_port; 87 struct sockaddr_storage last_from; 88 socklen_t last_fromlen; 89 u8 last_identifier; 90 struct radius_msg *last_reply; 91 u8 last_authenticator[16]; 92 93 unsigned int remediation:1; 94 unsigned int macacl:1; 95 96 struct hostapd_radius_attr *accept_attr; 97 }; 98 99 /** 100 * struct radius_client - Internal RADIUS server data for a client 101 */ 102 struct radius_client { 103 struct radius_client *next; 104 struct in_addr addr; 105 struct in_addr mask; 106 #ifdef CONFIG_IPV6 107 struct in6_addr addr6; 108 struct in6_addr mask6; 109 #endif /* CONFIG_IPV6 */ 110 char *shared_secret; 111 int shared_secret_len; 112 struct radius_session *sessions; 113 struct radius_server_counters counters; 114 }; 115 116 /** 117 * struct radius_server_data - Internal RADIUS server data 118 */ 119 struct radius_server_data { 120 /** 121 * auth_sock - Socket for RADIUS authentication messages 122 */ 123 int auth_sock; 124 125 /** 126 * acct_sock - Socket for RADIUS accounting messages 127 */ 128 int acct_sock; 129 130 /** 131 * clients - List of authorized RADIUS clients 132 */ 133 struct radius_client *clients; 134 135 /** 136 * next_sess_id - Next session identifier 137 */ 138 unsigned int next_sess_id; 139 140 /** 141 * conf_ctx - Context pointer for callbacks 142 * 143 * This is used as the ctx argument in get_eap_user() calls. 144 */ 145 void *conf_ctx; 146 147 /** 148 * num_sess - Number of active sessions 149 */ 150 int num_sess; 151 152 /** 153 * eap_sim_db_priv - EAP-SIM/AKA database context 154 * 155 * This is passed to the EAP-SIM/AKA server implementation as a 156 * callback context. 157 */ 158 void *eap_sim_db_priv; 159 160 /** 161 * ssl_ctx - TLS context 162 * 163 * This is passed to the EAP server implementation as a callback 164 * context for TLS operations. 165 */ 166 void *ssl_ctx; 167 168 /** 169 * pac_opaque_encr_key - PAC-Opaque encryption key for EAP-FAST 170 * 171 * This parameter is used to set a key for EAP-FAST to encrypt the 172 * PAC-Opaque data. It can be set to %NULL if EAP-FAST is not used. If 173 * set, must point to a 16-octet key. 174 */ 175 u8 *pac_opaque_encr_key; 176 177 /** 178 * eap_fast_a_id - EAP-FAST authority identity (A-ID) 179 * 180 * If EAP-FAST is not used, this can be set to %NULL. In theory, this 181 * is a variable length field, but due to some existing implementations 182 * requiring A-ID to be 16 octets in length, it is recommended to use 183 * that length for the field to provide interoperability with deployed 184 * peer implementations. 185 */ 186 u8 *eap_fast_a_id; 187 188 /** 189 * eap_fast_a_id_len - Length of eap_fast_a_id buffer in octets 190 */ 191 size_t eap_fast_a_id_len; 192 193 /** 194 * eap_fast_a_id_info - EAP-FAST authority identifier information 195 * 196 * This A-ID-Info contains a user-friendly name for the A-ID. For 197 * example, this could be the enterprise and server names in 198 * human-readable format. This field is encoded as UTF-8. If EAP-FAST 199 * is not used, this can be set to %NULL. 200 */ 201 char *eap_fast_a_id_info; 202 203 /** 204 * eap_fast_prov - EAP-FAST provisioning modes 205 * 206 * 0 = provisioning disabled, 1 = only anonymous provisioning allowed, 207 * 2 = only authenticated provisioning allowed, 3 = both provisioning 208 * modes allowed. 209 */ 210 int eap_fast_prov; 211 212 /** 213 * pac_key_lifetime - EAP-FAST PAC-Key lifetime in seconds 214 * 215 * This is the hard limit on how long a provisioned PAC-Key can be 216 * used. 217 */ 218 int pac_key_lifetime; 219 220 /** 221 * pac_key_refresh_time - EAP-FAST PAC-Key refresh time in seconds 222 * 223 * This is a soft limit on the PAC-Key. The server will automatically 224 * generate a new PAC-Key when this number of seconds (or fewer) of the 225 * lifetime remains. 226 */ 227 int pac_key_refresh_time; 228 229 /** 230 * eap_sim_aka_result_ind - EAP-SIM/AKA protected success indication 231 * 232 * This controls whether the protected success/failure indication 233 * (AT_RESULT_IND) is used with EAP-SIM and EAP-AKA. 234 */ 235 int eap_sim_aka_result_ind; 236 237 /** 238 * tnc - Trusted Network Connect (TNC) 239 * 240 * This controls whether TNC is enabled and will be required before the 241 * peer is allowed to connect. Note: This is only used with EAP-TTLS 242 * and EAP-FAST. If any other EAP method is enabled, the peer will be 243 * allowed to connect without TNC. 244 */ 245 int tnc; 246 247 /** 248 * pwd_group - The D-H group assigned for EAP-pwd 249 * 250 * If EAP-pwd is not used it can be set to zero. 251 */ 252 u16 pwd_group; 253 254 /** 255 * server_id - Server identity 256 */ 257 const char *server_id; 258 259 /** 260 * erp - Whether EAP Re-authentication Protocol (ERP) is enabled 261 * 262 * This controls whether the authentication server derives ERP key 263 * hierarchy (rRK and rIK) from full EAP authentication and allows 264 * these keys to be used to perform ERP to derive rMSK instead of full 265 * EAP authentication to derive MSK. 266 */ 267 int erp; 268 269 const char *erp_domain; 270 271 struct dl_list erp_keys; /* struct eap_server_erp_key */ 272 273 unsigned int tls_session_lifetime; 274 275 unsigned int tls_flags; 276 277 /** 278 * wps - Wi-Fi Protected Setup context 279 * 280 * If WPS is used with an external RADIUS server (which is quite 281 * unlikely configuration), this is used to provide a pointer to WPS 282 * context data. Normally, this can be set to %NULL. 283 */ 284 struct wps_context *wps; 285 286 /** 287 * ipv6 - Whether to enable IPv6 support in the RADIUS server 288 */ 289 int ipv6; 290 291 /** 292 * start_time - Timestamp of server start 293 */ 294 struct os_reltime start_time; 295 296 /** 297 * counters - Statistics counters for server operations 298 * 299 * These counters are the sum over all clients. 300 */ 301 struct radius_server_counters counters; 302 303 /** 304 * get_eap_user - Callback for fetching EAP user information 305 * @ctx: Context data from conf_ctx 306 * @identity: User identity 307 * @identity_len: identity buffer length in octets 308 * @phase2: Whether this is for Phase 2 identity 309 * @user: Data structure for filling in the user information 310 * Returns: 0 on success, -1 on failure 311 * 312 * This is used to fetch information from user database. The callback 313 * will fill in information about allowed EAP methods and the user 314 * password. The password field will be an allocated copy of the 315 * password data and RADIUS server will free it after use. 316 */ 317 int (*get_eap_user)(void *ctx, const u8 *identity, size_t identity_len, 318 int phase2, struct eap_user *user); 319 320 /** 321 * eap_req_id_text - Optional data for EAP-Request/Identity 322 * 323 * This can be used to configure an optional, displayable message that 324 * will be sent in EAP-Request/Identity. This string can contain an 325 * ASCII-0 character (nul) to separate network infromation per RFC 326 * 4284. The actual string length is explicit provided in 327 * eap_req_id_text_len since nul character will not be used as a string 328 * terminator. 329 */ 330 char *eap_req_id_text; 331 332 /** 333 * eap_req_id_text_len - Length of eap_req_id_text buffer in octets 334 */ 335 size_t eap_req_id_text_len; 336 337 /* 338 * msg_ctx - Context data for wpa_msg() calls 339 */ 340 void *msg_ctx; 341 342 #ifdef CONFIG_RADIUS_TEST 343 char *dump_msk_file; 344 #endif /* CONFIG_RADIUS_TEST */ 345 346 char *subscr_remediation_url; 347 u8 subscr_remediation_method; 348 349 #ifdef CONFIG_SQLITE 350 sqlite3 *db; 351 #endif /* CONFIG_SQLITE */ 352 }; 353 354 355 #define RADIUS_DEBUG(args...) \ 356 wpa_printf(MSG_DEBUG, "RADIUS SRV: " args) 357 #define RADIUS_ERROR(args...) \ 358 wpa_printf(MSG_ERROR, "RADIUS SRV: " args) 359 #define RADIUS_DUMP(args...) \ 360 wpa_hexdump(MSG_MSGDUMP, "RADIUS SRV: " args) 361 #define RADIUS_DUMP_ASCII(args...) \ 362 wpa_hexdump_ascii(MSG_MSGDUMP, "RADIUS SRV: " args) 363 364 365 static void radius_server_session_timeout(void *eloop_ctx, void *timeout_ctx); 366 static void radius_server_session_remove_timeout(void *eloop_ctx, 367 void *timeout_ctx); 368 369 void srv_log(struct radius_session *sess, const char *fmt, ...) 370 PRINTF_FORMAT(2, 3); 371 372 void srv_log(struct radius_session *sess, const char *fmt, ...) 373 { 374 va_list ap; 375 char *buf; 376 int buflen; 377 378 va_start(ap, fmt); 379 buflen = vsnprintf(NULL, 0, fmt, ap) + 1; 380 va_end(ap); 381 382 buf = os_malloc(buflen); 383 if (buf == NULL) 384 return; 385 va_start(ap, fmt); 386 vsnprintf(buf, buflen, fmt, ap); 387 va_end(ap); 388 389 RADIUS_DEBUG("[0x%x %s] %s", sess->sess_id, sess->nas_ip, buf); 390 391 #ifdef CONFIG_SQLITE 392 if (sess->server->db) { 393 char *sql; 394 sql = sqlite3_mprintf("INSERT INTO authlog" 395 "(timestamp,session,nas_ip,username,note)" 396 " VALUES (" 397 "strftime('%%Y-%%m-%%d %%H:%%M:%%f'," 398 "'now'),%u,%Q,%Q,%Q)", 399 sess->sess_id, sess->nas_ip, 400 sess->username, buf); 401 if (sql) { 402 if (sqlite3_exec(sess->server->db, sql, NULL, NULL, 403 NULL) != SQLITE_OK) { 404 RADIUS_ERROR("Failed to add authlog entry into sqlite database: %s", 405 sqlite3_errmsg(sess->server->db)); 406 } 407 sqlite3_free(sql); 408 } 409 } 410 #endif /* CONFIG_SQLITE */ 411 412 os_free(buf); 413 } 414 415 416 static struct radius_client * 417 radius_server_get_client(struct radius_server_data *data, struct in_addr *addr, 418 int ipv6) 419 { 420 struct radius_client *client = data->clients; 421 422 while (client) { 423 #ifdef CONFIG_IPV6 424 if (ipv6) { 425 struct in6_addr *addr6; 426 int i; 427 428 addr6 = (struct in6_addr *) addr; 429 for (i = 0; i < 16; i++) { 430 if ((addr6->s6_addr[i] & 431 client->mask6.s6_addr[i]) != 432 (client->addr6.s6_addr[i] & 433 client->mask6.s6_addr[i])) { 434 i = 17; 435 break; 436 } 437 } 438 if (i == 16) { 439 break; 440 } 441 } 442 #endif /* CONFIG_IPV6 */ 443 if (!ipv6 && (client->addr.s_addr & client->mask.s_addr) == 444 (addr->s_addr & client->mask.s_addr)) { 445 break; 446 } 447 448 client = client->next; 449 } 450 451 return client; 452 } 453 454 455 static struct radius_session * 456 radius_server_get_session(struct radius_client *client, unsigned int sess_id) 457 { 458 struct radius_session *sess = client->sessions; 459 460 while (sess) { 461 if (sess->sess_id == sess_id) { 462 break; 463 } 464 sess = sess->next; 465 } 466 467 return sess; 468 } 469 470 471 static void radius_server_session_free(struct radius_server_data *data, 472 struct radius_session *sess) 473 { 474 eloop_cancel_timeout(radius_server_session_timeout, data, sess); 475 eloop_cancel_timeout(radius_server_session_remove_timeout, data, sess); 476 eap_server_sm_deinit(sess->eap); 477 radius_msg_free(sess->last_msg); 478 os_free(sess->last_from_addr); 479 radius_msg_free(sess->last_reply); 480 os_free(sess->username); 481 os_free(sess->nas_ip); 482 os_free(sess); 483 data->num_sess--; 484 } 485 486 487 static void radius_server_session_remove(struct radius_server_data *data, 488 struct radius_session *sess) 489 { 490 struct radius_client *client = sess->client; 491 struct radius_session *session, *prev; 492 493 eloop_cancel_timeout(radius_server_session_remove_timeout, data, sess); 494 495 prev = NULL; 496 session = client->sessions; 497 while (session) { 498 if (session == sess) { 499 if (prev == NULL) { 500 client->sessions = sess->next; 501 } else { 502 prev->next = sess->next; 503 } 504 radius_server_session_free(data, sess); 505 break; 506 } 507 prev = session; 508 session = session->next; 509 } 510 } 511 512 513 static void radius_server_session_remove_timeout(void *eloop_ctx, 514 void *timeout_ctx) 515 { 516 struct radius_server_data *data = eloop_ctx; 517 struct radius_session *sess = timeout_ctx; 518 RADIUS_DEBUG("Removing completed session 0x%x", sess->sess_id); 519 radius_server_session_remove(data, sess); 520 } 521 522 523 static void radius_server_session_timeout(void *eloop_ctx, void *timeout_ctx) 524 { 525 struct radius_server_data *data = eloop_ctx; 526 struct radius_session *sess = timeout_ctx; 527 528 RADIUS_DEBUG("Timing out authentication session 0x%x", sess->sess_id); 529 radius_server_session_remove(data, sess); 530 } 531 532 533 static struct radius_session * 534 radius_server_new_session(struct radius_server_data *data, 535 struct radius_client *client) 536 { 537 struct radius_session *sess; 538 539 if (data->num_sess >= RADIUS_MAX_SESSION) { 540 RADIUS_DEBUG("Maximum number of existing session - no room " 541 "for a new session"); 542 return NULL; 543 } 544 545 sess = os_zalloc(sizeof(*sess)); 546 if (sess == NULL) 547 return NULL; 548 549 sess->server = data; 550 sess->client = client; 551 sess->sess_id = data->next_sess_id++; 552 sess->next = client->sessions; 553 client->sessions = sess; 554 eloop_register_timeout(RADIUS_SESSION_TIMEOUT, 0, 555 radius_server_session_timeout, data, sess); 556 data->num_sess++; 557 return sess; 558 } 559 560 561 #ifdef CONFIG_TESTING_OPTIONS 562 static void radius_server_testing_options_tls(struct radius_session *sess, 563 const char *tls, 564 struct eap_config *eap_conf) 565 { 566 int test = atoi(tls); 567 568 switch (test) { 569 case 1: 570 srv_log(sess, "TLS test - break VerifyData"); 571 eap_conf->tls_test_flags = TLS_BREAK_VERIFY_DATA; 572 break; 573 case 2: 574 srv_log(sess, "TLS test - break ServerKeyExchange ServerParams hash"); 575 eap_conf->tls_test_flags = TLS_BREAK_SRV_KEY_X_HASH; 576 break; 577 case 3: 578 srv_log(sess, "TLS test - break ServerKeyExchange ServerParams Signature"); 579 eap_conf->tls_test_flags = TLS_BREAK_SRV_KEY_X_SIGNATURE; 580 break; 581 case 4: 582 srv_log(sess, "TLS test - RSA-DHE using a short 511-bit prime"); 583 eap_conf->tls_test_flags = TLS_DHE_PRIME_511B; 584 break; 585 case 5: 586 srv_log(sess, "TLS test - RSA-DHE using a short 767-bit prime"); 587 eap_conf->tls_test_flags = TLS_DHE_PRIME_767B; 588 break; 589 case 6: 590 srv_log(sess, "TLS test - RSA-DHE using a bogus 15 \"prime\""); 591 eap_conf->tls_test_flags = TLS_DHE_PRIME_15; 592 break; 593 case 7: 594 srv_log(sess, "TLS test - RSA-DHE using a short 58-bit prime in long container"); 595 eap_conf->tls_test_flags = TLS_DHE_PRIME_58B; 596 break; 597 case 8: 598 srv_log(sess, "TLS test - RSA-DHE using a non-prime"); 599 eap_conf->tls_test_flags = TLS_DHE_NON_PRIME; 600 break; 601 default: 602 srv_log(sess, "Unrecognized TLS test"); 603 break; 604 } 605 } 606 #endif /* CONFIG_TESTING_OPTIONS */ 607 608 static void radius_server_testing_options(struct radius_session *sess, 609 struct eap_config *eap_conf) 610 { 611 #ifdef CONFIG_TESTING_OPTIONS 612 const char *pos; 613 614 pos = os_strstr(sess->username, "@test-"); 615 if (pos == NULL) 616 return; 617 pos += 6; 618 if (os_strncmp(pos, "tls-", 4) == 0) 619 radius_server_testing_options_tls(sess, pos + 4, eap_conf); 620 else 621 srv_log(sess, "Unrecognized test: %s", pos); 622 #endif /* CONFIG_TESTING_OPTIONS */ 623 } 624 625 626 static struct radius_session * 627 radius_server_get_new_session(struct radius_server_data *data, 628 struct radius_client *client, 629 struct radius_msg *msg, const char *from_addr) 630 { 631 u8 *user; 632 size_t user_len; 633 int res; 634 struct radius_session *sess; 635 struct eap_config eap_conf; 636 struct eap_user tmp; 637 638 RADIUS_DEBUG("Creating a new session"); 639 640 if (radius_msg_get_attr_ptr(msg, RADIUS_ATTR_USER_NAME, &user, 641 &user_len, NULL) < 0) { 642 RADIUS_DEBUG("Could not get User-Name"); 643 return NULL; 644 } 645 RADIUS_DUMP_ASCII("User-Name", user, user_len); 646 647 os_memset(&tmp, 0, sizeof(tmp)); 648 res = data->get_eap_user(data->conf_ctx, user, user_len, 0, &tmp); 649 bin_clear_free(tmp.password, tmp.password_len); 650 651 if (res != 0) { 652 RADIUS_DEBUG("User-Name not found from user database"); 653 return NULL; 654 } 655 656 RADIUS_DEBUG("Matching user entry found"); 657 sess = radius_server_new_session(data, client); 658 if (sess == NULL) { 659 RADIUS_DEBUG("Failed to create a new session"); 660 return NULL; 661 } 662 sess->accept_attr = tmp.accept_attr; 663 sess->macacl = tmp.macacl; 664 665 sess->username = os_malloc(user_len * 4 + 1); 666 if (sess->username == NULL) { 667 radius_server_session_remove(data, sess); 668 return NULL; 669 } 670 printf_encode(sess->username, user_len * 4 + 1, user, user_len); 671 672 sess->nas_ip = os_strdup(from_addr); 673 if (sess->nas_ip == NULL) { 674 radius_server_session_remove(data, sess); 675 return NULL; 676 } 677 678 srv_log(sess, "New session created"); 679 680 os_memset(&eap_conf, 0, sizeof(eap_conf)); 681 eap_conf.ssl_ctx = data->ssl_ctx; 682 eap_conf.msg_ctx = data->msg_ctx; 683 eap_conf.eap_sim_db_priv = data->eap_sim_db_priv; 684 eap_conf.backend_auth = TRUE; 685 eap_conf.eap_server = 1; 686 eap_conf.pac_opaque_encr_key = data->pac_opaque_encr_key; 687 eap_conf.eap_fast_a_id = data->eap_fast_a_id; 688 eap_conf.eap_fast_a_id_len = data->eap_fast_a_id_len; 689 eap_conf.eap_fast_a_id_info = data->eap_fast_a_id_info; 690 eap_conf.eap_fast_prov = data->eap_fast_prov; 691 eap_conf.pac_key_lifetime = data->pac_key_lifetime; 692 eap_conf.pac_key_refresh_time = data->pac_key_refresh_time; 693 eap_conf.eap_sim_aka_result_ind = data->eap_sim_aka_result_ind; 694 eap_conf.tnc = data->tnc; 695 eap_conf.wps = data->wps; 696 eap_conf.pwd_group = data->pwd_group; 697 eap_conf.server_id = (const u8 *) data->server_id; 698 eap_conf.server_id_len = os_strlen(data->server_id); 699 eap_conf.erp = data->erp; 700 eap_conf.tls_session_lifetime = data->tls_session_lifetime; 701 eap_conf.tls_flags = data->tls_flags; 702 radius_server_testing_options(sess, &eap_conf); 703 sess->eap = eap_server_sm_init(sess, &radius_server_eapol_cb, 704 &eap_conf); 705 if (sess->eap == NULL) { 706 RADIUS_DEBUG("Failed to initialize EAP state machine for the " 707 "new session"); 708 radius_server_session_remove(data, sess); 709 return NULL; 710 } 711 sess->eap_if = eap_get_interface(sess->eap); 712 sess->eap_if->eapRestart = TRUE; 713 sess->eap_if->portEnabled = TRUE; 714 715 RADIUS_DEBUG("New session 0x%x initialized", sess->sess_id); 716 717 return sess; 718 } 719 720 721 static struct radius_msg * 722 radius_server_encapsulate_eap(struct radius_server_data *data, 723 struct radius_client *client, 724 struct radius_session *sess, 725 struct radius_msg *request) 726 { 727 struct radius_msg *msg; 728 int code; 729 unsigned int sess_id; 730 struct radius_hdr *hdr = radius_msg_get_hdr(request); 731 732 if (sess->eap_if->eapFail) { 733 sess->eap_if->eapFail = FALSE; 734 code = RADIUS_CODE_ACCESS_REJECT; 735 } else if (sess->eap_if->eapSuccess) { 736 sess->eap_if->eapSuccess = FALSE; 737 code = RADIUS_CODE_ACCESS_ACCEPT; 738 } else { 739 sess->eap_if->eapReq = FALSE; 740 code = RADIUS_CODE_ACCESS_CHALLENGE; 741 } 742 743 msg = radius_msg_new(code, hdr->identifier); 744 if (msg == NULL) { 745 RADIUS_DEBUG("Failed to allocate reply message"); 746 return NULL; 747 } 748 749 sess_id = htonl(sess->sess_id); 750 if (code == RADIUS_CODE_ACCESS_CHALLENGE && 751 !radius_msg_add_attr(msg, RADIUS_ATTR_STATE, 752 (u8 *) &sess_id, sizeof(sess_id))) { 753 RADIUS_DEBUG("Failed to add State attribute"); 754 } 755 756 if (sess->eap_if->eapReqData && 757 !radius_msg_add_eap(msg, wpabuf_head(sess->eap_if->eapReqData), 758 wpabuf_len(sess->eap_if->eapReqData))) { 759 RADIUS_DEBUG("Failed to add EAP-Message attribute"); 760 } 761 762 if (code == RADIUS_CODE_ACCESS_ACCEPT && sess->eap_if->eapKeyData) { 763 int len; 764 #ifdef CONFIG_RADIUS_TEST 765 if (data->dump_msk_file) { 766 FILE *f; 767 char buf[2 * 64 + 1]; 768 f = fopen(data->dump_msk_file, "a"); 769 if (f) { 770 len = sess->eap_if->eapKeyDataLen; 771 if (len > 64) 772 len = 64; 773 len = wpa_snprintf_hex( 774 buf, sizeof(buf), 775 sess->eap_if->eapKeyData, len); 776 buf[len] = '\0'; 777 fprintf(f, "%s\n", buf); 778 fclose(f); 779 } 780 } 781 #endif /* CONFIG_RADIUS_TEST */ 782 if (sess->eap_if->eapKeyDataLen > 64) { 783 len = 32; 784 } else { 785 len = sess->eap_if->eapKeyDataLen / 2; 786 } 787 if (!radius_msg_add_mppe_keys(msg, hdr->authenticator, 788 (u8 *) client->shared_secret, 789 client->shared_secret_len, 790 sess->eap_if->eapKeyData + len, 791 len, sess->eap_if->eapKeyData, 792 len)) { 793 RADIUS_DEBUG("Failed to add MPPE key attributes"); 794 } 795 } 796 797 #ifdef CONFIG_HS20 798 if (code == RADIUS_CODE_ACCESS_ACCEPT && sess->remediation && 799 data->subscr_remediation_url) { 800 u8 *buf; 801 size_t url_len = os_strlen(data->subscr_remediation_url); 802 buf = os_malloc(1 + url_len); 803 if (buf == NULL) { 804 radius_msg_free(msg); 805 return NULL; 806 } 807 buf[0] = data->subscr_remediation_method; 808 os_memcpy(&buf[1], data->subscr_remediation_url, url_len); 809 if (!radius_msg_add_wfa( 810 msg, RADIUS_VENDOR_ATTR_WFA_HS20_SUBSCR_REMEDIATION, 811 buf, 1 + url_len)) { 812 RADIUS_DEBUG("Failed to add WFA-HS20-SubscrRem"); 813 } 814 os_free(buf); 815 } else if (code == RADIUS_CODE_ACCESS_ACCEPT && sess->remediation) { 816 u8 buf[1]; 817 if (!radius_msg_add_wfa( 818 msg, RADIUS_VENDOR_ATTR_WFA_HS20_SUBSCR_REMEDIATION, 819 buf, 0)) { 820 RADIUS_DEBUG("Failed to add WFA-HS20-SubscrRem"); 821 } 822 } 823 #endif /* CONFIG_HS20 */ 824 825 if (radius_msg_copy_attr(msg, request, RADIUS_ATTR_PROXY_STATE) < 0) { 826 RADIUS_DEBUG("Failed to copy Proxy-State attribute(s)"); 827 radius_msg_free(msg); 828 return NULL; 829 } 830 831 if (code == RADIUS_CODE_ACCESS_ACCEPT) { 832 struct hostapd_radius_attr *attr; 833 for (attr = sess->accept_attr; attr; attr = attr->next) { 834 if (!radius_msg_add_attr(msg, attr->type, 835 wpabuf_head(attr->val), 836 wpabuf_len(attr->val))) { 837 wpa_printf(MSG_ERROR, "Could not add RADIUS attribute"); 838 radius_msg_free(msg); 839 return NULL; 840 } 841 } 842 } 843 844 if (radius_msg_finish_srv(msg, (u8 *) client->shared_secret, 845 client->shared_secret_len, 846 hdr->authenticator) < 0) { 847 RADIUS_DEBUG("Failed to add Message-Authenticator attribute"); 848 } 849 850 return msg; 851 } 852 853 854 static struct radius_msg * 855 radius_server_macacl(struct radius_server_data *data, 856 struct radius_client *client, 857 struct radius_session *sess, 858 struct radius_msg *request) 859 { 860 struct radius_msg *msg; 861 int code; 862 struct radius_hdr *hdr = radius_msg_get_hdr(request); 863 u8 *pw; 864 size_t pw_len; 865 866 code = RADIUS_CODE_ACCESS_ACCEPT; 867 868 if (radius_msg_get_attr_ptr(request, RADIUS_ATTR_USER_PASSWORD, &pw, 869 &pw_len, NULL) < 0) { 870 RADIUS_DEBUG("Could not get User-Password"); 871 code = RADIUS_CODE_ACCESS_REJECT; 872 } else { 873 int res; 874 struct eap_user tmp; 875 876 os_memset(&tmp, 0, sizeof(tmp)); 877 res = data->get_eap_user(data->conf_ctx, (u8 *) sess->username, 878 os_strlen(sess->username), 0, &tmp); 879 if (res || !tmp.macacl || tmp.password == NULL) { 880 RADIUS_DEBUG("No MAC ACL user entry"); 881 bin_clear_free(tmp.password, tmp.password_len); 882 code = RADIUS_CODE_ACCESS_REJECT; 883 } else { 884 u8 buf[128]; 885 res = radius_user_password_hide( 886 request, tmp.password, tmp.password_len, 887 (u8 *) client->shared_secret, 888 client->shared_secret_len, 889 buf, sizeof(buf)); 890 bin_clear_free(tmp.password, tmp.password_len); 891 892 if (res < 0 || pw_len != (size_t) res || 893 os_memcmp_const(pw, buf, res) != 0) { 894 RADIUS_DEBUG("Incorrect User-Password"); 895 code = RADIUS_CODE_ACCESS_REJECT; 896 } 897 } 898 } 899 900 msg = radius_msg_new(code, hdr->identifier); 901 if (msg == NULL) { 902 RADIUS_DEBUG("Failed to allocate reply message"); 903 return NULL; 904 } 905 906 if (radius_msg_copy_attr(msg, request, RADIUS_ATTR_PROXY_STATE) < 0) { 907 RADIUS_DEBUG("Failed to copy Proxy-State attribute(s)"); 908 radius_msg_free(msg); 909 return NULL; 910 } 911 912 if (code == RADIUS_CODE_ACCESS_ACCEPT) { 913 struct hostapd_radius_attr *attr; 914 for (attr = sess->accept_attr; attr; attr = attr->next) { 915 if (!radius_msg_add_attr(msg, attr->type, 916 wpabuf_head(attr->val), 917 wpabuf_len(attr->val))) { 918 wpa_printf(MSG_ERROR, "Could not add RADIUS attribute"); 919 radius_msg_free(msg); 920 return NULL; 921 } 922 } 923 } 924 925 if (radius_msg_finish_srv(msg, (u8 *) client->shared_secret, 926 client->shared_secret_len, 927 hdr->authenticator) < 0) { 928 RADIUS_DEBUG("Failed to add Message-Authenticator attribute"); 929 } 930 931 return msg; 932 } 933 934 935 static int radius_server_reject(struct radius_server_data *data, 936 struct radius_client *client, 937 struct radius_msg *request, 938 struct sockaddr *from, socklen_t fromlen, 939 const char *from_addr, int from_port) 940 { 941 struct radius_msg *msg; 942 int ret = 0; 943 struct eap_hdr eapfail; 944 struct wpabuf *buf; 945 struct radius_hdr *hdr = radius_msg_get_hdr(request); 946 947 RADIUS_DEBUG("Reject invalid request from %s:%d", 948 from_addr, from_port); 949 950 msg = radius_msg_new(RADIUS_CODE_ACCESS_REJECT, hdr->identifier); 951 if (msg == NULL) { 952 return -1; 953 } 954 955 os_memset(&eapfail, 0, sizeof(eapfail)); 956 eapfail.code = EAP_CODE_FAILURE; 957 eapfail.identifier = 0; 958 eapfail.length = host_to_be16(sizeof(eapfail)); 959 960 if (!radius_msg_add_eap(msg, (u8 *) &eapfail, sizeof(eapfail))) { 961 RADIUS_DEBUG("Failed to add EAP-Message attribute"); 962 } 963 964 if (radius_msg_copy_attr(msg, request, RADIUS_ATTR_PROXY_STATE) < 0) { 965 RADIUS_DEBUG("Failed to copy Proxy-State attribute(s)"); 966 radius_msg_free(msg); 967 return -1; 968 } 969 970 if (radius_msg_finish_srv(msg, (u8 *) client->shared_secret, 971 client->shared_secret_len, 972 hdr->authenticator) < 973 0) { 974 RADIUS_DEBUG("Failed to add Message-Authenticator attribute"); 975 } 976 977 if (wpa_debug_level <= MSG_MSGDUMP) { 978 radius_msg_dump(msg); 979 } 980 981 data->counters.access_rejects++; 982 client->counters.access_rejects++; 983 buf = radius_msg_get_buf(msg); 984 if (sendto(data->auth_sock, wpabuf_head(buf), wpabuf_len(buf), 0, 985 (struct sockaddr *) from, sizeof(*from)) < 0) { 986 wpa_printf(MSG_INFO, "sendto[RADIUS SRV]: %s", strerror(errno)); 987 ret = -1; 988 } 989 990 radius_msg_free(msg); 991 992 return ret; 993 } 994 995 996 static int radius_server_request(struct radius_server_data *data, 997 struct radius_msg *msg, 998 struct sockaddr *from, socklen_t fromlen, 999 struct radius_client *client, 1000 const char *from_addr, int from_port, 1001 struct radius_session *force_sess) 1002 { 1003 struct wpabuf *eap = NULL; 1004 int res, state_included = 0; 1005 u8 statebuf[4]; 1006 unsigned int state; 1007 struct radius_session *sess; 1008 struct radius_msg *reply; 1009 int is_complete = 0; 1010 1011 if (force_sess) 1012 sess = force_sess; 1013 else { 1014 res = radius_msg_get_attr(msg, RADIUS_ATTR_STATE, statebuf, 1015 sizeof(statebuf)); 1016 state_included = res >= 0; 1017 if (res == sizeof(statebuf)) { 1018 state = WPA_GET_BE32(statebuf); 1019 sess = radius_server_get_session(client, state); 1020 } else { 1021 sess = NULL; 1022 } 1023 } 1024 1025 if (sess) { 1026 RADIUS_DEBUG("Request for session 0x%x", sess->sess_id); 1027 } else if (state_included) { 1028 RADIUS_DEBUG("State attribute included but no session found"); 1029 radius_server_reject(data, client, msg, from, fromlen, 1030 from_addr, from_port); 1031 return -1; 1032 } else { 1033 sess = radius_server_get_new_session(data, client, msg, 1034 from_addr); 1035 if (sess == NULL) { 1036 RADIUS_DEBUG("Could not create a new session"); 1037 radius_server_reject(data, client, msg, from, fromlen, 1038 from_addr, from_port); 1039 return -1; 1040 } 1041 } 1042 1043 if (sess->last_from_port == from_port && 1044 sess->last_identifier == radius_msg_get_hdr(msg)->identifier && 1045 os_memcmp(sess->last_authenticator, 1046 radius_msg_get_hdr(msg)->authenticator, 16) == 0) { 1047 RADIUS_DEBUG("Duplicate message from %s", from_addr); 1048 data->counters.dup_access_requests++; 1049 client->counters.dup_access_requests++; 1050 1051 if (sess->last_reply) { 1052 struct wpabuf *buf; 1053 buf = radius_msg_get_buf(sess->last_reply); 1054 res = sendto(data->auth_sock, wpabuf_head(buf), 1055 wpabuf_len(buf), 0, 1056 (struct sockaddr *) from, fromlen); 1057 if (res < 0) { 1058 wpa_printf(MSG_INFO, "sendto[RADIUS SRV]: %s", 1059 strerror(errno)); 1060 } 1061 return 0; 1062 } 1063 1064 RADIUS_DEBUG("No previous reply available for duplicate " 1065 "message"); 1066 return -1; 1067 } 1068 1069 eap = radius_msg_get_eap(msg); 1070 if (eap == NULL && sess->macacl) { 1071 reply = radius_server_macacl(data, client, sess, msg); 1072 if (reply == NULL) 1073 return -1; 1074 goto send_reply; 1075 } 1076 if (eap == NULL) { 1077 RADIUS_DEBUG("No EAP-Message in RADIUS packet from %s", 1078 from_addr); 1079 data->counters.packets_dropped++; 1080 client->counters.packets_dropped++; 1081 return -1; 1082 } 1083 1084 RADIUS_DUMP("Received EAP data", wpabuf_head(eap), wpabuf_len(eap)); 1085 1086 /* FIX: if Code is Request, Success, or Failure, send Access-Reject; 1087 * RFC3579 Sect. 2.6.2. 1088 * Include EAP-Response/Nak with no preferred method if 1089 * code == request. 1090 * If code is not 1-4, discard the packet silently. 1091 * Or is this already done by the EAP state machine? */ 1092 1093 wpabuf_free(sess->eap_if->eapRespData); 1094 sess->eap_if->eapRespData = eap; 1095 sess->eap_if->eapResp = TRUE; 1096 eap_server_sm_step(sess->eap); 1097 1098 if ((sess->eap_if->eapReq || sess->eap_if->eapSuccess || 1099 sess->eap_if->eapFail) && sess->eap_if->eapReqData) { 1100 RADIUS_DUMP("EAP data from the state machine", 1101 wpabuf_head(sess->eap_if->eapReqData), 1102 wpabuf_len(sess->eap_if->eapReqData)); 1103 } else if (sess->eap_if->eapFail) { 1104 RADIUS_DEBUG("No EAP data from the state machine, but eapFail " 1105 "set"); 1106 } else if (eap_sm_method_pending(sess->eap)) { 1107 radius_msg_free(sess->last_msg); 1108 sess->last_msg = msg; 1109 sess->last_from_port = from_port; 1110 os_free(sess->last_from_addr); 1111 sess->last_from_addr = os_strdup(from_addr); 1112 sess->last_fromlen = fromlen; 1113 os_memcpy(&sess->last_from, from, fromlen); 1114 return -2; 1115 } else { 1116 RADIUS_DEBUG("No EAP data from the state machine - ignore this" 1117 " Access-Request silently (assuming it was a " 1118 "duplicate)"); 1119 data->counters.packets_dropped++; 1120 client->counters.packets_dropped++; 1121 return -1; 1122 } 1123 1124 if (sess->eap_if->eapSuccess || sess->eap_if->eapFail) 1125 is_complete = 1; 1126 if (sess->eap_if->eapFail) 1127 srv_log(sess, "EAP authentication failed"); 1128 else if (sess->eap_if->eapSuccess) 1129 srv_log(sess, "EAP authentication succeeded"); 1130 1131 reply = radius_server_encapsulate_eap(data, client, sess, msg); 1132 1133 send_reply: 1134 if (reply) { 1135 struct wpabuf *buf; 1136 struct radius_hdr *hdr; 1137 1138 RADIUS_DEBUG("Reply to %s:%d", from_addr, from_port); 1139 if (wpa_debug_level <= MSG_MSGDUMP) { 1140 radius_msg_dump(reply); 1141 } 1142 1143 switch (radius_msg_get_hdr(reply)->code) { 1144 case RADIUS_CODE_ACCESS_ACCEPT: 1145 srv_log(sess, "Sending Access-Accept"); 1146 data->counters.access_accepts++; 1147 client->counters.access_accepts++; 1148 break; 1149 case RADIUS_CODE_ACCESS_REJECT: 1150 srv_log(sess, "Sending Access-Reject"); 1151 data->counters.access_rejects++; 1152 client->counters.access_rejects++; 1153 break; 1154 case RADIUS_CODE_ACCESS_CHALLENGE: 1155 data->counters.access_challenges++; 1156 client->counters.access_challenges++; 1157 break; 1158 } 1159 buf = radius_msg_get_buf(reply); 1160 res = sendto(data->auth_sock, wpabuf_head(buf), 1161 wpabuf_len(buf), 0, 1162 (struct sockaddr *) from, fromlen); 1163 if (res < 0) { 1164 wpa_printf(MSG_INFO, "sendto[RADIUS SRV]: %s", 1165 strerror(errno)); 1166 } 1167 radius_msg_free(sess->last_reply); 1168 sess->last_reply = reply; 1169 sess->last_from_port = from_port; 1170 hdr = radius_msg_get_hdr(msg); 1171 sess->last_identifier = hdr->identifier; 1172 os_memcpy(sess->last_authenticator, hdr->authenticator, 16); 1173 } else { 1174 data->counters.packets_dropped++; 1175 client->counters.packets_dropped++; 1176 } 1177 1178 if (is_complete) { 1179 RADIUS_DEBUG("Removing completed session 0x%x after timeout", 1180 sess->sess_id); 1181 eloop_cancel_timeout(radius_server_session_remove_timeout, 1182 data, sess); 1183 eloop_register_timeout(RADIUS_SESSION_MAINTAIN, 0, 1184 radius_server_session_remove_timeout, 1185 data, sess); 1186 } 1187 1188 return 0; 1189 } 1190 1191 1192 static void radius_server_receive_auth(int sock, void *eloop_ctx, 1193 void *sock_ctx) 1194 { 1195 struct radius_server_data *data = eloop_ctx; 1196 u8 *buf = NULL; 1197 union { 1198 struct sockaddr_storage ss; 1199 struct sockaddr_in sin; 1200 #ifdef CONFIG_IPV6 1201 struct sockaddr_in6 sin6; 1202 #endif /* CONFIG_IPV6 */ 1203 } from; 1204 socklen_t fromlen; 1205 int len; 1206 struct radius_client *client = NULL; 1207 struct radius_msg *msg = NULL; 1208 char abuf[50]; 1209 int from_port = 0; 1210 1211 buf = os_malloc(RADIUS_MAX_MSG_LEN); 1212 if (buf == NULL) { 1213 goto fail; 1214 } 1215 1216 fromlen = sizeof(from); 1217 len = recvfrom(sock, buf, RADIUS_MAX_MSG_LEN, 0, 1218 (struct sockaddr *) &from.ss, &fromlen); 1219 if (len < 0) { 1220 wpa_printf(MSG_INFO, "recvfrom[radius_server]: %s", 1221 strerror(errno)); 1222 goto fail; 1223 } 1224 1225 #ifdef CONFIG_IPV6 1226 if (data->ipv6) { 1227 if (inet_ntop(AF_INET6, &from.sin6.sin6_addr, abuf, 1228 sizeof(abuf)) == NULL) 1229 abuf[0] = '\0'; 1230 from_port = ntohs(from.sin6.sin6_port); 1231 RADIUS_DEBUG("Received %d bytes from %s:%d", 1232 len, abuf, from_port); 1233 1234 client = radius_server_get_client(data, 1235 (struct in_addr *) 1236 &from.sin6.sin6_addr, 1); 1237 } 1238 #endif /* CONFIG_IPV6 */ 1239 1240 if (!data->ipv6) { 1241 os_strlcpy(abuf, inet_ntoa(from.sin.sin_addr), sizeof(abuf)); 1242 from_port = ntohs(from.sin.sin_port); 1243 RADIUS_DEBUG("Received %d bytes from %s:%d", 1244 len, abuf, from_port); 1245 1246 client = radius_server_get_client(data, &from.sin.sin_addr, 0); 1247 } 1248 1249 RADIUS_DUMP("Received data", buf, len); 1250 1251 if (client == NULL) { 1252 RADIUS_DEBUG("Unknown client %s - packet ignored", abuf); 1253 data->counters.invalid_requests++; 1254 goto fail; 1255 } 1256 1257 msg = radius_msg_parse(buf, len); 1258 if (msg == NULL) { 1259 RADIUS_DEBUG("Parsing incoming RADIUS frame failed"); 1260 data->counters.malformed_access_requests++; 1261 client->counters.malformed_access_requests++; 1262 goto fail; 1263 } 1264 1265 os_free(buf); 1266 buf = NULL; 1267 1268 if (wpa_debug_level <= MSG_MSGDUMP) { 1269 radius_msg_dump(msg); 1270 } 1271 1272 if (radius_msg_get_hdr(msg)->code != RADIUS_CODE_ACCESS_REQUEST) { 1273 RADIUS_DEBUG("Unexpected RADIUS code %d", 1274 radius_msg_get_hdr(msg)->code); 1275 data->counters.unknown_types++; 1276 client->counters.unknown_types++; 1277 goto fail; 1278 } 1279 1280 data->counters.access_requests++; 1281 client->counters.access_requests++; 1282 1283 if (radius_msg_verify_msg_auth(msg, (u8 *) client->shared_secret, 1284 client->shared_secret_len, NULL)) { 1285 RADIUS_DEBUG("Invalid Message-Authenticator from %s", abuf); 1286 data->counters.bad_authenticators++; 1287 client->counters.bad_authenticators++; 1288 goto fail; 1289 } 1290 1291 if (radius_server_request(data, msg, (struct sockaddr *) &from, 1292 fromlen, client, abuf, from_port, NULL) == 1293 -2) 1294 return; /* msg was stored with the session */ 1295 1296 fail: 1297 radius_msg_free(msg); 1298 os_free(buf); 1299 } 1300 1301 1302 static void radius_server_receive_acct(int sock, void *eloop_ctx, 1303 void *sock_ctx) 1304 { 1305 struct radius_server_data *data = eloop_ctx; 1306 u8 *buf = NULL; 1307 union { 1308 struct sockaddr_storage ss; 1309 struct sockaddr_in sin; 1310 #ifdef CONFIG_IPV6 1311 struct sockaddr_in6 sin6; 1312 #endif /* CONFIG_IPV6 */ 1313 } from; 1314 socklen_t fromlen; 1315 int len, res; 1316 struct radius_client *client = NULL; 1317 struct radius_msg *msg = NULL, *resp = NULL; 1318 char abuf[50]; 1319 int from_port = 0; 1320 struct radius_hdr *hdr; 1321 struct wpabuf *rbuf; 1322 1323 buf = os_malloc(RADIUS_MAX_MSG_LEN); 1324 if (buf == NULL) { 1325 goto fail; 1326 } 1327 1328 fromlen = sizeof(from); 1329 len = recvfrom(sock, buf, RADIUS_MAX_MSG_LEN, 0, 1330 (struct sockaddr *) &from.ss, &fromlen); 1331 if (len < 0) { 1332 wpa_printf(MSG_INFO, "recvfrom[radius_server]: %s", 1333 strerror(errno)); 1334 goto fail; 1335 } 1336 1337 #ifdef CONFIG_IPV6 1338 if (data->ipv6) { 1339 if (inet_ntop(AF_INET6, &from.sin6.sin6_addr, abuf, 1340 sizeof(abuf)) == NULL) 1341 abuf[0] = '\0'; 1342 from_port = ntohs(from.sin6.sin6_port); 1343 RADIUS_DEBUG("Received %d bytes from %s:%d", 1344 len, abuf, from_port); 1345 1346 client = radius_server_get_client(data, 1347 (struct in_addr *) 1348 &from.sin6.sin6_addr, 1); 1349 } 1350 #endif /* CONFIG_IPV6 */ 1351 1352 if (!data->ipv6) { 1353 os_strlcpy(abuf, inet_ntoa(from.sin.sin_addr), sizeof(abuf)); 1354 from_port = ntohs(from.sin.sin_port); 1355 RADIUS_DEBUG("Received %d bytes from %s:%d", 1356 len, abuf, from_port); 1357 1358 client = radius_server_get_client(data, &from.sin.sin_addr, 0); 1359 } 1360 1361 RADIUS_DUMP("Received data", buf, len); 1362 1363 if (client == NULL) { 1364 RADIUS_DEBUG("Unknown client %s - packet ignored", abuf); 1365 data->counters.invalid_acct_requests++; 1366 goto fail; 1367 } 1368 1369 msg = radius_msg_parse(buf, len); 1370 if (msg == NULL) { 1371 RADIUS_DEBUG("Parsing incoming RADIUS frame failed"); 1372 data->counters.malformed_acct_requests++; 1373 client->counters.malformed_acct_requests++; 1374 goto fail; 1375 } 1376 1377 os_free(buf); 1378 buf = NULL; 1379 1380 if (wpa_debug_level <= MSG_MSGDUMP) { 1381 radius_msg_dump(msg); 1382 } 1383 1384 if (radius_msg_get_hdr(msg)->code != RADIUS_CODE_ACCOUNTING_REQUEST) { 1385 RADIUS_DEBUG("Unexpected RADIUS code %d", 1386 radius_msg_get_hdr(msg)->code); 1387 data->counters.unknown_acct_types++; 1388 client->counters.unknown_acct_types++; 1389 goto fail; 1390 } 1391 1392 data->counters.acct_requests++; 1393 client->counters.acct_requests++; 1394 1395 if (radius_msg_verify_acct_req(msg, (u8 *) client->shared_secret, 1396 client->shared_secret_len)) { 1397 RADIUS_DEBUG("Invalid Authenticator from %s", abuf); 1398 data->counters.acct_bad_authenticators++; 1399 client->counters.acct_bad_authenticators++; 1400 goto fail; 1401 } 1402 1403 /* TODO: Write accounting information to a file or database */ 1404 1405 hdr = radius_msg_get_hdr(msg); 1406 1407 resp = radius_msg_new(RADIUS_CODE_ACCOUNTING_RESPONSE, hdr->identifier); 1408 if (resp == NULL) 1409 goto fail; 1410 1411 radius_msg_finish_acct_resp(resp, (u8 *) client->shared_secret, 1412 client->shared_secret_len, 1413 hdr->authenticator); 1414 1415 RADIUS_DEBUG("Reply to %s:%d", abuf, from_port); 1416 if (wpa_debug_level <= MSG_MSGDUMP) { 1417 radius_msg_dump(resp); 1418 } 1419 rbuf = radius_msg_get_buf(resp); 1420 data->counters.acct_responses++; 1421 client->counters.acct_responses++; 1422 res = sendto(data->acct_sock, wpabuf_head(rbuf), wpabuf_len(rbuf), 0, 1423 (struct sockaddr *) &from.ss, fromlen); 1424 if (res < 0) { 1425 wpa_printf(MSG_INFO, "sendto[RADIUS SRV]: %s", 1426 strerror(errno)); 1427 } 1428 1429 fail: 1430 radius_msg_free(resp); 1431 radius_msg_free(msg); 1432 os_free(buf); 1433 } 1434 1435 1436 static int radius_server_disable_pmtu_discovery(int s) 1437 { 1438 int r = -1; 1439 #if defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DONT) 1440 /* Turn off Path MTU discovery on IPv4/UDP sockets. */ 1441 int action = IP_PMTUDISC_DONT; 1442 r = setsockopt(s, IPPROTO_IP, IP_MTU_DISCOVER, &action, 1443 sizeof(action)); 1444 if (r == -1) 1445 wpa_printf(MSG_ERROR, "Failed to set IP_MTU_DISCOVER: " 1446 "%s", strerror(errno)); 1447 #endif 1448 return r; 1449 } 1450 1451 1452 static int radius_server_open_socket(int port) 1453 { 1454 int s; 1455 struct sockaddr_in addr; 1456 1457 s = socket(PF_INET, SOCK_DGRAM, 0); 1458 if (s < 0) { 1459 wpa_printf(MSG_INFO, "RADIUS: socket: %s", strerror(errno)); 1460 return -1; 1461 } 1462 1463 radius_server_disable_pmtu_discovery(s); 1464 1465 os_memset(&addr, 0, sizeof(addr)); 1466 addr.sin_family = AF_INET; 1467 addr.sin_port = htons(port); 1468 if (bind(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) { 1469 wpa_printf(MSG_INFO, "RADIUS: bind: %s", strerror(errno)); 1470 close(s); 1471 return -1; 1472 } 1473 1474 return s; 1475 } 1476 1477 1478 #ifdef CONFIG_IPV6 1479 static int radius_server_open_socket6(int port) 1480 { 1481 int s; 1482 struct sockaddr_in6 addr; 1483 1484 s = socket(PF_INET6, SOCK_DGRAM, 0); 1485 if (s < 0) { 1486 wpa_printf(MSG_INFO, "RADIUS: socket[IPv6]: %s", 1487 strerror(errno)); 1488 return -1; 1489 } 1490 1491 os_memset(&addr, 0, sizeof(addr)); 1492 addr.sin6_family = AF_INET6; 1493 os_memcpy(&addr.sin6_addr, &in6addr_any, sizeof(in6addr_any)); 1494 addr.sin6_port = htons(port); 1495 if (bind(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) { 1496 wpa_printf(MSG_INFO, "RADIUS: bind: %s", strerror(errno)); 1497 close(s); 1498 return -1; 1499 } 1500 1501 return s; 1502 } 1503 #endif /* CONFIG_IPV6 */ 1504 1505 1506 static void radius_server_free_sessions(struct radius_server_data *data, 1507 struct radius_session *sessions) 1508 { 1509 struct radius_session *session, *prev; 1510 1511 session = sessions; 1512 while (session) { 1513 prev = session; 1514 session = session->next; 1515 radius_server_session_free(data, prev); 1516 } 1517 } 1518 1519 1520 static void radius_server_free_clients(struct radius_server_data *data, 1521 struct radius_client *clients) 1522 { 1523 struct radius_client *client, *prev; 1524 1525 client = clients; 1526 while (client) { 1527 prev = client; 1528 client = client->next; 1529 1530 radius_server_free_sessions(data, prev->sessions); 1531 os_free(prev->shared_secret); 1532 os_free(prev); 1533 } 1534 } 1535 1536 1537 static struct radius_client * 1538 radius_server_read_clients(const char *client_file, int ipv6) 1539 { 1540 FILE *f; 1541 const int buf_size = 1024; 1542 char *buf, *pos; 1543 struct radius_client *clients, *tail, *entry; 1544 int line = 0, mask, failed = 0, i; 1545 struct in_addr addr; 1546 #ifdef CONFIG_IPV6 1547 struct in6_addr addr6; 1548 #endif /* CONFIG_IPV6 */ 1549 unsigned int val; 1550 1551 f = fopen(client_file, "r"); 1552 if (f == NULL) { 1553 RADIUS_ERROR("Could not open client file '%s'", client_file); 1554 return NULL; 1555 } 1556 1557 buf = os_malloc(buf_size); 1558 if (buf == NULL) { 1559 fclose(f); 1560 return NULL; 1561 } 1562 1563 clients = tail = NULL; 1564 while (fgets(buf, buf_size, f)) { 1565 /* Configuration file format: 1566 * 192.168.1.0/24 secret 1567 * 192.168.1.2 secret 1568 * fe80::211:22ff:fe33:4455/64 secretipv6 1569 */ 1570 line++; 1571 buf[buf_size - 1] = '\0'; 1572 pos = buf; 1573 while (*pos != '\0' && *pos != '\n') 1574 pos++; 1575 if (*pos == '\n') 1576 *pos = '\0'; 1577 if (*buf == '\0' || *buf == '#') 1578 continue; 1579 1580 pos = buf; 1581 while ((*pos >= '0' && *pos <= '9') || *pos == '.' || 1582 (*pos >= 'a' && *pos <= 'f') || *pos == ':' || 1583 (*pos >= 'A' && *pos <= 'F')) { 1584 pos++; 1585 } 1586 1587 if (*pos == '\0') { 1588 failed = 1; 1589 break; 1590 } 1591 1592 if (*pos == '/') { 1593 char *end; 1594 *pos++ = '\0'; 1595 mask = strtol(pos, &end, 10); 1596 if ((pos == end) || 1597 (mask < 0 || mask > (ipv6 ? 128 : 32))) { 1598 failed = 1; 1599 break; 1600 } 1601 pos = end; 1602 } else { 1603 mask = ipv6 ? 128 : 32; 1604 *pos++ = '\0'; 1605 } 1606 1607 if (!ipv6 && inet_aton(buf, &addr) == 0) { 1608 failed = 1; 1609 break; 1610 } 1611 #ifdef CONFIG_IPV6 1612 if (ipv6 && inet_pton(AF_INET6, buf, &addr6) <= 0) { 1613 if (inet_pton(AF_INET, buf, &addr) <= 0) { 1614 failed = 1; 1615 break; 1616 } 1617 /* Convert IPv4 address to IPv6 */ 1618 if (mask <= 32) 1619 mask += (128 - 32); 1620 os_memset(addr6.s6_addr, 0, 10); 1621 addr6.s6_addr[10] = 0xff; 1622 addr6.s6_addr[11] = 0xff; 1623 os_memcpy(addr6.s6_addr + 12, (char *) &addr.s_addr, 1624 4); 1625 } 1626 #endif /* CONFIG_IPV6 */ 1627 1628 while (*pos == ' ' || *pos == '\t') { 1629 pos++; 1630 } 1631 1632 if (*pos == '\0') { 1633 failed = 1; 1634 break; 1635 } 1636 1637 entry = os_zalloc(sizeof(*entry)); 1638 if (entry == NULL) { 1639 failed = 1; 1640 break; 1641 } 1642 entry->shared_secret = os_strdup(pos); 1643 if (entry->shared_secret == NULL) { 1644 failed = 1; 1645 os_free(entry); 1646 break; 1647 } 1648 entry->shared_secret_len = os_strlen(entry->shared_secret); 1649 if (!ipv6) { 1650 entry->addr.s_addr = addr.s_addr; 1651 val = 0; 1652 for (i = 0; i < mask; i++) 1653 val |= 1 << (31 - i); 1654 entry->mask.s_addr = htonl(val); 1655 } 1656 #ifdef CONFIG_IPV6 1657 if (ipv6) { 1658 int offset = mask / 8; 1659 1660 os_memcpy(entry->addr6.s6_addr, addr6.s6_addr, 16); 1661 os_memset(entry->mask6.s6_addr, 0xff, offset); 1662 val = 0; 1663 for (i = 0; i < (mask % 8); i++) 1664 val |= 1 << (7 - i); 1665 if (offset < 16) 1666 entry->mask6.s6_addr[offset] = val; 1667 } 1668 #endif /* CONFIG_IPV6 */ 1669 1670 if (tail == NULL) { 1671 clients = tail = entry; 1672 } else { 1673 tail->next = entry; 1674 tail = entry; 1675 } 1676 } 1677 1678 if (failed) { 1679 RADIUS_ERROR("Invalid line %d in '%s'", line, client_file); 1680 radius_server_free_clients(NULL, clients); 1681 clients = NULL; 1682 } 1683 1684 os_free(buf); 1685 fclose(f); 1686 1687 return clients; 1688 } 1689 1690 1691 /** 1692 * radius_server_init - Initialize RADIUS server 1693 * @conf: Configuration for the RADIUS server 1694 * Returns: Pointer to private RADIUS server context or %NULL on failure 1695 * 1696 * This initializes a RADIUS server instance and returns a context pointer that 1697 * will be used in other calls to the RADIUS server module. The server can be 1698 * deinitialize by calling radius_server_deinit(). 1699 */ 1700 struct radius_server_data * 1701 radius_server_init(struct radius_server_conf *conf) 1702 { 1703 struct radius_server_data *data; 1704 1705 #ifndef CONFIG_IPV6 1706 if (conf->ipv6) { 1707 wpa_printf(MSG_ERROR, "RADIUS server compiled without IPv6 support"); 1708 return NULL; 1709 } 1710 #endif /* CONFIG_IPV6 */ 1711 1712 data = os_zalloc(sizeof(*data)); 1713 if (data == NULL) 1714 return NULL; 1715 1716 dl_list_init(&data->erp_keys); 1717 os_get_reltime(&data->start_time); 1718 data->conf_ctx = conf->conf_ctx; 1719 data->eap_sim_db_priv = conf->eap_sim_db_priv; 1720 data->ssl_ctx = conf->ssl_ctx; 1721 data->msg_ctx = conf->msg_ctx; 1722 data->ipv6 = conf->ipv6; 1723 if (conf->pac_opaque_encr_key) { 1724 data->pac_opaque_encr_key = os_malloc(16); 1725 if (data->pac_opaque_encr_key) { 1726 os_memcpy(data->pac_opaque_encr_key, 1727 conf->pac_opaque_encr_key, 16); 1728 } 1729 } 1730 if (conf->eap_fast_a_id) { 1731 data->eap_fast_a_id = os_malloc(conf->eap_fast_a_id_len); 1732 if (data->eap_fast_a_id) { 1733 os_memcpy(data->eap_fast_a_id, conf->eap_fast_a_id, 1734 conf->eap_fast_a_id_len); 1735 data->eap_fast_a_id_len = conf->eap_fast_a_id_len; 1736 } 1737 } 1738 if (conf->eap_fast_a_id_info) 1739 data->eap_fast_a_id_info = os_strdup(conf->eap_fast_a_id_info); 1740 data->eap_fast_prov = conf->eap_fast_prov; 1741 data->pac_key_lifetime = conf->pac_key_lifetime; 1742 data->pac_key_refresh_time = conf->pac_key_refresh_time; 1743 data->get_eap_user = conf->get_eap_user; 1744 data->eap_sim_aka_result_ind = conf->eap_sim_aka_result_ind; 1745 data->tnc = conf->tnc; 1746 data->wps = conf->wps; 1747 data->pwd_group = conf->pwd_group; 1748 data->server_id = conf->server_id; 1749 if (conf->eap_req_id_text) { 1750 data->eap_req_id_text = os_malloc(conf->eap_req_id_text_len); 1751 if (data->eap_req_id_text) { 1752 os_memcpy(data->eap_req_id_text, conf->eap_req_id_text, 1753 conf->eap_req_id_text_len); 1754 data->eap_req_id_text_len = conf->eap_req_id_text_len; 1755 } 1756 } 1757 data->erp = conf->erp; 1758 data->erp_domain = conf->erp_domain; 1759 data->tls_session_lifetime = conf->tls_session_lifetime; 1760 data->tls_flags = conf->tls_flags; 1761 1762 if (conf->subscr_remediation_url) { 1763 data->subscr_remediation_url = 1764 os_strdup(conf->subscr_remediation_url); 1765 } 1766 data->subscr_remediation_method = conf->subscr_remediation_method; 1767 1768 #ifdef CONFIG_SQLITE 1769 if (conf->sqlite_file) { 1770 if (sqlite3_open(conf->sqlite_file, &data->db)) { 1771 RADIUS_ERROR("Could not open SQLite file '%s'", 1772 conf->sqlite_file); 1773 radius_server_deinit(data); 1774 return NULL; 1775 } 1776 } 1777 #endif /* CONFIG_SQLITE */ 1778 1779 #ifdef CONFIG_RADIUS_TEST 1780 if (conf->dump_msk_file) 1781 data->dump_msk_file = os_strdup(conf->dump_msk_file); 1782 #endif /* CONFIG_RADIUS_TEST */ 1783 1784 data->clients = radius_server_read_clients(conf->client_file, 1785 conf->ipv6); 1786 if (data->clients == NULL) { 1787 wpa_printf(MSG_ERROR, "No RADIUS clients configured"); 1788 radius_server_deinit(data); 1789 return NULL; 1790 } 1791 1792 #ifdef CONFIG_IPV6 1793 if (conf->ipv6) 1794 data->auth_sock = radius_server_open_socket6(conf->auth_port); 1795 else 1796 #endif /* CONFIG_IPV6 */ 1797 data->auth_sock = radius_server_open_socket(conf->auth_port); 1798 if (data->auth_sock < 0) { 1799 wpa_printf(MSG_ERROR, "Failed to open UDP socket for RADIUS authentication server"); 1800 radius_server_deinit(data); 1801 return NULL; 1802 } 1803 if (eloop_register_read_sock(data->auth_sock, 1804 radius_server_receive_auth, 1805 data, NULL)) { 1806 radius_server_deinit(data); 1807 return NULL; 1808 } 1809 1810 if (conf->acct_port) { 1811 #ifdef CONFIG_IPV6 1812 if (conf->ipv6) 1813 data->acct_sock = radius_server_open_socket6( 1814 conf->acct_port); 1815 else 1816 #endif /* CONFIG_IPV6 */ 1817 data->acct_sock = radius_server_open_socket(conf->acct_port); 1818 if (data->acct_sock < 0) { 1819 wpa_printf(MSG_ERROR, "Failed to open UDP socket for RADIUS accounting server"); 1820 radius_server_deinit(data); 1821 return NULL; 1822 } 1823 if (eloop_register_read_sock(data->acct_sock, 1824 radius_server_receive_acct, 1825 data, NULL)) { 1826 radius_server_deinit(data); 1827 return NULL; 1828 } 1829 } else { 1830 data->acct_sock = -1; 1831 } 1832 1833 return data; 1834 } 1835 1836 1837 /** 1838 * radius_server_erp_flush - Flush all ERP keys 1839 * @data: RADIUS server context from radius_server_init() 1840 */ 1841 void radius_server_erp_flush(struct radius_server_data *data) 1842 { 1843 struct eap_server_erp_key *erp; 1844 1845 if (data == NULL) 1846 return; 1847 while ((erp = dl_list_first(&data->erp_keys, struct eap_server_erp_key, 1848 list)) != NULL) { 1849 dl_list_del(&erp->list); 1850 bin_clear_free(erp, sizeof(*erp)); 1851 } 1852 } 1853 1854 1855 /** 1856 * radius_server_deinit - Deinitialize RADIUS server 1857 * @data: RADIUS server context from radius_server_init() 1858 */ 1859 void radius_server_deinit(struct radius_server_data *data) 1860 { 1861 if (data == NULL) 1862 return; 1863 1864 if (data->auth_sock >= 0) { 1865 eloop_unregister_read_sock(data->auth_sock); 1866 close(data->auth_sock); 1867 } 1868 1869 if (data->acct_sock >= 0) { 1870 eloop_unregister_read_sock(data->acct_sock); 1871 close(data->acct_sock); 1872 } 1873 1874 radius_server_free_clients(data, data->clients); 1875 1876 os_free(data->pac_opaque_encr_key); 1877 os_free(data->eap_fast_a_id); 1878 os_free(data->eap_fast_a_id_info); 1879 os_free(data->eap_req_id_text); 1880 #ifdef CONFIG_RADIUS_TEST 1881 os_free(data->dump_msk_file); 1882 #endif /* CONFIG_RADIUS_TEST */ 1883 os_free(data->subscr_remediation_url); 1884 1885 #ifdef CONFIG_SQLITE 1886 if (data->db) 1887 sqlite3_close(data->db); 1888 #endif /* CONFIG_SQLITE */ 1889 1890 radius_server_erp_flush(data); 1891 1892 os_free(data); 1893 } 1894 1895 1896 /** 1897 * radius_server_get_mib - Get RADIUS server MIB information 1898 * @data: RADIUS server context from radius_server_init() 1899 * @buf: Buffer for returning the MIB data in text format 1900 * @buflen: buf length in octets 1901 * Returns: Number of octets written into buf 1902 */ 1903 int radius_server_get_mib(struct radius_server_data *data, char *buf, 1904 size_t buflen) 1905 { 1906 int ret, uptime; 1907 unsigned int idx; 1908 char *end, *pos; 1909 struct os_reltime now; 1910 struct radius_client *cli; 1911 1912 /* RFC 2619 - RADIUS Authentication Server MIB */ 1913 1914 if (data == NULL || buflen == 0) 1915 return 0; 1916 1917 pos = buf; 1918 end = buf + buflen; 1919 1920 os_get_reltime(&now); 1921 uptime = (now.sec - data->start_time.sec) * 100 + 1922 ((now.usec - data->start_time.usec) / 10000) % 100; 1923 ret = os_snprintf(pos, end - pos, 1924 "RADIUS-AUTH-SERVER-MIB\n" 1925 "radiusAuthServIdent=hostapd\n" 1926 "radiusAuthServUpTime=%d\n" 1927 "radiusAuthServResetTime=0\n" 1928 "radiusAuthServConfigReset=4\n", 1929 uptime); 1930 if (os_snprintf_error(end - pos, ret)) { 1931 *pos = '\0'; 1932 return pos - buf; 1933 } 1934 pos += ret; 1935 1936 ret = os_snprintf(pos, end - pos, 1937 "radiusAuthServTotalAccessRequests=%u\n" 1938 "radiusAuthServTotalInvalidRequests=%u\n" 1939 "radiusAuthServTotalDupAccessRequests=%u\n" 1940 "radiusAuthServTotalAccessAccepts=%u\n" 1941 "radiusAuthServTotalAccessRejects=%u\n" 1942 "radiusAuthServTotalAccessChallenges=%u\n" 1943 "radiusAuthServTotalMalformedAccessRequests=%u\n" 1944 "radiusAuthServTotalBadAuthenticators=%u\n" 1945 "radiusAuthServTotalPacketsDropped=%u\n" 1946 "radiusAuthServTotalUnknownTypes=%u\n" 1947 "radiusAccServTotalRequests=%u\n" 1948 "radiusAccServTotalInvalidRequests=%u\n" 1949 "radiusAccServTotalResponses=%u\n" 1950 "radiusAccServTotalMalformedRequests=%u\n" 1951 "radiusAccServTotalBadAuthenticators=%u\n" 1952 "radiusAccServTotalUnknownTypes=%u\n", 1953 data->counters.access_requests, 1954 data->counters.invalid_requests, 1955 data->counters.dup_access_requests, 1956 data->counters.access_accepts, 1957 data->counters.access_rejects, 1958 data->counters.access_challenges, 1959 data->counters.malformed_access_requests, 1960 data->counters.bad_authenticators, 1961 data->counters.packets_dropped, 1962 data->counters.unknown_types, 1963 data->counters.acct_requests, 1964 data->counters.invalid_acct_requests, 1965 data->counters.acct_responses, 1966 data->counters.malformed_acct_requests, 1967 data->counters.acct_bad_authenticators, 1968 data->counters.unknown_acct_types); 1969 if (os_snprintf_error(end - pos, ret)) { 1970 *pos = '\0'; 1971 return pos - buf; 1972 } 1973 pos += ret; 1974 1975 for (cli = data->clients, idx = 0; cli; cli = cli->next, idx++) { 1976 char abuf[50], mbuf[50]; 1977 #ifdef CONFIG_IPV6 1978 if (data->ipv6) { 1979 if (inet_ntop(AF_INET6, &cli->addr6, abuf, 1980 sizeof(abuf)) == NULL) 1981 abuf[0] = '\0'; 1982 if (inet_ntop(AF_INET6, &cli->mask6, mbuf, 1983 sizeof(mbuf)) == NULL) 1984 mbuf[0] = '\0'; 1985 } 1986 #endif /* CONFIG_IPV6 */ 1987 if (!data->ipv6) { 1988 os_strlcpy(abuf, inet_ntoa(cli->addr), sizeof(abuf)); 1989 os_strlcpy(mbuf, inet_ntoa(cli->mask), sizeof(mbuf)); 1990 } 1991 1992 ret = os_snprintf(pos, end - pos, 1993 "radiusAuthClientIndex=%u\n" 1994 "radiusAuthClientAddress=%s/%s\n" 1995 "radiusAuthServAccessRequests=%u\n" 1996 "radiusAuthServDupAccessRequests=%u\n" 1997 "radiusAuthServAccessAccepts=%u\n" 1998 "radiusAuthServAccessRejects=%u\n" 1999 "radiusAuthServAccessChallenges=%u\n" 2000 "radiusAuthServMalformedAccessRequests=%u\n" 2001 "radiusAuthServBadAuthenticators=%u\n" 2002 "radiusAuthServPacketsDropped=%u\n" 2003 "radiusAuthServUnknownTypes=%u\n" 2004 "radiusAccServTotalRequests=%u\n" 2005 "radiusAccServTotalInvalidRequests=%u\n" 2006 "radiusAccServTotalResponses=%u\n" 2007 "radiusAccServTotalMalformedRequests=%u\n" 2008 "radiusAccServTotalBadAuthenticators=%u\n" 2009 "radiusAccServTotalUnknownTypes=%u\n", 2010 idx, 2011 abuf, mbuf, 2012 cli->counters.access_requests, 2013 cli->counters.dup_access_requests, 2014 cli->counters.access_accepts, 2015 cli->counters.access_rejects, 2016 cli->counters.access_challenges, 2017 cli->counters.malformed_access_requests, 2018 cli->counters.bad_authenticators, 2019 cli->counters.packets_dropped, 2020 cli->counters.unknown_types, 2021 cli->counters.acct_requests, 2022 cli->counters.invalid_acct_requests, 2023 cli->counters.acct_responses, 2024 cli->counters.malformed_acct_requests, 2025 cli->counters.acct_bad_authenticators, 2026 cli->counters.unknown_acct_types); 2027 if (os_snprintf_error(end - pos, ret)) { 2028 *pos = '\0'; 2029 return pos - buf; 2030 } 2031 pos += ret; 2032 } 2033 2034 return pos - buf; 2035 } 2036 2037 2038 static int radius_server_get_eap_user(void *ctx, const u8 *identity, 2039 size_t identity_len, int phase2, 2040 struct eap_user *user) 2041 { 2042 struct radius_session *sess = ctx; 2043 struct radius_server_data *data = sess->server; 2044 int ret; 2045 2046 ret = data->get_eap_user(data->conf_ctx, identity, identity_len, 2047 phase2, user); 2048 if (ret == 0 && user) { 2049 sess->accept_attr = user->accept_attr; 2050 sess->remediation = user->remediation; 2051 sess->macacl = user->macacl; 2052 } 2053 2054 if (ret) { 2055 RADIUS_DEBUG("%s: User-Name not found from user database", 2056 __func__); 2057 } 2058 2059 return ret; 2060 } 2061 2062 2063 static const char * radius_server_get_eap_req_id_text(void *ctx, size_t *len) 2064 { 2065 struct radius_session *sess = ctx; 2066 struct radius_server_data *data = sess->server; 2067 *len = data->eap_req_id_text_len; 2068 return data->eap_req_id_text; 2069 } 2070 2071 2072 static void radius_server_log_msg(void *ctx, const char *msg) 2073 { 2074 struct radius_session *sess = ctx; 2075 srv_log(sess, "EAP: %s", msg); 2076 } 2077 2078 2079 #ifdef CONFIG_ERP 2080 2081 static const char * radius_server_get_erp_domain(void *ctx) 2082 { 2083 struct radius_session *sess = ctx; 2084 struct radius_server_data *data = sess->server; 2085 2086 return data->erp_domain; 2087 } 2088 2089 2090 static struct eap_server_erp_key * 2091 radius_server_erp_get_key(void *ctx, const char *keyname) 2092 { 2093 struct radius_session *sess = ctx; 2094 struct radius_server_data *data = sess->server; 2095 struct eap_server_erp_key *erp; 2096 2097 dl_list_for_each(erp, &data->erp_keys, struct eap_server_erp_key, 2098 list) { 2099 if (os_strcmp(erp->keyname_nai, keyname) == 0) 2100 return erp; 2101 } 2102 2103 return NULL; 2104 } 2105 2106 2107 static int radius_server_erp_add_key(void *ctx, struct eap_server_erp_key *erp) 2108 { 2109 struct radius_session *sess = ctx; 2110 struct radius_server_data *data = sess->server; 2111 2112 dl_list_add(&data->erp_keys, &erp->list); 2113 return 0; 2114 } 2115 2116 #endif /* CONFIG_ERP */ 2117 2118 2119 static const struct eapol_callbacks radius_server_eapol_cb = 2120 { 2121 .get_eap_user = radius_server_get_eap_user, 2122 .get_eap_req_id_text = radius_server_get_eap_req_id_text, 2123 .log_msg = radius_server_log_msg, 2124 #ifdef CONFIG_ERP 2125 .get_erp_send_reauth_start = NULL, 2126 .get_erp_domain = radius_server_get_erp_domain, 2127 .erp_get_key = radius_server_erp_get_key, 2128 .erp_add_key = radius_server_erp_add_key, 2129 #endif /* CONFIG_ERP */ 2130 }; 2131 2132 2133 /** 2134 * radius_server_eap_pending_cb - Pending EAP data notification 2135 * @data: RADIUS server context from radius_server_init() 2136 * @ctx: Pending EAP context pointer 2137 * 2138 * This function is used to notify EAP server module that a pending operation 2139 * has been completed and processing of the EAP session can proceed. 2140 */ 2141 void radius_server_eap_pending_cb(struct radius_server_data *data, void *ctx) 2142 { 2143 struct radius_client *cli; 2144 struct radius_session *s, *sess = NULL; 2145 struct radius_msg *msg; 2146 2147 if (data == NULL) 2148 return; 2149 2150 for (cli = data->clients; cli; cli = cli->next) { 2151 for (s = cli->sessions; s; s = s->next) { 2152 if (s->eap == ctx && s->last_msg) { 2153 sess = s; 2154 break; 2155 } 2156 } 2157 if (sess) 2158 break; 2159 } 2160 2161 if (sess == NULL) { 2162 RADIUS_DEBUG("No session matched callback ctx"); 2163 return; 2164 } 2165 2166 msg = sess->last_msg; 2167 sess->last_msg = NULL; 2168 eap_sm_pending_cb(sess->eap); 2169 if (radius_server_request(data, msg, 2170 (struct sockaddr *) &sess->last_from, 2171 sess->last_fromlen, cli, 2172 sess->last_from_addr, 2173 sess->last_from_port, sess) == -2) 2174 return; /* msg was stored with the session */ 2175 2176 radius_msg_free(msg); 2177 } 2178