1526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt/* 2526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * HLR/AuC testing gateway for hostapd EAP-SIM/AKA database/authenticator 3526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * Copyright (c) 2005-2007, Jouni Malinen <j@w1.fi> 4526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * 5526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * This program is free software; you can redistribute it and/or modify 6526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * it under the terms of the GNU General Public License version 2 as 7526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * published by the Free Software Foundation. 8526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * 9526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * Alternatively, this software may be distributed under the terms of BSD 10526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * license. 11526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * 12526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * See README and COPYING for more details. 13526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * 14526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * This is an example implementation of the EAP-SIM/AKA database/authentication 15526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * gateway interface to HLR/AuC. It is expected to be replaced with an 16526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * implementation of SS7 gateway to GSM/UMTS authentication center (HLR/AuC) or 17526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * a local implementation of SIM triplet and AKA authentication data generator. 18526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * 19526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * hostapd will send SIM/AKA authentication queries over a UNIX domain socket 20526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * to and external program, e.g., this hlr_auc_gw. This interface uses simple 21526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * text-based format: 22526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * 23526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * EAP-SIM / GSM triplet query/response: 24526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * SIM-REQ-AUTH <IMSI> <max_chal> 25526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * SIM-RESP-AUTH <IMSI> Kc1:SRES1:RAND1 Kc2:SRES2:RAND2 [Kc3:SRES3:RAND3] 26526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * SIM-RESP-AUTH <IMSI> FAILURE 27526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * 28526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * EAP-AKA / UMTS query/response: 29526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * AKA-REQ-AUTH <IMSI> 30526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * AKA-RESP-AUTH <IMSI> <RAND> <AUTN> <IK> <CK> <RES> 31526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * AKA-RESP-AUTH <IMSI> FAILURE 32526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * 33526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * EAP-AKA / UMTS AUTS (re-synchronization): 34526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * AKA-AUTS <IMSI> <AUTS> <RAND> 35526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * 36526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * IMSI and max_chal are sent as an ASCII string, 37526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * Kc/SRES/RAND/AUTN/IK/CK/RES/AUTS as hex strings. 38526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * 39526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * The example implementation here reads GSM authentication triplets from a 40526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * text file in IMSI:Kc:SRES:RAND format, IMSI in ASCII, other fields as hex 41526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * strings. This is used to simulate an HLR/AuC. As such, it is not very useful 42526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * for real life authentication, but it is useful both as an example 43526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * implementation and for EAP-SIM testing. 44526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt */ 45526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 46526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#include "includes.h" 47526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#include <sys/un.h> 48526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 49526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#include "common.h" 50526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#include "milenage.h" 51526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 52526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic const char *default_socket_path = "/tmp/hlr_auc_gw.sock"; 53526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic const char *socket_path; 54526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic int serv_sock = -1; 55526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 56526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt/* GSM triplets */ 57526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstruct gsm_triplet { 58526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct gsm_triplet *next; 59526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt char imsi[20]; 60526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt u8 kc[8]; 61526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt u8 sres[4]; 62526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt u8 _rand[16]; 63526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt}; 64526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 65526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic struct gsm_triplet *gsm_db = NULL, *gsm_db_pos = NULL; 66526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 67526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt/* OPc and AMF parameters for Milenage (Example algorithms for AKA). */ 68526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstruct milenage_parameters { 69526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct milenage_parameters *next; 70526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt char imsi[20]; 71526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt u8 ki[16]; 72526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt u8 opc[16]; 73526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt u8 amf[2]; 74526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt u8 sqn[6]; 75526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt}; 76526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 77526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic struct milenage_parameters *milenage_db = NULL; 78526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 79526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#define EAP_SIM_MAX_CHAL 3 80526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 81526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#define EAP_AKA_RAND_LEN 16 82526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#define EAP_AKA_AUTN_LEN 16 83526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#define EAP_AKA_AUTS_LEN 14 84526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#define EAP_AKA_RES_MAX_LEN 16 85526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#define EAP_AKA_IK_LEN 16 86526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#define EAP_AKA_CK_LEN 16 87526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 88526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 89526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic int open_socket(const char *path) 90526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 91526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct sockaddr_un addr; 92526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt int s; 93526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 94526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt s = socket(PF_UNIX, SOCK_DGRAM, 0); 95526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (s < 0) { 96526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt perror("socket(PF_UNIX)"); 97526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return -1; 98526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 99526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 100526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt memset(&addr, 0, sizeof(addr)); 101526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt addr.sun_family = AF_UNIX; 102526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_strlcpy(addr.sun_path, path, sizeof(addr.sun_path)); 103526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (bind(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) { 104526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt perror("bind(PF_UNIX)"); 105526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt close(s); 106526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return -1; 107526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 108526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 109526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return s; 110526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 111526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 112526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 113526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic int read_gsm_triplets(const char *fname) 114526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 115526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt FILE *f; 116526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt char buf[200], *pos, *pos2; 117526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct gsm_triplet *g = NULL; 118526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt int line, ret = 0; 119526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 120526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (fname == NULL) 121526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return -1; 122526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 123526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt f = fopen(fname, "r"); 124526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (f == NULL) { 125526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt printf("Could not open GSM tripler data file '%s'\n", fname); 126526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return -1; 127526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 128526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 129526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt line = 0; 130526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt while (fgets(buf, sizeof(buf), f)) { 131526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt line++; 132526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 133526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* Parse IMSI:Kc:SRES:RAND */ 134526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt buf[sizeof(buf) - 1] = '\0'; 135526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (buf[0] == '#') 136526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt continue; 137526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt pos = buf; 138526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt while (*pos != '\0' && *pos != '\n') 139526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt pos++; 140526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (*pos == '\n') 141526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt *pos = '\0'; 142526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt pos = buf; 143526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (*pos == '\0') 144526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt continue; 145526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 146526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt g = os_zalloc(sizeof(*g)); 147526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (g == NULL) { 148526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt ret = -1; 149526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt break; 150526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 151526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 152526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* IMSI */ 153526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt pos2 = strchr(pos, ':'); 154526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (pos2 == NULL) { 155526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt printf("%s:%d - Invalid IMSI (%s)\n", 156526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt fname, line, pos); 157526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt ret = -1; 158526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt break; 159526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 160526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt *pos2 = '\0'; 161526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (strlen(pos) >= sizeof(g->imsi)) { 162526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt printf("%s:%d - Too long IMSI (%s)\n", 163526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt fname, line, pos); 164526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt ret = -1; 165526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt break; 166526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 167526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_strlcpy(g->imsi, pos, sizeof(g->imsi)); 168526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt pos = pos2 + 1; 169526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 170526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* Kc */ 171526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt pos2 = strchr(pos, ':'); 172526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (pos2 == NULL) { 173526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt printf("%s:%d - Invalid Kc (%s)\n", fname, line, pos); 174526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt ret = -1; 175526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt break; 176526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 177526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt *pos2 = '\0'; 178526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (strlen(pos) != 16 || hexstr2bin(pos, g->kc, 8)) { 179526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt printf("%s:%d - Invalid Kc (%s)\n", fname, line, pos); 180526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt ret = -1; 181526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt break; 182526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 183526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt pos = pos2 + 1; 184526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 185526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* SRES */ 186526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt pos2 = strchr(pos, ':'); 187526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (pos2 == NULL) { 188526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt printf("%s:%d - Invalid SRES (%s)\n", fname, line, 189526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt pos); 190526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt ret = -1; 191526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt break; 192526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 193526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt *pos2 = '\0'; 194526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (strlen(pos) != 8 || hexstr2bin(pos, g->sres, 4)) { 195526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt printf("%s:%d - Invalid SRES (%s)\n", fname, line, 196526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt pos); 197526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt ret = -1; 198526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt break; 199526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 200526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt pos = pos2 + 1; 201526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 202526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* RAND */ 203526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt pos2 = strchr(pos, ':'); 204526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (pos2) 205526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt *pos2 = '\0'; 206526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (strlen(pos) != 32 || hexstr2bin(pos, g->_rand, 16)) { 207526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt printf("%s:%d - Invalid RAND (%s)\n", fname, line, 208526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt pos); 209526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt ret = -1; 210526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt break; 211526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 212526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt pos = pos2 + 1; 213526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 214526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt g->next = gsm_db; 215526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt gsm_db = g; 216526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt g = NULL; 217526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 218526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt free(g); 219526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 220526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt fclose(f); 221526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 222526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return ret; 223526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 224526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 225526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 226526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic struct gsm_triplet * get_gsm_triplet(const char *imsi) 227526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 228526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct gsm_triplet *g = gsm_db_pos; 229526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 230526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt while (g) { 231526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (strcmp(g->imsi, imsi) == 0) { 232526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt gsm_db_pos = g->next; 233526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return g; 234526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 235526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt g = g->next; 236526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 237526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 238526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt g = gsm_db; 239526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt while (g && g != gsm_db_pos) { 240526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (strcmp(g->imsi, imsi) == 0) { 241526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt gsm_db_pos = g->next; 242526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return g; 243526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 244526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt g = g->next; 245526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 246526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 247526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return NULL; 248526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 249526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 250526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 251526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic int read_milenage(const char *fname) 252526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 253526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt FILE *f; 254526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt char buf[200], *pos, *pos2; 255526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct milenage_parameters *m = NULL; 256526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt int line, ret = 0; 257526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 258526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (fname == NULL) 259526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return -1; 260526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 261526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt f = fopen(fname, "r"); 262526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (f == NULL) { 263526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt printf("Could not open Milenage data file '%s'\n", fname); 264526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return -1; 265526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 266526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 267526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt line = 0; 268526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt while (fgets(buf, sizeof(buf), f)) { 269526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt line++; 270526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 271526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* Parse IMSI Ki OPc AMF SQN */ 272526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt buf[sizeof(buf) - 1] = '\0'; 273526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (buf[0] == '#') 274526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt continue; 275526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt pos = buf; 276526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt while (*pos != '\0' && *pos != '\n') 277526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt pos++; 278526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (*pos == '\n') 279526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt *pos = '\0'; 280526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt pos = buf; 281526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (*pos == '\0') 282526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt continue; 283526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 284526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt m = os_zalloc(sizeof(*m)); 285526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (m == NULL) { 286526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt ret = -1; 287526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt break; 288526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 289526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 290526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* IMSI */ 291526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt pos2 = strchr(pos, ' '); 292526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (pos2 == NULL) { 293526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt printf("%s:%d - Invalid IMSI (%s)\n", 294526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt fname, line, pos); 295526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt ret = -1; 296526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt break; 297526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 298526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt *pos2 = '\0'; 299526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (strlen(pos) >= sizeof(m->imsi)) { 300526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt printf("%s:%d - Too long IMSI (%s)\n", 301526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt fname, line, pos); 302526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt ret = -1; 303526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt break; 304526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 305526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_strlcpy(m->imsi, pos, sizeof(m->imsi)); 306526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt pos = pos2 + 1; 307526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 308526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* Ki */ 309526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt pos2 = strchr(pos, ' '); 310526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (pos2 == NULL) { 311526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt printf("%s:%d - Invalid Ki (%s)\n", fname, line, pos); 312526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt ret = -1; 313526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt break; 314526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 315526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt *pos2 = '\0'; 316526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (strlen(pos) != 32 || hexstr2bin(pos, m->ki, 16)) { 317526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt printf("%s:%d - Invalid Ki (%s)\n", fname, line, pos); 318526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt ret = -1; 319526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt break; 320526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 321526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt pos = pos2 + 1; 322526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 323526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* OPc */ 324526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt pos2 = strchr(pos, ' '); 325526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (pos2 == NULL) { 326526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt printf("%s:%d - Invalid OPc (%s)\n", fname, line, pos); 327526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt ret = -1; 328526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt break; 329526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 330526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt *pos2 = '\0'; 331526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (strlen(pos) != 32 || hexstr2bin(pos, m->opc, 16)) { 332526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt printf("%s:%d - Invalid OPc (%s)\n", fname, line, pos); 333526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt ret = -1; 334526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt break; 335526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 336526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt pos = pos2 + 1; 337526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 338526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* AMF */ 339526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt pos2 = strchr(pos, ' '); 340526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (pos2 == NULL) { 341526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt printf("%s:%d - Invalid AMF (%s)\n", fname, line, pos); 342526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt ret = -1; 343526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt break; 344526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 345526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt *pos2 = '\0'; 346526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (strlen(pos) != 4 || hexstr2bin(pos, m->amf, 2)) { 347526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt printf("%s:%d - Invalid AMF (%s)\n", fname, line, pos); 348526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt ret = -1; 349526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt break; 350526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 351526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt pos = pos2 + 1; 352526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 353526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* SQN */ 354526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt pos2 = strchr(pos, ' '); 355526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (pos2) 356526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt *pos2 = '\0'; 357526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (strlen(pos) != 12 || hexstr2bin(pos, m->sqn, 6)) { 358526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt printf("%s:%d - Invalid SEQ (%s)\n", fname, line, pos); 359526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt ret = -1; 360526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt break; 361526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 362526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt pos = pos2 + 1; 363526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 364526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt m->next = milenage_db; 365526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt milenage_db = m; 366526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt m = NULL; 367526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 368526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt free(m); 369526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 370526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt fclose(f); 371526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 372526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return ret; 373526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 374526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 375526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 376526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic struct milenage_parameters * get_milenage(const char *imsi) 377526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 378526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct milenage_parameters *m = milenage_db; 379526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 380526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt while (m) { 381526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (strcmp(m->imsi, imsi) == 0) 382526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt break; 383526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt m = m->next; 384526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 385526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 386526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return m; 387526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 388526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 389526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 390526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic void sim_req_auth(int s, struct sockaddr_un *from, socklen_t fromlen, 391526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt char *imsi) 392526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 393526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt int count, max_chal, ret; 394526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt char *pos; 395526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt char reply[1000], *rpos, *rend; 396526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct milenage_parameters *m; 397526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct gsm_triplet *g; 398526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 399526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt reply[0] = '\0'; 400526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 401526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt pos = strchr(imsi, ' '); 402526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (pos) { 403526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt *pos++ = '\0'; 404526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt max_chal = atoi(pos); 405526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (max_chal < 1 || max_chal < EAP_SIM_MAX_CHAL) 406526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt max_chal = EAP_SIM_MAX_CHAL; 407526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } else 408526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt max_chal = EAP_SIM_MAX_CHAL; 409526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 410526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt rend = &reply[sizeof(reply)]; 411526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt rpos = reply; 412526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt ret = snprintf(rpos, rend - rpos, "SIM-RESP-AUTH %s", imsi); 413526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (ret < 0 || ret >= rend - rpos) 414526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return; 415526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt rpos += ret; 416526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 417526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt m = get_milenage(imsi); 418526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (m) { 419526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt u8 _rand[16], sres[4], kc[8]; 420526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt for (count = 0; count < max_chal; count++) { 421526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (os_get_random(_rand, 16) < 0) 422526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return; 423526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt gsm_milenage(m->opc, m->ki, _rand, sres, kc); 424526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt *rpos++ = ' '; 425526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt rpos += wpa_snprintf_hex(rpos, rend - rpos, kc, 8); 426526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt *rpos++ = ':'; 427526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt rpos += wpa_snprintf_hex(rpos, rend - rpos, sres, 4); 428526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt *rpos++ = ':'; 429526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt rpos += wpa_snprintf_hex(rpos, rend - rpos, _rand, 16); 430526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 431526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt *rpos = '\0'; 432526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt goto send; 433526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 434526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 435526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt count = 0; 436526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt while (count < max_chal && (g = get_gsm_triplet(imsi))) { 437526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (strcmp(g->imsi, imsi) != 0) 438526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt continue; 439526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 440526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (rpos < rend) 441526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt *rpos++ = ' '; 442526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt rpos += wpa_snprintf_hex(rpos, rend - rpos, g->kc, 8); 443526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (rpos < rend) 444526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt *rpos++ = ':'; 445526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt rpos += wpa_snprintf_hex(rpos, rend - rpos, g->sres, 4); 446526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (rpos < rend) 447526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt *rpos++ = ':'; 448526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt rpos += wpa_snprintf_hex(rpos, rend - rpos, g->_rand, 16); 449526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt count++; 450526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 451526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 452526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (count == 0) { 453526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt printf("No GSM triplets found for %s\n", imsi); 454526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt ret = snprintf(rpos, rend - rpos, " FAILURE"); 455526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (ret < 0 || ret >= rend - rpos) 456526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return; 457526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt rpos += ret; 458526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 459526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 460526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtsend: 461526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt printf("Send: %s\n", reply); 462526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (sendto(s, reply, rpos - reply, 0, 463526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt (struct sockaddr *) from, fromlen) < 0) 464526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt perror("send"); 465526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 466526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 467526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 468526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic void aka_req_auth(int s, struct sockaddr_un *from, socklen_t fromlen, 469526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt char *imsi) 470526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 471526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* AKA-RESP-AUTH <IMSI> <RAND> <AUTN> <IK> <CK> <RES> */ 472526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt char reply[1000], *pos, *end; 473526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt u8 _rand[EAP_AKA_RAND_LEN]; 474526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt u8 autn[EAP_AKA_AUTN_LEN]; 475526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt u8 ik[EAP_AKA_IK_LEN]; 476526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt u8 ck[EAP_AKA_CK_LEN]; 477526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt u8 res[EAP_AKA_RES_MAX_LEN]; 478526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt size_t res_len; 479526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt int ret; 480526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct milenage_parameters *m; 481526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 482526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt m = get_milenage(imsi); 483526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (m) { 484526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (os_get_random(_rand, EAP_AKA_RAND_LEN) < 0) 485526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return; 486526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt res_len = EAP_AKA_RES_MAX_LEN; 487526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt inc_byte_array(m->sqn, 6); 488526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt printf("AKA: Milenage with SQN=%02x%02x%02x%02x%02x%02x\n", 489526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt m->sqn[0], m->sqn[1], m->sqn[2], 490526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt m->sqn[3], m->sqn[4], m->sqn[5]); 491526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt milenage_generate(m->opc, m->amf, m->ki, m->sqn, _rand, 492526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt autn, ik, ck, res, &res_len); 493526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } else { 494526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt printf("Unknown IMSI: %s\n", imsi); 495526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#ifdef AKA_USE_FIXED_TEST_VALUES 496526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt printf("Using fixed test values for AKA\n"); 497526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt memset(_rand, '0', EAP_AKA_RAND_LEN); 498526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt memset(autn, '1', EAP_AKA_AUTN_LEN); 499526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt memset(ik, '3', EAP_AKA_IK_LEN); 500526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt memset(ck, '4', EAP_AKA_CK_LEN); 501526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt memset(res, '2', EAP_AKA_RES_MAX_LEN); 502526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt res_len = EAP_AKA_RES_MAX_LEN; 503526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#else /* AKA_USE_FIXED_TEST_VALUES */ 504526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return; 505526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#endif /* AKA_USE_FIXED_TEST_VALUES */ 506526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 507526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 508526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt pos = reply; 509526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt end = &reply[sizeof(reply)]; 510526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt ret = snprintf(pos, end - pos, "AKA-RESP-AUTH %s ", imsi); 511526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (ret < 0 || ret >= end - pos) 512526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return; 513526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt pos += ret; 514526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt pos += wpa_snprintf_hex(pos, end - pos, _rand, EAP_AKA_RAND_LEN); 515526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt *pos++ = ' '; 516526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt pos += wpa_snprintf_hex(pos, end - pos, autn, EAP_AKA_AUTN_LEN); 517526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt *pos++ = ' '; 518526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt pos += wpa_snprintf_hex(pos, end - pos, ik, EAP_AKA_IK_LEN); 519526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt *pos++ = ' '; 520526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt pos += wpa_snprintf_hex(pos, end - pos, ck, EAP_AKA_CK_LEN); 521526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt *pos++ = ' '; 522526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt pos += wpa_snprintf_hex(pos, end - pos, res, res_len); 523526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 524526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt printf("Send: %s\n", reply); 525526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 526526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (sendto(s, reply, pos - reply, 0, (struct sockaddr *) from, 527526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt fromlen) < 0) 528526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt perror("send"); 529526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 530526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 531526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 532526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic void aka_auts(int s, struct sockaddr_un *from, socklen_t fromlen, 533526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt char *imsi) 534526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 535dde787cc314cd04caa4ea5f031cc8a02495ca513Dmitry Shmidt char *auts, *__rand; 536526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt u8 _auts[EAP_AKA_AUTS_LEN], _rand[EAP_AKA_RAND_LEN], sqn[6]; 537526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct milenage_parameters *m; 538526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 539526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* AKA-AUTS <IMSI> <AUTS> <RAND> */ 540526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 541526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt auts = strchr(imsi, ' '); 542526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (auts == NULL) 543526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return; 544526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt *auts++ = '\0'; 545526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 546dde787cc314cd04caa4ea5f031cc8a02495ca513Dmitry Shmidt __rand = strchr(auts, ' '); 547dde787cc314cd04caa4ea5f031cc8a02495ca513Dmitry Shmidt if (__rand == NULL) 548526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return; 549dde787cc314cd04caa4ea5f031cc8a02495ca513Dmitry Shmidt *__rand++ = '\0'; 550526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 551dde787cc314cd04caa4ea5f031cc8a02495ca513Dmitry Shmidt printf("AKA-AUTS: IMSI=%s AUTS=%s RAND=%s\n", imsi, auts, __rand); 552526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (hexstr2bin(auts, _auts, EAP_AKA_AUTS_LEN) || 553dde787cc314cd04caa4ea5f031cc8a02495ca513Dmitry Shmidt hexstr2bin(__rand, _rand, EAP_AKA_RAND_LEN)) { 554526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt printf("Could not parse AUTS/RAND\n"); 555526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return; 556526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 557526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 558526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt m = get_milenage(imsi); 559526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (m == NULL) { 560526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt printf("Unknown IMSI: %s\n", imsi); 561526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return; 562526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 563526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 564526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (milenage_auts(m->opc, m->ki, _rand, _auts, sqn)) { 565526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt printf("AKA-AUTS: Incorrect MAC-S\n"); 566526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } else { 567526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt memcpy(m->sqn, sqn, 6); 568526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt printf("AKA-AUTS: Re-synchronized: " 569526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "SQN=%02x%02x%02x%02x%02x%02x\n", 570526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sqn[0], sqn[1], sqn[2], sqn[3], sqn[4], sqn[5]); 571526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 572526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 573526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 574526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 575526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic int process(int s) 576526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 577526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt char buf[1000]; 578526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct sockaddr_un from; 579526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt socklen_t fromlen; 580526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt ssize_t res; 581526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 582526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt fromlen = sizeof(from); 583526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt res = recvfrom(s, buf, sizeof(buf), 0, (struct sockaddr *) &from, 584526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt &fromlen); 585526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (res < 0) { 586526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt perror("recvfrom"); 587526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return -1; 588526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 589526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 590526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (res == 0) 591526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return 0; 592526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 593526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if ((size_t) res >= sizeof(buf)) 594526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt res = sizeof(buf) - 1; 595526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt buf[res] = '\0'; 596526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 597526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt printf("Received: %s\n", buf); 598526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 599526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (strncmp(buf, "SIM-REQ-AUTH ", 13) == 0) 600526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sim_req_auth(s, &from, fromlen, buf + 13); 601526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt else if (strncmp(buf, "AKA-REQ-AUTH ", 13) == 0) 602526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt aka_req_auth(s, &from, fromlen, buf + 13); 603526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt else if (strncmp(buf, "AKA-AUTS ", 9) == 0) 604526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt aka_auts(s, &from, fromlen, buf + 9); 605526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt else 606526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt printf("Unknown request: %s\n", buf); 607526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 608526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return 0; 609526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 610526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 611526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 612526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic void cleanup(void) 613526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 614526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct gsm_triplet *g, *gprev; 615526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct milenage_parameters *m, *prev; 616526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 617526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt g = gsm_db; 618526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt while (g) { 619526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt gprev = g; 620526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt g = g->next; 621526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt free(gprev); 622526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 623526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 624526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt m = milenage_db; 625526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt while (m) { 626526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt prev = m; 627526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt m = m->next; 628526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt free(prev); 629526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 630526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 631526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt close(serv_sock); 632526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt unlink(socket_path); 633526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 634526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 635526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 636526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic void handle_term(int sig) 637526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 638526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt printf("Signal %d - terminate\n", sig); 639526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt exit(0); 640526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 641526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 642526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 643526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic void usage(void) 644526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 645526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt printf("HLR/AuC testing gateway for hostapd EAP-SIM/AKA " 646526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "database/authenticator\n" 647526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "Copyright (c) 2005-2007, Jouni Malinen <j@w1.fi>\n" 648526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "\n" 649526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "usage:\n" 650526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "hlr_auc_gw [-h] [-s<socket path>] [-g<triplet file>] " 651526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "[-m<milenage file>]\n" 652526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "\n" 653526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "options:\n" 654526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt " -h = show this usage help\n" 655526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt " -s<socket path> = path for UNIX domain socket\n" 656526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt " (default: %s)\n" 657526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt " -g<triplet file> = path for GSM authentication triplets\n" 658526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt " -m<milenage file> = path for Milenage keys\n", 659526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt default_socket_path); 660526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 661526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 662526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 663526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtint main(int argc, char *argv[]) 664526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 665526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt int c; 666526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt char *milenage_file = NULL; 667526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt char *gsm_triplet_file = NULL; 668526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 669526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt socket_path = default_socket_path; 670526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 671526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt for (;;) { 672526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt c = getopt(argc, argv, "g:hm:s:"); 673526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (c < 0) 674526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt break; 675526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt switch (c) { 676526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt case 'g': 677526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt gsm_triplet_file = optarg; 678526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt break; 679526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt case 'h': 680526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt usage(); 681526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return 0; 682526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt case 'm': 683526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt milenage_file = optarg; 684526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt break; 685526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt case 's': 686526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt socket_path = optarg; 687526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt break; 688526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt default: 689526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt usage(); 690526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return -1; 691526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 692526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 693526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 694526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (gsm_triplet_file && read_gsm_triplets(gsm_triplet_file) < 0) 695526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return -1; 696526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 697526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (milenage_file && read_milenage(milenage_file) < 0) 698526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return -1; 699526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 700526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt serv_sock = open_socket(socket_path); 701526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (serv_sock < 0) 702526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return -1; 703526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 704526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt printf("Listening for requests on %s\n", socket_path); 705526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 706526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt atexit(cleanup); 707526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt signal(SIGTERM, handle_term); 708526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt signal(SIGINT, handle_term); 709526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 710526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt for (;;) 711526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt process(serv_sock); 712526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 713526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return 0; 714526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 715