18d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* 28d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * hostapd / EAP-SIM database/authenticator gateway 304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * Copyright (c) 2005-2010, 2012, Jouni Malinen <j@w1.fi> 48d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 5c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * This software may be distributed under the terms of the BSD license. 6c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * See README for more details. 78d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 88d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This is an example implementation of the EAP-SIM/AKA database/authentication 98d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * gateway interface that is using an external program as an SS7 gateway to 108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * GSM/UMTS authentication center (HLR/AuC). hlr_auc_gw is an example 118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * implementation of such a gateway program. This eap_sim_db.c takes care of 128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * EAP-SIM/AKA pseudonyms and re-auth identities. It can be used with different 138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * gateway implementations for HLR/AuC access. Alternatively, it can also be 148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * completely replaced if the in-memory database of pseudonyms/re-auth 158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * identities is not suitable for some cases. 168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "includes.h" 198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include <sys/un.h> 204530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt#ifdef CONFIG_SQLITE 214530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt#include <sqlite3.h> 224530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt#endif /* CONFIG_SQLITE */ 238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common.h" 258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "crypto/random.h" 268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "eap_common/eap_sim_common.h" 278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "eap_server/eap_sim_db.h" 288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "eloop.h" 298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct eap_sim_pseudonym { 318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_sim_pseudonym *next; 324530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt char *permanent; /* permanent username */ 334530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt char *pseudonym; /* pseudonym username */ 348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}; 358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct eap_sim_db_pending { 378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_sim_db_pending *next; 384530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt char imsi[20]; 398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt enum { PENDING, SUCCESS, FAILURE } state; 408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void *cb_session_ctx; 418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int aka; 428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt union { 438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct { 448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 kc[EAP_SIM_MAX_CHAL][EAP_SIM_KC_LEN]; 458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 sres[EAP_SIM_MAX_CHAL][EAP_SIM_SRES_LEN]; 468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 rand[EAP_SIM_MAX_CHAL][GSM_RAND_LEN]; 478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int num_chal; 488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } sim; 498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct { 508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 rand[EAP_AKA_RAND_LEN]; 518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 autn[EAP_AKA_AUTN_LEN]; 528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 ik[EAP_AKA_IK_LEN]; 538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 ck[EAP_AKA_CK_LEN]; 548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 res[EAP_AKA_RES_MAX_LEN]; 558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t res_len; 568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } aka; 578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } u; 588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}; 598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct eap_sim_db_data { 618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int sock; 628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *fname; 638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *local_sock; 648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void (*get_complete_cb)(void *ctx, void *session_ctx); 658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void *ctx; 668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_sim_pseudonym *pseudonyms; 678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_sim_reauth *reauths; 688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_sim_db_pending *pending; 69d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt unsigned int eap_sim_db_timeout; 704530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt#ifdef CONFIG_SQLITE 714530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt sqlite3 *sqlite_db; 724530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt char db_tmp_identity[100]; 734530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt char db_tmp_pseudonym_str[100]; 744530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt struct eap_sim_pseudonym db_tmp_pseudonym; 754530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt struct eap_sim_reauth db_tmp_reauth; 764530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt#endif /* CONFIG_SQLITE */ 778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}; 788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 80d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtstatic void eap_sim_db_del_timeout(void *eloop_ctx, void *user_ctx); 81d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtstatic void eap_sim_db_query_timeout(void *eloop_ctx, void *user_ctx); 82d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 83d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 844530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt#ifdef CONFIG_SQLITE 854530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 864530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidtstatic int db_table_exists(sqlite3 *db, const char *name) 874530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt{ 884530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt char cmd[128]; 894530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt os_snprintf(cmd, sizeof(cmd), "SELECT 1 FROM %s;", name); 904530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt return sqlite3_exec(db, cmd, NULL, NULL, NULL) == SQLITE_OK; 914530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt} 924530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 934530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 944530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidtstatic int db_table_create_pseudonym(sqlite3 *db) 954530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt{ 964530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt char *err = NULL; 974530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt const char *sql = 984530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt "CREATE TABLE pseudonyms(" 994530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt " permanent CHAR(21) PRIMARY KEY," 1004530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt " pseudonym CHAR(21) NOT NULL" 1014530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt ");"; 1024530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 1034530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SIM DB: Adding database table for " 1044530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt "pseudonym information"); 1054530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (sqlite3_exec(db, sql, NULL, NULL, &err) != SQLITE_OK) { 1064530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt wpa_printf(MSG_ERROR, "EAP-SIM DB: SQLite error: %s", err); 1074530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt sqlite3_free(err); 1084530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt return -1; 1094530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt } 1104530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 1114530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt return 0; 1124530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt} 1134530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 1144530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 1154530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidtstatic int db_table_create_reauth(sqlite3 *db) 1164530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt{ 1174530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt char *err = NULL; 1184530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt const char *sql = 1194530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt "CREATE TABLE reauth(" 1204530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt " permanent CHAR(21) PRIMARY KEY," 1214530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt " reauth_id CHAR(21) NOT NULL," 1224530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt " counter INTEGER," 1234530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt " mk CHAR(40)," 1244530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt " k_encr CHAR(32)," 1254530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt " k_aut CHAR(64)," 1264530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt " k_re CHAR(64)" 1274530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt ");"; 1284530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 1294530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SIM DB: Adding database table for " 1304530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt "reauth information"); 1314530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (sqlite3_exec(db, sql, NULL, NULL, &err) != SQLITE_OK) { 1324530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt wpa_printf(MSG_ERROR, "EAP-SIM DB: SQLite error: %s", err); 1334530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt sqlite3_free(err); 1344530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt return -1; 1354530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt } 1364530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 1374530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt return 0; 1384530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt} 1394530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 1404530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 1414530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidtstatic sqlite3 * db_open(const char *db_file) 1424530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt{ 1434530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt sqlite3 *db; 1444530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 1454530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (sqlite3_open(db_file, &db)) { 1464530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt wpa_printf(MSG_ERROR, "EAP-SIM DB: Failed to open database " 1474530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt "%s: %s", db_file, sqlite3_errmsg(db)); 1484530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt sqlite3_close(db); 1494530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt return NULL; 1504530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt } 1514530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 1524530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (!db_table_exists(db, "pseudonyms") && 1534530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt db_table_create_pseudonym(db) < 0) { 1544530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt sqlite3_close(db); 1554530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt return NULL; 1564530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt } 1574530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 1584530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (!db_table_exists(db, "reauth") && 1594530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt db_table_create_reauth(db) < 0) { 1604530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt sqlite3_close(db); 1614530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt return NULL; 1624530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt } 1634530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 1644530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt return db; 1654530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt} 1664530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 1674530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 1684530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidtstatic int valid_db_string(const char *str) 1694530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt{ 1704530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt const char *pos = str; 1714530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt while (*pos) { 1724530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if ((*pos < '0' || *pos > '9') && 1734530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt (*pos < 'a' || *pos > 'f')) 1744530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt return 0; 1754530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt pos++; 1764530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt } 1774530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt return 1; 1784530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt} 1794530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 1804530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 1814530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidtstatic int db_add_pseudonym(struct eap_sim_db_data *data, 1824530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt const char *permanent, char *pseudonym) 1834530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt{ 1844530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt char cmd[128]; 1854530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt char *err = NULL; 1864530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 1874530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (!valid_db_string(permanent) || !valid_db_string(pseudonym)) { 1884530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt os_free(pseudonym); 1894530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt return -1; 1904530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt } 1914530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 1924530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt os_snprintf(cmd, sizeof(cmd), "INSERT OR REPLACE INTO pseudonyms " 1934530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt "(permanent, pseudonym) VALUES ('%s', '%s');", 1944530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt permanent, pseudonym); 1954530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt os_free(pseudonym); 1964530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (sqlite3_exec(data->sqlite_db, cmd, NULL, NULL, &err) != SQLITE_OK) 1974530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt { 1984530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt wpa_printf(MSG_ERROR, "EAP-SIM DB: SQLite error: %s", err); 1994530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt sqlite3_free(err); 2004530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt return -1; 2014530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt } 2024530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 2034530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt return 0; 2044530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt} 2054530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 2064530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 2074530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidtstatic int get_pseudonym_cb(void *ctx, int argc, char *argv[], char *col[]) 2084530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt{ 2094530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt struct eap_sim_db_data *data = ctx; 2104530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt int i; 2114530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 2124530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt for (i = 0; i < argc; i++) { 2134530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (os_strcmp(col[i], "permanent") == 0 && argv[i]) { 2144530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt os_strlcpy(data->db_tmp_identity, argv[i], 2154530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt sizeof(data->db_tmp_identity)); 2164530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt } 2174530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt } 2184530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 2194530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt return 0; 2204530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt} 2214530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 2224530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 2234530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidtstatic char * 2244530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidtdb_get_pseudonym(struct eap_sim_db_data *data, const char *pseudonym) 2254530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt{ 2264530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt char cmd[128]; 2274530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 2284530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (!valid_db_string(pseudonym)) 2294530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt return NULL; 2304530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt os_memset(&data->db_tmp_identity, 0, sizeof(data->db_tmp_identity)); 2314530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt os_snprintf(cmd, sizeof(cmd), 2324530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt "SELECT permanent FROM pseudonyms WHERE pseudonym='%s';", 2334530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt pseudonym); 2344530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (sqlite3_exec(data->sqlite_db, cmd, get_pseudonym_cb, data, NULL) != 2354530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt SQLITE_OK) 2364530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt return NULL; 2374530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (data->db_tmp_identity[0] == '\0') 2384530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt return NULL; 2394530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt return data->db_tmp_identity; 2404530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt} 2414530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 2424530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 2434530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidtstatic int db_add_reauth(struct eap_sim_db_data *data, const char *permanent, 2444530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt char *reauth_id, u16 counter, const u8 *mk, 2454530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt const u8 *k_encr, const u8 *k_aut, const u8 *k_re) 2464530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt{ 2474530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt char cmd[2000], *pos, *end; 2484530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt char *err = NULL; 2494530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 2504530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (!valid_db_string(permanent) || !valid_db_string(reauth_id)) { 2514530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt os_free(reauth_id); 2524530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt return -1; 2534530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt } 2544530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 2554530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt pos = cmd; 2564530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt end = pos + sizeof(cmd); 2574530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt pos += os_snprintf(pos, end - pos, "INSERT OR REPLACE INTO reauth " 2584530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt "(permanent, reauth_id, counter%s%s%s%s) " 2594530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt "VALUES ('%s', '%s', %u", 2604530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt mk ? ", mk" : "", 2614530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt k_encr ? ", k_encr" : "", 2624530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt k_aut ? ", k_aut" : "", 2634530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt k_re ? ", k_re" : "", 2644530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt permanent, reauth_id, counter); 2654530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt os_free(reauth_id); 2664530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 2674530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (mk) { 2684530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt pos += os_snprintf(pos, end - pos, ", '"); 2694530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt pos += wpa_snprintf_hex(pos, end - pos, mk, EAP_SIM_MK_LEN); 2704530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt pos += os_snprintf(pos, end - pos, "'"); 2714530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt } 2724530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 2734530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (k_encr) { 2744530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt pos += os_snprintf(pos, end - pos, ", '"); 2754530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt pos += wpa_snprintf_hex(pos, end - pos, k_encr, 2764530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt EAP_SIM_K_ENCR_LEN); 2774530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt pos += os_snprintf(pos, end - pos, "'"); 2784530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt } 2794530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 2804530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (k_aut) { 2814530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt pos += os_snprintf(pos, end - pos, ", '"); 2824530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt pos += wpa_snprintf_hex(pos, end - pos, k_aut, 2834530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt EAP_AKA_PRIME_K_AUT_LEN); 2844530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt pos += os_snprintf(pos, end - pos, "'"); 2854530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt } 2864530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 2874530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (k_re) { 2884530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt pos += os_snprintf(pos, end - pos, ", '"); 2894530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt pos += wpa_snprintf_hex(pos, end - pos, k_re, 2904530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt EAP_AKA_PRIME_K_RE_LEN); 2914530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt pos += os_snprintf(pos, end - pos, "'"); 2924530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt } 2934530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 2944530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt os_snprintf(pos, end - pos, ");"); 2954530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 2964530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (sqlite3_exec(data->sqlite_db, cmd, NULL, NULL, &err) != SQLITE_OK) 2974530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt { 2984530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt wpa_printf(MSG_ERROR, "EAP-SIM DB: SQLite error: %s", err); 2994530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt sqlite3_free(err); 3004530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt return -1; 3014530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt } 3024530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 3034530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt return 0; 3044530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt} 3054530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 3064530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 3074530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidtstatic int get_reauth_cb(void *ctx, int argc, char *argv[], char *col[]) 3084530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt{ 3094530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt struct eap_sim_db_data *data = ctx; 3104530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt int i; 3114530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt struct eap_sim_reauth *reauth = &data->db_tmp_reauth; 3124530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 3134530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt for (i = 0; i < argc; i++) { 3144530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (os_strcmp(col[i], "permanent") == 0 && argv[i]) { 3154530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt os_strlcpy(data->db_tmp_identity, argv[i], 3164530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt sizeof(data->db_tmp_identity)); 3174530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt reauth->permanent = data->db_tmp_identity; 3184530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt } else if (os_strcmp(col[i], "counter") == 0 && argv[i]) { 3194530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt reauth->counter = atoi(argv[i]); 3204530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt } else if (os_strcmp(col[i], "mk") == 0 && argv[i]) { 3214530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt hexstr2bin(argv[i], reauth->mk, sizeof(reauth->mk)); 3224530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt } else if (os_strcmp(col[i], "k_encr") == 0 && argv[i]) { 3234530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt hexstr2bin(argv[i], reauth->k_encr, 3244530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt sizeof(reauth->k_encr)); 3254530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt } else if (os_strcmp(col[i], "k_aut") == 0 && argv[i]) { 3264530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt hexstr2bin(argv[i], reauth->k_aut, 3274530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt sizeof(reauth->k_aut)); 3284530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt } else if (os_strcmp(col[i], "k_re") == 0 && argv[i]) { 3294530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt hexstr2bin(argv[i], reauth->k_re, 3304530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt sizeof(reauth->k_re)); 3314530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt } 3324530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt } 3334530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 3344530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt return 0; 3354530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt} 3364530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 3374530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 3384530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidtstatic struct eap_sim_reauth * 3394530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidtdb_get_reauth(struct eap_sim_db_data *data, const char *reauth_id) 3404530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt{ 3414530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt char cmd[256]; 3424530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 3434530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (!valid_db_string(reauth_id)) 3444530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt return NULL; 3454530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt os_memset(&data->db_tmp_reauth, 0, sizeof(data->db_tmp_reauth)); 3464530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt os_strlcpy(data->db_tmp_pseudonym_str, reauth_id, 3474530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt sizeof(data->db_tmp_pseudonym_str)); 3484530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt data->db_tmp_reauth.reauth_id = data->db_tmp_pseudonym_str; 3494530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt os_snprintf(cmd, sizeof(cmd), 3504530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt "SELECT * FROM reauth WHERE reauth_id='%s';", reauth_id); 3514530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (sqlite3_exec(data->sqlite_db, cmd, get_reauth_cb, data, NULL) != 3524530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt SQLITE_OK) 3534530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt return NULL; 3544530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (data->db_tmp_reauth.permanent == NULL) 3554530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt return NULL; 3564530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt return &data->db_tmp_reauth; 3574530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt} 3584530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 3594530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 3604530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidtstatic void db_remove_reauth(struct eap_sim_db_data *data, 3614530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt struct eap_sim_reauth *reauth) 3624530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt{ 3634530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt char cmd[256]; 3644530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 3654530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (!valid_db_string(reauth->permanent)) 3664530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt return; 3674530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt os_snprintf(cmd, sizeof(cmd), 3684530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt "DELETE FROM reauth WHERE permanent='%s';", 3694530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt reauth->permanent); 3704530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt sqlite3_exec(data->sqlite_db, cmd, NULL, NULL, NULL); 3714530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt} 3724530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 3734530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt#endif /* CONFIG_SQLITE */ 3744530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 3754530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 3768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct eap_sim_db_pending * 3774530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidteap_sim_db_get_pending(struct eap_sim_db_data *data, const char *imsi, int aka) 3788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_sim_db_pending *entry, *prev = NULL; 3808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt entry = data->pending; 3828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (entry) { 3834530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (entry->aka == aka && os_strcmp(entry->imsi, imsi) == 0) { 3848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (prev) 3858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt prev->next = entry->next; 3868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 3878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->pending = entry->next; 3888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 3898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt prev = entry; 3918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt entry = entry->next; 3928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return entry; 3948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void eap_sim_db_add_pending(struct eap_sim_db_data *data, 3988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_sim_db_pending *entry) 3998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt entry->next = data->pending; 4018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->pending = entry; 4028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 405d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtstatic void eap_sim_db_free_pending(struct eap_sim_db_data *data, 406d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt struct eap_sim_db_pending *entry) 407d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt{ 408d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt eloop_cancel_timeout(eap_sim_db_query_timeout, data, entry); 409d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt eloop_cancel_timeout(eap_sim_db_del_timeout, data, entry); 410d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt os_free(entry); 411d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt} 412d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 413d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 414d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtstatic void eap_sim_db_del_pending(struct eap_sim_db_data *data, 415d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt struct eap_sim_db_pending *entry) 416d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt{ 417d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt struct eap_sim_db_pending **pp = &data->pending; 418d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 419d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt while (*pp != NULL) { 420d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (*pp == entry) { 421d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt *pp = entry->next; 422d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt eap_sim_db_free_pending(data, entry); 423d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return; 424d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } 425d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt pp = &(*pp)->next; 426d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } 427d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt} 428d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 429d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 430d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtstatic void eap_sim_db_del_timeout(void *eloop_ctx, void *user_ctx) 431d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt{ 432d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt struct eap_sim_db_data *data = eloop_ctx; 433d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt struct eap_sim_db_pending *entry = user_ctx; 434d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 435d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SIM DB: Delete query timeout for %p", entry); 436d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt eap_sim_db_del_pending(data, entry); 437d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt} 438d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 439d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 440d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtstatic void eap_sim_db_query_timeout(void *eloop_ctx, void *user_ctx) 441d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt{ 442d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt struct eap_sim_db_data *data = eloop_ctx; 443d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt struct eap_sim_db_pending *entry = user_ctx; 444d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 445d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt /* 446d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt * Report failure and allow some time for EAP server to process it 447d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt * before deleting the query. 448d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt */ 449d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SIM DB: Query timeout for %p", entry); 450d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt entry->state = FAILURE; 451d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt data->get_complete_cb(data->ctx, entry->cb_session_ctx); 452d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt eloop_register_timeout(1, 0, eap_sim_db_del_timeout, data, entry); 453d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt} 454d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 455d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 4568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void eap_sim_db_sim_resp_auth(struct eap_sim_db_data *data, 4578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *imsi, char *buf) 4588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *start, *end, *pos; 4608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_sim_db_pending *entry; 4618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int num_chal; 4628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 4648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * SIM-RESP-AUTH <IMSI> Kc(i):SRES(i):RAND(i) ... 4658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * SIM-RESP-AUTH <IMSI> FAILURE 4668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * (IMSI = ASCII string, Kc/SRES/RAND = hex string) 4678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 4688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4694530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt entry = eap_sim_db_get_pending(data, imsi, 0); 4708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (entry == NULL) { 4718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SIM DB: No pending entry for the " 4728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "received message found"); 4738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 4748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt start = buf; 4778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_strncmp(start, "FAILURE", 7) == 0) { 4788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SIM DB: External server reported " 4798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "failure"); 4808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt entry->state = FAILURE; 4818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_sim_db_add_pending(data, entry); 4828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->get_complete_cb(data->ctx, entry->cb_session_ctx); 4838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 4848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt num_chal = 0; 4878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (num_chal < EAP_SIM_MAX_CHAL) { 4888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt end = os_strchr(start, ' '); 4898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (end) 4908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *end = '\0'; 4918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = os_strchr(start, ':'); 4938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pos == NULL) 4948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto parse_fail; 4958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos = '\0'; 4968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hexstr2bin(start, entry->u.sim.kc[num_chal], 4978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt EAP_SIM_KC_LEN)) 4988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto parse_fail; 4998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt start = pos + 1; 5018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = os_strchr(start, ':'); 5028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pos == NULL) 5038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto parse_fail; 5048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos = '\0'; 5058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hexstr2bin(start, entry->u.sim.sres[num_chal], 5068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt EAP_SIM_SRES_LEN)) 5078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto parse_fail; 5088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt start = pos + 1; 5108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hexstr2bin(start, entry->u.sim.rand[num_chal], 5118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt GSM_RAND_LEN)) 5128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto parse_fail; 5138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt num_chal++; 5158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (end == NULL) 5168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 5178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 5188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt start = end + 1; 5198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt entry->u.sim.num_chal = num_chal; 5218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt entry->state = SUCCESS; 5238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SIM DB: Authentication data parsed " 5248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "successfully - callback"); 5258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_sim_db_add_pending(data, entry); 5268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->get_complete_cb(data->ctx, entry->cb_session_ctx); 5278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 5288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtparse_fail: 5308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SIM DB: Failed to parse response string"); 531d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt eap_sim_db_free_pending(data, entry); 5328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 5338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void eap_sim_db_aka_resp_auth(struct eap_sim_db_data *data, 5368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *imsi, char *buf) 5378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 5388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *start, *end; 5398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_sim_db_pending *entry; 5408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 5428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * AKA-RESP-AUTH <IMSI> <RAND> <AUTN> <IK> <CK> <RES> 5438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * AKA-RESP-AUTH <IMSI> FAILURE 5448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * (IMSI = ASCII string, RAND/AUTN/IK/CK/RES = hex string) 5458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 5468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5474530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt entry = eap_sim_db_get_pending(data, imsi, 1); 5488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (entry == NULL) { 5498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SIM DB: No pending entry for the " 5508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "received message found"); 5518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 5528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt start = buf; 5558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_strncmp(start, "FAILURE", 7) == 0) { 5568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SIM DB: External server reported " 5578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "failure"); 5588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt entry->state = FAILURE; 5598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_sim_db_add_pending(data, entry); 5608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->get_complete_cb(data->ctx, entry->cb_session_ctx); 5618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 5628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt end = os_strchr(start, ' '); 5658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (end == NULL) 5668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto parse_fail; 5678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *end = '\0'; 5688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hexstr2bin(start, entry->u.aka.rand, EAP_AKA_RAND_LEN)) 5698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto parse_fail; 5708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt start = end + 1; 5728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt end = os_strchr(start, ' '); 5738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (end == NULL) 5748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto parse_fail; 5758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *end = '\0'; 5768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hexstr2bin(start, entry->u.aka.autn, EAP_AKA_AUTN_LEN)) 5778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto parse_fail; 5788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt start = end + 1; 5808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt end = os_strchr(start, ' '); 5818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (end == NULL) 5828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto parse_fail; 5838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *end = '\0'; 5848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hexstr2bin(start, entry->u.aka.ik, EAP_AKA_IK_LEN)) 5858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto parse_fail; 5868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt start = end + 1; 5888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt end = os_strchr(start, ' '); 5898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (end == NULL) 5908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto parse_fail; 5918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *end = '\0'; 5928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hexstr2bin(start, entry->u.aka.ck, EAP_AKA_CK_LEN)) 5938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto parse_fail; 5948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt start = end + 1; 5968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt end = os_strchr(start, ' '); 5978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (end) 5988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *end = '\0'; 5998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else { 6008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt end = start; 6018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (*end) 6028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt end++; 6038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt entry->u.aka.res_len = (end - start) / 2; 6058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (entry->u.aka.res_len > EAP_AKA_RES_MAX_LEN) { 6068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SIM DB: Too long RES"); 6078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt entry->u.aka.res_len = 0; 6088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto parse_fail; 6098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hexstr2bin(start, entry->u.aka.res, entry->u.aka.res_len)) 6118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto parse_fail; 6128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt entry->state = SUCCESS; 6148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SIM DB: Authentication data parsed " 6158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "successfully - callback"); 6168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_sim_db_add_pending(data, entry); 6178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->get_complete_cb(data->ctx, entry->cb_session_ctx); 6188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 6198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtparse_fail: 6218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SIM DB: Failed to parse response string"); 622d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt eap_sim_db_free_pending(data, entry); 6238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 6248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void eap_sim_db_receive(int sock, void *eloop_ctx, void *sock_ctx) 6278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 6288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_sim_db_data *data = eloop_ctx; 6298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char buf[1000], *pos, *cmd, *imsi; 6308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int res; 6318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 632fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt res = recv(sock, buf, sizeof(buf) - 1, 0); 6338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res < 0) 6348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 635fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt buf[res] = '\0'; 6368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_ascii_key(MSG_MSGDUMP, "EAP-SIM DB: Received from an " 6378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "external source", (u8 *) buf, res); 6388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res == 0) 6398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 6408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data->get_complete_cb == NULL) { 6428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SIM DB: No get_complete_cb " 6438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "registered"); 6448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 6458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* <cmd> <IMSI> ... */ 6488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cmd = buf; 6508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = os_strchr(cmd, ' '); 6518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pos == NULL) 6528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto parse_fail; 6538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos = '\0'; 6548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt imsi = pos + 1; 6558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = os_strchr(imsi, ' '); 6568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pos == NULL) 6578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto parse_fail; 6588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos = '\0'; 6598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SIM DB: External response=%s for IMSI %s", 6608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cmd, imsi); 6618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_strcmp(cmd, "SIM-RESP-AUTH") == 0) 6638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_sim_db_sim_resp_auth(data, imsi, pos + 1); 6648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (os_strcmp(cmd, "AKA-RESP-AUTH") == 0) 6658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_sim_db_aka_resp_auth(data, imsi, pos + 1); 6668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 6678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "EAP-SIM DB: Unknown external response " 6688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "'%s'", cmd); 6698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 6708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtparse_fail: 6728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SIM DB: Failed to parse response string"); 6738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 6748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int eap_sim_db_open_socket(struct eap_sim_db_data *data) 6778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 6788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct sockaddr_un addr; 6798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt static int counter = 0; 6808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_strncmp(data->fname, "unix:", 5) != 0) 6828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 6838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->sock = socket(PF_UNIX, SOCK_DGRAM, 0); 6858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data->sock < 0) { 686cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_printf(MSG_INFO, "socket(eap_sim_db): %s", strerror(errno)); 6878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 6888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&addr, 0, sizeof(addr)); 6918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt addr.sun_family = AF_UNIX; 6928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_snprintf(addr.sun_path, sizeof(addr.sun_path), 6938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "/tmp/eap_sim_db_%d-%d", getpid(), counter++); 69461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt os_free(data->local_sock); 6958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->local_sock = os_strdup(addr.sun_path); 696bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt if (data->local_sock == NULL) { 697bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt close(data->sock); 698bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt data->sock = -1; 699bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt return -1; 700bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt } 7018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (bind(data->sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) { 702cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_printf(MSG_INFO, "bind(eap_sim_db): %s", strerror(errno)); 7038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt close(data->sock); 7048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->sock = -1; 7058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 7068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&addr, 0, sizeof(addr)); 7098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt addr.sun_family = AF_UNIX; 7108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_strlcpy(addr.sun_path, data->fname + 5, sizeof(addr.sun_path)); 7118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (connect(data->sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) { 712cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_printf(MSG_INFO, "connect(eap_sim_db): %s", 713cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt strerror(errno)); 7148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_ascii(MSG_INFO, "HLR/AuC GW socket", 7158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (u8 *) addr.sun_path, 7168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_strlen(addr.sun_path)); 7178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt close(data->sock); 7188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->sock = -1; 719bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt unlink(data->local_sock); 720bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt os_free(data->local_sock); 721bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt data->local_sock = NULL; 7228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 7238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_read_sock(data->sock, eap_sim_db_receive, data, NULL); 7268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 7288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 7298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void eap_sim_db_close_socket(struct eap_sim_db_data *data) 7328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 7338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data->sock >= 0) { 7348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_unregister_read_sock(data->sock); 7358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt close(data->sock); 7368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->sock = -1; 7378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data->local_sock) { 7398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unlink(data->local_sock); 7408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(data->local_sock); 7418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->local_sock = NULL; 7428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 7448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 7478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_sim_db_init - Initialize EAP-SIM DB / authentication gateway interface 7488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @config: Configuration data (e.g., file name) 749d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt * @db_timeout: Database lookup timeout 7508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @get_complete_cb: Callback function for reporting availability of triplets 7518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @ctx: Context pointer for get_complete_cb 7528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: Pointer to a private data structure or %NULL on failure 7538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 7544530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidtstruct eap_sim_db_data * 755d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidteap_sim_db_init(const char *config, unsigned int db_timeout, 7564530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt void (*get_complete_cb)(void *ctx, void *session_ctx), 7574530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt void *ctx) 7588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 7598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_sim_db_data *data; 7604530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt char *pos; 7618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data = os_zalloc(sizeof(*data)); 7638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data == NULL) 7648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 7658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->sock = -1; 7678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->get_complete_cb = get_complete_cb; 7688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->ctx = ctx; 769d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt data->eap_sim_db_timeout = db_timeout; 7708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->fname = os_strdup(config); 7718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data->fname == NULL) 7728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 7734530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt pos = os_strstr(data->fname, " db="); 7744530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (pos) { 7754530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt *pos = '\0'; 7764530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt#ifdef CONFIG_SQLITE 7774530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt pos += 4; 7784530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt data->sqlite_db = db_open(pos); 7794530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (data->sqlite_db == NULL) 7804530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt goto fail; 7814530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt#endif /* CONFIG_SQLITE */ 7824530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt } 7838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_strncmp(data->fname, "unix:", 5) == 0) { 78561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (eap_sim_db_open_socket(data)) { 78661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SIM DB: External database " 78761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt "connection not available - will retry " 78861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt "later"); 78961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 7908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return data; 7938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtfail: 7958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_sim_db_close_socket(data); 7968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(data->fname); 7978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(data); 7988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 7998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 8008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void eap_sim_db_free_pseudonym(struct eap_sim_pseudonym *p) 8038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 8044530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt os_free(p->permanent); 8058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(p->pseudonym); 8068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(p); 8078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 8088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void eap_sim_db_free_reauth(struct eap_sim_reauth *r) 8118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 8124530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt os_free(r->permanent); 8138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(r->reauth_id); 8148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(r); 8158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 8168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 8198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_sim_db_deinit - Deinitialize EAP-SIM DB/authentication gw interface 8208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @priv: Private data pointer from eap_sim_db_init() 8218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 8228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid eap_sim_db_deinit(void *priv) 8238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 8248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_sim_db_data *data = priv; 8258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_sim_pseudonym *p, *prev; 8268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_sim_reauth *r, *prevr; 8278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_sim_db_pending *pending, *prev_pending; 8288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8294530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt#ifdef CONFIG_SQLITE 8304530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (data->sqlite_db) { 8314530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt sqlite3_close(data->sqlite_db); 8324530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt data->sqlite_db = NULL; 8334530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt } 8344530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt#endif /* CONFIG_SQLITE */ 8354530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 8368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_sim_db_close_socket(data); 8378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(data->fname); 8388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p = data->pseudonyms; 8408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (p) { 8418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt prev = p; 8428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p = p->next; 8438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_sim_db_free_pseudonym(prev); 8448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt r = data->reauths; 8478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (r) { 8488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt prevr = r; 8498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt r = r->next; 8508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_sim_db_free_reauth(prevr); 8518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pending = data->pending; 8548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (pending) { 8558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt prev_pending = pending; 8568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pending = pending->next; 857d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt eap_sim_db_free_pending(data, prev_pending); 8588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(data); 8618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 8628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int eap_sim_db_send(struct eap_sim_db_data *data, const char *msg, 8658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t len) 8668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 8678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int _errno = 0; 8688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (send(data->sock, msg, len, 0) < 0) { 8708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt _errno = errno; 871cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_printf(MSG_INFO, "send[EAP-SIM DB UNIX]: %s", 872cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt strerror(errno)); 8738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (_errno == ENOTCONN || _errno == EDESTADDRREQ || _errno == EINVAL || 8768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt _errno == ECONNREFUSED) { 8778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Try to reconnect */ 8788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_sim_db_close_socket(data); 8798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (eap_sim_db_open_socket(data) < 0) 8808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 8818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SIM DB: Reconnected to the " 8828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "external server"); 8838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (send(data->sock, msg, len, 0) < 0) { 884cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_printf(MSG_INFO, "send[EAP-SIM DB UNIX]: %s", 885cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt strerror(errno)); 8868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 8878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 8918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 8928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 894d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtstatic void eap_sim_db_expire_pending(struct eap_sim_db_data *data, 895d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt struct eap_sim_db_pending *entry) 8968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 897d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt eloop_register_timeout(data->eap_sim_db_timeout, 0, 898d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt eap_sim_db_query_timeout, data, entry); 8998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 9008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 9038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_sim_db_get_gsm_triplets - Get GSM triplets 9044530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt * @data: Private data pointer from eap_sim_db_init() 9054530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt * @username: Permanent username (prefix | IMSI) 9068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @max_chal: Maximum number of triplets 9078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @_rand: Buffer for RAND values 9088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @kc: Buffer for Kc values 9098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sres: Buffer for SRES values 9108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @cb_session_ctx: Session callback context for get_complete_cb() 9118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: Number of triplets received (has to be less than or equal to 9128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * max_chal), -1 (EAP_SIM_DB_FAILURE) on error (e.g., user not found), or 9138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * -2 (EAP_SIM_DB_PENDING) if results are not yet available. In this case, the 9148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * callback function registered with eap_sim_db_init() will be called once the 9158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * results become available. 9168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 9178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * When using an external server for GSM triplets, this function can always 9188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * start a request and return EAP_SIM_DB_PENDING immediately if authentication 9198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * triplets are not available. Once the triplets are received, callback 9208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * function registered with eap_sim_db_init() is called to notify EAP state 9218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * machine to reprocess the message. This eap_sim_db_get_gsm_triplets() 9228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * function will then be called again and the newly received triplets will then 9238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * be given to the caller. 9248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 9254530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidtint eap_sim_db_get_gsm_triplets(struct eap_sim_db_data *data, 9264530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt const char *username, int max_chal, 9278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *_rand, u8 *kc, u8 *sres, 9288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void *cb_session_ctx) 9298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 9308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_sim_db_pending *entry; 9318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int len, ret; 9328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char msg[40]; 9334530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt const char *imsi; 9344530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt size_t imsi_len; 9358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9364530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (username == NULL || username[0] != EAP_SIM_PERMANENT_PREFIX || 9374530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt username[1] == '\0' || os_strlen(username) > sizeof(entry->imsi)) { 9384530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SIM DB: unexpected username '%s'", 9394530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt username); 9408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return EAP_SIM_DB_FAILURE; 9418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9424530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt imsi = username + 1; 9434530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SIM DB: Get GSM triplets for IMSI '%s'", 9444530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt imsi); 9458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9464530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt entry = eap_sim_db_get_pending(data, imsi, 0); 9478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (entry) { 9488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int num_chal; 9498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (entry->state == FAILURE) { 9508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SIM DB: Pending entry -> " 9518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "failure"); 952d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt eap_sim_db_free_pending(data, entry); 9538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return EAP_SIM_DB_FAILURE; 9548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (entry->state == PENDING) { 9578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SIM DB: Pending entry -> " 9588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "still pending"); 9598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_sim_db_add_pending(data, entry); 9608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return EAP_SIM_DB_PENDING; 9618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SIM DB: Pending entry -> " 9648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "%d challenges", entry->u.sim.num_chal); 9658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt num_chal = entry->u.sim.num_chal; 9668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (num_chal > max_chal) 9678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt num_chal = max_chal; 9688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(_rand, entry->u.sim.rand, num_chal * GSM_RAND_LEN); 9698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(sres, entry->u.sim.sres, 9708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt num_chal * EAP_SIM_SRES_LEN); 9718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(kc, entry->u.sim.kc, num_chal * EAP_SIM_KC_LEN); 972d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt eap_sim_db_free_pending(data, entry); 9738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return num_chal; 9748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data->sock < 0) { 9778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (eap_sim_db_open_socket(data) < 0) 9788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return EAP_SIM_DB_FAILURE; 9798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9814530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt imsi_len = os_strlen(imsi); 9828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = os_snprintf(msg, sizeof(msg), "SIM-REQ-AUTH "); 983fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt if (os_snprintf_error(sizeof(msg), len) || 984fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt len + imsi_len >= sizeof(msg)) 9858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return EAP_SIM_DB_FAILURE; 9864530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt os_memcpy(msg + len, imsi, imsi_len); 9874530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt len += imsi_len; 9888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = os_snprintf(msg + len, sizeof(msg) - len, " %d", max_chal); 989fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt if (os_snprintf_error(sizeof(msg) - len, ret)) 9908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return EAP_SIM_DB_FAILURE; 9918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len += ret; 9928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9934530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SIM DB: requesting SIM authentication " 9944530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt "data for IMSI '%s'", imsi); 9958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (eap_sim_db_send(data, msg, len) < 0) 9968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return EAP_SIM_DB_FAILURE; 9978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt entry = os_zalloc(sizeof(*entry)); 9998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (entry == NULL) 10008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return EAP_SIM_DB_FAILURE; 10018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10024530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt os_strlcpy(entry->imsi, imsi, sizeof(entry->imsi)); 10038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt entry->cb_session_ctx = cb_session_ctx; 10048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt entry->state = PENDING; 10058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_sim_db_add_pending(data, entry); 1006d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt eap_sim_db_expire_pending(data, entry); 1007d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SIM DB: Added query %p", entry); 10088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return EAP_SIM_DB_PENDING; 10108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 10118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic char * eap_sim_db_get_next(struct eap_sim_db_data *data, char prefix) 10148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 10158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *id, *pos, *end; 10168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 buf[10]; 10178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (random_get_bytes(buf, sizeof(buf))) 10198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 10208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt id = os_malloc(sizeof(buf) * 2 + 2); 10218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (id == NULL) 10228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 10238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = id; 10258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt end = id + sizeof(buf) * 2 + 2; 10268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos++ = prefix; 1027fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt wpa_snprintf_hex(pos, end - pos, buf, sizeof(buf)); 10288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return id; 10308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 10318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 10348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_sim_db_get_next_pseudonym - EAP-SIM DB: Get next pseudonym 10354530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt * @data: Private data pointer from eap_sim_db_init() 103604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * @method: EAP method (SIM/AKA/AKA') 10378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: Next pseudonym (allocated string) or %NULL on failure 10388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 10398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function is used to generate a pseudonym for EAP-SIM. The returned 10408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * pseudonym is not added to database at this point; it will need to be added 10418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * with eap_sim_db_add_pseudonym() once the authentication has been completed 10428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * successfully. Caller is responsible for freeing the returned buffer. 10438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 10444530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidtchar * eap_sim_db_get_next_pseudonym(struct eap_sim_db_data *data, 10454530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt enum eap_sim_db_method method) 10468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 104704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt char prefix = EAP_SIM_REAUTH_ID_PREFIX; 104804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 104904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt switch (method) { 105004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt case EAP_SIM_DB_SIM: 105104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt prefix = EAP_SIM_PSEUDONYM_PREFIX; 105204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt break; 105304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt case EAP_SIM_DB_AKA: 105404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt prefix = EAP_AKA_PSEUDONYM_PREFIX; 105504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt break; 105604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt case EAP_SIM_DB_AKA_PRIME: 105704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt prefix = EAP_AKA_PRIME_PSEUDONYM_PREFIX; 105804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt break; 105904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 106004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 106104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return eap_sim_db_get_next(data, prefix); 10628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 10638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 10668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_sim_db_get_next_reauth_id - EAP-SIM DB: Get next reauth_id 10674530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt * @data: Private data pointer from eap_sim_db_init() 106804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * @method: EAP method (SIM/AKA/AKA') 10698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: Next reauth_id (allocated string) or %NULL on failure 10708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 10718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function is used to generate a fast re-authentication identity for 10728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * EAP-SIM. The returned reauth_id is not added to database at this point; it 10738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * will need to be added with eap_sim_db_add_reauth() once the authentication 10748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * has been completed successfully. Caller is responsible for freeing the 10758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * returned buffer. 10768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 10774530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidtchar * eap_sim_db_get_next_reauth_id(struct eap_sim_db_data *data, 10784530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt enum eap_sim_db_method method) 10798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 108004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt char prefix = EAP_SIM_REAUTH_ID_PREFIX; 108104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 108204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt switch (method) { 108304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt case EAP_SIM_DB_SIM: 108404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt prefix = EAP_SIM_REAUTH_ID_PREFIX; 108504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt break; 108604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt case EAP_SIM_DB_AKA: 108704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt prefix = EAP_AKA_REAUTH_ID_PREFIX; 108804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt break; 108904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt case EAP_SIM_DB_AKA_PRIME: 109004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt prefix = EAP_AKA_PRIME_REAUTH_ID_PREFIX; 109104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt break; 109204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 109304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 109404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return eap_sim_db_get_next(data, prefix); 10958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 10968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 10998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_sim_db_add_pseudonym - EAP-SIM DB: Add new pseudonym 11004530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt * @data: Private data pointer from eap_sim_db_init() 11014530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt * @permanent: Permanent username 11028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @pseudonym: Pseudonym for this user. This needs to be an allocated buffer, 11038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * e.g., return value from eap_sim_db_get_next_pseudonym(). Caller must not 11048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * free it. 11058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 on success, -1 on failure 11068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 11078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function adds a new pseudonym for EAP-SIM user. EAP-SIM DB is 11088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * responsible of freeing pseudonym buffer once it is not needed anymore. 11098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 11104530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidtint eap_sim_db_add_pseudonym(struct eap_sim_db_data *data, 11114530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt const char *permanent, char *pseudonym) 11128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 11138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_sim_pseudonym *p; 11144530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SIM DB: Add pseudonym '%s' for permanent " 11154530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt "username '%s'", pseudonym, permanent); 11168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* TODO: could store last two pseudonyms */ 11184530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt#ifdef CONFIG_SQLITE 11194530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (data->sqlite_db) 11204530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt return db_add_pseudonym(data, permanent, pseudonym); 11214530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt#endif /* CONFIG_SQLITE */ 11224530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt for (p = data->pseudonyms; p; p = p->next) { 11234530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (os_strcmp(permanent, p->permanent) == 0) 11244530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt break; 11254530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt } 11268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p) { 11278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SIM DB: Replacing previous " 11288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "pseudonym: %s", p->pseudonym); 11298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(p->pseudonym); 11308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p->pseudonym = pseudonym; 11318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 11328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p = os_zalloc(sizeof(*p)); 11358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p == NULL) { 11368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(pseudonym); 11378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 11388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p->next = data->pseudonyms; 11414530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt p->permanent = os_strdup(permanent); 11424530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (p->permanent == NULL) { 11438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(p); 11448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(pseudonym); 11458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 11468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p->pseudonym = pseudonym; 11488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->pseudonyms = p; 11498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SIM DB: Added new pseudonym entry"); 11518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 11528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 11538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct eap_sim_reauth * 11564530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidteap_sim_db_add_reauth_data(struct eap_sim_db_data *data, 11574530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt const char *permanent, 11584530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt char *reauth_id, u16 counter) 11598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 11608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_sim_reauth *r; 11618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11624530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt for (r = data->reauths; r; r = r->next) { 11634530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (os_strcmp(r->permanent, permanent) == 0) 11644530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt break; 11654530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt } 11668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (r) { 11688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SIM DB: Replacing previous " 11698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "reauth_id: %s", r->reauth_id); 11708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(r->reauth_id); 11718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt r->reauth_id = reauth_id; 11728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 11738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt r = os_zalloc(sizeof(*r)); 11748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (r == NULL) { 11758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(reauth_id); 11768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 11778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt r->next = data->reauths; 11804530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt r->permanent = os_strdup(permanent); 11814530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (r->permanent == NULL) { 11828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(r); 11838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(reauth_id); 11848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 11858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt r->reauth_id = reauth_id; 11878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->reauths = r; 11888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SIM DB: Added new reauth entry"); 11898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt r->counter = counter; 11928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return r; 11948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 11958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 11988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_sim_db_add_reauth - EAP-SIM DB: Add new re-authentication entry 11998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @priv: Private data pointer from eap_sim_db_init() 12004530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt * @permanent: Permanent username 12018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @identity_len: Length of identity 12028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @reauth_id: reauth_id for this user. This needs to be an allocated buffer, 12038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * e.g., return value from eap_sim_db_get_next_reauth_id(). Caller must not 12048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * free it. 12058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @counter: AT_COUNTER value for fast re-authentication 12068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @mk: 16-byte MK from the previous full authentication or %NULL 12078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 on success, -1 on failure 12088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 12098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function adds a new re-authentication entry for an EAP-SIM user. 12108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * EAP-SIM DB is responsible of freeing reauth_id buffer once it is not needed 12118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * anymore. 12128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 12134530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidtint eap_sim_db_add_reauth(struct eap_sim_db_data *data, const char *permanent, 12144530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt char *reauth_id, u16 counter, const u8 *mk) 12158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 12168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_sim_reauth *r; 12178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12184530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SIM DB: Add reauth_id '%s' for permanent " 12194530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt "identity '%s'", reauth_id, permanent); 12204530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 12214530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt#ifdef CONFIG_SQLITE 12224530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (data->sqlite_db) 12234530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt return db_add_reauth(data, permanent, reauth_id, counter, mk, 12244530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt NULL, NULL, NULL); 12254530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt#endif /* CONFIG_SQLITE */ 12264530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt r = eap_sim_db_add_reauth_data(data, permanent, reauth_id, counter); 12278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (r == NULL) 12288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 12298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(r->mk, mk, EAP_SIM_MK_LEN); 12318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 12338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 12348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef EAP_SERVER_AKA_PRIME 12378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 12388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_sim_db_add_reauth_prime - EAP-AKA' DB: Add new re-authentication entry 12394530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt * @data: Private data pointer from eap_sim_db_init() 12404530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt * @permanent: Permanent username 12418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @reauth_id: reauth_id for this user. This needs to be an allocated buffer, 12428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * e.g., return value from eap_sim_db_get_next_reauth_id(). Caller must not 12438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * free it. 12448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @counter: AT_COUNTER value for fast re-authentication 12458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @k_encr: K_encr from the previous full authentication 12468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @k_aut: K_aut from the previous full authentication 12478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @k_re: 32-byte K_re from the previous full authentication 12488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 on success, -1 on failure 12498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 12508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function adds a new re-authentication entry for an EAP-AKA' user. 12518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * EAP-SIM DB is responsible of freeing reauth_id buffer once it is not needed 12528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * anymore. 12538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 12544530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidtint eap_sim_db_add_reauth_prime(struct eap_sim_db_data *data, 12554530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt const char *permanent, char *reauth_id, 12564530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt u16 counter, const u8 *k_encr, 12574530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt const u8 *k_aut, const u8 *k_re) 12588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 12598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_sim_reauth *r; 12608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12614530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SIM DB: Add reauth_id '%s' for permanent " 12624530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt "identity '%s'", reauth_id, permanent); 12634530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 12644530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt#ifdef CONFIG_SQLITE 12654530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (data->sqlite_db) 12664530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt return db_add_reauth(data, permanent, reauth_id, counter, NULL, 12674530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt k_encr, k_aut, k_re); 12684530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt#endif /* CONFIG_SQLITE */ 12694530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt r = eap_sim_db_add_reauth_data(data, permanent, reauth_id, counter); 12708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (r == NULL) 12718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 12728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(r->k_encr, k_encr, EAP_SIM_K_ENCR_LEN); 12748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(r->k_aut, k_aut, EAP_AKA_PRIME_K_AUT_LEN); 12758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(r->k_re, k_re, EAP_AKA_PRIME_K_RE_LEN); 12768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 12788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 12798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* EAP_SERVER_AKA_PRIME */ 12808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 12838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_sim_db_get_permanent - EAP-SIM DB: Get permanent identity 12844530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt * @data: Private data pointer from eap_sim_db_init() 12854530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt * @pseudonym: Pseudonym username 12864530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt * Returns: Pointer to permanent username or %NULL if not found 12878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 12884530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidtconst char * 12894530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidteap_sim_db_get_permanent(struct eap_sim_db_data *data, const char *pseudonym) 12908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 12918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_sim_pseudonym *p; 12928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12934530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt#ifdef CONFIG_SQLITE 12944530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (data->sqlite_db) 12954530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt return db_get_pseudonym(data, pseudonym); 12964530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt#endif /* CONFIG_SQLITE */ 12978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12984530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt p = data->pseudonyms; 12994530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt while (p) { 13004530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (os_strcmp(p->pseudonym, pseudonym) == 0) 13014530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt return p->permanent; 13024530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt p = p->next; 13034530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt } 13048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13054530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt return NULL; 13068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 13078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 13108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_sim_db_get_reauth_entry - EAP-SIM DB: Get re-authentication entry 13114530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt * @data: Private data pointer from eap_sim_db_init() 13124530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt * @reauth_id: Fast re-authentication username 13138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: Pointer to the re-auth entry, or %NULL if not found 13148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 13158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct eap_sim_reauth * 13164530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidteap_sim_db_get_reauth_entry(struct eap_sim_db_data *data, 13174530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt const char *reauth_id) 13188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 13198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_sim_reauth *r; 13208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13214530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt#ifdef CONFIG_SQLITE 13224530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (data->sqlite_db) 13234530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt return db_get_reauth(data, reauth_id); 13244530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt#endif /* CONFIG_SQLITE */ 13254530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 13264530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt r = data->reauths; 13274530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt while (r) { 13284530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (os_strcmp(r->reauth_id, reauth_id) == 0) 13294530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt break; 13304530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt r = r->next; 13314530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt } 13324530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 13338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return r; 13348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 13358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 13388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_sim_db_remove_reauth - EAP-SIM DB: Remove re-authentication entry 13394530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt * @data: Private data pointer from eap_sim_db_init() 13408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @reauth: Pointer to re-authentication entry from 13418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_sim_db_get_reauth_entry() 13428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 13434530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidtvoid eap_sim_db_remove_reauth(struct eap_sim_db_data *data, 13444530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt struct eap_sim_reauth *reauth) 13458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 13468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_sim_reauth *r, *prev = NULL; 13474530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt#ifdef CONFIG_SQLITE 13484530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (data->sqlite_db) { 13494530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt db_remove_reauth(data, reauth); 13504530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt return; 13514530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt } 13524530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt#endif /* CONFIG_SQLITE */ 13538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt r = data->reauths; 13548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (r) { 13558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (r == reauth) { 13568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (prev) 13578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt prev->next = r->next; 13588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 13598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->reauths = r->next; 13608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_sim_db_free_reauth(r); 13618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 13628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt prev = r; 13648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt r = r->next; 13658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 13678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 13708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_sim_db_get_aka_auth - Get AKA authentication values 13714530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt * @data: Private data pointer from eap_sim_db_init() 13724530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt * @username: Permanent username (prefix | IMSI) 13738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @_rand: Buffer for RAND value 13748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @autn: Buffer for AUTN value 13758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @ik: Buffer for IK value 13768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @ck: Buffer for CK value 13778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @res: Buffer for RES value 13788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @res_len: Buffer for RES length 13798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @cb_session_ctx: Session callback context for get_complete_cb() 13808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 on success, -1 (EAP_SIM_DB_FAILURE) on error (e.g., user not 13818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * found), or -2 (EAP_SIM_DB_PENDING) if results are not yet available. In this 13828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * case, the callback function registered with eap_sim_db_init() will be 13838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * called once the results become available. 13848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 13858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * When using an external server for AKA authentication, this function can 13868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * always start a request and return EAP_SIM_DB_PENDING immediately if 13878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * authentication triplets are not available. Once the authentication data are 13888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * received, callback function registered with eap_sim_db_init() is called to 13898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * notify EAP state machine to reprocess the message. This 13908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_sim_db_get_aka_auth() function will then be called again and the newly 13918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * received triplets will then be given to the caller. 13928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 13934530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidtint eap_sim_db_get_aka_auth(struct eap_sim_db_data *data, const char *username, 13944530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt u8 *_rand, u8 *autn, u8 *ik, u8 *ck, 13954530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt u8 *res, size_t *res_len, void *cb_session_ctx) 13968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 13978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_sim_db_pending *entry; 13988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int len; 13998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char msg[40]; 14004530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt const char *imsi; 14014530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt size_t imsi_len; 14028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14034530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (username == NULL || 14044530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt (username[0] != EAP_AKA_PERMANENT_PREFIX && 14054530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt username[0] != EAP_AKA_PRIME_PERMANENT_PREFIX) || 14064530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt username[1] == '\0' || os_strlen(username) > sizeof(entry->imsi)) { 14074530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SIM DB: unexpected username '%s'", 14084530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt username); 14098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return EAP_SIM_DB_FAILURE; 14108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 14114530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt imsi = username + 1; 14124530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SIM DB: Get AKA auth for IMSI '%s'", 14134530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt imsi); 14148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14154530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt entry = eap_sim_db_get_pending(data, imsi, 1); 14168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (entry) { 14178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (entry->state == FAILURE) { 1418d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt eap_sim_db_free_pending(data, entry); 14198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SIM DB: Failure"); 14208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return EAP_SIM_DB_FAILURE; 14218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 14228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (entry->state == PENDING) { 14248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_sim_db_add_pending(data, entry); 14258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SIM DB: Pending"); 14268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return EAP_SIM_DB_PENDING; 14278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 14288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SIM DB: Returning successfully " 14308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "received authentication data"); 14318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(_rand, entry->u.aka.rand, EAP_AKA_RAND_LEN); 14328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(autn, entry->u.aka.autn, EAP_AKA_AUTN_LEN); 14338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(ik, entry->u.aka.ik, EAP_AKA_IK_LEN); 14348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(ck, entry->u.aka.ck, EAP_AKA_CK_LEN); 14358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(res, entry->u.aka.res, EAP_AKA_RES_MAX_LEN); 14368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *res_len = entry->u.aka.res_len; 1437d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt eap_sim_db_free_pending(data, entry); 14388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 14398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 14408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data->sock < 0) { 14428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (eap_sim_db_open_socket(data) < 0) 14438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return EAP_SIM_DB_FAILURE; 14448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 14458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14464530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt imsi_len = os_strlen(imsi); 14478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = os_snprintf(msg, sizeof(msg), "AKA-REQ-AUTH "); 1448fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt if (os_snprintf_error(sizeof(msg), len) || 1449fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt len + imsi_len >= sizeof(msg)) 14508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return EAP_SIM_DB_FAILURE; 14514530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt os_memcpy(msg + len, imsi, imsi_len); 14524530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt len += imsi_len; 14538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14544530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SIM DB: requesting AKA authentication " 14554530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt "data for IMSI '%s'", imsi); 14568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (eap_sim_db_send(data, msg, len) < 0) 14578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return EAP_SIM_DB_FAILURE; 14588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt entry = os_zalloc(sizeof(*entry)); 14608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (entry == NULL) 14618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return EAP_SIM_DB_FAILURE; 14628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt entry->aka = 1; 14644530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt os_strlcpy(entry->imsi, imsi, sizeof(entry->imsi)); 14658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt entry->cb_session_ctx = cb_session_ctx; 14668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt entry->state = PENDING; 14678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_sim_db_add_pending(data, entry); 1468d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt eap_sim_db_expire_pending(data, entry); 1469d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SIM DB: Added query %p", entry); 14708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return EAP_SIM_DB_PENDING; 14728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 14738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 14768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_sim_db_resynchronize - Resynchronize AKA AUTN 14774530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt * @data: Private data pointer from eap_sim_db_init() 14784530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt * @username: Permanent username 14798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @auts: AUTS value from the peer 14808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @_rand: RAND value used in the rejected message 14818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 on success, -1 on failure 14828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 14838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function is called when the peer reports synchronization failure in the 14848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * AUTN value by sending AUTS. The AUTS and RAND values should be sent to 14858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * HLR/AuC to allow it to resynchronize with the peer. After this, 14868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_sim_db_get_aka_auth() will be called again to to fetch updated 14878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * RAND/AUTN values for the next challenge. 14888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 14894530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidtint eap_sim_db_resynchronize(struct eap_sim_db_data *data, 14904530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt const char *username, 14914530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt const u8 *auts, const u8 *_rand) 14928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 14934530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt const char *imsi; 14944530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt size_t imsi_len; 14958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14964530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (username == NULL || 14974530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt (username[0] != EAP_AKA_PERMANENT_PREFIX && 14984530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt username[0] != EAP_AKA_PRIME_PERMANENT_PREFIX) || 14994530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt username[1] == '\0' || os_strlen(username) > 20) { 15004530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SIM DB: unexpected username '%s'", 15014530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt username); 15028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 15038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 15044530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt imsi = username + 1; 15054530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SIM DB: Get AKA auth for IMSI '%s'", 15064530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt imsi); 15078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data->sock >= 0) { 15098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char msg[100]; 15108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int len, ret; 15118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15124530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt imsi_len = os_strlen(imsi); 15138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = os_snprintf(msg, sizeof(msg), "AKA-AUTS "); 1514fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt if (os_snprintf_error(sizeof(msg), len) || 1515fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt len + imsi_len >= sizeof(msg)) 15168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 15174530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt os_memcpy(msg + len, imsi, imsi_len); 15184530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt len += imsi_len; 15198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = os_snprintf(msg + len, sizeof(msg) - len, " "); 1521fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt if (os_snprintf_error(sizeof(msg) - len, ret)) 15228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 15238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len += ret; 15248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len += wpa_snprintf_hex(msg + len, sizeof(msg) - len, 15258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt auts, EAP_AKA_AUTS_LEN); 15268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = os_snprintf(msg + len, sizeof(msg) - len, " "); 1527fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt if (os_snprintf_error(sizeof(msg) - len, ret)) 15288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 15298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len += ret; 15308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len += wpa_snprintf_hex(msg + len, sizeof(msg) - len, 15318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt _rand, EAP_AKA_RAND_LEN); 15324530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SIM DB: reporting AKA AUTS for " 15334530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt "IMSI '%s'", imsi); 15348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (eap_sim_db_send(data, msg, len) < 0) 15358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 15368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 15378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 15398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 15404530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 15414530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 15424530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt/** 15434530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt * sim_get_username - Extract username from SIM identity 15444530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt * @identity: Identity 15454530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt * @identity_len: Identity length 15464530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt * Returns: Allocated buffer with the username part of the identity 15474530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt * 15484530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt * Caller is responsible for freeing the returned buffer with os_free(). 15494530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt */ 15504530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidtchar * sim_get_username(const u8 *identity, size_t identity_len) 15514530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt{ 15524530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt size_t pos; 15534530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 15544530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (identity == NULL) 15554530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt return NULL; 15564530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 15574530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt for (pos = 0; pos < identity_len; pos++) { 15584530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (identity[pos] == '@' || identity[pos] == '\0') 15594530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt break; 15604530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt } 15614530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 15624b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt return dup_binstr(identity, pos); 15634530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt} 1564