github.com/decred/dcrlnd@v0.7.6/rpcperms/interceptor.go (about)

     1  package rpcperms
     2  
     3  import (
     4  	"context"
     5  	"errors"
     6  	"fmt"
     7  	"sync"
     8  	"sync/atomic"
     9  
    10  	"github.com/decred/dcrlnd/lnrpc"
    11  	"github.com/decred/dcrlnd/lnrpc/initchainsyncrpc"
    12  	"github.com/decred/dcrlnd/macaroons"
    13  	"github.com/decred/dcrlnd/monitoring"
    14  	"github.com/decred/dcrlnd/subscribe"
    15  	"github.com/decred/slog"
    16  	grpc_middleware "github.com/grpc-ecosystem/go-grpc-middleware"
    17  	"google.golang.org/grpc"
    18  	"gopkg.in/macaroon-bakery.v2/bakery"
    19  )
    20  
    21  // rpcState is an enum that we use to keep track of the current RPC service
    22  // state. This will transition as we go from startup to unlocking the wallet,
    23  // and finally fully active.
    24  type rpcState uint8
    25  
    26  const (
    27  	// waitingToStart indicates that we're at the beginning of the startup
    28  	// process. In a cluster evironment this may mean that we're waiting to
    29  	// become the leader in which case RPC calls will be disabled until
    30  	// this instance has been elected as leader.
    31  	waitingToStart rpcState = iota
    32  
    33  	// walletNotCreated is the starting state if the RPC server is active,
    34  	// but the wallet is not yet created. In this state we'll only allow
    35  	// calls to the WalletUnlockerService.
    36  	walletNotCreated
    37  
    38  	// walletLocked indicates the RPC server is active, but the wallet is
    39  	// locked. In this state we'll only allow calls to the
    40  	// WalletUnlockerService.
    41  	walletLocked
    42  
    43  	// walletUnlocked means that the wallet has been unlocked, but the full
    44  	// RPC server is not yeat ready.
    45  	walletUnlocked
    46  
    47  	// rpcActive means that the RPC server is ready to accept calls.
    48  	rpcActive
    49  
    50  	// serverActive means that the lnd server is ready to accept calls.
    51  	serverActive
    52  )
    53  
    54  var (
    55  	// ErrWaitingToStart is returned if LND is still wating to start,
    56  	// possibly blocked until elected as the leader.
    57  	ErrWaitingToStart = fmt.Errorf("waiting to start, RPC services not " +
    58  		"available")
    59  
    60  	// ErrNoWallet is returned if the wallet does not exist.
    61  	ErrNoWallet = fmt.Errorf("wallet not created, create one to enable " +
    62  		"full RPC access")
    63  
    64  	// ErrWalletLocked is returned if the wallet is locked and any service
    65  	// other than the WalletUnlocker is called.
    66  	ErrWalletLocked = fmt.Errorf("wallet locked, unlock it to enable " +
    67  		"full RPC access")
    68  
    69  	// ErrWalletUnlocked is returned if the WalletUnlocker service is
    70  	// called when the wallet already has been unlocked.
    71  	ErrWalletUnlocked = fmt.Errorf("wallet already unlocked, " +
    72  		"WalletUnlocker service is no longer available")
    73  
    74  	// ErrRPCStarting is returned if the wallet has been unlocked but the
    75  	// RPC server is not yet ready to accept calls.
    76  	ErrRPCStarting = fmt.Errorf("the RPC server is in the process of " +
    77  		"starting up, but not yet ready to accept calls")
    78  
    79  	// macaroonWhitelist defines methods that we don't require macaroons to
    80  	// access. We also allow these methods to be called even if not all
    81  	// mandatory middlewares are registered yet. If the wallet is locked
    82  	// then a middleware cannot register itself, creating an impossible
    83  	// situation. Also, a middleware might want to check the state of lnd
    84  	// by calling the State service before it registers itself. So we also
    85  	// need to exclude those calls from the mandatory middleware check.
    86  	macaroonWhitelist = map[string]struct{}{
    87  		// We allow all calls to the WalletUnlocker without macaroons.
    88  		"/lnrpc.WalletUnlocker/GenSeed":        {},
    89  		"/lnrpc.WalletUnlocker/InitWallet":     {},
    90  		"/lnrpc.WalletUnlocker/UnlockWallet":   {},
    91  		"/lnrpc.WalletUnlocker/ChangePassword": {},
    92  
    93  		// The State service must be available at all times, even
    94  		// before we can check macaroons, so we whitelist it.
    95  		"/lnrpc.State/SubscribeState": {},
    96  		"/lnrpc.State/GetState":       {},
    97  	}
    98  )
    99  
   100  // InterceptorChain is a struct that can be added to the running GRPC server,
   101  // intercepting API calls. This is useful for logging, enforcing permissions,
   102  // supporting middleware etc. The following diagram shows the order of each
   103  // interceptor in the chain and when exactly requests/responses are intercepted
   104  // and forwarded to external middleware for approval/modification. Middleware in
   105  // general can only intercept gRPC requests/responses that are sent by the
   106  // client with a macaroon that contains a custom caveat that is supported by one
   107  // of the registered middlewares.
   108  //
   109  //	    |
   110  //	    | gRPC request from client
   111  //	    |
   112  //	+---v--------------------------------+
   113  //	|   InterceptorChain                 |
   114  //	+-+----------------------------------+
   115  //	  | Log Interceptor                  |
   116  //	  +----------------------------------+
   117  //	  | RPC State Interceptor            |
   118  //	  +----------------------------------+
   119  //	  | Macaroon Interceptor             |
   120  //	  +----------------------------------+--------> +---------------------+
   121  //	  | RPC Macaroon Middleware Handler  |<-------- | External Middleware |
   122  //	  +----------------------------------+          |   - approve request |
   123  //	  | Prometheus Interceptor           |          +---------------------+
   124  //	  +-+--------------------------------+
   125  //	    | validated gRPC request from client
   126  //	+---v--------------------------------+
   127  //	|   main gRPC server                 |
   128  //	+---+--------------------------------+
   129  //	    |
   130  //	    | original gRPC request to client
   131  //	    |
   132  //	+---v--------------------------------+--------> +---------------------+
   133  //	|   RPC Macaroon Middleware Handler  |<-------- | External Middleware |
   134  //	+---+--------------------------------+          |   - modify response |
   135  //	    |                                           +---------------------+
   136  //	    | edited gRPC request to client
   137  //	    v
   138  type InterceptorChain struct {
   139  	// lastRequestID is the ID of the last gRPC request or stream that was
   140  	// intercepted by the middleware interceptor.
   141  	//
   142  	// NOTE: Must be used atomically!
   143  	lastRequestID uint64
   144  
   145  	// Required by the grpc-gateway/v2 library for forward compatibility.
   146  	lnrpc.UnimplementedStateServer
   147  
   148  	started sync.Once
   149  	stopped sync.Once
   150  
   151  	// state is the current RPC state of our RPC server.
   152  	state rpcState
   153  
   154  	// ntfnServer is a subscription server we use to notify clients of the
   155  	// State service when the state changes.
   156  	ntfnServer *subscribe.Server
   157  
   158  	// noMacaroons should be set true if we don't want to check macaroons.
   159  	noMacaroons bool
   160  
   161  	// svc is the macaroon service used to enforce permissions in case
   162  	// macaroons are used.
   163  	svc *macaroons.Service
   164  
   165  	// permissionMap is the permissions to enforce if macaroons are used.
   166  	permissionMap map[string][]bakery.Op
   167  
   168  	// rpcsLog is the logger used to log calles to the RPCs intercepted.
   169  	rpcsLog slog.Logger
   170  
   171  	// registeredMiddleware is a map of all macaroon permission based RPC
   172  	// middleware clients that are currently registered. The map is keyed
   173  	// by the middleware's name.
   174  	registeredMiddleware map[string]*MiddlewareHandler
   175  
   176  	// mandatoryMiddleware is a list of all middleware that is considered to
   177  	// be mandatory. If any of them is not registered then all RPC requests
   178  	// (except for the macaroon white listed methods and the middleware
   179  	// registration itself) are blocked. This is a security feature to make
   180  	// sure that requests can't just go through unobserved/unaudited if a
   181  	// middleware crashes.
   182  	mandatoryMiddleware []string
   183  
   184  	quit chan struct{}
   185  	sync.RWMutex
   186  }
   187  
   188  // A compile time check to ensure that InterceptorChain fully implements the
   189  // StateServer gRPC service.
   190  var _ lnrpc.StateServer = (*InterceptorChain)(nil)
   191  
   192  // NewInterceptorChain creates a new InterceptorChain.
   193  func NewInterceptorChain(log slog.Logger, noMacaroons bool,
   194  	mandatoryMiddleware []string) *InterceptorChain {
   195  
   196  	return &InterceptorChain{
   197  		state:                waitingToStart,
   198  		ntfnServer:           subscribe.NewServer(),
   199  		noMacaroons:          noMacaroons,
   200  		permissionMap:        make(map[string][]bakery.Op),
   201  		rpcsLog:              log,
   202  		registeredMiddleware: make(map[string]*MiddlewareHandler),
   203  		mandatoryMiddleware:  mandatoryMiddleware,
   204  		quit:                 make(chan struct{}),
   205  	}
   206  }
   207  
   208  // Start starts the InterceptorChain, which is needed to start the state
   209  // subscription server it powers.
   210  func (r *InterceptorChain) Start() error {
   211  	var err error
   212  	r.started.Do(func() {
   213  		err = r.ntfnServer.Start()
   214  	})
   215  
   216  	return err
   217  }
   218  
   219  // Stop stops the InterceptorChain and its internal state subscription server.
   220  func (r *InterceptorChain) Stop() error {
   221  	var err error
   222  	r.stopped.Do(func() {
   223  		close(r.quit)
   224  		err = r.ntfnServer.Stop()
   225  	})
   226  
   227  	return err
   228  }
   229  
   230  // SetWalletNotCreated moves the RPC state from either waitingToStart to
   231  // walletNotCreated.
   232  func (r *InterceptorChain) SetWalletNotCreated() {
   233  	r.Lock()
   234  	defer r.Unlock()
   235  
   236  	r.state = walletNotCreated
   237  	_ = r.ntfnServer.SendUpdate(r.state)
   238  }
   239  
   240  // SetWalletLocked moves the RPC state from either walletNotCreated to
   241  // walletLocked.
   242  func (r *InterceptorChain) SetWalletLocked() {
   243  	r.Lock()
   244  	defer r.Unlock()
   245  
   246  	r.state = walletLocked
   247  	_ = r.ntfnServer.SendUpdate(r.state)
   248  }
   249  
   250  // SetWalletUnlocked moves the RPC state from either walletNotCreated or
   251  // walletLocked to walletUnlocked.
   252  func (r *InterceptorChain) SetWalletUnlocked() {
   253  	r.Lock()
   254  	defer r.Unlock()
   255  
   256  	r.state = walletUnlocked
   257  	_ = r.ntfnServer.SendUpdate(r.state)
   258  }
   259  
   260  // SetRPCActive moves the RPC state from walletUnlocked to rpcActive.
   261  func (r *InterceptorChain) SetRPCActive() {
   262  	r.Lock()
   263  	defer r.Unlock()
   264  
   265  	r.state = rpcActive
   266  	_ = r.ntfnServer.SendUpdate(r.state)
   267  }
   268  
   269  // SetServerActive moves the RPC state from walletUnlocked to rpcActive.
   270  func (r *InterceptorChain) SetServerActive() {
   271  	r.Lock()
   272  	defer r.Unlock()
   273  
   274  	r.state = serverActive
   275  	_ = r.ntfnServer.SendUpdate(r.state)
   276  }
   277  
   278  // rpcStateToWalletState converts rpcState to lnrpc.WalletState. Returns
   279  // WAITING_TO_START and an error on conversion error.
   280  func rpcStateToWalletState(state rpcState) (lnrpc.WalletState, error) {
   281  	const defaultState = lnrpc.WalletState_WAITING_TO_START
   282  	var walletState lnrpc.WalletState
   283  
   284  	switch state {
   285  	case waitingToStart:
   286  		walletState = lnrpc.WalletState_WAITING_TO_START
   287  	case walletNotCreated:
   288  		walletState = lnrpc.WalletState_NON_EXISTING
   289  	case walletLocked:
   290  		walletState = lnrpc.WalletState_LOCKED
   291  	case walletUnlocked:
   292  		walletState = lnrpc.WalletState_UNLOCKED
   293  	case rpcActive:
   294  		walletState = lnrpc.WalletState_RPC_ACTIVE
   295  	case serverActive:
   296  		walletState = lnrpc.WalletState_SERVER_ACTIVE
   297  
   298  	default:
   299  		return defaultState, fmt.Errorf("unknown wallet state %v", state)
   300  	}
   301  
   302  	return walletState, nil
   303  }
   304  
   305  // SubscribeState subscribes to the state of the wallet. The current wallet
   306  // state will always be delivered immediately.
   307  //
   308  // NOTE: Part of the StateService interface.
   309  func (r *InterceptorChain) SubscribeState(_ *lnrpc.SubscribeStateRequest,
   310  	stream lnrpc.State_SubscribeStateServer) error {
   311  
   312  	sendStateUpdate := func(state rpcState) error {
   313  		walletState, err := rpcStateToWalletState(state)
   314  		if err != nil {
   315  			return err
   316  		}
   317  
   318  		return stream.Send(&lnrpc.SubscribeStateResponse{
   319  			State: walletState,
   320  		})
   321  	}
   322  
   323  	// Subscribe to state updates.
   324  	client, err := r.ntfnServer.Subscribe()
   325  	if err != nil {
   326  		return err
   327  	}
   328  	defer client.Cancel()
   329  
   330  	// Always start by sending the current state.
   331  	r.RLock()
   332  	state := r.state
   333  	r.RUnlock()
   334  
   335  	if err := sendStateUpdate(state); err != nil {
   336  		return err
   337  	}
   338  
   339  	for {
   340  		select {
   341  		case e := <-client.Updates():
   342  			newState := e.(rpcState)
   343  
   344  			// Ignore already sent state.
   345  			if newState == state {
   346  				continue
   347  			}
   348  
   349  			state = newState
   350  			err := sendStateUpdate(state)
   351  			if err != nil {
   352  				return err
   353  			}
   354  
   355  		// The response stream's context for whatever reason has been
   356  		// closed. If context is closed by an exceeded deadline we will
   357  		// return an error.
   358  		case <-stream.Context().Done():
   359  			if errors.Is(stream.Context().Err(), context.Canceled) {
   360  				return nil
   361  			}
   362  			return stream.Context().Err()
   363  
   364  		case <-r.quit:
   365  			return fmt.Errorf("server exiting")
   366  		}
   367  	}
   368  }
   369  
   370  // GetState returns the current wallet state.
   371  func (r *InterceptorChain) GetState(_ context.Context,
   372  	_ *lnrpc.GetStateRequest) (*lnrpc.GetStateResponse, error) {
   373  
   374  	r.RLock()
   375  	state := r.state
   376  	r.RUnlock()
   377  
   378  	walletState, err := rpcStateToWalletState(state)
   379  	if err != nil {
   380  		return nil, err
   381  	}
   382  
   383  	return &lnrpc.GetStateResponse{
   384  		State: walletState,
   385  	}, nil
   386  }
   387  
   388  // AddMacaroonService adds a macaroon service to the interceptor. After this is
   389  // done every RPC call made will have to pass a valid macaroon to be accepted.
   390  func (r *InterceptorChain) AddMacaroonService(svc *macaroons.Service) {
   391  	r.Lock()
   392  	defer r.Unlock()
   393  
   394  	r.svc = svc
   395  }
   396  
   397  // MacaroonService returns the currently registered macaroon service. This might
   398  // be nil if none was registered (yet).
   399  func (r *InterceptorChain) MacaroonService() *macaroons.Service {
   400  	r.RLock()
   401  	defer r.RUnlock()
   402  
   403  	return r.svc
   404  }
   405  
   406  // AddPermission adds a new macaroon rule for the given method.
   407  func (r *InterceptorChain) AddPermission(method string, ops []bakery.Op) error {
   408  	r.Lock()
   409  	defer r.Unlock()
   410  
   411  	if _, ok := r.permissionMap[method]; ok {
   412  		return fmt.Errorf("detected duplicate macaroon constraints "+
   413  			"for path: %v", method)
   414  	}
   415  
   416  	r.permissionMap[method] = ops
   417  	return nil
   418  }
   419  
   420  // Permissions returns the current set of macaroon permissions.
   421  func (r *InterceptorChain) Permissions() map[string][]bakery.Op {
   422  	r.RLock()
   423  	defer r.RUnlock()
   424  
   425  	// Make a copy under the read lock to avoid races.
   426  	c := make(map[string][]bakery.Op)
   427  	for k, v := range r.permissionMap {
   428  		s := make([]bakery.Op, len(v))
   429  		copy(s, v)
   430  		c[k] = s
   431  	}
   432  
   433  	return c
   434  }
   435  
   436  // RegisterMiddleware registers a new middleware that will handle request/
   437  // response interception for all RPC messages that are initiated with a custom
   438  // macaroon caveat. The name of the custom caveat a middleware is handling is
   439  // also its unique identifier. Only one middleware can be registered for each
   440  // custom caveat.
   441  func (r *InterceptorChain) RegisterMiddleware(mw *MiddlewareHandler) error {
   442  	r.Lock()
   443  	defer r.Unlock()
   444  
   445  	// The name of the middleware is the unique identifier.
   446  	registered, ok := r.registeredMiddleware[mw.middlewareName]
   447  	if ok {
   448  		return fmt.Errorf("a middleware with the name '%s' is already "+
   449  			"registered", registered.middlewareName)
   450  	}
   451  
   452  	// For now, we only want one middleware per custom caveat name. If we
   453  	// allowed multiple middlewares handling the same caveat there would be
   454  	// a need for extra call chaining logic, and they could overwrite each
   455  	// other's responses.
   456  	for name, middleware := range r.registeredMiddleware {
   457  		if middleware.customCaveatName == mw.customCaveatName {
   458  			return fmt.Errorf("a middleware is already registered "+
   459  				"for the custom caveat name '%s': %v",
   460  				mw.customCaveatName, name)
   461  		}
   462  	}
   463  
   464  	r.registeredMiddleware[mw.middlewareName] = mw
   465  
   466  	return nil
   467  }
   468  
   469  // RemoveMiddleware removes the middleware that handles the given custom caveat
   470  // name.
   471  func (r *InterceptorChain) RemoveMiddleware(middlewareName string) {
   472  	r.Lock()
   473  	defer r.Unlock()
   474  
   475  	log.Debugf("Removing middleware %s", middlewareName)
   476  
   477  	delete(r.registeredMiddleware, middlewareName)
   478  }
   479  
   480  // CustomCaveatSupported makes sure a middleware that handles the given custom
   481  // caveat name is registered. If none is, an error is returned, signalling to
   482  // the macaroon bakery and its validator to reject macaroons that have a custom
   483  // caveat with that name.
   484  //
   485  // NOTE: This method is part of the macaroons.CustomCaveatAcceptor interface.
   486  func (r *InterceptorChain) CustomCaveatSupported(customCaveatName string) error {
   487  	r.RLock()
   488  	defer r.RUnlock()
   489  
   490  	// We only accept requests with a custom caveat if we also have a
   491  	// middleware registered that handles that custom caveat. That is
   492  	// crucial for security! Otherwise a request with an encumbered (=has
   493  	// restricted permissions based upon the custom caveat condition)
   494  	// macaroon would not be validated against the limitations that the
   495  	// custom caveat implicate. Since the map is keyed by the _name_ of the
   496  	// middleware, we need to loop through all of them to see if one has
   497  	// the given custom macaroon caveat name.
   498  	for _, middleware := range r.registeredMiddleware {
   499  		if middleware.customCaveatName == customCaveatName {
   500  			return nil
   501  		}
   502  	}
   503  
   504  	return fmt.Errorf("cannot accept macaroon with custom caveat '%s', "+
   505  		"no middleware registered to handle it", customCaveatName)
   506  }
   507  
   508  // CreateServerOpts creates the GRPC server options that can be added to a GRPC
   509  // server in order to add this InterceptorChain.
   510  func (r *InterceptorChain) CreateServerOpts() []grpc.ServerOption {
   511  	var unaryInterceptors []grpc.UnaryServerInterceptor
   512  	var strmInterceptors []grpc.StreamServerInterceptor
   513  
   514  	// The first interceptors we'll add to the chain is our logging
   515  	// interceptors, so we can automatically log all errors that happen
   516  	// during RPC calls.
   517  	unaryInterceptors = append(
   518  		unaryInterceptors, errorLogUnaryServerInterceptor(r.rpcsLog),
   519  	)
   520  	strmInterceptors = append(
   521  		strmInterceptors, errorLogStreamServerInterceptor(r.rpcsLog),
   522  	)
   523  
   524  	// Next we'll add our RPC state check interceptors, that will check
   525  	// whether the attempted call is allowed in the current state.
   526  	unaryInterceptors = append(
   527  		unaryInterceptors, r.rpcStateUnaryServerInterceptor(),
   528  	)
   529  	strmInterceptors = append(
   530  		strmInterceptors, r.rpcStateStreamServerInterceptor(),
   531  	)
   532  
   533  	// We'll add the macaroon interceptors. If macaroons aren't disabled,
   534  	// then these interceptors will enforce macaroon authentication.
   535  	unaryInterceptors = append(
   536  		unaryInterceptors, r.MacaroonUnaryServerInterceptor(),
   537  	)
   538  	strmInterceptors = append(
   539  		strmInterceptors, r.MacaroonStreamServerInterceptor(),
   540  	)
   541  
   542  	// Next, we'll add the interceptors for our custom macaroon caveat based
   543  	// middleware.
   544  	unaryInterceptors = append(
   545  		unaryInterceptors, r.middlewareUnaryServerInterceptor(),
   546  	)
   547  	strmInterceptors = append(
   548  		strmInterceptors, r.middlewareStreamServerInterceptor(),
   549  	)
   550  
   551  	// Get interceptors for Prometheus to gather gRPC performance metrics.
   552  	// If monitoring is disabled, GetPromInterceptors() will return empty
   553  	// slices.
   554  	promUnaryInterceptors, promStrmInterceptors :=
   555  		monitoring.GetPromInterceptors()
   556  
   557  	// Concatenate the slices of unary and stream interceptors respectively.
   558  	unaryInterceptors = append(unaryInterceptors, promUnaryInterceptors...)
   559  	strmInterceptors = append(strmInterceptors, promStrmInterceptors...)
   560  
   561  	// Create server options from the interceptors we just set up.
   562  	chainedUnary := grpc_middleware.WithUnaryServerChain(
   563  		unaryInterceptors...,
   564  	)
   565  	chainedStream := grpc_middleware.WithStreamServerChain(
   566  		strmInterceptors...,
   567  	)
   568  	serverOpts := []grpc.ServerOption{chainedUnary, chainedStream}
   569  
   570  	return serverOpts
   571  }
   572  
   573  // errorLogUnaryServerInterceptor is a simple UnaryServerInterceptor that will
   574  // automatically log any errors that occur when serving a client's unary
   575  // request.
   576  func errorLogUnaryServerInterceptor(logger slog.Logger) grpc.UnaryServerInterceptor {
   577  	return func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo,
   578  		handler grpc.UnaryHandler) (interface{}, error) {
   579  
   580  		resp, err := handler(ctx, req)
   581  		if err != nil {
   582  			// TODO(roasbeef): also log request details?
   583  			logger.Errorf("[%v]: %v", info.FullMethod, err)
   584  		}
   585  
   586  		return resp, err
   587  	}
   588  }
   589  
   590  // errorLogStreamServerInterceptor is a simple StreamServerInterceptor that
   591  // will log any errors that occur while processing a client or server streaming
   592  // RPC.
   593  func errorLogStreamServerInterceptor(logger slog.Logger) grpc.StreamServerInterceptor {
   594  	return func(srv interface{}, ss grpc.ServerStream,
   595  		info *grpc.StreamServerInfo, handler grpc.StreamHandler) error {
   596  
   597  		err := handler(srv, ss)
   598  		if err != nil {
   599  			logger.Errorf("[%v]: %v", info.FullMethod, err)
   600  		}
   601  
   602  		return err
   603  	}
   604  }
   605  
   606  // checkMacaroon validates that the context contains the macaroon needed to
   607  // invoke the given RPC method.
   608  func (r *InterceptorChain) checkMacaroon(ctx context.Context,
   609  	fullMethod string) error {
   610  
   611  	// If noMacaroons is set, we'll always allow the call.
   612  	if r.noMacaroons {
   613  		return nil
   614  	}
   615  
   616  	// Check whether the method is whitelisted, if so we'll allow it
   617  	// regardless of macaroons.
   618  	_, ok := macaroonWhitelist[fullMethod]
   619  	if ok {
   620  		return nil
   621  	}
   622  
   623  	r.RLock()
   624  	svc := r.svc
   625  	r.RUnlock()
   626  
   627  	// If the macaroon service is not yet active, we cannot allow
   628  	// the call.
   629  	if svc == nil {
   630  		return fmt.Errorf("unable to determine macaroon permissions")
   631  	}
   632  
   633  	r.RLock()
   634  	uriPermissions, ok := r.permissionMap[fullMethod]
   635  	r.RUnlock()
   636  	if !ok {
   637  		return fmt.Errorf("%s: unknown permissions required for method",
   638  			fullMethod)
   639  	}
   640  
   641  	// Find out if there is an external validator registered for
   642  	// this method. Fall back to the internal one if there isn't.
   643  	validator, ok := svc.ExternalValidators[fullMethod]
   644  	if !ok {
   645  		validator = svc
   646  	}
   647  
   648  	// Now that we know what validator to use, let it do its work.
   649  	return validator.ValidateMacaroon(ctx, uriPermissions, fullMethod)
   650  }
   651  
   652  // MacaroonUnaryServerInterceptor is a GRPC interceptor that checks whether the
   653  // request is authorized by the included macaroons.
   654  func (r *InterceptorChain) MacaroonUnaryServerInterceptor() grpc.UnaryServerInterceptor {
   655  	return func(ctx context.Context, req interface{},
   656  		info *grpc.UnaryServerInfo,
   657  		handler grpc.UnaryHandler) (interface{}, error) {
   658  
   659  		// Check macaroons.
   660  		if err := r.checkMacaroon(ctx, info.FullMethod); err != nil {
   661  			return nil, err
   662  		}
   663  
   664  		return handler(ctx, req)
   665  	}
   666  }
   667  
   668  // MacaroonStreamServerInterceptor is a GRPC interceptor that checks whether
   669  // the request is authorized by the included macaroons.
   670  func (r *InterceptorChain) MacaroonStreamServerInterceptor() grpc.StreamServerInterceptor {
   671  	return func(srv interface{}, ss grpc.ServerStream,
   672  		info *grpc.StreamServerInfo, handler grpc.StreamHandler) error {
   673  
   674  		// Check macaroons.
   675  		err := r.checkMacaroon(ss.Context(), info.FullMethod)
   676  		if err != nil {
   677  			return err
   678  		}
   679  
   680  		return handler(srv, ss)
   681  	}
   682  }
   683  
   684  // checkRPCState checks whether a call to the given server is allowed in the
   685  // current RPC state.
   686  func (r *InterceptorChain) checkRPCState(srv interface{}) error {
   687  	// The StateService is being accessed, we allow the call regardless of
   688  	// the current state.
   689  	_, ok := srv.(lnrpc.StateServer)
   690  	if ok {
   691  		return nil
   692  	}
   693  
   694  	r.RLock()
   695  	state := r.state
   696  	r.RUnlock()
   697  
   698  	switch state {
   699  
   700  	// Do not accept any RPC calls (unless to the state service) until LND
   701  	// has not started.
   702  	case waitingToStart:
   703  		return ErrWaitingToStart
   704  
   705  	// If the wallet does not exists, only calls to the WalletUnlocker are
   706  	// accepted.
   707  	case walletNotCreated:
   708  		_, ok := srv.(lnrpc.WalletUnlockerServer)
   709  		if !ok {
   710  			return ErrNoWallet
   711  		}
   712  
   713  	// If the wallet is locked, only calls to the WalletUnlocker are
   714  	// accepted.
   715  	case walletLocked:
   716  		_, ok := srv.(lnrpc.WalletUnlockerServer)
   717  		if !ok {
   718  			return ErrWalletLocked
   719  		}
   720  
   721  	// If the wallet is unlocked, but the RPC not yet active, we reject.
   722  	case walletUnlocked:
   723  		_, ok := srv.(lnrpc.WalletUnlockerServer)
   724  		if ok {
   725  			return ErrWalletUnlocked
   726  		}
   727  
   728  		_, isSyncerSvr := srv.(initchainsyncrpc.InitialChainSyncServer)
   729  		if isSyncerSvr {
   730  			return nil
   731  		}
   732  
   733  		return ErrRPCStarting
   734  
   735  	// If the RPC server or lnd server is active, we allow calls to any
   736  	// service except the WalletUnlocker.
   737  	case rpcActive, serverActive:
   738  		_, ok := srv.(lnrpc.WalletUnlockerServer)
   739  		if ok {
   740  			return ErrWalletUnlocked
   741  		}
   742  
   743  	default:
   744  		return fmt.Errorf("unknown RPC state: %v", state)
   745  	}
   746  
   747  	return nil
   748  }
   749  
   750  // rpcStateUnaryServerInterceptor is a GRPC interceptor that checks whether
   751  // calls to the given gGRPC server is allowed in the current rpc state.
   752  func (r *InterceptorChain) rpcStateUnaryServerInterceptor() grpc.UnaryServerInterceptor {
   753  	return func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo,
   754  		handler grpc.UnaryHandler) (interface{}, error) {
   755  
   756  		if err := r.checkRPCState(info.Server); err != nil {
   757  			return nil, err
   758  		}
   759  
   760  		return handler(ctx, req)
   761  	}
   762  }
   763  
   764  // rpcStateStreamServerInterceptor is a GRPC interceptor that checks whether
   765  // calls to the given gGRPC server is allowed in the current rpc state.
   766  func (r *InterceptorChain) rpcStateStreamServerInterceptor() grpc.StreamServerInterceptor {
   767  	return func(srv interface{}, ss grpc.ServerStream,
   768  		info *grpc.StreamServerInfo, handler grpc.StreamHandler) error {
   769  
   770  		if err := r.checkRPCState(srv); err != nil {
   771  			return err
   772  		}
   773  
   774  		return handler(srv, ss)
   775  	}
   776  }
   777  
   778  // middlewareUnaryServerInterceptor is a unary gRPC interceptor that intercepts
   779  // all requests and responses that are sent with a macaroon containing a custom
   780  // caveat condition that is handled by registered middleware.
   781  func (r *InterceptorChain) middlewareUnaryServerInterceptor() grpc.UnaryServerInterceptor {
   782  	return func(ctx context.Context,
   783  		req interface{}, info *grpc.UnaryServerInfo,
   784  		handler grpc.UnaryHandler) (interface{}, error) {
   785  
   786  		// Make sure we don't allow any requests through if one of the
   787  		// mandatory middlewares is missing.
   788  		fullMethod := info.FullMethod
   789  		if err := r.checkMandatoryMiddleware(fullMethod); err != nil {
   790  			return nil, err
   791  		}
   792  
   793  		// If there is no middleware registered, we don't need to
   794  		// intercept anything.
   795  		if !r.middlewareRegistered() {
   796  			return handler(ctx, req)
   797  		}
   798  
   799  		msg, err := NewMessageInterceptionRequest(
   800  			ctx, TypeRequest, false, info.FullMethod, req,
   801  		)
   802  		if err != nil {
   803  			return nil, err
   804  		}
   805  
   806  		requestID := atomic.AddUint64(&r.lastRequestID, 1)
   807  		err = r.acceptRequest(requestID, msg)
   808  		if err != nil {
   809  			return nil, err
   810  		}
   811  
   812  		resp, respErr := handler(ctx, req)
   813  		if respErr != nil {
   814  			return resp, respErr
   815  		}
   816  
   817  		return r.interceptResponse(
   818  			ctx, requestID, false, info.FullMethod, resp,
   819  		)
   820  	}
   821  }
   822  
   823  // middlewareStreamServerInterceptor is a streaming gRPC interceptor that
   824  // intercepts all requests and responses that are sent with a macaroon
   825  // containing a custom caveat condition that is handled by registered
   826  // middleware.
   827  func (r *InterceptorChain) middlewareStreamServerInterceptor() grpc.StreamServerInterceptor {
   828  	return func(srv interface{},
   829  		ss grpc.ServerStream, info *grpc.StreamServerInfo,
   830  		handler grpc.StreamHandler) error {
   831  
   832  		// Don't intercept the interceptor itself which is a streaming
   833  		// RPC too!
   834  		fullMethod := info.FullMethod
   835  		if fullMethod == lnrpc.RegisterRPCMiddlewareURI {
   836  			return handler(srv, ss)
   837  		}
   838  
   839  		// Make sure we don't allow any requests through if one of the
   840  		// mandatory middlewares is missing. We add this check here to
   841  		// make sure the middleware registration itself can still be
   842  		// called.
   843  		if err := r.checkMandatoryMiddleware(fullMethod); err != nil {
   844  			return err
   845  		}
   846  
   847  		// If there is no middleware registered, we don't need to
   848  		// intercept anything.
   849  		if !r.middlewareRegistered() {
   850  			return handler(srv, ss)
   851  		}
   852  
   853  		// To give the middleware a chance to accept or reject the
   854  		// establishment of the stream itself (and not only when the
   855  		// first message is sent on the stream), we send an intercept
   856  		// request for the stream auth now:
   857  		msg, err := NewStreamAuthInterceptionRequest(
   858  			ss.Context(), info.FullMethod,
   859  		)
   860  		if err != nil {
   861  			return err
   862  		}
   863  
   864  		requestID := atomic.AddUint64(&r.lastRequestID, 1)
   865  		err = r.acceptRequest(requestID, msg)
   866  		if err != nil {
   867  			return err
   868  		}
   869  
   870  		wrappedSS := &serverStreamWrapper{
   871  			ServerStream: ss,
   872  			requestID:    requestID,
   873  			fullMethod:   info.FullMethod,
   874  			interceptor:  r,
   875  		}
   876  
   877  		return handler(srv, wrappedSS)
   878  	}
   879  }
   880  
   881  // checkMandatoryMiddleware makes sure that each of the middlewares declared as
   882  // mandatory is currently registered.
   883  func (r *InterceptorChain) checkMandatoryMiddleware(fullMethod string) error {
   884  	r.RLock()
   885  	defer r.RUnlock()
   886  
   887  	// Allow calls that are whitelisted for macaroons as well, otherwise we
   888  	// get into impossible situations where the wallet is locked but the
   889  	// unlock call is denied because the middleware isn't registered. But
   890  	// the middleware cannot register itself because the wallet is locked.
   891  	if _, ok := macaroonWhitelist[fullMethod]; ok {
   892  		return nil
   893  	}
   894  
   895  	// Not a white listed call so make sure every mandatory middleware is
   896  	// currently connected to lnd.
   897  	for _, name := range r.mandatoryMiddleware {
   898  		if _, ok := r.registeredMiddleware[name]; !ok {
   899  			return fmt.Errorf("mandatory middleware '%s' is "+
   900  				"currently not registered, not allowing any "+
   901  				"RPC calls", name)
   902  		}
   903  	}
   904  
   905  	return nil
   906  }
   907  
   908  // middlewareRegistered returns true if there is at least one middleware
   909  // currently registered.
   910  func (r *InterceptorChain) middlewareRegistered() bool {
   911  	r.RLock()
   912  	defer r.RUnlock()
   913  
   914  	return len(r.registeredMiddleware) > 0
   915  }
   916  
   917  // acceptRequest sends an intercept request to all middlewares that have
   918  // registered for it. This means either a middleware has requested read-only
   919  // access or the request actually has a macaroon with a caveat the middleware
   920  // registered for.
   921  func (r *InterceptorChain) acceptRequest(requestID uint64,
   922  	msg *InterceptionRequest) error {
   923  
   924  	r.RLock()
   925  	defer r.RUnlock()
   926  
   927  	for _, middleware := range r.registeredMiddleware {
   928  		// If there is a custom caveat in the macaroon, make sure the
   929  		// middleware registered for it. Or if a middleware registered
   930  		// for read-only mode, it also gets the request.
   931  		hasCustomCaveat := macaroons.HasCustomCaveat(
   932  			msg.Macaroon, middleware.customCaveatName,
   933  		)
   934  		if !hasCustomCaveat && !middleware.readOnly {
   935  			continue
   936  		}
   937  
   938  		msg.CustomCaveatCondition = macaroons.GetCustomCaveatCondition(
   939  			msg.Macaroon, middleware.customCaveatName,
   940  		)
   941  
   942  		resp, err := middleware.intercept(requestID, msg)
   943  
   944  		// Error during interception itself.
   945  		if err != nil {
   946  			return err
   947  		}
   948  
   949  		// Error returned from middleware client.
   950  		if resp.err != nil {
   951  			return resp.err
   952  		}
   953  	}
   954  
   955  	return nil
   956  }
   957  
   958  // interceptResponse sends out an intercept request for an RPC response. Since
   959  // middleware that hasn't registered for the read-only mode has the option to
   960  // overwrite/replace the response, this needs to be handled differently than the
   961  // request/auth path above.
   962  func (r *InterceptorChain) interceptResponse(ctx context.Context,
   963  	requestID uint64, isStream bool, fullMethod string,
   964  	m interface{}) (interface{}, error) {
   965  
   966  	r.RLock()
   967  	defer r.RUnlock()
   968  
   969  	currentMessage := m
   970  	for _, middleware := range r.registeredMiddleware {
   971  		msg, err := NewMessageInterceptionRequest(
   972  			ctx, TypeResponse, isStream, fullMethod, currentMessage,
   973  		)
   974  		if err != nil {
   975  			return nil, err
   976  		}
   977  
   978  		// If there is a custom caveat in the macaroon, make sure the
   979  		// middleware registered for it. Or if a middleware registered
   980  		// for read-only mode, it also gets the request.
   981  		hasCustomCaveat := macaroons.HasCustomCaveat(
   982  			msg.Macaroon, middleware.customCaveatName,
   983  		)
   984  		if !hasCustomCaveat && !middleware.readOnly {
   985  			continue
   986  		}
   987  
   988  		msg.CustomCaveatCondition = macaroons.GetCustomCaveatCondition(
   989  			msg.Macaroon, middleware.customCaveatName,
   990  		)
   991  
   992  		resp, err := middleware.intercept(requestID, msg)
   993  
   994  		// Error during interception itself.
   995  		if err != nil {
   996  			return nil, err
   997  		}
   998  
   999  		// Error returned from middleware client.
  1000  		if resp.err != nil {
  1001  			return nil, resp.err
  1002  		}
  1003  
  1004  		// The message was replaced, make sure the next middleware in
  1005  		// line receives the updated message.
  1006  		if !middleware.readOnly && resp.replace {
  1007  			currentMessage = resp.replacement
  1008  		}
  1009  	}
  1010  
  1011  	return currentMessage, nil
  1012  }
  1013  
  1014  // serverStreamWrapper is a struct that wraps a server stream in a way that all
  1015  // requests and responses can be intercepted individually.
  1016  type serverStreamWrapper struct {
  1017  	// ServerStream is the stream that's being wrapped.
  1018  	grpc.ServerStream
  1019  
  1020  	requestID uint64
  1021  
  1022  	fullMethod string
  1023  
  1024  	interceptor *InterceptorChain
  1025  }
  1026  
  1027  // SendMsg is called when lnd sends a message to the client. This is wrapped to
  1028  // intercept streaming RPC responses.
  1029  func (w *serverStreamWrapper) SendMsg(m interface{}) error {
  1030  	newMsg, err := w.interceptor.interceptResponse(
  1031  		w.ServerStream.Context(), w.requestID, true, w.fullMethod, m,
  1032  	)
  1033  	if err != nil {
  1034  		return err
  1035  	}
  1036  
  1037  	return w.ServerStream.SendMsg(newMsg)
  1038  }
  1039  
  1040  // RecvMsg is called when lnd wants to receive a message from the client. This
  1041  // is wrapped to intercept streaming RPC requests.
  1042  func (w *serverStreamWrapper) RecvMsg(m interface{}) error {
  1043  	err := w.ServerStream.RecvMsg(m)
  1044  	if err != nil {
  1045  		return err
  1046  	}
  1047  
  1048  	msg, err := NewMessageInterceptionRequest(
  1049  		w.ServerStream.Context(), TypeRequest, true, w.fullMethod,
  1050  		m,
  1051  	)
  1052  	if err != nil {
  1053  		return err
  1054  	}
  1055  
  1056  	return w.interceptor.acceptRequest(w.requestID, msg)
  1057  }