xref: /freebsd/contrib/wpa/src/ap/authsrv.c (revision 5b9c547c072b84410b50897cc53710c75b2f6b74)
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(&params, 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, &params)) {
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