Skip to content

Commit b5f84a5

Browse files
committed
multi: extract session ID from context
1 parent c0fba9a commit b5f84a5

9 files changed

+178
-34
lines changed

firewall/privacy_mapper.go

+4-2
Original file line numberDiff line numberDiff line change
@@ -106,9 +106,11 @@ func (p *PrivacyMapper) Intercept(ctx context.Context,
106106
"interception request: %v", err)
107107
}
108108

109-
sessionID, err := session.IDFromMacaroon(ri.Macaroon)
109+
sessionID, ok, err := ri.extractSessionID()
110110
if err != nil {
111-
return nil, fmt.Errorf("could not extract ID from macaroon")
111+
return nil, fmt.Errorf("could not extract session ID: %v", err)
112+
} else if !ok {
113+
return nil, fmt.Errorf("no session ID found in request")
112114
}
113115

114116
log.Tracef("PrivacyMapper: Intercepting %v", ri)

firewall/request_info.go

+45
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@ import (
44
"fmt"
55
"strings"
66

7+
"github.com/lightninglabs/lightning-terminal/session"
78
"github.com/lightningnetwork/lnd/lnrpc"
9+
"google.golang.org/grpc/metadata"
810
"gopkg.in/macaroon.v2"
911
)
1012

@@ -38,18 +40,27 @@ type RequestInfo struct {
3840
MetaInfo *InterceptMetaInfo
3941
Rules *InterceptRules
4042
WithPrivacy bool
43+
MDPairs metadata.MD
4144
}
4245

