Skip to content

Commit edab9a4

Browse files
authored
Merge pull request #617 from ellemouton/allowLNDWhitelistCalls
multi: allow LND and subserver whitelisted calls
2 parents dfb4fff + e766e9a commit edab9a4

File tree

12 files changed

+281
-108
lines changed

12 files changed

+281
-108
lines changed

itest/litd_mode_integrated_test.go

Lines changed: 170 additions & 80 deletions
Large diffs are not rendered by default.

itest/litd_mode_remote_test.go

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -63,11 +63,11 @@ func remoteTestSuite(ctx context.Context, net *NetworkHarness, t *testing.T,
6363
runGRPCAuthTest(
6464
ttt, cfg.LitAddr(), cfg.LitTLSCertPath,
6565
endpoint.macaroonFn(cfg),
66+
endpoint.noAuth,
6667
endpoint.requestFn,
6768
endpoint.successPattern,
6869
endpointEnabled,
69-
"unknown permissions required for "+
70-
"method",
70+
"unknown request",
7171
)
7272
})
7373
}
@@ -90,11 +90,11 @@ func remoteTestSuite(ctx context.Context, net *NetworkHarness, t *testing.T,
9090
runUIPasswordCheck(
9191
ttt, cfg.LitAddr(), cfg.LitTLSCertPath,
9292
cfg.UIPassword, endpoint.requestFn,
93+
endpoint.noAuth,
9394
shouldFailWithoutMacaroon,
9495
endpoint.successPattern,
9596
endpointEnabled,
96-
"unknown permissions required for "+
97-
"method",
97+
"unknown request",
9898
)
9999
})
100100
}
@@ -117,8 +117,7 @@ func remoteTestSuite(ctx context.Context, net *NetworkHarness, t *testing.T,
117117
ttt, cfg.LitAddr(), cfg.UIPassword,
118118
endpoint.grpcWebURI, withoutUIPassword,
119119
endpointEnabled,
120-
"unknown permissions required for "+
121-
"method",
120+
"unknown request", endpoint.noAuth,
122121
)
123122
})
124123
}
@@ -142,12 +141,11 @@ func remoteTestSuite(ctx context.Context, net *NetworkHarness, t *testing.T,
142141
tt.Run(endpoint.name+" lit port", func(ttt *testing.T) {
143142
runGRPCAuthTest(
144143
ttt, cfg.LitAddr(), cfg.LitTLSCertPath,
145-
superMacFile,
144+
superMacFile, endpoint.noAuth,
146145
endpoint.requestFn,
147146
endpoint.successPattern,
148147
endpointEnabled,
149-
"unknown permissions required for "+
150-
"method",
148+
"unknown request",
151149
)
152150
})
153151
}
@@ -168,7 +166,7 @@ func remoteTestSuite(ctx context.Context, net *NetworkHarness, t *testing.T,
168166
endpoint.restWebURI,
169167
endpoint.successPattern,
170168
endpoint.restPOST, withoutUIPassword,
171-
endpointDisabled,
169+
endpointDisabled, endpoint.noAuth,
172170
)
173171
})
174172
}
@@ -199,7 +197,7 @@ func remoteTestSuite(ctx context.Context, net *NetworkHarness, t *testing.T,
199197
endpoint.successPattern,
200198
endpoint.allowedThroughLNC,
201199
"unknown service",
202-
endpointDisabled,
200+
endpointDisabled, endpoint.noAuth,
203201
)
204202
})
205203
}
@@ -244,7 +242,7 @@ func remoteTestSuite(ctx context.Context, net *NetworkHarness, t *testing.T,
244242
ttt, rawLNCConn, endpoint.requestFn,
245243
endpoint.successPattern,
246244
allowed, "permission denied",
247-
endpointDisabled,
245+
endpointDisabled, endpoint.noAuth,
248246
)
249247
})
250248
}

