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 sess_id = htonl(sess->sess_id); 924 if (code == RADIUS_CODE_ACCESS_CHALLENGE && 925 !radius_msg_add_attr(msg, RADIUS_ATTR_STATE, 926 (u8 *) &sess_id, sizeof(sess_id))) { 927 RADIUS_DEBUG("Failed to add State attribute"); 928 } 929 930 if (sess->eap_if->eapReqData && 931 !radius_msg_add_eap(msg, wpabuf_head(sess->eap_if->eapReqData), 932 wpabuf_len(sess->eap_if->eapReqData))) { 933 RADIUS_DEBUG("Failed to add EAP-Message attribute"); 934 } 935 936 if (code == RADIUS_CODE_ACCESS_ACCEPT && sess->eap_if->eapKeyData) { 937 int len; 938 #ifdef CONFIG_RADIUS_TEST 939 char buf[2 * 64 + 1]; 940 941 len = sess->eap_if->eapKeyDataLen; 942 if (len > 64) 943 len = 64; 944 len = wpa_snprintf_hex(buf, sizeof(buf), 945 sess->eap_if->eapKeyData, len); 946 buf[len] = '\0'; 947 948 if (data->dump_msk_file) { 949 FILE *f; 950 951 f = fopen(data->dump_msk_file, "a"); 952 if (f) { 953 len = sess->eap_if->eapKeyDataLen; 954 if (len > 64) 955 len = 64; 956 len = wpa_snprintf_hex( 957 buf, sizeof(buf), 958 sess->eap_if->eapKeyData, len); 959 buf[len] = '\0'; 960 fprintf(f, "%s\n", buf); 961 fclose(f); 962 } 963 } 964 965 db_update_last_msk(sess, buf); 966 #endif /* CONFIG_RADIUS_TEST */ 967 if (sess->eap_if->eapKeyDataLen > 64) { 968 len = 32; 969 } else { 970 len = sess->eap_if->eapKeyDataLen / 2; 971 } 972 if (!radius_msg_add_mppe_keys(msg, hdr->authenticator, 973 (u8 *) client->shared_secret, 974 client->shared_secret_len, 975 sess->eap_if->eapKeyData + len, 976 len, sess->eap_if->eapKeyData, 977 len)) { 978 RADIUS_DEBUG("Failed to add MPPE key attributes"); 979 } 980 981 if (sess->eap_if->eapSessionId && 982 !radius_msg_add_attr(msg, RADIUS_ATTR_EAP_KEY_NAME, 983 sess->eap_if->eapSessionId, 984 sess->eap_if->eapSessionIdLen)) { 985 RADIUS_DEBUG("Failed to add EAP-Key-Name attribute"); 986 } 987 } 988 989 #ifdef CONFIG_HS20 990 if (code == RADIUS_CODE_ACCESS_ACCEPT && sess->remediation && 991 data->subscr_remediation_url) { 992 u8 *buf; 993 size_t url_len = os_strlen(data->subscr_remediation_url); 994 buf = os_malloc(1 + url_len); 995 if (buf == NULL) { 996 radius_msg_free(msg); 997 return NULL; 998 } 999 buf[0] = data->subscr_remediation_method; 1000 os_memcpy(&buf[1], data->subscr_remediation_url, url_len); 1001 if (!radius_msg_add_wfa( 1002 msg, RADIUS_VENDOR_ATTR_WFA_HS20_SUBSCR_REMEDIATION, 1003 buf, 1 + url_len)) { 1004 RADIUS_DEBUG("Failed to add WFA-HS20-SubscrRem"); 1005 } 1006 os_free(buf); 1007 } else if (code == RADIUS_CODE_ACCESS_ACCEPT && sess->remediation) { 1008 u8 buf[1]; 1009 if (!radius_msg_add_wfa( 1010 msg, RADIUS_VENDOR_ATTR_WFA_HS20_SUBSCR_REMEDIATION, 1011 buf, 0)) { 1012 RADIUS_DEBUG("Failed to add WFA-HS20-SubscrRem"); 1013 } 1014 } else if (code == RADIUS_CODE_ACCESS_ACCEPT && 1015 data->hs20_sim_provisioning_url && 1016 radius_server_is_sim_method(sess) && 1017 radius_server_hs20_missing_sim_pps(request)) { 1018 u8 *buf, *pos, hash[HS20_MOBILE_ID_HASH_LEN]; 1019 size_t prefix_len, url_len; 1020 1021 RADIUS_DEBUG("Device needs HS 2.0 SIM provisioning"); 1022 1023 if (os_get_random(hash, HS20_MOBILE_ID_HASH_LEN) < 0) { 1024 radius_msg_free(msg); 1025 return NULL; 1026 } 1027 RADIUS_DUMP("hotspot2dot0-mobile-identifier-hash", 1028 hash, HS20_MOBILE_ID_HASH_LEN); 1029 1030 if (radius_server_sim_provisioning_session(sess, hash) < 0) { 1031 radius_msg_free(msg); 1032 return NULL; 1033 } 1034 1035 prefix_len = os_strlen(data->hs20_sim_provisioning_url); 1036 url_len = prefix_len + 2 * HS20_MOBILE_ID_HASH_LEN; 1037 buf = os_malloc(1 + url_len + 1); 1038 if (!buf) { 1039 radius_msg_free(msg); 1040 return NULL; 1041 } 1042 pos = buf; 1043 *pos++ = data->subscr_remediation_method; 1044 os_memcpy(pos, data->hs20_sim_provisioning_url, prefix_len); 1045 pos += prefix_len; 1046 wpa_snprintf_hex((char *) pos, 2 * HS20_MOBILE_ID_HASH_LEN + 1, 1047 hash, HS20_MOBILE_ID_HASH_LEN); 1048 RADIUS_DEBUG("HS 2.0 subscription remediation URL: %s", 1049 (char *) &buf[1]); 1050 if (!radius_msg_add_wfa( 1051 msg, RADIUS_VENDOR_ATTR_WFA_HS20_SUBSCR_REMEDIATION, 1052 buf, 1 + url_len)) { 1053 RADIUS_DEBUG("Failed to add WFA-HS20-SubscrRem"); 1054 } 1055 os_free(buf); 1056 } 1057 1058 if (code == RADIUS_CODE_ACCESS_ACCEPT && sess->t_c_filtering) { 1059 u8 buf[4] = { 0x01, 0x00, 0x00, 0x00 }; /* E=1 */ 1060 const char *url = data->t_c_server_url, *pos; 1061 char *url2, *end2, *pos2; 1062 size_t url_len; 1063 1064 if (!radius_msg_add_wfa( 1065 msg, RADIUS_VENDOR_ATTR_WFA_HS20_T_C_FILTERING, 1066 buf, sizeof(buf))) { 1067 RADIUS_DEBUG("Failed to add WFA-HS20-T-C-Filtering"); 1068 radius_msg_free(msg); 1069 return NULL; 1070 } 1071 1072 if (!url) { 1073 RADIUS_DEBUG("No t_c_server_url configured"); 1074 radius_msg_free(msg); 1075 return NULL; 1076 } 1077 1078 pos = os_strstr(url, "@1@"); 1079 if (!pos) { 1080 RADIUS_DEBUG("No @1@ macro in t_c_server_url"); 1081 radius_msg_free(msg); 1082 return NULL; 1083 } 1084 1085 url_len = os_strlen(url) + ETH_ALEN * 3 - 1 - 3; 1086 url2 = os_malloc(url_len + 1); 1087 if (!url2) { 1088 RADIUS_DEBUG("Failed to allocate room for T&C Server URL"); 1089 os_free(url2); 1090 radius_msg_free(msg); 1091 return NULL; 1092 } 1093 pos2 = url2; 1094 end2 = url2 + url_len + 1; 1095 os_memcpy(pos2, url, pos - url); 1096 pos2 += pos - url; 1097 os_snprintf(pos2, end2 - pos2, MACSTR, MAC2STR(sess->mac_addr)); 1098 pos2 += ETH_ALEN * 3 - 1; 1099 os_memcpy(pos2, pos + 3, os_strlen(pos + 3)); 1100 if (!radius_msg_add_wfa(msg, 1101 RADIUS_VENDOR_ATTR_WFA_HS20_T_C_URL, 1102 (const u8 *) url2, url_len)) { 1103 RADIUS_DEBUG("Failed to add WFA-HS20-T-C-URL"); 1104 os_free(url2); 1105 radius_msg_free(msg); 1106 return NULL; 1107 } 1108 os_free(url2); 1109 1110 radius_srv_hs20_t_c_pending(sess); 1111 } 1112 #endif /* CONFIG_HS20 */ 1113 1114 if (radius_msg_copy_attr(msg, request, RADIUS_ATTR_PROXY_STATE) < 0) { 1115 RADIUS_DEBUG("Failed to copy Proxy-State attribute(s)"); 1116 radius_msg_free(msg); 1117 return NULL; 1118 } 1119 1120 if (code == RADIUS_CODE_ACCESS_ACCEPT) { 1121 struct hostapd_radius_attr *attr; 1122 for (attr = sess->accept_attr; attr; attr = attr->next) { 1123 if (!radius_msg_add_attr(msg, attr->type, 1124 wpabuf_head(attr->val), 1125 wpabuf_len(attr->val))) { 1126 wpa_printf(MSG_ERROR, "Could not add RADIUS attribute"); 1127 radius_msg_free(msg); 1128 return NULL; 1129 } 1130 } 1131 } 1132 1133 if (code == RADIUS_CODE_ACCESS_REJECT) { 1134 if (radius_msg_add_attr_int32(msg, RADIUS_ATTR_WLAN_REASON_CODE, 1135 reason) < 0) { 1136 RADIUS_DEBUG("Failed to add WLAN-Reason-Code attribute"); 1137 radius_msg_free(msg); 1138 return NULL; 1139 } 1140 } 1141 1142 if (radius_msg_finish_srv(msg, (u8 *) client->shared_secret, 1143 client->shared_secret_len, 1144 hdr->authenticator) < 0) { 1145 RADIUS_DEBUG("Failed to add Message-Authenticator attribute"); 1146 } 1147 1148 if (code == RADIUS_CODE_ACCESS_ACCEPT) 1149 radius_server_add_session(sess); 1150 1151 return msg; 1152 } 1153 1154 1155 static struct radius_msg * 1156 radius_server_macacl(struct radius_server_data *data, 1157 struct radius_client *client, 1158 struct radius_session *sess, 1159 struct radius_msg *request) 1160 { 1161 struct radius_msg *msg; 1162 int code; 1163 struct radius_hdr *hdr = radius_msg_get_hdr(request); 1164 u8 *pw; 1165 size_t pw_len; 1166 1167 code = RADIUS_CODE_ACCESS_ACCEPT; 1168 1169 if (radius_msg_get_attr_ptr(request, RADIUS_ATTR_USER_PASSWORD, &pw, 1170 &pw_len, NULL) < 0) { 1171 RADIUS_DEBUG("Could not get User-Password"); 1172 code = RADIUS_CODE_ACCESS_REJECT; 1173 } else { 1174 int res; 1175 struct eap_user tmp; 1176 1177 os_memset(&tmp, 0, sizeof(tmp)); 1178 res = data->get_eap_user(data->conf_ctx, (u8 *) sess->username, 1179 os_strlen(sess->username), 0, &tmp); 1180 if (res || !tmp.macacl || tmp.password == NULL) { 1181 RADIUS_DEBUG("No MAC ACL user entry"); 1182 bin_clear_free(tmp.password, tmp.password_len); 1183 code = RADIUS_CODE_ACCESS_REJECT; 1184 } else { 1185 u8 buf[128]; 1186 res = radius_user_password_hide( 1187 request, tmp.password, tmp.password_len, 1188 (u8 *) client->shared_secret, 1189 client->shared_secret_len, 1190 buf, sizeof(buf)); 1191 bin_clear_free(tmp.password, tmp.password_len); 1192 1193 if (res < 0 || pw_len != (size_t) res || 1194 os_memcmp_const(pw, buf, res) != 0) { 1195 RADIUS_DEBUG("Incorrect User-Password"); 1196 code = RADIUS_CODE_ACCESS_REJECT; 1197 } 1198 } 1199 } 1200 1201 msg = radius_msg_new(code, hdr->identifier); 1202 if (msg == NULL) { 1203 RADIUS_DEBUG("Failed to allocate reply message"); 1204 return NULL; 1205 } 1206 1207 if (radius_msg_copy_attr(msg, request, RADIUS_ATTR_PROXY_STATE) < 0) { 1208 RADIUS_DEBUG("Failed to copy Proxy-State attribute(s)"); 1209 radius_msg_free(msg); 1210 return NULL; 1211 } 1212 1213 if (code == RADIUS_CODE_ACCESS_ACCEPT) { 1214 struct hostapd_radius_attr *attr; 1215 for (attr = sess->accept_attr; attr; attr = attr->next) { 1216 if (!radius_msg_add_attr(msg, attr->type, 1217 wpabuf_head(attr->val), 1218 wpabuf_len(attr->val))) { 1219 wpa_printf(MSG_ERROR, "Could not add RADIUS attribute"); 1220 radius_msg_free(msg); 1221 return NULL; 1222 } 1223 } 1224 } 1225 1226 if (radius_msg_finish_srv(msg, (u8 *) client->shared_secret, 1227 client->shared_secret_len, 1228 hdr->authenticator) < 0) { 1229 RADIUS_DEBUG("Failed to add Message-Authenticator attribute"); 1230 } 1231 1232 return msg; 1233 } 1234 1235 1236 static int radius_server_reject(struct radius_server_data *data, 1237 struct radius_client *client, 1238 struct radius_msg *request, 1239 struct sockaddr *from, socklen_t fromlen, 1240 const char *from_addr, int from_port) 1241 { 1242 struct radius_msg *msg; 1243 int ret = 0; 1244 struct eap_hdr eapfail; 1245 struct wpabuf *buf; 1246 struct radius_hdr *hdr = radius_msg_get_hdr(request); 1247 1248 RADIUS_DEBUG("Reject invalid request from %s:%d", 1249 from_addr, from_port); 1250 1251 msg = radius_msg_new(RADIUS_CODE_ACCESS_REJECT, hdr->identifier); 1252 if (msg == NULL) { 1253 return -1; 1254 } 1255 1256 os_memset(&eapfail, 0, sizeof(eapfail)); 1257 eapfail.code = EAP_CODE_FAILURE; 1258 eapfail.identifier = 0; 1259 eapfail.length = host_to_be16(sizeof(eapfail)); 1260 1261 if (!radius_msg_add_eap(msg, (u8 *) &eapfail, sizeof(eapfail))) { 1262 RADIUS_DEBUG("Failed to add EAP-Message attribute"); 1263 } 1264 1265 if (radius_msg_copy_attr(msg, request, RADIUS_ATTR_PROXY_STATE) < 0) { 1266 RADIUS_DEBUG("Failed to copy Proxy-State attribute(s)"); 1267 radius_msg_free(msg); 1268 return -1; 1269 } 1270 1271 if (radius_msg_finish_srv(msg, (u8 *) client->shared_secret, 1272 client->shared_secret_len, 1273 hdr->authenticator) < 1274 0) { 1275 RADIUS_DEBUG("Failed to add Message-Authenticator attribute"); 1276 } 1277 1278 if (wpa_debug_level <= MSG_MSGDUMP) { 1279 radius_msg_dump(msg); 1280 } 1281 1282 data->counters.access_rejects++; 1283 client->counters.access_rejects++; 1284 buf = radius_msg_get_buf(msg); 1285 if (sendto(data->auth_sock, wpabuf_head(buf), wpabuf_len(buf), 0, 1286 (struct sockaddr *) from, sizeof(*from)) < 0) { 1287 wpa_printf(MSG_INFO, "sendto[RADIUS SRV]: %s", strerror(errno)); 1288 ret = -1; 1289 } 1290 1291 radius_msg_free(msg); 1292 1293 return ret; 1294 } 1295 1296 1297 static void radius_server_hs20_t_c_check(struct radius_session *sess, 1298 struct radius_msg *msg) 1299 { 1300 #ifdef CONFIG_HS20 1301 u8 *buf, *pos, *end, type, sublen, *timestamp = NULL; 1302 size_t len; 1303 1304 buf = NULL; 1305 for (;;) { 1306 if (radius_msg_get_attr_ptr(msg, RADIUS_ATTR_VENDOR_SPECIFIC, 1307 &buf, &len, buf) < 0) 1308 break; 1309 if (len < 6) 1310 continue; 1311 pos = buf; 1312 end = buf + len; 1313 if (WPA_GET_BE32(pos) != RADIUS_VENDOR_ID_WFA) 1314 continue; 1315 pos += 4; 1316 1317 type = *pos++; 1318 sublen = *pos++; 1319 if (sublen < 2) 1320 continue; /* invalid length */ 1321 sublen -= 2; /* skip header */ 1322 if (pos + sublen > end) 1323 continue; /* invalid WFA VSA */ 1324 1325 if (type == RADIUS_VENDOR_ATTR_WFA_HS20_TIMESTAMP && len >= 4) { 1326 timestamp = pos; 1327 break; 1328 } 1329 } 1330 1331 if (!timestamp) 1332 return; 1333 RADIUS_DEBUG("HS20-Timestamp: %u", WPA_GET_BE32(timestamp)); 1334 if (sess->t_c_timestamp != WPA_GET_BE32(timestamp)) { 1335 RADIUS_DEBUG("Last read T&C timestamp does not match HS20-Timestamp --> require filtering"); 1336 sess->t_c_filtering = 1; 1337 } 1338 #endif /* CONFIG_HS20 */ 1339 } 1340 1341 1342 static int radius_server_request(struct radius_server_data *data, 1343 struct radius_msg *msg, 1344 struct sockaddr *from, socklen_t fromlen, 1345 struct radius_client *client, 1346 const char *from_addr, int from_port, 1347 struct radius_session *force_sess) 1348 { 1349 struct wpabuf *eap = NULL; 1350 int res, state_included = 0; 1351 u8 statebuf[4]; 1352 unsigned int state; 1353 struct radius_session *sess; 1354 struct radius_msg *reply; 1355 int is_complete = 0; 1356 1357 if (force_sess) 1358 sess = force_sess; 1359 else { 1360 res = radius_msg_get_attr(msg, RADIUS_ATTR_STATE, statebuf, 1361 sizeof(statebuf)); 1362 state_included = res >= 0; 1363 if (res == sizeof(statebuf)) { 1364 state = WPA_GET_BE32(statebuf); 1365 sess = radius_server_get_session(client, state); 1366 } else { 1367 sess = NULL; 1368 } 1369 } 1370 1371 if (sess) { 1372 RADIUS_DEBUG("Request for session 0x%x", sess->sess_id); 1373 } else if (state_included) { 1374 RADIUS_DEBUG("State attribute included but no session found"); 1375 radius_server_reject(data, client, msg, from, fromlen, 1376 from_addr, from_port); 1377 return -1; 1378 } else { 1379 sess = radius_server_get_new_session(data, client, msg, 1380 from_addr); 1381 if (sess == NULL) { 1382 RADIUS_DEBUG("Could not create a new session"); 1383 radius_server_reject(data, client, msg, from, fromlen, 1384 from_addr, from_port); 1385 return -1; 1386 } 1387 } 1388 1389 if (sess->last_from_port == from_port && 1390 sess->last_identifier == radius_msg_get_hdr(msg)->identifier && 1391 os_memcmp(sess->last_authenticator, 1392 radius_msg_get_hdr(msg)->authenticator, 16) == 0) { 1393 RADIUS_DEBUG("Duplicate message from %s", from_addr); 1394 data->counters.dup_access_requests++; 1395 client->counters.dup_access_requests++; 1396 1397 if (sess->last_reply) { 1398 struct wpabuf *buf; 1399 buf = radius_msg_get_buf(sess->last_reply); 1400 res = sendto(data->auth_sock, wpabuf_head(buf), 1401 wpabuf_len(buf), 0, 1402 (struct sockaddr *) from, fromlen); 1403 if (res < 0) { 1404 wpa_printf(MSG_INFO, "sendto[RADIUS SRV]: %s", 1405 strerror(errno)); 1406 } 1407 return 0; 1408 } 1409 1410 RADIUS_DEBUG("No previous reply available for duplicate " 1411 "message"); 1412 return -1; 1413 } 1414 1415 eap = radius_msg_get_eap(msg); 1416 if (eap == NULL && sess->macacl) { 1417 reply = radius_server_macacl(data, client, sess, msg); 1418 if (reply == NULL) 1419 return -1; 1420 goto send_reply; 1421 } 1422 if (eap == NULL) { 1423 RADIUS_DEBUG("No EAP-Message in RADIUS packet from %s", 1424 from_addr); 1425 data->counters.packets_dropped++; 1426 client->counters.packets_dropped++; 1427 return -1; 1428 } 1429 1430 RADIUS_DUMP("Received EAP data", wpabuf_head(eap), wpabuf_len(eap)); 1431 1432 /* FIX: if Code is Request, Success, or Failure, send Access-Reject; 1433 * RFC3579 Sect. 2.6.2. 1434 * Include EAP-Response/Nak with no preferred method if 1435 * code == request. 1436 * If code is not 1-4, discard the packet silently. 1437 * Or is this already done by the EAP state machine? */ 1438 1439 wpabuf_free(sess->eap_if->eapRespData); 1440 sess->eap_if->eapRespData = eap; 1441 sess->eap_if->eapResp = true; 1442 eap_server_sm_step(sess->eap); 1443 1444 if ((sess->eap_if->eapReq || sess->eap_if->eapSuccess || 1445 sess->eap_if->eapFail) && sess->eap_if->eapReqData) { 1446 RADIUS_DUMP("EAP data from the state machine", 1447 wpabuf_head(sess->eap_if->eapReqData), 1448 wpabuf_len(sess->eap_if->eapReqData)); 1449 } else if (sess->eap_if->eapFail) { 1450 RADIUS_DEBUG("No EAP data from the state machine, but eapFail " 1451 "set"); 1452 } else if (eap_sm_method_pending(sess->eap)) { 1453 radius_msg_free(sess->last_msg); 1454 sess->last_msg = msg; 1455 sess->last_from_port = from_port; 1456 os_free(sess->last_from_addr); 1457 sess->last_from_addr = os_strdup(from_addr); 1458 sess->last_fromlen = fromlen; 1459 os_memcpy(&sess->last_from, from, fromlen); 1460 return -2; 1461 } else { 1462 RADIUS_DEBUG("No EAP data from the state machine - ignore this" 1463 " Access-Request silently (assuming it was a " 1464 "duplicate)"); 1465 data->counters.packets_dropped++; 1466 client->counters.packets_dropped++; 1467 return -1; 1468 } 1469 1470 if (sess->eap_if->eapSuccess || sess->eap_if->eapFail) 1471 is_complete = 1; 1472 if (sess->eap_if->eapFail) { 1473 srv_log(sess, "EAP authentication failed"); 1474 db_update_last_msk(sess, "FAIL"); 1475 } else if (sess->eap_if->eapSuccess) { 1476 srv_log(sess, "EAP authentication succeeded"); 1477 } 1478 1479 if (sess->eap_if->eapSuccess) 1480 radius_server_hs20_t_c_check(sess, msg); 1481 1482 reply = radius_server_encapsulate_eap(data, client, sess, msg); 1483 1484 send_reply: 1485 if (reply) { 1486 struct wpabuf *buf; 1487 struct radius_hdr *hdr; 1488 1489 RADIUS_DEBUG("Reply to %s:%d", from_addr, from_port); 1490 if (wpa_debug_level <= MSG_MSGDUMP) { 1491 radius_msg_dump(reply); 1492 } 1493 1494 switch (radius_msg_get_hdr(reply)->code) { 1495 case RADIUS_CODE_ACCESS_ACCEPT: 1496 srv_log(sess, "Sending Access-Accept"); 1497 data->counters.access_accepts++; 1498 client->counters.access_accepts++; 1499 break; 1500 case RADIUS_CODE_ACCESS_REJECT: 1501 srv_log(sess, "Sending Access-Reject"); 1502 data->counters.access_rejects++; 1503 client->counters.access_rejects++; 1504 break; 1505 case RADIUS_CODE_ACCESS_CHALLENGE: 1506 data->counters.access_challenges++; 1507 client->counters.access_challenges++; 1508 break; 1509 } 1510 buf = radius_msg_get_buf(reply); 1511 res = sendto(data->auth_sock, wpabuf_head(buf), 1512 wpabuf_len(buf), 0, 1513 (struct sockaddr *) from, fromlen); 1514 if (res < 0) { 1515 wpa_printf(MSG_INFO, "sendto[RADIUS SRV]: %s", 1516 strerror(errno)); 1517 } 1518 radius_msg_free(sess->last_reply); 1519 sess->last_reply = reply; 1520 sess->last_from_port = from_port; 1521 hdr = radius_msg_get_hdr(msg); 1522 sess->last_identifier = hdr->identifier; 1523 os_memcpy(sess->last_authenticator, hdr->authenticator, 16); 1524 } else { 1525 data->counters.packets_dropped++; 1526 client->counters.packets_dropped++; 1527 } 1528 1529 if (is_complete) { 1530 RADIUS_DEBUG("Removing completed session 0x%x after timeout", 1531 sess->sess_id); 1532 eloop_cancel_timeout(radius_server_session_remove_timeout, 1533 data, sess); 1534 eloop_register_timeout(RADIUS_SESSION_MAINTAIN, 0, 1535 radius_server_session_remove_timeout, 1536 data, sess); 1537 } 1538 1539 return 0; 1540 } 1541 1542 1543 static void 1544 radius_server_receive_disconnect_resp(struct radius_server_data *data, 1545 struct radius_client *client, 1546 struct radius_msg *msg, int ack) 1547 { 1548 struct radius_hdr *hdr; 1549 1550 if (!client->pending_dac_disconnect_req) { 1551 RADIUS_DEBUG("Ignore unexpected Disconnect response"); 1552 radius_msg_free(msg); 1553 return; 1554 } 1555 1556 hdr = radius_msg_get_hdr(msg); 1557 if (hdr->identifier != client->pending_dac_disconnect_id) { 1558 RADIUS_DEBUG("Ignore unexpected Disconnect response with unexpected identifier %u (expected %u)", 1559 hdr->identifier, 1560 client->pending_dac_disconnect_id); 1561 radius_msg_free(msg); 1562 return; 1563 } 1564 1565 if (radius_msg_verify(msg, (const u8 *) client->shared_secret, 1566 client->shared_secret_len, 1567 client->pending_dac_disconnect_req, 0)) { 1568 RADIUS_DEBUG("Ignore Disconnect response with invalid authenticator"); 1569 radius_msg_free(msg); 1570 return; 1571 } 1572 1573 RADIUS_DEBUG("Disconnect-%s received for " MACSTR, 1574 ack ? "ACK" : "NAK", 1575 MAC2STR(client->pending_dac_disconnect_addr)); 1576 1577 radius_msg_free(msg); 1578 radius_msg_free(client->pending_dac_disconnect_req); 1579 client->pending_dac_disconnect_req = NULL; 1580 } 1581 1582 1583 static void radius_server_receive_coa_resp(struct radius_server_data *data, 1584 struct radius_client *client, 1585 struct radius_msg *msg, int ack) 1586 { 1587 struct radius_hdr *hdr; 1588 #ifdef CONFIG_SQLITE 1589 char addrtxt[3 * ETH_ALEN]; 1590 char *sql; 1591 int res; 1592 #endif /* CONFIG_SQLITE */ 1593 1594 if (!client->pending_dac_coa_req) { 1595 RADIUS_DEBUG("Ignore unexpected CoA response"); 1596 radius_msg_free(msg); 1597 return; 1598 } 1599 1600 hdr = radius_msg_get_hdr(msg); 1601 if (hdr->identifier != client->pending_dac_coa_id) { 1602 RADIUS_DEBUG("Ignore unexpected CoA response with unexpected identifier %u (expected %u)", 1603 hdr->identifier, 1604 client->pending_dac_coa_id); 1605 radius_msg_free(msg); 1606 return; 1607 } 1608 1609 if (radius_msg_verify(msg, (const u8 *) client->shared_secret, 1610 client->shared_secret_len, 1611 client->pending_dac_coa_req, 0)) { 1612 RADIUS_DEBUG("Ignore CoA response with invalid authenticator"); 1613 radius_msg_free(msg); 1614 return; 1615 } 1616 1617 RADIUS_DEBUG("CoA-%s received for " MACSTR, 1618 ack ? "ACK" : "NAK", 1619 MAC2STR(client->pending_dac_coa_addr)); 1620 1621 radius_msg_free(msg); 1622 radius_msg_free(client->pending_dac_coa_req); 1623 client->pending_dac_coa_req = NULL; 1624 1625 #ifdef CONFIG_SQLITE 1626 if (!data->db) 1627 return; 1628 1629 os_snprintf(addrtxt, sizeof(addrtxt), MACSTR, 1630 MAC2STR(client->pending_dac_coa_addr)); 1631 1632 if (ack) { 1633 sql = sqlite3_mprintf("UPDATE current_sessions SET hs20_t_c_filtering=0, waiting_coa_ack=0, coa_ack_received=1 WHERE mac_addr=%Q", 1634 addrtxt); 1635 } else { 1636 sql = sqlite3_mprintf("UPDATE current_sessions SET waiting_coa_ack=0 WHERE mac_addr=%Q", 1637 addrtxt); 1638 } 1639 if (!sql) 1640 return; 1641 1642 res = sqlite3_exec(data->db, sql, NULL, NULL, NULL); 1643 sqlite3_free(sql); 1644 if (res != SQLITE_OK) { 1645 RADIUS_ERROR("Failed to update current_sessions entry: %s", 1646 sqlite3_errmsg(data->db)); 1647 return; 1648 } 1649 #endif /* CONFIG_SQLITE */ 1650 } 1651 1652 1653 static void radius_server_receive_auth(int sock, void *eloop_ctx, 1654 void *sock_ctx) 1655 { 1656 struct radius_server_data *data = eloop_ctx; 1657 u8 *buf = NULL; 1658 union { 1659 struct sockaddr_storage ss; 1660 struct sockaddr_in sin; 1661 #ifdef CONFIG_IPV6 1662 struct sockaddr_in6 sin6; 1663 #endif /* CONFIG_IPV6 */ 1664 } from; 1665 socklen_t fromlen; 1666 int len; 1667 struct radius_client *client = NULL; 1668 struct radius_msg *msg = NULL; 1669 char abuf[50]; 1670 int from_port = 0; 1671 1672 buf = os_malloc(RADIUS_MAX_MSG_LEN); 1673 if (buf == NULL) { 1674 goto fail; 1675 } 1676 1677 fromlen = sizeof(from); 1678 len = recvfrom(sock, buf, RADIUS_MAX_MSG_LEN, 0, 1679 (struct sockaddr *) &from.ss, &fromlen); 1680 if (len < 0) { 1681 wpa_printf(MSG_INFO, "recvfrom[radius_server]: %s", 1682 strerror(errno)); 1683 goto fail; 1684 } 1685 1686 #ifdef CONFIG_IPV6 1687 if (data->ipv6) { 1688 if (inet_ntop(AF_INET6, &from.sin6.sin6_addr, abuf, 1689 sizeof(abuf)) == NULL) 1690 abuf[0] = '\0'; 1691 from_port = ntohs(from.sin6.sin6_port); 1692 RADIUS_DEBUG("Received %d bytes from %s:%d", 1693 len, abuf, from_port); 1694 1695 client = radius_server_get_client(data, 1696 (struct in_addr *) 1697 &from.sin6.sin6_addr, 1); 1698 } 1699 #endif /* CONFIG_IPV6 */ 1700 1701 if (!data->ipv6) { 1702 os_strlcpy(abuf, inet_ntoa(from.sin.sin_addr), sizeof(abuf)); 1703 from_port = ntohs(from.sin.sin_port); 1704 RADIUS_DEBUG("Received %d bytes from %s:%d", 1705 len, abuf, from_port); 1706 1707 client = radius_server_get_client(data, &from.sin.sin_addr, 0); 1708 } 1709 1710 RADIUS_DUMP("Received data", buf, len); 1711 1712 if (client == NULL) { 1713 RADIUS_DEBUG("Unknown client %s - packet ignored", abuf); 1714 data->counters.invalid_requests++; 1715 goto fail; 1716 } 1717 1718 msg = radius_msg_parse(buf, len); 1719 if (msg == NULL) { 1720 RADIUS_DEBUG("Parsing incoming RADIUS frame failed"); 1721 data->counters.malformed_access_requests++; 1722 client->counters.malformed_access_requests++; 1723 goto fail; 1724 } 1725 1726 os_free(buf); 1727 buf = NULL; 1728 1729 if (wpa_debug_level <= MSG_MSGDUMP) { 1730 radius_msg_dump(msg); 1731 } 1732 1733 if (radius_msg_get_hdr(msg)->code == RADIUS_CODE_DISCONNECT_ACK) { 1734 radius_server_receive_disconnect_resp(data, client, msg, 1); 1735 return; 1736 } 1737 1738 if (radius_msg_get_hdr(msg)->code == RADIUS_CODE_DISCONNECT_NAK) { 1739 radius_server_receive_disconnect_resp(data, client, msg, 0); 1740 return; 1741 } 1742 1743 if (radius_msg_get_hdr(msg)->code == RADIUS_CODE_COA_ACK) { 1744 radius_server_receive_coa_resp(data, client, msg, 1); 1745 return; 1746 } 1747 1748 if (radius_msg_get_hdr(msg)->code == RADIUS_CODE_COA_NAK) { 1749 radius_server_receive_coa_resp(data, client, msg, 0); 1750 return; 1751 } 1752 1753 if (radius_msg_get_hdr(msg)->code != RADIUS_CODE_ACCESS_REQUEST) { 1754 RADIUS_DEBUG("Unexpected RADIUS code %d", 1755 radius_msg_get_hdr(msg)->code); 1756 data->counters.unknown_types++; 1757 client->counters.unknown_types++; 1758 goto fail; 1759 } 1760 1761 data->counters.access_requests++; 1762 client->counters.access_requests++; 1763 1764 if (radius_msg_verify_msg_auth(msg, (u8 *) client->shared_secret, 1765 client->shared_secret_len, NULL)) { 1766 RADIUS_DEBUG("Invalid Message-Authenticator from %s", abuf); 1767 data->counters.bad_authenticators++; 1768 client->counters.bad_authenticators++; 1769 goto fail; 1770 } 1771 1772 if (radius_server_request(data, msg, (struct sockaddr *) &from, 1773 fromlen, client, abuf, from_port, NULL) == 1774 -2) 1775 return; /* msg was stored with the session */ 1776 1777 fail: 1778 radius_msg_free(msg); 1779 os_free(buf); 1780 } 1781 1782 1783 static void radius_server_receive_acct(int sock, void *eloop_ctx, 1784 void *sock_ctx) 1785 { 1786 struct radius_server_data *data = eloop_ctx; 1787 u8 *buf = NULL; 1788 union { 1789 struct sockaddr_storage ss; 1790 struct sockaddr_in sin; 1791 #ifdef CONFIG_IPV6 1792 struct sockaddr_in6 sin6; 1793 #endif /* CONFIG_IPV6 */ 1794 } from; 1795 socklen_t fromlen; 1796 int len, res; 1797 struct radius_client *client = NULL; 1798 struct radius_msg *msg = NULL, *resp = NULL; 1799 char abuf[50]; 1800 int from_port = 0; 1801 struct radius_hdr *hdr; 1802 struct wpabuf *rbuf; 1803 1804 buf = os_malloc(RADIUS_MAX_MSG_LEN); 1805 if (buf == NULL) { 1806 goto fail; 1807 } 1808 1809 fromlen = sizeof(from); 1810 len = recvfrom(sock, buf, RADIUS_MAX_MSG_LEN, 0, 1811 (struct sockaddr *) &from.ss, &fromlen); 1812 if (len < 0) { 1813 wpa_printf(MSG_INFO, "recvfrom[radius_server]: %s", 1814 strerror(errno)); 1815 goto fail; 1816 } 1817 1818 #ifdef CONFIG_IPV6 1819 if (data->ipv6) { 1820 if (inet_ntop(AF_INET6, &from.sin6.sin6_addr, abuf, 1821 sizeof(abuf)) == NULL) 1822 abuf[0] = '\0'; 1823 from_port = ntohs(from.sin6.sin6_port); 1824 RADIUS_DEBUG("Received %d bytes from %s:%d", 1825 len, abuf, from_port); 1826 1827 client = radius_server_get_client(data, 1828 (struct in_addr *) 1829 &from.sin6.sin6_addr, 1); 1830 } 1831 #endif /* CONFIG_IPV6 */ 1832 1833 if (!data->ipv6) { 1834 os_strlcpy(abuf, inet_ntoa(from.sin.sin_addr), sizeof(abuf)); 1835 from_port = ntohs(from.sin.sin_port); 1836 RADIUS_DEBUG("Received %d bytes from %s:%d", 1837 len, abuf, from_port); 1838 1839 client = radius_server_get_client(data, &from.sin.sin_addr, 0); 1840 } 1841 1842 RADIUS_DUMP("Received data", buf, len); 1843 1844 if (client == NULL) { 1845 RADIUS_DEBUG("Unknown client %s - packet ignored", abuf); 1846 data->counters.invalid_acct_requests++; 1847 goto fail; 1848 } 1849 1850 msg = radius_msg_parse(buf, len); 1851 if (msg == NULL) { 1852 RADIUS_DEBUG("Parsing incoming RADIUS frame failed"); 1853 data->counters.malformed_acct_requests++; 1854 client->counters.malformed_acct_requests++; 1855 goto fail; 1856 } 1857 1858 os_free(buf); 1859 buf = NULL; 1860 1861 if (wpa_debug_level <= MSG_MSGDUMP) { 1862 radius_msg_dump(msg); 1863 } 1864 1865 if (radius_msg_get_hdr(msg)->code != RADIUS_CODE_ACCOUNTING_REQUEST) { 1866 RADIUS_DEBUG("Unexpected RADIUS code %d", 1867 radius_msg_get_hdr(msg)->code); 1868 data->counters.unknown_acct_types++; 1869 client->counters.unknown_acct_types++; 1870 goto fail; 1871 } 1872 1873 data->counters.acct_requests++; 1874 client->counters.acct_requests++; 1875 1876 if (radius_msg_verify_acct_req(msg, (u8 *) client->shared_secret, 1877 client->shared_secret_len)) { 1878 RADIUS_DEBUG("Invalid Authenticator from %s", abuf); 1879 data->counters.acct_bad_authenticators++; 1880 client->counters.acct_bad_authenticators++; 1881 goto fail; 1882 } 1883 1884 /* TODO: Write accounting information to a file or database */ 1885 1886 hdr = radius_msg_get_hdr(msg); 1887 1888 resp = radius_msg_new(RADIUS_CODE_ACCOUNTING_RESPONSE, hdr->identifier); 1889 if (resp == NULL) 1890 goto fail; 1891 1892 radius_msg_finish_acct_resp(resp, (u8 *) client->shared_secret, 1893 client->shared_secret_len, 1894 hdr->authenticator); 1895 1896 RADIUS_DEBUG("Reply to %s:%d", abuf, from_port); 1897 if (wpa_debug_level <= MSG_MSGDUMP) { 1898 radius_msg_dump(resp); 1899 } 1900 rbuf = radius_msg_get_buf(resp); 1901 data->counters.acct_responses++; 1902 client->counters.acct_responses++; 1903 res = sendto(data->acct_sock, wpabuf_head(rbuf), wpabuf_len(rbuf), 0, 1904 (struct sockaddr *) &from.ss, fromlen); 1905 if (res < 0) { 1906 wpa_printf(MSG_INFO, "sendto[RADIUS SRV]: %s", 1907 strerror(errno)); 1908 } 1909 1910 fail: 1911 radius_msg_free(resp); 1912 radius_msg_free(msg); 1913 os_free(buf); 1914 } 1915 1916 1917 static int radius_server_disable_pmtu_discovery(int s) 1918 { 1919 int r = -1; 1920 #if defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DONT) 1921 /* Turn off Path MTU discovery on IPv4/UDP sockets. */ 1922 int action = IP_PMTUDISC_DONT; 1923 r = setsockopt(s, IPPROTO_IP, IP_MTU_DISCOVER, &action, 1924 sizeof(action)); 1925 if (r == -1) 1926 wpa_printf(MSG_ERROR, "Failed to set IP_MTU_DISCOVER: " 1927 "%s", strerror(errno)); 1928 #endif 1929 return r; 1930 } 1931 1932 1933 static int radius_server_open_socket(int port) 1934 { 1935 int s; 1936 struct sockaddr_in addr; 1937 1938 s = socket(PF_INET, SOCK_DGRAM, 0); 1939 if (s < 0) { 1940 wpa_printf(MSG_INFO, "RADIUS: socket: %s", strerror(errno)); 1941 return -1; 1942 } 1943 1944 radius_server_disable_pmtu_discovery(s); 1945 1946 os_memset(&addr, 0, sizeof(addr)); 1947 addr.sin_family = AF_INET; 1948 addr.sin_port = htons(port); 1949 if (bind(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) { 1950 wpa_printf(MSG_INFO, "RADIUS: bind: %s", strerror(errno)); 1951 close(s); 1952 return -1; 1953 } 1954 1955 return s; 1956 } 1957 1958 1959 #ifdef CONFIG_IPV6 1960 static int radius_server_open_socket6(int port) 1961 { 1962 int s; 1963 struct sockaddr_in6 addr; 1964 1965 s = socket(PF_INET6, SOCK_DGRAM, 0); 1966 if (s < 0) { 1967 wpa_printf(MSG_INFO, "RADIUS: socket[IPv6]: %s", 1968 strerror(errno)); 1969 return -1; 1970 } 1971 1972 os_memset(&addr, 0, sizeof(addr)); 1973 addr.sin6_family = AF_INET6; 1974 os_memcpy(&addr.sin6_addr, &in6addr_any, sizeof(in6addr_any)); 1975 addr.sin6_port = htons(port); 1976 if (bind(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) { 1977 wpa_printf(MSG_INFO, "RADIUS: bind: %s", strerror(errno)); 1978 close(s); 1979 return -1; 1980 } 1981 1982 return s; 1983 } 1984 #endif /* CONFIG_IPV6 */ 1985 1986 1987 static void radius_server_free_sessions(struct radius_server_data *data, 1988 struct radius_session *sessions) 1989 { 1990 struct radius_session *session, *prev; 1991 1992 session = sessions; 1993 while (session) { 1994 prev = session; 1995 session = session->next; 1996 radius_server_session_free(data, prev); 1997 } 1998 } 1999 2000 2001 static void radius_server_free_clients(struct radius_server_data *data, 2002 struct radius_client *clients) 2003 { 2004 struct radius_client *client, *prev; 2005 2006 client = clients; 2007 while (client) { 2008 prev = client; 2009 client = client->next; 2010 2011 radius_server_free_sessions(data, prev->sessions); 2012 os_free(prev->shared_secret); 2013 radius_msg_free(prev->pending_dac_coa_req); 2014 radius_msg_free(prev->pending_dac_disconnect_req); 2015 os_free(prev); 2016 } 2017 } 2018 2019 2020 static struct radius_client * 2021 radius_server_read_clients(const char *client_file, int ipv6) 2022 { 2023 FILE *f; 2024 const int buf_size = 1024; 2025 char *buf, *pos; 2026 struct radius_client *clients, *tail, *entry; 2027 int line = 0, mask, failed = 0, i; 2028 struct in_addr addr; 2029 #ifdef CONFIG_IPV6 2030 struct in6_addr addr6; 2031 #endif /* CONFIG_IPV6 */ 2032 unsigned int val; 2033 2034 f = fopen(client_file, "r"); 2035 if (f == NULL) { 2036 RADIUS_ERROR("Could not open client file '%s'", client_file); 2037 return NULL; 2038 } 2039 2040 buf = os_malloc(buf_size); 2041 if (buf == NULL) { 2042 fclose(f); 2043 return NULL; 2044 } 2045 2046 clients = tail = NULL; 2047 while (fgets(buf, buf_size, f)) { 2048 /* Configuration file format: 2049 * 192.168.1.0/24 secret 2050 * 192.168.1.2 secret 2051 * fe80::211:22ff:fe33:4455/64 secretipv6 2052 */ 2053 line++; 2054 buf[buf_size - 1] = '\0'; 2055 pos = buf; 2056 while (*pos != '\0' && *pos != '\n') 2057 pos++; 2058 if (*pos == '\n') 2059 *pos = '\0'; 2060 if (*buf == '\0' || *buf == '#') 2061 continue; 2062 2063 pos = buf; 2064 while ((*pos >= '0' && *pos <= '9') || *pos == '.' || 2065 (*pos >= 'a' && *pos <= 'f') || *pos == ':' || 2066 (*pos >= 'A' && *pos <= 'F')) { 2067 pos++; 2068 } 2069 2070 if (*pos == '\0') { 2071 failed = 1; 2072 break; 2073 } 2074 2075 if (*pos == '/') { 2076 char *end; 2077 *pos++ = '\0'; 2078 mask = strtol(pos, &end, 10); 2079 if ((pos == end) || 2080 (mask < 0 || mask > (ipv6 ? 128 : 32))) { 2081 failed = 1; 2082 break; 2083 } 2084 pos = end; 2085 } else { 2086 mask = ipv6 ? 128 : 32; 2087 *pos++ = '\0'; 2088 } 2089 2090 if (!ipv6 && inet_aton(buf, &addr) == 0) { 2091 failed = 1; 2092 break; 2093 } 2094 #ifdef CONFIG_IPV6 2095 if (ipv6 && inet_pton(AF_INET6, buf, &addr6) <= 0) { 2096 if (inet_pton(AF_INET, buf, &addr) <= 0) { 2097 failed = 1; 2098 break; 2099 } 2100 /* Convert IPv4 address to IPv6 */ 2101 if (mask <= 32) 2102 mask += (128 - 32); 2103 os_memset(addr6.s6_addr, 0, 10); 2104 addr6.s6_addr[10] = 0xff; 2105 addr6.s6_addr[11] = 0xff; 2106 os_memcpy(addr6.s6_addr + 12, (char *) &addr.s_addr, 2107 4); 2108 } 2109 #endif /* CONFIG_IPV6 */ 2110 2111 while (*pos == ' ' || *pos == '\t') { 2112 pos++; 2113 } 2114 2115 if (*pos == '\0') { 2116 failed = 1; 2117 break; 2118 } 2119 2120 entry = os_zalloc(sizeof(*entry)); 2121 if (entry == NULL) { 2122 failed = 1; 2123 break; 2124 } 2125 entry->shared_secret = os_strdup(pos); 2126 if (entry->shared_secret == NULL) { 2127 failed = 1; 2128 os_free(entry); 2129 break; 2130 } 2131 entry->shared_secret_len = os_strlen(entry->shared_secret); 2132 if (!ipv6) { 2133 entry->addr.s_addr = addr.s_addr; 2134 val = 0; 2135 for (i = 0; i < mask; i++) 2136 val |= 1U << (31 - i); 2137 entry->mask.s_addr = htonl(val); 2138 } 2139 #ifdef CONFIG_IPV6 2140 if (ipv6) { 2141 int offset = mask / 8; 2142 2143 os_memcpy(entry->addr6.s6_addr, addr6.s6_addr, 16); 2144 os_memset(entry->mask6.s6_addr, 0xff, offset); 2145 val = 0; 2146 for (i = 0; i < (mask % 8); i++) 2147 val |= 1 << (7 - i); 2148 if (offset < 16) 2149 entry->mask6.s6_addr[offset] = val; 2150 } 2151 #endif /* CONFIG_IPV6 */ 2152 2153 if (tail == NULL) { 2154 clients = tail = entry; 2155 } else { 2156 tail->next = entry; 2157 tail = entry; 2158 } 2159 } 2160 2161 if (failed) { 2162 RADIUS_ERROR("Invalid line %d in '%s'", line, client_file); 2163 radius_server_free_clients(NULL, clients); 2164 clients = NULL; 2165 } 2166 2167 os_free(buf); 2168 fclose(f); 2169 2170 return clients; 2171 } 2172 2173 2174 /** 2175 * radius_server_init - Initialize RADIUS server 2176 * @conf: Configuration for the RADIUS server 2177 * Returns: Pointer to private RADIUS server context or %NULL on failure 2178 * 2179 * This initializes a RADIUS server instance and returns a context pointer that 2180 * will be used in other calls to the RADIUS server module. The server can be 2181 * deinitialize by calling radius_server_deinit(). 2182 */ 2183 struct radius_server_data * 2184 radius_server_init(struct radius_server_conf *conf) 2185 { 2186 struct radius_server_data *data; 2187 2188 #ifndef CONFIG_IPV6 2189 if (conf->ipv6) { 2190 wpa_printf(MSG_ERROR, "RADIUS server compiled without IPv6 support"); 2191 return NULL; 2192 } 2193 #endif /* CONFIG_IPV6 */ 2194 2195 data = os_zalloc(sizeof(*data)); 2196 if (data == NULL) 2197 return NULL; 2198 2199 data->eap_cfg = conf->eap_cfg; 2200 data->auth_sock = -1; 2201 data->acct_sock = -1; 2202 dl_list_init(&data->erp_keys); 2203 os_get_reltime(&data->start_time); 2204 data->conf_ctx = conf->conf_ctx; 2205 conf->eap_cfg->backend_auth = true; 2206 conf->eap_cfg->eap_server = 1; 2207 data->ipv6 = conf->ipv6; 2208 data->get_eap_user = conf->get_eap_user; 2209 if (conf->eap_req_id_text) { 2210 data->eap_req_id_text = os_malloc(conf->eap_req_id_text_len); 2211 if (!data->eap_req_id_text) 2212 goto fail; 2213 os_memcpy(data->eap_req_id_text, conf->eap_req_id_text, 2214 conf->eap_req_id_text_len); 2215 data->eap_req_id_text_len = conf->eap_req_id_text_len; 2216 } 2217 data->erp_domain = conf->erp_domain; 2218 2219 if (conf->subscr_remediation_url) { 2220 data->subscr_remediation_url = 2221 os_strdup(conf->subscr_remediation_url); 2222 if (!data->subscr_remediation_url) 2223 goto fail; 2224 } 2225 data->subscr_remediation_method = conf->subscr_remediation_method; 2226 if (conf->hs20_sim_provisioning_url) { 2227 data->hs20_sim_provisioning_url = 2228 os_strdup(conf->hs20_sim_provisioning_url); 2229 if (!data->hs20_sim_provisioning_url) 2230 goto fail; 2231 } 2232 2233 if (conf->t_c_server_url) { 2234 data->t_c_server_url = os_strdup(conf->t_c_server_url); 2235 if (!data->t_c_server_url) 2236 goto fail; 2237 } 2238 2239 #ifdef CONFIG_SQLITE 2240 if (conf->sqlite_file) { 2241 if (sqlite3_open(conf->sqlite_file, &data->db)) { 2242 RADIUS_ERROR("Could not open SQLite file '%s'", 2243 conf->sqlite_file); 2244 goto fail; 2245 } 2246 } 2247 #endif /* CONFIG_SQLITE */ 2248 2249 #ifdef CONFIG_RADIUS_TEST 2250 if (conf->dump_msk_file) 2251 data->dump_msk_file = os_strdup(conf->dump_msk_file); 2252 #endif /* CONFIG_RADIUS_TEST */ 2253 2254 data->clients = radius_server_read_clients(conf->client_file, 2255 conf->ipv6); 2256 if (data->clients == NULL) { 2257 wpa_printf(MSG_ERROR, "No RADIUS clients configured"); 2258 goto fail; 2259 } 2260 2261 #ifdef CONFIG_IPV6 2262 if (conf->ipv6) 2263 data->auth_sock = radius_server_open_socket6(conf->auth_port); 2264 else 2265 #endif /* CONFIG_IPV6 */ 2266 data->auth_sock = radius_server_open_socket(conf->auth_port); 2267 if (data->auth_sock < 0) { 2268 wpa_printf(MSG_ERROR, "Failed to open UDP socket for RADIUS authentication server"); 2269 goto fail; 2270 } 2271 if (eloop_register_read_sock(data->auth_sock, 2272 radius_server_receive_auth, 2273 data, NULL)) { 2274 goto fail; 2275 } 2276 2277 if (conf->acct_port) { 2278 #ifdef CONFIG_IPV6 2279 if (conf->ipv6) 2280 data->acct_sock = radius_server_open_socket6( 2281 conf->acct_port); 2282 else 2283 #endif /* CONFIG_IPV6 */ 2284 data->acct_sock = radius_server_open_socket(conf->acct_port); 2285 if (data->acct_sock < 0) { 2286 wpa_printf(MSG_ERROR, "Failed to open UDP socket for RADIUS accounting server"); 2287 goto fail; 2288 } 2289 if (eloop_register_read_sock(data->acct_sock, 2290 radius_server_receive_acct, 2291 data, NULL)) 2292 goto fail; 2293 } else { 2294 data->acct_sock = -1; 2295 } 2296 2297 return data; 2298 fail: 2299 radius_server_deinit(data); 2300 return NULL; 2301 } 2302 2303 2304 /** 2305 * radius_server_erp_flush - Flush all ERP keys 2306 * @data: RADIUS server context from radius_server_init() 2307 */ 2308 void radius_server_erp_flush(struct radius_server_data *data) 2309 { 2310 struct eap_server_erp_key *erp; 2311 2312 if (data == NULL) 2313 return; 2314 while ((erp = dl_list_first(&data->erp_keys, struct eap_server_erp_key, 2315 list)) != NULL) { 2316 dl_list_del(&erp->list); 2317 bin_clear_free(erp, sizeof(*erp)); 2318 } 2319 } 2320 2321 2322 /** 2323 * radius_server_deinit - Deinitialize RADIUS server 2324 * @data: RADIUS server context from radius_server_init() 2325 */ 2326 void radius_server_deinit(struct radius_server_data *data) 2327 { 2328 if (data == NULL) 2329 return; 2330 2331 if (data->auth_sock >= 0) { 2332 eloop_unregister_read_sock(data->auth_sock); 2333 close(data->auth_sock); 2334 } 2335 2336 if (data->acct_sock >= 0) { 2337 eloop_unregister_read_sock(data->acct_sock); 2338 close(data->acct_sock); 2339 } 2340 2341 radius_server_free_clients(data, data->clients); 2342 2343 os_free(data->eap_req_id_text); 2344 #ifdef CONFIG_RADIUS_TEST 2345 os_free(data->dump_msk_file); 2346 #endif /* CONFIG_RADIUS_TEST */ 2347 os_free(data->subscr_remediation_url); 2348 os_free(data->hs20_sim_provisioning_url); 2349 os_free(data->t_c_server_url); 2350 2351 #ifdef CONFIG_SQLITE 2352 if (data->db) 2353 sqlite3_close(data->db); 2354 #endif /* CONFIG_SQLITE */ 2355 2356 radius_server_erp_flush(data); 2357 2358 os_free(data); 2359 } 2360 2361 2362 /** 2363 * radius_server_get_mib - Get RADIUS server MIB information 2364 * @data: RADIUS server context from radius_server_init() 2365 * @buf: Buffer for returning the MIB data in text format 2366 * @buflen: buf length in octets 2367 * Returns: Number of octets written into buf 2368 */ 2369 int radius_server_get_mib(struct radius_server_data *data, char *buf, 2370 size_t buflen) 2371 { 2372 int ret, uptime; 2373 unsigned int idx; 2374 char *end, *pos; 2375 struct os_reltime now; 2376 struct radius_client *cli; 2377 2378 /* RFC 2619 - RADIUS Authentication Server MIB */ 2379 2380 if (data == NULL || buflen == 0) 2381 return 0; 2382 2383 pos = buf; 2384 end = buf + buflen; 2385 2386 os_get_reltime(&now); 2387 uptime = (now.sec - data->start_time.sec) * 100 + 2388 ((now.usec - data->start_time.usec) / 10000) % 100; 2389 ret = os_snprintf(pos, end - pos, 2390 "RADIUS-AUTH-SERVER-MIB\n" 2391 "radiusAuthServIdent=hostapd\n" 2392 "radiusAuthServUpTime=%d\n" 2393 "radiusAuthServResetTime=0\n" 2394 "radiusAuthServConfigReset=4\n", 2395 uptime); 2396 if (os_snprintf_error(end - pos, ret)) { 2397 *pos = '\0'; 2398 return pos - buf; 2399 } 2400 pos += ret; 2401 2402 ret = os_snprintf(pos, end - pos, 2403 "radiusAuthServTotalAccessRequests=%u\n" 2404 "radiusAuthServTotalInvalidRequests=%u\n" 2405 "radiusAuthServTotalDupAccessRequests=%u\n" 2406 "radiusAuthServTotalAccessAccepts=%u\n" 2407 "radiusAuthServTotalAccessRejects=%u\n" 2408 "radiusAuthServTotalAccessChallenges=%u\n" 2409 "radiusAuthServTotalMalformedAccessRequests=%u\n" 2410 "radiusAuthServTotalBadAuthenticators=%u\n" 2411 "radiusAuthServTotalPacketsDropped=%u\n" 2412 "radiusAuthServTotalUnknownTypes=%u\n" 2413 "radiusAccServTotalRequests=%u\n" 2414 "radiusAccServTotalInvalidRequests=%u\n" 2415 "radiusAccServTotalResponses=%u\n" 2416 "radiusAccServTotalMalformedRequests=%u\n" 2417 "radiusAccServTotalBadAuthenticators=%u\n" 2418 "radiusAccServTotalUnknownTypes=%u\n", 2419 data->counters.access_requests, 2420 data->counters.invalid_requests, 2421 data->counters.dup_access_requests, 2422 data->counters.access_accepts, 2423 data->counters.access_rejects, 2424 data->counters.access_challenges, 2425 data->counters.malformed_access_requests, 2426 data->counters.bad_authenticators, 2427 data->counters.packets_dropped, 2428 data->counters.unknown_types, 2429 data->counters.acct_requests, 2430 data->counters.invalid_acct_requests, 2431 data->counters.acct_responses, 2432 data->counters.malformed_acct_requests, 2433 data->counters.acct_bad_authenticators, 2434 data->counters.unknown_acct_types); 2435 if (os_snprintf_error(end - pos, ret)) { 2436 *pos = '\0'; 2437 return pos - buf; 2438 } 2439 pos += ret; 2440 2441 for (cli = data->clients, idx = 0; cli; cli = cli->next, idx++) { 2442 char abuf[50], mbuf[50]; 2443 #ifdef CONFIG_IPV6 2444 if (data->ipv6) { 2445 if (inet_ntop(AF_INET6, &cli->addr6, abuf, 2446 sizeof(abuf)) == NULL) 2447 abuf[0] = '\0'; 2448 if (inet_ntop(AF_INET6, &cli->mask6, mbuf, 2449 sizeof(mbuf)) == NULL) 2450 mbuf[0] = '\0'; 2451 } 2452 #endif /* CONFIG_IPV6 */ 2453 if (!data->ipv6) { 2454 os_strlcpy(abuf, inet_ntoa(cli->addr), sizeof(abuf)); 2455 os_strlcpy(mbuf, inet_ntoa(cli->mask), sizeof(mbuf)); 2456 } 2457 2458 ret = os_snprintf(pos, end - pos, 2459 "radiusAuthClientIndex=%u\n" 2460 "radiusAuthClientAddress=%s/%s\n" 2461 "radiusAuthServAccessRequests=%u\n" 2462 "radiusAuthServDupAccessRequests=%u\n" 2463 "radiusAuthServAccessAccepts=%u\n" 2464 "radiusAuthServAccessRejects=%u\n" 2465 "radiusAuthServAccessChallenges=%u\n" 2466 "radiusAuthServMalformedAccessRequests=%u\n" 2467 "radiusAuthServBadAuthenticators=%u\n" 2468 "radiusAuthServPacketsDropped=%u\n" 2469 "radiusAuthServUnknownTypes=%u\n" 2470 "radiusAccServTotalRequests=%u\n" 2471 "radiusAccServTotalInvalidRequests=%u\n" 2472 "radiusAccServTotalResponses=%u\n" 2473 "radiusAccServTotalMalformedRequests=%u\n" 2474 "radiusAccServTotalBadAuthenticators=%u\n" 2475 "radiusAccServTotalUnknownTypes=%u\n", 2476 idx, 2477 abuf, mbuf, 2478 cli->counters.access_requests, 2479 cli->counters.dup_access_requests, 2480 cli->counters.access_accepts, 2481 cli->counters.access_rejects, 2482 cli->counters.access_challenges, 2483 cli->counters.malformed_access_requests, 2484 cli->counters.bad_authenticators, 2485 cli->counters.packets_dropped, 2486 cli->counters.unknown_types, 2487 cli->counters.acct_requests, 2488 cli->counters.invalid_acct_requests, 2489 cli->counters.acct_responses, 2490 cli->counters.malformed_acct_requests, 2491 cli->counters.acct_bad_authenticators, 2492 cli->counters.unknown_acct_types); 2493 if (os_snprintf_error(end - pos, ret)) { 2494 *pos = '\0'; 2495 return pos - buf; 2496 } 2497 pos += ret; 2498 } 2499 2500 return pos - buf; 2501 } 2502 2503 2504 static int radius_server_get_eap_user(void *ctx, const u8 *identity, 2505 size_t identity_len, int phase2, 2506 struct eap_user *user) 2507 { 2508 struct radius_session *sess = ctx; 2509 struct radius_server_data *data = sess->server; 2510 int ret; 2511 2512 ret = data->get_eap_user(data->conf_ctx, identity, identity_len, 2513 phase2, user); 2514 if (ret == 0 && user) { 2515 sess->accept_attr = user->accept_attr; 2516 sess->remediation = user->remediation; 2517 sess->macacl = user->macacl; 2518 sess->t_c_timestamp = user->t_c_timestamp; 2519 } 2520 2521 if (ret) { 2522 RADIUS_DEBUG("%s: User-Name not found from user database", 2523 __func__); 2524 } 2525 2526 return ret; 2527 } 2528 2529 2530 static const char * radius_server_get_eap_req_id_text(void *ctx, size_t *len) 2531 { 2532 struct radius_session *sess = ctx; 2533 struct radius_server_data *data = sess->server; 2534 *len = data->eap_req_id_text_len; 2535 return data->eap_req_id_text; 2536 } 2537 2538 2539 static void radius_server_log_msg(void *ctx, const char *msg) 2540 { 2541 struct radius_session *sess = ctx; 2542 srv_log(sess, "EAP: %s", msg); 2543 } 2544 2545 2546 #ifdef CONFIG_ERP 2547 2548 static const char * radius_server_get_erp_domain(void *ctx) 2549 { 2550 struct radius_session *sess = ctx; 2551 struct radius_server_data *data = sess->server; 2552 2553 return data->erp_domain; 2554 } 2555 2556 2557 static struct eap_server_erp_key * 2558 radius_server_erp_get_key(void *ctx, const char *keyname) 2559 { 2560 struct radius_session *sess = ctx; 2561 struct radius_server_data *data = sess->server; 2562 2563 return radius_server_erp_find_key(data, keyname); 2564 } 2565 2566 2567 static int radius_server_erp_add_key(void *ctx, struct eap_server_erp_key *erp) 2568 { 2569 struct radius_session *sess = ctx; 2570 struct radius_server_data *data = sess->server; 2571 2572 dl_list_add(&data->erp_keys, &erp->list); 2573 return 0; 2574 } 2575 2576 #endif /* CONFIG_ERP */ 2577 2578 2579 static const struct eapol_callbacks radius_server_eapol_cb = 2580 { 2581 .get_eap_user = radius_server_get_eap_user, 2582 .get_eap_req_id_text = radius_server_get_eap_req_id_text, 2583 .log_msg = radius_server_log_msg, 2584 #ifdef CONFIG_ERP 2585 .get_erp_send_reauth_start = NULL, 2586 .get_erp_domain = radius_server_get_erp_domain, 2587 .erp_get_key = radius_server_erp_get_key, 2588 .erp_add_key = radius_server_erp_add_key, 2589 #endif /* CONFIG_ERP */ 2590 }; 2591 2592 2593 /** 2594 * radius_server_eap_pending_cb - Pending EAP data notification 2595 * @data: RADIUS server context from radius_server_init() 2596 * @ctx: Pending EAP context pointer 2597 * 2598 * This function is used to notify EAP server module that a pending operation 2599 * has been completed and processing of the EAP session can proceed. 2600 */ 2601 void radius_server_eap_pending_cb(struct radius_server_data *data, void *ctx) 2602 { 2603 struct radius_client *cli; 2604 struct radius_session *s, *sess = NULL; 2605 struct radius_msg *msg; 2606 2607 if (data == NULL) 2608 return; 2609 2610 for (cli = data->clients; cli; cli = cli->next) { 2611 for (s = cli->sessions; s; s = s->next) { 2612 if (s->eap == ctx && s->last_msg) { 2613 sess = s; 2614 break; 2615 } 2616 } 2617 if (sess) 2618 break; 2619 } 2620 2621 if (sess == NULL) { 2622 RADIUS_DEBUG("No session matched callback ctx"); 2623 return; 2624 } 2625 2626 msg = sess->last_msg; 2627 sess->last_msg = NULL; 2628 eap_sm_pending_cb(sess->eap); 2629 if (radius_server_request(data, msg, 2630 (struct sockaddr *) &sess->last_from, 2631 sess->last_fromlen, cli, 2632 sess->last_from_addr, 2633 sess->last_from_port, sess) == -2) 2634 return; /* msg was stored with the session */ 2635 2636 radius_msg_free(msg); 2637 } 2638 2639 2640 #ifdef CONFIG_SQLITE 2641 2642 struct db_session_fields { 2643 char *identity; 2644 char *nas; 2645 int hs20_t_c_filtering; 2646 int waiting_coa_ack; 2647 int coa_ack_received; 2648 }; 2649 2650 2651 static int get_db_session_fields(void *ctx, int argc, char *argv[], char *col[]) 2652 { 2653 struct db_session_fields *fields = ctx; 2654 int i; 2655 2656 for (i = 0; i < argc; i++) { 2657 if (!argv[i]) 2658 continue; 2659 2660 RADIUS_DEBUG("Session DB: %s=%s", col[i], argv[i]); 2661 2662 if (os_strcmp(col[i], "identity") == 0) { 2663 os_free(fields->identity); 2664 fields->identity = os_strdup(argv[i]); 2665 } else if (os_strcmp(col[i], "nas") == 0) { 2666 os_free(fields->nas); 2667 fields->nas = os_strdup(argv[i]); 2668 } else if (os_strcmp(col[i], "hs20_t_c_filtering") == 0) { 2669 fields->hs20_t_c_filtering = atoi(argv[i]); 2670 } else if (os_strcmp(col[i], "waiting_coa_ack") == 0) { 2671 fields->waiting_coa_ack = atoi(argv[i]); 2672 } else if (os_strcmp(col[i], "coa_ack_received") == 0) { 2673 fields->coa_ack_received = atoi(argv[i]); 2674 } 2675 } 2676 2677 return 0; 2678 } 2679 2680 2681 static void free_db_session_fields(struct db_session_fields *fields) 2682 { 2683 os_free(fields->identity); 2684 fields->identity = NULL; 2685 os_free(fields->nas); 2686 fields->nas = NULL; 2687 } 2688 2689 #endif /* CONFIG_SQLITE */ 2690 2691 2692 int radius_server_dac_request(struct radius_server_data *data, const char *req) 2693 { 2694 #ifdef CONFIG_SQLITE 2695 char *sql; 2696 int res; 2697 int disconnect; 2698 const char *pos = req; 2699 u8 addr[ETH_ALEN]; 2700 char addrtxt[3 * ETH_ALEN]; 2701 int t_c_clear = 0; 2702 struct db_session_fields fields; 2703 struct sockaddr_in das; 2704 struct radius_client *client; 2705 struct radius_msg *msg; 2706 struct wpabuf *buf; 2707 u8 identifier; 2708 struct os_time now; 2709 2710 if (!data) 2711 return -1; 2712 2713 /* req: <disconnect|coa> <MAC Address> [t_c_clear] */ 2714 2715 if (os_strncmp(pos, "disconnect ", 11) == 0) { 2716 disconnect = 1; 2717 pos += 11; 2718 } else if (os_strncmp(req, "coa ", 4) == 0) { 2719 disconnect = 0; 2720 pos += 4; 2721 } else { 2722 return -1; 2723 } 2724 2725 if (hwaddr_aton(pos, addr)) 2726 return -1; 2727 pos = os_strchr(pos, ' '); 2728 if (pos) { 2729 if (os_strstr(pos, "t_c_clear")) 2730 t_c_clear = 1; 2731 } 2732 2733 if (!disconnect && !t_c_clear) { 2734 RADIUS_ERROR("DAC request for CoA without any authorization change"); 2735 return -1; 2736 } 2737 2738 if (!data->db) { 2739 RADIUS_ERROR("SQLite database not in use"); 2740 return -1; 2741 } 2742 2743 os_snprintf(addrtxt, sizeof(addrtxt), MACSTR, MAC2STR(addr)); 2744 2745 sql = sqlite3_mprintf("SELECT * FROM current_sessions WHERE mac_addr=%Q", 2746 addrtxt); 2747 if (!sql) 2748 return -1; 2749 2750 os_memset(&fields, 0, sizeof(fields)); 2751 res = sqlite3_exec(data->db, sql, get_db_session_fields, &fields, NULL); 2752 sqlite3_free(sql); 2753 if (res != SQLITE_OK) { 2754 RADIUS_ERROR("Failed to find matching current_sessions entry from sqlite database: %s", 2755 sqlite3_errmsg(data->db)); 2756 free_db_session_fields(&fields); 2757 return -1; 2758 } 2759 2760 if (!fields.nas) { 2761 RADIUS_ERROR("No NAS information found from current_sessions"); 2762 free_db_session_fields(&fields); 2763 return -1; 2764 } 2765 2766 os_memset(&das, 0, sizeof(das)); 2767 das.sin_family = AF_INET; 2768 das.sin_addr.s_addr = inet_addr(fields.nas); 2769 das.sin_port = htons(3799); 2770 2771 free_db_session_fields(&fields); 2772 2773 client = radius_server_get_client(data, &das.sin_addr, 0); 2774 if (!client) { 2775 RADIUS_ERROR("No NAS information available to protect the packet"); 2776 return -1; 2777 } 2778 2779 identifier = client->next_dac_identifier++; 2780 2781 msg = radius_msg_new(disconnect ? RADIUS_CODE_DISCONNECT_REQUEST : 2782 RADIUS_CODE_COA_REQUEST, identifier); 2783 if (!msg) 2784 return -1; 2785 2786 os_snprintf(addrtxt, sizeof(addrtxt), RADIUS_802_1X_ADDR_FORMAT, 2787 MAC2STR(addr)); 2788 if (!radius_msg_add_attr(msg, RADIUS_ATTR_CALLING_STATION_ID, 2789 (u8 *) addrtxt, os_strlen(addrtxt))) { 2790 RADIUS_ERROR("Could not add Calling-Station-Id"); 2791 radius_msg_free(msg); 2792 return -1; 2793 } 2794 2795 if (!disconnect && t_c_clear) { 2796 u8 val[4] = { 0x00, 0x00, 0x00, 0x00 }; /* E=0 */ 2797 2798 if (!radius_msg_add_wfa( 2799 msg, RADIUS_VENDOR_ATTR_WFA_HS20_T_C_FILTERING, 2800 val, sizeof(val))) { 2801 RADIUS_DEBUG("Failed to add WFA-HS20-T-C-Filtering"); 2802 radius_msg_free(msg); 2803 return -1; 2804 } 2805 } 2806 2807 os_get_time(&now); 2808 if (!radius_msg_add_attr_int32(msg, RADIUS_ATTR_EVENT_TIMESTAMP, 2809 now.sec)) { 2810 RADIUS_ERROR("Failed to add Event-Timestamp attribute"); 2811 radius_msg_free(msg); 2812 return -1; 2813 } 2814 2815 radius_msg_finish_acct(msg, (u8 *) client->shared_secret, 2816 client->shared_secret_len); 2817 2818 if (wpa_debug_level <= MSG_MSGDUMP) 2819 radius_msg_dump(msg); 2820 2821 buf = radius_msg_get_buf(msg); 2822 if (sendto(data->auth_sock, wpabuf_head(buf), wpabuf_len(buf), 0, 2823 (struct sockaddr *) &das, sizeof(das)) < 0) { 2824 RADIUS_ERROR("Failed to send packet - sendto: %s", 2825 strerror(errno)); 2826 radius_msg_free(msg); 2827 return -1; 2828 } 2829 2830 if (disconnect) { 2831 radius_msg_free(client->pending_dac_disconnect_req); 2832 client->pending_dac_disconnect_req = msg; 2833 client->pending_dac_disconnect_id = identifier; 2834 os_memcpy(client->pending_dac_disconnect_addr, addr, ETH_ALEN); 2835 } else { 2836 radius_msg_free(client->pending_dac_coa_req); 2837 client->pending_dac_coa_req = msg; 2838 client->pending_dac_coa_id = identifier; 2839 os_memcpy(client->pending_dac_coa_addr, addr, ETH_ALEN); 2840 } 2841 2842 return 0; 2843 #else /* CONFIG_SQLITE */ 2844 return -1; 2845 #endif /* CONFIG_SQLITE */ 2846 } 2847