Skip to content

Commit a14d7ae

Browse files
committed
firewall: map session ID to group ID in privacy mapper interceptor
1 parent 60c10bd commit a14d7ae

File tree

3 files changed

+66
-16
lines changed

3 files changed

+66
-16
lines changed

firewall/privacy_mapper.go

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -46,16 +46,22 @@ var _ mid.RequestInterceptor = (*PrivacyMapper)(nil)
4646
// PrivacyMapper is a RequestInterceptor that maps any pseudo names in certain
4747
// requests to their real values and vice versa for responses.
4848
type PrivacyMapper struct {
49-
newDB firewalldb.NewPrivacyMapDB
50-
randIntn func(int) (int, error)
49+
newDB firewalldb.NewPrivacyMapDB
50+
randIntn func(int) (int, error)
51+
sessionIDIndexDB session.IDToGroupIndex
5152
}
5253

5354
// NewPrivacyMapper returns a new instance of PrivacyMapper. The randIntn
5455
// function is used to draw randomness for request field obfuscation.
5556
func NewPrivacyMapper(newDB firewalldb.NewPrivacyMapDB,
56-
randIntn func(int) (int, error)) *PrivacyMapper {
57+
randIntn func(int) (int, error),
58+
sessionIDIndexDB session.IDToGroupIndex) *PrivacyMapper {
5759

58-
return &PrivacyMapper{newDB: newDB, randIntn: randIntn}
60+
return &PrivacyMapper{
61+
newDB: newDB,
62+
randIntn: randIntn,
63+
sessionIDIndexDB: sessionIDIndexDB,
64+
}
5965
}
6066

6167
// Name returns the name of the interceptor.
@@ -91,6 +97,12 @@ func (p *PrivacyMapper) Intercept(ctx context.Context,
9197
return nil, fmt.Errorf("could not extract ID from macaroon")
9298
}
9399

100+
// Get group ID for session ID.
101+
groupID, err := p.sessionIDIndexDB.GetGroupID(sessionID)
102+
if err != nil {
103+
return nil, err
104+
}
105+
94106
log.Tracef("PrivacyMapper: Intercepting %v", ri)
95107

