diff --git a/cmd/litcli/sessions.go b/cmd/litcli/sessions.go index 3c44ea596..d16e27e03 100644 --- a/cmd/litcli/sessions.go +++ b/cmd/litcli/sessions.go @@ -7,6 +7,7 @@ import ( "time" "github.com/lightninglabs/lightning-terminal/litrpc" + "github.com/lightningnetwork/lnd/macaroons" "github.com/urfave/cli" ) @@ -62,9 +63,18 @@ var addSessionCommand = cli.Command{ Usage: "session type to be created which will " + "determine the permissions a user has when " + "connecting with the session. Options " + - "include readonly|admin", + "include readonly|admin|custom", Value: "readonly", }, + cli.StringSliceFlag{ + Name: "uri", + Usage: "A URI that should be included in the " + + "macaroon of a custom session. Note that " + + "this flag will only be used if the 'type' " + + "flag is set to 'custom'. This flag can be " + + "specified multiple times if multiple URIs " + + "should be included", + }, }, } @@ -87,17 +97,26 @@ func addSession(ctx *cli.Context) error { return err } + var macPerms []*litrpc.MacaroonPermission + for _, uri := range ctx.StringSlice("uri") { + macPerms = append(macPerms, &litrpc.MacaroonPermission{ + Entity: macaroons.PermissionEntityCustomURI, + Action: uri, + }) + } + sessionLength := time.Second * time.Duration(ctx.Uint64("expiry")) sessionExpiry := time.Now().Add(sessionLength).Unix() ctxb := context.Background() resp, err := client.AddSession( ctxb, &litrpc.AddSessionRequest{ - Label: label, - SessionType: sessType, - ExpiryTimestampSeconds: uint64(sessionExpiry), - MailboxServerAddr: ctx.String("mailboxserveraddr"), - DevServer: ctx.Bool("devserver"), + Label: label, + SessionType: sessType, + ExpiryTimestampSeconds: uint64(sessionExpiry), + MailboxServerAddr: ctx.String("mailboxserveraddr"), + DevServer: ctx.Bool("devserver"), + MacaroonCustomPermissions: macPerms, }, ) if err != nil { @@ -115,6 +134,8 @@ func parseSessionType(sessionType string) (litrpc.SessionType, error) { return litrpc.SessionType_TYPE_MACAROON_ADMIN, nil case "readonly": return litrpc.SessionType_TYPE_MACAROON_READONLY, nil + case "custom": + return litrpc.SessionType_TYPE_MACAROON_CUSTOM, nil default: return 0, fmt.Errorf("unsupported session type %s", sessionType) } diff --git a/itest/litd_mode_integrated_test.go b/itest/litd_mode_integrated_test.go index c268f4c5b..fe152d600 100644 --- a/itest/litd_mode_integrated_test.go +++ b/itest/litd_mode_integrated_test.go @@ -28,6 +28,7 @@ import ( "github.com/lightningnetwork/lnd/lnrpc" "github.com/lightningnetwork/lnd/lnrpc/routerrpc" "github.com/lightningnetwork/lnd/lnrpc/walletrpc" + "github.com/lightningnetwork/lnd/macaroons" "github.com/stretchr/testify/require" "golang.org/x/net/http2" "google.golang.org/grpc" @@ -224,6 +225,13 @@ var ( allowedThroughLNC: false, grpcWebURI: "/litrpc.Sessions/ListSessions", }} + + // customURIs is a map of endpoint URIs that we want to allow via a + // custom-macaroon session type. + customURIs = map[string]bool{ + "/lnrpc.Lightning/GetInfo": true, + "/frdrpc.FaradayServer/RevenueReport": true, + } ) // testModeIntegrated makes sure that in integrated mode all daemons work @@ -367,20 +375,109 @@ func testModeIntegrated(net *NetworkHarness, t *harnessTest) { t.t.Run("lnc auth", func(tt *testing.T) { cfg := net.Alice.Cfg + ctx := context.Background() + ctxt, cancel := context.WithTimeout(ctx, defaultTimeout) + defer cancel() + + rawLNCConn := setUpLNCConn( + ctxt, t.t, cfg.LitAddr(), cfg.TLSCertPath, + cfg.LitMacPath, + litrpc.SessionType_TYPE_MACAROON_READONLY, nil, + ) + defer rawLNCConn.Close() + for _, endpoint := range endpoints { endpoint := endpoint tt.Run(endpoint.name+" lit port", func(ttt *testing.T) { runLNCAuthTest( - ttt, cfg.LitAddr(), cfg.TLSCertPath, - cfg.LitMacPath, endpoint.requestFn, + ttt, rawLNCConn, endpoint.requestFn, endpoint.successPattern, endpoint.allowedThroughLNC, + "unknown service", + ) + }) + } + }) + + t.t.Run("lnc auth custom mac perms", func(tt *testing.T) { + cfg := net.Alice.Cfg + + ctx := context.Background() + ctxt, cancel := context.WithTimeout(ctx, defaultTimeout) + defer cancel() + + customPerms := make( + []*litrpc.MacaroonPermission, 0, len(customURIs), + ) + + customURIKeyword := macaroons.PermissionEntityCustomURI + for uri := range customURIs { + customPerms = append( + customPerms, &litrpc.MacaroonPermission{ + Entity: customURIKeyword, + Action: uri, + }, + ) + } + + rawLNCConn := setUpLNCConn( + ctxt, t.t, cfg.LitAddr(), cfg.TLSCertPath, + cfg.LitMacPath, + litrpc.SessionType_TYPE_MACAROON_CUSTOM, customPerms, + ) + defer rawLNCConn.Close() + + for _, endpoint := range endpoints { + endpoint := endpoint + tt.Run(endpoint.name+" lit port", func(ttt *testing.T) { + allowed := customURIs[endpoint.grpcWebURI] + runLNCAuthTest( + ttt, rawLNCConn, endpoint.requestFn, + endpoint.successPattern, + allowed, "permission denied", ) }) } }) } +// setUpLNCConn creates a new LNC session and then creates a connection to that +// session via the mailbox that the session was created with. +func setUpLNCConn(ctx context.Context, t *testing.T, hostPort, tlsCertPath, + macPath string, sessType litrpc.SessionType, + customMacPerms []*litrpc.MacaroonPermission) *grpc.ClientConn { + + rawConn, err := connectRPC(ctx, hostPort, tlsCertPath) + require.NoError(t, err) + + macBytes, err := ioutil.ReadFile(macPath) + require.NoError(t, err) + ctxm := macaroonContext(ctx, macBytes) + + // We first need to create an LNC session that we can use to connect. + litClient := litrpc.NewSessionsClient(rawConn) + sessResp, err := litClient.AddSession(ctxm, &litrpc.AddSessionRequest{ + Label: "integration-test", + SessionType: sessType, + ExpiryTimestampSeconds: uint64( + time.Now().Add(5 * time.Minute).Unix(), + ), + MailboxServerAddr: mailboxServerAddr, + MacaroonCustomPermissions: customMacPerms, + }) + require.NoError(t, err) + + // Try the LNC connection now. + connectPhrase := strings.Split( + sessResp.Session.PairingSecretMnemonic, " ", + ) + + rawLNCConn, err := connectMailbox(ctx, connectPhrase) + require.NoError(t, err) + + return rawLNCConn +} + // runCertificateCheck checks that the TLS certificates presented to clients are // what we expect them to be. func runCertificateCheck(t *testing.T, node *HarnessNode) { @@ -624,44 +721,15 @@ func runRESTAuthTest(t *testing.T, hostPort, uiPassword, macaroonPath, restURI, // runLNCAuthTest tests authentication of the given interface when connecting // through Lightning Node Connect. -func runLNCAuthTest(t *testing.T, hostPort, tlsCertPath, macPath string, - makeRequest requestFn, successContent string, callAllowed bool) { - - ctxb := context.Background() - ctxt, cancel := context.WithTimeout(ctxb, defaultTimeout) - defer cancel() - - rawConn, err := connectRPC(ctxt, hostPort, tlsCertPath) - require.NoError(t, err) +func runLNCAuthTest(t *testing.T, rawLNCConn grpc.ClientConnInterface, + makeRequest requestFn, successContent string, callAllowed bool, + expectErrContains string) { - macBytes, err := ioutil.ReadFile(macPath) - require.NoError(t, err) - ctxm := macaroonContext(ctxt, macBytes) - - // We first need to create an LNC session that we can use to connect. - // We use the UI password to create the session. - litClient := litrpc.NewSessionsClient(rawConn) - sessResp, err := litClient.AddSession(ctxm, &litrpc.AddSessionRequest{ - Label: "integration-test", - SessionType: litrpc.SessionType_TYPE_MACAROON_READONLY, - ExpiryTimestampSeconds: uint64( - time.Now().Add(5 * time.Minute).Unix(), - ), - MailboxServerAddr: mailboxServerAddr, - }) - require.NoError(t, err) - - // Try the LNC connection now. - connectPhrase := strings.Split( - sessResp.Session.PairingSecretMnemonic, " ", + ctxt, cancel := context.WithTimeout( + context.Background(), defaultTimeout, ) - - ctxt, cancel = context.WithTimeout(ctxb, defaultTimeout) defer cancel() - rawLNCConn, err := connectMailbox(ctxt, connectPhrase) - require.NoError(t, err) - // We should be able to make a request via LNC to the given RPC // endpoint, unless it is explicitly disallowed (we currently don't want // to support creating more sessions through LNC until we have all @@ -671,7 +739,7 @@ func runLNCAuthTest(t *testing.T, hostPort, tlsCertPath, macPath string, // Is this a disallowed call? if !callAllowed { require.Error(t, err) - require.Contains(t, err.Error(), "unknown service") + require.Contains(t, err.Error(), expectErrContains) return } @@ -767,7 +835,7 @@ func getServerCertificates(hostPort string) ([]*x509.Certificate, error) { // connectMailbox tries to establish a connection through LNC using the given // connect phrase and the test mailbox server. func connectMailbox(ctx context.Context, - connectPhrase []string) (grpc.ClientConnInterface, error) { + connectPhrase []string) (*grpc.ClientConn, error) { var mnemonicWords [mailbox.NumPassphraseWords]string copy(mnemonicWords[:], connectPhrase) diff --git a/itest/litd_mode_remote_test.go b/itest/litd_mode_remote_test.go index b99663911..59a1f3c2b 100644 --- a/itest/litd_mode_remote_test.go +++ b/itest/litd_mode_remote_test.go @@ -6,7 +6,9 @@ import ( "testing" "github.com/btcsuite/btcd/btcutil" + "github.com/lightninglabs/lightning-terminal/litrpc" "github.com/lightningnetwork/lnd/lnrpc" + "github.com/lightningnetwork/lnd/macaroons" "github.com/stretchr/testify/require" ) @@ -134,14 +136,66 @@ func testModeRemote(net *NetworkHarness, t *harnessTest) { t.t.Run("lnc auth", func(tt *testing.T) { cfg := net.Bob.Cfg + ctx := context.Background() + ctxt, cancel := context.WithTimeout(ctx, defaultTimeout) + defer cancel() + + rawLNCConn := setUpLNCConn( + ctxt, tt, cfg.LitAddr(), cfg.LitTLSCertPath, + cfg.LitMacPath, + litrpc.SessionType_TYPE_MACAROON_READONLY, nil, + ) + defer rawLNCConn.Close() + for _, endpoint := range endpoints { endpoint := endpoint tt.Run(endpoint.name+" lit port", func(ttt *testing.T) { runLNCAuthTest( - ttt, cfg.LitAddr(), cfg.LitTLSCertPath, - cfg.LitMacPath, endpoint.requestFn, + ttt, rawLNCConn, endpoint.requestFn, endpoint.successPattern, endpoint.allowedThroughLNC, + "unknown service", + ) + }) + } + }) + + t.t.Run("lnc auth custom mac perms", func(tt *testing.T) { + cfg := net.Bob.Cfg + + ctx := context.Background() + ctxt, cancel := context.WithTimeout(ctx, defaultTimeout) + defer cancel() + + customPerms := make( + []*litrpc.MacaroonPermission, 0, len(customURIs), + ) + + customURIKeyword := macaroons.PermissionEntityCustomURI + for uri := range customURIs { + customPerms = append( + customPerms, &litrpc.MacaroonPermission{ + Entity: customURIKeyword, + Action: uri, + }, + ) + } + + rawLNCConn := setUpLNCConn( + ctxt, tt, cfg.LitAddr(), cfg.LitTLSCertPath, + cfg.LitMacPath, + litrpc.SessionType_TYPE_MACAROON_CUSTOM, customPerms, + ) + defer rawLNCConn.Close() + + for _, endpoint := range endpoints { + endpoint := endpoint + tt.Run(endpoint.name+" lit port", func(ttt *testing.T) { + allowed := customURIs[endpoint.grpcWebURI] + runLNCAuthTest( + ttt, rawLNCConn, endpoint.requestFn, + endpoint.successPattern, + allowed, "permission denied", ) }) } diff --git a/litrpc/lit-sessions.pb.go b/litrpc/lit-sessions.pb.go index 7170f4e74..1a8e15147 100644 --- a/litrpc/lit-sessions.pb.go +++ b/litrpc/lit-sessions.pb.go @@ -320,17 +320,18 @@ type Session struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Label string `protobuf:"bytes,1,opt,name=label,proto3" json:"label,omitempty"` - SessionState SessionState `protobuf:"varint,2,opt,name=session_state,json=sessionState,proto3,enum=litrpc.SessionState" json:"session_state,omitempty"` - SessionType SessionType `protobuf:"varint,3,opt,name=session_type,json=sessionType,proto3,enum=litrpc.SessionType" json:"session_type,omitempty"` - ExpiryTimestampSeconds uint64 `protobuf:"varint,4,opt,name=expiry_timestamp_seconds,json=expiryTimestampSeconds,proto3" json:"expiry_timestamp_seconds,omitempty"` - MailboxServerAddr string `protobuf:"bytes,5,opt,name=mailbox_server_addr,json=mailboxServerAddr,proto3" json:"mailbox_server_addr,omitempty"` - DevServer bool `protobuf:"varint,6,opt,name=dev_server,json=devServer,proto3" json:"dev_server,omitempty"` - PairingSecret []byte `protobuf:"bytes,7,opt,name=pairing_secret,json=pairingSecret,proto3" json:"pairing_secret,omitempty"` - PairingSecretMnemonic string `protobuf:"bytes,8,opt,name=pairing_secret_mnemonic,json=pairingSecretMnemonic,proto3" json:"pairing_secret_mnemonic,omitempty"` - LocalPublicKey []byte `protobuf:"bytes,9,opt,name=local_public_key,json=localPublicKey,proto3" json:"local_public_key,omitempty"` - RemotePublicKey []byte `protobuf:"bytes,10,opt,name=remote_public_key,json=remotePublicKey,proto3" json:"remote_public_key,omitempty"` - CreatedAt uint64 `protobuf:"varint,11,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"` + Label string `protobuf:"bytes,1,opt,name=label,proto3" json:"label,omitempty"` + SessionState SessionState `protobuf:"varint,2,opt,name=session_state,json=sessionState,proto3,enum=litrpc.SessionState" json:"session_state,omitempty"` + SessionType SessionType `protobuf:"varint,3,opt,name=session_type,json=sessionType,proto3,enum=litrpc.SessionType" json:"session_type,omitempty"` + ExpiryTimestampSeconds uint64 `protobuf:"varint,4,opt,name=expiry_timestamp_seconds,json=expiryTimestampSeconds,proto3" json:"expiry_timestamp_seconds,omitempty"` + MailboxServerAddr string `protobuf:"bytes,5,opt,name=mailbox_server_addr,json=mailboxServerAddr,proto3" json:"mailbox_server_addr,omitempty"` + DevServer bool `protobuf:"varint,6,opt,name=dev_server,json=devServer,proto3" json:"dev_server,omitempty"` + PairingSecret []byte `protobuf:"bytes,7,opt,name=pairing_secret,json=pairingSecret,proto3" json:"pairing_secret,omitempty"` + PairingSecretMnemonic string `protobuf:"bytes,8,opt,name=pairing_secret_mnemonic,json=pairingSecretMnemonic,proto3" json:"pairing_secret_mnemonic,omitempty"` + LocalPublicKey []byte `protobuf:"bytes,9,opt,name=local_public_key,json=localPublicKey,proto3" json:"local_public_key,omitempty"` + RemotePublicKey []byte `protobuf:"bytes,10,opt,name=remote_public_key,json=remotePublicKey,proto3" json:"remote_public_key,omitempty"` + CreatedAt uint64 `protobuf:"varint,11,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"` + MacaroonRecipe *MacaroonRecipe `protobuf:"bytes,12,opt,name=macaroon_recipe,json=macaroonRecipe,proto3" json:"macaroon_recipe,omitempty"` } func (x *Session) Reset() { @@ -442,6 +443,68 @@ func (x *Session) GetCreatedAt() uint64 { return 0 } +func (x *Session) GetMacaroonRecipe() *MacaroonRecipe { + if x != nil { + return x.MacaroonRecipe + } + return nil +} + +type MacaroonRecipe struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Permissions []*MacaroonPermission `protobuf:"bytes,1,rep,name=permissions,proto3" json:"permissions,omitempty"` + Caveats []string `protobuf:"bytes,2,rep,name=caveats,proto3" json:"caveats,omitempty"` +} + +func (x *MacaroonRecipe) Reset() { + *x = MacaroonRecipe{} + if protoimpl.UnsafeEnabled { + mi := &file_lit_sessions_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *MacaroonRecipe) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MacaroonRecipe) ProtoMessage() {} + +func (x *MacaroonRecipe) ProtoReflect() protoreflect.Message { + mi := &file_lit_sessions_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use MacaroonRecipe.ProtoReflect.Descriptor instead. +func (*MacaroonRecipe) Descriptor() ([]byte, []int) { + return file_lit_sessions_proto_rawDescGZIP(), []int{4} +} + +func (x *MacaroonRecipe) GetPermissions() []*MacaroonPermission { + if x != nil { + return x.Permissions + } + return nil +} + +func (x *MacaroonRecipe) GetCaveats() []string { + if x != nil { + return x.Caveats + } + return nil +} + type ListSessionsRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -451,7 +514,7 @@ type ListSessionsRequest struct { func (x *ListSessionsRequest) Reset() { *x = ListSessionsRequest{} if protoimpl.UnsafeEnabled { - mi := &file_lit_sessions_proto_msgTypes[4] + mi := &file_lit_sessions_proto_msgTypes[5] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -464,7 +527,7 @@ func (x *ListSessionsRequest) String() string { func (*ListSessionsRequest) ProtoMessage() {} func (x *ListSessionsRequest) ProtoReflect() protoreflect.Message { - mi := &file_lit_sessions_proto_msgTypes[4] + mi := &file_lit_sessions_proto_msgTypes[5] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -477,7 +540,7 @@ func (x *ListSessionsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ListSessionsRequest.ProtoReflect.Descriptor instead. func (*ListSessionsRequest) Descriptor() ([]byte, []int) { - return file_lit_sessions_proto_rawDescGZIP(), []int{4} + return file_lit_sessions_proto_rawDescGZIP(), []int{5} } type ListSessionsResponse struct { @@ -491,7 +554,7 @@ type ListSessionsResponse struct { func (x *ListSessionsResponse) Reset() { *x = ListSessionsResponse{} if protoimpl.UnsafeEnabled { - mi := &file_lit_sessions_proto_msgTypes[5] + mi := &file_lit_sessions_proto_msgTypes[6] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -504,7 +567,7 @@ func (x *ListSessionsResponse) String() string { func (*ListSessionsResponse) ProtoMessage() {} func (x *ListSessionsResponse) ProtoReflect() protoreflect.Message { - mi := &file_lit_sessions_proto_msgTypes[5] + mi := &file_lit_sessions_proto_msgTypes[6] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -517,7 +580,7 @@ func (x *ListSessionsResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ListSessionsResponse.ProtoReflect.Descriptor instead. func (*ListSessionsResponse) Descriptor() ([]byte, []int) { - return file_lit_sessions_proto_rawDescGZIP(), []int{5} + return file_lit_sessions_proto_rawDescGZIP(), []int{6} } func (x *ListSessionsResponse) GetSessions() []*Session { @@ -538,7 +601,7 @@ type RevokeSessionRequest struct { func (x *RevokeSessionRequest) Reset() { *x = RevokeSessionRequest{} if protoimpl.UnsafeEnabled { - mi := &file_lit_sessions_proto_msgTypes[6] + mi := &file_lit_sessions_proto_msgTypes[7] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -551,7 +614,7 @@ func (x *RevokeSessionRequest) String() string { func (*RevokeSessionRequest) ProtoMessage() {} func (x *RevokeSessionRequest) ProtoReflect() protoreflect.Message { - mi := &file_lit_sessions_proto_msgTypes[6] + mi := &file_lit_sessions_proto_msgTypes[7] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -564,7 +627,7 @@ func (x *RevokeSessionRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use RevokeSessionRequest.ProtoReflect.Descriptor instead. func (*RevokeSessionRequest) Descriptor() ([]byte, []int) { - return file_lit_sessions_proto_rawDescGZIP(), []int{6} + return file_lit_sessions_proto_rawDescGZIP(), []int{7} } func (x *RevokeSessionRequest) GetLocalPublicKey() []byte { @@ -583,7 +646,7 @@ type RevokeSessionResponse struct { func (x *RevokeSessionResponse) Reset() { *x = RevokeSessionResponse{} if protoimpl.UnsafeEnabled { - mi := &file_lit_sessions_proto_msgTypes[7] + mi := &file_lit_sessions_proto_msgTypes[8] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -596,7 +659,7 @@ func (x *RevokeSessionResponse) String() string { func (*RevokeSessionResponse) ProtoMessage() {} func (x *RevokeSessionResponse) ProtoReflect() protoreflect.Message { - mi := &file_lit_sessions_proto_msgTypes[7] + mi := &file_lit_sessions_proto_msgTypes[8] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -609,7 +672,7 @@ func (x *RevokeSessionResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use RevokeSessionResponse.ProtoReflect.Descriptor instead. func (*RevokeSessionResponse) Descriptor() ([]byte, []int) { - return file_lit_sessions_proto_rawDescGZIP(), []int{7} + return file_lit_sessions_proto_rawDescGZIP(), []int{8} } var File_lit_sessions_proto protoreflect.FileDescriptor @@ -646,7 +709,7 @@ var file_lit_sessions_proto_rawDesc = []byte{ 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x29, 0x0a, 0x07, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x6c, 0x69, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x07, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, - 0x22, 0xf7, 0x03, 0x0a, 0x07, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x14, 0x0a, 0x05, + 0x22, 0xb8, 0x04, 0x0a, 0x07, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x12, 0x39, 0x0a, 0x0d, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x14, 0x2e, 0x6c, 0x69, 0x74, 0x72, @@ -677,50 +740,61 @@ var file_lit_sessions_proto_rawDesc = []byte{ 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0f, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x21, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x04, 0x42, 0x02, 0x30, 0x01, 0x52, - 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x22, 0x15, 0x0a, 0x13, 0x4c, 0x69, - 0x73, 0x74, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x22, 0x43, 0x0a, 0x14, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, - 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2b, 0x0a, 0x08, 0x73, 0x65, 0x73, - 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x6c, 0x69, - 0x74, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x08, 0x73, 0x65, - 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x40, 0x0a, 0x14, 0x52, 0x65, 0x76, 0x6f, 0x6b, 0x65, - 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x28, - 0x0a, 0x10, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x5f, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, - 0x65, 0x79, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0e, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x50, - 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x22, 0x17, 0x0a, 0x15, 0x52, 0x65, 0x76, 0x6f, - 0x6b, 0x65, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x2a, 0x72, 0x0a, 0x0b, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, - 0x12, 0x1a, 0x0a, 0x16, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x4d, 0x41, 0x43, 0x41, 0x52, 0x4f, 0x4f, - 0x4e, 0x5f, 0x52, 0x45, 0x41, 0x44, 0x4f, 0x4e, 0x4c, 0x59, 0x10, 0x00, 0x12, 0x17, 0x0a, 0x13, - 0x54, 0x59, 0x50, 0x45, 0x5f, 0x4d, 0x41, 0x43, 0x41, 0x52, 0x4f, 0x4f, 0x4e, 0x5f, 0x41, 0x44, - 0x4d, 0x49, 0x4e, 0x10, 0x01, 0x12, 0x18, 0x0a, 0x14, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x4d, 0x41, - 0x43, 0x41, 0x52, 0x4f, 0x4f, 0x4e, 0x5f, 0x43, 0x55, 0x53, 0x54, 0x4f, 0x4d, 0x10, 0x02, 0x12, - 0x14, 0x0a, 0x10, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, 0x49, 0x5f, 0x50, 0x41, 0x53, 0x53, 0x57, - 0x4f, 0x52, 0x44, 0x10, 0x03, 0x2a, 0x59, 0x0a, 0x0c, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, - 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x11, 0x0a, 0x0d, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x43, - 0x52, 0x45, 0x41, 0x54, 0x45, 0x44, 0x10, 0x00, 0x12, 0x10, 0x0a, 0x0c, 0x53, 0x54, 0x41, 0x54, - 0x45, 0x5f, 0x49, 0x4e, 0x5f, 0x55, 0x53, 0x45, 0x10, 0x01, 0x12, 0x11, 0x0a, 0x0d, 0x53, 0x54, - 0x41, 0x54, 0x45, 0x5f, 0x52, 0x45, 0x56, 0x4f, 0x4b, 0x45, 0x44, 0x10, 0x02, 0x12, 0x11, 0x0a, - 0x0d, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x45, 0x58, 0x50, 0x49, 0x52, 0x45, 0x44, 0x10, 0x03, - 0x32, 0xe8, 0x01, 0x0a, 0x08, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x43, 0x0a, - 0x0a, 0x41, 0x64, 0x64, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x19, 0x2e, 0x6c, 0x69, - 0x74, 0x72, 0x70, 0x63, 0x2e, 0x41, 0x64, 0x64, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x6c, 0x69, 0x74, 0x72, 0x70, 0x63, 0x2e, - 0x41, 0x64, 0x64, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x49, 0x0a, 0x0c, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, - 0x6e, 0x73, 0x12, 0x1b, 0x2e, 0x6c, 0x69, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69, 0x73, 0x74, - 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x1c, 0x2e, 0x6c, 0x69, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x65, 0x73, - 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4c, 0x0a, - 0x0d, 0x52, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1c, - 0x2e, 0x6c, 0x69, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x52, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x53, 0x65, - 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x6c, - 0x69, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x52, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x53, 0x65, 0x73, 0x73, - 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x34, 0x5a, 0x32, 0x67, - 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6c, 0x69, 0x67, 0x68, 0x74, 0x6e, - 0x69, 0x6e, 0x67, 0x6c, 0x61, 0x62, 0x73, 0x2f, 0x6c, 0x69, 0x67, 0x68, 0x74, 0x6e, 0x69, 0x6e, - 0x67, 0x2d, 0x74, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x6c, 0x2f, 0x6c, 0x69, 0x74, 0x72, 0x70, - 0x63, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x3f, 0x0a, 0x0f, 0x6d, 0x61, + 0x63, 0x61, 0x72, 0x6f, 0x6f, 0x6e, 0x5f, 0x72, 0x65, 0x63, 0x69, 0x70, 0x65, 0x18, 0x0c, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x6c, 0x69, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x4d, 0x61, 0x63, + 0x61, 0x72, 0x6f, 0x6f, 0x6e, 0x52, 0x65, 0x63, 0x69, 0x70, 0x65, 0x52, 0x0e, 0x6d, 0x61, 0x63, + 0x61, 0x72, 0x6f, 0x6f, 0x6e, 0x52, 0x65, 0x63, 0x69, 0x70, 0x65, 0x22, 0x68, 0x0a, 0x0e, 0x4d, + 0x61, 0x63, 0x61, 0x72, 0x6f, 0x6f, 0x6e, 0x52, 0x65, 0x63, 0x69, 0x70, 0x65, 0x12, 0x3c, 0x0a, + 0x0b, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x6c, 0x69, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x4d, 0x61, 0x63, 0x61, + 0x72, 0x6f, 0x6f, 0x6e, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x0b, + 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x63, + 0x61, 0x76, 0x65, 0x61, 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x63, 0x61, + 0x76, 0x65, 0x61, 0x74, 0x73, 0x22, 0x15, 0x0a, 0x13, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x65, 0x73, + 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x43, 0x0a, 0x14, + 0x4c, 0x69, 0x73, 0x74, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2b, 0x0a, 0x08, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, + 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x6c, 0x69, 0x74, 0x72, 0x70, 0x63, 0x2e, + 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x08, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, + 0x73, 0x22, 0x40, 0x0a, 0x14, 0x52, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x53, 0x65, 0x73, 0x73, 0x69, + 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x28, 0x0a, 0x10, 0x6c, 0x6f, 0x63, + 0x61, 0x6c, 0x5f, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x08, 0x20, + 0x01, 0x28, 0x0c, 0x52, 0x0e, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, + 0x4b, 0x65, 0x79, 0x22, 0x17, 0x0a, 0x15, 0x52, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x53, 0x65, 0x73, + 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2a, 0x72, 0x0a, 0x0b, + 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1a, 0x0a, 0x16, 0x54, + 0x59, 0x50, 0x45, 0x5f, 0x4d, 0x41, 0x43, 0x41, 0x52, 0x4f, 0x4f, 0x4e, 0x5f, 0x52, 0x45, 0x41, + 0x44, 0x4f, 0x4e, 0x4c, 0x59, 0x10, 0x00, 0x12, 0x17, 0x0a, 0x13, 0x54, 0x59, 0x50, 0x45, 0x5f, + 0x4d, 0x41, 0x43, 0x41, 0x52, 0x4f, 0x4f, 0x4e, 0x5f, 0x41, 0x44, 0x4d, 0x49, 0x4e, 0x10, 0x01, + 0x12, 0x18, 0x0a, 0x14, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x4d, 0x41, 0x43, 0x41, 0x52, 0x4f, 0x4f, + 0x4e, 0x5f, 0x43, 0x55, 0x53, 0x54, 0x4f, 0x4d, 0x10, 0x02, 0x12, 0x14, 0x0a, 0x10, 0x54, 0x59, + 0x50, 0x45, 0x5f, 0x55, 0x49, 0x5f, 0x50, 0x41, 0x53, 0x53, 0x57, 0x4f, 0x52, 0x44, 0x10, 0x03, + 0x2a, 0x59, 0x0a, 0x0c, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, + 0x12, 0x11, 0x0a, 0x0d, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, + 0x44, 0x10, 0x00, 0x12, 0x10, 0x0a, 0x0c, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x49, 0x4e, 0x5f, + 0x55, 0x53, 0x45, 0x10, 0x01, 0x12, 0x11, 0x0a, 0x0d, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x52, + 0x45, 0x56, 0x4f, 0x4b, 0x45, 0x44, 0x10, 0x02, 0x12, 0x11, 0x0a, 0x0d, 0x53, 0x54, 0x41, 0x54, + 0x45, 0x5f, 0x45, 0x58, 0x50, 0x49, 0x52, 0x45, 0x44, 0x10, 0x03, 0x32, 0xe8, 0x01, 0x0a, 0x08, + 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x43, 0x0a, 0x0a, 0x41, 0x64, 0x64, 0x53, + 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x19, 0x2e, 0x6c, 0x69, 0x74, 0x72, 0x70, 0x63, 0x2e, + 0x41, 0x64, 0x64, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x1a, 0x2e, 0x6c, 0x69, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x41, 0x64, 0x64, 0x53, 0x65, + 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x49, 0x0a, + 0x0c, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x1b, 0x2e, + 0x6c, 0x69, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x65, 0x73, 0x73, 0x69, + 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x6c, 0x69, 0x74, + 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4c, 0x0a, 0x0d, 0x52, 0x65, 0x76, 0x6f, + 0x6b, 0x65, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1c, 0x2e, 0x6c, 0x69, 0x74, 0x72, + 0x70, 0x63, 0x2e, 0x52, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x6c, 0x69, 0x74, 0x72, 0x70, 0x63, + 0x2e, 0x52, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x34, 0x5a, 0x32, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, + 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6c, 0x69, 0x67, 0x68, 0x74, 0x6e, 0x69, 0x6e, 0x67, 0x6c, 0x61, + 0x62, 0x73, 0x2f, 0x6c, 0x69, 0x67, 0x68, 0x74, 0x6e, 0x69, 0x6e, 0x67, 0x2d, 0x74, 0x65, 0x72, + 0x6d, 0x69, 0x6e, 0x61, 0x6c, 0x2f, 0x6c, 0x69, 0x74, 0x72, 0x70, 0x63, 0x62, 0x06, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -736,7 +810,7 @@ func file_lit_sessions_proto_rawDescGZIP() []byte { } var file_lit_sessions_proto_enumTypes = make([]protoimpl.EnumInfo, 2) -var file_lit_sessions_proto_msgTypes = make([]protoimpl.MessageInfo, 8) +var file_lit_sessions_proto_msgTypes = make([]protoimpl.MessageInfo, 9) var file_lit_sessions_proto_goTypes = []interface{}{ (SessionType)(0), // 0: litrpc.SessionType (SessionState)(0), // 1: litrpc.SessionState @@ -744,29 +818,32 @@ var file_lit_sessions_proto_goTypes = []interface{}{ (*MacaroonPermission)(nil), // 3: litrpc.MacaroonPermission (*AddSessionResponse)(nil), // 4: litrpc.AddSessionResponse (*Session)(nil), // 5: litrpc.Session - (*ListSessionsRequest)(nil), // 6: litrpc.ListSessionsRequest - (*ListSessionsResponse)(nil), // 7: litrpc.ListSessionsResponse - (*RevokeSessionRequest)(nil), // 8: litrpc.RevokeSessionRequest - (*RevokeSessionResponse)(nil), // 9: litrpc.RevokeSessionResponse + (*MacaroonRecipe)(nil), // 6: litrpc.MacaroonRecipe + (*ListSessionsRequest)(nil), // 7: litrpc.ListSessionsRequest + (*ListSessionsResponse)(nil), // 8: litrpc.ListSessionsResponse + (*RevokeSessionRequest)(nil), // 9: litrpc.RevokeSessionRequest + (*RevokeSessionResponse)(nil), // 10: litrpc.RevokeSessionResponse } var file_lit_sessions_proto_depIdxs = []int32{ - 0, // 0: litrpc.AddSessionRequest.session_type:type_name -> litrpc.SessionType - 3, // 1: litrpc.AddSessionRequest.macaroon_custom_permissions:type_name -> litrpc.MacaroonPermission - 5, // 2: litrpc.AddSessionResponse.session:type_name -> litrpc.Session - 1, // 3: litrpc.Session.session_state:type_name -> litrpc.SessionState - 0, // 4: litrpc.Session.session_type:type_name -> litrpc.SessionType - 5, // 5: litrpc.ListSessionsResponse.sessions:type_name -> litrpc.Session - 2, // 6: litrpc.Sessions.AddSession:input_type -> litrpc.AddSessionRequest - 6, // 7: litrpc.Sessions.ListSessions:input_type -> litrpc.ListSessionsRequest - 8, // 8: litrpc.Sessions.RevokeSession:input_type -> litrpc.RevokeSessionRequest - 4, // 9: litrpc.Sessions.AddSession:output_type -> litrpc.AddSessionResponse - 7, // 10: litrpc.Sessions.ListSessions:output_type -> litrpc.ListSessionsResponse - 9, // 11: litrpc.Sessions.RevokeSession:output_type -> litrpc.RevokeSessionResponse - 9, // [9:12] is the sub-list for method output_type - 6, // [6:9] is the sub-list for method input_type - 6, // [6:6] is the sub-list for extension type_name - 6, // [6:6] is the sub-list for extension extendee - 0, // [0:6] is the sub-list for field type_name + 0, // 0: litrpc.AddSessionRequest.session_type:type_name -> litrpc.SessionType + 3, // 1: litrpc.AddSessionRequest.macaroon_custom_permissions:type_name -> litrpc.MacaroonPermission + 5, // 2: litrpc.AddSessionResponse.session:type_name -> litrpc.Session + 1, // 3: litrpc.Session.session_state:type_name -> litrpc.SessionState + 0, // 4: litrpc.Session.session_type:type_name -> litrpc.SessionType + 6, // 5: litrpc.Session.macaroon_recipe:type_name -> litrpc.MacaroonRecipe + 3, // 6: litrpc.MacaroonRecipe.permissions:type_name -> litrpc.MacaroonPermission + 5, // 7: litrpc.ListSessionsResponse.sessions:type_name -> litrpc.Session + 2, // 8: litrpc.Sessions.AddSession:input_type -> litrpc.AddSessionRequest + 7, // 9: litrpc.Sessions.ListSessions:input_type -> litrpc.ListSessionsRequest + 9, // 10: litrpc.Sessions.RevokeSession:input_type -> litrpc.RevokeSessionRequest + 4, // 11: litrpc.Sessions.AddSession:output_type -> litrpc.AddSessionResponse + 8, // 12: litrpc.Sessions.ListSessions:output_type -> litrpc.ListSessionsResponse + 10, // 13: litrpc.Sessions.RevokeSession:output_type -> litrpc.RevokeSessionResponse + 11, // [11:14] is the sub-list for method output_type + 8, // [8:11] is the sub-list for method input_type + 8, // [8:8] is the sub-list for extension type_name + 8, // [8:8] is the sub-list for extension extendee + 0, // [0:8] is the sub-list for field type_name } func init() { file_lit_sessions_proto_init() } @@ -824,7 +901,7 @@ func file_lit_sessions_proto_init() { } } file_lit_sessions_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ListSessionsRequest); i { + switch v := v.(*MacaroonRecipe); i { case 0: return &v.state case 1: @@ -836,7 +913,7 @@ func file_lit_sessions_proto_init() { } } file_lit_sessions_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ListSessionsResponse); i { + switch v := v.(*ListSessionsRequest); i { case 0: return &v.state case 1: @@ -848,7 +925,7 @@ func file_lit_sessions_proto_init() { } } file_lit_sessions_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*RevokeSessionRequest); i { + switch v := v.(*ListSessionsResponse); i { case 0: return &v.state case 1: @@ -860,6 +937,18 @@ func file_lit_sessions_proto_init() { } } file_lit_sessions_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RevokeSessionRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_lit_sessions_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*RevokeSessionResponse); i { case 0: return &v.state @@ -878,7 +967,7 @@ func file_lit_sessions_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_lit_sessions_proto_rawDesc, NumEnums: 2, - NumMessages: 8, + NumMessages: 9, NumExtensions: 0, NumServices: 1, }, diff --git a/litrpc/lit-sessions.proto b/litrpc/lit-sessions.proto index 234d726d8..abd916f59 100644 --- a/litrpc/lit-sessions.proto +++ b/litrpc/lit-sessions.proto @@ -76,6 +76,14 @@ message Session { bytes remote_public_key = 10; uint64 created_at = 11 [jstype = JS_STRING]; + + MacaroonRecipe macaroon_recipe = 12; +} + +message MacaroonRecipe { + repeated MacaroonPermission permissions = 1; + + repeated string caveats = 2; } message ListSessionsRequest { diff --git a/session_rpcserver.go b/session_rpcserver.go index 1272ff034..55bb39222 100644 --- a/session_rpcserver.go +++ b/session_rpcserver.go @@ -11,7 +11,9 @@ import ( "github.com/lightninglabs/lightning-node-connect/mailbox" "github.com/lightninglabs/lightning-terminal/litrpc" "github.com/lightninglabs/lightning-terminal/session" + "github.com/lightningnetwork/lnd/macaroons" "google.golang.org/grpc" + "gopkg.in/macaroon-bakery.v2/bakery" "gopkg.in/macaroon-bakery.v2/bakery/checkers" "gopkg.in/macaroon.v2" ) @@ -123,16 +125,46 @@ func (s *sessionRpcServer) AddSession(_ context.Context, return nil, err } - if typ != session.TypeMacaroonAdmin && - typ != session.TypeMacaroonReadonly { + var permissions []bakery.Op + switch typ { + // For the default session types we use empty caveats and permissions, + // the macaroons are baked correctly when creating the session. + case session.TypeMacaroonAdmin, session.TypeMacaroonReadonly: + + // For the custom macaroon type, we use the custom permissions specified + // in the request. For the time being, the caveats list will be empty + // for this type. + case session.TypeMacaroonCustom: + if len(req.MacaroonCustomPermissions) == 0 { + return nil, fmt.Errorf("custom macaroon " + + "permissions must be specified for the " + + "custom macaroon session type") + } - return nil, fmt.Errorf("invalid session type, only admin " + - "and readonly macaroon types supported in LiT") + for _, op := range req.MacaroonCustomPermissions { + if op.Entity == macaroons.PermissionEntityCustomURI { + _, ok := s.cfg.permMgr.URIPermissions(op.Action) + if !ok { + return nil, fmt.Errorf("URI %s is "+ + "unknown to LiT", op.Action) + } + } + + permissions = append(permissions, bakery.Op{ + Entity: op.Entity, + Action: op.Action, + }) + } + + // No other types are currently supported. + default: + return nil, fmt.Errorf("invalid session type, only admin, " + + "readonly and custom macaroon types supported in LiT") } sess, err := session.NewSession( req.Label, typ, expiry, req.MailboxServerAddr, req.DevServer, - nil, nil, + permissions, nil, ) if err != nil { return nil, fmt.Errorf("error creating new session: %v", err) @@ -184,19 +216,29 @@ func (s *sessionRpcServer) resumeSession(sess *session.Session) error { return nil } - if sess.Type != session.TypeMacaroonAdmin && - sess.Type != session.TypeMacaroonReadonly { + var ( + caveats []macaroon.Caveat + permissions []bakery.Op + readOnly = sess.Type == session.TypeMacaroonReadonly + ) + switch sess.Type { + // For the default session types we use empty caveats and permissions, + // the macaroons are baked correctly when creating the session. + case session.TypeMacaroonAdmin, session.TypeMacaroonReadonly: + permissions = s.cfg.permMgr.ActivePermissions(readOnly) + + // For custom session types, we use the caveats and permissions that + // were persisted on session creation. + case session.TypeMacaroonCustom: + permissions = sess.MacaroonRecipe.Permissions + // No other types are currently supported. + default: log.Debugf("Not resuming session %x with type %d", pubKeyBytes, sess.Type) return nil } - var ( - caveats []macaroon.Caveat - readOnly = sess.Type == session.TypeMacaroonReadonly - ) - // Add the session expiry as a macaroon caveat. macExpiry := checkers.TimeBeforeCaveat(sess.Expiry) caveats = append(caveats, macaroon.Caveat{ @@ -206,7 +248,7 @@ func (s *sessionRpcServer) resumeSession(sess *session.Session) error { mac, err := s.cfg.superMacBaker( context.Background(), sess.MacaroonRootKey, &session.MacaroonRecipe{ - Permissions: s.cfg.permMgr.ActivePermissions(readOnly), + Permissions: permissions, Caveats: caveats, }, ) @@ -380,6 +422,8 @@ func marshalRPCSession(sess *session.Session) (*litrpc.Session, error) { return nil, err } + macRecipe := marshalRPCMacaroonRecipe(sess.MacaroonRecipe) + return &litrpc.Session{ Label: sess.Label, SessionState: rpcState, @@ -392,9 +436,38 @@ func marshalRPCSession(sess *session.Session) (*litrpc.Session, error) { LocalPublicKey: sess.LocalPublicKey.SerializeCompressed(), RemotePublicKey: remotePubKey, CreatedAt: uint64(sess.CreatedAt.Unix()), + MacaroonRecipe: macRecipe, }, nil } +// marshalRPCMacaroonRecipe converts a macaroon recipe (permissions and caveats) +// into its RPC counterpart. +func marshalRPCMacaroonRecipe( + recipe *session.MacaroonRecipe) *litrpc.MacaroonRecipe { + + if recipe == nil { + return nil + } + + perms := make([]*litrpc.MacaroonPermission, len(recipe.Permissions)) + for i, op := range recipe.Permissions { + perms[i] = &litrpc.MacaroonPermission{ + Entity: op.Entity, + Action: op.Action, + } + } + + caveats := make([]string, len(recipe.Caveats)) + for i, cav := range recipe.Caveats { + caveats[i] = string(cav.Id) + } + + return &litrpc.MacaroonRecipe{ + Permissions: perms, + Caveats: caveats, + } +} + // marshalRPCState converts a session state to its RPC counterpart. func marshalRPCState(state session.State) (litrpc.SessionState, error) { switch state {