diff --git a/docs/release-notes/release-notes-0.14.2.md b/docs/release-notes/release-notes-0.14.2.md index b473e5d17..094438654 100644 --- a/docs/release-notes/release-notes-0.14.2.md +++ b/docs/release-notes/release-notes-0.14.2.md @@ -92,6 +92,10 @@ Postgres](https://github.com/lightningnetwork/lnd/pull/6111) exposed](https://github.com/lightningnetwork/lnd/pull/6146) inside WaitingCloseResp from calling `PendingChannels`. +* [CustomCaveatCondition is now properly + set](https://github.com/lightningnetwork/lnd/pull/6185) on + `RPCMiddlewareRequest` messages. + ## Routing @@ -104,6 +108,7 @@ Postgres](https://github.com/lightningnetwork/lnd/pull/6111) * Andras Banki-Horvath * Bjarne Magnussen +* Daniel McNally * Elle Mouton * Harsha Goli * Joost Jager diff --git a/lntest/itest/lnd_rpc_middleware_interceptor_test.go b/lntest/itest/lnd_rpc_middleware_interceptor_test.go index 48be71fca..ebc6676bf 100644 --- a/lntest/itest/lnd_rpc_middleware_interceptor_test.go +++ b/lntest/itest/lnd_rpc_middleware_interceptor_test.go @@ -195,7 +195,7 @@ func middlewareInterceptionTest(t *testing.T, node *lntest.HarnessNode, // block the execution of the main task otherwise. req := &lnrpc.ListChannelsRequest{ActiveOnly: true} go registration.interceptUnary( - "/lnrpc.Lightning/ListChannels", req, nil, + "/lnrpc.Lightning/ListChannels", req, nil, readOnly, ) // Do the actual call now and wait for the interceptor to do its thing. @@ -208,7 +208,7 @@ func middlewareInterceptionTest(t *testing.T, node *lntest.HarnessNode, // Let's test the same for a streaming endpoint. req2 := &lnrpc.PeerEventSubscription{} go registration.interceptStream( - "/lnrpc.Lightning/SubscribePeerEvents", req2, nil, + "/lnrpc.Lightning/SubscribePeerEvents", req2, nil, readOnly, ) // Do the actual call now and wait for the interceptor to do its thing. @@ -327,6 +327,7 @@ func middlewareManipulationTest(t *testing.T, node *lntest.HarnessNode, req := &lnrpc.ListChannelsRequest{ActiveOnly: true} go registration.interceptUnary( "/lnrpc.Lightning/ListChannels", req, replacementResponse, + readOnly, ) // Do the actual call now and wait for the interceptor to do its thing. @@ -349,7 +350,7 @@ func middlewareManipulationTest(t *testing.T, node *lntest.HarnessNode, req2 := &lnrpc.PeerEventSubscription{} go registration.interceptStream( "/lnrpc.Lightning/SubscribePeerEvents", req2, - replacementResponse2, + replacementResponse2, readOnly, ) // Do the actual call now and wait for the interceptor to do its thing. @@ -522,11 +523,21 @@ func registerMiddleware(t *testing.T, node *lntest.HarnessNode, // NOTE: Must be called in a goroutine as this will block until the response is // read from the response channel. func (h *middlewareHarness) interceptUnary(methodURI string, - expectedRequest proto.Message, responseReplacement proto.Message) { + expectedRequest proto.Message, responseReplacement proto.Message, + readOnly bool) { // Read intercept message and make sure it's for an RPC request. reqIntercept, err := h.stream.Recv() require.NoError(h.t, err) + + // Make sure the custom condition is populated correctly (if we're using + // a macaroon with a custom condition). + if !readOnly { + require.Equal( + h.t, "itest-value", reqIntercept.CustomCaveatCondition, + ) + } + req := reqIntercept.GetRequest() require.NotNil(h.t, req) @@ -564,11 +575,21 @@ func (h *middlewareHarness) interceptUnary(methodURI string, // NOTE: Must be called in a goroutine as this will block until the first // response is read from the response channel. func (h *middlewareHarness) interceptStream(methodURI string, - expectedRequest proto.Message, responseReplacement proto.Message) { + expectedRequest proto.Message, responseReplacement proto.Message, + readOnly bool) { // Read intercept message and make sure it's for an RPC stream auth. authIntercept, err := h.stream.Recv() require.NoError(h.t, err) + + // Make sure the custom condition is populated correctly (if we're using + // a macaroon with a custom condition). + if !readOnly { + require.Equal( + h.t, "itest-value", authIntercept.CustomCaveatCondition, + ) + } + auth := authIntercept.GetStreamAuth() require.NotNil(h.t, auth) diff --git a/rpcperms/interceptor.go b/rpcperms/interceptor.go index 7be2f0ea0..0065cdf47 100644 --- a/rpcperms/interceptor.go +++ b/rpcperms/interceptor.go @@ -910,7 +910,7 @@ func (r *InterceptorChain) middlewareRegistered() bool { // acceptRequest sends an intercept request to all middlewares that have // registered for it. This means either a middleware has requested read-only -// access or the request actually has a macaroon which a caveat the middleware +// access or the request actually has a macaroon with a caveat the middleware // registered for. func (r *InterceptorChain) acceptRequest(requestID uint64, msg *InterceptionRequest) error { @@ -929,6 +929,10 @@ func (r *InterceptorChain) acceptRequest(requestID uint64, continue } + msg.CustomCaveatCondition = macaroons.GetCustomCaveatCondition( + msg.Macaroon, middleware.customCaveatName, + ) + resp, err := middleware.intercept(requestID, msg) // Error during interception itself. @@ -975,6 +979,10 @@ func (r *InterceptorChain) interceptResponse(ctx context.Context, continue } + msg.CustomCaveatCondition = macaroons.GetCustomCaveatCondition( + msg.Macaroon, middleware.customCaveatName, + ) + resp, err := middleware.intercept(requestID, msg) // Error during interception itself.