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 struct os_time timestamp; 428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int aka; 438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt union { 448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct { 458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 kc[EAP_SIM_MAX_CHAL][EAP_SIM_KC_LEN]; 468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 sres[EAP_SIM_MAX_CHAL][EAP_SIM_SRES_LEN]; 478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 rand[EAP_SIM_MAX_CHAL][GSM_RAND_LEN]; 488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int num_chal; 498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } sim; 508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct { 518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 rand[EAP_AKA_RAND_LEN]; 528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 autn[EAP_AKA_AUTN_LEN]; 538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 ik[EAP_AKA_IK_LEN]; 548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 ck[EAP_AKA_CK_LEN]; 558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 res[EAP_AKA_RES_MAX_LEN]; 568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t res_len; 578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } aka; 588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } u; 598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}; 608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct eap_sim_db_data { 628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int sock; 638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *fname; 648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *local_sock; 658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void (*get_complete_cb)(void *ctx, void *session_ctx); 668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void *ctx; 678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_sim_pseudonym *pseudonyms; 688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_sim_reauth *reauths; 698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_sim_db_pending *pending; 704530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt#ifdef CONFIG_SQLITE 714530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt sqlite3 *sqlite_db; 724530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt char db_tmp_identity[100]; 734530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt char db_tmp_pseudonym_str[100]; 744530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt struct eap_sim_pseudonym db_tmp_pseudonym; 754530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt struct eap_sim_reauth db_tmp_reauth; 764530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt#endif /* CONFIG_SQLITE */ 778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}; 788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 804530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt#ifdef CONFIG_SQLITE 814530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 824530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidtstatic int db_table_exists(sqlite3 *db, const char *name) 834530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt{ 844530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt char cmd[128]; 854530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt os_snprintf(cmd, sizeof(cmd), "SELECT 1 FROM %s;", name); 864530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt return sqlite3_exec(db, cmd, NULL, NULL, NULL) == SQLITE_OK; 874530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt} 884530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 894530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 904530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidtstatic int db_table_create_pseudonym(sqlite3 *db) 914530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt{ 924530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt char *err = NULL; 934530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt const char *sql = 944530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt "CREATE TABLE pseudonyms(" 954530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt " permanent CHAR(21) PRIMARY KEY," 964530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt " pseudonym CHAR(21) NOT NULL" 974530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt ");"; 984530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 994530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SIM DB: Adding database table for " 1004530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt "pseudonym information"); 1014530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (sqlite3_exec(db, sql, NULL, NULL, &err) != SQLITE_OK) { 1024530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt wpa_printf(MSG_ERROR, "EAP-SIM DB: SQLite error: %s", err); 1034530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt sqlite3_free(err); 1044530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt return -1; 1054530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt } 1064530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 1074530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt return 0; 1084530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt} 1094530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 1104530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 1114530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidtstatic int db_table_create_reauth(sqlite3 *db) 1124530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt{ 1134530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt char *err = NULL; 1144530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt const char *sql = 1154530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt "CREATE TABLE reauth(" 1164530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt " permanent CHAR(21) PRIMARY KEY," 1174530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt " reauth_id CHAR(21) NOT NULL," 1184530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt " counter INTEGER," 1194530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt " mk CHAR(40)," 1204530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt " k_encr CHAR(32)," 1214530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt " k_aut CHAR(64)," 1224530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt " k_re CHAR(64)" 1234530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt ");"; 1244530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 1254530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SIM DB: Adding database table for " 1264530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt "reauth information"); 1274530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (sqlite3_exec(db, sql, NULL, NULL, &err) != SQLITE_OK) { 1284530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt wpa_printf(MSG_ERROR, "EAP-SIM DB: SQLite error: %s", err); 1294530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt sqlite3_free(err); 1304530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt return -1; 1314530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt } 1324530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 1334530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt return 0; 1344530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt} 1354530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 1364530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 1374530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidtstatic sqlite3 * db_open(const char *db_file) 1384530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt{ 1394530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt sqlite3 *db; 1404530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 1414530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (sqlite3_open(db_file, &db)) { 1424530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt wpa_printf(MSG_ERROR, "EAP-SIM DB: Failed to open database " 1434530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt "%s: %s", db_file, sqlite3_errmsg(db)); 1444530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt sqlite3_close(db); 1454530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt return NULL; 1464530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt } 1474530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 1484530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (!db_table_exists(db, "pseudonyms") && 1494530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt db_table_create_pseudonym(db) < 0) { 1504530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt sqlite3_close(db); 1514530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt return NULL; 1524530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt } 1534530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 1544530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (!db_table_exists(db, "reauth") && 1554530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt db_table_create_reauth(db) < 0) { 1564530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt sqlite3_close(db); 1574530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt return NULL; 1584530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt } 1594530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 1604530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt return db; 1614530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt} 1624530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 1634530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 1644530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidtstatic int valid_db_string(const char *str) 1654530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt{ 1664530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt const char *pos = str; 1674530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt while (*pos) { 1684530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if ((*pos < '0' || *pos > '9') && 1694530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt (*pos < 'a' || *pos > 'f')) 1704530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt return 0; 1714530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt pos++; 1724530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt } 1734530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt return 1; 1744530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt} 1754530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 1764530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 1774530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidtstatic int db_add_pseudonym(struct eap_sim_db_data *data, 1784530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt const char *permanent, char *pseudonym) 1794530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt{ 1804530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt char cmd[128]; 1814530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt char *err = NULL; 1824530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 1834530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (!valid_db_string(permanent) || !valid_db_string(pseudonym)) { 1844530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt os_free(pseudonym); 1854530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt return -1; 1864530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt } 1874530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 1884530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt os_snprintf(cmd, sizeof(cmd), "INSERT OR REPLACE INTO pseudonyms " 1894530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt "(permanent, pseudonym) VALUES ('%s', '%s');", 1904530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt permanent, pseudonym); 1914530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt os_free(pseudonym); 1924530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (sqlite3_exec(data->sqlite_db, cmd, NULL, NULL, &err) != SQLITE_OK) 1934530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt { 1944530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt wpa_printf(MSG_ERROR, "EAP-SIM DB: SQLite error: %s", err); 1954530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt sqlite3_free(err); 1964530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt return -1; 1974530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt } 1984530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 1994530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt return 0; 2004530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt} 2014530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 2024530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 2034530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidtstatic int get_pseudonym_cb(void *ctx, int argc, char *argv[], char *col[]) 2044530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt{ 2054530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt struct eap_sim_db_data *data = ctx; 2064530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt int i; 2074530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 2084530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt for (i = 0; i < argc; i++) { 2094530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (os_strcmp(col[i], "permanent") == 0 && argv[i]) { 2104530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt os_strlcpy(data->db_tmp_identity, argv[i], 2114530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt sizeof(data->db_tmp_identity)); 2124530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt } 2134530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt } 2144530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 2154530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt return 0; 2164530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt} 2174530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 2184530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 2194530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidtstatic char * 2204530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidtdb_get_pseudonym(struct eap_sim_db_data *data, const char *pseudonym) 2214530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt{ 2224530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt char cmd[128]; 2234530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 2244530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (!valid_db_string(pseudonym)) 2254530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt return NULL; 2264530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt os_memset(&data->db_tmp_identity, 0, sizeof(data->db_tmp_identity)); 2274530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt os_snprintf(cmd, sizeof(cmd), 2284530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt "SELECT permanent FROM pseudonyms WHERE pseudonym='%s';", 2294530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt pseudonym); 2304530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (sqlite3_exec(data->sqlite_db, cmd, get_pseudonym_cb, data, NULL) != 2314530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt SQLITE_OK) 2324530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt return NULL; 2334530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (data->db_tmp_identity[0] == '\0') 2344530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt return NULL; 2354530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt return data->db_tmp_identity; 2364530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt} 2374530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 2384530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 2394530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidtstatic int db_add_reauth(struct eap_sim_db_data *data, const char *permanent, 2404530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt char *reauth_id, u16 counter, const u8 *mk, 2414530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt const u8 *k_encr, const u8 *k_aut, const u8 *k_re) 2424530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt{ 2434530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt char cmd[2000], *pos, *end; 2444530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt char *err = NULL; 2454530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 2464530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (!valid_db_string(permanent) || !valid_db_string(reauth_id)) { 2474530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt os_free(reauth_id); 2484530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt return -1; 2494530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt } 2504530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 2514530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt pos = cmd; 2524530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt end = pos + sizeof(cmd); 2534530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt pos += os_snprintf(pos, end - pos, "INSERT OR REPLACE INTO reauth " 2544530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt "(permanent, reauth_id, counter%s%s%s%s) " 2554530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt "VALUES ('%s', '%s', %u", 2564530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt mk ? ", mk" : "", 2574530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt k_encr ? ", k_encr" : "", 2584530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt k_aut ? ", k_aut" : "", 2594530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt k_re ? ", k_re" : "", 2604530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt permanent, reauth_id, counter); 2614530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt os_free(reauth_id); 2624530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 2634530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (mk) { 2644530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt pos += os_snprintf(pos, end - pos, ", '"); 2654530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt pos += wpa_snprintf_hex(pos, end - pos, mk, EAP_SIM_MK_LEN); 2664530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt pos += os_snprintf(pos, end - pos, "'"); 2674530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt } 2684530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 2694530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (k_encr) { 2704530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt pos += os_snprintf(pos, end - pos, ", '"); 2714530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt pos += wpa_snprintf_hex(pos, end - pos, k_encr, 2724530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt EAP_SIM_K_ENCR_LEN); 2734530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt pos += os_snprintf(pos, end - pos, "'"); 2744530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt } 2754530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 2764530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (k_aut) { 2774530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt pos += os_snprintf(pos, end - pos, ", '"); 2784530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt pos += wpa_snprintf_hex(pos, end - pos, k_aut, 2794530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt EAP_AKA_PRIME_K_AUT_LEN); 2804530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt pos += os_snprintf(pos, end - pos, "'"); 2814530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt } 2824530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 2834530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (k_re) { 2844530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt pos += os_snprintf(pos, end - pos, ", '"); 2854530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt pos += wpa_snprintf_hex(pos, end - pos, k_re, 2864530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt EAP_AKA_PRIME_K_RE_LEN); 2874530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt pos += os_snprintf(pos, end - pos, "'"); 2884530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt } 2894530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 2904530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt os_snprintf(pos, end - pos, ");"); 2914530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 2924530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (sqlite3_exec(data->sqlite_db, cmd, NULL, NULL, &err) != SQLITE_OK) 2934530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt { 2944530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt wpa_printf(MSG_ERROR, "EAP-SIM DB: SQLite error: %s", err); 2954530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt sqlite3_free(err); 2964530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt return -1; 2974530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt } 2984530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 2994530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt return 0; 3004530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt} 3014530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 3024530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 3034530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidtstatic int get_reauth_cb(void *ctx, int argc, char *argv[], char *col[]) 3044530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt{ 3054530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt struct eap_sim_db_data *data = ctx; 3064530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt int i; 3074530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt struct eap_sim_reauth *reauth = &data->db_tmp_reauth; 3084530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 3094530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt for (i = 0; i < argc; i++) { 3104530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (os_strcmp(col[i], "permanent") == 0 && argv[i]) { 3114530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt os_strlcpy(data->db_tmp_identity, argv[i], 3124530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt sizeof(data->db_tmp_identity)); 3134530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt reauth->permanent = data->db_tmp_identity; 3144530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt } else if (os_strcmp(col[i], "counter") == 0 && argv[i]) { 3154530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt reauth->counter = atoi(argv[i]); 3164530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt } else if (os_strcmp(col[i], "mk") == 0 && argv[i]) { 3174530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt hexstr2bin(argv[i], reauth->mk, sizeof(reauth->mk)); 3184530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt } else if (os_strcmp(col[i], "k_encr") == 0 && argv[i]) { 3194530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt hexstr2bin(argv[i], reauth->k_encr, 3204530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt sizeof(reauth->k_encr)); 3214530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt } else if (os_strcmp(col[i], "k_aut") == 0 && argv[i]) { 3224530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt hexstr2bin(argv[i], reauth->k_aut, 3234530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt sizeof(reauth->k_aut)); 3244530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt } else if (os_strcmp(col[i], "k_re") == 0 && argv[i]) { 3254530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt hexstr2bin(argv[i], reauth->k_re, 3264530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt sizeof(reauth->k_re)); 3274530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt } 3284530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt } 3294530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 3304530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt return 0; 3314530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt} 3324530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 3334530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 3344530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidtstatic struct eap_sim_reauth * 3354530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidtdb_get_reauth(struct eap_sim_db_data *data, const char *reauth_id) 3364530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt{ 3374530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt char cmd[256]; 3384530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 3394530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (!valid_db_string(reauth_id)) 3404530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt return NULL; 3414530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt os_memset(&data->db_tmp_reauth, 0, sizeof(data->db_tmp_reauth)); 3424530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt os_strlcpy(data->db_tmp_pseudonym_str, reauth_id, 3434530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt sizeof(data->db_tmp_pseudonym_str)); 3444530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt data->db_tmp_reauth.reauth_id = data->db_tmp_pseudonym_str; 3454530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt os_snprintf(cmd, sizeof(cmd), 3464530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt "SELECT * FROM reauth WHERE reauth_id='%s';", reauth_id); 3474530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (sqlite3_exec(data->sqlite_db, cmd, get_reauth_cb, data, NULL) != 3484530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt SQLITE_OK) 3494530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt return NULL; 3504530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (data->db_tmp_reauth.permanent == NULL) 3514530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt return NULL; 3524530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt return &data->db_tmp_reauth; 3534530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt} 3544530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 3554530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 3564530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidtstatic void db_remove_reauth(struct eap_sim_db_data *data, 3574530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt struct eap_sim_reauth *reauth) 3584530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt{ 3594530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt char cmd[256]; 3604530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 3614530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (!valid_db_string(reauth->permanent)) 3624530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt return; 3634530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt os_snprintf(cmd, sizeof(cmd), 3644530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt "DELETE FROM reauth WHERE permanent='%s';", 3654530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt reauth->permanent); 3664530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt sqlite3_exec(data->sqlite_db, cmd, NULL, NULL, NULL); 3674530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt} 3684530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 3694530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt#endif /* CONFIG_SQLITE */ 3704530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 3714530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 3728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct eap_sim_db_pending * 3734530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidteap_sim_db_get_pending(struct eap_sim_db_data *data, const char *imsi, int aka) 3748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_sim_db_pending *entry, *prev = NULL; 3768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt entry = data->pending; 3788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (entry) { 3794530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (entry->aka == aka && os_strcmp(entry->imsi, imsi) == 0) { 3808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (prev) 3818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt prev->next = entry->next; 3828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 3838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->pending = entry->next; 3848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 3858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt prev = entry; 3878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt entry = entry->next; 3888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return entry; 3908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void eap_sim_db_add_pending(struct eap_sim_db_data *data, 3948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_sim_db_pending *entry) 3958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt entry->next = data->pending; 3978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->pending = entry; 3988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void eap_sim_db_sim_resp_auth(struct eap_sim_db_data *data, 4028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *imsi, char *buf) 4038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *start, *end, *pos; 4058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_sim_db_pending *entry; 4068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int num_chal; 4078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 4098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * SIM-RESP-AUTH <IMSI> Kc(i):SRES(i):RAND(i) ... 4108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * SIM-RESP-AUTH <IMSI> FAILURE 4118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * (IMSI = ASCII string, Kc/SRES/RAND = hex string) 4128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 4138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4144530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt entry = eap_sim_db_get_pending(data, imsi, 0); 4158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (entry == NULL) { 4168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SIM DB: No pending entry for the " 4178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "received message found"); 4188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 4198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt start = buf; 4228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_strncmp(start, "FAILURE", 7) == 0) { 4238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SIM DB: External server reported " 4248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "failure"); 4258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt entry->state = FAILURE; 4268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_sim_db_add_pending(data, entry); 4278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->get_complete_cb(data->ctx, entry->cb_session_ctx); 4288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 4298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt num_chal = 0; 4328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (num_chal < EAP_SIM_MAX_CHAL) { 4338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt end = os_strchr(start, ' '); 4348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (end) 4358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *end = '\0'; 4368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = os_strchr(start, ':'); 4388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pos == NULL) 4398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto parse_fail; 4408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos = '\0'; 4418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hexstr2bin(start, entry->u.sim.kc[num_chal], 4428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt EAP_SIM_KC_LEN)) 4438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto parse_fail; 4448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt start = pos + 1; 4468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = os_strchr(start, ':'); 4478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pos == NULL) 4488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto parse_fail; 4498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos = '\0'; 4508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hexstr2bin(start, entry->u.sim.sres[num_chal], 4518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt EAP_SIM_SRES_LEN)) 4528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto parse_fail; 4538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt start = pos + 1; 4558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hexstr2bin(start, entry->u.sim.rand[num_chal], 4568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt GSM_RAND_LEN)) 4578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto parse_fail; 4588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt num_chal++; 4608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (end == NULL) 4618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 4628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 4638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt start = end + 1; 4648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt entry->u.sim.num_chal = num_chal; 4668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt entry->state = SUCCESS; 4688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SIM DB: Authentication data parsed " 4698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "successfully - callback"); 4708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_sim_db_add_pending(data, entry); 4718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->get_complete_cb(data->ctx, entry->cb_session_ctx); 4728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 4738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtparse_fail: 4758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SIM DB: Failed to parse response string"); 4768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(entry); 4778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void eap_sim_db_aka_resp_auth(struct eap_sim_db_data *data, 4818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *imsi, char *buf) 4828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *start, *end; 4848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_sim_db_pending *entry; 4858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 4878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * AKA-RESP-AUTH <IMSI> <RAND> <AUTN> <IK> <CK> <RES> 4888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * AKA-RESP-AUTH <IMSI> FAILURE 4898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * (IMSI = ASCII string, RAND/AUTN/IK/CK/RES = hex string) 4908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 4918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4924530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt entry = eap_sim_db_get_pending(data, imsi, 1); 4938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (entry == NULL) { 4948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SIM DB: No pending entry for the " 4958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "received message found"); 4968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 4978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt start = buf; 5008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_strncmp(start, "FAILURE", 7) == 0) { 5018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SIM DB: External server reported " 5028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "failure"); 5038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt entry->state = FAILURE; 5048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_sim_db_add_pending(data, entry); 5058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->get_complete_cb(data->ctx, entry->cb_session_ctx); 5068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 5078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt end = os_strchr(start, ' '); 5108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (end == NULL) 5118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto parse_fail; 5128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *end = '\0'; 5138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hexstr2bin(start, entry->u.aka.rand, EAP_AKA_RAND_LEN)) 5148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto parse_fail; 5158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt start = end + 1; 5178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt end = os_strchr(start, ' '); 5188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (end == NULL) 5198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto parse_fail; 5208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *end = '\0'; 5218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hexstr2bin(start, entry->u.aka.autn, EAP_AKA_AUTN_LEN)) 5228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto parse_fail; 5238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt start = end + 1; 5258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt end = os_strchr(start, ' '); 5268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (end == NULL) 5278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto parse_fail; 5288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *end = '\0'; 5298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hexstr2bin(start, entry->u.aka.ik, EAP_AKA_IK_LEN)) 5308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto parse_fail; 5318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt start = end + 1; 5338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt end = os_strchr(start, ' '); 5348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (end == NULL) 5358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto parse_fail; 5368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *end = '\0'; 5378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hexstr2bin(start, entry->u.aka.ck, EAP_AKA_CK_LEN)) 5388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto parse_fail; 5398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt start = end + 1; 5418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt end = os_strchr(start, ' '); 5428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (end) 5438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *end = '\0'; 5448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else { 5458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt end = start; 5468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (*end) 5478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt end++; 5488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt entry->u.aka.res_len = (end - start) / 2; 5508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (entry->u.aka.res_len > EAP_AKA_RES_MAX_LEN) { 5518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SIM DB: Too long RES"); 5528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt entry->u.aka.res_len = 0; 5538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto parse_fail; 5548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hexstr2bin(start, entry->u.aka.res, entry->u.aka.res_len)) 5568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto parse_fail; 5578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt entry->state = SUCCESS; 5598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SIM DB: Authentication data parsed " 5608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "successfully - callback"); 5618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_sim_db_add_pending(data, entry); 5628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->get_complete_cb(data->ctx, entry->cb_session_ctx); 5638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 5648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtparse_fail: 5668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SIM DB: Failed to parse response string"); 5678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(entry); 5688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 5698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void eap_sim_db_receive(int sock, void *eloop_ctx, void *sock_ctx) 5728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 5738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_sim_db_data *data = eloop_ctx; 5748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char buf[1000], *pos, *cmd, *imsi; 5758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int res; 5768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = recv(sock, buf, sizeof(buf), 0); 5788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res < 0) 5798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 5808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_ascii_key(MSG_MSGDUMP, "EAP-SIM DB: Received from an " 5818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "external source", (u8 *) buf, res); 5828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res == 0) 5838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 5848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res >= (int) sizeof(buf)) 5858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = sizeof(buf) - 1; 5868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf[res] = '\0'; 5878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data->get_complete_cb == NULL) { 5898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SIM DB: No get_complete_cb " 5908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "registered"); 5918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 5928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* <cmd> <IMSI> ... */ 5958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cmd = buf; 5978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = os_strchr(cmd, ' '); 5988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pos == NULL) 5998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto parse_fail; 6008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos = '\0'; 6018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt imsi = pos + 1; 6028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = os_strchr(imsi, ' '); 6038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pos == NULL) 6048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto parse_fail; 6058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos = '\0'; 6068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SIM DB: External response=%s for IMSI %s", 6078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cmd, imsi); 6088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_strcmp(cmd, "SIM-RESP-AUTH") == 0) 6108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_sim_db_sim_resp_auth(data, imsi, pos + 1); 6118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (os_strcmp(cmd, "AKA-RESP-AUTH") == 0) 6128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_sim_db_aka_resp_auth(data, imsi, pos + 1); 6138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 6148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "EAP-SIM DB: Unknown external response " 6158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "'%s'", cmd); 6168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 6178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtparse_fail: 6198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SIM DB: Failed to parse response string"); 6208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 6218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int eap_sim_db_open_socket(struct eap_sim_db_data *data) 6248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 6258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct sockaddr_un addr; 6268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt static int counter = 0; 6278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_strncmp(data->fname, "unix:", 5) != 0) 6298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 6308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->sock = socket(PF_UNIX, SOCK_DGRAM, 0); 6328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data->sock < 0) { 6338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt perror("socket(eap_sim_db)"); 6348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 6358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&addr, 0, sizeof(addr)); 6388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt addr.sun_family = AF_UNIX; 6398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_snprintf(addr.sun_path, sizeof(addr.sun_path), 6408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "/tmp/eap_sim_db_%d-%d", getpid(), counter++); 64161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt os_free(data->local_sock); 6428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->local_sock = os_strdup(addr.sun_path); 6438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (bind(data->sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) { 6448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt perror("bind(eap_sim_db)"); 6458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt close(data->sock); 6468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->sock = -1; 6478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 6488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&addr, 0, sizeof(addr)); 6518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt addr.sun_family = AF_UNIX; 6528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_strlcpy(addr.sun_path, data->fname + 5, sizeof(addr.sun_path)); 6538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (connect(data->sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) { 6548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt perror("connect(eap_sim_db)"); 6558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_ascii(MSG_INFO, "HLR/AuC GW socket", 6568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (u8 *) addr.sun_path, 6578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_strlen(addr.sun_path)); 6588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt close(data->sock); 6598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->sock = -1; 6608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 6618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_read_sock(data->sock, eap_sim_db_receive, data, NULL); 6648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 6668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 6678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void eap_sim_db_close_socket(struct eap_sim_db_data *data) 6708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 6718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data->sock >= 0) { 6728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_unregister_read_sock(data->sock); 6738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt close(data->sock); 6748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->sock = -1; 6758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data->local_sock) { 6778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unlink(data->local_sock); 6788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(data->local_sock); 6798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->local_sock = NULL; 6808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 6828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 6858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_sim_db_init - Initialize EAP-SIM DB / authentication gateway interface 6868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @config: Configuration data (e.g., file name) 6878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @get_complete_cb: Callback function for reporting availability of triplets 6888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @ctx: Context pointer for get_complete_cb 6898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: Pointer to a private data structure or %NULL on failure 6908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 6914530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidtstruct eap_sim_db_data * 6924530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidteap_sim_db_init(const char *config, 6934530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt void (*get_complete_cb)(void *ctx, void *session_ctx), 6944530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt void *ctx) 6958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 6968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_sim_db_data *data; 6974530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt char *pos; 6988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data = os_zalloc(sizeof(*data)); 7008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data == NULL) 7018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 7028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->sock = -1; 7048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->get_complete_cb = get_complete_cb; 7058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->ctx = ctx; 7068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->fname = os_strdup(config); 7078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data->fname == NULL) 7088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 7094530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt pos = os_strstr(data->fname, " db="); 7104530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (pos) { 7114530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt *pos = '\0'; 7124530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt#ifdef CONFIG_SQLITE 7134530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt pos += 4; 7144530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt data->sqlite_db = db_open(pos); 7154530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (data->sqlite_db == NULL) 7164530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt goto fail; 7174530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt#endif /* CONFIG_SQLITE */ 7184530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt } 7198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_strncmp(data->fname, "unix:", 5) == 0) { 72161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (eap_sim_db_open_socket(data)) { 72261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SIM DB: External database " 72361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt "connection not available - will retry " 72461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt "later"); 72561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 7268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return data; 7298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtfail: 7318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_sim_db_close_socket(data); 7328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(data->fname); 7338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(data); 7348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 7358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 7368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void eap_sim_db_free_pseudonym(struct eap_sim_pseudonym *p) 7398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 7404530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt os_free(p->permanent); 7418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(p->pseudonym); 7428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(p); 7438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 7448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void eap_sim_db_free_reauth(struct eap_sim_reauth *r) 7478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 7484530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt os_free(r->permanent); 7498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(r->reauth_id); 7508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(r); 7518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 7528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 7558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_sim_db_deinit - Deinitialize EAP-SIM DB/authentication gw interface 7568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @priv: Private data pointer from eap_sim_db_init() 7578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 7588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid eap_sim_db_deinit(void *priv) 7598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 7608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_sim_db_data *data = priv; 7618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_sim_pseudonym *p, *prev; 7628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_sim_reauth *r, *prevr; 7638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_sim_db_pending *pending, *prev_pending; 7648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7654530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt#ifdef CONFIG_SQLITE 7664530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (data->sqlite_db) { 7674530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt sqlite3_close(data->sqlite_db); 7684530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt data->sqlite_db = NULL; 7694530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt } 7704530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt#endif /* CONFIG_SQLITE */ 7714530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 7728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_sim_db_close_socket(data); 7738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(data->fname); 7748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p = data->pseudonyms; 7768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (p) { 7778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt prev = p; 7788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p = p->next; 7798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_sim_db_free_pseudonym(prev); 7808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt r = data->reauths; 7838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (r) { 7848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt prevr = r; 7858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt r = r->next; 7868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_sim_db_free_reauth(prevr); 7878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pending = data->pending; 7908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (pending) { 7918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt prev_pending = pending; 7928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pending = pending->next; 7938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(prev_pending); 7948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(data); 7978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 7988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int eap_sim_db_send(struct eap_sim_db_data *data, const char *msg, 8018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t len) 8028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 8038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int _errno = 0; 8048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (send(data->sock, msg, len, 0) < 0) { 8068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt _errno = errno; 8078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt perror("send[EAP-SIM DB UNIX]"); 8088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (_errno == ENOTCONN || _errno == EDESTADDRREQ || _errno == EINVAL || 8118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt _errno == ECONNREFUSED) { 8128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Try to reconnect */ 8138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_sim_db_close_socket(data); 8148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (eap_sim_db_open_socket(data) < 0) 8158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 8168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SIM DB: Reconnected to the " 8178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "external server"); 8188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (send(data->sock, msg, len, 0) < 0) { 8198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt perror("send[EAP-SIM DB UNIX]"); 8208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 8218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 8258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 8268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void eap_sim_db_expire_pending(struct eap_sim_db_data *data) 8298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 8308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* TODO: add limit for maximum length for pending list; remove latest 8318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * (i.e., last) entry from the list if the limit is reached; could also 8328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * use timeout to expire pending entries */ 8338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 8348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 8378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_sim_db_get_gsm_triplets - Get GSM triplets 8384530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt * @data: Private data pointer from eap_sim_db_init() 8394530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt * @username: Permanent username (prefix | IMSI) 8408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @max_chal: Maximum number of triplets 8418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @_rand: Buffer for RAND values 8428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @kc: Buffer for Kc values 8438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sres: Buffer for SRES values 8448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @cb_session_ctx: Session callback context for get_complete_cb() 8458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: Number of triplets received (has to be less than or equal to 8468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * max_chal), -1 (EAP_SIM_DB_FAILURE) on error (e.g., user not found), or 8478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * -2 (EAP_SIM_DB_PENDING) if results are not yet available. In this case, the 8488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * callback function registered with eap_sim_db_init() will be called once the 8498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * results become available. 8508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 8518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * When using an external server for GSM triplets, this function can always 8528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * start a request and return EAP_SIM_DB_PENDING immediately if authentication 8538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * triplets are not available. Once the triplets are received, callback 8548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * function registered with eap_sim_db_init() is called to notify EAP state 8558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * machine to reprocess the message. This eap_sim_db_get_gsm_triplets() 8568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * function will then be called again and the newly received triplets will then 8578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * be given to the caller. 8588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 8594530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidtint eap_sim_db_get_gsm_triplets(struct eap_sim_db_data *data, 8604530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt const char *username, int max_chal, 8618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *_rand, u8 *kc, u8 *sres, 8628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void *cb_session_ctx) 8638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 8648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_sim_db_pending *entry; 8658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int len, ret; 8668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char msg[40]; 8674530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt const char *imsi; 8684530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt size_t imsi_len; 8698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8704530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (username == NULL || username[0] != EAP_SIM_PERMANENT_PREFIX || 8714530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt username[1] == '\0' || os_strlen(username) > sizeof(entry->imsi)) { 8724530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SIM DB: unexpected username '%s'", 8734530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt username); 8748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return EAP_SIM_DB_FAILURE; 8758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8764530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt imsi = username + 1; 8774530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SIM DB: Get GSM triplets for IMSI '%s'", 8784530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt imsi); 8798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8804530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt entry = eap_sim_db_get_pending(data, imsi, 0); 8818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (entry) { 8828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int num_chal; 8838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (entry->state == FAILURE) { 8848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SIM DB: Pending entry -> " 8858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "failure"); 8868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(entry); 8878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return EAP_SIM_DB_FAILURE; 8888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (entry->state == PENDING) { 8918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SIM DB: Pending entry -> " 8928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "still pending"); 8938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_sim_db_add_pending(data, entry); 8948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return EAP_SIM_DB_PENDING; 8958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SIM DB: Pending entry -> " 8988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "%d challenges", entry->u.sim.num_chal); 8998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt num_chal = entry->u.sim.num_chal; 9008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (num_chal > max_chal) 9018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt num_chal = max_chal; 9028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(_rand, entry->u.sim.rand, num_chal * GSM_RAND_LEN); 9038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(sres, entry->u.sim.sres, 9048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt num_chal * EAP_SIM_SRES_LEN); 9058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(kc, entry->u.sim.kc, num_chal * EAP_SIM_KC_LEN); 9068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(entry); 9078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return num_chal; 9088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data->sock < 0) { 9118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (eap_sim_db_open_socket(data) < 0) 9128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return EAP_SIM_DB_FAILURE; 9138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9154530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt imsi_len = os_strlen(imsi); 9168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = os_snprintf(msg, sizeof(msg), "SIM-REQ-AUTH "); 9174530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (len < 0 || len + imsi_len >= sizeof(msg)) 9188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return EAP_SIM_DB_FAILURE; 9194530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt os_memcpy(msg + len, imsi, imsi_len); 9204530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt len += imsi_len; 9218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = os_snprintf(msg + len, sizeof(msg) - len, " %d", max_chal); 9228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret < 0 || (size_t) ret >= sizeof(msg) - len) 9238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return EAP_SIM_DB_FAILURE; 9248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len += ret; 9258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9264530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SIM DB: requesting SIM authentication " 9274530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt "data for IMSI '%s'", imsi); 9288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (eap_sim_db_send(data, msg, len) < 0) 9298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return EAP_SIM_DB_FAILURE; 9308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt entry = os_zalloc(sizeof(*entry)); 9328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (entry == NULL) 9338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return EAP_SIM_DB_FAILURE; 9348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_get_time(&entry->timestamp); 9364530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt os_strlcpy(entry->imsi, imsi, sizeof(entry->imsi)); 9378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt entry->cb_session_ctx = cb_session_ctx; 9388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt entry->state = PENDING; 9398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_sim_db_add_pending(data, entry); 9408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_sim_db_expire_pending(data); 9418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return EAP_SIM_DB_PENDING; 9438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 9448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic char * eap_sim_db_get_next(struct eap_sim_db_data *data, char prefix) 9478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 9488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *id, *pos, *end; 9498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 buf[10]; 9508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (random_get_bytes(buf, sizeof(buf))) 9528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 9538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt id = os_malloc(sizeof(buf) * 2 + 2); 9548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (id == NULL) 9558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 9568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = id; 9588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt end = id + sizeof(buf) * 2 + 2; 9598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos++ = prefix; 9608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += wpa_snprintf_hex(pos, end - pos, buf, sizeof(buf)); 9618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return id; 9638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 9648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 9678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_sim_db_get_next_pseudonym - EAP-SIM DB: Get next pseudonym 9684530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt * @data: Private data pointer from eap_sim_db_init() 96904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * @method: EAP method (SIM/AKA/AKA') 9708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: Next pseudonym (allocated string) or %NULL on failure 9718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 9728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function is used to generate a pseudonym for EAP-SIM. The returned 9738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * pseudonym is not added to database at this point; it will need to be added 9748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * with eap_sim_db_add_pseudonym() once the authentication has been completed 9758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * successfully. Caller is responsible for freeing the returned buffer. 9768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 9774530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidtchar * eap_sim_db_get_next_pseudonym(struct eap_sim_db_data *data, 9784530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt enum eap_sim_db_method method) 9798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 98004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt char prefix = EAP_SIM_REAUTH_ID_PREFIX; 98104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 98204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt switch (method) { 98304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt case EAP_SIM_DB_SIM: 98404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt prefix = EAP_SIM_PSEUDONYM_PREFIX; 98504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt break; 98604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt case EAP_SIM_DB_AKA: 98704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt prefix = EAP_AKA_PSEUDONYM_PREFIX; 98804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt break; 98904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt case EAP_SIM_DB_AKA_PRIME: 99004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt prefix = EAP_AKA_PRIME_PSEUDONYM_PREFIX; 99104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt break; 99204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 99304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 99404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return eap_sim_db_get_next(data, prefix); 9958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 9968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 9998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_sim_db_get_next_reauth_id - EAP-SIM DB: Get next reauth_id 10004530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt * @data: Private data pointer from eap_sim_db_init() 100104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * @method: EAP method (SIM/AKA/AKA') 10028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: Next reauth_id (allocated string) or %NULL on failure 10038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 10048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function is used to generate a fast re-authentication identity for 10058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * EAP-SIM. The returned reauth_id is not added to database at this point; it 10068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * will need to be added with eap_sim_db_add_reauth() once the authentication 10078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * has been completed successfully. Caller is responsible for freeing the 10088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * returned buffer. 10098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 10104530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidtchar * eap_sim_db_get_next_reauth_id(struct eap_sim_db_data *data, 10114530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt enum eap_sim_db_method method) 10128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 101304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt char prefix = EAP_SIM_REAUTH_ID_PREFIX; 101404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 101504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt switch (method) { 101604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt case EAP_SIM_DB_SIM: 101704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt prefix = EAP_SIM_REAUTH_ID_PREFIX; 101804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt break; 101904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt case EAP_SIM_DB_AKA: 102004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt prefix = EAP_AKA_REAUTH_ID_PREFIX; 102104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt break; 102204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt case EAP_SIM_DB_AKA_PRIME: 102304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt prefix = EAP_AKA_PRIME_REAUTH_ID_PREFIX; 102404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt break; 102504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 102604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 102704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return eap_sim_db_get_next(data, prefix); 10288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 10298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 10328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_sim_db_add_pseudonym - EAP-SIM DB: Add new pseudonym 10334530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt * @data: Private data pointer from eap_sim_db_init() 10344530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt * @permanent: Permanent username 10358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @pseudonym: Pseudonym for this user. This needs to be an allocated buffer, 10368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * e.g., return value from eap_sim_db_get_next_pseudonym(). Caller must not 10378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * free it. 10388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 on success, -1 on failure 10398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 10408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function adds a new pseudonym for EAP-SIM user. EAP-SIM DB is 10418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * responsible of freeing pseudonym buffer once it is not needed anymore. 10428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 10434530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidtint eap_sim_db_add_pseudonym(struct eap_sim_db_data *data, 10444530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt const char *permanent, char *pseudonym) 10458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 10468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_sim_pseudonym *p; 10474530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SIM DB: Add pseudonym '%s' for permanent " 10484530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt "username '%s'", pseudonym, permanent); 10498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* TODO: could store last two pseudonyms */ 10514530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt#ifdef CONFIG_SQLITE 10524530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (data->sqlite_db) 10534530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt return db_add_pseudonym(data, permanent, pseudonym); 10544530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt#endif /* CONFIG_SQLITE */ 10554530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt for (p = data->pseudonyms; p; p = p->next) { 10564530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (os_strcmp(permanent, p->permanent) == 0) 10574530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt break; 10584530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt } 10598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p) { 10608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SIM DB: Replacing previous " 10618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "pseudonym: %s", p->pseudonym); 10628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(p->pseudonym); 10638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p->pseudonym = pseudonym; 10648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 10658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p = os_zalloc(sizeof(*p)); 10688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p == NULL) { 10698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(pseudonym); 10708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 10718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p->next = data->pseudonyms; 10744530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt p->permanent = os_strdup(permanent); 10754530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (p->permanent == NULL) { 10768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(p); 10778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(pseudonym); 10788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 10798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p->pseudonym = pseudonym; 10818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->pseudonyms = p; 10828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SIM DB: Added new pseudonym entry"); 10848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 10858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 10868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct eap_sim_reauth * 10894530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidteap_sim_db_add_reauth_data(struct eap_sim_db_data *data, 10904530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt const char *permanent, 10914530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt char *reauth_id, u16 counter) 10928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 10938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_sim_reauth *r; 10948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10954530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt for (r = data->reauths; r; r = r->next) { 10964530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (os_strcmp(r->permanent, permanent) == 0) 10974530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt break; 10984530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt } 10998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (r) { 11018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SIM DB: Replacing previous " 11028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "reauth_id: %s", r->reauth_id); 11038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(r->reauth_id); 11048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt r->reauth_id = reauth_id; 11058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 11068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt r = os_zalloc(sizeof(*r)); 11078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (r == NULL) { 11088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(reauth_id); 11098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 11108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt r->next = data->reauths; 11134530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt r->permanent = os_strdup(permanent); 11144530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (r->permanent == NULL) { 11158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(r); 11168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(reauth_id); 11178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 11188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt r->reauth_id = reauth_id; 11208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->reauths = r; 11218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SIM DB: Added new reauth entry"); 11228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt r->counter = counter; 11258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return r; 11278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 11288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 11318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_sim_db_add_reauth - EAP-SIM DB: Add new re-authentication entry 11328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @priv: Private data pointer from eap_sim_db_init() 11334530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt * @permanent: Permanent username 11348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @identity_len: Length of identity 11358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @reauth_id: reauth_id for this user. This needs to be an allocated buffer, 11368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * e.g., return value from eap_sim_db_get_next_reauth_id(). Caller must not 11378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * free it. 11388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @counter: AT_COUNTER value for fast re-authentication 11398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @mk: 16-byte MK from the previous full authentication or %NULL 11408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 on success, -1 on failure 11418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 11428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function adds a new re-authentication entry for an EAP-SIM user. 11438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * EAP-SIM DB is responsible of freeing reauth_id buffer once it is not needed 11448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * anymore. 11458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 11464530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidtint eap_sim_db_add_reauth(struct eap_sim_db_data *data, const char *permanent, 11474530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt char *reauth_id, u16 counter, const u8 *mk) 11488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 11498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_sim_reauth *r; 11508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11514530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SIM DB: Add reauth_id '%s' for permanent " 11524530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt "identity '%s'", reauth_id, permanent); 11534530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 11544530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt#ifdef CONFIG_SQLITE 11554530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (data->sqlite_db) 11564530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt return db_add_reauth(data, permanent, reauth_id, counter, mk, 11574530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt NULL, NULL, NULL); 11584530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt#endif /* CONFIG_SQLITE */ 11594530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt r = eap_sim_db_add_reauth_data(data, permanent, reauth_id, counter); 11608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (r == NULL) 11618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 11628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(r->mk, mk, EAP_SIM_MK_LEN); 11648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 11668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 11678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef EAP_SERVER_AKA_PRIME 11708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 11718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_sim_db_add_reauth_prime - EAP-AKA' DB: Add new re-authentication entry 11724530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt * @data: Private data pointer from eap_sim_db_init() 11734530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt * @permanent: Permanent username 11748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @reauth_id: reauth_id for this user. This needs to be an allocated buffer, 11758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * e.g., return value from eap_sim_db_get_next_reauth_id(). Caller must not 11768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * free it. 11778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @counter: AT_COUNTER value for fast re-authentication 11788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @k_encr: K_encr from the previous full authentication 11798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @k_aut: K_aut from the previous full authentication 11808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @k_re: 32-byte K_re from the previous full authentication 11818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 on success, -1 on failure 11828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 11838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function adds a new re-authentication entry for an EAP-AKA' user. 11848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * EAP-SIM DB is responsible of freeing reauth_id buffer once it is not needed 11858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * anymore. 11868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 11874530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidtint eap_sim_db_add_reauth_prime(struct eap_sim_db_data *data, 11884530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt const char *permanent, char *reauth_id, 11894530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt u16 counter, const u8 *k_encr, 11904530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt const u8 *k_aut, const u8 *k_re) 11918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 11928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_sim_reauth *r; 11938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11944530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SIM DB: Add reauth_id '%s' for permanent " 11954530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt "identity '%s'", reauth_id, permanent); 11964530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 11974530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt#ifdef CONFIG_SQLITE 11984530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (data->sqlite_db) 11994530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt return db_add_reauth(data, permanent, reauth_id, counter, NULL, 12004530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt k_encr, k_aut, k_re); 12014530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt#endif /* CONFIG_SQLITE */ 12024530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt r = eap_sim_db_add_reauth_data(data, permanent, reauth_id, counter); 12038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (r == NULL) 12048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 12058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(r->k_encr, k_encr, EAP_SIM_K_ENCR_LEN); 12078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(r->k_aut, k_aut, EAP_AKA_PRIME_K_AUT_LEN); 12088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(r->k_re, k_re, EAP_AKA_PRIME_K_RE_LEN); 12098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 12118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 12128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* EAP_SERVER_AKA_PRIME */ 12138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 12168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_sim_db_get_permanent - EAP-SIM DB: Get permanent identity 12174530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt * @data: Private data pointer from eap_sim_db_init() 12184530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt * @pseudonym: Pseudonym username 12194530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt * Returns: Pointer to permanent username or %NULL if not found 12208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 12214530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidtconst char * 12224530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidteap_sim_db_get_permanent(struct eap_sim_db_data *data, const char *pseudonym) 12238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 12248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_sim_pseudonym *p; 12258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12264530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt#ifdef CONFIG_SQLITE 12274530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (data->sqlite_db) 12284530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt return db_get_pseudonym(data, pseudonym); 12294530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt#endif /* CONFIG_SQLITE */ 12308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12314530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt p = data->pseudonyms; 12324530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt while (p) { 12334530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (os_strcmp(p->pseudonym, pseudonym) == 0) 12344530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt return p->permanent; 12354530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt p = p->next; 12364530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt } 12378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12384530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt return NULL; 12398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 12408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 12438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_sim_db_get_reauth_entry - EAP-SIM DB: Get re-authentication entry 12444530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt * @data: Private data pointer from eap_sim_db_init() 12454530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt * @reauth_id: Fast re-authentication username 12468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: Pointer to the re-auth entry, or %NULL if not found 12478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 12488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct eap_sim_reauth * 12494530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidteap_sim_db_get_reauth_entry(struct eap_sim_db_data *data, 12504530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt const char *reauth_id) 12518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 12528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_sim_reauth *r; 12538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12544530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt#ifdef CONFIG_SQLITE 12554530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (data->sqlite_db) 12564530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt return db_get_reauth(data, reauth_id); 12574530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt#endif /* CONFIG_SQLITE */ 12584530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 12594530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt r = data->reauths; 12604530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt while (r) { 12614530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (os_strcmp(r->reauth_id, reauth_id) == 0) 12624530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt break; 12634530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt r = r->next; 12644530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt } 12654530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 12668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return r; 12678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 12688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 12718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_sim_db_remove_reauth - EAP-SIM DB: Remove re-authentication entry 12724530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt * @data: Private data pointer from eap_sim_db_init() 12738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @reauth: Pointer to re-authentication entry from 12748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_sim_db_get_reauth_entry() 12758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 12764530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidtvoid eap_sim_db_remove_reauth(struct eap_sim_db_data *data, 12774530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt struct eap_sim_reauth *reauth) 12788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 12798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_sim_reauth *r, *prev = NULL; 12804530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt#ifdef CONFIG_SQLITE 12814530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (data->sqlite_db) { 12824530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt db_remove_reauth(data, reauth); 12834530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt return; 12844530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt } 12854530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt#endif /* CONFIG_SQLITE */ 12868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt r = data->reauths; 12878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (r) { 12888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (r == reauth) { 12898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (prev) 12908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt prev->next = r->next; 12918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 12928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->reauths = r->next; 12938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_sim_db_free_reauth(r); 12948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 12958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 12968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt prev = r; 12978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt r = r->next; 12988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 12998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 13008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 13038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_sim_db_get_aka_auth - Get AKA authentication values 13044530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt * @data: Private data pointer from eap_sim_db_init() 13054530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt * @username: Permanent username (prefix | IMSI) 13068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @_rand: Buffer for RAND value 13078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @autn: Buffer for AUTN value 13088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @ik: Buffer for IK value 13098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @ck: Buffer for CK value 13108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @res: Buffer for RES value 13118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @res_len: Buffer for RES length 13128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @cb_session_ctx: Session callback context for get_complete_cb() 13138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 on success, -1 (EAP_SIM_DB_FAILURE) on error (e.g., user not 13148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * found), or -2 (EAP_SIM_DB_PENDING) if results are not yet available. In this 13158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * case, the callback function registered with eap_sim_db_init() will be 13168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * called once the results become available. 13178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 13188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * When using an external server for AKA authentication, this function can 13198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * always start a request and return EAP_SIM_DB_PENDING immediately if 13208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * authentication triplets are not available. Once the authentication data are 13218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * received, callback function registered with eap_sim_db_init() is called to 13228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * notify EAP state machine to reprocess the message. This 13238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_sim_db_get_aka_auth() function will then be called again and the newly 13248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * received triplets will then be given to the caller. 13258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 13264530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidtint eap_sim_db_get_aka_auth(struct eap_sim_db_data *data, const char *username, 13274530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt u8 *_rand, u8 *autn, u8 *ik, u8 *ck, 13284530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt u8 *res, size_t *res_len, void *cb_session_ctx) 13298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 13308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_sim_db_pending *entry; 13318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int len; 13328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char msg[40]; 13334530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt const char *imsi; 13344530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt size_t imsi_len; 13358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13364530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (username == NULL || 13374530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt (username[0] != EAP_AKA_PERMANENT_PREFIX && 13384530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt username[0] != EAP_AKA_PRIME_PERMANENT_PREFIX) || 13394530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt username[1] == '\0' || os_strlen(username) > sizeof(entry->imsi)) { 13404530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SIM DB: unexpected username '%s'", 13414530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt username); 13428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return EAP_SIM_DB_FAILURE; 13438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13444530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt imsi = username + 1; 13454530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SIM DB: Get AKA auth for IMSI '%s'", 13464530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt imsi); 13478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13484530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt entry = eap_sim_db_get_pending(data, imsi, 1); 13498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (entry) { 13508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (entry->state == FAILURE) { 13518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(entry); 13528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SIM DB: Failure"); 13538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return EAP_SIM_DB_FAILURE; 13548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (entry->state == PENDING) { 13578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_sim_db_add_pending(data, entry); 13588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SIM DB: Pending"); 13598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return EAP_SIM_DB_PENDING; 13608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SIM DB: Returning successfully " 13638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "received authentication data"); 13648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(_rand, entry->u.aka.rand, EAP_AKA_RAND_LEN); 13658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(autn, entry->u.aka.autn, EAP_AKA_AUTN_LEN); 13668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(ik, entry->u.aka.ik, EAP_AKA_IK_LEN); 13678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(ck, entry->u.aka.ck, EAP_AKA_CK_LEN); 13688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(res, entry->u.aka.res, EAP_AKA_RES_MAX_LEN); 13698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *res_len = entry->u.aka.res_len; 13708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(entry); 13718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 13728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data->sock < 0) { 13758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (eap_sim_db_open_socket(data) < 0) 13768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return EAP_SIM_DB_FAILURE; 13778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13794530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt imsi_len = os_strlen(imsi); 13808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = os_snprintf(msg, sizeof(msg), "AKA-REQ-AUTH "); 13814530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (len < 0 || len + imsi_len >= sizeof(msg)) 13828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return EAP_SIM_DB_FAILURE; 13834530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt os_memcpy(msg + len, imsi, imsi_len); 13844530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt len += imsi_len; 13858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13864530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SIM DB: requesting AKA authentication " 13874530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt "data for IMSI '%s'", imsi); 13888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (eap_sim_db_send(data, msg, len) < 0) 13898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return EAP_SIM_DB_FAILURE; 13908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt entry = os_zalloc(sizeof(*entry)); 13928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (entry == NULL) 13938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return EAP_SIM_DB_FAILURE; 13948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_get_time(&entry->timestamp); 13968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt entry->aka = 1; 13974530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt os_strlcpy(entry->imsi, imsi, sizeof(entry->imsi)); 13988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt entry->cb_session_ctx = cb_session_ctx; 13998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt entry->state = PENDING; 14008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_sim_db_add_pending(data, entry); 14018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_sim_db_expire_pending(data); 14028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return EAP_SIM_DB_PENDING; 14048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 14058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 14088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_sim_db_resynchronize - Resynchronize AKA AUTN 14094530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt * @data: Private data pointer from eap_sim_db_init() 14104530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt * @username: Permanent username 14118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @auts: AUTS value from the peer 14128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @_rand: RAND value used in the rejected message 14138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 on success, -1 on failure 14148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 14158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function is called when the peer reports synchronization failure in the 14168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * AUTN value by sending AUTS. The AUTS and RAND values should be sent to 14178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * HLR/AuC to allow it to resynchronize with the peer. After this, 14188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_sim_db_get_aka_auth() will be called again to to fetch updated 14198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * RAND/AUTN values for the next challenge. 14208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 14214530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidtint eap_sim_db_resynchronize(struct eap_sim_db_data *data, 14224530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt const char *username, 14234530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt const u8 *auts, const u8 *_rand) 14248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 14254530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt const char *imsi; 14264530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt size_t imsi_len; 14278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14284530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (username == NULL || 14294530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt (username[0] != EAP_AKA_PERMANENT_PREFIX && 14304530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt username[0] != EAP_AKA_PRIME_PERMANENT_PREFIX) || 14314530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt username[1] == '\0' || os_strlen(username) > 20) { 14324530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SIM DB: unexpected username '%s'", 14334530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt username); 14348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 14358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 14364530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt imsi = username + 1; 14374530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SIM DB: Get AKA auth for IMSI '%s'", 14384530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt imsi); 14398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data->sock >= 0) { 14418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char msg[100]; 14428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int len, ret; 14438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14444530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt imsi_len = os_strlen(imsi); 14458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = os_snprintf(msg, sizeof(msg), "AKA-AUTS "); 14464530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (len < 0 || len + imsi_len >= sizeof(msg)) 14478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 14484530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt os_memcpy(msg + len, imsi, imsi_len); 14494530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt len += imsi_len; 14508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = os_snprintf(msg + len, sizeof(msg) - len, " "); 14528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret < 0 || (size_t) ret >= sizeof(msg) - len) 14538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 14548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len += ret; 14558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len += wpa_snprintf_hex(msg + len, sizeof(msg) - len, 14568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt auts, EAP_AKA_AUTS_LEN); 14578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = os_snprintf(msg + len, sizeof(msg) - len, " "); 14588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret < 0 || (size_t) ret >= sizeof(msg) - len) 14598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 14608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len += ret; 14618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len += wpa_snprintf_hex(msg + len, sizeof(msg) - len, 14628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt _rand, EAP_AKA_RAND_LEN); 14634530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-SIM DB: reporting AKA AUTS for " 14644530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt "IMSI '%s'", imsi); 14658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (eap_sim_db_send(data, msg, len) < 0) 14668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 14678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 14688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 14708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 14714530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 14724530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 14734530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt/** 14744530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt * sim_get_username - Extract username from SIM identity 14754530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt * @identity: Identity 14764530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt * @identity_len: Identity length 14774530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt * Returns: Allocated buffer with the username part of the identity 14784530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt * 14794530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt * Caller is responsible for freeing the returned buffer with os_free(). 14804530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt */ 14814530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidtchar * sim_get_username(const u8 *identity, size_t identity_len) 14824530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt{ 14834530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt char *username; 14844530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt size_t pos; 14854530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 14864530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (identity == NULL) 14874530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt return NULL; 14884530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 14894530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt for (pos = 0; pos < identity_len; pos++) { 14904530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (identity[pos] == '@' || identity[pos] == '\0') 14914530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt break; 14924530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt } 14934530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 14944530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt username = os_malloc(pos + 1); 14954530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (username == NULL) 14964530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt return NULL; 14974530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt os_memcpy(username, identity, pos); 14984530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt username[pos] = '\0'; 14994530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 15004530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt return username; 15014530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt} 1502