4346
// NewInfoFromRequest parses the given RPC middleware interception request and
4447
// returns a RequestInfo struct.
4548
func NewInfoFromRequest(req *lnrpc.RPCMiddlewareRequest) (*RequestInfo, error) {
49+
md := make(metadata.MD)
50+
for k, vs := range req.MetadataPairs {
51+
for _, v := range vs.Values {
52+
md.Append(k, v)
53+
}
54+
}
55+
4656
var ri *RequestInfo
4757
switch t := req.InterceptType.(type) {
4858
case *lnrpc.RPCMiddlewareRequest_StreamAuth:
4959
ri = &RequestInfo{
5060
MWRequestType: MWRequestTypeStreamAuth,
5161
URI: t.StreamAuth.MethodFullUri,
5262
Streaming: true,
63+
MDPairs: md,
5364
}
5465

5566
case *lnrpc.RPCMiddlewareRequest_Request:
@@ -60,6 +71,7 @@ func NewInfoFromRequest(req *lnrpc.RPCMiddlewareRequest) (*RequestInfo, error) {
6071
IsError: t.Request.IsError,
6172
Serialized: t.Request.Serialized,
6273
Streaming: t.Request.StreamRpc,
74+
MDPairs: md,
6375
}
6476

6577
case *lnrpc.RPCMiddlewareRequest_Response:
@@ -70,6 +82,7 @@ func NewInfoFromRequest(req *lnrpc.RPCMiddlewareRequest) (*RequestInfo, error) {
7082
IsError: t.Response.IsError,
7183
Serialized: t.Response.Serialized,
7284
Streaming: t.Response.StreamRpc,
85+
MDPairs: md,
7386
}
7487

7588
default:
@@ -134,3 +147,35 @@ func (ri *RequestInfo) String() string {
134147
ri.GRPCMessageType, ri.Streaming, strings.Join(ri.Caveats, ","),
135148
ri.MetaInfo, ri.Rules)
136149
}
150+
151+
func (ri *RequestInfo) extractSessionID() (session.ID, bool, error) {
152+
// First prize is to extract the session ID from the MD pairs.
153+
id, ok, err := session.FromGrpcMD(ri.MDPairs)
154+
if err != nil {
155+
return id, ok, err
156+
} else if ok {
157+
return id, ok, nil
158+
}
159+
160+
// TODO(elle): This is a temporary workaround to support older versions
161+
// of LND that don't attach metadata pairs to the request.
162+
// We should remove this once we have bumped our minimum compatible
163+
// LND version to one that always attaches metadata pairs.
164+
// This is because the macaroon root key ID is not a reliable way of
165+
// extracting the session ID since the macaroon root key ID may also
166+
// be the first 4 bytes of an account ID and so collisions are possible
167+
// here.
168+
169+
// Otherwise, fall back to extracting the session ID from the macaroon.
170+
if ri.Macaroon == nil {
171+
return session.ID{}, false, nil
172+
}
173+
174+
id, err = session.IDFromMacaroon(ri.Macaroon)
175+
if err != nil {
176+
return session.ID{}, false, fmt.Errorf("could not extract "+
177+
"ID from macaroon: %w", err)
178+
}
179+
180+
return id, true, nil
181+
}

firewall/request_logger.go

+5-7
Original file line numberDiff line numberDiff line change
@@ -184,13 +184,11 @@ func (r *RequestLogger) addNewAction(ri *RequestInfo,
184184

185185
// If no macaroon is provided, then an empty 4-byte array is used as the
186186
// session ID. Otherwise, the macaroon is used to derive a session ID.
187-
var sessionID [4]byte
188-
if ri.Macaroon != nil {
189-
var err error
190-
sessionID, err = session.IDFromMacaroon(ri.Macaroon)
191-
if err != nil {
192-
return fmt.Errorf("could not extract ID from macaroon")
193-
}
187+
var sessionID session.ID
188+
if sessID, ok, err := ri.extractSessionID(); err != nil {
189+
return fmt.Errorf("could not extract session ID: %v", err)
190+
} else if ok {
191+
sessionID = sessID
194192
}
195193

196194
action := &firewalldb.Action{

firewall/rule_enforcer.go

+4-2
Original file line numberDiff line numberDiff line change
@@ -233,9 +233,11 @@ func (r *RuleEnforcer) Intercept(ctx context.Context,
233233
func (r *RuleEnforcer) handleRequest(ctx context.Context,
234234
ri *RequestInfo) (proto.Message, error) {
235235

236-
sessionID, err := session.IDFromMacaroon(ri.Macaroon)
236+
sessionID, ok, err := ri.extractSessionID()
237237
if err != nil {
238-
return nil, fmt.Errorf("could not extract ID from macaroon")
238+
return nil, fmt.Errorf("could not extract session ID: %v", err)
239+
} else if !ok {
240+
return nil, fmt.Errorf("no session ID found in request")
239241
}
240242

241243
rules, err := r.collectEnforcers(ctx, ri, sessionID)

go.mod

+9-5
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ require (
66
github.com/btcsuite/btcd/btcutil v1.1.5
77
github.com/btcsuite/btcd/chaincfg/chainhash v1.1.0
88
github.com/btcsuite/btclog/v2 v2.0.1-0.20250110154127-3ae4bf1cb318
9-
github.com/btcsuite/btcwallet/walletdb v1.4.4
9+
github.com/btcsuite/btcwallet/walletdb v1.5.1
1010
github.com/davecgh/go-spew v1.1.1
1111
github.com/go-errors/errors v1.0.1
1212
github.com/golang-migrate/migrate/v4 v4.17.0
@@ -34,7 +34,7 @@ require (
3434
github.com/lightningnetwork/lnd/clock v1.1.1
3535
github.com/lightningnetwork/lnd/fn v1.2.3
3636
github.com/lightningnetwork/lnd/fn/v2 v2.0.8
37-
github.com/lightningnetwork/lnd/kvdb v1.4.13
37+
github.com/lightningnetwork/lnd/kvdb v1.4.15
3838
github.com/lightningnetwork/lnd/tlv v1.3.0
3939
github.com/lightningnetwork/lnd/tor v1.1.6
4040
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f
@@ -68,11 +68,11 @@ require (
6868
github.com/beorn7/perks v1.0.1 // indirect
6969
github.com/btcsuite/btcd/btcutil/psbt v1.1.10 // indirect
7070
github.com/btcsuite/btclog v0.0.0-20241003133417-09c4e92e319c // indirect
71-
github.com/btcsuite/btcwallet v0.16.12 // indirect
71+
github.com/btcsuite/btcwallet v0.16.13 // indirect
7272
github.com/btcsuite/btcwallet/wallet/txauthor v1.3.5 // indirect
7373
github.com/btcsuite/btcwallet/wallet/txrules v1.2.2 // indirect
7474
github.com/btcsuite/btcwallet/wallet/txsizes v1.2.5 // indirect
75-
github.com/btcsuite/btcwallet/wtxmgr v1.5.4 // indirect
75+
github.com/btcsuite/btcwallet/wtxmgr v1.5.6 // indirect
7676
github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd // indirect
7777
github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792 // indirect
7878
github.com/btcsuite/winsvc v1.0.0 // indirect
@@ -144,7 +144,7 @@ require (
144144
github.com/lightningnetwork/lightning-onion v1.2.1-0.20240712235311-98bd56499dfb // indirect
145145
github.com/lightningnetwork/lnd/healthcheck v1.2.6 // indirect
146146
github.com/lightningnetwork/lnd/queue v1.1.1 // indirect
147-
github.com/lightningnetwork/lnd/sqldb v1.0.7 // indirect
147+
github.com/lightningnetwork/lnd/sqldb v1.0.9 // indirect
148148
github.com/lightningnetwork/lnd/ticker v1.1.1 // indirect
149149
github.com/ltcsuite/ltcd v0.0.0-20190101042124-f37f8bf35796 // indirect
150150
github.com/mattn/go-isatty v0.0.20 // indirect
@@ -238,3 +238,7 @@ replace (
238238
replace google.golang.org/protobuf => github.com/lightninglabs/protobuf-go-hex-display v1.34.2-hex-display
239239

240240
go 1.23.6
241+
242+
replace github.com/lightninglabs/lndclient => github.com/ellemouton/lndclient v1.0.1-0.20250420083827-f6ba7f319771
243+
244+
replace github.com/lightningnetwork/lnd => github.com/ellemouton/lnd v0.8.0-beta-rc3.0.20250420082546-0054b82f488c

go.sum

+14-14
Original file line numberDiff line numberDiff line change
@@ -674,18 +674,18 @@ github.com/btcsuite/btclog v0.0.0-20241003133417-09c4e92e319c/go.mod h1:w7xnGOhw
674674
github.com/btcsuite/btclog/v2 v2.0.1-0.20250110154127-3ae4bf1cb318 h1:oCjIcinPt7XQ644MP/22JcjYEC84qRc3bRBH0d7Hhd4=
675675
github.com/btcsuite/btclog/v2 v2.0.1-0.20250110154127-3ae4bf1cb318/go.mod h1:XItGUfVOxotJL8kkuk2Hj3EVow5KCugXl3wWfQ6K0AE=
676676
github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg=
677-
github.com/btcsuite/btcwallet v0.16.12 h1:9SREKY892i1xTGlGLcu6x7O+WSQFn6+uQrSuskAOqh0=
678-
github.com/btcsuite/btcwallet v0.16.12/go.mod h1:jBn+ThFrx/QqW0nXiGvXtJytju4aVoW7C0hY4s/+9vo=
677+
github.com/btcsuite/btcwallet v0.16.13 h1:JGu+wrihQ0I00ODb3w92JtBPbrHxZhbcvU01O+e+lKw=
678+
github.com/btcsuite/btcwallet v0.16.13/go.mod h1:H6dfoZcWPonM2wbVsR2ZBY0PKNZKdQyLAmnX8vL9JFA=
679679
github.com/btcsuite/btcwallet/wallet/txauthor v1.3.5 h1:Rr0njWI3r341nhSPesKQ2JF+ugDSzdPoeckS75SeDZk=
680680
github.com/btcsuite/btcwallet/wallet/txauthor v1.3.5/go.mod h1:+tXJ3Ym0nlQc/iHSwW1qzjmPs3ev+UVWMbGgfV1OZqU=
681681
github.com/btcsuite/btcwallet/wallet/txrules v1.2.2 h1:YEO+Lx1ZJJAtdRrjuhXjWrYsmAk26wLTlNzxt2q0lhk=
682682
github.com/btcsuite/btcwallet/wallet/txrules v1.2.2/go.mod h1:4v+grppsDpVn91SJv+mZT7B8hEV4nSmpREM4I8Uohws=
683683
github.com/btcsuite/btcwallet/wallet/txsizes v1.2.5 h1:93o5Xz9dYepBP4RMFUc9RGIFXwqP2volSWRkYJFrNtI=
684684
github.com/btcsuite/btcwallet/wallet/txsizes v1.2.5/go.mod h1:lQ+e9HxZ85QP7r3kdxItkiMSloSLg1PEGis5o5CXUQw=
685-
github.com/btcsuite/btcwallet/walletdb v1.4.4 h1:BDel6iT/ltYSIYKs0YbjwnEDi7xR3yzABIsQxN2F1L8=
686-
github.com/btcsuite/btcwallet/walletdb v1.4.4/go.mod h1:jk/hvpLFINF0C1kfTn0bfx2GbnFT+Nvnj6eblZALfjs=
687-
github.com/btcsuite/btcwallet/wtxmgr v1.5.4 h1:hJjHy1h/dJwSfD9uDsCwcH21D1iOrus6OrI5gR9E/O0=
688-
github.com/btcsuite/btcwallet/wtxmgr v1.5.4/go.mod h1:lAv0b1Vj9Ig5U8QFm0yiJ9WqPl8yGO/6l7JxdHY1PKE=
685+
github.com/btcsuite/btcwallet/walletdb v1.5.1 h1:HgMhDNCrtEFPC+8q0ei5DQ5U9Tl4RCspA22DEKXlopI=
686+
github.com/btcsuite/btcwallet/walletdb v1.5.1/go.mod h1:jk/hvpLFINF0C1kfTn0bfx2GbnFT+Nvnj6eblZALfjs=
687+
github.com/btcsuite/btcwallet/wtxmgr v1.5.6 h1:Zwvr/rrJYdOLqdBCSr4eICEstnEA+NBUvjIWLkrXaYI=
688+
github.com/btcsuite/btcwallet/wtxmgr v1.5.6/go.mod h1:lzVbDkk/jRao2ib5kge46aLZW1yFc8RFNycdYpnsmZA=
689689
github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd h1:R/opQEbFEy9JGkIguV40SvRY1uliPX8ifOvi6ICsFCw=
690690
github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg=
691691
github.com/btcsuite/golangcrypto v0.0.0-20150304025918-53f62d9b43e8/go.mod h1:tYvUd8KLhm/oXvUeSEs2VlLghFjQt9+ZaF9ghH0JNjc=
@@ -782,6 +782,10 @@ github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3
782782
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
783783
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
784784
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
785+
github.com/ellemouton/lnd v0.8.0-beta-rc3.0.20250420082546-0054b82f488c h1:s7MHib5gBaRubKGT46Q5ikPCf1lMM+gAGdDKTIuDBuI=
786+
github.com/ellemouton/lnd v0.8.0-beta-rc3.0.20250420082546-0054b82f488c/go.mod h1:BP+neeFpmeAA7o5hu3zp3FwOEl26idSyPV9zBOavp6E=
787+
github.com/ellemouton/lndclient v1.0.1-0.20250420083827-f6ba7f319771 h1:EgF9pA37S4M9rIJJFJjB63KzskWEDjcpNtkfM8gngGA=
788+
github.com/ellemouton/lndclient v1.0.1-0.20250420083827-f6ba7f319771/go.mod h1:TK2XVsbgbZAgkWisTyHQOhrAt7gs7iqjXqQ+C9FzzrU=
785789
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
786790
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
787791
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
@@ -1161,8 +1165,6 @@ github.com/lightninglabs/lightning-node-connect v0.3.3-alpha.0.20250306111457-ca
11611165
github.com/lightninglabs/lightning-node-connect v0.3.3-alpha.0.20250306111457-cad4234830cc/go.mod h1:yrfNoMrGcWljHoQ31+dCSc0R7mBdYqISQeZABlrdkz4=
11621166
github.com/lightninglabs/lightning-node-connect/hashmailrpc v1.0.2 h1:Er1miPZD2XZwcfE4xoS5AILqP1mj7kqnhbBSxW9BDxY=
11631167
github.com/lightninglabs/lightning-node-connect/hashmailrpc v1.0.2/go.mod h1:antQGRDRJiuyQF6l+k6NECCSImgCpwaZapATth2Chv4=
1164-
github.com/lightninglabs/lndclient v0.19.0-3 h1:PGGlDaz8x1dXGowDfAWhbuDqXTKNaJyb7SOTrRdG1es=
1165-
github.com/lightninglabs/lndclient v0.19.0-3/go.mod h1:5YMrFx00NvcmUHGZRxT4Qw/gOfR5x50/ReJmJ6w0yVk=
11661168
github.com/lightninglabs/loop v0.29.0-beta.rc2.0.20250306160707-1091a628755c h1:Ox7SfusBRizc7tOKy9HKXodR7rcvpko08EH9aP/+euQ=
11671169
github.com/lightninglabs/loop v0.29.0-beta.rc2.0.20250306160707-1091a628755c/go.mod h1:IzzOw/v4VwKmotJrmPyM8P+FPZ/XBbxa4u2JuDYrtAU=
11681170
github.com/lightninglabs/loop/looprpc v1.0.4-0.20250306160707-1091a628755c h1:ueEVZjeUKI3CoTJAdpDbXKHTSd9OfY8OPqTDBjeHhfs=
@@ -1185,8 +1187,6 @@ github.com/lightninglabs/taproot-assets v0.5.2-0.20250401150538-a9ea76a9ed3c h1:
11851187
github.com/lightninglabs/taproot-assets v0.5.2-0.20250401150538-a9ea76a9ed3c/go.mod h1:e3SjXbbi4xKhOzq54c672Z/j9UTRq5DLJGx/URgVTJo=
11861188
github.com/lightningnetwork/lightning-onion v1.2.1-0.20240712235311-98bd56499dfb h1:yfM05S8DXKhuCBp5qSMZdtSwvJ+GFzl94KbXMNB1JDY=
11871189
github.com/lightningnetwork/lightning-onion v1.2.1-0.20240712235311-98bd56499dfb/go.mod h1:c0kvRShutpj3l6B9WtTsNTBUtjSmjZXbJd9ZBRQOSKI=
1188-
github.com/lightningnetwork/lnd v0.19.0-beta.rc1.0.20250327183348-eb822a5e117f h1:+Bejv2Ij/ryUjLacBd5au0acMH0AYs0lhb7ki5rx9ms=
1189-
github.com/lightningnetwork/lnd v0.19.0-beta.rc1.0.20250327183348-eb822a5e117f/go.mod h1:BP+neeFpmeAA7o5hu3zp3FwOEl26idSyPV9zBOavp6E=
11901190
github.com/lightningnetwork/lnd/cert v1.2.2 h1:71YK6hogeJtxSxw2teq3eGeuy4rHGKcFf0d0Uy4qBjI=
11911191
github.com/lightningnetwork/lnd/cert v1.2.2/go.mod h1:jQmFn/Ez4zhDgq2hnYSw8r35bqGVxViXhX6Cd7HXM6U=
11921192
github.com/lightningnetwork/lnd/clock v1.1.1 h1:OfR3/zcJd2RhH0RU+zX/77c0ZiOnIMsDIBjgjWdZgA0=
@@ -1197,12 +1197,12 @@ github.com/lightningnetwork/lnd/fn/v2 v2.0.8 h1:r2SLz7gZYQPVc3IZhU82M66guz3Zk2oY
11971197
github.com/lightningnetwork/lnd/fn/v2 v2.0.8/go.mod h1:TOzwrhjB/Azw1V7aa8t21ufcQmdsQOQMDtxVOQWNl8s=
11981198
github.com/lightningnetwork/lnd/healthcheck v1.2.6 h1:1sWhqr93GdkWy4+6U7JxBfcyZIE78MhIHTJZfPx7qqI=
11991199
github.com/lightningnetwork/lnd/healthcheck v1.2.6/go.mod h1:Mu02um4CWY/zdTOvFje7WJgJcHyX2zq/FG3MhOAiGaQ=
1200-
github.com/lightningnetwork/lnd/kvdb v1.4.13 h1:fe3sFBxsgcXl16G1zj6O/wZf0hbBHOxFe8pCgmnHZxM=
1201-
github.com/lightningnetwork/lnd/kvdb v1.4.13/go.mod h1:1y0Z81CGQu4SMpcnAie/oK4tzgEqFQqFdj6k3fz2s8s=
1200+
github.com/lightningnetwork/lnd/kvdb v1.4.15 h1:3eN6uGcubvGB5itPp1D0D4uEEkIMYht3w0LDnqLzAWI=
1201+
github.com/lightningnetwork/lnd/kvdb v1.4.15/go.mod h1:HW+bvwkxNaopkz3oIgBV6NEnV4jCEZCACFUcNg4xSjM=
12021202
github.com/lightningnetwork/lnd/queue v1.1.1 h1:99ovBlpM9B0FRCGYJo6RSFDlt8/vOkQQZznVb18iNMI=
12031203
github.com/lightningnetwork/lnd/queue v1.1.1/go.mod h1:7A6nC1Qrm32FHuhx/mi1cieAiBZo5O6l8IBIoQxvkz4=
1204-
github.com/lightningnetwork/lnd/sqldb v1.0.7 h1:wQ4DdHY++uwxwth2CHL7s+duGqmMLaoIRBOQCa9HPTk=
1205-
github.com/lightningnetwork/lnd/sqldb v1.0.7/go.mod h1:OG09zL/PHPaBJefp4HsPz2YLUJ+zIQHbpgCtLnOx8I4=
1204+
github.com/lightningnetwork/lnd/sqldb v1.0.9 h1:7OHi+Hui823mB/U9NzCdlZTAGSVdDCbjp33+6d/Q+G0=
1205+
github.com/lightningnetwork/lnd/sqldb v1.0.9/go.mod h1:OG09zL/PHPaBJefp4HsPz2YLUJ+zIQHbpgCtLnOx8I4=
12061206
github.com/lightningnetwork/lnd/ticker v1.1.1 h1:J/b6N2hibFtC7JLV77ULQp++QLtCwT6ijJlbdiZFbSM=
12071207
github.com/lightningnetwork/lnd/ticker v1.1.1/go.mod h1:waPTRAAcwtu7Ji3+3k+u/xH5GHovTsCoSVpho0KDvdA=
12081208
github.com/lightningnetwork/lnd/tlv v1.3.0 h1:exS/KCPEgpOgviIttfiXAPaUqw2rHQrnUOpP7HPBPiY=

session/context.go

+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package session
2+
3+
import (
4+
"encoding/hex"
5+
6+
"google.golang.org/grpc/metadata"
7+
)
8+
9+
type contextKey struct {
10+
name string
11+
}
12+
13+
var sessionIDCtxKey = contextKey{"lit_session_id"}
14+
15+
func FromGrpcMD(md metadata.MD) (ID, bool, error) {
16+
val := md.Get(sessionIDCtxKey.name)
17+
if len(val) == 0 {
18+
return ID{}, false, nil
19+
}
20+
21+
b, err := hex.DecodeString(val[0])
22+
if err != nil {
23+
return ID{}, false, err
24+
}
25+
26+
sessID, err := IDFromBytes(b)
27+
if err != nil {
28+
return ID{}, false, err
29+
}
30+
31+
return sessID, true, nil
32+
}
33+
34+
func AddToGrpcMD(md metadata.MD, id ID) {
35+
md.Set(sessionIDCtxKey.name, hex.EncodeToString(id[:]))
36+
}

session/server.go

+3-2
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ import (
1818

1919
type sessionID [33]byte
2020

21-
type GRPCServerCreator func(opts ...grpc.ServerOption) *grpc.Server
21+
type GRPCServerCreator func(sessionID ID,
22+
opts ...grpc.ServerOption) *grpc.Server
2223

2324
type mailboxSession struct {
2425
server *grpc.Server
@@ -70,7 +71,7 @@ func (m *mailboxSession) start(session *Session,
7071
}
7172

7273
noiseConn := mailbox.NewNoiseGrpcConn(keys)
73-
m.server = serverCreator(grpc.Creds(noiseConn))
74+
m.server = serverCreator(session.ID, grpc.Creds(noiseConn))
7475

7576
m.wg.Add(1)
7677
go m.run(mailboxServer)

session_rpcserver.go

+58-2
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import (
2626
"github.com/lightningnetwork/lnd/fn"
2727
"github.com/lightningnetwork/lnd/macaroons"
2828
"google.golang.org/grpc"
29+
"google.golang.org/grpc/metadata"
2930
"gopkg.in/macaroon-bakery.v2/bakery"
3031
"gopkg.in/macaroon-bakery.v2/bakery/checkers"
3132
"gopkg.in/macaroon.v2"
@@ -77,10 +78,24 @@ func newSessionRPCServer(cfg *sessionRpcServerConfig) (*sessionRpcServer,
7778
// actual mailbox server that spins up the Terminal Connect server
7879
// interface.
7980
server := session.NewServer(
80-
func(opts ...grpc.ServerOption) *grpc.Server {
81-
allOpts := append(cfg.grpcOptions, opts...)
81+
func(id session.ID, opts ...grpc.ServerOption) *grpc.Server {
82+
allOpts := []grpc.ServerOption{
83+
grpc.StreamInterceptor(
84+
addSessionIDToStreamCtx(id),
85+
),
86+
grpc.ChainUnaryInterceptor(
87+
addSessionIDToUnaryCtx(id),
88+
),
89+
}
90+
91+
allOpts = append(allOpts, cfg.grpcOptions...)
92+
allOpts = append(allOpts, opts...)
93+
94+
// Construct the gRPC server with the options.
8295
grpcServer := grpc.NewServer(allOpts...)
8396

97+
// Register various grpc servers with the LNC session
98+
// server.
8499
cfg.registerGrpcServers(grpcServer)
85100

86101
return grpcServer
@@ -94,6 +109,47 @@ func newSessionRPCServer(cfg *sessionRpcServerConfig) (*sessionRpcServer,
94109
}, nil
95110
}
96111

112+
type wrappedServerStream struct {
113+
grpc.ServerStream
114+
ctx context.Context
115+
}
116+
117+
func (w *wrappedServerStream) Context() context.Context {
118+
return w.ctx
119+
}
120+
121+
func addSessionIDToStreamCtx(id session.ID) grpc.StreamServerInterceptor {
122+
return func(srv interface{}, ss grpc.ServerStream,
123+
info *grpc.StreamServerInfo, handler grpc.StreamHandler) error {
124+
125+
md, _ := metadata.FromIncomingContext(ss.Context())
126+
mdCopy := md.Copy()
127+
session.AddToGrpcMD(mdCopy, id)
128+
129+
// Wrap the original stream with our custom context.
130+
wrapped := &wrappedServerStream{
131+
ServerStream: ss,
132+
ctx: metadata.NewIncomingContext(
133+
ss.Context(), mdCopy,
134+
),
135+
}
136+
137+
return handler(srv, wrapped)
138+
}
139+
}
140+
141+
func addSessionIDToUnaryCtx(id session.ID) grpc.UnaryServerInterceptor {
142+
return func(ctx context.Context, req any, info *grpc.UnaryServerInfo,
143+
handler grpc.UnaryHandler) (resp any, err error) {
144+
145+
md, _ := metadata.FromIncomingContext(ctx)
146+
mdCopy := md.Copy()
147+
session.AddToGrpcMD(mdCopy, id)
148+
149+
return handler(metadata.NewIncomingContext(ctx, mdCopy), req)
150+
}
151+
}
152+
97153
// start all the components necessary for the sessionRpcServer to start serving
98154
// requests. This includes resuming all non-revoked sessions.
99155
func (s *sessionRpcServer) start(ctx context.Context) error {

0 commit comments

Comments
 (0)