aboutsummaryrefslogtreecommitdiffstats
path: root/openbsc/src
diff options
context:
space:
mode:
Diffstat (limited to 'openbsc/src')
-rw-r--r--openbsc/src/libbsc/bsc_vty.c29
-rw-r--r--openbsc/src/libcommon/gsm_data.c1
-rw-r--r--openbsc/src/libmsc/gsm_04_08.c31
-rw-r--r--openbsc/src/libmsc/vty_interface_layer3.c15
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;