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
This commit is contained in:
parent
fb26c60a2f
commit
3b5d407203
|
@ -242,8 +242,17 @@ int sgsn_ctrl_cmds_install(void);
|
||||||
/*
|
/*
|
||||||
* ACL handling
|
* ACL handling
|
||||||
*/
|
*/
|
||||||
struct imsi_acl_entry;
|
struct imsi_acl_entry {
|
||||||
struct imsi_acl_entry *sgsn_acl_lookup(const char *imsi);
|
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);
|
int gprs_sndcp_vty_init(void);
|
||||||
struct sgsn_instance;
|
struct sgsn_instance;
|
||||||
|
|
|
@ -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 \
|
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 \
|
sgsn_main.c sgsn_vty.c sgsn_libgtp.c \
|
||||||
gprs_llc.c gprs_llc_parse.c gprs_llc_vty.c crc24.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 = \
|
osmo_sgsn_LDADD = \
|
||||||
$(top_builddir)/src/libcommon/libcommon.a \
|
$(top_builddir)/src/libcommon/libcommon.a \
|
||||||
-lgtp $(OSMO_LIBS) $(LIBOSMOABIS_LIBS)
|
-lgtp $(OSMO_LIBS) $(LIBOSMOABIS_LIBS)
|
||||||
|
|
|
@ -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);
|
snprintf(mccmnc, sizeof(mccmnc), "%03d%02d", ra_id.mcc, ra_id.mnc);
|
||||||
if (strncmp(mccmnc, mi_string, 5) &&
|
if (strncmp(mccmnc, mi_string, 5) &&
|
||||||
(sgsn->cfg.acl_enabled &&
|
(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",
|
LOGP(DMM, LOGL_NOTICE, "Rejecting ATTACH REQUEST IMSI=%s\n",
|
||||||
mi_string);
|
mi_string);
|
||||||
return gsm48_tx_gmm_att_rej_oldmsg(msg,
|
return gsm48_tx_gmm_att_rej_oldmsg(msg,
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
|
@ -345,6 +345,7 @@ int main(int argc, char **argv)
|
||||||
bssgp_vty_init();
|
bssgp_vty_init();
|
||||||
gprs_llc_vty_init();
|
gprs_llc_vty_init();
|
||||||
gprs_sndcp_vty_init();
|
gprs_sndcp_vty_init();
|
||||||
|
sgsn_auth_init(&sgsn_inst);
|
||||||
/* FIXME: register signal handler for SS_L_NS */
|
/* FIXME: register signal handler for SS_L_NS */
|
||||||
|
|
||||||
rc = sgsn_parse_config(sgsn_inst.config_file, &sgsn_inst.cfg);
|
rc = sgsn_parse_config(sgsn_inst.config_file, &sgsn_inst.cfg);
|
||||||
|
|
|
@ -41,11 +41,6 @@
|
||||||
|
|
||||||
static struct sgsn_config *g_cfg = NULL;
|
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 */
|
#define GSM48_MAX_APN_LEN 102 /* 10.5.6.1 */
|
||||||
static char *gprs_apn2str(uint8_t *apn, unsigned int len)
|
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;
|
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,
|
DEFUN(imsi_acl, cfg_imsi_acl_cmd,
|
||||||
"imsi-acl (add|del) IMSI",
|
"imsi-acl (add|del) IMSI",
|
||||||
|
@ -383,9 +336,9 @@ DEFUN(imsi_acl, cfg_imsi_acl_cmd,
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
if (!strcmp(op, "add"))
|
if (!strcmp(op, "add"))
|
||||||
rc = sgsn_acl_add(imsi);
|
rc = sgsn_acl_add(imsi, g_cfg);
|
||||||
else
|
else
|
||||||
rc = sgsn_acl_del(imsi);
|
rc = sgsn_acl_del(imsi, g_cfg);
|
||||||
|
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
vty_out(vty, "%% unable to %s ACL\n", op);
|
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;
|
int rc;
|
||||||
|
|
||||||
g_cfg = cfg;
|
g_cfg = cfg;
|
||||||
INIT_LLIST_HEAD(&g_cfg->imsi_acl);
|
|
||||||
|
|
||||||
rc = vty_read_config_file(config_file, NULL);
|
rc = vty_read_config_file(config_file, NULL);
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
|
|
|
@ -15,6 +15,7 @@ sgsn_test_LDADD = \
|
||||||
$(top_builddir)/src/gprs/gprs_sgsn.o \
|
$(top_builddir)/src/gprs/gprs_sgsn.o \
|
||||||
$(top_builddir)/src/gprs/sgsn_vty.o \
|
$(top_builddir)/src/gprs/sgsn_vty.o \
|
||||||
$(top_builddir)/src/gprs/sgsn_libgtp.o \
|
$(top_builddir)/src/gprs/sgsn_libgtp.o \
|
||||||
|
$(top_builddir)/src/gprs/sgsn_auth.o \
|
||||||
$(LIBOSMOCORE_LIBS) \
|
$(LIBOSMOCORE_LIBS) \
|
||||||
$(LIBOSMOGSM_LIBS) \
|
$(LIBOSMOGSM_LIBS) \
|
||||||
$(LIBOSMOGB_LIBS) \
|
$(LIBOSMOGB_LIBS) \
|
||||||
|
|
Loading…
Reference in New Issue