From: Max msuraev@sysmocom.de
This enables easier expansion of available policies in future. --- openbsc/include/openbsc/gsm_data.h | 5 +++++ openbsc/src/libbsc/net_init.c | 2 +- openbsc/src/libmsc/vty_interface_layer3.c | 4 ++-- 3 files changed, 8 insertions(+), 3 deletions(-)
diff --git a/openbsc/include/openbsc/gsm_data.h b/openbsc/include/openbsc/gsm_data.h index 6d7aba3..593a86f 100644 --- a/openbsc/include/openbsc/gsm_data.h +++ b/openbsc/include/openbsc/gsm_data.h @@ -18,6 +18,11 @@ struct gsm_subscriber_group;
#define OBSC_LINKID_CB(__msgb) (__msgb)->cb[3]
+enum gsm_subscr_ext_alloc_policy { + GSM_SUBSCR_DONT_CREATE = 0, + GSM_SUBSCR_RANDOM_EXT = 1, +}; + enum gsm_security_event { GSM_SECURITY_NOAVAIL, GSM_SECURITY_AUTH_FAILED, diff --git a/openbsc/src/libbsc/net_init.c b/openbsc/src/libbsc/net_init.c index 568a0b8..00a8a9b 100644 --- a/openbsc/src/libbsc/net_init.c +++ b/openbsc/src/libbsc/net_init.c @@ -48,7 +48,7 @@ struct gsm_network *gsm_network_init(uint16_t country_code, uint16_t network_cod INIT_LLIST_HEAD(&net->bsc_data->mscs);
net->subscr_group->net = net; - net->create_subscriber = 1; + net->create_subscriber = GSM_SUBSCR_RANDOM_EXT;
net->country_code = country_code; net->network_code = network_code; diff --git a/openbsc/src/libmsc/vty_interface_layer3.c b/openbsc/src/libmsc/vty_interface_layer3.c index 790fedf..4dd0573 100644 --- a/openbsc/src/libmsc/vty_interface_layer3.c +++ b/openbsc/src/libmsc/vty_interface_layer3.c @@ -1036,7 +1036,7 @@ DEFUN(cfg_nitb_subscr_create, cfg_nitb_subscr_create_cmd, "Make a new record when a subscriber is first seen.\n") { struct gsm_network *gsmnet = gsmnet_from_vty(vty); - gsmnet->create_subscriber = 1; + gsmnet->create_subscriber = GSM_SUBSCR_RANDOM_EXT; return CMD_SUCCESS; }
@@ -1045,7 +1045,7 @@ DEFUN(cfg_nitb_no_subscr_create, cfg_nitb_no_subscr_create_cmd, NO_STR "Make a new record when a subscriber is first seen.\n") { struct gsm_network *gsmnet = gsmnet_from_vty(vty); - gsmnet->create_subscriber = 0; + gsmnet->create_subscriber = GSM_SUBSCR_DONT_CREATE; return CMD_SUCCESS; }
From: Max msuraev@sysmocom.de
--- openbsc/.gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/openbsc/.gitignore b/openbsc/.gitignore index bae3b65..0a2965d 100644 --- a/openbsc/.gitignore +++ b/openbsc/.gitignore @@ -88,7 +88,7 @@ tests/package.m4 tests/testsuite tests/testsuite.log
- +gsn_restart src/openbsc.cfg* writtenconfig/ gtphub_restart_count
From: Max msuraev@sysmocom.de
Move common code to wrapper function. --- openbsc/src/libmsc/gsm_04_08.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-)
diff --git a/openbsc/src/libmsc/gsm_04_08.c b/openbsc/src/libmsc/gsm_04_08.c index 05cb886..bb1b49a 100644 --- a/openbsc/src/libmsc/gsm_04_08.c +++ b/openbsc/src/libmsc/gsm_04_08.c @@ -507,6 +507,14 @@ static int mm_tx_identity_req(struct gsm_subscriber_connection *conn, uint8_t id return gsm48_conn_sendmsg(msg, conn, NULL); }
+static struct gsm_subscriber *subscr_create(const struct gsm_network *net, + const char *imsi) +{ + if (GSM_SUBSCR_DONT_CREATE == net->create_subscriber) + return NULL; + + return subscr_create_subscriber(net->subscr_group, imsi); +}
/* Parse Chapter 9.2.11 Identity Response */ static int mm_rx_id_resp(struct gsm_subscriber_connection *conn, struct msgb *msg) @@ -530,9 +538,8 @@ static int mm_rx_id_resp(struct gsm_subscriber_connection *conn, struct msgb *ms if (!conn->subscr) { conn->subscr = subscr_get_by_imsi(net->subscr_group, mi_string); - if (!conn->subscr && net->create_subscriber) - conn->subscr = subscr_create_subscriber( - net->subscr_group, mi_string); + if (!conn->subscr) + conn->subscr = subscr_create(net, mi_string); } if (!conn->subscr && conn->loc_operation) { gsm0408_loc_upd_rej(conn, bts->network->reject_cause); @@ -641,9 +648,8 @@ static int mm_rx_loc_upd_req(struct gsm_subscriber_connection *conn, struct msgb
/* look up subscriber based on IMSI, create if not found */ subscr = subscr_get_by_imsi(bts->network->subscr_group, mi_string); - if (!subscr && bts->network->create_subscriber) { - subscr = subscr_create_subscriber( - bts->network->subscr_group, mi_string); + if (!subscr) { + subscr = subscr_create(bts->network, mi_string); } if (!subscr) { gsm0408_loc_upd_rej(conn, bts->network->reject_cause);
From: Max msuraev@sysmocom.de
Move copy-pasted code into separate function to make writing more tests easier. --- openbsc/tests/db/db_test.c | 91 +++++++++++++++++++--------------------------- 1 file changed, 37 insertions(+), 54 deletions(-)
diff --git a/openbsc/tests/db/db_test.c b/openbsc/tests/db/db_test.c index fb159a5..6b40e84 100644 --- a/openbsc/tests/db/db_test.c +++ b/openbsc/tests/db/db_test.c @@ -159,10 +159,43 @@ static void test_sms_migrate(void) subscr_put(rcv_subscr); }
-int main() +static void test_subs(const char *alice_imsi, char *imei1, char *imei2) { - char scratch_str[256]; + struct gsm_subscriber *alice = NULL, *alice_db; + char scratch_str[256];
+ alice = db_create_subscriber(alice_imsi); + db_subscriber_assoc_imei(alice, imei1); + if (imei2) + db_subscriber_assoc_imei(alice, imei2); + db_subscriber_alloc_tmsi(alice); + alice->lac=42; + db_sync_subscriber(alice); + /* Get by TMSI */ + snprintf(scratch_str, sizeof(scratch_str), "%"PRIu32, alice->tmsi); + alice_db = db_get_subscriber(GSM_SUBSCRIBER_TMSI, scratch_str); + COMPARE(alice, alice_db); + SUBSCR_PUT(alice_db); + /* Get by IMSI */ + alice_db = db_get_subscriber(GSM_SUBSCRIBER_IMSI, alice_imsi); + COMPARE(alice, alice_db); + SUBSCR_PUT(alice_db); + /* Get by id */ + snprintf(scratch_str, sizeof(scratch_str), "%llu", alice->id); + alice_db = db_get_subscriber(GSM_SUBSCRIBER_ID, scratch_str); + COMPARE(alice, alice_db); + SUBSCR_PUT(alice_db); + /* Get by extension */ + alice_db = db_get_subscriber(GSM_SUBSCRIBER_EXTENSION, alice->extension); + if (alice_db) { + COMPARE(alice, alice_db); + SUBSCR_PUT(alice_db); + } + SUBSCR_PUT(alice); +} + +int main() +{ printf("Testing subscriber database code.\n"); osmo_init_logging(&log_info); log_set_print_filename(osmo_stderr_target, 0); @@ -193,58 +226,8 @@ int main() SUBSCR_PUT(alice_db); SUBSCR_PUT(alice);
- alice_imsi = "3693245423445"; - alice = db_create_subscriber(alice_imsi); - db_subscriber_assoc_imei(alice, "1234567890"); - db_subscriber_alloc_tmsi(alice); - alice->lac=42; - db_sync_subscriber(alice); - /* Get by TMSI */ - snprintf(scratch_str, sizeof(scratch_str), "%"PRIu32, alice->tmsi); - alice_db = db_get_subscriber(GSM_SUBSCRIBER_TMSI, scratch_str); - COMPARE(alice, alice_db); - SUBSCR_PUT(alice_db); - /* Get by IMSI */ - alice_db = db_get_subscriber(GSM_SUBSCRIBER_IMSI, alice_imsi); - COMPARE(alice, alice_db); - SUBSCR_PUT(alice_db); - /* Get by id */ - snprintf(scratch_str, sizeof(scratch_str), "%llu", alice->id); - alice_db = db_get_subscriber(GSM_SUBSCRIBER_ID, scratch_str); - COMPARE(alice, alice_db); - SUBSCR_PUT(alice_db); - /* Get by extension */ - alice_db = db_get_subscriber(GSM_SUBSCRIBER_EXTENSION, alice->extension); - COMPARE(alice, alice_db); - SUBSCR_PUT(alice_db); - SUBSCR_PUT(alice); - - alice_imsi = "9993245423445"; - alice = db_create_subscriber(alice_imsi); - db_subscriber_alloc_tmsi(alice); - alice->lac=42; - db_sync_subscriber(alice); - db_subscriber_assoc_imei(alice, "1234567890"); - db_subscriber_assoc_imei(alice, "6543560920"); - /* Get by TMSI */ - snprintf(scratch_str, sizeof(scratch_str), "%"PRIu32, alice->tmsi); - alice_db = db_get_subscriber(GSM_SUBSCRIBER_TMSI, scratch_str); - COMPARE(alice, alice_db); - SUBSCR_PUT(alice_db); - /* Get by IMSI */ - alice_db = db_get_subscriber(GSM_SUBSCRIBER_IMSI, alice_imsi); - COMPARE(alice, alice_db); - SUBSCR_PUT(alice_db); - /* Get by id */ - snprintf(scratch_str, sizeof(scratch_str), "%llu", alice->id); - alice_db = db_get_subscriber(GSM_SUBSCRIBER_ID, scratch_str); - COMPARE(alice, alice_db); - SUBSCR_PUT(alice_db); - /* Get by extension */ - alice_db = db_get_subscriber(GSM_SUBSCRIBER_EXTENSION, alice->extension); - COMPARE(alice, alice_db); - SUBSCR_PUT(alice_db); - SUBSCR_PUT(alice); + test_subs("3693245423445", "1234567890", NULL); + test_subs("9993245423445", "1234567890", "6543560920");
/* create it again and see it fails */ alice = db_create_subscriber(alice_imsi);
On 04 May 2016, at 13:02, msuraev@sysmocom.de wrote:
From: Max msuraev@sysmocom.de
Move copy-pasted code into separate function to make writing more tests easier.
and change behavior..
+static void test_subs(const char *alice_imsi, char *imei1, char *imei2) {
- char scratch_str[256];
- struct gsm_subscriber *alice = NULL, *alice_db;
char scratch_str[256];
tabs vs. spaces
- /* Get by extension */
- alice_db = db_get_subscriber(GSM_SUBSCRIBER_EXTENSION, alice->extension);
- if (alice_db) {
COMPARE(alice, alice_db);SUBSCR_PUT(alice_db);- }
- SUBSCR_PUT(alice);
The if looks a bit weak here? So no error if the look-up code starts to break? In general I think we want to have strong post conditions. If alice_db should be !NULL then we should aggressively check for it.
From: Max msuraev@sysmocom.de
* extend "auth policy" vty command with new option "prefix" * add vty command "authorize-prefix" for setting arbitrary prefix * add basic vty test * add optional "imsi-prefix" argument to subscriber-create-on-demand vty command
With those in place we can now set the prefix against which MS's IMSI will be checked.
If IMSI's prefix match our configuration than MS is allowed to access the network. If subscriber is already marked as authorized in HLR than it'll be allowed regardless of IMSI prefix.
The same way we can decide whether to create subscribers on-demand basesd on IMSI prefix match. Similar to authorization this restriction can be overridden by manually creating subscriber via vty, ctrl interface or directly in HLR.
Note: this is NITB option, not to be confused with SGSN option with the same name.
Fixes: OS#1647 --- openbsc/include/openbsc/gprs_sgsn.h | 1 - openbsc/include/openbsc/gsm_data.h | 5 +++++ openbsc/include/openbsc/gsm_subscriber.h | 1 - openbsc/src/libbsc/bsc_vty.c | 27 ++++++++++++++++++++++++--- openbsc/src/libbsc/net_init.c | 1 + openbsc/src/libcommon/gsm_data.c | 1 + openbsc/src/libmsc/gsm_04_08.c | 21 +++++++++++++++++++-- openbsc/src/libmsc/vty_interface_layer3.c | 16 ++++++++++++---- openbsc/tests/vty_test_runner.py | 14 ++++++++++++++ 9 files changed, 76 insertions(+), 11 deletions(-)
diff --git a/openbsc/include/openbsc/gprs_sgsn.h b/openbsc/include/openbsc/gprs_sgsn.h index 49d5407..bf18ea1 100644 --- a/openbsc/include/openbsc/gprs_sgsn.h +++ b/openbsc/include/openbsc/gprs_sgsn.h @@ -12,7 +12,6 @@
#include <openbsc/gsm_data.h>
-#define GSM_IMSI_LENGTH 17 #define GSM_IMEI_LENGTH 17 #define GSM_EXTENSION_LENGTH 15 #define GSM_APN_LENGTH 102 diff --git a/openbsc/include/openbsc/gsm_data.h b/openbsc/include/openbsc/gsm_data.h index 593a86f..4844412 100644 --- a/openbsc/include/openbsc/gsm_data.h +++ b/openbsc/include/openbsc/gsm_data.h @@ -8,6 +8,8 @@
#include <openbsc/rest_octets.h>
+#define GSM_IMSI_LENGTH 17 + /** annotations for msgb ownership */ #define __uses
@@ -21,6 +23,7 @@ struct gsm_subscriber_group; enum gsm_subscr_ext_alloc_policy { GSM_SUBSCR_DONT_CREATE = 0, GSM_SUBSCR_RANDOM_EXT = 1, + GSM_SUBSCR_MATCH_PREF = 2, };
enum gsm_security_event { @@ -206,6 +209,7 @@ enum gsm_auth_policy { GSM_AUTH_POLICY_CLOSED, /* only subscribers authorized in DB */ GSM_AUTH_POLICY_ACCEPT_ALL, /* accept everyone, even if not authorized in DB */ GSM_AUTH_POLICY_TOKEN, /* accept first, send token per sms, then revoke authorization */ + GSM_AUTH_POLICY_PREFIX, /* accept IMSIs with a given prefix */ };
#define GSM_T3101_DEFAULT 10 @@ -220,6 +224,7 @@ struct gsm_network { char *name_long; char *name_short; enum gsm_auth_policy auth_policy; + char auth_prefix[GSM_IMSI_LENGTH]; enum gsm48_reject_value reject_cause; int a5_encryption; int neci; diff --git a/openbsc/include/openbsc/gsm_subscriber.h b/openbsc/include/openbsc/gsm_subscriber.h index 7d6c776..7108bff 100644 --- a/openbsc/include/openbsc/gsm_subscriber.h +++ b/openbsc/include/openbsc/gsm_subscriber.h @@ -5,7 +5,6 @@ #include <osmocom/core/linuxlist.h>
#define GSM_IMEI_LENGTH 17 -#define GSM_IMSI_LENGTH 17 #define GSM_NAME_LENGTH 160
#define GSM_EXTENSION_LENGTH 15 /* MSISDN can only be 15 digits length */ diff --git a/openbsc/src/libbsc/bsc_vty.c b/openbsc/src/libbsc/bsc_vty.c index b928738..dfcca24 100644 --- a/openbsc/src/libbsc/bsc_vty.c +++ b/openbsc/src/libbsc/bsc_vty.c @@ -189,8 +189,11 @@ static void net_dump_vty(struct vty *vty, struct gsm_network *net) net->name_long, VTY_NEWLINE); vty_out(vty, " Short network name: '%s'%s", net->name_short, VTY_NEWLINE); - vty_out(vty, " Authentication policy: %s%s", - gsm_auth_policy_name(net->auth_policy), VTY_NEWLINE); + vty_out(vty, " Authentication policy: %s", + gsm_auth_policy_name(net->auth_policy)); + if (net->auth_prefix[0] != '\0') + vty_out(vty, ", authorized prefix: %s", net->auth_prefix); + vty_out(vty, "%s", VTY_NEWLINE); vty_out(vty, " Location updating reject cause: %u%s", net->reject_cause, VTY_NEWLINE); vty_out(vty, " Encryption: A5/%u%s", net->a5_encryption, @@ -776,6 +779,8 @@ static int config_write_net(struct vty *vty) vty_out(vty, " short name %s%s", gsmnet->name_short, VTY_NEWLINE); vty_out(vty, " long name %s%s", gsmnet->name_long, VTY_NEWLINE); vty_out(vty, " auth policy %s%s", gsm_auth_policy_name(gsmnet->auth_policy), VTY_NEWLINE); + if (gsmnet->auth_prefix[0] != '\0') + vty_out(vty, " authorize-prefix %s%s", gsmnet->auth_prefix, VTY_NEWLINE); vty_out(vty, " location updating reject cause %u%s", gsmnet->reject_cause, VTY_NEWLINE); vty_out(vty, " encryption a5 %u%s", gsmnet->a5_encryption, VTY_NEWLINE); @@ -1384,11 +1389,12 @@ DEFUN(cfg_net_name_long,
DEFUN(cfg_net_auth_policy, cfg_net_auth_policy_cmd, - "auth policy (closed|accept-all|token)", + "auth policy (closed|accept-all|prefix|token)", "Authentication (not cryptographic)\n" "Set the GSM network authentication policy\n" "Require the MS to be activated in HLR\n" "Accept all MS, whether in HLR or not\n" + "Use IMSI prefix for authorization decision\n" "Use SMS-token based authentication\n") { enum gsm_auth_policy policy = gsm_auth_policy_parse(argv[0]); @@ -1399,6 +1405,20 @@ DEFUN(cfg_net_auth_policy, return CMD_SUCCESS; }
+/* Note: limit on the prefix length is set by internal vty code limitations */ +DEFUN(cfg_net_authorize_prefix, cfg_net_authorize_prefix_cmd, + "authorize-prefix <0-9999999999>", + "Set IMSI prefix which will be used for authorization decision\n" + "PREFIX of IMSIs which are allowed to use the network\n") +{ + struct gsm_network *gsmnet = gsmnet_from_vty(vty); + + strncpy(gsmnet->auth_prefix, argv[0], GSM_IMSI_LENGTH); + gsmnet->auth_prefix[GSM_IMSI_LENGTH - 1] = '\0'; + + return CMD_SUCCESS; +} + DEFUN(cfg_net_reject_cause, cfg_net_reject_cause_cmd, "location updating reject cause <2-111>", @@ -3912,6 +3932,7 @@ int bsc_vty_init(const struct log_info *cat) install_element(GSMNET_NODE, &cfg_net_name_short_cmd); install_element(GSMNET_NODE, &cfg_net_name_long_cmd); install_element(GSMNET_NODE, &cfg_net_auth_policy_cmd); + install_element(GSMNET_NODE, &cfg_net_authorize_prefix_cmd); install_element(GSMNET_NODE, &cfg_net_reject_cause_cmd); install_element(GSMNET_NODE, &cfg_net_encryption_cmd); install_element(GSMNET_NODE, &cfg_net_neci_cmd); diff --git a/openbsc/src/libbsc/net_init.c b/openbsc/src/libbsc/net_init.c index 00a8a9b..ed23f33 100644 --- a/openbsc/src/libbsc/net_init.c +++ b/openbsc/src/libbsc/net_init.c @@ -54,6 +54,7 @@ struct gsm_network *gsm_network_init(uint16_t country_code, uint16_t network_cod net->network_code = network_code; net->num_bts = 0; net->reject_cause = GSM48_REJECT_ROAMING_NOT_ALLOWED; + net->auth_prefix[GSM_IMSI_LENGTH - 1] = '\0'; net->T3101 = GSM_T3101_DEFAULT; net->T3105 = GSM_T3105_DEFAULT; net->T3113 = GSM_T3113_DEFAULT; diff --git a/openbsc/src/libcommon/gsm_data.c b/openbsc/src/libcommon/gsm_data.c index 242c014..4b4be42 100644 --- a/openbsc/src/libcommon/gsm_data.c +++ b/openbsc/src/libcommon/gsm_data.c @@ -161,6 +161,7 @@ static const struct value_string auth_policy_names[] = { { GSM_AUTH_POLICY_CLOSED, "closed" }, { GSM_AUTH_POLICY_ACCEPT_ALL, "accept-all" }, { GSM_AUTH_POLICY_TOKEN, "token" }, + { GSM_AUTH_POLICY_PREFIX, "prefix" }, { 0, NULL } };
diff --git a/openbsc/src/libmsc/gsm_04_08.c b/openbsc/src/libmsc/gsm_04_08.c index bb1b49a..ab950c7 100644 --- a/openbsc/src/libmsc/gsm_04_08.c +++ b/openbsc/src/libmsc/gsm_04_08.c @@ -25,6 +25,7 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <stdbool.h> #include <errno.h> #include <time.h> #include <netinet/in.h> @@ -244,8 +245,15 @@ int gsm48_secure_channel(struct gsm_subscriber_connection *conn, int key_seq, return -EINVAL; /* not reached */ }
+static bool subscr_prefix_check(const char *auth_prefix, const char *imsi) +{ + return (strncmp(imsi, auth_prefix, strnlen(auth_prefix, + GSM_IMSI_LENGTH)) == 0); +} + static int authorize_subscriber(struct gsm_loc_updating_operation *loc, - struct gsm_subscriber *subscriber) + struct gsm_subscriber *subscriber, + const char *auth_prefix) { if (!subscriber) return 0; @@ -261,6 +269,10 @@ static int authorize_subscriber(struct gsm_loc_updating_operation *loc, switch (subscriber->group->net->auth_policy) { case GSM_AUTH_POLICY_CLOSED: return subscriber->authorized; + case GSM_AUTH_POLICY_PREFIX: + if (subscriber->authorized) + return 1; + return subscr_prefix_check(auth_prefix, subscriber->imsi); case GSM_AUTH_POLICY_TOKEN: if (subscriber->authorized) return subscriber->authorized; @@ -366,7 +378,8 @@ static int gsm0408_authorize(struct gsm_subscriber_connection *conn, struct msgb if (!conn->loc_operation) return 0;
- if (authorize_subscriber(conn->loc_operation, conn->subscr)) + if (authorize_subscriber(conn->loc_operation, conn->subscr, + conn->bts->network->auth_prefix)) return gsm48_secure_channel(conn, conn->loc_operation->key_seq, _gsm0408_authorize_sec_cb, NULL); @@ -513,6 +526,10 @@ static struct gsm_subscriber *subscr_create(const struct gsm_network *net, if (GSM_SUBSCR_DONT_CREATE == net->create_subscriber) return NULL;
+ if (net->create_subscriber & GSM_SUBSCR_MATCH_PREF) + if (!subscr_prefix_check(net->auth_prefix, imsi)) + return NULL; + return subscr_create_subscriber(net->subscr_group, imsi); }
diff --git a/openbsc/src/libmsc/vty_interface_layer3.c b/openbsc/src/libmsc/vty_interface_layer3.c index 4dd0573..0ac2e90 100644 --- a/openbsc/src/libmsc/vty_interface_layer3.c +++ b/openbsc/src/libmsc/vty_interface_layer3.c @@ -1032,11 +1032,15 @@ DEFUN(cfg_nitb, cfg_nitb_cmd, }
DEFUN(cfg_nitb_subscr_create, cfg_nitb_subscr_create_cmd, - "subscriber-create-on-demand", - "Make a new record when a subscriber is first seen.\n") + "subscriber-create-on-demand [imsi-prefix]", + "Make a new record when a subscriber is first seen.\n" + "Create subscribers only if IMSI matches the prefix specified in " + "authorize-prefix command \n") { struct gsm_network *gsmnet = gsmnet_from_vty(vty); gsmnet->create_subscriber = GSM_SUBSCR_RANDOM_EXT; + if (argc) + gsmnet->create_subscriber |= GSM_SUBSCR_MATCH_PREF; return CMD_SUCCESS; }
@@ -1070,9 +1074,13 @@ DEFUN(cfg_nitb_no_assign_tmsi, cfg_nitb_no_assign_tmsi_cmd, static int config_write_nitb(struct vty *vty) { struct gsm_network *gsmnet = gsmnet_from_vty(vty); + const char *pref = gsmnet->create_subscriber ? "" : "no ", + *ims = (gsmnet->create_subscriber & GSM_SUBSCR_MATCH_PREF) ? + " imsi-prefix" : ""; + vty_out(vty, "nitb%s", VTY_NEWLINE); - vty_out(vty, " %ssubscriber-create-on-demand%s", - gsmnet->create_subscriber ? "" : "no ", VTY_NEWLINE); + vty_out(vty, " %ssubscriber-create-on-demand%s%s", + pref, ims, VTY_NEWLINE); vty_out(vty, " %sassign-tmsi%s", gsmnet->avoid_tmsi ? "no " : "", VTY_NEWLINE); return CMD_SUCCESS; diff --git a/openbsc/tests/vty_test_runner.py b/openbsc/tests/vty_test_runner.py index c088855..e240811 100644 --- a/openbsc/tests/vty_test_runner.py +++ b/openbsc/tests/vty_test_runner.py @@ -231,6 +231,20 @@ class TestVTYNITB(TestVTYGenericBSC):
self.assertEquals(self.vty.node(), 'config-mncc-int')
+ def testVtyAuthorization(self): + self.vty.enable() + self.vty.command("configure terminal") + self.vty.command("network") + self.assertTrue(self.vty.verify("auth policy closed", [''])) + self.assertTrue(self.vty.verify("auth policy prefix", [''])) + self.assertTrue(self.vty.verify("authorize-prefix 220380", [''])) + self.vty.command("end") + self.vty.command("configure terminal") + self.vty.command("nitb") + self.assertTrue(self.vty.verify("subscriber-create-on-demand", [''])) + self.assertTrue(self.vty.verify("subscriber-create-on-demand imsi-prefix", [''])) + self.vty.command("end") + def testSi2Q(self): self.vty.enable() self.vty.command("configure terminal")
From: Max msuraev@sysmocom.de
Previously if subscriber was automatically created it got assigned random MSISDN number between 20000 and 49999. Make it optional (defaulting to previous behavior) by adding following:
* optional "no-extension" argument to subscriber-create-on-demand * db unit tests * vty test
The range for random extension can now be specified with "subscriber-create-on-demand random" command.
Note: using the db made with new code might result in subscribers with empty extension. Such subscribers cannot be deleted using old code. Make sure not to mix db versions or manually fix it by editing sqlite with external program.
Fixes: OS#1658 --- openbsc/include/openbsc/db.h | 8 +++-- openbsc/include/openbsc/gsm_data.h | 3 ++ openbsc/include/openbsc/gsm_subscriber.h | 5 ++- openbsc/src/libbsc/net_init.c | 3 +- openbsc/src/libcommon/gsm_subscriber_base.c | 1 + openbsc/src/libmsc/ctrl_commands.c | 9 ++++- openbsc/src/libmsc/db.c | 37 ++++++++++++-------- openbsc/src/libmsc/gsm_04_08.c | 10 ++++-- openbsc/src/libmsc/gsm_subscriber.c | 6 ++-- openbsc/src/libmsc/vty_interface_layer3.c | 53 ++++++++++++++++++++++++++--- openbsc/tests/db/db_test.c | 18 ++++++---- openbsc/tests/vty_test_runner.py | 49 ++++++++++++++++++++++++++ 12 files changed, 168 insertions(+), 34 deletions(-)
diff --git a/openbsc/include/openbsc/db.h b/openbsc/include/openbsc/db.h index 6699a86..bb90705 100644 --- a/openbsc/include/openbsc/db.h +++ b/openbsc/include/openbsc/db.h @@ -20,6 +20,8 @@ #ifndef _DB_H #define _DB_H
+#include <stdbool.h> + #include "gsm_subscriber.h"
struct gsm_equipment; @@ -35,13 +37,15 @@ int db_prepare(void); int db_fini(void);
/* subscriber management */ -struct gsm_subscriber *db_create_subscriber(const char *imsi); +struct gsm_subscriber *db_create_subscriber(const char *imsi, uint64_t smin, + uint64_t smax, bool alloc_exten); struct gsm_subscriber *db_get_subscriber(enum gsm_subscriber_field field, const char *subscr); int db_sync_subscriber(struct gsm_subscriber *subscriber); int db_subscriber_expire(void *priv, void (*callback)(void *priv, long long unsigned int id)); int db_subscriber_alloc_tmsi(struct gsm_subscriber *subscriber); -int db_subscriber_alloc_exten(struct gsm_subscriber *subscriber); +int db_subscriber_alloc_exten(struct gsm_subscriber *subscriber, uint64_t smin, + uint64_t smax); int db_subscriber_alloc_token(struct gsm_subscriber *subscriber, uint32_t* token); int db_subscriber_assoc_imei(struct gsm_subscriber *subscriber, char *imei); int db_subscriber_delete(struct gsm_subscriber *subscriber); diff --git a/openbsc/include/openbsc/gsm_data.h b/openbsc/include/openbsc/gsm_data.h index 4844412..8fbb26e 100644 --- a/openbsc/include/openbsc/gsm_data.h +++ b/openbsc/include/openbsc/gsm_data.h @@ -24,6 +24,7 @@ enum gsm_subscr_ext_alloc_policy { GSM_SUBSCR_DONT_CREATE = 0, GSM_SUBSCR_RANDOM_EXT = 1, GSM_SUBSCR_MATCH_PREF = 2, + GSM_SUBSCR_NO_EXT = 4 };
enum gsm_security_event { @@ -293,6 +294,8 @@ struct gsm_network {
/* subscriber related features */ int create_subscriber; + uint64_t ext_min; + uint64_t ext_max; struct gsm_subscriber_group *subscr_group; struct gsm_sms_queue *sms_queue;
diff --git a/openbsc/include/openbsc/gsm_subscriber.h b/openbsc/include/openbsc/gsm_subscriber.h index 7108bff..3fabb63 100644 --- a/openbsc/include/openbsc/gsm_subscriber.h +++ b/openbsc/include/openbsc/gsm_subscriber.h @@ -1,6 +1,8 @@ #ifndef _GSM_SUBSCR_H #define _GSM_SUBSCR_H
+#include <stdbool.h> + #include "gsm_data.h" #include <osmocom/core/linuxlist.h>
@@ -90,7 +92,8 @@ enum gsm_subscriber_update_reason { struct gsm_subscriber *subscr_get(struct gsm_subscriber *subscr); struct gsm_subscriber *subscr_put(struct gsm_subscriber *subscr); struct gsm_subscriber *subscr_create_subscriber(struct gsm_subscriber_group *sgrp, - const char *imsi); + const char *imsi, uint64_t smin, + uint64_t smax, bool ext); struct gsm_subscriber *subscr_get_by_tmsi(struct gsm_subscriber_group *sgrp, uint32_t tmsi); struct gsm_subscriber *subscr_get_by_imsi(struct gsm_subscriber_group *sgrp, diff --git a/openbsc/src/libbsc/net_init.c b/openbsc/src/libbsc/net_init.c index ed23f33..9d47698 100644 --- a/openbsc/src/libbsc/net_init.c +++ b/openbsc/src/libbsc/net_init.c @@ -105,7 +105,8 @@ struct gsm_network *gsm_network_init(uint16_t country_code, uint16_t network_cod net->stats.bts.rsl_fail = osmo_counter_alloc("net.bts.rsl_fail");
net->mncc_recv = mncc_recv; - + net->ext_min = GSM_MIN_EXTEN; + net->ext_max = GSM_MAX_EXTEN; gsm_net_update_ctype(net);
return net; diff --git a/openbsc/src/libcommon/gsm_subscriber_base.c b/openbsc/src/libcommon/gsm_subscriber_base.c index a455824..5f0a1be 100644 --- a/openbsc/src/libcommon/gsm_subscriber_base.c +++ b/openbsc/src/libcommon/gsm_subscriber_base.c @@ -60,6 +60,7 @@ struct gsm_subscriber *subscr_alloc(void) llist_add_tail(&s->entry, &active_subscribers); s->use_count = 1; s->tmsi = GSM_RESERVED_TMSI; + s->extension[0] = '\0';
INIT_LLIST_HEAD(&s->requests);
diff --git a/openbsc/src/libmsc/ctrl_commands.c b/openbsc/src/libmsc/ctrl_commands.c index 9ac39de..3fd8d0b 100644 --- a/openbsc/src/libmsc/ctrl_commands.c +++ b/openbsc/src/libmsc/ctrl_commands.c @@ -18,6 +18,9 @@ * along with this program. If not, see http://www.gnu.org/licenses/. * */ + +#include <stdbool.h> + #include <osmocom/ctrl/control_cmd.h> #include <openbsc/gsm_data.h> #include <openbsc/gsm_subscriber.h> @@ -83,6 +86,8 @@ static int set_subscriber_modify(struct ctrl_cmd *cmd, void *data) char *tmp, *imsi, *msisdn, *alg, *ki, *saveptr = NULL; struct gsm_subscriber* subscr; int rc; + bool ext = (GSM_SUBSCR_RANDOM_EXT & net->create_subscriber) ? true : + false;
tmp = talloc_strdup(cmd, cmd->value); if (!tmp) @@ -95,7 +100,9 @@ static int set_subscriber_modify(struct ctrl_cmd *cmd, void *data)
subscr = subscr_get_by_imsi(net->subscr_group, imsi); if (!subscr) - subscr = subscr_create_subscriber(net->subscr_group, imsi); + subscr = subscr_create_subscriber(net->subscr_group, imsi, + net->ext_min, + net->ext_max, ext); if (!subscr) goto fail;
diff --git a/openbsc/src/libmsc/db.c b/openbsc/src/libmsc/db.c index 267b5ef..c2a956d 100644 --- a/openbsc/src/libmsc/db.c +++ b/openbsc/src/libmsc/db.c @@ -23,6 +23,7 @@ #include <inttypes.h> #include <libgen.h> #include <stdio.h> +#include <stdbool.h> #include <stdlib.h> #include <string.h> #include <errno.h> @@ -500,7 +501,8 @@ int db_fini(void) return 0; }
-struct gsm_subscriber *db_create_subscriber(const char *imsi) +struct gsm_subscriber *db_create_subscriber(const char *imsi, uint64_t smin, + uint64_t smax, bool alloc_exten) { dbi_result result; struct gsm_subscriber *subscr; @@ -532,7 +534,8 @@ struct gsm_subscriber *db_create_subscriber(const char *imsi) strncpy(subscr->imsi, imsi, GSM_IMSI_LENGTH-1); dbi_result_free(result); LOGP(DDB, LOGL_INFO, "New Subscriber: ID %llu, IMSI %s\n", subscr->id, subscr->imsi); - db_subscriber_alloc_exten(subscr); + if (alloc_exten) + db_subscriber_alloc_exten(subscr, smin, smax); return subscr; }
@@ -937,8 +940,11 @@ int db_sync_subscriber(struct gsm_subscriber *subscriber)
dbi_conn_quote_string_copy(conn, subscriber->name, &q_name); - dbi_conn_quote_string_copy(conn, - subscriber->extension, &q_extension); + if (subscriber->extension[0] != '\0') + dbi_conn_quote_string_copy(conn, + subscriber->extension, &q_extension); + else + q_extension = strdup("NULL"); if (subscriber->tmsi != GSM_RESERVED_TMSI) { sprintf(tmsi, "%u", subscriber->tmsi); @@ -1043,15 +1049,17 @@ int db_subscriber_delete(struct gsm_subscriber *subscr) } dbi_result_free(result);
- result = dbi_conn_queryf(conn, - "DELETE FROM SMS WHERE src_addr=%s OR dest_addr=%s", - subscr->extension, subscr->extension); - if (!result) { - LOGP(DDB, LOGL_ERROR, - "Failed to delete SMS for %llu\n", subscr->id); - return -1; + if (subscr->extension[0] != '\0') { + result = dbi_conn_queryf(conn, + "DELETE FROM SMS WHERE src_addr=%s OR dest_addr=%s", + subscr->extension, subscr->extension); + if (!result) { + LOGP(DDB, LOGL_ERROR, + "Failed to delete SMS for %llu\n", subscr->id); + return -1; + } + dbi_result_free(result); } - dbi_result_free(result);
result = dbi_conn_queryf(conn, "DELETE FROM VLR WHERE subscriber_id=%llu", @@ -1231,13 +1239,14 @@ int db_subscriber_alloc_tmsi(struct gsm_subscriber *subscriber) return 0; }
-int db_subscriber_alloc_exten(struct gsm_subscriber *subscriber) +int db_subscriber_alloc_exten(struct gsm_subscriber *subscriber, uint64_t smin, + uint64_t smax) { dbi_result result = NULL; uint32_t try;
for (;;) { - try = (rand()%(GSM_MAX_EXTEN-GSM_MIN_EXTEN+1)+GSM_MIN_EXTEN); + try = (rand() % (smax - smin + 1) + smin); result = dbi_conn_queryf(conn, "SELECT * FROM Subscriber " "WHERE extension = %i", diff --git a/openbsc/src/libmsc/gsm_04_08.c b/openbsc/src/libmsc/gsm_04_08.c index ab950c7..e498b6a 100644 --- a/openbsc/src/libmsc/gsm_04_08.c +++ b/openbsc/src/libmsc/gsm_04_08.c @@ -523,14 +523,19 @@ static int mm_tx_identity_req(struct gsm_subscriber_connection *conn, uint8_t id static struct gsm_subscriber *subscr_create(const struct gsm_network *net, const char *imsi) { + const char *ap = net->auth_prefix; + bool ext = (GSM_SUBSCR_RANDOM_EXT & net->create_subscriber) ? true : + false; + if (GSM_SUBSCR_DONT_CREATE == net->create_subscriber) return NULL;
if (net->create_subscriber & GSM_SUBSCR_MATCH_PREF) - if (!subscr_prefix_check(net->auth_prefix, imsi)) + if (!subscr_prefix_check(ap, imsi)) return NULL;
- return subscr_create_subscriber(net->subscr_group, imsi); + return subscr_create_subscriber(net->subscr_group, imsi, net->ext_min, + net->ext_max, ext); }
/* Parse Chapter 9.2.11 Identity Response */ @@ -582,7 +587,6 @@ static int mm_rx_id_resp(struct gsm_subscriber_connection *conn, struct msgb *ms return gsm0408_authorize(conn, msg); }
- static void loc_upd_rej_cb(void *data) { struct gsm_subscriber_connection *conn = data; diff --git a/openbsc/src/libmsc/gsm_subscriber.c b/openbsc/src/libmsc/gsm_subscriber.c index 57c10cf..7d62888 100644 --- a/openbsc/src/libmsc/gsm_subscriber.c +++ b/openbsc/src/libmsc/gsm_subscriber.c @@ -203,9 +203,11 @@ void subscr_remove_request(struct subscr_request *request) }
struct gsm_subscriber *subscr_create_subscriber(struct gsm_subscriber_group *sgrp, - const char *imsi) + const char *imsi, uint64_t smin, + uint64_t smax, bool ext) { - struct gsm_subscriber *subscr = db_create_subscriber(imsi); + struct gsm_subscriber *subscr = + db_create_subscriber(imsi, smin, smax, ext); if (subscr) subscr->group = sgrp; return subscr; diff --git a/openbsc/src/libmsc/vty_interface_layer3.c b/openbsc/src/libmsc/vty_interface_layer3.c index 0ac2e90..bf7a947 100644 --- a/openbsc/src/libmsc/vty_interface_layer3.c +++ b/openbsc/src/libmsc/vty_interface_layer3.c @@ -21,6 +21,8 @@ #include <stdlib.h> #include <limits.h> #include <unistd.h> +#include <stdbool.h> +#include <inttypes.h> #include <time.h>
#include <osmocom/vty/command.h> @@ -235,12 +237,16 @@ DEFUN(subscriber_create, { struct gsm_network *gsmnet = gsmnet_from_vty(vty); struct gsm_subscriber *subscr; + bool ext = (GSM_SUBSCR_RANDOM_EXT == gsmnet->create_subscriber) ? true : + false;
subscr = subscr_get_by_imsi(gsmnet->subscr_group, argv[0]); if (subscr) db_sync_subscriber(subscr); else { - subscr = subscr_create_subscriber(gsmnet->subscr_group, argv[0]); + subscr = subscr_create_subscriber(gsmnet->subscr_group, argv[0], + gsmnet->ext_min, + gsmnet->ext_max, ext);
if (!subscr) { vty_out(vty, "%% No subscriber created for IMSI %s%s", @@ -1031,6 +1037,34 @@ DEFUN(cfg_nitb, cfg_nitb_cmd, return CMD_SUCCESS; }
+/* Note: limit on the prefix length is set by internal vty code limitations */ +DEFUN(cfg_nitb_subscr_random, cfg_nitb_subscr_random_cmd, + "subscriber-create-on-demand random <1-9999999999> <2-9999999999>", + "Set random parameters for a new record when a subscriber is first seen.\n" + "Set random parameters for a new record when a subscriber is first seen.\n" + "Minimum for subscriber extension\n""Maximum for subscriber extension\n") +{ + struct gsm_network *gsmnet = gsmnet_from_vty(vty); + uint64_t mi = atoi(argv[0]), ma = atoi(argv[1]); + if (mi >= ma) { + vty_out(vty, "Incorrect range: %s >= %s, expected MIN < MAX%s", + argv[0], argv[1], VTY_NEWLINE); + return CMD_WARNING; + } + gsmnet->ext_min = mi; + gsmnet->ext_max = ma; + return CMD_SUCCESS; +} + +DEFUN(cfg_nitb_subscr_noext, cfg_nitb_subscr_noext_cmd, + "subscriber-create-no-extension", + "Do not assign extension when creating subscriber on demand.\n") +{ + struct gsm_network *gsmnet = gsmnet_from_vty(vty); + gsmnet->create_subscriber |= GSM_SUBSCR_NO_EXT; + return CMD_SUCCESS; +} + DEFUN(cfg_nitb_subscr_create, cfg_nitb_subscr_create_cmd, "subscriber-create-on-demand [imsi-prefix]", "Make a new record when a subscriber is first seen.\n" @@ -1038,9 +1072,11 @@ DEFUN(cfg_nitb_subscr_create, cfg_nitb_subscr_create_cmd, "authorize-prefix command \n") { struct gsm_network *gsmnet = gsmnet_from_vty(vty); - gsmnet->create_subscriber = GSM_SUBSCR_RANDOM_EXT; + if (!gsmnet->create_subscriber) + gsmnet->create_subscriber = GSM_SUBSCR_RANDOM_EXT; if (argc) gsmnet->create_subscriber |= GSM_SUBSCR_MATCH_PREF; + return CMD_SUCCESS; }
@@ -1079,8 +1115,15 @@ static int config_write_nitb(struct vty *vty) " imsi-prefix" : "";
vty_out(vty, "nitb%s", VTY_NEWLINE); - vty_out(vty, " %ssubscriber-create-on-demand%s%s", - pref, ims, VTY_NEWLINE); + vty_out(vty, " %ssubscriber-create-on-demand%s%s", pref, ims, + VTY_NEWLINE); + if (gsmnet->create_subscriber & GSM_SUBSCR_NO_EXT) + vty_out(vty, " subscriber-create-no-extension%s", VTY_NEWLINE); + if (gsmnet->ext_min != GSM_MIN_EXTEN || gsmnet->ext_max != GSM_MAX_EXTEN) + vty_out(vty, " subscriber-create-on-demand random %"PRIu64" %" + PRIu64"%s", gsmnet->ext_min, gsmnet->ext_max, + VTY_NEWLINE); + vty_out(vty, " %sassign-tmsi%s", gsmnet->avoid_tmsi ? "no " : "", VTY_NEWLINE); return CMD_SUCCESS; @@ -1135,6 +1178,8 @@ int bsc_vty_init_extra(void) install_element(CONFIG_NODE, &cfg_nitb_cmd); install_node(&nitb_node, config_write_nitb); install_element(NITB_NODE, &cfg_nitb_subscr_create_cmd); + install_element(NITB_NODE, &cfg_nitb_subscr_noext_cmd); + install_element(NITB_NODE, &cfg_nitb_subscr_random_cmd); install_element(NITB_NODE, &cfg_nitb_no_subscr_create_cmd); install_element(NITB_NODE, &cfg_nitb_assign_tmsi_cmd); install_element(NITB_NODE, &cfg_nitb_no_assign_tmsi_cmd); diff --git a/openbsc/tests/db/db_test.c b/openbsc/tests/db/db_test.c index 6b40e84..1deaf1b 100644 --- a/openbsc/tests/db/db_test.c +++ b/openbsc/tests/db/db_test.c @@ -28,6 +28,7 @@ #include <stdio.h> #include <string.h> #include <stdlib.h> +#include <stdbool.h> #include <inttypes.h>
static struct gsm_network dummy_net; @@ -159,12 +160,13 @@ static void test_sms_migrate(void) subscr_put(rcv_subscr); }
-static void test_subs(const char *alice_imsi, char *imei1, char *imei2) +static void test_subs(const char *alice_imsi, char *imei1, char *imei2, bool ext) { struct gsm_subscriber *alice = NULL, *alice_db; char scratch_str[256];
- alice = db_create_subscriber(alice_imsi); + alice = db_create_subscriber(alice_imsi, GSM_MIN_EXTEN, GSM_MAX_EXTEN, + ext); db_subscriber_assoc_imei(alice, imei1); if (imei2) db_subscriber_assoc_imei(alice, imei2); @@ -219,18 +221,22 @@ int main() struct gsm_subscriber *alice_db;
char *alice_imsi = "3243245432345"; - alice = db_create_subscriber(alice_imsi); + alice = db_create_subscriber(alice_imsi, GSM_MIN_EXTEN, GSM_MAX_EXTEN, + true); db_sync_subscriber(alice); alice_db = db_get_subscriber(GSM_SUBSCRIBER_IMSI, alice->imsi); COMPARE(alice, alice_db); SUBSCR_PUT(alice_db); SUBSCR_PUT(alice);
- test_subs("3693245423445", "1234567890", NULL); - test_subs("9993245423445", "1234567890", "6543560920"); + test_subs("3693245423445", "1234567890", NULL, true); + test_subs("9993245423445", "1234567890", "6543560920", true); + test_subs("3123122223445", "1234567890", NULL, false); + test_subs("9123121223445", "1234567890", "6543560920", false);
/* create it again and see it fails */ - alice = db_create_subscriber(alice_imsi); + alice = db_create_subscriber(alice_imsi, GSM_MIN_EXTEN, GSM_MAX_EXTEN, + true); OSMO_ASSERT(!alice);
test_sms(); diff --git a/openbsc/tests/vty_test_runner.py b/openbsc/tests/vty_test_runner.py index e240811..9dd8103 100644 --- a/openbsc/tests/vty_test_runner.py +++ b/openbsc/tests/vty_test_runner.py @@ -422,11 +422,15 @@ class TestVTYNITB(TestVTYGenericBSC): self.vty.enable()
imsi = "204300854013739" + imsi2 = "204301824913769" + imsi3 = "100500854113769" + imsi4 = "100583744053769" wrong_imsi = "204300999999999"
# Lets create one res = self.vty.command('subscriber create imsi '+imsi) self.assert_(res.find(" IMSI: "+imsi) > 0) + self.assert_(res.find("Extension") > 0)
self.vty.verify('subscriber imsi '+wrong_imsi+' name wrong', ['% No subscriber found for imsi '+wrong_imsi]) res = self.vty.command('subscriber imsi '+imsi+' name '+('X' * 160)) @@ -440,9 +444,54 @@ class TestVTYNITB(TestVTYGenericBSC):
self.vty.verify('subscriber imsi '+imsi+' extension '+('1' * 14), [''])
+ # With narrow random interval + self.vty.command("configure terminal") + self.vty.command("nitb") + self.assertTrue(self.vty.verify("subscriber-create-on-demand", [''])) + # wrong interval + res = self.vty.command("subscriber-create-on-demand random 221 122") + self.assert_(res.find("122") > 0) + self.assert_(res.find("221") > 0) + # correct interval + self.assertTrue(self.vty.verify("subscriber-create-on-demand random 221 222", [''])) + self.vty.command("end") + + res = self.vty.command('subscriber create imsi ' + imsi2) + self.assert_(res.find(" IMSI: " + imsi2) > 0) + self.assert_(res.find("221") > 0 or res.find("222") > 0) + self.assert_(res.find(" Extension: ") > 0) + + # Without extension + self.vty.command("configure terminal") + self.vty.command("nitb") + self.assertTrue(self.vty.verify("subscriber-create-no-extension", [''])) + self.vty.command("end") + + res = self.vty.command('subscriber create imsi ' + imsi3) + self.assert_(res.find(" IMSI: " + imsi3) > 0) + self.assertEquals(res.find("Extension"), -1) + + # With extension again + self.vty.command("configure terminal") + self.vty.command("nitb") + self.assertTrue(self.vty.verify("no subscriber-create-on-demand", [''])) + self.assertTrue(self.vty.verify("subscriber-create-on-demand", [''])) + self.assertTrue(self.vty.verify("subscriber-create-on-demand random 221 666", [''])) + self.vty.command("end") + + res = self.vty.command('subscriber create imsi ' + imsi4) + self.assert_(res.find(" IMSI: " + imsi4) > 0) + self.assert_(res.find(" Extension: ") > 0) + # Delete it res = self.vty.command('subscriber delete imsi '+imsi) self.assert_(res != "") + res = self.vty.command('subscriber delete imsi ' + imsi2) + self.assert_(res != "") + res = self.vty.command('subscriber delete imsi ' + imsi3) + self.assert_(res != "") + res = self.vty.command('subscriber delete imsi ' + imsi4) + self.assert_(res != "")
def testShowPagingGroup(self): res = self.vty.command("show paging-group 255 1234567")
On 04 May 2016, at 13:02, msuraev@sysmocom.de wrote:
+enum gsm_subscr_ext_alloc_policy {
- GSM_SUBSCR_DONT_CREATE = 0,
- GSM_SUBSCR_RANDOM_EXT = 1,
+};
Neels reminded us to name things well. "extension alloc policy" is not the right word. The first item doesn't control the creation of the extension but the creation of the subscriber.
enum gsm_subscr_creation_mode { GSM_SUBSCR_DONT_CREATE GSM_SUBSCR_CREAT_W_RAND_EXT, GSM_SUBSCR_CREAT_W_NO_EXT }>
enum gsm_security_event { GSM_SECURITY_NOAVAIL, GSM_SECURITY_AUTH_FAILED, diff --git a/openbsc/src/libbsc/net_init.c b/openbsc/src/libbsc/net_init.c index 568a0b8..00a8a9b 100644 --- a/openbsc/src/libbsc/net_init.c +++ b/openbsc/src/libbsc/net_init.c @@ -48,7 +48,7 @@ struct gsm_network *gsm_network_init(uint16_t country_code, uint16_t network_cod INIT_LLIST_HEAD(&net->bsc_data->mscs);
net->subscr_group->net = net;
- net->create_subscriber = 1;
- net->create_subscriber = GSM_SUBSCR_RANDOM_EXT;
rename variable to creation_mode? or better name?