1214501Srpaulo/*
2214501Srpaulo * Authentication server setup
3214501Srpaulo * Copyright (c) 2002-2009, Jouni Malinen <j@w1.fi>
4214501Srpaulo *
5252726Srpaulo * This software may be distributed under the terms of the BSD license.
6252726Srpaulo * See README for more details.
7214501Srpaulo */
8214501Srpaulo
9214501Srpaulo#include "utils/includes.h"
10214501Srpaulo
11214501Srpaulo#include "utils/common.h"
12214501Srpaulo#include "crypto/tls.h"
13214501Srpaulo#include "eap_server/eap.h"
14214501Srpaulo#include "eap_server/eap_sim_db.h"
15214501Srpaulo#include "eapol_auth/eapol_auth_sm.h"
16214501Srpaulo#include "radius/radius_server.h"
17214501Srpaulo#include "hostapd.h"
18214501Srpaulo#include "ap_config.h"
19214501Srpaulo#include "sta_info.h"
20214501Srpaulo#include "authsrv.h"
21214501Srpaulo
22214501Srpaulo
23214501Srpaulo#if defined(EAP_SERVER_SIM) || defined(EAP_SERVER_AKA)
24214501Srpaulo#define EAP_SIM_DB
25214501Srpaulo#endif /* EAP_SERVER_SIM || EAP_SERVER_AKA */
26214501Srpaulo
27214501Srpaulo
28214501Srpaulo#ifdef EAP_SIM_DB
29214501Srpaulostatic int hostapd_sim_db_cb_sta(struct hostapd_data *hapd,
30214501Srpaulo				 struct sta_info *sta, void *ctx)
31214501Srpaulo{
32214501Srpaulo	if (eapol_auth_eap_pending_cb(sta->eapol_sm, ctx) == 0)
33214501Srpaulo		return 1;
34214501Srpaulo	return 0;
35214501Srpaulo}
36214501Srpaulo
37214501Srpaulo
38214501Srpaulostatic void hostapd_sim_db_cb(void *ctx, void *session_ctx)
39214501Srpaulo{
40214501Srpaulo	struct hostapd_data *hapd = ctx;
41214501Srpaulo	if (ap_for_each_sta(hapd, hostapd_sim_db_cb_sta, session_ctx) == 0) {
42214501Srpaulo#ifdef RADIUS_SERVER
43214501Srpaulo		radius_server_eap_pending_cb(hapd->radius_srv, session_ctx);
44214501Srpaulo#endif /* RADIUS_SERVER */
45214501Srpaulo	}
46214501Srpaulo}
47214501Srpaulo#endif /* EAP_SIM_DB */
48214501Srpaulo
49214501Srpaulo
50214501Srpaulo#ifdef RADIUS_SERVER
51214501Srpaulo
52214501Srpaulostatic int hostapd_radius_get_eap_user(void *ctx, const u8 *identity,
53214501Srpaulo				       size_t identity_len, int phase2,
54214501Srpaulo				       struct eap_user *user)
55214501Srpaulo{
56214501Srpaulo	const struct hostapd_eap_user *eap_user;
57252726Srpaulo	int i;
58214501Srpaulo
59214501Srpaulo	eap_user = hostapd_get_eap_user(ctx, identity, identity_len, phase2);
60214501Srpaulo	if (eap_user == NULL)
61214501Srpaulo		return -1;
62214501Srpaulo
63214501Srpaulo	if (user == NULL)
64214501Srpaulo		return 0;
65214501Srpaulo
66214501Srpaulo	os_memset(user, 0, sizeof(*user));
67252726Srpaulo	for (i = 0; i < EAP_MAX_METHODS; i++) {
68214501Srpaulo		user->methods[i].vendor = eap_user->methods[i].vendor;
69214501Srpaulo		user->methods[i].method = eap_user->methods[i].method;
70214501Srpaulo	}
71214501Srpaulo
72214501Srpaulo	if (eap_user->password) {
73214501Srpaulo		user->password = os_malloc(eap_user->password_len);
74214501Srpaulo		if (user->password == NULL)
75214501Srpaulo			return -1;
76214501Srpaulo		os_memcpy(user->password, eap_user->password,
77214501Srpaulo			  eap_user->password_len);
78214501Srpaulo		user->password_len = eap_user->password_len;
79214501Srpaulo		user->password_hash = eap_user->password_hash;
80214501Srpaulo	}
81214501Srpaulo	user->force_version = eap_user->force_version;
82214501Srpaulo	user->ttls_auth = eap_user->ttls_auth;
83214501Srpaulo
84214501Srpaulo	return 0;
85214501Srpaulo}
86214501Srpaulo
87214501Srpaulo
88214501Srpaulostatic int hostapd_setup_radius_srv(struct hostapd_data *hapd)
89214501Srpaulo{
90214501Srpaulo	struct radius_server_conf srv;
91214501Srpaulo	struct hostapd_bss_config *conf = hapd->conf;
92214501Srpaulo	os_memset(&srv, 0, sizeof(srv));
93214501Srpaulo	srv.client_file = conf->radius_server_clients;
94214501Srpaulo	srv.auth_port = conf->radius_server_auth_port;
95252726Srpaulo	srv.conf_ctx = hapd;
96214501Srpaulo	srv.eap_sim_db_priv = hapd->eap_sim_db_priv;
97214501Srpaulo	srv.ssl_ctx = hapd->ssl_ctx;
98214501Srpaulo	srv.msg_ctx = hapd->msg_ctx;
99214501Srpaulo	srv.pac_opaque_encr_key = conf->pac_opaque_encr_key;
100214501Srpaulo	srv.eap_fast_a_id = conf->eap_fast_a_id;
101214501Srpaulo	srv.eap_fast_a_id_len = conf->eap_fast_a_id_len;
102214501Srpaulo	srv.eap_fast_a_id_info = conf->eap_fast_a_id_info;
103214501Srpaulo	srv.eap_fast_prov = conf->eap_fast_prov;
104214501Srpaulo	srv.pac_key_lifetime = conf->pac_key_lifetime;
105214501Srpaulo	srv.pac_key_refresh_time = conf->pac_key_refresh_time;
106214501Srpaulo	srv.eap_sim_aka_result_ind = conf->eap_sim_aka_result_ind;
107214501Srpaulo	srv.tnc = conf->tnc;
108214501Srpaulo	srv.wps = hapd->wps;
109214501Srpaulo	srv.ipv6 = conf->radius_server_ipv6;
110214501Srpaulo	srv.get_eap_user = hostapd_radius_get_eap_user;
111214501Srpaulo	srv.eap_req_id_text = conf->eap_req_id_text;
112214501Srpaulo	srv.eap_req_id_text_len = conf->eap_req_id_text_len;
113252726Srpaulo	srv.pwd_group = conf->pwd_group;
114252726Srpaulo#ifdef CONFIG_RADIUS_TEST
115252726Srpaulo	srv.dump_msk_file = conf->dump_msk_file;
116252726Srpaulo#endif /* CONFIG_RADIUS_TEST */
117214501Srpaulo
118214501Srpaulo	hapd->radius_srv = radius_server_init(&srv);
119214501Srpaulo	if (hapd->radius_srv == NULL) {
120214501Srpaulo		wpa_printf(MSG_ERROR, "RADIUS server initialization failed.");
121214501Srpaulo		return -1;
122214501Srpaulo	}
123214501Srpaulo
124214501Srpaulo	return 0;
125214501Srpaulo}
126214501Srpaulo
127214501Srpaulo#endif /* RADIUS_SERVER */
128214501Srpaulo
129214501Srpaulo
130214501Srpauloint authsrv_init(struct hostapd_data *hapd)
131214501Srpaulo{
132214501Srpaulo#ifdef EAP_TLS_FUNCS
133214501Srpaulo	if (hapd->conf->eap_server &&
134214501Srpaulo	    (hapd->conf->ca_cert || hapd->conf->server_cert ||
135214501Srpaulo	     hapd->conf->dh_file)) {
136214501Srpaulo		struct tls_connection_params params;
137214501Srpaulo
138214501Srpaulo		hapd->ssl_ctx = tls_init(NULL);
139214501Srpaulo		if (hapd->ssl_ctx == NULL) {
140214501Srpaulo			wpa_printf(MSG_ERROR, "Failed to initialize TLS");
141214501Srpaulo			authsrv_deinit(hapd);
142214501Srpaulo			return -1;
143214501Srpaulo		}
144214501Srpaulo
145214501Srpaulo		os_memset(&params, 0, sizeof(params));
146214501Srpaulo		params.ca_cert = hapd->conf->ca_cert;
147214501Srpaulo		params.client_cert = hapd->conf->server_cert;
148214501Srpaulo		params.private_key = hapd->conf->private_key;
149214501Srpaulo		params.private_key_passwd = hapd->conf->private_key_passwd;
150214501Srpaulo		params.dh_file = hapd->conf->dh_file;
151214501Srpaulo
152214501Srpaulo		if (tls_global_set_params(hapd->ssl_ctx, &params)) {
153214501Srpaulo			wpa_printf(MSG_ERROR, "Failed to set TLS parameters");
154214501Srpaulo			authsrv_deinit(hapd);
155214501Srpaulo			return -1;
156214501Srpaulo		}
157214501Srpaulo
158214501Srpaulo		if (tls_global_set_verify(hapd->ssl_ctx,
159214501Srpaulo					  hapd->conf->check_crl)) {
160214501Srpaulo			wpa_printf(MSG_ERROR, "Failed to enable check_crl");
161214501Srpaulo			authsrv_deinit(hapd);
162214501Srpaulo			return -1;
163214501Srpaulo		}
164214501Srpaulo	}
165214501Srpaulo#endif /* EAP_TLS_FUNCS */
166214501Srpaulo
167214501Srpaulo#ifdef EAP_SIM_DB
168214501Srpaulo	if (hapd->conf->eap_sim_db) {
169214501Srpaulo		hapd->eap_sim_db_priv =
170214501Srpaulo			eap_sim_db_init(hapd->conf->eap_sim_db,
171214501Srpaulo					hostapd_sim_db_cb, hapd);
172214501Srpaulo		if (hapd->eap_sim_db_priv == NULL) {
173214501Srpaulo			wpa_printf(MSG_ERROR, "Failed to initialize EAP-SIM "
174214501Srpaulo				   "database interface");
175214501Srpaulo			authsrv_deinit(hapd);
176214501Srpaulo			return -1;
177214501Srpaulo		}
178214501Srpaulo	}
179214501Srpaulo#endif /* EAP_SIM_DB */
180214501Srpaulo
181214501Srpaulo#ifdef RADIUS_SERVER
182214501Srpaulo	if (hapd->conf->radius_server_clients &&
183214501Srpaulo	    hostapd_setup_radius_srv(hapd))
184214501Srpaulo		return -1;
185214501Srpaulo#endif /* RADIUS_SERVER */
186214501Srpaulo
187214501Srpaulo	return 0;
188214501Srpaulo}
189214501Srpaulo
190214501Srpaulo
191214501Srpaulovoid authsrv_deinit(struct hostapd_data *hapd)
192214501Srpaulo{
193214501Srpaulo#ifdef RADIUS_SERVER
194214501Srpaulo	radius_server_deinit(hapd->radius_srv);
195214501Srpaulo	hapd->radius_srv = NULL;
196214501Srpaulo#endif /* RADIUS_SERVER */
197214501Srpaulo
198214501Srpaulo#ifdef EAP_TLS_FUNCS
199214501Srpaulo	if (hapd->ssl_ctx) {
200214501Srpaulo		tls_deinit(hapd->ssl_ctx);
201214501Srpaulo		hapd->ssl_ctx = NULL;
202214501Srpaulo	}
203214501Srpaulo#endif /* EAP_TLS_FUNCS */
204214501Srpaulo
205214501Srpaulo#ifdef EAP_SIM_DB
206214501Srpaulo	if (hapd->eap_sim_db_priv) {
207214501Srpaulo		eap_sim_db_deinit(hapd->eap_sim_db_priv);
208214501Srpaulo		hapd->eap_sim_db_priv = NULL;
209214501Srpaulo	}
210214501Srpaulo#endif /* EAP_SIM_DB */
211214501Srpaulo}
212