Skip to content

Commit 8293352

Browse files
committed
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 <[email protected]>
1 parent 101aeea commit 8293352

File tree

8 files changed

+24
-8
lines changed

8 files changed

+24
-8
lines changed

common/configvar.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,8 @@ struct configvar {
6262
#define OPT_DYNAMIC (1 << (OPT_USER_START+6))
6363
/* Keep whitespace at the end of the option argument */
6464
#define OPT_KEEP_WHITESPACE (1 << (OPT_USER_START+7))
65+
/* Don't show value in listconfigs */
66+
#define OPT_CONCEAL (1 << (OPT_USER_START+8))
6567

6668
/* Use this instead of opt_register_*_arg if you want OPT_* from above */
6769
#define clnopt_witharg(names, type, cb, show, arg, desc) \

doc/developers-guide/plugin-development/a-day-in-the-life-of-a-plugin.md

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -124,10 +124,11 @@ Plugins are free to register any `name` for their `rpcmethod` as long as the nam
124124

125125
There are currently four supported option 'types':
126126

127-
- string: a string
128-
- bool: a boolean
129-
- int: parsed as a signed integer (64-bit)
130-
- flag: no-arg flag option. Presented as `true` if config specifies it.
127+
- `string`: a string
128+
- `string-conceal`: a string which will appear as "..." in `listconfigs`.
129+
- `bool`: a boolean
130+
- `int`: parsed as a signed integer (64-bit)
131+
- `flag`: no-arg flag option. Presented as `true` if config specifies it.
131132

132133
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
133134
sense.

lightningd/configs.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,9 @@ static const char *get_opt_val(const struct opt_table *ot,
6565
char buf[],
6666
const struct configvar *cv)
6767
{
68+
if (ot->type & OPT_CONCEAL)
69+
return "...";
70+
6871
if (ot->show == (void *)opt_show_charp) {
6972
/* Don't truncate or quote! */
7073
return *(char **)ot->u.carg;

lightningd/options.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2095,8 +2095,10 @@ void add_config_deprecated(struct lightningd *ld,
20952095
if (!opt->show(buf, sizeof(buf) - sizeof("..."), opt->u.carg))
20962096
buf[0] = '\0';
20972097

2098-
if ((opt->type & OPT_SHOWINT)
2099-
|| (opt->type & OPT_SHOWMSATS)) {
2098+
if (opt->type & OPT_CONCEAL) {
2099+
strcpy(buf, "...");
2100+
} else if ((opt->type & OPT_SHOWINT)
2101+
|| (opt->type & OPT_SHOWMSATS)) {
21002102
if (streq(buf, "")
21012103
|| strspn(buf, "-0123456789.") != strlen(buf))
21022104
errx(1, "Bad literal for %s: %s", name0, buf);

lightningd/plugin.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1168,7 +1168,10 @@ static const char *plugin_opt_add(struct plugin *plugin, const char *buffer,
11681168
/* These all take an arg. */
11691169
char *(*cb_arg)(const char *optarg, void *arg);
11701170

1171-
if (json_tok_streq(buffer, typetok, "string")) {
1171+
if (json_tok_streq(buffer, typetok, "string-conceal")) {
1172+
optflags |= OPT_CONCEAL;
1173+
cb_arg = (void *)plugin_opt_string_check;
1174+
} else if (json_tok_streq(buffer, typetok, "string")) {
11721175
cb_arg = (void *)plugin_opt_string_check;
11731176
} else if (json_tok_streq(buffer, typetok, "int")) {
11741177
cb_arg = (void *)plugin_opt_long_check;

plugins/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,4 @@ cln-renepay
1818
recover
1919
cln-askrene
2020
recklessrpc
21+
exposesecret

plugins/exposesecret.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@ int main(int argc, char *argv[])
156156
plugin_main(argv, init, take(exposesecret),
157157
PLUGIN_RESTARTABLE, true, NULL, commands, ARRAY_SIZE(commands),
158158
NULL, 0, NULL, 0, NULL, 0,
159-
plugin_option("exposesecret-passphrase", "string",
159+
plugin_option("exposesecret-passphrase", "string-conceal",
160160
"Enable exposesecret command to allow HSM Secret backup, with this passphrase",
161161
charp_option, NULL, &exposesecret->exposure_passphrase),
162162
NULL);

tests/test_plugin.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4453,6 +4453,10 @@ def test_listchannels_broken_message(node_factory):
44534453
def test_exposesecret(node_factory):
44544454
l1, l2 = node_factory.get_nodes(2, opts=[{'exposesecret-passphrase': "test_exposesecret"}, {}])
44554455

4456+
# listconfigs will conceal the value for us, even if we ask directly.
4457+
l1.rpc.listconfigs()['configs']['exposesecret-passphrase']['value_str'] == '...'
4458+
l1.rpc.listconfigs('exposesecret-passphrase')['configs']['exposesecret-passphrase']['value_str'] == '...'
4459+
44564460
# l2 won't expose the secret!
44574461
with pytest.raises(RpcError, match="exposesecrets-passphrase is not set"):
44584462
l2.rpc.exposesecret(passphrase='test_exposesecret')

0 commit comments

Comments
 (0)