From 5325ff6352aadd20058d8be55e77e4d5b06df0c0 Mon Sep 17 00:00:00 2001 From: Christian Decker Date: Wed, 4 Dec 2019 16:51:47 +0100 Subject: [PATCH] json-rpc: Don't let users send messages that are handled internally We cannot let users use `sendcustommsg` to inject messages that are handled internally since it could result in our internal state tracking being borked. --- lightningd/peer_control.c | 12 ++++++++++++ tools/gen/header_template | 9 +++++++++ tools/gen/impl_template | 12 ++++++++++++ 3 files changed, 33 insertions(+) diff --git a/lightningd/peer_control.c b/lightningd/peer_control.c index d56ca6207..d674ba5f1 100644 --- a/lightningd/peer_control.c +++ b/lightningd/peer_control.c @@ -2385,6 +2385,7 @@ static struct command_result *json_sendcustommsg(struct command *cmd, struct peer *peer; struct subd *owner; u8 *msg; + int type; if (!param(cmd, buffer, params, p_req("node_id", param_node_id, &dest), @@ -2392,6 +2393,17 @@ static struct command_result *json_sendcustommsg(struct command *cmd, NULL)) return command_param_failed(); + type = fromwire_peektype(msg); + if (wire_type_is_defined(type)) { + return command_fail( + cmd, JSONRPC2_INVALID_REQUEST, + "Cannot send messages of type %d (%s). It is not possible " + "to send messages that have a type managed internally " + "since that might cause issues with the internal state " + "tracking.", + type, wire_type_name(type)); + } + peer = peer_by_id(cmd->ld, dest); if (!peer) { return command_fail(cmd, JSONRPC2_INVALID_REQUEST, diff --git a/tools/gen/header_template b/tools/gen/header_template index c7e816d93..6175dcd5a 100644 --- a/tools/gen/header_template +++ b/tools/gen/header_template @@ -26,6 +26,15 @@ enum ${enum_set['name']} { ## The 'name' functions for the enums % for enum_set in enum_sets: const char *${enum_set['name']}_name(int e); + +/** + * Determine whether a given message type is defined as a message. + * + * Returns true if the message type is part of the message definitions we have + * generated parsers for, false if it is a custom message that cannot be + * handled internally. + */ +bool ${enum_set['name']}_is_defined(u16 type); % endfor ## Structs for subtypes + tlv messages diff --git a/tools/gen/impl_template b/tools/gen/impl_template index 118d57a26..1c4f2e231 100644 --- a/tools/gen/impl_template +++ b/tools/gen/impl_template @@ -31,6 +31,18 @@ const char *${enum_set['name']}_name(int e) snprintf(invalidbuf, sizeof(invalidbuf), "INVALID %i", e); return invalidbuf; } + +bool ${enum_set['name']}_is_defined(u16 type) +{ + switch ((enum ${enum_set['name']})type) { + % for msg in enum_set['set']: + case ${msg.enum_name()}:; + % endfor + return true; + } + return false; +} + % endfor ## START PARTIALS ## Subtype and TLV-msg towire_