1e28a4053SRui Paulo /* 2e28a4053SRui Paulo * Authentication server setup 3e28a4053SRui Paulo * Copyright (c) 2002-2009, Jouni Malinen <j@w1.fi> 4e28a4053SRui Paulo * 5*f05cddf9SRui Paulo * This software may be distributed under the terms of the BSD license. 6*f05cddf9SRui 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; 57*f05cddf9SRui 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)); 67*f05cddf9SRui 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; 82e28a4053SRui Paulo user->ttls_auth = eap_user->ttls_auth; 83e28a4053SRui Paulo 84e28a4053SRui Paulo return 0; 85e28a4053SRui Paulo } 86e28a4053SRui Paulo 87e28a4053SRui Paulo 88e28a4053SRui Paulo static int hostapd_setup_radius_srv(struct hostapd_data *hapd) 89e28a4053SRui Paulo { 90e28a4053SRui Paulo struct radius_server_conf srv; 91e28a4053SRui Paulo struct hostapd_bss_config *conf = hapd->conf; 92e28a4053SRui Paulo os_memset(&srv, 0, sizeof(srv)); 93e28a4053SRui Paulo srv.client_file = conf->radius_server_clients; 94e28a4053SRui Paulo srv.auth_port = conf->radius_server_auth_port; 95*f05cddf9SRui Paulo srv.conf_ctx = hapd; 96e28a4053SRui Paulo srv.eap_sim_db_priv = hapd->eap_sim_db_priv; 97e28a4053SRui Paulo srv.ssl_ctx = hapd->ssl_ctx; 98e28a4053SRui Paulo srv.msg_ctx = hapd->msg_ctx; 99e28a4053SRui Paulo srv.pac_opaque_encr_key = conf->pac_opaque_encr_key; 100e28a4053SRui Paulo srv.eap_fast_a_id = conf->eap_fast_a_id; 101e28a4053SRui Paulo srv.eap_fast_a_id_len = conf->eap_fast_a_id_len; 102e28a4053SRui Paulo srv.eap_fast_a_id_info = conf->eap_fast_a_id_info; 103e28a4053SRui Paulo srv.eap_fast_prov = conf->eap_fast_prov; 104e28a4053SRui Paulo srv.pac_key_lifetime = conf->pac_key_lifetime; 105e28a4053SRui Paulo srv.pac_key_refresh_time = conf->pac_key_refresh_time; 106e28a4053SRui Paulo srv.eap_sim_aka_result_ind = conf->eap_sim_aka_result_ind; 107e28a4053SRui Paulo srv.tnc = conf->tnc; 108e28a4053SRui Paulo srv.wps = hapd->wps; 109e28a4053SRui Paulo srv.ipv6 = conf->radius_server_ipv6; 110e28a4053SRui Paulo srv.get_eap_user = hostapd_radius_get_eap_user; 111e28a4053SRui Paulo srv.eap_req_id_text = conf->eap_req_id_text; 112e28a4053SRui Paulo srv.eap_req_id_text_len = conf->eap_req_id_text_len; 113*f05cddf9SRui Paulo srv.pwd_group = conf->pwd_group; 114*f05cddf9SRui Paulo #ifdef CONFIG_RADIUS_TEST 115*f05cddf9SRui Paulo srv.dump_msk_file = conf->dump_msk_file; 116*f05cddf9SRui Paulo #endif /* CONFIG_RADIUS_TEST */ 117e28a4053SRui Paulo 118e28a4053SRui Paulo hapd->radius_srv = radius_server_init(&srv); 119e28a4053SRui Paulo if (hapd->radius_srv == NULL) { 120e28a4053SRui Paulo wpa_printf(MSG_ERROR, "RADIUS server initialization failed."); 121e28a4053SRui Paulo return -1; 122e28a4053SRui Paulo } 123e28a4053SRui Paulo 124e28a4053SRui Paulo return 0; 125e28a4053SRui Paulo } 126e28a4053SRui Paulo 127e28a4053SRui Paulo #endif /* RADIUS_SERVER */ 128e28a4053SRui Paulo 129e28a4053SRui Paulo 130e28a4053SRui Paulo int authsrv_init(struct hostapd_data *hapd) 131e28a4053SRui Paulo { 132e28a4053SRui Paulo #ifdef EAP_TLS_FUNCS 133e28a4053SRui Paulo if (hapd->conf->eap_server && 134e28a4053SRui Paulo (hapd->conf->ca_cert || hapd->conf->server_cert || 135e28a4053SRui Paulo hapd->conf->dh_file)) { 136e28a4053SRui Paulo struct tls_connection_params params; 137e28a4053SRui Paulo 138e28a4053SRui Paulo hapd->ssl_ctx = tls_init(NULL); 139e28a4053SRui Paulo if (hapd->ssl_ctx == NULL) { 140e28a4053SRui Paulo wpa_printf(MSG_ERROR, "Failed to initialize TLS"); 141e28a4053SRui Paulo authsrv_deinit(hapd); 142e28a4053SRui Paulo return -1; 143e28a4053SRui Paulo } 144e28a4053SRui Paulo 145e28a4053SRui Paulo os_memset(¶ms, 0, sizeof(params)); 146e28a4053SRui Paulo params.ca_cert = hapd->conf->ca_cert; 147e28a4053SRui Paulo params.client_cert = hapd->conf->server_cert; 148e28a4053SRui Paulo params.private_key = hapd->conf->private_key; 149e28a4053SRui Paulo params.private_key_passwd = hapd->conf->private_key_passwd; 150e28a4053SRui Paulo params.dh_file = hapd->conf->dh_file; 151e28a4053SRui Paulo 152e28a4053SRui Paulo if (tls_global_set_params(hapd->ssl_ctx, ¶ms)) { 153e28a4053SRui Paulo wpa_printf(MSG_ERROR, "Failed to set TLS parameters"); 154e28a4053SRui Paulo authsrv_deinit(hapd); 155e28a4053SRui Paulo return -1; 156e28a4053SRui Paulo } 157e28a4053SRui Paulo 158e28a4053SRui Paulo if (tls_global_set_verify(hapd->ssl_ctx, 159e28a4053SRui Paulo hapd->conf->check_crl)) { 160e28a4053SRui Paulo wpa_printf(MSG_ERROR, "Failed to enable check_crl"); 161e28a4053SRui Paulo authsrv_deinit(hapd); 162e28a4053SRui Paulo return -1; 163e28a4053SRui Paulo } 164e28a4053SRui Paulo } 165e28a4053SRui Paulo #endif /* EAP_TLS_FUNCS */ 166e28a4053SRui Paulo 167e28a4053SRui Paulo #ifdef EAP_SIM_DB 168e28a4053SRui Paulo if (hapd->conf->eap_sim_db) { 169e28a4053SRui Paulo hapd->eap_sim_db_priv = 170e28a4053SRui Paulo eap_sim_db_init(hapd->conf->eap_sim_db, 171e28a4053SRui Paulo hostapd_sim_db_cb, hapd); 172e28a4053SRui Paulo if (hapd->eap_sim_db_priv == NULL) { 173e28a4053SRui Paulo wpa_printf(MSG_ERROR, "Failed to initialize EAP-SIM " 174e28a4053SRui Paulo "database interface"); 175e28a4053SRui Paulo authsrv_deinit(hapd); 176e28a4053SRui Paulo return -1; 177e28a4053SRui Paulo } 178e28a4053SRui Paulo } 179e28a4053SRui Paulo #endif /* EAP_SIM_DB */ 180e28a4053SRui Paulo 181e28a4053SRui Paulo #ifdef RADIUS_SERVER 182e28a4053SRui Paulo if (hapd->conf->radius_server_clients && 183e28a4053SRui Paulo hostapd_setup_radius_srv(hapd)) 184e28a4053SRui Paulo return -1; 185e28a4053SRui Paulo #endif /* RADIUS_SERVER */ 186e28a4053SRui Paulo 187e28a4053SRui Paulo return 0; 188e28a4053SRui Paulo } 189e28a4053SRui Paulo 190e28a4053SRui Paulo 191e28a4053SRui Paulo void authsrv_deinit(struct hostapd_data *hapd) 192e28a4053SRui Paulo { 193e28a4053SRui Paulo #ifdef RADIUS_SERVER 194e28a4053SRui Paulo radius_server_deinit(hapd->radius_srv); 195e28a4053SRui Paulo hapd->radius_srv = NULL; 196e28a4053SRui Paulo #endif /* RADIUS_SERVER */ 197e28a4053SRui Paulo 198e28a4053SRui Paulo #ifdef EAP_TLS_FUNCS 199e28a4053SRui Paulo if (hapd->ssl_ctx) { 200e28a4053SRui Paulo tls_deinit(hapd->ssl_ctx); 201e28a4053SRui Paulo hapd->ssl_ctx = NULL; 202e28a4053SRui Paulo } 203e28a4053SRui Paulo #endif /* EAP_TLS_FUNCS */ 204e28a4053SRui Paulo 205e28a4053SRui Paulo #ifdef EAP_SIM_DB 206e28a4053SRui Paulo if (hapd->eap_sim_db_priv) { 207e28a4053SRui Paulo eap_sim_db_deinit(hapd->eap_sim_db_priv); 208e28a4053SRui Paulo hapd->eap_sim_db_priv = NULL; 209e28a4053SRui Paulo } 210e28a4053SRui Paulo #endif /* EAP_SIM_DB */ 211e28a4053SRui Paulo } 212