96108
switch r := req.InterceptType.(type) {
@@ -108,7 +120,7 @@ func (p *PrivacyMapper) Intercept(ctx context.Context,
108120
}
109121

110122
replacement, err := p.checkAndReplaceIncomingRequest(
111-
ctx, r.Request.MethodFullUri, msg, sessionID,
123+
ctx, r.Request.MethodFullUri, msg, groupID,
112124
)
113125
if err != nil {
114126
return mid.RPCErr(req, err)
@@ -142,7 +154,7 @@ func (p *PrivacyMapper) Intercept(ctx context.Context,
142154
}
143155

144156
replacement, err := p.replaceOutgoingResponse(
145-
ctx, r.Response.MethodFullUri, msg, sessionID,
157+
ctx, r.Response.MethodFullUri, msg, groupID,
146158
)
147159
if err != nil {
148160
return mid.RPCErr(req, err)
@@ -167,10 +179,10 @@ func (p *PrivacyMapper) Intercept(ctx context.Context,
167179
// checkAndReplaceIncomingRequest inspects an incoming request and optionally
168180
// modifies some of the request parameters.
169181
func (p *PrivacyMapper) checkAndReplaceIncomingRequest(ctx context.Context,
170-
uri string, req proto.Message, sessionID session.ID) (proto.Message,
182+
uri string, req proto.Message, groupID session.ID) (proto.Message,
171183
error) {
172184

173-
db := p.newDB(sessionID)
185+
db := p.newDB(groupID)
174186

175187
// If we don't have a handler for the URI, we don't allow the request
176188
// to go through.
@@ -193,9 +205,9 @@ func (p *PrivacyMapper) checkAndReplaceIncomingRequest(ctx context.Context,
193205
// replaceOutgoingResponse inspects the responses before sending them out to the
194206
// client and replaces them if needed.
195207
func (p *PrivacyMapper) replaceOutgoingResponse(ctx context.Context, uri string,
196-
resp proto.Message, sessionID session.ID) (proto.Message, error) {
208+
resp proto.Message, groupID session.ID) (proto.Message, error) {
197209

198-
db := p.newDB(sessionID)
210+
db := p.newDB(groupID)
199211

200212
// If we don't have a handler for the URI, we don't allow the response
201213
// to go to avoid accidental leaks.

firewall/privacy_mapper_test.go

Lines changed: 43 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package firewall
22

33
import (
44
"context"
5+
"fmt"
56
"testing"
67
"time"
78

@@ -292,9 +293,12 @@ func TestPrivacyMapper(t *testing.T) {
292293

293294
db := newMockDB(t, mapPreloadRealToPseudo, sessionID)
294295

296+
err = db.AddSessionAndGroupIDPair(sessionID, sessionID)
297+
require.NoError(t, err)
298+
295299
// randIntn is used for deterministic testing.
296300
randIntn := func(n int) (int, error) { return 100, nil }
297-
p := NewPrivacyMapper(db.NewSessionDB, randIntn)
301+
p := NewPrivacyMapper(db.NewSessionDB, randIntn, db)
298302

299303
for _, test := range tests {
300304
t.Run(test.name, func(t *testing.T) {
@@ -355,7 +359,7 @@ func TestPrivacyMapper(t *testing.T) {
355359
rawMsg, err := proto.Marshal(msg)
356360
require.NoError(t, err)
357361

358-
p = NewPrivacyMapper(db.NewSessionDB, CryptoRandIntn)
362+
p = NewPrivacyMapper(db.NewSessionDB, CryptoRandIntn, db)
359363
require.NoError(t, err)
360364

361365
// We test the independent outgoing amount (incoming amount
@@ -440,12 +444,21 @@ func TestPrivacyMapper(t *testing.T) {
440444
})
441445
}
442446

443-
type mockDB map[string]*mockPrivacyMapDB
447+
type mockDB struct {
448+
privDB map[string]*mockPrivacyMapDB
449+
450+
sessionIDIndex map[session.ID]session.ID
451+
groupIDIndex map[session.ID][]session.ID
452+
}
444453

445454
func newMockDB(t *testing.T, preloadRealToPseudo map[string]string,
446455
sessID session.ID) mockDB {
447456

448-
db := make(mockDB)
457+
db := mockDB{
458+
privDB: make(map[string]*mockPrivacyMapDB),
459+
sessionIDIndex: make(map[session.ID]session.ID),
460+
groupIDIndex: make(map[session.ID][]session.ID),
461+
}
449462
sessDB := db.NewSessionDB(sessID)
450463

451464
_ = sessDB.Update(func(tx firewalldb.PrivacyMapTx) error {
@@ -459,17 +472,41 @@ func newMockDB(t *testing.T, preloadRealToPseudo map[string]string,
459472
}
460473

461474
func (m mockDB) NewSessionDB(sessionID session.ID) firewalldb.PrivacyMapDB {
462-
db, ok := m[string(sessionID[:])]
475+
db, ok := m.privDB[string(sessionID[:])]
463476
if ok {
464477
return db
465478
}
466479

467480
newDB := newMockPrivacyMapDB()
468-
m[string(sessionID[:])] = newDB
481+
m.privDB[string(sessionID[:])] = newDB
469482

470483
return newDB
471484
}
472485

486+
func (m mockDB) AddSessionAndGroupIDPair(sessionID, groupID session.ID) error {
487+
m.sessionIDIndex[sessionID] = groupID
488+
m.groupIDIndex[groupID] = append(m.groupIDIndex[groupID], sessionID)
489+
return nil
490+
}
491+
492+
func (m mockDB) GetGroupID(sessionID session.ID) (session.ID, error) {
493+
groupID, ok := m.sessionIDIndex[sessionID]
494+
if !ok {
495+
return session.ID{}, fmt.Errorf("group ID not found")
496+
}
497+
498+
return groupID, nil
499+
}
500+
501+
func (m mockDB) GetSessionIDs(groupID session.ID) ([]session.ID, error) {
502+
sessionIDs, ok := m.groupIDIndex[groupID]
503+
if !ok {
504+
return nil, fmt.Errorf("group ID not found")
505+
}
506+
507+
return sessionIDs, nil
508+
}
509+
473510
func newMockPrivacyMapDB() *mockPrivacyMapDB {
474511
return &mockPrivacyMapDB{
475512
r2p: make(map[string]string),

terminal.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -814,6 +814,7 @@ func (g *LightningTerminal) startInternalSubServers(
814814

815815
privacyMapper := firewall.NewPrivacyMapper(
816816
g.firewallDB.PrivacyDB, firewall.CryptoRandIntn,
817+
g.sessionDB,
817818
)
818819

819820
mw := []mid.RequestInterceptor{

0 commit comments

Comments
 (0)