mirror of
https://github.com/aljazceru/lightning.git
synced 2025-12-19 15:14:23 +01:00
onion_message: don't use general secret, use per-message secret.
We had a scheme where lightningd itself would put a per-node secret in the blinded path, then we'd tell the caller when it was used. Then it simply checks the alias to determine if the correct path was used. But this doesn't work when we start to offer multiple blinded paths. So go for a far simpler scheme, where the secret is generated (and stored) by the caller, and hand it back to them. We keep the split "with secret" or "without secret" API, since I'm sure callers who don't care about the secret won't check that it doesn't exist! And without that, someone can use a blinded path for a different message and get a response which may reveal the node. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
committed by
Christian Decker
parent
4cfd972407
commit
5becfa6ee1
@@ -11,7 +11,7 @@
|
|||||||
#define HSM_MIN_VERSION 1
|
#define HSM_MIN_VERSION 1
|
||||||
|
|
||||||
/* wire/hsmd_wire.csv contents version:
|
/* wire/hsmd_wire.csv contents version:
|
||||||
* 43c435f61de3af0dd7a91514d94b3e0762c962fce5b39be430538f8c6c4b0695
|
* dd89bf9323dff42200003fb864abb6608f3aa645b636fdae3ec81d804ac05196
|
||||||
*/
|
*/
|
||||||
#define HSM_MAX_VERSION 2
|
#define HSM_MAX_VERSION 2
|
||||||
#endif /* LIGHTNING_COMMON_HSM_VERSION_H */
|
#endif /* LIGHTNING_COMMON_HSM_VERSION_H */
|
||||||
|
|||||||
@@ -118,8 +118,7 @@ msgdata,connectd_ping_reply,totlen,u16,
|
|||||||
|
|
||||||
# We tell lightningd we got an onionmsg
|
# We tell lightningd we got an onionmsg
|
||||||
msgtype,connectd_got_onionmsg_to_us,2145
|
msgtype,connectd_got_onionmsg_to_us,2145
|
||||||
msgdata,connectd_got_onionmsg_to_us,node_alias,pubkey,
|
msgdata,connectd_got_onionmsg_to_us,path_secret,?secret,
|
||||||
msgdata,connectd_got_onionmsg_to_us,self_id,?secret,
|
|
||||||
msgdata,connectd_got_onionmsg_to_us,reply,?blinded_path,
|
msgdata,connectd_got_onionmsg_to_us,reply,?blinded_path,
|
||||||
msgdata,connectd_got_onionmsg_to_us,rawmsg_len,u16,
|
msgdata,connectd_got_onionmsg_to_us,rawmsg_len,u16,
|
||||||
msgdata,connectd_got_onionmsg_to_us,rawmsg,u8,rawmsg_len
|
msgdata,connectd_got_onionmsg_to_us,rawmsg,u8,rawmsg_len
|
||||||
|
|||||||
|
@@ -75,7 +75,7 @@ void handle_onion_message(struct daemon *daemon,
|
|||||||
towire_tlvstream_raw(&omsg, final_om->fields);
|
towire_tlvstream_raw(&omsg, final_om->fields);
|
||||||
daemon_conn_send(daemon->master,
|
daemon_conn_send(daemon->master,
|
||||||
take(towire_connectd_got_onionmsg_to_us(NULL,
|
take(towire_connectd_got_onionmsg_to_us(NULL,
|
||||||
&final_alias, final_path_id,
|
final_path_id,
|
||||||
final_om->reply_path,
|
final_om->reply_path,
|
||||||
omsg)));
|
omsg)));
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -1650,23 +1650,22 @@ type prefix, since Core Lightning does not know how to parse the message.
|
|||||||
Because this is a chained hook, the daemon expects the result to be
|
Because this is a chained hook, the daemon expects the result to be
|
||||||
`{'result': 'continue'}`. It will fail if something else is returned.
|
`{'result': 'continue'}`. It will fail if something else is returned.
|
||||||
|
|
||||||
### `onion_message_blinded` and `onion_message_ourpath`
|
### `onion_message_recv` and `onion_message_recv_secret`
|
||||||
|
|
||||||
**(WARNING: experimental-offers only)**
|
**(WARNING: experimental-offers only)**
|
||||||
|
|
||||||
These two hooks are almost identical, in that they are called when
|
These two hooks are almost identical, in that they are called when
|
||||||
an onion message is received.
|
an onion message is received.
|
||||||
|
|
||||||
`onion_message_blinded` is used for unsolicited messages (where the
|
`onion_message_recv` is used for unsolicited messages (where the
|
||||||
source knows that it is sending to this node), and
|
source knows that it is sending to this node), and
|
||||||
`onion_message_ourpath` is used for messages which use a blinded path
|
`onion_message_recv_secret` is used for messages which use a blinded path
|
||||||
we supplied (where the source doesn't know that this node is the
|
we supplied. The latter hook will have a `pathsecret` field, the
|
||||||
destination). The latter hook will have a `our_alias` field, the
|
|
||||||
former never will.
|
former never will.
|
||||||
|
|
||||||
These hooks are separate, because replies MUST be ignored unless they
|
These hooks are separate, because replies MUST be ignored unless they
|
||||||
use the correct path (i.e. `onion_message_ourpath`, with the expected
|
use the correct path (i.e. `onion_message_recv_secret`, with the expected
|
||||||
`our_alias`). This avoids the source trying to probe for responses
|
`pathsecret`). This avoids the source trying to probe for responses
|
||||||
without using the designated delivery path.
|
without using the designated delivery path.
|
||||||
|
|
||||||
The payload for a call follows this format:
|
The payload for a call follows this format:
|
||||||
@@ -1674,7 +1673,7 @@ The payload for a call follows this format:
|
|||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"onion_message": {
|
"onion_message": {
|
||||||
"our_alias": "02df5ffe895c778e10f7742a6c5b8a0cefbe9465df58b92fadeb883752c8107c8f",
|
"pathsecret": "0000000000000000000000000000000000000000000000000000000000000000",
|
||||||
"reply_first_node": "02df5ffe895c778e10f7742a6c5b8a0cefbe9465df58b92fadeb883752c8107c8f",
|
"reply_first_node": "02df5ffe895c778e10f7742a6c5b8a0cefbe9465df58b92fadeb883752c8107c8f",
|
||||||
"reply_blinding": "02df5ffe895c778e10f7742a6c5b8a0cefbe9465df58b92fadeb883752c8107c8f",
|
"reply_blinding": "02df5ffe895c778e10f7742a6c5b8a0cefbe9465df58b92fadeb883752c8107c8f",
|
||||||
"reply_path": [ {"id": "02df5ffe895c778e10f7742a6c5b8a0cefbe9465df58b92fadeb883752c8107c8f",
|
"reply_path": [ {"id": "02df5ffe895c778e10f7742a6c5b8a0cefbe9465df58b92fadeb883752c8107c8f",
|
||||||
@@ -1691,7 +1690,6 @@ The payload for a call follows this format:
|
|||||||
All fields shown here are optional.
|
All fields shown here are optional.
|
||||||
|
|
||||||
We suggest just returning `{'result': 'continue'}`; any other result
|
We suggest just returning `{'result': 'continue'}`; any other result
|
||||||
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
|
|
||||||
will cause the message not to be handed to any other hooks.
|
will cause the message not to be handed to any other hooks.
|
||||||
|
|
||||||
## Bitcoin backend
|
## Bitcoin backend
|
||||||
|
|||||||
@@ -30,7 +30,6 @@ msgtype,hsmd_init_reply_v2,113
|
|||||||
msgdata,hsmd_init_reply_v2,node_id,node_id,
|
msgdata,hsmd_init_reply_v2,node_id,node_id,
|
||||||
msgdata,hsmd_init_reply_v2,bip32,ext_key,
|
msgdata,hsmd_init_reply_v2,bip32,ext_key,
|
||||||
msgdata,hsmd_init_reply_v2,bolt12,pubkey,
|
msgdata,hsmd_init_reply_v2,bolt12,pubkey,
|
||||||
msgdata,hsmd_init_reply_v2,onion_reply_secret,secret,
|
|
||||||
|
|
||||||
# Declare a new channel.
|
# Declare a new channel.
|
||||||
msgtype,hsmd_new_channel,30
|
msgtype,hsmd_new_channel,30
|
||||||
|
|||||||
|
@@ -1648,7 +1648,6 @@ u8 *hsmd_init(struct secret hsm_secret,
|
|||||||
u32 salt = 0;
|
u32 salt = 0;
|
||||||
struct ext_key master_extkey, child_extkey;
|
struct ext_key master_extkey, child_extkey;
|
||||||
struct node_id node_id;
|
struct node_id node_id;
|
||||||
struct secret onion_reply_secret;
|
|
||||||
|
|
||||||
/*~ Don't swap this. */
|
/*~ Don't swap this. */
|
||||||
sodium_mlock(secretstuff.hsm_secret.data,
|
sodium_mlock(secretstuff.hsm_secret.data,
|
||||||
@@ -1766,14 +1765,6 @@ u8 *hsmd_init(struct secret hsm_secret,
|
|||||||
hsmd_status_failed(STATUS_FAIL_INTERNAL_ERROR,
|
hsmd_status_failed(STATUS_FAIL_INTERNAL_ERROR,
|
||||||
"Could derive bolt12 public key.");
|
"Could derive bolt12 public key.");
|
||||||
|
|
||||||
/*~ We derive a secret for onion_message's self_id so we can tell
|
|
||||||
* if it used a path we created (i.e. do not leak our public id!) */
|
|
||||||
hkdf_sha256(&onion_reply_secret, sizeof(onion_reply_secret),
|
|
||||||
NULL, 0,
|
|
||||||
&secretstuff.hsm_secret,
|
|
||||||
sizeof(secretstuff.hsm_secret),
|
|
||||||
"onion reply secret", strlen("onion reply secret"));
|
|
||||||
|
|
||||||
/* We derive the derived_secret key for generating pseudorandom keys
|
/* We derive the derived_secret key for generating pseudorandom keys
|
||||||
* by taking input string from the makesecret RPC */
|
* by taking input string from the makesecret RPC */
|
||||||
hkdf_sha256(&secretstuff.derived_secret, sizeof(struct secret), NULL, 0,
|
hkdf_sha256(&secretstuff.derived_secret, sizeof(struct secret), NULL, 0,
|
||||||
@@ -1785,5 +1776,5 @@ u8 *hsmd_init(struct secret hsm_secret,
|
|||||||
*/
|
*/
|
||||||
return take(towire_hsmd_init_reply_v2(
|
return take(towire_hsmd_init_reply_v2(
|
||||||
NULL, &node_id, &secretstuff.bip32,
|
NULL, &node_id, &secretstuff.bip32,
|
||||||
&bolt12, &onion_reply_secret));
|
&bolt12));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -119,16 +119,17 @@ struct ext_key *hsm_init(struct lightningd *ld)
|
|||||||
msg = wire_sync_read(tmpctx, ld->hsm_fd);
|
msg = wire_sync_read(tmpctx, ld->hsm_fd);
|
||||||
if (!fromwire_hsmd_init_reply_v2(msg,
|
if (!fromwire_hsmd_init_reply_v2(msg,
|
||||||
&ld->id, bip32_base,
|
&ld->id, bip32_base,
|
||||||
&ld->bolt12_base,
|
&ld->bolt12_base)) {
|
||||||
&ld->onion_reply_secret)) {
|
|
||||||
/* v1 had x-only pubkey */
|
/* v1 had x-only pubkey */
|
||||||
u8 pubkey32[33];
|
u8 pubkey32[33];
|
||||||
|
/* And gave us a secret to use for onion_reply paths */
|
||||||
|
struct secret onion_reply_secret;
|
||||||
|
|
||||||
pubkey32[0] = SECP256K1_TAG_PUBKEY_EVEN;
|
pubkey32[0] = SECP256K1_TAG_PUBKEY_EVEN;
|
||||||
if (!fromwire_hsmd_init_reply_v1(msg,
|
if (!fromwire_hsmd_init_reply_v1(msg,
|
||||||
&ld->id, bip32_base,
|
&ld->id, bip32_base,
|
||||||
pubkey32 + 1,
|
pubkey32 + 1,
|
||||||
&ld->onion_reply_secret)) {
|
&onion_reply_secret)) {
|
||||||
if (ld->config.keypass)
|
if (ld->config.keypass)
|
||||||
errx(EXITCODE_HSM_BAD_PASSWORD, "Wrong password for encrypted hsm_secret.");
|
errx(EXITCODE_HSM_BAD_PASSWORD, "Wrong password for encrypted hsm_secret.");
|
||||||
errx(EXITCODE_HSM_GENERIC_ERROR, "HSM did not give init reply");
|
errx(EXITCODE_HSM_GENERIC_ERROR, "HSM did not give init reply");
|
||||||
|
|||||||
@@ -124,9 +124,6 @@ struct lightningd {
|
|||||||
/* The public base for our payer_id keys */
|
/* The public base for our payer_id keys */
|
||||||
struct pubkey bolt12_base;
|
struct pubkey bolt12_base;
|
||||||
|
|
||||||
/* The secret we put in onion message paths to know it's ours. */
|
|
||||||
struct secret onion_reply_secret;
|
|
||||||
|
|
||||||
/* Feature set we offer. */
|
/* Feature set we offer. */
|
||||||
struct feature_set *our_features;
|
struct feature_set *our_features;
|
||||||
|
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
struct onion_message_hook_payload {
|
struct onion_message_hook_payload {
|
||||||
/* Optional */
|
/* Optional */
|
||||||
struct blinded_path *reply_path;
|
struct blinded_path *reply_path;
|
||||||
struct pubkey *our_alias;
|
struct secret *pathsecret;
|
||||||
struct tlv_onionmsg_tlv *om;
|
struct tlv_onionmsg_tlv *om;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -45,8 +45,8 @@ static void onion_message_serialize(struct onion_message_hook_payload *payload,
|
|||||||
struct plugin *plugin)
|
struct plugin *plugin)
|
||||||
{
|
{
|
||||||
json_object_start(stream, "onion_message");
|
json_object_start(stream, "onion_message");
|
||||||
if (payload->our_alias)
|
if (payload->pathsecret)
|
||||||
json_add_pubkey(stream, "our_alias", payload->our_alias);
|
json_add_secret(stream, "pathsecret", payload->pathsecret);
|
||||||
|
|
||||||
if (payload->reply_path)
|
if (payload->reply_path)
|
||||||
json_add_blindedpath(stream, "reply_blindedpath",
|
json_add_blindedpath(stream, "reply_blindedpath",
|
||||||
@@ -86,34 +86,32 @@ onion_message_hook_cb(struct onion_message_hook_payload *payload STEALS)
|
|||||||
tal_free(payload);
|
tal_free(payload);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Two hooks, because it's critical we only accept blinding if we expect that
|
/* This is for unsolicted messages */
|
||||||
* exact blinding key. Otherwise, we can be probed using old blinded paths. */
|
REGISTER_PLUGIN_HOOK(onion_message_recv,
|
||||||
REGISTER_PLUGIN_HOOK(onion_message_blinded,
|
|
||||||
plugin_hook_continue,
|
plugin_hook_continue,
|
||||||
onion_message_hook_cb,
|
onion_message_hook_cb,
|
||||||
onion_message_serialize,
|
onion_message_serialize,
|
||||||
struct onion_message_hook_payload *);
|
struct onion_message_hook_payload *);
|
||||||
|
|
||||||
REGISTER_PLUGIN_HOOK(onion_message_ourpath,
|
/* This is for messages claiming to be using our paths: caller must
|
||||||
|
* check pathsecret! */
|
||||||
|
REGISTER_PLUGIN_HOOK(onion_message_recv_secret,
|
||||||
plugin_hook_continue,
|
plugin_hook_continue,
|
||||||
onion_message_hook_cb,
|
onion_message_hook_cb,
|
||||||
onion_message_serialize,
|
onion_message_serialize,
|
||||||
struct onion_message_hook_payload *);
|
struct onion_message_hook_payload *);
|
||||||
|
|
||||||
|
|
||||||
void handle_onionmsg_to_us(struct lightningd *ld, const u8 *msg)
|
void handle_onionmsg_to_us(struct lightningd *ld, const u8 *msg)
|
||||||
{
|
{
|
||||||
struct onion_message_hook_payload *payload;
|
struct onion_message_hook_payload *payload;
|
||||||
u8 *submsg;
|
u8 *submsg;
|
||||||
struct secret *self_id;
|
|
||||||
size_t submsglen;
|
size_t submsglen;
|
||||||
const u8 *subptr;
|
const u8 *subptr;
|
||||||
|
|
||||||
payload = tal(tmpctx, struct onion_message_hook_payload);
|
payload = tal(tmpctx, struct onion_message_hook_payload);
|
||||||
payload->our_alias = tal(payload, struct pubkey);
|
|
||||||
|
|
||||||
if (!fromwire_connectd_got_onionmsg_to_us(payload, msg,
|
if (!fromwire_connectd_got_onionmsg_to_us(payload, msg,
|
||||||
payload->our_alias,
|
&payload->pathsecret,
|
||||||
&self_id,
|
|
||||||
&payload->reply_path,
|
&payload->reply_path,
|
||||||
&submsg)) {
|
&submsg)) {
|
||||||
log_broken(ld->log, "bad got_onionmsg_tous: %s",
|
log_broken(ld->log, "bad got_onionmsg_tous: %s",
|
||||||
@@ -126,12 +124,6 @@ void handle_onionmsg_to_us(struct lightningd *ld, const u8 *msg)
|
|||||||
return;
|
return;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* If there's no self_id, or it's not correct, ignore alias: alias
|
|
||||||
* means we created the path it's using. */
|
|
||||||
if (!self_id || !secret_eq_consttime(self_id, &ld->onion_reply_secret))
|
|
||||||
payload->our_alias = tal_free(payload->our_alias);
|
|
||||||
tal_free(self_id);
|
|
||||||
|
|
||||||
submsglen = tal_bytelen(submsg);
|
submsglen = tal_bytelen(submsg);
|
||||||
subptr = submsg;
|
subptr = submsg;
|
||||||
payload->om = fromwire_tlv_onionmsg_tlv(payload, &subptr, &submsglen);
|
payload->om = fromwire_tlv_onionmsg_tlv(payload, &subptr, &submsglen);
|
||||||
@@ -144,15 +136,15 @@ void handle_onionmsg_to_us(struct lightningd *ld, const u8 *msg)
|
|||||||
|
|
||||||
/* Make sure connectd gets this right. */
|
/* Make sure connectd gets this right. */
|
||||||
log_debug(ld->log, "Got onionmsg%s%s",
|
log_debug(ld->log, "Got onionmsg%s%s",
|
||||||
payload->our_alias ? " via-ourpath": "",
|
payload->pathsecret ? " with pathsecret": "",
|
||||||
payload->reply_path ? " reply_path": "");
|
payload->reply_path ? " reply_path": "");
|
||||||
|
|
||||||
/* We'll free this on return */
|
/* We'll free this on return */
|
||||||
tal_steal(ld, payload);
|
tal_steal(ld, payload);
|
||||||
if (payload->our_alias)
|
if (payload->pathsecret)
|
||||||
plugin_hook_call_onion_message_ourpath(ld, NULL, payload);
|
plugin_hook_call_onion_message_recv_secret(ld, NULL, payload);
|
||||||
else
|
else
|
||||||
plugin_hook_call_onion_message_blinded(ld, NULL, payload);
|
plugin_hook_call_onion_message_recv(ld, NULL, payload);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct onion_hop {
|
struct onion_hop {
|
||||||
@@ -286,9 +278,11 @@ static struct command_result *json_blindedpath(struct command *cmd,
|
|||||||
size_t nhops;
|
size_t nhops;
|
||||||
struct json_stream *response;
|
struct json_stream *response;
|
||||||
struct tlv_encrypted_data_tlv *tlv;
|
struct tlv_encrypted_data_tlv *tlv;
|
||||||
|
struct secret *pathsecret;
|
||||||
|
|
||||||
if (!param(cmd, buffer, params,
|
if (!param(cmd, buffer, params,
|
||||||
p_req("ids", param_pubkeys, &ids),
|
p_req("ids", param_pubkeys, &ids),
|
||||||
|
p_req("pathsecret", param_secret, &pathsecret),
|
||||||
NULL))
|
NULL))
|
||||||
return command_param_failed();
|
return command_param_failed();
|
||||||
|
|
||||||
@@ -338,8 +332,8 @@ static struct command_result *json_blindedpath(struct command *cmd,
|
|||||||
path->path[nhops-1] = tal(path->path, struct onionmsg_hop);
|
path->path[nhops-1] = tal(path->path, struct onionmsg_hop);
|
||||||
|
|
||||||
tlv = tlv_encrypted_data_tlv_new(tmpctx);
|
tlv = tlv_encrypted_data_tlv_new(tmpctx);
|
||||||
tlv->path_id = (u8 *)tal_dup(tlv, struct secret,
|
|
||||||
&cmd->ld->onion_reply_secret);
|
tlv->path_id = (u8 *)tal_dup(tlv, struct secret, pathsecret);
|
||||||
path->path[nhops-1]->encrypted_recipient_data
|
path->path[nhops-1]->encrypted_recipient_data
|
||||||
= encrypt_tlv_encrypted_data(path->path[nhops-1],
|
= encrypt_tlv_encrypted_data(path->path[nhops-1],
|
||||||
&blinding_iter,
|
&blinding_iter,
|
||||||
|
|||||||
@@ -29,8 +29,8 @@ static LIST_HEAD(sent_list);
|
|||||||
struct sent {
|
struct sent {
|
||||||
/* We're in sent_invreqs, awaiting reply. */
|
/* We're in sent_invreqs, awaiting reply. */
|
||||||
struct list_node list;
|
struct list_node list;
|
||||||
/* The alias used by reply */
|
/* The secret used by reply */
|
||||||
struct pubkey *reply_alias;
|
struct secret *reply_secret;
|
||||||
/* The command which sent us. */
|
/* The command which sent us. */
|
||||||
struct command *cmd;
|
struct command *cmd;
|
||||||
/* The offer we are trying to get an invoice/payment for. */
|
/* The offer we are trying to get an invoice/payment for. */
|
||||||
@@ -48,12 +48,12 @@ struct sent {
|
|||||||
u32 wait_timeout;
|
u32 wait_timeout;
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct sent *find_sent_by_alias(const struct pubkey *alias)
|
static struct sent *find_sent_by_secret(const struct secret *pathsecret)
|
||||||
{
|
{
|
||||||
struct sent *i;
|
struct sent *i;
|
||||||
|
|
||||||
list_for_each(&sent_list, i, list) {
|
list_for_each(&sent_list, i, list) {
|
||||||
if (i->reply_alias && pubkey_eq(i->reply_alias, alias))
|
if (i->reply_secret && secret_eq_consttime(i->reply_secret, pathsecret))
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -409,18 +409,16 @@ static struct command_result *recv_modern_onion_message(struct command *cmd,
|
|||||||
const char *buf,
|
const char *buf,
|
||||||
const jsmntok_t *params)
|
const jsmntok_t *params)
|
||||||
{
|
{
|
||||||
const jsmntok_t *om, *aliastok;
|
const jsmntok_t *om, *secrettok;
|
||||||
struct sent *sent;
|
struct sent *sent;
|
||||||
struct pubkey alias;
|
struct secret pathsecret;
|
||||||
struct command_result *err;
|
struct command_result *err;
|
||||||
|
|
||||||
om = json_get_member(buf, params, "onion_message");
|
om = json_get_member(buf, params, "onion_message");
|
||||||
|
|
||||||
aliastok = json_get_member(buf, om, "our_alias");
|
secrettok = json_get_member(buf, om, "pathsecret");
|
||||||
if (!aliastok || !json_to_pubkey(buf, aliastok, &alias))
|
json_to_secret(buf, secrettok, &pathsecret);
|
||||||
return command_hook_success(cmd);
|
sent = find_sent_by_secret(&pathsecret);
|
||||||
|
|
||||||
sent = find_sent_by_alias(&alias);
|
|
||||||
if (!sent) {
|
if (!sent) {
|
||||||
plugin_log(cmd->plugin, LOG_DBG,
|
plugin_log(cmd->plugin, LOG_DBG,
|
||||||
"No match for modern onion %.*s",
|
"No match for modern onion %.*s",
|
||||||
@@ -703,11 +701,6 @@ static struct command_result *use_reply_path(struct command *cmd,
|
|||||||
json_tok_full_len(result),
|
json_tok_full_len(result),
|
||||||
json_tok_full(buf, result));
|
json_tok_full(buf, result));
|
||||||
|
|
||||||
/* Remember our alias we used so we can recognize reply */
|
|
||||||
sending->sent->reply_alias
|
|
||||||
= tal_dup(sending->sent, struct pubkey,
|
|
||||||
&rpath->path[tal_count(rpath->path)-1]->blinded_node_id);
|
|
||||||
|
|
||||||
return send_modern_message(cmd, rpath, sending);
|
return send_modern_message(cmd, rpath, sending);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -722,6 +715,10 @@ static struct command_result *make_reply_path(struct command *cmd,
|
|||||||
return command_fail(cmd, PAY_ROUTE_NOT_FOUND,
|
return command_fail(cmd, PAY_ROUTE_NOT_FOUND,
|
||||||
"Refusing to talk to ourselves");
|
"Refusing to talk to ourselves");
|
||||||
|
|
||||||
|
/* Create transient secret so we can validate reply! */
|
||||||
|
sending->sent->reply_secret = tal(sending->sent, struct secret);
|
||||||
|
randombytes_buf(sending->sent->reply_secret, sizeof(struct secret));
|
||||||
|
|
||||||
req = jsonrpc_request_start(cmd->plugin, cmd, "blindedpath",
|
req = jsonrpc_request_start(cmd->plugin, cmd, "blindedpath",
|
||||||
use_reply_path,
|
use_reply_path,
|
||||||
forward_error,
|
forward_error,
|
||||||
@@ -733,6 +730,7 @@ static struct command_result *make_reply_path(struct command *cmd,
|
|||||||
for (int i = nhops - 2; i >= 0; i--)
|
for (int i = nhops - 2; i >= 0; i--)
|
||||||
json_add_pubkey(req->js, NULL, &sending->sent->path[i]);
|
json_add_pubkey(req->js, NULL, &sending->sent->path[i]);
|
||||||
json_array_end(req->js);
|
json_array_end(req->js);
|
||||||
|
json_add_secret(req->js, "pathsecret", sending->sent->reply_secret);
|
||||||
return send_outreq(cmd->plugin, req);
|
return send_outreq(cmd->plugin, req);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1723,7 +1721,7 @@ static const char *init(struct plugin *p, const char *buf UNUSED,
|
|||||||
|
|
||||||
static const struct plugin_hook hooks[] = {
|
static const struct plugin_hook hooks[] = {
|
||||||
{
|
{
|
||||||
"onion_message_ourpath",
|
"onion_message_recv_secret",
|
||||||
recv_modern_onion_message
|
recv_modern_onion_message
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -127,7 +127,7 @@ static struct command_result *onion_message_modern_call(struct command *cmd,
|
|||||||
|
|
||||||
static const struct plugin_hook hooks[] = {
|
static const struct plugin_hook hooks[] = {
|
||||||
{
|
{
|
||||||
"onion_message_blinded",
|
"onion_message_recv",
|
||||||
onion_message_modern_call
|
onion_message_modern_call
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user