diff options
Diffstat (limited to 'openbsc/src')
-rw-r--r-- | openbsc/src/libbsc/bsc_vty.c | 29 | ||||
-rw-r--r-- | openbsc/src/libcommon/gsm_data.c | 1 | ||||
-rw-r--r-- | openbsc/src/libmsc/gsm_04_08.c | 31 | ||||
-rw-r--r-- | openbsc/src/libmsc/vty_interface_layer3.c | 15 |
4 files changed, 66 insertions, 10 deletions
diff --git a/openbsc/src/libbsc/bsc_vty.c b/openbsc/src/libbsc/bsc_vty.c index 46ad45723..f4d47b480 100644 --- a/openbsc/src/libbsc/bsc_vty.c +++ b/openbsc/src/libbsc/bsc_vty.c @@ -190,8 +190,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->authorized_reg_str) + vty_out(vty, ", authorized regexp: %s", net->authorized_reg_str); + 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, @@ -791,6 +794,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->authorized_reg_str) + vty_out(vty, " authorized-regexp %s%s", gsmnet->authorized_reg_str, 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); @@ -1398,11 +1403,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|regexp|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 regular expression for IMSI authorization decision\n" "Use SMS-token based authentication\n") { enum gsm_auth_policy policy = gsm_auth_policy_parse(argv[0]); @@ -1413,6 +1419,22 @@ DEFUN(cfg_net_auth_policy, return CMD_SUCCESS; } +DEFUN(cfg_net_authorize_regexp, cfg_net_authorize_regexp_cmd, + "authorized-regexp REGEXP", + "Set regexp for IMSI which will be used for authorization decision\n" + "Regular expression, IMSIs matching it are allowed to use the network\n") +{ + struct gsm_network *gsmnet = gsmnet_from_vty(vty); + if (gsm_parse_reg(gsmnet, &gsmnet->authorized_regexp, + &gsmnet->authorized_reg_str, argc, argv) != 0) { + vty_out(vty, "%%Failed to parse the authorized-regexp: '%s'%s", + argv[0], VTY_NEWLINE); + return CMD_WARNING; + } + + return CMD_SUCCESS; +} + DEFUN(cfg_net_reject_cause, cfg_net_reject_cause_cmd, "location updating reject cause <2-111>", @@ -3973,6 +3995,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_regexp_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/libcommon/gsm_data.c b/openbsc/src/libcommon/gsm_data.c index 4e235fd6b..9d794eec9 100644 --- a/openbsc/src/libcommon/gsm_data.c +++ b/openbsc/src/libcommon/gsm_data.c @@ -162,6 +162,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_REGEXP, "regexp" }, { 0, NULL } }; diff --git a/openbsc/src/libmsc/gsm_04_08.c b/openbsc/src/libmsc/gsm_04_08.c index 74da34b19..92c4cfe0e 100644 --- a/openbsc/src/libmsc/gsm_04_08.c +++ b/openbsc/src/libmsc/gsm_04_08.c @@ -25,9 +25,12 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <stdbool.h> #include <errno.h> #include <time.h> #include <netinet/in.h> +#include <regex.h> +#include <sys/types.h> #include "bscconfig.h" @@ -244,6 +247,17 @@ int gsm48_secure_channel(struct gsm_subscriber_connection *conn, int key_seq, return -EINVAL; /* not reached */ } +static bool subscr_regexp_check(const struct gsm_network *net, const char *imsi) +{ + if (!net->authorized_reg_str) + return false; + + if (regexec(&net->authorized_regexp, imsi, 0, NULL, 0) != REG_NOMATCH) + return true; + + return false; +} + static int authorize_subscriber(struct gsm_loc_updating_operation *loc, struct gsm_subscriber *subscriber) { @@ -261,6 +275,13 @@ 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_REGEXP: + if (subscriber->authorized) + return 1; + if (subscr_regexp_check(subscriber->group->net, + subscriber->imsi)) + subscriber->authorized = 1; + return subscriber->authorized; case GSM_AUTH_POLICY_TOKEN: if (subscriber->authorized) return subscriber->authorized; @@ -509,10 +530,14 @@ 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) { - if (net->subscr_creation_mode != GSM_SUBSCR_DONT_CREATE) - return subscr_create_subscriber(net->subscr_group, imsi); + if (net->subscr_creation_mode == GSM_SUBSCR_DONT_CREATE) + return NULL; + + if (net->subscr_creation_mode & GSM_SUBSCR_CREAT_W_REGEXP) + if (!subscr_regexp_check(net, imsi)) + return NULL; - return NULL; + return subscr_create_subscriber(net->subscr_group, imsi); } /* Parse Chapter 9.2.11 Identity Response */ diff --git a/openbsc/src/libmsc/vty_interface_layer3.c b/openbsc/src/libmsc/vty_interface_layer3.c index 5d74e04fa..3f67b9aa8 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 [regexp]", + "Make a new record when a subscriber is first seen.\n" + "Create subscribers only if IMSI matches the regexp specified in " + "authorized-regexp command\n") { struct gsm_network *gsmnet = gsmnet_from_vty(vty); gsmnet->subscr_creation_mode = GSM_SUBSCR_CREAT_W_RAND_EXT; + if (argc) + gsmnet->subscr_creation_mode |= GSM_SUBSCR_CREAT_W_REGEXP; return CMD_SUCCESS; } @@ -1070,9 +1074,12 @@ 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); + enum gsm_subscr_creation_mode scm = gsmnet->subscr_creation_mode; + const char *reg = (scm & GSM_SUBSCR_CREAT_W_REGEXP) ? " regexp" : "", + *pref = scm ? "" : "no "; vty_out(vty, "nitb%s", VTY_NEWLINE); - vty_out(vty, " %ssubscriber-create-on-demand%s", - gsmnet->subscr_creation_mode ? "" : "no ", VTY_NEWLINE); + vty_out(vty, " %ssubscriber-create-on-demand%s%s", + pref, reg, VTY_NEWLINE); vty_out(vty, " %sassign-tmsi%s", gsmnet->avoid_tmsi ? "no " : "", VTY_NEWLINE); return CMD_SUCCESS; |