diff --git a/cmd/lncli/main.go b/cmd/lncli/main.go index 99a35b30..0336f966 100644 --- a/cmd/lncli/main.go +++ b/cmd/lncli/main.go @@ -11,7 +11,7 @@ import ( "path/filepath" "strings" - "gopkg.in/macaroon.v1" + macaroon "gopkg.in/macaroon.v2" "github.com/lightningnetwork/lnd/lnrpc" "github.com/lightningnetwork/lnd/macaroons" diff --git a/glide.lock b/glide.lock index ad818493..b89ddbb3 100644 --- a/glide.lock +++ b/glide.lock @@ -1,5 +1,5 @@ -hash: 70e2030c50a730ad0ad428176f12851f35178e31e262bae82cedd89579a14b40 -updated: 2018-01-24T15:24:09.346726778-08:00 +hash: f72fdbb4d93ddd98991e830f978bfe9e08623e2a9976857b0f7668641486369c +updated: 2018-01-29T15:55:37.905498329-07:00 imports: - name: github.com/aead/chacha20 version: d31a916ded42d1640b9d89a26f8abd53cc96790c @@ -204,11 +204,11 @@ imports: - transport - name: gopkg.in/errgo.v1 version: 442357a80af5c6bf9b6d51ae791a39c3421004f3 -- name: gopkg.in/macaroon-bakery.v1 - version: 8e14f8b0f5e286ad100ca8d6ce5bde0f0dfb8b21 +- name: gopkg.in/macaroon-bakery.v2 + version: 04cf5ef151a211d929975161aea7c65f94c90446 subpackages: - bakery - bakery/checkers -- name: gopkg.in/macaroon.v1 - version: ab101776739ee61baab9bc50e4b33b5aeb3ac843 +- name: gopkg.in/macaroon.v2 + version: bed2a428da6e56d950bed5b41fcbae3141e5b0d0 testImports: [] diff --git a/glide.yaml b/glide.yaml index 990a04ca..12e78c67 100644 --- a/glide.yaml +++ b/glide.yaml @@ -74,8 +74,8 @@ import: - chaincfg - package: github.com/lightninglabs/neutrino version: 6c8f30a130bb170348ceb754ce4204156efe2741 -- package: gopkg.in/macaroon.v1 -- package: gopkg.in/macaroon-bakery.v1 +- package: gopkg.in/macaroon.v2 +- package: gopkg.in/macaroon-bakery.v2 - package: github.com/juju/loggo - package: github.com/rogpeppe/fastuuid - package: gopkg.in/errgo.v1 diff --git a/lnd.go b/lnd.go index f54657e3..d27b23fc 100644 --- a/lnd.go +++ b/lnd.go @@ -24,7 +24,7 @@ import ( "sync" "time" - "gopkg.in/macaroon-bakery.v1/bakery" + "gopkg.in/macaroon-bakery.v2/bakery" "golang.org/x/net/context" @@ -143,10 +143,15 @@ func lndMain() error { defer chanDB.Close() // Only process macaroons if --no-macaroons isn't set. - var macaroonService *bakery.Service + ctx := context.Background() + ctx, cancel := context.WithCancel(ctx) + defer cancel() + + var macaroonService *bakery.Bakery if !cfg.NoMacaroons { // Create the macaroon authentication/authorization service. - macaroonService, err = macaroons.NewService(macaroonDatabaseDir) + macaroonService, err = macaroons.NewService(macaroonDatabaseDir, + macaroons.IPLockChecker) if err != nil { srvrLog.Errorf("unable to create macaroon service: %v", err) return err @@ -154,8 +159,8 @@ func lndMain() error { // Create macaroon files for lncli to use if they don't exist. if !fileExists(cfg.AdminMacPath) && !fileExists(cfg.ReadMacPath) { - err = genMacaroons(macaroonService, cfg.AdminMacPath, - cfg.ReadMacPath) + err = genMacaroons(ctx, macaroonService, + cfg.AdminMacPath, cfg.ReadMacPath) if err != nil { ltndLog.Errorf("unable to create macaroon "+ "files: %v", err) @@ -368,9 +373,19 @@ func lndMain() error { } server.fundingMgr = fundingMgr + // Check macaroon authentication if macaroons aren't disabled. + if macaroonService != nil { + serverOpts = append(serverOpts, + grpc.UnaryInterceptor(macaroons.UnaryServerInterceptor( + macaroonService, permissions)), + grpc.StreamInterceptor(macaroons.StreamServerInterceptor( + macaroonService, permissions)), + ) + } + // Initialize, and register our implementation of the gRPC interface // exported by the rpcServer. - rpcServer := newRPCServer(server, macaroonService) + rpcServer := newRPCServer(server) if err := rpcServer.Start(); err != nil { return err } @@ -393,10 +408,6 @@ func lndMain() error { } // Finally, start the REST proxy for our gRPC server above. - ctx := context.Background() - ctx, cancel := context.WithCancel(ctx) - defer cancel() - mux := proxy.NewServeMux() err = lnrpc.RegisterLightningHandlerFromEndpoint(ctx, mux, cfg.RPCListeners[0], proxyOpts) @@ -648,27 +659,16 @@ func genCertPair(certFile, keyFile string) error { // genMacaroons generates a pair of macaroon files; one admin-level and one // read-only. These can also be used to generate more granular macaroons. -func genMacaroons(svc *bakery.Service, admFile, roFile string) error { - // Generate the admin macaroon and write it to a file. - admMacaroon, err := svc.NewMacaroon("", nil, nil) - if err != nil { - return err - } - admBytes, err := admMacaroon.MarshalBinary() - if err != nil { - return err - } - if err = ioutil.WriteFile(admFile, admBytes, 0600); err != nil { - return err - } +func genMacaroons(ctx context.Context, svc *bakery.Bakery, admFile, + roFile string) error { // Generate the read-only macaroon and write it to a file. - roMacaroon, err := macaroons.AddConstraints(admMacaroon, - macaroons.AllowConstraint(roPermissions...)) + roMacaroon, err := svc.Oven.NewMacaroon(ctx, bakery.LatestVersion, nil, + readPermissions...) if err != nil { return err } - roBytes, err := roMacaroon.MarshalBinary() + roBytes, err := roMacaroon.M().MarshalBinary() if err != nil { return err } @@ -677,6 +677,20 @@ func genMacaroons(svc *bakery.Service, admFile, roFile string) error { return err } + // Generate the admin macaroon and write it to a file. + admMacaroon, err := svc.Oven.NewMacaroon(ctx, bakery.LatestVersion, + nil, append(readPermissions, writePermissions...)...) + if err != nil { + return err + } + admBytes, err := admMacaroon.M().MarshalBinary() + if err != nil { + return err + } + if err = ioutil.WriteFile(admFile, admBytes, 0600); err != nil { + return err + } + return nil } @@ -685,7 +699,7 @@ func genMacaroons(svc *bakery.Service, admFile, roFile string) error { // the user to this RPC server. func waitForWalletPassword(grpcEndpoints, restEndpoints []string, serverOpts []grpc.ServerOption, proxyOpts []grpc.DialOption, - tlsConf *tls.Config, macaroonService *bakery.Service) ([]byte, []byte, error) { + tlsConf *tls.Config, macaroonService *bakery.Bakery) ([]byte, []byte, error) { // Set up a new PasswordService, which will listen // for passwords provided over RPC. diff --git a/lntest/node.go b/lntest/node.go index f18aacb9..e35cadc1 100644 --- a/lntest/node.go +++ b/lntest/node.go @@ -18,7 +18,7 @@ import ( "golang.org/x/net/context" "google.golang.org/grpc" "google.golang.org/grpc/credentials" - macaroon "gopkg.in/macaroon.v1" + macaroon "gopkg.in/macaroon.v2" "github.com/go-errors/errors" "github.com/lightningnetwork/lnd/lnrpc" diff --git a/macaroons/auth.go b/macaroons/auth.go index c616b014..e088197e 100644 --- a/macaroons/auth.go +++ b/macaroons/auth.go @@ -3,15 +3,13 @@ package macaroons import ( "encoding/hex" "fmt" - "net" + + "google.golang.org/grpc/metadata" "golang.org/x/net/context" - "google.golang.org/grpc/metadata" - "google.golang.org/grpc/peer" - "gopkg.in/macaroon-bakery.v1/bakery" - "gopkg.in/macaroon-bakery.v1/bakery/checkers" - macaroon "gopkg.in/macaroon.v1" + "gopkg.in/macaroon-bakery.v2/bakery" + macaroon "gopkg.in/macaroon.v2" ) // MacaroonCredential wraps a macaroon to implement the @@ -54,13 +52,11 @@ func NewMacaroonCredential(m *macaroon.Macaroon) MacaroonCredential { // bakery service, context, and uri. Within the passed context.Context, we // expect a macaroon to be encoded as request metadata using the key // "macaroon". -func ValidateMacaroon(ctx context.Context, method string, - svc *bakery.Service) error { +func ValidateMacaroon(ctx context.Context, requiredPermissions []bakery.Op, + svc *bakery.Bakery) error { // Get macaroon bytes from context and unmarshal into macaroon. - // - // TODO(aakselrod): use FromIncomingContext after grpc update in glide. - md, ok := metadata.FromContext(ctx) + md, ok := metadata.FromIncomingContext(ctx) if !ok { return fmt.Errorf("unable to get metadata from context") } @@ -69,16 +65,6 @@ func ValidateMacaroon(ctx context.Context, method string, len(md["macaroon"])) } - // Get peer info and extract IP address from it for macaroon check - pr, ok := peer.FromContext(ctx) - if !ok { - return fmt.Errorf("unable to get peer info from context") - } - peerAddr, _, err := net.SplitHostPort(pr.Addr.String()) - if err != nil { - return fmt.Errorf("unable to parse peer address") - } - // With the macaroon obtained, we'll now decode the hex-string // encoding, then unmarshal it from binary into its concrete struct // representation. @@ -93,12 +79,8 @@ func ValidateMacaroon(ctx context.Context, method string, } // Check the method being called against the permitted operation and - // the expiration time and return the result. - // - // TODO(aakselrod): Add more checks as required. - return svc.Check(macaroon.Slice{mac}, checkers.New( - AllowChecker(method), - TimeoutChecker(), - IPLockChecker(peerAddr), - )) + // the expiration time and IP address and return the result. + authChecker := svc.Checker.Auth(macaroon.Slice{mac}) + _, err = authChecker.Allow(ctx, requiredPermissions...) + return err } diff --git a/macaroons/constraints.go b/macaroons/constraints.go index 50a9a123..f5277dd3 100644 --- a/macaroons/constraints.go +++ b/macaroons/constraints.go @@ -5,14 +5,22 @@ import ( "net" "time" - "gopkg.in/macaroon-bakery.v1/bakery/checkers" - macaroon "gopkg.in/macaroon.v1" + "google.golang.org/grpc/peer" + + "gopkg.in/macaroon-bakery.v2/bakery/checkers" + macaroon "gopkg.in/macaroon.v2" + + "golang.org/x/net/context" ) -// Constraint type adds a layer of indirection over macaroon caveats and -// checkers. +// Constraint type adds a layer of indirection over macaroon caveats. type Constraint func(*macaroon.Macaroon) error +// Checker type adds a layer of indirection over macaroon checkers. A Checker +// returns the name of the checker and the checker function; these are used to +// register the function with the bakery service's compound checker. +type Checker func() (string, checkers.Func) + // AddConstraints returns new derived macaroon by applying every passed // constraint and tightening its restrictions. func AddConstraints(mac *macaroon.Macaroon, cs ...Constraint) (*macaroon.Macaroon, error) { @@ -27,21 +35,7 @@ func AddConstraints(mac *macaroon.Macaroon, cs ...Constraint) (*macaroon.Macaroo // Each *Constraint function is a functional option, which takes a pointer // to the macaroon and adds another restriction to it. For each *Constraint, -// the corresponding *Checker is provided. - -// AllowConstraint restricts allowed operations set to the ones -// passed to it. -func AllowConstraint(ops ...string) func(*macaroon.Macaroon) error { - return func(mac *macaroon.Macaroon) error { - caveat := checkers.AllowCaveat(ops...) - return mac.AddFirstPartyCaveat(caveat.Condition) - } -} - -// AllowChecker wraps default checkers.OperationChecker. -func AllowChecker(method string) checkers.Checker { - return checkers.OperationChecker(method) -} +// the corresponding *Checker is provided if not provided by default. // TimeoutConstraint restricts the lifetime of the macaroon // to the amount of seconds given. @@ -50,15 +44,10 @@ func TimeoutConstraint(seconds int64) func(*macaroon.Macaroon) error { macaroonTimeout := time.Duration(seconds) requestTimeout := time.Now().Add(time.Second * macaroonTimeout) caveat := checkers.TimeBeforeCaveat(requestTimeout) - return mac.AddFirstPartyCaveat(caveat.Condition) + return mac.AddFirstPartyCaveat([]byte(caveat.Condition)) } } -// TimeoutChecker wraps default checkers.TimeBefore checker. -func TimeoutChecker() checkers.Checker { - return checkers.TimeBefore -} - // IPLockConstraint locks macaroon to a specific IP address. // If address is an empty string, this constraint does nothing to // accommodate default value's desired behavior. @@ -69,24 +58,33 @@ func IPLockConstraint(ipAddr string) func(*macaroon.Macaroon) error { if macaroonIPAddr == nil { return fmt.Errorf("incorrect macaroon IP-lock address") } - caveat := checkers.ClientIPAddrCaveat(macaroonIPAddr) - return mac.AddFirstPartyCaveat(caveat.Condition) + caveat := checkers.Condition("ipaddr", + macaroonIPAddr.String()) + return mac.AddFirstPartyCaveat([]byte(caveat)) } return nil } } // IPLockChecker accepts client IP from the validation context and compares it -// with IP locked in the macaroon. -func IPLockChecker(clientIP string) checkers.Checker { - return checkers.CheckerFunc{ - Condition_: checkers.CondClientIPAddr, - Check_: func(_, cav string) error { - if !net.ParseIP(cav).Equal(net.ParseIP(clientIP)) { - msg := "macaroon locked to different IP address" - return fmt.Errorf(msg) - } - return nil - }, +// with IP locked in the macaroon. It is of the `Checker` type. +func IPLockChecker() (string, checkers.Func) { + return "ipaddr", func(ctx context.Context, cond, arg string) error { + // Get peer info and extract IP address from it for macaroon + // check. + pr, ok := peer.FromContext(ctx) + if !ok { + return fmt.Errorf("unable to get peer info from context") + } + peerAddr, _, err := net.SplitHostPort(pr.Addr.String()) + if err != nil { + return fmt.Errorf("unable to parse peer address") + } + + if !net.ParseIP(arg).Equal(net.ParseIP(peerAddr)) { + msg := "macaroon locked to different IP address" + return fmt.Errorf(msg) + } + return nil } } diff --git a/macaroons/service.go b/macaroons/service.go index d54c1027..6d6b1706 100644 --- a/macaroons/service.go +++ b/macaroons/service.go @@ -1,9 +1,15 @@ package macaroons import ( + "fmt" "path" - "gopkg.in/macaroon-bakery.v1/bakery" + "google.golang.org/grpc" + + "gopkg.in/macaroon-bakery.v2/bakery" + "gopkg.in/macaroon-bakery.v2/bakery/checkers" + + "golang.org/x/net/context" "github.com/boltdb/bolt" ) @@ -15,8 +21,13 @@ var ( ) // NewService returns a service backed by the macaroon Bolt DB stored in the -// passed directory. -func NewService(dir string) (*bakery.Service, error) { +// passed directory. The `checks` argument can be any of the `Checker` type +// functions defined in this package, or a custom checker if desired. This +// constructor prevents double-registration of checkers to prevent panics, so +// listing the same checker more than once is not harmful. Default checkers, +// such as those for `allow`, `time-before`, `declared`, and `error` caveats +// are registered automatically and don't need to be added. +func NewService(dir string, checks ...Checker) (*bakery.Bakery, error) { // Open the database that we'll use to store the primary macaroon key, // and all generated macaroons+caveats. macaroonDB, err := bolt.Open(path.Join(dir, dbFilename), 0600, @@ -29,19 +40,90 @@ func NewService(dir string) (*bakery.Service, error) { if err != nil { return nil, err } - macaroonStore, err := NewStorage(macaroonDB) - if err != nil { - return nil, err - } - macaroonParams := bakery.NewServiceParams{ + macaroonParams := bakery.BakeryParams{ Location: "lnd", - Store: macaroonStore, RootKeyStore: rootKeyStore, // No third-party caveat support for now. // TODO(aakselrod): Add third-party caveat support. Locator: nil, Key: nil, } - return bakery.NewService(macaroonParams) + + svc := bakery.New(macaroonParams) + + // Register all custom caveat checkers with the bakery's checker. + // TODO(aakselrod): Add more checks as required. + checker := svc.Checker.FirstPartyCaveatChecker.(*checkers.Checker) + for _, check := range checks { + cond, fun := check() + if !isRegistered(checker, cond) { + checker.Register(cond, "std", fun) + } + } + + return svc, nil +} + +// isRegistered checks to see if the required checker has already been +// registered in order to avoid a panic caused by double registration. +func isRegistered(c *checkers.Checker, name string) bool { + if c == nil { + return false + } + + for _, info := range c.Info() { + if info.Name == name && info.Prefix == "std" { + return true + } + } + + return false +} + +// UnaryServerInterceptor is a GRPC interceptor that checks whether the +// request is authorized by the included macaroons. +func UnaryServerInterceptor(svc *bakery.Bakery, + permissionMap map[string][]bakery.Op) grpc.UnaryServerInterceptor { + + return func(ctx context.Context, req interface{}, + info *grpc.UnaryServerInfo, + handler grpc.UnaryHandler) (interface{}, error) { + + if _, ok := permissionMap[info.FullMethod]; !ok { + return nil, fmt.Errorf("%s: unknown permissions "+ + "required for method", info.FullMethod) + } + + err := ValidateMacaroon(ctx, permissionMap[info.FullMethod], + svc) + if err != nil { + return nil, err + } + + return handler(ctx, req) + } +} + +// StreamServerInterceptor is a GRPC interceptor that checks whether the +// request is authorized by the included macaroons. +func StreamServerInterceptor(svc *bakery.Bakery, + permissionMap map[string][]bakery.Op) grpc.StreamServerInterceptor { + + return func(srv interface{}, ss grpc.ServerStream, + info *grpc.StreamServerInfo, handler grpc.StreamHandler) error { + + if _, ok := permissionMap[info.FullMethod]; !ok { + return fmt.Errorf("%s: unknown permissions required "+ + "for method", info.FullMethod) + } + + err := ValidateMacaroon(ss.Context(), + permissionMap[info.FullMethod], svc) + if err != nil { + return err + } + + return handler(srv, ss) + } } diff --git a/macaroons/store.go b/macaroons/store.go index 232e0d6c..d57c2ba9 100644 --- a/macaroons/store.go +++ b/macaroons/store.go @@ -5,6 +5,8 @@ import ( "fmt" "io" + "golang.org/x/net/context" + "github.com/boltdb/bolt" ) @@ -21,7 +23,7 @@ var ( // just 0, to emulate the memory storage that comes with bakery. // // TODO(aakselrod): Add support for key rotation. - defaultRootKeyID = "0" + defaultRootKeyID = []byte("0") // macaroonBucketName is the name of the macaroon store bucket. macaroonBucketName = []byte("macaroons") @@ -49,13 +51,13 @@ func NewRootKeyStorage(db *bolt.DB) (*RootKeyStorage, error) { } // Get implements the Get method for the bakery.RootKeyStorage interface. -func (r *RootKeyStorage) Get(id string) ([]byte, error) { +func (r *RootKeyStorage) Get(_ context.Context, id []byte) ([]byte, error) { var rootKey []byte err := r.View(func(tx *bolt.Tx) error { - dbKey := tx.Bucket(rootKeyBucketName).Get([]byte(id)) + dbKey := tx.Bucket(rootKeyBucketName).Get(id) if len(dbKey) == 0 { return fmt.Errorf("root key with id %s doesn't exist", - id) + string(id)) } rootKey = make([]byte, len(dbKey)) @@ -72,12 +74,12 @@ func (r *RootKeyStorage) Get(id string) ([]byte, error) { // RootKey implements the RootKey method for the bakery.RootKeyStorage // interface. // TODO(aakselrod): Add support for key rotation. -func (r *RootKeyStorage) RootKey() ([]byte, string, error) { +func (r *RootKeyStorage) RootKey(_ context.Context) ([]byte, []byte, error) { var rootKey []byte id := defaultRootKeyID err := r.Update(func(tx *bolt.Tx) error { ns := tx.Bucket(rootKeyBucketName) - rootKey = ns.Get([]byte(id)) + rootKey = ns.Get(id) // If there's no root key stored in the bucket yet, create one. if len(rootKey) != 0 { @@ -89,69 +91,11 @@ func (r *RootKeyStorage) RootKey() ([]byte, string, error) { if _, err := io.ReadFull(rand.Reader, rootKey[:]); err != nil { return err } - return ns.Put([]byte(id), rootKey) + return ns.Put(id, rootKey) }) if err != nil { - return nil, "", err + return nil, nil, err } return rootKey, id, nil } - -// Storage implements the bakery.Storage interface. -type Storage struct { - *bolt.DB -} - -// NewStorage creates a Storage instance. -// -// TODO(aakselrod): Add support for encryption of data with passphrase. -func NewStorage(db *bolt.DB) (*Storage, error) { - // If the store's bucket doesn't exist, create it. - err := db.Update(func(tx *bolt.Tx) error { - _, err := tx.CreateBucketIfNotExists(macaroonBucketName) - return err - }) - if err != nil { - return nil, err - } - - // Return the DB wrapped in a Storage object. - return &Storage{db}, nil -} - -// Put implements the Put method for the bakery.Storage interface. -func (s *Storage) Put(location string, item string) error { - return s.Update(func(tx *bolt.Tx) error { - return tx.Bucket(macaroonBucketName).Put([]byte(location), - []byte(item)) - }) -} - -// Get implements the Get method for the bakery.Storage interface. -func (s *Storage) Get(location string) (string, error) { - var item []byte - err := s.View(func(tx *bolt.Tx) error { - itemBytes := tx.Bucket(macaroonBucketName).Get([]byte(location)) - if len(itemBytes) == 0 { - return fmt.Errorf("couldn't get item for location %s", - location) - } - - item = make([]byte, len(itemBytes)) - copy(item, itemBytes) - return nil - }) - if err != nil { - return "", err - } - - return string(item), nil -} - -// Del implements the Del method for the bakery.Storage interface. -func (s *Storage) Del(location string) error { - return s.Update(func(tx *bolt.Tx) error { - return tx.Bucket(macaroonBucketName).Delete([]byte(location)) - }) -} diff --git a/rpcserver.go b/rpcserver.go index 5bb1dc19..185679b8 100644 --- a/rpcserver.go +++ b/rpcserver.go @@ -13,7 +13,7 @@ import ( "strings" "time" - "gopkg.in/macaroon-bakery.v1/bakery" + "gopkg.in/macaroon-bakery.v2/bakery" "sync" "sync/atomic" @@ -25,7 +25,6 @@ import ( "github.com/lightningnetwork/lnd/lnrpc" "github.com/lightningnetwork/lnd/lnwallet" "github.com/lightningnetwork/lnd/lnwire" - "github.com/lightningnetwork/lnd/macaroons" "github.com/lightningnetwork/lnd/routing" "github.com/lightningnetwork/lnd/zpay32" "github.com/roasbeef/btcd/blockchain" @@ -43,25 +42,227 @@ import ( var ( defaultAccount uint32 = waddrmgr.DefaultAccountNum - // roPermissions is a slice of method names that are considered "read-only" - // for authorization purposes, all lowercase. - roPermissions = []string{ - "verifymessage", - "getinfo", - "listpeers", - "walletbalance", - "channelbalance", - "listchannels", - "readinvoices", - "gettransactions", - "describegraph", - "getchaninfo", - "getnodeinfo", - "queryroutes", - "getnetworkinfo", - "listpayments", - "decodepayreq", - "feereport", + // readPermissions is a slice of all entities that allow read + // permissions for authorization purposes, all lowercase. + readPermissions = []bakery.Op{ + { + Entity: "onchain", + Action: "read", + }, + { + Entity: "offchain", + Action: "read", + }, + { + Entity: "address", + Action: "read", + }, + { + Entity: "message", + Action: "read", + }, + { + Entity: "peers", + Action: "read", + }, + { + Entity: "info", + Action: "read", + }, + } + + // writePermissions is a slice of all entities that allow write + // permissions for authorization purposes, all lowercase. + writePermissions = []bakery.Op{ + { + Entity: "onchain", + Action: "write", + }, + { + Entity: "offchain", + Action: "write", + }, + { + Entity: "address", + Action: "write", + }, + { + Entity: "message", + Action: "write", + }, + { + Entity: "peers", + Action: "write", + }, + { + Entity: "info", + Action: "write", + }, + } + + // permissions maps RPC calls to the permissions they require. + permissions = map[string][]bakery.Op{ + "/lnrpc.Lightning/SendCoins": {{ + Entity: "onchain", + Action: "write", + }}, + "/lnrpc.Lightning/SendMany": {{ + Entity: "onchain", + Action: "write", + }}, + "/lnrpc.Lightning/NewAddress": {{ + Entity: "address", + Action: "write", + }}, + "/lnrpc.Lightning/NewWitnessAddress": {{ + Entity: "address", + Action: "write", + }}, + "/lnrpc.Lightning/SignMessage": {{ + Entity: "message", + Action: "write", + }}, + "/lnrpc.Lightning/VerifyMessage": {{ + Entity: "message", + Action: "read", + }}, + "/lnrpc.Lightning/ConnectPeer": {{ + Entity: "peers", + Action: "write", + }}, + "/lnrpc.Lightning/DisconnectPeer": {{ + Entity: "peers", + Action: "write", + }}, + "/lnrpc.Lightning/OpenChannel": {{ + Entity: "onchain", + Action: "write", + }, { + Entity: "offchain", + Action: "write", + }}, + "/lnrpc.Lightning/OpenchannelSync": {{ + Entity: "onchain", + Action: "write", + }, { + Entity: "offchain", + Action: "write", + }}, + "/lnrpc.Lightning/CloseChannel": {{ + Entity: "onchain", + Action: "write", + }, { + Entity: "offchain", + Action: "write", + }}, + "/lnrpc.Lightning/GetInfo": {{ + Entity: "info", + Action: "read", + }}, + "/lnrpc.Lightning/ListPeers": {{ + Entity: "peers", + Action: "read", + }}, + "/lnrpc.Lightning/WalletBalance": {{ + Entity: "onchain", + Action: "read", + }}, + "/lnrpc.Lightning/ChannelBalance": {{ + Entity: "offchain", + Action: "read", + }}, + "/lnrpc.Lightning/PendingChannels": {{ + Entity: "offchain", + Action: "read", + }}, + "/lnrpc.Lightning/ListChannels": {{ + Entity: "offchain", + Action: "read", + }}, + "/lnrpc.Lightning/SendPayment": {{ + Entity: "offchain", + Action: "write", + }}, + "/lnrpc.Lightning/SendPaymentSync": {{ + Entity: "offchain", + Action: "write", + }}, + "/lnrpc.Lightning/AddInvoice": {{ + Entity: "offchain", + Action: "write", + }}, + "/lnrpc.Lightning/LookupInvoice": {{ + Entity: "offchain", + Action: "read", + }}, + "/lnrpc.Lightning/ListInvoices": {{ + Entity: "offchain", + Action: "read", + }}, + "/lnrpc.Lightning/SubscribeInvoices": {{ + Entity: "offchain", + Action: "read", + }}, + "/lnrpc.Lightning/SubscribeTransactions": {{ + Entity: "onchain", + Action: "read", + }}, + "/lnrpc.Lightning/GetTransactions": {{ + Entity: "onchain", + Action: "read", + }}, + "/lnrpc.Lightning/DescribeGraph": {{ + Entity: "info", + Action: "read", + }}, + "/lnrpc.Lightning/GetChanInfo": {{ + Entity: "info", + Action: "read", + }}, + "/lnrpc.Lightning/GetNodeInfo": {{ + Entity: "info", + Action: "read", + }}, + "/lnrpc.Lightning/QueryRoutes": {{ + Entity: "info", + Action: "read", + }}, + "/lnrpc.Lightning/GetNetworkInfo": {{ + Entity: "info", + Action: "read", + }}, + "/lnrpc.Lightning/StopDaemon": {{ + Entity: "info", + Action: "write", + }}, + "/lnrpc.Lightning/SubscribeChannelGraph": {{ + Entity: "info", + Action: "read", + }}, + "/lnrpc.Lightning/ListPayments": {{ + Entity: "offchain", + Action: "read", + }}, + "/lnrpc.Lightning/DeleteAllPayments": {{ + Entity: "offchain", + Action: "write", + }}, + "/lnrpc.Lightning/DebugLevel": {{ + Entity: "info", + Action: "write", + }}, + "/lnrpc.Lightning/DecodePayReq": {{ + Entity: "offchain", + Action: "read", + }}, + "/lnrpc.Lightning/FeeReport": {{ + Entity: "offchain", + Action: "read", + }}, + "/lnrpc.Lightning/UpdateChannelPolicy": {{ + Entity: "offchain", + Action: "write", + }}, } ) @@ -77,10 +278,6 @@ type rpcServer struct { started int32 // To be used atomically. shutdown int32 // To be used atomically. - // authSvc is the authentication/authorization service backed by - // macaroons. - authSvc *bakery.Service - server *server wg sync.WaitGroup @@ -93,11 +290,10 @@ type rpcServer struct { var _ lnrpc.LightningServer = (*rpcServer)(nil) // newRPCServer creates and returns a new instance of the rpcServer. -func newRPCServer(s *server, authSvc *bakery.Service) *rpcServer { +func newRPCServer(s *server) *rpcServer { return &rpcServer{ - server: s, - authSvc: authSvc, - quit: make(chan struct{}, 1), + server: s, + quit: make(chan struct{}, 1), } } @@ -201,14 +397,6 @@ func determineFeePerByte(feeEstimator lnwallet.FeeEstimator, targetConf int32, func (r *rpcServer) SendCoins(ctx context.Context, in *lnrpc.SendCoinsRequest) (*lnrpc.SendCoinsResponse, error) { - // Check macaroon to see if this is allowed. - if r.authSvc != nil { - if err := macaroons.ValidateMacaroon(ctx, "sendcoins", - r.authSvc); err != nil { - return nil, err - } - } - // Based on the passed fee related paramters, we'll determine an // approriate fee rate for this transaction. feePerByte, err := determineFeePerByte( @@ -237,14 +425,6 @@ func (r *rpcServer) SendCoins(ctx context.Context, func (r *rpcServer) SendMany(ctx context.Context, in *lnrpc.SendManyRequest) (*lnrpc.SendManyResponse, error) { - // Check macaroon to see if this is allowed. - if r.authSvc != nil { - if err := macaroons.ValidateMacaroon(ctx, "sendcoins", - r.authSvc); err != nil { - return nil, err - } - } - // Based on the passed fee related paramters, we'll determine an // approriate fee rate for this transaction. feePerByte, err := determineFeePerByte( @@ -271,14 +451,6 @@ func (r *rpcServer) SendMany(ctx context.Context, func (r *rpcServer) NewAddress(ctx context.Context, in *lnrpc.NewAddressRequest) (*lnrpc.NewAddressResponse, error) { - // Check macaroon to see if this is allowed. - if r.authSvc != nil { - if err := macaroons.ValidateMacaroon(ctx, "newaddress", - r.authSvc); err != nil { - return nil, err - } - } - // Translate the gRPC proto address type to the wallet controller's // available address types. var addrType lnwallet.AddressType @@ -305,14 +477,6 @@ func (r *rpcServer) NewAddress(ctx context.Context, func (r *rpcServer) NewWitnessAddress(ctx context.Context, in *lnrpc.NewWitnessAddressRequest) (*lnrpc.NewAddressResponse, error) { - // Check macaroon to see if this is allowed. - if r.authSvc != nil { - if err := macaroons.ValidateMacaroon(ctx, "newaddress", - r.authSvc); err != nil { - return nil, err - } - } - addr, err := r.server.cc.wallet.NewAddress( lnwallet.NestedWitnessPubKey, false, ) @@ -331,14 +495,6 @@ func (r *rpcServer) NewWitnessAddress(ctx context.Context, func (r *rpcServer) SignMessage(ctx context.Context, in *lnrpc.SignMessageRequest) (*lnrpc.SignMessageResponse, error) { - // Check macaroon to see if this is allowed. - if r.authSvc != nil { - if err := macaroons.ValidateMacaroon(ctx, "signmessage", - r.authSvc); err != nil { - return nil, err - } - } - if in.Msg == nil { return nil, fmt.Errorf("need a message to sign") } @@ -359,14 +515,6 @@ func (r *rpcServer) SignMessage(ctx context.Context, func (r *rpcServer) VerifyMessage(ctx context.Context, in *lnrpc.VerifyMessageRequest) (*lnrpc.VerifyMessageResponse, error) { - // Check macaroon to see if this is allowed. - if r.authSvc != nil { - if err := macaroons.ValidateMacaroon(ctx, "verifymessage", - r.authSvc); err != nil { - return nil, err - } - } - if in.Msg == nil { return nil, fmt.Errorf("need a message to verify") } @@ -406,14 +554,6 @@ func (r *rpcServer) VerifyMessage(ctx context.Context, func (r *rpcServer) ConnectPeer(ctx context.Context, in *lnrpc.ConnectPeerRequest) (*lnrpc.ConnectPeerResponse, error) { - // Check macaroon to see if this is allowed. - if r.authSvc != nil { - if err := macaroons.ValidateMacaroon(ctx, "connectpeer", - r.authSvc); err != nil { - return nil, err - } - } - // The server hasn't yet started, so it won't be able to service any of // our requests, so we'll bail early here. if !r.server.Started() { @@ -475,14 +615,6 @@ func (r *rpcServer) ConnectPeer(ctx context.Context, func (r *rpcServer) DisconnectPeer(ctx context.Context, in *lnrpc.DisconnectPeerRequest) (*lnrpc.DisconnectPeerResponse, error) { - // Check macaroon to see if this is allowed. - if r.authSvc != nil { - if err := macaroons.ValidateMacaroon(ctx, "disconnectpeer", - r.authSvc); err != nil { - return nil, err - } - } - rpcsLog.Debugf("[disconnectpeer] from peer(%s)", in.PubKey) if !r.server.Started() { @@ -532,14 +664,6 @@ func (r *rpcServer) DisconnectPeer(ctx context.Context, func (r *rpcServer) OpenChannel(in *lnrpc.OpenChannelRequest, updateStream lnrpc.Lightning_OpenChannelServer) error { - // Check macaroon to see if this is allowed. - if r.authSvc != nil { - if err := macaroons.ValidateMacaroon(updateStream.Context(), - "openchannel", r.authSvc); err != nil { - return err - } - } - rpcsLog.Tracef("[openchannel] request to peerid(%v) "+ "allocation(us=%v, them=%v)", in.TargetPeerId, in.LocalFundingAmount, in.PushSat) @@ -686,14 +810,6 @@ out: func (r *rpcServer) OpenChannelSync(ctx context.Context, in *lnrpc.OpenChannelRequest) (*lnrpc.ChannelPoint, error) { - // Check macaroon to see if this is allowed. - if r.authSvc != nil { - if err := macaroons.ValidateMacaroon(ctx, "openchannel", - r.authSvc); err != nil { - return nil, err - } - } - rpcsLog.Tracef("[openchannel] request to peerid(%v) "+ "allocation(us=%v, them=%v)", in.TargetPeerId, in.LocalFundingAmount, in.PushSat) @@ -818,14 +934,6 @@ func getChanPointFundingTxid(chanPoint *lnrpc.ChannelPoint) ([]byte, error) { func (r *rpcServer) CloseChannel(in *lnrpc.CloseChannelRequest, updateStream lnrpc.Lightning_CloseChannelServer) error { - // Check macaroon to see if this is allowed. - if r.authSvc != nil { - if err := macaroons.ValidateMacaroon(updateStream.Context(), - "closechannel", r.authSvc); err != nil { - return err - } - } - force := in.Force index := in.ChannelPoint.OutputIndex txidHash, err := getChanPointFundingTxid(in.GetChannelPoint()) @@ -1033,14 +1141,6 @@ func (r *rpcServer) fetchActiveChannel(chanPoint wire.OutPoint) (*lnwallet.Light func (r *rpcServer) GetInfo(ctx context.Context, in *lnrpc.GetInfoRequest) (*lnrpc.GetInfoResponse, error) { - // Check macaroon to see if this is allowed. - if r.authSvc != nil { - if err := macaroons.ValidateMacaroon(ctx, "getinfo", - r.authSvc); err != nil { - return nil, err - } - } - var activeChannels uint32 serverPeers := r.server.Peers() for _, serverPeer := range serverPeers { @@ -1098,7 +1198,6 @@ func (r *rpcServer) GetInfo(ctx context.Context, Testnet: activeNetParams.Params == &chaincfg.TestNet3Params, Chains: activeChains, Uris: uris, - Alias: nodeAnn.Alias.String(), }, nil } @@ -1106,14 +1205,6 @@ func (r *rpcServer) GetInfo(ctx context.Context, func (r *rpcServer) ListPeers(ctx context.Context, in *lnrpc.ListPeersRequest) (*lnrpc.ListPeersResponse, error) { - // Check macaroon to see if this is allowed. - if r.authSvc != nil { - if err := macaroons.ValidateMacaroon(ctx, "listpeers", - r.authSvc); err != nil { - return nil, err - } - } - rpcsLog.Tracef("[listpeers] request") serverPeers := r.server.Peers() @@ -1167,14 +1258,6 @@ func (r *rpcServer) ListPeers(ctx context.Context, func (r *rpcServer) WalletBalance(ctx context.Context, in *lnrpc.WalletBalanceRequest) (*lnrpc.WalletBalanceResponse, error) { - // Check macaroon to see if this is allowed. - if r.authSvc != nil { - if err := macaroons.ValidateMacaroon(ctx, "walletbalance", - r.authSvc); err != nil { - return nil, err - } - } - // Get total balance, from txs that have >= 0 confirmations. totalBal, err := r.server.cc.wallet.ConfirmedBalance(0, in.WitnessOnly) if err != nil { @@ -1204,14 +1287,6 @@ func (r *rpcServer) WalletBalance(ctx context.Context, func (r *rpcServer) ChannelBalance(ctx context.Context, in *lnrpc.ChannelBalanceRequest) (*lnrpc.ChannelBalanceResponse, error) { - // Check macaroon to see if this is allowed. - if r.authSvc != nil { - if err := macaroons.ValidateMacaroon(ctx, "channelbalance", - r.authSvc); err != nil { - return nil, err - } - } - channels, err := r.server.chanDB.FetchAllChannels() if err != nil { return nil, err @@ -1234,14 +1309,6 @@ func (r *rpcServer) ChannelBalance(ctx context.Context, func (r *rpcServer) PendingChannels(ctx context.Context, in *lnrpc.PendingChannelsRequest) (*lnrpc.PendingChannelsResponse, error) { - // Check macaroon to see if this is allowed. - if r.authSvc != nil { - if err := macaroons.ValidateMacaroon(ctx, "listchannels", - r.authSvc); err != nil { - return nil, err - } - } - rpcsLog.Debugf("[pendingchannels]") resp := &lnrpc.PendingChannelsResponse{} @@ -1402,14 +1469,6 @@ func (r *rpcServer) PendingChannels(ctx context.Context, func (r *rpcServer) ListChannels(ctx context.Context, in *lnrpc.ListChannelsRequest) (*lnrpc.ListChannelsResponse, error) { - // Check macaroon to see if this is allowed. - if r.authSvc != nil { - if err := macaroons.ValidateMacaroon(ctx, "listchannels", - r.authSvc); err != nil { - return nil, err - } - } - resp := &lnrpc.ListChannelsResponse{} graph := r.server.chanDB.ChannelGraph() @@ -1552,14 +1611,6 @@ func validatePayReqExpiry(payReq *zpay32.Invoice) error { // bi-directional stream allowing clients to rapidly send payments through the // Lightning Network with a single persistent connection. func (r *rpcServer) SendPayment(paymentStream lnrpc.Lightning_SendPaymentServer) error { - // Check macaroon to see if this is allowed. - if r.authSvc != nil { - if err := macaroons.ValidateMacaroon(paymentStream.Context(), - "sendpayment", r.authSvc); err != nil { - return err - } - } - // For each payment we need to know the msat amount, the destination // public key, and the payment hash. type payment struct { @@ -1805,14 +1856,6 @@ func (r *rpcServer) SendPayment(paymentStream lnrpc.Lightning_SendPaymentServer) func (r *rpcServer) SendPaymentSync(ctx context.Context, nextPayment *lnrpc.SendRequest) (*lnrpc.SendResponse, error) { - // Check macaroon to see if this is allowed. - if r.authSvc != nil { - if err := macaroons.ValidateMacaroon(ctx, "sendpayment", - r.authSvc); err != nil { - return nil, err - } - } - // TODO(roasbeef): enforce fee limits, pass into router, ditch if exceed limit // * limit either a %, or absolute, or iff more than sending @@ -1939,14 +1982,6 @@ func (r *rpcServer) SendPaymentSync(ctx context.Context, func (r *rpcServer) AddInvoice(ctx context.Context, invoice *lnrpc.Invoice) (*lnrpc.AddInvoiceResponse, error) { - // Check macaroon to see if this is allowed. - if r.authSvc != nil { - if err := macaroons.ValidateMacaroon(ctx, "addinvoice", - r.authSvc); err != nil { - return nil, err - } - } - var paymentPreimage [32]byte switch { @@ -2164,14 +2199,6 @@ func createRPCInvoice(invoice *channeldb.Invoice) (*lnrpc.Invoice, error) { func (r *rpcServer) LookupInvoice(ctx context.Context, req *lnrpc.PaymentHash) (*lnrpc.Invoice, error) { - // Check macaroon to see if this is allowed. - if r.authSvc != nil { - if err := macaroons.ValidateMacaroon(ctx, "readinvoices", - r.authSvc); err != nil { - return nil, err - } - } - var ( payHash [32]byte rHash []byte @@ -2221,14 +2248,6 @@ func (r *rpcServer) LookupInvoice(ctx context.Context, func (r *rpcServer) ListInvoices(ctx context.Context, req *lnrpc.ListInvoiceRequest) (*lnrpc.ListInvoiceResponse, error) { - // Check macaroon to see if this is allowed. - if r.authSvc != nil { - if err := macaroons.ValidateMacaroon(ctx, "readinvoices", - r.authSvc); err != nil { - return nil, err - } - } - dbInvoices, err := r.server.chanDB.FetchAllInvoices(req.PendingOnly) if err != nil { return nil, err @@ -2255,14 +2274,6 @@ func (r *rpcServer) ListInvoices(ctx context.Context, func (r *rpcServer) SubscribeInvoices(req *lnrpc.InvoiceSubscription, updateStream lnrpc.Lightning_SubscribeInvoicesServer) error { - // Check macaroon to see if this is allowed. - if r.authSvc != nil { - if err := macaroons.ValidateMacaroon(updateStream.Context(), - "readinvoices", r.authSvc); err != nil { - return err - } - } - invoiceClient := r.server.invoices.SubscribeNotifications() defer invoiceClient.Cancel() @@ -2291,14 +2302,6 @@ func (r *rpcServer) SubscribeInvoices(req *lnrpc.InvoiceSubscription, func (r *rpcServer) SubscribeTransactions(req *lnrpc.GetTransactionsRequest, updateStream lnrpc.Lightning_SubscribeTransactionsServer) error { - // Check macaroon to see if this is allowed. - if r.authSvc != nil { - if err := macaroons.ValidateMacaroon(updateStream.Context(), - "gettransactions", r.authSvc); err != nil { - return err - } - } - txClient, err := r.server.cc.wallet.SubscribeTransactions() if err != nil { return err @@ -2340,14 +2343,6 @@ func (r *rpcServer) SubscribeTransactions(req *lnrpc.GetTransactionsRequest, func (r *rpcServer) GetTransactions(ctx context.Context, _ *lnrpc.GetTransactionsRequest) (*lnrpc.TransactionDetails, error) { - // Check macaroon to see if this is allowed. - if r.authSvc != nil { - if err := macaroons.ValidateMacaroon(ctx, "gettransactions", - r.authSvc); err != nil { - return nil, err - } - } - // TODO(roasbeef): add pagination support transactions, err := r.server.cc.wallet.ListTransactionDetails() if err != nil { @@ -2387,14 +2382,6 @@ func (r *rpcServer) GetTransactions(ctx context.Context, func (r *rpcServer) DescribeGraph(ctx context.Context, _ *lnrpc.ChannelGraphRequest) (*lnrpc.ChannelGraph, error) { - // Check macaroon to see if this is allowed. - if r.authSvc != nil { - if err := macaroons.ValidateMacaroon(ctx, "describegraph", - r.authSvc); err != nil { - return nil, err - } - } - resp := &lnrpc.ChannelGraph{} // Obtain the pointer to the global singleton channel graph, this will @@ -2501,14 +2488,6 @@ func (r *rpcServer) GetChanInfo(ctx context.Context, graph := r.server.chanDB.ChannelGraph() - // Check macaroon to see if this is allowed. - if r.authSvc != nil { - if err := macaroons.ValidateMacaroon(ctx, "getchaninfo", - r.authSvc); err != nil { - return nil, err - } - } - edgeInfo, edge1, edge2, err := graph.FetchChannelEdgesByID(in.ChanId) if err != nil { return nil, err @@ -2527,14 +2506,6 @@ func (r *rpcServer) GetChanInfo(ctx context.Context, func (r *rpcServer) GetNodeInfo(ctx context.Context, in *lnrpc.NodeInfoRequest) (*lnrpc.NodeInfo, error) { - // Check macaroon to see if this is allowed. - if r.authSvc != nil { - if err := macaroons.ValidateMacaroon(ctx, "getnodeinfo", - r.authSvc); err != nil { - return nil, err - } - } - graph := r.server.chanDB.ChannelGraph() // First, parse the hex-encoded public key into a full in-memory public @@ -2608,14 +2579,6 @@ func (r *rpcServer) GetNodeInfo(ctx context.Context, func (r *rpcServer) QueryRoutes(ctx context.Context, in *lnrpc.QueryRoutesRequest) (*lnrpc.QueryRoutesResponse, error) { - // Check macaroon to see if this is allowed. - if r.authSvc != nil { - if err := macaroons.ValidateMacaroon(ctx, "queryroutes", - r.authSvc); err != nil { - return nil, err - } - } - // First parse the hex-encdoed public key into a full public key objet // we can properly manipulate. pubKeyBytes, err := hex.DecodeString(in.PubKey) @@ -2682,14 +2645,6 @@ func marshallRoute(route *routing.Route) *lnrpc.Route { func (r *rpcServer) GetNetworkInfo(ctx context.Context, _ *lnrpc.NetworkInfoRequest) (*lnrpc.NetworkInfo, error) { - // Check macaroon to see if this is allowed. - if r.authSvc != nil { - if err := macaroons.ValidateMacaroon(ctx, "getnetworkinfo", - r.authSvc); err != nil { - return nil, err - } - } - graph := r.server.chanDB.ChannelGraph() var ( @@ -2805,14 +2760,6 @@ func (r *rpcServer) GetNetworkInfo(ctx context.Context, func (r *rpcServer) StopDaemon(ctx context.Context, _ *lnrpc.StopRequest) (*lnrpc.StopResponse, error) { - // Check macaroon to see if this is allowed. - if r.authSvc != nil { - if err := macaroons.ValidateMacaroon(ctx, "stopdaemon", - r.authSvc); err != nil { - return nil, err - } - } - shutdownRequestChannel <- struct{}{} return &lnrpc.StopResponse{}, nil } @@ -2826,14 +2773,6 @@ func (r *rpcServer) StopDaemon(ctx context.Context, func (r *rpcServer) SubscribeChannelGraph(req *lnrpc.GraphTopologySubscription, updateStream lnrpc.Lightning_SubscribeChannelGraphServer) error { - // Check macaroon to see if this is allowed. - if r.authSvc != nil { - if err := macaroons.ValidateMacaroon(updateStream.Context(), - "describegraph", r.authSvc); err != nil { - return err - } - } - // First, we start by subscribing to a new intent to receive // notifications from the channel router. client, err := r.server.chanRouter.SubscribeTopology() @@ -2951,14 +2890,6 @@ func marshallTopologyChange(topChange *routing.TopologyChange) *lnrpc.GraphTopol func (r *rpcServer) ListPayments(ctx context.Context, _ *lnrpc.ListPaymentsRequest) (*lnrpc.ListPaymentsResponse, error) { - // Check macaroon to see if this is allowed. - if r.authSvc != nil { - if err := macaroons.ValidateMacaroon(ctx, "listpayments", - r.authSvc); err != nil { - return nil, err - } - } - rpcsLog.Debugf("[ListPayments]") payments, err := r.server.chanDB.FetchAllPayments() @@ -2992,14 +2923,6 @@ func (r *rpcServer) ListPayments(ctx context.Context, func (r *rpcServer) DeleteAllPayments(ctx context.Context, _ *lnrpc.DeleteAllPaymentsRequest) (*lnrpc.DeleteAllPaymentsResponse, error) { - // Check macaroon to see if this is allowed. - if r.authSvc != nil { - if err := macaroons.ValidateMacaroon(ctx, "deleteallpayments", - r.authSvc); err != nil { - return nil, err - } - } - rpcsLog.Debugf("[DeleteAllPayments]") if err := r.server.chanDB.DeleteAllPayments(); err != nil { @@ -3016,14 +2939,6 @@ func (r *rpcServer) DeleteAllPayments(ctx context.Context, func (r *rpcServer) DebugLevel(ctx context.Context, req *lnrpc.DebugLevelRequest) (*lnrpc.DebugLevelResponse, error) { - // Check macaroon to see if this is allowed. - if r.authSvc != nil { - if err := macaroons.ValidateMacaroon(ctx, "debuglevel", - r.authSvc); err != nil { - return nil, err - } - } - // If show is set, then we simply print out the list of available // sub-systems. if req.Show { @@ -3049,14 +2964,6 @@ func (r *rpcServer) DebugLevel(ctx context.Context, func (r *rpcServer) DecodePayReq(ctx context.Context, req *lnrpc.PayReqString) (*lnrpc.PayReq, error) { - // Check macaroon to see if this is allowed. - if r.authSvc != nil { - if err := macaroons.ValidateMacaroon(ctx, "decodepayreq", - r.authSvc); err != nil { - return nil, err - } - } - rpcsLog.Tracef("[decodepayreq] decoding: %v", req.PayReq) // Fist we'll attempt to decode the payment request string, if the @@ -3117,13 +3024,6 @@ const feeBase = 1000000 func (r *rpcServer) FeeReport(ctx context.Context, _ *lnrpc.FeeReportRequest) (*lnrpc.FeeReportResponse, error) { - if r.authSvc != nil { - if err := macaroons.ValidateMacaroon(ctx, "feereport", - r.authSvc); err != nil { - return nil, err - } - } - // TODO(roasbeef): use UnaryInterceptor to add automated logging channelGraph := r.server.chanDB.ChannelGraph() @@ -3174,13 +3074,6 @@ const minFeeRate = 1e-6 func (r *rpcServer) UpdateChannelPolicy(ctx context.Context, req *lnrpc.PolicyUpdateRequest) (*lnrpc.PolicyUpdateResponse, error) { - if r.authSvc != nil { - if err := macaroons.ValidateMacaroon(ctx, "updatechannelpolicy", - r.authSvc); err != nil { - return nil, err - } - } - var targetChans []wire.OutPoint switch scope := req.Scope.(type) { // If the request is targeting all active channels, then we don't need diff --git a/walletunlocker/service.go b/walletunlocker/service.go index 51aaf805..34780518 100644 --- a/walletunlocker/service.go +++ b/walletunlocker/service.go @@ -8,7 +8,7 @@ import ( "github.com/roasbeef/btcd/chaincfg" "github.com/roasbeef/btcwallet/wallet" "golang.org/x/net/context" - "gopkg.in/macaroon-bakery.v1/bakery" + "gopkg.in/macaroon-bakery.v2/bakery" ) // UnlockerService implements the WalletUnlocker service used to provide lnd @@ -29,7 +29,7 @@ type UnlockerService struct { } // New creates and returns a new UnlockerService. -func New(authSvc *bakery.Service, chainDir string, +func New(authSvc *bakery.Bakery, chainDir string, params *chaincfg.Params) *UnlockerService { return &UnlockerService{ CreatePasswords: make(chan []byte, 1),