Browse Source

config: explicitly disallow nonsensical options.

1. "conf" can't be specified in a configuration file.
2. "lightning-dir" can't be specified in a configuration file unless the file
   was explicitly set with --conf=.
3. "network" options can't be set in a per-network configuration file.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
travis-debug
Rusty Russell 5 years ago
parent
commit
e3dbd78536
  1. 72
      common/configdir.c
  2. 7
      common/configdir.h
  3. 4
      lightningd/options.c

72
common/configdir.c

@ -191,17 +191,53 @@ static void opt_show_network(char buf[OPT_SHOW_LEN], const void *unused)
snprintf(buf, OPT_SHOW_LEN, "%s", chainparams->network_name);
}
/* Special option to ignore stuff we've parsed really early on */
char *opt_ignore(const char *arg, void *unused)
/* We track where we're getting options from, so we can detect misuse */
enum parse_state {
CMDLINE = 1,
FORCED_CONFIG = 2,
TOPLEVEL_CONFIG = 4,
NETWORK_CONFIG = 8,
};
static enum parse_state parse_state = CMDLINE;
static char *opt_restricted_cmdline(const char *arg, const void *unused)
{
if (parse_state != CMDLINE)
return "not permitted in configuration files";
return NULL;
}
char *opt_ignore_noarg(void *unused)
static char *opt_restricted_toplevel_noarg(const void *unused)
{
if (parse_state == NETWORK_CONFIG)
return "not permitted in network-specific configuration files";
return NULL;
}
static char *opt_restricted_toplevel(const char *arg, const void *unused)
{
return opt_restricted_toplevel_noarg(NULL);
}
static char *opt_restricted_forceconf_only(const char *arg, const void *unused)
{
if (parse_state != CMDLINE && parse_state != FORCED_CONFIG)
return "not permitted in implicit configuration files";
return NULL;
}
bool is_restricted_ignored(const void *fn)
{
return fn == opt_restricted_toplevel_noarg
|| fn == opt_restricted_toplevel
|| fn == opt_restricted_forceconf_only;
}
bool is_restricted_print_if_nonnull(const void *fn)
{
return fn == opt_restricted_cmdline;
}
void setup_option_allocators(void)
{
/*~ These functions make ccan/opt use tal for allocations */
@ -236,12 +272,17 @@ void parse_config_files(const char *config_filename,
bool early)
{
if (config_filename) {
parse_state = FORCED_CONFIG;
parse_include(config_filename, true, early);
parse_state = CMDLINE;
return;
}
parse_state = TOPLEVEL_CONFIG;
parse_implied_config_file(config_basedir, NULL, early);
parse_state = NETWORK_CONFIG;
parse_implied_config_file(config_basedir, chainparams->network_name, early);
parse_state = CMDLINE;
}
/* Could be a yet-to-be-upgraded dir (definitely testnet), or could be
@ -303,14 +344,16 @@ void initial_config_opts(const tal_t *ctx,
/* Now, reset and ignore --conf option from now on. */
opt_free_table();
opt_register_early_arg("--conf=<file>", opt_ignore, NULL,
/* This is only ever valid on cmdline */
opt_register_early_arg("--conf=<file>",
opt_restricted_cmdline, NULL,
config_filename,
"Specify configuration file");
/* If they set --conf it can still set --lightning-dir */
if (!*config_filename) {
opt_register_early_arg("--lightning-dir=<dir>",
opt_ignore, opt_show_charp,
opt_restricted_forceconf_only, opt_show_charp,
config_basedir,
"Set base directory: network-specific subdirectory is under here");
} else {
@ -372,22 +415,29 @@ void initial_config_opts(const tal_t *ctx,
/* Now, reset and ignore those options from now on. */
opt_free_table();
opt_register_early_arg("--conf=<file>", opt_ignore, NULL,
opt_register_early_arg("--conf=<file>",
opt_restricted_cmdline, NULL,
config_filename,
"Specify configuration file");
/* This is never in a default config file (since we used the defaults to find it!). */
opt_register_early_arg("--lightning-dir=<dir>",
opt_ignore, opt_show_charp,
opt_restricted_forceconf_only, opt_show_charp,
config_basedir,
"Set base directory: network-specific subdirectory is under here");
opt_register_early_arg("--network", opt_ignore, opt_show_network,
opt_register_early_arg("--network",
opt_restricted_toplevel, opt_show_network,
NULL,
"Select the network parameters (bitcoin, testnet,"
" regtest, litecoin or litecoin-testnet)");
opt_register_early_noarg("--testnet", opt_ignore_noarg, NULL,
opt_register_early_noarg("--testnet",
opt_restricted_toplevel_noarg, NULL,
"Alias for --network=testnet");
opt_register_early_noarg("--signet", opt_ignore_noarg, NULL,
opt_register_early_noarg("--signet",
opt_restricted_toplevel_noarg, NULL,
"Alias for --network=signet");
opt_register_early_noarg("--mainnet", opt_ignore_noarg, NULL,
opt_register_early_noarg("--mainnet",
opt_restricted_toplevel_noarg, NULL,
"Alias for --network=bitcoin");
/* They can set this later, it's just less effective. */

7
common/configdir.h

@ -1,6 +1,7 @@
#ifndef LIGHTNING_COMMON_CONFIGDIR_H
#define LIGHTNING_COMMON_CONFIGDIR_H
#include "config.h"
#include <ccan/ptrint/ptrint.h>
#include <ccan/tal/tal.h>
/* Put things we're going to get rid of behind this, so testers can catch
@ -28,8 +29,8 @@ void parse_config_files(const char *config_filename,
const char *config_basedir,
bool early);
/* For listconfigs to access. */
char *opt_ignore(const char *arg, void *unused);
char *opt_ignore_noarg(void *unused);
/* For listconfigs to detect. */
bool is_restricted_ignored(const void *fn);
bool is_restricted_print_if_nonnull(const void *fn);
#endif /* LIGHTNING_COMMON_CONFIGDIR_H */

4
lightningd/options.c

@ -1079,7 +1079,7 @@ static void add_config(struct lightningd *ld,
/* Ignore hidden options (deprecated) */
} else if (opt->cb == (void *)opt_usage_and_exit
|| opt->cb == (void *)version_and_exit
|| opt->cb == (void *)opt_ignore_noarg
|| is_restricted_ignored(opt->cb)
|| opt->cb == (void *)opt_lightningd_usage
|| opt->cb == (void *)test_subdaemons_and_exit
/* FIXME: we can't recover this. */
@ -1129,7 +1129,7 @@ static void add_config(struct lightningd *ld,
answer = buf;
} else if (opt->cb_arg == (void *)opt_set_talstr
|| opt->cb_arg == (void *)opt_set_charp
|| opt->cb_arg == (void *)opt_ignore) {
|| is_restricted_print_if_nonnull(opt->cb_arg)) {
const char *arg = *(char **)opt->u.carg;
if (arg)
answer = tal_fmt(name0, "%s", arg);

Loading…
Cancel
Save