/*
 * hostapd / EAP-SIM database/authenticator gateway
 * Copyright (c) 2005-2010, 2012, Jouni Malinen <j@w1.fi>
 *
 * This software may be distributed under the terms of the BSD license.
 * See README for more details.
 *
 * This is an example implementation of the EAP-SIM/AKA database/authentication
 * gateway interface that is using an external program as an SS7 gateway to
 * GSM/UMTS authentication center (HLR/AuC). hlr_auc_gw is an example
 * implementation of such a gateway program. This eap_sim_db.c takes care of
 * EAP-SIM/AKA pseudonyms and re-auth identities. It can be used with different
 * gateway implementations for HLR/AuC access. Alternatively, it can also be
 * completely replaced if the in-memory database of pseudonyms/re-auth
 * identities is not suitable for some cases.
 */

#include "includes.h"
#include <sys/un.h>
#ifdef CONFIG_SQLITE
#include <sqlite3.h>
#endif /* CONFIG_SQLITE */

#include "common.h"
#include "crypto/random.h"
#include "eap_common/eap_sim_common.h"
#include "eap_server/eap_sim_db.h"
#include "eloop.h"

struct eap_sim_pseudonym {
	struct eap_sim_pseudonym *next;
	char *permanent; /* permanent username */
	char *pseudonym; /* pseudonym username */
};

struct eap_sim_db_pending {
	struct eap_sim_db_pending *next;
	char imsi[20];
	enum { PENDING, SUCCESS, FAILURE } state;
	void *cb_session_ctx;
	struct os_time timestamp;
	int aka;
	union {
		struct {
			u8 kc[EAP_SIM_MAX_CHAL][EAP_SIM_KC_LEN];
			u8 sres[EAP_SIM_MAX_CHAL][EAP_SIM_SRES_LEN];
			u8 rand[EAP_SIM_MAX_CHAL][GSM_RAND_LEN];
			int num_chal;
		} sim;
		struct {
			u8 rand[EAP_AKA_RAND_LEN];
			u8 autn[EAP_AKA_AUTN_LEN];
			u8 ik[EAP_AKA_IK_LEN];
			u8 ck[EAP_AKA_CK_LEN];
			u8 res[EAP_AKA_RES_MAX_LEN];
			size_t res_len;
		} aka;
	} u;
};

struct eap_sim_db_data {
	int sock;
	char *fname;
	char *local_sock;
	void (*get_complete_cb)(void *ctx, void *session_ctx);
	void *ctx;
	struct eap_sim_pseudonym *pseudonyms;
	struct eap_sim_reauth *reauths;
	struct eap_sim_db_pending *pending;
#ifdef CONFIG_SQLITE
	sqlite3 *sqlite_db;
	char db_tmp_identity[100];
	char db_tmp_pseudonym_str[100];
	struct eap_sim_pseudonym db_tmp_pseudonym;
	struct eap_sim_reauth db_tmp_reauth;
#endif /* CONFIG_SQLITE */
};


#ifdef CONFIG_SQLITE

static int db_table_exists(sqlite3 *db, const char *name)
{
	char cmd[128];
	os_snprintf(cmd, sizeof(cmd), "SELECT 1 FROM %s;", name);
	return sqlite3_exec(db, cmd, NULL, NULL, NULL) == SQLITE_OK;
}


static int db_table_create_pseudonym(sqlite3 *db)
{
	char *err = NULL;
	const char *sql =
		"CREATE TABLE pseudonyms("
		"  permanent CHAR(21) PRIMARY KEY,"
		"  pseudonym CHAR(21) NOT NULL"
		");";

	wpa_printf(MSG_DEBUG, "EAP-SIM DB: Adding database table for "
		   "pseudonym information");
	if (sqlite3_exec(db, sql, NULL, NULL, &err) != SQLITE_OK) {
		wpa_printf(MSG_ERROR, "EAP-SIM DB: SQLite error: %s", err);
		sqlite3_free(err);
		return -1;
	}

	return 0;
}


static int db_table_create_reauth(sqlite3 *db)
{
	char *err = NULL;
	const char *sql =
		"CREATE TABLE reauth("
		"  permanent CHAR(21) PRIMARY KEY,"
		"  reauth_id CHAR(21) NOT NULL,"
		"  counter INTEGER,"
		"  mk CHAR(40),"
		"  k_encr CHAR(32),"
		"  k_aut CHAR(64),"
		"  k_re CHAR(64)"
		");";

	wpa_printf(MSG_DEBUG, "EAP-SIM DB: Adding database table for "
		   "reauth information");
	if (sqlite3_exec(db, sql, NULL, NULL, &err) != SQLITE_OK) {
		wpa_printf(MSG_ERROR, "EAP-SIM DB: SQLite error: %s", err);
		sqlite3_free(err);
		return -1;
	}

	return 0;
}


static sqlite3 * db_open(const char *db_file)
{
	sqlite3 *db;

	if (sqlite3_open(db_file, &db)) {
		wpa_printf(MSG_ERROR, "EAP-SIM DB: Failed to open database "
			   "%s: %s", db_file, sqlite3_errmsg(db));
		sqlite3_close(db);
		return NULL;
	}

	if (!db_table_exists(db, "pseudonyms") &&
	    db_table_create_pseudonym(db) < 0) {
		sqlite3_close(db);
		return NULL;
	}

	if (!db_table_exists(db, "reauth") &&
	    db_table_create_reauth(db) < 0) {
		sqlite3_close(db);
		return NULL;
	}

	return db;
}


static int valid_db_string(const char *str)
{
	const char *pos = str;
	while (*pos) {
		if ((*pos < '0' || *pos > '9') &&
		    (*pos < 'a' || *pos > 'f'))
			return 0;
		pos++;
	}
	return 1;
}


static int db_add_pseudonym(struct eap_sim_db_data *data,
			    const char *permanent, char *pseudonym)
{
	char cmd[128];
	char *err = NULL;

	if (!valid_db_string(permanent) || !valid_db_string(pseudonym)) {
		os_free(pseudonym);
		return -1;
	}

	os_snprintf(cmd, sizeof(cmd), "INSERT OR REPLACE INTO pseudonyms "
		    "(permanent, pseudonym) VALUES ('%s', '%s');",
		    permanent, pseudonym);
	os_free(pseudonym);
	if (sqlite3_exec(data->sqlite_db, cmd, NULL, NULL, &err) != SQLITE_OK)
	{
		wpa_printf(MSG_ERROR, "EAP-SIM DB: SQLite error: %s", err);
		sqlite3_free(err);
		return -1;
	}

	return 0;
}


