rpcperms

package
v0.17.5-beta Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 19, 2024 License: MIT Imports: 21 Imported by: 0

Documentation

Index

Constants

View Source
const Subsystem = "RPCP"

Subsystem defines the logging code for this subsystem.

Variables

View Source
var (
	// ErrWaitingToStart is returned if LND is still waiting to start,
	// possibly blocked until elected as the leader.
	ErrWaitingToStart = fmt.Errorf("waiting to start, RPC services not " +
		"available")

	// ErrNoWallet is returned if the wallet does not exist.
	ErrNoWallet = fmt.Errorf("wallet not created, create one to enable " +
		"full RPC access")

	// ErrWalletLocked is returned if the wallet is locked and any service
	// other than the WalletUnlocker is called.
	ErrWalletLocked = fmt.Errorf("wallet locked, unlock it to enable " +
		"full RPC access")

	// ErrWalletUnlocked is returned if the WalletUnlocker service is
	// called when the wallet already has been unlocked.
	ErrWalletUnlocked = fmt.Errorf("wallet already unlocked, " +
		"WalletUnlocker service is no longer available")

	// ErrRPCStarting is returned if the wallet has been unlocked but the
	// RPC server is not yet ready to accept calls.
	ErrRPCStarting = fmt.Errorf("the RPC server is in the process of " +
		"starting up, but not yet ready to accept calls")
)
View Source
var (
	// ErrShuttingDown is the error that's returned when the server is
	// shutting down and a request cannot be served anymore.
	ErrShuttingDown = errors.New("server shutting down")

	// ErrTimeoutReached is the error that's returned if any of the
	// middleware's tasks is not completed in the given time.
	ErrTimeoutReached = errors.New("intercept timeout reached")
)

Functions

func DisableLog

func DisableLog()

DisableLog disables all library log output. Logging output is disabled by default until UseLogger is called.

func UseLogger

func UseLogger(logger btclog.Logger)

UseLogger uses a specified Logger to output package logging info. This should be used in preference to SetLogWriter if the caller is also using btclog.

Types

type InterceptType

type InterceptType uint8

InterceptType defines the different types of intercept messages a middleware can receive.

const (
	// TypeStreamAuth is the type of intercept message that is sent when a
	// client or streaming RPC is initialized. A message with this type will
	// be sent out during stream initialization so a middleware can
	// accept/deny the whole stream instead of only single messages on the
	// stream.
	TypeStreamAuth InterceptType = 1

	// TypeRequest is the type of intercept message that is sent when an RPC
	// request message is sent to lnd. For client-streaming RPCs a new
	// message of this type is sent for each individual RPC request sent to
	// the stream. Middleware has the option to modify a request message
	// before it is delivered to lnd.
	TypeRequest InterceptType = 2

	// TypeResponse is the type of intercept message that is sent when an
	// RPC response message is sent from lnd to a client. For
	// server-streaming RPCs a new message of this type is sent for each
	// individual RPC response sent to the stream. Middleware has the option
	// to modify a response message before it is sent out to the client.
	TypeResponse InterceptType = 3
)

type InterceptionRequest

type InterceptionRequest struct {
	// Type is the type of the interception message.
	Type InterceptType

	// StreamRPC is set to true if the invoked RPC method is client or
	// server streaming.
	StreamRPC bool

	// Macaroon holds the macaroon that the client sent to lnd.
	Macaroon *macaroon.Macaroon

	// RawMacaroon holds the raw binary serialized macaroon that the client
	// sent to lnd.
	RawMacaroon []byte

	// CustomCaveatName is the name of the custom caveat that the middleware
	// was intercepting for.
	CustomCaveatName string

	// CustomCaveatCondition is the condition of the custom caveat that the
	// middleware was intercepting for. This can be empty for custom caveats
	// that only have a name (marker caveats).
	CustomCaveatCondition string

	// FullURI is the full RPC method URI that was invoked.
	FullURI string

	// ProtoSerialized is the full request or response object in the
	// protobuf binary serialization format.
	ProtoSerialized []byte

	// ProtoTypeName is the fully qualified name of the protobuf type of the
	// request or response message that is serialized in the field above.
	ProtoTypeName string

	// IsError indicates that the message contained within this request is
	// an error. Will only ever be true for response messages.
	IsError bool
}

