Skip to content

Commit f011bc8

Browse files
committed
multi: validate macaroons for lit calls
Use the new macaroon service to verify LitURI calls.
1 parent 50cfd3b commit f011bc8

File tree

6 files changed

+81
-116
lines changed

6 files changed

+81
-116
lines changed

itest/litd_mode_integrated_test.go

Lines changed: 53 additions & 96 deletions
Original file line numberDiff line numberDiff line change
@@ -134,81 +134,60 @@ var (
134134
ctx, &litrpc.ListSessionsRequest{},
135135
)
136136
}
137+
litMacaroonFn = func(cfg *LitNodeConfig) string {
138+
return cfg.LitMacPath
139+
}
137140

138141
endpoints = []struct {
139-
name string
140-
macaroonFn macaroonFn
141-
requestFn requestFn
142-
successPattern string
143-
supportsMacAuthOnLndPort bool
144-
supportsMacAuthOnLitPort bool
145-
supportsUIPasswordOnLndPort bool
146-
supportsUIPasswordOnLitPort bool
147-
allowedThroughLNC bool
148-
grpcWebURI string
149-
restWebURI string
142+
name string
143+
macaroonFn macaroonFn
144+
requestFn requestFn
145+
successPattern string
146+
allowedThroughLNC bool
147+
grpcWebURI string
148+
restWebURI string
150149
}{{
151-
name: "lnrpc",
152-
macaroonFn: lndMacaroonFn,
153-
requestFn: lndRequestFn,
154-
successPattern: "\"identity_pubkey\":\"0",
155-
supportsMacAuthOnLndPort: true,
156-
supportsMacAuthOnLitPort: true,
157-
supportsUIPasswordOnLndPort: false,
158-
supportsUIPasswordOnLitPort: true,
159-
allowedThroughLNC: true,
160-
grpcWebURI: "/lnrpc.Lightning/GetInfo",
161-
restWebURI: "/v1/getinfo",
150+
name: "lnrpc",
151+
macaroonFn: lndMacaroonFn,
152+
requestFn: lndRequestFn,
153+
successPattern: "\"identity_pubkey\":\"0",
154+
allowedThroughLNC: true,
155+
grpcWebURI: "/lnrpc.Lightning/GetInfo",
156+
restWebURI: "/v1/getinfo",
162157
}, {
163-
name: "frdrpc",
164-
macaroonFn: faradayMacaroonFn,
165-
requestFn: faradayRequestFn,
166-
successPattern: "\"reports\":[]",
167-
supportsMacAuthOnLndPort: true,
168-
supportsMacAuthOnLitPort: true,
169-
supportsUIPasswordOnLndPort: false,
170-
supportsUIPasswordOnLitPort: true,
171-
allowedThroughLNC: true,
172-
grpcWebURI: "/frdrpc.FaradayServer/RevenueReport",
173-
restWebURI: "/v1/faraday/revenue",
158+
name: "frdrpc",
159+
macaroonFn: faradayMacaroonFn,
160+
requestFn: faradayRequestFn,
161+
successPattern: "\"reports\":[]",
162+
allowedThroughLNC: true,
163+
grpcWebURI: "/frdrpc.FaradayServer/RevenueReport",
164+
restWebURI: "/v1/faraday/revenue",
174165
}, {
175-
name: "looprpc",
176-
macaroonFn: loopMacaroonFn,
177-
requestFn: loopRequestFn,
178-
successPattern: "\"swaps\":[]",
179-
supportsMacAuthOnLndPort: true,
180-
supportsMacAuthOnLitPort: true,
181-
supportsUIPasswordOnLndPort: false,
182-
supportsUIPasswordOnLitPort: true,
183-
allowedThroughLNC: true,
184-
grpcWebURI: "/looprpc.SwapClient/ListSwaps",
185-
restWebURI: "/v1/loop/swaps",
166+
name: "looprpc",
167+
macaroonFn: loopMacaroonFn,
168+
requestFn: loopRequestFn,
169+
successPattern: "\"swaps\":[]",
170+
allowedThroughLNC: true,
171+
grpcWebURI: "/looprpc.SwapClient/ListSwaps",
172+
restWebURI: "/v1/loop/swaps",
186173
}, {
187-
name: "poolrpc",
188-
macaroonFn: poolMacaroonFn,
189-
requestFn: poolRequestFn,
190-
successPattern: "\"accounts_active\":0",
191-
supportsMacAuthOnLndPort: true,
192-
supportsMacAuthOnLitPort: true,
193-
supportsUIPasswordOnLndPort: false,
194-
supportsUIPasswordOnLitPort: true,
195-
allowedThroughLNC: true,
196-
grpcWebURI: "/poolrpc.Trader/GetInfo",
197-
restWebURI: "/v1/pool/info",
174+
name: "poolrpc",
175+
macaroonFn: poolMacaroonFn,
176+
requestFn: poolRequestFn,
177+
successPattern: "\"accounts_active\":0",
178+
allowedThroughLNC: true,
179+
grpcWebURI: "/poolrpc.Trader/GetInfo",
180+
restWebURI: "/v1/pool/info",
198181
}, {
199182
name: "litrpc",
200-
macaroonFn: nil,
183+
macaroonFn: litMacaroonFn,
201184
requestFn: litRequestFn,
202185
// In some test cases we actually expect some sessions, so we
203186
// don't explicitly check for an empty array but just the
204187
// existence of the array in the response.
205-
successPattern: "\"sessions\":[",
206-
supportsMacAuthOnLndPort: false,
207-
supportsMacAuthOnLitPort: false,
208-
supportsUIPasswordOnLndPort: true,
209-
supportsUIPasswordOnLitPort: true,
210-
allowedThroughLNC: false,
211-
grpcWebURI: "/litrpc.Sessions/ListSessions",
188+
successPattern: "\"sessions\":[",
189+
allowedThroughLNC: false,
190+
grpcWebURI: "/litrpc.Sessions/ListSessions",
212191
}}
213192
)
214193

