plugin: Restrict plugin notifications only to announced topics

We want to have well-behaved notifications that are clearly announced
during the initialization, kill plugins that don't behave.
This commit is contained in:
Christian Decker 2021-04-28 17:21:14 +02:00 committed by Rusty Russell
parent 62e3358a5b
commit f08ae49134
2 changed files with 33 additions and 6 deletions

View file

@ -417,6 +417,18 @@ static const char *plugin_notify_handle(struct plugin *plugin,
return NULL;
}
/* Check if the plugin is allowed to send a notification of the
* specified topic, i.e., whether the plugin has announced the topic
* correctly in its manifest. */
static bool plugin_notification_allowed(const struct plugin *plugin, const char *topic)
{
for (size_t i=0; i<tal_count(plugin->notification_topics); i++)
if (streq(plugin->notification_topics[i], topic))
return true;
return false;
}
/* Returns the error string, or NULL */
static const char *plugin_notification_handle(struct plugin *plugin,
const jsmntok_t *toks)
@ -453,13 +465,26 @@ static const char *plugin_notification_handle(struct plugin *plugin,
methname = json_strdup(tmpctx, plugin->buffer, methtok);
if (notifications_have_topic(plugin->plugins, methname)) {
if (!plugin_notification_allowed(plugin, methname)) {
log_unusual(
plugin->log,
"Plugin attempted to send a notification to topic "
"\"%s\" it hasn't declared in its manifest, not "
"forwarding to subscribers.",
methname);
return NULL;
} else {
n = jsonrpc_notification_start(NULL, methname);
json_add_string(n->stream, "origin", plugin->shortname);
json_add_tok(n->stream, "payload", paramstok, plugin->buffer);
json_add_tok(n->stream, "payload", paramstok,
plugin->buffer);
jsonrpc_notification_end(n);
plugins_notify(plugin->plugins, take(n));
return NULL;
}
} else {
return tal_fmt(plugin, "Unknown notification method %.*s",
json_tok_full_len(methtok),

View file

@ -91,6 +91,8 @@ struct plugin {
/* Location of the RPC filename in case we need to defer RPC
* initialization or need to recover from a disconnect. */
const char *rpc_location;
char **notification_topics;
};
/* command_result is mainly used as a compile-time check to encourage you