InterceptionRequest is a struct holding all information that is sent to a middleware whenever there is something to intercept (auth, request, response).

func NewMessageInterceptionRequest

func NewMessageInterceptionRequest(ctx context.Context,
	authType InterceptType, isStream bool, fullMethod string,
	m interface{}) (*InterceptionRequest, error)

NewMessageInterceptionRequest creates a new interception request for either a request or response message.

func NewStreamAuthInterceptionRequest

func NewStreamAuthInterceptionRequest(ctx context.Context,
	fullMethod string) (*InterceptionRequest, error)

NewStreamAuthInterceptionRequest creates a new interception request for a stream authentication message.

func (*InterceptionRequest) ToRPC

func (r *InterceptionRequest) ToRPC(requestID,
	msgID uint64) (*lnrpc.RPCMiddlewareRequest, error)

ToRPC converts the interception request to its RPC counterpart.

type InterceptorChain

type InterceptorChain struct {

	// Required by the grpc-gateway/v2 library for forward compatibility.
	lnrpc.UnimplementedStateServer

	sync.RWMutex
	// contains filtered or unexported fields
}

InterceptorChain is a struct that can be added to the running GRPC server, intercepting API calls. This is useful for logging, enforcing permissions, supporting middleware etc. The following diagram shows the order of each interceptor in the chain and when exactly requests/responses are intercepted and forwarded to external middleware for approval/modification. Middleware in general can only intercept gRPC requests/responses that are sent by the client with a macaroon that contains a custom caveat that is supported by one of the registered middlewares.

    |
    | gRPC request from client
    |
+---v--------------------------------+
|   InterceptorChain                 |
+-+----------------------------------+
  | Log Interceptor                  |
  +----------------------------------+
  | RPC State Interceptor            |
  +----------------------------------+
  | Macaroon Interceptor             |
  +----------------------------------+--------> +---------------------+
  | RPC Macaroon Middleware Handler  |<-------- | External Middleware |
  +----------------------------------+          |   - modify request |
  | Prometheus Interceptor           |          +---------------------+
  +-+--------------------------------+
    | validated gRPC request from client
+---v--------------------------------+
|   main gRPC server                 |
+---+--------------------------------+
    |
    | original gRPC request to client
    |
+---v--------------------------------+--------> +---------------------+
|   RPC Macaroon Middleware Handler  |<-------- | External Middleware |
+---+--------------------------------+          |   - modify response |
    |                                           +---------------------+
    | edited gRPC request to client
    v

func NewInterceptorChain

func NewInterceptorChain(log btclog.Logger, noMacaroons bool,
	mandatoryMiddleware []string) *InterceptorChain

NewInterceptorChain creates a new InterceptorChain.

func (*InterceptorChain) AddMacaroonService

func (r *InterceptorChain) AddMacaroonService(svc *macaroons.Service)

AddMacaroonService adds a macaroon service to the interceptor. After this is done every RPC call made will have to pass a valid macaroon to be accepted.

func (*InterceptorChain) AddPermission

func (r *InterceptorChain) AddPermission(method string, ops []bakery.Op) error

AddPermission adds a new macaroon rule for the given method.

func (*InterceptorChain) CreateServerOpts

func (r *InterceptorChain) CreateServerOpts() []grpc.ServerOption

CreateServerOpts creates the GRPC server options that can be added to a GRPC server in order to add this InterceptorChain.

func (*InterceptorChain) CustomCaveatSupported

func (r *InterceptorChain) CustomCaveatSupported(customCaveatName string) error

CustomCaveatSupported makes sure a middleware that handles the given custom caveat name is registered. If none is, an error is returned, signalling to the macaroon bakery and its validator to reject macaroons that have a custom caveat with that name.

NOTE: This method is part of the macaroons.CustomCaveatAcceptor interface.

