1/*
2 * RADIUS authentication server
3 * Copyright (c) 2005-2009, 2011-2014, 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 "includes.h"
10#include <net/if.h>
11#ifdef CONFIG_SQLITE
12#include <sqlite3.h>
13#endif /* CONFIG_SQLITE */
14
15#include "common.h"
16#include "radius.h"
17#include "eloop.h"
18#include "eap_server/eap.h"
19#include "ap/ap_config.h"
20#include "crypto/tls.h"
21#include "radius_server.h"
22
23/**
24 * RADIUS_SESSION_TIMEOUT - Session timeout in seconds
25 */
26#define RADIUS_SESSION_TIMEOUT 60
27
28/**
29 * RADIUS_MAX_SESSION - Maximum number of active sessions
30 */
31#define RADIUS_MAX_SESSION 100
32
33/**
34 * RADIUS_MAX_MSG_LEN - Maximum message length for incoming RADIUS messages
35 */
36#define RADIUS_MAX_MSG_LEN 3000
37
38static const struct eapol_callbacks radius_server_eapol_cb;
39
40struct radius_client;
41struct radius_server_data;
42
43/**
44 * struct radius_server_counters - RADIUS server statistics counters
45 */
46struct radius_server_counters {
47	u32 access_requests;
48	u32 invalid_requests;
49	u32 dup_access_requests;
50	u32 access_accepts;
51	u32 access_rejects;
52	u32 access_challenges;
53	u32 malformed_access_requests;
54	u32 bad_authenticators;
55	u32 packets_dropped;
56	u32 unknown_types;
57
58	u32 acct_requests;
59	u32 invalid_acct_requests;
60	u32 acct_responses;
61	u32 malformed_acct_requests;
62	u32 acct_bad_authenticators;
63	u32 unknown_acct_types;
64};
65
66/**
67 * struct radius_session - Internal RADIUS server data for a session
68 */
69struct radius_session {
70	struct radius_session *next;
71	struct radius_client *client;
72	struct radius_server_data *server;
73	unsigned int sess_id;
74	struct eap_sm *eap;
75	struct eap_eapol_interface *eap_if;
76	char *username; /* from User-Name attribute */
77	char *nas_ip;
78
79	struct radius_msg *last_msg;
80	char *last_from_addr;
81	int last_from_port;
82	struct sockaddr_storage last_from;
83	socklen_t last_fromlen;
84	u8 last_identifier;
85	struct radius_msg *last_reply;
86	u8 last_authenticator[16];
87
88	unsigned int remediation:1;
89	unsigned int macacl:1;
90
91	struct hostapd_radius_attr *accept_attr;
92};
93
94/**
95 * struct radius_client - Internal RADIUS server data for a client
96 */
97struct radius_client {
98	struct radius_client *next;
99	struct in_addr addr;
100	struct in_addr mask;
101#ifdef CONFIG_IPV6
102	struct in6_addr addr6;
103	struct in6_addr mask6;
104#endif /* CONFIG_IPV6 */
105	char *shared_secret;
106	int shared_secret_len;
107	struct radius_session *sessions;
108	struct radius_server_counters counters;
109};
110
111/**
112 * struct radius_server_data - Internal RADIUS server data
113 */
114struct radius_server_data {
115	/**
116	 * auth_sock - Socket for RADIUS authentication messages
117	 */
118	int auth_sock;
119
120	/**
121	 * acct_sock - Socket for RADIUS accounting messages
122	 */
123	int acct_sock;
124
125	/**
126	 * clients - List of authorized RADIUS clients
127	 */
128	struct radius_client *clients;
129
130	/**
131	 * next_sess_id - Next session identifier
132	 */
133	unsigned int next_sess_id;
134
135	/**
136	 * conf_ctx - Context pointer for callbacks
137	 *
138	 * This is used as the ctx argument in get_eap_user() calls.
139	 */
140	void *conf_ctx;
141
142	/**
143	 * num_sess - Number of active sessions
144	 */
145	int num_sess;
146
147	/**
148	 * eap_sim_db_priv - EAP-SIM/AKA database context
149	 *
150	 * This is passed to the EAP-SIM/AKA server implementation as a
151	 * callback context.
152	 */
153	void *eap_sim_db_priv;
154
155	/**
156	 * ssl_ctx - TLS context
157	 *
158	 * This is passed to the EAP server implementation as a callback
159	 * context for TLS operations.
160	 */
161	void *ssl_ctx;
162
163	/**
164	 * pac_opaque_encr_key - PAC-Opaque encryption key for EAP-FAST
165	 *
166	 * This parameter is used to set a key for EAP-FAST to encrypt the
167	 * PAC-Opaque data. It can be set to %NULL if EAP-FAST is not used. If
168	 * set, must point to a 16-octet key.
169	 */
170	u8 *pac_opaque_encr_key;
171
172	/**
173	 * eap_fast_a_id - EAP-FAST authority identity (A-ID)
174	 *
175	 * If EAP-FAST is not used, this can be set to %NULL. In theory, this
176	 * is a variable length field, but due to some existing implementations
177	 * requiring A-ID to be 16 octets in length, it is recommended to use
178	 * that length for the field to provide interoperability with deployed
179	 * peer implementations.
180	 */
181	u8 *eap_fast_a_id;
182
183	/**
184	 * eap_fast_a_id_len - Length of eap_fast_a_id buffer in octets
185	 */
186	size_t eap_fast_a_id_len;
187
188	/**
189	 * eap_fast_a_id_info - EAP-FAST authority identifier information
190	 *
191	 * This A-ID-Info contains a user-friendly name for the A-ID. For
192	 * example, this could be the enterprise and server names in
193	 * human-readable format. This field is encoded as UTF-8. If EAP-FAST
194	 * is not used, this can be set to %NULL.
195	 */
196	char *eap_fast_a_id_info;
197
198	/**
199	 * eap_fast_prov - EAP-FAST provisioning modes
200	 *
201	 * 0 = provisioning disabled, 1 = only anonymous provisioning allowed,
202	 * 2 = only authenticated provisioning allowed, 3 = both provisioning
203	 * modes allowed.
204	 */
205	int eap_fast_prov;
206
207	/**
208	 * pac_key_lifetime - EAP-FAST PAC-Key lifetime in seconds
209	 *
210	 * This is the hard limit on how long a provisioned PAC-Key can be
211	 * used.
212	 */
213	int pac_key_lifetime;
214
215	/**
216	 * pac_key_refresh_time - EAP-FAST PAC-Key refresh time in seconds
217	 *
218	 * This is a soft limit on the PAC-Key. The server will automatically
219	 * generate a new PAC-Key when this number of seconds (or fewer) of the
220	 * lifetime remains.
221	 */
222	int pac_key_refresh_time;
223
224	/**
225	 * eap_sim_aka_result_ind - EAP-SIM/AKA protected success indication
226	 *
227	 * This controls whether the protected success/failure indication
228	 * (AT_RESULT_IND) is used with EAP-SIM and EAP-AKA.
229	 */
230	int eap_sim_aka_result_ind;
231
232	/**
233	 * tnc - Trusted Network Connect (TNC)
234	 *
235	 * This controls whether TNC is enabled and will be required before the
236	 * peer is allowed to connect. Note: This is only used with EAP-TTLS
237	 * and EAP-FAST. If any other EAP method is enabled, the peer will be
238	 * allowed to connect without TNC.
239	 */
240	int tnc;
241
242	/**
243	 * pwd_group - The D-H group assigned for EAP-pwd
244	 *
245	 * If EAP-pwd is not used it can be set to zero.
246	 */
247	u16 pwd_group;
248
249	/**
250	 * server_id - Server identity
251	 */
252	const char *server_id;
253
254	/**
255	 * erp - Whether EAP Re-authentication Protocol (ERP) is enabled
256	 *
257	 * This controls whether the authentication server derives ERP key
258	 * hierarchy (rRK and rIK) from full EAP authentication and allows
259	 * these keys to be used to perform ERP to derive rMSK instead of full
260	 * EAP authentication to derive MSK.
261	 */
262	int erp;
263
264	const char *erp_domain;
265
266	struct dl_list erp_keys; /* struct eap_server_erp_key */
267
268	unsigned int tls_session_lifetime;
269
270	/**
271	 * wps - Wi-Fi Protected Setup context
272	 *
273	 * If WPS is used with an external RADIUS server (which is quite
274	 * unlikely configuration), this is used to provide a pointer to WPS
275	 * context data. Normally, this can be set to %NULL.
276	 */
277	struct wps_context *wps;
278
279	/**
280	 * ipv6 - Whether to enable IPv6 support in the RADIUS server
281	 */
282	int ipv6;
283
284	/**
285	 * start_time - Timestamp of server start
286	 */
287	struct os_reltime start_time;
288
289	/**
290	 * counters - Statistics counters for server operations
291	 *
292	 * These counters are the sum over all clients.
293	 */
294	struct radius_server_counters counters;
295
296	/**
297	 * get_eap_user - Callback for fetching EAP user information
298	 * @ctx: Context data from conf_ctx
299	 * @identity: User identity
300	 * @identity_len: identity buffer length in octets
301	 * @phase2: Whether this is for Phase 2 identity
302	 * @user: Data structure for filling in the user information
303	 * Returns: 0 on success, -1 on failure
304	 *
305	 * This is used to fetch information from user database. The callback
306	 * will fill in information about allowed EAP methods and the user
307	 * password. The password field will be an allocated copy of the
308	 * password data and RADIUS server will free it after use.
309	 */
310	int (*get_eap_user)(void *ctx, const u8 *identity, size_t identity_len,
311			    int phase2, struct eap_user *user);
312
313	/**
314	 * eap_req_id_text - Optional data for EAP-Request/Identity
315	 *
316	 * This can be used to configure an optional, displayable message that
317	 * will be sent in EAP-Request/Identity. This string can contain an
318	 * ASCII-0 character (nul) to separate network infromation per RFC
319	 * 4284. The actual string length is explicit provided in
320	 * eap_req_id_text_len since nul character will not be used as a string
321	 * terminator.
322	 */
323	char *eap_req_id_text;
324
325	/**
326	 * eap_req_id_text_len - Length of eap_req_id_text buffer in octets
327	 */
328	size_t eap_req_id_text_len;
329
330	/*
331	 * msg_ctx - Context data for wpa_msg() calls
332	 */
333	void *msg_ctx;
334
335#ifdef CONFIG_RADIUS_TEST
336	char *dump_msk_file;
337#endif /* CONFIG_RADIUS_TEST */
338
339	char *subscr_remediation_url;
340	u8 subscr_remediation_method;
341
342#ifdef CONFIG_SQLITE
343	sqlite3 *db;
344#endif /* CONFIG_SQLITE */
345};
346
347
348#define RADIUS_DEBUG(args...) \
349wpa_printf(MSG_DEBUG, "RADIUS SRV: " args)
350#define RADIUS_ERROR(args...) \
351wpa_printf(MSG_ERROR, "RADIUS SRV: " args)
352#define RADIUS_DUMP(args...) \
353wpa_hexdump(MSG_MSGDUMP, "RADIUS SRV: " args)
354#define RADIUS_DUMP_ASCII(args...) \
355wpa_hexdump_ascii(MSG_MSGDUMP, "RADIUS SRV: " args)
356
357
358static void radius_server_session_timeout(void *eloop_ctx, void *timeout_ctx);
359static void radius_server_session_remove_timeout(void *eloop_ctx,
360						 void *timeout_ctx);
361
362void srv_log(struct radius_session *sess, const char *fmt, ...)
363PRINTF_FORMAT(2, 3);
364
365void srv_log(struct radius_session *sess, const char *fmt, ...)
366{
367	va_list ap;
368	char *buf;
369	int buflen;
370
371	va_start(ap, fmt);
372	buflen = vsnprintf(NULL, 0, fmt, ap) + 1;
373	va_end(ap);
374
375	buf = os_malloc(buflen);
376	if (buf == NULL)
377		return;
378	va_start(ap, fmt);
379	vsnprintf(buf, buflen, fmt, ap);
380	va_end(ap);
381
382	RADIUS_DEBUG("[0x%x %s] %s", sess->sess_id, sess->nas_ip, buf);
383
384#ifdef CONFIG_SQLITE
385	if (sess->server->db) {
386		char *sql;
387		sql = sqlite3_mprintf("INSERT INTO authlog"
388				      "(timestamp,session,nas_ip,username,note)"
389				      " VALUES ("
390				      "strftime('%%Y-%%m-%%d %%H:%%M:%%f',"
391				      "'now'),%u,%Q,%Q,%Q)",
392				      sess->sess_id, sess->nas_ip,
393				      sess->username, buf);
394		if (sql) {
395			if (sqlite3_exec(sess->server->db, sql, NULL, NULL,
396					 NULL) != SQLITE_OK) {
397				RADIUS_ERROR("Failed to add authlog entry into sqlite database: %s",
398					     sqlite3_errmsg(sess->server->db));
399			}
400			sqlite3_free(sql);
401		}
402	}
403#endif /* CONFIG_SQLITE */
404
405	os_free(buf);
406}
407
408
409static struct radius_client *
410radius_server_get_client(struct radius_server_data *data, struct in_addr *addr,
411			 int ipv6)
412{
413	struct radius_client *client = data->clients;
414
415	while (client) {
416#ifdef CONFIG_IPV6
417		if (ipv6) {
418			struct in6_addr *addr6;
419			int i;
420
421			addr6 = (struct in6_addr *) addr;
422			for (i = 0; i < 16; i++) {
423				if ((addr6->s6_addr[i] &
424				     client->mask6.s6_addr[i]) !=
425				    (client->addr6.s6_addr[i] &
426				     client->mask6.s6_addr[i])) {
427					i = 17;
428					break;
429				}
430			}
431			if (i == 16) {
432				break;
433			}
434		}
435#endif /* CONFIG_IPV6 */
436		if (!ipv6 && (client->addr.s_addr & client->mask.s_addr) ==
437		    (addr->s_addr & client->mask.s_addr)) {
438			break;
439		}
440
441		client = client->next;
442	}
443
444	return client;
445}
446
447
448static struct radius_session *
449radius_server_get_session(struct radius_client *client, unsigned int sess_id)
450{
451	struct radius_session *sess = client->sessions;
452
453	while (sess) {
454		if (sess->sess_id == sess_id) {
455			break;
456		}
457		sess = sess->next;
458	}
459
460	return sess;
461}
462
463
464static void radius_server_session_free(struct radius_server_data *data,
465				       struct radius_session *sess)
466{
467	eloop_cancel_timeout(radius_server_session_timeout, data, sess);
468	eloop_cancel_timeout(radius_server_session_remove_timeout, data, sess);
469	eap_server_sm_deinit(sess->eap);
470	radius_msg_free(sess->last_msg);
471	os_free(sess->last_from_addr);
472	radius_msg_free(sess->last_reply);
473	os_free(sess->username);
474	os_free(sess->nas_ip);
475	os_free(sess);
476	data->num_sess--;
477}
478
479
480static void radius_server_session_remove(struct radius_server_data *data,
481					 struct radius_session *sess)
482{
483	struct radius_client *client = sess->client;
484	struct radius_session *session, *prev;
485
486	eloop_cancel_timeout(radius_server_session_remove_timeout, data, sess);
487
488	prev = NULL;
489	session = client->sessions;
490	while (session) {
491		if (session == sess) {
492			if (prev == NULL) {
493				client->sessions = sess->next;
494			} else {
495				prev->next = sess->next;
496			}
497			radius_server_session_free(data, sess);
498			break;
499		}
500		prev = session;
501		session = session->next;
502	}
503}
504
505
506static void radius_server_session_remove_timeout(void *eloop_ctx,
507						 void *timeout_ctx)
508{
509	struct radius_server_data *data = eloop_ctx;
510	struct radius_session *sess = timeout_ctx;
511	RADIUS_DEBUG("Removing completed session 0x%x", sess->sess_id);
512	radius_server_session_remove(data, sess);
513}
514
515
516static void radius_server_session_timeout(void *eloop_ctx, void *timeout_ctx)
517{
518	struct radius_server_data *data = eloop_ctx;
519	struct radius_session *sess = timeout_ctx;
520
521	RADIUS_DEBUG("Timing out authentication session 0x%x", sess->sess_id);
522	radius_server_session_remove(data, sess);
523}
524
525
526static struct radius_session *
527radius_server_new_session(struct radius_server_data *data,
528			  struct radius_client *client)
529{
530	struct radius_session *sess;
531
532	if (data->num_sess >= RADIUS_MAX_SESSION) {
533		RADIUS_DEBUG("Maximum number of existing session - no room "
534			     "for a new session");
535		return NULL;
536	}
537
538	sess = os_zalloc(sizeof(*sess));
539	if (sess == NULL)
540		return NULL;
541
542	sess->server = data;
543	sess->client = client;
544	sess->sess_id = data->next_sess_id++;
545	sess->next = client->sessions;
546	client->sessions = sess;
547	eloop_register_timeout(RADIUS_SESSION_TIMEOUT, 0,
548			       radius_server_session_timeout, data, sess);
549	data->num_sess++;
550	return sess;
551}
552
553
554#ifdef CONFIG_TESTING_OPTIONS
555static void radius_server_testing_options_tls(struct radius_session *sess,
556					      const char *tls,
557					      struct eap_config *eap_conf)
558{
559	int test = atoi(tls);
560
561	switch (test) {
562	case 1:
563		srv_log(sess, "TLS test - break VerifyData");
564		eap_conf->tls_test_flags = TLS_BREAK_VERIFY_DATA;
565		break;
566	case 2:
567		srv_log(sess, "TLS test - break ServerKeyExchange ServerParams hash");
568		eap_conf->tls_test_flags = TLS_BREAK_SRV_KEY_X_HASH;
569		break;
570	case 3:
571		srv_log(sess, "TLS test - break ServerKeyExchange ServerParams Signature");
572		eap_conf->tls_test_flags = TLS_BREAK_SRV_KEY_X_SIGNATURE;
573		break;
574	case 4:
575		srv_log(sess, "TLS test - RSA-DHE using a short 511-bit prime");
576		eap_conf->tls_test_flags = TLS_DHE_PRIME_511B;
577		break;
578	case 5:
579		srv_log(sess, "TLS test - RSA-DHE using a short 767-bit prime");
580		eap_conf->tls_test_flags = TLS_DHE_PRIME_767B;
581		break;
582	case 6:
583		srv_log(sess, "TLS test - RSA-DHE using a bogus 15 \"prime\"");
584		eap_conf->tls_test_flags = TLS_DHE_PRIME_15;
585		break;
586	case 7:
587		srv_log(sess, "TLS test - RSA-DHE using a short 58-bit prime in long container");
588		eap_conf->tls_test_flags = TLS_DHE_PRIME_58B;
589		break;
590	case 8:
591		srv_log(sess, "TLS test - RSA-DHE using a non-prime");
592		eap_conf->tls_test_flags = TLS_DHE_NON_PRIME;
593		break;
594	default:
595		srv_log(sess, "Unrecognized TLS test");
596		break;
597	}
598}
599#endif /* CONFIG_TESTING_OPTIONS */
600
601static void radius_server_testing_options(struct radius_session *sess,
602					  struct eap_config *eap_conf)
603{
604#ifdef CONFIG_TESTING_OPTIONS
605	const char *pos;
606
607	pos = os_strstr(sess->username, "@test-");
608	if (pos == NULL)
609		return;
610	pos += 6;
611	if (os_strncmp(pos, "tls-", 4) == 0)
612		radius_server_testing_options_tls(sess, pos + 4, eap_conf);
613	else
614		srv_log(sess, "Unrecognized test: %s", pos);
615#endif /* CONFIG_TESTING_OPTIONS */
616}
617
618
619static struct radius_session *
620radius_server_get_new_session(struct radius_server_data *data,
621			      struct radius_client *client,
622			      struct radius_msg *msg, const char *from_addr)
623{
624	u8 *user;
625	size_t user_len;
626	int res;
627	struct radius_session *sess;
628	struct eap_config eap_conf;
629	struct eap_user tmp;
630
631	RADIUS_DEBUG("Creating a new session");
632
633	if (radius_msg_get_attr_ptr(msg, RADIUS_ATTR_USER_NAME, &user,
634				    &user_len, NULL) < 0) {
635		RADIUS_DEBUG("Could not get User-Name");
636		return NULL;
637	}
638	RADIUS_DUMP_ASCII("User-Name", user, user_len);
639
640	os_memset(&tmp, 0, sizeof(tmp));
641	res = data->get_eap_user(data->conf_ctx, user, user_len, 0, &tmp);
642	bin_clear_free(tmp.password, tmp.password_len);
643
644	if (res != 0) {
645		RADIUS_DEBUG("User-Name not found from user database");
646		return NULL;
647	}
648
649	RADIUS_DEBUG("Matching user entry found");
650	sess = radius_server_new_session(data, client);
651	if (sess == NULL) {
652		RADIUS_DEBUG("Failed to create a new session");
653		return NULL;
654	}
655	sess->accept_attr = tmp.accept_attr;
656	sess->macacl = tmp.macacl;
657
658	sess->username = os_malloc(user_len * 4 + 1);
659	if (sess->username == NULL) {
660		radius_server_session_free(data, sess);
661		return NULL;
662	}
663	printf_encode(sess->username, user_len * 4 + 1, user, user_len);
664
665	sess->nas_ip = os_strdup(from_addr);
666	if (sess->nas_ip == NULL) {
667		radius_server_session_free(data, sess);
668		return NULL;
669	}
670
671	srv_log(sess, "New session created");
672
673	os_memset(&eap_conf, 0, sizeof(eap_conf));
674	eap_conf.ssl_ctx = data->ssl_ctx;
675	eap_conf.msg_ctx = data->msg_ctx;
676	eap_conf.eap_sim_db_priv = data->eap_sim_db_priv;
677	eap_conf.backend_auth = TRUE;
678	eap_conf.eap_server = 1;
679	eap_conf.pac_opaque_encr_key = data->pac_opaque_encr_key;
680	eap_conf.eap_fast_a_id = data->eap_fast_a_id;
681	eap_conf.eap_fast_a_id_len = data->eap_fast_a_id_len;
682	eap_conf.eap_fast_a_id_info = data->eap_fast_a_id_info;
683	eap_conf.eap_fast_prov = data->eap_fast_prov;
684	eap_conf.pac_key_lifetime = data->pac_key_lifetime;
685	eap_conf.pac_key_refresh_time = data->pac_key_refresh_time;
686	eap_conf.eap_sim_aka_result_ind = data->eap_sim_aka_result_ind;
687	eap_conf.tnc = data->tnc;
688	eap_conf.wps = data->wps;
689	eap_conf.pwd_group = data->pwd_group;
690	eap_conf.server_id = (const u8 *) data->server_id;
691	eap_conf.server_id_len = os_strlen(data->server_id);
692	eap_conf.erp = data->erp;
693	eap_conf.tls_session_lifetime = data->tls_session_lifetime;
694	radius_server_testing_options(sess, &eap_conf);
695	sess->eap = eap_server_sm_init(sess, &radius_server_eapol_cb,
696				       &eap_conf);
697	if (sess->eap == NULL) {
698		RADIUS_DEBUG("Failed to initialize EAP state machine for the "
699			     "new session");
700		radius_server_session_free(data, sess);
701		return NULL;
702	}
703	sess->eap_if = eap_get_interface(sess->eap);
704	sess->eap_if->eapRestart = TRUE;
705	sess->eap_if->portEnabled = TRUE;
706
707	RADIUS_DEBUG("New session 0x%x initialized", sess->sess_id);
708
709	return sess;
710}
711
712
713static struct radius_msg *
714radius_server_encapsulate_eap(struct radius_server_data *data,
715			      struct radius_client *client,
716			      struct radius_session *sess,
717			      struct radius_msg *request)
718{
719	struct radius_msg *msg;
720	int code;
721	unsigned int sess_id;
722	struct radius_hdr *hdr = radius_msg_get_hdr(request);
723
724	if (sess->eap_if->eapFail) {
725		sess->eap_if->eapFail = FALSE;
726		code = RADIUS_CODE_ACCESS_REJECT;
727	} else if (sess->eap_if->eapSuccess) {
728		sess->eap_if->eapSuccess = FALSE;
729		code = RADIUS_CODE_ACCESS_ACCEPT;
730	} else {
731		sess->eap_if->eapReq = FALSE;
732		code = RADIUS_CODE_ACCESS_CHALLENGE;
733	}
734
735	msg = radius_msg_new(code, hdr->identifier);
736	if (msg == NULL) {
737		RADIUS_DEBUG("Failed to allocate reply message");
738		return NULL;
739	}
740
741	sess_id = htonl(sess->sess_id);
742	if (code == RADIUS_CODE_ACCESS_CHALLENGE &&
743	    !radius_msg_add_attr(msg, RADIUS_ATTR_STATE,
744				 (u8 *) &sess_id, sizeof(sess_id))) {
745		RADIUS_DEBUG("Failed to add State attribute");
746	}
747
748	if (sess->eap_if->eapReqData &&
749	    !radius_msg_add_eap(msg, wpabuf_head(sess->eap_if->eapReqData),
750				wpabuf_len(sess->eap_if->eapReqData))) {
751		RADIUS_DEBUG("Failed to add EAP-Message attribute");
752	}
753
754	if (code == RADIUS_CODE_ACCESS_ACCEPT && sess->eap_if->eapKeyData) {
755		int len;
756#ifdef CONFIG_RADIUS_TEST
757		if (data->dump_msk_file) {
758			FILE *f;
759			char buf[2 * 64 + 1];
760			f = fopen(data->dump_msk_file, "a");
761			if (f) {
762				len = sess->eap_if->eapKeyDataLen;
763				if (len > 64)
764					len = 64;
765				len = wpa_snprintf_hex(
766					buf, sizeof(buf),
767					sess->eap_if->eapKeyData, len);
768				buf[len] = '\0';
769				fprintf(f, "%s\n", buf);
770				fclose(f);
771			}
772		}
773#endif /* CONFIG_RADIUS_TEST */
774		if (sess->eap_if->eapKeyDataLen > 64) {
775			len = 32;
776		} else {
777			len = sess->eap_if->eapKeyDataLen / 2;
778		}
779		if (!radius_msg_add_mppe_keys(msg, hdr->authenticator,
780					      (u8 *) client->shared_secret,
781					      client->shared_secret_len,
782					      sess->eap_if->eapKeyData + len,
783					      len, sess->eap_if->eapKeyData,
784					      len)) {
785			RADIUS_DEBUG("Failed to add MPPE key attributes");
786		}
787	}
788
789#ifdef CONFIG_HS20
790	if (code == RADIUS_CODE_ACCESS_ACCEPT && sess->remediation &&
791	    data->subscr_remediation_url) {
792		u8 *buf;
793		size_t url_len = os_strlen(data->subscr_remediation_url);
794		buf = os_malloc(1 + url_len);
795		if (buf == NULL) {
796			radius_msg_free(msg);
797			return NULL;
798		}
799		buf[0] = data->subscr_remediation_method;
800		os_memcpy(&buf[1], data->subscr_remediation_url, url_len);
801		if (!radius_msg_add_wfa(
802			    msg, RADIUS_VENDOR_ATTR_WFA_HS20_SUBSCR_REMEDIATION,
803			    buf, 1 + url_len)) {
804			RADIUS_DEBUG("Failed to add WFA-HS20-SubscrRem");
805		}
806		os_free(buf);
807	} else if (code == RADIUS_CODE_ACCESS_ACCEPT && sess->remediation) {
808		u8 buf[1];
809		if (!radius_msg_add_wfa(
810			    msg, RADIUS_VENDOR_ATTR_WFA_HS20_SUBSCR_REMEDIATION,
811			    buf, 0)) {
812			RADIUS_DEBUG("Failed to add WFA-HS20-SubscrRem");
813		}
814	}
815#endif /* CONFIG_HS20 */
816
817	if (radius_msg_copy_attr(msg, request, RADIUS_ATTR_PROXY_STATE) < 0) {
818		RADIUS_DEBUG("Failed to copy Proxy-State attribute(s)");
819		radius_msg_free(msg);
820		return NULL;
821	}
822
823	if (code == RADIUS_CODE_ACCESS_ACCEPT) {
824		struct hostapd_radius_attr *attr;
825		for (attr = sess->accept_attr; attr; attr = attr->next) {
826			if (!radius_msg_add_attr(msg, attr->type,
827						 wpabuf_head(attr->val),
828						 wpabuf_len(attr->val))) {
829				wpa_printf(MSG_ERROR, "Could not add RADIUS attribute");
830				radius_msg_free(msg);
831				return NULL;
832			}
833		}
834	}
835
836	if (radius_msg_finish_srv(msg, (u8 *) client->shared_secret,
837				  client->shared_secret_len,
838				  hdr->authenticator) < 0) {
839		RADIUS_DEBUG("Failed to add Message-Authenticator attribute");
840	}
841
842	return msg;
843}
844
845
846static struct radius_msg *
847radius_server_macacl(struct radius_server_data *data,
848		     struct radius_client *client,
849		     struct radius_session *sess,
850		     struct radius_msg *request)
851{
852	struct radius_msg *msg;
853	int code;
854	struct radius_hdr *hdr = radius_msg_get_hdr(request);
855	u8 *pw;
856	size_t pw_len;
857
858	code = RADIUS_CODE_ACCESS_ACCEPT;
859
860	if (radius_msg_get_attr_ptr(request, RADIUS_ATTR_USER_PASSWORD, &pw,
861				    &pw_len, NULL) < 0) {
862		RADIUS_DEBUG("Could not get User-Password");
863		code = RADIUS_CODE_ACCESS_REJECT;
864	} else {
865		int res;
866		struct eap_user tmp;
867
868		os_memset(&tmp, 0, sizeof(tmp));
869		res = data->get_eap_user(data->conf_ctx, (u8 *) sess->username,
870					 os_strlen(sess->username), 0, &tmp);
871		if (res || !tmp.macacl || tmp.password == NULL) {
872			RADIUS_DEBUG("No MAC ACL user entry");
873			bin_clear_free(tmp.password, tmp.password_len);
874			code = RADIUS_CODE_ACCESS_REJECT;
875		} else {
876			u8 buf[128];
877			res = radius_user_password_hide(
878				request, tmp.password, tmp.password_len,
879				(u8 *) client->shared_secret,
880				client->shared_secret_len,
881				buf, sizeof(buf));
882			bin_clear_free(tmp.password, tmp.password_len);
883
884			if (res < 0 || pw_len != (size_t) res ||
885			    os_memcmp_const(pw, buf, res) != 0) {
886				RADIUS_DEBUG("Incorrect User-Password");
887				code = RADIUS_CODE_ACCESS_REJECT;
888			}
889		}
890	}
891
892	msg = radius_msg_new(code, hdr->identifier);
893	if (msg == NULL) {
894		RADIUS_DEBUG("Failed to allocate reply message");
895		return NULL;
896	}
897
898	if (radius_msg_copy_attr(msg, request, RADIUS_ATTR_PROXY_STATE) < 0) {
899		RADIUS_DEBUG("Failed to copy Proxy-State attribute(s)");
900		radius_msg_free(msg);
901		return NULL;
902	}
903
904	if (code == RADIUS_CODE_ACCESS_ACCEPT) {
905		struct hostapd_radius_attr *attr;
906		for (attr = sess->accept_attr; attr; attr = attr->next) {
907			if (!radius_msg_add_attr(msg, attr->type,
908						 wpabuf_head(attr->val),
909						 wpabuf_len(attr->val))) {
910				wpa_printf(MSG_ERROR, "Could not add RADIUS attribute");
911				radius_msg_free(msg);
912				return NULL;
913			}
914		}
915	}
916
917	if (radius_msg_finish_srv(msg, (u8 *) client->shared_secret,
918				  client->shared_secret_len,
919				  hdr->authenticator) < 0) {
920		RADIUS_DEBUG("Failed to add Message-Authenticator attribute");
921	}
922
923	return msg;
924}
925
926
927static int radius_server_reject(struct radius_server_data *data,
928				struct radius_client *client,
929				struct radius_msg *request,
930				struct sockaddr *from, socklen_t fromlen,
931				const char *from_addr, int from_port)
932{
933	struct radius_msg *msg;
934	int ret = 0;
935	struct eap_hdr eapfail;
936	struct wpabuf *buf;
937	struct radius_hdr *hdr = radius_msg_get_hdr(request);
938
939	RADIUS_DEBUG("Reject invalid request from %s:%d",
940		     from_addr, from_port);
941
942	msg = radius_msg_new(RADIUS_CODE_ACCESS_REJECT, hdr->identifier);
943	if (msg == NULL) {
944		return -1;
945	}
946
947	os_memset(&eapfail, 0, sizeof(eapfail));
948	eapfail.code = EAP_CODE_FAILURE;
949	eapfail.identifier = 0;
950	eapfail.length = host_to_be16(sizeof(eapfail));
951
952	if (!radius_msg_add_eap(msg, (u8 *) &eapfail, sizeof(eapfail))) {
953		RADIUS_DEBUG("Failed to add EAP-Message attribute");
954	}
955
956	if (radius_msg_copy_attr(msg, request, RADIUS_ATTR_PROXY_STATE) < 0) {
957		RADIUS_DEBUG("Failed to copy Proxy-State attribute(s)");
958		radius_msg_free(msg);
959		return -1;
960	}
961
962	if (radius_msg_finish_srv(msg, (u8 *) client->shared_secret,
963				  client->shared_secret_len,
964				  hdr->authenticator) <
965	    0) {
966		RADIUS_DEBUG("Failed to add Message-Authenticator attribute");
967	}
968
969	if (wpa_debug_level <= MSG_MSGDUMP) {
970		radius_msg_dump(msg);
971	}
972
973	data->counters.access_rejects++;
974	client->counters.access_rejects++;
975	buf = radius_msg_get_buf(msg);
976	if (sendto(data->auth_sock, wpabuf_head(buf), wpabuf_len(buf), 0,
977		   (struct sockaddr *) from, sizeof(*from)) < 0) {
978		wpa_printf(MSG_INFO, "sendto[RADIUS SRV]: %s", strerror(errno));
979		ret = -1;
980	}
981
982	radius_msg_free(msg);
983
984	return ret;
985}
986
987
988static int radius_server_request(struct radius_server_data *data,
989				 struct radius_msg *msg,
990				 struct sockaddr *from, socklen_t fromlen,
991				 struct radius_client *client,
992				 const char *from_addr, int from_port,
993				 struct radius_session *force_sess)
994{
995	struct wpabuf *eap = NULL;
996	int res, state_included = 0;
997	u8 statebuf[4];
998	unsigned int state;
999	struct radius_session *sess;
1000	struct radius_msg *reply;
1001	int is_complete = 0;
1002
1003	if (force_sess)
1004		sess = force_sess;
1005	else {
1006		res = radius_msg_get_attr(msg, RADIUS_ATTR_STATE, statebuf,
1007					  sizeof(statebuf));
1008		state_included = res >= 0;
1009		if (res == sizeof(statebuf)) {
1010			state = WPA_GET_BE32(statebuf);
1011			sess = radius_server_get_session(client, state);
1012		} else {
1013			sess = NULL;
1014		}
1015	}
1016
1017	if (sess) {
1018		RADIUS_DEBUG("Request for session 0x%x", sess->sess_id);
1019	} else if (state_included) {
1020		RADIUS_DEBUG("State attribute included but no session found");
1021		radius_server_reject(data, client, msg, from, fromlen,
1022				     from_addr, from_port);
1023		return -1;
1024	} else {
1025		sess = radius_server_get_new_session(data, client, msg,
1026						     from_addr);
1027		if (sess == NULL) {
1028			RADIUS_DEBUG("Could not create a new session");
1029			radius_server_reject(data, client, msg, from, fromlen,
1030					     from_addr, from_port);
1031			return -1;
1032		}
1033	}
1034
1035	if (sess->last_from_port == from_port &&
1036	    sess->last_identifier == radius_msg_get_hdr(msg)->identifier &&
1037	    os_memcmp(sess->last_authenticator,
1038		      radius_msg_get_hdr(msg)->authenticator, 16) == 0) {
1039		RADIUS_DEBUG("Duplicate message from %s", from_addr);
1040		data->counters.dup_access_requests++;
1041		client->counters.dup_access_requests++;
1042
1043		if (sess->last_reply) {
1044			struct wpabuf *buf;
1045			buf = radius_msg_get_buf(sess->last_reply);
1046			res = sendto(data->auth_sock, wpabuf_head(buf),
1047				     wpabuf_len(buf), 0,
1048				     (struct sockaddr *) from, fromlen);
1049			if (res < 0) {
1050				wpa_printf(MSG_INFO, "sendto[RADIUS SRV]: %s",
1051					   strerror(errno));
1052			}
1053			return 0;
1054		}
1055
1056		RADIUS_DEBUG("No previous reply available for duplicate "
1057			     "message");
1058		return -1;
1059	}
1060
1061	eap = radius_msg_get_eap(msg);
1062	if (eap == NULL && sess->macacl) {
1063		reply = radius_server_macacl(data, client, sess, msg);
1064		if (reply == NULL)
1065			return -1;
1066		goto send_reply;
1067	}
1068	if (eap == NULL) {
1069		RADIUS_DEBUG("No EAP-Message in RADIUS packet from %s",
1070			     from_addr);
1071		data->counters.packets_dropped++;
1072		client->counters.packets_dropped++;
1073		return -1;
1074	}
1075
1076	RADIUS_DUMP("Received EAP data", wpabuf_head(eap), wpabuf_len(eap));
1077
1078	/* FIX: if Code is Request, Success, or Failure, send Access-Reject;
1079	 * RFC3579 Sect. 2.6.2.
1080	 * Include EAP-Response/Nak with no preferred method if
1081	 * code == request.
1082	 * If code is not 1-4, discard the packet silently.
1083	 * Or is this already done by the EAP state machine? */
1084
1085	wpabuf_free(sess->eap_if->eapRespData);
1086	sess->eap_if->eapRespData = eap;
1087	sess->eap_if->eapResp = TRUE;
1088	eap_server_sm_step(sess->eap);
1089
1090	if ((sess->eap_if->eapReq || sess->eap_if->eapSuccess ||
1091	     sess->eap_if->eapFail) && sess->eap_if->eapReqData) {
1092		RADIUS_DUMP("EAP data from the state machine",
1093			    wpabuf_head(sess->eap_if->eapReqData),
1094			    wpabuf_len(sess->eap_if->eapReqData));
1095	} else if (sess->eap_if->eapFail) {
1096		RADIUS_DEBUG("No EAP data from the state machine, but eapFail "
1097			     "set");
1098	} else if (eap_sm_method_pending(sess->eap)) {
1099		radius_msg_free(sess->last_msg);
1100		sess->last_msg = msg;
1101		sess->last_from_port = from_port;
1102		os_free(sess->last_from_addr);
1103		sess->last_from_addr = os_strdup(from_addr);
1104		sess->last_fromlen = fromlen;
1105		os_memcpy(&sess->last_from, from, fromlen);
1106		return -2;
1107	} else {
1108		RADIUS_DEBUG("No EAP data from the state machine - ignore this"
1109			     " Access-Request silently (assuming it was a "
1110			     "duplicate)");
1111		data->counters.packets_dropped++;
1112		client->counters.packets_dropped++;
1113		return -1;
1114	}
1115
1116	if (sess->eap_if->eapSuccess || sess->eap_if->eapFail)
1117		is_complete = 1;
1118	if (sess->eap_if->eapFail)
1119		srv_log(sess, "EAP authentication failed");
1120	else if (sess->eap_if->eapSuccess)
1121		srv_log(sess, "EAP authentication succeeded");
1122
1123	reply = radius_server_encapsulate_eap(data, client, sess, msg);
1124
1125send_reply:
1126	if (reply) {
1127		struct wpabuf *buf;
1128		struct radius_hdr *hdr;
1129
1130		RADIUS_DEBUG("Reply to %s:%d", from_addr, from_port);
1131		if (wpa_debug_level <= MSG_MSGDUMP) {
1132			radius_msg_dump(reply);
1133		}
1134
1135		switch (radius_msg_get_hdr(reply)->code) {
1136		case RADIUS_CODE_ACCESS_ACCEPT:
1137			srv_log(sess, "Sending Access-Accept");
1138			data->counters.access_accepts++;
1139			client->counters.access_accepts++;
1140			break;
1141		case RADIUS_CODE_ACCESS_REJECT:
1142			srv_log(sess, "Sending Access-Reject");
1143			data->counters.access_rejects++;
1144			client->counters.access_rejects++;
1145			break;
1146		case RADIUS_CODE_ACCESS_CHALLENGE:
1147			data->counters.access_challenges++;
1148			client->counters.access_challenges++;
1149			break;
1150		}
1151		buf = radius_msg_get_buf(reply);
1152		res = sendto(data->auth_sock, wpabuf_head(buf),
1153			     wpabuf_len(buf), 0,
1154			     (struct sockaddr *) from, fromlen);
1155		if (res < 0) {
1156			wpa_printf(MSG_INFO, "sendto[RADIUS SRV]: %s",
1157				   strerror(errno));
1158		}
1159		radius_msg_free(sess->last_reply);
1160		sess->last_reply = reply;
1161		sess->last_from_port = from_port;
1162		hdr = radius_msg_get_hdr(msg);
1163		sess->last_identifier = hdr->identifier;
1164		os_memcpy(sess->last_authenticator, hdr->authenticator, 16);
1165	} else {
1166		data->counters.packets_dropped++;
1167		client->counters.packets_dropped++;
1168	}
1169
1170	if (is_complete) {
1171		RADIUS_DEBUG("Removing completed session 0x%x after timeout",
1172			     sess->sess_id);
1173		eloop_cancel_timeout(radius_server_session_remove_timeout,
1174				     data, sess);
1175		eloop_register_timeout(10, 0,
1176				       radius_server_session_remove_timeout,
1177				       data, sess);
1178	}
1179
1180	return 0;
1181}
1182
1183
1184static void radius_server_receive_auth(int sock, void *eloop_ctx,
1185				       void *sock_ctx)
1186{
1187	struct radius_server_data *data = eloop_ctx;
1188	u8 *buf = NULL;
1189	union {
1190		struct sockaddr_storage ss;
1191		struct sockaddr_in sin;
1192#ifdef CONFIG_IPV6
1193		struct sockaddr_in6 sin6;
1194#endif /* CONFIG_IPV6 */
1195	} from;
1196	socklen_t fromlen;
1197	int len;
1198	struct radius_client *client = NULL;
1199	struct radius_msg *msg = NULL;
1200	char abuf[50];
1201	int from_port = 0;
1202
1203	buf = os_malloc(RADIUS_MAX_MSG_LEN);
1204	if (buf == NULL) {
1205		goto fail;
1206	}
1207
1208	fromlen = sizeof(from);
1209	len = recvfrom(sock, buf, RADIUS_MAX_MSG_LEN, 0,
1210		       (struct sockaddr *) &from.ss, &fromlen);
1211	if (len < 0) {
1212		wpa_printf(MSG_INFO, "recvfrom[radius_server]: %s",
1213			   strerror(errno));
1214		goto fail;
1215	}
1216
1217#ifdef CONFIG_IPV6
1218	if (data->ipv6) {
1219		if (inet_ntop(AF_INET6, &from.sin6.sin6_addr, abuf,
1220			      sizeof(abuf)) == NULL)
1221			abuf[0] = '\0';
1222		from_port = ntohs(from.sin6.sin6_port);
1223		RADIUS_DEBUG("Received %d bytes from %s:%d",
1224			     len, abuf, from_port);
1225
1226		client = radius_server_get_client(data,
1227						  (struct in_addr *)
1228						  &from.sin6.sin6_addr, 1);
1229	}
1230#endif /* CONFIG_IPV6 */
1231
1232	if (!data->ipv6) {
1233		os_strlcpy(abuf, inet_ntoa(from.sin.sin_addr), sizeof(abuf));
1234		from_port = ntohs(from.sin.sin_port);
1235		RADIUS_DEBUG("Received %d bytes from %s:%d",
1236			     len, abuf, from_port);
1237
1238		client = radius_server_get_client(data, &from.sin.sin_addr, 0);
1239	}
1240
1241	RADIUS_DUMP("Received data", buf, len);
1242
1243	if (client == NULL) {
1244		RADIUS_DEBUG("Unknown client %s - packet ignored", abuf);
1245		data->counters.invalid_requests++;
1246		goto fail;
1247	}
1248
1249	msg = radius_msg_parse(buf, len);
1250	if (msg == NULL) {
1251		RADIUS_DEBUG("Parsing incoming RADIUS frame failed");
1252		data->counters.malformed_access_requests++;
1253		client->counters.malformed_access_requests++;
1254		goto fail;
1255	}
1256
1257	os_free(buf);
1258	buf = NULL;
1259
1260	if (wpa_debug_level <= MSG_MSGDUMP) {
1261		radius_msg_dump(msg);
1262	}
1263
1264	if (radius_msg_get_hdr(msg)->code != RADIUS_CODE_ACCESS_REQUEST) {
1265		RADIUS_DEBUG("Unexpected RADIUS code %d",
1266			     radius_msg_get_hdr(msg)->code);
1267		data->counters.unknown_types++;
1268		client->counters.unknown_types++;
1269		goto fail;
1270	}
1271
1272	data->counters.access_requests++;
1273	client->counters.access_requests++;
1274
1275	if (radius_msg_verify_msg_auth(msg, (u8 *) client->shared_secret,
1276				       client->shared_secret_len, NULL)) {
1277		RADIUS_DEBUG("Invalid Message-Authenticator from %s", abuf);
1278		data->counters.bad_authenticators++;
1279		client->counters.bad_authenticators++;
1280		goto fail;
1281	}
1282
1283	if (radius_server_request(data, msg, (struct sockaddr *) &from,
1284				  fromlen, client, abuf, from_port, NULL) ==
1285	    -2)
1286		return; /* msg was stored with the session */
1287
1288fail:
1289	radius_msg_free(msg);
1290	os_free(buf);
1291}
1292
1293
1294static void radius_server_receive_acct(int sock, void *eloop_ctx,
1295				       void *sock_ctx)
1296{
1297	struct radius_server_data *data = eloop_ctx;
1298	u8 *buf = NULL;
1299	union {
1300		struct sockaddr_storage ss;
1301		struct sockaddr_in sin;
1302#ifdef CONFIG_IPV6
1303		struct sockaddr_in6 sin6;
1304#endif /* CONFIG_IPV6 */
1305	} from;
1306	socklen_t fromlen;
1307	int len, res;
1308	struct radius_client *client = NULL;
1309	struct radius_msg *msg = NULL, *resp = NULL;
1310	char abuf[50];
1311	int from_port = 0;
1312	struct radius_hdr *hdr;
1313	struct wpabuf *rbuf;
1314
1315	buf = os_malloc(RADIUS_MAX_MSG_LEN);
1316	if (buf == NULL) {
1317		goto fail;
1318	}
1319
1320	fromlen = sizeof(from);
1321	len = recvfrom(sock, buf, RADIUS_MAX_MSG_LEN, 0,
1322		       (struct sockaddr *) &from.ss, &fromlen);
1323	if (len < 0) {
1324		wpa_printf(MSG_INFO, "recvfrom[radius_server]: %s",
1325			   strerror(errno));
1326		goto fail;
1327	}
1328
1329#ifdef CONFIG_IPV6
1330	if (data->ipv6) {
1331		if (inet_ntop(AF_INET6, &from.sin6.sin6_addr, abuf,
1332			      sizeof(abuf)) == NULL)
1333			abuf[0] = '\0';
1334		from_port = ntohs(from.sin6.sin6_port);
1335		RADIUS_DEBUG("Received %d bytes from %s:%d",
1336			     len, abuf, from_port);
1337
1338		client = radius_server_get_client(data,
1339						  (struct in_addr *)
1340						  &from.sin6.sin6_addr, 1);
1341	}
1342#endif /* CONFIG_IPV6 */
1343
1344	if (!data->ipv6) {
1345		os_strlcpy(abuf, inet_ntoa(from.sin.sin_addr), sizeof(abuf));
1346		from_port = ntohs(from.sin.sin_port);
1347		RADIUS_DEBUG("Received %d bytes from %s:%d",
1348			     len, abuf, from_port);
1349
1350		client = radius_server_get_client(data, &from.sin.sin_addr, 0);
1351	}
1352
1353	RADIUS_DUMP("Received data", buf, len);
1354
1355	if (client == NULL) {
1356		RADIUS_DEBUG("Unknown client %s - packet ignored", abuf);
1357		data->counters.invalid_acct_requests++;
1358		goto fail;
1359	}
1360
1361	msg = radius_msg_parse(buf, len);
1362	if (msg == NULL) {
1363		RADIUS_DEBUG("Parsing incoming RADIUS frame failed");
1364		data->counters.malformed_acct_requests++;
1365		client->counters.malformed_acct_requests++;
1366		goto fail;
1367	}
1368
1369	os_free(buf);
1370	buf = NULL;
1371
1372	if (wpa_debug_level <= MSG_MSGDUMP) {
1373		radius_msg_dump(msg);
1374	}
1375
1376	if (radius_msg_get_hdr(msg)->code != RADIUS_CODE_ACCOUNTING_REQUEST) {
1377		RADIUS_DEBUG("Unexpected RADIUS code %d",
1378			     radius_msg_get_hdr(msg)->code);
1379		data->counters.unknown_acct_types++;
1380		client->counters.unknown_acct_types++;
1381		goto fail;
1382	}
1383
1384	data->counters.acct_requests++;
1385	client->counters.acct_requests++;
1386
1387	if (radius_msg_verify_acct_req(msg, (u8 *) client->shared_secret,
1388				       client->shared_secret_len)) {
1389		RADIUS_DEBUG("Invalid Authenticator from %s", abuf);
1390		data->counters.acct_bad_authenticators++;
1391		client->counters.acct_bad_authenticators++;
1392		goto fail;
1393	}
1394
1395	/* TODO: Write accounting information to a file or database */
1396
1397	hdr = radius_msg_get_hdr(msg);
1398
1399	resp = radius_msg_new(RADIUS_CODE_ACCOUNTING_RESPONSE, hdr->identifier);
1400	if (resp == NULL)
1401		goto fail;
1402
1403	radius_msg_finish_acct_resp(resp, (u8 *) client->shared_secret,
1404				    client->shared_secret_len,
1405				    hdr->authenticator);
1406
1407	RADIUS_DEBUG("Reply to %s:%d", abuf, from_port);
1408	if (wpa_debug_level <= MSG_MSGDUMP) {
1409		radius_msg_dump(resp);
1410	}
1411	rbuf = radius_msg_get_buf(resp);
1412	data->counters.acct_responses++;
1413	client->counters.acct_responses++;
1414	res = sendto(data->acct_sock, wpabuf_head(rbuf), wpabuf_len(rbuf), 0,
1415		     (struct sockaddr *) &from.ss, fromlen);
1416	if (res < 0) {
1417		wpa_printf(MSG_INFO, "sendto[RADIUS SRV]: %s",
1418			   strerror(errno));
1419	}
1420
1421fail:
1422	radius_msg_free(resp);
1423	radius_msg_free(msg);
1424	os_free(buf);
1425}
1426
1427
1428static int radius_server_disable_pmtu_discovery(int s)
1429{
1430	int r = -1;
1431#if defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DONT)
1432	/* Turn off Path MTU discovery on IPv4/UDP sockets. */
1433	int action = IP_PMTUDISC_DONT;
1434	r = setsockopt(s, IPPROTO_IP, IP_MTU_DISCOVER, &action,
1435		       sizeof(action));
1436	if (r == -1)
1437		wpa_printf(MSG_ERROR, "Failed to set IP_MTU_DISCOVER: "
1438			   "%s", strerror(errno));
1439#endif
1440	return r;
1441}
1442
1443
1444static int radius_server_open_socket(int port)
1445{
1446	int s;
1447	struct sockaddr_in addr;
1448
1449	s = socket(PF_INET, SOCK_DGRAM, 0);
1450	if (s < 0) {
1451		wpa_printf(MSG_INFO, "RADIUS: socket: %s", strerror(errno));
1452		return -1;
1453	}
1454
1455	radius_server_disable_pmtu_discovery(s);
1456
1457	os_memset(&addr, 0, sizeof(addr));
1458	addr.sin_family = AF_INET;
1459	addr.sin_port = htons(port);
1460	if (bind(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
1461		wpa_printf(MSG_INFO, "RADIUS: bind: %s", strerror(errno));
1462		close(s);
1463		return -1;
1464	}
1465
1466	return s;
1467}
1468
1469
1470#ifdef CONFIG_IPV6
1471static int radius_server_open_socket6(int port)
1472{
1473	int s;
1474	struct sockaddr_in6 addr;
1475
1476	s = socket(PF_INET6, SOCK_DGRAM, 0);
1477	if (s < 0) {
1478		wpa_printf(MSG_INFO, "RADIUS: socket[IPv6]: %s",
1479			   strerror(errno));
1480		return -1;
1481	}
1482
1483	os_memset(&addr, 0, sizeof(addr));
1484	addr.sin6_family = AF_INET6;
1485	os_memcpy(&addr.sin6_addr, &in6addr_any, sizeof(in6addr_any));
1486	addr.sin6_port = htons(port);
1487	if (bind(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
1488		wpa_printf(MSG_INFO, "RADIUS: bind: %s", strerror(errno));
1489		close(s);
1490		return -1;
1491	}
1492
1493	return s;
1494}
1495#endif /* CONFIG_IPV6 */
1496
1497
1498static void radius_server_free_sessions(struct radius_server_data *data,
1499					struct radius_session *sessions)
1500{
1501	struct radius_session *session, *prev;
1502
1503	session = sessions;
1504	while (session) {
1505		prev = session;
1506		session = session->next;
1507		radius_server_session_free(data, prev);
1508	}
1509}
1510
1511
1512static void radius_server_free_clients(struct radius_server_data *data,
1513				       struct radius_client *clients)
1514{
1515	struct radius_client *client, *prev;
1516
1517	client = clients;
1518	while (client) {
1519		prev = client;
1520		client = client->next;
1521
1522		radius_server_free_sessions(data, prev->sessions);
1523		os_free(prev->shared_secret);
1524		os_free(prev);
1525	}
1526}
1527
1528
1529static struct radius_client *
1530radius_server_read_clients(const char *client_file, int ipv6)
1531{
1532	FILE *f;
1533	const int buf_size = 1024;
1534	char *buf, *pos;
1535	struct radius_client *clients, *tail, *entry;
1536	int line = 0, mask, failed = 0, i;
1537	struct in_addr addr;
1538#ifdef CONFIG_IPV6
1539	struct in6_addr addr6;
1540#endif /* CONFIG_IPV6 */
1541	unsigned int val;
1542
1543	f = fopen(client_file, "r");
1544	if (f == NULL) {
1545		RADIUS_ERROR("Could not open client file '%s'", client_file);
1546		return NULL;
1547	}
1548
1549	buf = os_malloc(buf_size);
1550	if (buf == NULL) {
1551		fclose(f);
1552		return NULL;
1553	}
1554
1555	clients = tail = NULL;
1556	while (fgets(buf, buf_size, f)) {
1557		/* Configuration file format:
1558		 * 192.168.1.0/24 secret
1559		 * 192.168.1.2 secret
1560		 * fe80::211:22ff:fe33:4455/64 secretipv6
1561		 */
1562		line++;
1563		buf[buf_size - 1] = '\0';
1564		pos = buf;
1565		while (*pos != '\0' && *pos != '\n')
1566			pos++;
1567		if (*pos == '\n')
1568			*pos = '\0';
1569		if (*buf == '\0' || *buf == '#')
1570			continue;
1571
1572		pos = buf;
1573		while ((*pos >= '0' && *pos <= '9') || *pos == '.' ||
1574		       (*pos >= 'a' && *pos <= 'f') || *pos == ':' ||
1575		       (*pos >= 'A' && *pos <= 'F')) {
1576			pos++;
1577		}
1578
1579		if (*pos == '\0') {
1580			failed = 1;
1581			break;
1582		}
1583
1584		if (*pos == '/') {
1585			char *end;
1586			*pos++ = '\0';
1587			mask = strtol(pos, &end, 10);
1588			if ((pos == end) ||
1589			    (mask < 0 || mask > (ipv6 ? 128 : 32))) {
1590				failed = 1;
1591				break;
1592			}
1593			pos = end;
1594		} else {
1595			mask = ipv6 ? 128 : 32;
1596			*pos++ = '\0';
1597		}
1598
1599		if (!ipv6 && inet_aton(buf, &addr) == 0) {
1600			failed = 1;
1601			break;
1602		}
1603#ifdef CONFIG_IPV6
1604		if (ipv6 && inet_pton(AF_INET6, buf, &addr6) <= 0) {
1605			if (inet_pton(AF_INET, buf, &addr) <= 0) {
1606				failed = 1;
1607				break;
1608			}
1609			/* Convert IPv4 address to IPv6 */
1610			if (mask <= 32)
1611				mask += (128 - 32);
1612			os_memset(addr6.s6_addr, 0, 10);
1613			addr6.s6_addr[10] = 0xff;
1614			addr6.s6_addr[11] = 0xff;
1615			os_memcpy(addr6.s6_addr + 12, (char *) &addr.s_addr,
1616				  4);
1617		}
1618#endif /* CONFIG_IPV6 */
1619
1620		while (*pos == ' ' || *pos == '\t') {
1621			pos++;
1622		}
1623
1624		if (*pos == '\0') {
1625			failed = 1;
1626			break;
1627		}
1628
1629		entry = os_zalloc(sizeof(*entry));
1630		if (entry == NULL) {
1631			failed = 1;
1632			break;
1633		}
1634		entry->shared_secret = os_strdup(pos);
1635		if (entry->shared_secret == NULL) {
1636			failed = 1;
1637			os_free(entry);
1638			break;
1639		}
1640		entry->shared_secret_len = os_strlen(entry->shared_secret);
1641		if (!ipv6) {
1642			entry->addr.s_addr = addr.s_addr;
1643			val = 0;
1644			for (i = 0; i < mask; i++)
1645				val |= 1 << (31 - i);
1646			entry->mask.s_addr = htonl(val);
1647		}
1648#ifdef CONFIG_IPV6
1649		if (ipv6) {
1650			int offset = mask / 8;
1651
1652			os_memcpy(entry->addr6.s6_addr, addr6.s6_addr, 16);
1653			os_memset(entry->mask6.s6_addr, 0xff, offset);
1654			val = 0;
1655			for (i = 0; i < (mask % 8); i++)
1656				val |= 1 << (7 - i);
1657			if (offset < 16)
1658				entry->mask6.s6_addr[offset] = val;
1659		}
1660#endif /* CONFIG_IPV6 */
1661
1662		if (tail == NULL) {
1663			clients = tail = entry;
1664		} else {
1665			tail->next = entry;
1666			tail = entry;
1667		}
1668	}
1669
1670	if (failed) {
1671		RADIUS_ERROR("Invalid line %d in '%s'", line, client_file);
1672		radius_server_free_clients(NULL, clients);
1673		clients = NULL;
1674	}
1675
1676	os_free(buf);
1677	fclose(f);
1678
1679	return clients;
1680}
1681
1682
1683/**
1684 * radius_server_init - Initialize RADIUS server
1685 * @conf: Configuration for the RADIUS server
1686 * Returns: Pointer to private RADIUS server context or %NULL on failure
1687 *
1688 * This initializes a RADIUS server instance and returns a context pointer that
1689 * will be used in other calls to the RADIUS server module. The server can be
1690 * deinitialize by calling radius_server_deinit().
1691 */
1692struct radius_server_data *
1693radius_server_init(struct radius_server_conf *conf)
1694{
1695	struct radius_server_data *data;
1696
1697#ifndef CONFIG_IPV6
1698	if (conf->ipv6) {
1699		wpa_printf(MSG_ERROR, "RADIUS server compiled without IPv6 support");
1700		return NULL;
1701	}
1702#endif /* CONFIG_IPV6 */
1703
1704	data = os_zalloc(sizeof(*data));
1705	if (data == NULL)
1706		return NULL;
1707
1708	dl_list_init(&data->erp_keys);
1709	os_get_reltime(&data->start_time);
1710	data->conf_ctx = conf->conf_ctx;
1711	data->eap_sim_db_priv = conf->eap_sim_db_priv;
1712	data->ssl_ctx = conf->ssl_ctx;
1713	data->msg_ctx = conf->msg_ctx;
1714	data->ipv6 = conf->ipv6;
1715	if (conf->pac_opaque_encr_key) {
1716		data->pac_opaque_encr_key = os_malloc(16);
1717		if (data->pac_opaque_encr_key) {
1718			os_memcpy(data->pac_opaque_encr_key,
1719				  conf->pac_opaque_encr_key, 16);
1720		}
1721	}
1722	if (conf->eap_fast_a_id) {
1723		data->eap_fast_a_id = os_malloc(conf->eap_fast_a_id_len);
1724		if (data->eap_fast_a_id) {
1725			os_memcpy(data->eap_fast_a_id, conf->eap_fast_a_id,
1726				  conf->eap_fast_a_id_len);
1727			data->eap_fast_a_id_len = conf->eap_fast_a_id_len;
1728		}
1729	}
1730	if (conf->eap_fast_a_id_info)
1731		data->eap_fast_a_id_info = os_strdup(conf->eap_fast_a_id_info);
1732	data->eap_fast_prov = conf->eap_fast_prov;
1733	data->pac_key_lifetime = conf->pac_key_lifetime;
1734	data->pac_key_refresh_time = conf->pac_key_refresh_time;
1735	data->get_eap_user = conf->get_eap_user;
1736	data->eap_sim_aka_result_ind = conf->eap_sim_aka_result_ind;
1737	data->tnc = conf->tnc;
1738	data->wps = conf->wps;
1739	data->pwd_group = conf->pwd_group;
1740	data->server_id = conf->server_id;
1741	if (conf->eap_req_id_text) {
1742		data->eap_req_id_text = os_malloc(conf->eap_req_id_text_len);
1743		if (data->eap_req_id_text) {
1744			os_memcpy(data->eap_req_id_text, conf->eap_req_id_text,
1745				  conf->eap_req_id_text_len);
1746			data->eap_req_id_text_len = conf->eap_req_id_text_len;
1747		}
1748	}
1749	data->erp = conf->erp;
1750	data->erp_domain = conf->erp_domain;
1751	data->tls_session_lifetime = conf->tls_session_lifetime;
1752
1753	if (conf->subscr_remediation_url) {
1754		data->subscr_remediation_url =
1755			os_strdup(conf->subscr_remediation_url);
1756	}
1757	data->subscr_remediation_method = conf->subscr_remediation_method;
1758
1759#ifdef CONFIG_SQLITE
1760	if (conf->sqlite_file) {
1761		if (sqlite3_open(conf->sqlite_file, &data->db)) {
1762			RADIUS_ERROR("Could not open SQLite file '%s'",
1763				     conf->sqlite_file);
1764			radius_server_deinit(data);
1765			return NULL;
1766		}
1767	}
1768#endif /* CONFIG_SQLITE */
1769
1770#ifdef CONFIG_RADIUS_TEST
1771	if (conf->dump_msk_file)
1772		data->dump_msk_file = os_strdup(conf->dump_msk_file);
1773#endif /* CONFIG_RADIUS_TEST */
1774
1775	data->clients = radius_server_read_clients(conf->client_file,
1776						   conf->ipv6);
1777	if (data->clients == NULL) {
1778		wpa_printf(MSG_ERROR, "No RADIUS clients configured");
1779		radius_server_deinit(data);
1780		return NULL;
1781	}
1782
1783#ifdef CONFIG_IPV6
1784	if (conf->ipv6)
1785		data->auth_sock = radius_server_open_socket6(conf->auth_port);
1786	else
1787#endif /* CONFIG_IPV6 */
1788	data->auth_sock = radius_server_open_socket(conf->auth_port);
1789	if (data->auth_sock < 0) {
1790		wpa_printf(MSG_ERROR, "Failed to open UDP socket for RADIUS authentication server");
1791		radius_server_deinit(data);
1792		return NULL;
1793	}
1794	if (eloop_register_read_sock(data->auth_sock,
1795				     radius_server_receive_auth,
1796				     data, NULL)) {
1797		radius_server_deinit(data);
1798		return NULL;
1799	}
1800
1801	if (conf->acct_port) {
1802#ifdef CONFIG_IPV6
1803		if (conf->ipv6)
1804			data->acct_sock = radius_server_open_socket6(
1805				conf->acct_port);
1806		else
1807#endif /* CONFIG_IPV6 */
1808		data->acct_sock = radius_server_open_socket(conf->acct_port);
1809		if (data->acct_sock < 0) {
1810			wpa_printf(MSG_ERROR, "Failed to open UDP socket for RADIUS accounting server");
1811			radius_server_deinit(data);
1812			return NULL;
1813		}
1814		if (eloop_register_read_sock(data->acct_sock,
1815					     radius_server_receive_acct,
1816					     data, NULL)) {
1817			radius_server_deinit(data);
1818			return NULL;
1819		}
1820	} else {
1821		data->acct_sock = -1;
1822	}
1823
1824	return data;
1825}
1826
1827
1828/**
1829 * radius_server_erp_flush - Flush all ERP keys
1830 * @data: RADIUS server context from radius_server_init()
1831 */
1832void radius_server_erp_flush(struct radius_server_data *data)
1833{
1834	struct eap_server_erp_key *erp;
1835
1836	if (data == NULL)
1837		return;
1838	while ((erp = dl_list_first(&data->erp_keys, struct eap_server_erp_key,
1839				    list)) != NULL) {
1840		dl_list_del(&erp->list);
1841		bin_clear_free(erp, sizeof(*erp));
1842	}
1843}
1844
1845
1846/**
1847 * radius_server_deinit - Deinitialize RADIUS server
1848 * @data: RADIUS server context from radius_server_init()
1849 */
1850void radius_server_deinit(struct radius_server_data *data)
1851{
1852	if (data == NULL)
1853		return;
1854
1855	if (data->auth_sock >= 0) {
1856		eloop_unregister_read_sock(data->auth_sock);
1857		close(data->auth_sock);
1858	}
1859
1860	if (data->acct_sock >= 0) {
1861		eloop_unregister_read_sock(data->acct_sock);
1862		close(data->acct_sock);
1863	}
1864
1865	radius_server_free_clients(data, data->clients);
1866
1867	os_free(data->pac_opaque_encr_key);
1868	os_free(data->eap_fast_a_id);
1869	os_free(data->eap_fast_a_id_info);
1870	os_free(data->eap_req_id_text);
1871#ifdef CONFIG_RADIUS_TEST
1872	os_free(data->dump_msk_file);
1873#endif /* CONFIG_RADIUS_TEST */
1874	os_free(data->subscr_remediation_url);
1875
1876#ifdef CONFIG_SQLITE
1877	if (data->db)
1878		sqlite3_close(data->db);
1879#endif /* CONFIG_SQLITE */
1880
1881	radius_server_erp_flush(data);
1882
1883	os_free(data);
1884}
1885
1886
1887/**
1888 * radius_server_get_mib - Get RADIUS server MIB information
1889 * @data: RADIUS server context from radius_server_init()
1890 * @buf: Buffer for returning the MIB data in text format
1891 * @buflen: buf length in octets
1892 * Returns: Number of octets written into buf
1893 */
1894int radius_server_get_mib(struct radius_server_data *data, char *buf,
1895			  size_t buflen)
1896{
1897	int ret, uptime;
1898	unsigned int idx;
1899	char *end, *pos;
1900	struct os_reltime now;
1901	struct radius_client *cli;
1902
1903	/* RFC 2619 - RADIUS Authentication Server MIB */
1904
1905	if (data == NULL || buflen == 0)
1906		return 0;
1907
1908	pos = buf;
1909	end = buf + buflen;
1910
1911	os_get_reltime(&now);
1912	uptime = (now.sec - data->start_time.sec) * 100 +
1913		((now.usec - data->start_time.usec) / 10000) % 100;
1914	ret = os_snprintf(pos, end - pos,
1915			  "RADIUS-AUTH-SERVER-MIB\n"
1916			  "radiusAuthServIdent=hostapd\n"
1917			  "radiusAuthServUpTime=%d\n"
1918			  "radiusAuthServResetTime=0\n"
1919			  "radiusAuthServConfigReset=4\n",
1920			  uptime);
1921	if (os_snprintf_error(end - pos, ret)) {
1922		*pos = '\0';
1923		return pos - buf;
1924	}
1925	pos += ret;
1926
1927	ret = os_snprintf(pos, end - pos,
1928			  "radiusAuthServTotalAccessRequests=%u\n"
1929			  "radiusAuthServTotalInvalidRequests=%u\n"
1930			  "radiusAuthServTotalDupAccessRequests=%u\n"
1931			  "radiusAuthServTotalAccessAccepts=%u\n"
1932			  "radiusAuthServTotalAccessRejects=%u\n"
1933			  "radiusAuthServTotalAccessChallenges=%u\n"
1934			  "radiusAuthServTotalMalformedAccessRequests=%u\n"
1935			  "radiusAuthServTotalBadAuthenticators=%u\n"
1936			  "radiusAuthServTotalPacketsDropped=%u\n"
1937			  "radiusAuthServTotalUnknownTypes=%u\n"
1938			  "radiusAccServTotalRequests=%u\n"
1939			  "radiusAccServTotalInvalidRequests=%u\n"
1940			  "radiusAccServTotalResponses=%u\n"
1941			  "radiusAccServTotalMalformedRequests=%u\n"
1942			  "radiusAccServTotalBadAuthenticators=%u\n"
1943			  "radiusAccServTotalUnknownTypes=%u\n",
1944			  data->counters.access_requests,
1945			  data->counters.invalid_requests,
1946			  data->counters.dup_access_requests,
1947			  data->counters.access_accepts,
1948			  data->counters.access_rejects,
1949			  data->counters.access_challenges,
1950			  data->counters.malformed_access_requests,
1951			  data->counters.bad_authenticators,
1952			  data->counters.packets_dropped,
1953			  data->counters.unknown_types,
1954			  data->counters.acct_requests,
1955			  data->counters.invalid_acct_requests,
1956			  data->counters.acct_responses,
1957			  data->counters.malformed_acct_requests,
1958			  data->counters.acct_bad_authenticators,
1959			  data->counters.unknown_acct_types);
1960	if (os_snprintf_error(end - pos, ret)) {
1961		*pos = '\0';
1962		return pos - buf;
1963	}
1964	pos += ret;
1965
1966	for (cli = data->clients, idx = 0; cli; cli = cli->next, idx++) {
1967		char abuf[50], mbuf[50];
1968#ifdef CONFIG_IPV6
1969		if (data->ipv6) {
1970			if (inet_ntop(AF_INET6, &cli->addr6, abuf,
1971				      sizeof(abuf)) == NULL)
1972				abuf[0] = '\0';
1973			if (inet_ntop(AF_INET6, &cli->mask6, mbuf,
1974				      sizeof(mbuf)) == NULL)
1975				mbuf[0] = '\0';
1976		}
1977#endif /* CONFIG_IPV6 */
1978		if (!data->ipv6) {
1979			os_strlcpy(abuf, inet_ntoa(cli->addr), sizeof(abuf));
1980			os_strlcpy(mbuf, inet_ntoa(cli->mask), sizeof(mbuf));
1981		}
1982
1983		ret = os_snprintf(pos, end - pos,
1984				  "radiusAuthClientIndex=%u\n"
1985				  "radiusAuthClientAddress=%s/%s\n"
1986				  "radiusAuthServAccessRequests=%u\n"
1987				  "radiusAuthServDupAccessRequests=%u\n"
1988				  "radiusAuthServAccessAccepts=%u\n"
1989				  "radiusAuthServAccessRejects=%u\n"
1990				  "radiusAuthServAccessChallenges=%u\n"
1991				  "radiusAuthServMalformedAccessRequests=%u\n"
1992				  "radiusAuthServBadAuthenticators=%u\n"
1993				  "radiusAuthServPacketsDropped=%u\n"
1994				  "radiusAuthServUnknownTypes=%u\n"
1995				  "radiusAccServTotalRequests=%u\n"
1996				  "radiusAccServTotalInvalidRequests=%u\n"
1997				  "radiusAccServTotalResponses=%u\n"
1998				  "radiusAccServTotalMalformedRequests=%u\n"
1999				  "radiusAccServTotalBadAuthenticators=%u\n"
2000				  "radiusAccServTotalUnknownTypes=%u\n",
2001				  idx,
2002				  abuf, mbuf,
2003				  cli->counters.access_requests,
2004				  cli->counters.dup_access_requests,
2005				  cli->counters.access_accepts,
2006				  cli->counters.access_rejects,
2007				  cli->counters.access_challenges,
2008				  cli->counters.malformed_access_requests,
2009				  cli->counters.bad_authenticators,
2010				  cli->counters.packets_dropped,
2011				  cli->counters.unknown_types,
2012				  cli->counters.acct_requests,
2013				  cli->counters.invalid_acct_requests,
2014				  cli->counters.acct_responses,
2015				  cli->counters.malformed_acct_requests,
2016				  cli->counters.acct_bad_authenticators,
2017				  cli->counters.unknown_acct_types);
2018		if (os_snprintf_error(end - pos, ret)) {
2019			*pos = '\0';
2020			return pos - buf;
2021		}
2022		pos += ret;
2023	}
2024
2025	return pos - buf;
2026}
2027
2028
2029static int radius_server_get_eap_user(void *ctx, const u8 *identity,
2030				      size_t identity_len, int phase2,
2031				      struct eap_user *user)
2032{
2033	struct radius_session *sess = ctx;
2034	struct radius_server_data *data = sess->server;
2035	int ret;
2036
2037	ret = data->get_eap_user(data->conf_ctx, identity, identity_len,
2038				 phase2, user);
2039	if (ret == 0 && user) {
2040		sess->accept_attr = user->accept_attr;
2041		sess->remediation = user->remediation;
2042		sess->macacl = user->macacl;
2043	}
2044
2045	if (ret) {
2046		RADIUS_DEBUG("%s: User-Name not found from user database",
2047			     __func__);
2048	}
2049
2050	return ret;
2051}
2052
2053
2054static const char * radius_server_get_eap_req_id_text(void *ctx, size_t *len)
2055{
2056	struct radius_session *sess = ctx;
2057	struct radius_server_data *data = sess->server;
2058	*len = data->eap_req_id_text_len;
2059	return data->eap_req_id_text;
2060}
2061
2062
2063static void radius_server_log_msg(void *ctx, const char *msg)
2064{
2065	struct radius_session *sess = ctx;
2066	srv_log(sess, "EAP: %s", msg);
2067}
2068
2069
2070#ifdef CONFIG_ERP
2071
2072static const char * radius_server_get_erp_domain(void *ctx)
2073{
2074	struct radius_session *sess = ctx;
2075	struct radius_server_data *data = sess->server;
2076
2077	return data->erp_domain;
2078}
2079
2080
2081static struct eap_server_erp_key *
2082radius_server_erp_get_key(void *ctx, const char *keyname)
2083{
2084	struct radius_session *sess = ctx;
2085	struct radius_server_data *data = sess->server;
2086	struct eap_server_erp_key *erp;
2087
2088	dl_list_for_each(erp, &data->erp_keys, struct eap_server_erp_key,
2089			 list) {
2090		if (os_strcmp(erp->keyname_nai, keyname) == 0)
2091			return erp;
2092	}
2093
2094	return NULL;
2095}
2096
2097
2098static int radius_server_erp_add_key(void *ctx, struct eap_server_erp_key *erp)
2099{
2100	struct radius_session *sess = ctx;
2101	struct radius_server_data *data = sess->server;
2102
2103	dl_list_add(&data->erp_keys, &erp->list);
2104	return 0;
2105}
2106
2107#endif /* CONFIG_ERP */
2108
2109
2110static const struct eapol_callbacks radius_server_eapol_cb =
2111{
2112	.get_eap_user = radius_server_get_eap_user,
2113	.get_eap_req_id_text = radius_server_get_eap_req_id_text,
2114	.log_msg = radius_server_log_msg,
2115#ifdef CONFIG_ERP
2116	.get_erp_send_reauth_start = NULL,
2117	.get_erp_domain = radius_server_get_erp_domain,
2118	.erp_get_key = radius_server_erp_get_key,
2119	.erp_add_key = radius_server_erp_add_key,
2120#endif /* CONFIG_ERP */
2121};
2122
2123
2124/**
2125 * radius_server_eap_pending_cb - Pending EAP data notification
2126 * @data: RADIUS server context from radius_server_init()
2127 * @ctx: Pending EAP context pointer
2128 *
2129 * This function is used to notify EAP server module that a pending operation
2130 * has been completed and processing of the EAP session can proceed.
2131 */
2132void radius_server_eap_pending_cb(struct radius_server_data *data, void *ctx)
2133{
2134	struct radius_client *cli;
2135	struct radius_session *s, *sess = NULL;
2136	struct radius_msg *msg;
2137
2138	if (data == NULL)
2139		return;
2140
2141	for (cli = data->clients; cli; cli = cli->next) {
2142		for (s = cli->sessions; s; s = s->next) {
2143			if (s->eap == ctx && s->last_msg) {
2144				sess = s;
2145				break;
2146			}
2147		}
2148		if (sess)
2149			break;
2150	}
2151
2152	if (sess == NULL) {
2153		RADIUS_DEBUG("No session matched callback ctx");
2154		return;
2155	}
2156
2157	msg = sess->last_msg;
2158	sess->last_msg = NULL;
2159	eap_sm_pending_cb(sess->eap);
2160	if (radius_server_request(data, msg,
2161				  (struct sockaddr *) &sess->last_from,
2162				  sess->last_fromlen, cli,
2163				  sess->last_from_addr,
2164				  sess->last_from_port, sess) == -2)
2165		return; /* msg was stored with the session */
2166
2167	radius_msg_free(msg);
2168}
2169