diff --git a/firewall/privacy_mapper.go b/firewall/privacy_mapper.go index fed4ba53..49aaf20f 100644 --- a/firewall/privacy_mapper.go +++ b/firewall/privacy_mapper.go @@ -106,9 +106,11 @@ func (p *PrivacyMapper) Intercept(ctx context.Context, "interception request: %v", err) } - sessionID, err := session.IDFromMacaroon(ri.Macaroon) + sessionID, err := ri.SessionID.UnwrapOrErr( + fmt.Errorf("no session ID found in request info"), + ) if err != nil { - return nil, fmt.Errorf("could not extract ID from macaroon") + return nil, err } log.Tracef("PrivacyMapper: Intercepting %v", ri) diff --git a/firewall/privacy_mapper_test.go b/firewall/privacy_mapper_test.go index 9dcc814b..61b24cd4 100644 --- a/firewall/privacy_mapper_test.go +++ b/firewall/privacy_mapper_test.go @@ -13,6 +13,7 @@ import ( "github.com/lightningnetwork/lnd/lnrpc" "github.com/lightningnetwork/lnd/rpcperms" "github.com/stretchr/testify/require" + "google.golang.org/grpc/metadata" "google.golang.org/protobuf/proto" "gopkg.in/macaroon-bakery.v2/bakery" "gopkg.in/macaroon.v2" @@ -907,6 +908,9 @@ func TestPrivacyMapper(t *testing.T) { rawMsg, err := proto.Marshal(test.msg) require.NoError(t, err) + md := make(metadata.MD) + session.AddToGRPCMetadata(md, sessionID) + interceptReq := &rpcperms.InterceptionRequest{ Type: test.msgType, Macaroon: mac, @@ -916,6 +920,7 @@ func TestPrivacyMapper(t *testing.T) { ProtoTypeName: string( proto.MessageName(test.msg), ), + CtxMetadataPairs: md, } mwReq, err := interceptReq.ToRPC(1, 2) @@ -1006,6 +1011,9 @@ func TestPrivacyMapper(t *testing.T) { amounts := make([]uint64, numSamples) timestamps := make([]uint64, numSamples) + md := make(metadata.MD) + session.AddToGRPCMetadata(md, sessionID) + for i := 0; i < numSamples; i++ { interceptReq := &rpcperms.InterceptionRequest{ Type: rpcperms.TypeResponse, @@ -1016,6 +1024,7 @@ func TestPrivacyMapper(t *testing.T) { ProtoTypeName: string( proto.MessageName(msg), ), + CtxMetadataPairs: md, } mwReq, err := interceptReq.ToRPC(1, 2) diff --git a/firewall/request_info.go b/firewall/request_info.go index 10a52493..fd312b71 100644 --- a/firewall/request_info.go +++ b/firewall/request_info.go @@ -4,7 +4,10 @@ import ( "fmt" "strings" + "github.com/lightninglabs/lightning-terminal/session" + "github.com/lightningnetwork/lnd/fn" "github.com/lightningnetwork/lnd/lnrpc" + "google.golang.org/grpc/metadata" "gopkg.in/macaroon.v2" ) @@ -25,6 +28,7 @@ const ( // RequestInfo stores the parsed representation of an incoming RPC middleware // request. type RequestInfo struct { + SessionID fn.Option[session.ID] MsgID uint64 RequestID uint64 MWRequestType string @@ -76,8 +80,22 @@ func NewInfoFromRequest(req *lnrpc.RPCMiddlewareRequest) (*RequestInfo, error) { return nil, fmt.Errorf("invalid request type: %T", t) } + md := make(metadata.MD) + for k, vs := range req.MetadataPairs { + for _, v := range vs.Values { + md.Append(k, v) + } + } + + sessionID, err := session.FromGRPCMetadata(md) + if err != nil { + return nil, fmt.Errorf("error extracting session ID "+ + "from request: %v", err) + } + ri.MsgID = req.MsgId ri.RequestID = req.RequestId + ri.SessionID = sessionID // If there is no macaroon in the request, then there is nothing left // to parse. diff --git a/firewall/request_logger.go b/firewall/request_logger.go index 3463dff2..0a98e645 100644 --- a/firewall/request_logger.go +++ b/firewall/request_logger.go @@ -194,6 +194,7 @@ func (r *RequestLogger) addNewAction(ctx context.Context, ri *RequestInfo, } actionReq := &firewalldb.AddActionReq{ + SessionID: ri.SessionID, MacaroonIdentifier: macaroonID, RPCMethod: ri.URI, } diff --git a/firewall/rule_enforcer.go b/firewall/rule_enforcer.go index 35f92c53..54d2b3a6 100644 --- a/firewall/rule_enforcer.go +++ b/firewall/rule_enforcer.go @@ -237,9 +237,11 @@ func (r *RuleEnforcer) Intercept(ctx context.Context, func (r *RuleEnforcer) handleRequest(ctx context.Context, ri *RequestInfo) (proto.Message, error) { - sessionID, err := session.IDFromMacaroon(ri.Macaroon) + sessionID, err := ri.SessionID.UnwrapOrErr( + fmt.Errorf("no session ID found in request info"), + ) if err != nil { - return nil, fmt.Errorf("could not extract ID from macaroon") + return nil, err } rules, err := r.collectEnforcers(ctx, ri, sessionID)