ctrl: Introduce CTRL command subscriber.by-*.aud3g <algo[,KI,(op|opc),OP_C[,ind_bitlen]]>
This command provides getter and setter to set and retrieve the authentication data for 3g subscribers. Change-Id: Ibe7aeec3cabab0406eb7a84ecd24e529ef1696c2 Related: SYS#5993changes/97/28397/2
parent
1d0a030aa4
commit
777860ddb5
|
@ -37,6 +37,12 @@ enum hlr_vty_node {
|
|||
MSLOOKUP_CLIENT_NODE,
|
||||
};
|
||||
|
||||
|
||||
#define A38_XOR_MIN_KEY_LEN 12
|
||||
#define A38_XOR_MAX_KEY_LEN 16
|
||||
#define A38_COMP128_KEY_LEN 16
|
||||
#define MILENAGE_KEY_LEN 16
|
||||
|
||||
int hlr_vty_is_config_node(struct vty *vty, int node);
|
||||
int hlr_vty_go_parent(struct vty *vty);
|
||||
void hlr_vty_init(void);
|
||||
|
|
149
src/ctrl.c
149
src/ctrl.c
|
@ -31,6 +31,7 @@
|
|||
#include <osmocom/hlr/hlr.h>
|
||||
#include <osmocom/hlr/ctrl.h>
|
||||
#include <osmocom/hlr/db.h>
|
||||
#include <osmocom/hlr/hlr_vty.h>
|
||||
|
||||
#define SEL_BY "by-"
|
||||
#define SEL_BY_IMSI SEL_BY "imsi-"
|
||||
|
@ -576,6 +577,153 @@ static int set_subscr_aud2g(struct ctrl_cmd *cmd, void *data)
|
|||
return CTRL_CMD_REPLY;
|
||||
}
|
||||
|
||||
/* value format: <algo[,KI,(op|opc),OP_C[,ind_bitlen]]> */
|
||||
CTRL_CMD_DEFINE(subscr_aud3g, "aud3g");
|
||||
static int verify_subscr_aud3g(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_aud3g(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_unused;
|
||||
struct osmo_sub_auth_data aud3g;
|
||||
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_unused, &aud3g, NULL);
|
||||
switch (rc) {
|
||||
case 0:
|
||||
break;
|
||||
case -ENOENT:
|
||||
case -ENOKEY:
|
||||
aud3g.algo = OSMO_AUTH_ALG_NONE;
|
||||
break;
|
||||
default:
|
||||
cmd->reply = "Error retrieving data from database.";
|
||||
return CTRL_CMD_ERROR;
|
||||
}
|
||||
|
||||
if (aud3g.algo == OSMO_AUTH_ALG_NONE) {
|
||||
cmd->reply = "none";
|
||||
return CTRL_CMD_REPLY;
|
||||
}
|
||||
|
||||
cmd->reply = talloc_asprintf(cmd, "%s,%s,%s,%s,%u", osmo_auth_alg_name(aud3g.algo),
|
||||
osmo_hexdump_nospc_c(cmd, aud3g.u.umts.k, sizeof(aud3g.u.umts.k)),
|
||||
aud3g.u.umts.opc_is_op ? "OP" : "OPC",
|
||||
osmo_hexdump_nospc_c(cmd, aud3g.u.umts.opc, sizeof(aud3g.u.umts.opc)),
|
||||
aud3g.u.umts.ind_bitlen);
|
||||
return CTRL_CMD_REPLY;
|
||||
}
|
||||
static int set_subscr_aud3g(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 aud3g = {
|
||||
.type = OSMO_AUTH_TYPE_UMTS,
|
||||
.u.umts = {
|
||||
.ind_bitlen = 5,
|
||||
},
|
||||
};
|
||||
bool ind_bitlen_present;
|
||||
|
||||
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) {
|
||||
aud3g.algo = OSMO_AUTH_ALG_NONE;
|
||||
} else if (!auth_algo_parse(tok, &aud3g.algo, &minlen, &maxlen)) {
|
||||
cmd->reply = "Unknown auth algorithm.";
|
||||
return CTRL_CMD_ERROR;
|
||||
}
|
||||
|
||||
if (aud3g.algo != OSMO_AUTH_ALG_NONE) {
|
||||
/* Parse K */
|
||||
tok = strtok_r(NULL, ",", &saveptr);
|
||||
if (!tok) {
|
||||
cmd->reply = "Invalid format.";
|
||||
return CTRL_CMD_ERROR;
|
||||
}
|
||||
aud3g.u.umts.k = tok;
|
||||
if (!osmo_is_hexstr(aud3g.u.umts.k, minlen * 2, maxlen * 2, true)) {
|
||||
cmd->reply = "Invalid KI.";
|
||||
return CTRL_CMD_ERROR;
|
||||
}
|
||||
|
||||
/* Parse OP/OPC choice */
|
||||
tok = strtok_r(NULL, ",", &saveptr);
|
||||
if (!tok) {
|
||||
cmd->reply = "Invalid format.";
|
||||
return CTRL_CMD_ERROR;
|
||||
}
|
||||
if (strcasecmp(tok, "op") == 0) {
|
||||
aud3g.u.umts.opc_is_op = true;
|
||||
} else if (strcasecmp(tok, "opc") == 0) {
|
||||
aud3g.u.umts.opc_is_op = false;
|
||||
} else {
|
||||
cmd->reply = "Invalid format.";
|
||||
return CTRL_CMD_ERROR;
|
||||
}
|
||||
|
||||
/* Parse OP/OPC value */
|
||||
ind_bitlen_present = !!strchr(saveptr, ',');
|
||||
tok = strtok_r(NULL, ind_bitlen_present ? "," : "\0", &saveptr);
|
||||
if (!tok) {
|
||||
cmd->reply = "Invalid format.";
|
||||
return CTRL_CMD_ERROR;
|
||||
}
|
||||
|
||||
aud3g.u.umts.opc = tok;
|
||||
if (!osmo_is_hexstr(aud3g.u.umts.opc, MILENAGE_KEY_LEN * 2, MILENAGE_KEY_LEN * 2, true)) {
|
||||
cmd->reply = talloc_asprintf(cmd, "Invalid OP/OPC.");
|
||||
return CTRL_CMD_ERROR;
|
||||
}
|
||||
|
||||
if (ind_bitlen_present) {
|
||||
/* Parse bitlen_ind */
|
||||
tok = strtok_r(NULL, "\0", &saveptr);
|
||||
if (!tok || tok[0] == '\0') {
|
||||
cmd->reply = "Invalid format.";
|
||||
return CTRL_CMD_ERROR;
|
||||
}
|
||||
aud3g.u.umts.ind_bitlen = atoi(tok);
|
||||
}
|
||||
}
|
||||
|
||||
if (db_subscr_update_aud_by_id(g_hlr->dbc, subscr.id, &aud3g)) {
|
||||
cmd->reply = "Update aud3g 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)
|
||||
{
|
||||
|
@ -615,6 +763,7 @@ static int hlr_ctrl_cmds_install()
|
|||
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);
|
||||
rc |= ctrl_cmd_install(CTRL_NODE_SUBSCR_BY, &cmd_subscr_aud3g);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
#include <osmocom/hlr/hlr.h>
|
||||
#include <osmocom/hlr/db.h>
|
||||
#include <osmocom/hlr/timestamp.h>
|
||||
#include <osmocom/hlr/hlr_vty.h>
|
||||
|
||||
struct vty;
|
||||
|
||||
|
@ -470,12 +471,6 @@ static bool is_hexkey_valid(struct vty *vty, const char *label,
|
|||
#define AUTH_ALG_TYPES_3G_HELP \
|
||||
"Use Milenage algorithm\n"
|
||||
|
||||
#define A38_XOR_MIN_KEY_LEN 12
|
||||
#define A38_XOR_MAX_KEY_LEN 16
|
||||
#define A38_COMP128_KEY_LEN 16
|
||||
|
||||
#define MILENAGE_KEY_LEN 16
|
||||
|
||||
bool auth_algo_parse(const char *alg_str, enum osmo_auth_algo *algo,
|
||||
int *minlen, int *maxlen)
|
||||
{
|
||||
|
|
|
@ -686,5 +686,26 @@ 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
|
||||
GET 117 subscriber.by-imsi-901991234567891.aud3g
|
||||
GET_REPLY 117 subscriber.by-imsi-901991234567891.aud3g none
|
||||
|
||||
SET 118 subscriber.by-imsi-901991234567891.aud3g milenage,c01ffedc1cadaeac1d1f1edacac1ab0a,OP,FB2A3D1B360F599ABAB99DB8669F8308
|
||||
SET_REPLY 118 subscriber.by-imsi-901991234567891.aud3g OK
|
||||
|
||||
GET 119 subscriber.by-imsi-901991234567891.aud3g
|
||||
GET_REPLY 119 subscriber.by-imsi-901991234567891.aud3g MILENAGE,c01ffedc1cadaeac1d1f1edacac1ab0a,OP,fb2a3d1b360f599abab99db8669f8308,5
|
||||
|
||||
SET 120 subscriber.by-imsi-901991234567891.aud3g milenage,c01ffedc1cadaeac1d1f1edacac1ab0a,OPC,FB2A3D1B360F599ABAB99DB8669F8308,7
|
||||
SET_REPLY 120 subscriber.by-imsi-901991234567891.aud3g OK
|
||||
|
||||
GET 121 subscriber.by-imsi-901991234567891.aud3g
|
||||
GET_REPLY 121 subscriber.by-imsi-901991234567891.aud3g MILENAGE,c01ffedc1cadaeac1d1f1edacac1ab0a,OPC,fb2a3d1b360f599abab99db8669f8308,7
|
||||
|
||||
SET 122 subscriber.by-imsi-901991234567891.aud3g none
|
||||
SET_REPLY 122 subscriber.by-imsi-901991234567891.aud3g OK
|
||||
|
||||
GET 123 subscriber.by-imsi-901991234567891.aud3g
|
||||
GET_REPLY 123 subscriber.by-imsi-901991234567891.aud3g none
|
||||
|
||||
SET 124 subscriber.delete 901991234567891
|
||||
SET_REPLY 124 subscriber.delete 124
|
||||
|
|
|
@ -132,3 +132,24 @@ ERROR 55 Unknown auth algorithm.
|
|||
|
||||
SET 56 subscriber.by-imsi-901990000000003.aud2g xor,2134
|
||||
ERROR 56 Invalid KI.
|
||||
|
||||
SET 57 subscriber.by-imsi-901990000000003.aud3g foobar
|
||||
ERROR 57 Value failed verification.
|
||||
|
||||
SET 58 subscriber.by-imsi-901990000000003.aud3g foobar,2134
|
||||
ERROR 58 Unknown auth algorithm.
|
||||
|
||||
SET 60 subscriber.by-imsi-901990000000003.aud3g milenage,2134
|
||||
ERROR 60 Invalid KI.
|
||||
|
||||
SET 61 subscriber.by-imsi-901990000000003.aud3g milenage,c01ffedc1cadaeac1d1f1edacac1ab0a,AAA
|
||||
ERROR 61 Invalid format.
|
||||
|
||||
SET 62 subscriber.by-imsi-901990000000003.aud3g milenage,c01ffedc1cadaeac1d1f1edacac1ab0a,OPC
|
||||
ERROR 62 Invalid format.
|
||||
|
||||
SET 63 subscriber.by-imsi-901990000000003.aud3g milenage,c01ffedc1cadaeac1d1f1edacac1ab0a,OPC,zzz
|
||||
ERROR 63 Invalid OP/OPC.
|
||||
|
||||
SET 64 subscriber.by-imsi-901990000000003.aud3g milenage,c01ffedc1cadaeac1d1f1edacac1ab0a,OPC,fb2a3d1b360f599abab99db8669f8308,
|
||||
ERROR 64 Invalid format.
|
||||
|
|
Loading…
Reference in New Issue