diff mbox

[v2] ctrl: Extend ctrl command to optionally handle alg+ki

Message ID 1460013330-75690-1-git-send-email-holger@freyther.de
State Not Applicable
Headers show

Commit Message

Holger Freyther April 7, 2016, 7:15 a.m. UTC
From: Holger Hans Peter Freyther <holger@moiji-mobile.com>

Extend the existing ctrl command to be able to specify the
algorithm and Ki. In contrast to the VTY no size check is
done. Together with the VTY this code only supports a small
part of what is supported by libosmocore.

The algorithm and ki are considered optional but if a valid
and non none algorithm is passed, a KI must be passed as well.

Extend the test coverage by passing the potential values. It
is not verified that the KI/algorithm is stored.
---
 openbsc/src/libmsc/ctrl_commands.c | 60 ++++++++++++++++++++++++++++++++++++--
 openbsc/tests/ctrl_test_runner.py  | 27 +++++++++++++++++
 2 files changed, 85 insertions(+), 2 deletions(-)
diff mbox

Patch

diff --git a/openbsc/src/libmsc/ctrl_commands.c b/openbsc/src/libmsc/ctrl_commands.c
index e48c6a3..9ac39de 100644
--- a/openbsc/src/libmsc/ctrl_commands.c
+++ b/openbsc/src/libmsc/ctrl_commands.c
@@ -24,9 +24,25 @@ 
 #include <openbsc/db.h>
 #include <openbsc/debug.h>
 
