aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPau Espin Pedrol <pespin@sysmocom.de>2022-06-20 16:48:45 +0200
committerPau Espin Pedrol <pespin@sysmocom.de>2022-06-21 10:35:18 +0200
commit1d0a030aa46336d5593921144b3bd558cad5ec01 (patch)
tree59fa5d8ad11e9f72b118fbf6c7eb7a920a4c26e2
parent3ca9a1fd4f09f598e251f00068967aab34d38e12 (diff)
ctrl: Introduce CTRL command subscriber.by-*.aud2g <algo[,ki]>
This command provides getter and setter to set and retrieve the authentication data for 2g subscribers. Change-Id: Ibebac232fa173bce8a075cacf477214d5bdb590f Related: SYS#5993
-rw-r--r--src/ctrl.c104
-rw-r--r--src/hlr_vty_subscr.c4
-rw-r--r--tests/test_subscriber.ctrl19
-rw-r--r--tests/test_subscriber_errors.ctrl9
4 files changed, 132 insertions, 4 deletions
diff --git a/src/ctrl.c b/src/ctrl.c
index 562ee75..c543559 100644
--- a/src/ctrl.c
+++ b/src/ctrl.c
@@ -37,6 +37,9 @@
#define SEL_BY_MSISDN SEL_BY "msisdn-"
#define SEL_BY_ID SEL_BY "id-"
+extern bool auth_algo_parse(const char *alg_str, enum osmo_auth_algo *algo,
+ int *minlen, int *maxlen);
+
#define hexdump_buf(buf) osmo_hexdump_nospc((void*)buf, sizeof(buf))
static bool startswith(const char *str, const char *start)
@@ -473,6 +476,106 @@ static int set_subscr_msisdn(struct ctrl_cmd *cmd, void *data)
return CTRL_CMD_REPLY;
}
+/* value format: <algo[,KI]> */
+CTRL_CMD_DEFINE(subscr_aud2g, "aud2g");
+static int verify_subscr_aud2g(struct ctrl_cmd *cmd, const char *value, void *data)
+{
+ if (!value)
+ return 1;
+ if (strcasecmp(value, "none") != 0 && !strchr(value, ','))
+ return 1;
+ return 0;
+}
+static int get_subscr_aud2g(struct ctrl_cmd *cmd, void *data)
+{
+ struct hlr_subscriber subscr;
+ struct hlr *hlr = data;
+ const char *by_selector = cmd->node;
+ struct osmo_sub_auth_data aud2g;
+ struct osmo_sub_auth_data aud3g_unused;
+ int rc;
+
+ if (!get_subscriber(hlr->dbc, by_selector, &subscr, cmd))
+ return CTRL_CMD_ERROR;
+
+ rc = db_get_auth_data(hlr->dbc, subscr.imsi, &aud2g, &aud3g_unused, NULL);
+ switch (rc) {
+ case 0:
+ break;
+ case -ENOENT:
+ case -ENOKEY:
+ aud2g.algo = OSMO_AUTH_ALG_NONE;
+ break;
+ default:
+ cmd->reply = "Error retrieving data from database.";
+ return CTRL_CMD_ERROR;
+ }
+
+ if (aud2g.algo == OSMO_AUTH_ALG_NONE) {
+ cmd->reply = "none";
+ return CTRL_CMD_REPLY;
+ }
+
+ cmd->reply = talloc_asprintf(cmd, "%s,%s", osmo_auth_alg_name(aud2g.algo),
+ hexdump_buf(aud2g.u.gsm.ki));
+ return CTRL_CMD_REPLY;
+}
+static int set_subscr_aud2g(struct ctrl_cmd *cmd, void *data)
+{
+ struct hlr_subscriber subscr;
+ struct hlr *hlr = data;
+ const char *by_selector = cmd->node;
+ char *tmp = NULL, *tok, *saveptr;
+ int minlen = 0;
+ int maxlen = 0;
+ struct sub_auth_data_str aud2g = {
+ .type = OSMO_AUTH_TYPE_GSM
+ };
+
+ if (!get_subscriber(hlr->dbc, by_selector, &subscr, cmd))
+ return CTRL_CMD_ERROR;
+
+ tmp = talloc_strdup(cmd, cmd->value);
+ if (!tmp) {
+ cmd->reply = "OOM";
+ return CTRL_CMD_ERROR;
+ }
+
+ /* Parse alg_type: */
+ tok = strtok_r(tmp, ",", &saveptr);
+ if (!tok) {
+ cmd->reply = "Invalid format";
+ return CTRL_CMD_ERROR;
+ }
+ if (strcmp(tok, "none") == 0) {
+ aud2g.algo = OSMO_AUTH_ALG_NONE;
+ } else if (!auth_algo_parse(tok, &aud2g.algo, &minlen, &maxlen)) {
+ cmd->reply = "Unknown auth algorithm.";
+ return CTRL_CMD_ERROR;
+ }
+
+ if (aud2g.algo != OSMO_AUTH_ALG_NONE) {
+ tok = strtok_r(NULL, "\0", &saveptr);
+ if (!tok) {
+ cmd->reply = "Invalid format.";
+ return CTRL_CMD_ERROR;
+ }
+ aud2g.u.gsm.ki = tok;
+ if (!osmo_is_hexstr(aud2g.u.gsm.ki, minlen * 2, maxlen * 2, true)) {
+ cmd->reply = "Invalid KI.";
+ return CTRL_CMD_ERROR;
+ }
+ }
+
+ if (db_subscr_update_aud_by_id(g_hlr->dbc, subscr.id, &aud2g)) {
+ cmd->reply = "Update aud2g failed.";
+ return CTRL_CMD_ERROR;
+ }
+
+ cmd->reply = "OK";
+ return CTRL_CMD_REPLY;
+}
+
static int hlr_ctrl_node_lookup(void *data, vector vline, int *node_type,
void **node_data, int *i)
{
@@ -511,6 +614,7 @@ static int hlr_ctrl_cmds_install()
rc |= ctrl_cmd_install(CTRL_NODE_SUBSCR_BY, &cmd_subscr_ps_enabled);
rc |= ctrl_cmd_install(CTRL_NODE_SUBSCR_BY, &cmd_subscr_cs_enabled);
rc |= ctrl_cmd_install(CTRL_NODE_SUBSCR_BY, &cmd_subscr_msisdn);
+ rc |= ctrl_cmd_install(CTRL_NODE_SUBSCR_BY, &cmd_subscr_aud2g);
return rc;
}
diff --git a/src/hlr_vty_subscr.c b/src/hlr_vty_subscr.c
index 3813393..a9f461d 100644
--- a/src/hlr_vty_subscr.c
+++ b/src/hlr_vty_subscr.c
@@ -476,8 +476,8 @@ static bool is_hexkey_valid(struct vty *vty, const char *label,
#define MILENAGE_KEY_LEN 16
-static bool auth_algo_parse(const char *alg_str, enum osmo_auth_algo *algo,
- int *minlen, int *maxlen)
+bool auth_algo_parse(const char *alg_str, enum osmo_auth_algo *algo,
+ int *minlen, int *maxlen)
{
if (!strcasecmp(alg_str, "none")) {
*algo = OSMO_AUTH_ALG_NONE;
diff --git a/tests/test_subscriber.ctrl b/tests/test_subscriber.ctrl
index 889f0a7..dadad35 100644
--- a/tests/test_subscriber.ctrl
+++ b/tests/test_subscriber.ctrl
@@ -671,5 +671,20 @@ periodic_lu_timer 0
periodic_rau_tau_timer 0
lmsi 00000000
-SET 112 subscriber.delete 901991234567891
-SET_REPLY 112 subscriber.delete 124
+GET 112 subscriber.by-imsi-901991234567891.aud2g
+GET_REPLY 112 subscriber.by-imsi-901991234567891.aud2g none
+
+SET 113 subscriber.by-imsi-901991234567891.aud2g xor,c01ffedc1cadaeac1d1f1edacac1ab0a
+SET_REPLY 113 subscriber.by-imsi-901991234567891.aud2g OK
+
+GET 114 subscriber.by-imsi-901991234567891.aud2g
+GET_REPLY 114 subscriber.by-imsi-901991234567891.aud2g XOR,c01ffedc1cadaeac1d1f1edacac1ab0a
+
+SET 115 subscriber.by-imsi-901991234567891.aud2g none
+SET_REPLY 115 subscriber.by-imsi-901991234567891.aud2g OK
+
+GET 116 subscriber.by-imsi-901991234567891.aud2g
+GET_REPLY 116 subscriber.by-imsi-901991234567891.aud2g none
+
+SET 117 subscriber.delete 901991234567891
+SET_REPLY 117 subscriber.delete 124
diff --git a/tests/test_subscriber_errors.ctrl b/tests/test_subscriber_errors.ctrl
index 403e0fa..ac9eec7 100644
--- a/tests/test_subscriber_errors.ctrl
+++ b/tests/test_subscriber_errors.ctrl
@@ -123,3 +123,12 @@ ERROR 52 Subscriber doesn't exist.
SET 53 subscriber.delete zzz
ERROR 53 Invalid IMSI value.
+
+SET 54 subscriber.by-imsi-901990000000003.aud2g foobar
+ERROR 54 Value failed verification.
+
+SET 55 subscriber.by-imsi-901990000000003.aud2g foobar,2134
+ERROR 55 Unknown auth algorithm.
+
+SET 56 subscriber.by-imsi-901990000000003.aud2g xor,2134
+ERROR 56 Invalid KI.