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:
parent
144b8b1ca7
commit
106f547733
|
@ -7,6 +7,12 @@
|
|||
#include <osmocom/gprs/gprs_ns.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 {
|
||||
/* 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;
|
||||
};
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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")
|
||||
|
|
Loading…
Reference in New Issue