+static bool alg_supported(const char *alg)
+{
+	/*
+	 * TODO: share this with the vty_interface and extend to all
+	 * algorithms supported by libosmocore now. Make it table based
+	 * as well.
+	 */
+	if (strcasecmp(alg, "none") == 0)
+		return true;
+	if (strcasecmp(alg, "xor") == 0)
+		return true;
+	if (strcasecmp(alg, "comp128v1") == 0)
+		return true;
+	return false;
+}
+
 static int verify_subscriber_modify(struct ctrl_cmd *cmd, const char *value, void *d)
 {
-	char *tmp, *imsi, *msisdn, *saveptr = NULL;
+	char *tmp, *imsi, *msisdn, *alg, *ki, *saveptr = NULL;
 	int rc = 0;
 
 	tmp = talloc_strdup(cmd, value);
@@ -35,6 +51,8 @@  static int verify_subscriber_modify(struct ctrl_cmd *cmd, const char *value, voi
 
 	imsi = strtok_r(tmp, ",", &saveptr);
 	msisdn = strtok_r(NULL, ",", &saveptr);
+	alg = strtok_r(NULL, ",", &saveptr);
+	ki = strtok_r(NULL, ",", &saveptr);
 
 	if (!imsi || !msisdn)
 		rc = 1;
@@ -42,6 +60,12 @@  static int verify_subscriber_modify(struct ctrl_cmd *cmd, const char *value, voi
 		rc = 1;
 	else if (strlen(msisdn) >= GSM_EXTENSION_LENGTH)
 		rc = 1;
+	else if (alg) {
+		if (!alg_supported(alg))
+			rc = 1;
+		else if (strcasecmp(alg, "none") != 0 && !ki)
+			rc = 1;
+	}
 
 	talloc_free(tmp);
 	return rc;
@@ -56,7 +80,7 @@  static int get_subscriber_modify(struct ctrl_cmd *cmd, void *data)
 static int set_subscriber_modify(struct ctrl_cmd *cmd, void *data)
 {
 	struct gsm_network *net = cmd->node;
-	char *tmp, *imsi, *msisdn, *saveptr = NULL;
+	char *tmp, *imsi, *msisdn, *alg, *ki, *saveptr = NULL;
 	struct gsm_subscriber* subscr;
 	int rc;
 
@@ -66,6 +90,8 @@  static int set_subscriber_modify(struct ctrl_cmd *cmd, void *data)
 
 	imsi = strtok_r(tmp, ",", &saveptr);
 	msisdn = strtok_r(NULL, ",", &saveptr);
+	alg = strtok_r(NULL, ",", &saveptr);
+	ki = strtok_r(NULL, ",", &saveptr);
 
 	subscr = subscr_get_by_imsi(net->subscr_group, imsi);
 	if (!subscr)
@@ -80,6 +106,36 @@  static int set_subscriber_modify(struct ctrl_cmd *cmd, void *data)
 	/* put it back to the db */
 	rc = db_sync_subscriber(subscr);
 	db_subscriber_update(subscr);
+
+	/* handle optional ciphering */
+	if (alg) {
+		if (strcasecmp(alg, "none") == 0)
+			db_sync_authinfo_for_subscr(NULL, subscr);
+		else {
+			struct gsm_auth_info ainfo = { 0, };
+			/* the verify should make sure that this is okay */
+			OSMO_ASSERT(alg);
+			OSMO_ASSERT(ki);
+
+			if (strcasecmp(alg, "xor") == 0)
+				ainfo.auth_algo = AUTH_ALGO_XOR;
+			else if (strcasecmp(alg, "comp128v1") == 0)
+				ainfo.auth_algo = AUTH_ALGO_COMP128v1;
+
+			rc = osmo_hexparse(ki, ainfo.a3a8_ki, sizeof(ainfo.a3a8_ki));
+			if (rc < 0) {
+				subscr_put(subscr);
+				talloc_free(tmp);
+				cmd->reply = "Failed to parse KI";
+				return CTRL_CMD_ERROR;
+			}
+
+			ainfo.a3a8_ki_len = rc;
+			db_sync_authinfo_for_subscr(&ainfo, subscr);
+			rc = 0;
+		}
+		db_sync_lastauthtuple_for_subscr(NULL, subscr);
+	}
 	subscr_put(subscr);
 
 	talloc_free(tmp);
diff --git a/openbsc/tests/ctrl_test_runner.py b/openbsc/tests/ctrl_test_runner.py
index 21850e3..7a12643 100644
--- a/openbsc/tests/ctrl_test_runner.py
+++ b/openbsc/tests/ctrl_test_runner.py
@@ -469,6 +469,33 @@  class TestCtrlNITB(TestCtrlBase):
         self.assertEquals(r['var'], 'number-of-bts')
         self.assertEquals(r['value'], '1')
 
+    def testSubscriberAddWithKi(self):
+        """Test that we can set the algorithm to none, xor, comp128v1"""
+
+        r = self.do_set('subscriber-modify-v1', '2620345,445566')
+        self.assertEquals(r['mtype'], 'SET_REPLY')
+        self.assertEquals(r['var'], 'subscriber-modify-v1')
+        self.assertEquals(r['value'], 'OK')
+
+        r = self.do_set('subscriber-modify-v1', '2620345,445566,none')
+        self.assertEquals(r['mtype'], 'SET_REPLY')
+        self.assertEquals(r['var'], 'subscriber-modify-v1')
+        self.assertEquals(r['value'], 'OK')
+
+        r = self.do_set('subscriber-modify-v1', '2620345,445566,xor')
+        self.assertEquals(r['mtype'], 'ERROR')
+        self.assertEquals(r['error'], 'Value failed verification.')
+
+        r = self.do_set('subscriber-modify-v1', '2620345,445566,comp128v1,00112233445566778899AABBCCDDEEFF')
+        self.assertEquals(r['mtype'], 'SET_REPLY')
+        self.assertEquals(r['var'], 'subscriber-modify-v1')
+        self.assertEquals(r['value'], 'OK')
+
+        r = self.do_set('subscriber-modify-v1', '2620345,445566,none')
+        self.assertEquals(r['mtype'], 'SET_REPLY')
+        self.assertEquals(r['var'], 'subscriber-modify-v1')
+        self.assertEquals(r['value'], 'OK')
+
     def testSubscriberAddRemove(self):
         r = self.do_set('subscriber-modify-v1', '2620345,445566')
         self.assertEquals(r['mtype'], 'SET_REPLY')