1 /* 2 * Authentication server setup 3 * Copyright (c) 2002-2009, 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 "utils/includes.h" 10 11 #include "utils/common.h" 12 #include "crypto/crypto.h" 13 #include "crypto/tls.h" 14 #include "eap_server/eap.h" 15 #include "eap_server/eap_sim_db.h" 16 #include "eapol_auth/eapol_auth_sm.h" 17 #include "radius/radius.h" 18 #include "radius/radius_server.h" 19 #include "hostapd.h" 20 #include "ap_config.h" 21 #include "sta_info.h" 22 #include "authsrv.h" 23 24 25 #if defined(EAP_SERVER_SIM) || defined(EAP_SERVER_AKA) 26 #define EAP_SIM_DB 27 #endif /* EAP_SERVER_SIM || EAP_SERVER_AKA */ 28 29 30 #ifdef EAP_SIM_DB hostapd_sim_db_cb_sta(struct hostapd_data * hapd,struct sta_info * sta,void * ctx)31 static int hostapd_sim_db_cb_sta(struct hostapd_data *hapd, 32 struct sta_info *sta, void *ctx) 33 { 34 if (eapol_auth_eap_pending_cb(sta->eapol_sm, ctx) == 0) 35 return 1; 36 return 0; 37 } 38 39 hostapd_sim_db_cb(void * ctx,void * session_ctx)40 static void hostapd_sim_db_cb(void *ctx, void *session_ctx) 41 { 42 struct hostapd_data *hapd = ctx; 43 if (ap_for_each_sta(hapd, hostapd_sim_db_cb_sta, session_ctx) == 0) { 44 #ifdef RADIUS_SERVER 45 radius_server_eap_pending_cb(hapd->radius_srv, session_ctx); 46 #endif /* RADIUS_SERVER */ 47 } 48 } 49 #endif /* EAP_SIM_DB */ 50 51 52 #ifdef RADIUS_SERVER 53 hostapd_radius_get_eap_user(void * ctx,const u8 * identity,size_t identity_len,int phase2,struct eap_user * user)54 static int hostapd_radius_get_eap_user(void *ctx, const u8 *identity, 55 size_t identity_len, int phase2, 56 struct eap_user *user) 57 { 58 const struct hostapd_eap_user *eap_user; 59 int i; 60 int rv = -1; 61 62 eap_user = hostapd_get_eap_user(ctx, identity, identity_len, phase2); 63 if (eap_user == NULL) 64 goto out; 65 66 if (user == NULL) 67 return 0; 68 69 os_memset(user, 0, sizeof(*user)); 70 for (i = 0; i < EAP_MAX_METHODS; i++) { 71 user->methods[i].vendor = eap_user->methods[i].vendor; 72 user->methods[i].method = eap_user->methods[i].method; 73 } 74 75 if (eap_user->password) { 76 user->password = os_memdup(eap_user->password, 77 eap_user->password_len); 78 if (user->password == NULL) 79 goto out; 80 user->password_len = eap_user->password_len; 81 user->password_hash = eap_user->password_hash; 82 if (eap_user->salt && eap_user->salt_len) { 83 user->salt = os_memdup(eap_user->salt, 84 eap_user->salt_len); 85 if (!user->salt) 86 goto out; 87 user->salt_len = eap_user->salt_len; 88 } 89 } 90 user->force_version = eap_user->force_version; 91 user->macacl = eap_user->macacl; 92 user->ttls_auth = eap_user->ttls_auth; 93 user->accept_attr = eap_user->accept_attr; 94 user->t_c_timestamp = eap_user->t_c_timestamp; 95 rv = 0; 96 97 out: 98 if (rv) 99 wpa_printf(MSG_DEBUG, "%s: Failed to find user", __func__); 100 101 return rv; 102 } 103 104 105 /** 106 * hostapd_radius_log_acct_req - Callback for logging received RADIUS 107 * accounting requests 108 * @ctx: Context (struct hostapd_data) 109 * @msg: Received RADIUS accounting request 110 * @status_type: Status type from the message (parsed Acct-Status-Type 111 * attribute) 112 * Returns: 0 on success, -1 on failure 113 */ hostapd_radius_log_acct_req(void * ctx,struct radius_msg * msg,u32 status_type)114 static int hostapd_radius_log_acct_req(void *ctx, struct radius_msg *msg, 115 u32 status_type) 116 { 117 char nas_id[RADIUS_MAX_ATTR_LEN + 1] = ""; 118 char session_id[RADIUS_MAX_ATTR_LEN + 1] = ""; 119 char username[RADIUS_MAX_ATTR_LEN + 1] = ""; 120 char calling_station_id[3 * ETH_ALEN] = ""; 121 u32 session_time = 0, terminate_cause = 0, 122 bytes_in = 0, bytes_out = 0, 123 packets_in = 0, packets_out = 0, 124 gigawords_in = 0, gigawords_out = 0; 125 unsigned long long total_bytes_in = 0, total_bytes_out = 0; 126 127 /* Parse NAS identification (required by RFC 2866, section 4.1) */ 128 if (radius_msg_get_attr(msg, RADIUS_ATTR_NAS_IDENTIFIER, (u8 *) nas_id, 129 sizeof(nas_id) - 1)) 130 nas_id[0] = '\0'; 131 132 /* Process Accounting-On and Accounting-Off messages separately */ 133 if (status_type == RADIUS_ACCT_STATUS_TYPE_ACCOUNTING_ON || 134 status_type == RADIUS_ACCT_STATUS_TYPE_ACCOUNTING_OFF) { 135 wpa_printf(MSG_INFO, "RADIUS ACCT: NAS='%s' status='%s'", 136 nas_id, 137 status_type == RADIUS_ACCT_STATUS_TYPE_ACCOUNTING_ON 138 ? "Accounting-On" : "Accounting-Off"); 139 return 0; 140 } 141 142 /* Parse session ID (required by RFC 2866, section 5.5) */ 143 if (radius_msg_get_attr(msg, RADIUS_ATTR_ACCT_SESSION_ID, 144 (u8 *) session_id, 145 sizeof(session_id) - 1) == 0) { 146 wpa_printf(MSG_DEBUG, 147 "RADIUS ACCT: request doesn't include session ID"); 148 return -1; 149 } 150 151 /* Parse user name */ 152 radius_msg_get_attr(msg, RADIUS_ATTR_USER_NAME, (u8 *) username, 153 sizeof(username) - 1); 154 155 /* Parse device identifier */ 156 radius_msg_get_attr(msg, RADIUS_ATTR_CALLING_STATION_ID, 157 (u8 *) calling_station_id, 158 sizeof(calling_station_id) - 1); 159 160 switch (status_type) { 161 case RADIUS_ACCT_STATUS_TYPE_START: 162 wpa_printf(MSG_INFO, 163 "RADIUS ACCT: NAS='%s' session='%s' status='Accounting-Start' station='%s' username='%s'", 164 nas_id, session_id, calling_station_id, username); 165 break; 166 case RADIUS_ACCT_STATUS_TYPE_STOP: 167 case RADIUS_ACCT_STATUS_TYPE_INTERIM_UPDATE: 168 /* Parse counters */ 169 radius_msg_get_attr_int32(msg, RADIUS_ATTR_ACCT_SESSION_TIME, 170 &session_time); 171 radius_msg_get_attr_int32(msg, 172 RADIUS_ATTR_ACCT_TERMINATE_CAUSE, 173 &terminate_cause); 174 radius_msg_get_attr_int32(msg, RADIUS_ATTR_ACCT_INPUT_OCTETS, 175 &bytes_in); 176 radius_msg_get_attr_int32(msg, RADIUS_ATTR_ACCT_OUTPUT_OCTETS, 177 &bytes_out); 178 radius_msg_get_attr_int32(msg, RADIUS_ATTR_ACCT_INPUT_PACKETS, 179 &packets_in); 180 radius_msg_get_attr_int32(msg, RADIUS_ATTR_ACCT_OUTPUT_PACKETS, 181 &packets_out); 182 radius_msg_get_attr_int32(msg, 183 RADIUS_ATTR_ACCT_INPUT_GIGAWORDS, 184 &gigawords_in); 185 radius_msg_get_attr_int32(msg, 186 RADIUS_ATTR_ACCT_OUTPUT_GIGAWORDS, 187 &gigawords_out); 188 189 /* RFC 2869, section 5.1 and 5.2 */ 190 total_bytes_in = ((u64) gigawords_in << 32) + bytes_in; 191 total_bytes_out = ((u64) gigawords_out << 32) + bytes_out; 192 193 wpa_printf(MSG_INFO, 194 "RADIUS ACCT: NAS='%s' session='%s' status='%s' station='%s' username='%s' session_time=%u term_cause=%u pck_in=%u pck_out=%u bytes_in=%llu bytes_out=%llu", 195 nas_id, session_id, 196 status_type == RADIUS_ACCT_STATUS_TYPE_STOP ? 197 "Accounting-Stop" : "Accounting-Interim-Update", 198 calling_station_id, username, session_time, 199 terminate_cause, packets_in, packets_out, 200 total_bytes_in, total_bytes_out); 201 break; 202 default: 203 wpa_printf(MSG_DEBUG, 204 "RADIUS ACCT: Unknown request status type %u", 205 status_type); 206 return -1; 207 } 208 209 return 0; 210 } 211 212 hostapd_setup_radius_srv(struct hostapd_data * hapd)213 static int hostapd_setup_radius_srv(struct hostapd_data *hapd) 214 { 215 struct radius_server_conf srv; 216 struct hostapd_bss_config *conf = hapd->conf; 217 218 #ifdef CONFIG_IEEE80211BE 219 if (!hostapd_mld_is_first_bss(hapd)) { 220 struct hostapd_data *first; 221 222 wpa_printf(MSG_DEBUG, 223 "MLD: Using RADIUS server of the first BSS"); 224 225 first = hostapd_mld_get_first_bss(hapd); 226 if (!first) 227 return -1; 228 hapd->radius_srv = first->radius_srv; 229 return 0; 230 } 231 #endif /* CONFIG_IEEE80211BE */ 232 233 os_memset(&srv, 0, sizeof(srv)); 234 srv.client_file = conf->radius_server_clients; 235 srv.auth_port = conf->radius_server_auth_port; 236 srv.acct_port = conf->radius_server_acct_port; 237 srv.conf_ctx = hapd; 238 srv.ipv6 = conf->radius_server_ipv6; 239 srv.get_eap_user = hostapd_radius_get_eap_user; 240 if (conf->radius_server_acct_log) 241 srv.acct_req_cb = hostapd_radius_log_acct_req; 242 srv.eap_req_id_text = conf->eap_req_id_text; 243 srv.eap_req_id_text_len = conf->eap_req_id_text_len; 244 srv.sqlite_file = conf->eap_user_sqlite; 245 #ifdef CONFIG_RADIUS_TEST 246 srv.dump_msk_file = conf->dump_msk_file; 247 #endif /* CONFIG_RADIUS_TEST */ 248 #ifdef CONFIG_HS20 249 srv.t_c_server_url = conf->t_c_server_url; 250 #endif /* CONFIG_HS20 */ 251 srv.erp_domain = conf->erp_domain; 252 srv.eap_cfg = hapd->eap_cfg; 253 254 hapd->radius_srv = radius_server_init(&srv); 255 if (hapd->radius_srv == NULL) { 256 wpa_printf(MSG_ERROR, "RADIUS server initialization failed."); 257 return -1; 258 } 259 260 return 0; 261 } 262 263 #endif /* RADIUS_SERVER */ 264 265 266 #ifdef EAP_TLS_FUNCS authsrv_tls_event(void * ctx,enum tls_event ev,union tls_event_data * data)267 static void authsrv_tls_event(void *ctx, enum tls_event ev, 268 union tls_event_data *data) 269 { 270 switch (ev) { 271 case TLS_CERT_CHAIN_SUCCESS: 272 wpa_printf(MSG_DEBUG, "authsrv: remote certificate verification success"); 273 break; 274 case TLS_CERT_CHAIN_FAILURE: 275 wpa_printf(MSG_INFO, "authsrv: certificate chain failure: reason=%d depth=%d subject='%s' err='%s'", 276 data->cert_fail.reason, 277 data->cert_fail.depth, 278 data->cert_fail.subject, 279 data->cert_fail.reason_txt); 280 break; 281 case TLS_PEER_CERTIFICATE: 282 wpa_printf(MSG_DEBUG, "authsrv: peer certificate: depth=%d serial_num=%s subject=%s", 283 data->peer_cert.depth, 284 data->peer_cert.serial_num ? data->peer_cert.serial_num : "N/A", 285 data->peer_cert.subject); 286 break; 287 case TLS_ALERT: 288 if (data->alert.is_local) 289 wpa_printf(MSG_DEBUG, "authsrv: local TLS alert: %s", 290 data->alert.description); 291 else 292 wpa_printf(MSG_DEBUG, "authsrv: remote TLS alert: %s", 293 data->alert.description); 294 break; 295 case TLS_UNSAFE_RENEGOTIATION_DISABLED: 296 /* Not applicable to TLS server */ 297 break; 298 } 299 } 300 #endif /* EAP_TLS_FUNCS */ 301 302 authsrv_eap_config(struct hostapd_data * hapd)303 static struct eap_config * authsrv_eap_config(struct hostapd_data *hapd) 304 { 305 struct eap_config *cfg; 306 307 cfg = os_zalloc(sizeof(*cfg)); 308 if (!cfg) 309 return NULL; 310 311 cfg->eap_server = hapd->conf->eap_server; 312 cfg->ssl_ctx = hapd->ssl_ctx; 313 cfg->msg_ctx = hapd->msg_ctx; 314 cfg->eap_sim_db_priv = hapd->eap_sim_db_priv; 315 cfg->tls_session_lifetime = hapd->conf->tls_session_lifetime; 316 cfg->tls_flags = hapd->conf->tls_flags; 317 cfg->max_auth_rounds = hapd->conf->max_auth_rounds; 318 cfg->max_auth_rounds_short = hapd->conf->max_auth_rounds_short; 319 if (hapd->conf->pac_opaque_encr_key) 320 cfg->pac_opaque_encr_key = 321 os_memdup(hapd->conf->pac_opaque_encr_key, 16); 322 if (hapd->conf->eap_fast_a_id) { 323 cfg->eap_fast_a_id = os_memdup(hapd->conf->eap_fast_a_id, 324 hapd->conf->eap_fast_a_id_len); 325 cfg->eap_fast_a_id_len = hapd->conf->eap_fast_a_id_len; 326 } 327 if (hapd->conf->eap_fast_a_id_info) 328 cfg->eap_fast_a_id_info = 329 os_strdup(hapd->conf->eap_fast_a_id_info); 330 cfg->eap_fast_prov = hapd->conf->eap_fast_prov; 331 cfg->pac_key_lifetime = hapd->conf->pac_key_lifetime; 332 cfg->pac_key_refresh_time = hapd->conf->pac_key_refresh_time; 333 cfg->eap_teap_auth = hapd->conf->eap_teap_auth; 334 cfg->eap_teap_separate_result = hapd->conf->eap_teap_separate_result; 335 cfg->eap_teap_id = hapd->conf->eap_teap_id; 336 cfg->eap_teap_method_sequence = hapd->conf->eap_teap_method_sequence; 337 cfg->eap_sim_aka_result_ind = hapd->conf->eap_sim_aka_result_ind; 338 cfg->eap_sim_id = hapd->conf->eap_sim_id; 339 cfg->imsi_privacy_key = hapd->imsi_privacy_key; 340 cfg->eap_sim_aka_fast_reauth_limit = 341 hapd->conf->eap_sim_aka_fast_reauth_limit; 342 cfg->tnc = hapd->conf->tnc; 343 cfg->wps = hapd->wps; 344 cfg->fragment_size = hapd->conf->fragment_size; 345 cfg->pwd_group = hapd->conf->pwd_group; 346 cfg->pbc_in_m1 = hapd->conf->pbc_in_m1; 347 if (hapd->conf->server_id) { 348 cfg->server_id = (u8 *) os_strdup(hapd->conf->server_id); 349 cfg->server_id_len = os_strlen(hapd->conf->server_id); 350 } else { 351 cfg->server_id = (u8 *) os_strdup("hostapd"); 352 cfg->server_id_len = 7; 353 } 354 cfg->erp = hapd->conf->eap_server_erp; 355 #ifdef CONFIG_TESTING_OPTIONS 356 cfg->skip_prot_success = hapd->conf->eap_skip_prot_success; 357 #endif /* CONFIG_TESTING_OPTIONS */ 358 359 return cfg; 360 } 361 362 authsrv_init(struct hostapd_data * hapd)363 int authsrv_init(struct hostapd_data *hapd) 364 { 365 #ifdef CONFIG_IEEE80211BE 366 if (!hostapd_mld_is_first_bss(hapd)) { 367 struct hostapd_data *first; 368 369 first = hostapd_mld_get_first_bss(hapd); 370 if (!first) 371 return -1; 372 373 if (!first->eap_cfg) { 374 wpa_printf(MSG_DEBUG, 375 "MLD: First BSS auth_serv does not exist. Init on its behalf"); 376 377 if (authsrv_init(first)) 378 return -1; 379 } 380 381 wpa_printf(MSG_DEBUG, "MLD: Using auth_serv of the first BSS"); 382 383 #ifdef EAP_TLS_FUNCS 384 hapd->ssl_ctx = first->ssl_ctx; 385 #endif /* EAP_TLS_FUNCS */ 386 hapd->eap_cfg = first->eap_cfg; 387 #ifdef EAP_SIM_DB 388 hapd->eap_sim_db_priv = first->eap_sim_db_priv; 389 #endif /* EAP_SIM_DB */ 390 return 0; 391 } 392 #endif /* CONFIG_IEEE80211BE */ 393 394 #ifdef EAP_TLS_FUNCS 395 if (hapd->conf->eap_server && 396 (hapd->conf->ca_cert || hapd->conf->server_cert || 397 hapd->conf->private_key || hapd->conf->dh_file || 398 hapd->conf->server_cert2 || hapd->conf->private_key2)) { 399 struct tls_config conf; 400 struct tls_connection_params params; 401 402 os_memset(&conf, 0, sizeof(conf)); 403 conf.tls_session_lifetime = hapd->conf->tls_session_lifetime; 404 if (hapd->conf->crl_reload_interval > 0 && 405 hapd->conf->check_crl <= 0) { 406 wpa_printf(MSG_INFO, 407 "Cannot enable CRL reload functionality - it depends on check_crl being set"); 408 } else if (hapd->conf->crl_reload_interval > 0) { 409 conf.crl_reload_interval = 410 hapd->conf->crl_reload_interval; 411 wpa_printf(MSG_INFO, 412 "Enabled CRL reload functionality"); 413 } 414 conf.tls_flags = hapd->conf->tls_flags; 415 conf.event_cb = authsrv_tls_event; 416 conf.cb_ctx = hapd; 417 hapd->ssl_ctx = tls_init(&conf); 418 if (hapd->ssl_ctx == NULL) { 419 wpa_printf(MSG_ERROR, "Failed to initialize TLS"); 420 authsrv_deinit(hapd); 421 return -1; 422 } 423 424 os_memset(¶ms, 0, sizeof(params)); 425 params.ca_cert = hapd->conf->ca_cert; 426 params.client_cert = hapd->conf->server_cert; 427 params.client_cert2 = hapd->conf->server_cert2; 428 params.private_key = hapd->conf->private_key; 429 params.private_key2 = hapd->conf->private_key2; 430 params.private_key_passwd = hapd->conf->private_key_passwd; 431 params.private_key_passwd2 = hapd->conf->private_key_passwd2; 432 params.dh_file = hapd->conf->dh_file; 433 params.openssl_ciphers = hapd->conf->openssl_ciphers; 434 params.openssl_ecdh_curves = hapd->conf->openssl_ecdh_curves; 435 params.ocsp_stapling_response = 436 hapd->conf->ocsp_stapling_response; 437 params.ocsp_stapling_response_multi = 438 hapd->conf->ocsp_stapling_response_multi; 439 params.check_cert_subject = hapd->conf->check_cert_subject; 440 441 if (tls_global_set_params(hapd->ssl_ctx, ¶ms)) { 442 wpa_printf(MSG_ERROR, "Failed to set TLS parameters"); 443 authsrv_deinit(hapd); 444 return -1; 445 } 446 447 if (tls_global_set_verify(hapd->ssl_ctx, 448 hapd->conf->check_crl, 449 hapd->conf->check_crl_strict)) { 450 wpa_printf(MSG_ERROR, "Failed to enable check_crl"); 451 authsrv_deinit(hapd); 452 return -1; 453 } 454 } 455 #endif /* EAP_TLS_FUNCS */ 456 457 #ifdef CRYPTO_RSA_OAEP_SHA256 458 crypto_rsa_key_free(hapd->imsi_privacy_key); 459 hapd->imsi_privacy_key = NULL; 460 if (hapd->conf->imsi_privacy_key) { 461 hapd->imsi_privacy_key = crypto_rsa_key_read( 462 hapd->conf->imsi_privacy_key, true); 463 if (!hapd->imsi_privacy_key) { 464 wpa_printf(MSG_ERROR, 465 "Failed to read/parse IMSI privacy key %s", 466 hapd->conf->imsi_privacy_key); 467 authsrv_deinit(hapd); 468 return -1; 469 } 470 } 471 #endif /* CRYPTO_RSA_OAEP_SHA256 */ 472 473 #ifdef EAP_SIM_DB 474 if (hapd->conf->eap_sim_db) { 475 hapd->eap_sim_db_priv = 476 eap_sim_db_init(hapd->conf->eap_sim_db, 477 hapd->conf->eap_sim_db_timeout, 478 hostapd_sim_db_cb, hapd); 479 if (hapd->eap_sim_db_priv == NULL) { 480 wpa_printf(MSG_ERROR, "Failed to initialize EAP-SIM " 481 "database interface"); 482 authsrv_deinit(hapd); 483 return -1; 484 } 485 } 486 #endif /* EAP_SIM_DB */ 487 488 hapd->eap_cfg = authsrv_eap_config(hapd); 489 if (!hapd->eap_cfg) { 490 wpa_printf(MSG_ERROR, 491 "Failed to build EAP server configuration"); 492 authsrv_deinit(hapd); 493 return -1; 494 } 495 496 #ifdef RADIUS_SERVER 497 if (hapd->conf->radius_server_clients && 498 hostapd_setup_radius_srv(hapd)) 499 return -1; 500 #endif /* RADIUS_SERVER */ 501 502 return 0; 503 } 504 505 authsrv_deinit(struct hostapd_data * hapd)506 void authsrv_deinit(struct hostapd_data *hapd) 507 { 508 #ifdef CONFIG_IEEE80211BE 509 if (!hostapd_mld_is_first_bss(hapd)) { 510 wpa_printf(MSG_DEBUG, 511 "MLD: Deinit auth_serv of a non-first BSS"); 512 513 hapd->radius_srv = NULL; 514 hapd->eap_cfg = NULL; 515 #ifdef EAP_SIM_DB 516 hapd->eap_sim_db_priv = NULL; 517 #endif /* EAP_SIM_DB */ 518 #ifdef EAP_TLS_FUNCS 519 hapd->ssl_ctx = NULL; 520 #endif /* EAP_TLS_FUNCS */ 521 return; 522 } 523 #endif /* CONFIG_IEEE80211BE */ 524 525 #ifdef RADIUS_SERVER 526 radius_server_deinit(hapd->radius_srv); 527 hapd->radius_srv = NULL; 528 #endif /* RADIUS_SERVER */ 529 530 #ifdef CRYPTO_RSA_OAEP_SHA256 531 crypto_rsa_key_free(hapd->imsi_privacy_key); 532 hapd->imsi_privacy_key = NULL; 533 #endif /* CRYPTO_RSA_OAEP_SHA256 */ 534 535 #ifdef EAP_TLS_FUNCS 536 if (hapd->ssl_ctx) { 537 tls_deinit(hapd->ssl_ctx); 538 hapd->ssl_ctx = NULL; 539 } 540 #endif /* EAP_TLS_FUNCS */ 541 542 #ifdef EAP_SIM_DB 543 if (hapd->eap_sim_db_priv) { 544 eap_sim_db_deinit(hapd->eap_sim_db_priv); 545 hapd->eap_sim_db_priv = NULL; 546 } 547 #endif /* EAP_SIM_DB */ 548 549 eap_server_config_free(hapd->eap_cfg); 550 hapd->eap_cfg = NULL; 551 } 552