1  /*
2   * RADIUS authentication server
3   * Copyright (c) 2005-2009, 2011-2019, 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_SESSION_MAINTAIN - Completed session expiration timeout in seconds
30   */
31  #define RADIUS_SESSION_MAINTAIN 5
32  
33  /**
34   * RADIUS_MAX_SESSION - Maximum number of active sessions
35   */
36  #define RADIUS_MAX_SESSION 1000
37  
38  static const struct eapol_callbacks radius_server_eapol_cb;
39  
40  struct radius_client;
41  struct radius_server_data;
42  
43  /**
44   * struct radius_server_counters - RADIUS server statistics counters
45   */
46  struct 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   */
69  struct 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  	u8 mac_addr[ETH_ALEN]; /* from Calling-Station-Id attribute */
79  
80  	struct radius_msg *last_msg;
81  	char *last_from_addr;
82  	int last_from_port;
83  	struct sockaddr_storage last_from;
84  	socklen_t last_fromlen;
85  	u8 last_identifier;
86  	struct radius_msg *last_reply;
87  	u8 last_authenticator[16];
88  
89  	unsigned int macacl:1;
90  	unsigned int t_c_filtering:1;
91  
92  	struct hostapd_radius_attr *accept_attr;
93  
94  	u32 t_c_timestamp; /* Last read T&C timestamp from user DB */
95  };
96  
97  /**
98   * struct radius_client - Internal RADIUS server data for a client
99   */
100  struct radius_client {
101  	struct radius_client *next;
102  	struct in_addr addr;
103  	struct in_addr mask;
104  #ifdef CONFIG_IPV6
105  	struct in6_addr addr6;
106  	struct in6_addr mask6;
107  #endif /* CONFIG_IPV6 */
108  	char *shared_secret;
109  	int shared_secret_len;
110  	struct radius_session *sessions;
111  	struct radius_server_counters counters;
112  
113  	u8 next_dac_identifier;
114  	struct radius_msg *pending_dac_coa_req;
115  	u8 pending_dac_coa_id;
116  	u8 pending_dac_coa_addr[ETH_ALEN];
117  	struct radius_msg *pending_dac_disconnect_req;
118  	u8 pending_dac_disconnect_id;
119  	u8 pending_dac_disconnect_addr[ETH_ALEN];
120  };
121  
122  /**
123   * struct radius_server_data - Internal RADIUS server data
124   */
125  struct radius_server_data {
126  	/**
127  	 * auth_sock - Socket for RADIUS authentication messages
128  	 */
129  	int auth_sock;
130  
131  	/**
132  	 * acct_sock - Socket for RADIUS accounting messages
133  	 */
134  	int acct_sock;
135  
136  	/**
137  	 * clients - List of authorized RADIUS clients
138  	 */
139  	struct radius_client *clients;
140  
141  	/**
142  	 * next_sess_id - Next session identifier
143  	 */
144  	unsigned int next_sess_id;
145  
146  	/**
147  	 * conf_ctx - Context pointer for callbacks
148  	 *
149  	 * This is used as the ctx argument in get_eap_user() and acct_req_cb()
150  	 * calls.
151  	 */
152  	void *conf_ctx;
153  
154  	/**
155  	 * num_sess - Number of active sessions
156  	 */
157  	int num_sess;
158  
159  	const char *erp_domain;
160  
161  	struct dl_list erp_keys; /* struct eap_server_erp_key */
162  
163  	/**
164  	 * ipv6 - Whether to enable IPv6 support in the RADIUS server
165  	 */
166  	int ipv6;
167  
168  	/**
169  	 * start_time - Timestamp of server start
170  	 */
171  	struct os_reltime start_time;
172  
173  	/**
174  	 * counters - Statistics counters for server operations
175  	 *
176  	 * These counters are the sum over all clients.
177  	 */
178  	struct radius_server_counters counters;
179  
180  	/**
181  	 * get_eap_user - Callback for fetching EAP user information
182  	 * @ctx: Context data from conf_ctx
183  	 * @identity: User identity
184  	 * @identity_len: identity buffer length in octets
185  	 * @phase2: Whether this is for Phase 2 identity
186  	 * @user: Data structure for filling in the user information
187  	 * Returns: 0 on success, -1 on failure
188  	 *
189  	 * This is used to fetch information from user database. The callback
190  	 * will fill in information about allowed EAP methods and the user
191  	 * password. The password field will be an allocated copy of the
192  	 * password data and RADIUS server will free it after use.
193  	 */
194  	int (*get_eap_user)(void *ctx, const u8 *identity, size_t identity_len,
195  			    int phase2, struct eap_user *user);
196  
197  	/**
198  	 * acct_req_cb - Callback for processing received RADIUS accounting
199  	 * requests
200  	 * @ctx: Context data from conf_ctx
201  	 * @msg: Received RADIUS accounting request
202  	 * @status_type: Status type from the message (parsed Acct-Status-Type
203  	 * attribute)
204  	 * Returns: 0 on success, -1 on failure
205  	 *
206  	 * This can be used to log accounting information into file, database,
207  	 * syslog server, etc.
208  	 * Callback should not modify the message.
209  	 * If 0 is returned, response is automatically created. Otherwise,
210  	 * no response is created.
211  	 *
212  	 * acct_req_cb can be set to null to omit any custom processing of
213  	 * account requests. Statistics counters will be incremented in any
214  	 * case.
215  	 */
216  	int (*acct_req_cb)(void *ctx, struct radius_msg *msg, u32 status_type);
217  
218  	/**
219  	 * eap_req_id_text - Optional data for EAP-Request/Identity
220  	 *
221  	 * This can be used to configure an optional, displayable message that
222  	 * will be sent in EAP-Request/Identity. This string can contain an
223  	 * ASCII-0 character (nul) to separate network infromation per RFC
224  	 * 4284. The actual string length is explicit provided in
225  	 * eap_req_id_text_len since nul character will not be used as a string
226  	 * terminator.
227  	 */
228  	char *eap_req_id_text;
229  
230  	/**
231  	 * eap_req_id_text_len - Length of eap_req_id_text buffer in octets
232  	 */
233  	size_t eap_req_id_text_len;
234  
235  #ifdef CONFIG_RADIUS_TEST
236  	char *dump_msk_file;
237  #endif /* CONFIG_RADIUS_TEST */
238  
239  	char *t_c_server_url;
240  
241  #ifdef CONFIG_SQLITE
242  	sqlite3 *db;
243  #endif /* CONFIG_SQLITE */
244  
245  	const struct eap_config *eap_cfg;
246  };
247  
248  
249  #define RADIUS_DEBUG(args...) \
250  wpa_printf(MSG_DEBUG, "RADIUS SRV: " args)
251  #define RADIUS_ERROR(args...) \
252  wpa_printf(MSG_ERROR, "RADIUS SRV: " args)
253  #define RADIUS_DUMP(args...) \
254  wpa_hexdump(MSG_MSGDUMP, "RADIUS SRV: " args)
255  #define RADIUS_DUMP_ASCII(args...) \
256  wpa_hexdump_ascii(MSG_MSGDUMP, "RADIUS SRV: " args)
257  
258  
259  static void radius_server_session_timeout(void *eloop_ctx, void *timeout_ctx);
260  static void radius_server_session_remove_timeout(void *eloop_ctx,
261  						 void *timeout_ctx);
262  
263  void srv_log(struct radius_session *sess, const char *fmt, ...)
264  PRINTF_FORMAT(2, 3);
265  
srv_log(struct radius_session * sess,const char * fmt,...)266  void srv_log(struct radius_session *sess, const char *fmt, ...)
267  {
268  	va_list ap;
269  	char *buf;
270  	int buflen;
271  
272  	va_start(ap, fmt);
273  	buflen = vsnprintf(NULL, 0, fmt, ap) + 1;
274  	va_end(ap);
275  
276  	buf = os_malloc(buflen);
277  	if (buf == NULL)
278  		return;
279  	va_start(ap, fmt);
280  	vsnprintf(buf, buflen, fmt, ap);
281  	va_end(ap);
282  
283  	RADIUS_DEBUG("[0x%x %s] %s", sess->sess_id, sess->nas_ip, buf);
284  
285  #ifdef CONFIG_SQLITE
286  	if (sess->server->db) {
287  		char *sql;
288  		sql = sqlite3_mprintf("INSERT INTO authlog"
289  				      "(timestamp,session,nas_ip,username,note)"
290  				      " VALUES ("
291  				      "strftime('%%Y-%%m-%%d %%H:%%M:%%f',"
292  				      "'now'),%u,%Q,%Q,%Q)",
293  				      sess->sess_id, sess->nas_ip,
294  				      sess->username, buf);
295  		if (sql) {
296  			if (sqlite3_exec(sess->server->db, sql, NULL, NULL,
297  					 NULL) != SQLITE_OK) {
298  				RADIUS_ERROR("Failed to add authlog entry into sqlite database: %s",
299  					     sqlite3_errmsg(sess->server->db));
300  			}
301  			sqlite3_free(sql);
302  		}
303  	}
304  #endif /* CONFIG_SQLITE */
305  
306  	os_free(buf);
307  }
308  
309  
310  static struct radius_client *
radius_server_get_client(struct radius_server_data * data,struct in_addr * addr,int ipv6)311  radius_server_get_client(struct radius_server_data *data, struct in_addr *addr,
312  			 int ipv6)
313  {
314  	struct radius_client *client = data->clients;
315  
316  	while (client) {
317  #ifdef CONFIG_IPV6
318  		if (ipv6) {
319  			struct in6_addr *addr6;
320  			int i;
321  
322  			addr6 = (struct in6_addr *) addr;
323  			for (i = 0; i < 16; i++) {
324  				if ((addr6->s6_addr[i] &
325  				     client->mask6.s6_addr[i]) !=
326  				    (client->addr6.s6_addr[i] &
327  				     client->mask6.s6_addr[i])) {
328  					i = 17;
329  					break;
330  				}
331  			}
332  			if (i == 16) {
333  				break;
334  			}
335  		}
336  #endif /* CONFIG_IPV6 */
337  		if (!ipv6 && (client->addr.s_addr & client->mask.s_addr) ==
338  		    (addr->s_addr & client->mask.s_addr)) {
339  			break;
340  		}
341  
342  		client = client->next;
343  	}
344  
345  	return client;
346  }
347  
348  
349  static struct radius_session *
radius_server_get_session(struct radius_client * client,unsigned int sess_id)350  radius_server_get_session(struct radius_client *client, unsigned int sess_id)
351  {
352  	struct radius_session *sess = client->sessions;
353  
354  	while (sess) {
355  		if (sess->sess_id == sess_id) {
356  			break;
357  		}
358  		sess = sess->next;
359  	}
360  
361  	return sess;
362  }
363  
364  
radius_server_session_free(struct radius_server_data * data,struct radius_session * sess)365  static void radius_server_session_free(struct radius_server_data *data,
366  				       struct radius_session *sess)
367  {
368  	eloop_cancel_timeout(radius_server_session_timeout, data, sess);
369  	eloop_cancel_timeout(radius_server_session_remove_timeout, data, sess);
370  	eap_server_sm_deinit(sess->eap);
371  	radius_msg_free(sess->last_msg);
372  	os_free(sess->last_from_addr);
373  	radius_msg_free(sess->last_reply);
374  	os_free(sess->username);
375  	os_free(sess->nas_ip);
376  	os_free(sess);
377  	data->num_sess--;
378  }
379  
380  
radius_server_session_remove(struct radius_server_data * data,struct radius_session * sess)381  static void radius_server_session_remove(struct radius_server_data *data,
382  					 struct radius_session *sess)
383  {
384  	struct radius_client *client = sess->client;
385  	struct radius_session *session, *prev;
386  
387  	eloop_cancel_timeout(radius_server_session_remove_timeout, data, sess);
388  
389  	prev = NULL;
390  	session = client->sessions;
391  	while (session) {
392  		if (session == sess) {
393  			if (prev == NULL) {
394  				client->sessions = sess->next;
395  			} else {
396  				prev->next = sess->next;
397  			}
398  			radius_server_session_free(data, sess);
399  			break;
400  		}
401  		prev = session;
402  		session = session->next;
403  	}
404  }
405  
406  
radius_server_session_remove_timeout(void * eloop_ctx,void * timeout_ctx)407  static void radius_server_session_remove_timeout(void *eloop_ctx,
408  						 void *timeout_ctx)
409  {
410  	struct radius_server_data *data = eloop_ctx;
411  	struct radius_session *sess = timeout_ctx;
412  	RADIUS_DEBUG("Removing completed session 0x%x", sess->sess_id);
413  	radius_server_session_remove(data, sess);
414  }
415  
416  
radius_server_session_timeout(void * eloop_ctx,void * timeout_ctx)417  static void radius_server_session_timeout(void *eloop_ctx, void *timeout_ctx)
418  {
419  	struct radius_server_data *data = eloop_ctx;
420  	struct radius_session *sess = timeout_ctx;
421  
422  	RADIUS_DEBUG("Timing out authentication session 0x%x", sess->sess_id);
423  	radius_server_session_remove(data, sess);
424  }
425  
426  
427  static struct radius_session *
radius_server_new_session(struct radius_server_data * data,struct radius_client * client)428  radius_server_new_session(struct radius_server_data *data,
429  			  struct radius_client *client)
430  {
431  	struct radius_session *sess;
432  
433  	if (data->num_sess >= RADIUS_MAX_SESSION) {
434  		RADIUS_DEBUG("Maximum number of existing session - no room "
435  			     "for a new session");
436  		return NULL;
437  	}
438  
439  	sess = os_zalloc(sizeof(*sess));
440  	if (sess == NULL)
441  		return NULL;
442  
443  	sess->server = data;
444  	sess->client = client;
445  	sess->sess_id = data->next_sess_id++;
446  	sess->next = client->sessions;
447  	client->sessions = sess;
448  	eloop_register_timeout(RADIUS_SESSION_TIMEOUT, 0,
449  			       radius_server_session_timeout, data, sess);
450  	data->num_sess++;
451  	return sess;
452  }
453  
454  
455  #ifdef CONFIG_TESTING_OPTIONS
radius_server_testing_options_tls(struct radius_session * sess,const char * tls,struct eap_session_data * eap_conf)456  static void radius_server_testing_options_tls(struct radius_session *sess,
457  					      const char *tls,
458  					      struct eap_session_data *eap_conf)
459  {
460  	int test = atoi(tls);
461  
462  	switch (test) {
463  	case 1:
464  		srv_log(sess, "TLS test - break VerifyData");
465  		eap_conf->tls_test_flags = TLS_BREAK_VERIFY_DATA;
466  		break;
467  	case 2:
468  		srv_log(sess, "TLS test - break ServerKeyExchange ServerParams hash");
469  		eap_conf->tls_test_flags = TLS_BREAK_SRV_KEY_X_HASH;
470  		break;
471  	case 3:
472  		srv_log(sess, "TLS test - break ServerKeyExchange ServerParams Signature");
473  		eap_conf->tls_test_flags = TLS_BREAK_SRV_KEY_X_SIGNATURE;
474  		break;
475  	case 4:
476  		srv_log(sess, "TLS test - RSA-DHE using a short 511-bit prime");
477  		eap_conf->tls_test_flags = TLS_DHE_PRIME_511B;
478  		break;
479  	case 5:
480  		srv_log(sess, "TLS test - RSA-DHE using a short 767-bit prime");
481  		eap_conf->tls_test_flags = TLS_DHE_PRIME_767B;
482  		break;
483  	case 6:
484  		srv_log(sess, "TLS test - RSA-DHE using a bogus 15 \"prime\"");
485  		eap_conf->tls_test_flags = TLS_DHE_PRIME_15;
486  		break;
487  	case 7:
488  		srv_log(sess, "TLS test - RSA-DHE using a short 58-bit prime in long container");
489  		eap_conf->tls_test_flags = TLS_DHE_PRIME_58B;
490  		break;
491  	case 8:
492  		srv_log(sess, "TLS test - RSA-DHE using a non-prime");
493  		eap_conf->tls_test_flags = TLS_DHE_NON_PRIME;
494  		break;
495  	default:
496  		srv_log(sess, "Unrecognized TLS test");
497  		break;
498  	}
499  }
500  #endif /* CONFIG_TESTING_OPTIONS */
501  
radius_server_testing_options(struct radius_session * sess,struct eap_session_data * eap_conf)502  static void radius_server_testing_options(struct radius_session *sess,
503  					  struct eap_session_data *eap_conf)
504  {
505  #ifdef CONFIG_TESTING_OPTIONS
506  	const char *pos;
507  
508  	pos = os_strstr(sess->username, "@test-");
509  	if (pos == NULL)
510  		return;
511  	pos += 6;
512  	if (os_strncmp(pos, "tls-", 4) == 0)
513  		radius_server_testing_options_tls(sess, pos + 4, eap_conf);
514  	else
515  		srv_log(sess, "Unrecognized test: %s", pos);
516  #endif /* CONFIG_TESTING_OPTIONS */
517  }
518  
519  
520  #ifdef CONFIG_ERP
521  static struct eap_server_erp_key *
radius_server_erp_find_key(struct radius_server_data * data,const char * keyname)522  radius_server_erp_find_key(struct radius_server_data *data, const char *keyname)
523  {
524  	struct eap_server_erp_key *erp;
525  
526  	dl_list_for_each(erp, &data->erp_keys, struct eap_server_erp_key,
527  			 list) {
528  		if (os_strcmp(erp->keyname_nai, keyname) == 0)
529  			return erp;
530  	}
531  
532  	return NULL;
533  }
534  #endif /* CONFIG_ERP */
535  
536  
537  static struct radius_session *
radius_server_get_new_session(struct radius_server_data * data,struct radius_client * client,struct radius_msg * msg,const char * from_addr)538  radius_server_get_new_session(struct radius_server_data *data,
539  			      struct radius_client *client,
540  			      struct radius_msg *msg, const char *from_addr)
541  {
542  	u8 *user, *id;
543  	size_t user_len, id_len;
544  	int res;
545  	struct radius_session *sess;
546  	struct eap_session_data eap_sess;
547  	struct eap_user *tmp;
548  
549  	RADIUS_DEBUG("Creating a new session");
550  
551  	if (radius_msg_get_attr_ptr(msg, RADIUS_ATTR_USER_NAME, &user,
552  				    &user_len, NULL) < 0) {
553  		RADIUS_DEBUG("Could not get User-Name");
554  		return NULL;
555  	}
556  	RADIUS_DUMP_ASCII("User-Name", user, user_len);
557  
558  	tmp = os_zalloc(sizeof(*tmp));
559  	if (!tmp)
560  		return NULL;
561  
562  	res = data->get_eap_user(data->conf_ctx, user, user_len, 0, tmp);
563  #ifdef CONFIG_ERP
564  	if (res != 0 && data->eap_cfg->erp) {
565  		char *username;
566  
567  		username = os_zalloc(user_len + 1);
568  		if (username) {
569  			os_memcpy(username, user, user_len);
570  			if (radius_server_erp_find_key(data, username))
571  				res = 0;
572  			os_free(username);
573  		}
574  	}
575  #endif /* CONFIG_ERP */
576  	if (res != 0) {
577  		RADIUS_DEBUG("User-Name not found from user database");
578  		eap_user_free(tmp);
579  		return NULL;
580  	}
581  
582  	RADIUS_DEBUG("Matching user entry found");
583  	sess = radius_server_new_session(data, client);
584  	if (sess == NULL) {
585  		RADIUS_DEBUG("Failed to create a new session");
586  		eap_user_free(tmp);
587  		return NULL;
588  	}
589  	sess->accept_attr = tmp->accept_attr;
590  	sess->macacl = tmp->macacl;
591  	eap_user_free(tmp);
592  
593  	sess->username = os_malloc(user_len * 4 + 1);
594  	if (sess->username == NULL) {
595  		radius_server_session_remove(data, sess);
596  		return NULL;
597  	}
598  	printf_encode(sess->username, user_len * 4 + 1, user, user_len);
599  
600  	sess->nas_ip = os_strdup(from_addr);
601  	if (sess->nas_ip == NULL) {
602  		radius_server_session_remove(data, sess);
603  		return NULL;
604  	}
605  
606  	if (radius_msg_get_attr_ptr(msg, RADIUS_ATTR_CALLING_STATION_ID, &id,
607  				    &id_len, NULL) == 0) {
608  		char buf[3 * ETH_ALEN];
609  
610  		os_memset(buf, 0, sizeof(buf));
611  		if (id_len >= sizeof(buf))
612  			id_len = sizeof(buf) - 1;
613  		os_memcpy(buf, id, id_len);
614  		if (hwaddr_aton2(buf, sess->mac_addr) < 0)
615  			os_memset(sess->mac_addr, 0, ETH_ALEN);
616  		else
617  			RADIUS_DEBUG("Calling-Station-Id: " MACSTR,
618  				     MAC2STR(sess->mac_addr));
619  	}
620  
621  	srv_log(sess, "New session created");
622  
623  	os_memset(&eap_sess, 0, sizeof(eap_sess));
624  	radius_server_testing_options(sess, &eap_sess);
625  	sess->eap = eap_server_sm_init(sess, &radius_server_eapol_cb,
626  				       data->eap_cfg, &eap_sess);
627  	if (sess->eap == NULL) {
628  		RADIUS_DEBUG("Failed to initialize EAP state machine for the "
629  			     "new session");
630  		radius_server_session_remove(data, sess);
631  		return NULL;
632  	}
633  	sess->eap_if = eap_get_interface(sess->eap);
634  	sess->eap_if->eapRestart = true;
635  	sess->eap_if->portEnabled = true;
636  
637  	RADIUS_DEBUG("New session 0x%x initialized", sess->sess_id);
638  
639  	return sess;
640  }
641  
642  
643  #ifdef CONFIG_HS20
radius_srv_hs20_t_c_pending(struct radius_session * sess)644  static void radius_srv_hs20_t_c_pending(struct radius_session *sess)
645  {
646  #ifdef CONFIG_SQLITE
647  	char *sql;
648  	char addr[3 * ETH_ALEN], *id_str;
649  	const u8 *id;
650  	size_t id_len;
651  
652  	if (!sess->server->db || !sess->eap ||
653  	    is_zero_ether_addr(sess->mac_addr))
654  		return;
655  
656  	os_snprintf(addr, sizeof(addr), MACSTR, MAC2STR(sess->mac_addr));
657  
658  	id = eap_get_identity(sess->eap, &id_len);
659  	if (!id)
660  		return;
661  	id_str = os_malloc(id_len + 1);
662  	if (!id_str)
663  		return;
664  	os_memcpy(id_str, id, id_len);
665  	id_str[id_len] = '\0';
666  
667  	sql = sqlite3_mprintf("INSERT OR REPLACE INTO pending_tc (mac_addr,identity) VALUES (%Q,%Q)",
668  			      addr, id_str);
669  	os_free(id_str);
670  	if (!sql)
671  		return;
672  
673  	if (sqlite3_exec(sess->server->db, sql, NULL, NULL, NULL) !=
674  	    SQLITE_OK) {
675  		RADIUS_ERROR("Failed to add pending_tc entry into sqlite database: %s",
676  			     sqlite3_errmsg(sess->server->db));
677  	}
678  	sqlite3_free(sql);
679  #endif /* CONFIG_SQLITE */
680  }
681  #endif /* CONFIG_HS20 */
682  
683  
radius_server_add_session(struct radius_session * sess)684  static void radius_server_add_session(struct radius_session *sess)
685  {
686  #ifdef CONFIG_SQLITE
687  	char *sql;
688  	char addr_txt[ETH_ALEN * 3];
689  	struct os_time now;
690  
691  	if (!sess->server->db)
692  		return;
693  
694  
695  	os_snprintf(addr_txt, sizeof(addr_txt), MACSTR,
696  		    MAC2STR(sess->mac_addr));
697  
698  	os_get_time(&now);
699  	sql = sqlite3_mprintf("INSERT OR REPLACE INTO current_sessions(mac_addr,identity,start_time,nas,hs20_t_c_filtering) VALUES (%Q,%Q,%d,%Q,%u)",
700  			      addr_txt, sess->username, now.sec,
701  			      sess->nas_ip, sess->t_c_filtering);
702  	if (sql) {
703  			if (sqlite3_exec(sess->server->db, sql, NULL, NULL,
704  					 NULL) != SQLITE_OK) {
705  				RADIUS_ERROR("Failed to add current_sessions entry into sqlite database: %s",
706  					     sqlite3_errmsg(sess->server->db));
707  			}
708  			sqlite3_free(sql);
709  	}
710  #endif /* CONFIG_SQLITE */
711  }
712  
713  
db_update_last_msk(struct radius_session * sess,const char * msk)714  static void db_update_last_msk(struct radius_session *sess, const char *msk)
715  {
716  #ifdef CONFIG_RADIUS_TEST
717  #ifdef CONFIG_SQLITE
718  	char *sql = NULL;
719  	char *id_str = NULL;
720  	const u8 *id;
721  	size_t id_len;
722  	const char *serial_num;
723  
724  	if (!sess->server->db)
725  		return;
726  
727  	serial_num = eap_get_serial_num(sess->eap);
728  	if (serial_num) {
729  		id_len = 5 + os_strlen(serial_num) + 1;
730  		id_str = os_malloc(id_len);
731  		if (!id_str)
732  			return;
733  		os_snprintf(id_str, id_len, "cert-%s", serial_num);
734  	} else {
735  		id = eap_get_identity(sess->eap, &id_len);
736  		if (!id)
737  			return;
738  		id_str = os_malloc(id_len + 1);
739  		if (!id_str)
740  			return;
741  		os_memcpy(id_str, id, id_len);
742  		id_str[id_len] = '\0';
743  	}
744  
745  	sql = sqlite3_mprintf("UPDATE users SET last_msk=%Q WHERE identity=%Q",
746  			      msk, id_str);
747  	os_free(id_str);
748  	if (!sql)
749  		return;
750  
751  	if (sqlite3_exec(sess->server->db, sql, NULL, NULL, NULL) !=
752  	    SQLITE_OK) {
753  		RADIUS_DEBUG("Failed to update last_msk: %s",
754  			     sqlite3_errmsg(sess->server->db));
755  	}
756  	sqlite3_free(sql);
757  #endif /* CONFIG_SQLITE */
758  #endif /* CONFIG_RADIUS_TEST */
759  }
760  
761  
762  static struct radius_msg *
radius_server_encapsulate_eap(struct radius_server_data * data,struct radius_client * client,struct radius_session * sess,struct radius_msg * request)763  radius_server_encapsulate_eap(struct radius_server_data *data,
764  			      struct radius_client *client,
765  			      struct radius_session *sess,
766  			      struct radius_msg *request)
767  {
768  	struct radius_msg *msg;
769  	int code;
770  	unsigned int sess_id;
771  	struct radius_hdr *hdr = radius_msg_get_hdr(request);
772  	u16 reason = WLAN_REASON_IEEE_802_1X_AUTH_FAILED;
773  
774  	if (sess->eap_if->eapFail) {
775  		sess->eap_if->eapFail = false;
776  		code = RADIUS_CODE_ACCESS_REJECT;
777  	} else if (sess->eap_if->eapSuccess) {
778  		sess->eap_if->eapSuccess = false;
779  		code = RADIUS_CODE_ACCESS_ACCEPT;
780  	} else {
781  		sess->eap_if->eapReq = false;
782  		code = RADIUS_CODE_ACCESS_CHALLENGE;
783  	}
784  
785  	msg = radius_msg_new(code, hdr->identifier);
786  	if (msg == NULL) {
787  		RADIUS_DEBUG("Failed to allocate reply message");
788  		return NULL;
789  	}
790  
791  	if (!radius_msg_add_msg_auth(msg)) {
792  		radius_msg_free(msg);
793  		return NULL;
794  	}
795  
796  	sess_id = htonl(sess->sess_id);
797  	if (code == RADIUS_CODE_ACCESS_CHALLENGE &&
798  	    !radius_msg_add_attr(msg, RADIUS_ATTR_STATE,
799  				 (u8 *) &sess_id, sizeof(sess_id))) {
800  		RADIUS_DEBUG("Failed to add State attribute");
801  	}
802  
803  	if (sess->eap_if->eapReqData &&
804  	    !radius_msg_add_eap(msg, wpabuf_head(sess->eap_if->eapReqData),
805  				wpabuf_len(sess->eap_if->eapReqData))) {
806  		RADIUS_DEBUG("Failed to add EAP-Message attribute");
807  	}
808  
809  	if (code == RADIUS_CODE_ACCESS_ACCEPT && sess->eap_if->eapKeyData) {
810  		int len;
811  #ifdef CONFIG_RADIUS_TEST
812  		char buf[2 * 64 + 1];
813  
814  		len = sess->eap_if->eapKeyDataLen;
815  		if (len > 64)
816  			len = 64;
817  		len = wpa_snprintf_hex(buf, sizeof(buf),
818  				       sess->eap_if->eapKeyData, len);
819  		buf[len] = '\0';
820  
821  		if (data->dump_msk_file) {
822  			FILE *f;
823  
824  			f = fopen(data->dump_msk_file, "a");
825  			if (f) {
826  				len = sess->eap_if->eapKeyDataLen;
827  				if (len > 64)
828  					len = 64;
829  				len = wpa_snprintf_hex(
830  					buf, sizeof(buf),
831  					sess->eap_if->eapKeyData, len);
832  				buf[len] = '\0';
833  				fprintf(f, "%s\n", buf);
834  				fclose(f);
835  			}
836  		}
837  
838  		db_update_last_msk(sess, buf);
839  #endif /* CONFIG_RADIUS_TEST */
840  		if (sess->eap_if->eapKeyDataLen > 64) {
841  			len = 32;
842  		} else {
843  			len = sess->eap_if->eapKeyDataLen / 2;
844  		}
845  		if (!radius_msg_add_mppe_keys(msg, hdr->authenticator,
846  					      (u8 *) client->shared_secret,
847  					      client->shared_secret_len,
848  					      sess->eap_if->eapKeyData + len,
849  					      len, sess->eap_if->eapKeyData,
850  					      len)) {
851  			RADIUS_DEBUG("Failed to add MPPE key attributes");
852  		}
853  
854  		if (sess->eap_if->eapSessionId &&
855  		    !radius_msg_add_attr(msg, RADIUS_ATTR_EAP_KEY_NAME,
856  					 sess->eap_if->eapSessionId,
857  					 sess->eap_if->eapSessionIdLen)) {
858  			RADIUS_DEBUG("Failed to add EAP-Key-Name attribute");
859  		}
860  	}
861  
862  #ifdef CONFIG_HS20
863  	if (code == RADIUS_CODE_ACCESS_ACCEPT && sess->t_c_filtering) {
864  		u8 buf[4] = { 0x01, 0x00, 0x00, 0x00 }; /* E=1 */
865  		const char *url = data->t_c_server_url, *pos;
866  		char *url2, *end2, *pos2;
867  		size_t url_len;
868  
869  		if (!radius_msg_add_wfa(
870  			    msg, RADIUS_VENDOR_ATTR_WFA_HS20_T_C_FILTERING,
871  			    buf, sizeof(buf))) {
872  			RADIUS_DEBUG("Failed to add WFA-HS20-T-C-Filtering");
873  			radius_msg_free(msg);
874  			return NULL;
875  		}
876  
877  		if (!url) {
878  			RADIUS_DEBUG("No t_c_server_url configured");
879  			radius_msg_free(msg);
880  			return NULL;
881  		}
882  
883  		pos = os_strstr(url, "@1@");
884  		if (!pos) {
885  			RADIUS_DEBUG("No @1@ macro in t_c_server_url");
886  			radius_msg_free(msg);
887  			return NULL;
888  		}
889  
890  		url_len = os_strlen(url) + ETH_ALEN * 3 - 1 - 3;
891  		url2 = os_malloc(url_len + 1);
892  		if (!url2) {
893  			RADIUS_DEBUG("Failed to allocate room for T&C Server URL");
894  			os_free(url2);
895  			radius_msg_free(msg);
896  			return NULL;
897  		}
898  		pos2 = url2;
899  		end2 = url2 + url_len + 1;
900  		os_memcpy(pos2, url, pos - url);
901  		pos2 += pos - url;
902  		os_snprintf(pos2, end2 - pos2, MACSTR, MAC2STR(sess->mac_addr));
903  		pos2 += ETH_ALEN * 3 - 1;
904  		os_memcpy(pos2, pos + 3, os_strlen(pos + 3));
905  		if (!radius_msg_add_wfa(msg,
906  					RADIUS_VENDOR_ATTR_WFA_HS20_T_C_URL,
907  					(const u8 *) url2, url_len)) {
908  			RADIUS_DEBUG("Failed to add WFA-HS20-T-C-URL");
909  			os_free(url2);
910  			radius_msg_free(msg);
911  			return NULL;
912  		}
913  		os_free(url2);
914  
915  		radius_srv_hs20_t_c_pending(sess);
916  	}
917  #endif /* CONFIG_HS20 */
918  
919  	if (radius_msg_copy_attr(msg, request, RADIUS_ATTR_PROXY_STATE) < 0) {
920  		RADIUS_DEBUG("Failed to copy Proxy-State attribute(s)");
921  		radius_msg_free(msg);
922  		return NULL;
923  	}
924  
925  	if (code == RADIUS_CODE_ACCESS_ACCEPT) {
926  		struct hostapd_radius_attr *attr;
927  		for (attr = sess->accept_attr; attr; attr = attr->next) {
928  			if (!radius_msg_add_attr(msg, attr->type,
929  						 wpabuf_head(attr->val),
930  						 wpabuf_len(attr->val))) {
931  				wpa_printf(MSG_ERROR, "Could not add RADIUS attribute");
932  				radius_msg_free(msg);
933  				return NULL;
934  			}
935  		}
936  	}
937  
938  	if (code == RADIUS_CODE_ACCESS_REJECT) {
939  		if (radius_msg_add_attr_int32(msg, RADIUS_ATTR_WLAN_REASON_CODE,
940  					      reason) < 0) {
941  			RADIUS_DEBUG("Failed to add WLAN-Reason-Code attribute");
942  			radius_msg_free(msg);
943  			return NULL;
944  		}
945  	}
946  
947  	if (radius_msg_finish_srv(msg, (u8 *) client->shared_secret,
948  				  client->shared_secret_len,
949  				  hdr->authenticator) < 0) {
950  		RADIUS_DEBUG("Failed to add Message-Authenticator attribute");
951  		radius_msg_free(msg);
952  		return NULL;
953  	}
954  
955  	if (code == RADIUS_CODE_ACCESS_ACCEPT)
956  		radius_server_add_session(sess);
957  
958  	return msg;
959  }
960  
961  
962  static struct radius_msg *
radius_server_macacl(struct radius_server_data * data,struct radius_client * client,struct radius_session * sess,struct radius_msg * request)963  radius_server_macacl(struct radius_server_data *data,
964  		     struct radius_client *client,
965  		     struct radius_session *sess,
966  		     struct radius_msg *request)
967  {
968  	struct radius_msg *msg;
969  	int code;
970  	struct radius_hdr *hdr = radius_msg_get_hdr(request);
971  	u8 *pw;
972  	size_t pw_len;
973  
974  	code = RADIUS_CODE_ACCESS_ACCEPT;
975  
976  	if (radius_msg_get_attr_ptr(request, RADIUS_ATTR_USER_PASSWORD, &pw,
977  				    &pw_len, NULL) < 0) {
978  		RADIUS_DEBUG("Could not get User-Password");
979  		code = RADIUS_CODE_ACCESS_REJECT;
980  	} else {
981  		int res;
982  		struct eap_user tmp;
983  
984  		os_memset(&tmp, 0, sizeof(tmp));
985  		res = data->get_eap_user(data->conf_ctx, (u8 *) sess->username,
986  					 os_strlen(sess->username), 0, &tmp);
987  		if (res || !tmp.macacl || tmp.password == NULL) {
988  			RADIUS_DEBUG("No MAC ACL user entry");
989  			bin_clear_free(tmp.password, tmp.password_len);
990  			code = RADIUS_CODE_ACCESS_REJECT;
991  		} else {
992  			u8 buf[128];
993  			res = radius_user_password_hide(
994  				request, tmp.password, tmp.password_len,
995  				(u8 *) client->shared_secret,
996  				client->shared_secret_len,
997  				buf, sizeof(buf));
998  			bin_clear_free(tmp.password, tmp.password_len);
999  
1000  			if (res < 0 || pw_len != (size_t) res ||
1001  			    os_memcmp_const(pw, buf, res) != 0) {
1002  				RADIUS_DEBUG("Incorrect User-Password");
1003  				code = RADIUS_CODE_ACCESS_REJECT;
1004  			}
1005  		}
1006  	}
1007  
1008  	msg = radius_msg_new(code, hdr->identifier);
1009  	if (msg == NULL) {
1010  		RADIUS_DEBUG("Failed to allocate reply message");
1011  		return NULL;
1012  	}
1013  
1014  	if (!radius_msg_add_msg_auth(msg)) {
1015  		radius_msg_free(msg);
1016  		return NULL;
1017  	}
1018  
1019  	if (radius_msg_copy_attr(msg, request, RADIUS_ATTR_PROXY_STATE) < 0) {
1020  		RADIUS_DEBUG("Failed to copy Proxy-State attribute(s)");
1021  		radius_msg_free(msg);
1022  		return NULL;
1023  	}
1024  
1025  	if (code == RADIUS_CODE_ACCESS_ACCEPT) {
1026  		struct hostapd_radius_attr *attr;
1027  		for (attr = sess->accept_attr; attr; attr = attr->next) {
1028  			if (!radius_msg_add_attr(msg, attr->type,
1029  						 wpabuf_head(attr->val),
1030  						 wpabuf_len(attr->val))) {
1031  				wpa_printf(MSG_ERROR, "Could not add RADIUS attribute");
1032  				radius_msg_free(msg);
1033  				return NULL;
1034  			}
1035  		}
1036  	}
1037  
1038  	if (radius_msg_finish_srv(msg, (u8 *) client->shared_secret,
1039  				  client->shared_secret_len,
1040  				  hdr->authenticator) < 0) {
1041  		RADIUS_DEBUG("Failed to add Message-Authenticator attribute");
1042  		radius_msg_free(msg);
1043  		return NULL;
1044  	}
1045  
1046  	return msg;
1047  }
1048  
1049  
radius_server_reject(struct radius_server_data * data,struct radius_client * client,struct radius_msg * request,struct sockaddr * from,socklen_t fromlen,const char * from_addr,int from_port)1050  static int radius_server_reject(struct radius_server_data *data,
1051  				struct radius_client *client,
1052  				struct radius_msg *request,
1053  				struct sockaddr *from, socklen_t fromlen,
1054  				const char *from_addr, int from_port)
1055  {
1056  	struct radius_msg *msg;
1057  	int ret = 0;
1058  	struct eap_hdr eapfail;
1059  	struct wpabuf *buf;
1060  	struct radius_hdr *hdr = radius_msg_get_hdr(request);
1061  
1062  	RADIUS_DEBUG("Reject invalid request from %s:%d",
1063  		     from_addr, from_port);
1064  
1065  	msg = radius_msg_new(RADIUS_CODE_ACCESS_REJECT, hdr->identifier);
1066  	if (msg == NULL) {
1067  		return -1;
1068  	}
1069  
1070  	if (!radius_msg_add_msg_auth(msg)) {
1071  		radius_msg_free(msg);
1072  		return -1;
1073  	}
1074  
1075  	os_memset(&eapfail, 0, sizeof(eapfail));
1076  	eapfail.code = EAP_CODE_FAILURE;
1077  	eapfail.identifier = 0;
1078  	eapfail.length = host_to_be16(sizeof(eapfail));
1079  
1080  	if (!radius_msg_add_eap(msg, (u8 *) &eapfail, sizeof(eapfail))) {
1081  		RADIUS_DEBUG("Failed to add EAP-Message attribute");
1082  	}
1083  
1084  	if (radius_msg_copy_attr(msg, request, RADIUS_ATTR_PROXY_STATE) < 0) {
1085  		RADIUS_DEBUG("Failed to copy Proxy-State attribute(s)");
1086  		radius_msg_free(msg);
1087  		return -1;
1088  	}
1089  
1090  	if (radius_msg_finish_srv(msg, (u8 *) client->shared_secret,
1091  				  client->shared_secret_len,
1092  				  hdr->authenticator) <
1093  	    0) {
1094  		RADIUS_DEBUG("Failed to add Message-Authenticator attribute");
1095  		radius_msg_free(msg);
1096  		return -1;
1097  	}
1098  
1099  	if (wpa_debug_level <= MSG_MSGDUMP) {
1100  		radius_msg_dump(msg);
1101  	}
1102  
1103  	data->counters.access_rejects++;
1104  	client->counters.access_rejects++;
1105  	buf = radius_msg_get_buf(msg);
1106  	if (sendto(data->auth_sock, wpabuf_head(buf), wpabuf_len(buf), 0,
1107  		   (struct sockaddr *) from, sizeof(*from)) < 0) {
1108  		wpa_printf(MSG_INFO, "sendto[RADIUS SRV]: %s", strerror(errno));
1109  		ret = -1;
1110  	}
1111  
1112  	radius_msg_free(msg);
1113  
1114  	return ret;
1115  }
1116  
1117  
radius_server_hs20_t_c_check(struct radius_session * sess,struct radius_msg * msg)1118  static void radius_server_hs20_t_c_check(struct radius_session *sess,
1119  					 struct radius_msg *msg)
1120  {
1121  #ifdef CONFIG_HS20
1122  	u8 *buf, *pos, *end, type, sublen, *timestamp = NULL;
1123  	size_t len;
1124  
1125  	buf = NULL;
1126  	for (;;) {
1127  		if (radius_msg_get_attr_ptr(msg, RADIUS_ATTR_VENDOR_SPECIFIC,
1128  					    &buf, &len, buf) < 0)
1129  			break;
1130  		if (len < 6)
1131  			continue;
1132  		pos = buf;
1133  		end = buf + len;
1134  		if (WPA_GET_BE32(pos) != RADIUS_VENDOR_ID_WFA)
1135  			continue;
1136  		pos += 4;
1137  
1138  		type = *pos++;
1139  		sublen = *pos++;
1140  		if (sublen < 2)
1141  			continue; /* invalid length */
1142  		sublen -= 2; /* skip header */
1143  		if (pos + sublen > end)
1144  			continue; /* invalid WFA VSA */
1145  
1146  		if (type == RADIUS_VENDOR_ATTR_WFA_HS20_TIMESTAMP && len >= 4) {
1147  			timestamp = pos;
1148  			break;
1149  		}
1150  	}
1151  
1152  	if (!timestamp)
1153  		return;
1154  	RADIUS_DEBUG("HS20-Timestamp: %u", WPA_GET_BE32(timestamp));
1155  	if (sess->t_c_timestamp != WPA_GET_BE32(timestamp)) {
1156  		RADIUS_DEBUG("Last read T&C timestamp does not match HS20-Timestamp --> require filtering");
1157  		sess->t_c_filtering = 1;
1158  	}
1159  #endif /* CONFIG_HS20 */
1160  }
1161  
1162  
radius_server_request(struct radius_server_data * data,struct radius_msg * msg,struct sockaddr * from,socklen_t fromlen,struct radius_client * client,const char * from_addr,int from_port,struct radius_session * force_sess)1163  static int radius_server_request(struct radius_server_data *data,
1164  				 struct radius_msg *msg,
1165  				 struct sockaddr *from, socklen_t fromlen,
1166  				 struct radius_client *client,
1167  				 const char *from_addr, int from_port,
1168  				 struct radius_session *force_sess)
1169  {
1170  	struct wpabuf *eap = NULL;
1171  	int res, state_included = 0;
1172  	u8 statebuf[4];
1173  	unsigned int state;
1174  	struct radius_session *sess;
1175  	struct radius_msg *reply;
1176  	int is_complete = 0;
1177  
1178  	if (force_sess)
1179  		sess = force_sess;
1180  	else {
1181  		res = radius_msg_get_attr(msg, RADIUS_ATTR_STATE, statebuf,
1182  					  sizeof(statebuf));
1183  		state_included = res >= 0;
1184  		if (res == sizeof(statebuf)) {
1185  			state = WPA_GET_BE32(statebuf);
1186  			sess = radius_server_get_session(client, state);
1187  		} else {
1188  			sess = NULL;
1189  		}
1190  	}
1191  
1192  	if (sess) {
1193  		RADIUS_DEBUG("Request for session 0x%x", sess->sess_id);
1194  	} else if (state_included) {
1195  		RADIUS_DEBUG("State attribute included but no session found");
1196  		radius_server_reject(data, client, msg, from, fromlen,
1197  				     from_addr, from_port);
1198  		return -1;
1199  	} else {
1200  		sess = radius_server_get_new_session(data, client, msg,
1201  						     from_addr);
1202  		if (sess == NULL) {
1203  			RADIUS_DEBUG("Could not create a new session");
1204  			radius_server_reject(data, client, msg, from, fromlen,
1205  					     from_addr, from_port);
1206  			return -1;
1207  		}
1208  	}
1209  
1210  	if (sess->last_from_port == from_port &&
1211  	    sess->last_identifier == radius_msg_get_hdr(msg)->identifier &&
1212  	    os_memcmp(sess->last_authenticator,
1213  		      radius_msg_get_hdr(msg)->authenticator, 16) == 0) {
1214  		RADIUS_DEBUG("Duplicate message from %s", from_addr);
1215  		data->counters.dup_access_requests++;
1216  		client->counters.dup_access_requests++;
1217  
1218  		if (sess->last_reply) {
1219  			struct wpabuf *buf;
1220  			buf = radius_msg_get_buf(sess->last_reply);
1221  			res = sendto(data->auth_sock, wpabuf_head(buf),
1222  				     wpabuf_len(buf), 0,
1223  				     (struct sockaddr *) from, fromlen);
1224  			if (res < 0) {
1225  				wpa_printf(MSG_INFO, "sendto[RADIUS SRV]: %s",
1226  					   strerror(errno));
1227  			}
1228  			return 0;
1229  		}
1230  
1231  		RADIUS_DEBUG("No previous reply available for duplicate "
1232  			     "message");
1233  		return -1;
1234  	}
1235  
1236  	eap = radius_msg_get_eap(msg);
1237  	if (eap == NULL && sess->macacl) {
1238  		reply = radius_server_macacl(data, client, sess, msg);
1239  		if (reply == NULL)
1240  			return -1;
1241  		goto send_reply;
1242  	}
1243  	if (eap == NULL) {
1244  		RADIUS_DEBUG("No EAP-Message in RADIUS packet from %s",
1245  			     from_addr);
1246  		data->counters.packets_dropped++;
1247  		client->counters.packets_dropped++;
1248  		return -1;
1249  	}
1250  
1251  	RADIUS_DUMP("Received EAP data", wpabuf_head(eap), wpabuf_len(eap));
1252  
1253  	/* FIX: if Code is Request, Success, or Failure, send Access-Reject;
1254  	 * RFC3579 Sect. 2.6.2.
1255  	 * Include EAP-Response/Nak with no preferred method if
1256  	 * code == request.
1257  	 * If code is not 1-4, discard the packet silently.
1258  	 * Or is this already done by the EAP state machine? */
1259  
1260  	wpabuf_free(sess->eap_if->eapRespData);
1261  	sess->eap_if->eapRespData = eap;
1262  	sess->eap_if->eapResp = true;
1263  	eap_server_sm_step(sess->eap);
1264  
1265  	if ((sess->eap_if->eapReq || sess->eap_if->eapSuccess ||
1266  	     sess->eap_if->eapFail) && sess->eap_if->eapReqData) {
1267  		RADIUS_DUMP("EAP data from the state machine",
1268  			    wpabuf_head(sess->eap_if->eapReqData),
1269  			    wpabuf_len(sess->eap_if->eapReqData));
1270  	} else if (sess->eap_if->eapFail) {
1271  		RADIUS_DEBUG("No EAP data from the state machine, but eapFail "
1272  			     "set");
1273  	} else if (eap_sm_method_pending(sess->eap)) {
1274  		radius_msg_free(sess->last_msg);
1275  		sess->last_msg = msg;
1276  		sess->last_from_port = from_port;
1277  		os_free(sess->last_from_addr);
1278  		sess->last_from_addr = os_strdup(from_addr);
1279  		sess->last_fromlen = fromlen;
1280  		os_memcpy(&sess->last_from, from, fromlen);
1281  		return -2;
1282  	} else {
1283  		RADIUS_DEBUG("No EAP data from the state machine - ignore this"
1284  			     " Access-Request silently (assuming it was a "
1285  			     "duplicate)");
1286  		data->counters.packets_dropped++;
1287  		client->counters.packets_dropped++;
1288  		return -1;
1289  	}
1290  
1291  	if (sess->eap_if->eapSuccess || sess->eap_if->eapFail)
1292  		is_complete = 1;
1293  	if (sess->eap_if->eapFail) {
1294  		srv_log(sess, "EAP authentication failed");
1295  		db_update_last_msk(sess, "FAIL");
1296  	} else if (sess->eap_if->eapSuccess) {
1297  		srv_log(sess, "EAP authentication succeeded");
1298  	}
1299  
1300  	if (sess->eap_if->eapSuccess)
1301  		radius_server_hs20_t_c_check(sess, msg);
1302  
1303  	reply = radius_server_encapsulate_eap(data, client, sess, msg);
1304  
1305  send_reply:
1306  	if (reply) {
1307  		struct wpabuf *buf;
1308  		struct radius_hdr *hdr;
1309  
1310  		RADIUS_DEBUG("Reply to %s:%d", from_addr, from_port);
1311  		if (wpa_debug_level <= MSG_MSGDUMP) {
1312  			radius_msg_dump(reply);
1313  		}
1314  
1315  		switch (radius_msg_get_hdr(reply)->code) {
1316  		case RADIUS_CODE_ACCESS_ACCEPT:
1317  			srv_log(sess, "Sending Access-Accept");
1318  			data->counters.access_accepts++;
1319  			client->counters.access_accepts++;
1320  			break;
1321  		case RADIUS_CODE_ACCESS_REJECT:
1322  			srv_log(sess, "Sending Access-Reject");
1323  			data->counters.access_rejects++;
1324  			client->counters.access_rejects++;
1325  			break;
1326  		case RADIUS_CODE_ACCESS_CHALLENGE:
1327  			data->counters.access_challenges++;
1328  			client->counters.access_challenges++;
1329  			break;
1330  		}
1331  		buf = radius_msg_get_buf(reply);
1332  		res = sendto(data->auth_sock, wpabuf_head(buf),
1333  			     wpabuf_len(buf), 0,
1334  			     (struct sockaddr *) from, fromlen);
1335  		if (res < 0) {
1336  			wpa_printf(MSG_INFO, "sendto[RADIUS SRV]: %s",
1337  				   strerror(errno));
1338  		}
1339  		radius_msg_free(sess->last_reply);
1340  		sess->last_reply = reply;
1341  		sess->last_from_port = from_port;
1342  		hdr = radius_msg_get_hdr(msg);
1343  		sess->last_identifier = hdr->identifier;
1344  		os_memcpy(sess->last_authenticator, hdr->authenticator, 16);
1345  	} else {
1346  		data->counters.packets_dropped++;
1347  		client->counters.packets_dropped++;
1348  	}
1349  
1350  	if (is_complete) {
1351  		RADIUS_DEBUG("Removing completed session 0x%x after timeout",
1352  			     sess->sess_id);
1353  		eloop_cancel_timeout(radius_server_session_remove_timeout,
1354  				     data, sess);
1355  		eloop_register_timeout(RADIUS_SESSION_MAINTAIN, 0,
1356  				       radius_server_session_remove_timeout,
1357  				       data, sess);
1358  	}
1359  
1360  	return 0;
1361  }
1362  
1363  
1364  static void
radius_server_receive_disconnect_resp(struct radius_server_data * data,struct radius_client * client,struct radius_msg * msg,int ack)1365  radius_server_receive_disconnect_resp(struct radius_server_data *data,
1366  				      struct radius_client *client,
1367  				      struct radius_msg *msg, int ack)
1368  {
1369  	struct radius_hdr *hdr;
1370  
1371  	if (!client->pending_dac_disconnect_req) {
1372  		RADIUS_DEBUG("Ignore unexpected Disconnect response");
1373  		radius_msg_free(msg);
1374  		return;
1375  	}
1376  
1377  	hdr = radius_msg_get_hdr(msg);
1378  	if (hdr->identifier != client->pending_dac_disconnect_id) {
1379  		RADIUS_DEBUG("Ignore unexpected Disconnect response with unexpected identifier %u (expected %u)",
1380  			     hdr->identifier,
1381  			     client->pending_dac_disconnect_id);
1382  		radius_msg_free(msg);
1383  		return;
1384  	}
1385  
1386  	if (radius_msg_verify(msg, (const u8 *) client->shared_secret,
1387  			      client->shared_secret_len,
1388  			      client->pending_dac_disconnect_req, 0)) {
1389  		RADIUS_DEBUG("Ignore Disconnect response with invalid authenticator");
1390  		radius_msg_free(msg);
1391  		return;
1392  	}
1393  
1394  	RADIUS_DEBUG("Disconnect-%s received for " MACSTR,
1395  		     ack ? "ACK" : "NAK",
1396  		     MAC2STR(client->pending_dac_disconnect_addr));
1397  
1398  	radius_msg_free(msg);
1399  	radius_msg_free(client->pending_dac_disconnect_req);
1400  	client->pending_dac_disconnect_req = NULL;
1401  }
1402  
1403  
radius_server_receive_coa_resp(struct radius_server_data * data,struct radius_client * client,struct radius_msg * msg,int ack)1404  static void radius_server_receive_coa_resp(struct radius_server_data *data,
1405  					   struct radius_client *client,
1406  					   struct radius_msg *msg, int ack)
1407  {
1408  	struct radius_hdr *hdr;
1409  #ifdef CONFIG_SQLITE
1410  	char addrtxt[3 * ETH_ALEN];
1411  	char *sql;
1412  	int res;
1413  #endif /* CONFIG_SQLITE */
1414  
1415  	if (!client->pending_dac_coa_req) {
1416  		RADIUS_DEBUG("Ignore unexpected CoA response");
1417  		radius_msg_free(msg);
1418  		return;
1419  	}
1420  
1421  	hdr = radius_msg_get_hdr(msg);
1422  	if (hdr->identifier != client->pending_dac_coa_id) {
1423  		RADIUS_DEBUG("Ignore unexpected CoA response with unexpected identifier %u (expected %u)",
1424  			     hdr->identifier,
1425  			     client->pending_dac_coa_id);
1426  		radius_msg_free(msg);
1427  		return;
1428  	}
1429  
1430  	if (radius_msg_verify(msg, (const u8 *) client->shared_secret,
1431  			      client->shared_secret_len,
1432  			      client->pending_dac_coa_req, 0)) {
1433  		RADIUS_DEBUG("Ignore CoA response with invalid authenticator");
1434  		radius_msg_free(msg);
1435  		return;
1436  	}
1437  
1438  	RADIUS_DEBUG("CoA-%s received for " MACSTR,
1439  		     ack ? "ACK" : "NAK",
1440  		     MAC2STR(client->pending_dac_coa_addr));
1441  
1442  	radius_msg_free(msg);
1443  	radius_msg_free(client->pending_dac_coa_req);
1444  	client->pending_dac_coa_req = NULL;
1445  
1446  #ifdef CONFIG_SQLITE
1447  	if (!data->db)
1448  		return;
1449  
1450  	os_snprintf(addrtxt, sizeof(addrtxt), MACSTR,
1451  		    MAC2STR(client->pending_dac_coa_addr));
1452  
1453  	if (ack) {
1454  		sql = sqlite3_mprintf("UPDATE current_sessions SET hs20_t_c_filtering=0, waiting_coa_ack=0, coa_ack_received=1 WHERE mac_addr=%Q",
1455  				      addrtxt);
1456  	} else {
1457  		sql = sqlite3_mprintf("UPDATE current_sessions SET waiting_coa_ack=0 WHERE mac_addr=%Q",
1458  				      addrtxt);
1459  	}
1460  	if (!sql)
1461  		return;
1462  
1463  	res = sqlite3_exec(data->db, sql, NULL, NULL, NULL);
1464  	sqlite3_free(sql);
1465  	if (res != SQLITE_OK) {
1466  		RADIUS_ERROR("Failed to update current_sessions entry: %s",
1467  			     sqlite3_errmsg(data->db));
1468  		return;
1469  	}
1470  #endif /* CONFIG_SQLITE */
1471  }
1472  
1473  
radius_server_receive_auth(int sock,void * eloop_ctx,void * sock_ctx)1474  static void radius_server_receive_auth(int sock, void *eloop_ctx,
1475  				       void *sock_ctx)
1476  {
1477  	struct radius_server_data *data = eloop_ctx;
1478  	u8 *buf = NULL;
1479  	union {
1480  		struct sockaddr_storage ss;
1481  		struct sockaddr_in sin;
1482  #ifdef CONFIG_IPV6
1483  		struct sockaddr_in6 sin6;
1484  #endif /* CONFIG_IPV6 */
1485  	} from;
1486  	socklen_t fromlen;
1487  	int len;
1488  	struct radius_client *client = NULL;
1489  	struct radius_msg *msg = NULL;
1490  	char abuf[50];
1491  	int from_port = 0;
1492  
1493  	buf = os_malloc(RADIUS_MAX_MSG_LEN);
1494  	if (buf == NULL) {
1495  		goto fail;
1496  	}
1497  
1498  	fromlen = sizeof(from);
1499  	len = recvfrom(sock, buf, RADIUS_MAX_MSG_LEN, 0,
1500  		       (struct sockaddr *) &from.ss, &fromlen);
1501  	if (len < 0) {
1502  		wpa_printf(MSG_INFO, "recvfrom[radius_server]: %s",
1503  			   strerror(errno));
1504  		goto fail;
1505  	}
1506  
1507  #ifdef CONFIG_IPV6
1508  	if (data->ipv6) {
1509  		if (inet_ntop(AF_INET6, &from.sin6.sin6_addr, abuf,
1510  			      sizeof(abuf)) == NULL)
1511  			abuf[0] = '\0';
1512  		from_port = ntohs(from.sin6.sin6_port);
1513  		RADIUS_DEBUG("Received %d bytes from %s:%d",
1514  			     len, abuf, from_port);
1515  
1516  		client = radius_server_get_client(data,
1517  						  (struct in_addr *)
1518  						  &from.sin6.sin6_addr, 1);
1519  	}
1520  #endif /* CONFIG_IPV6 */
1521  
1522  	if (!data->ipv6) {
1523  		os_strlcpy(abuf, inet_ntoa(from.sin.sin_addr), sizeof(abuf));
1524  		from_port = ntohs(from.sin.sin_port);
1525  		RADIUS_DEBUG("Received %d bytes from %s:%d",
1526  			     len, abuf, from_port);
1527  
1528  		client = radius_server_get_client(data, &from.sin.sin_addr, 0);
1529  	}
1530  
1531  	RADIUS_DUMP("Received data", buf, len);
1532  
1533  	if (client == NULL) {
1534  		RADIUS_DEBUG("Unknown client %s - packet ignored", abuf);
1535  		data->counters.invalid_requests++;
1536  		goto fail;
1537  	}
1538  
1539  	msg = radius_msg_parse(buf, len);
1540  	if (msg == NULL) {
1541  		RADIUS_DEBUG("Parsing incoming RADIUS frame failed");
1542  		data->counters.malformed_access_requests++;
1543  		client->counters.malformed_access_requests++;
1544  		goto fail;
1545  	}
1546  
1547  	os_free(buf);
1548  	buf = NULL;
1549  
1550  	if (wpa_debug_level <= MSG_MSGDUMP) {
1551  		radius_msg_dump(msg);
1552  	}
1553  
1554  	if (radius_msg_get_hdr(msg)->code == RADIUS_CODE_DISCONNECT_ACK) {
1555  		radius_server_receive_disconnect_resp(data, client, msg, 1);
1556  		return;
1557  	}
1558  
1559  	if (radius_msg_get_hdr(msg)->code == RADIUS_CODE_DISCONNECT_NAK) {
1560  		radius_server_receive_disconnect_resp(data, client, msg, 0);
1561  		return;
1562  	}
1563  
1564  	if (radius_msg_get_hdr(msg)->code == RADIUS_CODE_COA_ACK) {
1565  		radius_server_receive_coa_resp(data, client, msg, 1);
1566  		return;
1567  	}
1568  
1569  	if (radius_msg_get_hdr(msg)->code == RADIUS_CODE_COA_NAK) {
1570  		radius_server_receive_coa_resp(data, client, msg, 0);
1571  		return;
1572  	}
1573  
1574  	if (radius_msg_get_hdr(msg)->code != RADIUS_CODE_ACCESS_REQUEST) {
1575  		RADIUS_DEBUG("Unexpected RADIUS code %d",
1576  			     radius_msg_get_hdr(msg)->code);
1577  		data->counters.unknown_types++;
1578  		client->counters.unknown_types++;
1579  		goto fail;
1580  	}
1581  
1582  	data->counters.access_requests++;
1583  	client->counters.access_requests++;
1584  
1585  	if (radius_msg_verify_msg_auth(msg, (u8 *) client->shared_secret,
1586  				       client->shared_secret_len, NULL)) {
1587  		RADIUS_DEBUG("Invalid Message-Authenticator from %s", abuf);
1588  		data->counters.bad_authenticators++;
1589  		client->counters.bad_authenticators++;
1590  		goto fail;
1591  	}
1592  
1593  	if (radius_server_request(data, msg, (struct sockaddr *) &from,
1594  				  fromlen, client, abuf, from_port, NULL) ==
1595  	    -2)
1596  		return; /* msg was stored with the session */
1597  
1598  fail:
1599  	radius_msg_free(msg);
1600  	os_free(buf);
1601  }
1602  
1603  
radius_server_receive_acct(int sock,void * eloop_ctx,void * sock_ctx)1604  static void radius_server_receive_acct(int sock, void *eloop_ctx,
1605  				       void *sock_ctx)
1606  {
1607  	struct radius_server_data *data = eloop_ctx;
1608  	u8 *buf = NULL;
1609  	union {
1610  		struct sockaddr_storage ss;
1611  		struct sockaddr_in sin;
1612  #ifdef CONFIG_IPV6
1613  		struct sockaddr_in6 sin6;
1614  #endif /* CONFIG_IPV6 */
1615  	} from;
1616  	socklen_t fromlen;
1617  	int len, res;
1618  	struct radius_client *client = NULL;
1619  	struct radius_msg *msg = NULL, *resp = NULL;
1620  	char abuf[50];
1621  	int from_port = 0;
1622  	struct radius_hdr *hdr;
1623  	struct wpabuf *rbuf;
1624  	u32 status_type;
1625  
1626  	buf = os_malloc(RADIUS_MAX_MSG_LEN);
1627  	if (buf == NULL) {
1628  		goto fail;
1629  	}
1630  
1631  	fromlen = sizeof(from);
1632  	len = recvfrom(sock, buf, RADIUS_MAX_MSG_LEN, 0,
1633  		       (struct sockaddr *) &from.ss, &fromlen);
1634  	if (len < 0) {
1635  		wpa_printf(MSG_INFO, "recvfrom[radius_server]: %s",
1636  			   strerror(errno));
1637  		goto fail;
1638  	}
1639  
1640  #ifdef CONFIG_IPV6
1641  	if (data->ipv6) {
1642  		if (inet_ntop(AF_INET6, &from.sin6.sin6_addr, abuf,
1643  			      sizeof(abuf)) == NULL)
1644  			abuf[0] = '\0';
1645  		from_port = ntohs(from.sin6.sin6_port);
1646  		RADIUS_DEBUG("Received %d bytes from %s:%d",
1647  			     len, abuf, from_port);
1648  
1649  		client = radius_server_get_client(data,
1650  						  (struct in_addr *)
1651  						  &from.sin6.sin6_addr, 1);
1652  	}
1653  #endif /* CONFIG_IPV6 */
1654  
1655  	if (!data->ipv6) {
1656  		os_strlcpy(abuf, inet_ntoa(from.sin.sin_addr), sizeof(abuf));
1657  		from_port = ntohs(from.sin.sin_port);
1658  		RADIUS_DEBUG("Received %d bytes from %s:%d",
1659  			     len, abuf, from_port);
1660  
1661  		client = radius_server_get_client(data, &from.sin.sin_addr, 0);
1662  	}
1663  
1664  	RADIUS_DUMP("Received data", buf, len);
1665  
1666  	if (client == NULL) {
1667  		RADIUS_DEBUG("Unknown client %s - packet ignored", abuf);
1668  		data->counters.invalid_acct_requests++;
1669  		goto fail;
1670  	}
1671  
1672  	msg = radius_msg_parse(buf, len);
1673  	if (msg == NULL) {
1674  		RADIUS_DEBUG("Parsing incoming RADIUS frame failed");
1675  		data->counters.malformed_acct_requests++;
1676  		client->counters.malformed_acct_requests++;
1677  		goto fail;
1678  	}
1679  
1680  	os_free(buf);
1681  	buf = NULL;
1682  
1683  	if (wpa_debug_level <= MSG_MSGDUMP) {
1684  		radius_msg_dump(msg);
1685  	}
1686  
1687  	if (radius_msg_get_hdr(msg)->code != RADIUS_CODE_ACCOUNTING_REQUEST) {
1688  		RADIUS_DEBUG("Unexpected RADIUS code %d",
1689  			     radius_msg_get_hdr(msg)->code);
1690  		data->counters.unknown_acct_types++;
1691  		client->counters.unknown_acct_types++;
1692  		goto fail;
1693  	}
1694  
1695  	data->counters.acct_requests++;
1696  	client->counters.acct_requests++;
1697  
1698  	if (radius_msg_verify_acct_req(msg, (u8 *) client->shared_secret,
1699  				       client->shared_secret_len)) {
1700  		RADIUS_DEBUG("Invalid Authenticator from %s", abuf);
1701  		data->counters.acct_bad_authenticators++;
1702  		client->counters.acct_bad_authenticators++;
1703  		goto fail;
1704  	}
1705  
1706  	/* Parse Acct-Status-Type from Accounting-Request */
1707  	if (radius_msg_get_attr_int32(msg, RADIUS_ATTR_ACCT_STATUS_TYPE,
1708  				      &status_type) != 0) {
1709  		RADIUS_DEBUG("Unable to parse Acct-Status-Type from %s", abuf);
1710  		goto fail;
1711  	}
1712  
1713  	/* Process accounting information by configured callback */
1714  	if (data->acct_req_cb &&
1715  	    data->acct_req_cb(data->conf_ctx, msg, status_type) != 0) {
1716  		RADIUS_DEBUG("Accounting request callback returned non-zero code indicating processing failure (from %s)",
1717  			     abuf);
1718  		goto fail;
1719  	}
1720  
1721  	hdr = radius_msg_get_hdr(msg);
1722  
1723  	resp = radius_msg_new(RADIUS_CODE_ACCOUNTING_RESPONSE, hdr->identifier);
1724  	if (resp == NULL)
1725  		goto fail;
1726  
1727  	if (radius_msg_finish_acct_resp(resp, (u8 *) client->shared_secret,
1728  					client->shared_secret_len,
1729  					hdr->authenticator) < 0) {
1730  		RADIUS_ERROR("Failed to add Message-Authenticator attribute");
1731  		goto fail;
1732  	}
1733  
1734  	RADIUS_DEBUG("Reply to %s:%d", abuf, from_port);
1735  	if (wpa_debug_level <= MSG_MSGDUMP) {
1736  		radius_msg_dump(resp);
1737  	}
1738  	rbuf = radius_msg_get_buf(resp);
1739  	data->counters.acct_responses++;
1740  	client->counters.acct_responses++;
1741  	res = sendto(data->acct_sock, wpabuf_head(rbuf), wpabuf_len(rbuf), 0,
1742  		     (struct sockaddr *) &from.ss, fromlen);
1743  	if (res < 0) {
1744  		wpa_printf(MSG_INFO, "sendto[RADIUS SRV]: %s",
1745  			   strerror(errno));
1746  	}
1747  
1748  fail:
1749  	radius_msg_free(resp);
1750  	radius_msg_free(msg);
1751  	os_free(buf);
1752  }
1753  
1754  
radius_server_disable_pmtu_discovery(int s)1755  static int radius_server_disable_pmtu_discovery(int s)
1756  {
1757  	int r = -1;
1758  #if defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DONT)
1759  	/* Turn off Path MTU discovery on IPv4/UDP sockets. */
1760  	int action = IP_PMTUDISC_DONT;
1761  	r = setsockopt(s, IPPROTO_IP, IP_MTU_DISCOVER, &action,
1762  		       sizeof(action));
1763  	if (r == -1)
1764  		wpa_printf(MSG_ERROR, "Failed to set IP_MTU_DISCOVER: "
1765  			   "%s", strerror(errno));
1766  #endif
1767  	return r;
1768  }
1769  
1770  
radius_server_open_socket(int port)1771  static int radius_server_open_socket(int port)
1772  {
1773  	int s;
1774  	struct sockaddr_in addr;
1775  
1776  	s = socket(PF_INET, SOCK_DGRAM, 0);
1777  	if (s < 0) {
1778  		wpa_printf(MSG_INFO, "RADIUS: socket: %s", strerror(errno));
1779  		return -1;
1780  	}
1781  
1782  	radius_server_disable_pmtu_discovery(s);
1783  
1784  	os_memset(&addr, 0, sizeof(addr));
1785  	addr.sin_family = AF_INET;
1786  	addr.sin_port = htons(port);
1787  	if (bind(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
1788  		wpa_printf(MSG_INFO, "RADIUS: bind: %s", strerror(errno));
1789  		close(s);
1790  		return -1;
1791  	}
1792  
1793  	return s;
1794  }
1795  
1796  
1797  #ifdef CONFIG_IPV6
radius_server_open_socket6(int port)1798  static int radius_server_open_socket6(int port)
1799  {
1800  	int s;
1801  	struct sockaddr_in6 addr;
1802  
1803  	s = socket(PF_INET6, SOCK_DGRAM, 0);
1804  	if (s < 0) {
1805  		wpa_printf(MSG_INFO, "RADIUS: socket[IPv6]: %s",
1806  			   strerror(errno));
1807  		return -1;
1808  	}
1809  
1810  	os_memset(&addr, 0, sizeof(addr));
1811  	addr.sin6_family = AF_INET6;
1812  	os_memcpy(&addr.sin6_addr, &in6addr_any, sizeof(in6addr_any));
1813  	addr.sin6_port = htons(port);
1814  	if (bind(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
1815  		wpa_printf(MSG_INFO, "RADIUS: bind: %s", strerror(errno));
1816  		close(s);
1817  		return -1;
1818  	}
1819  
1820  	return s;
1821  }
1822  #endif /* CONFIG_IPV6 */
1823  
1824  
radius_server_free_sessions(struct radius_server_data * data,struct radius_session * sessions)1825  static void radius_server_free_sessions(struct radius_server_data *data,
1826  					struct radius_session *sessions)
1827  {
1828  	struct radius_session *session, *prev;
1829  
1830  	session = sessions;
1831  	while (session) {
1832  		prev = session;
1833  		session = session->next;
1834  		radius_server_session_free(data, prev);
1835  	}
1836  }
1837  
1838  
radius_server_free_clients(struct radius_server_data * data,struct radius_client * clients)1839  static void radius_server_free_clients(struct radius_server_data *data,
1840  				       struct radius_client *clients)
1841  {
1842  	struct radius_client *client, *prev;
1843  
1844  	client = clients;
1845  	while (client) {
1846  		prev = client;
1847  		client = client->next;
1848  
1849  		radius_server_free_sessions(data, prev->sessions);
1850  		os_free(prev->shared_secret);
1851  		radius_msg_free(prev->pending_dac_coa_req);
1852  		radius_msg_free(prev->pending_dac_disconnect_req);
1853  		os_free(prev);
1854  	}
1855  }
1856  
1857  
1858  static struct radius_client *
radius_server_read_clients(const char * client_file,int ipv6)1859  radius_server_read_clients(const char *client_file, int ipv6)
1860  {
1861  	FILE *f;
1862  	const int buf_size = 1024;
1863  	char *buf, *pos;
1864  	struct radius_client *clients, *tail, *entry;
1865  	int line = 0, mask, failed = 0, i;
1866  	struct in_addr addr;
1867  #ifdef CONFIG_IPV6
1868  	struct in6_addr addr6;
1869  #endif /* CONFIG_IPV6 */
1870  	unsigned int val;
1871  
1872  	f = fopen(client_file, "r");
1873  	if (f == NULL) {
1874  		RADIUS_ERROR("Could not open client file '%s'", client_file);
1875  		return NULL;
1876  	}
1877  
1878  	buf = os_malloc(buf_size);
1879  	if (buf == NULL) {
1880  		fclose(f);
1881  		return NULL;
1882  	}
1883  
1884  	clients = tail = NULL;
1885  	while (fgets(buf, buf_size, f)) {
1886  		/* Configuration file format:
1887  		 * 192.168.1.0/24 secret
1888  		 * 192.168.1.2 secret
1889  		 * fe80::211:22ff:fe33:4455/64 secretipv6
1890  		 */
1891  		line++;
1892  		buf[buf_size - 1] = '\0';
1893  		pos = buf;
1894  		while (*pos != '\0' && *pos != '\n')
1895  			pos++;
1896  		if (*pos == '\n')
1897  			*pos = '\0';
1898  		if (*buf == '\0' || *buf == '#')
1899  			continue;
1900  
1901  		pos = buf;
1902  		while ((*pos >= '0' && *pos <= '9') || *pos == '.' ||
1903  		       (*pos >= 'a' && *pos <= 'f') || *pos == ':' ||
1904  		       (*pos >= 'A' && *pos <= 'F')) {
1905  			pos++;
1906  		}
1907  
1908  		if (*pos == '\0') {
1909  			failed = 1;
1910  			break;
1911  		}
1912  
1913  		if (*pos == '/') {
1914  			char *end;
1915  			*pos++ = '\0';
1916  			mask = strtol(pos, &end, 10);
1917  			if ((pos == end) ||
1918  			    (mask < 0 || mask > (ipv6 ? 128 : 32))) {
1919  				failed = 1;
1920  				break;
1921  			}
1922  			pos = end;
1923  		} else {
1924  			mask = ipv6 ? 128 : 32;
1925  			*pos++ = '\0';
1926  		}
1927  
1928  		if (!ipv6 && inet_aton(buf, &addr) == 0) {
1929  			failed = 1;
1930  			break;
1931  		}
1932  #ifdef CONFIG_IPV6
1933  		if (ipv6 && inet_pton(AF_INET6, buf, &addr6) <= 0) {
1934  			if (inet_pton(AF_INET, buf, &addr) <= 0) {
1935  				failed = 1;
1936  				break;
1937  			}
1938  			/* Convert IPv4 address to IPv6 */
1939  			if (mask <= 32)
1940  				mask += (128 - 32);
1941  			os_memset(addr6.s6_addr, 0, 10);
1942  			addr6.s6_addr[10] = 0xff;
1943  			addr6.s6_addr[11] = 0xff;
1944  			os_memcpy(addr6.s6_addr + 12, (char *) &addr.s_addr,
1945  				  4);
1946  		}
1947  #endif /* CONFIG_IPV6 */
1948  
1949  		while (*pos == ' ' || *pos == '\t') {
1950  			pos++;
1951  		}
1952  
1953  		if (*pos == '\0') {
1954  			failed = 1;
1955  			break;
1956  		}
1957  
1958  		entry = os_zalloc(sizeof(*entry));
1959  		if (entry == NULL) {
1960  			failed = 1;
1961  			break;
1962  		}
1963  		entry->shared_secret = os_strdup(pos);
1964  		if (entry->shared_secret == NULL) {
1965  			failed = 1;
1966  			os_free(entry);
1967  			break;
1968  		}
1969  		entry->shared_secret_len = os_strlen(entry->shared_secret);
1970  		if (!ipv6) {
1971  			entry->addr.s_addr = addr.s_addr;
1972  			val = 0;
1973  			for (i = 0; i < mask; i++)
1974  				val |= 1U << (31 - i);
1975  			entry->mask.s_addr = htonl(val);
1976  		}
1977  #ifdef CONFIG_IPV6
1978  		if (ipv6) {
1979  			int offset = mask / 8;
1980  
1981  			os_memcpy(entry->addr6.s6_addr, addr6.s6_addr, 16);
1982  			os_memset(entry->mask6.s6_addr, 0xff, offset);
1983  			val = 0;
1984  			for (i = 0; i < (mask % 8); i++)
1985  				val |= 1 << (7 - i);
1986  			if (offset < 16)
1987  				entry->mask6.s6_addr[offset] = val;
1988  		}
1989  #endif /* CONFIG_IPV6 */
1990  
1991  		if (tail == NULL) {
1992  			clients = tail = entry;
1993  		} else {
1994  			tail->next = entry;
1995  			tail = entry;
1996  		}
1997  	}
1998  
1999  	if (failed) {
2000  		RADIUS_ERROR("Invalid line %d in '%s'", line, client_file);
2001  		radius_server_free_clients(NULL, clients);
2002  		clients = NULL;
2003  	}
2004  
2005  	os_free(buf);
2006  	fclose(f);
2007  
2008  	return clients;
2009  }
2010  
2011  
2012  /**
2013   * radius_server_init - Initialize RADIUS server
2014   * @conf: Configuration for the RADIUS server
2015   * Returns: Pointer to private RADIUS server context or %NULL on failure
2016   *
2017   * This initializes a RADIUS server instance and returns a context pointer that
2018   * will be used in other calls to the RADIUS server module. The server can be
2019   * deinitialize by calling radius_server_deinit().
2020   */
2021  struct radius_server_data *
radius_server_init(struct radius_server_conf * conf)2022  radius_server_init(struct radius_server_conf *conf)
2023  {
2024  	struct radius_server_data *data;
2025  
2026  #ifndef CONFIG_IPV6
2027  	if (conf->ipv6) {
2028  		wpa_printf(MSG_ERROR, "RADIUS server compiled without IPv6 support");
2029  		return NULL;
2030  	}
2031  #endif /* CONFIG_IPV6 */
2032  
2033  	data = os_zalloc(sizeof(*data));
2034  	if (data == NULL)
2035  		return NULL;
2036  
2037  	data->eap_cfg = conf->eap_cfg;
2038  	data->auth_sock = -1;
2039  	data->acct_sock = -1;
2040  	dl_list_init(&data->erp_keys);
2041  	os_get_reltime(&data->start_time);
2042  	data->conf_ctx = conf->conf_ctx;
2043  	conf->eap_cfg->backend_auth = true;
2044  	conf->eap_cfg->eap_server = 1;
2045  	data->ipv6 = conf->ipv6;
2046  	data->get_eap_user = conf->get_eap_user;
2047  	data->acct_req_cb = conf->acct_req_cb;
2048  	if (conf->eap_req_id_text) {
2049  		data->eap_req_id_text = os_malloc(conf->eap_req_id_text_len);
2050  		if (!data->eap_req_id_text)
2051  			goto fail;
2052  		os_memcpy(data->eap_req_id_text, conf->eap_req_id_text,
2053  			  conf->eap_req_id_text_len);
2054  		data->eap_req_id_text_len = conf->eap_req_id_text_len;
2055  	}
2056  	data->erp_domain = conf->erp_domain;
2057  
2058  	if (conf->t_c_server_url) {
2059  		data->t_c_server_url = os_strdup(conf->t_c_server_url);
2060  		if (!data->t_c_server_url)
2061  			goto fail;
2062  	}
2063  
2064  #ifdef CONFIG_SQLITE
2065  	if (conf->sqlite_file) {
2066  		if (sqlite3_open(conf->sqlite_file, &data->db)) {
2067  			RADIUS_ERROR("Could not open SQLite file '%s'",
2068  				     conf->sqlite_file);
2069  			goto fail;
2070  		}
2071  	}
2072  #endif /* CONFIG_SQLITE */
2073  
2074  #ifdef CONFIG_RADIUS_TEST
2075  	if (conf->dump_msk_file)
2076  		data->dump_msk_file = os_strdup(conf->dump_msk_file);
2077  #endif /* CONFIG_RADIUS_TEST */
2078  
2079  	data->clients = radius_server_read_clients(conf->client_file,
2080  						   conf->ipv6);
2081  	if (data->clients == NULL) {
2082  		wpa_printf(MSG_ERROR, "No RADIUS clients configured");
2083  		goto fail;
2084  	}
2085  
2086  #ifdef CONFIG_IPV6
2087  	if (conf->ipv6)
2088  		data->auth_sock = radius_server_open_socket6(conf->auth_port);
2089  	else
2090  #endif /* CONFIG_IPV6 */
2091  	data->auth_sock = radius_server_open_socket(conf->auth_port);
2092  	if (data->auth_sock < 0) {
2093  		wpa_printf(MSG_ERROR, "Failed to open UDP socket for RADIUS authentication server");
2094  		goto fail;
2095  	}
2096  	if (eloop_register_read_sock(data->auth_sock,
2097  				     radius_server_receive_auth,
2098  				     data, NULL)) {
2099  		goto fail;
2100  	}
2101  
2102  	if (conf->acct_port) {
2103  #ifdef CONFIG_IPV6
2104  		if (conf->ipv6)
2105  			data->acct_sock = radius_server_open_socket6(
2106  				conf->acct_port);
2107  		else
2108  #endif /* CONFIG_IPV6 */
2109  		data->acct_sock = radius_server_open_socket(conf->acct_port);
2110  		if (data->acct_sock < 0) {
2111  			wpa_printf(MSG_ERROR, "Failed to open UDP socket for RADIUS accounting server");
2112  			goto fail;
2113  		}
2114  		if (eloop_register_read_sock(data->acct_sock,
2115  					     radius_server_receive_acct,
2116  					     data, NULL))
2117  			goto fail;
2118  	} else {
2119  		data->acct_sock = -1;
2120  	}
2121  
2122  	return data;
2123  fail:
2124  	radius_server_deinit(data);
2125  	return NULL;
2126  }
2127  
2128  
2129  /**
2130   * radius_server_erp_flush - Flush all ERP keys
2131   * @data: RADIUS server context from radius_server_init()
2132   */
radius_server_erp_flush(struct radius_server_data * data)2133  void radius_server_erp_flush(struct radius_server_data *data)
2134  {
2135  	struct eap_server_erp_key *erp;
2136  
2137  	if (data == NULL)
2138  		return;
2139  	while ((erp = dl_list_first(&data->erp_keys, struct eap_server_erp_key,
2140  				    list)) != NULL) {
2141  		dl_list_del(&erp->list);
2142  		bin_clear_free(erp, sizeof(*erp));
2143  	}
2144  }
2145  
2146  
2147  /**
2148   * radius_server_deinit - Deinitialize RADIUS server
2149   * @data: RADIUS server context from radius_server_init()
2150   */
radius_server_deinit(struct radius_server_data * data)2151  void radius_server_deinit(struct radius_server_data *data)
2152  {
2153  	if (data == NULL)
2154  		return;
2155  
2156  	if (data->auth_sock >= 0) {
2157  		eloop_unregister_read_sock(data->auth_sock);
2158  		close(data->auth_sock);
2159  	}
2160  
2161  	if (data->acct_sock >= 0) {
2162  		eloop_unregister_read_sock(data->acct_sock);
2163  		close(data->acct_sock);
2164  	}
2165  
2166  	radius_server_free_clients(data, data->clients);
2167  
2168  	os_free(data->eap_req_id_text);
2169  #ifdef CONFIG_RADIUS_TEST
2170  	os_free(data->dump_msk_file);
2171  #endif /* CONFIG_RADIUS_TEST */
2172  	os_free(data->t_c_server_url);
2173  
2174  #ifdef CONFIG_SQLITE
2175  	if (data->db)
2176  		sqlite3_close(data->db);
2177  #endif /* CONFIG_SQLITE */
2178  
2179  	radius_server_erp_flush(data);
2180  
2181  	os_free(data);
2182  }
2183  
2184  
2185  /**
2186   * radius_server_get_mib - Get RADIUS server MIB information
2187   * @data: RADIUS server context from radius_server_init()
2188   * @buf: Buffer for returning the MIB data in text format
2189   * @buflen: buf length in octets
2190   * Returns: Number of octets written into buf
2191   */
radius_server_get_mib(struct radius_server_data * data,char * buf,size_t buflen)2192  int radius_server_get_mib(struct radius_server_data *data, char *buf,
2193  			  size_t buflen)
2194  {
2195  	int ret, uptime;
2196  	unsigned int idx;
2197  	char *end, *pos;
2198  	struct os_reltime now;
2199  	struct radius_client *cli;
2200  
2201  	/* RFC 2619 - RADIUS Authentication Server MIB */
2202  
2203  	if (data == NULL || buflen == 0)
2204  		return 0;
2205  
2206  	pos = buf;
2207  	end = buf + buflen;
2208  
2209  	os_get_reltime(&now);
2210  	uptime = (now.sec - data->start_time.sec) * 100 +
2211  		((now.usec - data->start_time.usec) / 10000) % 100;
2212  	ret = os_snprintf(pos, end - pos,
2213  			  "RADIUS-AUTH-SERVER-MIB\n"
2214  			  "radiusAuthServIdent=hostapd\n"
2215  			  "radiusAuthServUpTime=%d\n"
2216  			  "radiusAuthServResetTime=0\n"
2217  			  "radiusAuthServConfigReset=4\n",
2218  			  uptime);
2219  	if (os_snprintf_error(end - pos, ret)) {
2220  		*pos = '\0';
2221  		return pos - buf;
2222  	}
2223  	pos += ret;
2224  
2225  	ret = os_snprintf(pos, end - pos,
2226  			  "radiusAuthServTotalAccessRequests=%u\n"
2227  			  "radiusAuthServTotalInvalidRequests=%u\n"
2228  			  "radiusAuthServTotalDupAccessRequests=%u\n"
2229  			  "radiusAuthServTotalAccessAccepts=%u\n"
2230  			  "radiusAuthServTotalAccessRejects=%u\n"
2231  			  "radiusAuthServTotalAccessChallenges=%u\n"
2232  			  "radiusAuthServTotalMalformedAccessRequests=%u\n"
2233  			  "radiusAuthServTotalBadAuthenticators=%u\n"
2234  			  "radiusAuthServTotalPacketsDropped=%u\n"
2235  			  "radiusAuthServTotalUnknownTypes=%u\n"
2236  			  "radiusAccServTotalRequests=%u\n"
2237  			  "radiusAccServTotalInvalidRequests=%u\n"
2238  			  "radiusAccServTotalResponses=%u\n"
2239  			  "radiusAccServTotalMalformedRequests=%u\n"
2240  			  "radiusAccServTotalBadAuthenticators=%u\n"
2241  			  "radiusAccServTotalUnknownTypes=%u\n",
2242  			  data->counters.access_requests,
2243  			  data->counters.invalid_requests,
2244  			  data->counters.dup_access_requests,
2245  			  data->counters.access_accepts,
2246  			  data->counters.access_rejects,
2247  			  data->counters.access_challenges,
2248  			  data->counters.malformed_access_requests,
2249  			  data->counters.bad_authenticators,
2250  			  data->counters.packets_dropped,
2251  			  data->counters.unknown_types,
2252  			  data->counters.acct_requests,
2253  			  data->counters.invalid_acct_requests,
2254  			  data->counters.acct_responses,
2255  			  data->counters.malformed_acct_requests,
2256  			  data->counters.acct_bad_authenticators,
2257  			  data->counters.unknown_acct_types);
2258  	if (os_snprintf_error(end - pos, ret)) {
2259  		*pos = '\0';
2260  		return pos - buf;
2261  	}
2262  	pos += ret;
2263  
2264  	for (cli = data->clients, idx = 0; cli; cli = cli->next, idx++) {
2265  		char abuf[50], mbuf[50];
2266  #ifdef CONFIG_IPV6
2267  		if (data->ipv6) {
2268  			if (inet_ntop(AF_INET6, &cli->addr6, abuf,
2269  				      sizeof(abuf)) == NULL)
2270  				abuf[0] = '\0';
2271  			if (inet_ntop(AF_INET6, &cli->mask6, mbuf,
2272  				      sizeof(mbuf)) == NULL)
2273  				mbuf[0] = '\0';
2274  		}
2275  #endif /* CONFIG_IPV6 */
2276  		if (!data->ipv6) {
2277  			os_strlcpy(abuf, inet_ntoa(cli->addr), sizeof(abuf));
2278  			os_strlcpy(mbuf, inet_ntoa(cli->mask), sizeof(mbuf));
2279  		}
2280  
2281  		ret = os_snprintf(pos, end - pos,
2282  				  "radiusAuthClientIndex=%u\n"
2283  				  "radiusAuthClientAddress=%s/%s\n"
2284  				  "radiusAuthServAccessRequests=%u\n"
2285  				  "radiusAuthServDupAccessRequests=%u\n"
2286  				  "radiusAuthServAccessAccepts=%u\n"
2287  				  "radiusAuthServAccessRejects=%u\n"
2288  				  "radiusAuthServAccessChallenges=%u\n"
2289  				  "radiusAuthServMalformedAccessRequests=%u\n"
2290  				  "radiusAuthServBadAuthenticators=%u\n"
2291  				  "radiusAuthServPacketsDropped=%u\n"
2292  				  "radiusAuthServUnknownTypes=%u\n"
2293  				  "radiusAccServTotalRequests=%u\n"
2294  				  "radiusAccServTotalInvalidRequests=%u\n"
2295  				  "radiusAccServTotalResponses=%u\n"
2296  				  "radiusAccServTotalMalformedRequests=%u\n"
2297  				  "radiusAccServTotalBadAuthenticators=%u\n"
2298  				  "radiusAccServTotalUnknownTypes=%u\n",
2299  				  idx,
2300  				  abuf, mbuf,
2301  				  cli->counters.access_requests,
2302  				  cli->counters.dup_access_requests,
2303  				  cli->counters.access_accepts,
2304  				  cli->counters.access_rejects,
2305  				  cli->counters.access_challenges,
2306  				  cli->counters.malformed_access_requests,
2307  				  cli->counters.bad_authenticators,
2308  				  cli->counters.packets_dropped,
2309  				  cli->counters.unknown_types,
2310  				  cli->counters.acct_requests,
2311  				  cli->counters.invalid_acct_requests,
2312  				  cli->counters.acct_responses,
2313  				  cli->counters.malformed_acct_requests,
2314  				  cli->counters.acct_bad_authenticators,
2315  				  cli->counters.unknown_acct_types);
2316  		if (os_snprintf_error(end - pos, ret)) {
2317  			*pos = '\0';
2318  			return pos - buf;
2319  		}
2320  		pos += ret;
2321  	}
2322  
2323  	return pos - buf;
2324  }
2325  
2326  
radius_server_get_eap_user(void * ctx,const u8 * identity,size_t identity_len,int phase2,struct eap_user * user)2327  static int radius_server_get_eap_user(void *ctx, const u8 *identity,
2328  				      size_t identity_len, int phase2,
2329  				      struct eap_user *user)
2330  {
2331  	struct radius_session *sess = ctx;
2332  	struct radius_server_data *data = sess->server;
2333  	int ret;
2334  
2335  	ret = data->get_eap_user(data->conf_ctx, identity, identity_len,
2336  				 phase2, user);
2337  	if (ret == 0 && user) {
2338  		sess->accept_attr = user->accept_attr;
2339  		sess->macacl = user->macacl;
2340  		sess->t_c_timestamp = user->t_c_timestamp;
2341  	}
2342  
2343  	if (ret) {
2344  		RADIUS_DEBUG("%s: User-Name not found from user database",
2345  			     __func__);
2346  	}
2347  
2348  	return ret;
2349  }
2350  
2351  
radius_server_get_eap_req_id_text(void * ctx,size_t * len)2352  static const char * radius_server_get_eap_req_id_text(void *ctx, size_t *len)
2353  {
2354  	struct radius_session *sess = ctx;
2355  	struct radius_server_data *data = sess->server;
2356  	*len = data->eap_req_id_text_len;
2357  	return data->eap_req_id_text;
2358  }
2359  
2360  
radius_server_log_msg(void * ctx,const char * msg)2361  static void radius_server_log_msg(void *ctx, const char *msg)
2362  {
2363  	struct radius_session *sess = ctx;
2364  	srv_log(sess, "EAP: %s", msg);
2365  }
2366  
2367  
2368  #ifdef CONFIG_ERP
2369  
radius_server_get_erp_domain(void * ctx)2370  static const char * radius_server_get_erp_domain(void *ctx)
2371  {
2372  	struct radius_session *sess = ctx;
2373  	struct radius_server_data *data = sess->server;
2374  
2375  	return data->erp_domain;
2376  }
2377  
2378  
2379  static struct eap_server_erp_key *
radius_server_erp_get_key(void * ctx,const char * keyname)2380  radius_server_erp_get_key(void *ctx, const char *keyname)
2381  {
2382  	struct radius_session *sess = ctx;
2383  	struct radius_server_data *data = sess->server;
2384  
2385  	return radius_server_erp_find_key(data, keyname);
2386  }
2387  
2388  
radius_server_erp_add_key(void * ctx,struct eap_server_erp_key * erp)2389  static int radius_server_erp_add_key(void *ctx, struct eap_server_erp_key *erp)
2390  {
2391  	struct radius_session *sess = ctx;
2392  	struct radius_server_data *data = sess->server;
2393  
2394  	dl_list_add(&data->erp_keys, &erp->list);
2395  	return 0;
2396  }
2397  
2398  #endif /* CONFIG_ERP */
2399  
2400  
2401  static const struct eapol_callbacks radius_server_eapol_cb =
2402  {
2403  	.get_eap_user = radius_server_get_eap_user,
2404  	.get_eap_req_id_text = radius_server_get_eap_req_id_text,
2405  	.log_msg = radius_server_log_msg,
2406  #ifdef CONFIG_ERP
2407  	.get_erp_send_reauth_start = NULL,
2408  	.get_erp_domain = radius_server_get_erp_domain,
2409  	.erp_get_key = radius_server_erp_get_key,
2410  	.erp_add_key = radius_server_erp_add_key,
2411  #endif /* CONFIG_ERP */
2412  };
2413  
2414  
2415  /**
2416   * radius_server_eap_pending_cb - Pending EAP data notification
2417   * @data: RADIUS server context from radius_server_init()
2418   * @ctx: Pending EAP context pointer
2419   *
2420   * This function is used to notify EAP server module that a pending operation
2421   * has been completed and processing of the EAP session can proceed.
2422   */
radius_server_eap_pending_cb(struct radius_server_data * data,void * ctx)2423  void radius_server_eap_pending_cb(struct radius_server_data *data, void *ctx)
2424  {
2425  	struct radius_client *cli;
2426  	struct radius_session *s, *sess = NULL;
2427  	struct radius_msg *msg;
2428  
2429  	if (data == NULL)
2430  		return;
2431  
2432  	for (cli = data->clients; cli; cli = cli->next) {
2433  		for (s = cli->sessions; s; s = s->next) {
2434  			if (s->eap == ctx && s->last_msg) {
2435  				sess = s;
2436  				break;
2437  			}
2438  		}
2439  		if (sess)
2440  			break;
2441  	}
2442  
2443  	if (sess == NULL) {
2444  		RADIUS_DEBUG("No session matched callback ctx");
2445  		return;
2446  	}
2447  
2448  	msg = sess->last_msg;
2449  	sess->last_msg = NULL;
2450  	eap_sm_pending_cb(sess->eap);
2451  	if (radius_server_request(data, msg,
2452  				  (struct sockaddr *) &sess->last_from,
2453  				  sess->last_fromlen, cli,
2454  				  sess->last_from_addr,
2455  				  sess->last_from_port, sess) == -2)
2456  		return; /* msg was stored with the session */
2457  
2458  	radius_msg_free(msg);
2459  }
2460  
2461  
2462  #ifdef CONFIG_SQLITE
2463  
2464  struct db_session_fields {
2465  	char *identity;
2466  	char *nas;
2467  	int hs20_t_c_filtering;
2468  	int waiting_coa_ack;
2469  	int coa_ack_received;
2470  };
2471  
2472  
get_db_session_fields(void * ctx,int argc,char * argv[],char * col[])2473  static int get_db_session_fields(void *ctx, int argc, char *argv[], char *col[])
2474  {
2475  	struct db_session_fields *fields = ctx;
2476  	int i;
2477  
2478  	for (i = 0; i < argc; i++) {
2479  		if (!argv[i])
2480  			continue;
2481  
2482  		RADIUS_DEBUG("Session DB: %s=%s", col[i], argv[i]);
2483  
2484  		if (os_strcmp(col[i], "identity") == 0) {
2485  			os_free(fields->identity);
2486  			fields->identity = os_strdup(argv[i]);
2487  		} else if (os_strcmp(col[i], "nas") == 0) {
2488  			os_free(fields->nas);
2489  			fields->nas = os_strdup(argv[i]);
2490  		} else if (os_strcmp(col[i], "hs20_t_c_filtering") == 0) {
2491  			fields->hs20_t_c_filtering = atoi(argv[i]);
2492  		} else if (os_strcmp(col[i], "waiting_coa_ack") == 0) {
2493  			fields->waiting_coa_ack = atoi(argv[i]);
2494  		} else if (os_strcmp(col[i], "coa_ack_received") == 0) {
2495  			fields->coa_ack_received = atoi(argv[i]);
2496  		}
2497  	}
2498  
2499  	return 0;
2500  }
2501  
2502  
free_db_session_fields(struct db_session_fields * fields)2503  static void free_db_session_fields(struct db_session_fields *fields)
2504  {
2505  	os_free(fields->identity);
2506  	fields->identity = NULL;
2507  	os_free(fields->nas);
2508  	fields->nas = NULL;
2509  }
2510  
2511  #endif /* CONFIG_SQLITE */
2512  
2513  
radius_server_dac_request(struct radius_server_data * data,const char * req)2514  int radius_server_dac_request(struct radius_server_data *data, const char *req)
2515  {
2516  #ifdef CONFIG_SQLITE
2517  	char *sql;
2518  	int res;
2519  	int disconnect;
2520  	const char *pos = req;
2521  	u8 addr[ETH_ALEN];
2522  	char addrtxt[3 * ETH_ALEN];
2523  	int t_c_clear = 0;
2524  	struct db_session_fields fields;
2525  	struct sockaddr_in das;
2526  	struct radius_client *client;
2527  	struct radius_msg *msg;
2528  	struct wpabuf *buf;
2529  	u8 identifier;
2530  	struct os_time now;
2531  
2532  	if (!data)
2533  		return -1;
2534  
2535  	/* req: <disconnect|coa> <MAC Address> [t_c_clear] */
2536  
2537  	if (os_strncmp(pos, "disconnect ", 11) == 0) {
2538  		disconnect = 1;
2539  		pos += 11;
2540  	} else if (os_strncmp(req, "coa ", 4) == 0) {
2541  		disconnect = 0;
2542  		pos += 4;
2543  	} else {
2544  		return -1;
2545  	}
2546  
2547  	if (hwaddr_aton(pos, addr))
2548  		return -1;
2549  	pos = os_strchr(pos, ' ');
2550  	if (pos) {
2551  		if (os_strstr(pos, "t_c_clear"))
2552  			t_c_clear = 1;
2553  	}
2554  
2555  	if (!disconnect && !t_c_clear) {
2556  		RADIUS_ERROR("DAC request for CoA without any authorization change");
2557  		return -1;
2558  	}
2559  
2560  	if (!data->db) {
2561  		RADIUS_ERROR("SQLite database not in use");
2562  		return -1;
2563  	}
2564  
2565  	os_snprintf(addrtxt, sizeof(addrtxt), MACSTR, MAC2STR(addr));
2566  
2567  	sql = sqlite3_mprintf("SELECT * FROM current_sessions WHERE mac_addr=%Q",
2568  			      addrtxt);
2569  	if (!sql)
2570  		return -1;
2571  
2572  	os_memset(&fields, 0, sizeof(fields));
2573  	res = sqlite3_exec(data->db, sql, get_db_session_fields, &fields, NULL);
2574  	sqlite3_free(sql);
2575  	if (res != SQLITE_OK) {
2576  		RADIUS_ERROR("Failed to find matching current_sessions entry from sqlite database: %s",
2577  			     sqlite3_errmsg(data->db));
2578  		free_db_session_fields(&fields);
2579  		return -1;
2580  	}
2581  
2582  	if (!fields.nas) {
2583  		RADIUS_ERROR("No NAS information found from current_sessions");
2584  		free_db_session_fields(&fields);
2585  		return -1;
2586  	}
2587  
2588  	os_memset(&das, 0, sizeof(das));
2589  	das.sin_family = AF_INET;
2590  	das.sin_addr.s_addr = inet_addr(fields.nas);
2591  	das.sin_port = htons(3799);
2592  
2593  	free_db_session_fields(&fields);
2594  
2595  	client = radius_server_get_client(data, &das.sin_addr, 0);
2596  	if (!client) {
2597  		RADIUS_ERROR("No NAS information available to protect the packet");
2598  		return -1;
2599  	}
2600  
2601  	identifier = client->next_dac_identifier++;
2602  
2603  	msg = radius_msg_new(disconnect ? RADIUS_CODE_DISCONNECT_REQUEST :
2604  			     RADIUS_CODE_COA_REQUEST, identifier);
2605  	if (!msg)
2606  		return -1;
2607  
2608  	os_snprintf(addrtxt, sizeof(addrtxt), RADIUS_802_1X_ADDR_FORMAT,
2609  		    MAC2STR(addr));
2610  	if (!radius_msg_add_attr(msg, RADIUS_ATTR_CALLING_STATION_ID,
2611  				 (u8 *) addrtxt, os_strlen(addrtxt))) {
2612  		RADIUS_ERROR("Could not add Calling-Station-Id");
2613  		radius_msg_free(msg);
2614  		return -1;
2615  	}
2616  
2617  	if (!disconnect && t_c_clear) {
2618  		u8 val[4] = { 0x00, 0x00, 0x00, 0x00 }; /* E=0 */
2619  
2620  		if (!radius_msg_add_wfa(
2621  			    msg, RADIUS_VENDOR_ATTR_WFA_HS20_T_C_FILTERING,
2622  			    val, sizeof(val))) {
2623  			RADIUS_DEBUG("Failed to add WFA-HS20-T-C-Filtering");
2624  			radius_msg_free(msg);
2625  			return -1;
2626  		}
2627  	}
2628  
2629  	os_get_time(&now);
2630  	if (!radius_msg_add_attr_int32(msg, RADIUS_ATTR_EVENT_TIMESTAMP,
2631  				       now.sec)) {
2632  		RADIUS_ERROR("Failed to add Event-Timestamp attribute");
2633  		radius_msg_free(msg);
2634  		return -1;
2635  	}
2636  
2637  	if (radius_msg_finish_acct(msg, (u8 *) client->shared_secret,
2638  				   client->shared_secret_len) < 0) {
2639  		RADIUS_ERROR("Failed to add Message-Authenticator attribute");
2640  		radius_msg_free(msg);
2641  		return -1;
2642  	}
2643  
2644  	if (wpa_debug_level <= MSG_MSGDUMP)
2645  		radius_msg_dump(msg);
2646  
2647  	buf = radius_msg_get_buf(msg);
2648  	if (sendto(data->auth_sock, wpabuf_head(buf), wpabuf_len(buf), 0,
2649  		   (struct sockaddr *) &das, sizeof(das)) < 0) {
2650  		RADIUS_ERROR("Failed to send packet - sendto: %s",
2651  			     strerror(errno));
2652  		radius_msg_free(msg);
2653  		return -1;
2654  	}
2655  
2656  	if (disconnect) {
2657  		radius_msg_free(client->pending_dac_disconnect_req);
2658  		client->pending_dac_disconnect_req = msg;
2659  		client->pending_dac_disconnect_id = identifier;
2660  		os_memcpy(client->pending_dac_disconnect_addr, addr, ETH_ALEN);
2661  	} else {
2662  		radius_msg_free(client->pending_dac_coa_req);
2663  		client->pending_dac_coa_req = msg;
2664  		client->pending_dac_coa_id = identifier;
2665  		os_memcpy(client->pending_dac_coa_addr, addr, ETH_ALEN);
2666  	}
2667  
2668  	return 0;
2669  #else /* CONFIG_SQLITE */
2670  	return -1;
2671  #endif /* CONFIG_SQLITE */
2672  }
2673