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
diff --git a/openbsc/include/openbsc/gprs_sgsn.h b/openbsc/include/openbsc/gprs_sgsn.h
index 9226c23..5c82227 100644
--- a/openbsc/include/openbsc/gprs_sgsn.h
+++ b/openbsc/include/openbsc/gprs_sgsn.h
@@ -242,8 +242,17 @@
 /*
  * 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 3957877..75eafdd 100644
--- a/openbsc/src/gprs/Makefile.am
+++ b/openbsc/src/gprs/Makefile.am
@@ -22,7 +22,7 @@
 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 99ab276..db0c2db 100644
--- a/openbsc/src/gprs/gprs_gmm.c
+++ b/openbsc/src/gprs/gprs_gmm.c
@@ -791,7 +791,7 @@
 			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 0000000..0a85934
--- /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 <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 <openbsc/sgsn.h>
+#include <openbsc/gprs_sgsn.h>
+
+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 41e11f7..d8e01ff 100644
--- a/openbsc/src/gprs/sgsn_main.c
+++ b/openbsc/src/gprs/sgsn_main.c
@@ -345,6 +345,7 @@
 	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 bfd5333..4c4eef3 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 @@
 	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 @@
 	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 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 af00a34..f822aac 100644
--- a/openbsc/tests/sgsn/Makefile.am
+++ b/openbsc/tests/sgsn/Makefile.am
@@ -15,6 +15,7 @@
 	$(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) \