static int get_pseudonym_cb(void *ctx, int argc, char *argv[], char *col[])
{
	struct eap_sim_db_data *data = ctx;
	int i;

	for (i = 0; i < argc; i++) {
		if (os_strcmp(col[i], "permanent") == 0 && argv[i]) {
			os_strlcpy(data->db_tmp_identity, argv[i],
				   sizeof(data->db_tmp_identity));
		}
	}

	return 0;
}


static char *
db_get_pseudonym(struct eap_sim_db_data *data, const char *pseudonym)
{
	char cmd[128];

	if (!valid_db_string(pseudonym))
		return NULL;
	os_memset(&data->db_tmp_identity, 0, sizeof(data->db_tmp_identity));
	os_snprintf(cmd, sizeof(cmd),
		    "SELECT permanent FROM pseudonyms WHERE pseudonym='%s';",
		    pseudonym);
	if (sqlite3_exec(data->sqlite_db, cmd, get_pseudonym_cb, data, NULL) !=
	    SQLITE_OK)
		return NULL;
	if (data->db_tmp_identity[0] == '\0')
		return NULL;
	return data->db_tmp_identity;
}


static int db_add_reauth(struct eap_sim_db_data *data, const char *permanent,
			 char *reauth_id, u16 counter, const u8 *mk,
			 const u8 *k_encr, const u8 *k_aut, const u8 *k_re)
{
	char cmd[2000], *pos, *end;
	char *err = NULL;

	if (!valid_db_string(permanent) || !valid_db_string(reauth_id)) {
		os_free(reauth_id);
		return -1;
	}

	pos = cmd;
	end = pos + sizeof(cmd);
	pos += os_snprintf(pos, end - pos, "INSERT OR REPLACE INTO reauth "
			   "(permanent, reauth_id, counter%s%s%s%s) "
			   "VALUES ('%s', '%s', %u",
			   mk ? ", mk" : "",
			   k_encr ? ", k_encr" : "",
			   k_aut ? ", k_aut" : "",
			   k_re ? ", k_re" : "",
			   permanent, reauth_id, counter);
	os_free(reauth_id);

	if (mk) {
		pos += os_snprintf(pos, end - pos, ", '");
		pos += wpa_snprintf_hex(pos, end - pos, mk, EAP_SIM_MK_LEN);
		pos += os_snprintf(pos, end - pos, "'");
	}

	if (k_encr) {
		pos += os_snprintf(pos, end - pos, ", '");
		pos += wpa_snprintf_hex(pos, end - pos, k_encr,
					EAP_SIM_K_ENCR_LEN);
		pos += os_snprintf(pos, end - pos, "'");
	}

	if (k_aut) {
		pos += os_snprintf(pos, end - pos, ", '");
		pos += wpa_snprintf_hex(pos, end - pos, k_aut,
					EAP_AKA_PRIME_K_AUT_LEN);
		pos += os_snprintf(pos, end - pos, "'");
	}

	if (k_re) {
		pos += os_snprintf(pos, end - pos, ", '");
		pos += wpa_snprintf_hex(pos, end - pos, k_re,
					EAP_AKA_PRIME_K_RE_LEN);
		pos += os_snprintf(pos, end - pos, "'");
	}

	os_snprintf(pos, end - pos, ");");

	if (sqlite3_exec(data->sqlite_db, cmd, NULL, NULL, &err) != SQLITE_OK)
	{
		wpa_printf(MSG_ERROR, "EAP-SIM DB: SQLite error: %s", err);
		sqlite3_free(err);
		return -1;
	}

	return 0;
}


static int get_reauth_cb(void *ctx, int argc, char *argv[], char *col[])
{
	struct eap_sim_db_data *data = ctx;
	int i;
	struct eap_sim_reauth *reauth = &data->db_tmp_reauth;

	for (i = 0; i < argc; i++) {
		if (os_strcmp(col[i], "permanent") == 0 && argv[i]) {
			os_strlcpy(data->db_tmp_identity, argv[i],
				   sizeof(data->db_tmp_identity));
			reauth->permanent = data->db_tmp_identity;
		} else if (os_strcmp(col[i], "counter") == 0 && argv[i]) {
			reauth->counter = atoi(argv[i]);
		} else if (os_strcmp(col[i], "mk") == 0 && argv[i]) {
			hexstr2bin(argv[i], reauth->mk, sizeof(reauth->mk));
		} else if (os_strcmp(col[i], "k_encr") == 0 && argv[i]) {
			hexstr2bin(argv[i], reauth->k_encr,
				   sizeof(reauth->k_encr));
		} else if (os_strcmp(col[i], "k_aut") == 0 && argv[i]) {
			hexstr2bin(argv[i], reauth->k_aut,
				   sizeof(reauth->k_aut));
		} else if (os_strcmp(col[i], "k_re") == 0 && argv[i]) {
			hexstr2bin(argv[i], reauth->k_re,
				   sizeof(reauth->k_re));
		}
	}

	return 0;
}


static struct eap_sim_reauth *
db_get_reauth(struct eap_sim_db_data *data, const char *reauth_id)
{
	char cmd[256];

	if (!valid_db_string(reauth_id))
		return NULL;
	os_memset(&data->db_tmp_reauth, 0, sizeof(data->db_tmp_reauth));
	os_strlcpy(data->db_tmp_pseudonym_str, reauth_id,
		   sizeof(data->db_tmp_pseudonym_str));
	data->db_tmp_reauth.reauth_id = data->db_tmp_pseudonym_str;
	os_snprintf(cmd, sizeof(cmd),
		    "SELECT * FROM reauth WHERE reauth_id='%s';", reauth_id);
	if (sqlite3_exec(data->sqlite_db, cmd, get_reauth_cb, data, NULL) !=
	    SQLITE_OK)
		return NULL;
	if (data->db_tmp_reauth.permanent == NULL)
		return NULL;
	return &data->db_tmp_reauth;
}


static void db_remove_reauth(struct eap_sim_db_data *data,
			     struct eap_sim_reauth *reauth)
{
	char cmd[256];

	if (!valid_db_string(reauth->permanent))
		return;
	os_snprintf(cmd, sizeof(cmd),
		    "DELETE FROM reauth WHERE permanent='%s';",
		    reauth->permanent);
	sqlite3_exec(data->sqlite_db, cmd, NULL, NULL, NULL);
}

#endif /* CONFIG_SQLITE */


