mirror of
https://gitea.osmocom.org/cellular-infrastructure/osmo-mgw.git
synced 2025-11-01 20:43:47 +00:00
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
This commit is contained in:
committed by
Holger Hans Peter Freyther
parent
144b8b1ca7
commit
106f547733
@@ -7,6 +7,12 @@
|
|||||||
#include <osmocom/gprs/gprs_ns.h>
|
#include <osmocom/gprs/gprs_ns.h>
|
||||||
#include <openbsc/gprs_sgsn.h>
|
#include <openbsc/gprs_sgsn.h>
|
||||||
|
|
||||||
|
enum sgsn_auth_policy {
|
||||||
|
SGSN_AUTH_POLICY_OPEN,
|
||||||
|
SGSN_AUTH_POLICY_CLOSED,
|
||||||
|
SGSN_AUTH_POLICY_ACL_ONLY
|
||||||
|
};
|
||||||
|
|
||||||
struct sgsn_config {
|
struct sgsn_config {
|
||||||
/* parsed from config file */
|
/* parsed from config file */
|
||||||
|
|
||||||
@@ -16,7 +22,7 @@ struct sgsn_config {
|
|||||||
/* misc */
|
/* misc */
|
||||||
struct gprs_ns_inst *nsi;
|
struct gprs_ns_inst *nsi;
|
||||||
|
|
||||||
int acl_enabled;
|
enum sgsn_auth_policy auth_policy;
|
||||||
struct llist_head imsi_acl;
|
struct llist_head imsi_acl;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -83,25 +83,41 @@ enum sgsn_auth_state sgsn_auth_state(struct sgsn_mm_ctx *mmctx,
|
|||||||
struct sgsn_config *cfg)
|
struct sgsn_config *cfg)
|
||||||
{
|
{
|
||||||
char mccmnc[16];
|
char mccmnc[16];
|
||||||
|
int check_net = 0;
|
||||||
|
int check_acl = 0;
|
||||||
|
|
||||||
OSMO_ASSERT(mmctx);
|
OSMO_ASSERT(mmctx);
|
||||||
|
|
||||||
if (!sgsn->cfg.acl_enabled)
|
switch (sgsn->cfg.auth_policy) {
|
||||||
|
case SGSN_AUTH_POLICY_OPEN:
|
||||||
return SGSN_AUTH_ACCEPTED;
|
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)) {
|
if (!strlen(mmctx->imsi)) {
|
||||||
LOGMMCTXP(LOGL_NOTICE, mmctx,
|
LOGMMCTXP(LOGL_NOTICE, mmctx,
|
||||||
"Missing IMSI, authorization state not known\n");
|
"Missing IMSI, authorization state not known\n");
|
||||||
return SGSN_AUTH_UNKNOWN;
|
return SGSN_AUTH_UNKNOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* As a temorary hack, we simply assume that the IMSI exists,
|
if (check_net) {
|
||||||
* as long as it is part of 'our' network */
|
/* We simply assume that the IMSI exists, as long as it is part
|
||||||
snprintf(mccmnc, sizeof(mccmnc), "%03d%02d", mmctx->ra.mcc, mmctx->ra.mnc);
|
* of 'our' network */
|
||||||
if (strncmp(mccmnc, mmctx->imsi, 5) == 0)
|
snprintf(mccmnc, sizeof(mccmnc), "%03d%02d",
|
||||||
return SGSN_AUTH_ACCEPTED;
|
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_ACCEPTED;
|
||||||
|
|
||||||
return SGSN_AUTH_REJECTED;
|
return SGSN_AUTH_REJECTED;
|
||||||
|
|||||||
@@ -78,7 +78,7 @@ static struct sgsn_instance sgsn_inst = {
|
|||||||
.config_file = "osmo_sgsn.cfg",
|
.config_file = "osmo_sgsn.cfg",
|
||||||
.cfg = {
|
.cfg = {
|
||||||
.gtp_statedir = "./",
|
.gtp_statedir = "./",
|
||||||
.acl_enabled = 1,
|
.auth_policy = SGSN_AUTH_POLICY_CLOSED,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
struct sgsn_instance *sgsn = &sgsn_inst;
|
struct sgsn_instance *sgsn = &sgsn_inst;
|
||||||
|
|||||||
@@ -41,6 +41,14 @@
|
|||||||
|
|
||||||
static struct sgsn_config *g_cfg = NULL;
|
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 */
|
#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)
|
||||||
{
|
{
|
||||||
@@ -127,7 +135,8 @@ static int config_write_sgsn(struct vty *vty)
|
|||||||
}
|
}
|
||||||
|
|
||||||
vty_out(vty, " auth-policy %s%s",
|
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)
|
llist_for_each_entry(acl, &g_cfg->imsi_acl, list)
|
||||||
vty_out(vty, " imsi-acl add %s%s", acl->imsi, VTY_NEWLINE);
|
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,
|
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"
|
"Autorization Policy of SGSN\n"
|
||||||
"Accept all IMSIs (DANGEROUS\n"
|
"Accept all IMSIs (DANGEROUS)\n"
|
||||||
"Accept only home network subscribers or those in ACL\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"))
|
int val = get_string_value(sgsn_auth_pol_strs, argv[0]);
|
||||||
g_cfg->acl_enabled = 0;
|
OSMO_ASSERT(val >= SGSN_AUTH_POLICY_OPEN && val <= SGSN_AUTH_POLICY_ACL_ONLY);
|
||||||
else
|
g_cfg->auth_policy = val;
|
||||||
g_cfg->acl_enabled = 1;
|
|
||||||
|
|
||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ static struct sgsn_instance sgsn_inst = {
|
|||||||
.config_file = "osmo_sgsn.cfg",
|
.config_file = "osmo_sgsn.cfg",
|
||||||
.cfg = {
|
.cfg = {
|
||||||
.gtp_statedir = "./",
|
.gtp_statedir = "./",
|
||||||
.acl_enabled = 1,
|
.auth_policy = SGSN_AUTH_POLICY_CLOSED,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
struct sgsn_instance *sgsn = &sgsn_inst;
|
struct sgsn_instance *sgsn = &sgsn_inst;
|
||||||
|
|||||||
@@ -722,6 +722,22 @@ class TestVTYSGSN(TestVTYGenericBSC):
|
|||||||
res = self.vty.command("show llc")
|
res = self.vty.command("show llc")
|
||||||
self.assert_(res.find('State of LLC Entities') >= 0)
|
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):
|
def add_nat_test(suite, workdir):
|
||||||
if not os.path.isfile(os.path.join(workdir, "src/osmo-bsc_nat/osmo-bsc_nat")):
|
if not os.path.isfile(os.path.join(workdir, "src/osmo-bsc_nat/osmo-bsc_nat")):
|
||||||
print("Skipping the NAT test")
|
print("Skipping the NAT test")
|
||||||
|
|||||||
Reference in New Issue
Block a user