From 3b5d4072035a87f85ffda6b155cbdd3bbc15deef Mon Sep 17 00:00:00 2001 From: Jacob Erlbeck Date: Fri, 24 Oct 2014 15:11:03 +0200 Subject: [PATCH] sgsn: Moved IMSI ACL management to sgsn_auth.c Currently the ACL code is located in sgsn_vty.c. This commit moves this to a new file sgsn_auth.c as a first step to make authorization more flexible in order to implement remote acquisition on subsciber data. Sponsored-by: On-Waves ehf --- openbsc/include/openbsc/gprs_sgsn.h | 13 +++++- openbsc/src/gprs/Makefile.am | 2 +- openbsc/src/gprs/gprs_gmm.c | 2 +- openbsc/src/gprs/sgsn_auth.c | 71 +++++++++++++++++++++++++++++ openbsc/src/gprs/sgsn_main.c | 1 + openbsc/src/gprs/sgsn_vty.c | 52 +-------------------- openbsc/tests/sgsn/Makefile.am | 1 + 7 files changed, 88 insertions(+), 54 deletions(-) create mode 100644 openbsc/src/gprs/sgsn_auth.c diff --git a/openbsc/include/openbsc/gprs_sgsn.h b/openbsc/include/openbsc/gprs_sgsn.h index 9226c23b9..5c82227d7 100644 --- a/openbsc/include/openbsc/gprs_sgsn.h +++ b/openbsc/include/openbsc/gprs_sgsn.h @@ -242,8 +242,17 @@ int sgsn_ctrl_cmds_install(void); /* * ACL handling */ -struct imsi_acl_entry; -struct imsi_acl_entry *sgsn_acl_lookup(const char *imsi); +struct imsi_acl_entry { + struct llist_head list; + char imsi[16+1]; +}; +struct sgsn_config; +struct sgsn_instance; + +void sgsn_auth_init(struct sgsn_instance *sgi); +struct imsi_acl_entry *sgsn_acl_lookup(const char *imsi, struct sgsn_config *cfg); +int sgsn_acl_add(const char *imsi, struct sgsn_config *cfg); +int sgsn_acl_del(const char *imsi, struct sgsn_config *cfg); int gprs_sndcp_vty_init(void); struct sgsn_instance; diff --git a/openbsc/src/gprs/Makefile.am b/openbsc/src/gprs/Makefile.am index 3957877b8..75eafddd3 100644 --- a/openbsc/src/gprs/Makefile.am +++ b/openbsc/src/gprs/Makefile.am @@ -22,7 +22,7 @@ osmo_gbproxy_LDADD = $(top_builddir)/src/libcommon/libcommon.a \ osmo_sgsn_SOURCES = gprs_gmm.c gprs_sgsn.c gprs_sndcp.c gprs_sndcp_vty.c \ sgsn_main.c sgsn_vty.c sgsn_libgtp.c \ gprs_llc.c gprs_llc_parse.c gprs_llc_vty.c crc24.c \ - sgsn_ctrl.c + sgsn_ctrl.c sgsn_auth.c osmo_sgsn_LDADD = \ $(top_builddir)/src/libcommon/libcommon.a \ -lgtp $(OSMO_LIBS) $(LIBOSMOABIS_LIBS) diff --git a/openbsc/src/gprs/gprs_gmm.c b/openbsc/src/gprs/gprs_gmm.c index 99ab2765c..db0c2dbf7 100644 --- a/openbsc/src/gprs/gprs_gmm.c +++ b/openbsc/src/gprs/gprs_gmm.c @@ -791,7 +791,7 @@ static int gsm48_rx_gmm_att_req(struct sgsn_mm_ctx *ctx, struct msgb *msg, snprintf(mccmnc, sizeof(mccmnc), "%03d%02d", ra_id.mcc, ra_id.mnc); if (strncmp(mccmnc, mi_string, 5) && (sgsn->cfg.acl_enabled && - !sgsn_acl_lookup(mi_string))) { + !sgsn_acl_lookup(mi_string, &sgsn->cfg))) { LOGP(DMM, LOGL_NOTICE, "Rejecting ATTACH REQUEST IMSI=%s\n", mi_string); return gsm48_tx_gmm_att_rej_oldmsg(msg, diff --git a/openbsc/src/gprs/sgsn_auth.c b/openbsc/src/gprs/sgsn_auth.c new file mode 100644 index 000000000..0a85934b0 --- /dev/null +++ b/openbsc/src/gprs/sgsn_auth.c @@ -0,0 +1,71 @@ +/* MS authorization and subscriber data handling */ + +/* (C) 2009-2010 by Harald Welte + * + * 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 . + * + */ + +#include +#include + +void sgsn_auth_init(struct sgsn_instance *sgi) +{ + INIT_LLIST_HEAD(&sgi->cfg.imsi_acl); +} + +/* temporary IMSI ACL hack */ +struct imsi_acl_entry *sgsn_acl_lookup(const char *imsi, struct sgsn_config *cfg) +{ + struct imsi_acl_entry *acl; + llist_for_each_entry(acl, &cfg->imsi_acl, list) { + if (!strcmp(imsi, acl->imsi)) + return acl; + } + return NULL; +} + +int sgsn_acl_add(const char *imsi, struct sgsn_config *cfg) +{ + struct imsi_acl_entry *acl; + + if (sgsn_acl_lookup(imsi, cfg)) + return -EEXIST; + + acl = talloc_zero(NULL, struct imsi_acl_entry); + if (!acl) + return -ENOMEM; + strncpy(acl->imsi, imsi, sizeof(acl->imsi)); + + llist_add(&acl->list, &cfg->imsi_acl); + + return 0; +} + +int sgsn_acl_del(const char *imsi, struct sgsn_config *cfg) +{ + struct imsi_acl_entry *acl; + + acl = sgsn_acl_lookup(imsi, cfg); + if (!acl) + return -ENODEV; + + llist_del(&acl->list); + talloc_free(acl); + + return 0; +} + diff --git a/openbsc/src/gprs/sgsn_main.c b/openbsc/src/gprs/sgsn_main.c index 41e11f72b..d8e01ff09 100644 --- a/openbsc/src/gprs/sgsn_main.c +++ b/openbsc/src/gprs/sgsn_main.c @@ -345,6 +345,7 @@ int main(int argc, char **argv) bssgp_vty_init(); gprs_llc_vty_init(); gprs_sndcp_vty_init(); + sgsn_auth_init(&sgsn_inst); /* FIXME: register signal handler for SS_L_NS */ rc = sgsn_parse_config(sgsn_inst.config_file, &sgsn_inst.cfg); diff --git a/openbsc/src/gprs/sgsn_vty.c b/openbsc/src/gprs/sgsn_vty.c index bfd5333d3..4c4eef331 100644 --- a/openbsc/src/gprs/sgsn_vty.c +++ b/openbsc/src/gprs/sgsn_vty.c @@ -41,11 +41,6 @@ static struct sgsn_config *g_cfg = NULL; -struct imsi_acl_entry { - struct llist_head list; - char imsi[16+1]; -}; - #define GSM48_MAX_APN_LEN 102 /* 10.5.6.1 */ static char *gprs_apn2str(uint8_t *apn, unsigned int len) { @@ -328,48 +323,6 @@ DEFUN(show_pdpctx_all, show_pdpctx_all_cmd, return CMD_SUCCESS; } -/* temporary IMSI ACL hack */ -struct imsi_acl_entry *sgsn_acl_lookup(const char *imsi) -{ - struct imsi_acl_entry *acl; - llist_for_each_entry(acl, &g_cfg->imsi_acl, list) { - if (!strcmp(imsi, acl->imsi)) - return acl; - } - return NULL; -} - -int sgsn_acl_add(const char *imsi) -{ - struct imsi_acl_entry *acl; - - if (sgsn_acl_lookup(imsi)) - return -EEXIST; - - acl = talloc_zero(NULL, struct imsi_acl_entry); - if (!acl) - return -ENOMEM; - strncpy(acl->imsi, imsi, sizeof(acl->imsi)); - - llist_add(&acl->list, &g_cfg->imsi_acl); - - return 0; -} - -int sgsn_acl_del(const char *imsi) -{ - struct imsi_acl_entry *acl; - - acl = sgsn_acl_lookup(imsi); - if (!acl) - return -ENODEV; - - llist_del(&acl->list); - talloc_free(acl); - - return 0; -} - DEFUN(imsi_acl, cfg_imsi_acl_cmd, "imsi-acl (add|del) IMSI", @@ -383,9 +336,9 @@ DEFUN(imsi_acl, cfg_imsi_acl_cmd, int rc; if (!strcmp(op, "add")) - rc = sgsn_acl_add(imsi); + rc = sgsn_acl_add(imsi, g_cfg); else - rc = sgsn_acl_del(imsi); + rc = sgsn_acl_del(imsi, g_cfg); if (rc < 0) { vty_out(vty, "%% unable to %s ACL\n", op); @@ -435,7 +388,6 @@ int sgsn_parse_config(const char *config_file, struct sgsn_config *cfg) int rc; g_cfg = cfg; - INIT_LLIST_HEAD(&g_cfg->imsi_acl); rc = vty_read_config_file(config_file, NULL); if (rc < 0) { diff --git a/openbsc/tests/sgsn/Makefile.am b/openbsc/tests/sgsn/Makefile.am index af00a34a8..f822aac44 100644 --- a/openbsc/tests/sgsn/Makefile.am +++ b/openbsc/tests/sgsn/Makefile.am @@ -15,6 +15,7 @@ sgsn_test_LDADD = \ $(top_builddir)/src/gprs/gprs_sgsn.o \ $(top_builddir)/src/gprs/sgsn_vty.o \ $(top_builddir)/src/gprs/sgsn_libgtp.o \ + $(top_builddir)/src/gprs/sgsn_auth.o \ $(LIBOSMOCORE_LIBS) \ $(LIBOSMOGSM_LIBS) \ $(LIBOSMOGB_LIBS) \