[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;
|
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)
|
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;
|
return 0;
|
||||||
|
|
||||||
gsm48_mi_to_string(mi_string, sizeof(mi_string), lu->mi, lu->mi_len);
|
gsm48_mi_to_string(mi_string, sizeof(mi_string), lu->mi, lu->mi_len);
|
||||||
|
return auth_imsi(bsc, mi_string);
|
||||||
/*
|
|
||||||
* Now apply blacklist/whitelist
|
|
||||||
*/
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -108,6 +108,17 @@ static const u_int8_t mgcp_msg[] = {
|
||||||
0x20, 0x20, 0x20,
|
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 {
|
struct filter_result {
|
||||||
const u_int8_t *data;
|
const u_int8_t *data;
|
||||||
const u_int16_t length;
|
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()
|
static void test_cr_filter()
|
||||||
{
|
{
|
||||||
|
int i, res;
|
||||||
struct msgb *msg = msgb_alloc(4096, "test_cr_filter");
|
struct msgb *msg = msgb_alloc(4096, "test_cr_filter");
|
||||||
copy_to_msg(msg, bssmap_cr, sizeof(bssmap_cr));
|
|
||||||
struct bsc_nat_parsed *parsed;
|
struct bsc_nat_parsed *parsed;
|
||||||
|
|
||||||
parsed = bsc_nat_parse(msg);
|
struct bsc_nat *nat = bsc_nat_alloc();
|
||||||
if (!parsed) {
|
struct bsc_connection *bsc = bsc_connection_alloc(nat);
|
||||||
fprintf(stderr, "FAIL: Failed to parse the message\n");
|
bsc->cfg = bsc_config_alloc(nat, "foo", 1234);
|
||||||
abort();
|
|
||||||
|
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);
|
msgb_free(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue