diff --git a/firewall/rule_enforcer.go b/firewall/rule_enforcer.go index db16269b..1ffe38ca 100644 --- a/firewall/rule_enforcer.go +++ b/firewall/rule_enforcer.go @@ -224,12 +224,7 @@ func (r *RuleEnforcer) handleRequest(ctx context.Context, return nil, fmt.Errorf("could not extract ID from macaroon") } - groupID, err := r.sessionDB.GetGroupID(sessionID) - if err != nil { - return nil, err - } - - rules, err := r.collectEnforcers(ri, groupID) + rules, err := r.collectEnforcers(ri, sessionID) if err != nil { return nil, fmt.Errorf("error parsing rules: %v", err) } @@ -269,12 +264,7 @@ func (r *RuleEnforcer) handleResponse(ctx context.Context, return nil, fmt.Errorf("could not extract ID from macaroon") } - groupID, err := r.sessionDB.GetGroupID(sessionID) - if err != nil { - return nil, err - } - - enforcers, err := r.collectEnforcers(ri, groupID) + enforcers, err := r.collectEnforcers(ri, sessionID) if err != nil { return nil, fmt.Errorf("error parsing rules: %v", err) } @@ -308,12 +298,7 @@ func (r *RuleEnforcer) handleErrorResponse(ctx context.Context, return nil, fmt.Errorf("could not extract ID from macaroon") } - groupID, err := r.sessionDB.GetGroupID(sessionID) - if err != nil { - return nil, err - } - - enforcers, err := r.collectEnforcers(ri, groupID) + enforcers, err := r.collectEnforcers(ri, sessionID) if err != nil { return nil, fmt.Errorf("error parsing rules: %v", err) } @@ -338,8 +323,8 @@ func (r *RuleEnforcer) handleErrorResponse(ctx context.Context, // collectRule initialises and returns all the Rules that need to be enforced // for the given request. -func (r *RuleEnforcer) collectEnforcers(ri *RequestInfo, groupID session.ID) ( - []rules.Enforcer, error) { +func (r *RuleEnforcer) collectEnforcers(ri *RequestInfo, + sessionID session.ID) ([]rules.Enforcer, error) { ruleEnforcers := make( []rules.Enforcer, 0, @@ -349,7 +334,7 @@ func (r *RuleEnforcer) collectEnforcers(ri *RequestInfo, groupID session.ID) ( for rule, value := range ri.Rules.FeatureRules[ri.MetaInfo.Feature] { r, err := r.initRule( ri.RequestID, rule, []byte(value), ri.MetaInfo.Feature, - groupID, false, ri.WithPrivacy, + sessionID, false, ri.WithPrivacy, ) if err != nil { return nil, err @@ -363,30 +348,40 @@ func (r *RuleEnforcer) collectEnforcers(ri *RequestInfo, groupID session.ID) ( // initRule initialises a rule.Rule with any required config values. func (r *RuleEnforcer) initRule(reqID uint64, name string, value []byte, - featureName string, groupID session.ID, sessionRule, - privacy bool) (rules.Enforcer, error) { + featureName string, sessionID session.ID, + sessionRule, privacy bool) (rules.Enforcer, error) { ruleValues, err := r.ruleMgrs.InitRuleValues(name, value) if err != nil { return nil, err } + session, err := r.sessionDB.GetSessionByID(sessionID) + if err != nil { + return nil, err + } + if privacy { - privMap := r.newPrivMap(groupID) - ruleValues, err = ruleValues.PseudoToReal(privMap) + privMap := r.newPrivMap(session.GroupID) + + ruleValues, err = ruleValues.PseudoToReal( + privMap, session.PrivacyFlags, + ) if err != nil { return nil, fmt.Errorf("could not prepare rule "+ "value: %v", err) } } - allActionsDB := r.actionsDB.GetActionsReadDB(groupID, featureName) + allActionsDB := r.actionsDB.GetActionsReadDB( + session.GroupID, featureName, + ) actionsDB := allActionsDB.GroupFeatureActionsDB() - rulesDB := r.ruleDB.GetKVStores(name, groupID, featureName) + rulesDB := r.ruleDB.GetKVStores(name, session.GroupID, featureName) if sessionRule { actionsDB = allActionsDB.GroupActionsDB() - rulesDB = r.ruleDB.GetKVStores(name, groupID, "") + rulesDB = r.ruleDB.GetKVStores(name, session.GroupID, "") } cfg := &rules.ConfigImpl{ diff --git a/rules/chan_policy_bounds.go b/rules/chan_policy_bounds.go index b20bcccb..ef939d7d 100644 --- a/rules/chan_policy_bounds.go +++ b/rules/chan_policy_bounds.go @@ -8,6 +8,7 @@ import ( "github.com/lightninglabs/lightning-terminal/firewalldb" "github.com/lightninglabs/lightning-terminal/litrpc" mid "github.com/lightninglabs/lightning-terminal/rpcmiddleware" + "github.com/lightninglabs/lightning-terminal/session" "github.com/lightningnetwork/lnd/lnrpc" "google.golang.org/protobuf/proto" ) @@ -318,8 +319,8 @@ func (f *ChanPolicyBounds) RuleName() string { // find the real values. This is a no-op for the ChanPolicyBounds rule. // // NOTE: this is part of the Values interface. -func (f *ChanPolicyBounds) PseudoToReal(_ firewalldb.PrivacyMapDB) (Values, - error) { +func (f *ChanPolicyBounds) PseudoToReal(_ firewalldb.PrivacyMapDB, + _ session.PrivacyFlags) (Values, error) { return f, nil } @@ -329,8 +330,8 @@ func (f *ChanPolicyBounds) PseudoToReal(_ firewalldb.PrivacyMapDB) (Values, // that should be persisted. This is a no-op for the ChanPolicyBounds rule. // // NOTE: this is part of the Values interface. -func (f *ChanPolicyBounds) RealToPseudo(_ firewalldb.PrivacyMapReader) (Values, - map[string]string, error) { +func (f *ChanPolicyBounds) RealToPseudo(_ firewalldb.PrivacyMapReader, + _ session.PrivacyFlags) (Values, map[string]string, error) { return f, nil, nil } diff --git a/rules/channel_restrictions.go b/rules/channel_restrictions.go index cf27a528..8594dde5 100644 --- a/rules/channel_restrictions.go +++ b/rules/channel_restrictions.go @@ -8,6 +8,7 @@ import ( "github.com/lightninglabs/lightning-terminal/firewalldb" "github.com/lightninglabs/lightning-terminal/litrpc" mid "github.com/lightninglabs/lightning-terminal/rpcmiddleware" + "github.com/lightninglabs/lightning-terminal/session" "github.com/lightningnetwork/lnd/lnrpc" "google.golang.org/protobuf/proto" ) @@ -334,10 +335,18 @@ func (c *ChannelRestrict) ToProto() *litrpc.RuleValue { // It constructs a new ChannelRestrict instance with these real channel IDs. // // NOTE: this is part of the Values interface. -func (c *ChannelRestrict) PseudoToReal(db firewalldb.PrivacyMapDB) (Values, - error) { +func (c *ChannelRestrict) PseudoToReal(db firewalldb.PrivacyMapDB, + flags session.PrivacyFlags) (Values, error) { restrictList := make([]uint64, len(c.DenyList)) + + // We don't obfuscate the channel IDs if the channel id flag is set. + if flags.Contains(session.ClearChanIDs) { + copy(restrictList, c.DenyList) + + return &ChannelRestrict{DenyList: restrictList}, nil + } + err := db.View(func(tx firewalldb.PrivacyMapTx) error { for i, chanID := range c.DenyList { real, err := firewalldb.RevealUint64(tx, chanID) @@ -349,15 +358,12 @@ func (c *ChannelRestrict) PseudoToReal(db firewalldb.PrivacyMapDB) (Values, } return nil - }, - ) + }) if err != nil { return nil, err } - return &ChannelRestrict{ - DenyList: restrictList, - }, nil + return &ChannelRestrict{DenyList: restrictList}, nil } // RealToPseudo converts all the real channel IDs into pseudo IDs. It returns a @@ -365,11 +371,19 @@ func (c *ChannelRestrict) PseudoToReal(db firewalldb.PrivacyMapDB) (Values, // not find in the given PrivacyMapReader. // // NOTE: this is part of the Values interface. -func (c *ChannelRestrict) RealToPseudo(db firewalldb.PrivacyMapReader) (Values, - map[string]string, error) { +func (c *ChannelRestrict) RealToPseudo(db firewalldb.PrivacyMapReader, + flags session.PrivacyFlags) (Values, map[string]string, error) { pseudoIDs := make([]uint64, len(c.DenyList)) privMapPairs := make(map[string]string) + + // We don't obfuscate the channel IDs if the channel id flag is set. + if flags.Contains(session.ClearChanIDs) { + copy(pseudoIDs, c.DenyList) + + return &ChannelRestrict{DenyList: pseudoIDs}, privMapPairs, nil + } + for i, c := range c.DenyList { // TODO(elle): check that this channel actually exists @@ -390,7 +404,5 @@ func (c *ChannelRestrict) RealToPseudo(db firewalldb.PrivacyMapReader) (Values, pseudoIDs[i] = pseudoCp } - return &ChannelRestrict{ - DenyList: pseudoIDs, - }, privMapPairs, nil + return &ChannelRestrict{DenyList: pseudoIDs}, privMapPairs, nil } diff --git a/rules/channel_restrictions_test.go b/rules/channel_restrictions_test.go index 1e7d00bb..d6ef6e8c 100644 --- a/rules/channel_restrictions_test.go +++ b/rules/channel_restrictions_test.go @@ -9,6 +9,7 @@ import ( "github.com/btcsuite/btcd/chaincfg/chainhash" "github.com/lightninglabs/lightning-terminal/firewalldb" + "github.com/lightninglabs/lightning-terminal/session" "github.com/lightninglabs/lndclient" "github.com/lightningnetwork/lnd/lnrpc" "github.com/stretchr/testify/require" @@ -173,6 +174,7 @@ func TestChannelRestrictRealToPseudo(t *testing.T) { tests := []struct { name string + privacyFlags session.PrivacyFlags dbPreLoad map[string]string expectNewPairs map[string]bool }{ @@ -200,6 +202,12 @@ func TestChannelRestrictRealToPseudo(t *testing.T) { chanID3: true, }, }, + { + name: "turned off mapping", + privacyFlags: session.PrivacyFlags{ + session.ClearChanIDs, + }, + }, } // Construct the ChannelRestrict deny list. Note that we repeat one of @@ -240,7 +248,9 @@ func TestChannelRestrictRealToPseudo(t *testing.T) { // rule. This will return the rule value in its pseudo // form along with any new privacy map pairs that should // be added to the DB. - v, newPairs, err := cr.RealToPseudo(privMapPairDB) + v, newPairs, err := cr.RealToPseudo( + privMapPairDB, test.privacyFlags, + ) require.NoError(t, err) require.Len(t, newPairs, len(test.expectNewPairs)) @@ -257,6 +267,16 @@ func TestChannelRestrictRealToPseudo(t *testing.T) { denyList, ok := v.(*ChannelRestrict) require.True(t, ok) + // We expect the original deny list if we switch off + // privacy mapping. + if test.privacyFlags.Contains( + session.ClearChanIDs) { + + for _, p := range cr.DenyList { + expectedDenyList[p] = true + } + } + // Assert that the resulting deny list is the same // length as the un-obfuscated one. require.Len(t, denyList.DenyList, len(cr.DenyList)) diff --git a/rules/history_limit.go b/rules/history_limit.go index 4d4ab95d..8ca0270f 100644 --- a/rules/history_limit.go +++ b/rules/history_limit.go @@ -8,6 +8,7 @@ import ( "github.com/lightninglabs/lightning-terminal/firewalldb" "github.com/lightninglabs/lightning-terminal/litrpc" mid "github.com/lightninglabs/lightning-terminal/rpcmiddleware" + "github.com/lightninglabs/lightning-terminal/session" "github.com/lightningnetwork/lnd/lnrpc" "google.golang.org/protobuf/proto" ) @@ -255,8 +256,8 @@ func (h *HistoryLimit) GetStartDate() time.Time { // find the real values. This is a no-op for the HistoryLimit rule. // // NOTE: this is part of the Values interface. -func (h *HistoryLimit) PseudoToReal(_ firewalldb.PrivacyMapDB) (Values, - error) { +func (h *HistoryLimit) PseudoToReal(_ firewalldb.PrivacyMapDB, + _ session.PrivacyFlags) (Values, error) { return h, nil } @@ -266,8 +267,8 @@ func (h *HistoryLimit) PseudoToReal(_ firewalldb.PrivacyMapDB) (Values, // that should be persisted. This is a no-op for the HistoryLimit rule. // // NOTE: this is part of the Values interface. -func (h *HistoryLimit) RealToPseudo(_ firewalldb.PrivacyMapReader) (Values, - map[string]string, error) { +func (h *HistoryLimit) RealToPseudo(_ firewalldb.PrivacyMapReader, + _ session.PrivacyFlags) (Values, map[string]string, error) { return h, nil, nil } diff --git a/rules/interfaces.go b/rules/interfaces.go index 83b09224..66fc27bf 100644 --- a/rules/interfaces.go +++ b/rules/interfaces.go @@ -6,6 +6,7 @@ import ( "github.com/lightninglabs/lightning-terminal/firewalldb" "github.com/lightninglabs/lightning-terminal/litrpc" + "github.com/lightninglabs/lightning-terminal/session" "google.golang.org/protobuf/proto" ) @@ -62,13 +63,14 @@ type Values interface { // keys, channel IDs, channel points etc. It returns a map of any new // real to pseudo strings that should be persisted that it did not find // in the given PrivacyMapReader. - RealToPseudo(db firewalldb.PrivacyMapReader) (Values, map[string]string, - error) + RealToPseudo(db firewalldb.PrivacyMapReader, + flags session.PrivacyFlags) (Values, map[string]string, error) // PseudoToReal attempts to convert any appropriate pseudo fields in // the rule Values to their corresponding real values. It uses the // passed PrivacyMapDB to find the real values. - PseudoToReal(db firewalldb.PrivacyMapDB) (Values, error) + PseudoToReal(db firewalldb.PrivacyMapDB, + flags session.PrivacyFlags) (Values, error) } // Marshal converts the rule Values to a json byte slice. diff --git a/rules/peer_restrictions.go b/rules/peer_restrictions.go index 793149c3..eff2dc1f 100644 --- a/rules/peer_restrictions.go +++ b/rules/peer_restrictions.go @@ -8,6 +8,7 @@ import ( "github.com/lightninglabs/lightning-terminal/firewalldb" "github.com/lightninglabs/lightning-terminal/litrpc" mid "github.com/lightninglabs/lightning-terminal/rpcmiddleware" + "github.com/lightninglabs/lightning-terminal/session" "github.com/lightninglabs/lndclient" "github.com/lightningnetwork/lnd/lnrpc" "google.golang.org/protobuf/proto" @@ -341,13 +342,21 @@ func (c *PeerRestrict) ToProto() *litrpc.RuleValue { // It constructs a new PeerRestrict instance with these real peer IDs. // // NOTE: this is part of the Values interface. -func (c *PeerRestrict) PseudoToReal(db firewalldb.PrivacyMapDB) (Values, - error) { +func (c *PeerRestrict) PseudoToReal(db firewalldb.PrivacyMapDB, + flags session.PrivacyFlags) (Values, error) { restrictList := make([]string, len(c.DenyList)) + + // We don't obfuscate if the clear pubkeys flag is set. + if flags.Contains(session.ClearPubkeys) { + copy(restrictList, c.DenyList) + + return &PeerRestrict{DenyList: restrictList}, nil + } + err := db.View(func(tx firewalldb.PrivacyMapTx) error { - for i, chanID := range c.DenyList { - real, err := firewalldb.RevealString(tx, chanID) + for i, peerPubKey := range c.DenyList { + real, err := firewalldb.RevealString(tx, peerPubKey) if err != nil { return err } @@ -362,9 +371,7 @@ func (c *PeerRestrict) PseudoToReal(db firewalldb.PrivacyMapDB) (Values, return nil, err } - return &PeerRestrict{ - DenyList: restrictList, - }, nil + return &PeerRestrict{DenyList: restrictList}, nil } // RealToPseudo converts all the real peer IDs into pseudo IDs. It returns a map @@ -372,11 +379,19 @@ func (c *PeerRestrict) PseudoToReal(db firewalldb.PrivacyMapDB) (Values, // find in the given PrivacyMapReader. // // NOTE: this is part of the Values interface. -func (c *PeerRestrict) RealToPseudo(db firewalldb.PrivacyMapReader) (Values, - map[string]string, error) { +func (c *PeerRestrict) RealToPseudo(db firewalldb.PrivacyMapReader, + flags session.PrivacyFlags) (Values, map[string]string, error) { pseudoIDs := make([]string, len(c.DenyList)) privMapPairs := make(map[string]string) + + // We don't obfuscate if the clear pubkeys flag is set. + if flags.Contains(session.ClearPubkeys) { + copy(pseudoIDs, c.DenyList) + + return &PeerRestrict{DenyList: pseudoIDs}, privMapPairs, nil + } + for i, id := range c.DenyList { // TODO(elle): check that this peer is actually one of our // channel peers. diff --git a/rules/peer_restrictions_test.go b/rules/peer_restrictions_test.go index b1f0af4c..ed93abab 100644 --- a/rules/peer_restrictions_test.go +++ b/rules/peer_restrictions_test.go @@ -8,6 +8,7 @@ import ( "github.com/btcsuite/btcd/chaincfg/chainhash" "github.com/lightninglabs/lightning-terminal/firewalldb" + "github.com/lightninglabs/lightning-terminal/session" "github.com/lightninglabs/lndclient" "github.com/lightningnetwork/lnd/lnrpc" "github.com/lightningnetwork/lnd/routing/route" @@ -157,6 +158,7 @@ func TestPeerRestrictCheckRequest(t *testing.T) { func TestPeerRestrictRealToPseudo(t *testing.T) { tests := []struct { name string + privacyFlags session.PrivacyFlags dbPreLoad map[string]string expectNewPairs map[string]bool }{ @@ -184,6 +186,12 @@ func TestPeerRestrictRealToPseudo(t *testing.T) { "peer 3": true, }, }, + { + name: "turned off mapping", + privacyFlags: []session.PrivacyFlag{ + session.ClearPubkeys, + }, + }, } // Construct the PeerRestrict deny list. Note that we repeat one of @@ -219,7 +227,9 @@ func TestPeerRestrictRealToPseudo(t *testing.T) { // rule. This will return the rule value in its pseudo // form along with any new privacy map pairs that should // be added to the DB. - v, newPairs, err := pr.RealToPseudo(privMapPairDB) + v, newPairs, err := pr.RealToPseudo( + privMapPairDB, test.privacyFlags, + ) require.NoError(t, err) require.Len(t, newPairs, len(test.expectNewPairs)) @@ -230,6 +240,14 @@ func TestPeerRestrictRealToPseudo(t *testing.T) { expectedDenyList[p] = true } + // We expect the original deny list if we switch off + // privacy mapping. + if test.privacyFlags.Contains(session.ClearPubkeys) { + for _, p := range pr.DenyList { + expectedDenyList[p] = true + } + } + // Assert that the element in the resulting deny list // matches all the elements in our expected deny list. denyList, ok := v.(*PeerRestrict) @@ -241,8 +259,8 @@ func TestPeerRestrictRealToPseudo(t *testing.T) { // Now iterate over the deny list and assert that each // value appears in our expected deny list. - for _, channel := range denyList.DenyList { - require.True(t, expectedDenyList[channel]) + for _, peer := range denyList.DenyList { + require.True(t, expectedDenyList[peer]) } }) } diff --git a/rules/rate_limit.go b/rules/rate_limit.go index ddafe9c9..8f776dcc 100644 --- a/rules/rate_limit.go +++ b/rules/rate_limit.go @@ -7,6 +7,7 @@ import ( "github.com/lightninglabs/lightning-terminal/firewalldb" "github.com/lightninglabs/lightning-terminal/litrpc" + "github.com/lightninglabs/lightning-terminal/session" "google.golang.org/protobuf/proto" "gopkg.in/macaroon-bakery.v2/bakery" ) @@ -266,8 +267,8 @@ func (r *RateLimit) ToProto() *litrpc.RuleValue { // find the real values. This is a no-op for the RateLimit rule. // // NOTE: this is part of the Values interface. -func (r *RateLimit) PseudoToReal(_ firewalldb.PrivacyMapDB) (Values, - error) { +func (r *RateLimit) PseudoToReal(_ firewalldb.PrivacyMapDB, + _ session.PrivacyFlags) (Values, error) { return r, nil } @@ -277,8 +278,8 @@ func (r *RateLimit) PseudoToReal(_ firewalldb.PrivacyMapDB) (Values, // that should be persisted. This is a no-op for the RateLimit rule. // // NOTE: this is part of the Values interface. -func (r *RateLimit) RealToPseudo(_ firewalldb.PrivacyMapReader) (Values, - map[string]string, error) { +func (r *RateLimit) RealToPseudo(_ firewalldb.PrivacyMapReader, + flags session.PrivacyFlags) (Values, map[string]string, error) { return r, nil, nil } diff --git a/session_rpcserver.go b/session_rpcserver.go index e2c5c91c..15623dae 100644 --- a/session_rpcserver.go +++ b/session_rpcserver.go @@ -948,6 +948,7 @@ func (s *sessionRpcServer) AddAutopilotSession(ctx context.Context, var privMapPairs map[string]string v, privMapPairs, err = v.RealToPseudo( knownPrivMapPairs, + session.PrivacyFlags{}, ) if err != nil { return nil, err @@ -1403,7 +1404,10 @@ func (s *sessionRpcServer) marshalRPCSession(sess *session.Session) ( db := s.cfg.privMap( sess.GroupID, ) - val, err = val.PseudoToReal(db) + val, err = val.PseudoToReal( + db, + session.PrivacyFlags{}, + ) if err != nil { return nil, err }