From 26a4562263454a0d4db6a4e099a3f7b460434ecf Mon Sep 17 00:00:00 2001 From: Slyghtning Date: Fri, 7 Mar 2025 09:56:54 +0100 Subject: [PATCH] itest: test for ip range checks for macaroons --- itest/lnd_macaroons_test.go | 72 ++++++++++++++++++++++++++++--------- 1 file changed, 56 insertions(+), 16 deletions(-) diff --git a/itest/lnd_macaroons_test.go b/itest/lnd_macaroons_test.go index b896d455a..936140508 100644 --- a/itest/lnd_macaroons_test.go +++ b/itest/lnd_macaroons_test.go @@ -37,9 +37,8 @@ func testMacaroonAuthentication(ht *lntest.HarnessTest) { name string run func(ctxt context.Context, t *testing.T) }{{ - // First test: Make sure we get an error if we use no macaroons - // but try to connect to a node that has macaroon authentication - // enabled. + // Make sure we get an error if we use no macaroons but try to + // connect to a node that has macaroon authentication enabled. name: "no macaroon", run: func(ctxt context.Context, t *testing.T) { conn, err := testNode.ConnectRPCWithMacaroon(nil) @@ -51,8 +50,7 @@ func testMacaroonAuthentication(ht *lntest.HarnessTest) { require.Contains(t, err.Error(), "expected 1 macaroon") }, }, { - // Second test: Ensure that an invalid macaroon also triggers an - // error. + // Ensure that an invalid macaroon also triggers an error. name: "invalid macaroon", run: func(ctxt context.Context, t *testing.T) { invalidMac, _ := macaroon.New( @@ -68,8 +66,7 @@ func testMacaroonAuthentication(ht *lntest.HarnessTest) { require.Contains(t, err.Error(), "invalid ID") }, }, { - // Third test: Try to access a write method with read-only - // macaroon. + // Try to access a write method with read-only macaroon. name: "read only macaroon", run: func(ctxt context.Context, t *testing.T) { readonlyMac, err := testNode.ReadMacaroon( @@ -85,8 +82,8 @@ func testMacaroonAuthentication(ht *lntest.HarnessTest) { require.Contains(t, err.Error(), "permission denied") }, }, { - // Fourth test: Check first-party caveat with timeout that - // expired 30 seconds ago. + // Check first-party caveat with timeout that expired 30 seconds + // ago. name: "expired macaroon", run: func(ctxt context.Context, t *testing.T) { readonlyMac, err := testNode.ReadMacaroon( @@ -106,7 +103,7 @@ func testMacaroonAuthentication(ht *lntest.HarnessTest) { require.Contains(t, err.Error(), "macaroon has expired") }, }, { - // Fifth test: Check first-party caveat with invalid IP address. + // Check first-party caveat with invalid IP address. name: "invalid IP macaroon", run: func(ctxt context.Context, t *testing.T) { readonlyMac, err := testNode.ReadMacaroon( @@ -128,7 +125,7 @@ func testMacaroonAuthentication(ht *lntest.HarnessTest) { require.Contains(t, err.Error(), "different IP address") }, }, { - // Sixth test: Make sure that if we do everything correct and + // Make sure that if we do everything correct and // send the admin macaroon with first-party caveats that we can // satisfy, we get a correct answer. name: "correct macaroon", @@ -149,8 +146,51 @@ func testMacaroonAuthentication(ht *lntest.HarnessTest) { assert.Contains(t, res.Address, "bcrt1") }, }, { - // Seventh test: Bake a macaroon that can only access exactly - // two RPCs and make sure it works as expected. + // Check first-party caveat with invalid IP range. + name: "invalid IP range macaroon", + run: func(ctxt context.Context, t *testing.T) { + readonlyMac, err := testNode.ReadMacaroon( + testNode.Cfg.ReadMacPath, defaultTimeout, + ) + require.NoError(t, err) + invalidIPRangeMac, err := macaroons.AddConstraints( + readonlyMac, macaroons.IPRangeLockConstraint( + "1.1.1.1/32", + ), + ) + require.NoError(t, err) + cleanup, client := macaroonClient( + t, testNode, invalidIPRangeMac, + ) + defer cleanup() + _, err = client.GetInfo(ctxt, infoReq) + require.Error(t, err) + require.Contains(t, err.Error(), "different IP range") + }, + }, { + // Make sure that if we do everything correct and send the admin + // macaroon with first-party caveats that we can satisfy, we get + // a correct answer. + name: "correct macaroon", + run: func(ctxt context.Context, t *testing.T) { + adminMac, err := testNode.ReadMacaroon( + testNode.Cfg.AdminMacPath, defaultTimeout, + ) + require.NoError(t, err) + adminMac, err = macaroons.AddConstraints( + adminMac, macaroons.TimeoutConstraint(30), + macaroons.IPRangeLockConstraint("127.0.0.0/8"), + ) + require.NoError(t, err) + cleanup, client := macaroonClient(t, testNode, adminMac) + defer cleanup() + res, err := client.NewAddress(ctxt, newAddrReq) + require.NoError(t, err, "get new address") + assert.Contains(t, res.Address, "bcrt1") + }, + }, { + // Bake a macaroon that can only access exactly two RPCs and + // make sure it works as expected. name: "custom URI permissions", run: func(ctxt context.Context, t *testing.T) { entity := macaroons.PermissionEntityCustomURI @@ -199,9 +239,9 @@ func testMacaroonAuthentication(ht *lntest.HarnessTest) { require.Contains(t, err.Error(), "permission denied") }, }, { - // Eighth test: check that with the CheckMacaroonPermissions - // RPC, we can check that a macaroon follows (or doesn't) - // permissions and constraints. + // Check that with the CheckMacaroonPermissions RPC, we can + // check that a macaroon follows (or doesn't) permissions and + // constraints. name: "unknown permissions", run: func(ctxt context.Context, t *testing.T) { // A test macaroon created with permissions from pool,