[nat] Implement IMSI filtering...
This commit is contained in:
parent
f830322846
commit
34a96aeb32
|
@ -193,6 +193,54 @@ int bsc_write(struct bsc_connection *bsc, struct msgb *msg, int proto)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* apply white/black list */
|
||||
static int auth_imsi(struct bsc_connection *bsc, const char *mi_string)
|
||||
{
|
||||
regmatch_t match[1];
|
||||
|
||||
/*
|
||||
* Now apply blacklist/whitelist of the BSC and the NAT.
|
||||
* 1.) Reject if the IMSI is not allowed at the BSC
|
||||
* 2.) Allow directly if the IMSI is allowed at the BSC
|
||||
* 3.) Reject if the IMSI not allowed at the global level.
|
||||
* 4.) Allow directly if the IMSI is allowed at the global level
|
||||
*/
|
||||
|
||||
/* 1. BSC deny */
|
||||
if (bsc->cfg->imsi_deny) {
|
||||
if (regexec(&bsc->cfg->imsi_deny_re, mi_string, 1, match, 0) == 0) {
|
||||
LOGP(DNAT, LOGL_ERROR,
|
||||
"Filtering %s by imsi_deny.\n", mi_string);
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
|
||||
/* 2. BSC allow */
|
||||
if (bsc->cfg->imsi_allow) {
|
||||
if (regexec(&bsc->cfg->imsi_allow_re, mi_string, 1, match, 0) == 0)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* 3. NAT deny */
|
||||
if (bsc->nat->imsi_deny) {
|
||||
if (regexec(&bsc->nat->imsi_deny_re, mi_string, 1, match, 0) == 0) {
|
||||
LOGP(DNAT, LOGL_ERROR,
|
||||
"Filtering %s by nat imsi_deny.\n", mi_string);
|
||||
return -3;
|
||||
}
|
||||
}
|
||||
|
||||
/* 4. NAT allow */
|
||||
if (bsc->nat->imsi_allow) {
|
||||
if (regexec(&bsc->nat->imsi_allow_re, mi_string, 0, NULL, 0) == 0)
|
||||
return 0;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* unmatched */
|
||||
return -3;
|
||||
}
|
||||
|
||||
static int _cr_check_loc_upd(struct bsc_connection *bsc, uint8_t *data, unsigned int length)
|
||||
{
|
||||
|
@ -217,12 +265,7 @@ static int _cr_check_loc_upd(struct bsc_connection *bsc, uint8_t *data, unsigned
|
|||
return 0;
|
||||
|
||||
gsm48_mi_to_string(mi_string, sizeof(mi_string), lu->mi, lu->mi_len);
|
||||
|
||||
/*
|
||||
* Now apply blacklist/whitelist
|
||||
*/
|
||||
|
||||
return 0;
|
||||
return auth_imsi(bsc, mi_string);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -108,6 +108,17 @@ static const u_int8_t mgcp_msg[] = {
|
|||
0x20, 0x20, 0x20,
|
||||
};
|
||||
|
||||
/* location updating request */
|
||||
static const u_int8_t bss_lu[] = {
|
||||
0x00, 0x2e, 0xfd,
|
||||
0x01, 0x91, 0x45, 0x14, 0x02, 0x02, 0x04, 0x02,
|
||||
0x42, 0xfe, 0x0f, 0x21, 0x00, 0x1f, 0x57, 0x05,
|
||||
0x08, 0x00, 0x72, 0xf4, 0x80, 0x20, 0x14, 0xc3,
|
||||
0x50, 0x17, 0x12, 0x05, 0x08, 0x70, 0x72, 0xf4,
|
||||
0x80, 0xff, 0xfe, 0x30, 0x08, 0x29, 0x44, 0x50,
|
||||
0x12, 0x03, 0x24, 0x01, 0x95, 0x00
|
||||
};
|
||||
|
||||
struct filter_result {
|
||||
const u_int8_t *data;
|
||||
const u_int16_t length;
|
||||
|
@ -540,21 +551,106 @@ static void test_mgcp_parse(void)
|
|||
}
|
||||
}
|
||||
|
||||
struct cr_filter {
|
||||
const u_int8_t *data;
|
||||
int length;
|
||||
int result;
|
||||
|
||||
const char *bsc_imsi_allow;
|
||||
const char *bsc_imsi_deny;
|
||||
const char *nat_imsi_allow;
|
||||
const char *nat_imsi_deny;
|
||||
};
|
||||
|
||||
static struct cr_filter cr_filter[] = {
|
||||
{
|
||||
.data = bssmap_cr,
|
||||
.length = sizeof(bssmap_cr),
|
||||
.result = 0,
|
||||
},
|
||||
{
|
||||
.data = bss_lu,
|
||||
.length = sizeof(bss_lu),
|
||||
.result = 0,
|
||||
},
|
||||
{
|
||||
/* nat deny is before blank/null BSC */
|
||||
.data = bss_lu,
|
||||
.length = sizeof(bss_lu),
|
||||
.result = -3,
|
||||
.nat_imsi_deny = "[0-9]*",
|
||||
},
|
||||
{
|
||||
/* nat deny is before blank/null BSC */
|
||||
.data = bss_lu,
|
||||
.length = sizeof(bss_lu),
|
||||
.result = -3,
|
||||
.nat_imsi_deny = "[0-9]*",
|
||||
.bsc_imsi_allow = "(2440(*",
|
||||
},
|
||||
{
|
||||
/* BSC allow is before NAT deny */
|
||||
.data = bss_lu,
|
||||
.length = sizeof(bss_lu),
|
||||
.result = 0,
|
||||
.bsc_imsi_allow = "[0-9]*",
|
||||
.nat_imsi_deny = "[0-9]*",
|
||||
},
|
||||
{
|
||||
/* filter as deny is first */
|
||||
.data = bss_lu,
|
||||
.length = sizeof(bss_lu),
|
||||
.result = -2,
|
||||
.bsc_imsi_deny = "[0-9]*",
|
||||
.bsc_imsi_allow = "[0-9]*",
|
||||
.nat_imsi_deny = "[0-9]*",
|
||||
.nat_imsi_allow = "[0-9]*",
|
||||
},
|
||||
|
||||
};
|
||||
|
||||
static void test_cr_filter()
|
||||
{
|
||||
int i, res;
|
||||
struct msgb *msg = msgb_alloc(4096, "test_cr_filter");
|
||||
copy_to_msg(msg, bssmap_cr, sizeof(bssmap_cr));
|
||||
struct bsc_nat_parsed *parsed;
|
||||
|
||||
parsed = bsc_nat_parse(msg);
|
||||
if (!parsed) {
|
||||
fprintf(stderr, "FAIL: Failed to parse the message\n");
|
||||
abort();
|
||||
struct bsc_nat *nat = bsc_nat_alloc();
|
||||
struct bsc_connection *bsc = bsc_connection_alloc(nat);
|
||||
bsc->cfg = bsc_config_alloc(nat, "foo", 1234);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(cr_filter); ++i) {
|
||||
msgb_reset(msg);
|
||||
copy_to_msg(msg, cr_filter[i].data, cr_filter[i].length);
|
||||
|
||||
bsc_parse_reg(nat, &nat->imsi_allow_re, &nat->imsi_allow,
|
||||
cr_filter[i].nat_imsi_allow ? 1 : 0,
|
||||
&cr_filter[i].nat_imsi_allow);
|
||||
bsc_parse_reg(nat, &nat->imsi_deny_re, &nat->imsi_deny,
|
||||
cr_filter[i].nat_imsi_deny ? 1 : 0,
|
||||
&cr_filter[i].nat_imsi_deny);
|
||||
bsc_parse_reg(bsc->cfg, &bsc->cfg->imsi_allow_re, &bsc->cfg->imsi_allow,
|
||||
cr_filter[i].bsc_imsi_allow ? 1 : 0,
|
||||
&cr_filter[i].bsc_imsi_allow);
|
||||
bsc_parse_reg(bsc->cfg, &bsc->cfg->imsi_deny_re, &bsc->cfg->imsi_deny,
|
||||
cr_filter[i].bsc_imsi_deny ? 1 : 0,
|
||||
&cr_filter[i].bsc_imsi_deny);
|
||||
|
||||
parsed = bsc_nat_parse(msg);
|
||||
if (!parsed) {
|
||||
fprintf(stderr, "FAIL: Failed to parse the message\n");
|
||||
abort();
|
||||
}
|
||||
|
||||
res = bsc_nat_filter_sccp_cr(bsc, msg, parsed);
|
||||
if (res != cr_filter[i].result) {
|
||||
fprintf(stderr, "FAIL: Wrong result %d for test %d.\n", res, i);
|
||||
abort();
|
||||
}
|
||||
|
||||
talloc_free(parsed);
|
||||
}
|
||||
|
||||
bsc_nat_filter_sccp_cr(NULL, msg, parsed);
|
||||
|
||||
talloc_free(parsed);
|
||||
msgb_free(msg);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue