[nat] Implement IMSI filtering...

This commit is contained in:
Holger Hans Peter Freyther 2010-05-14 19:49:35 +08:00
parent f830322846
commit 34a96aeb32
2 changed files with 153 additions and 14 deletions

View File

@ -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);
}

View File

@ -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);
}