4
4
"fmt"
5
5
"strings"
6
6
7
+ "github.com/lightninglabs/lightning-terminal/session"
7
8
"github.com/lightningnetwork/lnd/lnrpc"
9
+ "google.golang.org/grpc/metadata"
8
10
"gopkg.in/macaroon.v2"
9
11
)
10
12
@@ -38,18 +40,27 @@ type RequestInfo struct {
38
40
MetaInfo * InterceptMetaInfo
39
41
Rules * InterceptRules
40
42
WithPrivacy bool
43
+ MDPairs metadata.MD
41
44
}
42
45
43
46
// NewInfoFromRequest parses the given RPC middleware interception request and
44
47
// returns a RequestInfo struct.
45
48
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
+
46
56
var ri * RequestInfo
47
57
switch t := req .InterceptType .(type ) {
48
58
case * lnrpc.RPCMiddlewareRequest_StreamAuth :
49
59
ri = & RequestInfo {
50
60
MWRequestType : MWRequestTypeStreamAuth ,
51
61
URI : t .StreamAuth .MethodFullUri ,
52
62
Streaming : true ,
63
+ MDPairs : md ,
53
64
}
54
65
55
66
case * lnrpc.RPCMiddlewareRequest_Request :
@@ -60,6 +71,7 @@ func NewInfoFromRequest(req *lnrpc.RPCMiddlewareRequest) (*RequestInfo, error) {
60
71
IsError : t .Request .IsError ,
61
72
Serialized : t .Request .Serialized ,
62
73
Streaming : t .Request .StreamRpc ,
74
+ MDPairs : md ,
63
75
}
64
76
65
77
case * lnrpc.RPCMiddlewareRequest_Response :
@@ -70,6 +82,7 @@ func NewInfoFromRequest(req *lnrpc.RPCMiddlewareRequest) (*RequestInfo, error) {
70
82
IsError : t .Response .IsError ,
71
83
Serialized : t .Response .Serialized ,
72
84
Streaming : t .Response .StreamRpc ,
85
+ MDPairs : md ,
73
86
}
74
87
75
88
default :
@@ -134,3 +147,35 @@ func (ri *RequestInfo) String() string {
134
147
ri .GRPCMessageType , ri .Streaming , strings .Join (ri .Caveats , "," ),
135
148
ri .MetaInfo , ri .Rules )
136
149
}
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
+ }
0 commit comments