@@ -236,10 +215,6 @@ func testModeIntegrated(net *NetworkHarness, t *harnessTest) {
236215
for _, endpoint := range endpoints {
237216
endpoint := endpoint
238217
tt.Run(endpoint.name+" lnd port", func(ttt *testing.T) {
239-
if !endpoint.supportsMacAuthOnLndPort {
240-
return
241-
}
242-
243218
runGRPCAuthTest(
244219
ttt, cfg.RPCAddr(), cfg.TLSCertPath,
245220
endpoint.macaroonFn(cfg),
@@ -249,10 +224,6 @@ func testModeIntegrated(net *NetworkHarness, t *harnessTest) {
249224
})
250225

251226
tt.Run(endpoint.name+" lit port", func(ttt *testing.T) {
252-
if !endpoint.supportsMacAuthOnLitPort {
253-
return
254-
}
255-
256227
runGRPCAuthTest(
257228
ttt, cfg.LitAddr(), cfg.TLSCertPath,
258229
endpoint.macaroonFn(cfg),
@@ -271,20 +242,16 @@ func testModeIntegrated(net *NetworkHarness, t *harnessTest) {
271242
tt.Run(endpoint.name+" lnd port", func(ttt *testing.T) {
272243
runUIPasswordCheck(
273244
ttt, cfg.RPCAddr(), cfg.TLSCertPath,
274-
cfg.UIPassword,
275-
endpoint.requestFn, true,
276-
!endpoint.supportsUIPasswordOnLndPort,
277-
endpoint.successPattern,
245+
cfg.UIPassword, endpoint.requestFn,
246+
true, endpoint.successPattern,
278247
)
279248
})
280249

281250
tt.Run(endpoint.name+" lit port", func(ttt *testing.T) {
282251
runUIPasswordCheck(
283252
ttt, cfg.LitAddr(), cfg.TLSCertPath,
284-
cfg.UIPassword,
285-
endpoint.requestFn, false,
286-
!endpoint.supportsUIPasswordOnLitPort,
287-
endpoint.successPattern,
253+
cfg.UIPassword, endpoint.requestFn,
254+
false, endpoint.successPattern,
288255
)
289256
})
290257
}
@@ -321,10 +288,6 @@ func testModeIntegrated(net *NetworkHarness, t *harnessTest) {
321288
for _, endpoint := range endpoints {
322289
endpoint := endpoint
323290
tt.Run(endpoint.name+" lnd port", func(ttt *testing.T) {
324-
if !endpoint.supportsMacAuthOnLndPort {
325-
return
326-
}
327-
328291
runGRPCAuthTest(
329292
ttt, cfg.RPCAddr(), cfg.TLSCertPath,
330293
superMacFile,
@@ -334,10 +297,6 @@ func testModeIntegrated(net *NetworkHarness, t *harnessTest) {
334297
})
335298

336299
tt.Run(endpoint.name+" lit port", func(ttt *testing.T) {
337-
if !endpoint.supportsMacAuthOnLitPort {
338-
return
339-
}
340-
341300
runGRPCAuthTest(
342301
ttt, cfg.LitAddr(), cfg.TLSCertPath,
343302
superMacFile,
@@ -454,8 +413,8 @@ func runGRPCAuthTest(t *testing.T, hostPort, tlsCertPath, macPath string,
454413

455414
// runUIPasswordCheck tests UI password authentication.
456415
func runUIPasswordCheck(t *testing.T, hostPort, tlsCertPath, uiPassword string,
457-
makeRequest requestFn, shouldFailWithoutMacaroon,
458-
shouldFailWithDummyMacaroon bool, successContent string) {
416+
makeRequest requestFn, shouldFailWithoutMacaroon bool,
417+
successContent string) {
459418

460419
ctxb := context.Background()
461420
ctxt, cancel := context.WithTimeout(ctxb, defaultTimeout)
@@ -503,13 +462,11 @@ func runUIPasswordCheck(t *testing.T, hostPort, tlsCertPath, uiPassword string,
503462
ctxm = uiPasswordContext(ctxt, uiPassword, true)
504463
resp, err = makeRequest(ctxm, rawConn)
505464

506-
if shouldFailWithDummyMacaroon {
507-
require.Error(t, err)
508-
require.Contains(
509-
t, err.Error(), "cannot get macaroon: root",
510-
)
511-
return
512-
}
465+
require.Error(t, err)
466+
require.Contains(
467+
t, err.Error(), "cannot get macaroon: root",
468+
)
469+
return
513470
}
514471

515472
// We expect the call to succeed.

itest/litd_mode_remote_test.go

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -43,10 +43,6 @@ func testModeRemote(net *NetworkHarness, t *harnessTest) {
4343
for _, endpoint := range endpoints {
4444
endpoint := endpoint
4545
tt.Run(endpoint.name+" lit port", func(ttt *testing.T) {
46-
if !endpoint.supportsMacAuthOnLitPort {
47-
return
48-
}
49-
5046
runGRPCAuthTest(
5147
ttt, cfg.LitAddr(), cfg.LitTLSCertPath,
5248
endpoint.macaroonFn(cfg),
@@ -65,10 +61,8 @@ func testModeRemote(net *NetworkHarness, t *harnessTest) {
6561
tt.Run(endpoint.name+" lit port", func(ttt *testing.T) {
6662
runUIPasswordCheck(
6763
ttt, cfg.LitAddr(), cfg.LitTLSCertPath,
68-
cfg.UIPassword,
69-
endpoint.requestFn, false,
70-
!endpoint.supportsUIPasswordOnLitPort,
71-
endpoint.successPattern,
64+
cfg.UIPassword, endpoint.requestFn,
65+
false, endpoint.successPattern,
7266
)
7367
})
7468
}
@@ -105,10 +99,6 @@ func testModeRemote(net *NetworkHarness, t *harnessTest) {
10599
for _, endpoint := range endpoints {
106100
endpoint := endpoint
107101
tt.Run(endpoint.name+" lit port", func(ttt *testing.T) {
108-
if !endpoint.supportsMacAuthOnLitPort {
109-
return
110-
}
111-
112102
runGRPCAuthTest(
113103
ttt, cfg.LitAddr(), cfg.LitTLSCertPath,
114104
superMacFile,

itest/litd_node.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ type LitNodeConfig struct {
6767
LoopMacPath string
6868
PoolMacPath string
6969
LitTLSCertPath string
70+
LitMacPath string
7071

7172
UIPassword string
7273
LitDir string
@@ -279,6 +280,9 @@ func newNode(cfg *LitNodeConfig, harness *NetworkHarness) (*HarnessNode, error)
279280
cfg.PoolMacPath = filepath.Join(
280281
cfg.PoolDir, cfg.NetParams.Name, "pool.macaroon",
281282
)
283+
cfg.LitMacPath = filepath.Join(
284+
cfg.LitDir, cfg.NetParams.Name, "lit.macaroon",
285+
)
282286
cfg.LitTLSCertPath = filepath.Join(cfg.LitDir, "tls.cert")
283287
cfg.GenerateListeningPorts()
284288

rpc_proxy.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -537,7 +537,7 @@ func (p *rpcProxy) basicAuthToMacaroon(basicAuth, requestURI string,
537537
}
538538

539539
case isLitURI(requestURI):
540-
return EmptyMacaroonBytes, nil
540+
macPath = p.cfg.MacaroonPath
541541

542542
default:
543543
return nil, fmt.Errorf("unknown gRPC web request: %v",

subserver_permissions.go

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,18 @@ var (
1212
// litPermissions is a map of all LiT RPC methods and their required
1313
// macaroon permissions to access the session service.
1414
litPermissions = map[string][]bakery.Op{
15-
"/litrpc.Sessions/AddSession": {{}},
16-
"/litrpc.Sessions/ListSessions": {{}},
17-
"/litrpc.Sessions/RevokeSession": {{}},
15+
"/litrpc.Sessions/AddSession": {{
16+
Entity: "sessions",
17+
Action: "write",
18+
}},
19+
"/litrpc.Sessions/ListSessions": {{
20+
Entity: "sessions",
21+
Action: "read",
22+
}},
23+
"/litrpc.Sessions/RevokeSession": {{
24+
Entity: "sessions",
25+
Action: "write",
26+
}},
1827
}
1928

2029
// whiteListedMethods is a map of all lnd RPC methods that don't require

terminal.go

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -775,12 +775,17 @@ func (g *LightningTerminal) ValidateMacaroon(ctx context.Context,
775775
}
776776

777777
case isLitURI(fullMethod):
778-
wrap := fmt.Errorf("invalid basic auth")
779-
_, err := g.rpcProxy.convertBasicAuth(ctx, fullMethod, wrap)
780-
if err != nil {
778+
if !g.macaroonServiceStarted {
779+
return fmt.Errorf("the macaroon service has not " +
780+
"started yet")
781+
}
782+
783+
if err := g.macaroonService.ValidateMacaroon(
784+
ctx, requiredPermissions, fullMethod,
785+
); err != nil {
781786
return &proxyErr{
782787
proxyContext: "lit",
783-
wrapped: fmt.Errorf("invalid auth: %v",
788+
wrapped: fmt.Errorf("invalid macaroon: %w",
784789
err),
785790
}
786791
}

0 commit comments

Comments
 (0)