diff options
author | Harald Welte <laforge@gnumonks.org> | 2012-09-14 11:11:42 +0200 |
---|---|---|
committer | Harald Welte <laforge@gnumonks.org> | 2012-09-14 11:11:42 +0200 |
commit | bfe531b54943751019d44fa4eef017d7936c3610 (patch) | |
tree | 209a4af91840a783ad4a4dfd1fd69b243450e666 /src/auc_core.c |
initial import of a minimalistic AUC (authentication center) core
Diffstat (limited to 'src/auc_core.c')
-rw-r--r-- | src/auc_core.c | 125 |
1 files changed, 125 insertions, 0 deletions
diff --git a/src/auc_core.c b/src/auc_core.c new file mode 100644 index 0000000..0fd09f8 --- /dev/null +++ b/src/auc_core.c @@ -0,0 +1,125 @@ +/* (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 <errno.h> +#include <string.h> + +#include <osmocom/core/linuxlist.h> +#include <osmocom/crypt/auth.h> + +#include "auc.h" + +#define NBUCKETS 1024 +static struct llist_head auc_buckets[NBUCKETS]; + +int auc_core_init(void *ctx) +{ + int i; + + for (i = 0; i < NBUCKETS; i++) + INIT_LLIST_HEAD(&auc_buckets[i]); + + return 0; +} + +static unsigned int osmo_auc_hashfn(const char *imsi) +{ + int len = strlen(imsi); + unsigned int res; + + res = atoi(imsi + len - 6); + + return res % NBUCKETS; +} + +int auc_add_rec(struct auc_rec *rec) +{ + struct auc_rec *exist; + unsigned int hash = osmo_auc_hashfn(rec->imsi); + struct llist_head *list = &auc_buckets[hash]; + + /* make sure we don't get duplicates */ + llist_for_each_entry(exist, list, hash_list) { + if (!strcmp(exist->imsi, rec->imsi)) + return -EEXIST; + } + + llist_add(&rec->hash_list, list); + + return 0; +} + +struct auc_rec *auc_lookup(const char *imsi) +{ + struct auc_rec *exist; + unsigned int hash = osmo_auc_hashfn(imsi); + struct llist_head *list = &auc_buckets[hash]; + + /* make sure we don't get duplicates */ + llist_for_each_entry(exist, list, hash_list) { + if (!strcmp(exist->imsi, imsi)) + return exist; + } + + return NULL; +} + +int auc_gen_vecs(struct osmo_auth_vector *vec, + const char *imsi, int n_vecs) +{ + struct auc_rec *rec; + int i; + + rec = auc_lookup(imsi); + if (!rec) + return -ENOENT; + + for (i = 0; i < n_vecs; i++) { + uint8_t rand[16]; + int rc; + + rc = auc_get_rand(rand, sizeof(rand)); + if (rc < 0) + return rc; + rc = osmo_auth_gen_vec(&vec[i], &rec->auth, rand); + if (rc < 0) + return rc; + } + + return 0; +} + +int auc_gen_vec_auts(struct osmo_auth_vector *vec, + const char *imsi, const uint8_t *rand_auts, + const uint8_t *auts) +{ + struct auc_rec *rec; + uint8_t rand[16]; + int rc; + + rec = auc_lookup(imsi); + if (!rec) + return -ENOENT; + + rc = auc_get_rand(rand, sizeof(rand)); + if (rc < 0) + return rc; + + return osmo_auth_gen_vec_auts(vec, &rec->auth, rand_auts, auts, rand); +} |