static struct eap_sim_db_pending *
eap_sim_db_get_pending(struct eap_sim_db_data *data, const char *imsi, int aka)
{
	struct eap_sim_db_pending *entry, *prev = NULL;

	entry = data->pending;
	while (entry) {
		if (entry->aka == aka && os_strcmp(entry->imsi, imsi) == 0) {
			if (prev)
				prev->next = entry->next;
			else
				data->pending = entry->next;
			break;
		}
		prev = entry;
		entry = entry->next;
	}
	return entry;
}


static void eap_sim_db_add_pending(struct eap_sim_db_data *data,
				   struct eap_sim_db_pending *entry)
{
	entry->next = data->pending;
	data->pending = entry;
}


static void eap_sim_db_sim_resp_auth(struct eap_sim_db_data *data,
				     const char *imsi, char *buf)
{
	char *start, *end, *pos;
	struct eap_sim_db_pending *entry;
	int num_chal;

	/*
	 * SIM-RESP-AUTH <IMSI> Kc(i):SRES(i):RAND(i) ...
	 * SIM-RESP-AUTH <IMSI> FAILURE
	 * (IMSI = ASCII string, Kc/SRES/RAND = hex string)
	 */

	entry = eap_sim_db_get_pending(data, imsi, 0);
	if (entry == NULL) {
		wpa_printf(MSG_DEBUG, "EAP-SIM DB: No pending entry for the "
			   "received message found");
		return;
	}

	start = buf;
	if (os_strncmp(start, "FAILURE", 7) == 0) {
		wpa_printf(MSG_DEBUG, "EAP-SIM DB: External server reported "
			   "failure");
		entry->state = FAILURE;
		eap_sim_db_add_pending(data, entry);
		data->get_complete_cb(data->ctx, entry->cb_session_ctx);
		return;
	}

	num_chal = 0;
	while (num_chal < EAP_SIM_MAX_CHAL) {
		end = os_strchr(start, ' ');
		if (end)
			*end = '\0';

		pos = os_strchr(start, ':');
		if (pos == NULL)
			goto parse_fail;
		*pos = '\0';
		if (hexstr2bin(start, entry->u.sim.kc[num_chal],
			       EAP_SIM_KC_LEN))
			goto parse_fail;

		start = pos + 1;
		pos = os_strchr(start, ':');
		if (pos == NULL)
			goto parse_fail;
		*pos = '\0';
		if (hexstr2bin(start, entry->u.sim.sres[num_chal],
			       EAP_SIM_SRES_LEN))
			goto parse_fail;

		start = pos + 1;
		if (hexstr2bin(start, entry->u.sim.rand[num_chal],
			       GSM_RAND_LEN))
			goto parse_fail;

		num_chal++;
		if (end == NULL)
			break;
		else
			start = end + 1;
	}
	entry->u.sim.num_chal = num_chal;

	entry->state = SUCCESS;
	wpa_printf(MSG_DEBUG, "EAP-SIM DB: Authentication data parsed "
		   "successfully - callback");
	eap_sim_db_add_pending(data, entry);
	data->get_complete_cb(data->ctx, entry->cb_session_ctx);
	return;

parse_fail:
	wpa_printf(MSG_DEBUG, "EAP-SIM DB: Failed to parse response string");
	os_free(entry);
}


static void eap_sim_db_aka_resp_auth(struct eap_sim_db_data *data,
				     const char *imsi, char *buf)
{
	char *start, *end;
	struct eap_sim_db_pending *entry;

	/*
	 * AKA-RESP-AUTH <IMSI> <RAND> <AUTN> <IK> <CK> <RES>
	 * AKA-RESP-AUTH <IMSI> FAILURE
	 * (IMSI = ASCII string, RAND/AUTN/IK/CK/RES = hex string)
	 */

	entry = eap_sim_db_get_pending(data, imsi, 1);
	if (entry == NULL) {
		wpa_printf(MSG_DEBUG, "EAP-SIM DB: No pending entry for the "
			   "received message found");
		return;
	}

	start = buf;
	if (os_strncmp(start, "FAILURE", 7) == 0) {
		wpa_printf(MSG_DEBUG, "EAP-SIM DB: External server reported "
			   "failure");
		entry->state = FAILURE;
		eap_sim_db_add_pending(data, entry);
		data->get_complete_cb(data->ctx, entry->cb_session_ctx);
		return;
	}

	end = os_strchr(start, ' ');
	if (end == NULL)
		goto parse_fail;
	*end = '\0';
	if (hexstr2bin(start, entry->u.aka.rand, EAP_AKA_RAND_LEN))
		goto parse_fail;

	start = end + 1;
	end = os_strchr(start, ' ');
	if (end == NULL)
		goto parse_fail;
	*end = '\0';
	if (hexstr2bin(start, entry->u.aka.autn, EAP_AKA_AUTN_LEN))
		goto parse_fail;

	start = end + 1;
	end = os_strchr(start, ' ');
	if (end == NULL)
		goto parse_fail;
	*end = '\0';
	if (hexstr2bin(start, entry->u.aka.ik, EAP_AKA_IK_LEN))
		goto parse_fail;

	start = end + 1;
	end = os_strchr(start, ' ');
	if (end == NULL)
		goto parse_fail;
	*end = '\0';
	if (hexstr2bin(start, entry->u.aka.ck, EAP_AKA_CK_LEN))
		goto parse_fail;

	start = end + 1;
	end = os_strchr(start, ' ');
	if (end)
		*end = '\0';
	else {
		end = start;
		while (*end)
			end++;
	}
	entry->u.aka.res_len = (end - start) / 2;
	if (entry->u.aka.res_len > EAP_AKA_RES_MAX_LEN) {
		wpa_printf(MSG_DEBUG, "EAP-SIM DB: Too long RES");
		entry->u.aka.res_len = 0;
		goto parse_fail;
	}
	if (hexstr2bin(start, entry->u.aka.res, entry->u.aka.res_len))
		goto parse_fail;

	entry->state = SUCCESS;
	wpa_printf(MSG_DEBUG, "EAP-SIM DB: Authentication data parsed "
		   "successfully - callback");
	eap_sim_db_add_pending(data, entry);
	data->get_complete_cb(data->ctx, entry->cb_session_ctx);
	return;

parse_fail:
	wpa_printf(MSG_DEBUG, "EAP-SIM DB: Failed to parse response string");
	os_free(entry);
}


