diff options
author | Neels Hofmeyr <neels@hofmeyr.de> | 2017-10-06 02:59:54 +0200 |
---|---|---|
committer | Neels Hofmeyr <neels@hofmeyr.de> | 2017-10-17 00:59:00 +0200 |
commit | 183e7009afc8577f0d89c99f92a5720697040494 (patch) | |
tree | 3c774fa05e32f09d3805845751b48d9554177153 | |
parent | b6837e36a34a1e9e7fafea822516e61285e3c09c (diff) |
implement subscriber vty interface, tests
Implement VTY commands for subscriber manipulation:
- create / delete subscriber
- modify MSISDN
- add/edit/remove 2G and 3G authentication data
- show by IMSI, MSISDN or DB ID.
(enable/disable CS/PS and purge/unpurge to follow later.)
Implement VTY unit tests for the new commands using new
osmo_verify_transcript_vty.py from osmo-python-tests.
Depends: libosmocore I1e94f5b0717b947d2a7a7d36bacdf04a75cb3522
osmo-python-tests Id47331009910e651372b9c9c76e12f2e8964cc2c
Change-Id: I42b3b70a0439a8f2e4964d7cc31e593c1f0d7537
-rw-r--r-- | src/Makefile.am | 2 | ||||
-rw-r--r-- | src/hlr_vty.c | 3 | ||||
-rw-r--r-- | src/hlr_vty_subscr.c | 484 | ||||
-rw-r--r-- | src/hlr_vty_subscr.h | 3 | ||||
-rw-r--r-- | tests/Makefile.am | 21 | ||||
-rw-r--r-- | tests/test_subscriber.vty | 348 |
6 files changed, 859 insertions, 2 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index b410ff3..fc7c653 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -23,6 +23,7 @@ noinst_HEADERS = \ rand.h \ ctrl.h \ hlr_vty.h \ + hlr_vty_subscr.h \ $(NULL) bin_PROGRAMS = \ @@ -46,6 +47,7 @@ osmo_hlr_SOURCES = \ logging.c \ rand_urandom.c \ hlr_vty.c \ + hlr_vty_subscr.c \ $(NULL) osmo_hlr_LDADD = \ diff --git a/src/hlr_vty.c b/src/hlr_vty.c index 946117e..a5eb26f 100644 --- a/src/hlr_vty.c +++ b/src/hlr_vty.c @@ -26,6 +26,7 @@ #include <osmocom/vty/logging.h> #include "hlr_vty.h" +#include "hlr_vty_subscr.h" static struct hlr *g_hlr = NULL; @@ -135,4 +136,6 @@ void hlr_vty_init(struct hlr *hlr, const struct log_info *cat) install_default(GSUP_NODE); install_element(GSUP_NODE, &cfg_hlr_gsup_bind_ip_cmd); + + hlr_vty_subscriber_init(hlr); } diff --git a/src/hlr_vty_subscr.c b/src/hlr_vty_subscr.c new file mode 100644 index 0000000..5704922 --- /dev/null +++ b/src/hlr_vty_subscr.c @@ -0,0 +1,484 @@ +/* OsmoHLR subscriber management VTY implementation */ +/* (C) 2017 by sysmocom s.f.m.c. GmbH <info@sysmocom.de> + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <stdlib.h> +#include <inttypes.h> +#include <string.h> +#include <errno.h> + +#include <osmocom/gsm/gsm23003.h> +#include <osmocom/vty/vty.h> +#include <osmocom/vty/command.h> +#include <osmocom/core/utils.h> + +#include "hlr.h" +#include "db.h" + +struct vty; + +#define hexdump_buf(buf) osmo_hexdump_nospc((void*)buf, sizeof(buf)) + +static struct hlr *g_hlr = NULL; + +static void subscr_dump_full_vty(struct vty *vty, struct hlr_subscriber *subscr) +{ + int rc; + struct osmo_sub_auth_data aud2g; + struct osmo_sub_auth_data aud3g; + + vty_out(vty, " ID: %"PRIu64"%s", subscr->id, VTY_NEWLINE); + + vty_out(vty, " IMSI: %s%s", subscr->imsi ? subscr->imsi : "none", VTY_NEWLINE); + vty_out(vty, " MSISDN: %s%s", *subscr->msisdn ? subscr->msisdn : "none", VTY_NEWLINE); + if (*subscr->vlr_number) + vty_out(vty, " VLR number: %s%s", subscr->vlr_number, VTY_NEWLINE); + if (*subscr->sgsn_number) + vty_out(vty, " SGSN number: %s%s", subscr->sgsn_number, VTY_NEWLINE); + if (*subscr->sgsn_address) + vty_out(vty, " SGSN address: %s%s", subscr->sgsn_address, VTY_NEWLINE); + if (subscr->periodic_lu_timer) + vty_out(vty, " Periodic LU timer: %u%s", subscr->periodic_lu_timer, VTY_NEWLINE); + if (subscr->periodic_rau_tau_timer) + vty_out(vty, " Periodic RAU/TAU timer: %u%s", subscr->periodic_rau_tau_timer, VTY_NEWLINE); + if (subscr->lmsi) + vty_out(vty, " LMSI: %x%s", subscr->lmsi, VTY_NEWLINE); + if (!subscr->nam_cs) + vty_out(vty, " CS disabled%s", VTY_NEWLINE); + if (subscr->ms_purged_cs) + vty_out(vty, " CS purged%s", VTY_NEWLINE); + if (!subscr->nam_ps) + vty_out(vty, " PS disabled%s", VTY_NEWLINE); + if (subscr->ms_purged_ps) + vty_out(vty, " PS purged%s", VTY_NEWLINE); + + if (!*subscr->imsi) + return; + + OSMO_ASSERT(g_hlr); + rc = db_get_auth_data(g_hlr->dbc, subscr->imsi, &aud2g, &aud3g, NULL); + + if (rc) { + if (rc == -ENOENT) { + aud2g.algo = OSMO_AUTH_ALG_NONE; + aud3g.algo = OSMO_AUTH_ALG_NONE; + } else { + vty_out(vty, "%% Error retrieving data from database (%d)%s", rc, VTY_NEWLINE); + return; + } + } + + if (aud2g.type != OSMO_AUTH_TYPE_NONE && aud2g.type != OSMO_AUTH_TYPE_GSM) { + vty_out(vty, "%% Error: 2G auth data is not of type 'GSM'%s", VTY_NEWLINE); + aud2g = (struct osmo_sub_auth_data){}; + } + + if (aud3g.type != OSMO_AUTH_TYPE_NONE && aud3g.type != OSMO_AUTH_TYPE_UMTS) { + vty_out(vty, "%% Error: 3G auth data is not of type 'UMTS'%s", VTY_NEWLINE); + aud3g = (struct osmo_sub_auth_data){}; + } + + if (aud2g.algo != OSMO_AUTH_ALG_NONE && aud2g.type != OSMO_AUTH_TYPE_NONE) { + vty_out(vty, " 2G auth: %s%s", + osmo_auth_alg_name(aud2g.algo), VTY_NEWLINE); + vty_out(vty, " KI=%s%s", + hexdump_buf(aud2g.u.gsm.ki), VTY_NEWLINE); + } + + if (aud3g.algo != OSMO_AUTH_ALG_NONE && aud3g.type != OSMO_AUTH_TYPE_NONE) { + vty_out(vty, " 3G auth: %s%s", osmo_auth_alg_name(aud3g.algo), VTY_NEWLINE); + vty_out(vty, " K=%s%s", hexdump_buf(aud3g.u.umts.k), VTY_NEWLINE); + vty_out(vty, " %s=%s%s", aud3g.u.umts.opc_is_op? "OP" : "OPC", + hexdump_buf(aud3g.u.umts.opc), VTY_NEWLINE); + vty_out(vty, " IND-bitlen=%u", aud3g.u.umts.ind_bitlen); + if (aud3g.u.umts.sqn) + vty_out(vty, " last-SQN=%"PRIu64, aud3g.u.umts.sqn); + vty_out(vty, VTY_NEWLINE); + } +} + +static int get_subscr_by_argv(struct vty *vty, const char *type, const char *id, struct hlr_subscriber *subscr) +{ + int rc = -1; + if (strcmp(type, "imsi") == 0) + rc = db_subscr_get_by_imsi(g_hlr->dbc, id, subscr); + else if (strcmp(type, "msisdn") == 0) + rc = db_subscr_get_by_msisdn(g_hlr->dbc, id, subscr); + else if (strcmp(type, "id") == 0) + rc = db_subscr_get_by_id(g_hlr->dbc, atoll(id), subscr); + if (rc) + vty_out(vty, "%% No subscriber for %s = '%s'%s", + type, id, VTY_NEWLINE); + return rc; +} + +#define SUBSCR_CMD "subscriber " +#define SUBSCR_CMD_HELP "Subscriber management commands\n" + +#define SUBSCR_ID "(imsi|msisdn|id) IDENT " +#define SUBSCR_ID_HELP \ + "Identify subscriber by IMSI\n" \ + "Identify subscriber by MSISDN (phone number)\n" \ + "Identify subscriber by database ID\n" \ + "IMSI/MSISDN/ID of the subscriber\n" + +#define SUBSCR SUBSCR_CMD SUBSCR_ID +#define SUBSCR_HELP SUBSCR_CMD_HELP SUBSCR_ID_HELP + +#define SUBSCR_UPDATE SUBSCR "update " +#define SUBSCR_UPDATE_HELP SUBSCR_HELP "Set or update subscriber data\n" + +DEFUN(subscriber_show, + subscriber_show_cmd, + SUBSCR "show", + SUBSCR_HELP "Show subscriber information\n") +{ + struct hlr_subscriber subscr; + const char *id_type = argv[0]; + const char *id = argv[1]; + + if (get_subscr_by_argv(vty, id_type, id, &subscr)) + return CMD_WARNING; + + subscr_dump_full_vty(vty, &subscr); + return CMD_SUCCESS; +} + +DEFUN(subscriber_create, + subscriber_create_cmd, + SUBSCR_CMD "imsi IDENT create", + SUBSCR_CMD_HELP + "Create subscriber by IMSI\n" + "IMSI/MSISDN/ID of the subscriber\n") +{ + int rc; + struct hlr_subscriber subscr; + const char *imsi = argv[0]; + + if (!osmo_imsi_str_valid(imsi)) { + vty_out(vty, "%% Not a valid IMSI: %s%s", imsi, VTY_NEWLINE); + return CMD_WARNING; + } + + rc = db_subscr_create(g_hlr->dbc, imsi); + + if (rc) { + if (rc == -EEXIST) + vty_out(vty, "%% Subscriber already exists for IMSI = %s%s", + imsi, VTY_NEWLINE); + else + vty_out(vty, "%% Error (rc=%d): cannot create subscriber for IMSI = %s%s", + rc, imsi, VTY_NEWLINE); + return CMD_WARNING; + } + + rc = db_subscr_get_by_imsi(g_hlr->dbc, imsi, &subscr); + vty_out(vty, "%% Created subscriber %s%s", imsi, VTY_NEWLINE); + + subscr_dump_full_vty(vty, &subscr); + + return CMD_SUCCESS; +} + +DEFUN(subscriber_delete, + subscriber_delete_cmd, + SUBSCR "delete", + SUBSCR_HELP "Delete subscriber from database\n") +{ + struct hlr_subscriber subscr; + int rc; + const char *id_type = argv[0]; + const char *id = argv[1]; + + /* Find out the IMSI regardless of which way the caller decided to + * identify the subscriber by. */ + if (get_subscr_by_argv(vty, id_type, id, &subscr)) + return CMD_WARNING; + + rc = db_subscr_delete_by_id(g_hlr->dbc, subscr.id); + if (rc) { + vty_out(vty, "%% Error: Failed to remove subscriber for IMSI '%s'%s", + subscr.imsi, VTY_NEWLINE); + return CMD_WARNING; + } + + vty_out(vty, "%% Deleted subscriber for IMSI '%s'%s", subscr.imsi, VTY_NEWLINE); + return CMD_SUCCESS; +} + +DEFUN(subscriber_msisdn, + subscriber_msisdn_cmd, + SUBSCR_UPDATE "msisdn MSISDN", + SUBSCR_UPDATE_HELP + "Set MSISDN (phone number) of the subscriber\n" + "New MSISDN (phone number)\n") +{ + struct hlr_subscriber subscr; + const char *id_type = argv[0]; + const char *id = argv[1]; + const char *msisdn = argv[2]; + + if (strlen(msisdn) > sizeof(subscr.msisdn) - 1) { + vty_out(vty, "%% MSISDN is too long, max. %zu characters are allowed%s", + sizeof(subscr.msisdn)-1, VTY_NEWLINE); + return CMD_WARNING; + } + + if (!osmo_msisdn_str_valid(msisdn)) { + vty_out(vty, "%% MSISDN invalid: '%s'%s", msisdn, VTY_NEWLINE); + return CMD_WARNING; + } + + if (get_subscr_by_argv(vty, id_type, id, &subscr)) + return CMD_WARNING; + + if (db_subscr_update_msisdn_by_imsi(g_hlr->dbc, subscr.imsi, msisdn)) { + vty_out(vty, "%% Error: cannot update MSISDN for subscriber IMSI='%s'%s", + subscr.imsi, VTY_NEWLINE); + return CMD_WARNING; + } + + vty_out(vty, "%% Updated subscriber IMSI='%s' to MSISDN='%s'%s", + subscr.imsi, msisdn, VTY_NEWLINE); + return CMD_SUCCESS; +} + +static bool is_hexkey_valid(struct vty *vty, const char *label, + const char *hex_str, int minlen, int maxlen) +{ + if (osmo_is_hexstr(hex_str, minlen * 2, maxlen * 2, true)) + return true; + vty_out(vty, "%% Invalid value for %s: '%s'%s", label, hex_str, VTY_NEWLINE); + return false; +} + +#define AUTH_ALG_TYPES_2G "(comp128v1|comp128v2|comp128v3|xor)" +#define AUTH_ALG_TYPES_2G_HELP \ + "Use COMP128v1 algorithm\n" \ + "Use COMP128v2 algorithm\n" \ + "Use COMP128v3 algorithm\n" \ + "Use XOR algorithm\n" + +#define AUTH_ALG_TYPES_3G "milenage" +#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 + +static 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; + *minlen = *maxlen = 0; + } else if (!strcasecmp(alg_str, "comp128v1")) { + *algo = OSMO_AUTH_ALG_COMP128v1; + *minlen = *maxlen = A38_COMP128_KEY_LEN; + } else if (!strcasecmp(alg_str, "comp128v2")) { + *algo = OSMO_AUTH_ALG_COMP128v2; + *minlen = *maxlen = A38_COMP128_KEY_LEN; + } else if (!strcasecmp(alg_str, "comp128v3")) { + *algo = OSMO_AUTH_ALG_COMP128v3; + *minlen = *maxlen = A38_COMP128_KEY_LEN; + } else if (!strcasecmp(alg_str, "xor")) { + *algo = OSMO_AUTH_ALG_XOR; + *minlen = A38_XOR_MIN_KEY_LEN; + *maxlen = A38_XOR_MAX_KEY_LEN; + } else if (!strcasecmp(alg_str, "milenage")) { + *algo = OSMO_AUTH_ALG_MILENAGE; + *minlen = *maxlen = MILENAGE_KEY_LEN; + } else + return false; + return true; +} + +DEFUN(subscriber_no_aud2g, + subscriber_no_aud2g_cmd, + SUBSCR_UPDATE "aud2g none", + SUBSCR_UPDATE_HELP + "Set 2G authentication data\n" + "Delete 2G authentication data\n") +{ + struct hlr_subscriber subscr; + int rc; + const char *id_type = argv[0]; + const char *id = argv[1]; + struct sub_auth_data_str aud = { + .type = OSMO_AUTH_TYPE_GSM, + .algo = OSMO_AUTH_ALG_NONE, + }; + + if (get_subscr_by_argv(vty, id_type, id, &subscr)) + return CMD_WARNING; + + rc = db_subscr_update_aud_by_id(g_hlr->dbc, subscr.id, &aud); + + if (rc) { + vty_out(vty, "%% Error: cannot disable 2G auth data for IMSI='%s'%s", + subscr.imsi, VTY_NEWLINE); + return CMD_WARNING; + } + return CMD_SUCCESS; +} + +DEFUN(subscriber_aud2g, + subscriber_aud2g_cmd, + SUBSCR_UPDATE "aud2g " AUTH_ALG_TYPES_2G " ki KI", + SUBSCR_UPDATE_HELP + "Set 2G authentication data\n" + AUTH_ALG_TYPES_2G_HELP + "Set Ki Encryption Key\n" "Ki as 32 hexadecimal characters\n") +{ + struct hlr_subscriber subscr; + int rc; + int minlen = 0; + int maxlen = 0; + const char *id_type = argv[0]; + const char *id = argv[1]; + const char *alg_type = argv[2]; + const char *ki = argv[3]; + struct sub_auth_data_str aud2g = { + .type = OSMO_AUTH_TYPE_GSM, + .u.gsm.ki = ki, + }; + + if (!auth_algo_parse(alg_type, &aud2g.algo, &minlen, &maxlen)) { + vty_out(vty, "%% Unknown auth algorithm: '%s'%s", alg_type, VTY_NEWLINE); + return CMD_WARNING; + } + + if (!is_hexkey_valid(vty, "KI", aud2g.u.gsm.ki, minlen, maxlen)) + return CMD_WARNING; + + if (get_subscr_by_argv(vty, id_type, id, &subscr)) + return CMD_WARNING; + + rc = db_subscr_update_aud_by_id(g_hlr->dbc, subscr.id, &aud2g); + + if (rc) { + vty_out(vty, "%% Error: cannot set 2G auth data for IMSI='%s'%s", + subscr.imsi, VTY_NEWLINE); + return CMD_WARNING; + } + return CMD_SUCCESS; +} + +DEFUN(subscriber_no_aud3g, + subscriber_no_aud3g_cmd, + SUBSCR_UPDATE "aud3g none", + SUBSCR_UPDATE_HELP + "Set UMTS authentication data (3G, and 2G with UMTS AKA)\n" + "Delete 3G authentication data\n") +{ + struct hlr_subscriber subscr; + int rc; + const char *id_type = argv[0]; + const char *id = argv[1]; + struct sub_auth_data_str aud = { + .type = OSMO_AUTH_TYPE_UMTS, + .algo = OSMO_AUTH_ALG_NONE, + }; + + if (get_subscr_by_argv(vty, id_type, id, &subscr)) + return CMD_WARNING; + + rc = db_subscr_update_aud_by_id(g_hlr->dbc, subscr.id, &aud); + + if (rc) { + vty_out(vty, "%% Error: cannot disable 3G auth data for IMSI='%s'%s", + subscr.imsi, VTY_NEWLINE); + return CMD_WARNING; + } + return CMD_SUCCESS; +} + +DEFUN(subscriber_aud3g, + subscriber_aud3g_cmd, + SUBSCR_UPDATE "aud3g " AUTH_ALG_TYPES_3G + " k K" + " (op|opc) OP_C" + " [ind-bitlen] [<0-28>]", + SUBSCR_UPDATE_HELP + "Set UMTS authentication data (3G, and 2G with UMTS AKA)\n" + AUTH_ALG_TYPES_3G_HELP + "Set Encryption Key K\n" "K as 32 hexadecimal characters\n" + "Set OP key\n" "Set OPC key\n" "OP or OPC as 32 hexadecimal characters\n" + "Set IND bit length\n" "IND bit length value (default: 5)\n") +{ + struct hlr_subscriber subscr; + int minlen = 0; + int maxlen = 0; + int rc; + const char *id_type = argv[0]; + const char *id = argv[1]; + const char *alg_type = AUTH_ALG_TYPES_3G; + const char *k = argv[2]; + bool opc_is_op = (strcasecmp("op", argv[3]) == 0); + const char *op_opc = argv[4]; + int ind_bitlen = argc > 6? atoi(argv[6]) : 5; + struct sub_auth_data_str aud3g = { + .type = OSMO_AUTH_TYPE_UMTS, + .u.umts = { + .k = k, + .opc_is_op = opc_is_op, + .opc = op_opc, + .ind_bitlen = ind_bitlen, + }, + }; + + if (!auth_algo_parse(alg_type, &aud3g.algo, &minlen, &maxlen)) { + vty_out(vty, "%% Unknown auth algorithm: '%s'%s", alg_type, VTY_NEWLINE); + return CMD_WARNING; + } + + if (!is_hexkey_valid(vty, "K", aud3g.u.umts.k, minlen, maxlen)) + return CMD_WARNING; + + if (!is_hexkey_valid(vty, opc_is_op ? "OP" : "OPC", aud3g.u.umts.opc, + MILENAGE_KEY_LEN, MILENAGE_KEY_LEN)) + return CMD_WARNING; + + if (get_subscr_by_argv(vty, id_type, id, &subscr)) + return CMD_WARNING; + + rc = db_subscr_update_aud_by_id(g_hlr->dbc, subscr.id, &aud3g); + + if (rc) { + vty_out(vty, "%% Error: cannot set 3G auth data for IMSI='%s'%s", + subscr.imsi, VTY_NEWLINE); + return CMD_WARNING; + } + return CMD_SUCCESS; +} + +void hlr_vty_subscriber_init(struct hlr *hlr) +{ + g_hlr = hlr; + + install_element_ve(&subscriber_show_cmd); + install_element(ENABLE_NODE, &subscriber_create_cmd); + install_element(ENABLE_NODE, &subscriber_delete_cmd); + install_element(ENABLE_NODE, &subscriber_msisdn_cmd); + install_element(ENABLE_NODE, &subscriber_no_aud2g_cmd); + install_element(ENABLE_NODE, &subscriber_aud2g_cmd); + install_element(ENABLE_NODE, &subscriber_no_aud3g_cmd); + install_element(ENABLE_NODE, &subscriber_aud3g_cmd); +} diff --git a/src/hlr_vty_subscr.h b/src/hlr_vty_subscr.h new file mode 100644 index 0000000..841db5a --- /dev/null +++ b/src/hlr_vty_subscr.h @@ -0,0 +1,3 @@ +#pragma once + +void hlr_vty_subscriber_init(struct hlr *hlr); diff --git a/tests/Makefile.am b/tests/Makefile.am index 0b625f5..8f1826d 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -26,6 +26,7 @@ EXTRA_DIST = \ testsuite.at \ $(srcdir)/package.m4 \ $(TESTSUITE) \ + test_subscriber.vty \ ctrl_test_runner.py \ $(NULL) @@ -36,10 +37,26 @@ DISTCLEANFILES = \ $(NULL) if ENABLE_EXT_TESTS -python-tests: $(BUILT_SOURCES) +python-tests: +# don't run vty and ctrl tests concurrently so that the ports don't conflict + $(MAKE) vty-test $(PYTHON) $(srcdir)/ctrl_test_runner.py -w $(abs_top_builddir) -v + +VTY_TEST_DB = hlr_vty_test.db + +# To update the VTY script from current application behavior, +# pass -u to vty_script_runner.py by doing: +# make vty-test U=-u +vty-test: + -rm -f $(VTY_TEST_DB) + sqlite3 $(VTY_TEST_DB) < $(top_srcdir)/sql/hlr.sql + osmo_verify_transcript_vty.py -v \ + -n OsmoHLR -p 4258 \ + -r "$(top_builddir)/src/osmo-hlr -c $(top_srcdir)/doc/examples/osmo-hlr.cfg -l hlr_vty_test.db" \ + $(U) $(srcdir)/*.vty + -rm -f $(VTY_TEST_DB) else -python-tests: $(BUILT_SOURCES) +python-tests: echo "Not running python-based tests (determined at configure-time)" endif diff --git a/tests/test_subscriber.vty b/tests/test_subscriber.vty new file mode 100644 index 0000000..2e0bdce --- /dev/null +++ b/tests/test_subscriber.vty @@ -0,0 +1,348 @@ +OsmoHLR> enable + +OsmoHLR# list +... + subscriber (imsi|msisdn|id) IDENT show + subscriber imsi IDENT create + subscriber (imsi|msisdn|id) IDENT delete + subscriber (imsi|msisdn|id) IDENT update msisdn MSISDN + subscriber (imsi|msisdn|id) IDENT update aud2g none + subscriber (imsi|msisdn|id) IDENT update aud2g (comp128v1|comp128v2|comp128v3|xor) ki KI + subscriber (imsi|msisdn|id) IDENT update aud3g none + subscriber (imsi|msisdn|id) IDENT update aud3g milenage k K (op|opc) OP_C [ind-bitlen] [<0-28>] + +OsmoHLR# subscriber? + subscriber Subscriber management commands + +OsmoHLR# subscriber ? + imsi Identify subscriber by IMSI + msisdn Identify subscriber by MSISDN (phone number) + id Identify subscriber by database ID + +OsmoHLR# subscriber imsi ? + IDENT IMSI/MSISDN/ID of the subscriber +OsmoHLR# subscriber msisdn ? + IDENT IMSI/MSISDN/ID of the subscriber +OsmoHLR# subscriber id ? + IDENT IMSI/MSISDN/ID of the subscriber + +OsmoHLR# subscriber imsi 123456789023000 show +% No subscriber for imsi = '123456789023000' +OsmoHLR# subscriber id 1 show +% No subscriber for id = '1' +OsmoHLR# subscriber msisdn 12345 show +% No subscriber for msisdn = '12345' + +OsmoHLR# subscriber imsi 1234567890230001 create +% Not a valid IMSI: 1234567890230001 +OsmoHLR# subscriber imsi 12345678902300x create +% Not a valid IMSI: 12345678902300x +OsmoHLR# subscriber imsi 12345 create +% Not a valid IMSI: 12345 + +OsmoHLR# subscriber imsi 123456789023000 create +% Created subscriber 123456789023000 + ID: 1 + IMSI: 123456789023000 + MSISDN: none + +OsmoHLR# subscriber imsi 123456789023000 show + ID: 1 + IMSI: 123456789023000 + MSISDN: none +OsmoHLR# subscriber id 1 show + ID: 1 + IMSI: 123456789023000 + MSISDN: none +OsmoHLR# subscriber msisdn 12345 show +% No subscriber for msisdn = '12345' + +OsmoHLR# subscriber imsi 123456789023000 update msisdn 12345 +% Updated subscriber IMSI='123456789023000' to MSISDN='12345' + +OsmoHLR# subscriber imsi 123456789023000 show + ID: 1 + IMSI: 123456789023000 + MSISDN: 12345 +OsmoHLR# subscriber id 1 show + ID: 1 + IMSI: 123456789023000 + MSISDN: 12345 +OsmoHLR# subscriber msisdn 12345 show + ID: 1 + IMSI: 123456789023000 + MSISDN: 12345 + +OsmoHLR# subscriber msisdn 12345 update msisdn 423 +% Updated subscriber IMSI='123456789023000' to MSISDN='423' +OsmoHLR# subscriber msisdn 12345 show +% No subscriber for msisdn = '12345' + +OsmoHLR# subscriber imsi 123456789023000 show + ID: 1 + IMSI: 123456789023000 + MSISDN: 423 +OsmoHLR# subscriber id 1 show + ID: 1 + IMSI: 123456789023000 + MSISDN: 423 +OsmoHLR# subscriber msisdn 423 show + ID: 1 + IMSI: 123456789023000 + MSISDN: 423 + +OsmoHLR# subscriber imsi 123456789023000 update ? + msisdn Set MSISDN (phone number) of the subscriber + aud2g Set 2G authentication data + aud3g Set UMTS authentication data (3G, and 2G with UMTS AKA) + +OsmoHLR# subscriber imsi 123456789023000 update aud2g ? + none Delete 2G authentication data + comp128v1 Use COMP128v1 algorithm + comp128v2 Use COMP128v2 algorithm + comp128v3 Use COMP128v3 algorithm + xor Use XOR algorithm + +OsmoHLR# subscriber imsi 123456789023000 update aud2g comp128v1 ? + ki Set Ki Encryption Key + +OsmoHLR# subscriber imsi 123456789023000 update aud2g comp128v1 ki ? + KI Ki as 32 hexadecimal characters + +OsmoHLR# subscriber imsi 123456789023000 update aud2g comp128v1 ki val ? + <cr> + +OsmoHLR# subscriber imsi 123456789023000 update aud2g xor ki Deaf0ff1ceD0d0DabbedD1ced1ceF00d +OsmoHLR# subscriber imsi 123456789023000 show + ID: 1 + IMSI: 123456789023000 + MSISDN: 423 + 2G auth: XOR + KI=deaf0ff1ced0d0dabbedd1ced1cef00d + +OsmoHLR# subscriber imsi 123456789023000 update aud2g comp128v1 ki BeefedCafeFaceAcedAddedDecadeFee +OsmoHLR# subscriber imsi 123456789023000 show + ID: 1 + IMSI: 123456789023000 + MSISDN: 423 + 2G auth: COMP128v1 + KI=beefedcafefaceacedaddeddecadefee +OsmoHLR# subscriber id 1 show + ID: 1 + IMSI: 123456789023000 + MSISDN: 423 + 2G auth: COMP128v1 + KI=beefedcafefaceacedaddeddecadefee +OsmoHLR# subscriber msisdn 423 show + ID: 1 + IMSI: 123456789023000 + MSISDN: 423 + 2G auth: COMP128v1 + KI=beefedcafefaceacedaddeddecadefee + +OsmoHLR# subscriber id 1 update aud2g comp128v2 ki CededEffacedAceFacedBadFadedBeef +OsmoHLR# subscriber id 1 show + ID: 1 + IMSI: 123456789023000 + MSISDN: 423 + 2G auth: COMP128v2 + KI=cededeffacedacefacedbadfadedbeef +OsmoHLR# subscriber msisdn 423 show + ID: 1 + IMSI: 123456789023000 + MSISDN: 423 + 2G auth: COMP128v2 + KI=cededeffacedacefacedbadfadedbeef +OsmoHLR# subscriber imsi 123456789023000 show + ID: 1 + IMSI: 123456789023000 + MSISDN: 423 + 2G auth: COMP128v2 + KI=cededeffacedacefacedbadfadedbeef + +OsmoHLR# subscriber msisdn 423 update aud2g comp128v3 ki C01ffedC1cadaeAc1d1f1edAcac1aB0a +OsmoHLR# subscriber msisdn 423 show + ID: 1 + IMSI: 123456789023000 + MSISDN: 423 + 2G auth: COMP128v3 + KI=c01ffedc1cadaeac1d1f1edacac1ab0a +OsmoHLR# subscriber imsi 123456789023000 show + ID: 1 + IMSI: 123456789023000 + MSISDN: 423 + 2G auth: COMP128v3 + KI=c01ffedc1cadaeac1d1f1edacac1ab0a +OsmoHLR# subscriber id 1 show + ID: 1 + IMSI: 123456789023000 + MSISDN: 423 + 2G auth: COMP128v3 + KI=c01ffedc1cadaeac1d1f1edacac1ab0a + +OsmoHLR# subscriber id 1 update aud2g nonsense ki BeefedCafeFaceAcedAddedDecadeFee +% Unknown command. +OsmoHLR# subscriber id 1 show + ID: 1 + IMSI: 123456789023000 + MSISDN: 423 + 2G auth: COMP128v3 + KI=c01ffedc1cadaeac1d1f1edacac1ab0a + +OsmoHLR# subscriber id 1 update aud2g milenage ki BeefedCafeFaceAcedAddedDecadeFee +% Unknown command. +OsmoHLR# subscriber id 1 show + ID: 1 + IMSI: 123456789023000 + MSISDN: 423 + 2G auth: COMP128v3 + KI=c01ffedc1cadaeac1d1f1edacac1ab0a + +OsmoHLR# subscriber id 1 update aud2g xor ki CoiffedCicadaeAcidifiedAcaciaBoa +% Invalid value for KI: 'CoiffedCicadaeAcidifiedAcaciaBoa' +OsmoHLR# subscriber id 1 show + ID: 1 + IMSI: 123456789023000 + MSISDN: 423 + 2G auth: COMP128v3 + KI=c01ffedc1cadaeac1d1f1edacac1ab0a + +OsmoHLR# subscriber id 1 update aud2g xor ki C01ffedC1cadaeAc1d1f1edAcac1aB0aX +% Invalid value for KI: 'C01ffedC1cadaeAc1d1f1edAcac1aB0aX' +OsmoHLR# subscriber id 1 show + ID: 1 + IMSI: 123456789023000 + MSISDN: 423 + 2G auth: COMP128v3 + KI=c01ffedc1cadaeac1d1f1edacac1ab0a + +OsmoHLR# subscriber id 1 update aud2g none +OsmoHLR# subscriber id 1 show + ID: 1 + IMSI: 123456789023000 + MSISDN: 423 + + +OsmoHLR# subscriber imsi 123456789023000 update aud3g ? + none Delete 3G authentication data + milenage Use Milenage algorithm + +OsmoHLR# subscriber imsi 123456789023000 update aud3g milenage ? + k Set Encryption Key K + +OsmoHLR# subscriber imsi 123456789023000 update aud3g milenage k ? + K K as 32 hexadecimal characters + +OsmoHLR# subscriber imsi 123456789023000 update aud3g milenage k Deaf0ff1ceD0d0DabbedD1ced1ceF00d ? + op Set OP key + opc Set OPC key + +OsmoHLR# subscriber imsi 123456789023000 update aud3g milenage k Deaf0ff1ceD0d0DabbedD1ced1ceF00d opc ? + OP_C OP or OPC as 32 hexadecimal characters + +OsmoHLR# subscriber imsi 123456789023000 update aud3g milenage k Deaf0ff1ceD0d0DabbedD1ced1ceF00d opc CededEffacedAceFacedBadFadedBeef ? + [ind-bitlen] Set IND bit length + +OsmoHLR# subscriber imsi 123456789023000 update aud3g milenage k Deaf0ff1ceD0d0DabbedD1ced1ceF00d opc CededEffacedAceFacedBadFadedBeef ind-bitlen ? + [<0-28>] IND bit length value (default: 5) + +OsmoHLR# subscriber imsi 123456789023000 update aud3g milenage k Deaf0ff1ceD0d0DabbedD1ced1ceF00d opc CededEffacedAceFacedBadFadedBeef +OsmoHLR# subscriber imsi 123456789023000 show + ID: 1 + IMSI: 123456789023000 + MSISDN: 423 + 3G auth: MILENAGE + K=deaf0ff1ced0d0dabbedd1ced1cef00d + OPC=cededeffacedacefacedbadfadedbeef + IND-bitlen=5 + + +OsmoHLR# subscriber imsi 123456789023000 update aud3g milenage k Deaf0ff1ceD0d0DabbedD1ced1ceF00d op DeafBeddedBabeAcceededFadedDecaf +OsmoHLR# subscriber imsi 123456789023000 show + ID: 1 + IMSI: 123456789023000 + MSISDN: 423 + 3G auth: MILENAGE + K=deaf0ff1ced0d0dabbedd1ced1cef00d + OP=deafbeddedbabeacceededfadeddecaf + IND-bitlen=5 + +OsmoHLR# subscriber imsi 123456789023000 update aud3g none +OsmoHLR# subscriber imsi 123456789023000 show + ID: 1 + IMSI: 123456789023000 + MSISDN: 423 + +OsmoHLR# subscriber imsi 123456789023000 update aud3g milenage k Deaf0ff1ceD0d0DabbedD1ced1ceF00d opc CededEffacedAceFacedBadFadedBeef ind-bitlen 23 +OsmoHLR# subscriber imsi 123456789023000 show + ID: 1 + IMSI: 123456789023000 + MSISDN: 423 + 3G auth: MILENAGE + K=deaf0ff1ced0d0dabbedd1ced1cef00d + OPC=cededeffacedacefacedbadfadedbeef + IND-bitlen=23 + +OsmoHLR# subscriber imsi 123456789023000 update aud3g milenage k CoiffedCicadaeAcidifiedAcaciaBoa opc CededEffacedAceFacedBadFadedBeef +% Invalid value for K: 'CoiffedCicadaeAcidifiedAcaciaBoa' +OsmoHLR# subscriber imsi 123456789023000 show + ID: 1 + IMSI: 123456789023000 + MSISDN: 423 + 3G auth: MILENAGE + K=deaf0ff1ced0d0dabbedd1ced1cef00d + OPC=cededeffacedacefacedbadfadedbeef + IND-bitlen=23 + +OsmoHLR# subscriber imsi 123456789023000 update aud3g milenage k Deaf0ff1ceD0d0DabbedD1ced1ceF00d opc CoiffedCicadaeAcidifiedAcaciaBoa +% Invalid value for OPC: 'CoiffedCicadaeAcidifiedAcaciaBoa' +OsmoHLR# subscriber imsi 123456789023000 show + ID: 1 + IMSI: 123456789023000 + MSISDN: 423 + 3G auth: MILENAGE + K=deaf0ff1ced0d0dabbedd1ced1cef00d + OPC=cededeffacedacefacedbadfadedbeef + IND-bitlen=23 + +OsmoHLR# subscriber imsi 123456789023000 update aud3g milenage k Deaf0ff1ceD0d0DabbedD1ced1ceF00d op CoiffedCicadaeAcidifiedAcaciaBoa +% Invalid value for OP: 'CoiffedCicadaeAcidifiedAcaciaBoa' +OsmoHLR# subscriber imsi 123456789023000 show + ID: 1 + IMSI: 123456789023000 + MSISDN: 423 + 3G auth: MILENAGE + K=deaf0ff1ced0d0dabbedd1ced1cef00d + OPC=cededeffacedacefacedbadfadedbeef + IND-bitlen=23 + +OsmoHLR# subscriber id 1 update aud2g comp128v2 ki CededEffacedAceFacedBadFadedBeef +OsmoHLR# subscriber id 1 show + ID: 1 + IMSI: 123456789023000 + MSISDN: 423 + 2G auth: COMP128v2 + KI=cededeffacedacefacedbadfadedbeef + 3G auth: MILENAGE + K=deaf0ff1ced0d0dabbedd1ced1cef00d + OPC=cededeffacedacefacedbadfadedbeef + IND-bitlen=23 + +OsmoHLR# subscriber imsi 123456789023000 delete +% Deleted subscriber for IMSI '123456789023000' + +OsmoHLR# subscriber imsi 123456789023000 show +% No subscriber for imsi = '123456789023000' +OsmoHLR# subscriber id 1 show +% No subscriber for id = '1' +OsmoHLR# subscriber msisdn 423 show +% No subscriber for msisdn = '423' + +OsmoHLR# subscriber imsi 123456789023000 create +% Created subscriber 123456789023000 + ID: 1 + IMSI: 123456789023000 + MSISDN: none + +OsmoHLR# subscriber imsi 123456789023000 delete +% Deleted subscriber for IMSI '123456789023000' |