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; 694530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt#ifdef CONFIG_SQLITE 704530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt sqlite3 *sqlite_db; 714530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt char db_tmp_identity[100]; 724530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt char db_tmp_pseudonym_str[100]; 734530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt struct eap_sim_pseudonym db_tmp_pseudonym; 744530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt struct eap_sim_reauth db_tmp_reauth; 754530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt#endif /* CONFIG_SQLITE */ 768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}; 778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 794530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt#ifdef CONFIG_SQLITE 804530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 814530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidtstatic int db_table_exists(sqlite3 *db, const char *name) 824530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt{ 834530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt char cmd[128]; 844530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt os_snprintf(cmd, sizeof(cmd), "SELECT 1 FROM %s;", name); 854530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt return sqlite3_exec(db, cmd, NULL, NULL, NULL) == SQLITE_OK; 864530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt} 874530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 884530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 894530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidtstatic int db_table_create_pseudonym(sqlite3 *db) 904530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt{ 914530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt char *err = NULL; 924530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt const char *sql = 934530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt "CREATE TABLE pseudonyms(" 944530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt " permanent CHAR(21) PRIMARY KEY," 954530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt " pseudonym CHAR(21) NOT NULL" 964530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt ");"; 974530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 984530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SIM DB: Adding database table for " 994530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt "pseudonym information"); 1004530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (sqlite3_exec(db, sql, NULL, NULL, &err) != SQLITE_OK) { 1014530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt wpa_printf(MSG_ERROR, "EAP-SIM DB: SQLite error: %s", err); 1024530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt sqlite3_free(err); 1034530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt return -1; 1044530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt } 1054530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 1064530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt return 0; 1074530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt} 1084530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 1094530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 1104530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidtstatic int db_table_create_reauth(sqlite3 *db) 1114530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt{ 1124530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt char *err = NULL; 1134530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt const char *sql = 1144530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt "CREATE TABLE reauth(" 1154530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt " permanent CHAR(21) PRIMARY KEY," 1164530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt " reauth_id CHAR(21) NOT NULL," 1174530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt " counter INTEGER," 1184530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt " mk CHAR(40)," 1194530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt " k_encr CHAR(32)," 1204530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt " k_aut CHAR(64)," 1214530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt " k_re CHAR(64)" 1224530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt ");"; 1234530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 1244530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SIM DB: Adding database table for " 1254530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt "reauth information"); 1264530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (sqlite3_exec(db, sql, NULL, NULL, &err) != SQLITE_OK) { 1274530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt wpa_printf(MSG_ERROR, "EAP-SIM DB: SQLite error: %s", err); 1284530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt sqlite3_free(err); 1294530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt return -1; 1304530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt } 1314530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 1324530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt return 0; 1334530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt} 1344530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 1354530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 1364530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidtstatic sqlite3 * db_open(const char *db_file) 1374530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt{ 1384530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt sqlite3 *db; 1394530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 1404530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (sqlite3_open(db_file, &db)) { 1414530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt wpa_printf(MSG_ERROR, "EAP-SIM DB: Failed to open database " 1424530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt "%s: %s", db_file, sqlite3_errmsg(db)); 1434530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt sqlite3_close(db); 1444530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt return NULL; 1454530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt } 1464530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 1474530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (!db_table_exists(db, "pseudonyms") && 1484530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt db_table_create_pseudonym(db) < 0) { 1494530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt sqlite3_close(db); 1504530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt return NULL; 1514530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt } 1524530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 1534530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (!db_table_exists(db, "reauth") && 1544530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt db_table_create_reauth(db) < 0) { 1554530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt sqlite3_close(db); 1564530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt return NULL; 1574530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt } 1584530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 1594530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt return db; 1604530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt} 1614530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 1624530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 1634530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidtstatic int valid_db_string(const char *str) 1644530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt{ 1654530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt const char *pos = str; 1664530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt while (*pos) { 1674530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if ((*pos < '0' || *pos > '9') && 1684530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt (*pos < 'a' || *pos > 'f')) 1694530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt return 0; 1704530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt pos++; 1714530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt } 1724530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt return 1; 1734530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt} 1744530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 1754530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 1764530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidtstatic int db_add_pseudonym(struct eap_sim_db_data *data, 1774530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt const char *permanent, char *pseudonym) 1784530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt{ 1794530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt char cmd[128]; 1804530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt char *err = NULL; 1814530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 1824530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (!valid_db_string(permanent) || !valid_db_string(pseudonym)) { 1834530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt os_free(pseudonym); 1844530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt return -1; 1854530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt } 1864530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 1874530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt os_snprintf(cmd, sizeof(cmd), "INSERT OR REPLACE INTO pseudonyms " 1884530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt "(permanent, pseudonym) VALUES ('%s', '%s');", 1894530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt permanent, pseudonym); 1904530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt os_free(pseudonym); 1914530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (sqlite3_exec(data->sqlite_db, cmd, NULL, NULL, &err) != SQLITE_OK) 1924530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt { 1934530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt wpa_printf(MSG_ERROR, "EAP-SIM DB: SQLite error: %s", err); 1944530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt sqlite3_free(err); 1954530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt return -1; 1964530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt } 1974530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 1984530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt return 0; 1994530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt} 2004530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 2014530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 2024530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidtstatic int get_pseudonym_cb(void *ctx, int argc, char *argv[], char *col[]) 2034530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt{ 2044530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt struct eap_sim_db_data *data = ctx; 2054530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt int i; 2064530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 2074530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt for (i = 0; i < argc; i++) { 2084530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (os_strcmp(col[i], "permanent") == 0 && argv[i]) { 2094530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt os_strlcpy(data->db_tmp_identity, argv[i], 2104530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt sizeof(data->db_tmp_identity)); 2114530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt } 2124530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt } 2134530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 2144530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt return 0; 2154530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt} 2164530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 2174530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 2184530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidtstatic char * 2194530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidtdb_get_pseudonym(struct eap_sim_db_data *data, const char *pseudonym) 2204530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt{ 2214530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt char cmd[128]; 2224530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 2234530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (!valid_db_string(pseudonym)) 2244530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt return NULL; 2254530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt os_memset(&data->db_tmp_identity, 0, sizeof(data->db_tmp_identity)); 2264530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt os_snprintf(cmd, sizeof(cmd), 2274530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt "SELECT permanent FROM pseudonyms WHERE pseudonym='%s';", 2284530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt pseudonym); 2294530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (sqlite3_exec(data->sqlite_db, cmd, get_pseudonym_cb, data, NULL) != 2304530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt SQLITE_OK) 2314530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt return NULL; 2324530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (data->db_tmp_identity[0] == '\0') 2334530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt return NULL; 2344530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt return data->db_tmp_identity; 2354530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt} 2364530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 2374530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 2384530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidtstatic int db_add_reauth(struct eap_sim_db_data *data, const char *permanent, 2394530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt char *reauth_id, u16 counter, const u8 *mk, 2404530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt const u8 *k_encr, const u8 *k_aut, const u8 *k_re) 2414530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt{ 2424530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt char cmd[2000], *pos, *end; 2434530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt char *err = NULL; 2444530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 2454530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (!valid_db_string(permanent) || !valid_db_string(reauth_id)) { 2464530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt os_free(reauth_id); 2474530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt return -1; 2484530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt } 2494530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 2504530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt pos = cmd; 2514530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt end = pos + sizeof(cmd); 2524530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt pos += os_snprintf(pos, end - pos, "INSERT OR REPLACE INTO reauth " 2534530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt "(permanent, reauth_id, counter%s%s%s%s) " 2544530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt "VALUES ('%s', '%s', %u", 2554530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt mk ? ", mk" : "", 2564530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt k_encr ? ", k_encr" : "", 2574530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt k_aut ? ", k_aut" : "", 2584530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt k_re ? ", k_re" : "", 2594530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt permanent, reauth_id, counter); 2604530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt os_free(reauth_id); 2614530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 2624530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (mk) { 2634530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt pos += os_snprintf(pos, end - pos, ", '"); 2644530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt pos += wpa_snprintf_hex(pos, end - pos, mk, EAP_SIM_MK_LEN); 2654530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt pos += os_snprintf(pos, end - pos, "'"); 2664530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt } 2674530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 2684530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (k_encr) { 2694530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt pos += os_snprintf(pos, end - pos, ", '"); 2704530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt pos += wpa_snprintf_hex(pos, end - pos, k_encr, 2714530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt EAP_SIM_K_ENCR_LEN); 2724530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt pos += os_snprintf(pos, end - pos, "'"); 2734530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt } 2744530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 2754530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (k_aut) { 2764530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt pos += os_snprintf(pos, end - pos, ", '"); 2774530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt pos += wpa_snprintf_hex(pos, end - pos, k_aut, 2784530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt EAP_AKA_PRIME_K_AUT_LEN); 2794530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt pos += os_snprintf(pos, end - pos, "'"); 2804530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt } 2814530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 2824530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (k_re) { 2834530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt pos += os_snprintf(pos, end - pos, ", '"); 2844530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt pos += wpa_snprintf_hex(pos, end - pos, k_re, 2854530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt EAP_AKA_PRIME_K_RE_LEN); 2864530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt pos += os_snprintf(pos, end - pos, "'"); 2874530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt } 2884530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 2894530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt os_snprintf(pos, end - pos, ");"); 2904530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 2914530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (sqlite3_exec(data->sqlite_db, cmd, NULL, NULL, &err) != SQLITE_OK) 2924530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt { 2934530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt wpa_printf(MSG_ERROR, "EAP-SIM DB: SQLite error: %s", err); 2944530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt sqlite3_free(err); 2954530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt return -1; 2964530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt } 2974530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 2984530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt return 0; 2994530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt} 3004530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 3014530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 3024530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidtstatic int get_reauth_cb(void *ctx, int argc, char *argv[], char *col[]) 3034530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt{ 3044530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt struct eap_sim_db_data *data = ctx; 3054530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt int i; 3064530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt struct eap_sim_reauth *reauth = &data->db_tmp_reauth; 3074530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 3084530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt for (i = 0; i < argc; i++) { 3094530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (os_strcmp(col[i], "permanent") == 0 && argv[i]) { 3104530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt os_strlcpy(data->db_tmp_identity, argv[i], 3114530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt sizeof(data->db_tmp_identity)); 3124530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt reauth->permanent = data->db_tmp_identity; 3134530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt } else if (os_strcmp(col[i], "counter") == 0 && argv[i]) { 3144530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt reauth->counter = atoi(argv[i]); 3154530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt } else if (os_strcmp(col[i], "mk") == 0 && argv[i]) { 3164530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt hexstr2bin(argv[i], reauth->mk, sizeof(reauth->mk)); 3174530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt } else if (os_strcmp(col[i], "k_encr") == 0 && argv[i]) { 3184530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt hexstr2bin(argv[i], reauth->k_encr, 3194530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt sizeof(reauth->k_encr)); 3204530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt } else if (os_strcmp(col[i], "k_aut") == 0 && argv[i]) { 3214530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt hexstr2bin(argv[i], reauth->k_aut, 3224530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt sizeof(reauth->k_aut)); 3234530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt } else if (os_strcmp(col[i], "k_re") == 0 && argv[i]) { 3244530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt hexstr2bin(argv[i], reauth->k_re, 3254530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt sizeof(reauth->k_re)); 3264530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt } 3274530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt } 3284530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 3294530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt return 0; 3304530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt} 3314530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 3324530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 3334530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidtstatic struct eap_sim_reauth * 3344530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidtdb_get_reauth(struct eap_sim_db_data *data, const char *reauth_id) 3354530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt{ 3364530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt char cmd[256]; 3374530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 3384530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (!valid_db_string(reauth_id)) 3394530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt return NULL; 3404530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt os_memset(&data->db_tmp_reauth, 0, sizeof(data->db_tmp_reauth)); 3414530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt os_strlcpy(data->db_tmp_pseudonym_str, reauth_id, 3424530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt sizeof(data->db_tmp_pseudonym_str)); 3434530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt data->db_tmp_reauth.reauth_id = data->db_tmp_pseudonym_str; 3444530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt os_snprintf(cmd, sizeof(cmd), 3454530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt "SELECT * FROM reauth WHERE reauth_id='%s';", reauth_id); 3464530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (sqlite3_exec(data->sqlite_db, cmd, get_reauth_cb, data, NULL) != 3474530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt SQLITE_OK) 3484530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt return NULL; 3494530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (data->db_tmp_reauth.permanent == NULL) 3504530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt return NULL; 3514530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt return &data->db_tmp_reauth; 3524530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt} 3534530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 3544530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 3554530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidtstatic void db_remove_reauth(struct eap_sim_db_data *data, 3564530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt struct eap_sim_reauth *reauth) 3574530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt{ 3584530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt char cmd[256]; 3594530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 3604530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (!valid_db_string(reauth->permanent)) 3614530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt return; 3624530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt os_snprintf(cmd, sizeof(cmd), 3634530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt "DELETE FROM reauth WHERE permanent='%s';", 3644530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt reauth->permanent); 3654530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt sqlite3_exec(data->sqlite_db, cmd, NULL, NULL, NULL); 3664530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt} 3674530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 3684530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt#endif /* CONFIG_SQLITE */ 3694530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 3704530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 3718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct eap_sim_db_pending * 3724530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidteap_sim_db_get_pending(struct eap_sim_db_data *data, const char *imsi, int aka) 3738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_sim_db_pending *entry, *prev = NULL; 3758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt entry = data->pending; 3778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (entry) { 3784530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (entry->aka == aka && os_strcmp(entry->imsi, imsi) == 0) { 3798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (prev) 3808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt prev->next = entry->next; 3818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 3828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->pending = entry->next; 3838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 3848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt prev = entry; 3868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt entry = entry->next; 3878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return entry; 3898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void eap_sim_db_add_pending(struct eap_sim_db_data *data, 3938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_sim_db_pending *entry) 3948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt entry->next = data->pending; 3968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->pending = entry; 3978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void eap_sim_db_sim_resp_auth(struct eap_sim_db_data *data, 4018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *imsi, char *buf) 4028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *start, *end, *pos; 4048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_sim_db_pending *entry; 4058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int num_chal; 4068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 4088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * SIM-RESP-AUTH <IMSI> Kc(i):SRES(i):RAND(i) ... 4098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * SIM-RESP-AUTH <IMSI> FAILURE 4108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * (IMSI = ASCII string, Kc/SRES/RAND = hex string) 4118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 4128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4134530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt entry = eap_sim_db_get_pending(data, imsi, 0); 4148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (entry == NULL) { 4158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SIM DB: No pending entry for the " 4168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "received message found"); 4178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 4188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt start = buf; 4218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_strncmp(start, "FAILURE", 7) == 0) { 4228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SIM DB: External server reported " 4238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "failure"); 4248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt entry->state = FAILURE; 4258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_sim_db_add_pending(data, entry); 4268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->get_complete_cb(data->ctx, entry->cb_session_ctx); 4278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 4288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt num_chal = 0; 4318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (num_chal < EAP_SIM_MAX_CHAL) { 4328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt end = os_strchr(start, ' '); 4338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (end) 4348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *end = '\0'; 4358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = os_strchr(start, ':'); 4378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pos == NULL) 4388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto parse_fail; 4398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos = '\0'; 4408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hexstr2bin(start, entry->u.sim.kc[num_chal], 4418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt EAP_SIM_KC_LEN)) 4428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto parse_fail; 4438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt start = pos + 1; 4458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = os_strchr(start, ':'); 4468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pos == NULL) 4478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto parse_fail; 4488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos = '\0'; 4498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hexstr2bin(start, entry->u.sim.sres[num_chal], 4508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt EAP_SIM_SRES_LEN)) 4518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto parse_fail; 4528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt start = pos + 1; 4548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hexstr2bin(start, entry->u.sim.rand[num_chal], 4558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt GSM_RAND_LEN)) 4568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto parse_fail; 4578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt num_chal++; 4598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (end == NULL) 4608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 4618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 4628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt start = end + 1; 4638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt entry->u.sim.num_chal = num_chal; 4658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt entry->state = SUCCESS; 4678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SIM DB: Authentication data parsed " 4688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "successfully - callback"); 4698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_sim_db_add_pending(data, entry); 4708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->get_complete_cb(data->ctx, entry->cb_session_ctx); 4718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 4728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtparse_fail: 4748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SIM DB: Failed to parse response string"); 4758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(entry); 4768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void eap_sim_db_aka_resp_auth(struct eap_sim_db_data *data, 4808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *imsi, char *buf) 4818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *start, *end; 4838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_sim_db_pending *entry; 4848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 4868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * AKA-RESP-AUTH <IMSI> <RAND> <AUTN> <IK> <CK> <RES> 4878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * AKA-RESP-AUTH <IMSI> FAILURE 4888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * (IMSI = ASCII string, RAND/AUTN/IK/CK/RES = hex string) 4898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 4908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4914530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt entry = eap_sim_db_get_pending(data, imsi, 1); 4928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (entry == NULL) { 4938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SIM DB: No pending entry for the " 4948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "received message found"); 4958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 4968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt start = buf; 4998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_strncmp(start, "FAILURE", 7) == 0) { 5008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SIM DB: External server reported " 5018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "failure"); 5028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt entry->state = FAILURE; 5038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_sim_db_add_pending(data, entry); 5048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->get_complete_cb(data->ctx, entry->cb_session_ctx); 5058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 5068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt end = os_strchr(start, ' '); 5098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (end == NULL) 5108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto parse_fail; 5118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *end = '\0'; 5128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hexstr2bin(start, entry->u.aka.rand, EAP_AKA_RAND_LEN)) 5138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto parse_fail; 5148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt start = end + 1; 5168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt end = os_strchr(start, ' '); 5178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (end == NULL) 5188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto parse_fail; 5198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *end = '\0'; 5208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hexstr2bin(start, entry->u.aka.autn, EAP_AKA_AUTN_LEN)) 5218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto parse_fail; 5228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt start = end + 1; 5248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt end = os_strchr(start, ' '); 5258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (end == NULL) 5268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto parse_fail; 5278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *end = '\0'; 5288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hexstr2bin(start, entry->u.aka.ik, EAP_AKA_IK_LEN)) 5298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto parse_fail; 5308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt start = end + 1; 5328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt end = os_strchr(start, ' '); 5338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (end == NULL) 5348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto parse_fail; 5358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *end = '\0'; 5368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hexstr2bin(start, entry->u.aka.ck, EAP_AKA_CK_LEN)) 5378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto parse_fail; 5388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt start = end + 1; 5408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt end = os_strchr(start, ' '); 5418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (end) 5428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *end = '\0'; 5438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else { 5448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt end = start; 5458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (*end) 5468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt end++; 5478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt entry->u.aka.res_len = (end - start) / 2; 5498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (entry->u.aka.res_len > EAP_AKA_RES_MAX_LEN) { 5508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SIM DB: Too long RES"); 5518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt entry->u.aka.res_len = 0; 5528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto parse_fail; 5538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hexstr2bin(start, entry->u.aka.res, entry->u.aka.res_len)) 5558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto parse_fail; 5568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt entry->state = SUCCESS; 5588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SIM DB: Authentication data parsed " 5598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "successfully - callback"); 5608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_sim_db_add_pending(data, entry); 5618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->get_complete_cb(data->ctx, entry->cb_session_ctx); 5628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 5638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtparse_fail: 5658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SIM DB: Failed to parse response string"); 5668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(entry); 5678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 5688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void eap_sim_db_receive(int sock, void *eloop_ctx, void *sock_ctx) 5718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 5728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_sim_db_data *data = eloop_ctx; 5738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char buf[1000], *pos, *cmd, *imsi; 5748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int res; 5758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = recv(sock, buf, sizeof(buf), 0); 5778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res < 0) 5788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 5798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_ascii_key(MSG_MSGDUMP, "EAP-SIM DB: Received from an " 5808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "external source", (u8 *) buf, res); 5818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res == 0) 5828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 5838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res >= (int) sizeof(buf)) 5848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = sizeof(buf) - 1; 5858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf[res] = '\0'; 5868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data->get_complete_cb == NULL) { 5888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SIM DB: No get_complete_cb " 5898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "registered"); 5908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 5918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* <cmd> <IMSI> ... */ 5948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cmd = buf; 5968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = os_strchr(cmd, ' '); 5978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pos == NULL) 5988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto parse_fail; 5998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos = '\0'; 6008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt imsi = pos + 1; 6018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = os_strchr(imsi, ' '); 6028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pos == NULL) 6038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto parse_fail; 6048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos = '\0'; 6058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SIM DB: External response=%s for IMSI %s", 6068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cmd, imsi); 6078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_strcmp(cmd, "SIM-RESP-AUTH") == 0) 6098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_sim_db_sim_resp_auth(data, imsi, pos + 1); 6108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (os_strcmp(cmd, "AKA-RESP-AUTH") == 0) 6118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_sim_db_aka_resp_auth(data, imsi, pos + 1); 6128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 6138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "EAP-SIM DB: Unknown external response " 6148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "'%s'", cmd); 6158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 6168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtparse_fail: 6188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SIM DB: Failed to parse response string"); 6198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 6208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int eap_sim_db_open_socket(struct eap_sim_db_data *data) 6238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 6248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct sockaddr_un addr; 6258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt static int counter = 0; 6268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_strncmp(data->fname, "unix:", 5) != 0) 6288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 6298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->sock = socket(PF_UNIX, SOCK_DGRAM, 0); 6318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data->sock < 0) { 632cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_printf(MSG_INFO, "socket(eap_sim_db): %s", strerror(errno)); 6338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 6348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&addr, 0, sizeof(addr)); 6378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt addr.sun_family = AF_UNIX; 6388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_snprintf(addr.sun_path, sizeof(addr.sun_path), 6398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "/tmp/eap_sim_db_%d-%d", getpid(), counter++); 64061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt os_free(data->local_sock); 6418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->local_sock = os_strdup(addr.sun_path); 642bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt if (data->local_sock == NULL) { 643bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt close(data->sock); 644bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt data->sock = -1; 645bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt return -1; 646bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt } 6478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (bind(data->sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) { 648cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_printf(MSG_INFO, "bind(eap_sim_db): %s", strerror(errno)); 6498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt close(data->sock); 6508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->sock = -1; 6518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 6528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&addr, 0, sizeof(addr)); 6558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt addr.sun_family = AF_UNIX; 6568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_strlcpy(addr.sun_path, data->fname + 5, sizeof(addr.sun_path)); 6578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (connect(data->sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) { 658cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_printf(MSG_INFO, "connect(eap_sim_db): %s", 659cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt strerror(errno)); 6608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_ascii(MSG_INFO, "HLR/AuC GW socket", 6618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (u8 *) addr.sun_path, 6628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_strlen(addr.sun_path)); 6638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt close(data->sock); 6648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->sock = -1; 665bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt unlink(data->local_sock); 666bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt os_free(data->local_sock); 667bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt data->local_sock = NULL; 6688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 6698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_read_sock(data->sock, eap_sim_db_receive, data, NULL); 6728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 6748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 6758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void eap_sim_db_close_socket(struct eap_sim_db_data *data) 6788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 6798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data->sock >= 0) { 6808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_unregister_read_sock(data->sock); 6818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt close(data->sock); 6828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->sock = -1; 6838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data->local_sock) { 6858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unlink(data->local_sock); 6868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(data->local_sock); 6878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->local_sock = NULL; 6888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 6908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 6938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_sim_db_init - Initialize EAP-SIM DB / authentication gateway interface 6948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @config: Configuration data (e.g., file name) 6958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @get_complete_cb: Callback function for reporting availability of triplets 6968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @ctx: Context pointer for get_complete_cb 6978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: Pointer to a private data structure or %NULL on failure 6988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 6994530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidtstruct eap_sim_db_data * 7004530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidteap_sim_db_init(const char *config, 7014530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt void (*get_complete_cb)(void *ctx, void *session_ctx), 7024530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt void *ctx) 7038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 7048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_sim_db_data *data; 7054530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt char *pos; 7068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data = os_zalloc(sizeof(*data)); 7088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data == NULL) 7098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 7108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->sock = -1; 7128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->get_complete_cb = get_complete_cb; 7138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->ctx = ctx; 7148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->fname = os_strdup(config); 7158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data->fname == NULL) 7168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 7174530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt pos = os_strstr(data->fname, " db="); 7184530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (pos) { 7194530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt *pos = '\0'; 7204530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt#ifdef CONFIG_SQLITE 7214530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt pos += 4; 7224530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt data->sqlite_db = db_open(pos); 7234530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (data->sqlite_db == NULL) 7244530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt goto fail; 7254530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt#endif /* CONFIG_SQLITE */ 7264530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt } 7278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_strncmp(data->fname, "unix:", 5) == 0) { 72961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (eap_sim_db_open_socket(data)) { 73061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SIM DB: External database " 73161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt "connection not available - will retry " 73261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt "later"); 73361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 7348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return data; 7378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtfail: 7398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_sim_db_close_socket(data); 7408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(data->fname); 7418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(data); 7428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 7438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 7448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void eap_sim_db_free_pseudonym(struct eap_sim_pseudonym *p) 7478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 7484530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt os_free(p->permanent); 7498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(p->pseudonym); 7508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(p); 7518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 7528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void eap_sim_db_free_reauth(struct eap_sim_reauth *r) 7558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 7564530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt os_free(r->permanent); 7578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(r->reauth_id); 7588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(r); 7598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 7608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 7638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_sim_db_deinit - Deinitialize EAP-SIM DB/authentication gw interface 7648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @priv: Private data pointer from eap_sim_db_init() 7658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 7668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid eap_sim_db_deinit(void *priv) 7678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 7688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_sim_db_data *data = priv; 7698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_sim_pseudonym *p, *prev; 7708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_sim_reauth *r, *prevr; 7718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_sim_db_pending *pending, *prev_pending; 7728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7734530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt#ifdef CONFIG_SQLITE 7744530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (data->sqlite_db) { 7754530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt sqlite3_close(data->sqlite_db); 7764530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt data->sqlite_db = NULL; 7774530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt } 7784530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt#endif /* CONFIG_SQLITE */ 7794530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 7808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_sim_db_close_socket(data); 7818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(data->fname); 7828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p = data->pseudonyms; 7848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (p) { 7858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt prev = p; 7868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p = p->next; 7878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_sim_db_free_pseudonym(prev); 7888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt r = data->reauths; 7918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (r) { 7928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt prevr = r; 7938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt r = r->next; 7948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_sim_db_free_reauth(prevr); 7958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pending = data->pending; 7988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (pending) { 7998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt prev_pending = pending; 8008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pending = pending->next; 8018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(prev_pending); 8028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(data); 8058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 8068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int eap_sim_db_send(struct eap_sim_db_data *data, const char *msg, 8098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t len) 8108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 8118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int _errno = 0; 8128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (send(data->sock, msg, len, 0) < 0) { 8148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt _errno = errno; 815cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_printf(MSG_INFO, "send[EAP-SIM DB UNIX]: %s", 816cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt strerror(errno)); 8178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (_errno == ENOTCONN || _errno == EDESTADDRREQ || _errno == EINVAL || 8208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt _errno == ECONNREFUSED) { 8218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Try to reconnect */ 8228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_sim_db_close_socket(data); 8238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (eap_sim_db_open_socket(data) < 0) 8248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 8258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SIM DB: Reconnected to the " 8268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "external server"); 8278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (send(data->sock, msg, len, 0) < 0) { 828cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_printf(MSG_INFO, "send[EAP-SIM DB UNIX]: %s", 829cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt strerror(errno)); 8308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 8318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 8358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 8368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void eap_sim_db_expire_pending(struct eap_sim_db_data *data) 8398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 8408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* TODO: add limit for maximum length for pending list; remove latest 8418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * (i.e., last) entry from the list if the limit is reached; could also 8428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * use timeout to expire pending entries */ 8438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 8448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 8478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_sim_db_get_gsm_triplets - Get GSM triplets 8484530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt * @data: Private data pointer from eap_sim_db_init() 8494530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt * @username: Permanent username (prefix | IMSI) 8508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @max_chal: Maximum number of triplets 8518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @_rand: Buffer for RAND values 8528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @kc: Buffer for Kc values 8538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sres: Buffer for SRES values 8548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @cb_session_ctx: Session callback context for get_complete_cb() 8558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: Number of triplets received (has to be less than or equal to 8568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * max_chal), -1 (EAP_SIM_DB_FAILURE) on error (e.g., user not found), or 8578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * -2 (EAP_SIM_DB_PENDING) if results are not yet available. In this case, the 8588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * callback function registered with eap_sim_db_init() will be called once the 8598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * results become available. 8608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 8618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * When using an external server for GSM triplets, this function can always 8628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * start a request and return EAP_SIM_DB_PENDING immediately if authentication 8638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * triplets are not available. Once the triplets are received, callback 8648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * function registered with eap_sim_db_init() is called to notify EAP state 8658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * machine to reprocess the message. This eap_sim_db_get_gsm_triplets() 8668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * function will then be called again and the newly received triplets will then 8678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * be given to the caller. 8688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 8694530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidtint eap_sim_db_get_gsm_triplets(struct eap_sim_db_data *data, 8704530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt const char *username, int max_chal, 8718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *_rand, u8 *kc, u8 *sres, 8728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void *cb_session_ctx) 8738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 8748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_sim_db_pending *entry; 8758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int len, ret; 8768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char msg[40]; 8774530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt const char *imsi; 8784530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt size_t imsi_len; 8798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8804530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (username == NULL || username[0] != EAP_SIM_PERMANENT_PREFIX || 8814530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt username[1] == '\0' || os_strlen(username) > sizeof(entry->imsi)) { 8824530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SIM DB: unexpected username '%s'", 8834530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt username); 8848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return EAP_SIM_DB_FAILURE; 8858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8864530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt imsi = username + 1; 8874530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SIM DB: Get GSM triplets for IMSI '%s'", 8884530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt imsi); 8898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8904530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt entry = eap_sim_db_get_pending(data, imsi, 0); 8918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (entry) { 8928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int num_chal; 8938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (entry->state == FAILURE) { 8948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SIM DB: Pending entry -> " 8958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "failure"); 8968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(entry); 8978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return EAP_SIM_DB_FAILURE; 8988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (entry->state == PENDING) { 9018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SIM DB: Pending entry -> " 9028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "still pending"); 9038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_sim_db_add_pending(data, entry); 9048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return EAP_SIM_DB_PENDING; 9058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SIM DB: Pending entry -> " 9088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "%d challenges", entry->u.sim.num_chal); 9098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt num_chal = entry->u.sim.num_chal; 9108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (num_chal > max_chal) 9118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt num_chal = max_chal; 9128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(_rand, entry->u.sim.rand, num_chal * GSM_RAND_LEN); 9138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(sres, entry->u.sim.sres, 9148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt num_chal * EAP_SIM_SRES_LEN); 9158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(kc, entry->u.sim.kc, num_chal * EAP_SIM_KC_LEN); 9168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(entry); 9178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return num_chal; 9188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data->sock < 0) { 9218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (eap_sim_db_open_socket(data) < 0) 9228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return EAP_SIM_DB_FAILURE; 9238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9254530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt imsi_len = os_strlen(imsi); 9268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = os_snprintf(msg, sizeof(msg), "SIM-REQ-AUTH "); 9274530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (len < 0 || len + imsi_len >= sizeof(msg)) 9288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return EAP_SIM_DB_FAILURE; 9294530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt os_memcpy(msg + len, imsi, imsi_len); 9304530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt len += imsi_len; 9318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = os_snprintf(msg + len, sizeof(msg) - len, " %d", max_chal); 9328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret < 0 || (size_t) ret >= sizeof(msg) - len) 9338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return EAP_SIM_DB_FAILURE; 9348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len += ret; 9358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9364530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SIM DB: requesting SIM authentication " 9374530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt "data for IMSI '%s'", imsi); 9388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (eap_sim_db_send(data, msg, len) < 0) 9398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return EAP_SIM_DB_FAILURE; 9408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt entry = os_zalloc(sizeof(*entry)); 9428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (entry == NULL) 9438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return EAP_SIM_DB_FAILURE; 9448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9454530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt os_strlcpy(entry->imsi, imsi, sizeof(entry->imsi)); 9468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt entry->cb_session_ctx = cb_session_ctx; 9478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt entry->state = PENDING; 9488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_sim_db_add_pending(data, entry); 9498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_sim_db_expire_pending(data); 9508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return EAP_SIM_DB_PENDING; 9528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 9538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic char * eap_sim_db_get_next(struct eap_sim_db_data *data, char prefix) 9568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 9578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *id, *pos, *end; 9588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 buf[10]; 9598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (random_get_bytes(buf, sizeof(buf))) 9618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 9628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt id = os_malloc(sizeof(buf) * 2 + 2); 9638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (id == NULL) 9648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 9658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = id; 9678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt end = id + sizeof(buf) * 2 + 2; 9688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos++ = prefix; 9698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += wpa_snprintf_hex(pos, end - pos, buf, sizeof(buf)); 9708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return id; 9728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 9738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 9768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_sim_db_get_next_pseudonym - EAP-SIM DB: Get next pseudonym 9774530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt * @data: Private data pointer from eap_sim_db_init() 97804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * @method: EAP method (SIM/AKA/AKA') 9798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: Next pseudonym (allocated string) or %NULL on failure 9808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 9818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function is used to generate a pseudonym for EAP-SIM. The returned 9828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * pseudonym is not added to database at this point; it will need to be added 9838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * with eap_sim_db_add_pseudonym() once the authentication has been completed 9848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * successfully. Caller is responsible for freeing the returned buffer. 9858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 9864530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidtchar * eap_sim_db_get_next_pseudonym(struct eap_sim_db_data *data, 9874530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt enum eap_sim_db_method method) 9888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 98904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt char prefix = EAP_SIM_REAUTH_ID_PREFIX; 99004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 99104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt switch (method) { 99204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt case EAP_SIM_DB_SIM: 99304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt prefix = EAP_SIM_PSEUDONYM_PREFIX; 99404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt break; 99504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt case EAP_SIM_DB_AKA: 99604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt prefix = EAP_AKA_PSEUDONYM_PREFIX; 99704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt break; 99804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt case EAP_SIM_DB_AKA_PRIME: 99904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt prefix = EAP_AKA_PRIME_PSEUDONYM_PREFIX; 100004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt break; 100104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 100204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 100304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return eap_sim_db_get_next(data, prefix); 10048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 10058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 10088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_sim_db_get_next_reauth_id - EAP-SIM DB: Get next reauth_id 10094530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt * @data: Private data pointer from eap_sim_db_init() 101004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * @method: EAP method (SIM/AKA/AKA') 10118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: Next reauth_id (allocated string) or %NULL on failure 10128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 10138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function is used to generate a fast re-authentication identity for 10148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * EAP-SIM. The returned reauth_id is not added to database at this point; it 10158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * will need to be added with eap_sim_db_add_reauth() once the authentication 10168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * has been completed successfully. Caller is responsible for freeing the 10178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * returned buffer. 10188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 10194530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidtchar * eap_sim_db_get_next_reauth_id(struct eap_sim_db_data *data, 10204530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt enum eap_sim_db_method method) 10218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 102204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt char prefix = EAP_SIM_REAUTH_ID_PREFIX; 102304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 102404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt switch (method) { 102504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt case EAP_SIM_DB_SIM: 102604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt prefix = EAP_SIM_REAUTH_ID_PREFIX; 102704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt break; 102804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt case EAP_SIM_DB_AKA: 102904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt prefix = EAP_AKA_REAUTH_ID_PREFIX; 103004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt break; 103104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt case EAP_SIM_DB_AKA_PRIME: 103204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt prefix = EAP_AKA_PRIME_REAUTH_ID_PREFIX; 103304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt break; 103404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 103504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 103604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return eap_sim_db_get_next(data, prefix); 10378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 10388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 10418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_sim_db_add_pseudonym - EAP-SIM DB: Add new pseudonym 10424530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt * @data: Private data pointer from eap_sim_db_init() 10434530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt * @permanent: Permanent username 10448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @pseudonym: Pseudonym for this user. This needs to be an allocated buffer, 10458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * e.g., return value from eap_sim_db_get_next_pseudonym(). Caller must not 10468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * free it. 10478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 on success, -1 on failure 10488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 10498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function adds a new pseudonym for EAP-SIM user. EAP-SIM DB is 10508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * responsible of freeing pseudonym buffer once it is not needed anymore. 10518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 10524530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidtint eap_sim_db_add_pseudonym(struct eap_sim_db_data *data, 10534530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt const char *permanent, char *pseudonym) 10548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 10558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_sim_pseudonym *p; 10564530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SIM DB: Add pseudonym '%s' for permanent " 10574530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt "username '%s'", pseudonym, permanent); 10588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* TODO: could store last two pseudonyms */ 10604530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt#ifdef CONFIG_SQLITE 10614530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (data->sqlite_db) 10624530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt return db_add_pseudonym(data, permanent, pseudonym); 10634530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt#endif /* CONFIG_SQLITE */ 10644530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt for (p = data->pseudonyms; p; p = p->next) { 10654530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (os_strcmp(permanent, p->permanent) == 0) 10664530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt break; 10674530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt } 10688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p) { 10698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SIM DB: Replacing previous " 10708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "pseudonym: %s", p->pseudonym); 10718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(p->pseudonym); 10728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p->pseudonym = pseudonym; 10738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 10748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p = os_zalloc(sizeof(*p)); 10778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p == NULL) { 10788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(pseudonym); 10798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 10808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p->next = data->pseudonyms; 10834530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt p->permanent = os_strdup(permanent); 10844530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (p->permanent == NULL) { 10858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(p); 10868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(pseudonym); 10878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 10888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p->pseudonym = pseudonym; 10908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->pseudonyms = p; 10918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SIM DB: Added new pseudonym entry"); 10938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 10948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 10958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct eap_sim_reauth * 10984530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidteap_sim_db_add_reauth_data(struct eap_sim_db_data *data, 10994530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt const char *permanent, 11004530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt char *reauth_id, u16 counter) 11018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 11028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_sim_reauth *r; 11038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11044530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt for (r = data->reauths; r; r = r->next) { 11054530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (os_strcmp(r->permanent, permanent) == 0) 11064530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt break; 11074530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt } 11088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (r) { 11108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SIM DB: Replacing previous " 11118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "reauth_id: %s", r->reauth_id); 11128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(r->reauth_id); 11138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt r->reauth_id = reauth_id; 11148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 11158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt r = os_zalloc(sizeof(*r)); 11168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (r == NULL) { 11178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(reauth_id); 11188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 11198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt r->next = data->reauths; 11224530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt r->permanent = os_strdup(permanent); 11234530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (r->permanent == NULL) { 11248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(r); 11258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(reauth_id); 11268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 11278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt r->reauth_id = reauth_id; 11298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->reauths = r; 11308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SIM DB: Added new reauth entry"); 11318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt r->counter = counter; 11348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return r; 11368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 11378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 11408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_sim_db_add_reauth - EAP-SIM DB: Add new re-authentication entry 11418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @priv: Private data pointer from eap_sim_db_init() 11424530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt * @permanent: Permanent username 11438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @identity_len: Length of identity 11448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @reauth_id: reauth_id for this user. This needs to be an allocated buffer, 11458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * e.g., return value from eap_sim_db_get_next_reauth_id(). Caller must not 11468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * free it. 11478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @counter: AT_COUNTER value for fast re-authentication 11488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @mk: 16-byte MK from the previous full authentication or %NULL 11498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 on success, -1 on failure 11508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 11518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function adds a new re-authentication entry for an EAP-SIM user. 11528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * EAP-SIM DB is responsible of freeing reauth_id buffer once it is not needed 11538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * anymore. 11548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 11554530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidtint eap_sim_db_add_reauth(struct eap_sim_db_data *data, const char *permanent, 11564530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt char *reauth_id, u16 counter, const u8 *mk) 11578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 11588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_sim_reauth *r; 11598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11604530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SIM DB: Add reauth_id '%s' for permanent " 11614530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt "identity '%s'", reauth_id, permanent); 11624530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 11634530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt#ifdef CONFIG_SQLITE 11644530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (data->sqlite_db) 11654530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt return db_add_reauth(data, permanent, reauth_id, counter, mk, 11664530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt NULL, NULL, NULL); 11674530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt#endif /* CONFIG_SQLITE */ 11684530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt r = eap_sim_db_add_reauth_data(data, permanent, reauth_id, counter); 11698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (r == NULL) 11708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 11718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(r->mk, mk, EAP_SIM_MK_LEN); 11738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 11758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 11768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef EAP_SERVER_AKA_PRIME 11798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 11808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_sim_db_add_reauth_prime - EAP-AKA' DB: Add new re-authentication entry 11814530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt * @data: Private data pointer from eap_sim_db_init() 11824530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt * @permanent: Permanent username 11838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @reauth_id: reauth_id for this user. This needs to be an allocated buffer, 11848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * e.g., return value from eap_sim_db_get_next_reauth_id(). Caller must not 11858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * free it. 11868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @counter: AT_COUNTER value for fast re-authentication 11878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @k_encr: K_encr from the previous full authentication 11888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @k_aut: K_aut from the previous full authentication 11898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @k_re: 32-byte K_re from the previous full authentication 11908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 on success, -1 on failure 11918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 11928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function adds a new re-authentication entry for an EAP-AKA' user. 11938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * EAP-SIM DB is responsible of freeing reauth_id buffer once it is not needed 11948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * anymore. 11958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 11964530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidtint eap_sim_db_add_reauth_prime(struct eap_sim_db_data *data, 11974530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt const char *permanent, char *reauth_id, 11984530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt u16 counter, const u8 *k_encr, 11994530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt const u8 *k_aut, const u8 *k_re) 12008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 12018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_sim_reauth *r; 12028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12034530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SIM DB: Add reauth_id '%s' for permanent " 12044530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt "identity '%s'", reauth_id, permanent); 12054530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 12064530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt#ifdef CONFIG_SQLITE 12074530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (data->sqlite_db) 12084530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt return db_add_reauth(data, permanent, reauth_id, counter, NULL, 12094530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt k_encr, k_aut, k_re); 12104530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt#endif /* CONFIG_SQLITE */ 12114530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt r = eap_sim_db_add_reauth_data(data, permanent, reauth_id, counter); 12128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (r == NULL) 12138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 12148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(r->k_encr, k_encr, EAP_SIM_K_ENCR_LEN); 12168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(r->k_aut, k_aut, EAP_AKA_PRIME_K_AUT_LEN); 12178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(r->k_re, k_re, EAP_AKA_PRIME_K_RE_LEN); 12188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 12208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 12218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* EAP_SERVER_AKA_PRIME */ 12228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 12258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_sim_db_get_permanent - EAP-SIM DB: Get permanent identity 12264530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt * @data: Private data pointer from eap_sim_db_init() 12274530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt * @pseudonym: Pseudonym username 12284530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt * Returns: Pointer to permanent username or %NULL if not found 12298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 12304530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidtconst char * 12314530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidteap_sim_db_get_permanent(struct eap_sim_db_data *data, const char *pseudonym) 12328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 12338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_sim_pseudonym *p; 12348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12354530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt#ifdef CONFIG_SQLITE 12364530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (data->sqlite_db) 12374530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt return db_get_pseudonym(data, pseudonym); 12384530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt#endif /* CONFIG_SQLITE */ 12398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12404530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt p = data->pseudonyms; 12414530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt while (p) { 12424530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (os_strcmp(p->pseudonym, pseudonym) == 0) 12434530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt return p->permanent; 12444530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt p = p->next; 12454530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt } 12468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12474530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt return NULL; 12488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 12498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 12528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_sim_db_get_reauth_entry - EAP-SIM DB: Get re-authentication entry 12534530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt * @data: Private data pointer from eap_sim_db_init() 12544530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt * @reauth_id: Fast re-authentication username 12558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: Pointer to the re-auth entry, or %NULL if not found 12568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 12578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct eap_sim_reauth * 12584530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidteap_sim_db_get_reauth_entry(struct eap_sim_db_data *data, 12594530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt const char *reauth_id) 12608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 12618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_sim_reauth *r; 12628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12634530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt#ifdef CONFIG_SQLITE 12644530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (data->sqlite_db) 12654530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt return db_get_reauth(data, reauth_id); 12664530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt#endif /* CONFIG_SQLITE */ 12674530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 12684530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt r = data->reauths; 12694530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt while (r) { 12704530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (os_strcmp(r->reauth_id, reauth_id) == 0) 12714530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt break; 12724530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt r = r->next; 12734530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt } 12744530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 12758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return r; 12768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 12778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 12808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_sim_db_remove_reauth - EAP-SIM DB: Remove re-authentication entry 12814530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt * @data: Private data pointer from eap_sim_db_init() 12828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @reauth: Pointer to re-authentication entry from 12838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_sim_db_get_reauth_entry() 12848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 12854530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidtvoid eap_sim_db_remove_reauth(struct eap_sim_db_data *data, 12864530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt struct eap_sim_reauth *reauth) 12878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 12888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_sim_reauth *r, *prev = NULL; 12894530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt#ifdef CONFIG_SQLITE 12904530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (data->sqlite_db) { 12914530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt db_remove_reauth(data, reauth); 12924530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt return; 12934530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt } 12944530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt#endif /* CONFIG_SQLITE */ 12958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt r = data->reauths; 12968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (r) { 12978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (r == reauth) { 12988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (prev) 12998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt prev->next = r->next; 13008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 13018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->reauths = r->next; 13028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_sim_db_free_reauth(r); 13038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 13048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt prev = r; 13068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt r = r->next; 13078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 13098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 13128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_sim_db_get_aka_auth - Get AKA authentication values 13134530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt * @data: Private data pointer from eap_sim_db_init() 13144530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt * @username: Permanent username (prefix | IMSI) 13158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @_rand: Buffer for RAND value 13168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @autn: Buffer for AUTN value 13178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @ik: Buffer for IK value 13188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @ck: Buffer for CK value 13198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @res: Buffer for RES value 13208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @res_len: Buffer for RES length 13218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @cb_session_ctx: Session callback context for get_complete_cb() 13228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 on success, -1 (EAP_SIM_DB_FAILURE) on error (e.g., user not 13238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * found), or -2 (EAP_SIM_DB_PENDING) if results are not yet available. In this 13248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * case, the callback function registered with eap_sim_db_init() will be 13258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * called once the results become available. 13268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 13278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * When using an external server for AKA authentication, this function can 13288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * always start a request and return EAP_SIM_DB_PENDING immediately if 13298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * authentication triplets are not available. Once the authentication data are 13308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * received, callback function registered with eap_sim_db_init() is called to 13318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * notify EAP state machine to reprocess the message. This 13328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_sim_db_get_aka_auth() function will then be called again and the newly 13338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * received triplets will then be given to the caller. 13348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 13354530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidtint eap_sim_db_get_aka_auth(struct eap_sim_db_data *data, const char *username, 13364530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt u8 *_rand, u8 *autn, u8 *ik, u8 *ck, 13374530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt u8 *res, size_t *res_len, void *cb_session_ctx) 13388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 13398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_sim_db_pending *entry; 13408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int len; 13418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char msg[40]; 13424530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt const char *imsi; 13434530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt size_t imsi_len; 13448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13454530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (username == NULL || 13464530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt (username[0] != EAP_AKA_PERMANENT_PREFIX && 13474530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt username[0] != EAP_AKA_PRIME_PERMANENT_PREFIX) || 13484530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt username[1] == '\0' || os_strlen(username) > sizeof(entry->imsi)) { 13494530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SIM DB: unexpected username '%s'", 13504530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt username); 13518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return EAP_SIM_DB_FAILURE; 13528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13534530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt imsi = username + 1; 13544530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SIM DB: Get AKA auth for IMSI '%s'", 13554530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt imsi); 13568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13574530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt entry = eap_sim_db_get_pending(data, imsi, 1); 13588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (entry) { 13598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (entry->state == FAILURE) { 13608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(entry); 13618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SIM DB: Failure"); 13628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return EAP_SIM_DB_FAILURE; 13638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (entry->state == PENDING) { 13668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_sim_db_add_pending(data, entry); 13678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SIM DB: Pending"); 13688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return EAP_SIM_DB_PENDING; 13698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SIM DB: Returning successfully " 13728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "received authentication data"); 13738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(_rand, entry->u.aka.rand, EAP_AKA_RAND_LEN); 13748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(autn, entry->u.aka.autn, EAP_AKA_AUTN_LEN); 13758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(ik, entry->u.aka.ik, EAP_AKA_IK_LEN); 13768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(ck, entry->u.aka.ck, EAP_AKA_CK_LEN); 13778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(res, entry->u.aka.res, EAP_AKA_RES_MAX_LEN); 13788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *res_len = entry->u.aka.res_len; 13798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(entry); 13808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 13818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data->sock < 0) { 13848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (eap_sim_db_open_socket(data) < 0) 13858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return EAP_SIM_DB_FAILURE; 13868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13884530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt imsi_len = os_strlen(imsi); 13898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = os_snprintf(msg, sizeof(msg), "AKA-REQ-AUTH "); 13904530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (len < 0 || len + imsi_len >= sizeof(msg)) 13918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return EAP_SIM_DB_FAILURE; 13924530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt os_memcpy(msg + len, imsi, imsi_len); 13934530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt len += imsi_len; 13948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13954530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SIM DB: requesting AKA authentication " 13964530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt "data for IMSI '%s'", imsi); 13978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (eap_sim_db_send(data, msg, len) < 0) 13988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return EAP_SIM_DB_FAILURE; 13998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt entry = os_zalloc(sizeof(*entry)); 14018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (entry == NULL) 14028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return EAP_SIM_DB_FAILURE; 14038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt entry->aka = 1; 14054530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt os_strlcpy(entry->imsi, imsi, sizeof(entry->imsi)); 14068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt entry->cb_session_ctx = cb_session_ctx; 14078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt entry->state = PENDING; 14088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_sim_db_add_pending(data, entry); 14098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_sim_db_expire_pending(data); 14108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return EAP_SIM_DB_PENDING; 14128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 14138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 14168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_sim_db_resynchronize - Resynchronize AKA AUTN 14174530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt * @data: Private data pointer from eap_sim_db_init() 14184530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt * @username: Permanent username 14198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @auts: AUTS value from the peer 14208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @_rand: RAND value used in the rejected message 14218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 on success, -1 on failure 14228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 14238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function is called when the peer reports synchronization failure in the 14248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * AUTN value by sending AUTS. The AUTS and RAND values should be sent to 14258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * HLR/AuC to allow it to resynchronize with the peer. After this, 14268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_sim_db_get_aka_auth() will be called again to to fetch updated 14278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * RAND/AUTN values for the next challenge. 14288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 14294530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidtint eap_sim_db_resynchronize(struct eap_sim_db_data *data, 14304530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt const char *username, 14314530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt const u8 *auts, const u8 *_rand) 14328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 14334530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt const char *imsi; 14344530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt size_t imsi_len; 14358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14364530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (username == NULL || 14374530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt (username[0] != EAP_AKA_PERMANENT_PREFIX && 14384530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt username[0] != EAP_AKA_PRIME_PERMANENT_PREFIX) || 14394530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt username[1] == '\0' || os_strlen(username) > 20) { 14404530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SIM DB: unexpected username '%s'", 14414530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt username); 14428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 14438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 14444530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt imsi = username + 1; 14454530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SIM DB: Get AKA auth for IMSI '%s'", 14464530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt imsi); 14478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data->sock >= 0) { 14498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char msg[100]; 14508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int len, ret; 14518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14524530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt imsi_len = os_strlen(imsi); 14538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = os_snprintf(msg, sizeof(msg), "AKA-AUTS "); 14544530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (len < 0 || len + imsi_len >= sizeof(msg)) 14558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 14564530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt os_memcpy(msg + len, imsi, imsi_len); 14574530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt len += imsi_len; 14588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = os_snprintf(msg + len, sizeof(msg) - len, " "); 14608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret < 0 || (size_t) ret >= sizeof(msg) - len) 14618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 14628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len += ret; 14638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len += wpa_snprintf_hex(msg + len, sizeof(msg) - len, 14648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt auts, EAP_AKA_AUTS_LEN); 14658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = os_snprintf(msg + len, sizeof(msg) - len, " "); 14668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret < 0 || (size_t) ret >= sizeof(msg) - len) 14678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 14688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len += ret; 14698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len += wpa_snprintf_hex(msg + len, sizeof(msg) - len, 14708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt _rand, EAP_AKA_RAND_LEN); 14714530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SIM DB: reporting AKA AUTS for " 14724530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt "IMSI '%s'", imsi); 14738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (eap_sim_db_send(data, msg, len) < 0) 14748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 14758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 14768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 14788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 14794530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 14804530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 14814530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt/** 14824530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt * sim_get_username - Extract username from SIM identity 14834530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt * @identity: Identity 14844530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt * @identity_len: Identity length 14854530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt * Returns: Allocated buffer with the username part of the identity 14864530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt * 14874530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt * Caller is responsible for freeing the returned buffer with os_free(). 14884530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt */ 14894530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidtchar * sim_get_username(const u8 *identity, size_t identity_len) 14904530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt{ 14914530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt size_t pos; 14924530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 14934530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (identity == NULL) 14944530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt return NULL; 14954530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 14964530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt for (pos = 0; pos < identity_len; pos++) { 14974530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (identity[pos] == '@' || identity[pos] == '\0') 14984530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt break; 14994530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt } 15004530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 15014b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt return dup_binstr(identity, pos); 15024530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt} 1503