1 /*
2 * Authentication server setup
3 * Copyright (c) 2002-2009, Jouni Malinen <j@w1.fi>
4 *
5 * This software may be distributed under the terms of the BSD license.
6 * See README for more details.
7 */
8
9 #include "utils/includes.h"
10
11 #include "utils/common.h"
12 #include "crypto/crypto.h"
13 #include "crypto/tls.h"
14 #include "eap_server/eap.h"
15 #include "eap_server/eap_sim_db.h"
16 #include "eapol_auth/eapol_auth_sm.h"
17 #include "radius/radius.h"
18 #include "radius/radius_server.h"
19 #include "hostapd.h"
20 #include "ap_config.h"
21 #include "sta_info.h"
22 #include "authsrv.h"
23
24
25 #if defined(EAP_SERVER_SIM) || defined(EAP_SERVER_AKA)
26 #define EAP_SIM_DB
27 #endif /* EAP_SERVER_SIM || EAP_SERVER_AKA */
28
29
30 #ifdef EAP_SIM_DB
hostapd_sim_db_cb_sta(struct hostapd_data * hapd,struct sta_info * sta,void * ctx)31 static int hostapd_sim_db_cb_sta(struct hostapd_data *hapd,
32 struct sta_info *sta, void *ctx)
33 {
34 if (eapol_auth_eap_pending_cb(sta->eapol_sm, ctx) == 0)
35 return 1;
36 return 0;
37 }
38
39
hostapd_sim_db_cb(void * ctx,void * session_ctx)40 static void hostapd_sim_db_cb(void *ctx, void *session_ctx)
41 {
42 struct hostapd_data *hapd = ctx;
43 if (ap_for_each_sta(hapd, hostapd_sim_db_cb_sta, session_ctx) == 0) {
44 #ifdef RADIUS_SERVER
45 radius_server_eap_pending_cb(hapd->radius_srv, session_ctx);
46 #endif /* RADIUS_SERVER */
47 }
48 }
49 #endif /* EAP_SIM_DB */
50
51
52 #ifdef RADIUS_SERVER
53
hostapd_radius_get_eap_user(void * ctx,const u8 * identity,size_t identity_len,int phase2,struct eap_user * user)54 static int hostapd_radius_get_eap_user(void *ctx, const u8 *identity,
55 size_t identity_len, int phase2,
56 struct eap_user *user)
57 {
58 const struct hostapd_eap_user *eap_user;
59 int i;
60 int rv = -1;
61
62 eap_user = hostapd_get_eap_user(ctx, identity, identity_len, phase2);
63 if (eap_user == NULL)
64 goto out;
65
66 if (user == NULL)
67 return 0;
68
69 os_memset(user, 0, sizeof(*user));
70 for (i = 0; i < EAP_MAX_METHODS; i++) {
71 user->methods[i].vendor = eap_user->methods[i].vendor;
72 user->methods[i].method = eap_user->methods[i].method;
73 }
74
75 if (eap_user->password) {
76 user->password = os_memdup(eap_user->password,
77 eap_user->password_len);
78 if (user->password == NULL)
79 goto out;
80 user->password_len = eap_user->password_len;
81 user->password_hash = eap_user->password_hash;
82 if (eap_user->salt && eap_user->salt_len) {
83 user->salt = os_memdup(eap_user->salt,
84 eap_user->salt_len);
85 if (!user->salt)
86 goto out;
87 user->salt_len = eap_user->salt_len;
88 }
89 }
90 user->force_version = eap_user->force_version;
91 user->macacl = eap_user->macacl;
92 user->ttls_auth = eap_user->ttls_auth;
93 user->accept_attr = eap_user->accept_attr;
94 user->t_c_timestamp = eap_user->t_c_timestamp;
95 rv = 0;
96
97 out:
98 if (rv)
99 wpa_printf(MSG_DEBUG, "%s: Failed to find user", __func__);
100
101 return rv;
102 }
103
104
105 /**
106 * hostapd_radius_log_acct_req - Callback for logging received RADIUS
107 * accounting requests
108 * @ctx: Context (struct hostapd_data)
109 * @msg: Received RADIUS accounting request
110 * @status_type: Status type from the message (parsed Acct-Status-Type
111 * attribute)
112 * Returns: 0 on success, -1 on failure
113 */
hostapd_radius_log_acct_req(void * ctx,struct radius_msg * msg,u32 status_type)114 static int hostapd_radius_log_acct_req(void *ctx, struct radius_msg *msg,
115 u32 status_type)
116 {
117 char nas_id[RADIUS_MAX_ATTR_LEN + 1] = "";
118 char session_id[RADIUS_MAX_ATTR_LEN + 1] = "";
119 char username[RADIUS_MAX_ATTR_LEN + 1] = "";
120 char calling_station_id[3 * ETH_ALEN] = "";
121 u32 session_time = 0, terminate_cause = 0,
122 bytes_in = 0, bytes_out = 0,
123 packets_in = 0, packets_out = 0,
124 gigawords_in = 0, gigawords_out = 0;
125 unsigned long long total_bytes_in = 0, total_bytes_out = 0;
126
127 /* Parse NAS identification (required by RFC 2866, section 4.1) */
128 if (radius_msg_get_attr(msg, RADIUS_ATTR_NAS_IDENTIFIER, (u8 *) nas_id,
129 sizeof(nas_id) - 1))
130 nas_id[0] = '\0';
131
132 /* Process Accounting-On and Accounting-Off messages separately */
133 if (status_type == RADIUS_ACCT_STATUS_TYPE_ACCOUNTING_ON ||
134 status_type == RADIUS_ACCT_STATUS_TYPE_ACCOUNTING_OFF) {
135 wpa_printf(MSG_INFO, "RADIUS ACCT: NAS='%s' status='%s'",
136 nas_id,
137 status_type == RADIUS_ACCT_STATUS_TYPE_ACCOUNTING_ON
138 ? "Accounting-On" : "Accounting-Off");
139 return 0;
140 }
141
142 /* Parse session ID (required by RFC 2866, section 5.5) */
143 if (radius_msg_get_attr(msg, RADIUS_ATTR_ACCT_SESSION_ID,
144 (u8 *) session_id,
145 sizeof(session_id) - 1) == 0) {
146 wpa_printf(MSG_DEBUG,
147 "RADIUS ACCT: request doesn't include session ID");
148 return -1;
149 }
150
151 /* Parse user name */
152 radius_msg_get_attr(msg, RADIUS_ATTR_USER_NAME, (u8 *) username,
153 sizeof(username) - 1);
154
155 /* Parse device identifier */
156 radius_msg_get_attr(msg, RADIUS_ATTR_CALLING_STATION_ID,
157 (u8 *) calling_station_id,
158 sizeof(calling_station_id) - 1);
159
160 switch (status_type) {
161 case RADIUS_ACCT_STATUS_TYPE_START:
162 wpa_printf(MSG_INFO,
163 "RADIUS ACCT: NAS='%s' session='%s' status='Accounting-Start' station='%s' username='%s'",
164 nas_id, session_id, calling_station_id, username);
165 break;
166 case RADIUS_ACCT_STATUS_TYPE_STOP:
167 case RADIUS_ACCT_STATUS_TYPE_INTERIM_UPDATE:
168 /* Parse counters */
169 radius_msg_get_attr_int32(msg, RADIUS_ATTR_ACCT_SESSION_TIME,
170 &session_time);
171 radius_msg_get_attr_int32(msg,
172 RADIUS_ATTR_ACCT_TERMINATE_CAUSE,
173 &terminate_cause);
174 radius_msg_get_attr_int32(msg, RADIUS_ATTR_ACCT_INPUT_OCTETS,
175 &bytes_in);
176 radius_msg_get_attr_int32(msg, RADIUS_ATTR_ACCT_OUTPUT_OCTETS,
177 &bytes_out);
178 radius_msg_get_attr_int32(msg, RADIUS_ATTR_ACCT_INPUT_PACKETS,
179 &packets_in);
180 radius_msg_get_attr_int32(msg, RADIUS_ATTR_ACCT_OUTPUT_PACKETS,
181 &packets_out);
182 radius_msg_get_attr_int32(msg,
183 RADIUS_ATTR_ACCT_INPUT_GIGAWORDS,
184 &gigawords_in);
185 radius_msg_get_attr_int32(msg,
186 RADIUS_ATTR_ACCT_OUTPUT_GIGAWORDS,
187 &gigawords_out);
188
189 /* RFC 2869, section 5.1 and 5.2 */
190 total_bytes_in = ((u64) gigawords_in << 32) + bytes_in;
191 total_bytes_out = ((u64) gigawords_out << 32) + bytes_out;
192
193 wpa_printf(MSG_INFO,
194 "RADIUS ACCT: NAS='%s' session='%s' status='%s' station='%s' username='%s' session_time=%u term_cause=%u pck_in=%u pck_out=%u bytes_in=%llu bytes_out=%llu",
195 nas_id, session_id,
196 status_type == RADIUS_ACCT_STATUS_TYPE_STOP ?
197 "Accounting-Stop" : "Accounting-Interim-Update",
198 calling_station_id, username, session_time,
199 terminate_cause, packets_in, packets_out,
200 total_bytes_in, total_bytes_out);
201 break;
202 default:
203 wpa_printf(MSG_DEBUG,
204 "RADIUS ACCT: Unknown request status type %u",
205 status_type);
206 return -1;
207 }
208
209 return 0;
210 }
211
212
hostapd_setup_radius_srv(struct hostapd_data * hapd)213 static int hostapd_setup_radius_srv(struct hostapd_data *hapd)
214 {
215 struct radius_server_conf srv;
216 struct hostapd_bss_config *conf = hapd->conf;
217
218 #ifdef CONFIG_IEEE80211BE
219 if (!hostapd_mld_is_first_bss(hapd)) {
220 struct hostapd_data *first;
221
222 wpa_printf(MSG_DEBUG,
223 "MLD: Using RADIUS server of the first BSS");
224
225 first = hostapd_mld_get_first_bss(hapd);
226 if (!first)
227 return -1;
228 hapd->radius_srv = first->radius_srv;
229 return 0;
230 }
231 #endif /* CONFIG_IEEE80211BE */
232
233 os_memset(&srv, 0, sizeof(srv));
234 srv.client_file = conf->radius_server_clients;
235 srv.auth_port = conf->radius_server_auth_port;
236 srv.acct_port = conf->radius_server_acct_port;
237 srv.conf_ctx = hapd;
238 srv.ipv6 = conf->radius_server_ipv6;
239 srv.get_eap_user = hostapd_radius_get_eap_user;
240 if (conf->radius_server_acct_log)
241 srv.acct_req_cb = hostapd_radius_log_acct_req;
242 srv.eap_req_id_text = conf->eap_req_id_text;
243 srv.eap_req_id_text_len = conf->eap_req_id_text_len;
244 srv.sqlite_file = conf->eap_user_sqlite;
245 #ifdef CONFIG_RADIUS_TEST
246 srv.dump_msk_file = conf->dump_msk_file;
247 #endif /* CONFIG_RADIUS_TEST */
248 #ifdef CONFIG_HS20
249 srv.t_c_server_url = conf->t_c_server_url;
250 #endif /* CONFIG_HS20 */
251 srv.erp_domain = conf->erp_domain;
252 srv.eap_cfg = hapd->eap_cfg;
253
254 hapd->radius_srv = radius_server_init(&srv);
255 if (hapd->radius_srv == NULL) {
256 wpa_printf(MSG_ERROR, "RADIUS server initialization failed.");
257 return -1;
258 }
259
260 return 0;
261 }
262
263 #endif /* RADIUS_SERVER */
264
265
266 #ifdef EAP_TLS_FUNCS
authsrv_tls_event(void * ctx,enum tls_event ev,union tls_event_data * data)267 static void authsrv_tls_event(void *ctx, enum tls_event ev,
268 union tls_event_data *data)
269 {
270 switch (ev) {
271 case TLS_CERT_CHAIN_SUCCESS:
272 wpa_printf(MSG_DEBUG, "authsrv: remote certificate verification success");
273 break;
274 case TLS_CERT_CHAIN_FAILURE:
275 wpa_printf(MSG_INFO, "authsrv: certificate chain failure: reason=%d depth=%d subject='%s' err='%s'",
276 data->cert_fail.reason,
277 data->cert_fail.depth,
278 data->cert_fail.subject,
279 data->cert_fail.reason_txt);
280 break;
281 case TLS_PEER_CERTIFICATE:
282 wpa_printf(MSG_DEBUG, "authsrv: peer certificate: depth=%d serial_num=%s subject=%s",
283 data->peer_cert.depth,
284 data->peer_cert.serial_num ? data->peer_cert.serial_num : "N/A",
285 data->peer_cert.subject);
286 break;
287 case TLS_ALERT:
288 if (data->alert.is_local)
289 wpa_printf(MSG_DEBUG, "authsrv: local TLS alert: %s",
290 data->alert.description);
291 else
292 wpa_printf(MSG_DEBUG, "authsrv: remote TLS alert: %s",
293 data->alert.description);
294 break;
295 case TLS_UNSAFE_RENEGOTIATION_DISABLED:
296 /* Not applicable to TLS server */
297 break;
298 }
299 }
300 #endif /* EAP_TLS_FUNCS */
301
302
authsrv_eap_config(struct hostapd_data * hapd)303 static struct eap_config * authsrv_eap_config(struct hostapd_data *hapd)
304 {
305 struct eap_config *cfg;
306
307 cfg = os_zalloc(sizeof(*cfg));
308 if (!cfg)
309 return NULL;
310
311 cfg->eap_server = hapd->conf->eap_server;
312 cfg->ssl_ctx = hapd->ssl_ctx;
313 cfg->msg_ctx = hapd->msg_ctx;
314 cfg->eap_sim_db_priv = hapd->eap_sim_db_priv;
315 cfg->tls_session_lifetime = hapd->conf->tls_session_lifetime;
316 cfg->tls_flags = hapd->conf->tls_flags;
317 cfg->max_auth_rounds = hapd->conf->max_auth_rounds;
318 cfg->max_auth_rounds_short = hapd->conf->max_auth_rounds_short;
319 if (hapd->conf->pac_opaque_encr_key)
320 cfg->pac_opaque_encr_key =
321 os_memdup(hapd->conf->pac_opaque_encr_key, 16);
322 if (hapd->conf->eap_fast_a_id) {
323 cfg->eap_fast_a_id = os_memdup(hapd->conf->eap_fast_a_id,
324 hapd->conf->eap_fast_a_id_len);
325 cfg->eap_fast_a_id_len = hapd->conf->eap_fast_a_id_len;
326 }
327 if (hapd->conf->eap_fast_a_id_info)
328 cfg->eap_fast_a_id_info =
329 os_strdup(hapd->conf->eap_fast_a_id_info);
330 cfg->eap_fast_prov = hapd->conf->eap_fast_prov;
331 cfg->pac_key_lifetime = hapd->conf->pac_key_lifetime;
332 cfg->pac_key_refresh_time = hapd->conf->pac_key_refresh_time;
333 cfg->eap_teap_auth = hapd->conf->eap_teap_auth;
334 cfg->eap_teap_separate_result = hapd->conf->eap_teap_separate_result;
335 cfg->eap_teap_id = hapd->conf->eap_teap_id;
336 cfg->eap_teap_method_sequence = hapd->conf->eap_teap_method_sequence;
337 cfg->eap_sim_aka_result_ind = hapd->conf->eap_sim_aka_result_ind;
338 cfg->eap_sim_id = hapd->conf->eap_sim_id;
339 cfg->imsi_privacy_key = hapd->imsi_privacy_key;
340 cfg->eap_sim_aka_fast_reauth_limit =
341 hapd->conf->eap_sim_aka_fast_reauth_limit;
342 cfg->tnc = hapd->conf->tnc;
343 cfg->wps = hapd->wps;
344 cfg->fragment_size = hapd->conf->fragment_size;
345 cfg->pwd_group = hapd->conf->pwd_group;
346 cfg->pbc_in_m1 = hapd->conf->pbc_in_m1;
347 if (hapd->conf->server_id) {
348 cfg->server_id = (u8 *) os_strdup(hapd->conf->server_id);
349 cfg->server_id_len = os_strlen(hapd->conf->server_id);
350 } else {
351 cfg->server_id = (u8 *) os_strdup("hostapd");
352 cfg->server_id_len = 7;
353 }
354 cfg->erp = hapd->conf->eap_server_erp;
355 #ifdef CONFIG_TESTING_OPTIONS
356 cfg->skip_prot_success = hapd->conf->eap_skip_prot_success;
357 #endif /* CONFIG_TESTING_OPTIONS */
358
359 return cfg;
360 }
361
362
authsrv_init(struct hostapd_data * hapd)363 int authsrv_init(struct hostapd_data *hapd)
364 {
365 #ifdef CONFIG_IEEE80211BE
366 if (!hostapd_mld_is_first_bss(hapd)) {
367 struct hostapd_data *first;
368
369 first = hostapd_mld_get_first_bss(hapd);
370 if (!first)
371 return -1;
372
373 if (!first->eap_cfg) {
374 wpa_printf(MSG_DEBUG,
375 "MLD: First BSS auth_serv does not exist. Init on its behalf");
376
377 if (authsrv_init(first))
378 return -1;
379 }
380
381 wpa_printf(MSG_DEBUG, "MLD: Using auth_serv of the first BSS");
382
383 #ifdef EAP_TLS_FUNCS
384 hapd->ssl_ctx = first->ssl_ctx;
385 #endif /* EAP_TLS_FUNCS */
386 hapd->eap_cfg = first->eap_cfg;
387 #ifdef EAP_SIM_DB
388 hapd->eap_sim_db_priv = first->eap_sim_db_priv;
389 #endif /* EAP_SIM_DB */
390 return 0;
391 }
392 #endif /* CONFIG_IEEE80211BE */
393
394 #ifdef EAP_TLS_FUNCS
395 if (hapd->conf->eap_server &&
396 (hapd->conf->ca_cert || hapd->conf->server_cert ||
397 hapd->conf->private_key || hapd->conf->dh_file ||
398 hapd->conf->server_cert2 || hapd->conf->private_key2)) {
399 struct tls_config conf;
400 struct tls_connection_params params;
401
402 os_memset(&conf, 0, sizeof(conf));
403 conf.tls_session_lifetime = hapd->conf->tls_session_lifetime;
404 if (hapd->conf->crl_reload_interval > 0 &&
405 hapd->conf->check_crl <= 0) {
406 wpa_printf(MSG_INFO,
407 "Cannot enable CRL reload functionality - it depends on check_crl being set");
408 } else if (hapd->conf->crl_reload_interval > 0) {
409 conf.crl_reload_interval =
410 hapd->conf->crl_reload_interval;
411 wpa_printf(MSG_INFO,
412 "Enabled CRL reload functionality");
413 }
414 conf.tls_flags = hapd->conf->tls_flags;
415 conf.event_cb = authsrv_tls_event;
416 conf.cb_ctx = hapd;
417 hapd->ssl_ctx = tls_init(&conf);
418 if (hapd->ssl_ctx == NULL) {
419 wpa_printf(MSG_ERROR, "Failed to initialize TLS");
420 authsrv_deinit(hapd);
421 return -1;
422 }
423
424 os_memset(¶ms, 0, sizeof(params));
425 params.ca_cert = hapd->conf->ca_cert;
426 params.client_cert = hapd->conf->server_cert;
427 params.client_cert2 = hapd->conf->server_cert2;
428 params.private_key = hapd->conf->private_key;
429 params.private_key2 = hapd->conf->private_key2;
430 params.private_key_passwd = hapd->conf->private_key_passwd;
431 params.private_key_passwd2 = hapd->conf->private_key_passwd2;
432 params.dh_file = hapd->conf->dh_file;
433 params.openssl_ciphers = hapd->conf->openssl_ciphers;
434 params.openssl_ecdh_curves = hapd->conf->openssl_ecdh_curves;
435 params.ocsp_stapling_response =
436 hapd->conf->ocsp_stapling_response;
437 params.ocsp_stapling_response_multi =
438 hapd->conf->ocsp_stapling_response_multi;
439 params.check_cert_subject = hapd->conf->check_cert_subject;
440
441 if (tls_global_set_params(hapd->ssl_ctx, ¶ms)) {
442 wpa_printf(MSG_ERROR, "Failed to set TLS parameters");
443 authsrv_deinit(hapd);
444 return -1;
445 }
446
447 if (tls_global_set_verify(hapd->ssl_ctx,
448 hapd->conf->check_crl,
449 hapd->conf->check_crl_strict)) {
450 wpa_printf(MSG_ERROR, "Failed to enable check_crl");
451 authsrv_deinit(hapd);
452 return -1;
453 }
454 }
455 #endif /* EAP_TLS_FUNCS */
456
457 #ifdef CRYPTO_RSA_OAEP_SHA256
458 crypto_rsa_key_free(hapd->imsi_privacy_key);
459 hapd->imsi_privacy_key = NULL;
460 if (hapd->conf->imsi_privacy_key) {
461 hapd->imsi_privacy_key = crypto_rsa_key_read(
462 hapd->conf->imsi_privacy_key, true);
463 if (!hapd->imsi_privacy_key) {
464 wpa_printf(MSG_ERROR,
465 "Failed to read/parse IMSI privacy key %s",
466 hapd->conf->imsi_privacy_key);
467 authsrv_deinit(hapd);
468 return -1;
469 }
470 }
471 #endif /* CRYPTO_RSA_OAEP_SHA256 */
472
473 #ifdef EAP_SIM_DB
474 if (hapd->conf->eap_sim_db) {
475 hapd->eap_sim_db_priv =
476 eap_sim_db_init(hapd->conf->eap_sim_db,
477 hapd->conf->eap_sim_db_timeout,
478 hostapd_sim_db_cb, hapd);
479 if (hapd->eap_sim_db_priv == NULL) {
480 wpa_printf(MSG_ERROR, "Failed to initialize EAP-SIM "
481 "database interface");
482 authsrv_deinit(hapd);
483 return -1;
484 }
485 }
486 #endif /* EAP_SIM_DB */
487
488 hapd->eap_cfg = authsrv_eap_config(hapd);
489 if (!hapd->eap_cfg) {
490 wpa_printf(MSG_ERROR,
491 "Failed to build EAP server configuration");
492 authsrv_deinit(hapd);
493 return -1;
494 }
495
496 #ifdef RADIUS_SERVER
497 if (hapd->conf->radius_server_clients &&
498 hostapd_setup_radius_srv(hapd))
499 return -1;
500 #endif /* RADIUS_SERVER */
501
502 return 0;
503 }
504
505
authsrv_deinit(struct hostapd_data * hapd)506 void authsrv_deinit(struct hostapd_data *hapd)
507 {
508 #ifdef CONFIG_IEEE80211BE
509 if (!hostapd_mld_is_first_bss(hapd)) {
510 wpa_printf(MSG_DEBUG,
511 "MLD: Deinit auth_serv of a non-first BSS");
512
513 hapd->radius_srv = NULL;
514 hapd->eap_cfg = NULL;
515 #ifdef EAP_SIM_DB
516 hapd->eap_sim_db_priv = NULL;
517 #endif /* EAP_SIM_DB */
518 #ifdef EAP_TLS_FUNCS
519 hapd->ssl_ctx = NULL;
520 #endif /* EAP_TLS_FUNCS */
521 return;
522 }
523 #endif /* CONFIG_IEEE80211BE */
524
525 #ifdef RADIUS_SERVER
526 radius_server_deinit(hapd->radius_srv);
527 hapd->radius_srv = NULL;
528 #endif /* RADIUS_SERVER */
529
530 #ifdef CRYPTO_RSA_OAEP_SHA256
531 crypto_rsa_key_free(hapd->imsi_privacy_key);
532 hapd->imsi_privacy_key = NULL;
533 #endif /* CRYPTO_RSA_OAEP_SHA256 */
534
535 #ifdef EAP_TLS_FUNCS
536 if (hapd->ssl_ctx) {
537 tls_deinit(hapd->ssl_ctx);
538 hapd->ssl_ctx = NULL;
539 }
540 #endif /* EAP_TLS_FUNCS */
541
542 #ifdef EAP_SIM_DB
543 if (hapd->eap_sim_db_priv) {
544 eap_sim_db_deinit(hapd->eap_sim_db_priv);
545 hapd->eap_sim_db_priv = NULL;
546 }
547 #endif /* EAP_SIM_DB */
548
549 eap_server_config_free(hapd->eap_cfg);
550 hapd->eap_cfg = NULL;
551 }
552