1e28a4053SRui Paulo /* 2e28a4053SRui Paulo * Authentication server setup 3e28a4053SRui Paulo * Copyright (c) 2002-2009, Jouni Malinen <j@w1.fi> 4e28a4053SRui Paulo * 5f05cddf9SRui Paulo * This software may be distributed under the terms of the BSD license. 6f05cddf9SRui Paulo * See README for more details. 7e28a4053SRui Paulo */ 8e28a4053SRui Paulo 9e28a4053SRui Paulo #include "utils/includes.h" 10e28a4053SRui Paulo 11e28a4053SRui Paulo #include "utils/common.h" 12e28a4053SRui Paulo #include "crypto/tls.h" 13e28a4053SRui Paulo #include "eap_server/eap.h" 14e28a4053SRui Paulo #include "eap_server/eap_sim_db.h" 15e28a4053SRui Paulo #include "eapol_auth/eapol_auth_sm.h" 16e28a4053SRui Paulo #include "radius/radius_server.h" 17e28a4053SRui Paulo #include "hostapd.h" 18e28a4053SRui Paulo #include "ap_config.h" 19e28a4053SRui Paulo #include "sta_info.h" 20e28a4053SRui Paulo #include "authsrv.h" 21e28a4053SRui Paulo 22e28a4053SRui Paulo 23e28a4053SRui Paulo #if defined(EAP_SERVER_SIM) || defined(EAP_SERVER_AKA) 24e28a4053SRui Paulo #define EAP_SIM_DB 25e28a4053SRui Paulo #endif /* EAP_SERVER_SIM || EAP_SERVER_AKA */ 26e28a4053SRui Paulo 27e28a4053SRui Paulo 28e28a4053SRui Paulo #ifdef EAP_SIM_DB 29e28a4053SRui Paulo static int hostapd_sim_db_cb_sta(struct hostapd_data *hapd, 30e28a4053SRui Paulo struct sta_info *sta, void *ctx) 31e28a4053SRui Paulo { 32e28a4053SRui Paulo if (eapol_auth_eap_pending_cb(sta->eapol_sm, ctx) == 0) 33e28a4053SRui Paulo return 1; 34e28a4053SRui Paulo return 0; 35e28a4053SRui Paulo } 36e28a4053SRui Paulo 37e28a4053SRui Paulo 38e28a4053SRui Paulo static void hostapd_sim_db_cb(void *ctx, void *session_ctx) 39e28a4053SRui Paulo { 40e28a4053SRui Paulo struct hostapd_data *hapd = ctx; 41e28a4053SRui Paulo if (ap_for_each_sta(hapd, hostapd_sim_db_cb_sta, session_ctx) == 0) { 42e28a4053SRui Paulo #ifdef RADIUS_SERVER 43e28a4053SRui Paulo radius_server_eap_pending_cb(hapd->radius_srv, session_ctx); 44e28a4053SRui Paulo #endif /* RADIUS_SERVER */ 45e28a4053SRui Paulo } 46e28a4053SRui Paulo } 47e28a4053SRui Paulo #endif /* EAP_SIM_DB */ 48e28a4053SRui Paulo 49e28a4053SRui Paulo 50e28a4053SRui Paulo #ifdef RADIUS_SERVER 51e28a4053SRui Paulo 52e28a4053SRui Paulo static int hostapd_radius_get_eap_user(void *ctx, const u8 *identity, 53e28a4053SRui Paulo size_t identity_len, int phase2, 54e28a4053SRui Paulo struct eap_user *user) 55e28a4053SRui Paulo { 56e28a4053SRui Paulo const struct hostapd_eap_user *eap_user; 57f05cddf9SRui Paulo int i; 58e28a4053SRui Paulo 59e28a4053SRui Paulo eap_user = hostapd_get_eap_user(ctx, identity, identity_len, phase2); 60e28a4053SRui Paulo if (eap_user == NULL) 61e28a4053SRui Paulo return -1; 62e28a4053SRui Paulo 63e28a4053SRui Paulo if (user == NULL) 64e28a4053SRui Paulo return 0; 65e28a4053SRui Paulo 66e28a4053SRui Paulo os_memset(user, 0, sizeof(*user)); 67f05cddf9SRui Paulo for (i = 0; i < EAP_MAX_METHODS; i++) { 68e28a4053SRui Paulo user->methods[i].vendor = eap_user->methods[i].vendor; 69e28a4053SRui Paulo user->methods[i].method = eap_user->methods[i].method; 70e28a4053SRui Paulo } 71e28a4053SRui Paulo 72e28a4053SRui Paulo if (eap_user->password) { 73e28a4053SRui Paulo user->password = os_malloc(eap_user->password_len); 74e28a4053SRui Paulo if (user->password == NULL) 75e28a4053SRui Paulo return -1; 76e28a4053SRui Paulo os_memcpy(user->password, eap_user->password, 77e28a4053SRui Paulo eap_user->password_len); 78e28a4053SRui Paulo user->password_len = eap_user->password_len; 79e28a4053SRui Paulo user->password_hash = eap_user->password_hash; 80e28a4053SRui Paulo } 81e28a4053SRui Paulo user->force_version = eap_user->force_version; 82*5b9c547cSRui Paulo user->macacl = eap_user->macacl; 83e28a4053SRui Paulo user->ttls_auth = eap_user->ttls_auth; 84*5b9c547cSRui Paulo user->remediation = eap_user->remediation; 85*5b9c547cSRui Paulo user->accept_attr = eap_user->accept_attr; 86e28a4053SRui Paulo 87e28a4053SRui Paulo return 0; 88e28a4053SRui Paulo } 89e28a4053SRui Paulo 90e28a4053SRui Paulo 91e28a4053SRui Paulo static int hostapd_setup_radius_srv(struct hostapd_data *hapd) 92e28a4053SRui Paulo { 93e28a4053SRui Paulo struct radius_server_conf srv; 94e28a4053SRui Paulo struct hostapd_bss_config *conf = hapd->conf; 95e28a4053SRui Paulo os_memset(&srv, 0, sizeof(srv)); 96e28a4053SRui Paulo srv.client_file = conf->radius_server_clients; 97e28a4053SRui Paulo srv.auth_port = conf->radius_server_auth_port; 98*5b9c547cSRui Paulo srv.acct_port = conf->radius_server_acct_port; 99f05cddf9SRui Paulo srv.conf_ctx = hapd; 100e28a4053SRui Paulo srv.eap_sim_db_priv = hapd->eap_sim_db_priv; 101e28a4053SRui Paulo srv.ssl_ctx = hapd->ssl_ctx; 102e28a4053SRui Paulo srv.msg_ctx = hapd->msg_ctx; 103e28a4053SRui Paulo srv.pac_opaque_encr_key = conf->pac_opaque_encr_key; 104e28a4053SRui Paulo srv.eap_fast_a_id = conf->eap_fast_a_id; 105e28a4053SRui Paulo srv.eap_fast_a_id_len = conf->eap_fast_a_id_len; 106e28a4053SRui Paulo srv.eap_fast_a_id_info = conf->eap_fast_a_id_info; 107e28a4053SRui Paulo srv.eap_fast_prov = conf->eap_fast_prov; 108e28a4053SRui Paulo srv.pac_key_lifetime = conf->pac_key_lifetime; 109e28a4053SRui Paulo srv.pac_key_refresh_time = conf->pac_key_refresh_time; 110e28a4053SRui Paulo srv.eap_sim_aka_result_ind = conf->eap_sim_aka_result_ind; 111e28a4053SRui Paulo srv.tnc = conf->tnc; 112e28a4053SRui Paulo srv.wps = hapd->wps; 113e28a4053SRui Paulo srv.ipv6 = conf->radius_server_ipv6; 114e28a4053SRui Paulo srv.get_eap_user = hostapd_radius_get_eap_user; 115e28a4053SRui Paulo srv.eap_req_id_text = conf->eap_req_id_text; 116e28a4053SRui Paulo srv.eap_req_id_text_len = conf->eap_req_id_text_len; 117f05cddf9SRui Paulo srv.pwd_group = conf->pwd_group; 118*5b9c547cSRui Paulo srv.server_id = conf->server_id ? conf->server_id : "hostapd"; 119*5b9c547cSRui Paulo srv.sqlite_file = conf->eap_user_sqlite; 120f05cddf9SRui Paulo #ifdef CONFIG_RADIUS_TEST 121f05cddf9SRui Paulo srv.dump_msk_file = conf->dump_msk_file; 122f05cddf9SRui Paulo #endif /* CONFIG_RADIUS_TEST */ 123*5b9c547cSRui Paulo #ifdef CONFIG_HS20 124*5b9c547cSRui Paulo srv.subscr_remediation_url = conf->subscr_remediation_url; 125*5b9c547cSRui Paulo srv.subscr_remediation_method = conf->subscr_remediation_method; 126*5b9c547cSRui Paulo #endif /* CONFIG_HS20 */ 127*5b9c547cSRui Paulo srv.erp = conf->eap_server_erp; 128*5b9c547cSRui Paulo srv.erp_domain = conf->erp_domain; 129e28a4053SRui Paulo 130e28a4053SRui Paulo hapd->radius_srv = radius_server_init(&srv); 131e28a4053SRui Paulo if (hapd->radius_srv == NULL) { 132e28a4053SRui Paulo wpa_printf(MSG_ERROR, "RADIUS server initialization failed."); 133e28a4053SRui Paulo return -1; 134e28a4053SRui Paulo } 135e28a4053SRui Paulo 136e28a4053SRui Paulo return 0; 137e28a4053SRui Paulo } 138e28a4053SRui Paulo 139e28a4053SRui Paulo #endif /* RADIUS_SERVER */ 140e28a4053SRui Paulo 141e28a4053SRui Paulo 142e28a4053SRui Paulo int authsrv_init(struct hostapd_data *hapd) 143e28a4053SRui Paulo { 144e28a4053SRui Paulo #ifdef EAP_TLS_FUNCS 145e28a4053SRui Paulo if (hapd->conf->eap_server && 146e28a4053SRui Paulo (hapd->conf->ca_cert || hapd->conf->server_cert || 147*5b9c547cSRui Paulo hapd->conf->private_key || hapd->conf->dh_file)) { 148e28a4053SRui Paulo struct tls_connection_params params; 149e28a4053SRui Paulo 150e28a4053SRui Paulo hapd->ssl_ctx = tls_init(NULL); 151e28a4053SRui Paulo if (hapd->ssl_ctx == NULL) { 152e28a4053SRui Paulo wpa_printf(MSG_ERROR, "Failed to initialize TLS"); 153e28a4053SRui Paulo authsrv_deinit(hapd); 154e28a4053SRui Paulo return -1; 155e28a4053SRui Paulo } 156e28a4053SRui Paulo 157e28a4053SRui Paulo os_memset(¶ms, 0, sizeof(params)); 158e28a4053SRui Paulo params.ca_cert = hapd->conf->ca_cert; 159e28a4053SRui Paulo params.client_cert = hapd->conf->server_cert; 160e28a4053SRui Paulo params.private_key = hapd->conf->private_key; 161e28a4053SRui Paulo params.private_key_passwd = hapd->conf->private_key_passwd; 162e28a4053SRui Paulo params.dh_file = hapd->conf->dh_file; 163*5b9c547cSRui Paulo params.openssl_ciphers = hapd->conf->openssl_ciphers; 164*5b9c547cSRui Paulo params.ocsp_stapling_response = 165*5b9c547cSRui Paulo hapd->conf->ocsp_stapling_response; 166e28a4053SRui Paulo 167e28a4053SRui Paulo if (tls_global_set_params(hapd->ssl_ctx, ¶ms)) { 168e28a4053SRui Paulo wpa_printf(MSG_ERROR, "Failed to set TLS parameters"); 169e28a4053SRui Paulo authsrv_deinit(hapd); 170e28a4053SRui Paulo return -1; 171e28a4053SRui Paulo } 172e28a4053SRui Paulo 173e28a4053SRui Paulo if (tls_global_set_verify(hapd->ssl_ctx, 174e28a4053SRui Paulo hapd->conf->check_crl)) { 175e28a4053SRui Paulo wpa_printf(MSG_ERROR, "Failed to enable check_crl"); 176e28a4053SRui Paulo authsrv_deinit(hapd); 177e28a4053SRui Paulo return -1; 178e28a4053SRui Paulo } 179e28a4053SRui Paulo } 180e28a4053SRui Paulo #endif /* EAP_TLS_FUNCS */ 181e28a4053SRui Paulo 182e28a4053SRui Paulo #ifdef EAP_SIM_DB 183e28a4053SRui Paulo if (hapd->conf->eap_sim_db) { 184e28a4053SRui Paulo hapd->eap_sim_db_priv = 185e28a4053SRui Paulo eap_sim_db_init(hapd->conf->eap_sim_db, 186e28a4053SRui Paulo hostapd_sim_db_cb, hapd); 187e28a4053SRui Paulo if (hapd->eap_sim_db_priv == NULL) { 188e28a4053SRui Paulo wpa_printf(MSG_ERROR, "Failed to initialize EAP-SIM " 189e28a4053SRui Paulo "database interface"); 190e28a4053SRui Paulo authsrv_deinit(hapd); 191e28a4053SRui Paulo return -1; 192e28a4053SRui Paulo } 193e28a4053SRui Paulo } 194e28a4053SRui Paulo #endif /* EAP_SIM_DB */ 195e28a4053SRui Paulo 196e28a4053SRui Paulo #ifdef RADIUS_SERVER 197e28a4053SRui Paulo if (hapd->conf->radius_server_clients && 198e28a4053SRui Paulo hostapd_setup_radius_srv(hapd)) 199e28a4053SRui Paulo return -1; 200e28a4053SRui Paulo #endif /* RADIUS_SERVER */ 201e28a4053SRui Paulo 202e28a4053SRui Paulo return 0; 203e28a4053SRui Paulo } 204e28a4053SRui Paulo 205e28a4053SRui Paulo 206e28a4053SRui Paulo void authsrv_deinit(struct hostapd_data *hapd) 207e28a4053SRui Paulo { 208e28a4053SRui Paulo #ifdef RADIUS_SERVER 209e28a4053SRui Paulo radius_server_deinit(hapd->radius_srv); 210e28a4053SRui Paulo hapd->radius_srv = NULL; 211e28a4053SRui Paulo #endif /* RADIUS_SERVER */ 212e28a4053SRui Paulo 213e28a4053SRui Paulo #ifdef EAP_TLS_FUNCS 214e28a4053SRui Paulo if (hapd->ssl_ctx) { 215e28a4053SRui Paulo tls_deinit(hapd->ssl_ctx); 216e28a4053SRui Paulo hapd->ssl_ctx = NULL; 217e28a4053SRui Paulo } 218e28a4053SRui Paulo #endif /* EAP_TLS_FUNCS */ 219e28a4053SRui Paulo 220e28a4053SRui Paulo #ifdef EAP_SIM_DB 221e28a4053SRui Paulo if (hapd->eap_sim_db_priv) { 222e28a4053SRui Paulo eap_sim_db_deinit(hapd->eap_sim_db_priv); 223e28a4053SRui Paulo hapd->eap_sim_db_priv = NULL; 224e28a4053SRui Paulo } 225e28a4053SRui Paulo #endif /* EAP_SIM_DB */ 226e28a4053SRui Paulo } 227