summaryrefslogtreecommitdiffstats
path: root/src/auc_rec_csv.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/auc_rec_csv.c')
-rw-r--r--src/auc_rec_csv.c226
1 files changed, 226 insertions, 0 deletions
diff --git a/src/auc_rec_csv.c b/src/auc_rec_csv.c
new file mode 100644
index 0000000..21a87a8
--- /dev/null
+++ b/src/auc_rec_csv.c
@@ -0,0 +1,226 @@
+/* (C) 2012 by Harald Welte <laforge@gnumonks.org>
+ *
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+#include <string.h>
+#include <errno.h>
+
+#include <osmocom/core/talloc.h>
+#include <osmocom/core/utils.h>
+#include "auc.h"
+
+/*
+# imsi,algo,ki,0,0,0,0
+# imsi,algo,k,opc,amf,sqn,opc_is_op
+2620301,1,000102030405060708090a0b0c0d0e0f,0,0,0,0
+2620301,1,000102030405060708090a0b0c0d0e0f,0f0e0d0c0b0a09080706050403020100,0001,32,0
+*/
+
+static struct auc_rec *auc_rec_from_csv(void *ctx,
+ const char *line_orig)
+{
+ char *line = talloc_strdup(ctx, line_orig);
+ char *tok;
+ struct auc_rec *rec;
+
+ if (!line)
+ return NULL;
+
+ rec = talloc_zero(ctx, struct auc_rec);
+ if (!rec) {
+ talloc_free(line);
+ return NULL;
+ }
+
+ /* IMSI */
+ tok = strtok(line, ",");
+ if (!tok)
+ goto ret_free;
+ strncpy(rec->imsi, tok, OSMO_MIN(strlen(tok), sizeof(rec->imsi)));
+ rec->imsi[sizeof(rec->imsi)-1] = '\0';
+
+ /* ALGO */
+ tok = strtok(NULL, ",");
+ if (!tok)
+ goto ret_free;
+ rec->auth.algo = atoi(tok);
+ if (rec->auth.algo > _OSMO_AUTH_ALG_NUM)
+ goto ret_free;
+
+ /* K / Ki */
+ tok = strtok(NULL, ",");
+ if (!tok)
+ goto ret_free;
+
+ switch (rec->auth.algo) {
+ case OSMO_AUTH_ALG_NONE:
+
+ break;
+ case OSMO_AUTH_ALG_COMP128v1:
+ case OSMO_AUTH_ALG_COMP128v2:
+ case OSMO_AUTH_ALG_COMP128v3:
+ osmo_hexparse(tok, rec->auth.u.gsm.ki,
+ sizeof(rec->auth.u.gsm.ki));
+ break;
+ case OSMO_AUTH_ALG_XOR:
+ case OSMO_AUTH_ALG_MILENAGE:
+ osmo_hexparse(tok, rec->auth.u.umts.k,
+ sizeof(rec->auth.u.umts.k));
+ /* OPC */
+ tok = strtok(NULL, ",");
+ if (!tok)
+ goto ret_free;
+ osmo_hexparse(tok, rec->auth.u.umts.opc,
+ sizeof(rec->auth.u.umts.opc));
+ /* AMF */
+ tok = strtok(NULL, ",");
+ if (!tok)
+ goto ret_free;
+ osmo_hexparse(tok, rec->auth.u.umts.amf,
+ sizeof(rec->auth.u.umts.amf));
+ /* SQN */
+ tok = strtok(NULL, ",");
+ if (!tok)
+ goto ret_free;
+ rec->auth.u.umts.sqn = strtoull(tok, NULL, 10);
+ /* IS_OP */
+ tok = strtok(NULL, ",");
+ if (!tok)
+ goto ret_free;
+ if (tok[0] == '1')
+ rec->auth.u.umts.opc_is_op = 1;
+ break;
+ }
+
+ talloc_free(line);
+
+ return rec;
+
+ret_free:
+ talloc_free(rec);
+ talloc_free(line);
+ return NULL;
+}
+
+static char *auc_rec_to_csv(void *ctx, const struct auc_rec *rec)
+{
+ char *line = talloc_zero_size(ctx, 256);
+ char *cur = line;
+ int i;
+
+ if (!line)
+ return NULL;
+
+ i = sprintf("%s,%u,", rec->imsi, rec->auth.algo);
+ if (i < 0)
+ goto ret_free;
+ cur += i;
+
+ switch (rec->auth.algo) {
+ case OSMO_AUTH_ALG_NONE:
+ break;
+ case OSMO_AUTH_ALG_COMP128v1:
+ case OSMO_AUTH_ALG_COMP128v2:
+ case OSMO_AUTH_ALG_COMP128v3:
+ i = sprintf(cur, "%s,0,0,0,0",
+ osmo_hexdump_nospc(rec->auth.u.gsm.ki,
+ sizeof(rec->auth.u.gsm.ki)));
+ if (i < 0)
+ goto ret_free;
+ cur += i;
+ break;
+ case OSMO_AUTH_ALG_XOR:
+ case OSMO_AUTH_ALG_MILENAGE:
+ i = sprintf(cur, "%s,",
+ osmo_hexdump_nospc(rec->auth.u.umts.k,
+ sizeof(rec->auth.u.umts.k)));
+ if (i < 0)
+ goto ret_free;
+ cur += i;
+
+ i = sprintf(cur, "%s,",
+ osmo_hexdump_nospc(rec->auth.u.umts.opc,
+ sizeof(rec->auth.u.umts.opc)));
+ if (i < 0)
+ goto ret_free;
+ cur += i;
+
+ i = sprintf(cur, "%s,",
+ osmo_hexdump_nospc(rec->auth.u.umts.amf,
+ sizeof(rec->auth.u.umts.amf)));
+ if (i < 0)
+ goto ret_free;
+ cur += i;
+
+ i = sprintf(cur, "%llu,%u", rec->auth.u.umts.sqn,
+ rec->auth.u.umts.opc_is_op);
+ if (i < 0)
+ goto ret_free;
+ cur += i;
+ break;
+ }
+
+ return line;
+
+ret_free:
+ talloc_free(line);
+ return NULL;
+}
+
+int auc_storage_read(void *ctx, const char *fname)
+{
+ FILE *file = fopen(fname, "r");
+ char *line = talloc_zero_size(ctx, 256);
+ int rc, num = 0;
+
+ while ((line = fgets(line, 256, file))) {
+ struct auc_rec *rec;
+
+ if (line[0] == '#')
+ continue;
+
+ rec = auc_rec_from_csv(ctx, line);
+ if (!rec)
+ continue;
+
+ rc = auc_add_rec(rec);
+ if (rc == 0)
+ num++;
+ }
+
+ return num;
+}
+
+static int auc_rec_dump(void *priv, void *ctx,
+ const struct auc_rec *rec)
+{
+ FILE *file = priv;
+ char *line;
+ int rc;
+
+ line = auc_rec_to_csv(ctx, rec);
+ if (!line)
+ return -EIO;
+
+ rc = fputs(line, file);
+
+ talloc_free(line);
+
+ return rc;
+}