MINOR: anon: store the anonymizing key in the CLI's appctx
In order to allow users to dump internal states using a specific key
without changing the global one, we're introducing a key in the CLI's
appctx. This key is preloaded from the global one when "set anon on"
is used (and if none exists, a random one is assigned). And the key
can optionally be assigned manually for the whole CLI session.
A "show anon" command was also added to show the anon state, and the
current key if the users has sufficient permissions. In addition, a
"debug dev hash" command was added to test the feature.
diff --git a/src/cli.c b/src/cli.c
index aaf0677..d238a23 100644
--- a/src/cli.c
+++ b/src/cli.c
@@ -1874,6 +1874,50 @@
return 0;
}
+/* enable or disable the anonymized mode, it returns 1 when it works or displays an error message if it doesn't. */
+static int cli_parse_set_anon(char **args, char *payload, struct appctx *appctx, void *private)
+{
+ uint32_t tmp;
+ long long key;
+
+ if (strcmp(args[2], "on") == 0) {
+ if (appctx->cli_anon_key != 0)
+ return cli_err(appctx, "Mode already enabled\n");
+ else {
+ if (*args[3]) {
+ key = atoll(args[3]);
+ if (key < 1 || key > UINT_MAX)
+ return cli_err(appctx, "Value out of range (1 to 4294967295 expected).\n");
+ appctx->cli_anon_key = key;
+ }
+ else {
+ tmp = HA_ATOMIC_LOAD(&global.anon_key);
+ if (tmp != 0)
+ appctx->cli_anon_key = tmp;
+ else
+ appctx->cli_anon_key = ha_random32();
+ }
+ }
+ }
+ else if (strcmp(args[2], "off") == 0) {
+ if (appctx->cli_anon_key == 0)
+ return cli_err(appctx, "Mode already disabled\n");
+ else if (*args[3]) {
+ return cli_err(appctx, "Key can't be added while disabling anonymized mode\n");
+ }
+ else {
+ appctx->cli_anon_key = 0;
+ }
+ }
+ else {
+ return cli_err(appctx,
+ "'set anon' only supports :\n"
+ " - 'on' [key] to enable the anonymized mode\n"
+ " - 'off' to disable the anonymized mode");
+ }
+ return 1;
+}
+
/* This function set the global anonyzing key, restricted to level 'admin' */
static int cli_parse_set_global_key(char **args, char *payload, struct appctx *appctx, void *private)
{
@@ -1892,6 +1936,28 @@
return 1;
}
+/* shows the anonymized mode state to everyone, and the key except for users, it always returns 1. */
+static int cli_parse_show_anon(char **args, char *payload, struct appctx *appctx, void *private)
+{
+ char *msg = NULL;
+ char *anon_mode = NULL;
+ uint32_t c_key = appctx->cli_anon_key;
+
+ if (!c_key)
+ anon_mode = "Anonymized mode disabled";
+ else
+ anon_mode = "Anonymized mode enabled";
+
+ if ( !((appctx->cli_level & ACCESS_LVL_MASK) < ACCESS_LVL_OPER) && c_key != 0) {
+ cli_dynmsg(appctx, LOG_INFO, memprintf(&msg, "%s\nKey : %u\n", anon_mode, c_key));
+ }
+ else {
+ cli_dynmsg(appctx, LOG_INFO, memprintf(&msg, "%s\n", anon_mode));
+ }
+
+ return 1;
+}
+
/* parse a "set rate-limit" command. It always returns 1. */
static int cli_parse_set_ratelimit(char **args, char *payload, struct appctx *appctx, void *private)
{
@@ -3200,11 +3266,13 @@
{ { "expert-mode", NULL }, NULL, cli_parse_expert_experimental_mode, NULL, NULL, NULL, ACCESS_MASTER }, // not listed
{ { "experimental-mode", NULL }, NULL, cli_parse_expert_experimental_mode, NULL, NULL, NULL, ACCESS_MASTER }, // not listed
{ { "mcli-debug-mode", NULL }, NULL, cli_parse_expert_experimental_mode, NULL, NULL, NULL, ACCESS_MASTER_ONLY }, // not listed
+ { { "set", "anon", NULL }, "set anon <setting> [value] : change the anonymized mode setting", cli_parse_set_anon, NULL, NULL },
{ { "set", "global-key", NULL }, "set global-key <value> : change the global anonymizing key", cli_parse_set_global_key, NULL, NULL },
{ { "set", "maxconn", "global", NULL }, "set maxconn global <value> : change the per-process maxconn setting", cli_parse_set_maxconn_global, NULL },
{ { "set", "rate-limit", NULL }, "set rate-limit <setting> <value> : change a rate limiting value", cli_parse_set_ratelimit, NULL },
{ { "set", "severity-output", NULL }, "set severity-output [none|number|string]: set presence of severity level in feedback information", cli_parse_set_severity_output, NULL, NULL },
{ { "set", "timeout", NULL }, "set timeout [cli] <delay> : change a timeout setting", cli_parse_set_timeout, NULL, NULL },
+ { { "show", "anon", NULL }, "show anon : display the current state of anonymized mode", cli_parse_show_anon, NULL },
{ { "show", "env", NULL }, "show env [var] : dump environment variables known to the process", cli_parse_show_env, cli_io_handler_show_env, NULL },
{ { "show", "cli", "sockets", NULL }, "show cli sockets : dump list of cli sockets", cli_parse_default, cli_io_handler_show_cli_sock, NULL, NULL, ACCESS_MASTER },
{ { "show", "cli", "level", NULL }, "show cli level : display the level of the current CLI session", cli_parse_show_lvl, NULL, NULL, NULL, ACCESS_MASTER},