static void eap_sim_db_receive(int sock, void *eloop_ctx, void *sock_ctx)
{
	struct eap_sim_db_data *data = eloop_ctx;
	char buf[1000], *pos, *cmd, *imsi;
	int res;

	res = recv(sock, buf, sizeof(buf), 0);
	if (res < 0)
		return;
	wpa_hexdump_ascii_key(MSG_MSGDUMP, "EAP-SIM DB: Received from an "
			      "external source", (u8 *) buf, res);
	if (res == 0)
		return;
	if (res >= (int) sizeof(buf))
		res = sizeof(buf) - 1;
	buf[res] = '\0';

	if (data->get_complete_cb == NULL) {
		wpa_printf(MSG_DEBUG, "EAP-SIM DB: No get_complete_cb "
			   "registered");
		return;
	}

	/* <cmd> <IMSI> ... */

	cmd = buf;
	pos = os_strchr(cmd, ' ');
	if (pos == NULL)
		goto parse_fail;
	*pos = '\0';
	imsi = pos + 1;
	pos = os_strchr(imsi, ' ');
	if (pos == NULL)
		goto parse_fail;
	*pos = '\0';
	wpa_printf(MSG_DEBUG, "EAP-SIM DB: External response=%s for IMSI %s",
		   cmd, imsi);

	if (os_strcmp(cmd, "SIM-RESP-AUTH") == 0)
		eap_sim_db_sim_resp_auth(data, imsi, pos + 1);
	else if (os_strcmp(cmd, "AKA-RESP-AUTH") == 0)
		eap_sim_db_aka_resp_auth(data, imsi, pos + 1);
	else
		wpa_printf(MSG_INFO, "EAP-SIM DB: Unknown external response "
			   "'%s'", cmd);
	return;

parse_fail:
	wpa_printf(MSG_DEBUG, "EAP-SIM DB: Failed to parse response string");
}


