18d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* 28d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * HLR/AuC testing gateway for hostapd EAP-SIM/AKA database/authenticator 35605286c30e1701491bd3af974ae423727750eddDmitry Shmidt * Copyright (c) 2005-2007, 2012-2013, 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 to HLR/AuC. It is expected to be replaced with an 108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * implementation of SS7 gateway to GSM/UMTS authentication center (HLR/AuC) or 118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * a local implementation of SIM triplet and AKA authentication data generator. 128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * hostapd will send SIM/AKA authentication queries over a UNIX domain socket 148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * to and external program, e.g., this hlr_auc_gw. This interface uses simple 158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * text-based format: 168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * EAP-SIM / GSM triplet query/response: 188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * SIM-REQ-AUTH <IMSI> <max_chal> 198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * SIM-RESP-AUTH <IMSI> Kc1:SRES1:RAND1 Kc2:SRES2:RAND2 [Kc3:SRES3:RAND3] 208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * SIM-RESP-AUTH <IMSI> FAILURE 21051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt * GSM-AUTH-REQ <IMSI> RAND1:RAND2[:RAND3] 22051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt * GSM-AUTH-RESP <IMSI> Kc1:SRES1:Kc2:SRES2[:Kc3:SRES3] 23051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt * GSM-AUTH-RESP <IMSI> FAILURE 248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * EAP-AKA / UMTS query/response: 268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * AKA-REQ-AUTH <IMSI> 278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * AKA-RESP-AUTH <IMSI> <RAND> <AUTN> <IK> <CK> <RES> 288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * AKA-RESP-AUTH <IMSI> FAILURE 298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * EAP-AKA / UMTS AUTS (re-synchronization): 318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * AKA-AUTS <IMSI> <AUTS> <RAND> 328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * IMSI and max_chal are sent as an ASCII string, 348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Kc/SRES/RAND/AUTN/IK/CK/RES/AUTS as hex strings. 358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 365605286c30e1701491bd3af974ae423727750eddDmitry Shmidt * An example implementation here reads GSM authentication triplets from a 378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * text file in IMSI:Kc:SRES:RAND format, IMSI in ASCII, other fields as hex 388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * strings. This is used to simulate an HLR/AuC. As such, it is not very useful 398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * for real life authentication, but it is useful both as an example 4004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * implementation and for EAP-SIM/AKA/AKA' testing. 4104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * 425605286c30e1701491bd3af974ae423727750eddDmitry Shmidt * For a stronger example design, Milenage and GSM-Milenage algorithms can be 435605286c30e1701491bd3af974ae423727750eddDmitry Shmidt * used to dynamically generate authenticatipn information for EAP-AKA/AKA' and 445605286c30e1701491bd3af974ae423727750eddDmitry Shmidt * EAP-SIM, respectively, if Ki is known. 455605286c30e1701491bd3af974ae423727750eddDmitry Shmidt * 4604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * SQN generation follows the not time-based Profile 2 described in 4704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * 3GPP TS 33.102 Annex C.3.2. The length of IND is 5 bits by default, but this 4804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * can be changed with a command line options if needed. 498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "includes.h" 528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include <sys/un.h> 5361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#ifdef CONFIG_SQLITE 5461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#include <sqlite3.h> 5561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif /* CONFIG_SQLITE */ 568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common.h" 588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "crypto/milenage.h" 598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "crypto/random.h" 608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic const char *default_socket_path = "/tmp/hlr_auc_gw.sock"; 628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic const char *socket_path; 638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int serv_sock = -1; 6404949598a23f501be6eec21697465fd46a28840aDmitry Shmidtstatic char *milenage_file = NULL; 6504949598a23f501be6eec21697465fd46a28840aDmitry Shmidtstatic int update_milenage = 0; 6604949598a23f501be6eec21697465fd46a28840aDmitry Shmidtstatic int sqn_changes = 0; 6704949598a23f501be6eec21697465fd46a28840aDmitry Shmidtstatic int ind_len = 5; 685605286c30e1701491bd3af974ae423727750eddDmitry Shmidtstatic int stdout_debug = 1; 698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* GSM triplets */ 718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct gsm_triplet { 728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct gsm_triplet *next; 738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char imsi[20]; 748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 kc[8]; 758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 sres[4]; 768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 _rand[16]; 778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}; 788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct gsm_triplet *gsm_db = NULL, *gsm_db_pos = NULL; 808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* OPc and AMF parameters for Milenage (Example algorithms for AKA). */ 828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct milenage_parameters { 838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct milenage_parameters *next; 848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char imsi[20]; 858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 ki[16]; 868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 opc[16]; 878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 amf[2]; 888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 sqn[6]; 894530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt int set; 908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}; 918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct milenage_parameters *milenage_db = NULL; 938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define EAP_SIM_MAX_CHAL 3 958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define EAP_AKA_RAND_LEN 16 978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define EAP_AKA_AUTN_LEN 16 988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define EAP_AKA_AUTS_LEN 14 998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define EAP_AKA_RES_MAX_LEN 16 1008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define EAP_AKA_IK_LEN 16 1018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define EAP_AKA_CK_LEN 16 1028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#ifdef CONFIG_SQLITE 10561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 10661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtstatic sqlite3 *sqlite_db = NULL; 10761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtstatic struct milenage_parameters db_tmp_milenage; 10861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 10961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 11061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtstatic int db_table_exists(sqlite3 *db, const char *name) 11161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 11261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt char cmd[128]; 11361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt os_snprintf(cmd, sizeof(cmd), "SELECT 1 FROM %s;", name); 11461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return sqlite3_exec(db, cmd, NULL, NULL, NULL) == SQLITE_OK; 11561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 11661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 11761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 11861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtstatic int db_table_create_milenage(sqlite3 *db) 11961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 12061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt char *err = NULL; 12161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt const char *sql = 12261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt "CREATE TABLE milenage(" 12361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt " imsi INTEGER PRIMARY KEY NOT NULL," 12461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt " ki CHAR(32) NOT NULL," 12561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt " opc CHAR(32) NOT NULL," 12661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt " amf CHAR(4) NOT NULL," 12761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt " sqn CHAR(12) NOT NULL" 12861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt ");"; 12961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 13061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt printf("Adding database table for milenage information\n"); 13161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (sqlite3_exec(db, sql, NULL, NULL, &err) != SQLITE_OK) { 13261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt printf("SQLite error: %s\n", err); 13361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt sqlite3_free(err); 13461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return -1; 13561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 13661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 13761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 0; 13861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 13961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 14061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 14161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtstatic sqlite3 * db_open(const char *db_file) 14261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 14361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt sqlite3 *db; 14461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 14561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (sqlite3_open(db_file, &db)) { 14661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt printf("Failed to open database %s: %s\n", 14761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt db_file, sqlite3_errmsg(db)); 14861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt sqlite3_close(db); 14961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return NULL; 15061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 15161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 15261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (!db_table_exists(db, "milenage") && 15361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt db_table_create_milenage(db) < 0) { 15461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt sqlite3_close(db); 15561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return NULL; 15661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 15761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 15861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return db; 15961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 16061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 16161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 16261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtstatic int get_milenage_cb(void *ctx, int argc, char *argv[], char *col[]) 16361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 16461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt struct milenage_parameters *m = ctx; 16561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt int i; 16661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 1674530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt m->set = 1; 1684530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 16961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt for (i = 0; i < argc; i++) { 17061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (os_strcmp(col[i], "ki") == 0 && argv[i] && 17161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt hexstr2bin(argv[i], m->ki, sizeof(m->ki))) { 17261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt printf("Invalid ki value in database\n"); 17361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return -1; 17461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 17561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 17661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (os_strcmp(col[i], "opc") == 0 && argv[i] && 17761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt hexstr2bin(argv[i], m->opc, sizeof(m->opc))) { 17861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt printf("Invalid opcvalue in database\n"); 17961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return -1; 18061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 18161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 18261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (os_strcmp(col[i], "amf") == 0 && argv[i] && 18361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt hexstr2bin(argv[i], m->amf, sizeof(m->amf))) { 18461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt printf("Invalid amf value in database\n"); 18561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return -1; 18661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 18761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 18861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (os_strcmp(col[i], "sqn") == 0 && argv[i] && 18961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt hexstr2bin(argv[i], m->sqn, sizeof(m->sqn))) { 19061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt printf("Invalid sqn value in database\n"); 19161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return -1; 19261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 19361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 19461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 19561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 0; 19661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 19761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 19861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 19961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtstatic struct milenage_parameters * db_get_milenage(const char *imsi_txt) 20061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 20161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt char cmd[128]; 20261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt unsigned long long imsi; 20361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 20461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt os_memset(&db_tmp_milenage, 0, sizeof(db_tmp_milenage)); 20561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt imsi = atoll(imsi_txt); 20661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt os_snprintf(db_tmp_milenage.imsi, sizeof(db_tmp_milenage.imsi), 20761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt "%llu", imsi); 20861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt os_snprintf(cmd, sizeof(cmd), 20961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt "SELECT ki,opc,amf,sqn FROM milenage WHERE imsi=%llu;", 21061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt imsi); 21161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (sqlite3_exec(sqlite_db, cmd, get_milenage_cb, &db_tmp_milenage, 21261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt NULL) != SQLITE_OK) 21361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return NULL; 21461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 2154530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (!db_tmp_milenage.set) 2164530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt return NULL; 21761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return &db_tmp_milenage; 21861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 21961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 22061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 22161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtstatic int db_update_milenage_sqn(struct milenage_parameters *m) 22261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 22361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt char cmd[128], val[13], *pos; 22461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 2255605286c30e1701491bd3af974ae423727750eddDmitry Shmidt if (sqlite_db == NULL) 2265605286c30e1701491bd3af974ae423727750eddDmitry Shmidt return 0; 2275605286c30e1701491bd3af974ae423727750eddDmitry Shmidt 22861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt pos = val; 22961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt pos += wpa_snprintf_hex(pos, sizeof(val), m->sqn, 6); 23061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt *pos = '\0'; 23161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt os_snprintf(cmd, sizeof(cmd), 23261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt "UPDATE milenage SET sqn='%s' WHERE imsi=%s;", 23361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt val, m->imsi); 23461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (sqlite3_exec(sqlite_db, cmd, NULL, NULL, NULL) != SQLITE_OK) { 23561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt printf("Failed to update SQN in database for IMSI %s\n", 23661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt m->imsi); 23761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return -1; 23861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 23961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 0; 24061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 24161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 24261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif /* CONFIG_SQLITE */ 24361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 24461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 2458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int open_socket(const char *path) 2468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct sockaddr_un addr; 2488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int s; 2498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt s = socket(PF_UNIX, SOCK_DGRAM, 0); 2518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (s < 0) { 2528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt perror("socket(PF_UNIX)"); 2538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 2548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt memset(&addr, 0, sizeof(addr)); 2578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt addr.sun_family = AF_UNIX; 2588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_strlcpy(addr.sun_path, path, sizeof(addr.sun_path)); 2598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (bind(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) { 26004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt perror("hlr-auc-gw: bind(PF_UNIX)"); 2618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt close(s); 2628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 2638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return s; 2668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int read_gsm_triplets(const char *fname) 2708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt FILE *f; 2728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char buf[200], *pos, *pos2; 2738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct gsm_triplet *g = NULL; 2748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int line, ret = 0; 2758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (fname == NULL) 2778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 2788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt f = fopen(fname, "r"); 2808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (f == NULL) { 2818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt printf("Could not open GSM tripler data file '%s'\n", fname); 2828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 2838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt line = 0; 2868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (fgets(buf, sizeof(buf), f)) { 2878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt line++; 2888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Parse IMSI:Kc:SRES:RAND */ 2908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf[sizeof(buf) - 1] = '\0'; 2918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (buf[0] == '#') 2928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 2938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = buf; 2948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (*pos != '\0' && *pos != '\n') 2958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos++; 2968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (*pos == '\n') 2978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos = '\0'; 2988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = buf; 2998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (*pos == '\0') 3008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 3018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt g = os_zalloc(sizeof(*g)); 3038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (g == NULL) { 3048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = -1; 3058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 3068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* IMSI */ 3098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos2 = strchr(pos, ':'); 3108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pos2 == NULL) { 3118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt printf("%s:%d - Invalid IMSI (%s)\n", 3128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt fname, line, pos); 3138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = -1; 3148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 3158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos2 = '\0'; 3178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (strlen(pos) >= sizeof(g->imsi)) { 3188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt printf("%s:%d - Too long IMSI (%s)\n", 3198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt fname, line, pos); 3208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = -1; 3218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 3228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_strlcpy(g->imsi, pos, sizeof(g->imsi)); 3248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = pos2 + 1; 3258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Kc */ 3278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos2 = strchr(pos, ':'); 3288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pos2 == NULL) { 3298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt printf("%s:%d - Invalid Kc (%s)\n", fname, line, pos); 3308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = -1; 3318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 3328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos2 = '\0'; 3348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (strlen(pos) != 16 || hexstr2bin(pos, g->kc, 8)) { 3358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt printf("%s:%d - Invalid Kc (%s)\n", fname, line, pos); 3368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = -1; 3378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 3388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = pos2 + 1; 3408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* SRES */ 3428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos2 = strchr(pos, ':'); 3438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pos2 == NULL) { 3448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt printf("%s:%d - Invalid SRES (%s)\n", fname, line, 3458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos); 3468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = -1; 3478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 3488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos2 = '\0'; 3508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (strlen(pos) != 8 || hexstr2bin(pos, g->sres, 4)) { 3518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt printf("%s:%d - Invalid SRES (%s)\n", fname, line, 3528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos); 3538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = -1; 3548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 3558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = pos2 + 1; 3578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* RAND */ 3598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos2 = strchr(pos, ':'); 3608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pos2) 3618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos2 = '\0'; 3628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (strlen(pos) != 32 || hexstr2bin(pos, g->_rand, 16)) { 3638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt printf("%s:%d - Invalid RAND (%s)\n", fname, line, 3648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos); 3658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = -1; 3668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 3678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = pos2 + 1; 3698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt g->next = gsm_db; 3718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt gsm_db = g; 3728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt g = NULL; 3738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 37404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt os_free(g); 3758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt fclose(f); 3778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return ret; 3798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct gsm_triplet * get_gsm_triplet(const char *imsi) 3838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct gsm_triplet *g = gsm_db_pos; 3858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (g) { 3878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (strcmp(g->imsi, imsi) == 0) { 3888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt gsm_db_pos = g->next; 3898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return g; 3908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt g = g->next; 3928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt g = gsm_db; 3958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (g && g != gsm_db_pos) { 3968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (strcmp(g->imsi, imsi) == 0) { 3978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt gsm_db_pos = g->next; 3988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return g; 3998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt g = g->next; 4018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 4048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int read_milenage(const char *fname) 4088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt FILE *f; 4108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char buf[200], *pos, *pos2; 4118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct milenage_parameters *m = NULL; 4128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int line, ret = 0; 4138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (fname == NULL) 4158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 4168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt f = fopen(fname, "r"); 4188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (f == NULL) { 4198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt printf("Could not open Milenage data file '%s'\n", fname); 4208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 4218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt line = 0; 4248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (fgets(buf, sizeof(buf), f)) { 4258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt line++; 4268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Parse IMSI Ki OPc AMF SQN */ 4288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf[sizeof(buf) - 1] = '\0'; 4298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (buf[0] == '#') 4308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 4318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = buf; 4328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (*pos != '\0' && *pos != '\n') 4338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos++; 4348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (*pos == '\n') 4358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos = '\0'; 4368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = buf; 4378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (*pos == '\0') 4388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 4398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt m = os_zalloc(sizeof(*m)); 4418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (m == NULL) { 4428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = -1; 4438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 4448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* IMSI */ 4478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos2 = strchr(pos, ' '); 4488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pos2 == NULL) { 4498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt printf("%s:%d - Invalid IMSI (%s)\n", 4508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt fname, line, pos); 4518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = -1; 4528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 4538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos2 = '\0'; 4558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (strlen(pos) >= sizeof(m->imsi)) { 4568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt printf("%s:%d - Too long IMSI (%s)\n", 4578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt fname, line, pos); 4588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = -1; 4598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 4608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_strlcpy(m->imsi, pos, sizeof(m->imsi)); 4628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = pos2 + 1; 4638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Ki */ 4658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos2 = strchr(pos, ' '); 4668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pos2 == NULL) { 4678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt printf("%s:%d - Invalid Ki (%s)\n", fname, line, pos); 4688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = -1; 4698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 4708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos2 = '\0'; 4728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (strlen(pos) != 32 || hexstr2bin(pos, m->ki, 16)) { 4738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt printf("%s:%d - Invalid Ki (%s)\n", fname, line, pos); 4748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = -1; 4758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 4768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = pos2 + 1; 4788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* OPc */ 4808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos2 = strchr(pos, ' '); 4818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pos2 == NULL) { 4828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt printf("%s:%d - Invalid OPc (%s)\n", fname, line, pos); 4838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = -1; 4848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 4858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos2 = '\0'; 4878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (strlen(pos) != 32 || hexstr2bin(pos, m->opc, 16)) { 4888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt printf("%s:%d - Invalid OPc (%s)\n", fname, line, pos); 4898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = -1; 4908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 4918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = pos2 + 1; 4938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* AMF */ 4958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos2 = strchr(pos, ' '); 4968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pos2 == NULL) { 4978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt printf("%s:%d - Invalid AMF (%s)\n", fname, line, pos); 4988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = -1; 4998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 5008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos2 = '\0'; 5028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (strlen(pos) != 4 || hexstr2bin(pos, m->amf, 2)) { 5038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt printf("%s:%d - Invalid AMF (%s)\n", fname, line, pos); 5048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = -1; 5058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 5068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = pos2 + 1; 5088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* SQN */ 5108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos2 = strchr(pos, ' '); 5118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pos2) 5128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos2 = '\0'; 5138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (strlen(pos) != 12 || hexstr2bin(pos, m->sqn, 6)) { 5148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt printf("%s:%d - Invalid SEQ (%s)\n", fname, line, pos); 5158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = -1; 5168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 5178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = pos2 + 1; 5198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt m->next = milenage_db; 5218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt milenage_db = m; 5228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt m = NULL; 5238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 52404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt os_free(m); 5258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt fclose(f); 5278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return ret; 5298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 5308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 53204949598a23f501be6eec21697465fd46a28840aDmitry Shmidtstatic void update_milenage_file(const char *fname) 53304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{ 53404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt FILE *f, *f2; 53504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt char buf[500], *pos; 53604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt char *end = buf + sizeof(buf); 53704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt struct milenage_parameters *m; 53804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt size_t imsi_len; 53904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 54004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt f = fopen(fname, "r"); 54104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (f == NULL) { 54204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt printf("Could not open Milenage data file '%s'\n", fname); 54304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return; 54404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 54504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 54604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt snprintf(buf, sizeof(buf), "%s.new", fname); 54704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt f2 = fopen(buf, "w"); 54804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (f2 == NULL) { 54904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt printf("Could not write Milenage data file '%s'\n", buf); 55004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt fclose(f); 55104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return; 55204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 55304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 55404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt while (fgets(buf, sizeof(buf), f)) { 55504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt /* IMSI Ki OPc AMF SQN */ 55604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt buf[sizeof(buf) - 1] = '\0'; 55704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 55804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt pos = strchr(buf, ' '); 55904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (buf[0] == '#' || pos == NULL || pos - buf >= 20) 56004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt goto no_update; 56104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 56204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt imsi_len = pos - buf; 56304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 56404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt for (m = milenage_db; m; m = m->next) { 56504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (strncmp(buf, m->imsi, imsi_len) == 0 && 56604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt m->imsi[imsi_len] == '\0') 56704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt break; 56804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 56904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 57004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (!m) 57104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt goto no_update; 57204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 57304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt pos = buf; 57404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt pos += snprintf(pos, end - pos, "%s ", m->imsi); 57504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt pos += wpa_snprintf_hex(pos, end - pos, m->ki, 16); 57604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt *pos++ = ' '; 57704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt pos += wpa_snprintf_hex(pos, end - pos, m->opc, 16); 57804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt *pos++ = ' '; 57904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt pos += wpa_snprintf_hex(pos, end - pos, m->amf, 2); 58004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt *pos++ = ' '; 58104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt pos += wpa_snprintf_hex(pos, end - pos, m->sqn, 6); 58204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt *pos++ = '\n'; 58304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 58404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt no_update: 58504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt fprintf(f2, "%s", buf); 58604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 58704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 58804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt fclose(f2); 58904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt fclose(f); 59004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 59104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt snprintf(buf, sizeof(buf), "%s.bak", fname); 59204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (rename(fname, buf) < 0) { 59304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt perror("rename"); 59404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return; 59504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 59604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 59704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt snprintf(buf, sizeof(buf), "%s.new", fname); 59804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (rename(buf, fname) < 0) { 59904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt perror("rename"); 60004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return; 60104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 60204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 60304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt} 60404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 60504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 6068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct milenage_parameters * get_milenage(const char *imsi) 6078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 6088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct milenage_parameters *m = milenage_db; 6098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (m) { 6118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (strcmp(m->imsi, imsi) == 0) 6128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 6138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt m = m->next; 6148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 61661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#ifdef CONFIG_SQLITE 61761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (!m) 61861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt m = db_get_milenage(imsi); 61961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif /* CONFIG_SQLITE */ 62061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 6218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return m; 6228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 6238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6255605286c30e1701491bd3af974ae423727750eddDmitry Shmidtstatic int sim_req_auth(char *imsi, char *resp, size_t resp_len) 6268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 6278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int count, max_chal, ret; 6288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *pos; 6295605286c30e1701491bd3af974ae423727750eddDmitry Shmidt char *rpos, *rend; 6308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct milenage_parameters *m; 6318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct gsm_triplet *g; 6328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6335605286c30e1701491bd3af974ae423727750eddDmitry Shmidt resp[0] = '\0'; 6348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = strchr(imsi, ' '); 6368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pos) { 6378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos++ = '\0'; 6388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt max_chal = atoi(pos); 6395605286c30e1701491bd3af974ae423727750eddDmitry Shmidt if (max_chal < 1 || max_chal > EAP_SIM_MAX_CHAL) 6408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt max_chal = EAP_SIM_MAX_CHAL; 6418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else 6428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt max_chal = EAP_SIM_MAX_CHAL; 6438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6445605286c30e1701491bd3af974ae423727750eddDmitry Shmidt rend = resp + resp_len; 6455605286c30e1701491bd3af974ae423727750eddDmitry Shmidt rpos = resp; 6468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = snprintf(rpos, rend - rpos, "SIM-RESP-AUTH %s", imsi); 6478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret < 0 || ret >= rend - rpos) 6485605286c30e1701491bd3af974ae423727750eddDmitry Shmidt return -1; 6498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rpos += ret; 6508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt m = get_milenage(imsi); 6528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (m) { 6538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 _rand[16], sres[4], kc[8]; 6548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (count = 0; count < max_chal; count++) { 6558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (random_get_bytes(_rand, 16) < 0) 6565605286c30e1701491bd3af974ae423727750eddDmitry Shmidt return -1; 6578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt gsm_milenage(m->opc, m->ki, _rand, sres, kc); 6588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *rpos++ = ' '; 6598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rpos += wpa_snprintf_hex(rpos, rend - rpos, kc, 8); 6608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *rpos++ = ':'; 6618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rpos += wpa_snprintf_hex(rpos, rend - rpos, sres, 4); 6628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *rpos++ = ':'; 6638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rpos += wpa_snprintf_hex(rpos, rend - rpos, _rand, 16); 6648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *rpos = '\0'; 6665605286c30e1701491bd3af974ae423727750eddDmitry Shmidt return 0; 6678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt count = 0; 6708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (count < max_chal && (g = get_gsm_triplet(imsi))) { 6718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (strcmp(g->imsi, imsi) != 0) 6728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 6738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (rpos < rend) 6758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *rpos++ = ' '; 6768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rpos += wpa_snprintf_hex(rpos, rend - rpos, g->kc, 8); 6778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (rpos < rend) 6788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *rpos++ = ':'; 6798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rpos += wpa_snprintf_hex(rpos, rend - rpos, g->sres, 4); 6808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (rpos < rend) 6818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *rpos++ = ':'; 6828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rpos += wpa_snprintf_hex(rpos, rend - rpos, g->_rand, 16); 6838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt count++; 6848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (count == 0) { 6878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt printf("No GSM triplets found for %s\n", imsi); 6888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = snprintf(rpos, rend - rpos, " FAILURE"); 6898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret < 0 || ret >= rend - rpos) 6905605286c30e1701491bd3af974ae423727750eddDmitry Shmidt return -1; 6918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rpos += ret; 6928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6945605286c30e1701491bd3af974ae423727750eddDmitry Shmidt return 0; 6958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 6968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 698051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidtstatic int gsm_auth_req(char *imsi, char *resp, size_t resp_len) 699051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt{ 700051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt int count, ret; 701051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt char *pos, *rpos, *rend; 702051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt struct milenage_parameters *m; 703051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt 704051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt resp[0] = '\0'; 705051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt 706051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt pos = os_strchr(imsi, ' '); 707051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt if (!pos) 708051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt return -1; 709051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt *pos++ = '\0'; 710051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt 711051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt rend = resp + resp_len; 712051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt rpos = resp; 713051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt ret = os_snprintf(rpos, rend - rpos, "GSM-AUTH-RESP %s", imsi); 714051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt if (ret < 0 || ret >= rend - rpos) 715051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt return -1; 716051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt rpos += ret; 717051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt 718051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt m = get_milenage(imsi); 719051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt if (m) { 720051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt u8 _rand[16], sres[4], kc[8]; 721051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt for (count = 0; count < EAP_SIM_MAX_CHAL; count++) { 722051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt if (hexstr2bin(pos, _rand, 16) != 0) 723051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt return -1; 724051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt gsm_milenage(m->opc, m->ki, _rand, sres, kc); 725051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt *rpos++ = count == 0 ? ' ' : ':'; 726051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt rpos += wpa_snprintf_hex(rpos, rend - rpos, kc, 8); 727051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt *rpos++ = ':'; 728051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt rpos += wpa_snprintf_hex(rpos, rend - rpos, sres, 4); 729051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt pos += 16 * 2; 730051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt if (*pos != ':') 731051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt break; 732051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt pos++; 733051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt } 734051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt *rpos = '\0'; 735051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt return 0; 736051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt } 737051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt 738051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt printf("No GSM triplets found for %s\n", imsi); 739051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt ret = os_snprintf(rpos, rend - rpos, " FAILURE"); 740051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt if (ret < 0 || ret >= rend - rpos) 741051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt return -1; 742051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt rpos += ret; 743051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt 744051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt return 0; 745051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt} 746051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt 747051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt 74804949598a23f501be6eec21697465fd46a28840aDmitry Shmidtstatic void inc_sqn(u8 *sqn) 74904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{ 75004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt u64 val, seq, ind; 75104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 75204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt /* 75304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * SQN = SEQ | IND = SEQ1 | SEQ2 | IND 75404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * 75504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * The mechanism used here is not time-based, so SEQ2 is void and 75604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * SQN = SEQ1 | IND. The length of IND is ind_len bits and the length 75704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * of SEQ1 is 48 - ind_len bits. 75804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt */ 75904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 76004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt /* Increment both SEQ and IND by one */ 76104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt val = ((u64) WPA_GET_BE32(sqn) << 16) | ((u64) WPA_GET_BE16(sqn + 4)); 76204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt seq = (val >> ind_len) + 1; 76304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt ind = (val + 1) & ((1 << ind_len) - 1); 76404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt val = (seq << ind_len) | ind; 76504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt WPA_PUT_BE32(sqn, val >> 16); 76604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt WPA_PUT_BE16(sqn + 4, val & 0xffff); 76704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt} 76804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 76904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 7705605286c30e1701491bd3af974ae423727750eddDmitry Shmidtstatic int aka_req_auth(char *imsi, char *resp, size_t resp_len) 7718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 7728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* AKA-RESP-AUTH <IMSI> <RAND> <AUTN> <IK> <CK> <RES> */ 7735605286c30e1701491bd3af974ae423727750eddDmitry Shmidt char *pos, *end; 7748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 _rand[EAP_AKA_RAND_LEN]; 7758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 autn[EAP_AKA_AUTN_LEN]; 7768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 ik[EAP_AKA_IK_LEN]; 7778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 ck[EAP_AKA_CK_LEN]; 7788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 res[EAP_AKA_RES_MAX_LEN]; 7798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t res_len; 7808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ret; 7818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct milenage_parameters *m; 78261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt int failed = 0; 7838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt m = get_milenage(imsi); 7858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (m) { 7868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (random_get_bytes(_rand, EAP_AKA_RAND_LEN) < 0) 7875605286c30e1701491bd3af974ae423727750eddDmitry Shmidt return -1; 7888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res_len = EAP_AKA_RES_MAX_LEN; 78904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt inc_sqn(m->sqn); 79061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#ifdef CONFIG_SQLITE 79161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt db_update_milenage_sqn(m); 79261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif /* CONFIG_SQLITE */ 79304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt sqn_changes = 1; 7945605286c30e1701491bd3af974ae423727750eddDmitry Shmidt if (stdout_debug) { 7955605286c30e1701491bd3af974ae423727750eddDmitry Shmidt printf("AKA: Milenage with SQN=%02x%02x%02x%02x%02x%02x\n", 7965605286c30e1701491bd3af974ae423727750eddDmitry Shmidt m->sqn[0], m->sqn[1], m->sqn[2], 7975605286c30e1701491bd3af974ae423727750eddDmitry Shmidt m->sqn[3], m->sqn[4], m->sqn[5]); 7985605286c30e1701491bd3af974ae423727750eddDmitry Shmidt } 7998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt milenage_generate(m->opc, m->amf, m->ki, m->sqn, _rand, 8008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt autn, ik, ck, res, &res_len); 8018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 8028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt printf("Unknown IMSI: %s\n", imsi); 8038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef AKA_USE_FIXED_TEST_VALUES 8048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt printf("Using fixed test values for AKA\n"); 8058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt memset(_rand, '0', EAP_AKA_RAND_LEN); 8068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt memset(autn, '1', EAP_AKA_AUTN_LEN); 8078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt memset(ik, '3', EAP_AKA_IK_LEN); 8088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt memset(ck, '4', EAP_AKA_CK_LEN); 8098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt memset(res, '2', EAP_AKA_RES_MAX_LEN); 8108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res_len = EAP_AKA_RES_MAX_LEN; 8118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* AKA_USE_FIXED_TEST_VALUES */ 81261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt failed = 1; 8138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* AKA_USE_FIXED_TEST_VALUES */ 8148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8165605286c30e1701491bd3af974ae423727750eddDmitry Shmidt pos = resp; 8175605286c30e1701491bd3af974ae423727750eddDmitry Shmidt end = resp + resp_len; 8188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = snprintf(pos, end - pos, "AKA-RESP-AUTH %s ", imsi); 8198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret < 0 || ret >= end - pos) 8205605286c30e1701491bd3af974ae423727750eddDmitry Shmidt return -1; 8218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += ret; 82261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (failed) { 82361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt ret = snprintf(pos, end - pos, "FAILURE"); 82461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (ret < 0 || ret >= end - pos) 8255605286c30e1701491bd3af974ae423727750eddDmitry Shmidt return -1; 82661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt pos += ret; 8275605286c30e1701491bd3af974ae423727750eddDmitry Shmidt return 0; 82861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 8298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += wpa_snprintf_hex(pos, end - pos, _rand, EAP_AKA_RAND_LEN); 8308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos++ = ' '; 8318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += wpa_snprintf_hex(pos, end - pos, autn, EAP_AKA_AUTN_LEN); 8328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos++ = ' '; 8338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += wpa_snprintf_hex(pos, end - pos, ik, EAP_AKA_IK_LEN); 8348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos++ = ' '; 8358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += wpa_snprintf_hex(pos, end - pos, ck, EAP_AKA_CK_LEN); 8368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos++ = ' '; 8378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += wpa_snprintf_hex(pos, end - pos, res, res_len); 8388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8395605286c30e1701491bd3af974ae423727750eddDmitry Shmidt return 0; 8408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 8418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8435605286c30e1701491bd3af974ae423727750eddDmitry Shmidtstatic int aka_auts(char *imsi, char *resp, size_t resp_len) 8448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 8458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *auts, *__rand; 8468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 _auts[EAP_AKA_AUTS_LEN], _rand[EAP_AKA_RAND_LEN], sqn[6]; 8478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct milenage_parameters *m; 8488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8495605286c30e1701491bd3af974ae423727750eddDmitry Shmidt resp[0] = '\0'; 8505605286c30e1701491bd3af974ae423727750eddDmitry Shmidt 8518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* AKA-AUTS <IMSI> <AUTS> <RAND> */ 8528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt auts = strchr(imsi, ' '); 8548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (auts == NULL) 8555605286c30e1701491bd3af974ae423727750eddDmitry Shmidt return -1; 8568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *auts++ = '\0'; 8578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt __rand = strchr(auts, ' '); 8598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (__rand == NULL) 8605605286c30e1701491bd3af974ae423727750eddDmitry Shmidt return -1; 8618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *__rand++ = '\0'; 8628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8635605286c30e1701491bd3af974ae423727750eddDmitry Shmidt if (stdout_debug) { 8645605286c30e1701491bd3af974ae423727750eddDmitry Shmidt printf("AKA-AUTS: IMSI=%s AUTS=%s RAND=%s\n", 8655605286c30e1701491bd3af974ae423727750eddDmitry Shmidt imsi, auts, __rand); 8665605286c30e1701491bd3af974ae423727750eddDmitry Shmidt } 8678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hexstr2bin(auts, _auts, EAP_AKA_AUTS_LEN) || 8688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hexstr2bin(__rand, _rand, EAP_AKA_RAND_LEN)) { 8698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt printf("Could not parse AUTS/RAND\n"); 8705605286c30e1701491bd3af974ae423727750eddDmitry Shmidt return -1; 8718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt m = get_milenage(imsi); 8748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (m == NULL) { 8758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt printf("Unknown IMSI: %s\n", imsi); 8765605286c30e1701491bd3af974ae423727750eddDmitry Shmidt return -1; 8778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (milenage_auts(m->opc, m->ki, _rand, _auts, sqn)) { 8808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt printf("AKA-AUTS: Incorrect MAC-S\n"); 8818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 8828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt memcpy(m->sqn, sqn, 6); 8835605286c30e1701491bd3af974ae423727750eddDmitry Shmidt if (stdout_debug) { 8845605286c30e1701491bd3af974ae423727750eddDmitry Shmidt printf("AKA-AUTS: Re-synchronized: " 8855605286c30e1701491bd3af974ae423727750eddDmitry Shmidt "SQN=%02x%02x%02x%02x%02x%02x\n", 8865605286c30e1701491bd3af974ae423727750eddDmitry Shmidt sqn[0], sqn[1], sqn[2], sqn[3], sqn[4], sqn[5]); 8875605286c30e1701491bd3af974ae423727750eddDmitry Shmidt } 88861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#ifdef CONFIG_SQLITE 88961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt db_update_milenage_sqn(m); 89061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif /* CONFIG_SQLITE */ 89104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt sqn_changes = 1; 8928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8935605286c30e1701491bd3af974ae423727750eddDmitry Shmidt 8945605286c30e1701491bd3af974ae423727750eddDmitry Shmidt return 0; 8955605286c30e1701491bd3af974ae423727750eddDmitry Shmidt} 8965605286c30e1701491bd3af974ae423727750eddDmitry Shmidt 8975605286c30e1701491bd3af974ae423727750eddDmitry Shmidt 8985605286c30e1701491bd3af974ae423727750eddDmitry Shmidtstatic int process_cmd(char *cmd, char *resp, size_t resp_len) 8995605286c30e1701491bd3af974ae423727750eddDmitry Shmidt{ 9005605286c30e1701491bd3af974ae423727750eddDmitry Shmidt if (os_strncmp(cmd, "SIM-REQ-AUTH ", 13) == 0) 9015605286c30e1701491bd3af974ae423727750eddDmitry Shmidt return sim_req_auth(cmd + 13, resp, resp_len); 9025605286c30e1701491bd3af974ae423727750eddDmitry Shmidt 903051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt if (os_strncmp(cmd, "GSM-AUTH-REQ ", 13) == 0) 904051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt return gsm_auth_req(cmd + 13, resp, resp_len); 905051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt 9065605286c30e1701491bd3af974ae423727750eddDmitry Shmidt if (os_strncmp(cmd, "AKA-REQ-AUTH ", 13) == 0) 9075605286c30e1701491bd3af974ae423727750eddDmitry Shmidt return aka_req_auth(cmd + 13, resp, resp_len); 9085605286c30e1701491bd3af974ae423727750eddDmitry Shmidt 9095605286c30e1701491bd3af974ae423727750eddDmitry Shmidt if (os_strncmp(cmd, "AKA-AUTS ", 9) == 0) 9105605286c30e1701491bd3af974ae423727750eddDmitry Shmidt return aka_auts(cmd + 9, resp, resp_len); 9115605286c30e1701491bd3af974ae423727750eddDmitry Shmidt 9125605286c30e1701491bd3af974ae423727750eddDmitry Shmidt printf("Unknown request: %s\n", cmd); 9135605286c30e1701491bd3af974ae423727750eddDmitry Shmidt return -1; 9148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 9158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int process(int s) 9188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 9195605286c30e1701491bd3af974ae423727750eddDmitry Shmidt char buf[1000], resp[1000]; 9208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct sockaddr_un from; 9218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt socklen_t fromlen; 9228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssize_t res; 9238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt fromlen = sizeof(from); 9258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = recvfrom(s, buf, sizeof(buf), 0, (struct sockaddr *) &from, 9268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &fromlen); 9278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res < 0) { 9288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt perror("recvfrom"); 9298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 9308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res == 0) 9338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 9348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if ((size_t) res >= sizeof(buf)) 9368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = sizeof(buf) - 1; 9378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf[res] = '\0'; 9388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt printf("Received: %s\n", buf); 9408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9415605286c30e1701491bd3af974ae423727750eddDmitry Shmidt if (process_cmd(buf, resp, sizeof(resp)) < 0) { 9425605286c30e1701491bd3af974ae423727750eddDmitry Shmidt printf("Failed to process request\n"); 9435605286c30e1701491bd3af974ae423727750eddDmitry Shmidt return -1; 9445605286c30e1701491bd3af974ae423727750eddDmitry Shmidt } 9455605286c30e1701491bd3af974ae423727750eddDmitry Shmidt 9465605286c30e1701491bd3af974ae423727750eddDmitry Shmidt if (resp[0] == '\0') { 9475605286c30e1701491bd3af974ae423727750eddDmitry Shmidt printf("No response\n"); 9485605286c30e1701491bd3af974ae423727750eddDmitry Shmidt return 0; 9495605286c30e1701491bd3af974ae423727750eddDmitry Shmidt } 9505605286c30e1701491bd3af974ae423727750eddDmitry Shmidt 9515605286c30e1701491bd3af974ae423727750eddDmitry Shmidt printf("Send: %s\n", resp); 9525605286c30e1701491bd3af974ae423727750eddDmitry Shmidt 9535605286c30e1701491bd3af974ae423727750eddDmitry Shmidt if (sendto(s, resp, os_strlen(resp), 0, (struct sockaddr *) &from, 9545605286c30e1701491bd3af974ae423727750eddDmitry Shmidt fromlen) < 0) 9555605286c30e1701491bd3af974ae423727750eddDmitry Shmidt perror("send"); 9568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 9588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 9598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void cleanup(void) 9628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 9638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct gsm_triplet *g, *gprev; 9648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct milenage_parameters *m, *prev; 9658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 96604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (update_milenage && milenage_file && sqn_changes) 96704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt update_milenage_file(milenage_file); 96804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 9698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt g = gsm_db; 9708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (g) { 9718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt gprev = g; 9728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt g = g->next; 97304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt os_free(gprev); 9748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt m = milenage_db; 9778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (m) { 9788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt prev = m; 9798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt m = m->next; 98004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt os_free(prev); 9818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9835605286c30e1701491bd3af974ae423727750eddDmitry Shmidt if (serv_sock >= 0) 9845605286c30e1701491bd3af974ae423727750eddDmitry Shmidt close(serv_sock); 9855605286c30e1701491bd3af974ae423727750eddDmitry Shmidt if (socket_path) 9865605286c30e1701491bd3af974ae423727750eddDmitry Shmidt unlink(socket_path); 98761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 98861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#ifdef CONFIG_SQLITE 98961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (sqlite_db) { 99061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt sqlite3_close(sqlite_db); 99161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt sqlite_db = NULL; 99261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 99361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif /* CONFIG_SQLITE */ 9948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 9958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void handle_term(int sig) 9988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 9998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt printf("Signal %d - terminate\n", sig); 10008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt exit(0); 10018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 10028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void usage(void) 10058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 10068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt printf("HLR/AuC testing gateway for hostapd EAP-SIM/AKA " 10078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "database/authenticator\n" 10085605286c30e1701491bd3af974ae423727750eddDmitry Shmidt "Copyright (c) 2005-2007, 2012-2013, Jouni Malinen <j@w1.fi>\n" 10098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "\n" 10108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "usage:\n" 101104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt "hlr_auc_gw [-hu] [-s<socket path>] [-g<triplet file>] " 101204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt "[-m<milenage file>] \\\n" 10135605286c30e1701491bd3af974ae423727750eddDmitry Shmidt " [-D<DB file>] [-i<IND len in bits>] [command]\n" 10148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "\n" 10158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "options:\n" 10168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " -h = show this usage help\n" 101704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt " -u = update SQN in Milenage file on exit\n" 10188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " -s<socket path> = path for UNIX domain socket\n" 10198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " (default: %s)\n" 10208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " -g<triplet file> = path for GSM authentication triplets\n" 102104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt " -m<milenage file> = path for Milenage keys\n" 102261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt " -D<DB file> = path to SQLite database\n" 10235605286c30e1701491bd3af974ae423727750eddDmitry Shmidt " -i<IND len in bits> = IND length for SQN (default: 5)\n" 10245605286c30e1701491bd3af974ae423727750eddDmitry Shmidt "\n" 10255605286c30e1701491bd3af974ae423727750eddDmitry Shmidt "If the optional command argument, like " 10265605286c30e1701491bd3af974ae423727750eddDmitry Shmidt "\"AKA-REQ-AUTH <IMSI>\" is used, a single\n" 10275605286c30e1701491bd3af974ae423727750eddDmitry Shmidt "command is processed with response sent to stdout. Otherwise, " 10285605286c30e1701491bd3af974ae423727750eddDmitry Shmidt "hlr_auc_gw opens\n" 10295605286c30e1701491bd3af974ae423727750eddDmitry Shmidt "a control interface and processes commands sent through it " 10305605286c30e1701491bd3af974ae423727750eddDmitry Shmidt "(e.g., by EAP server\n" 10315605286c30e1701491bd3af974ae423727750eddDmitry Shmidt "in hostapd).\n", 10328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default_socket_path); 10338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 10348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint main(int argc, char *argv[]) 10378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 10388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int c; 10398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *gsm_triplet_file = NULL; 104061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt char *sqlite_db_file = NULL; 10415605286c30e1701491bd3af974ae423727750eddDmitry Shmidt int ret = 0; 10428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 104304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (os_program_init()) 104404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return -1; 104504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 10468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt socket_path = default_socket_path; 10478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (;;) { 104961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt c = getopt(argc, argv, "D:g:hi:m:s:u"); 10508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (c < 0) 10518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 10528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (c) { 105361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt case 'D': 105461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#ifdef CONFIG_SQLITE 105561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt sqlite_db_file = optarg; 105661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt break; 105761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#else /* CONFIG_SQLITE */ 105861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt printf("No SQLite support included in the build\n"); 105961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return -1; 106061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif /* CONFIG_SQLITE */ 10618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case 'g': 10628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt gsm_triplet_file = optarg; 10638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 10648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case 'h': 10658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt usage(); 10668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 106704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt case 'i': 106804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt ind_len = atoi(optarg); 106904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (ind_len < 0 || ind_len > 32) { 107004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt printf("Invalid IND length\n"); 107104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return -1; 107204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 107304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt break; 10748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case 'm': 10758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt milenage_file = optarg; 10768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 10778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case 's': 10788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt socket_path = optarg; 10798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 108004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt case 'u': 108104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt update_milenage = 1; 108204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt break; 10838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 10848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt usage(); 10858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 10868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 108961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (!gsm_triplet_file && !milenage_file && !sqlite_db_file) { 109061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt usage(); 109161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return -1; 109261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 109361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 109461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#ifdef CONFIG_SQLITE 109561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (sqlite_db_file && (sqlite_db = db_open(sqlite_db_file)) == NULL) 109661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return -1; 109761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif /* CONFIG_SQLITE */ 109861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 10998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (gsm_triplet_file && read_gsm_triplets(gsm_triplet_file) < 0) 11008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 11018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (milenage_file && read_milenage(milenage_file) < 0) 11038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 11048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11055605286c30e1701491bd3af974ae423727750eddDmitry Shmidt if (optind == argc) { 11065605286c30e1701491bd3af974ae423727750eddDmitry Shmidt serv_sock = open_socket(socket_path); 11075605286c30e1701491bd3af974ae423727750eddDmitry Shmidt if (serv_sock < 0) 11085605286c30e1701491bd3af974ae423727750eddDmitry Shmidt return -1; 11098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11105605286c30e1701491bd3af974ae423727750eddDmitry Shmidt printf("Listening for requests on %s\n", socket_path); 11118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11125605286c30e1701491bd3af974ae423727750eddDmitry Shmidt atexit(cleanup); 11135605286c30e1701491bd3af974ae423727750eddDmitry Shmidt signal(SIGTERM, handle_term); 11145605286c30e1701491bd3af974ae423727750eddDmitry Shmidt signal(SIGINT, handle_term); 11158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11165605286c30e1701491bd3af974ae423727750eddDmitry Shmidt for (;;) 11175605286c30e1701491bd3af974ae423727750eddDmitry Shmidt process(serv_sock); 11185605286c30e1701491bd3af974ae423727750eddDmitry Shmidt } else { 11195605286c30e1701491bd3af974ae423727750eddDmitry Shmidt char buf[1000]; 11205605286c30e1701491bd3af974ae423727750eddDmitry Shmidt socket_path = NULL; 11215605286c30e1701491bd3af974ae423727750eddDmitry Shmidt stdout_debug = 0; 11225605286c30e1701491bd3af974ae423727750eddDmitry Shmidt if (process_cmd(argv[optind], buf, sizeof(buf)) < 0) { 11235605286c30e1701491bd3af974ae423727750eddDmitry Shmidt printf("FAIL\n"); 11245605286c30e1701491bd3af974ae423727750eddDmitry Shmidt ret = -1; 11255605286c30e1701491bd3af974ae423727750eddDmitry Shmidt } else { 11265605286c30e1701491bd3af974ae423727750eddDmitry Shmidt printf("%s\n", buf); 11275605286c30e1701491bd3af974ae423727750eddDmitry Shmidt } 11285605286c30e1701491bd3af974ae423727750eddDmitry Shmidt cleanup(); 11295605286c30e1701491bd3af974ae423727750eddDmitry Shmidt } 11308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 113161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#ifdef CONFIG_SQLITE 113261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (sqlite_db) { 113361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt sqlite3_close(sqlite_db); 113461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt sqlite_db = NULL; 113561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 113661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif /* CONFIG_SQLITE */ 113761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 113804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt os_program_deinit(); 113904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 11405605286c30e1701491bd3af974ae423727750eddDmitry Shmidt return ret; 11418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1142