From 98fac9fb99b44e0dc24d212759af933b9ec16ddb Mon Sep 17 00:00:00 2001 From: Joost Jager Date: Tue, 11 Jun 2019 08:54:29 +0200 Subject: [PATCH] htlcswitch+invoices: always return incorrect_or_unknown_payment_details In order to prevent information leaks by nodes probing with a payment hash, this commit changes exit hop processing so that it always returns incorrect_or_unknown_payment_details and leaves the prober in the dark about whether an invoice actually exists. --- htlcswitch/link.go | 28 +++++--------------- htlcswitch/link_test.go | 6 ++--- invoices/invoiceregistry.go | 51 +++---------------------------------- 3 files changed, 14 insertions(+), 71 deletions(-) diff --git a/htlcswitch/link.go b/htlcswitch/link.go index f39e41aa..9e940529 100644 --- a/htlcswitch/link.go +++ b/htlcswitch/link.go @@ -1204,29 +1204,15 @@ func (l *channelLink) processHodlEvent(hodlEvent invoices.HodlEvent, ) } } else { - l.debugf("Received hodl cancel event for %v, reason=%v", - hash, hodlEvent.CancelReason) + l.debugf("Received hodl cancel event for %v", hash) hodlAction = func(htlc hodlHtlc) error { - var failure lnwire.FailureMessage - switch hodlEvent.CancelReason { - - case invoices.CancelAmountTooLow: - fallthrough - case invoices.CancelInvoiceUnknown: - fallthrough - case invoices.CancelInvoiceCanceled: - failure = lnwire.NewFailIncorrectDetails( - htlc.pd.Amount, - ) - - case invoices.CancelExpiryTooSoon: - failure = &lnwire.FailFinalExpiryTooSoon{} - - default: - return fmt.Errorf("unknown cancel reason: %v", - hodlEvent.CancelReason) - } + // In case of a cancel, always return + // incorrect_or_unknown_payment_details in order to + // avoid leaking info. + failure := lnwire.NewFailIncorrectDetails( + htlc.pd.Amount, + ) l.sendHTLCError( htlc.pd.HtlcIndex, failure, htlc.obfuscator, diff --git a/htlcswitch/link_test.go b/htlcswitch/link_test.go index 4635d231..31236e4e 100644 --- a/htlcswitch/link_test.go +++ b/htlcswitch/link_test.go @@ -1413,10 +1413,10 @@ func TestChannelLinkExpiryTooSoonExitNode(t *testing.T) { } switch ferr.FailureMessage.(type) { - case *lnwire.FailFinalExpiryTooSoon: + case *lnwire.FailIncorrectDetails: default: - t.Fatalf("incorrect error, expected final time lock too "+ - "early, instead have: %v", err) + t.Fatalf("expected incorrect_or_unknown_payment_details, "+ + "instead have: %v", err) } } diff --git a/invoices/invoiceregistry.go b/invoices/invoiceregistry.go index 9a7add0e..9d498581 100644 --- a/invoices/invoiceregistry.go +++ b/invoices/invoiceregistry.go @@ -28,41 +28,6 @@ var ( DebugHash = DebugPre.Hash() ) -// HtlcCancelReason defines reasons for which htlcs can be canceled. -type HtlcCancelReason uint8 - -const ( - // CancelInvoiceUnknown is returned if the preimage is unknown. - CancelInvoiceUnknown HtlcCancelReason = iota - - // CancelExpiryTooSoon is returned when the timelock of the htlc - // does not satisfy the invoice cltv expiry requirement. - CancelExpiryTooSoon - - // CancelInvoiceCanceled is returned when the invoice is already - // canceled and can't be paid to anymore. - CancelInvoiceCanceled - - // CancelAmountTooLow is returned when the amount paid is too low. - CancelAmountTooLow -) - -// String returns a human readable identifier for the cancel reason. -func (r HtlcCancelReason) String() string { - switch r { - case CancelInvoiceUnknown: - return "InvoiceUnknown" - case CancelExpiryTooSoon: - return "ExpiryTooSoon" - case CancelInvoiceCanceled: - return "InvoiceCanceled" - case CancelAmountTooLow: - return "CancelAmountTooLow" - default: - return "Unknown" - } -} - var ( // ErrInvoiceExpiryTooSoon is returned when an invoice is attempted to be // accepted or settled with not enough blocks remaining. @@ -82,10 +47,6 @@ type HodlEvent struct { // Hash is the htlc hash. Hash lntypes.Hash - - // CancelReason specifies the reason why invoice registry decided to - // cancel the htlc. - CancelReason HtlcCancelReason } // InvoiceRegistry is a central registry of all the outstanding invoices @@ -644,8 +605,7 @@ func (i *InvoiceRegistry) NotifyExitHopHtlc(rHash lntypes.Hash, debugLog("invoice already canceled") return &HodlEvent{ - Hash: rHash, - CancelReason: CancelInvoiceCanceled, + Hash: rHash, }, nil // If invoice is already accepted, add this htlc to the list of @@ -661,8 +621,7 @@ func (i *InvoiceRegistry) NotifyExitHopHtlc(rHash lntypes.Hash, debugLog("expiry too soon") return &HodlEvent{ - Hash: rHash, - CancelReason: CancelExpiryTooSoon, + Hash: rHash, }, nil // If there are not enough blocks left, cancel the htlc. @@ -670,8 +629,7 @@ func (i *InvoiceRegistry) NotifyExitHopHtlc(rHash lntypes.Hash, debugLog("amount too low") return &HodlEvent{ - Hash: rHash, - CancelReason: CancelAmountTooLow, + Hash: rHash, }, nil // If this call settled the invoice, settle the htlc. Otherwise @@ -750,8 +708,7 @@ func (i *InvoiceRegistry) CancelInvoice(payHash lntypes.Hash) error { log.Debugf("Invoice(%v): canceled", payHash) i.notifyHodlSubscribers(HodlEvent{ - Hash: payHash, - CancelReason: CancelInvoiceCanceled, + Hash: payHash, }) i.notifyClients(payHash, invoice, channeldb.ContractCanceled)