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