1 /* 2 * RADIUS authentication server 3 * Copyright (c) 2005-2009, 2011-2019, Jouni Malinen <j@w1.fi> 4 * 5 * This software may be distributed under the terms of the BSD license. 6 * See README for more details. 7 */ 8 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 static const struct eapol_callbacks radius_server_eapol_cb; 39 40 struct radius_client; 41 struct radius_server_data; 42 43 /** 44 * struct radius_server_counters - RADIUS server statistics counters 45 */ 46 struct radius_server_counters { 47 u32 access_requests; 48 u32 invalid_requests; 49 u32 dup_access_requests; 50 u32 access_accepts; 51 u32 access_rejects; 52 u32 access_challenges; 53 u32 malformed_access_requests; 54 u32 bad_authenticators; 55 u32 packets_dropped; 56 u32 unknown_types; 57 58 u32 acct_requests; 59 u32 invalid_acct_requests; 60 u32 acct_responses; 61 u32 malformed_acct_requests; 62 u32 acct_bad_authenticators; 63 u32 unknown_acct_types; 64 }; 65 66 /** 67 * struct radius_session - Internal RADIUS server data for a session 68 */ 69 struct radius_session { 70 struct radius_session *next; 71 struct radius_client *client; 72 struct radius_server_data *server; 73 unsigned int sess_id; 74 struct eap_sm *eap; 75 struct eap_eapol_interface *eap_if; 76 char *username; /* from User-Name attribute */ 77 char *nas_ip; 78 u8 mac_addr[ETH_ALEN]; /* from Calling-Station-Id attribute */ 79 80 struct radius_msg *last_msg; 81 char *last_from_addr; 82 int last_from_port; 83 struct sockaddr_storage last_from; 84 socklen_t last_fromlen; 85 u8 last_identifier; 86 struct radius_msg *last_reply; 87 u8 last_authenticator[16]; 88 89 unsigned int macacl:1; 90 unsigned int t_c_filtering:1; 91 92 struct hostapd_radius_attr *accept_attr; 93 94 u32 t_c_timestamp; /* Last read T&C timestamp from user DB */ 95 }; 96 97 /** 98 * struct radius_client - Internal RADIUS server data for a client 99 */ 100 struct radius_client { 101 struct radius_client *next; 102 struct in_addr addr; 103 struct in_addr mask; 104 #ifdef CONFIG_IPV6 105 struct in6_addr addr6; 106 struct in6_addr mask6; 107 #endif /* CONFIG_IPV6 */ 108 char *shared_secret; 109 int shared_secret_len; 110 struct radius_session *sessions; 111 struct radius_server_counters counters; 112 113 u8 next_dac_identifier; 114 struct radius_msg *pending_dac_coa_req; 115 u8 pending_dac_coa_id; 116 u8 pending_dac_coa_addr[ETH_ALEN]; 117 struct radius_msg *pending_dac_disconnect_req; 118 u8 pending_dac_disconnect_id; 119 u8 pending_dac_disconnect_addr[ETH_ALEN]; 120 }; 121 122 /** 123 * struct radius_server_data - Internal RADIUS server data 124 */ 125 struct radius_server_data { 126 /** 127 * auth_sock - Socket for RADIUS authentication messages 128 */ 129 int auth_sock; 130 131 /** 132 * acct_sock - Socket for RADIUS accounting messages 133 */ 134 int acct_sock; 135 136 /** 137 * clients - List of authorized RADIUS clients 138 */ 139 struct radius_client *clients; 140 141 /** 142 * next_sess_id - Next session identifier 143 */ 144 unsigned int next_sess_id; 145 146 /** 147 * conf_ctx - Context pointer for callbacks 148 * 149 * This is used as the ctx argument in get_eap_user() and acct_req_cb() 150 * calls. 151 */ 152 void *conf_ctx; 153 154 /** 155 * num_sess - Number of active sessions 156 */ 157 int num_sess; 158 159 const char *erp_domain; 160 161 struct dl_list erp_keys; /* struct eap_server_erp_key */ 162 163 /** 164 * ipv6 - Whether to enable IPv6 support in the RADIUS server 165 */ 166 int ipv6; 167 168 /** 169 * start_time - Timestamp of server start 170 */ 171 struct os_reltime start_time; 172 173 /** 174 * counters - Statistics counters for server operations 175 * 176 * These counters are the sum over all clients. 177 */ 178 struct radius_server_counters counters; 179 180 /** 181 * get_eap_user - Callback for fetching EAP user information 182 * @ctx: Context data from conf_ctx 183 * @identity: User identity 184 * @identity_len: identity buffer length in octets 185 * @phase2: Whether this is for Phase 2 identity 186 * @user: Data structure for filling in the user information 187 * Returns: 0 on success, -1 on failure 188 * 189 * This is used to fetch information from user database. The callback 190 * will fill in information about allowed EAP methods and the user 191 * password. The password field will be an allocated copy of the 192 * password data and RADIUS server will free it after use. 193 */ 194 int (*get_eap_user)(void *ctx, const u8 *identity, size_t identity_len, 195 int phase2, struct eap_user *user); 196 197 /** 198 * acct_req_cb - Callback for processing received RADIUS accounting 199 * requests 200 * @ctx: Context data from conf_ctx 201 * @msg: Received RADIUS accounting request 202 * @status_type: Status type from the message (parsed Acct-Status-Type 203 * attribute) 204 * Returns: 0 on success, -1 on failure 205 * 206 * This can be used to log accounting information into file, database, 207 * syslog server, etc. 208 * Callback should not modify the message. 209 * If 0 is returned, response is automatically created. Otherwise, 210 * no response is created. 211 * 212 * acct_req_cb can be set to null to omit any custom processing of 213 * account requests. Statistics counters will be incremented in any 214 * case. 215 */ 216 int (*acct_req_cb)(void *ctx, struct radius_msg *msg, u32 status_type); 217 218 /** 219 * eap_req_id_text - Optional data for EAP-Request/Identity 220 * 221 * This can be used to configure an optional, displayable message that 222 * will be sent in EAP-Request/Identity. This string can contain an 223 * ASCII-0 character (nul) to separate network infromation per RFC 224 * 4284. The actual string length is explicit provided in 225 * eap_req_id_text_len since nul character will not be used as a string 226 * terminator. 227 */ 228 char *eap_req_id_text; 229 230 /** 231 * eap_req_id_text_len - Length of eap_req_id_text buffer in octets 232 */ 233 size_t eap_req_id_text_len; 234 235 #ifdef CONFIG_RADIUS_TEST 236 char *dump_msk_file; 237 #endif /* CONFIG_RADIUS_TEST */ 238 239 char *t_c_server_url; 240 241 #ifdef CONFIG_SQLITE 242 sqlite3 *db; 243 #endif /* CONFIG_SQLITE */ 244 245 const struct eap_config *eap_cfg; 246 }; 247 248 249 #define RADIUS_DEBUG(args...) \ 250 wpa_printf(MSG_DEBUG, "RADIUS SRV: " args) 251 #define RADIUS_ERROR(args...) \ 252 wpa_printf(MSG_ERROR, "RADIUS SRV: " args) 253 #define RADIUS_DUMP(args...) \ 254 wpa_hexdump(MSG_MSGDUMP, "RADIUS SRV: " args) 255 #define RADIUS_DUMP_ASCII(args...) \ 256 wpa_hexdump_ascii(MSG_MSGDUMP, "RADIUS SRV: " args) 257 258 259 static void radius_server_session_timeout(void *eloop_ctx, void *timeout_ctx); 260 static void radius_server_session_remove_timeout(void *eloop_ctx, 261 void *timeout_ctx); 262 263 void srv_log(struct radius_session *sess, const char *fmt, ...) 264 PRINTF_FORMAT(2, 3); 265 266 void srv_log(struct radius_session *sess, const char *fmt, ...) 267 { 268 va_list ap; 269 char *buf; 270 int buflen; 271 272 va_start(ap, fmt); 273 buflen = vsnprintf(NULL, 0, fmt, ap) + 1; 274 va_end(ap); 275 276 buf = os_malloc(buflen); 277 if (buf == NULL) 278 return; 279 va_start(ap, fmt); 280 vsnprintf(buf, buflen, fmt, ap); 281 va_end(ap); 282 283 RADIUS_DEBUG("[0x%x %s] %s", sess->sess_id, sess->nas_ip, buf); 284 285 #ifdef CONFIG_SQLITE 286 if (sess->server->db) { 287 char *sql; 288 sql = sqlite3_mprintf("INSERT INTO authlog" 289 "(timestamp,session,nas_ip,username,note)" 290 " VALUES (" 291 "strftime('%%Y-%%m-%%d %%H:%%M:%%f'," 292 "'now'),%u,%Q,%Q,%Q)", 293 sess->sess_id, sess->nas_ip, 294 sess->username, buf); 295 if (sql) { 296 if (sqlite3_exec(sess->server->db, sql, NULL, NULL, 297 NULL) != SQLITE_OK) { 298 RADIUS_ERROR("Failed to add authlog entry into sqlite database: %s", 299 sqlite3_errmsg(sess->server->db)); 300 } 301 sqlite3_free(sql); 302 } 303 } 304 #endif /* CONFIG_SQLITE */ 305 306 os_free(buf); 307 } 308 309 310 static struct radius_client * 311 radius_server_get_client(struct radius_server_data *data, struct in_addr *addr, 312 int ipv6) 313 { 314 struct radius_client *client = data->clients; 315 316 while (client) { 317 #ifdef CONFIG_IPV6 318 if (ipv6) { 319 struct in6_addr *addr6; 320 int i; 321 322 addr6 = (struct in6_addr *) addr; 323 for (i = 0; i < 16; i++) { 324 if ((addr6->s6_addr[i] & 325 client->mask6.s6_addr[i]) != 326 (client->addr6.s6_addr[i] & 327 client->mask6.s6_addr[i])) { 328 i = 17; 329 break; 330 } 331 } 332 if (i == 16) { 333 break; 334 } 335 } 336 #endif /* CONFIG_IPV6 */ 337 if (!ipv6 && (client->addr.s_addr & client->mask.s_addr) == 338 (addr->s_addr & client->mask.s_addr)) { 339 break; 340 } 341 342 client = client->next; 343 } 344 345 return client; 346 } 347 348 349 static struct radius_session * 350 radius_server_get_session(struct radius_client *client, unsigned int sess_id) 351 { 352 struct radius_session *sess = client->sessions; 353 354 while (sess) { 355 if (sess->sess_id == sess_id) { 356 break; 357 } 358 sess = sess->next; 359 } 360 361 return sess; 362 } 363 364 365 static void radius_server_session_free(struct radius_server_data *data, 366 struct radius_session *sess) 367 { 368 eloop_cancel_timeout(radius_server_session_timeout, data, sess); 369 eloop_cancel_timeout(radius_server_session_remove_timeout, data, sess); 370 eap_server_sm_deinit(sess->eap); 371 radius_msg_free(sess->last_msg); 372 os_free(sess->last_from_addr); 373 radius_msg_free(sess->last_reply); 374 os_free(sess->username); 375 os_free(sess->nas_ip); 376 os_free(sess); 377 if (data) 378 data->num_sess--; 379 } 380 381 382 static void radius_server_session_remove(struct radius_server_data *data, 383 struct radius_session *sess) 384 { 385 struct radius_client *client = sess->client; 386 struct radius_session *session, *prev; 387 388 eloop_cancel_timeout(radius_server_session_remove_timeout, data, sess); 389 390 prev = NULL; 391 session = client->sessions; 392 while (session) { 393 if (session == sess) { 394 if (prev == NULL) { 395 client->sessions = sess->next; 396 } else { 397 prev->next = sess->next; 398 } 399 radius_server_session_free(data, sess); 400 break; 401 } 402 prev = session; 403 session = session->next; 404 } 405 } 406 407 408 static void radius_server_session_remove_timeout(void *eloop_ctx, 409 void *timeout_ctx) 410 { 411 struct radius_server_data *data = eloop_ctx; 412 struct radius_session *sess = timeout_ctx; 413 RADIUS_DEBUG("Removing completed session 0x%x", sess->sess_id); 414 radius_server_session_remove(data, sess); 415 } 416 417 418 static void radius_server_session_timeout(void *eloop_ctx, void *timeout_ctx) 419 { 420 struct radius_server_data *data = eloop_ctx; 421 struct radius_session *sess = timeout_ctx; 422 423 RADIUS_DEBUG("Timing out authentication session 0x%x", sess->sess_id); 424 radius_server_session_remove(data, sess); 425 } 426 427 428 static struct radius_session * 429 radius_server_new_session(struct radius_server_data *data, 430 struct radius_client *client) 431 { 432 struct radius_session *sess; 433 434 if (data->num_sess >= RADIUS_MAX_SESSION) { 435 RADIUS_DEBUG("Maximum number of existing session - no room " 436 "for a new session"); 437 return NULL; 438 } 439 440 sess = os_zalloc(sizeof(*sess)); 441 if (sess == NULL) 442 return NULL; 443 444 sess->server = data; 445 sess->client = client; 446 sess->sess_id = data->next_sess_id++; 447 sess->next = client->sessions; 448 client->sessions = sess; 449 eloop_register_timeout(RADIUS_SESSION_TIMEOUT, 0, 450 radius_server_session_timeout, data, sess); 451 data->num_sess++; 452 return sess; 453 } 454 455 456 #ifdef CONFIG_TESTING_OPTIONS 457 static void radius_server_testing_options_tls(struct radius_session *sess, 458 const char *tls, 459 struct eap_session_data *eap_conf) 460 { 461 int test = atoi(tls); 462 463 switch (test) { 464 case 1: 465 srv_log(sess, "TLS test - break VerifyData"); 466 eap_conf->tls_test_flags = TLS_BREAK_VERIFY_DATA; 467 break; 468 case 2: 469 srv_log(sess, "TLS test - break ServerKeyExchange ServerParams hash"); 470 eap_conf->tls_test_flags = TLS_BREAK_SRV_KEY_X_HASH; 471 break; 472 case 3: 473 srv_log(sess, "TLS test - break ServerKeyExchange ServerParams Signature"); 474 eap_conf->tls_test_flags = TLS_BREAK_SRV_KEY_X_SIGNATURE; 475 break; 476 case 4: 477 srv_log(sess, "TLS test - RSA-DHE using a short 511-bit prime"); 478 eap_conf->tls_test_flags = TLS_DHE_PRIME_511B; 479 break; 480 case 5: 481 srv_log(sess, "TLS test - RSA-DHE using a short 767-bit prime"); 482 eap_conf->tls_test_flags = TLS_DHE_PRIME_767B; 483 break; 484 case 6: 485 srv_log(sess, "TLS test - RSA-DHE using a bogus 15 \"prime\""); 486 eap_conf->tls_test_flags = TLS_DHE_PRIME_15; 487 break; 488 case 7: 489 srv_log(sess, "TLS test - RSA-DHE using a short 58-bit prime in long container"); 490 eap_conf->tls_test_flags = TLS_DHE_PRIME_58B; 491 break; 492 case 8: 493 srv_log(sess, "TLS test - RSA-DHE using a non-prime"); 494 eap_conf->tls_test_flags = TLS_DHE_NON_PRIME; 495 break; 496 default: 497 srv_log(sess, "Unrecognized TLS test"); 498 break; 499 } 500 } 501 #endif /* CONFIG_TESTING_OPTIONS */ 502 503 static void radius_server_testing_options(struct radius_session *sess, 504 struct eap_session_data *eap_conf) 505 { 506 #ifdef CONFIG_TESTING_OPTIONS 507 const char *pos; 508 509 pos = os_strstr(sess->username, "@test-"); 510 if (pos == NULL) 511 return; 512 pos += 6; 513 if (os_strncmp(pos, "tls-", 4) == 0) 514 radius_server_testing_options_tls(sess, pos + 4, eap_conf); 515 else 516 srv_log(sess, "Unrecognized test: %s", pos); 517 #endif /* CONFIG_TESTING_OPTIONS */ 518 } 519 520 521 #ifdef CONFIG_ERP 522 static struct eap_server_erp_key * 523 radius_server_erp_find_key(struct radius_server_data *data, const char *keyname) 524 { 525 struct eap_server_erp_key *erp; 526 527 dl_list_for_each(erp, &data->erp_keys, struct eap_server_erp_key, 528 list) { 529 if (os_strcmp(erp->keyname_nai, keyname) == 0) 530 return erp; 531 } 532 533 return NULL; 534 } 535 #endif /* CONFIG_ERP */ 536 537 538 static struct radius_session * 539 radius_server_get_new_session(struct radius_server_data *data, 540 struct radius_client *client, 541 struct radius_msg *msg, const char *from_addr) 542 { 543 u8 *user, *id; 544 size_t user_len, id_len; 545 int res; 546 struct radius_session *sess; 547 struct eap_session_data eap_sess; 548 struct eap_user *tmp; 549 550 RADIUS_DEBUG("Creating a new session"); 551 552 if (radius_msg_get_attr_ptr(msg, RADIUS_ATTR_USER_NAME, &user, 553 &user_len, NULL) < 0) { 554 RADIUS_DEBUG("Could not get User-Name"); 555 return NULL; 556 } 557 RADIUS_DUMP_ASCII("User-Name", user, user_len); 558 559 tmp = os_zalloc(sizeof(*tmp)); 560 if (!tmp) 561 return NULL; 562 563 res = data->get_eap_user(data->conf_ctx, user, user_len, 0, tmp); 564 #ifdef CONFIG_ERP 565 if (res != 0 && data->eap_cfg->erp) { 566 char *username; 567 568 username = os_zalloc(user_len + 1); 569 if (username) { 570 os_memcpy(username, user, user_len); 571 if (radius_server_erp_find_key(data, username)) 572 res = 0; 573 os_free(username); 574 } 575 } 576 #endif /* CONFIG_ERP */ 577 if (res != 0) { 578 RADIUS_DEBUG("User-Name not found from user database"); 579 eap_user_free(tmp); 580 return NULL; 581 } 582 583 RADIUS_DEBUG("Matching user entry found"); 584 sess = radius_server_new_session(data, client); 585 if (sess == NULL) { 586 RADIUS_DEBUG("Failed to create a new session"); 587 eap_user_free(tmp); 588 return NULL; 589 } 590 sess->accept_attr = tmp->accept_attr; 591 sess->macacl = tmp->macacl; 592 eap_user_free(tmp); 593 594 sess->username = os_malloc(user_len * 4 + 1); 595 if (sess->username == NULL) { 596 radius_server_session_remove(data, sess); 597 return NULL; 598 } 599 printf_encode(sess->username, user_len * 4 + 1, user, user_len); 600 601 sess->nas_ip = os_strdup(from_addr); 602 if (sess->nas_ip == NULL) { 603 radius_server_session_remove(data, sess); 604 return NULL; 605 } 606 607 if (radius_msg_get_attr_ptr(msg, RADIUS_ATTR_CALLING_STATION_ID, &id, 608 &id_len, NULL) == 0) { 609 char buf[3 * ETH_ALEN]; 610 611 os_memset(buf, 0, sizeof(buf)); 612 if (id_len >= sizeof(buf)) 613 id_len = sizeof(buf) - 1; 614 os_memcpy(buf, id, id_len); 615 if (hwaddr_aton2(buf, sess->mac_addr) < 0) 616 os_memset(sess->mac_addr, 0, ETH_ALEN); 617 else 618 RADIUS_DEBUG("Calling-Station-Id: " MACSTR, 619 MAC2STR(sess->mac_addr)); 620 } 621 622 srv_log(sess, "New session created"); 623 624 os_memset(&eap_sess, 0, sizeof(eap_sess)); 625 radius_server_testing_options(sess, &eap_sess); 626 sess->eap = eap_server_sm_init(sess, &radius_server_eapol_cb, 627 data->eap_cfg, &eap_sess); 628 if (sess->eap == NULL) { 629 RADIUS_DEBUG("Failed to initialize EAP state machine for the " 630 "new session"); 631 radius_server_session_remove(data, sess); 632 return NULL; 633 } 634 sess->eap_if = eap_get_interface(sess->eap); 635 sess->eap_if->eapRestart = true; 636 sess->eap_if->portEnabled = true; 637 638 RADIUS_DEBUG("New session 0x%x initialized", sess->sess_id); 639 640 return sess; 641 } 642 643 644 #ifdef CONFIG_HS20 645 static void radius_srv_hs20_t_c_pending(struct radius_session *sess) 646 { 647 #ifdef CONFIG_SQLITE 648 char *sql; 649 char addr[3 * ETH_ALEN], *id_str; 650 const u8 *id; 651 size_t id_len; 652 653 if (!sess->server->db || !sess->eap || 654 is_zero_ether_addr(sess->mac_addr)) 655 return; 656 657 os_snprintf(addr, sizeof(addr), MACSTR, MAC2STR(sess->mac_addr)); 658 659 id = eap_get_identity(sess->eap, &id_len); 660 if (!id) 661 return; 662 id_str = os_malloc(id_len + 1); 663 if (!id_str) 664 return; 665 os_memcpy(id_str, id, id_len); 666 id_str[id_len] = '\0'; 667 668 sql = sqlite3_mprintf("INSERT OR REPLACE INTO pending_tc (mac_addr,identity) VALUES (%Q,%Q)", 669 addr, id_str); 670 os_free(id_str); 671 if (!sql) 672 return; 673 674 if (sqlite3_exec(sess->server->db, sql, NULL, NULL, NULL) != 675 SQLITE_OK) { 676 RADIUS_ERROR("Failed to add pending_tc entry into sqlite database: %s", 677 sqlite3_errmsg(sess->server->db)); 678 } 679 sqlite3_free(sql); 680 #endif /* CONFIG_SQLITE */ 681 } 682 #endif /* CONFIG_HS20 */ 683 684 685 static void radius_server_add_session(struct radius_session *sess) 686 { 687 #ifdef CONFIG_SQLITE 688 char *sql; 689 char addr_txt[ETH_ALEN * 3]; 690 struct os_time now; 691 692 if (!sess->server->db) 693 return; 694 695 696 os_snprintf(addr_txt, sizeof(addr_txt), MACSTR, 697 MAC2STR(sess->mac_addr)); 698 699 os_get_time(&now); 700 sql = sqlite3_mprintf("INSERT OR REPLACE INTO current_sessions(mac_addr,identity,start_time,nas,hs20_t_c_filtering) VALUES (%Q,%Q,%d,%Q,%u)", 701 addr_txt, sess->username, now.sec, 702 sess->nas_ip, sess->t_c_filtering); 703 if (sql) { 704 if (sqlite3_exec(sess->server->db, sql, NULL, NULL, 705 NULL) != SQLITE_OK) { 706 RADIUS_ERROR("Failed to add current_sessions entry into sqlite database: %s", 707 sqlite3_errmsg(sess->server->db)); 708 } 709 sqlite3_free(sql); 710 } 711 #endif /* CONFIG_SQLITE */ 712 } 713 714 715 static void db_update_last_msk(struct radius_session *sess, const char *msk) 716 { 717 #ifdef CONFIG_RADIUS_TEST 718 #ifdef CONFIG_SQLITE 719 char *sql = NULL; 720 char *id_str = NULL; 721 const u8 *id; 722 size_t id_len; 723 const char *serial_num; 724 725 if (!sess->server->db) 726 return; 727 728 serial_num = eap_get_serial_num(sess->eap); 729 if (serial_num) { 730 id_len = 5 + os_strlen(serial_num) + 1; 731 id_str = os_malloc(id_len); 732 if (!id_str) 733 return; 734 os_snprintf(id_str, id_len, "cert-%s", serial_num); 735 } else { 736 id = eap_get_identity(sess->eap, &id_len); 737 if (!id) 738 return; 739 id_str = os_malloc(id_len + 1); 740 if (!id_str) 741 return; 742 os_memcpy(id_str, id, id_len); 743 id_str[id_len] = '\0'; 744 } 745 746 sql = sqlite3_mprintf("UPDATE users SET last_msk=%Q WHERE identity=%Q", 747 msk, id_str); 748 os_free(id_str); 749 if (!sql) 750 return; 751 752 if (sqlite3_exec(sess->server->db, sql, NULL, NULL, NULL) != 753 SQLITE_OK) { 754 RADIUS_DEBUG("Failed to update last_msk: %s", 755 sqlite3_errmsg(sess->server->db)); 756 } 757 sqlite3_free(sql); 758 #endif /* CONFIG_SQLITE */ 759 #endif /* CONFIG_RADIUS_TEST */ 760 } 761 762 763 static struct radius_msg * 764 radius_server_encapsulate_eap(struct radius_server_data *data, 765 struct radius_client *client, 766 struct radius_session *sess, 767 struct radius_msg *request) 768 { 769 struct radius_msg *msg; 770 int code; 771 unsigned int sess_id; 772 struct radius_hdr *hdr = radius_msg_get_hdr(request); 773 u16 reason = WLAN_REASON_IEEE_802_1X_AUTH_FAILED; 774 775 if (sess->eap_if->eapFail) { 776 sess->eap_if->eapFail = false; 777 code = RADIUS_CODE_ACCESS_REJECT; 778 } else if (sess->eap_if->eapSuccess) { 779 sess->eap_if->eapSuccess = false; 780 code = RADIUS_CODE_ACCESS_ACCEPT; 781 } else { 782 sess->eap_if->eapReq = false; 783 code = RADIUS_CODE_ACCESS_CHALLENGE; 784 } 785 786 msg = radius_msg_new(code, hdr->identifier); 787 if (msg == NULL) { 788 RADIUS_DEBUG("Failed to allocate reply message"); 789 return NULL; 790 } 791 792 if (!radius_msg_add_msg_auth(msg)) { 793 radius_msg_free(msg); 794 return NULL; 795 } 796 797 sess_id = htonl(sess->sess_id); 798 if (code == RADIUS_CODE_ACCESS_CHALLENGE && 799 !radius_msg_add_attr(msg, RADIUS_ATTR_STATE, 800 (u8 *) &sess_id, sizeof(sess_id))) { 801 RADIUS_DEBUG("Failed to add State attribute"); 802 } 803 804 if (sess->eap_if->eapReqData && 805 !radius_msg_add_eap(msg, wpabuf_head(sess->eap_if->eapReqData), 806 wpabuf_len(sess->eap_if->eapReqData))) { 807 RADIUS_DEBUG("Failed to add EAP-Message attribute"); 808 } 809 810 if (code == RADIUS_CODE_ACCESS_ACCEPT && sess->eap_if->eapKeyData) { 811 int len; 812 #ifdef CONFIG_RADIUS_TEST 813 char buf[2 * 64 + 1]; 814 815 len = sess->eap_if->eapKeyDataLen; 816 if (len > 64) 817 len = 64; 818 len = wpa_snprintf_hex(buf, sizeof(buf), 819 sess->eap_if->eapKeyData, len); 820 buf[len] = '\0'; 821 822 if (data->dump_msk_file) { 823 FILE *f; 824 825 f = fopen(data->dump_msk_file, "a"); 826 if (f) { 827 len = sess->eap_if->eapKeyDataLen; 828 if (len > 64) 829 len = 64; 830 len = wpa_snprintf_hex( 831 buf, sizeof(buf), 832 sess->eap_if->eapKeyData, len); 833 buf[len] = '\0'; 834 fprintf(f, "%s\n", buf); 835 fclose(f); 836 } 837 } 838 839 db_update_last_msk(sess, buf); 840 #endif /* CONFIG_RADIUS_TEST */ 841 if (sess->eap_if->eapKeyDataLen > 64) { 842 len = 32; 843 } else { 844 len = sess->eap_if->eapKeyDataLen / 2; 845 } 846 if (!radius_msg_add_mppe_keys(msg, hdr->authenticator, 847 (u8 *) client->shared_secret, 848 client->shared_secret_len, 849 sess->eap_if->eapKeyData + len, 850 len, sess->eap_if->eapKeyData, 851 len)) { 852 RADIUS_DEBUG("Failed to add MPPE key attributes"); 853 } 854 855 if (sess->eap_if->eapSessionId && 856 !radius_msg_add_attr(msg, RADIUS_ATTR_EAP_KEY_NAME, 857 sess->eap_if->eapSessionId, 858 sess->eap_if->eapSessionIdLen)) { 859 RADIUS_DEBUG("Failed to add EAP-Key-Name attribute"); 860 } 861 } 862 863 #ifdef CONFIG_HS20 864 if (code == RADIUS_CODE_ACCESS_ACCEPT && sess->t_c_filtering) { 865 u8 buf[4] = { 0x01, 0x00, 0x00, 0x00 }; /* E=1 */ 866 const char *url = data->t_c_server_url, *pos; 867 char *url2, *end2, *pos2; 868 size_t url_len; 869 870 if (!radius_msg_add_wfa( 871 msg, RADIUS_VENDOR_ATTR_WFA_HS20_T_C_FILTERING, 872 buf, sizeof(buf))) { 873 RADIUS_DEBUG("Failed to add WFA-HS20-T-C-Filtering"); 874 radius_msg_free(msg); 875 return NULL; 876 } 877 878 if (!url) { 879 RADIUS_DEBUG("No t_c_server_url configured"); 880 radius_msg_free(msg); 881 return NULL; 882 } 883 884 pos = os_strstr(url, "@1@"); 885 if (!pos) { 886 RADIUS_DEBUG("No @1@ macro in t_c_server_url"); 887 radius_msg_free(msg); 888 return NULL; 889 } 890 891 url_len = os_strlen(url) + ETH_ALEN * 3 - 1 - 3; 892 url2 = os_malloc(url_len + 1); 893 if (!url2) { 894 RADIUS_DEBUG("Failed to allocate room for T&C Server URL"); 895 os_free(url2); 896 radius_msg_free(msg); 897 return NULL; 898 } 899 pos2 = url2; 900 end2 = url2 + url_len + 1; 901 os_memcpy(pos2, url, pos - url); 902 pos2 += pos - url; 903 os_snprintf(pos2, end2 - pos2, MACSTR, MAC2STR(sess->mac_addr)); 904 pos2 += ETH_ALEN * 3 - 1; 905 os_memcpy(pos2, pos + 3, os_strlen(pos + 3)); 906 if (!radius_msg_add_wfa(msg, 907 RADIUS_VENDOR_ATTR_WFA_HS20_T_C_URL, 908 (const u8 *) url2, url_len)) { 909 RADIUS_DEBUG("Failed to add WFA-HS20-T-C-URL"); 910 os_free(url2); 911 radius_msg_free(msg); 912 return NULL; 913 } 914 os_free(url2); 915 916 radius_srv_hs20_t_c_pending(sess); 917 } 918 #endif /* CONFIG_HS20 */ 919 920 if (radius_msg_copy_attr(msg, request, RADIUS_ATTR_PROXY_STATE) < 0) { 921 RADIUS_DEBUG("Failed to copy Proxy-State attribute(s)"); 922 radius_msg_free(msg); 923 return NULL; 924 } 925 926 if (code == RADIUS_CODE_ACCESS_ACCEPT) { 927 struct hostapd_radius_attr *attr; 928 for (attr = sess->accept_attr; attr; attr = attr->next) { 929 if (!radius_msg_add_attr(msg, attr->type, 930 wpabuf_head(attr->val), 931 wpabuf_len(attr->val))) { 932 wpa_printf(MSG_ERROR, "Could not add RADIUS attribute"); 933 radius_msg_free(msg); 934 return NULL; 935 } 936 } 937 } 938 939 if (code == RADIUS_CODE_ACCESS_REJECT) { 940 if (radius_msg_add_attr_int32(msg, RADIUS_ATTR_WLAN_REASON_CODE, 941 reason) < 0) { 942 RADIUS_DEBUG("Failed to add WLAN-Reason-Code attribute"); 943 radius_msg_free(msg); 944 return NULL; 945 } 946 } 947 948 if (radius_msg_finish_srv(msg, (u8 *) client->shared_secret, 949 client->shared_secret_len, 950 hdr->authenticator) < 0) { 951 RADIUS_DEBUG("Failed to add Message-Authenticator attribute"); 952 radius_msg_free(msg); 953 return NULL; 954 } 955 956 if (code == RADIUS_CODE_ACCESS_ACCEPT) 957 radius_server_add_session(sess); 958 959 return msg; 960 } 961 962 963 static struct radius_msg * 964 radius_server_macacl(struct radius_server_data *data, 965 struct radius_client *client, 966 struct radius_session *sess, 967 struct radius_msg *request) 968 { 969 struct radius_msg *msg; 970 int code; 971 struct radius_hdr *hdr = radius_msg_get_hdr(request); 972 u8 *pw; 973 size_t pw_len; 974 975 code = RADIUS_CODE_ACCESS_ACCEPT; 976 977 if (radius_msg_get_attr_ptr(request, RADIUS_ATTR_USER_PASSWORD, &pw, 978 &pw_len, NULL) < 0) { 979 RADIUS_DEBUG("Could not get User-Password"); 980 code = RADIUS_CODE_ACCESS_REJECT; 981 } else { 982 int res; 983 struct eap_user tmp; 984 985 os_memset(&tmp, 0, sizeof(tmp)); 986 res = data->get_eap_user(data->conf_ctx, (u8 *) sess->username, 987 os_strlen(sess->username), 0, &tmp); 988 if (res || !tmp.macacl || tmp.password == NULL) { 989 RADIUS_DEBUG("No MAC ACL user entry"); 990 bin_clear_free(tmp.password, tmp.password_len); 991 code = RADIUS_CODE_ACCESS_REJECT; 992 } else { 993 u8 buf[128]; 994 res = radius_user_password_hide( 995 request, tmp.password, tmp.password_len, 996 (u8 *) client->shared_secret, 997 client->shared_secret_len, 998 buf, sizeof(buf)); 999 bin_clear_free(tmp.password, tmp.password_len); 1000 1001 if (res < 0 || pw_len != (size_t) res || 1002 os_memcmp_const(pw, buf, res) != 0) { 1003 RADIUS_DEBUG("Incorrect User-Password"); 1004 code = RADIUS_CODE_ACCESS_REJECT; 1005 } 1006 } 1007 } 1008 1009 msg = radius_msg_new(code, hdr->identifier); 1010 if (msg == NULL) { 1011 RADIUS_DEBUG("Failed to allocate reply message"); 1012 return NULL; 1013 } 1014 1015 if (!radius_msg_add_msg_auth(msg)) { 1016 radius_msg_free(msg); 1017 return NULL; 1018 } 1019 1020 if (radius_msg_copy_attr(msg, request, RADIUS_ATTR_PROXY_STATE) < 0) { 1021 RADIUS_DEBUG("Failed to copy Proxy-State attribute(s)"); 1022 radius_msg_free(msg); 1023 return NULL; 1024 } 1025 1026 if (code == RADIUS_CODE_ACCESS_ACCEPT) { 1027 struct hostapd_radius_attr *attr; 1028 for (attr = sess->accept_attr; attr; attr = attr->next) { 1029 if (!radius_msg_add_attr(msg, attr->type, 1030 wpabuf_head(attr->val), 1031 wpabuf_len(attr->val))) { 1032 wpa_printf(MSG_ERROR, "Could not add RADIUS attribute"); 1033 radius_msg_free(msg); 1034 return NULL; 1035 } 1036 } 1037 } 1038 1039 if (radius_msg_finish_srv(msg, (u8 *) client->shared_secret, 1040 client->shared_secret_len, 1041 hdr->authenticator) < 0) { 1042 RADIUS_DEBUG("Failed to add Message-Authenticator attribute"); 1043 radius_msg_free(msg); 1044 return NULL; 1045 } 1046 1047 return msg; 1048 } 1049 1050 1051 static int radius_server_reject(struct radius_server_data *data, 1052 struct radius_client *client, 1053 struct radius_msg *request, 1054 struct sockaddr *from, socklen_t fromlen, 1055 const char *from_addr, int from_port) 1056 { 1057 struct radius_msg *msg; 1058 int ret = 0; 1059 struct eap_hdr eapfail; 1060 struct wpabuf *buf; 1061 struct radius_hdr *hdr = radius_msg_get_hdr(request); 1062 1063 RADIUS_DEBUG("Reject invalid request from %s:%d", 1064 from_addr, from_port); 1065 1066 msg = radius_msg_new(RADIUS_CODE_ACCESS_REJECT, hdr->identifier); 1067 if (msg == NULL) { 1068 return -1; 1069 } 1070 1071 if (!radius_msg_add_msg_auth(msg)) { 1072 radius_msg_free(msg); 1073 return -1; 1074 } 1075 1076 os_memset(&eapfail, 0, sizeof(eapfail)); 1077 eapfail.code = EAP_CODE_FAILURE; 1078 eapfail.identifier = 0; 1079 eapfail.length = host_to_be16(sizeof(eapfail)); 1080 1081 if (!radius_msg_add_eap(msg, (u8 *) &eapfail, sizeof(eapfail))) { 1082 RADIUS_DEBUG("Failed to add EAP-Message attribute"); 1083 } 1084 1085 if (radius_msg_copy_attr(msg, request, RADIUS_ATTR_PROXY_STATE) < 0) { 1086 RADIUS_DEBUG("Failed to copy Proxy-State attribute(s)"); 1087 radius_msg_free(msg); 1088 return -1; 1089 } 1090 1091 if (radius_msg_finish_srv(msg, (u8 *) client->shared_secret, 1092 client->shared_secret_len, 1093 hdr->authenticator) < 1094 0) { 1095 RADIUS_DEBUG("Failed to add Message-Authenticator attribute"); 1096 radius_msg_free(msg); 1097 return -1; 1098 } 1099 1100 if (wpa_debug_level <= MSG_MSGDUMP) { 1101 radius_msg_dump(msg); 1102 } 1103 1104 data->counters.access_rejects++; 1105 client->counters.access_rejects++; 1106 buf = radius_msg_get_buf(msg); 1107 if (sendto(data->auth_sock, wpabuf_head(buf), wpabuf_len(buf), 0, 1108 (struct sockaddr *) from, sizeof(*from)) < 0) { 1109 wpa_printf(MSG_INFO, "sendto[RADIUS SRV]: %s", strerror(errno)); 1110 ret = -1; 1111 } 1112 1113 radius_msg_free(msg); 1114 1115 return ret; 1116 } 1117 1118 1119 static void radius_server_hs20_t_c_check(struct radius_session *sess, 1120 struct radius_msg *msg) 1121 { 1122 #ifdef CONFIG_HS20 1123 u8 *buf, *pos, *end, type, sublen, *timestamp = NULL; 1124 size_t len; 1125 1126 buf = NULL; 1127 for (;;) { 1128 if (radius_msg_get_attr_ptr(msg, RADIUS_ATTR_VENDOR_SPECIFIC, 1129 &buf, &len, buf) < 0) 1130 break; 1131 if (len < 6) 1132 continue; 1133 pos = buf; 1134 end = buf + len; 1135 if (WPA_GET_BE32(pos) != RADIUS_VENDOR_ID_WFA) 1136 continue; 1137 pos += 4; 1138 1139 type = *pos++; 1140 sublen = *pos++; 1141 if (sublen < 2) 1142 continue; /* invalid length */ 1143 sublen -= 2; /* skip header */ 1144 if (pos + sublen > end) 1145 continue; /* invalid WFA VSA */ 1146 1147 if (type == RADIUS_VENDOR_ATTR_WFA_HS20_TIMESTAMP && len >= 4) { 1148 timestamp = pos; 1149 break; 1150 } 1151 } 1152 1153 if (!timestamp) 1154 return; 1155 RADIUS_DEBUG("HS20-Timestamp: %u", WPA_GET_BE32(timestamp)); 1156 if (sess->t_c_timestamp != WPA_GET_BE32(timestamp)) { 1157 RADIUS_DEBUG("Last read T&C timestamp does not match HS20-Timestamp --> require filtering"); 1158 sess->t_c_filtering = 1; 1159 } 1160 #endif /* CONFIG_HS20 */ 1161 } 1162 1163 1164 static int radius_server_request(struct radius_server_data *data, 1165 struct radius_msg *msg, 1166 struct sockaddr *from, socklen_t fromlen, 1167 struct radius_client *client, 1168 const char *from_addr, int from_port, 1169 struct radius_session *force_sess) 1170 { 1171 struct wpabuf *eap = NULL; 1172 int res, state_included = 0; 1173 u8 statebuf[4]; 1174 unsigned int state; 1175 struct radius_session *sess; 1176 struct radius_msg *reply; 1177 int is_complete = 0; 1178 1179 if (force_sess) 1180 sess = force_sess; 1181 else { 1182 res = radius_msg_get_attr(msg, RADIUS_ATTR_STATE, statebuf, 1183 sizeof(statebuf)); 1184 state_included = res >= 0; 1185 if (res == sizeof(statebuf)) { 1186 state = WPA_GET_BE32(statebuf); 1187 sess = radius_server_get_session(client, state); 1188 } else { 1189 sess = NULL; 1190 } 1191 } 1192 1193 if (sess) { 1194 RADIUS_DEBUG("Request for session 0x%x", sess->sess_id); 1195 } else if (state_included) { 1196 RADIUS_DEBUG("State attribute included but no session found"); 1197 radius_server_reject(data, client, msg, from, fromlen, 1198 from_addr, from_port); 1199 return -1; 1200 } else { 1201 sess = radius_server_get_new_session(data, client, msg, 1202 from_addr); 1203 if (sess == NULL) { 1204 RADIUS_DEBUG("Could not create a new session"); 1205 radius_server_reject(data, client, msg, from, fromlen, 1206 from_addr, from_port); 1207 return -1; 1208 } 1209 } 1210 1211 if (sess->last_from_port == from_port && 1212 sess->last_identifier == radius_msg_get_hdr(msg)->identifier && 1213 os_memcmp(sess->last_authenticator, 1214 radius_msg_get_hdr(msg)->authenticator, 16) == 0) { 1215 RADIUS_DEBUG("Duplicate message from %s", from_addr); 1216 data->counters.dup_access_requests++; 1217 client->counters.dup_access_requests++; 1218 1219 if (sess->last_reply) { 1220 struct wpabuf *buf; 1221 buf = radius_msg_get_buf(sess->last_reply); 1222 res = sendto(data->auth_sock, wpabuf_head(buf), 1223 wpabuf_len(buf), 0, 1224 (struct sockaddr *) from, fromlen); 1225 if (res < 0) { 1226 wpa_printf(MSG_INFO, "sendto[RADIUS SRV]: %s", 1227 strerror(errno)); 1228 } 1229 return 0; 1230 } 1231 1232 RADIUS_DEBUG("No previous reply available for duplicate " 1233 "message"); 1234 return -1; 1235 } 1236 1237 eap = radius_msg_get_eap(msg); 1238 if (eap == NULL && sess->macacl) { 1239 reply = radius_server_macacl(data, client, sess, msg); 1240 if (reply == NULL) 1241 return -1; 1242 goto send_reply; 1243 } 1244 if (eap == NULL) { 1245 RADIUS_DEBUG("No EAP-Message in RADIUS packet from %s", 1246 from_addr); 1247 data->counters.packets_dropped++; 1248 client->counters.packets_dropped++; 1249 return -1; 1250 } 1251 1252 RADIUS_DUMP("Received EAP data", wpabuf_head(eap), wpabuf_len(eap)); 1253 1254 /* FIX: if Code is Request, Success, or Failure, send Access-Reject; 1255 * RFC3579 Sect. 2.6.2. 1256 * Include EAP-Response/Nak with no preferred method if 1257 * code == request. 1258 * If code is not 1-4, discard the packet silently. 1259 * Or is this already done by the EAP state machine? */ 1260 1261 wpabuf_free(sess->eap_if->eapRespData); 1262 sess->eap_if->eapRespData = eap; 1263 sess->eap_if->eapResp = true; 1264 eap_server_sm_step(sess->eap); 1265 1266 if ((sess->eap_if->eapReq || sess->eap_if->eapSuccess || 1267 sess->eap_if->eapFail) && sess->eap_if->eapReqData) { 1268 RADIUS_DUMP("EAP data from the state machine", 1269 wpabuf_head(sess->eap_if->eapReqData), 1270 wpabuf_len(sess->eap_if->eapReqData)); 1271 } else if (sess->eap_if->eapFail) { 1272 RADIUS_DEBUG("No EAP data from the state machine, but eapFail " 1273 "set"); 1274 } else if (eap_sm_method_pending(sess->eap)) { 1275 radius_msg_free(sess->last_msg); 1276 sess->last_msg = msg; 1277 sess->last_from_port = from_port; 1278 os_free(sess->last_from_addr); 1279 sess->last_from_addr = os_strdup(from_addr); 1280 sess->last_fromlen = fromlen; 1281 os_memcpy(&sess->last_from, from, fromlen); 1282 return -2; 1283 } else { 1284 RADIUS_DEBUG("No EAP data from the state machine - ignore this" 1285 " Access-Request silently (assuming it was a " 1286 "duplicate)"); 1287 data->counters.packets_dropped++; 1288 client->counters.packets_dropped++; 1289 return -1; 1290 } 1291 1292 if (sess->eap_if->eapSuccess || sess->eap_if->eapFail) 1293 is_complete = 1; 1294 if (sess->eap_if->eapFail) { 1295 srv_log(sess, "EAP authentication failed"); 1296 db_update_last_msk(sess, "FAIL"); 1297 } else if (sess->eap_if->eapSuccess) { 1298 srv_log(sess, "EAP authentication succeeded"); 1299 } 1300 1301 if (sess->eap_if->eapSuccess) 1302 radius_server_hs20_t_c_check(sess, msg); 1303 1304 reply = radius_server_encapsulate_eap(data, client, sess, msg); 1305 1306 send_reply: 1307 if (reply) { 1308 struct wpabuf *buf; 1309 struct radius_hdr *hdr; 1310 1311 RADIUS_DEBUG("Reply to %s:%d", from_addr, from_port); 1312 if (wpa_debug_level <= MSG_MSGDUMP) { 1313 radius_msg_dump(reply); 1314 } 1315 1316 switch (radius_msg_get_hdr(reply)->code) { 1317 case RADIUS_CODE_ACCESS_ACCEPT: 1318 srv_log(sess, "Sending Access-Accept"); 1319 data->counters.access_accepts++; 1320 client->counters.access_accepts++; 1321 break; 1322 case RADIUS_CODE_ACCESS_REJECT: 1323 srv_log(sess, "Sending Access-Reject"); 1324 data->counters.access_rejects++; 1325 client->counters.access_rejects++; 1326 break; 1327 case RADIUS_CODE_ACCESS_CHALLENGE: 1328 data->counters.access_challenges++; 1329 client->counters.access_challenges++; 1330 break; 1331 } 1332 buf = radius_msg_get_buf(reply); 1333 res = sendto(data->auth_sock, wpabuf_head(buf), 1334 wpabuf_len(buf), 0, 1335 (struct sockaddr *) from, fromlen); 1336 if (res < 0) { 1337 wpa_printf(MSG_INFO, "sendto[RADIUS SRV]: %s", 1338 strerror(errno)); 1339 } 1340 radius_msg_free(sess->last_reply); 1341 sess->last_reply = reply; 1342 sess->last_from_port = from_port; 1343 hdr = radius_msg_get_hdr(msg); 1344 sess->last_identifier = hdr->identifier; 1345 os_memcpy(sess->last_authenticator, hdr->authenticator, 16); 1346 } else { 1347 data->counters.packets_dropped++; 1348 client->counters.packets_dropped++; 1349 } 1350 1351 if (is_complete) { 1352 RADIUS_DEBUG("Removing completed session 0x%x after timeout", 1353 sess->sess_id); 1354 eloop_cancel_timeout(radius_server_session_remove_timeout, 1355 data, sess); 1356 eloop_register_timeout(RADIUS_SESSION_MAINTAIN, 0, 1357 radius_server_session_remove_timeout, 1358 data, sess); 1359 } 1360 1361 return 0; 1362 } 1363 1364 1365 static void 1366 radius_server_receive_disconnect_resp(struct radius_server_data *data, 1367 struct radius_client *client, 1368 struct radius_msg *msg, int ack) 1369 { 1370 struct radius_hdr *hdr; 1371 1372 if (!client->pending_dac_disconnect_req) { 1373 RADIUS_DEBUG("Ignore unexpected Disconnect response"); 1374 radius_msg_free(msg); 1375 return; 1376 } 1377 1378 hdr = radius_msg_get_hdr(msg); 1379 if (hdr->identifier != client->pending_dac_disconnect_id) { 1380 RADIUS_DEBUG("Ignore unexpected Disconnect response with unexpected identifier %u (expected %u)", 1381 hdr->identifier, 1382 client->pending_dac_disconnect_id); 1383 radius_msg_free(msg); 1384 return; 1385 } 1386 1387 if (radius_msg_verify(msg, (const u8 *) client->shared_secret, 1388 client->shared_secret_len, 1389 client->pending_dac_disconnect_req, 0)) { 1390 RADIUS_DEBUG("Ignore Disconnect response with invalid authenticator"); 1391 radius_msg_free(msg); 1392 return; 1393 } 1394 1395 RADIUS_DEBUG("Disconnect-%s received for " MACSTR, 1396 ack ? "ACK" : "NAK", 1397 MAC2STR(client->pending_dac_disconnect_addr)); 1398 1399 radius_msg_free(msg); 1400 radius_msg_free(client->pending_dac_disconnect_req); 1401 client->pending_dac_disconnect_req = NULL; 1402 } 1403 1404 1405 static void radius_server_receive_coa_resp(struct radius_server_data *data, 1406 struct radius_client *client, 1407 struct radius_msg *msg, int ack) 1408 { 1409 struct radius_hdr *hdr; 1410 #ifdef CONFIG_SQLITE 1411 char addrtxt[3 * ETH_ALEN]; 1412 char *sql; 1413 int res; 1414 #endif /* CONFIG_SQLITE */ 1415 1416 if (!client->pending_dac_coa_req) { 1417 RADIUS_DEBUG("Ignore unexpected CoA response"); 1418 radius_msg_free(msg); 1419 return; 1420 } 1421 1422 hdr = radius_msg_get_hdr(msg); 1423 if (hdr->identifier != client->pending_dac_coa_id) { 1424 RADIUS_DEBUG("Ignore unexpected CoA response with unexpected identifier %u (expected %u)", 1425 hdr->identifier, 1426 client->pending_dac_coa_id); 1427 radius_msg_free(msg); 1428 return; 1429 } 1430 1431 if (radius_msg_verify(msg, (const u8 *) client->shared_secret, 1432 client->shared_secret_len, 1433 client->pending_dac_coa_req, 0)) { 1434 RADIUS_DEBUG("Ignore CoA response with invalid authenticator"); 1435 radius_msg_free(msg); 1436 return; 1437 } 1438 1439 RADIUS_DEBUG("CoA-%s received for " MACSTR, 1440 ack ? "ACK" : "NAK", 1441 MAC2STR(client->pending_dac_coa_addr)); 1442 1443 radius_msg_free(msg); 1444 radius_msg_free(client->pending_dac_coa_req); 1445 client->pending_dac_coa_req = NULL; 1446 1447 #ifdef CONFIG_SQLITE 1448 if (!data->db) 1449 return; 1450 1451 os_snprintf(addrtxt, sizeof(addrtxt), MACSTR, 1452 MAC2STR(client->pending_dac_coa_addr)); 1453 1454 if (ack) { 1455 sql = sqlite3_mprintf("UPDATE current_sessions SET hs20_t_c_filtering=0, waiting_coa_ack=0, coa_ack_received=1 WHERE mac_addr=%Q", 1456 addrtxt); 1457 } else { 1458 sql = sqlite3_mprintf("UPDATE current_sessions SET waiting_coa_ack=0 WHERE mac_addr=%Q", 1459 addrtxt); 1460 } 1461 if (!sql) 1462 return; 1463 1464 res = sqlite3_exec(data->db, sql, NULL, NULL, NULL); 1465 sqlite3_free(sql); 1466 if (res != SQLITE_OK) { 1467 RADIUS_ERROR("Failed to update current_sessions entry: %s", 1468 sqlite3_errmsg(data->db)); 1469 return; 1470 } 1471 #endif /* CONFIG_SQLITE */ 1472 } 1473 1474 1475 static void radius_server_receive_auth(int sock, void *eloop_ctx, 1476 void *sock_ctx) 1477 { 1478 struct radius_server_data *data = eloop_ctx; 1479 u8 *buf = NULL; 1480 union { 1481 struct sockaddr_storage ss; 1482 struct sockaddr_in sin; 1483 #ifdef CONFIG_IPV6 1484 struct sockaddr_in6 sin6; 1485 #endif /* CONFIG_IPV6 */ 1486 } from; 1487 socklen_t fromlen; 1488 int len; 1489 struct radius_client *client = NULL; 1490 struct radius_msg *msg = NULL; 1491 char abuf[50]; 1492 int from_port = 0; 1493 1494 buf = os_malloc(RADIUS_MAX_MSG_LEN); 1495 if (buf == NULL) { 1496 goto fail; 1497 } 1498 1499 fromlen = sizeof(from); 1500 len = recvfrom(sock, buf, RADIUS_MAX_MSG_LEN, 0, 1501 (struct sockaddr *) &from.ss, &fromlen); 1502 if (len < 0) { 1503 wpa_printf(MSG_INFO, "recvfrom[radius_server]: %s", 1504 strerror(errno)); 1505 goto fail; 1506 } 1507 1508 #ifdef CONFIG_IPV6 1509 if (data->ipv6) { 1510 if (inet_ntop(AF_INET6, &from.sin6.sin6_addr, abuf, 1511 sizeof(abuf)) == NULL) 1512 abuf[0] = '\0'; 1513 from_port = ntohs(from.sin6.sin6_port); 1514 RADIUS_DEBUG("Received %d bytes from %s:%d", 1515 len, abuf, from_port); 1516 1517 client = radius_server_get_client(data, 1518 (struct in_addr *) 1519 &from.sin6.sin6_addr, 1); 1520 } 1521 #endif /* CONFIG_IPV6 */ 1522 1523 if (!data->ipv6) { 1524 os_strlcpy(abuf, inet_ntoa(from.sin.sin_addr), sizeof(abuf)); 1525 from_port = ntohs(from.sin.sin_port); 1526 RADIUS_DEBUG("Received %d bytes from %s:%d", 1527 len, abuf, from_port); 1528 1529 client = radius_server_get_client(data, &from.sin.sin_addr, 0); 1530 } 1531 1532 RADIUS_DUMP("Received data", buf, len); 1533 1534 if (client == NULL) { 1535 RADIUS_DEBUG("Unknown client %s - packet ignored", abuf); 1536 data->counters.invalid_requests++; 1537 goto fail; 1538 } 1539 1540 msg = radius_msg_parse(buf, len); 1541 if (msg == NULL) { 1542 RADIUS_DEBUG("Parsing incoming RADIUS frame failed"); 1543 data->counters.malformed_access_requests++; 1544 client->counters.malformed_access_requests++; 1545 goto fail; 1546 } 1547 1548 os_free(buf); 1549 buf = NULL; 1550 1551 if (wpa_debug_level <= MSG_MSGDUMP) { 1552 radius_msg_dump(msg); 1553 } 1554 1555 if (radius_msg_get_hdr(msg)->code == RADIUS_CODE_DISCONNECT_ACK) { 1556 radius_server_receive_disconnect_resp(data, client, msg, 1); 1557 return; 1558 } 1559 1560 if (radius_msg_get_hdr(msg)->code == RADIUS_CODE_DISCONNECT_NAK) { 1561 radius_server_receive_disconnect_resp(data, client, msg, 0); 1562 return; 1563 } 1564 1565 if (radius_msg_get_hdr(msg)->code == RADIUS_CODE_COA_ACK) { 1566 radius_server_receive_coa_resp(data, client, msg, 1); 1567 return; 1568 } 1569 1570 if (radius_msg_get_hdr(msg)->code == RADIUS_CODE_COA_NAK) { 1571 radius_server_receive_coa_resp(data, client, msg, 0); 1572 return; 1573 } 1574 1575 if (radius_msg_get_hdr(msg)->code != RADIUS_CODE_ACCESS_REQUEST) { 1576 RADIUS_DEBUG("Unexpected RADIUS code %d", 1577 radius_msg_get_hdr(msg)->code); 1578 data->counters.unknown_types++; 1579 client->counters.unknown_types++; 1580 goto fail; 1581 } 1582 1583 data->counters.access_requests++; 1584 client->counters.access_requests++; 1585 1586 if (radius_msg_verify_msg_auth(msg, (u8 *) client->shared_secret, 1587 client->shared_secret_len, NULL)) { 1588 RADIUS_DEBUG("Invalid Message-Authenticator from %s", abuf); 1589 data->counters.bad_authenticators++; 1590 client->counters.bad_authenticators++; 1591 goto fail; 1592 } 1593 1594 if (radius_server_request(data, msg, (struct sockaddr *) &from, 1595 fromlen, client, abuf, from_port, NULL) == 1596 -2) 1597 return; /* msg was stored with the session */ 1598 1599 fail: 1600 radius_msg_free(msg); 1601 os_free(buf); 1602 } 1603 1604 1605 static void radius_server_receive_acct(int sock, void *eloop_ctx, 1606 void *sock_ctx) 1607 { 1608 struct radius_server_data *data = eloop_ctx; 1609 u8 *buf = NULL; 1610 union { 1611 struct sockaddr_storage ss; 1612 struct sockaddr_in sin; 1613 #ifdef CONFIG_IPV6 1614 struct sockaddr_in6 sin6; 1615 #endif /* CONFIG_IPV6 */ 1616 } from; 1617 socklen_t fromlen; 1618 int len, res; 1619 struct radius_client *client = NULL; 1620 struct radius_msg *msg = NULL, *resp = NULL; 1621 char abuf[50]; 1622 int from_port = 0; 1623 struct radius_hdr *hdr; 1624 struct wpabuf *rbuf; 1625 u32 status_type; 1626 1627 buf = os_malloc(RADIUS_MAX_MSG_LEN); 1628 if (buf == NULL) { 1629 goto fail; 1630 } 1631 1632 fromlen = sizeof(from); 1633 len = recvfrom(sock, buf, RADIUS_MAX_MSG_LEN, 0, 1634 (struct sockaddr *) &from.ss, &fromlen); 1635 if (len < 0) { 1636 wpa_printf(MSG_INFO, "recvfrom[radius_server]: %s", 1637 strerror(errno)); 1638 goto fail; 1639 } 1640 1641 #ifdef CONFIG_IPV6 1642 if (data->ipv6) { 1643 if (inet_ntop(AF_INET6, &from.sin6.sin6_addr, abuf, 1644 sizeof(abuf)) == NULL) 1645 abuf[0] = '\0'; 1646 from_port = ntohs(from.sin6.sin6_port); 1647 RADIUS_DEBUG("Received %d bytes from %s:%d", 1648 len, abuf, from_port); 1649 1650 client = radius_server_get_client(data, 1651 (struct in_addr *) 1652 &from.sin6.sin6_addr, 1); 1653 } 1654 #endif /* CONFIG_IPV6 */ 1655 1656 if (!data->ipv6) { 1657 os_strlcpy(abuf, inet_ntoa(from.sin.sin_addr), sizeof(abuf)); 1658 from_port = ntohs(from.sin.sin_port); 1659 RADIUS_DEBUG("Received %d bytes from %s:%d", 1660 len, abuf, from_port); 1661 1662 client = radius_server_get_client(data, &from.sin.sin_addr, 0); 1663 } 1664 1665 RADIUS_DUMP("Received data", buf, len); 1666 1667 if (client == NULL) { 1668 RADIUS_DEBUG("Unknown client %s - packet ignored", abuf); 1669 data->counters.invalid_acct_requests++; 1670 goto fail; 1671 } 1672 1673 msg = radius_msg_parse(buf, len); 1674 if (msg == NULL) { 1675 RADIUS_DEBUG("Parsing incoming RADIUS frame failed"); 1676 data->counters.malformed_acct_requests++; 1677 client->counters.malformed_acct_requests++; 1678 goto fail; 1679 } 1680 1681 os_free(buf); 1682 buf = NULL; 1683 1684 if (wpa_debug_level <= MSG_MSGDUMP) { 1685 radius_msg_dump(msg); 1686 } 1687 1688 if (radius_msg_get_hdr(msg)->code != RADIUS_CODE_ACCOUNTING_REQUEST) { 1689 RADIUS_DEBUG("Unexpected RADIUS code %d", 1690 radius_msg_get_hdr(msg)->code); 1691 data->counters.unknown_acct_types++; 1692 client->counters.unknown_acct_types++; 1693 goto fail; 1694 } 1695 1696 data->counters.acct_requests++; 1697 client->counters.acct_requests++; 1698 1699 if (radius_msg_verify_acct_req(msg, (u8 *) client->shared_secret, 1700 client->shared_secret_len)) { 1701 RADIUS_DEBUG("Invalid Authenticator from %s", abuf); 1702 data->counters.acct_bad_authenticators++; 1703 client->counters.acct_bad_authenticators++; 1704 goto fail; 1705 } 1706 1707 /* Parse Acct-Status-Type from Accounting-Request */ 1708 if (radius_msg_get_attr_int32(msg, RADIUS_ATTR_ACCT_STATUS_TYPE, 1709 &status_type) != 0) { 1710 RADIUS_DEBUG("Unable to parse Acct-Status-Type from %s", abuf); 1711 goto fail; 1712 } 1713 1714 /* Process accounting information by configured callback */ 1715 if (data->acct_req_cb && 1716 data->acct_req_cb(data->conf_ctx, msg, status_type) != 0) { 1717 RADIUS_DEBUG("Accounting request callback returned non-zero code indicating processing failure (from %s)", 1718 abuf); 1719 goto fail; 1720 } 1721 1722 hdr = radius_msg_get_hdr(msg); 1723 1724 resp = radius_msg_new(RADIUS_CODE_ACCOUNTING_RESPONSE, hdr->identifier); 1725 if (resp == NULL) 1726 goto fail; 1727 1728 if (radius_msg_finish_acct_resp(resp, (u8 *) client->shared_secret, 1729 client->shared_secret_len, 1730 hdr->authenticator) < 0) { 1731 RADIUS_ERROR("Failed to add Message-Authenticator attribute"); 1732 goto fail; 1733 } 1734 1735 RADIUS_DEBUG("Reply to %s:%d", abuf, from_port); 1736 if (wpa_debug_level <= MSG_MSGDUMP) { 1737 radius_msg_dump(resp); 1738 } 1739 rbuf = radius_msg_get_buf(resp); 1740 data->counters.acct_responses++; 1741 client->counters.acct_responses++; 1742 res = sendto(data->acct_sock, wpabuf_head(rbuf), wpabuf_len(rbuf), 0, 1743 (struct sockaddr *) &from.ss, fromlen); 1744 if (res < 0) { 1745 wpa_printf(MSG_INFO, "sendto[RADIUS SRV]: %s", 1746 strerror(errno)); 1747 } 1748 1749 fail: 1750 radius_msg_free(resp); 1751 radius_msg_free(msg); 1752 os_free(buf); 1753 } 1754 1755 1756 static int radius_server_disable_pmtu_discovery(int s) 1757 { 1758 int r = -1; 1759 #if defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DONT) 1760 /* Turn off Path MTU discovery on IPv4/UDP sockets. */ 1761 int action = IP_PMTUDISC_DONT; 1762 r = setsockopt(s, IPPROTO_IP, IP_MTU_DISCOVER, &action, 1763 sizeof(action)); 1764 if (r == -1) 1765 wpa_printf(MSG_ERROR, "Failed to set IP_MTU_DISCOVER: " 1766 "%s", strerror(errno)); 1767 #endif 1768 return r; 1769 } 1770 1771 1772 static int radius_server_open_socket(int port) 1773 { 1774 int s; 1775 struct sockaddr_in addr; 1776 1777 s = socket(PF_INET, SOCK_DGRAM, 0); 1778 if (s < 0) { 1779 wpa_printf(MSG_INFO, "RADIUS: socket: %s", strerror(errno)); 1780 return -1; 1781 } 1782 1783 radius_server_disable_pmtu_discovery(s); 1784 1785 os_memset(&addr, 0, sizeof(addr)); 1786 addr.sin_family = AF_INET; 1787 addr.sin_port = htons(port); 1788 if (bind(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) { 1789 wpa_printf(MSG_INFO, "RADIUS: bind: %s", strerror(errno)); 1790 close(s); 1791 return -1; 1792 } 1793 1794 return s; 1795 } 1796 1797 1798 #ifdef CONFIG_IPV6 1799 static int radius_server_open_socket6(int port) 1800 { 1801 int s; 1802 struct sockaddr_in6 addr; 1803 1804 s = socket(PF_INET6, SOCK_DGRAM, 0); 1805 if (s < 0) { 1806 wpa_printf(MSG_INFO, "RADIUS: socket[IPv6]: %s", 1807 strerror(errno)); 1808 return -1; 1809 } 1810 1811 os_memset(&addr, 0, sizeof(addr)); 1812 addr.sin6_family = AF_INET6; 1813 os_memcpy(&addr.sin6_addr, &in6addr_any, sizeof(in6addr_any)); 1814 addr.sin6_port = htons(port); 1815 if (bind(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) { 1816 wpa_printf(MSG_INFO, "RADIUS: bind: %s", strerror(errno)); 1817 close(s); 1818 return -1; 1819 } 1820 1821 return s; 1822 } 1823 #endif /* CONFIG_IPV6 */ 1824 1825 1826 static void radius_server_free_sessions(struct radius_server_data *data, 1827 struct radius_session *sessions) 1828 { 1829 struct radius_session *session, *prev; 1830 1831 session = sessions; 1832 while (session) { 1833 prev = session; 1834 session = session->next; 1835 radius_server_session_free(data, prev); 1836 } 1837 } 1838 1839 1840 static void radius_server_free_clients(struct radius_server_data *data, 1841 struct radius_client *clients) 1842 { 1843 struct radius_client *client, *prev; 1844 1845 client = clients; 1846 while (client) { 1847 prev = client; 1848 client = client->next; 1849 1850 radius_server_free_sessions(data, prev->sessions); 1851 os_free(prev->shared_secret); 1852 radius_msg_free(prev->pending_dac_coa_req); 1853 radius_msg_free(prev->pending_dac_disconnect_req); 1854 os_free(prev); 1855 } 1856 } 1857 1858 1859 static struct radius_client * 1860 radius_server_read_clients(const char *client_file, int ipv6) 1861 { 1862 FILE *f; 1863 const int buf_size = 1024; 1864 char *buf, *pos; 1865 struct radius_client *clients, *tail, *entry; 1866 int line = 0, mask, failed = 0, i; 1867 struct in_addr addr; 1868 #ifdef CONFIG_IPV6 1869 struct in6_addr addr6; 1870 #endif /* CONFIG_IPV6 */ 1871 unsigned int val; 1872 1873 f = fopen(client_file, "r"); 1874 if (f == NULL) { 1875 RADIUS_ERROR("Could not open client file '%s'", client_file); 1876 return NULL; 1877 } 1878 1879 buf = os_malloc(buf_size); 1880 if (buf == NULL) { 1881 fclose(f); 1882 return NULL; 1883 } 1884 1885 clients = tail = NULL; 1886 while (fgets(buf, buf_size, f)) { 1887 /* Configuration file format: 1888 * 192.168.1.0/24 secret 1889 * 192.168.1.2 secret 1890 * fe80::211:22ff:fe33:4455/64 secretipv6 1891 */ 1892 line++; 1893 buf[buf_size - 1] = '\0'; 1894 pos = buf; 1895 while (*pos != '\0' && *pos != '\n') 1896 pos++; 1897 if (*pos == '\n') 1898 *pos = '\0'; 1899 if (*buf == '\0' || *buf == '#') 1900 continue; 1901 1902 pos = buf; 1903 while ((*pos >= '0' && *pos <= '9') || *pos == '.' || 1904 (*pos >= 'a' && *pos <= 'f') || *pos == ':' || 1905 (*pos >= 'A' && *pos <= 'F')) { 1906 pos++; 1907 } 1908 1909 if (*pos == '\0') { 1910 failed = 1; 1911 break; 1912 } 1913 1914 if (*pos == '/') { 1915 char *end; 1916 *pos++ = '\0'; 1917 mask = strtol(pos, &end, 10); 1918 if ((pos == end) || 1919 (mask < 0 || mask > (ipv6 ? 128 : 32))) { 1920 failed = 1; 1921 break; 1922 } 1923 pos = end; 1924 } else { 1925 mask = ipv6 ? 128 : 32; 1926 *pos++ = '\0'; 1927 } 1928 1929 if (!ipv6 && inet_aton(buf, &addr) == 0) { 1930 failed = 1; 1931 break; 1932 } 1933 #ifdef CONFIG_IPV6 1934 if (ipv6 && inet_pton(AF_INET6, buf, &addr6) <= 0) { 1935 if (inet_pton(AF_INET, buf, &addr) <= 0) { 1936 failed = 1; 1937 break; 1938 } 1939 /* Convert IPv4 address to IPv6 */ 1940 if (mask <= 32) 1941 mask += (128 - 32); 1942 os_memset(addr6.s6_addr, 0, 10); 1943 addr6.s6_addr[10] = 0xff; 1944 addr6.s6_addr[11] = 0xff; 1945 os_memcpy(addr6.s6_addr + 12, (char *) &addr.s_addr, 1946 4); 1947 } 1948 #endif /* CONFIG_IPV6 */ 1949 1950 while (*pos == ' ' || *pos == '\t') { 1951 pos++; 1952 } 1953 1954 if (*pos == '\0') { 1955 failed = 1; 1956 break; 1957 } 1958 1959 entry = os_zalloc(sizeof(*entry)); 1960 if (entry == NULL) { 1961 failed = 1; 1962 break; 1963 } 1964 entry->shared_secret = os_strdup(pos); 1965 if (entry->shared_secret == NULL) { 1966 failed = 1; 1967 os_free(entry); 1968 break; 1969 } 1970 entry->shared_secret_len = os_strlen(entry->shared_secret); 1971 if (!ipv6) { 1972 entry->addr.s_addr = addr.s_addr; 1973 val = 0; 1974 for (i = 0; i < mask; i++) 1975 val |= 1U << (31 - i); 1976 entry->mask.s_addr = htonl(val); 1977 } 1978 #ifdef CONFIG_IPV6 1979 if (ipv6) { 1980 int offset = mask / 8; 1981 1982 os_memcpy(entry->addr6.s6_addr, addr6.s6_addr, 16); 1983 os_memset(entry->mask6.s6_addr, 0xff, offset); 1984 val = 0; 1985 for (i = 0; i < (mask % 8); i++) 1986 val |= 1 << (7 - i); 1987 if (offset < 16) 1988 entry->mask6.s6_addr[offset] = val; 1989 } 1990 #endif /* CONFIG_IPV6 */ 1991 1992 if (tail == NULL) { 1993 clients = tail = entry; 1994 } else { 1995 tail->next = entry; 1996 tail = entry; 1997 } 1998 } 1999 2000 if (failed) { 2001 RADIUS_ERROR("Invalid line %d in '%s'", line, client_file); 2002 radius_server_free_clients(NULL, clients); 2003 clients = NULL; 2004 } 2005 2006 os_free(buf); 2007 fclose(f); 2008 2009 return clients; 2010 } 2011 2012 2013 /** 2014 * radius_server_init - Initialize RADIUS server 2015 * @conf: Configuration for the RADIUS server 2016 * Returns: Pointer to private RADIUS server context or %NULL on failure 2017 * 2018 * This initializes a RADIUS server instance and returns a context pointer that 2019 * will be used in other calls to the RADIUS server module. The server can be 2020 * deinitialize by calling radius_server_deinit(). 2021 */ 2022 struct radius_server_data * 2023 radius_server_init(struct radius_server_conf *conf) 2024 { 2025 struct radius_server_data *data; 2026 2027 #ifndef CONFIG_IPV6 2028 if (conf->ipv6) { 2029 wpa_printf(MSG_ERROR, "RADIUS server compiled without IPv6 support"); 2030 return NULL; 2031 } 2032 #endif /* CONFIG_IPV6 */ 2033 2034 data = os_zalloc(sizeof(*data)); 2035 if (data == NULL) 2036 return NULL; 2037 2038 data->eap_cfg = conf->eap_cfg; 2039 data->auth_sock = -1; 2040 data->acct_sock = -1; 2041 dl_list_init(&data->erp_keys); 2042 os_get_reltime(&data->start_time); 2043 data->conf_ctx = conf->conf_ctx; 2044 conf->eap_cfg->backend_auth = true; 2045 conf->eap_cfg->eap_server = 1; 2046 data->ipv6 = conf->ipv6; 2047 data->get_eap_user = conf->get_eap_user; 2048 data->acct_req_cb = conf->acct_req_cb; 2049 if (conf->eap_req_id_text) { 2050 data->eap_req_id_text = os_malloc(conf->eap_req_id_text_len); 2051 if (!data->eap_req_id_text) 2052 goto fail; 2053 os_memcpy(data->eap_req_id_text, conf->eap_req_id_text, 2054 conf->eap_req_id_text_len); 2055 data->eap_req_id_text_len = conf->eap_req_id_text_len; 2056 } 2057 data->erp_domain = conf->erp_domain; 2058 2059 if (conf->t_c_server_url) { 2060 data->t_c_server_url = os_strdup(conf->t_c_server_url); 2061 if (!data->t_c_server_url) 2062 goto fail; 2063 } 2064 2065 #ifdef CONFIG_SQLITE 2066 if (conf->sqlite_file) { 2067 if (sqlite3_open(conf->sqlite_file, &data->db)) { 2068 RADIUS_ERROR("Could not open SQLite file '%s'", 2069 conf->sqlite_file); 2070 goto fail; 2071 } 2072 } 2073 #endif /* CONFIG_SQLITE */ 2074 2075 #ifdef CONFIG_RADIUS_TEST 2076 if (conf->dump_msk_file) 2077 data->dump_msk_file = os_strdup(conf->dump_msk_file); 2078 #endif /* CONFIG_RADIUS_TEST */ 2079 2080 data->clients = radius_server_read_clients(conf->client_file, 2081 conf->ipv6); 2082 if (data->clients == NULL) { 2083 wpa_printf(MSG_ERROR, "No RADIUS clients configured"); 2084 goto fail; 2085 } 2086 2087 #ifdef CONFIG_IPV6 2088 if (conf->ipv6) 2089 data->auth_sock = radius_server_open_socket6(conf->auth_port); 2090 else 2091 #endif /* CONFIG_IPV6 */ 2092 data->auth_sock = radius_server_open_socket(conf->auth_port); 2093 if (data->auth_sock < 0) { 2094 wpa_printf(MSG_ERROR, "Failed to open UDP socket for RADIUS authentication server"); 2095 goto fail; 2096 } 2097 if (eloop_register_read_sock(data->auth_sock, 2098 radius_server_receive_auth, 2099 data, NULL)) { 2100 goto fail; 2101 } 2102 2103 if (conf->acct_port) { 2104 #ifdef CONFIG_IPV6 2105 if (conf->ipv6) 2106 data->acct_sock = radius_server_open_socket6( 2107 conf->acct_port); 2108 else 2109 #endif /* CONFIG_IPV6 */ 2110 data->acct_sock = radius_server_open_socket(conf->acct_port); 2111 if (data->acct_sock < 0) { 2112 wpa_printf(MSG_ERROR, "Failed to open UDP socket for RADIUS accounting server"); 2113 goto fail; 2114 } 2115 if (eloop_register_read_sock(data->acct_sock, 2116 radius_server_receive_acct, 2117 data, NULL)) 2118 goto fail; 2119 } else { 2120 data->acct_sock = -1; 2121 } 2122 2123 return data; 2124 fail: 2125 radius_server_deinit(data); 2126 return NULL; 2127 } 2128 2129 2130 /** 2131 * radius_server_erp_flush - Flush all ERP keys 2132 * @data: RADIUS server context from radius_server_init() 2133 */ 2134 void radius_server_erp_flush(struct radius_server_data *data) 2135 { 2136 struct eap_server_erp_key *erp; 2137 2138 if (data == NULL) 2139 return; 2140 while ((erp = dl_list_first(&data->erp_keys, struct eap_server_erp_key, 2141 list)) != NULL) { 2142 dl_list_del(&erp->list); 2143 bin_clear_free(erp, sizeof(*erp)); 2144 } 2145 } 2146 2147 2148 /** 2149 * radius_server_deinit - Deinitialize RADIUS server 2150 * @data: RADIUS server context from radius_server_init() 2151 */ 2152 void radius_server_deinit(struct radius_server_data *data) 2153 { 2154 if (data == NULL) 2155 return; 2156 2157 if (data->auth_sock >= 0) { 2158 eloop_unregister_read_sock(data->auth_sock); 2159 close(data->auth_sock); 2160 } 2161 2162 if (data->acct_sock >= 0) { 2163 eloop_unregister_read_sock(data->acct_sock); 2164 close(data->acct_sock); 2165 } 2166 2167 radius_server_free_clients(data, data->clients); 2168 2169 os_free(data->eap_req_id_text); 2170 #ifdef CONFIG_RADIUS_TEST 2171 os_free(data->dump_msk_file); 2172 #endif /* CONFIG_RADIUS_TEST */ 2173 os_free(data->t_c_server_url); 2174 2175 #ifdef CONFIG_SQLITE 2176 if (data->db) 2177 sqlite3_close(data->db); 2178 #endif /* CONFIG_SQLITE */ 2179 2180 radius_server_erp_flush(data); 2181 2182 os_free(data); 2183 } 2184 2185 2186 /** 2187 * radius_server_get_mib - Get RADIUS server MIB information 2188 * @data: RADIUS server context from radius_server_init() 2189 * @buf: Buffer for returning the MIB data in text format 2190 * @buflen: buf length in octets 2191 * Returns: Number of octets written into buf 2192 */ 2193 int radius_server_get_mib(struct radius_server_data *data, char *buf, 2194 size_t buflen) 2195 { 2196 int ret, uptime; 2197 unsigned int idx; 2198 char *end, *pos; 2199 struct os_reltime now; 2200 struct radius_client *cli; 2201 2202 /* RFC 2619 - RADIUS Authentication Server MIB */ 2203 2204 if (data == NULL || buflen == 0) 2205 return 0; 2206 2207 pos = buf; 2208 end = buf + buflen; 2209 2210 os_get_reltime(&now); 2211 uptime = (now.sec - data->start_time.sec) * 100 + 2212 ((now.usec - data->start_time.usec) / 10000) % 100; 2213 ret = os_snprintf(pos, end - pos, 2214 "RADIUS-AUTH-SERVER-MIB\n" 2215 "radiusAuthServIdent=hostapd\n" 2216 "radiusAuthServUpTime=%d\n" 2217 "radiusAuthServResetTime=0\n" 2218 "radiusAuthServConfigReset=4\n", 2219 uptime); 2220 if (os_snprintf_error(end - pos, ret)) { 2221 *pos = '\0'; 2222 return pos - buf; 2223 } 2224 pos += ret; 2225 2226 ret = os_snprintf(pos, end - pos, 2227 "radiusAuthServTotalAccessRequests=%u\n" 2228 "radiusAuthServTotalInvalidRequests=%u\n" 2229 "radiusAuthServTotalDupAccessRequests=%u\n" 2230 "radiusAuthServTotalAccessAccepts=%u\n" 2231 "radiusAuthServTotalAccessRejects=%u\n" 2232 "radiusAuthServTotalAccessChallenges=%u\n" 2233 "radiusAuthServTotalMalformedAccessRequests=%u\n" 2234 "radiusAuthServTotalBadAuthenticators=%u\n" 2235 "radiusAuthServTotalPacketsDropped=%u\n" 2236 "radiusAuthServTotalUnknownTypes=%u\n" 2237 "radiusAccServTotalRequests=%u\n" 2238 "radiusAccServTotalInvalidRequests=%u\n" 2239 "radiusAccServTotalResponses=%u\n" 2240 "radiusAccServTotalMalformedRequests=%u\n" 2241 "radiusAccServTotalBadAuthenticators=%u\n" 2242 "radiusAccServTotalUnknownTypes=%u\n", 2243 data->counters.access_requests, 2244 data->counters.invalid_requests, 2245 data->counters.dup_access_requests, 2246 data->counters.access_accepts, 2247 data->counters.access_rejects, 2248 data->counters.access_challenges, 2249 data->counters.malformed_access_requests, 2250 data->counters.bad_authenticators, 2251 data->counters.packets_dropped, 2252 data->counters.unknown_types, 2253 data->counters.acct_requests, 2254 data->counters.invalid_acct_requests, 2255 data->counters.acct_responses, 2256 data->counters.malformed_acct_requests, 2257 data->counters.acct_bad_authenticators, 2258 data->counters.unknown_acct_types); 2259 if (os_snprintf_error(end - pos, ret)) { 2260 *pos = '\0'; 2261 return pos - buf; 2262 } 2263 pos += ret; 2264 2265 for (cli = data->clients, idx = 0; cli; cli = cli->next, idx++) { 2266 char abuf[50], mbuf[50]; 2267 #ifdef CONFIG_IPV6 2268 if (data->ipv6) { 2269 if (inet_ntop(AF_INET6, &cli->addr6, abuf, 2270 sizeof(abuf)) == NULL) 2271 abuf[0] = '\0'; 2272 if (inet_ntop(AF_INET6, &cli->mask6, mbuf, 2273 sizeof(mbuf)) == NULL) 2274 mbuf[0] = '\0'; 2275 } 2276 #endif /* CONFIG_IPV6 */ 2277 if (!data->ipv6) { 2278 os_strlcpy(abuf, inet_ntoa(cli->addr), sizeof(abuf)); 2279 os_strlcpy(mbuf, inet_ntoa(cli->mask), sizeof(mbuf)); 2280 } 2281 2282 ret = os_snprintf(pos, end - pos, 2283 "radiusAuthClientIndex=%u\n" 2284 "radiusAuthClientAddress=%s/%s\n" 2285 "radiusAuthServAccessRequests=%u\n" 2286 "radiusAuthServDupAccessRequests=%u\n" 2287 "radiusAuthServAccessAccepts=%u\n" 2288 "radiusAuthServAccessRejects=%u\n" 2289 "radiusAuthServAccessChallenges=%u\n" 2290 "radiusAuthServMalformedAccessRequests=%u\n" 2291 "radiusAuthServBadAuthenticators=%u\n" 2292 "radiusAuthServPacketsDropped=%u\n" 2293 "radiusAuthServUnknownTypes=%u\n" 2294 "radiusAccServTotalRequests=%u\n" 2295 "radiusAccServTotalInvalidRequests=%u\n" 2296 "radiusAccServTotalResponses=%u\n" 2297 "radiusAccServTotalMalformedRequests=%u\n" 2298 "radiusAccServTotalBadAuthenticators=%u\n" 2299 "radiusAccServTotalUnknownTypes=%u\n", 2300 idx, 2301 abuf, mbuf, 2302 cli->counters.access_requests, 2303 cli->counters.dup_access_requests, 2304 cli->counters.access_accepts, 2305 cli->counters.access_rejects, 2306 cli->counters.access_challenges, 2307 cli->counters.malformed_access_requests, 2308 cli->counters.bad_authenticators, 2309 cli->counters.packets_dropped, 2310 cli->counters.unknown_types, 2311 cli->counters.acct_requests, 2312 cli->counters.invalid_acct_requests, 2313 cli->counters.acct_responses, 2314 cli->counters.malformed_acct_requests, 2315 cli->counters.acct_bad_authenticators, 2316 cli->counters.unknown_acct_types); 2317 if (os_snprintf_error(end - pos, ret)) { 2318 *pos = '\0'; 2319 return pos - buf; 2320 } 2321 pos += ret; 2322 } 2323 2324 return pos - buf; 2325 } 2326 2327 2328 static int radius_server_get_eap_user(void *ctx, const u8 *identity, 2329 size_t identity_len, int phase2, 2330 struct eap_user *user) 2331 { 2332 struct radius_session *sess = ctx; 2333 struct radius_server_data *data = sess->server; 2334 int ret; 2335 2336 ret = data->get_eap_user(data->conf_ctx, identity, identity_len, 2337 phase2, user); 2338 if (ret == 0 && user) { 2339 sess->accept_attr = user->accept_attr; 2340 sess->macacl = user->macacl; 2341 sess->t_c_timestamp = user->t_c_timestamp; 2342 } 2343 2344 if (ret) { 2345 RADIUS_DEBUG("%s: User-Name not found from user database", 2346 __func__); 2347 } 2348 2349 return ret; 2350 } 2351 2352 2353 static const char * radius_server_get_eap_req_id_text(void *ctx, size_t *len) 2354 { 2355 struct radius_session *sess = ctx; 2356 struct radius_server_data *data = sess->server; 2357 *len = data->eap_req_id_text_len; 2358 return data->eap_req_id_text; 2359 } 2360 2361 2362 static void radius_server_log_msg(void *ctx, const char *msg) 2363 { 2364 struct radius_session *sess = ctx; 2365 srv_log(sess, "EAP: %s", msg); 2366 } 2367 2368 2369 #ifdef CONFIG_ERP 2370 2371 static const char * radius_server_get_erp_domain(void *ctx) 2372 { 2373 struct radius_session *sess = ctx; 2374 struct radius_server_data *data = sess->server; 2375 2376 return data->erp_domain; 2377 } 2378 2379 2380 static struct eap_server_erp_key * 2381 radius_server_erp_get_key(void *ctx, const char *keyname) 2382 { 2383 struct radius_session *sess = ctx; 2384 struct radius_server_data *data = sess->server; 2385 2386 return radius_server_erp_find_key(data, keyname); 2387 } 2388 2389 2390 static int radius_server_erp_add_key(void *ctx, struct eap_server_erp_key *erp) 2391 { 2392 struct radius_session *sess = ctx; 2393 struct radius_server_data *data = sess->server; 2394 2395 dl_list_add(&data->erp_keys, &erp->list); 2396 return 0; 2397 } 2398 2399 #endif /* CONFIG_ERP */ 2400 2401 2402 static const struct eapol_callbacks radius_server_eapol_cb = 2403 { 2404 .get_eap_user = radius_server_get_eap_user, 2405 .get_eap_req_id_text = radius_server_get_eap_req_id_text, 2406 .log_msg = radius_server_log_msg, 2407 #ifdef CONFIG_ERP 2408 .get_erp_send_reauth_start = NULL, 2409 .get_erp_domain = radius_server_get_erp_domain, 2410 .erp_get_key = radius_server_erp_get_key, 2411 .erp_add_key = radius_server_erp_add_key, 2412 #endif /* CONFIG_ERP */ 2413 }; 2414 2415 2416 /** 2417 * radius_server_eap_pending_cb - Pending EAP data notification 2418 * @data: RADIUS server context from radius_server_init() 2419 * @ctx: Pending EAP context pointer 2420 * 2421 * This function is used to notify EAP server module that a pending operation 2422 * has been completed and processing of the EAP session can proceed. 2423 */ 2424 void radius_server_eap_pending_cb(struct radius_server_data *data, void *ctx) 2425 { 2426 struct radius_client *cli; 2427 struct radius_session *s, *sess = NULL; 2428 struct radius_msg *msg; 2429 2430 if (data == NULL) 2431 return; 2432 2433 for (cli = data->clients; cli; cli = cli->next) { 2434 for (s = cli->sessions; s; s = s->next) { 2435 if (s->eap == ctx && s->last_msg) { 2436 sess = s; 2437 break; 2438 } 2439 } 2440 if (sess) 2441 break; 2442 } 2443 2444 if (sess == NULL) { 2445 RADIUS_DEBUG("No session matched callback ctx"); 2446 return; 2447 } 2448 2449 msg = sess->last_msg; 2450 sess->last_msg = NULL; 2451 eap_sm_pending_cb(sess->eap); 2452 if (radius_server_request(data, msg, 2453 (struct sockaddr *) &sess->last_from, 2454 sess->last_fromlen, cli, 2455 sess->last_from_addr, 2456 sess->last_from_port, sess) == -2) 2457 return; /* msg was stored with the session */ 2458 2459 radius_msg_free(msg); 2460 } 2461 2462 2463 #ifdef CONFIG_SQLITE 2464 2465 struct db_session_fields { 2466 char *identity; 2467 char *nas; 2468 int hs20_t_c_filtering; 2469 int waiting_coa_ack; 2470 int coa_ack_received; 2471 }; 2472 2473 2474 static int get_db_session_fields(void *ctx, int argc, char *argv[], char *col[]) 2475 { 2476 struct db_session_fields *fields = ctx; 2477 int i; 2478 2479 for (i = 0; i < argc; i++) { 2480 if (!argv[i]) 2481 continue; 2482 2483 RADIUS_DEBUG("Session DB: %s=%s", col[i], argv[i]); 2484 2485 if (os_strcmp(col[i], "identity") == 0) { 2486 os_free(fields->identity); 2487 fields->identity = os_strdup(argv[i]); 2488 } else if (os_strcmp(col[i], "nas") == 0) { 2489 os_free(fields->nas); 2490 fields->nas = os_strdup(argv[i]); 2491 } else if (os_strcmp(col[i], "hs20_t_c_filtering") == 0) { 2492 fields->hs20_t_c_filtering = atoi(argv[i]); 2493 } else if (os_strcmp(col[i], "waiting_coa_ack") == 0) { 2494 fields->waiting_coa_ack = atoi(argv[i]); 2495 } else if (os_strcmp(col[i], "coa_ack_received") == 0) { 2496 fields->coa_ack_received = atoi(argv[i]); 2497 } 2498 } 2499 2500 return 0; 2501 } 2502 2503 2504 static void free_db_session_fields(struct db_session_fields *fields) 2505 { 2506 os_free(fields->identity); 2507 fields->identity = NULL; 2508 os_free(fields->nas); 2509 fields->nas = NULL; 2510 } 2511 2512 #endif /* CONFIG_SQLITE */ 2513 2514 2515 int radius_server_dac_request(struct radius_server_data *data, const char *req) 2516 { 2517 #ifdef CONFIG_SQLITE 2518 char *sql; 2519 int res; 2520 int disconnect; 2521 const char *pos = req; 2522 u8 addr[ETH_ALEN]; 2523 char addrtxt[3 * ETH_ALEN]; 2524 int t_c_clear = 0; 2525 struct db_session_fields fields; 2526 struct sockaddr_in das; 2527 struct radius_client *client; 2528 struct radius_msg *msg; 2529 struct wpabuf *buf; 2530 u8 identifier; 2531 struct os_time now; 2532 2533 if (!data) 2534 return -1; 2535 2536 /* req: <disconnect|coa> <MAC Address> [t_c_clear] */ 2537 2538 if (os_strncmp(pos, "disconnect ", 11) == 0) { 2539 disconnect = 1; 2540 pos += 11; 2541 } else if (os_strncmp(req, "coa ", 4) == 0) { 2542 disconnect = 0; 2543 pos += 4; 2544 } else { 2545 return -1; 2546 } 2547 2548 if (hwaddr_aton(pos, addr)) 2549 return -1; 2550 pos = os_strchr(pos, ' '); 2551 if (pos) { 2552 if (os_strstr(pos, "t_c_clear")) 2553 t_c_clear = 1; 2554 } 2555 2556 if (!disconnect && !t_c_clear) { 2557 RADIUS_ERROR("DAC request for CoA without any authorization change"); 2558 return -1; 2559 } 2560 2561 if (!data->db) { 2562 RADIUS_ERROR("SQLite database not in use"); 2563 return -1; 2564 } 2565 2566 os_snprintf(addrtxt, sizeof(addrtxt), MACSTR, MAC2STR(addr)); 2567 2568 sql = sqlite3_mprintf("SELECT * FROM current_sessions WHERE mac_addr=%Q", 2569 addrtxt); 2570 if (!sql) 2571 return -1; 2572 2573 os_memset(&fields, 0, sizeof(fields)); 2574 res = sqlite3_exec(data->db, sql, get_db_session_fields, &fields, NULL); 2575 sqlite3_free(sql); 2576 if (res != SQLITE_OK) { 2577 RADIUS_ERROR("Failed to find matching current_sessions entry from sqlite database: %s", 2578 sqlite3_errmsg(data->db)); 2579 free_db_session_fields(&fields); 2580 return -1; 2581 } 2582 2583 if (!fields.nas) { 2584 RADIUS_ERROR("No NAS information found from current_sessions"); 2585 free_db_session_fields(&fields); 2586 return -1; 2587 } 2588 2589 os_memset(&das, 0, sizeof(das)); 2590 das.sin_family = AF_INET; 2591 das.sin_addr.s_addr = inet_addr(fields.nas); 2592 das.sin_port = htons(3799); 2593 2594 free_db_session_fields(&fields); 2595 2596 client = radius_server_get_client(data, &das.sin_addr, 0); 2597 if (!client) { 2598 RADIUS_ERROR("No NAS information available to protect the packet"); 2599 return -1; 2600 } 2601 2602 identifier = client->next_dac_identifier++; 2603 2604 msg = radius_msg_new(disconnect ? RADIUS_CODE_DISCONNECT_REQUEST : 2605 RADIUS_CODE_COA_REQUEST, identifier); 2606 if (!msg) 2607 return -1; 2608 2609 os_snprintf(addrtxt, sizeof(addrtxt), RADIUS_802_1X_ADDR_FORMAT, 2610 MAC2STR(addr)); 2611 if (!radius_msg_add_attr(msg, RADIUS_ATTR_CALLING_STATION_ID, 2612 (u8 *) addrtxt, os_strlen(addrtxt))) { 2613 RADIUS_ERROR("Could not add Calling-Station-Id"); 2614 radius_msg_free(msg); 2615 return -1; 2616 } 2617 2618 if (!disconnect && t_c_clear) { 2619 u8 val[4] = { 0x00, 0x00, 0x00, 0x00 }; /* E=0 */ 2620 2621 if (!radius_msg_add_wfa( 2622 msg, RADIUS_VENDOR_ATTR_WFA_HS20_T_C_FILTERING, 2623 val, sizeof(val))) { 2624 RADIUS_DEBUG("Failed to add WFA-HS20-T-C-Filtering"); 2625 radius_msg_free(msg); 2626 return -1; 2627 } 2628 } 2629 2630 os_get_time(&now); 2631 if (!radius_msg_add_attr_int32(msg, RADIUS_ATTR_EVENT_TIMESTAMP, 2632 now.sec)) { 2633 RADIUS_ERROR("Failed to add Event-Timestamp attribute"); 2634 radius_msg_free(msg); 2635 return -1; 2636 } 2637 2638 if (radius_msg_finish_acct(msg, (u8 *) client->shared_secret, 2639 client->shared_secret_len) < 0) { 2640 RADIUS_ERROR("Failed to add Message-Authenticator attribute"); 2641 radius_msg_free(msg); 2642 return -1; 2643 } 2644 2645 if (wpa_debug_level <= MSG_MSGDUMP) 2646 radius_msg_dump(msg); 2647 2648 buf = radius_msg_get_buf(msg); 2649 if (sendto(data->auth_sock, wpabuf_head(buf), wpabuf_len(buf), 0, 2650 (struct sockaddr *) &das, sizeof(das)) < 0) { 2651 RADIUS_ERROR("Failed to send packet - sendto: %s", 2652 strerror(errno)); 2653 radius_msg_free(msg); 2654 return -1; 2655 } 2656 2657 if (disconnect) { 2658 radius_msg_free(client->pending_dac_disconnect_req); 2659 client->pending_dac_disconnect_req = msg; 2660 client->pending_dac_disconnect_id = identifier; 2661 os_memcpy(client->pending_dac_disconnect_addr, addr, ETH_ALEN); 2662 } else { 2663 radius_msg_free(client->pending_dac_coa_req); 2664 client->pending_dac_coa_req = msg; 2665 client->pending_dac_coa_id = identifier; 2666 os_memcpy(client->pending_dac_coa_addr, addr, ETH_ALEN); 2667 } 2668 2669 return 0; 2670 #else /* CONFIG_SQLITE */ 2671 return -1; 2672 #endif /* CONFIG_SQLITE */ 2673 } 2674