func (*InterceptorChain) GetState

GetState returns the current wallet state.

func (*InterceptorChain) MacaroonService

func (r *InterceptorChain) MacaroonService() *macaroons.Service

MacaroonService returns the currently registered macaroon service. This might be nil if none was registered (yet).

func (*InterceptorChain) MacaroonStreamServerInterceptor

func (r *InterceptorChain) MacaroonStreamServerInterceptor() grpc.StreamServerInterceptor

MacaroonStreamServerInterceptor is a GRPC interceptor that checks whether the request is authorized by the included macaroons.

func (*InterceptorChain) MacaroonUnaryServerInterceptor

func (r *InterceptorChain) MacaroonUnaryServerInterceptor() grpc.UnaryServerInterceptor

MacaroonUnaryServerInterceptor is a GRPC interceptor that checks whether the request is authorized by the included macaroons.

func (*InterceptorChain) Permissions

func (r *InterceptorChain) Permissions() map[string][]bakery.Op

Permissions returns the current set of macaroon permissions.

func (*InterceptorChain) RegisterMiddleware

func (r *InterceptorChain) RegisterMiddleware(mw *MiddlewareHandler) error

RegisterMiddleware registers a new middleware that will handle request/ response interception for all RPC messages that are initiated with a custom macaroon caveat. The name of the custom caveat a middleware is handling is also its unique identifier. Only one middleware can be registered for each custom caveat.

func (*InterceptorChain) RemoveMiddleware

func (r *InterceptorChain) RemoveMiddleware(middlewareName string)

RemoveMiddleware removes the middleware that handles the given custom caveat name.

func (*InterceptorChain) SetRPCActive

func (r *InterceptorChain) SetRPCActive()

SetRPCActive moves the RPC state from walletUnlocked to rpcActive.

func (*InterceptorChain) SetServerActive

func (r *InterceptorChain) SetServerActive()

SetServerActive moves the RPC state from walletUnlocked to rpcActive.

func (*InterceptorChain) SetWalletLocked

func (r *InterceptorChain) SetWalletLocked()

SetWalletLocked moves the RPC state from either walletNotCreated to walletLocked.

func (*InterceptorChain) SetWalletNotCreated

func (r *InterceptorChain) SetWalletNotCreated()

SetWalletNotCreated moves the RPC state from either waitingToStart to walletNotCreated.

func (*InterceptorChain) SetWalletUnlocked

func (r *InterceptorChain) SetWalletUnlocked()

SetWalletUnlocked moves the RPC state from either walletNotCreated or walletLocked to walletUnlocked.

func (*InterceptorChain) Start

func (r *InterceptorChain) Start() error

Start starts the InterceptorChain, which is needed to start the state subscription server it powers.

func (*InterceptorChain) Stop

func (r *InterceptorChain) Stop() error

Stop stops the InterceptorChain and its internal state subscription server.

func (*InterceptorChain) SubscribeState

SubscribeState subscribes to the state of the wallet. The current wallet state will always be delivered immediately.

NOTE: Part of the StateService interface.

type MiddlewareHandler

type MiddlewareHandler struct {
	// contains filtered or unexported fields
}

MiddlewareHandler is a type that communicates with a middleware over the established bi-directional RPC stream. It sends messages to the middleware whenever the custom business logic implemented there should give feedback to a request or response that's happening on the main gRPC server.

func NewMiddlewareHandler

func NewMiddlewareHandler(name, customCaveatName string, readOnly bool,
	receive func() (*lnrpc.RPCMiddlewareResponse, error),
	send func(request *lnrpc.RPCMiddlewareRequest) error,
	timeout time.Duration, params *chaincfg.Params,
	quit chan struct{}) *MiddlewareHandler

NewMiddlewareHandler creates a new handler for the middleware with the given name and custom caveat name.

func (*MiddlewareHandler) Run

func (h *MiddlewareHandler) Run() error

Run is the main loop for the middleware handler. This function will block until it receives the signal that lnd is shutting down, or the rpc stream is cancelled by the client.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL