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