Skip to content

Commit 109c6eb

Browse files
rustyrussellcdecker
authored andcommitted
channeld: include proper sha value in BADONION errors.
Fortunately, we can calculate the sha256 ourselves, so the outgoing channeld doesn't need to tell us. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
1 parent 8f8783c commit 109c6eb

File tree

4 files changed

+30
-12
lines changed

4 files changed

+30
-12
lines changed

channeld/channeld.c

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -529,7 +529,8 @@ static void handle_peer_announcement_signatures(struct peer *peer, const u8 *msg
529529

530530
static struct secret *get_shared_secret(const tal_t *ctx,
531531
const struct htlc *htlc,
532-
enum onion_type *why_bad)
532+
enum onion_type *why_bad,
533+
struct sha256 *next_onion_sha)
533534
{
534535
struct pubkey ephemeral;
535536
struct onionpacket *op;
@@ -559,6 +560,10 @@ static struct secret *get_shared_secret(const tal_t *ctx,
559560
return tal_free(secret);
560561
}
561562

563+
/* Calculate sha256 we'll hand to next peer, in case they complain. */
564+
msg = serialize_onionpacket(tmpctx, rs->next);
565+
sha256(next_onion_sha, msg, tal_bytelen(msg));
566+
562567
return secret;
563568
}
564569

@@ -592,7 +597,8 @@ static void handle_peer_add_htlc(struct peer *peer, const u8 *msg)
592597
/* If this is wrong, we don't complain yet; when it's confirmed we'll
593598
* send it to the master which handles all HTLC failures. */
594599
htlc->shared_secret = get_shared_secret(htlc, htlc,
595-
&htlc->why_bad_onion);
600+
&htlc->why_bad_onion,
601+
&htlc->next_onion_sha);
596602
}
597603

598604
static void handle_peer_feechange(struct peer *peer, const u8 *msg)
@@ -1799,12 +1805,10 @@ static void send_fail_or_fulfill(struct peer *peer, const struct htlc *h)
17991805
} else if (h->failcode || h->fail) {
18001806
const u8 *onion;
18011807
if (h->failcode) {
1802-
/* FIXME: we need sha256_of_onion from peer. */
1803-
struct sha256 dummy;
1804-
memset(&dummy, 0, sizeof(dummy));
18051808
/* Local failure, make a message. */
18061809
u8 *failmsg = make_failmsg(tmpctx, peer, h, h->failcode,
1807-
h->failed_scid, &dummy);
1810+
h->failed_scid,
1811+
&h->next_onion_sha);
18081812
onion = create_onionreply(tmpctx, h->shared_secret,
18091813
failmsg);
18101814
} else /* Remote failure, just forward. */
@@ -2613,7 +2617,8 @@ static void init_shared_secrets(struct channel *channel,
26132617

26142618
htlc = channel_get_htlc(channel, REMOTE, htlcs[i].id);
26152619
htlc->shared_secret = get_shared_secret(htlc, htlc,
2616-
&htlc->why_bad_onion);
2620+
&htlc->why_bad_onion,
2621+
&htlc->next_onion_sha);
26172622
}
26182623
}
26192624

channeld/channeld_htlc.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ struct htlc {
2525
struct secret *shared_secret;
2626
/* If incoming HTLC has shared_secret, this is which BADONION error */
2727
enum onion_type why_bad_onion;
28+
/* sha256 of next_onion, in case peer says it was malformed. */
29+
struct sha256 next_onion_sha;
2830

2931
/* FIXME: We could union these together: */
3032
/* Routing information sent with this HTLC. */

lightningd/pay.c

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -359,10 +359,8 @@ remote_routing_failure(const tal_t *ctx,
359359
/* If the error is a BADONION, then it's on behalf of the
360360
* following node. */
361361
if (failcode & BADONION) {
362-
log_debug(log, "failcode %u => erring_node %s",
363-
failcode,
364-
type_to_string(tmpctx, struct pubkey,
365-
&route_nodes[origin_index + 1]));
362+
log_debug(log, "failcode %u from onionreply %s",
363+
failcode, tal_hex(tmpctx, failure->msg));
366364
erring_node = &route_nodes[origin_index + 1];
367365
} else
368366
erring_node = &route_nodes[origin_index];

tests/test_misc.py

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import json
99
import os
1010
import pytest
11+
import re
1112
import shutil
1213
import signal
1314
import socket
@@ -1137,9 +1138,11 @@ def test_check_command(node_factory):
11371138
sock.close()
11381139

11391140

1141+
@unittest.skipIf(not DEVELOPER, "need log_all_io")
11401142
def test_bad_onion(node_factory, bitcoind):
11411143
"""Test that we get a reasonable error from sendpay when an onion is bad"""
1142-
l1, l2, l3, l4 = node_factory.line_graph(4, wait_for_announce=True)
1144+
l1, l2, l3, l4 = node_factory.line_graph(4, wait_for_announce=True,
1145+
opts={'log_all_io': True})
11431146

11441147
h = l4.rpc.invoice(123000, 'test_bad_onion', 'description')['payment_hash']
11451148
route = l1.rpc.getroute(l4.info['id'], 123000, 1)['route']
@@ -1163,6 +1166,16 @@ def test_bad_onion(node_factory, bitcoind):
11631166
assert err.value.error['data']['erring_node'] == mangled_nodeid
11641167
assert err.value.error['data']['erring_channel'] == route[2]['channel']
11651168

1169+
# We should see a WIRE_UPDATE_FAIL_MALFORMED_HTLC from l4.
1170+
line = l4.daemon.is_in_log(r'\[OUT\] 0087')
1171+
# 008739d3149a5c37e95f9dae718ce46efc60248e110e10117d384870a6762e8e33030000000000000000d7fc52f6c32773aabca55628fe616058aecc44a384e0abfa85c0c48b449dd38dc005
1172+
# type<--------------channelid---------------------------------------><--htlc-id-----><--------------------------------------------- sha_of_onion --->code
1173+
sha = re.search(r' 0087.{64}.{16}(.{64})', line).group(1)
1174+
1175+
# Should see same sha in onionreply
1176+
line = l1.daemon.is_in_log(r'failcode .* from onionreply .*')
1177+
assert re.search(r'onionreply .*{}'.format(sha), line)
1178+
11661179
# Replace id with a different pubkey, so onion encoded badly at second hop.
11671180
route[1]['id'] = mangled_nodeid
11681181
l1.rpc.sendpay(route, h)

0 commit comments

Comments
 (0)