perms/manager.go

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,13 @@ func NewManager(withAllSubServers bool) (*Manager, error) {
4949
permissions := make(map[string]map[string][]bakery.Op)
5050
permissions[litPerms] = RequiredPermissions
5151
permissions[lndPerms] = lnd.MainRPCServerPermissions()
52-
for k, v := range whiteListedLNDMethods {
53-
permissions[lndPerms][k] = v
52+
53+
for url := range whiteListedLitMethods {
54+
permissions[litPerms][url] = []bakery.Op{}
55+
}
56+
57+
for url := range whiteListedLNDMethods {
58+
permissions[lndPerms][url] = []bakery.Op{}
5459
}
5560

5661
// Collect all LND sub-server permissions along with the name of the
@@ -96,10 +101,22 @@ func NewManager(withAllSubServers bool) (*Manager, error) {
96101
}, nil
97102
}
98103

104+
// IsWhiteListedURL returns true if the given URL has been whitelisted meaning
105+
// that it does not require a macaroon for validation. A URL is considered
106+
// white-listed if it has no operations associated with a URL.
107+
func (pm *Manager) IsWhiteListedURL(url string) bool {
108+
pm.permsMu.Lock()
109+
defer pm.permsMu.Unlock()
110+
111+
ops, ok := pm.perms[url]
112+
113+
return ok && len(ops) == 0
114+
}
115+
99116
// RegisterSubServer adds the permissions of a given sub-server to the set
100117
// managed by the Manager.
101118
func (pm *Manager) RegisterSubServer(name string,
102-
permissions map[string][]bakery.Op) {
119+
permissions map[string][]bakery.Op, whiteListURLs map[string]struct{}) {
103120

104121
pm.permsMu.Lock()
105122
defer pm.permsMu.Unlock()
@@ -109,6 +126,15 @@ func (pm *Manager) RegisterSubServer(name string,
109126
for uri, ops := range permissions {
110127
pm.perms[uri] = ops
111128
}
129+
130+
for url := range whiteListURLs {
131+
pm.perms[url] = nil
132+
133+
if pm.fixedPerms[name] == nil {
134+
pm.fixedPerms[name] = make(map[string][]bakery.Op)
135+
}
136+
pm.fixedPerms[name][url] = []bakery.Op{}
137+
}
112138
}
113139

114140
// OnLNDBuildTags should be called once a list of LND build tags has been

perms/permissions.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ var (
8080

8181
// whiteListedLNDMethods is a map of all lnd RPC methods that don't
8282
// require any macaroon authentication.
83-
whiteListedLNDMethods = map[string][]bakery.Op{
83+
whiteListedLNDMethods = map[string]struct{}{
8484
"/lnrpc.WalletUnlocker/GenSeed": {},
8585
"/lnrpc.WalletUnlocker/InitWallet": {},
8686
"/lnrpc.WalletUnlocker/UnlockWallet": {},
@@ -92,6 +92,10 @@ var (
9292
"/lnrpc.State/GetState": {},
9393
}
9494

95+
// whiteListedLitMethods is a map of all LiT's RPC methods that don't
96+
// require any macaroon authentication.
97+
whiteListedLitMethods = map[string]struct{}{}
98+
9599
// lndSubServerNameToTag is a map from the name of an LND subserver to
96100
// the name of the LND tag that corresponds to the subserver. This map
97101
// only contains the subserver-to-tag pairs for the pairs where the

rpc_proxy.go

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,15 @@ const (
3434
HeaderMacaroon = "Macaroon"
3535
)
3636

37-
// ErrWaitingToStart is returned if Lit's rpcProxy is not yet ready to handle
38-
// calls.
39-
var ErrWaitingToStart = fmt.Errorf("waiting for the RPC server to start")
37+
var (
38+
// ErrWaitingToStart is returned if Lit's rpcProxy is not yet ready to
39+
// handle calls.
40+
ErrWaitingToStart = fmt.Errorf("waiting for the RPC server to start")
41+
42+
// ErrUnknownRequest is an error returned when the request URI is
43+
// unknown if the permissions for the request are unknown.
44+
ErrUnknownRequest = fmt.Errorf("unknown request")
45+
)
4046

4147
// proxyErr is an error type that adds more context to an error occurring in the
4248
// proxy.
@@ -375,8 +381,7 @@ func (p *rpcProxy) UnaryServerInterceptor(ctx context.Context, req interface{},
375381

376382
uriPermissions, ok := p.permsMgr.URIPermissions(info.FullMethod)
377383
if !ok {
378-
return nil, fmt.Errorf("%s: unknown permissions "+
379-
"required for method", info.FullMethod)
384+
return nil, ErrUnknownRequest
380385
}
381386

382387
// For now, basic authentication is just a quick fix until we
@@ -420,8 +425,7 @@ func (p *rpcProxy) StreamServerInterceptor(srv interface{},
420425

421426
uriPermissions, ok := p.permsMgr.URIPermissions(info.FullMethod)
422427
if !ok {
423-
return fmt.Errorf("%s: unknown permissions required "+
424-
"for method", info.FullMethod)
428+
return ErrUnknownRequest
425429
}
426430

427431
// For now, basic authentication is just a quick fix until we
@@ -521,8 +525,7 @@ func (p *rpcProxy) basicAuthToMacaroon(basicAuth, requestURI string,
521525
macPath = p.cfg.MacaroonPath
522526

523527
default:
524-
return nil, fmt.Errorf("unknown gRPC web request: %v",
525-
requestURI)
528+
return nil, ErrUnknownRequest
526529
}
527530

528531
switch {
@@ -572,8 +575,7 @@ func (p *rpcProxy) convertSuperMacaroon(ctx context.Context, macHex string,
572575

573576
requiredPermissions, ok := p.permsMgr.URIPermissions(fullMethod)
574577
if !ok {
575-
return nil, fmt.Errorf("%s: unknown permissions required for "+
576-
"method", fullMethod)
578+
return nil, ErrUnknownRequest
577579
}
578580

579581
// We have a super macaroon, from here on out we'll return errors if

subservers/faraday.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,3 +118,11 @@ func (f *faradaySubServer) MacPath() string {
118118
func (f *faradaySubServer) Permissions() map[string][]bakery.Op {
119119
return perms.RequiredPermissions
120120
}
121+
122+
// WhiteListedURLs returns a map of all the sub-server's URLs that can be
123+
// accessed without a macaroon.
124+
//
125+
// NOTE: this is part of the SubServer interface.
126+
func (f *faradaySubServer) WhiteListedURLs() map[string]struct{} {
127+
return nil
128+
}

subservers/interface.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,4 +58,8 @@ type SubServer interface {
5858
// Permissions returns a map of all RPC methods and their required
5959
// macaroon permissions to access the sub-server.
6060
Permissions() map[string][]bakery.Op
61+
62+
// WhiteListedURLs returns a map of all the sub-server's URLs that can
63+
// be accessed without a macaroon.
64+
WhiteListedURLs() map[string]struct{}
6165
}

subservers/loop.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,3 +128,11 @@ func (l *loopSubServer) MacPath() string {
128128
func (l *loopSubServer) Permissions() map[string][]bakery.Op {
129129
return perms.RequiredPermissions
130130
}
131+
132+
// WhiteListedURLs returns a map of all the sub-server's URLs that can be
133+
// accessed without a macaroon.
134+
//
135+
// NOTE: this is part of the SubServer interface.
136+
func (l *loopSubServer) WhiteListedURLs() map[string]struct{} {
137+
return nil
138+
}

subservers/manager.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,9 @@ func (s *Manager) AddServer(ss SubServer) {
5454
quit: make(chan struct{}),
5555
})
5656

57-
s.permsMgr.RegisterSubServer(ss.Name(), ss.Permissions())
57+
s.permsMgr.RegisterSubServer(
58+
ss.Name(), ss.Permissions(), ss.WhiteListedURLs(),
59+
)
5860
}
5961

6062
// StartIntegratedServers starts all the manager's sub-servers that should be

subservers/pool.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,3 +118,11 @@ func (p *poolSubServer) MacPath() string {
118118
func (p *poolSubServer) Permissions() map[string][]bakery.Op {
119119
return perms.RequiredPermissions
120120
}
121+
122+
// WhiteListedURLs returns a map of all the sub-server's URLs that can be
123+
// accessed without a macaroon.
124+
//
125+
// NOTE: this is part of the SubServer interface.
126+
func (p *poolSubServer) WhiteListedURLs() map[string]struct{} {
127+
return nil
128+
}

0 commit comments

Comments
 (0)