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