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