mirror of
https://github.com/ElementsProject/lightning.git
synced 2025-01-18 21:35:11 +01:00
config: add the ability for plugins to specify that config values should be concealed.
And use it for `exposesecret-passphrase`. This is probably overly cautious, but it makes me feel a little better that we won't leak it to someone with read-only access. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
parent
101aeea52c
commit
8293352425
@ -62,6 +62,8 @@ struct configvar {
|
||||
#define OPT_DYNAMIC (1 << (OPT_USER_START+6))
|
||||
/* Keep whitespace at the end of the option argument */
|
||||
#define OPT_KEEP_WHITESPACE (1 << (OPT_USER_START+7))
|
||||
/* Don't show value in listconfigs */
|
||||
#define OPT_CONCEAL (1 << (OPT_USER_START+8))
|
||||
|
||||
/* Use this instead of opt_register_*_arg if you want OPT_* from above */
|
||||
#define clnopt_witharg(names, type, cb, show, arg, desc) \
|
||||
|
@ -124,10 +124,11 @@ Plugins are free to register any `name` for their `rpcmethod` as long as the nam
|
||||
|
||||
There are currently four supported option 'types':
|
||||
|
||||
- string: a string
|
||||
- bool: a boolean
|
||||
- int: parsed as a signed integer (64-bit)
|
||||
- flag: no-arg flag option. Presented as `true` if config specifies it.
|
||||
- `string`: a string
|
||||
- `string-conceal`: a string which will appear as "..." in `listconfigs`.
|
||||
- `bool`: a boolean
|
||||
- `int`: parsed as a signed integer (64-bit)
|
||||
- `flag`: no-arg flag option. Presented as `true` if config specifies it.
|
||||
|
||||
In addition, string and int types can specify `"multi": true` to indicate they can be specified multiple times. These will always be represented in `init` as a (possibly empty) JSON array. "multi" flag types do not make
|
||||
sense.
|
||||
|
@ -65,6 +65,9 @@ static const char *get_opt_val(const struct opt_table *ot,
|
||||
char buf[],
|
||||
const struct configvar *cv)
|
||||
{
|
||||
if (ot->type & OPT_CONCEAL)
|
||||
return "...";
|
||||
|
||||
if (ot->show == (void *)opt_show_charp) {
|
||||
/* Don't truncate or quote! */
|
||||
return *(char **)ot->u.carg;
|
||||
|
@ -2095,7 +2095,9 @@ void add_config_deprecated(struct lightningd *ld,
|
||||
if (!opt->show(buf, sizeof(buf) - sizeof("..."), opt->u.carg))
|
||||
buf[0] = '\0';
|
||||
|
||||
if ((opt->type & OPT_SHOWINT)
|
||||
if (opt->type & OPT_CONCEAL) {
|
||||
strcpy(buf, "...");
|
||||
} else if ((opt->type & OPT_SHOWINT)
|
||||
|| (opt->type & OPT_SHOWMSATS)) {
|
||||
if (streq(buf, "")
|
||||
|| strspn(buf, "-0123456789.") != strlen(buf))
|
||||
|
@ -1168,7 +1168,10 @@ static const char *plugin_opt_add(struct plugin *plugin, const char *buffer,
|
||||
/* These all take an arg. */
|
||||
char *(*cb_arg)(const char *optarg, void *arg);
|
||||
|
||||
if (json_tok_streq(buffer, typetok, "string")) {
|
||||
if (json_tok_streq(buffer, typetok, "string-conceal")) {
|
||||
optflags |= OPT_CONCEAL;
|
||||
cb_arg = (void *)plugin_opt_string_check;
|
||||
} else if (json_tok_streq(buffer, typetok, "string")) {
|
||||
cb_arg = (void *)plugin_opt_string_check;
|
||||
} else if (json_tok_streq(buffer, typetok, "int")) {
|
||||
cb_arg = (void *)plugin_opt_long_check;
|
||||
|
1
plugins/.gitignore
vendored
1
plugins/.gitignore
vendored
@ -18,3 +18,4 @@ cln-renepay
|
||||
recover
|
||||
cln-askrene
|
||||
recklessrpc
|
||||
exposesecret
|
||||
|
@ -156,7 +156,7 @@ int main(int argc, char *argv[])
|
||||
plugin_main(argv, init, take(exposesecret),
|
||||
PLUGIN_RESTARTABLE, true, NULL, commands, ARRAY_SIZE(commands),
|
||||
NULL, 0, NULL, 0, NULL, 0,
|
||||
plugin_option("exposesecret-passphrase", "string",
|
||||
plugin_option("exposesecret-passphrase", "string-conceal",
|
||||
"Enable exposesecret command to allow HSM Secret backup, with this passphrase",
|
||||
charp_option, NULL, &exposesecret->exposure_passphrase),
|
||||
NULL);
|
||||
|
@ -4453,6 +4453,10 @@ def test_listchannels_broken_message(node_factory):
|
||||
def test_exposesecret(node_factory):
|
||||
l1, l2 = node_factory.get_nodes(2, opts=[{'exposesecret-passphrase': "test_exposesecret"}, {}])
|
||||
|
||||
# listconfigs will conceal the value for us, even if we ask directly.
|
||||
l1.rpc.listconfigs()['configs']['exposesecret-passphrase']['value_str'] == '...'
|
||||
l1.rpc.listconfigs('exposesecret-passphrase')['configs']['exposesecret-passphrase']['value_str'] == '...'
|
||||
|
||||
# l2 won't expose the secret!
|
||||
with pytest.raises(RpcError, match="exposesecrets-passphrase is not set"):
|
||||
l2.rpc.exposesecret(passphrase='test_exposesecret')
|
||||
|
Loading…
Reference in New Issue
Block a user