@@ -28,6 +28,7 @@ import (
28
28
"github.com/lightningnetwork/lnd/lnrpc"
29
29
"github.com/lightningnetwork/lnd/lnrpc/routerrpc"
30
30
"github.com/lightningnetwork/lnd/lnrpc/walletrpc"
31
+ "github.com/lightningnetwork/lnd/macaroons"
31
32
"github.com/stretchr/testify/require"
32
33
"golang.org/x/net/http2"
33
34
"google.golang.org/grpc"
@@ -224,6 +225,13 @@ var (
224
225
allowedThroughLNC : false ,
225
226
grpcWebURI : "/litrpc.Sessions/ListSessions" ,
226
227
}}
228
+
229
+ // customURIs is a map of endpoint URIs that we want to allow via a
230
+ // custom-macaroon session type.
231
+ customURIs = map [string ]bool {
232
+ "/lnrpc.Lightning/GetInfo" : true ,
233
+ "/frdrpc.FaradayServer/RevenueReport" : true ,
234
+ }
227
235
)
228
236
229
237
// testModeIntegrated makes sure that in integrated mode all daemons work
@@ -367,20 +375,109 @@ func testModeIntegrated(net *NetworkHarness, t *harnessTest) {
367
375
t .t .Run ("lnc auth" , func (tt * testing.T ) {
368
376
cfg := net .Alice .Cfg
369
377
378
+ ctx := context .Background ()
379
+ ctxt , cancel := context .WithTimeout (ctx , defaultTimeout )
380
+ defer cancel ()
381
+
382
+ rawLNCConn := setUpLNCConn (
383
+ ctxt , t .t , cfg .LitAddr (), cfg .TLSCertPath ,
384
+ cfg .LitMacPath ,
385
+ litrpc .SessionType_TYPE_MACAROON_READONLY , nil ,
386
+ )
387
+ defer rawLNCConn .Close ()
388
+
370
389
for _ , endpoint := range endpoints {
371
390
endpoint := endpoint
372
391
tt .Run (endpoint .name + " lit port" , func (ttt * testing.T ) {
373
392
runLNCAuthTest (
374
- ttt , cfg .LitAddr (), cfg .TLSCertPath ,
375
- cfg .LitMacPath , endpoint .requestFn ,
393
+ ttt , rawLNCConn , endpoint .requestFn ,
376
394
endpoint .successPattern ,
377
395
endpoint .allowedThroughLNC ,
396
+ "unknown service" ,
397
+ )
398
+ })
399
+ }
400
+ })
401
+
402
+ t .t .Run ("lnc auth custom mac perms" , func (tt * testing.T ) {
403
+ cfg := net .Alice .Cfg
404
+
405
+ ctx := context .Background ()
406
+ ctxt , cancel := context .WithTimeout (ctx , defaultTimeout )
407
+ defer cancel ()
408
+
409
+ customPerms := make (
410
+ []* litrpc.MacaroonPermission , 0 , len (customURIs ),
411
+ )
412
+
413
+ customURIKeyword := macaroons .PermissionEntityCustomURI
414
+ for uri := range customURIs {
415
+ customPerms = append (
416
+ customPerms , & litrpc.MacaroonPermission {
417
+ Entity : customURIKeyword ,
418
+ Action : uri ,
419
+ },
420
+ )
421
+ }
422
+
423
+ rawLNCConn := setUpLNCConn (
424
+ ctxt , t .t , cfg .LitAddr (), cfg .TLSCertPath ,
425
+ cfg .LitMacPath ,
426
+ litrpc .SessionType_TYPE_MACAROON_CUSTOM , customPerms ,
427
+ )
428
+ defer rawLNCConn .Close ()
429
+
430
+ for _ , endpoint := range endpoints {
431
+ endpoint := endpoint
432
+ tt .Run (endpoint .name + " lit port" , func (ttt * testing.T ) {
433
+ allowed := customURIs [endpoint .grpcWebURI ]
434
+ runLNCAuthTest (
435
+ ttt , rawLNCConn , endpoint .requestFn ,
436
+ endpoint .successPattern ,
437
+ allowed , "permission denied" ,
378
438
)
379
439
})
380
440
}
381
441
})
382
442
}
383
443
444
+ // setUpLNCConn creates a new LNC session and then creates a connection to that
445
+ // session via the mailbox that the session was created with.
446
+ func setUpLNCConn (ctx context.Context , t * testing.T , hostPort , tlsCertPath ,
447
+ macPath string , sessType litrpc.SessionType ,
448
+ customMacPerms []* litrpc.MacaroonPermission ) * grpc.ClientConn {
449
+
450
+ rawConn , err := connectRPC (ctx , hostPort , tlsCertPath )
451
+ require .NoError (t , err )
452
+
453
+ macBytes , err := ioutil .ReadFile (macPath )
454
+ require .NoError (t , err )
455
+ ctxm := macaroonContext (ctx , macBytes )
456
+
457
+ // We first need to create an LNC session that we can use to connect.
458
+ litClient := litrpc .NewSessionsClient (rawConn )
459
+ sessResp , err := litClient .AddSession (ctxm , & litrpc.AddSessionRequest {
460
+ Label : "integration-test" ,
461
+ SessionType : sessType ,
462
+ ExpiryTimestampSeconds : uint64 (
463
+ time .Now ().Add (5 * time .Minute ).Unix (),
464
+ ),
465
+ MailboxServerAddr : mailboxServerAddr ,
466
+ MacaroonCustomPermissions : customMacPerms ,
467
+ })
468
+ require .NoError (t , err )
469
+
470
+ // Try the LNC connection now.
471
+ connectPhrase := strings .Split (
472
+ sessResp .Session .PairingSecretMnemonic , " " ,
473
+ )
474
+
475
+ rawLNCConn , err := connectMailbox (ctx , connectPhrase )
476
+ require .NoError (t , err )
477
+
478
+ return rawLNCConn
479
+ }
480
+
384
481
// runCertificateCheck checks that the TLS certificates presented to clients are
385
482
// what we expect them to be.
386
483
func runCertificateCheck (t * testing.T , node * HarnessNode ) {
@@ -624,44 +721,15 @@ func runRESTAuthTest(t *testing.T, hostPort, uiPassword, macaroonPath, restURI,
624
721
625
722
// runLNCAuthTest tests authentication of the given interface when connecting
626
723
// through Lightning Node Connect.
627
- func runLNCAuthTest (t * testing.T , hostPort , tlsCertPath , macPath string ,
628
- makeRequest requestFn , successContent string , callAllowed bool ) {
629
-
630
- ctxb := context .Background ()
631
- ctxt , cancel := context .WithTimeout (ctxb , defaultTimeout )
632
- defer cancel ()
633
-
634
- rawConn , err := connectRPC (ctxt , hostPort , tlsCertPath )
635
- require .NoError (t , err )
724
+ func runLNCAuthTest (t * testing.T , rawLNCConn grpc.ClientConnInterface ,
725
+ makeRequest requestFn , successContent string , callAllowed bool ,
726
+ expectErrContains string ) {
636
727
637
- macBytes , err := ioutil .ReadFile (macPath )
638
- require .NoError (t , err )
639
- ctxm := macaroonContext (ctxt , macBytes )
640
-
641
- // We first need to create an LNC session that we can use to connect.
642
- // We use the UI password to create the session.
643
- litClient := litrpc .NewSessionsClient (rawConn )
644
- sessResp , err := litClient .AddSession (ctxm , & litrpc.AddSessionRequest {
645
- Label : "integration-test" ,
646
- SessionType : litrpc .SessionType_TYPE_MACAROON_READONLY ,
647
- ExpiryTimestampSeconds : uint64 (
648
- time .Now ().Add (5 * time .Minute ).Unix (),
649
- ),
650
- MailboxServerAddr : mailboxServerAddr ,
651
- })
652
- require .NoError (t , err )
653
-
654
- // Try the LNC connection now.
655
- connectPhrase := strings .Split (
656
- sessResp .Session .PairingSecretMnemonic , " " ,
728
+ ctxt , cancel := context .WithTimeout (
729
+ context .Background (), defaultTimeout ,
657
730
)
658
-
659
- ctxt , cancel = context .WithTimeout (ctxb , defaultTimeout )
660
731
defer cancel ()
661
732
662
- rawLNCConn , err := connectMailbox (ctxt , connectPhrase )
663
- require .NoError (t , err )
664
-
665
733
// We should be able to make a request via LNC to the given RPC
666
734
// endpoint, unless it is explicitly disallowed (we currently don't want
667
735
// to support creating more sessions through LNC until we have all
@@ -671,7 +739,7 @@ func runLNCAuthTest(t *testing.T, hostPort, tlsCertPath, macPath string,
671
739
// Is this a disallowed call?
672
740
if ! callAllowed {
673
741
require .Error (t , err )
674
- require .Contains (t , err .Error (), "unknown service" )
742
+ require .Contains (t , err .Error (), expectErrContains )
675
743
676
744
return
677
745
}
@@ -767,7 +835,7 @@ func getServerCertificates(hostPort string) ([]*x509.Certificate, error) {
767
835
// connectMailbox tries to establish a connection through LNC using the given
768
836
// connect phrase and the test mailbox server.
769
837
func connectMailbox (ctx context.Context ,
770
- connectPhrase []string ) (grpc.ClientConnInterface , error ) {
838
+ connectPhrase []string ) (* grpc.ClientConn , error ) {
771
839
772
840
var mnemonicWords [mailbox .NumPassphraseWords ]string
773
841
copy (mnemonicWords [:], connectPhrase )
0 commit comments