diff --git a/lnd.go b/lnd.go index b4fde604..d5bc7768 100644 --- a/lnd.go +++ b/lnd.go @@ -145,6 +145,12 @@ type RPCSubserverConfig struct { // per URI, they are all required. See rpcserver.go for a list of valid // action and entity values. Permissions map[string][]bakery.Op + + // MacaroonValidator is a custom macaroon validator that should be used + // instead of the default lnd validator. If specified, the custom + // validator is used for all URIs specified in the above Permissions + // map. + MacaroonValidator macaroons.MacaroonValidator } // ListenerWithSignal is a net.Listener that has an additional Ready channel that diff --git a/rpcserver.go b/rpcserver.go index be6e7a8e..784179f4 100644 --- a/rpcserver.go +++ b/rpcserver.go @@ -661,10 +661,12 @@ func newRPCServer(cfg *Config, s *server, macService *macaroons.Service, return nil, err } - // External subserver possibly need to register their own permissions. + // External subserver possibly need to register their own permissions + // and macaroon validator. for _, lis := range listeners { extSubserver := lis.ExternalRPCSubserverCfg if extSubserver != nil { + macValidator := extSubserver.MacaroonValidator for method, ops := range extSubserver.Permissions { // For each new method:ops combo, we also ensure // that non of the sub-servers try to override @@ -677,6 +679,23 @@ func newRPCServer(cfg *Config, s *server, macService *macaroons.Service, } permissions[method] = ops + + // Give the external subservers the possibility + // to also use their own validator to check any + // macaroons attached to calls to this method. + // This allows them to have their own root key + // ID database and permission entities. + if macValidator != nil { + err := macService.RegisterExternalValidator( + method, macValidator, + ) + if err != nil { + return nil, fmt.Errorf("could "+ + "not register "+ + "external macaroon "+ + "validator: %v", err) + } + } } } }