9
0
Fork 0
This repository has been archived on 2022-03-30. You can view files and clone it, but cannot push or open issues or pull requests.
osmo-auc/src/auc_rec_csv.c

237 lines
5.0 KiB
C

/* (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, long offset_nextline)
{
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);
if (strlen(tok) != 8)
printf("SQN must be 8 digits wide in order to support updates\n");
else {
/* save file offfset for SQN so we can update it */
rec->offset_sqn = offset_nextline - (strlen(line_orig) - (tok - line));
}
/* 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;
long offset_nextline;
if (line[0] == '#')
continue;
offset_nextline = ftell(file);
rec = auc_rec_from_csv(ctx, line, offset_nextline);
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;
}