aboutsummaryrefslogtreecommitdiffstats
path: root/hostapd/hlr_auc_gw.c
diff options
context:
space:
mode:
authorDmitry Shmidt <dimitrysh@google.com>2012-08-29 16:22:06 -0700
committerDmitry Shmidt <dimitrysh@google.com>2012-09-04 17:24:09 -0700
commit61d9df3e62aaa0e87ad05452fcb95142159a17b6 (patch)
tree192ecb010484c58cdec7d39086d64723063268ae /hostapd/hlr_auc_gw.c
parent4b86ea55603eded752b5773179884a35e74e1a89 (diff)
downloadexternal_wpa_supplicant_8-61d9df3e62aaa0e87ad05452fcb95142159a17b6.zip
external_wpa_supplicant_8-61d9df3e62aaa0e87ad05452fcb95142159a17b6.tar.gz
external_wpa_supplicant_8-61d9df3e62aaa0e87ad05452fcb95142159a17b6.tar.bz2
wpa_supplicant: Update to 29-Aug-2012 TOT
commit 6ffdc2f7bd496ace7a46e055f9714e7db4b1f722 Author: Jouni Malinen <jouni@qca.qualcomm.com> Date: Fri Mar 2 22:31:04 2012 +0200 WFD: Add preliminary WSD request processing and response This commit does not yet address support for different device roles, i.e., the same set of subelements are returned regardless of which role was indicated in the request. Signed-hostap: Jouni Malinen <jouni@qca.qualcomm.com> Change-Id: I9d63acce719b982c02e589bb59602382e82988c8 Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
Diffstat (limited to 'hostapd/hlr_auc_gw.c')
-rw-r--r--hostapd/hlr_auc_gw.c197
1 files changed, 194 insertions, 3 deletions
diff --git a/hostapd/hlr_auc_gw.c b/hostapd/hlr_auc_gw.c
index 516d859..e27ddab 100644
--- a/hostapd/hlr_auc_gw.c
+++ b/hostapd/hlr_auc_gw.c
@@ -43,6 +43,9 @@
#include "includes.h"
#include <sys/un.h>
+#ifdef CONFIG_SQLITE
+#include <sqlite3.h>
+#endif /* CONFIG_SQLITE */
#include "common.h"
#include "crypto/milenage.h"
@@ -89,6 +92,140 @@ static struct milenage_parameters *milenage_db = NULL;
#define EAP_AKA_CK_LEN 16
+#ifdef CONFIG_SQLITE
+
+static sqlite3 *sqlite_db = NULL;
+static struct milenage_parameters db_tmp_milenage;
+
+
+static int db_table_exists(sqlite3 *db, const char *name)
+{
+ char cmd[128];
+ os_snprintf(cmd, sizeof(cmd), "SELECT 1 FROM %s;", name);
+ return sqlite3_exec(db, cmd, NULL, NULL, NULL) == SQLITE_OK;
+}
+
+
+static int db_table_create_milenage(sqlite3 *db)
+{
+ char *err = NULL;
+ const char *sql =
+ "CREATE TABLE milenage("
+ " imsi INTEGER PRIMARY KEY NOT NULL,"
+ " ki CHAR(32) NOT NULL,"
+ " opc CHAR(32) NOT NULL,"
+ " amf CHAR(4) NOT NULL,"
+ " sqn CHAR(12) NOT NULL"
+ ");";
+
+ printf("Adding database table for milenage information\n");
+ if (sqlite3_exec(db, sql, NULL, NULL, &err) != SQLITE_OK) {
+ printf("SQLite error: %s\n", err);
+ sqlite3_free(err);
+ return -1;
+ }
+
+ return 0;
+}
+
+
+static sqlite3 * db_open(const char *db_file)
+{
+ sqlite3 *db;
+
+ if (sqlite3_open(db_file, &db)) {
+ printf("Failed to open database %s: %s\n",
+ db_file, sqlite3_errmsg(db));
+ sqlite3_close(db);
+ return NULL;
+ }
+
+ if (!db_table_exists(db, "milenage") &&
+ db_table_create_milenage(db) < 0) {
+ sqlite3_close(db);
+ return NULL;
+ }
+
+ return db;
+}
+
+
+static int get_milenage_cb(void *ctx, int argc, char *argv[], char *col[])
+{
+ struct milenage_parameters *m = ctx;
+ int i;
+
+ for (i = 0; i < argc; i++) {
+ if (os_strcmp(col[i], "ki") == 0 && argv[i] &&
+ hexstr2bin(argv[i], m->ki, sizeof(m->ki))) {
+ printf("Invalid ki value in database\n");
+ return -1;
+ }
+
+ if (os_strcmp(col[i], "opc") == 0 && argv[i] &&
+ hexstr2bin(argv[i], m->opc, sizeof(m->opc))) {
+ printf("Invalid opcvalue in database\n");
+ return -1;
+ }
+
+ if (os_strcmp(col[i], "amf") == 0 && argv[i] &&
+ hexstr2bin(argv[i], m->amf, sizeof(m->amf))) {
+ printf("Invalid amf value in database\n");
+ return -1;
+ }
+
+ if (os_strcmp(col[i], "sqn") == 0 && argv[i] &&
+ hexstr2bin(argv[i], m->sqn, sizeof(m->sqn))) {
+ printf("Invalid sqn value in database\n");
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+
+static struct milenage_parameters * db_get_milenage(const char *imsi_txt)
+{
+ char cmd[128];
+ unsigned long long imsi;
+
+ os_memset(&db_tmp_milenage, 0, sizeof(db_tmp_milenage));
+ imsi = atoll(imsi_txt);
+ os_snprintf(db_tmp_milenage.imsi, sizeof(db_tmp_milenage.imsi),
+ "%llu", imsi);
+ os_snprintf(cmd, sizeof(cmd),
+ "SELECT ki,opc,amf,sqn FROM milenage WHERE imsi=%llu;",
+ imsi);
+ if (sqlite3_exec(sqlite_db, cmd, get_milenage_cb, &db_tmp_milenage,
+ NULL) != SQLITE_OK)
+ return NULL;
+
+ return &db_tmp_milenage;
+}
+
+
+static int db_update_milenage_sqn(struct milenage_parameters *m)
+{
+ char cmd[128], val[13], *pos;
+
+ pos = val;
+ pos += wpa_snprintf_hex(pos, sizeof(val), m->sqn, 6);
+ *pos = '\0';
+ os_snprintf(cmd, sizeof(cmd),
+ "UPDATE milenage SET sqn='%s' WHERE imsi=%s;",
+ val, m->imsi);
+ if (sqlite3_exec(sqlite_db, cmd, NULL, NULL, NULL) != SQLITE_OK) {
+ printf("Failed to update SQN in database for IMSI %s\n",
+ m->imsi);
+ return -1;
+ }
+ return 0;
+}
+
+#endif /* CONFIG_SQLITE */
+
+
static int open_socket(const char *path)
{
struct sockaddr_un addr;
@@ -460,6 +597,11 @@ static struct milenage_parameters * get_milenage(const char *imsi)
m = m->next;
}
+#ifdef CONFIG_SQLITE
+ if (!m)
+ m = db_get_milenage(imsi);
+#endif /* CONFIG_SQLITE */
+
return m;
}
@@ -577,6 +719,7 @@ static void aka_req_auth(int s, struct sockaddr_un *from, socklen_t fromlen,
size_t res_len;
int ret;
struct milenage_parameters *m;
+ int failed = 0;
m = get_milenage(imsi);
if (m) {
@@ -584,6 +727,9 @@ static void aka_req_auth(int s, struct sockaddr_un *from, socklen_t fromlen,
return;
res_len = EAP_AKA_RES_MAX_LEN;
inc_sqn(m->sqn);
+#ifdef CONFIG_SQLITE
+ db_update_milenage_sqn(m);
+#endif /* CONFIG_SQLITE */
sqn_changes = 1;
printf("AKA: Milenage with SQN=%02x%02x%02x%02x%02x%02x\n",
m->sqn[0], m->sqn[1], m->sqn[2],
@@ -601,7 +747,7 @@ static void aka_req_auth(int s, struct sockaddr_un *from, socklen_t fromlen,
memset(res, '2', EAP_AKA_RES_MAX_LEN);
res_len = EAP_AKA_RES_MAX_LEN;
#else /* AKA_USE_FIXED_TEST_VALUES */
- return;
+ failed = 1;
#endif /* AKA_USE_FIXED_TEST_VALUES */
}
@@ -611,6 +757,13 @@ static void aka_req_auth(int s, struct sockaddr_un *from, socklen_t fromlen,
if (ret < 0 || ret >= end - pos)
return;
pos += ret;
+ if (failed) {
+ ret = snprintf(pos, end - pos, "FAILURE");
+ if (ret < 0 || ret >= end - pos)
+ return;
+ pos += ret;
+ goto done;
+ }
pos += wpa_snprintf_hex(pos, end - pos, _rand, EAP_AKA_RAND_LEN);
*pos++ = ' ';
pos += wpa_snprintf_hex(pos, end - pos, autn, EAP_AKA_AUTN_LEN);
@@ -621,6 +774,7 @@ static void aka_req_auth(int s, struct sockaddr_un *from, socklen_t fromlen,
*pos++ = ' ';
pos += wpa_snprintf_hex(pos, end - pos, res, res_len);
+done:
printf("Send: %s\n", reply);
if (sendto(s, reply, pos - reply, 0, (struct sockaddr *) from,
@@ -668,6 +822,9 @@ static void aka_auts(int s, struct sockaddr_un *from, socklen_t fromlen,
printf("AKA-AUTS: Re-synchronized: "
"SQN=%02x%02x%02x%02x%02x%02x\n",
sqn[0], sqn[1], sqn[2], sqn[3], sqn[4], sqn[5]);
+#ifdef CONFIG_SQLITE
+ db_update_milenage_sqn(m);
+#endif /* CONFIG_SQLITE */
sqn_changes = 1;
}
}
@@ -734,6 +891,13 @@ static void cleanup(void)
close(serv_sock);
unlink(socket_path);
+
+#ifdef CONFIG_SQLITE
+ if (sqlite_db) {
+ sqlite3_close(sqlite_db);
+ sqlite_db = NULL;
+ }
+#endif /* CONFIG_SQLITE */
}
@@ -753,7 +917,7 @@ static void usage(void)
"usage:\n"
"hlr_auc_gw [-hu] [-s<socket path>] [-g<triplet file>] "
"[-m<milenage file>] \\\n"
- " [-i<IND len in bits>]\n"
+ " [-D<DB file>] [-i<IND len in bits>]\n"
"\n"
"options:\n"
" -h = show this usage help\n"
@@ -762,6 +926,7 @@ static void usage(void)
" (default: %s)\n"
" -g<triplet file> = path for GSM authentication triplets\n"
" -m<milenage file> = path for Milenage keys\n"
+ " -D<DB file> = path to SQLite database\n"
" -i<IND len in bits> = IND length for SQN (default: 5)\n",
default_socket_path);
}
@@ -771,6 +936,7 @@ int main(int argc, char *argv[])
{
int c;
char *gsm_triplet_file = NULL;
+ char *sqlite_db_file = NULL;
if (os_program_init())
return -1;
@@ -778,10 +944,18 @@ int main(int argc, char *argv[])
socket_path = default_socket_path;
for (;;) {
- c = getopt(argc, argv, "g:hi:m:s:u");
+ c = getopt(argc, argv, "D:g:hi:m:s:u");
if (c < 0)
break;
switch (c) {
+ case 'D':
+#ifdef CONFIG_SQLITE
+ sqlite_db_file = optarg;
+ break;
+#else /* CONFIG_SQLITE */
+ printf("No SQLite support included in the build\n");
+ return -1;
+#endif /* CONFIG_SQLITE */
case 'g':
gsm_triplet_file = optarg;
break;
@@ -810,6 +984,16 @@ int main(int argc, char *argv[])
}
}
+ if (!gsm_triplet_file && !milenage_file && !sqlite_db_file) {
+ usage();
+ return -1;
+ }
+
+#ifdef CONFIG_SQLITE
+ if (sqlite_db_file && (sqlite_db = db_open(sqlite_db_file)) == NULL)
+ return -1;
+#endif /* CONFIG_SQLITE */
+
if (gsm_triplet_file && read_gsm_triplets(gsm_triplet_file) < 0)
return -1;
@@ -829,6 +1013,13 @@ int main(int argc, char *argv[])
for (;;)
process(serv_sock);
+#ifdef CONFIG_SQLITE
+ if (sqlite_db) {
+ sqlite3_close(sqlite_db);
+ sqlite_db = NULL;
+ }
+#endif /* CONFIG_SQLITE */
+
os_program_deinit();
return 0;