From 106f547733450afda1ddbd7e886dc8c902fed4d4 Mon Sep 17 00:00:00 2001 From: Jacob Erlbeck Date: Tue, 4 Nov 2014 10:08:37 +0100 Subject: sgsn: Add 'acl-only' authentication policy Currently the VTY 'auth-policy' command results in setting or clearing the acl_enabled flag. This also enables the matching of the MCC/MNC prefix of the IMSI. This patch adds an additional policy 'acl-only' which disables the MCC/MNC matching and relies on the ACL only. Sponsored-by: On-Waves ehf --- openbsc/include/openbsc/sgsn.h | 8 +++++++- openbsc/src/gprs/sgsn_auth.c | 30 +++++++++++++++++++++++------- openbsc/src/gprs/sgsn_main.c | 2 +- openbsc/src/gprs/sgsn_vty.c | 25 +++++++++++++++++-------- openbsc/tests/sgsn/sgsn_test.c | 2 +- openbsc/tests/vty_test_runner.py | 16 ++++++++++++++++ 6 files changed, 65 insertions(+), 18 deletions(-) (limited to 'openbsc') diff --git a/openbsc/include/openbsc/sgsn.h b/openbsc/include/openbsc/sgsn.h index f7af7509b..33bc72f9d 100644 --- a/openbsc/include/openbsc/sgsn.h +++ b/openbsc/include/openbsc/sgsn.h @@ -7,6 +7,12 @@ #include #include +enum sgsn_auth_policy { + SGSN_AUTH_POLICY_OPEN, + SGSN_AUTH_POLICY_CLOSED, + SGSN_AUTH_POLICY_ACL_ONLY +}; + struct sgsn_config { /* parsed from config file */ @@ -16,7 +22,7 @@ struct sgsn_config { /* misc */ struct gprs_ns_inst *nsi; - int acl_enabled; + enum sgsn_auth_policy auth_policy; struct llist_head imsi_acl; }; diff --git a/openbsc/src/gprs/sgsn_auth.c b/openbsc/src/gprs/sgsn_auth.c index e123909f2..d2d4913b6 100644 --- a/openbsc/src/gprs/sgsn_auth.c +++ b/openbsc/src/gprs/sgsn_auth.c @@ -83,25 +83,41 @@ enum sgsn_auth_state sgsn_auth_state(struct sgsn_mm_ctx *mmctx, struct sgsn_config *cfg) { char mccmnc[16]; + int check_net = 0; + int check_acl = 0; OSMO_ASSERT(mmctx); - if (!sgsn->cfg.acl_enabled) + switch (sgsn->cfg.auth_policy) { + case SGSN_AUTH_POLICY_OPEN: return SGSN_AUTH_ACCEPTED; + case SGSN_AUTH_POLICY_CLOSED: + check_net = 1; + check_acl = 1; + break; + + case SGSN_AUTH_POLICY_ACL_ONLY: + check_acl = 1; + break; + } + if (!strlen(mmctx->imsi)) { LOGMMCTXP(LOGL_NOTICE, mmctx, "Missing IMSI, authorization state not known\n"); return SGSN_AUTH_UNKNOWN; } - /* As a temorary hack, we simply assume that the IMSI exists, - * as long as it is part of 'our' network */ - snprintf(mccmnc, sizeof(mccmnc), "%03d%02d", mmctx->ra.mcc, mmctx->ra.mnc); - if (strncmp(mccmnc, mmctx->imsi, 5) == 0) - return SGSN_AUTH_ACCEPTED; + if (check_net) { + /* We simply assume that the IMSI exists, as long as it is part + * of 'our' network */ + snprintf(mccmnc, sizeof(mccmnc), "%03d%02d", + mmctx->ra.mcc, mmctx->ra.mnc); + if (strncmp(mccmnc, mmctx->imsi, 5) == 0) + return SGSN_AUTH_ACCEPTED; + } - if (sgsn_acl_lookup(mmctx->imsi, &sgsn->cfg)) + if (check_acl && sgsn_acl_lookup(mmctx->imsi, &sgsn->cfg)) return SGSN_AUTH_ACCEPTED; return SGSN_AUTH_REJECTED; diff --git a/openbsc/src/gprs/sgsn_main.c b/openbsc/src/gprs/sgsn_main.c index d8e01ff09..c7c852d5e 100644 --- a/openbsc/src/gprs/sgsn_main.c +++ b/openbsc/src/gprs/sgsn_main.c @@ -78,7 +78,7 @@ static struct sgsn_instance sgsn_inst = { .config_file = "osmo_sgsn.cfg", .cfg = { .gtp_statedir = "./", - .acl_enabled = 1, + .auth_policy = SGSN_AUTH_POLICY_CLOSED, }, }; struct sgsn_instance *sgsn = &sgsn_inst; diff --git a/openbsc/src/gprs/sgsn_vty.c b/openbsc/src/gprs/sgsn_vty.c index 4c4eef331..63816710e 100644 --- a/openbsc/src/gprs/sgsn_vty.c +++ b/openbsc/src/gprs/sgsn_vty.c @@ -41,6 +41,14 @@ static struct sgsn_config *g_cfg = NULL; +const struct value_string sgsn_auth_pol_strs[] = { + { SGSN_AUTH_POLICY_OPEN, "accept-all" }, + { SGSN_AUTH_POLICY_CLOSED, "closed" }, + { SGSN_AUTH_POLICY_ACL_ONLY, "acl-only" }, + { 0, NULL } +}; + + #define GSM48_MAX_APN_LEN 102 /* 10.5.6.1 */ static char *gprs_apn2str(uint8_t *apn, unsigned int len) { @@ -127,7 +135,8 @@ static int config_write_sgsn(struct vty *vty) } vty_out(vty, " auth-policy %s%s", - g_cfg->acl_enabled ? "closed" : "accept-all", VTY_NEWLINE); + get_value_string(sgsn_auth_pol_strs, g_cfg->auth_policy), + VTY_NEWLINE); llist_for_each_entry(acl, &g_cfg->imsi_acl, list) vty_out(vty, " imsi-acl add %s%s", acl->imsi, VTY_NEWLINE); @@ -349,15 +358,15 @@ DEFUN(imsi_acl, cfg_imsi_acl_cmd, } DEFUN(cfg_auth_policy, cfg_auth_policy_cmd, - "auth-policy (accept-all|closed)", + "auth-policy (accept-all|closed|acl-only)", "Autorization Policy of SGSN\n" - "Accept all IMSIs (DANGEROUS\n" - "Accept only home network subscribers or those in ACL\n") + "Accept all IMSIs (DANGEROUS)\n" + "Accept only home network subscribers or those in the ACL\n" + "Accept only subscribers in the ACL\n") { - if (!strcmp(argv[0], "accept-all")) - g_cfg->acl_enabled = 0; - else - g_cfg->acl_enabled = 1; + int val = get_string_value(sgsn_auth_pol_strs, argv[0]); + OSMO_ASSERT(val >= SGSN_AUTH_POLICY_OPEN && val <= SGSN_AUTH_POLICY_ACL_ONLY); + g_cfg->auth_policy = val; return CMD_SUCCESS; } diff --git a/openbsc/tests/sgsn/sgsn_test.c b/openbsc/tests/sgsn/sgsn_test.c index 218092f2c..00259a571 100644 --- a/openbsc/tests/sgsn/sgsn_test.c +++ b/openbsc/tests/sgsn/sgsn_test.c @@ -41,7 +41,7 @@ static struct sgsn_instance sgsn_inst = { .config_file = "osmo_sgsn.cfg", .cfg = { .gtp_statedir = "./", - .acl_enabled = 1, + .auth_policy = SGSN_AUTH_POLICY_CLOSED, }, }; struct sgsn_instance *sgsn = &sgsn_inst; diff --git a/openbsc/tests/vty_test_runner.py b/openbsc/tests/vty_test_runner.py index 82c0871a8..468d415e8 100644 --- a/openbsc/tests/vty_test_runner.py +++ b/openbsc/tests/vty_test_runner.py @@ -722,6 +722,22 @@ class TestVTYSGSN(TestVTYGenericBSC): res = self.vty.command("show llc") self.assert_(res.find('State of LLC Entities') >= 0) + def testVtyAuth(self): + self.vty.enable() + self.assertTrue(self.vty.verify('configure terminal', [''])) + self.assertEquals(self.vty.node(), 'config') + self.assertTrue(self.vty.verify('sgsn', [''])) + self.assertEquals(self.vty.node(), 'config-sgsn') + self.assertTrue(self.vty.verify('auth-policy accept-all', [''])) + res = self.vty.command("show running-config") + self.assert_(res.find('auth-policy accept-all') > 0) + self.assertTrue(self.vty.verify('auth-policy acl-only', [''])) + res = self.vty.command("show running-config") + self.assert_(res.find('auth-policy acl-only') > 0) + self.assertTrue(self.vty.verify('auth-policy closed', [''])) + res = self.vty.command("show running-config") + self.assert_(res.find('auth-policy closed') > 0) + def add_nat_test(suite, workdir): if not os.path.isfile(os.path.join(workdir, "src/osmo-bsc_nat/osmo-bsc_nat")): print("Skipping the NAT test") -- cgit v1.2.3