diff --git a/firewall/privacy_mapper.go b/firewall/privacy_mapper.go index 41db864f..7a2f8fe4 100644 --- a/firewall/privacy_mapper.go +++ b/firewall/privacy_mapper.go @@ -312,6 +312,12 @@ func (p *PrivacyMapper) checkers(db firewalldb.PrivacyMapDB, handleChannelOpenResponse(db, flags), mid.PassThroughErrorHandler, ), + + "/lnrpc.Lightning/ConnectPeer": mid.NewRequestRewriter( + &lnrpc.ConnectPeerRequest{}, + &lnrpc.ConnectPeerResponse{}, + handleConnectPeerRequest(db, flags), + ), } } @@ -1612,6 +1618,63 @@ func handleChannelOpenResponse(db firewalldb.PrivacyMapDB, } } +func handleConnectPeerRequest(db firewalldb.PrivacyMapDB, + flags session.PrivacyFlags) func(ctx context.Context, + r *lnrpc.ConnectPeerRequest) (proto.Message, error) { + + return func(_ context.Context, r *lnrpc.ConnectPeerRequest) ( + proto.Message, error) { + + var addr *lnrpc.LightningAddress + + err := db.View(func(tx firewalldb.PrivacyMapTx) error { + var err error + + // Note, this only works if the pubkey alias was + // already created via other calls, e.g. via + // ListChannels or GetNodeInfo. + pubkey := r.Addr.Pubkey + if !flags.Contains(session.ClearPubkeys) { + pubkey, err = firewalldb.RevealString( + tx, r.Addr.Pubkey, + ) + if err != nil { + return err + } + } + + host := r.Addr.Host + if !flags.Contains(session.ClearNetworkAddresses) { + host, err = firewalldb.RevealString( + tx, r.Addr.Host, + ) + if err != nil { + return err + } + } + + addr = &lnrpc.LightningAddress{ + Pubkey: pubkey, + Host: host, + } + + return nil + }) + if err != nil { + return nil, err + } + + return &lnrpc.ConnectPeerRequest{ + // Obfuscated fields. + Addr: addr, + + // Non-obfuscated fields. + Perm: r.Perm, + Timeout: r.Timeout, + }, nil + } +} + // maybeHideAmount hides an amount if the privacy flag is not set. func maybeHideAmount(flags session.PrivacyFlags, randIntn func(int) (int, error), a int64) (int64, error) { diff --git a/firewall/privacy_mapper_test.go b/firewall/privacy_mapper_test.go index 2a0d0a36..5c09c155 100644 --- a/firewall/privacy_mapper_test.go +++ b/firewall/privacy_mapper_test.go @@ -77,6 +77,7 @@ func TestPrivacyMapper(t *testing.T) { outPoint(clearTxID, 0): outPoint(obfusTxID0, obfusOut0), outPoint(clearTxID, 1): outPoint(obfusTxID1, obfusOut1), "01020304": "c8134495", + "secret-host.com": "sksiuekalkdoowurekdf", } var ( @@ -827,6 +828,45 @@ func TestPrivacyMapper(t *testing.T) { OutputIndex: 0, }, }, + + { + name: "ConnectPeer Request", + uri: "/lnrpc.Lightning/ConnectPeer", + msgType: rpcperms.TypeRequest, + msg: &lnrpc.ConnectPeerRequest{ + Addr: &lnrpc.LightningAddress{ + Pubkey: "c8134495", + Host: "sksiuekalkdoowurekdf", + }, + }, + expectedReplacement: &lnrpc.ConnectPeerRequest{ + Addr: &lnrpc.LightningAddress{ + Pubkey: "01020304", + Host: "secret-host.com", + }, + }, + }, + { + name: "ConnectPeer Request clear", + uri: "/lnrpc.Lightning/ConnectPeer", + msgType: rpcperms.TypeRequest, + msg: &lnrpc.ConnectPeerRequest{ + Addr: &lnrpc.LightningAddress{ + Pubkey: "c8134495", + Host: "secret-host.com", + }, + }, + privacyFlags: []session.PrivacyFlag{ + session.ClearPubkeys, + session.ClearNetworkAddresses, + }, + expectedReplacement: &lnrpc.ConnectPeerRequest{ + Addr: &lnrpc.LightningAddress{ + Pubkey: "c8134495", + Host: "secret-host.com", + }, + }, + }, } decodedID := &lnrpc.MacaroonId{ diff --git a/session/privacy_flags.go b/session/privacy_flags.go index e7db26ce..5cc8815b 100644 --- a/session/privacy_flags.go +++ b/session/privacy_flags.go @@ -45,16 +45,21 @@ const ( // ClearClosingTxIds is a privacy flag that indicates that the channel // closing transaction ids in the API should not be obfuscated. ClearClosingTxIds PrivacyFlag = 6 + + // ClearNetworkAddresses is a privacy flag that indicates that the + // network addresses in the API should not be obfuscated. + ClearNetworkAddresses PrivacyFlag = 7 ) var flagMap = map[PrivacyFlag]string{ - ClearPubkeys: "ClearPubkeys", - ClearAmounts: "ClearAmounts", - ClearChanIDs: "ClearChanIDs", - ClearTimeStamps: "ClearTimeStamps", - ClearChanInitiator: "ClearChanInitiator", - ClearHTLCs: "ClearHTLCs", - ClearClosingTxIds: "ClearClosingTxIds", + ClearPubkeys: "ClearPubkeys", + ClearAmounts: "ClearAmounts", + ClearChanIDs: "ClearChanIDs", + ClearTimeStamps: "ClearTimeStamps", + ClearChanInitiator: "ClearChanInitiator", + ClearHTLCs: "ClearHTLCs", + ClearClosingTxIds: "ClearClosingTxIds", + ClearNetworkAddresses: "ClearNetworkAddresses", } // String returns a string representation of the privacy flag. diff --git a/session/privacy_flags_test.go b/session/privacy_flags_test.go index e544839b..4a38d8b1 100644 --- a/session/privacy_flags_test.go +++ b/session/privacy_flags_test.go @@ -56,4 +56,9 @@ func TestPrivacyFlags(t *testing.T) { require.True(t, flags.Contains(ClearPubkeys)) require.True(t, flags.Contains(ClearAmounts)) require.False(t, flags.Contains(ClearChanIDs)) + + autoOpenFlags := PrivacyFlags{ClearPubkeys, ClearNetworkAddresses} + require.NoError(t, err) + require.Equal(t, "ClearPubkeys|ClearNetworkAddresses", + autoOpenFlags.String()) }