mirror of
https://github.com/lightningnetwork/lnd.git
synced 2025-07-28 13:52:55 +02:00
multi: upgrade macaroons to v2, replace per-method auth with interceptors
This commit reworks the macaroon authentication framework to use the v2 macaroon format and bakery API. It also replaces the code in each RPC method which calls the macaroon verifier with interceptors which call the macaroon verifier instead. In addition, the operation permissions are reworked to fit the new format of "allow" commands (specifically, entity/operation permissions instead of method permissions).
This commit is contained in:
68
lnd.go
68
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.
|
||||
|
Reference in New Issue
Block a user