aboutsummaryrefslogtreecommitdiffstats
path: root/openbsc/src/libmsc
diff options
context:
space:
mode:
authorMax <msuraev@sysmocom.de>2016-05-24 14:23:27 +0200
committerHarald Welte <laforge@gnumonks.org>2016-06-05 09:36:37 +0000
commitddee01fa8fe3b71d39b1e0b9e9ceb93366d56242 (patch)
tree13e0c96154a1158d740d3a607a0d04362baf598d /openbsc/src/libmsc
parentd7df7ae39276e825af2a1b7ac82eb74b42ec7775 (diff)
Add regexp authorization policy for IMSI
* extend "auth policy" vty command with new option "regexp" * add vty command "authorized-regexp" for setting arbitrary POSIX regular expression * add basic vty test * add optional "regexp" argument to subscriber-create-on-demand vty command With those in place we can now set the regexp against which MS's IMSI will be matched. If IMSI match the regexp 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 matching. The same way we can decide whether to create subscribers on-demand basesd on IMSI regexp match. Similar to authorization this restriction can be overridden by manually creating subscriber via vty, ctrl interface or directly in HLR. Change-Id: I525f4b80676de47d1d422686da2ca012301b0129 Fixes: OS#1647
Diffstat (limited to 'openbsc/src/libmsc')
-rw-r--r--openbsc/src/libmsc/gsm_04_08.c31
-rw-r--r--openbsc/src/libmsc/vty_interface_layer3.c15
2 files changed, 39 insertions, 7 deletions
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;