static int eap_sim_db_open_socket(struct eap_sim_db_data *data)
{
	struct sockaddr_un addr;
	static int counter = 0;

	if (os_strncmp(data->fname, "unix:", 5) != 0)
		return -1;

	data->sock = socket(PF_UNIX, SOCK_DGRAM, 0);
	if (data->sock < 0) {
		perror("socket(eap_sim_db)");
		return -1;
	}

	os_memset(&addr, 0, sizeof(addr));
	addr.sun_family = AF_UNIX;
	os_snprintf(addr.sun_path, sizeof(addr.sun_path),
		    "/tmp/eap_sim_db_%d-%d", getpid(), counter++);
	os_free(data->local_sock);
	data->local_sock = os_strdup(addr.sun_path);
	if (bind(data->sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
		perror("bind(eap_sim_db)");
		close(data->sock);
		data->sock = -1;
		return -1;
	}

	os_memset(&addr, 0, sizeof(addr));
	addr.sun_family = AF_UNIX;
	os_strlcpy(addr.sun_path, data->fname + 5, sizeof(addr.sun_path));
	if (connect(data->sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
		perror("connect(eap_sim_db)");
		wpa_hexdump_ascii(MSG_INFO, "HLR/AuC GW socket",
				  (u8 *) addr.sun_path,
				  os_strlen(addr.sun_path));
		close(data->sock);
		data->sock = -1;
		return -1;
	}

	eloop_register_read_sock(data->sock, eap_sim_db_receive, data, NULL);

	return 0;
}


static void eap_sim_db_close_socket(struct eap_sim_db_data *data)
{
	if (data->sock >= 0) {
		eloop_unregister_read_sock(data->sock);
		close(data->sock);
		data->sock = -1;
	}
	if (data->local_sock) {
		unlink(data->local_sock);
		os_free(data->local_sock);
		data->local_sock = NULL;
	}
}


/**
 * eap_sim_db_init - Initialize EAP-SIM DB / authentication gateway interface
 * @config: Configuration data (e.g., file name)
 * @get_complete_cb: Callback function for reporting availability of triplets
 * @ctx: Context pointer for get_complete_cb
 * Returns: Pointer to a private data structure or %NULL on failure
 */
struct eap_sim_db_data *
eap_sim_db_init(const char *config,
		void (*get_complete_cb)(void *ctx, void *session_ctx),
		void *ctx)
{
	struct eap_sim_db_data *data;
	char *pos;

	data = os_zalloc(sizeof(*data));
	if (data == NULL)
		return NULL;

	data->sock = -1;
	data->get_complete_cb = get_complete_cb;
	data->ctx = ctx;
	data->fname = os_strdup(config);
	if (data->fname == NULL)
		goto fail;
	pos = os_strstr(data->fname, " db=");
	if (pos) {
		*pos = '\0';
#ifdef CONFIG_SQLITE
		pos += 4;
		data->sqlite_db = db_open(pos);
		if (data->sqlite_db == NULL)
			goto fail;
#endif /* CONFIG_SQLITE */
	}

	if (os_strncmp(data->fname, "unix:", 5) == 0) {
		if (eap_sim_db_open_socket(data)) {
			wpa_printf(MSG_DEBUG, "EAP-SIM DB: External database "
				   "connection not available - will retry "
				   "later");
		}
	}

	return data;

fail:
	eap_sim_db_close_socket(data);
	os_free(data->fname);
	os_free(data);
	return NULL;
}


static void eap_sim_db_free_pseudonym(struct eap_sim_pseudonym *p)
{
	os_free(p->permanent);
	os_free(p->pseudonym);
	os_free(p);
}


static void eap_sim_db_free_reauth(struct eap_sim_reauth *r)
{
	os_free(r->permanent);
	os_free(r->reauth_id);
	os_free(r);
}


/**
 * eap_sim_db_deinit - Deinitialize EAP-SIM DB/authentication gw interface
 * @priv: Private data pointer from eap_sim_db_init()
 */
void eap_sim_db_deinit(void *priv)
{
	struct eap_sim_db_data *data = priv;
	struct eap_sim_pseudonym *p, *prev;
	struct eap_sim_reauth *r, *prevr;
	struct eap_sim_db_pending *pending, *prev_pending;

#ifdef CONFIG_SQLITE
	if (data->sqlite_db) {
		sqlite3_close(data->sqlite_db);
		data->sqlite_db = NULL;
	}
#endif /* CONFIG_SQLITE */

	eap_sim_db_close_socket(data);
	os_free(data->fname);

	p = data->pseudonyms;
	while (p) {
		prev = p;
		p = p->next;
		eap_sim_db_free_pseudonym(prev);
	}

	r = data->reauths;
	while (r) {
		prevr = r;
		r = r->next;
		eap_sim_db_free_reauth(prevr);
	}

	pending = data->pending;
	while (pending) {
		prev_pending = pending;
		pending = pending->next;
		os_free(prev_pending);
	}

	os_free(data);
}


static int eap_sim_db_send(struct eap_sim_db_data *data, const char *msg,
			   size_t len)
{
	int _errno = 0;

	if (send(data->sock, msg, len, 0) < 0) {
		_errno = errno;
		perror("send[EAP-SIM DB UNIX]");
	}

	if (_errno == ENOTCONN || _errno == EDESTADDRREQ || _errno == EINVAL ||
	    _errno == ECONNREFUSED) {
		/* Try to reconnect */
		eap_sim_db_close_socket(data);
		if (eap_sim_db_open_socket(data) < 0)
			return -1;
		wpa_printf(MSG_DEBUG, "EAP-SIM DB: Reconnected to the "
			   "external server");
		if (send(data->sock, msg, len, 0) < 0) {
			perror("send[EAP-SIM DB UNIX]");
			return -1;
		}
	}

	return 0;
}


static void eap_sim_db_expire_pending(struct eap_sim_db_data *data)
{
	/* TODO: add limit for maximum length for pending list; remove latest
	 * (i.e., last) entry from the list if the limit is reached; could also
	 * use timeout to expire pending entries */
}


/**
 * eap_sim_db_get_gsm_triplets - Get GSM triplets
 * @data: Private data pointer from eap_sim_db_init()
 * @username: Permanent username (prefix | IMSI)
 * @max_chal: Maximum number of triplets
 * @_rand: Buffer for RAND values
 * @kc: Buffer for Kc values
 * @sres: Buffer for SRES values
 * @cb_session_ctx: Session callback context for get_complete_cb()
 * Returns: Number of triplets received (has to be less than or equal to
 * max_chal), -1 (EAP_SIM_DB_FAILURE) on error (e.g., user not found), or
 * -2 (EAP_SIM_DB_PENDING) if results are not yet available. In this case, the
 * callback function registered with eap_sim_db_init() will be called once the
 * results become available.
 *
 * When using an external server for GSM triplets, this function can always
 * start a request and return EAP_SIM_DB_PENDING immediately if authentication
 * triplets are not available. Once the triplets are received, callback
 * function registered with eap_sim_db_init() is called to notify EAP state
 * machine to reprocess the message. This eap_sim_db_get_gsm_triplets()
 * function will then be called again and the newly received triplets will then
 * be given to the caller.
 */
int eap_sim_db_get_gsm_triplets(struct eap_sim_db_data *data,
				const char *username, int max_chal,
				u8 *_rand, u8 *kc, u8 *sres,
				void *cb_session_ctx)
{
	struct eap_sim_db_pending *entry;
	int len, ret;
	char msg[40];
	const char *imsi;
	size_t imsi_len;

	if (username == NULL || username[0] != EAP_SIM_PERMANENT_PREFIX ||
	    username[1] == '\0' || os_strlen(username) > sizeof(entry->imsi)) {
		wpa_printf(MSG_DEBUG, "EAP-SIM DB: unexpected username '%s'",
			   username);
		return EAP_SIM_DB_FAILURE;
	}
	imsi = username + 1;
	wpa_printf(MSG_DEBUG, "EAP-SIM DB: Get GSM triplets for IMSI '%s'",
		   imsi);

	entry = eap_sim_db_get_pending(data, imsi, 0);
	if (entry) {
		int num_chal;
		if (entry->state == FAILURE) {
			wpa_printf(MSG_DEBUG, "EAP-SIM DB: Pending entry -> "
				   "failure");
			os_free(entry);
			return EAP_SIM_DB_FAILURE;
		}

		if (entry->state == PENDING) {
			wpa_printf(MSG_DEBUG, "EAP-SIM DB: Pending entry -> "
				   "still pending");
			eap_sim_db_add_pending(data, entry);
			return EAP_SIM_DB_PENDING;
		}

		wpa_printf(MSG_DEBUG, "EAP-SIM DB: Pending entry -> "
			   "%d challenges", entry->u.sim.num_chal);
		num_chal = entry->u.sim.num_chal;
		if (num_chal > max_chal)
			num_chal = max_chal;
		os_memcpy(_rand, entry->u.sim.rand, num_chal * GSM_RAND_LEN);
		os_memcpy(sres, entry->u.sim.sres,
			  num_chal * EAP_SIM_SRES_LEN);
		os_memcpy(kc, entry->u.sim.kc, num_chal * EAP_SIM_KC_LEN);
		os_free(entry);
		return num_chal;
	}

	if (data->sock < 0) {
		if (eap_sim_db_open_socket(data) < 0)
			return EAP_SIM_DB_FAILURE;
	}

	imsi_len = os_strlen(imsi);
	len = os_snprintf(msg, sizeof(msg), "SIM-REQ-AUTH ");
	if (len < 0 || len + imsi_len >= sizeof(msg))
		return EAP_SIM_DB_FAILURE;
	os_memcpy(msg + len, imsi, imsi_len);
	len += imsi_len;
	ret = os_snprintf(msg + len, sizeof(msg) - len, " %d", max_chal);
	if (ret < 0 || (size_t) ret >= sizeof(msg) - len)
		return EAP_SIM_DB_FAILURE;
	len += ret;

	wpa_printf(MSG_DEBUG, "EAP-SIM DB: requesting SIM authentication "
		   "data for IMSI '%s'", imsi);
	if (eap_sim_db_send(data, msg, len) < 0)
		return EAP_SIM_DB_FAILURE;

	entry = os_zalloc(sizeof(*entry));
	if (entry == NULL)
		return EAP_SIM_DB_FAILURE;

	os_get_time(&entry->timestamp);
	os_strlcpy(entry->imsi, imsi, sizeof(entry->imsi));
	entry->cb_session_ctx = cb_session_ctx;
	entry->state = PENDING;
	eap_sim_db_add_pending(data, entry);
	eap_sim_db_expire_pending(data);

	return EAP_SIM_DB_PENDING;
}


static char * eap_sim_db_get_next(struct eap_sim_db_data *data, char prefix)
{
	char *id, *pos, *end;
	u8 buf[10];

	if (random_get_bytes(buf, sizeof(buf)))
		return NULL;
	id = os_malloc(sizeof(buf) * 2 + 2);
	if (id == NULL)
		return NULL;

	pos = id;
	end = id + sizeof(buf) * 2 + 2;
	*pos++ = prefix;
	pos += wpa_snprintf_hex(pos, end - pos, buf, sizeof(buf));
	
	return id;
}


/**
 * eap_sim_db_get_next_pseudonym - EAP-SIM DB: Get next pseudonym
 * @data: Private data pointer from eap_sim_db_init()
 * @method: EAP method (SIM/AKA/AKA')
 * Returns: Next pseudonym (allocated string) or %NULL on failure
 *
 * This function is used to generate a pseudonym for EAP-SIM. The returned
 * pseudonym is not added to database at this point; it will need to be added
 * with eap_sim_db_add_pseudonym() once the authentication has been completed
 * successfully. Caller is responsible for freeing the returned buffer.
 */
char * eap_sim_db_get_next_pseudonym(struct eap_sim_db_data *data,
				     enum eap_sim_db_method method)
{
	char prefix = EAP_SIM_REAUTH_ID_PREFIX;

	switch (method) {
	case EAP_SIM_DB_SIM:
		prefix = EAP_SIM_PSEUDONYM_PREFIX;
		break;
	case EAP_SIM_DB_AKA:
		prefix = EAP_AKA_PSEUDONYM_PREFIX;
		break;
	case EAP_SIM_DB_AKA_PRIME:
		prefix = EAP_AKA_PRIME_PSEUDONYM_PREFIX;
		break;
	}

	return eap_sim_db_get_next(data, prefix);
}


/**
 * eap_sim_db_get_next_reauth_id - EAP-SIM DB: Get next reauth_id
 * @data: Private data pointer from eap_sim_db_init()
 * @method: EAP method (SIM/AKA/AKA')
 * Returns: Next reauth_id (allocated string) or %NULL on failure
 *
 * This function is used to generate a fast re-authentication identity for
 * EAP-SIM. The returned reauth_id is not added to database at this point; it
 * will need to be added with eap_sim_db_add_reauth() once the authentication
 * has been completed successfully. Caller is responsible for freeing the
 * returned buffer.
 */
char * eap_sim_db_get_next_reauth_id(struct eap_sim_db_data *data,
				     enum eap_sim_db_method method)
{
	char prefix = EAP_SIM_REAUTH_ID_PREFIX;

	switch (method) {
	case EAP_SIM_DB_SIM:
		prefix = EAP_SIM_REAUTH_ID_PREFIX;
		break;
	case EAP_SIM_DB_AKA:
		prefix = EAP_AKA_REAUTH_ID_PREFIX;
		break;
	case EAP_SIM_DB_AKA_PRIME:
		prefix = EAP_AKA_PRIME_REAUTH_ID_PREFIX;
		break;
	}

	return eap_sim_db_get_next(data, prefix);
}


/**
 * eap_sim_db_add_pseudonym - EAP-SIM DB: Add new pseudonym
 * @data: Private data pointer from eap_sim_db_init()
 * @permanent: Permanent username
 * @pseudonym: Pseudonym for this user. This needs to be an allocated buffer,
 * e.g., return value from eap_sim_db_get_next_pseudonym(). Caller must not
 * free it.
 * Returns: 0 on success, -1 on failure
 *
 * This function adds a new pseudonym for EAP-SIM user. EAP-SIM DB is
 * responsible of freeing pseudonym buffer once it is not needed anymore.
 */
int eap_sim_db_add_pseudonym(struct eap_sim_db_data *data,
			     const char *permanent, char *pseudonym)
{
	struct eap_sim_pseudonym *p;
	wpa_printf(MSG_DEBUG, "EAP-SIM DB: Add pseudonym '%s' for permanent "
		   "username '%s'", pseudonym, permanent);

	/* TODO: could store last two pseudonyms */
#ifdef CONFIG_SQLITE
	if (data->sqlite_db)
		return db_add_pseudonym(data, permanent, pseudonym);
#endif /* CONFIG_SQLITE */
	for (p = data->pseudonyms; p; p = p->next) {
		if (os_strcmp(permanent, p->permanent) == 0)
			break;
	}
	if (p) {
		wpa_printf(MSG_DEBUG, "EAP-SIM DB: Replacing previous "
			   "pseudonym: %s", p->pseudonym);
		os_free(p->pseudonym);
		p->pseudonym = pseudonym;
		return 0;
	}

	p = os_zalloc(sizeof(*p));
	if (p == NULL) {
		os_free(pseudonym);
		return -1;
	}

	p->next = data->pseudonyms;
	p->permanent = os_strdup(permanent);
	if (p->permanent == NULL) {
		os_free(p);
		os_free(pseudonym);
		return -1;
	}
	p->pseudonym = pseudonym;
	data->pseudonyms = p;

	wpa_printf(MSG_DEBUG, "EAP-SIM DB: Added new pseudonym entry");
	return 0;
}


static struct eap_sim_reauth *
eap_sim_db_add_reauth_data(struct eap_sim_db_data *data,
			   const char *permanent,
			   char *reauth_id, u16 counter)
{
	struct eap_sim_reauth *r;

	for (r = data->reauths; r; r = r->next) {
		if (os_strcmp(r->permanent, permanent) == 0)
			break;
	}

	if (r) {
		wpa_printf(MSG_DEBUG, "EAP-SIM DB: Replacing previous "
			   "reauth_id: %s", r->reauth_id);
		os_free(r->reauth_id);
		r->reauth_id = reauth_id;
	} else {
		r = os_zalloc(sizeof(*r));
		if (r == NULL) {
			os_free(reauth_id);
			return NULL;
		}

		r->next = data->reauths;
		r->permanent = os_strdup(permanent);
		if (r->permanent == NULL) {
			os_free(r);
			os_free(reauth_id);
			return NULL;
		}
		r->reauth_id = reauth_id;
		data->reauths = r;
		wpa_printf(MSG_DEBUG, "EAP-SIM DB: Added new reauth entry");
	}

	r->counter = counter;

	return r;
}


/**
 * eap_sim_db_add_reauth - EAP-SIM DB: Add new re-authentication entry
 * @priv: Private data pointer from eap_sim_db_init()
 * @permanent: Permanent username
 * @identity_len: Length of identity
 * @reauth_id: reauth_id for this user. This needs to be an allocated buffer,
 * e.g., return value from eap_sim_db_get_next_reauth_id(). Caller must not
 * free it.
 * @counter: AT_COUNTER value for fast re-authentication
 * @mk: 16-byte MK from the previous full authentication or %NULL
 * Returns: 0 on success, -1 on failure
 *
 * This function adds a new re-authentication entry for an EAP-SIM user.
 * EAP-SIM DB is responsible of freeing reauth_id buffer once it is not needed
 * anymore.
 */
int eap_sim_db_add_reauth(struct eap_sim_db_data *data, const char *permanent,
			  char *reauth_id, u16 counter, const u8 *mk)
{
	struct eap_sim_reauth *r;

	wpa_printf(MSG_DEBUG, "EAP-SIM DB: Add reauth_id '%s' for permanent "
		   "identity '%s'", reauth_id, permanent);

#ifdef CONFIG_SQLITE
	if (data->sqlite_db)
		return db_add_reauth(data, permanent, reauth_id, counter, mk,
				     NULL, NULL, NULL);
#endif /* CONFIG_SQLITE */
	r = eap_sim_db_add_reauth_data(data, permanent, reauth_id, counter);
	if (r == NULL)
		return -1;

	os_memcpy(r->mk, mk, EAP_SIM_MK_LEN);

	return 0;
}


#ifdef EAP_SERVER_AKA_PRIME
/**
 * eap_sim_db_add_reauth_prime - EAP-AKA' DB: Add new re-authentication entry
 * @data: Private data pointer from eap_sim_db_init()
 * @permanent: Permanent username
 * @reauth_id: reauth_id for this user. This needs to be an allocated buffer,
 * e.g., return value from eap_sim_db_get_next_reauth_id(). Caller must not
 * free it.
 * @counter: AT_COUNTER value for fast re-authentication
 * @k_encr: K_encr from the previous full authentication
 * @k_aut: K_aut from the previous full authentication
 * @k_re: 32-byte K_re from the previous full authentication
 * Returns: 0 on success, -1 on failure
 *
 * This function adds a new re-authentication entry for an EAP-AKA' user.
 * EAP-SIM DB is responsible of freeing reauth_id buffer once it is not needed
 * anymore.
 */
int eap_sim_db_add_reauth_prime(struct eap_sim_db_data *data,
				const char *permanent, char *reauth_id,
				u16 counter, const u8 *k_encr,
				const u8 *k_aut, const u8 *k_re)
{
	struct eap_sim_reauth *r;

	wpa_printf(MSG_DEBUG, "EAP-SIM DB: Add reauth_id '%s' for permanent "
		   "identity '%s'", reauth_id, permanent);

#ifdef CONFIG_SQLITE
	if (data->sqlite_db)
		return db_add_reauth(data, permanent, reauth_id, counter, NULL,
				     k_encr, k_aut, k_re);
#endif /* CONFIG_SQLITE */
	r = eap_sim_db_add_reauth_data(data, permanent, reauth_id, counter);
	if (r == NULL)
		return -1;

	os_memcpy(r->k_encr, k_encr, EAP_SIM_K_ENCR_LEN);
	os_memcpy(r->k_aut, k_aut, EAP_AKA_PRIME_K_AUT_LEN);
	os_memcpy(r->k_re, k_re, EAP_AKA_PRIME_K_RE_LEN);

	return 0;
}
#endif /* EAP_SERVER_AKA_PRIME */


/**
 * eap_sim_db_get_permanent - EAP-SIM DB: Get permanent identity
 * @data: Private data pointer from eap_sim_db_init()
 * @pseudonym: Pseudonym username
 * Returns: Pointer to permanent username or %NULL if not found
 */
const char *
eap_sim_db_get_permanent(struct eap_sim_db_data *data, const char *pseudonym)
{
	struct eap_sim_pseudonym *p;

#ifdef CONFIG_SQLITE
	if (data->sqlite_db)
		return db_get_pseudonym(data, pseudonym);
#endif /* CONFIG_SQLITE */

	p = data->pseudonyms;
	while (p) {
		if (os_strcmp(p->pseudonym, pseudonym) == 0)
			return p->permanent;
		p = p->next;
	}

	return NULL;
}


/**
 * eap_sim_db_get_reauth_entry - EAP-SIM DB: Get re-authentication entry
 * @data: Private data pointer from eap_sim_db_init()
 * @reauth_id: Fast re-authentication username
 * Returns: Pointer to the re-auth entry, or %NULL if not found
 */
struct eap_sim_reauth *
eap_sim_db_get_reauth_entry(struct eap_sim_db_data *data,
			    const char *reauth_id)
{
	struct eap_sim_reauth *r;

#ifdef CONFIG_SQLITE
	if (data->sqlite_db)
		return db_get_reauth(data, reauth_id);
#endif /* CONFIG_SQLITE */

	r = data->reauths;
	while (r) {
		if (os_strcmp(r->reauth_id, reauth_id) == 0)
			break;
		r = r->next;
	}

	return r;
}


/**
 * eap_sim_db_remove_reauth - EAP-SIM DB: Remove re-authentication entry
 * @data: Private data pointer from eap_sim_db_init()
 * @reauth: Pointer to re-authentication entry from
 * eap_sim_db_get_reauth_entry()
 */
void eap_sim_db_remove_reauth(struct eap_sim_db_data *data,
			      struct eap_sim_reauth *reauth)
{
	struct eap_sim_reauth *r, *prev = NULL;
#ifdef CONFIG_SQLITE
	if (data->sqlite_db) {
		db_remove_reauth(data, reauth);
		return;
	}
#endif /* CONFIG_SQLITE */
	r = data->reauths;
	while (r) {
		if (r == reauth) {
			if (prev)
				prev->next = r->next;
			else
				data->reauths = r->next;
			eap_sim_db_free_reauth(r);
			return;
		}
		prev = r;
		r = r->next;
	}
}


/**
 * eap_sim_db_get_aka_auth - Get AKA authentication values
 * @data: Private data pointer from eap_sim_db_init()
 * @username: Permanent username (prefix | IMSI)
 * @_rand: Buffer for RAND value
 * @autn: Buffer for AUTN value
 * @ik: Buffer for IK value
 * @ck: Buffer for CK value
 * @res: Buffer for RES value
 * @res_len: Buffer for RES length
 * @cb_session_ctx: Session callback context for get_complete_cb()
 * Returns: 0 on success, -1 (EAP_SIM_DB_FAILURE) on error (e.g., user not
 * found), or -2 (EAP_SIM_DB_PENDING) if results are not yet available. In this
 * case, the callback function registered with eap_sim_db_init() will be
 * called once the results become available.
 *
 * When using an external server for AKA authentication, this function can
 * always start a request and return EAP_SIM_DB_PENDING immediately if
 * authentication triplets are not available. Once the authentication data are
 * received, callback function registered with eap_sim_db_init() is called to
 * notify EAP state machine to reprocess the message. This
 * eap_sim_db_get_aka_auth() function will then be called again and the newly
 * received triplets will then be given to the caller.
 */
int eap_sim_db_get_aka_auth(struct eap_sim_db_data *data, const char *username,
			    u8 *_rand, u8 *autn, u8 *ik, u8 *ck,
			    u8 *res, size_t *res_len, void *cb_session_ctx)
{
	struct eap_sim_db_pending *entry;
	int len;
	char msg[40];
	const char *imsi;
	size_t imsi_len;

	if (username == NULL ||
	    (username[0] != EAP_AKA_PERMANENT_PREFIX &&
	     username[0] != EAP_AKA_PRIME_PERMANENT_PREFIX) ||
	    username[1] == '\0' || os_strlen(username) > sizeof(entry->imsi)) {
		wpa_printf(MSG_DEBUG, "EAP-SIM DB: unexpected username '%s'",
			   username);
		return EAP_SIM_DB_FAILURE;
	}
	imsi = username + 1;
	wpa_printf(MSG_DEBUG, "EAP-SIM DB: Get AKA auth for IMSI '%s'",
		   imsi);

	entry = eap_sim_db_get_pending(data, imsi, 1);
	if (entry) {
		if (entry->state == FAILURE) {
			os_free(entry);
			wpa_printf(MSG_DEBUG, "EAP-SIM DB: Failure");
			return EAP_SIM_DB_FAILURE;
		}

		if (entry->state == PENDING) {
			eap_sim_db_add_pending(data, entry);
			wpa_printf(MSG_DEBUG, "EAP-SIM DB: Pending");
			return EAP_SIM_DB_PENDING;
		}

		wpa_printf(MSG_DEBUG, "EAP-SIM DB: Returning successfully "
			   "received authentication data");
		os_memcpy(_rand, entry->u.aka.rand, EAP_AKA_RAND_LEN);
		os_memcpy(autn, entry->u.aka.autn, EAP_AKA_AUTN_LEN);
		os_memcpy(ik, entry->u.aka.ik, EAP_AKA_IK_LEN);
		os_memcpy(ck, entry->u.aka.ck, EAP_AKA_CK_LEN);
		os_memcpy(res, entry->u.aka.res, EAP_AKA_RES_MAX_LEN);
		*res_len = entry->u.aka.res_len;
		os_free(entry);
		return 0;
	}

	if (data->sock < 0) {
		if (eap_sim_db_open_socket(data) < 0)
			return EAP_SIM_DB_FAILURE;
	}

	imsi_len = os_strlen(imsi);
	len = os_snprintf(msg, sizeof(msg), "AKA-REQ-AUTH ");
	if (len < 0 || len + imsi_len >= sizeof(msg))
		return EAP_SIM_DB_FAILURE;
	os_memcpy(msg + len, imsi, imsi_len);
	len += imsi_len;

	wpa_printf(MSG_DEBUG, "EAP-SIM DB: requesting AKA authentication "
		    "data for IMSI '%s'", imsi);
	if (eap_sim_db_send(data, msg, len) < 0)
		return EAP_SIM_DB_FAILURE;

	entry = os_zalloc(sizeof(*entry));
	if (entry == NULL)
		return EAP_SIM_DB_FAILURE;

	os_get_time(&entry->timestamp);
	entry->aka = 1;
	os_strlcpy(entry->imsi, imsi, sizeof(entry->imsi));
	entry->cb_session_ctx = cb_session_ctx;
	entry->state = PENDING;
	eap_sim_db_add_pending(data, entry);
	eap_sim_db_expire_pending(data);

	return EAP_SIM_DB_PENDING;
}


/**
 * eap_sim_db_resynchronize - Resynchronize AKA AUTN
 * @data: Private data pointer from eap_sim_db_init()
 * @username: Permanent username
 * @auts: AUTS value from the peer
 * @_rand: RAND value used in the rejected message
 * Returns: 0 on success, -1 on failure
 *
 * This function is called when the peer reports synchronization failure in the
 * AUTN value by sending AUTS. The AUTS and RAND values should be sent to
 * HLR/AuC to allow it to resynchronize with the peer. After this,
 * eap_sim_db_get_aka_auth() will be called again to to fetch updated
 * RAND/AUTN values for the next challenge.
 */
int eap_sim_db_resynchronize(struct eap_sim_db_data *data,
			     const char *username,
			     const u8 *auts, const u8 *_rand)
{
	const char *imsi;
	size_t imsi_len;

	if (username == NULL ||
	    (username[0] != EAP_AKA_PERMANENT_PREFIX &&
	     username[0] != EAP_AKA_PRIME_PERMANENT_PREFIX) ||
	    username[1] == '\0' || os_strlen(username) > 20) {
		wpa_printf(MSG_DEBUG, "EAP-SIM DB: unexpected username '%s'",
			   username);
		return -1;
	}
	imsi = username + 1;
	wpa_printf(MSG_DEBUG, "EAP-SIM DB: Get AKA auth for IMSI '%s'",
		   imsi);

	if (data->sock >= 0) {
		char msg[100];
		int len, ret;

		imsi_len = os_strlen(imsi);
		len = os_snprintf(msg, sizeof(msg), "AKA-AUTS ");
		if (len < 0 || len + imsi_len >= sizeof(msg))
			return -1;
		os_memcpy(msg + len, imsi, imsi_len);
		len += imsi_len;

		ret = os_snprintf(msg + len, sizeof(msg) - len, " ");
		if (ret < 0 || (size_t) ret >= sizeof(msg) - len)
			return -1;
		len += ret;
		len += wpa_snprintf_hex(msg + len, sizeof(msg) - len,
					auts, EAP_AKA_AUTS_LEN);
		ret = os_snprintf(msg + len, sizeof(msg) - len, " ");
		if (ret < 0 || (size_t) ret >= sizeof(msg) - len)
			return -1;
		len += ret;
		len += wpa_snprintf_hex(msg + len, sizeof(msg) - len,
					_rand, EAP_AKA_RAND_LEN);
		wpa_printf(MSG_DEBUG, "EAP-SIM DB: reporting AKA AUTS for "
			   "IMSI '%s'", imsi);
		if (eap_sim_db_send(data, msg, len) < 0)
			return -1;
	}

	return 0;
}


/**
 * sim_get_username - Extract username from SIM identity
 * @identity: Identity
 * @identity_len: Identity length
 * Returns: Allocated buffer with the username part of the identity
 *
 * Caller is responsible for freeing the returned buffer with os_free().
 */
char * sim_get_username(const u8 *identity, size_t identity_len)
{
	char *username;
	size_t pos;

	if (identity == NULL)
		return NULL;

	for (pos = 0; pos < identity_len; pos++) {
		if (identity[pos] == '@' || identity[pos] == '\0')
			break;
	}

	username = os_malloc(pos + 1);
	if (username == NULL)
		return NULL;
	os_memcpy(username, identity, pos);
	username[pos] = '\0';

	return username;
}
