Skip to content

Commit 76ed920

Browse files
committed
rpc_proxy: only allow requests if sub-server is ready
1 parent d87c8d9 commit 76ed920

File tree

2 files changed

+52
-11
lines changed

2 files changed

+52
-11
lines changed

rpc_proxy.go

Lines changed: 51 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import (
1515
"github.com/lightninglabs/lightning-terminal/litrpc"
1616
"github.com/lightninglabs/lightning-terminal/perms"
1717
"github.com/lightninglabs/lightning-terminal/session"
18+
litstatus "github.com/lightninglabs/lightning-terminal/status"
1819
"github.com/lightninglabs/lightning-terminal/subservers"
1920
"github.com/lightningnetwork/lnd/lncfg"
2021
"github.com/lightningnetwork/lnd/macaroons"
@@ -61,7 +62,8 @@ func (e *proxyErr) Unwrap() error {
6162
// component.
6263
func newRpcProxy(cfg *Config, validator macaroons.MacaroonValidator,
6364
superMacValidator session.SuperMacaroonValidator,
64-
permsMgr *perms.Manager, subServerMgr *subservers.Manager) *rpcProxy {
65+
permsMgr *perms.Manager, subServerMgr *subservers.Manager,
66+
statusMgr *litstatus.Manager) *rpcProxy {
6567

6668
// The gRPC web calls are protected by HTTP basic auth which is defined
6769
// by base64(username:password). Because we only have a password, we
@@ -82,6 +84,7 @@ func newRpcProxy(cfg *Config, validator macaroons.MacaroonValidator,
8284
macValidator: validator,
8385
superMacValidator: superMacValidator,
8486
subServerMgr: subServerMgr,
87+
statusMgr: statusMgr,
8588
}
8689
p.grpcServer = grpc.NewServer(
8790
// From the grpxProxy doc: This codec is *crucial* to the
@@ -156,6 +159,7 @@ type rpcProxy struct {
156159
basicAuth string
157160
permsMgr *perms.Manager
158161
subServerMgr *subservers.Manager
162+
statusMgr *litstatus.Manager
159163

160164
macValidator macaroons.MacaroonValidator
161165
superMacValidator session.SuperMacaroonValidator
@@ -297,6 +301,10 @@ func (p *rpcProxy) makeDirector(allowLitRPC bool) func(ctx context.Context,
297301
}
298302
}
299303

304+
if err := p.checkSubSystemStarted(requestURI); err != nil {
305+
return outCtx, nil, err
306+
}
307+
300308
// Direct the call to the correct backend. All gRPC calls end up
301309
// here since our gRPC server instance doesn't have any handlers
302310
// registered itself. So all daemon calls that are remote are
@@ -323,12 +331,6 @@ func (p *rpcProxy) makeDirector(allowLitRPC bool) func(ctx context.Context,
323331
)
324332
}
325333

326-
// If the rpcProxy has not started yet, then the lnd connection
327-
// will not be initialised yet.
328-
if !p.hasStarted() {
329-
return outCtx, nil, ErrWaitingToStart
330-
}
331-
332334
return outCtx, p.lndConn, nil
333335
}
334336
}
@@ -339,8 +341,8 @@ func (p *rpcProxy) UnaryServerInterceptor(ctx context.Context, req interface{},
339341
info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{},
340342
error) {
341343

342-
if !p.hasStarted() && !isStatusReq(info.FullMethod) {
343-
return nil, ErrWaitingToStart
344+
if err := p.checkSubSystemStarted(info.FullMethod); err != nil {
345+
return nil, err
344346
}
345347

346348
uriPermissions, ok := p.permsMgr.URIPermissions(info.FullMethod)
@@ -384,8 +386,8 @@ func (p *rpcProxy) StreamServerInterceptor(srv interface{},
384386
ss grpc.ServerStream, info *grpc.StreamServerInfo,
385387
handler grpc.StreamHandler) error {
386388

387-
if !p.hasStarted() && !isStatusReq(info.FullMethod) {
388-
return ErrWaitingToStart
389+
if err := p.checkSubSystemStarted(info.FullMethod); err != nil {
390+
return err
389391
}
390392

391393
uriPermissions, ok := p.permsMgr.URIPermissions(info.FullMethod)
@@ -572,6 +574,44 @@ func (p *rpcProxy) convertSuperMacaroon(ctx context.Context, macHex string,
572574
return nil, nil
573575
}
574576

577+
// checkSubSystemStarted checks if the subsystem responsible for handling the
578+
// given URI has started.
579+
func (p *rpcProxy) checkSubSystemStarted(requestURI string) error {
580+
// A request to Lit's status server is always allowed.
581+
if isStatusReq(requestURI) {
582+
return nil
583+
}
584+
585+
// Check if the rpcProxy has started yet.
586+
if !p.hasStarted() {
587+
return ErrWaitingToStart
588+
}
589+
590+
// Currently, Lit and LND are not registered with the sub-server
591+
// manager, so we let any request for them through.
592+
if p.permsMgr.IsSubServerURI(subservers.LIT, requestURI) ||
593+
p.permsMgr.IsSubServerURI(subservers.LND, requestURI) {
594+
595+
return nil
596+
}
597+
598+
// Check that the sub-server manager does have a sub-server registered
599+
// that can handle the given URI.
600+
handled, system := p.subServerMgr.Handles(requestURI)
601+
if !handled {
602+
return fmt.Errorf("unknown gRPC web request: %v", requestURI)
603+
}
604+
605+
// Check with the status manger to see if the sub-server is ready to
606+
// handle the request.
607+
started, startErr := p.statusMgr.GetStatus(system)
608+
if !started {
609+
return fmt.Errorf("%s is not running: %s", system, startErr)
610+
}
611+
612+
return nil
613+
}
614+
575615
// readMacaroon tries to read the macaroon file at the specified path and create
576616
// gRPC dial options from it.
577617
func readMacaroon(macPath string) ([]byte, error) {

terminal.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,7 @@ func (g *LightningTerminal) Run() error {
241241
// server is started.
242242
g.rpcProxy = newRpcProxy(
243243
g.cfg, g, g.validateSuperMacaroon, g.permsMgr, g.subServerMgr,
244+
g.statusMgr,
244245
)
245246

246247
litrpc.RegisterProxyServer(g.rpcProxy.grpcServer, g.rpcProxy)

0 commit comments

Comments
 (0)