diff options
author | Jacob Erlbeck <jerlbeck@sysmocom.de> | 2014-08-07 10:46:29 +0200 |
---|---|---|
committer | Jacob Erlbeck <jerlbeck@sysmocom.de> | 2014-08-13 10:41:23 +0200 |
commit | 291f0508c52666d592ee111254364b0a6809d0ae (patch) | |
tree | 751d1c5ed2357d22d265a5d2a726a79ee4fe95d2 | |
parent | 89d3d343d1d15fb5f48826c73171c51b61b47efb (diff) |
gbproxy: Test and fix IMSI/TMSI matching
This adds a test for gbprox_set_patch_filter() and
gbprox_check_imsi().
It also fixes the masking of the type field when IMSIs are checked by
using GSM_MI_TYPE_MASK (0x07) instead of 0x0f.
Sponsored-by: On-Waves ehf
-rw-r--r-- | openbsc/include/openbsc/gb_proxy.h | 2 | ||||
-rw-r--r-- | openbsc/src/gprs/gb_proxy.c | 14 | ||||
-rw-r--r-- | openbsc/tests/gbproxy/gbproxy_test.c | 72 | ||||
-rw-r--r-- | openbsc/tests/gbproxy/gbproxy_test.ok | 2 |
4 files changed, 84 insertions, 6 deletions
diff --git a/openbsc/include/openbsc/gb_proxy.h b/openbsc/include/openbsc/gb_proxy.h index 5a580cdb9..9cd1abbb2 100644 --- a/openbsc/include/openbsc/gb_proxy.h +++ b/openbsc/include/openbsc/gb_proxy.h @@ -130,4 +130,6 @@ void gbprox_register_tlli(struct gbproxy_peer *peer, uint32_t tlli, struct gbproxy_peer *gbproxy_peer_alloc(struct gbproxy_config *cfg, uint16_t bvci); void gbproxy_peer_free(struct gbproxy_peer *peer); +int gbprox_check_imsi(struct gbproxy_peer *peer, + const uint8_t *imsi, size_t imsi_len); #endif diff --git a/openbsc/src/gprs/gb_proxy.c b/openbsc/src/gprs/gb_proxy.c index 103ecb59e..e7975497a 100644 --- a/openbsc/src/gprs/gb_proxy.c +++ b/openbsc/src/gprs/gb_proxy.c @@ -354,7 +354,7 @@ static int is_mi_tmsi(const uint8_t *value, size_t value_len) if (value_len != GSM48_TMSI_LEN) return 0; - if (!value || (value[0] & 0x0f) != GSM_MI_TYPE_TMSI) + if (!value || (value[0] & GSM_MI_TYPE_MASK) != GSM_MI_TYPE_TMSI) return 0; return 1; @@ -366,7 +366,7 @@ static int is_mi_imsi(const uint8_t *value, size_t value_len) if (value_len == 0) return 0; - if (!value || (value[0] & 0x0f) != GSM_MI_TYPE_IMSI) + if (!value || (value[0] & GSM_MI_TYPE_MASK) != GSM_MI_TYPE_IMSI) return 0; return 1; @@ -507,8 +507,8 @@ int gbprox_set_patch_filter(struct gbproxy_config *cfg, const char *filter, return -1; } -static int gbprox_check_imsi(struct gbproxy_peer *peer, - const uint8_t *imsi, size_t imsi_len) +int gbprox_check_imsi(struct gbproxy_peer *peer, + const uint8_t *imsi, size_t imsi_len) { char mi_buf[200]; int rc; @@ -516,8 +516,10 @@ static int gbprox_check_imsi(struct gbproxy_peer *peer, if (!peer->cfg->check_imsi) return 1; - rc = gsm48_mi_to_string(mi_buf, sizeof(mi_buf), imsi, imsi_len); - if (rc < 1) { + rc = is_mi_imsi(imsi, imsi_len); + if (rc > 0) + rc = gsm48_mi_to_string(mi_buf, sizeof(mi_buf), imsi, imsi_len); + if (rc <= 0) { LOGP(DGPRS, LOGL_NOTICE, "Invalid IMSI %s\n", osmo_hexdump(imsi, imsi_len)); return -1; diff --git a/openbsc/tests/gbproxy/gbproxy_test.c b/openbsc/tests/gbproxy/gbproxy_test.c index 229d2d45f..bb2b1aab8 100644 --- a/openbsc/tests/gbproxy/gbproxy_test.c +++ b/openbsc/tests/gbproxy/gbproxy_test.c @@ -1474,6 +1474,77 @@ static void test_gbproxy_tlli_expire(void) } } +static void test_gbproxy_imsi_matching(void) +{ + struct gbproxy_config cfg = {0}; + struct gbproxy_peer *peer; + const char *err_msg = NULL; + const uint8_t imsi1[] = { GSM_MI_TYPE_IMSI | 0x10, 0x32, 0x54, 0xf6 }; + const uint8_t imsi2[] = { GSM_MI_TYPE_IMSI | GSM_MI_ODD | 0x10, 0x32, 0x54, 0x76 }; + const uint8_t imsi3_bad[] = { GSM_MI_TYPE_IMSI | 0x10, 0xee, 0x54, 0xff }; + const uint8_t tmsi1[] = { GSM_MI_TYPE_TMSI | 0xf0, 0x11, 0x22, 0x33, 0x44 }; + const uint8_t tmsi2_bad[] = { GSM_MI_TYPE_TMSI | 0xf0, 0x11, 0x22 }; + const uint8_t imei1[] = { GSM_MI_TYPE_IMEI | 0x10, 0x32, 0x54, 0xf6 }; + const uint8_t imei2[] = { GSM_MI_TYPE_IMEI | GSM_MI_ODD | 0x10, 0x32, 0x54, 0x76 }; + const char *filter_re1 = ".*"; + const char *filter_re2 = "^1234"; + const char *filter_re3 = "^4321"; + const char *filter_re4_bad = "^12["; + + printf("=== Test IMSI/TMSI matching ===\n\n"); + + gbproxy_init_config(&cfg); + OSMO_ASSERT(cfg.check_imsi == 0); + + OSMO_ASSERT(gbprox_set_patch_filter(&cfg, filter_re1, &err_msg) == 0); + OSMO_ASSERT(cfg.check_imsi == 1); + + OSMO_ASSERT(gbprox_set_patch_filter(&cfg, filter_re2, &err_msg) == 0); + OSMO_ASSERT(cfg.check_imsi == 1); + + err_msg = NULL; + OSMO_ASSERT(gbprox_set_patch_filter(&cfg, filter_re4_bad, &err_msg) == -1); + OSMO_ASSERT(err_msg != NULL); + OSMO_ASSERT(cfg.check_imsi == 0); + + OSMO_ASSERT(gbprox_set_patch_filter(&cfg, filter_re2, &err_msg) == 0); + OSMO_ASSERT(cfg.check_imsi == 1); + + OSMO_ASSERT(gbprox_set_patch_filter(&cfg, NULL, &err_msg) == 0); + OSMO_ASSERT(cfg.check_imsi == 0); + + peer = gbproxy_peer_alloc(&cfg, 20); + + OSMO_ASSERT(gbprox_set_patch_filter(&cfg, filter_re2, &err_msg) == 0); + OSMO_ASSERT(cfg.check_imsi == 1); + + OSMO_ASSERT(gbprox_check_imsi(peer, imsi1, ARRAY_SIZE(imsi1)) == 1); + OSMO_ASSERT(gbprox_check_imsi(peer, imsi2, ARRAY_SIZE(imsi2)) == 1); + /* imsi3_bad contains 0xE and 0xF digits, but the conversion function + * doesn't complain, so gbprox_check_imsi() doesn't return -1 in this + * case. */ + OSMO_ASSERT(gbprox_check_imsi(peer, imsi3_bad, ARRAY_SIZE(imsi3_bad)) == 0); + OSMO_ASSERT(gbprox_check_imsi(peer, tmsi1, ARRAY_SIZE(tmsi1)) == -1); + OSMO_ASSERT(gbprox_check_imsi(peer, tmsi2_bad, ARRAY_SIZE(tmsi2_bad)) == -1); + OSMO_ASSERT(gbprox_check_imsi(peer, imei1, ARRAY_SIZE(imei1)) == -1); + OSMO_ASSERT(gbprox_check_imsi(peer, imei2, ARRAY_SIZE(imei2)) == -1); + + OSMO_ASSERT(gbprox_set_patch_filter(&cfg, filter_re3, &err_msg) == 0); + OSMO_ASSERT(cfg.check_imsi == 1); + + OSMO_ASSERT(gbprox_check_imsi(peer, imsi1, ARRAY_SIZE(imsi1)) == 0); + OSMO_ASSERT(gbprox_check_imsi(peer, imsi2, ARRAY_SIZE(imsi2)) == 0); + OSMO_ASSERT(gbprox_check_imsi(peer, imsi3_bad, ARRAY_SIZE(imsi3_bad)) == 0); + OSMO_ASSERT(gbprox_check_imsi(peer, tmsi1, ARRAY_SIZE(tmsi1)) == -1); + OSMO_ASSERT(gbprox_check_imsi(peer, tmsi2_bad, ARRAY_SIZE(tmsi2_bad)) == -1); + OSMO_ASSERT(gbprox_check_imsi(peer, imei1, ARRAY_SIZE(imei1)) == -1); + OSMO_ASSERT(gbprox_check_imsi(peer, imei2, ARRAY_SIZE(imei2)) == -1); + + /* TODO: Check correct length but wrong type with is_mi_tmsi */ + + gbproxy_peer_free(peer); +} + static struct log_info_cat gprs_categories[] = { [DGPRS] = { .name = "DGPRS", @@ -1517,6 +1588,7 @@ int main(int argc, char **argv) test_tlv_shift_functions(); test_gbproxy(); test_gbproxy_ident_changes(); + test_gbproxy_imsi_matching(); test_gbproxy_ra_patching(); test_gbproxy_tlli_expire(); printf("===== GbProxy test END\n\n"); diff --git a/openbsc/tests/gbproxy/gbproxy_test.ok b/openbsc/tests/gbproxy/gbproxy_test.ok index 455364883..c893ff363 100644 --- a/openbsc/tests/gbproxy/gbproxy_test.ok +++ b/openbsc/tests/gbproxy/gbproxy_test.ok @@ -1479,6 +1479,8 @@ Peers: NSEI 8192, BVCI 4098, not blocked, RAI 112-332-16464-96 NSEI mismatch : 1 TLLI-Cache: 0 +=== Test IMSI/TMSI matching === + === test_gbproxy_ra_patching === --- Initialise SGSN --- |