From ec327b6e038179a667d601bb9842adee5d192e63 Mon Sep 17 00:00:00 2001 From: Forrest Marshall Date: Wed, 6 Nov 2019 21:00:32 -0800 Subject: [PATCH] Implment access-request system (workflow API) --- constants.go | 3 + lib/auth/auth.go | 80 + lib/auth/auth_with_roles.go | 93 +- lib/auth/clt.go | 72 +- lib/auth/grpcserver.go | 68 + lib/auth/helpers.go | 31 + lib/auth/init.go | 3 + lib/auth/native/native.go | 7 + lib/auth/proto/auth.pb.go | 1229 ++++++++++- lib/auth/proto/auth.proto | 33 + lib/auth/tls_test.go | 93 + lib/client/api.go | 62 +- lib/client/client.go | 98 + lib/client/identity.go | 120 +- lib/defaults/defaults.go | 5 + lib/events/api.go | 11 + lib/events/codes.go | 13 + lib/services/access_request.go | 508 +++++ lib/services/access_request_test.go | 129 ++ lib/services/authority.go | 3 + lib/services/events.go | 3 + lib/services/local/dynamic_access.go | 164 ++ lib/services/local/events.go | 64 + lib/services/resource.go | 3 + lib/services/role.go | 38 +- lib/services/types.pb.go | 2197 +++++++++++++++----- lib/services/types.proto | 57 + tool/tctl/common/access_request_command.go | 171 ++ tool/tctl/common/auth_command.go | 4 +- tool/tctl/common/token_command.go | 5 +- tool/tctl/main.go | 1 + tool/tsh/tsh.go | 234 ++- 32 files changed, 4951 insertions(+), 651 deletions(-) create mode 100644 lib/services/access_request.go create mode 100644 lib/services/access_request_test.go create mode 100644 lib/services/local/dynamic_access.go create mode 100644 tool/tctl/common/access_request_command.go diff --git a/constants.go b/constants.go index b901226cace0a..250cb46c4d6ce 100644 --- a/constants.go +++ b/constants.go @@ -373,6 +373,9 @@ const ( CertExtensionTeleportRouteToCluster = "teleport-route-to-cluster" // CertExtensionTeleportTraits is used to propagate traits about the user. CertExtensionTeleportTraits = "teleport-traits" + // CertExtensionTeleportActiveRequests is used to track which privilege + // escalation requests were used to construct the certificate. + CertExtensionTeleportActiveRequests = "teleport-active-requests" ) const ( diff --git a/lib/auth/auth.go b/lib/auth/auth.go index 93ccb725e5137..fa992affa0917 100644 --- a/lib/auth/auth.go +++ b/lib/auth/auth.go @@ -77,6 +77,9 @@ func NewAuthServer(cfg *InitConfig, opts ...AuthServerOption) (*AuthServer, erro if cfg.Access == nil { cfg.Access = local.NewAccessService(cfg.Backend) } + if cfg.DynamicAccess == nil { + cfg.DynamicAccess = local.NewDynamicAccessService(cfg.Backend) + } if cfg.ClusterConfiguration == nil { cfg.ClusterConfiguration = local.NewClusterConfigurationService(cfg.Backend) } @@ -111,6 +114,7 @@ func NewAuthServer(cfg *InitConfig, opts ...AuthServerOption) (*AuthServer, erro Provisioner: cfg.Provisioner, Identity: cfg.Identity, Access: cfg.Access, + DynamicAccess: cfg.DynamicAccess, ClusterConfiguration: cfg.ClusterConfiguration, IAuditLog: cfg.AuditLog, Events: cfg.Events, @@ -132,6 +136,7 @@ type AuthServices struct { services.Provisioner services.Identity services.Access + services.DynamicAccess services.ClusterConfiguration services.Events events.IAuditLog @@ -408,6 +413,9 @@ type certRequest struct { routeToCluster string // traits hold claim data used to populate a role at runtime. traits wrappers.Traits + // activeRequests tracks privilege escalation requests applied + // during the construction of the certificate. + activeRequests services.RequestIDs } // GenerateUserTestCerts is used to generate user certificate, used internally for tests @@ -509,6 +517,7 @@ func (s *AuthServer) generateUserCert(req certRequest) (*certs, error) { PermitAgentForwarding: req.checker.CanForwardAgents(), RouteToCluster: req.routeToCluster, Traits: req.traits, + ActiveRequests: req.activeRequests, }) if err != nil { return nil, trace.Wrap(err) @@ -1350,6 +1359,77 @@ func (a *AuthServer) DeleteRole(name string) error { return a.Access.DeleteRole(name) } +func (a *AuthServer) CreateAccessRequest(req services.AccessRequest) error { + if err := services.ValidateAccessRequest(a, req); err != nil { + return trace.Wrap(err) + } + ttl, err := a.calculateMaxAccessTTL(req) + if err != nil { + return trace.Wrap(err) + } + now := a.clock.Now().UTC() + req.SetCreationTime(now) + exp := now.Add(ttl) + // Set acccess expiry if an allowable default was not provided. + if req.GetAccessExpiry().Before(now) || req.GetAccessExpiry().After(exp) { + req.SetAccessExpiry(exp) + } + // By default, resource expiry should match access expiry. + req.SetExpiry(req.GetAccessExpiry()) + // If the access-request is in a pending state, then the expiry of the underlying resource + // is capped to to PendingAccessDuration in order to limit orphaned access requests. + if req.GetState().IsPending() { + pexp := now.Add(defaults.PendingAccessDuration) + if pexp.Before(req.Expiry()) { + req.SetExpiry(pexp) + } + } + if err := a.DynamicAccess.CreateAccessRequest(req); err != nil { + return trace.Wrap(err) + } + err = a.EmitAuditEvent(events.AccessRequestCreated, events.EventFields{ + events.AccessRequestID: req.GetName(), + events.EventUser: req.GetUser(), + events.UserRoles: req.GetRoles(), + events.AccessRequestState: req.GetState().String(), + }) + return trace.Wrap(err) +} + +func (a *AuthServer) SetAccessRequestState(reqID string, state services.RequestState, updatedBy ...string) error { + if err := a.DynamicAccess.SetAccessRequestState(reqID, state); err != nil { + return trace.Wrap(err) + } + u := "unknown" + if len(updatedBy) == 1 { + u = updatedBy[0] + } + err := a.EmitAuditEvent(events.AccessRequestUpdated, events.EventFields{ + events.AccessRequestID: reqID, + events.AccessRequestState: state.String(), + events.AccessRequestUpdateBy: u, + }) + return trace.Wrap(err) +} + +// calculateMaxAccessTTL determines the maximum allowable TTL for a given access request +// based on the MaxSessionTTLs of the roles being requested (a access request's life cannot +// exceed the smallest allowable MaxSessionTTL value of the roles that it requests). +func (a *AuthServer) calculateMaxAccessTTL(req services.AccessRequest) (time.Duration, error) { + minTTL := defaults.MaxAccessDuration + for _, roleName := range req.GetRoles() { + role, err := a.GetRole(roleName) + if err != nil { + return 0, trace.Wrap(err) + } + roleTTL := time.Duration(role.GetOptions().MaxSessionTTL) + if roleTTL > 0 && roleTTL < minTTL { + minTTL = roleTTL + } + } + return minTTL, nil +} + // NewKeepAliver returns a new instance of keep aliver func (a *AuthServer) NewKeepAliver(ctx context.Context) (services.KeepAliver, error) { cancelCtx, cancel := context.WithCancel(ctx) diff --git a/lib/auth/auth_with_roles.go b/lib/auth/auth_with_roles.go index fecf7e0624442..65b95c2d35196 100644 --- a/lib/auth/auth_with_roles.go +++ b/lib/auth/auth_with_roles.go @@ -452,7 +452,16 @@ func (a *AuthWithRoles) NewWatcher(ctx context.Context, watch services.Watch) (s return nil, trace.Wrap(err) } } - + case services.KindAccessRequest: + var filter services.AccessRequestFilter + if err := filter.FromMap(kind.Filter); err != nil { + return nil, trace.Wrap(err) + } + if filter.User == "" || a.currentUserAction(filter.User) != nil { + if err := a.action(defaults.Namespace, services.KindAccessRequest, services.VerbRead); err != nil { + return nil, trace.Wrap(err) + } + } default: return nil, trace.AccessDenied("not authorized to watch %v events", kind.Kind) } @@ -778,6 +787,47 @@ func (a *AuthWithRoles) DeleteWebSession(user string, sid string) error { return a.authServer.DeleteWebSession(user, sid) } +func (a *AuthWithRoles) GetAccessRequests(filter services.AccessRequestFilter) ([]services.AccessRequest, error) { + // An exception is made to allow users to get their own access requests. + if filter.User == "" || a.currentUserAction(filter.User) != nil { + if err := a.action(defaults.Namespace, services.KindAccessRequest, services.VerbList); err != nil { + return nil, trace.Wrap(err) + } + if err := a.action(defaults.Namespace, services.KindAccessRequest, services.VerbRead); err != nil { + return nil, trace.Wrap(err) + } + } + return a.authServer.GetAccessRequests(filter) +} + +func (a *AuthWithRoles) CreateAccessRequest(req services.AccessRequest) error { + // An exception is made to allow users to create access *pending* requests for themselves. + if !req.GetState().IsPending() || a.currentUserAction(req.GetUser()) != nil { + if err := a.action(defaults.Namespace, services.KindAccessRequest, services.VerbCreate); err != nil { + return trace.Wrap(err) + } + } + // Ensure that an access request cannot outlive the identity that creates it. + if req.GetAccessExpiry().Before(a.authServer.GetClock().Now()) || req.GetAccessExpiry().After(a.identity.Expires) { + req.SetAccessExpiry(a.identity.Expires) + } + return a.authServer.CreateAccessRequest(req) +} + +func (a *AuthWithRoles) SetAccessRequestState(reqID string, state services.RequestState) error { + if err := a.action(defaults.Namespace, services.KindAccessRequest, services.VerbUpdate); err != nil { + return trace.Wrap(err) + } + return a.authServer.SetAccessRequestState(reqID, state, a.user.GetName()) +} + +func (a *AuthWithRoles) DeleteAccessRequest(name string) error { + if err := a.action(defaults.Namespace, services.KindAccessRequest, services.VerbUpdate); err != nil { + return trace.Wrap(err) + } + return a.authServer.DeleteAccessRequest(name) +} + func (a *AuthWithRoles) GetUsers(withSecrets bool) ([]services.User, error) { if withSecrets { // TODO(fspmarshall): replace admin requirement with VerbReadWithSecrets once we've @@ -908,6 +958,44 @@ func (a *AuthWithRoles) GenerateUserCerts(ctx context.Context, req proto.UserCer return nil, trace.AccessDenied("this request can be only executed by an admin") } + // TODO(fspmarshall): Move this logic to AuthServer. + if len(req.AccessRequests) > 0 { + // add any applicable access request values. + for _, reqID := range req.AccessRequests { + accessReq, err := a.authServer.GetAccessRequest(reqID) + if err != nil { + if trace.IsNotFound(err) { + return nil, trace.AccessDenied("invalid access request %q", reqID) + } + return nil, trace.Wrap(err) + } + if accessReq.GetUser() != req.Username { + return nil, trace.AccessDenied("invalid access request %q", reqID) + } + if !accessReq.GetState().IsApproved() { + if accessReq.GetState().IsDenied() { + return nil, trace.AccessDenied("access-request %q has been denied", reqID) + } + return nil, trace.AccessDenied("access-request %q is awaiting approval", reqID) + } + if err := services.ValidateAccessRequest(a.authServer, accessReq); err != nil { + return nil, trace.Wrap(err) + } + aexp := accessReq.GetAccessExpiry() + if aexp.Before(a.authServer.GetClock().Now()) { + return nil, trace.AccessDenied("access-request %q is expired", reqID) + } + if aexp.Before(req.Expires) { + // cannot generate a cert that would outlive the access request + req.Expires = aexp + } + roles = append(roles, accessReq.GetRoles()...) + } + // nothing prevents an access-request from including roles already posessed by the + // user, so we must make sure to trim duplicate roles. + roles = utils.Deduplicate(roles) + } + // Extract the user and role set for whom the certificate will be generated. user, err := a.GetUser(req.Username, false) if err != nil { @@ -929,6 +1017,9 @@ func (a *AuthWithRoles) GenerateUserCerts(ctx context.Context, req proto.UserCer routeToCluster: req.RouteToCluster, checker: checker, traits: traits, + activeRequests: services.RequestIDs{ + AccessRequests: req.AccessRequests, + }, }) if err != nil { return nil, trace.Wrap(err) diff --git a/lib/auth/clt.go b/lib/auth/clt.go index 202afeaaf7886..962f155cd29d6 100644 --- a/lib/auth/clt.go +++ b/lib/auth/clt.go @@ -123,7 +123,7 @@ func DecodeClusterName(serverName string) (string, error) { } const suffix = "." + teleport.APIDomain if !strings.HasSuffix(serverName, suffix) { - return "", trace.BadParameter("unrecognized name, expected suffix %v, got %q", teleport.APIDomain, serverName) + return "", trace.NotFound("no cluster name is encoded") } clusterName := strings.TrimSuffix(serverName, suffix) @@ -810,6 +810,7 @@ func (c *Client) NewWatcher(ctx context.Context, watch services.Watch) (services Name: kind.Name, Kind: kind.Kind, LoadSecrets: kind.LoadSecrets, + Filter: kind.Filter, }) } stream, err := clt.WatchEvents(cancelCtx, &protoWatch) @@ -2530,6 +2531,67 @@ func (c *Client) DeleteTrustedCluster(name string) error { return trace.Wrap(err) } +func (c *Client) GetAccessRequests(filter services.AccessRequestFilter) ([]services.AccessRequest, error) { + clt, err := c.grpc() + if err != nil { + return nil, trace.Wrap(err) + } + rsp, err := clt.GetAccessRequests(context.TODO(), &filter) + if err != nil { + return nil, trail.FromGRPC(err) + } + reqs := make([]services.AccessRequest, 0, len(rsp.AccessRequests)) + for _, req := range rsp.AccessRequests { + reqs = append(reqs, req) + } + return reqs, nil +} + +func (c *Client) CreateAccessRequest(req services.AccessRequest) error { + r, ok := req.(*services.AccessRequestV3) + if !ok { + return trace.BadParameter("unexpected access request type %T", req) + } + clt, err := c.grpc() + if err != nil { + return trace.Wrap(err) + } + _, err = clt.CreateAccessRequest(context.TODO(), r) + if err != nil { + return trail.FromGRPC(err) + } + return nil +} + +func (c *Client) DeleteAccessRequest(reqID string) error { + clt, err := c.grpc() + if err != nil { + return trace.Wrap(err) + } + _, err = clt.DeleteAccessRequest(context.TODO(), &proto.RequestID{ + ID: reqID, + }) + if err != nil { + return trail.FromGRPC(err) + } + return nil +} + +func (c *Client) SetAccessRequestState(reqID string, state services.RequestState) error { + clt, err := c.grpc() + if err != nil { + return trace.Wrap(err) + } + _, err = clt.SetAccessRequestState(context.TODO(), &proto.RequestStateSetter{ + ID: reqID, + State: state, + }) + if err != nil { + return trail.FromGRPC(err) + } + return nil +} + // WebService implements features used by Web UI clients type WebService interface { // GetWebSessionInfo checks if a web sesion is valid, returns session id in case if @@ -2750,4 +2812,12 @@ type ClientI interface { // ProcessKubeCSR processes CSR request against Kubernetes CA, returns // signed certificate if sucessful. ProcessKubeCSR(req KubeCSR) (*KubeCSRResponse, error) + // GetAccessRequests lists all existing access requests. + GetAccessRequests(services.AccessRequestFilter) ([]services.AccessRequest, error) + // CreateAccessRequest creates a new access request. + CreateAccessRequest(req services.AccessRequest) error + // DeleteAccessRequest deletes an access request. + DeleteAccessRequest(reqID string) error + // SetAccessRequestState updates the state of an existing access request. + SetAccessRequestState(reqID string, state services.RequestState) error } diff --git a/lib/auth/grpcserver.go b/lib/auth/grpcserver.go index a47967faa1477..e3990823a12d3 100644 --- a/lib/auth/grpcserver.go +++ b/lib/auth/grpcserver.go @@ -85,6 +85,7 @@ func (g *GRPCServer) WatchEvents(watch *proto.Watch, stream proto.AuthService_Wa Name: kind.Name, Kind: kind.Kind, LoadSecrets: kind.LoadSecrets, + Filter: kind.Filter, }) } watcher, err := auth.NewWatcher(stream.Context(), servicesWatch) @@ -185,6 +186,66 @@ func (g *GRPCServer) GetUsers(req *proto.GetUsersRequest, stream proto.AuthServi return nil } +func (g *GRPCServer) GetAccessRequests(ctx context.Context, f *services.AccessRequestFilter) (*proto.AccessRequests, error) { + auth, err := g.authenticate(ctx) + if err != nil { + return nil, trail.ToGRPC(err) + } + var filter services.AccessRequestFilter + if f != nil { + filter = *f + } + reqs, err := auth.AuthWithRoles.GetAccessRequests(filter) + if err != nil { + return nil, trail.ToGRPC(err) + } + collector := make([]*services.AccessRequestV3, 0, len(reqs)) + for _, req := range reqs { + r, ok := req.(*services.AccessRequestV3) + if !ok { + err = trace.BadParameter("unexpected access request type %T", req) + return nil, trail.ToGRPC(err) + } + collector = append(collector, r) + } + return &proto.AccessRequests{ + AccessRequests: collector, + }, nil +} + +func (g *GRPCServer) CreateAccessRequest(ctx context.Context, req *services.AccessRequestV3) (*empty.Empty, error) { + auth, err := g.authenticate(ctx) + if err != nil { + return nil, trail.ToGRPC(err) + } + if err := auth.AuthWithRoles.CreateAccessRequest(req); err != nil { + return nil, trail.ToGRPC(err) + } + return &empty.Empty{}, nil +} + +func (g *GRPCServer) DeleteAccessRequest(ctx context.Context, id *proto.RequestID) (*empty.Empty, error) { + auth, err := g.authenticate(ctx) + if err != nil { + return nil, trail.ToGRPC(err) + } + if err := auth.AuthWithRoles.DeleteAccessRequest(id.ID); err != nil { + return nil, trail.ToGRPC(err) + } + return &empty.Empty{}, nil +} + +func (g *GRPCServer) SetAccessRequestState(ctx context.Context, req *proto.RequestStateSetter) (*empty.Empty, error) { + auth, err := g.authenticate(ctx) + if err != nil { + return nil, trail.ToGRPC(err) + } + if err := auth.SetAccessRequestState(req.ID, req.State); err != nil { + return nil, trail.ToGRPC(err) + } + return &empty.Empty{}, nil +} + type grpcContext struct { *AuthContext *AuthWithRoles @@ -305,6 +366,10 @@ func eventToGRPC(in services.Event) (*proto.Event, error) { out.Resource = &proto.Event_TunnelConnection{ TunnelConnection: r, } + case *services.AccessRequestV3: + out.Resource = &proto.Event_AccessRequest{ + AccessRequest: r, + } default: return nil, trace.BadParameter("resource type %T is not supported", in.Resource) } @@ -371,6 +436,9 @@ func eventFromGRPC(in proto.Event) (*services.Event, error) { } else if r := in.GetTunnelConnection(); r != nil { out.Resource = r return &out, nil + } else if r := in.GetAccessRequest(); r != nil { + out.Resource = r + return &out, nil } else { return nil, trace.BadParameter("received unsupported resource %T", in.Resource) } diff --git a/lib/auth/helpers.go b/lib/auth/helpers.go index 4a2a326c6b30e..8c1965130bac8 100644 --- a/lib/auth/helpers.go +++ b/lib/auth/helpers.go @@ -641,6 +641,37 @@ type clt interface { UpsertUser(services.User) error } +// CreateUserRoleAndRequestable creates two roles for a user, one base role with allowed login +// matching username, and another role with a login matching rolename that can be requested. +func CreateUserRoleAndRequestable(clt clt, username string, rolename string) (services.User, error) { + user, err := services.NewUser(username) + if err != nil { + return nil, trace.Wrap(err) + } + baseRole := services.RoleForUser(user) + baseRole.SetLogins(services.Allow, []string{username}) + baseRole.SetAccessRequestConditions(services.Allow, services.AccessRequestConditions{ + Roles: []string{rolename}, + }) + err = clt.UpsertRole(baseRole) + if err != nil { + return nil, trace.Wrap(err) + } + user.AddRole(baseRole.GetName()) + err = clt.UpsertUser(user) + if err != nil { + return nil, trace.Wrap(err) + } + requestableRole := services.RoleForUser(user) + requestableRole.SetName(rolename) + requestableRole.SetLogins(services.Allow, []string{rolename}) + err = clt.UpsertRole(requestableRole) + if err != nil { + return nil, trace.Wrap(err) + } + return user, nil +} + // CreateUserAndRole creates user and role and assignes role to a user, used in tests func CreateUserAndRole(clt clt, username string, allowedLogins []string) (services.User, services.Role, error) { user, err := services.NewUser(username) diff --git a/lib/auth/init.go b/lib/auth/init.go index 2e7e4d084939b..453704260806a 100644 --- a/lib/auth/init.go +++ b/lib/auth/init.go @@ -105,6 +105,9 @@ type InitConfig struct { // Access is service controlling access to resources Access services.Access + // DynamicAccess is a service that manages dynamic RBAC. + DynamicAccess services.DynamicAccess + // Events is an event service Events services.Events diff --git a/lib/auth/native/native.go b/lib/auth/native/native.go index 726a0425c82d8..7a0d740577310 100644 --- a/lib/auth/native/native.go +++ b/lib/auth/native/native.go @@ -291,6 +291,13 @@ func (k *Keygen) GenerateUserCert(c services.UserCertParams) ([]byte, error) { if c.RouteToCluster != "" { cert.Permissions.Extensions[teleport.CertExtensionTeleportRouteToCluster] = c.RouteToCluster } + if !c.ActiveRequests.IsEmpty() { + requests, err := c.ActiveRequests.Marshal() + if err != nil { + return nil, trace.Wrap(err) + } + cert.Permissions.Extensions[teleport.CertExtensionTeleportActiveRequests] = string(requests) + } } signer, err := ssh.ParsePrivateKey(c.PrivateCASigningKey) diff --git a/lib/auth/proto/auth.pb.go b/lib/auth/proto/auth.pb.go index deab35c8d59a8..3795b65df52b4 100644 --- a/lib/auth/proto/auth.pb.go +++ b/lib/auth/proto/auth.pb.go @@ -60,7 +60,7 @@ func (x Operation) String() string { return proto.EnumName(Operation_name, int32(x)) } func (Operation) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_auth_7c0b95a1fa9bddec, []int{0} + return fileDescriptor_auth_3713a8b32977094f, []int{0} } // Event returns cluster event @@ -82,6 +82,7 @@ type Event struct { // *Event_Server // *Event_ReverseTunnel // *Event_TunnelConnection + // *Event_AccessRequest Resource isEvent_Resource `protobuf_oneof:"Resource"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` @@ -92,7 +93,7 @@ func (m *Event) Reset() { *m = Event{} } func (m *Event) String() string { return proto.CompactTextString(m) } func (*Event) ProtoMessage() {} func (*Event) Descriptor() ([]byte, []int) { - return fileDescriptor_auth_7c0b95a1fa9bddec, []int{0} + return fileDescriptor_auth_3713a8b32977094f, []int{0} } func (m *Event) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -163,6 +164,9 @@ type Event_ReverseTunnel struct { type Event_TunnelConnection struct { TunnelConnection *services.TunnelConnectionV2 `protobuf:"bytes,13,opt,name=TunnelConnection,oneof"` } +type Event_AccessRequest struct { + AccessRequest *services.AccessRequestV3 `protobuf:"bytes,14,opt,name=AccessRequest,oneof"` +} func (*Event_ResourceHeader) isEvent_Resource() {} func (*Event_CertAuthority) isEvent_Resource() {} @@ -176,6 +180,7 @@ func (*Event_Namespace) isEvent_Resource() {} func (*Event_Server) isEvent_Resource() {} func (*Event_ReverseTunnel) isEvent_Resource() {} func (*Event_TunnelConnection) isEvent_Resource() {} +func (*Event_AccessRequest) isEvent_Resource() {} func (m *Event) GetResource() isEvent_Resource { if m != nil { @@ -275,6 +280,13 @@ func (m *Event) GetTunnelConnection() *services.TunnelConnectionV2 { return nil } +func (m *Event) GetAccessRequest() *services.AccessRequestV3 { + if x, ok := m.GetResource().(*Event_AccessRequest); ok { + return x.AccessRequest + } + return nil +} + // XXX_OneofFuncs is for the internal use of the proto package. func (*Event) XXX_OneofFuncs() (func(msg proto.Message, b *proto.Buffer) error, func(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error), func(msg proto.Message) (n int), []interface{}) { return _Event_OneofMarshaler, _Event_OneofUnmarshaler, _Event_OneofSizer, []interface{}{ @@ -290,6 +302,7 @@ func (*Event) XXX_OneofFuncs() (func(msg proto.Message, b *proto.Buffer) error, (*Event_Server)(nil), (*Event_ReverseTunnel)(nil), (*Event_TunnelConnection)(nil), + (*Event_AccessRequest)(nil), } } @@ -357,6 +370,11 @@ func _Event_OneofMarshaler(msg proto.Message, b *proto.Buffer) error { if err := b.EncodeMessage(x.TunnelConnection); err != nil { return err } + case *Event_AccessRequest: + _ = b.EncodeVarint(14<<3 | proto.WireBytes) + if err := b.EncodeMessage(x.AccessRequest); err != nil { + return err + } case nil: default: return fmt.Errorf("Event.Resource has unexpected type %T", x) @@ -463,6 +481,14 @@ func _Event_OneofUnmarshaler(msg proto.Message, tag, wire int, b *proto.Buffer) err := b.DecodeMessage(msg) m.Resource = &Event_TunnelConnection{msg} return true, err + case 14: // Resource.AccessRequest + if wire != proto.WireBytes { + return true, proto.ErrInternalBadWireType + } + msg := new(services.AccessRequestV3) + err := b.DecodeMessage(msg) + m.Resource = &Event_AccessRequest{msg} + return true, err default: return false, nil } @@ -532,6 +558,11 @@ func _Event_OneofSizer(msg proto.Message) (n int) { n += 1 // tag and wire n += proto.SizeVarint(uint64(s)) n += s + case *Event_AccessRequest: + s := proto.Size(x.AccessRequest) + n += 1 // tag and wire + n += proto.SizeVarint(uint64(s)) + n += s case nil: default: panic(fmt.Sprintf("proto: unexpected type %T in oneof", x)) @@ -552,7 +583,7 @@ func (m *Watch) Reset() { *m = Watch{} } func (m *Watch) String() string { return proto.CompactTextString(m) } func (*Watch) ProtoMessage() {} func (*Watch) Descriptor() ([]byte, []int) { - return fileDescriptor_auth_7c0b95a1fa9bddec, []int{1} + return fileDescriptor_auth_3713a8b32977094f, []int{1} } func (m *Watch) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -597,17 +628,20 @@ type WatchKind struct { // Name is an optional specific resource type to watch, // if specified only the events with a specific resource // name will be sent - Name string `protobuf:"bytes,3,opt,name=Name,proto3" json:"name"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + Name string `protobuf:"bytes,3,opt,name=Name,proto3" json:"name"` + // Filter is an optional mapping of custom filter parameters. + // Valid values vary by resource kind. + Filter map[string]string `protobuf:"bytes,4,rep,name=Filter" json:"filter,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } func (m *WatchKind) Reset() { *m = WatchKind{} } func (m *WatchKind) String() string { return proto.CompactTextString(m) } func (*WatchKind) ProtoMessage() {} func (*WatchKind) Descriptor() ([]byte, []int) { - return fileDescriptor_auth_7c0b95a1fa9bddec, []int{2} + return fileDescriptor_auth_3713a8b32977094f, []int{2} } func (m *WatchKind) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -657,6 +691,13 @@ func (m *WatchKind) GetName() string { return "" } +func (m *WatchKind) GetFilter() map[string]string { + if m != nil { + return m.Filter + } + return nil +} + // Set of certificates corresponding to a single public key. type Certs struct { // SSH X509 cert (PEM-encoded). @@ -672,7 +713,7 @@ func (m *Certs) Reset() { *m = Certs{} } func (m *Certs) String() string { return proto.CompactTextString(m) } func (*Certs) ProtoMessage() {} func (*Certs) Descriptor() ([]byte, []int) { - return fileDescriptor_auth_7c0b95a1fa9bddec, []int{3} + return fileDescriptor_auth_3713a8b32977094f, []int{3} } func (m *Certs) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -732,7 +773,10 @@ type UserCertsRequest struct { // RouteToCluster is an optional cluster name to add to the certificate, // so that requests originating with this certificate will be redirected // to this cluster - RouteToCluster string `protobuf:"bytes,5,opt,name=RouteToCluster,proto3" json:"route_to_cluster,omitempty"` + RouteToCluster string `protobuf:"bytes,5,opt,name=RouteToCluster,proto3" json:"route_to_cluster,omitempty"` + // AccessRequests is an optional list of request IDs indicating requests whose + // escalated privileges should be added to the certificate. + AccessRequests []string `protobuf:"bytes,6,rep,name=AccessRequests" json:"access_requests,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` @@ -742,7 +786,7 @@ func (m *UserCertsRequest) Reset() { *m = UserCertsRequest{} } func (m *UserCertsRequest) String() string { return proto.CompactTextString(m) } func (*UserCertsRequest) ProtoMessage() {} func (*UserCertsRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_auth_7c0b95a1fa9bddec, []int{4} + return fileDescriptor_auth_3713a8b32977094f, []int{4} } func (m *UserCertsRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -806,6 +850,13 @@ func (m *UserCertsRequest) GetRouteToCluster() string { return "" } +func (m *UserCertsRequest) GetAccessRequests() []string { + if m != nil { + return m.AccessRequests + } + return nil +} + // GetUserRequest specifies paramters for the GetUser method. type GetUserRequest struct { // Name is the name of the desired user. @@ -821,7 +872,7 @@ func (m *GetUserRequest) Reset() { *m = GetUserRequest{} } func (m *GetUserRequest) String() string { return proto.CompactTextString(m) } func (*GetUserRequest) ProtoMessage() {} func (*GetUserRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_auth_7c0b95a1fa9bddec, []int{5} + return fileDescriptor_auth_3713a8b32977094f, []int{5} } func (m *GetUserRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -877,7 +928,7 @@ func (m *GetUsersRequest) Reset() { *m = GetUsersRequest{} } func (m *GetUsersRequest) String() string { return proto.CompactTextString(m) } func (*GetUsersRequest) ProtoMessage() {} func (*GetUsersRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_auth_7c0b95a1fa9bddec, []int{6} + return fileDescriptor_auth_3713a8b32977094f, []int{6} } func (m *GetUsersRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -913,14 +964,171 @@ func (m *GetUsersRequest) GetWithSecrets() bool { return false } +// AccessRequests is a collection of AccessRequest values. +type AccessRequests struct { + AccessRequests []*services.AccessRequestV3 `protobuf:"bytes,1,rep,name=AccessRequests" json:"access_requests"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *AccessRequests) Reset() { *m = AccessRequests{} } +func (m *AccessRequests) String() string { return proto.CompactTextString(m) } +func (*AccessRequests) ProtoMessage() {} +func (*AccessRequests) Descriptor() ([]byte, []int) { + return fileDescriptor_auth_3713a8b32977094f, []int{7} +} +func (m *AccessRequests) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *AccessRequests) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_AccessRequests.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalTo(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (dst *AccessRequests) XXX_Merge(src proto.Message) { + xxx_messageInfo_AccessRequests.Merge(dst, src) +} +func (m *AccessRequests) XXX_Size() int { + return m.Size() +} +func (m *AccessRequests) XXX_DiscardUnknown() { + xxx_messageInfo_AccessRequests.DiscardUnknown(m) +} + +var xxx_messageInfo_AccessRequests proto.InternalMessageInfo + +func (m *AccessRequests) GetAccessRequests() []*services.AccessRequestV3 { + if m != nil { + return m.AccessRequests + } + return nil +} + +// RequestStateSetter encodes the paramters necessary to update the +// state of a privilege escalation request. +type RequestStateSetter struct { + ID string `protobuf:"bytes,1,opt,name=ID,proto3" json:"id"` + State services.RequestState `protobuf:"varint,2,opt,name=State,proto3,enum=services.RequestState" json:"state"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *RequestStateSetter) Reset() { *m = RequestStateSetter{} } +func (m *RequestStateSetter) String() string { return proto.CompactTextString(m) } +func (*RequestStateSetter) ProtoMessage() {} +func (*RequestStateSetter) Descriptor() ([]byte, []int) { + return fileDescriptor_auth_3713a8b32977094f, []int{8} +} +func (m *RequestStateSetter) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *RequestStateSetter) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_RequestStateSetter.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalTo(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (dst *RequestStateSetter) XXX_Merge(src proto.Message) { + xxx_messageInfo_RequestStateSetter.Merge(dst, src) +} +func (m *RequestStateSetter) XXX_Size() int { + return m.Size() +} +func (m *RequestStateSetter) XXX_DiscardUnknown() { + xxx_messageInfo_RequestStateSetter.DiscardUnknown(m) +} + +var xxx_messageInfo_RequestStateSetter proto.InternalMessageInfo + +func (m *RequestStateSetter) GetID() string { + if m != nil { + return m.ID + } + return "" +} + +func (m *RequestStateSetter) GetState() services.RequestState { + if m != nil { + return m.State + } + return services.RequestState_NONE +} + +// RequestID is the unique identifier of an access request. +type RequestID struct { + ID string `protobuf:"bytes,1,opt,name=ID,proto3" json:"id"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *RequestID) Reset() { *m = RequestID{} } +func (m *RequestID) String() string { return proto.CompactTextString(m) } +func (*RequestID) ProtoMessage() {} +func (*RequestID) Descriptor() ([]byte, []int) { + return fileDescriptor_auth_3713a8b32977094f, []int{9} +} +func (m *RequestID) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *RequestID) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_RequestID.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalTo(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (dst *RequestID) XXX_Merge(src proto.Message) { + xxx_messageInfo_RequestID.Merge(dst, src) +} +func (m *RequestID) XXX_Size() int { + return m.Size() +} +func (m *RequestID) XXX_DiscardUnknown() { + xxx_messageInfo_RequestID.DiscardUnknown(m) +} + +var xxx_messageInfo_RequestID proto.InternalMessageInfo + +func (m *RequestID) GetID() string { + if m != nil { + return m.ID + } + return "" +} + func init() { proto.RegisterType((*Event)(nil), "proto.Event") proto.RegisterType((*Watch)(nil), "proto.Watch") proto.RegisterType((*WatchKind)(nil), "proto.WatchKind") + proto.RegisterMapType((map[string]string)(nil), "proto.WatchKind.FilterEntry") proto.RegisterType((*Certs)(nil), "proto.Certs") proto.RegisterType((*UserCertsRequest)(nil), "proto.UserCertsRequest") proto.RegisterType((*GetUserRequest)(nil), "proto.GetUserRequest") proto.RegisterType((*GetUsersRequest)(nil), "proto.GetUsersRequest") + proto.RegisterType((*AccessRequests)(nil), "proto.AccessRequests") + proto.RegisterType((*RequestStateSetter)(nil), "proto.RequestStateSetter") + proto.RegisterType((*RequestID)(nil), "proto.RequestID") proto.RegisterEnum("proto.Operation", Operation_name, Operation_value) } @@ -947,6 +1155,14 @@ type AuthServiceClient interface { GetUser(ctx context.Context, in *GetUserRequest, opts ...grpc.CallOption) (*services.UserV2, error) // GetUsers gets all current user resources. GetUsers(ctx context.Context, in *GetUsersRequest, opts ...grpc.CallOption) (AuthService_GetUsersClient, error) + // GetAccessRequests gets all pending access requests. + GetAccessRequests(ctx context.Context, in *services.AccessRequestFilter, opts ...grpc.CallOption) (*AccessRequests, error) + // CreateAccessRequest creates a new access request. + CreateAccessRequest(ctx context.Context, in *services.AccessRequestV3, opts ...grpc.CallOption) (*empty.Empty, error) + // DeleteAccessRequest deletes an access request. + DeleteAccessRequest(ctx context.Context, in *RequestID, opts ...grpc.CallOption) (*empty.Empty, error) + // SetAccessRequestState sets the state of an access request. + SetAccessRequestState(ctx context.Context, in *RequestStateSetter, opts ...grpc.CallOption) (*empty.Empty, error) } type authServiceClient struct { @@ -1082,6 +1298,42 @@ func (x *authServiceGetUsersClient) Recv() (*services.UserV2, error) { return m, nil } +func (c *authServiceClient) GetAccessRequests(ctx context.Context, in *services.AccessRequestFilter, opts ...grpc.CallOption) (*AccessRequests, error) { + out := new(AccessRequests) + err := c.cc.Invoke(ctx, "/proto.AuthService/GetAccessRequests", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *authServiceClient) CreateAccessRequest(ctx context.Context, in *services.AccessRequestV3, opts ...grpc.CallOption) (*empty.Empty, error) { + out := new(empty.Empty) + err := c.cc.Invoke(ctx, "/proto.AuthService/CreateAccessRequest", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *authServiceClient) DeleteAccessRequest(ctx context.Context, in *RequestID, opts ...grpc.CallOption) (*empty.Empty, error) { + out := new(empty.Empty) + err := c.cc.Invoke(ctx, "/proto.AuthService/DeleteAccessRequest", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *authServiceClient) SetAccessRequestState(ctx context.Context, in *RequestStateSetter, opts ...grpc.CallOption) (*empty.Empty, error) { + out := new(empty.Empty) + err := c.cc.Invoke(ctx, "/proto.AuthService/SetAccessRequestState", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + // Server API for AuthService service type AuthServiceServer interface { @@ -1097,6 +1349,14 @@ type AuthServiceServer interface { GetUser(context.Context, *GetUserRequest) (*services.UserV2, error) // GetUsers gets all current user resources. GetUsers(*GetUsersRequest, AuthService_GetUsersServer) error + // GetAccessRequests gets all pending access requests. + GetAccessRequests(context.Context, *services.AccessRequestFilter) (*AccessRequests, error) + // CreateAccessRequest creates a new access request. + CreateAccessRequest(context.Context, *services.AccessRequestV3) (*empty.Empty, error) + // DeleteAccessRequest deletes an access request. + DeleteAccessRequest(context.Context, *RequestID) (*empty.Empty, error) + // SetAccessRequestState sets the state of an access request. + SetAccessRequestState(context.Context, *RequestStateSetter) (*empty.Empty, error) } func RegisterAuthServiceServer(s *grpc.Server, srv AuthServiceServer) { @@ -1225,6 +1485,78 @@ func (x *authServiceGetUsersServer) Send(m *services.UserV2) error { return x.ServerStream.SendMsg(m) } +func _AuthService_GetAccessRequests_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(services.AccessRequestFilter) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AuthServiceServer).GetAccessRequests(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/proto.AuthService/GetAccessRequests", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AuthServiceServer).GetAccessRequests(ctx, req.(*services.AccessRequestFilter)) + } + return interceptor(ctx, in, info, handler) +} + +func _AuthService_CreateAccessRequest_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(services.AccessRequestV3) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AuthServiceServer).CreateAccessRequest(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/proto.AuthService/CreateAccessRequest", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AuthServiceServer).CreateAccessRequest(ctx, req.(*services.AccessRequestV3)) + } + return interceptor(ctx, in, info, handler) +} + +func _AuthService_DeleteAccessRequest_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(RequestID) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AuthServiceServer).DeleteAccessRequest(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/proto.AuthService/DeleteAccessRequest", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AuthServiceServer).DeleteAccessRequest(ctx, req.(*RequestID)) + } + return interceptor(ctx, in, info, handler) +} + +func _AuthService_SetAccessRequestState_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(RequestStateSetter) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AuthServiceServer).SetAccessRequestState(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/proto.AuthService/SetAccessRequestState", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AuthServiceServer).SetAccessRequestState(ctx, req.(*RequestStateSetter)) + } + return interceptor(ctx, in, info, handler) +} + var _AuthService_serviceDesc = grpc.ServiceDesc{ ServiceName: "proto.AuthService", HandlerType: (*AuthServiceServer)(nil), @@ -1241,6 +1573,22 @@ var _AuthService_serviceDesc = grpc.ServiceDesc{ MethodName: "GetUser", Handler: _AuthService_GetUser_Handler, }, + { + MethodName: "GetAccessRequests", + Handler: _AuthService_GetAccessRequests_Handler, + }, + { + MethodName: "CreateAccessRequest", + Handler: _AuthService_CreateAccessRequest_Handler, + }, + { + MethodName: "DeleteAccessRequest", + Handler: _AuthService_DeleteAccessRequest_Handler, + }, + { + MethodName: "SetAccessRequestState", + Handler: _AuthService_SetAccessRequestState_Handler, + }, }, Streams: []grpc.StreamDesc{ { @@ -1463,6 +1811,20 @@ func (m *Event_TunnelConnection) MarshalTo(dAtA []byte) (int, error) { } return i, nil } +func (m *Event_AccessRequest) MarshalTo(dAtA []byte) (int, error) { + i := 0 + if m.AccessRequest != nil { + dAtA[i] = 0x72 + i++ + i = encodeVarintAuth(dAtA, i, uint64(m.AccessRequest.Size())) + n14, err := m.AccessRequest.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n14 + } + return i, nil +} func (m *Watch) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -1533,6 +1895,23 @@ func (m *WatchKind) MarshalTo(dAtA []byte) (int, error) { i = encodeVarintAuth(dAtA, i, uint64(len(m.Name))) i += copy(dAtA[i:], m.Name) } + if len(m.Filter) > 0 { + for k, _ := range m.Filter { + dAtA[i] = 0x22 + i++ + v := m.Filter[k] + mapSize := 1 + len(k) + sovAuth(uint64(len(k))) + 1 + len(v) + sovAuth(uint64(len(v))) + i = encodeVarintAuth(dAtA, i, uint64(mapSize)) + dAtA[i] = 0xa + i++ + i = encodeVarintAuth(dAtA, i, uint64(len(k))) + i += copy(dAtA[i:], k) + dAtA[i] = 0x12 + i++ + i = encodeVarintAuth(dAtA, i, uint64(len(v))) + i += copy(dAtA[i:], v) + } + } if m.XXX_unrecognized != nil { i += copy(dAtA[i:], m.XXX_unrecognized) } @@ -1602,11 +1981,11 @@ func (m *UserCertsRequest) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x1a i++ i = encodeVarintAuth(dAtA, i, uint64(github_com_gogo_protobuf_types.SizeOfStdTime(m.Expires))) - n14, err := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Expires, dAtA[i:]) + n15, err := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Expires, dAtA[i:]) if err != nil { return 0, err } - i += n14 + i += n15 if len(m.Format) > 0 { dAtA[i] = 0x22 i++ @@ -1619,6 +1998,21 @@ func (m *UserCertsRequest) MarshalTo(dAtA []byte) (int, error) { i = encodeVarintAuth(dAtA, i, uint64(len(m.RouteToCluster))) i += copy(dAtA[i:], m.RouteToCluster) } + if len(m.AccessRequests) > 0 { + for _, s := range m.AccessRequests { + dAtA[i] = 0x32 + i++ + l = len(s) + for l >= 1<<7 { + dAtA[i] = uint8(uint64(l)&0x7f | 0x80) + l >>= 7 + i++ + } + dAtA[i] = uint8(l) + i++ + i += copy(dAtA[i:], s) + } + } if m.XXX_unrecognized != nil { i += copy(dAtA[i:], m.XXX_unrecognized) } @@ -1693,35 +2087,127 @@ func (m *GetUsersRequest) MarshalTo(dAtA []byte) (int, error) { return i, nil } -func encodeVarintAuth(dAtA []byte, offset int, v uint64) int { - for v >= 1<<7 { - dAtA[offset] = uint8(v&0x7f | 0x80) - v >>= 7 - offset++ +func (m *AccessRequests) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err } - dAtA[offset] = uint8(v) - return offset + 1 + return dAtA[:n], nil } -func (m *Event) Size() (n int) { + +func (m *AccessRequests) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i var l int _ = l - if m.Type != 0 { - n += 1 + sovAuth(uint64(m.Type)) - } - if m.Resource != nil { - n += m.Resource.Size() + if len(m.AccessRequests) > 0 { + for _, msg := range m.AccessRequests { + dAtA[i] = 0xa + i++ + i = encodeVarintAuth(dAtA, i, uint64(msg.Size())) + n, err := msg.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n + } } if m.XXX_unrecognized != nil { - n += len(m.XXX_unrecognized) + i += copy(dAtA[i:], m.XXX_unrecognized) } - return n + return i, nil } -func (m *Event_ResourceHeader) Size() (n int) { - var l int - _ = l - if m.ResourceHeader != nil { - l = m.ResourceHeader.Size() +func (m *RequestStateSetter) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *RequestStateSetter) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if len(m.ID) > 0 { + dAtA[i] = 0xa + i++ + i = encodeVarintAuth(dAtA, i, uint64(len(m.ID))) + i += copy(dAtA[i:], m.ID) + } + if m.State != 0 { + dAtA[i] = 0x10 + i++ + i = encodeVarintAuth(dAtA, i, uint64(m.State)) + } + if m.XXX_unrecognized != nil { + i += copy(dAtA[i:], m.XXX_unrecognized) + } + return i, nil +} + +func (m *RequestID) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *RequestID) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if len(m.ID) > 0 { + dAtA[i] = 0xa + i++ + i = encodeVarintAuth(dAtA, i, uint64(len(m.ID))) + i += copy(dAtA[i:], m.ID) + } + if m.XXX_unrecognized != nil { + i += copy(dAtA[i:], m.XXX_unrecognized) + } + return i, nil +} + +func encodeVarintAuth(dAtA []byte, offset int, v uint64) int { + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return offset + 1 +} +func (m *Event) Size() (n int) { + var l int + _ = l + if m.Type != 0 { + n += 1 + sovAuth(uint64(m.Type)) + } + if m.Resource != nil { + n += m.Resource.Size() + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *Event_ResourceHeader) Size() (n int) { + var l int + _ = l + if m.ResourceHeader != nil { + l = m.ResourceHeader.Size() n += 1 + l + sovAuth(uint64(l)) } return n @@ -1825,6 +2311,15 @@ func (m *Event_TunnelConnection) Size() (n int) { } return n } +func (m *Event_AccessRequest) Size() (n int) { + var l int + _ = l + if m.AccessRequest != nil { + l = m.AccessRequest.Size() + n += 1 + l + sovAuth(uint64(l)) + } + return n +} func (m *Watch) Size() (n int) { var l int _ = l @@ -1854,6 +2349,14 @@ func (m *WatchKind) Size() (n int) { if l > 0 { n += 1 + l + sovAuth(uint64(l)) } + if len(m.Filter) > 0 { + for k, v := range m.Filter { + _ = k + _ = v + mapEntrySize := 1 + len(k) + sovAuth(uint64(len(k))) + 1 + len(v) + sovAuth(uint64(len(v))) + n += mapEntrySize + 1 + sovAuth(uint64(mapEntrySize)) + } + } if m.XXX_unrecognized != nil { n += len(m.XXX_unrecognized) } @@ -1898,6 +2401,12 @@ func (m *UserCertsRequest) Size() (n int) { if l > 0 { n += 1 + l + sovAuth(uint64(l)) } + if len(m.AccessRequests) > 0 { + for _, s := range m.AccessRequests { + l = len(s) + n += 1 + l + sovAuth(uint64(l)) + } + } if m.XXX_unrecognized != nil { n += len(m.XXX_unrecognized) } @@ -1932,6 +2441,50 @@ func (m *GetUsersRequest) Size() (n int) { return n } +func (m *AccessRequests) Size() (n int) { + var l int + _ = l + if len(m.AccessRequests) > 0 { + for _, e := range m.AccessRequests { + l = e.Size() + n += 1 + l + sovAuth(uint64(l)) + } + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *RequestStateSetter) Size() (n int) { + var l int + _ = l + l = len(m.ID) + if l > 0 { + n += 1 + l + sovAuth(uint64(l)) + } + if m.State != 0 { + n += 1 + sovAuth(uint64(m.State)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *RequestID) Size() (n int) { + var l int + _ = l + l = len(m.ID) + if l > 0 { + n += 1 + l + sovAuth(uint64(l)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + func sovAuth(x uint64) (n int) { for { n++ @@ -2377,6 +2930,38 @@ func (m *Event) Unmarshal(dAtA []byte) error { } m.Resource = &Event_TunnelConnection{v} iNdEx = postIndex + case 14: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field AccessRequest", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuth + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthAuth + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + v := &services.AccessRequestV3{} + if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + m.Resource = &Event_AccessRequest{v} + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipAuth(dAtA[iNdEx:]) @@ -2588,6 +3173,124 @@ func (m *WatchKind) Unmarshal(dAtA []byte) error { } m.Name = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Filter", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuth + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthAuth + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Filter == nil { + m.Filter = make(map[string]string) + } + var mapkey string + var mapvalue string + for iNdEx < postIndex { + entryPreIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuth + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + if fieldNum == 1 { + var stringLenmapkey uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuth + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLenmapkey |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLenmapkey := int(stringLenmapkey) + if intStringLenmapkey < 0 { + return ErrInvalidLengthAuth + } + postStringIndexmapkey := iNdEx + intStringLenmapkey + if postStringIndexmapkey > l { + return io.ErrUnexpectedEOF + } + mapkey = string(dAtA[iNdEx:postStringIndexmapkey]) + iNdEx = postStringIndexmapkey + } else if fieldNum == 2 { + var stringLenmapvalue uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuth + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLenmapvalue |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLenmapvalue := int(stringLenmapvalue) + if intStringLenmapvalue < 0 { + return ErrInvalidLengthAuth + } + postStringIndexmapvalue := iNdEx + intStringLenmapvalue + if postStringIndexmapvalue > l { + return io.ErrUnexpectedEOF + } + mapvalue = string(dAtA[iNdEx:postStringIndexmapvalue]) + iNdEx = postStringIndexmapvalue + } else { + iNdEx = entryPreIndex + skippy, err := skipAuth(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthAuth + } + if (iNdEx + skippy) > postIndex { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + m.Filter[mapkey] = mapvalue + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipAuth(dAtA[iNdEx:]) @@ -2900,6 +3603,35 @@ func (m *UserCertsRequest) Unmarshal(dAtA []byte) error { } m.RouteToCluster = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex + case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field AccessRequests", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuth + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthAuth + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.AccessRequests = append(m.AccessRequests, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipAuth(dAtA[iNdEx:]) @@ -3093,6 +3825,267 @@ func (m *GetUsersRequest) Unmarshal(dAtA []byte) error { } return nil } +func (m *AccessRequests) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuth + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: AccessRequests: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: AccessRequests: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field AccessRequests", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuth + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthAuth + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.AccessRequests = append(m.AccessRequests, &services.AccessRequestV3{}) + if err := m.AccessRequests[len(m.AccessRequests)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipAuth(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthAuth + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *RequestStateSetter) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuth + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: RequestStateSetter: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: RequestStateSetter: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ID", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuth + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthAuth + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ID = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field State", wireType) + } + m.State = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuth + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.State |= (services.RequestState(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipAuth(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthAuth + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *RequestID) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuth + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: RequestID: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: RequestID: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ID", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuth + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthAuth + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ID = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipAuth(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthAuth + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func skipAuth(dAtA []byte) (n int, err error) { l := len(dAtA) iNdEx := 0 @@ -3198,79 +4191,95 @@ var ( ErrIntOverflowAuth = fmt.Errorf("proto: integer overflow") ) -func init() { proto.RegisterFile("auth.proto", fileDescriptor_auth_7c0b95a1fa9bddec) } - -var fileDescriptor_auth_7c0b95a1fa9bddec = []byte{ - // 1129 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x74, 0x55, 0xc1, 0x6e, 0xdb, 0x46, - 0x13, 0x36, 0x6d, 0xc9, 0x96, 0x56, 0x8a, 0xa2, 0x6c, 0xf2, 0xdb, 0x8c, 0x92, 0x88, 0x81, 0xfe, - 0x8b, 0x91, 0x06, 0x52, 0xc0, 0xa0, 0x45, 0x61, 0x14, 0x08, 0x42, 0x57, 0x89, 0x03, 0x1b, 0xae, - 0x4b, 0xc9, 0x32, 0xd0, 0x1e, 0x04, 0x9a, 0x1a, 0x4b, 0x84, 0x29, 0x2e, 0xbb, 0xbb, 0x54, 0x2b, - 0xf4, 0x25, 0x7a, 0xec, 0x8b, 0xf4, 0x1d, 0x7c, 0xec, 0xb9, 0x07, 0xb6, 0x75, 0x6f, 0x7c, 0x8a, - 0x62, 0x97, 0xa4, 0x48, 0xca, 0xee, 0x89, 0xdc, 0xef, 0x9b, 0xf9, 0x66, 0x77, 0x66, 0x76, 0x16, - 0x21, 0x2b, 0xe0, 0xb3, 0xae, 0x4f, 0x09, 0x27, 0xb8, 0x2c, 0x3f, 0xad, 0x27, 0x53, 0x32, 0x25, - 0xf2, 0xb7, 0x27, 0xfe, 0x62, 0xb2, 0xf5, 0x6c, 0x4a, 0xc8, 0xd4, 0x85, 0x9e, 0x5c, 0x5d, 0x06, - 0x57, 0x3d, 0x98, 0xfb, 0x7c, 0x99, 0x90, 0xda, 0x3a, 0xc9, 0x9d, 0x39, 0x30, 0x6e, 0xcd, 0xfd, - 0xc4, 0xe0, 0x60, 0xea, 0xf0, 0x59, 0x70, 0xd9, 0xb5, 0xc9, 0xbc, 0x37, 0xa5, 0xd6, 0xc2, 0xe1, - 0x16, 0x77, 0x88, 0x67, 0xb9, 0x3d, 0x0e, 0x2e, 0xf8, 0x84, 0xf2, 0x9e, 0xeb, 0x5c, 0xf6, 0x18, - 0xd0, 0x85, 0x63, 0x03, 0xeb, 0xf1, 0xa5, 0x0f, 0x2c, 0xf6, 0xed, 0x84, 0x15, 0x54, 0xee, 0x2f, - 0xc0, 0xe3, 0xf8, 0x4b, 0x54, 0x1a, 0x2e, 0x7d, 0x50, 0x95, 0x97, 0xca, 0x7e, 0x43, 0x6f, 0xc6, - 0x7c, 0xf7, 0x1b, 0x1f, 0xa8, 0x54, 0x33, 0x70, 0x14, 0x6a, 0x0d, 0xe1, 0xfa, 0x9a, 0xcc, 0x1d, - 0x2e, 0x37, 0x68, 0x4a, 0x0f, 0xfc, 0x1d, 0x6a, 0x98, 0xc0, 0x48, 0x40, 0x6d, 0x38, 0x02, 0x6b, - 0x02, 0x54, 0xdd, 0x7c, 0xa9, 0xec, 0xd7, 0x74, 0xb5, 0x9b, 0x86, 0xec, 0x16, 0x79, 0x63, 0x37, - 0x0a, 0x35, 0x4c, 0x13, 0x2c, 0xd3, 0x3b, 0xda, 0x30, 0xd7, 0x94, 0xf0, 0x18, 0x3d, 0x38, 0x04, - 0xca, 0xdf, 0x07, 0x7c, 0x46, 0xa8, 0xc3, 0x97, 0xea, 0x96, 0x94, 0x7e, 0x9a, 0x49, 0x17, 0xe8, - 0x91, 0x6e, 0x3c, 0x8f, 0x42, 0x4d, 0xb5, 0x81, 0xf2, 0xb1, 0x95, 0xa2, 0x85, 0x08, 0x45, 0x3d, - 0xfc, 0x3d, 0xaa, 0x0f, 0x44, 0xbe, 0xec, 0x21, 0xb9, 0x06, 0x8f, 0xa9, 0xa5, 0xf5, 0xad, 0xe7, - 0xd9, 0x91, 0x6e, 0x3c, 0x8b, 0x42, 0x6d, 0x8f, 0x49, 0x6c, 0xcc, 0x25, 0x58, 0x50, 0x2f, 0x88, - 0x61, 0x1b, 0x35, 0xce, 0x28, 0x59, 0x38, 0xcc, 0x21, 0x9e, 0x84, 0xd4, 0xb2, 0x94, 0x6f, 0x65, - 0xf2, 0x45, 0x7e, 0xa4, 0x1b, 0x2f, 0xa2, 0x50, 0x7b, 0xea, 0xa7, 0x68, 0x1c, 0xa3, 0x98, 0xa2, - 0xa2, 0x0b, 0xbe, 0x40, 0xb5, 0x43, 0x37, 0x60, 0x1c, 0xe8, 0xa9, 0x35, 0x07, 0x75, 0x5b, 0x46, - 0xd8, 0xcb, 0x25, 0x28, 0x23, 0x47, 0xba, 0xd1, 0x8a, 0x42, 0x6d, 0xd7, 0x8e, 0xa1, 0xb1, 0x67, - 0xcd, 0x8b, 0xe9, 0xcf, 0x2b, 0xc9, 0xdc, 0xc7, 0xcb, 0x43, 0xe2, 0x5d, 0x39, 0x53, 0x75, 0xe7, - 0x4e, 0xee, 0xf3, 0xf4, 0xe8, 0x6d, 0x92, 0xfb, 0x44, 0xdc, 0x96, 0xe8, 0x5a, 0xee, 0xf3, 0x0e, - 0xf8, 0x00, 0x95, 0xce, 0x19, 0x50, 0xb5, 0x22, 0x75, 0x9b, 0x99, 0xae, 0x40, 0x47, 0x7a, 0xdc, - 0x72, 0x01, 0x03, 0x5a, 0x10, 0x91, 0x3e, 0xc2, 0xd7, 0x24, 0x2e, 0xa8, 0xd5, 0x75, 0x5f, 0x81, - 0x8e, 0xde, 0xc6, 0xbe, 0x94, 0xb8, 0xc5, 0xf3, 0x49, 0x1f, 0x7c, 0x82, 0xaa, 0xe2, 0x80, 0xcc, - 0xb7, 0x6c, 0x50, 0x91, 0x14, 0x78, 0x9c, 0x09, 0xac, 0x28, 0x63, 0x2f, 0x0a, 0xb5, 0xc7, 0x5e, - 0xba, 0x2c, 0x08, 0x65, 0x02, 0xd8, 0x40, 0xdb, 0x03, 0xa0, 0x0b, 0xa0, 0x6a, 0x4d, 0x4a, 0xe1, - 0x5c, 0xef, 0x48, 0x7c, 0xa4, 0x1b, 0x4f, 0xa2, 0x50, 0x6b, 0x32, 0xb9, 0x2a, 0xc8, 0x24, 0x9e, - 0x22, 0xd5, 0x26, 0x2c, 0x80, 0x32, 0x18, 0x06, 0x9e, 0x07, 0xae, 0x5a, 0x5f, 0x4f, 0x75, 0x81, - 0x4e, 0xdb, 0x9c, 0xc6, 0xe0, 0x98, 0x4b, 0xb4, 0x98, 0xea, 0x82, 0x03, 0xbe, 0x46, 0xcd, 0xf8, - 0xef, 0x90, 0x78, 0x1e, 0xd8, 0xe2, 0x46, 0xab, 0x0f, 0x64, 0x8c, 0xe7, 0x59, 0x8c, 0x75, 0x8b, - 0x91, 0x6e, 0x68, 0x51, 0xa8, 0x3d, 0x8b, 0xe5, 0x45, 0x41, 0x13, 0xa2, 0x10, 0xe9, 0x8e, 0xb0, - 0x81, 0x50, 0x25, 0xbd, 0xc6, 0x9d, 0x23, 0x54, 0xbe, 0xb0, 0xb8, 0x3d, 0xc3, 0xef, 0x50, 0xf9, - 0xd8, 0xf1, 0x26, 0x4c, 0x55, 0x5e, 0x6e, 0xc9, 0x8a, 0xc5, 0x03, 0x46, 0x92, 0x82, 0x30, 0xf6, - 0x6e, 0x42, 0x6d, 0x23, 0x0a, 0xb5, 0x87, 0xd7, 0xc2, 0x2c, 0x37, 0x65, 0x62, 0xbf, 0xce, 0xcf, - 0xa8, 0xba, 0x32, 0xc6, 0xcf, 0x51, 0x49, 0x7c, 0xe5, 0xb4, 0xaa, 0x1a, 0x95, 0x28, 0xd4, 0x4a, - 0xc2, 0xcd, 0x94, 0x28, 0xd6, 0x51, 0xed, 0x84, 0x58, 0x93, 0x01, 0xd8, 0x14, 0x38, 0x93, 0xe3, - 0xa8, 0x62, 0x34, 0xa3, 0x50, 0xab, 0xbb, 0xc4, 0x9a, 0x8c, 0x59, 0x8c, 0x9b, 0x79, 0x23, 0xa1, - 0x28, 0xef, 0xcf, 0x56, 0xa6, 0x28, 0x4a, 0x6f, 0x4a, 0xb4, 0xf3, 0x2d, 0x2a, 0x8b, 0xb9, 0xc1, - 0xf0, 0xff, 0xd1, 0xd6, 0x60, 0x70, 0x24, 0xe3, 0xd6, 0x8d, 0x47, 0x51, 0xa8, 0x3d, 0x60, 0x6c, - 0x96, 0xdb, 0xac, 0x60, 0x85, 0xd1, 0xf0, 0x64, 0x20, 0xe3, 0x26, 0x46, 0xdc, 0xcd, 0x9f, 0x48, - 0xb0, 0x9d, 0xdf, 0x36, 0x51, 0x53, 0xb4, 0xb2, 0xd4, 0x35, 0xe1, 0x87, 0x00, 0x18, 0xc7, 0xaf, - 0x51, 0xf5, 0x2c, 0xb8, 0x74, 0x1d, 0xfb, 0x18, 0x96, 0x49, 0x90, 0x46, 0x14, 0x6a, 0xc8, 0x97, - 0xe0, 0xf8, 0x1a, 0x96, 0x66, 0x66, 0x80, 0xf7, 0x51, 0x45, 0x28, 0x88, 0x7d, 0xca, 0x60, 0x55, - 0xa3, 0x1e, 0x85, 0x5a, 0x25, 0x48, 0x30, 0x73, 0xc5, 0xe2, 0x01, 0xda, 0xe9, 0xff, 0xe4, 0x3b, - 0x14, 0x58, 0x32, 0x41, 0x5b, 0xdd, 0xf8, 0x59, 0xe9, 0xa6, 0xcf, 0x4a, 0x77, 0x98, 0x3e, 0x2b, - 0xc6, 0x8b, 0xa4, 0x12, 0x8f, 0x20, 0x76, 0xc9, 0x76, 0xfe, 0xcb, 0x9f, 0x9a, 0x62, 0xa6, 0x4a, - 0xf8, 0x35, 0xda, 0xfe, 0x40, 0xe8, 0xdc, 0xe2, 0x72, 0x6a, 0x56, 0xe3, 0x2e, 0xbf, 0x92, 0x48, - 0xee, 0xb0, 0x89, 0x0d, 0xfe, 0x80, 0x1a, 0x26, 0x09, 0x38, 0x0c, 0x49, 0x32, 0x05, 0xe4, 0x30, - 0xac, 0x1a, 0xed, 0x28, 0xd4, 0x5a, 0x54, 0x30, 0x63, 0x4e, 0xc6, 0xc9, 0xf4, 0xc8, 0xf9, 0xaf, - 0x79, 0x75, 0x5c, 0xd4, 0xf8, 0x08, 0x5c, 0x9c, 0x2c, 0x4d, 0x5a, 0x5a, 0x3a, 0xe5, 0xbe, 0xd2, - 0xe1, 0xaf, 0x50, 0xed, 0xc2, 0xe1, 0xb3, 0x62, 0x33, 0xc8, 0x31, 0xf8, 0xa3, 0xc3, 0x67, 0x69, - 0x33, 0xe4, 0x02, 0xe6, 0xcd, 0x3b, 0x7d, 0xf4, 0x30, 0x89, 0xb6, 0xaa, 0x91, 0x5e, 0x14, 0x54, - 0xb2, 0xee, 0xca, 0x0b, 0x16, 0x64, 0x5e, 0xbd, 0x42, 0xd5, 0xd5, 0x53, 0x8a, 0x2b, 0xa8, 0xf4, - 0xe9, 0xf4, 0xd3, 0xb0, 0xb9, 0x81, 0x77, 0xd0, 0xd6, 0xd9, 0xf9, 0xb0, 0xa9, 0x60, 0x84, 0xb6, - 0xbf, 0xee, 0x9f, 0xf4, 0x87, 0xfd, 0xe6, 0xa6, 0xfe, 0xc7, 0x26, 0xaa, 0x89, 0x07, 0x6a, 0x10, - 0xdf, 0x4b, 0xfc, 0x0e, 0x35, 0x06, 0xe0, 0x4d, 0x8e, 0x01, 0xfc, 0xf7, 0xae, 0xb3, 0x00, 0x86, - 0x73, 0xd3, 0x6a, 0x85, 0xb6, 0x76, 0xef, 0x54, 0xb4, 0x2f, 0x8e, 0xb3, 0xaf, 0xe0, 0xcf, 0x50, - 0x4d, 0xde, 0x1c, 0xf9, 0xd0, 0x33, 0x5c, 0xcf, 0x5f, 0xbd, 0x56, 0xba, 0x92, 0xe4, 0x1b, 0x05, - 0x7f, 0x8e, 0xd0, 0xb9, 0xcf, 0x80, 0xf2, 0x53, 0x32, 0x01, 0x7c, 0xcf, 0x30, 0x6b, 0xdd, 0x17, - 0x1d, 0x1f, 0xa0, 0x47, 0x1f, 0xc1, 0x13, 0x27, 0x84, 0x55, 0x53, 0xe3, 0xbd, 0x44, 0x7b, 0xbd, - 0xcd, 0x57, 0x41, 0x63, 0x33, 0x1d, 0xed, 0x24, 0x39, 0xc6, 0xff, 0x4b, 0x88, 0x62, 0x85, 0x5b, - 0x77, 0xde, 0x06, 0xfc, 0x05, 0xaa, 0xa4, 0x75, 0xc1, 0xbb, 0x45, 0x27, 0xf6, 0x9f, 0x5e, 0x6f, - 0x14, 0xe3, 0xc9, 0xcd, 0xdf, 0x6d, 0xe5, 0xe6, 0xb6, 0xad, 0xfc, 0x7e, 0xdb, 0x56, 0xfe, 0xba, - 0x6d, 0x2b, 0xbf, 0xfe, 0xd3, 0xde, 0xb8, 0xdc, 0x96, 0x02, 0x6f, 0xff, 0x0d, 0x00, 0x00, 0xff, - 0xff, 0xfa, 0x3e, 0xb7, 0x43, 0xb2, 0x09, 0x00, 0x00, +func init() { proto.RegisterFile("auth.proto", fileDescriptor_auth_3713a8b32977094f) } + +var fileDescriptor_auth_3713a8b32977094f = []byte{ + // 1386 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x7c, 0x56, 0x41, 0x6f, 0xdb, 0x46, + 0x16, 0x36, 0x65, 0x49, 0x96, 0x9e, 0x1c, 0x45, 0x19, 0x3b, 0x36, 0xa3, 0x38, 0xa6, 0xa1, 0x5c, + 0x8c, 0x6c, 0x20, 0x05, 0x0a, 0x76, 0x37, 0x6b, 0x2c, 0x10, 0x84, 0xb6, 0x12, 0x3b, 0x31, 0xb2, + 0x59, 0x4a, 0x51, 0x80, 0xf6, 0x20, 0xd0, 0xf4, 0x8b, 0x45, 0x98, 0x22, 0xd5, 0x99, 0x91, 0x5a, + 0x5f, 0xfb, 0x0b, 0x7a, 0xec, 0xbf, 0xe9, 0x35, 0xc7, 0xfe, 0x02, 0xb6, 0x4d, 0x6f, 0xfc, 0x0d, + 0x39, 0x14, 0x33, 0x24, 0x25, 0x0e, 0x1d, 0xf7, 0x44, 0xce, 0xf7, 0xde, 0xf7, 0xcd, 0xcc, 0xc7, + 0x37, 0x6f, 0x08, 0x60, 0xcf, 0xf8, 0xb8, 0x3d, 0xa5, 0x01, 0x0f, 0x48, 0x49, 0x3e, 0x9a, 0x9b, + 0x17, 0xc1, 0x45, 0x20, 0x5f, 0x3b, 0xe2, 0x2d, 0x0e, 0x36, 0xef, 0x5f, 0x04, 0xc1, 0x85, 0x87, + 0x1d, 0x39, 0x3a, 0x9b, 0x7d, 0xec, 0xe0, 0x64, 0xca, 0xaf, 0x92, 0xa0, 0x91, 0x0f, 0x72, 0x77, + 0x82, 0x8c, 0xdb, 0x93, 0x69, 0x92, 0x70, 0x70, 0xe1, 0xf2, 0xf1, 0xec, 0xac, 0xed, 0x04, 0x93, + 0xce, 0x05, 0xb5, 0xe7, 0x2e, 0xb7, 0xb9, 0x1b, 0xf8, 0xb6, 0xd7, 0xe1, 0xe8, 0xe1, 0x34, 0xa0, + 0xbc, 0xe3, 0xb9, 0x67, 0x1d, 0x86, 0x74, 0xee, 0x3a, 0xc8, 0x3a, 0xfc, 0x6a, 0x8a, 0x2c, 0xe6, + 0xb6, 0x7e, 0xa9, 0x42, 0xa9, 0x37, 0x47, 0x9f, 0x93, 0x67, 0x50, 0x1c, 0x5c, 0x4d, 0x51, 0xd7, + 0xf6, 0xb4, 0xfd, 0x7a, 0xb7, 0x11, 0xc7, 0xdb, 0xff, 0x9b, 0x22, 0x95, 0x6a, 0x26, 0x89, 0x42, + 0xa3, 0x2e, 0xa8, 0x8f, 0x83, 0x89, 0xcb, 0xe5, 0x02, 0x2d, 0xc9, 0x20, 0xdf, 0x40, 0xdd, 0x42, + 0x16, 0xcc, 0xa8, 0x83, 0xc7, 0x68, 0x9f, 0x23, 0xd5, 0x0b, 0x7b, 0xda, 0x7e, 0xad, 0xab, 0xb7, + 0xd3, 0x29, 0xdb, 0x6a, 0xdc, 0xdc, 0x8a, 0x42, 0x83, 0xd0, 0x04, 0x5b, 0xea, 0x1d, 0xaf, 0x58, + 0x39, 0x25, 0x32, 0x82, 0x5b, 0x87, 0x48, 0xf9, 0x8b, 0x19, 0x1f, 0x07, 0xd4, 0xe5, 0x57, 0xfa, + 0xaa, 0x94, 0xbe, 0xb7, 0x94, 0x56, 0xc2, 0xc3, 0xae, 0xb9, 0x13, 0x85, 0x86, 0xee, 0x20, 0xe5, + 0x23, 0x3b, 0x45, 0x95, 0x19, 0x54, 0x3d, 0xf2, 0x2d, 0xac, 0xf7, 0x85, 0x5f, 0xce, 0x20, 0xb8, + 0x44, 0x9f, 0xe9, 0xc5, 0xfc, 0xd2, 0xb3, 0xd1, 0x61, 0xd7, 0xbc, 0x1f, 0x85, 0xc6, 0x36, 0x93, + 0xd8, 0x88, 0x4b, 0x50, 0x51, 0x57, 0xc4, 0x88, 0x03, 0xf5, 0x77, 0x34, 0x98, 0xbb, 0xcc, 0x0d, + 0x7c, 0x09, 0xe9, 0x25, 0x29, 0xdf, 0x5c, 0xca, 0xab, 0xf1, 0x61, 0xd7, 0x7c, 0x10, 0x85, 0xc6, + 0xbd, 0x69, 0x8a, 0xc6, 0x73, 0xa8, 0x16, 0xa9, 0x14, 0xf2, 0x01, 0x6a, 0x87, 0xde, 0x8c, 0x71, + 0xa4, 0x6f, 0xed, 0x09, 0xea, 0x65, 0x39, 0xc3, 0x76, 0xc6, 0xa0, 0x65, 0x70, 0xd8, 0x35, 0x9b, + 0x51, 0x68, 0x6c, 0x39, 0x31, 0x34, 0xf2, 0xed, 0x89, 0x6a, 0x7f, 0x56, 0x49, 0x7a, 0x1f, 0x0f, + 0x0f, 0x03, 0xff, 0xa3, 0x7b, 0xa1, 0xaf, 0x5d, 0xf3, 0x3e, 0x1b, 0x1e, 0x3e, 0x4d, 0xbc, 0x4f, + 0xc4, 0x1d, 0x89, 0xe6, 0xbc, 0xcf, 0x12, 0xc8, 0x01, 0x14, 0xdf, 0x33, 0xa4, 0x7a, 0x45, 0xea, + 0x36, 0x96, 0xba, 0x02, 0x1d, 0x76, 0xe3, 0x92, 0x9b, 0x31, 0xa4, 0x8a, 0x88, 0xe4, 0x08, 0xae, + 0x15, 0x78, 0xa8, 0x57, 0xf3, 0x5c, 0x81, 0x0e, 0x9f, 0xc6, 0x5c, 0x1a, 0x78, 0xea, 0xfe, 0x24, + 0x87, 0x9c, 0x42, 0x55, 0x6c, 0x90, 0x4d, 0x6d, 0x07, 0x75, 0x90, 0x02, 0x1b, 0x4b, 0x81, 0x45, + 0xc8, 0xdc, 0x8e, 0x42, 0x63, 0xc3, 0x4f, 0x87, 0x8a, 0xd0, 0x52, 0x80, 0x98, 0x50, 0xee, 0x23, + 0x9d, 0x23, 0xd5, 0x6b, 0x52, 0x8a, 0x64, 0x6a, 0x47, 0xe2, 0xc3, 0xae, 0xb9, 0x19, 0x85, 0x46, + 0x83, 0xc9, 0x91, 0x22, 0x93, 0x30, 0x85, 0xd5, 0x16, 0xce, 0x91, 0x32, 0x1c, 0xcc, 0x7c, 0x1f, + 0x3d, 0x7d, 0x3d, 0x6f, 0xb5, 0x12, 0x4e, 0xcb, 0x9c, 0xc6, 0xe0, 0x88, 0x4b, 0x54, 0xb5, 0x5a, + 0x21, 0x90, 0x4b, 0x68, 0xc4, 0x6f, 0x87, 0x81, 0xef, 0xa3, 0x23, 0x4e, 0xb4, 0x7e, 0x4b, 0xce, + 0xb1, 0xb3, 0x9c, 0x23, 0x9f, 0x31, 0xec, 0x9a, 0x46, 0x14, 0x1a, 0xf7, 0x63, 0x79, 0xf1, 0x41, + 0x93, 0x80, 0x32, 0xd3, 0x35, 0x61, 0xb1, 0x9b, 0x17, 0x8e, 0x83, 0x8c, 0x59, 0xf8, 0xdd, 0x0c, + 0x19, 0xd7, 0xeb, 0xf9, 0xdd, 0x28, 0xe1, 0xb4, 0x70, 0x6c, 0x09, 0x8e, 0x68, 0x8c, 0xaa, 0xbb, + 0x51, 0x08, 0x26, 0x40, 0x25, 0xed, 0x13, 0xad, 0x63, 0x28, 0x7d, 0xb0, 0xb9, 0x33, 0x26, 0xcf, + 0xa1, 0xf4, 0xc6, 0xf5, 0xcf, 0x99, 0xae, 0xed, 0xad, 0xca, 0x92, 0x88, 0x3b, 0x98, 0x0c, 0x8a, + 0x80, 0xb9, 0xfd, 0x29, 0x34, 0x56, 0xa2, 0xd0, 0xb8, 0x7d, 0x29, 0xd2, 0x32, 0x6d, 0x2c, 0xe6, + 0xb5, 0x7e, 0x2c, 0x40, 0x75, 0x91, 0x4d, 0x76, 0xa0, 0x28, 0x9e, 0xb2, 0x1f, 0x56, 0xcd, 0x4a, + 0x14, 0x1a, 0x45, 0xc1, 0xb3, 0x24, 0x4a, 0xba, 0x50, 0x3b, 0x0d, 0xec, 0xf3, 0x3e, 0x3a, 0x14, + 0x39, 0x93, 0x0d, 0xaf, 0x62, 0x36, 0xa2, 0xd0, 0x58, 0xf7, 0x02, 0xfb, 0x7c, 0xc4, 0x62, 0xdc, + 0xca, 0x26, 0x09, 0x45, 0x79, 0x42, 0x57, 0x97, 0x8a, 0xa2, 0xb8, 0x2c, 0x89, 0x92, 0xd7, 0x50, + 0x7e, 0xe9, 0x7a, 0x1c, 0xa9, 0x5e, 0x94, 0xeb, 0xdf, 0xc9, 0xaf, 0xbf, 0x1d, 0x87, 0x7b, 0x3e, + 0xa7, 0x57, 0x71, 0x41, 0x7d, 0x94, 0x40, 0x66, 0x23, 0x89, 0x42, 0xf3, 0x3f, 0x50, 0xcb, 0x24, + 0x93, 0x06, 0xac, 0x5e, 0xe2, 0x55, 0xbc, 0x13, 0x4b, 0xbc, 0x92, 0x4d, 0x28, 0xcd, 0x6d, 0x6f, + 0x86, 0x72, 0xe1, 0x55, 0x2b, 0x1e, 0x1c, 0x14, 0x9e, 0x69, 0xad, 0xff, 0x43, 0x49, 0x34, 0x48, + 0x46, 0x1e, 0xc2, 0x6a, 0xbf, 0x7f, 0x2c, 0x49, 0xeb, 0xe6, 0x9d, 0x28, 0x34, 0x6e, 0x31, 0x36, + 0xce, 0xcc, 0x25, 0xa2, 0x22, 0x69, 0x70, 0xda, 0x97, 0x2a, 0x49, 0x12, 0xf7, 0xb2, 0xce, 0x8a, + 0x68, 0xeb, 0x4b, 0x01, 0x1a, 0xe2, 0xcc, 0x4a, 0xdd, 0xe4, 0x13, 0x92, 0xc7, 0x50, 0x7d, 0x37, + 0x3b, 0xf3, 0x5c, 0xe7, 0x4d, 0xb2, 0xb2, 0x75, 0xb3, 0x1e, 0x85, 0x06, 0x4c, 0x25, 0x38, 0xba, + 0xc4, 0x2b, 0x6b, 0x99, 0x40, 0xf6, 0xa1, 0x22, 0x14, 0x84, 0x5d, 0xf1, 0x92, 0xcd, 0xf5, 0x28, + 0x34, 0x2a, 0xb3, 0x04, 0xb3, 0x16, 0x51, 0xd2, 0x87, 0xb5, 0xde, 0x0f, 0x53, 0x97, 0x22, 0x4b, + 0xae, 0x8a, 0x66, 0x3b, 0xbe, 0x3f, 0xdb, 0xe9, 0xfd, 0xd9, 0x1e, 0xa4, 0xf7, 0xa7, 0xf9, 0x20, + 0xa9, 0x88, 0x3b, 0x18, 0x53, 0x96, 0x2b, 0xff, 0xe9, 0x37, 0x43, 0xb3, 0x52, 0x25, 0xf2, 0x18, + 0xca, 0x2f, 0x03, 0x3a, 0xb1, 0xb9, 0xbc, 0x1e, 0xaa, 0x89, 0xfb, 0x12, 0x51, 0xdc, 0x97, 0x08, + 0x79, 0x09, 0x75, 0x2b, 0x98, 0x71, 0x1c, 0x04, 0x49, 0xbb, 0x93, 0x5d, 0xbf, 0x6a, 0xee, 0x46, + 0xa1, 0xd1, 0xa4, 0x22, 0x32, 0xe2, 0xc1, 0x28, 0x69, 0x93, 0x19, 0x7e, 0x8e, 0x45, 0x7a, 0x50, + 0x57, 0xca, 0x9e, 0xe9, 0xe5, 0xbd, 0xd5, 0xfd, 0x6a, 0x7c, 0x43, 0xa8, 0x87, 0x25, 0xeb, 0x79, + 0x8e, 0xd4, 0xf2, 0xa0, 0xfe, 0x0a, 0xb9, 0x30, 0x28, 0xf5, 0x3e, 0x2d, 0x44, 0xed, 0xab, 0x85, + 0xf8, 0x5f, 0xa8, 0x7d, 0x70, 0xf9, 0x58, 0x2d, 0x6d, 0x79, 0x6d, 0x7c, 0xef, 0xf2, 0x71, 0x5a, + 0xda, 0x99, 0x09, 0xb3, 0xe9, 0xad, 0x1e, 0xdc, 0x4e, 0x66, 0x5b, 0x7c, 0xea, 0xae, 0x2a, 0xa8, + 0x2d, 0xcf, 0x4a, 0x56, 0x50, 0x95, 0x19, 0xe7, 0xf7, 0x4e, 0x86, 0xd7, 0xdc, 0x88, 0xcf, 0xf9, + 0xdf, 0x74, 0x95, 0x0d, 0x71, 0xd8, 0x73, 0x46, 0x5d, 0xb3, 0x07, 0x81, 0x24, 0xef, 0xe2, 0xea, + 0xc6, 0x3e, 0x72, 0xe1, 0xfd, 0x16, 0x14, 0x4e, 0x8e, 0x12, 0x83, 0xca, 0x51, 0x68, 0x14, 0xdc, + 0x73, 0xab, 0x70, 0x72, 0x44, 0xfe, 0x0d, 0x25, 0x99, 0x26, 0x6d, 0xa9, 0x77, 0xb7, 0xb2, 0x0d, + 0x7a, 0x29, 0x62, 0x56, 0xa3, 0xd0, 0x28, 0x89, 0xbf, 0x04, 0xb4, 0xe2, 0xfc, 0xd6, 0x43, 0xa8, + 0x26, 0x19, 0x27, 0x47, 0x37, 0xa9, 0x3f, 0x7a, 0x04, 0xd5, 0xc5, 0x0f, 0x17, 0xa9, 0x40, 0xf1, + 0xe4, 0xed, 0xc9, 0xa0, 0xb1, 0x42, 0xd6, 0x60, 0xf5, 0xdd, 0xfb, 0x41, 0x43, 0x23, 0x00, 0xe5, + 0xa3, 0xde, 0x69, 0x6f, 0xd0, 0x6b, 0x14, 0xba, 0x5f, 0x8a, 0x50, 0x13, 0xbf, 0x31, 0xfd, 0x78, + 0x01, 0xe4, 0x39, 0xd4, 0xfb, 0xe8, 0x9f, 0xbf, 0x41, 0x9c, 0xbe, 0xf0, 0xdc, 0x39, 0x32, 0x92, + 0xb9, 0xd3, 0x16, 0x68, 0x73, 0xeb, 0xda, 0x71, 0xe8, 0x89, 0x8f, 0xb8, 0xaf, 0x91, 0x7f, 0x40, + 0x4d, 0xf6, 0x1a, 0xf9, 0x3b, 0xc8, 0xc8, 0x7a, 0xb6, 0xff, 0x34, 0xd3, 0x91, 0x0c, 0x3e, 0xd1, + 0xc8, 0x3f, 0x01, 0xde, 0x4f, 0x19, 0x52, 0xfe, 0x36, 0x38, 0x47, 0xf2, 0x95, 0x2b, 0xaf, 0xf9, + 0xb5, 0xd9, 0xc9, 0x01, 0xdc, 0x79, 0x85, 0xbe, 0xd8, 0x21, 0x2e, 0x3a, 0x02, 0xd9, 0x4e, 0xb4, + 0xf3, 0x3d, 0x62, 0x31, 0x69, 0x9c, 0xd6, 0x85, 0xb5, 0xa4, 0xb2, 0xc8, 0xdd, 0x24, 0xa0, 0xd6, + 0x75, 0xf3, 0xda, 0x1f, 0x04, 0xf9, 0x17, 0x54, 0xd2, 0x6a, 0x24, 0x5b, 0x2a, 0x89, 0xdd, 0xc8, + 0x7a, 0xa2, 0x91, 0x13, 0xb1, 0x4e, 0x9e, 0xab, 0xc0, 0x07, 0x37, 0x54, 0x5a, 0xd2, 0x74, 0xd3, + 0x45, 0xe5, 0x58, 0xc7, 0xb0, 0x71, 0x48, 0xd1, 0xe6, 0xa8, 0xe0, 0xe4, 0xe6, 0xb2, 0xbd, 0xe9, + 0x13, 0x91, 0xe7, 0xb0, 0x71, 0x84, 0x1e, 0xe6, 0x95, 0xd2, 0x8b, 0x6e, 0x51, 0x5e, 0x37, 0x0a, + 0xbc, 0x86, 0xbb, 0xfd, 0xdc, 0xae, 0x64, 0x71, 0x92, 0x7b, 0xaa, 0x44, 0xe6, 0x20, 0xdc, 0xa4, + 0x65, 0x6e, 0x7e, 0xfa, 0x63, 0x57, 0xfb, 0xf4, 0x79, 0x57, 0xfb, 0xf5, 0xf3, 0xae, 0xf6, 0xfb, + 0xe7, 0x5d, 0xed, 0xe7, 0x3f, 0x77, 0x57, 0xce, 0xca, 0x32, 0xeb, 0xe9, 0x5f, 0x01, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xb0, 0x04, 0x19, 0xfa, 0x0c, 0x00, 0x00, } diff --git a/lib/auth/proto/auth.proto b/lib/auth/proto/auth.proto index e7bc3de0e6a2e..61e27cc846670 100644 --- a/lib/auth/proto/auth.proto +++ b/lib/auth/proto/auth.proto @@ -53,6 +53,8 @@ message Event { services.ReverseTunnelV2 ReverseTunnel = 12 [(gogoproto.jsontag) = "reverse_tunnel,omitempty"]; // TunnelConnection is a resource for tunnel connnections services.TunnelConnectionV2 TunnelConnection = 13 [(gogoproto.jsontag) = "tunnel_connection,omitempty"]; + // AccessRequest is a resource for access requests + services.AccessRequestV3 AccessRequest = 14 [(gogoproto.jsontag) = "access_request,omitempty"]; } } @@ -72,6 +74,9 @@ message WatchKind { // if specified only the events with a specific resource // name will be sent string Name = 3 [(gogoproto.jsontag) = "name"]; + // Filter is an optional mapping of custom filter parameters. + // Valid values vary by resource kind. + map Filter = 4 [(gogoproto.jsontag) = "filter,omitempty"]; } // Set of certificates corresponding to a single public key. @@ -100,6 +105,9 @@ message UserCertsRequest { // so that requests originating with this certificate will be redirected // to this cluster string RouteToCluster = 5 [(gogoproto.jsontag) = "route_to_cluster,omitempty"]; + // AccessRequests is an optional list of request IDs indicating requests whose + // escalated privileges should be added to the certificate. + repeated string AccessRequests = 6 [(gogoproto.jsontag) = "access_requests,omitempty"]; } // GetUserRequest specifies paramters for the GetUser method. @@ -116,6 +124,23 @@ message GetUsersRequest { bool WithSecrets = 1 [(gogoproto.jsontag) = "with_secrets"]; } +// AccessRequests is a collection of AccessRequest values. +message AccessRequests { + repeated services.AccessRequestV3 AccessRequests = 1 [(gogoproto.jsontag) = "access_requests"]; +} + +// RequestStateSetter encodes the paramters necessary to update the +// state of a privilege escalation request. +message RequestStateSetter { + string ID = 1 [(gogoproto.jsontag) = "id"]; + services.RequestState State = 2 [(gogoproto.jsontag) = "state"]; +} + +// RequestID is the unique identifier of an access request. +message RequestID { + string ID = 1 [(gogoproto.jsontag) = "id"]; +} + // AuthService is authentication/authorization service implementation service AuthService { // SendKeepAlives allows node to send a stream of keep alive requests @@ -130,4 +155,12 @@ service AuthService { rpc GetUser(GetUserRequest) returns (services.UserV2); // GetUsers gets all current user resources. rpc GetUsers(GetUsersRequest) returns (stream services.UserV2); + // GetAccessRequests gets all pending access requests. + rpc GetAccessRequests(services.AccessRequestFilter) returns (AccessRequests); + // CreateAccessRequest creates a new access request. + rpc CreateAccessRequest(services.AccessRequestV3) returns (google.protobuf.Empty); + // DeleteAccessRequest deletes an access request. + rpc DeleteAccessRequest(RequestID) returns (google.protobuf.Empty); + // SetAccessRequestState sets the state of an access request. + rpc SetAccessRequestState(RequestStateSetter) returns (google.protobuf.Empty); } diff --git a/lib/auth/tls_test.go b/lib/auth/tls_test.go index 0032e83d54fae..7460d26da0987 100644 --- a/lib/auth/tls_test.go +++ b/lib/auth/tls_test.go @@ -1357,6 +1357,99 @@ func (s *TLSSuite) TestGetCertAuthority(c *check.C) { fixtures.ExpectAccessDenied(c, err) } +func (s *TLSSuite) TestAccessRequest(c *check.C) { + priv, pub, err := s.server.Auth().GenerateKeyPair("") + c.Assert(err, check.IsNil) + + // make sure we can parse the private and public key + privateKey, err := ssh.ParseRawPrivateKey(priv) + c.Assert(err, check.IsNil) + + _, err = tlsca.MarshalPublicKeyFromPrivateKeyPEM(privateKey) + c.Assert(err, check.IsNil) + + _, _, _, _, err = ssh.ParseAuthorizedKey(pub) + c.Assert(err, check.IsNil) + + user := "user1" + role := "some-role" + _, err = CreateUserRoleAndRequestable(s.server.Auth(), user, role) + c.Assert(err, check.IsNil) + + testUser := TestUser(user) + testUser.TTL = time.Hour + userClient, err := s.server.NewClient(testUser) + c.Assert(err, check.IsNil) + + req, err := services.NewAccessRequest(user, role) + c.Assert(err, check.IsNil) + + c.Assert(userClient.CreateAccessRequest(req), check.IsNil) + + // sanity check; ensure that roles for which no `allow` directive + // exists cannot be requested. + badReq, err := services.NewAccessRequest(user, "some-fake-role") + c.Assert(err, check.IsNil) + c.Assert(userClient.CreateAccessRequest(badReq), check.NotNil) + + // generateCerts executes a GenerateUserCerts request, optionally applying + // one or more access-requests to the certificate. + generateCerts := func(reqIDs ...string) (*proto.Certs, error) { + return userClient.GenerateUserCerts(context.TODO(), proto.UserCertsRequest{ + PublicKey: pub, + Username: user, + Expires: time.Now().Add(time.Hour).UTC(), + Format: teleport.CertificateFormatStandard, + AccessRequests: reqIDs, + }) + } + + // certContainsRole checks if a PEM encoded TLS cert contains the + // specified role. + certContainsRole := func(cert []byte, role string) bool { + tlsCert, err := tlsca.ParseCertificatePEM(cert) + c.Assert(err, check.IsNil) + identity, err := tlsca.FromSubject(tlsCert.Subject, tlsCert.NotAfter) + c.Assert(err, check.IsNil) + return utils.SliceContainsStr(identity.Groups, role) + } + + // sanity check; ensure that role is not held if no request is applied. + userCerts, err := generateCerts() + c.Assert(err, check.IsNil) + if certContainsRole(userCerts.TLS, role) { + c.Errorf("unexpected role %s", role) + } + + // attempt to apply request in PENDING state (should fail) + _, err = generateCerts(req.GetName()) + c.Assert(err, check.NotNil) + + // verify that user does not have the ability to approve their own request (not a special case, this + // user just wasn't created with the necessary roles for request management). + c.Assert(userClient.SetAccessRequestState(req.GetName(), services.RequestState_APPROVED), check.NotNil) + + // attempt to apply request in APPROVED state (should succeed) + c.Assert(s.server.Auth().SetAccessRequestState(req.GetName(), services.RequestState_APPROVED), check.IsNil) + userCerts, err = generateCerts(req.GetName()) + c.Assert(err, check.IsNil) + // ensure that the requested role was actually applied to the cert + if !certContainsRole(userCerts.TLS, role) { + c.Errorf("missing requested role %s", role) + } + + // attempt to apply request in DENIED state (should fail) + c.Assert(s.server.Auth().SetAccessRequestState(req.GetName(), services.RequestState_DENIED), check.IsNil) + _, err = generateCerts(req.GetName()) + c.Assert(err, check.NotNil) + + // ensure that once in the DENIED state, a request cannot be set back to PENDING state. + c.Assert(s.server.Auth().SetAccessRequestState(req.GetName(), services.RequestState_PENDING), check.NotNil) + + // ensure that once in the DENIED state, a request cannot be set back to APPROVED state. + c.Assert(s.server.Auth().SetAccessRequestState(req.GetName(), services.RequestState_APPROVED), check.NotNil) +} + // TestGenerateCerts tests edge cases around authorization of // certificate generation for servers and users func (s *TLSSuite) TestGenerateCerts(c *check.C) { diff --git a/lib/client/api.go b/lib/client/api.go index 719df33844780..f1aede653e8c4 100644 --- a/lib/client/api.go +++ b/lib/client/api.go @@ -297,6 +297,10 @@ type ProfileStatus struct { // Traits hold claim data used to populate a role at runtime. Traits wrappers.Traits + + // ActiveRequests tracks the privilege escalation requests applied + // during certificate construction. + ActiveRequests services.RequestIDs } // IsExpired returns true if profile is not expired yet @@ -397,13 +401,22 @@ func readProfile(profileDir string, profileName string) (*ProfileStatus, error) } } + var activeRequests services.RequestIDs + rawRequests, ok := cert.Extensions[teleport.CertExtensionTeleportActiveRequests] + if ok { + if err := activeRequests.Unmarshal([]byte(rawRequests)); err != nil { + return nil, trace.Wrap(err) + } + } + // Extract extensions from certificate. This lists the abilities of the // certificate (like can the user request a PTY, port forwarding, etc.) var extensions []string for ext, _ := range cert.Extensions { if ext == teleport.CertExtensionTeleportRoles || ext == teleport.CertExtensionTeleportTraits || - ext == teleport.CertExtensionTeleportRouteToCluster { + ext == teleport.CertExtensionTeleportRouteToCluster || + ext == teleport.CertExtensionTeleportActiveRequests { continue } extensions = append(extensions, ext) @@ -426,13 +439,14 @@ func readProfile(profileDir string, profileName string) (*ProfileStatus, error) Scheme: "https", Host: profile.WebProxyAddr, }, - Username: profile.Username, - Logins: cert.ValidPrincipals, - ValidUntil: validUntil, - Extensions: extensions, - Roles: roles, - Cluster: clusterName, - Traits: traits, + Username: profile.Username, + Logins: cert.ValidPrincipals, + ValidUntil: validUntil, + Extensions: extensions, + Roles: roles, + Cluster: clusterName, + Traits: traits, + ActiveRequests: activeRequests, }, nil } @@ -875,6 +889,38 @@ func (tc *TeleportClient) GenerateCertsForCluster(ctx context.Context, routeToCl return proxyClient.GenerateCertsForCluster(ctx, routeToCluster) } +func (tc *TeleportClient) ReissueUserCerts(ctx context.Context, params ReissueParams) error { + proxyClient, err := tc.ConnectToProxy(ctx) + if err != nil { + return trace.Wrap(err) + } + return proxyClient.ReissueUserCerts(ctx, params) +} + +func (tc *TeleportClient) CreateAccessRequest(ctx context.Context, req services.AccessRequest) error { + proxyClient, err := tc.ConnectToProxy(ctx) + if err != nil { + return trace.Wrap(err) + } + return proxyClient.CreateAccessRequest(ctx, req) +} + +func (tc *TeleportClient) GetAccessRequests(ctx context.Context, filter services.AccessRequestFilter) ([]services.AccessRequest, error) { + proxyClient, err := tc.ConnectToProxy(ctx) + if err != nil { + return nil, trace.Wrap(err) + } + return proxyClient.GetAccessRequests(ctx, filter) +} + +func (tc *TeleportClient) NewWatcher(ctx context.Context, watch services.Watch) (services.Watcher, error) { + proxyClient, err := tc.ConnectToProxy(ctx) + if err != nil { + return nil, trace.Wrap(err) + } + return proxyClient.NewWatcher(ctx, watch) +} + // SSH connects to a node and, if 'command' is specified, executes the command on it, // otherwise runs interactive shell // diff --git a/lib/client/client.go b/lib/client/client.go index 999c1cc5537b4..221a85f7828ca 100644 --- a/lib/client/client.go +++ b/lib/client/client.go @@ -166,6 +166,104 @@ func (proxy *ProxyClient) GenerateCertsForCluster(ctx context.Context, routeToCl return trace.Wrap(err) } +// ReissueParams encodes optional paramters for +// user certificate reissue. +type ReissueParams struct { + RouteToCluster string + AccessRequests []string +} + +// ReissueUserCerts generates certificates for the user +// that have a metadata instructing server to route the requests to the cluster +func (proxy *ProxyClient) ReissueUserCerts(ctx context.Context, params ReissueParams) error { + localAgent := proxy.teleportClient.LocalAgent() + key, err := localAgent.GetKey() + if err != nil { + return trace.Wrap(err) + } + cert, err := key.SSHCert() + if err != nil { + return trace.Wrap(err) + } + tlsCert, err := key.TLSCertificate() + if err != nil { + return trace.Wrap(err) + } + clusterName, err := tlsca.ClusterName(tlsCert.Issuer) + if err != nil { + return trace.Wrap(err) + } + clt, err := proxy.ConnectToCluster(ctx, clusterName, true) + if err != nil { + return trace.Wrap(err) + } + + if params.RouteToCluster != "" { + // Before requesting a certificate, check if the requested cluster is valid. + _, err = clt.GetCertAuthority(services.CertAuthID{ + Type: services.HostCA, + DomainName: params.RouteToCluster, + }, false) + if err != nil { + return trace.NotFound("cluster %v not found", params.RouteToCluster) + } + } + req := proto.UserCertsRequest{ + Username: cert.KeyId, + PublicKey: key.Pub, + Expires: time.Unix(int64(cert.ValidBefore), 0), + RouteToCluster: params.RouteToCluster, + AccessRequests: params.AccessRequests, + } + if _, ok := cert.Permissions.Extensions[teleport.CertExtensionTeleportRoles]; !ok { + req.Format = teleport.CertificateFormatOldSSH + } + + certs, err := clt.GenerateUserCerts(ctx, req) + if err != nil { + return trace.Wrap(err) + } + key.Cert = certs.SSH + key.TLSCert = certs.TLS + + // save the cert to the local storage (~/.tsh usually): + _, err = localAgent.AddKey(key) + return trace.Wrap(err) +} + +// CreateAccessRequest attempts to create a new request for escalated privilege. +func (proxy *ProxyClient) CreateAccessRequest(ctx context.Context, req services.AccessRequest) error { + site, err := proxy.ConnectToCurrentCluster(ctx, false) + if err != nil { + return trace.Wrap(err) + } + return site.CreateAccessRequest(req) +} + +func (proxy *ProxyClient) GetAccessRequests(ctx context.Context, filter services.AccessRequestFilter) ([]services.AccessRequest, error) { + site, err := proxy.ConnectToCurrentCluster(ctx, false) + if err != nil { + return nil, trace.Wrap(err) + } + reqs, err := site.GetAccessRequests(filter) + if err != nil { + return nil, trace.Wrap(err) + } + return reqs, nil +} + +func (proxy *ProxyClient) NewWatcher(ctx context.Context, watch services.Watch) (services.Watcher, error) { + site, err := proxy.ConnectToCurrentCluster(ctx, false) + if err != nil { + return nil, trace.Wrap(err) + } + watcher, err := site.NewWatcher(ctx, watch) + if err != nil { + return nil, trace.Wrap(err) + } + return watcher, nil +} + // FindServersByLabels returns list of the nodes which have labels exactly matching // the given label set. // diff --git a/lib/client/identity.go b/lib/client/identity.go index ad2d68d3ecdfc..1a9a2bdc0eeff 100644 --- a/lib/client/identity.go +++ b/lib/client/identity.go @@ -17,6 +17,8 @@ limitations under the License. package client import ( + "bufio" + "bytes" "io" "io/ioutil" "os" @@ -53,6 +55,10 @@ const ( // two different files (in the same directory) IdentityFormatOpenSSH IdentityFileFormat = "openssh" + // IdentityFormatTLS is a standard TLS format used by common TLS clients (e.g. GRPC) where + // certificate and key are stored in separate files. + IdentityFormatTLS IdentityFileFormat = "tls" + // DefaultIdentityFormat is what Teleport uses by default DefaultIdentityFormat = IdentityFormatFile ) @@ -130,9 +136,119 @@ func MakeIdentityFile(filePath string, key *Key, format IdentityFileFormat, cert if err != nil { return trace.Wrap(err) } + + case IdentityFormatTLS: + keyPath := filePath + ".key" + certPath := filePath + ".crt" + casPath := filePath + ".cas" + + err = ioutil.WriteFile(certPath, key.TLSCert, fileMode) + if err != nil { + return trace.Wrap(err) + } + + err = ioutil.WriteFile(keyPath, key.Priv, fileMode) + if err != nil { + return trace.Wrap(err) + } + var caCerts []byte + for _, ca := range certAuthorities { + for _, keyPair := range ca.GetTLSKeyPairs() { + caCerts = append(caCerts, keyPair.Cert...) + } + } + err = ioutil.WriteFile(casPath, caCerts, fileMode) + if err != nil { + return trace.Wrap(err) + } default: - return trace.BadParameter("unsupported identity format: %q, use either %q or %q", - format, IdentityFormatFile, IdentityFormatOpenSSH) + return trace.BadParameter("unsupported identity format: %q, use one of %q, %q, or %q", + format, IdentityFormatFile, IdentityFormatOpenSSH, IdentityFormatTLS) } return nil } + +// IdentityFile represents the basic components of an identity file. +type IdentityFile struct { + PrivateKey []byte + Certs struct { + SSH []byte + TLS []byte + } + CACerts struct { + SSH [][]byte + TLS [][]byte + } +} + +// DecodeIdentityFile attempts to break up the contents of an identity file +// into its respective components. +func DecodeIdentityFile(r io.Reader) (*IdentityFile, error) { + scanner := bufio.NewScanner(r) + var ident IdentityFile + // Subslice of scanner's buffer pointing to current line + // with leading and trailing whitespace trimmed. + var line []byte + // Attempt to scan to the next line. + scanln := func() bool { + if !scanner.Scan() { + line = nil + return false + } + line = bytes.TrimSpace(scanner.Bytes()) + return true + } + // Check if the current line starts with prefix `p`. + peekln := func(p string) bool { + return bytes.HasPrefix(line, []byte(p)) + } + // Get an "owned" copy of the current line. + cloneln := func() []byte { + ln := make([]byte, len(line)) + copy(ln, line) + return ln + } + // Scan through all lines of identity file. Lines with a known prefix + // are copied out of the scanner's buffer. All others are ignored. + for scanln() { + switch { + case peekln("ssh"): + ident.Certs.SSH = cloneln() + case peekln("@cert-authority"): + ident.CACerts.SSH = append(ident.CACerts.SSH, cloneln()) + case peekln("-----BEGIN"): + // Current line marks the beginning of a PEM block. Consume all + // lines until a corresponding END is found. + var pemBlock []byte + for { + pemBlock = append(pemBlock, line...) + pemBlock = append(pemBlock, '\n') + if peekln("-----END") { + break + } + if !scanln() { + // If scanner has terminated in the middle of a PEM block, either + // the reader encountered an error, or the PEM block is a fragment. + if err := scanner.Err(); err != nil { + return nil, trace.Wrap(err) + } + return nil, trace.BadParameter("invalid PEM block (fragment)") + } + } + // Decide where to place the pem block based on + // which pem blocks have already been found. + switch { + case ident.PrivateKey == nil: + ident.PrivateKey = pemBlock + case ident.Certs.TLS == nil: + ident.Certs.TLS = pemBlock + default: + ident.CACerts.TLS = append(ident.CACerts.TLS, pemBlock) + } + } + } + if err := scanner.Err(); err != nil { + return nil, trace.Wrap(err) + } + return &ident, nil +} diff --git a/lib/defaults/defaults.go b/lib/defaults/defaults.go index 99eba901a1514..6d87ab129a0e2 100644 --- a/lib/defaults/defaults.go +++ b/lib/defaults/defaults.go @@ -368,6 +368,11 @@ const ( // certificate rotations, by default to set to maximum allowed user // cert duration RotationGracePeriod = MaxCertDuration + // PendingAccessDuration defines the expiry of a pending access request. + PendingAccessDuration = time.Hour + // MaxAccessDuration defines the maximum time for which an access request + // can be active. + MaxAccessDuration = MaxCertDuration ) // list of roles teleport service can run as: diff --git a/lib/events/api.go b/lib/events/api.go index 527385bd233a2..a0eda28d820a9 100644 --- a/lib/events/api.go +++ b/lib/events/api.go @@ -139,6 +139,17 @@ const ( // UserConnector is the connector used to create the user. UserConnector = "connector" + // AccessRequestCreateEvent is emitted when a new access request is created. + AccessRequestCreateEvent = "access_request.create" + // AccessRequestUpdateEvent is emitted when a request's state is updated. + AccessRequestUpdateEvent = "access_request.update" + // AccessRequestUpdateBy indicates the user that updated the request state. + AccessRequestUpdateBy = "updated_by" + // AccessRequestState is the state of a request. + AccessRequestState = "state" + // AccessRequestID is the ID of an access request. + AccessRequestID = "id" + // ExecEvent is an exec command executed by script or user on // the server side ExecEvent = "exec" diff --git a/lib/events/codes.go b/lib/events/codes.go index 694a4b5c00b42..4229e29ddadd1 100644 --- a/lib/events/codes.go +++ b/lib/events/codes.go @@ -150,6 +150,15 @@ var ( Name: AuthAttemptEvent, Code: AuthAttemptFailureCode, } + // AccessRequestCreated is emitted when an access request is created. + AccessRequestCreated = Event{ + Name: AccessRequestCreateEvent, + Code: AccessRequestCreateCode, + } + AccessRequestUpdated = Event{ + Name: AccessRequestUpdateEvent, + Code: AccessRequestUpdateCode, + } ) var ( @@ -203,4 +212,8 @@ var ( ClientDisconnectCode = "T3006I" // AuthAttemptFailureCode is the auth attempt failure event code. AuthAttemptFailureCode = "T3007W" + // AccessRequestCreateCode is the the access request creation code. + AccessRequestCreateCode = "T5000I" + // AccessRequestUpdateCode is the access request state update code. + AccessRequestUpdateCode = "T5001I" ) diff --git a/lib/services/access_request.go b/lib/services/access_request.go new file mode 100644 index 0000000000000..4c46f5d33ba17 --- /dev/null +++ b/lib/services/access_request.go @@ -0,0 +1,508 @@ +/* +Copyright 2019 Gravitational, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package services + +import ( + "fmt" + "time" + + "github.com/gravitational/teleport/lib/utils" + + "github.com/gravitational/trace" + + "github.com/jonboulle/clockwork" + "github.com/pborman/uuid" +) + +// RequestIDs is a collection of IDs for privelege escalation requests. +type RequestIDs struct { + AccessRequests []string `json:"access_requests,omitempty"` +} + +func (r *RequestIDs) Marshal() ([]byte, error) { + data, err := utils.FastMarshal(r) + if err != nil { + return nil, trace.Wrap(err) + } + return data, nil +} + +func (r *RequestIDs) Unmarshal(data []byte) error { + if err := utils.FastUnmarshal(data, r); err != nil { + return trace.Wrap(err) + } + return trace.Wrap(r.Check()) +} + +func (r *RequestIDs) Check() error { + for _, id := range r.AccessRequests { + if uuid.Parse(id) == nil { + return trace.BadParameter("invalid request id %q", id) + } + } + return nil +} + +func (r *RequestIDs) IsEmpty() bool { + return len(r.AccessRequests) < 1 +} + +// stateVariants allows iteration of the expected variants +// of RequestState. +var stateVariants = [4]RequestState{ + RequestState_NONE, + RequestState_PENDING, + RequestState_APPROVED, + RequestState_DENIED, +} + +// Parse attempts to interpret a value as a string representation +// of a RequestState. +func (s *RequestState) Parse(val string) error { + for _, state := range stateVariants { + if state.String() == val { + *s = state + return nil + } + } + return trace.BadParameter("unknown request state: %q", val) +} + +// key values for map encoding of request filter +const ( + keyID = "id" + keyUser = "user" + keyState = "state" +) + +func (f *AccessRequestFilter) IntoMap() map[string]string { + m := make(map[string]string) + if f.ID != "" { + m[keyID] = f.ID + } + if f.User != "" { + m[keyUser] = f.User + } + if !f.State.IsNone() { + m[keyState] = f.State.String() + } + return m +} + +func (f *AccessRequestFilter) FromMap(m map[string]string) error { + for key, val := range m { + switch key { + case keyID: + f.ID = val + case keyUser: + f.User = val + case keyState: + if err := f.State.Parse(val); err != nil { + return trace.Wrap(err) + } + default: + return trace.BadParameter("unknown filter key %s", key) + } + } + return nil +} + +// Match checks if a given access request matches this filter. +func (f *AccessRequestFilter) Match(req AccessRequest) bool { + if f.ID != "" && req.GetName() != f.ID { + return false + } + if f.User != "" && req.GetUser() != f.User { + return false + } + if !f.State.IsNone() && req.GetState() != f.State { + return false + } + return true +} + +func (f *AccessRequestFilter) Equals(o AccessRequestFilter) bool { + return f.ID == o.ID && f.User == o.User && f.State == o.State +} + +// DynamicAccess is a service which manages dynamic RBAC. +type DynamicAccess interface { + // CreateAccessRequest stores a new access request. + CreateAccessRequest(AccessRequest) error + // SetAccessRequestState updates the state of an existing access request. + SetAccessRequestState(reqID string, state RequestState) error + // GetAccessRequest gets an access request by name (uuid). + GetAccessRequest(string) (AccessRequest, error) + // GetAccessRequests gets all currently active access requests. + GetAccessRequests(AccessRequestFilter) ([]AccessRequest, error) + // DeleteAccessRequest deletes an access request. + DeleteAccessRequest(string) error +} + +// AccessRequest is a request for temporarily granted roles +type AccessRequest interface { + Resource + // GetUser gets the name of the requesting user + GetUser() string + // GetRoles gets the roles being requested by the user + GetRoles() []string + // GetState gets the current state of the request + GetState() RequestState + // SetState sets the approval state of the request + SetState(RequestState) error + // GetCreationTime gets the time at which the request was + // originally registered with the auth server. + GetCreationTime() time.Time + // SetCreationTime sets the creation time of the request. + SetCreationTime(time.Time) + // GetAccessExpiry gets the upper limit for which this request + // may be considered active. + GetAccessExpiry() time.Time + // SetAccessExpiry sets the upper limit for which this request + // may be considered active. + SetAccessExpiry(time.Time) + // CheckAndSetDefaults validates the access request and + // supplies default values where appropriate. + CheckAndSetDefaults() error + // Equals checks equality between access request values. + Equals(AccessRequest) bool +} + +func (s RequestState) IsNone() bool { + return s == RequestState_NONE +} + +func (s RequestState) IsPending() bool { + return s == RequestState_PENDING +} + +func (s RequestState) IsApproved() bool { + return s == RequestState_APPROVED +} + +func (s RequestState) IsDenied() bool { + return s == RequestState_DENIED +} + +// NewAccessRequest assembled an AccessReqeust resource. +func NewAccessRequest(user string, roles ...string) (AccessRequest, error) { + req := AccessRequestV3{ + Kind: KindAccessRequest, + Version: V3, + Metadata: Metadata{ + Name: uuid.New(), + }, + Spec: AccessRequestSpecV3{ + User: user, + Roles: roles, + State: RequestState_PENDING, + }, + } + if err := req.CheckAndSetDefaults(); err != nil { + return nil, trace.Wrap(err) + } + return &req, nil +} + +type UserAndRoleGetter interface { + UserGetter + RoleGetter +} + +func ValidateAccessRequest(getter UserAndRoleGetter, req AccessRequest) error { + user, err := getter.GetUser(req.GetUser(), false) + if err != nil { + return trace.Wrap(err) + } + type rstate struct { + allowed bool + denied bool + } + roleStates := make(map[string]rstate, len(req.GetRoles())) + for _, r := range req.GetRoles() { + roleStates[r] = rstate{false, false} + } + for _, roleName := range user.GetRoles() { + role, err := getter.GetRole(roleName) + if err != nil { + return trace.Wrap(err) + } + Allow: + for _, r := range role.GetAccessRequestConditions(Allow).Roles { + s, ok := roleStates[r] + if !ok { + continue Allow + } + s.allowed = true + roleStates[r] = s + } + Deny: + for _, r := range role.GetAccessRequestConditions(Deny).Roles { + s, ok := roleStates[r] + if !ok { + continue Deny + } + s.denied = true + roleStates[r] = s + } + } + for roleName, roleState := range roleStates { + if roleState.denied || !roleState.allowed { + return trace.BadParameter("user %q cannot request role %q", req.GetUser(), roleName) + } + } + return nil +} + +func (r *AccessRequestV3) GetUser() string { + return r.Spec.User +} + +func (r *AccessRequestV3) GetRoles() []string { + return r.Spec.Roles +} + +func (r *AccessRequestV3) GetState() RequestState { + return r.Spec.State +} + +func (r *AccessRequestV3) SetState(state RequestState) error { + if r.Spec.State.IsDenied() { + if state.IsDenied() { + return nil + } + return trace.BadParameter("cannot set request-state %q (already denied)", state.String()) + } + r.Spec.State = state + return nil +} + +func (r *AccessRequestV3) GetCreationTime() time.Time { + return r.Spec.Created +} + +func (r *AccessRequestV3) SetCreationTime(t time.Time) { + r.Spec.Created = t +} + +func (r *AccessRequestV3) GetAccessExpiry() time.Time { + return r.Spec.Expires +} + +func (r *AccessRequestV3) SetAccessExpiry(expiry time.Time) { + r.Spec.Expires = expiry +} + +func (r *AccessRequestV3) CheckAndSetDefaults() error { + if err := r.Metadata.CheckAndSetDefaults(); err != nil { + return trace.Wrap(err) + } + if r.GetState().IsNone() { + r.SetState(RequestState_PENDING) + } + if err := r.Check(); err != nil { + return trace.Wrap(err) + } + return nil +} + +func (r *AccessRequestV3) Check() error { + if r.Kind == "" { + return trace.BadParameter("access request kind not set") + } + if r.Version == "" { + return trace.BadParameter("access request version not set") + } + if r.GetName() == "" { + return trace.BadParameter("access request id not set") + } + if uuid.Parse(r.GetName()) == nil { + return trace.BadParameter("invalid access request id %q", r.GetName()) + } + if r.GetUser() == "" { + return trace.BadParameter("access request user name not set") + } + if len(r.GetRoles()) < 1 { + return trace.BadParameter("access request does not specify any roles") + } + return nil +} + +func (r *AccessRequestV3) Equals(other AccessRequest) bool { + o, ok := other.(*AccessRequestV3) + if !ok { + return false + } + if r.GetName() != o.GetName() { + return false + } + return r.Spec.Equals(&o.Spec) +} + +func (s *AccessRequestSpecV3) Equals(other *AccessRequestSpecV3) bool { + if s.User != other.User { + return false + } + if len(s.Roles) != len(other.Roles) { + return false + } + for i, role := range s.Roles { + if role != other.Roles[i] { + return false + } + } + if s.Created != other.Created { + return false + } + if s.Expires != other.Expires { + return false + } + return s.State == other.State +} + +type AccessRequestMarshaler interface { + MarshalAccessRequest(req AccessRequest, opts ...MarshalOption) ([]byte, error) + UnmarshalAccessRequest(bytes []byte, opts ...MarshalOption) (AccessRequest, error) +} + +type accessRequestMarshaler struct{} + +func (r *accessRequestMarshaler) MarshalAccessRequest(req AccessRequest, opts ...MarshalOption) ([]byte, error) { + cfg, err := collectOptions(opts) + if err != nil { + return nil, trace.Wrap(err) + } + switch r := req.(type) { + case *AccessRequestV3: + if !cfg.PreserveResourceID { + // avoid modifying the original object + // to prevent unexpected data races + cp := *r + cp.SetResourceID(0) + r = &cp + } + return utils.FastMarshal(r) + default: + return nil, trace.BadParameter("unrecognized access request type: %T", req) + } +} + +func (r *accessRequestMarshaler) UnmarshalAccessRequest(data []byte, opts ...MarshalOption) (AccessRequest, error) { + cfg, err := collectOptions(opts) + if err != nil { + return nil, trace.Wrap(err) + } + var req AccessRequestV3 + if cfg.SkipValidation { + if err := utils.FastUnmarshal(data, &req); err != nil { + return nil, trace.Wrap(err) + } + } else { + if err := utils.UnmarshalWithSchema(GetAccessRequestSchema(), &req, data); err != nil { + return nil, trace.Wrap(err) + } + } + if err := req.CheckAndSetDefaults(); err != nil { + return nil, trace.Wrap(err) + } + if cfg.ID != 0 { + req.SetResourceID(cfg.ID) + } + if !cfg.Expires.IsZero() { + req.SetExpiry(cfg.Expires) + } + return &req, nil +} + +var accessRequestMarshalerInstance AccessRequestMarshaler = &accessRequestMarshaler{} + +func GetAccessRequestMarshaler() AccessRequestMarshaler { + marshalerMutex.Lock() + defer marshalerMutex.Unlock() + return accessRequestMarshalerInstance +} + +const AccessRequestSpecSchema = `{ + "type": "object", + "additionalProperties": false, + "properties": { + "user": { "type": "string" }, + "roles": { + "type": "array", + "items": { "type": "string" } + }, + "state": { "type": "integer" }, + "created": { "type": "string" }, + "expires": { "type": "string" } + } +}` + +func GetAccessRequestSchema() string { + return fmt.Sprintf(V2SchemaTemplate, MetadataSchema, AccessRequestSpecSchema, DefaultDefinitions) +} + +func (r *AccessRequestV3) GetKind() string { + return r.Kind +} + +func (r *AccessRequestV3) GetSubKind() string { + return r.SubKind +} + +func (r *AccessRequestV3) SetSubKind(subKind string) { + r.SubKind = subKind +} + +func (r *AccessRequestV3) GetVersion() string { + return r.Version +} + +func (r *AccessRequestV3) GetName() string { + return r.Metadata.Name +} + +func (r *AccessRequestV3) SetName(name string) { + r.Metadata.Name = name +} + +func (r *AccessRequestV3) Expiry() time.Time { + return r.Metadata.Expiry() +} + +func (r *AccessRequestV3) SetExpiry(expiry time.Time) { + r.Metadata.SetExpiry(expiry) +} + +func (r *AccessRequestV3) SetTTL(clock clockwork.Clock, ttl time.Duration) { + r.Metadata.SetTTL(clock, ttl) +} + +func (r *AccessRequestV3) GetMetadata() Metadata { + return r.Metadata +} + +func (r *AccessRequestV3) GetResourceID() int64 { + return r.Metadata.GetID() +} + +func (r *AccessRequestV3) SetResourceID(id int64) { + r.Metadata.SetID(id) +} + +func (r *AccessRequestV3) String() string { + return fmt.Sprintf("AccessRequest(user=%v,roles=%+v)", r.Spec.User, r.Spec.Roles) +} diff --git a/lib/services/access_request_test.go b/lib/services/access_request_test.go new file mode 100644 index 0000000000000..5a73f08dbc2c6 --- /dev/null +++ b/lib/services/access_request_test.go @@ -0,0 +1,129 @@ +/* +Copyright 2019 Gravitational, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package services + +import ( + "fmt" + + "github.com/gravitational/teleport/lib/utils" + + . "gopkg.in/check.v1" +) + +type AccessRequestSuite struct { +} + +var _ = Suite(&AccessRequestSuite{}) +var _ = fmt.Printf + +func (s *AccessRequestSuite) SetUpSuite(c *C) { + utils.InitLoggerForTests() +} + +// TestRequestMarshaling verifies that marshaling/unmarshaling access requests +// works as expected (failures likely indicate a problem with json schema). +func (s *AccessRequestSuite) TestRequestMarshaling(c *C) { + req1, err := NewAccessRequest("some-user", "role-1", "role-2") + c.Assert(err, IsNil) + + marshaled, err := GetAccessRequestMarshaler().MarshalAccessRequest(req1) + c.Assert(err, IsNil) + + req2, err := GetAccessRequestMarshaler().UnmarshalAccessRequest(marshaled) + c.Assert(err, IsNil) + + if !req1.Equals(req2) { + c.Errorf("unexpected inequality %+v <---> %+v", req1, req2) + } +} + +// TestRequestFilterMatching verifies expected matching behavior for AccessRequestFilter. +func (s *AccessRequestSuite) TestRequestFilterMatching(c *C) { + reqA, err := NewAccessRequest("alice", "role-a") + c.Assert(err, IsNil) + + reqB, err := NewAccessRequest("bob", "role-b") + c.Assert(err, IsNil) + + testCases := []struct { + user string + id string + matchA bool + matchB bool + }{ + {"", "", true, true}, + {"alice", "", true, false}, + {"", reqA.GetName(), true, false}, + {"bob", reqA.GetName(), false, false}, + {"carol", "", false, false}, + } + for _, tc := range testCases { + m := AccessRequestFilter{ + User: tc.user, + ID: tc.id, + } + if m.Match(reqA) != tc.matchA { + c.Errorf("bad filter behavior (a) %+v", tc) + } + if m.Match(reqB) != tc.matchB { + c.Errorf("bad filter behavior (b) %+v", tc) + } + } +} + +// TestRequestFilterConversion verifies that filters convert to and from +// maps correctly. +func (s *AccessRequestSuite) TestRequestFilterConversion(c *C) { + testCases := []struct { + f AccessRequestFilter + m map[string]string + }{ + { + AccessRequestFilter{User: "alice", ID: "foo", State: RequestState_PENDING}, + map[string]string{"user": "alice", "id": "foo", "state": "PENDING"}, + }, + { + AccessRequestFilter{User: "bob"}, + map[string]string{"user": "bob"}, + }, + { + AccessRequestFilter{}, + map[string]string{}, + }, + } + for _, tc := range testCases { + + if m := tc.f.IntoMap(); !utils.StringMapsEqual(m, tc.m) { + c.Errorf("bad map encoding: expected %+v, got %+v", tc.m, m) + } + var f AccessRequestFilter + if err := f.FromMap(tc.m); err != nil { + c.Errorf("failed to parse %+v: %s", tc.m, err) + } + if !f.Equals(tc.f) { + c.Errorf("bad map decoding: expected %+v, got %+v", tc.f, f) + } + } + badMaps := []map[string]string{ + {"food": "carrots"}, + {"state": "homesick"}, + } + for _, m := range badMaps { + var f AccessRequestFilter + c.Assert(f.FromMap(m), NotNil) + } +} diff --git a/lib/services/authority.go b/lib/services/authority.go index c8fd60164edfe..dafe46f14facc 100644 --- a/lib/services/authority.go +++ b/lib/services/authority.go @@ -111,6 +111,9 @@ type UserCertParams struct { RouteToCluster string // Traits hold claim data used to populate a role at runtime. Traits wrappers.Traits + // ActiveRequests tracks privilege escalation requests applied during + // certificate construction. + ActiveRequests RequestIDs } // CertRoles defines certificate roles diff --git a/lib/services/events.go b/lib/services/events.go index ea77527a9584f..326a60b675a94 100644 --- a/lib/services/events.go +++ b/lib/services/events.go @@ -48,6 +48,9 @@ type WatchKind struct { Name string // LoadSecrets specifies whether to load secrets LoadSecrets bool + // Filter supplies custom event filter parameters that differ by + // resource (e.g. "state":"pending" for access requests). + Filter map[string]string } // Event represents an event that happened in the backend diff --git a/lib/services/local/dynamic_access.go b/lib/services/local/dynamic_access.go new file mode 100644 index 0000000000000..5bad7632f05f5 --- /dev/null +++ b/lib/services/local/dynamic_access.go @@ -0,0 +1,164 @@ +/* +Copyright 2019 Gravitational, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package local + +import ( + "bytes" + "context" + + "github.com/gravitational/teleport/lib/backend" + "github.com/gravitational/teleport/lib/services" + + "github.com/gravitational/trace" +) + +// DynamicAccessService manages dynamic RBAC +type DynamicAccessService struct { + backend.Backend +} + +// NewDynamicAccessService returns new dynamic access service instance +func NewDynamicAccessService(backend backend.Backend) *AccessService { + return &AccessService{Backend: backend} +} + +func (s *AccessService) CreateAccessRequest(req services.AccessRequest) error { + if err := req.CheckAndSetDefaults(); err != nil { + return trace.Wrap(err) + } + item, err := itemFromAccessRequest(req) + if err != nil { + return trace.Wrap(err) + } + if _, err := s.Create(context.TODO(), item); err != nil { + return trace.Wrap(err) + } + return nil +} + +func (s *AccessService) SetAccessRequestState(name string, state services.RequestState) error { + item, err := s.Get(context.TODO(), accessRequestKey(name)) + if err != nil { + if trace.IsNotFound(err) { + return trace.NotFound("cannot set state of access request %q (not found)", name) + } + return trace.Wrap(err) + } + req, err := itemToAccessRequest(*item) + if err != nil { + return trace.Wrap(err) + } + if err := req.SetState(state); err != nil { + return trace.Wrap(err) + } + // approved requests should have a resource expiry which matches + // the underlying access expiry. + if state.IsApproved() { + req.SetExpiry(req.GetAccessExpiry()) + } + newItem, err := itemFromAccessRequest(req) + if err != nil { + return trace.Wrap(err) + } + if _, err := s.CompareAndSwap(context.TODO(), *item, newItem); err != nil { + return trace.Wrap(err) + } + return nil +} + +func (s *AccessService) GetAccessRequest(name string) (services.AccessRequest, error) { + item, err := s.Get(context.TODO(), accessRequestKey(name)) + if err != nil { + if trace.IsNotFound(err) { + return nil, trace.NotFound("access request %q not found", name) + } + return nil, trace.Wrap(err) + } + req, err := itemToAccessRequest(*item) + if err != nil { + return nil, trace.Wrap(err) + } + return req, nil +} + +func (s *AccessService) GetAccessRequests(filter services.AccessRequestFilter) ([]services.AccessRequest, error) { + result, err := s.GetRange(context.TODO(), backend.Key(accessRequestsPrefix), backend.RangeEnd(backend.Key(accessRequestsPrefix)), backend.NoLimit) + if err != nil { + return nil, trace.Wrap(err) + } + var requests []services.AccessRequest + for _, item := range result.Items { + if !bytes.HasSuffix(item.Key, []byte(paramsPrefix)) { + continue + } + req, err := itemToAccessRequest(item) + if err != nil { + return nil, trace.Wrap(err) + } + if !filter.Match(req) { + // TODO(fspmarshall): optimize filtering to + // avoid full query/iteration in some cases. + continue + } + requests = append(requests, req) + } + return requests, nil +} + +func (s *AccessService) DeleteAccessRequest(name string) error { + err := s.Delete(context.TODO(), accessRequestKey(name)) + if err != nil { + if trace.IsNotFound(err) { + return trace.NotFound("cannot delete access request %q (not found)", name) + } + return trace.Wrap(err) + } + return nil +} + +func itemFromAccessRequest(req services.AccessRequest) (backend.Item, error) { + value, err := services.GetAccessRequestMarshaler().MarshalAccessRequest(req) + if err != nil { + return backend.Item{}, trace.Wrap(err) + } + return backend.Item{ + Key: accessRequestKey(req.GetName()), + Value: value, + Expires: req.Expiry(), + ID: req.GetResourceID(), + }, nil +} + +func itemToAccessRequest(item backend.Item) (services.AccessRequest, error) { + req, err := services.GetAccessRequestMarshaler().UnmarshalAccessRequest( + item.Value, + services.WithResourceID(item.ID), + services.WithExpires(item.Expires), + ) + if err != nil { + return nil, trace.Wrap(err) + } + return req, nil +} + +func accessRequestKey(name string) []byte { + return backend.Key(accessRequestsPrefix, name, paramsPrefix) +} + +const ( + accessRequestsPrefix = "access_requests" +) diff --git a/lib/services/local/events.go b/lib/services/local/events.go index af6288b1b5803..a84da7a367064 100644 --- a/lib/services/local/events.go +++ b/lib/services/local/events.go @@ -82,6 +82,12 @@ func (e *EventsService) NewWatcher(ctx context.Context, watch services.Watch) (s parser = newTunnelConnectionParser() case services.KindReverseTunnel: parser = newReverseTunnelParser() + case services.KindAccessRequest: + p, err := newAccessRequestParser(kind.Filter) + if err != nil { + return nil, trace.Wrap(err) + } + parser = p default: return nil, trace.BadParameter("watcher on object kind %v is not supported", kind) } @@ -134,6 +140,10 @@ func (w *watcher) parseEvent(e backend.Event) (*services.Event, error) { if err != nil { return nil, trace.Wrap(err) } + // if resource is nil, then it was well-formed but is being filtered out. + if resource == nil { + return nil, nil + } return &services.Event{Type: e.Type, Resource: resource}, nil } } @@ -157,6 +167,10 @@ func (w *watcher) forwardEvents() { } continue } + // event is being filtered out + if converted == nil { + continue + } select { case w.eventsC <- *converted: case <-w.backendWatcher.Done(): @@ -485,6 +499,56 @@ func (p *roleParser) parse(event backend.Event) (services.Resource, error) { } } +func newAccessRequestParser(m map[string]string) (*accessRequestParser, error) { + var filter services.AccessRequestFilter + if err := filter.FromMap(m); err != nil { + return nil, trace.Wrap(err) + } + return &accessRequestParser{ + filter: filter, + matchPrefix: backend.Key(accessRequestsPrefix), + matchSuffix: backend.Key(paramsPrefix), + }, nil +} + +type accessRequestParser struct { + filter services.AccessRequestFilter + matchPrefix []byte + matchSuffix []byte +} + +func (p *accessRequestParser) prefix() []byte { + return p.matchPrefix +} + +func (p *accessRequestParser) match(key []byte) bool { + if !bytes.HasPrefix(key, p.matchPrefix) { + return false + } + if !bytes.HasSuffix(key, p.matchSuffix) { + return false + } + return true +} + +func (p *accessRequestParser) parse(event backend.Event) (services.Resource, error) { + switch event.Type { + case backend.OpDelete: + return resourceHeader(event, services.KindAccessRequest, services.V3, 1) + case backend.OpPut: + req, err := itemToAccessRequest(event.Item) + if err != nil { + return nil, trace.Wrap(err) + } + if !p.filter.Match(req) { + return nil, nil + } + return req, nil + default: + return nil, trace.BadParameter("event %v is not supported", event.Type) + } +} + func newUserParser() *userParser { return &userParser{ matchPrefix: backend.Key(webPrefix, usersPrefix), diff --git a/lib/services/resource.go b/lib/services/resource.go index 0344bb882a743..869ae4ae9dd7e 100644 --- a/lib/services/resource.go +++ b/lib/services/resource.go @@ -62,6 +62,9 @@ const ( // KindRole is a role resource KindRole = "role" + // KindAccessRequest is an AccessReqeust resource + KindAccessRequest = "access_request" + // KindOIDC is OIDC connector resource KindOIDC = "oidc" diff --git a/lib/services/role.go b/lib/services/role.go index 10ec5b2c47a72..60a201fc2170b 100644 --- a/lib/services/role.go +++ b/lib/services/role.go @@ -86,7 +86,7 @@ func RoleNameForCertAuthority(name string) string { } // NewAdminRole is the default admin role for all local users if another role -// is not explicitly assigned (Enterprise only). +// is not explicitly assigned (this role applies to all users in OSS version). func NewAdminRole() Role { role := &RoleV3{ Kind: KindRole, @@ -265,6 +265,11 @@ type Role interface { GetKubeGroups(RoleConditionType) []string // SetKubeGroups sets kubernetes groups for allow or deny condition. SetKubeGroups(RoleConditionType, []string) + + // GetAccessRequestConditions gets allow/deny conditions for access requests. + GetAccessRequestConditions(RoleConditionType) AccessRequestConditions + // SetAccessRequestConditions sets allow/deny conditions for access requests. + SetAccessRequestConditions(RoleConditionType, AccessRequestConditions) } // ApplyTraits applies the passed in traits to any variables within the role @@ -516,6 +521,27 @@ func (r *RoleV3) SetKubeGroups(rct RoleConditionType, groups []string) { } } +// GetAccessRequestConditions gets conditions for access requests. +func (r *RoleV3) GetAccessRequestConditions(rct RoleConditionType) AccessRequestConditions { + cond := r.Spec.Deny.Request + if rct == Allow { + cond = r.Spec.Allow.Request + } + if cond == nil { + return AccessRequestConditions{} + } + return *cond +} + +// SetAccessRequestConditions sets allow/deny conditions for access requests. +func (r *RoleV3) SetAccessRequestConditions(rct RoleConditionType, cond AccessRequestConditions) { + if rct == Allow { + r.Spec.Allow.Request = &cond + } else { + r.Spec.Deny.Request = &cond + } +} + // GetNamespaces gets a list of namespaces this role is allowed or denied access to. func (r *RoleV3) GetNamespaces(rct RoleConditionType) []string { if rct == Allow { @@ -2198,6 +2224,16 @@ const RoleSpecV3SchemaDefinitions = ` "type": "array", "items": { "type": "string" } }, + "request": { + "type": "object", + "additionalProperties": false, + "properties": { + "roles": { + "type": "array", + "items": { "type": "string" } + } + } + }, "rules": { "type": "array", "items": { diff --git a/lib/services/types.pb.go b/lib/services/types.pb.go index d1b79397158a3..1398a1699fd64 100644 --- a/lib/services/types.pb.go +++ b/lib/services/types.pb.go @@ -30,6 +30,36 @@ var _ = time.Kitchen // proto package needs to be updated. const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package +// RequestState represents the state of a request for escalated privilege. +type RequestState int32 + +const ( + RequestState_NONE RequestState = 0 + RequestState_PENDING RequestState = 1 + RequestState_APPROVED RequestState = 2 + RequestState_DENIED RequestState = 3 +) + +var RequestState_name = map[int32]string{ + 0: "NONE", + 1: "PENDING", + 2: "APPROVED", + 3: "DENIED", +} +var RequestState_value = map[string]int32{ + "NONE": 0, + "PENDING": 1, + "APPROVED": 2, + "DENIED": 3, +} + +func (x RequestState) String() string { + return proto.EnumName(RequestState_name, int32(x)) +} +func (RequestState) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_types_1f32999e8058ec6f, []int{0} +} + type KeepAlive struct { // ServerName is a server name to keep alive ServerName string `protobuf:"bytes,1,opt,name=ServerName,proto3" json:"server_name"` @@ -48,7 +78,7 @@ func (m *KeepAlive) Reset() { *m = KeepAlive{} } func (m *KeepAlive) String() string { return proto.CompactTextString(m) } func (*KeepAlive) ProtoMessage() {} func (*KeepAlive) Descriptor() ([]byte, []int) { - return fileDescriptor_types_f8fbcac97a7a4b42, []int{0} + return fileDescriptor_types_1f32999e8058ec6f, []int{0} } func (m *KeepAlive) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -101,7 +131,7 @@ func (m *Metadata) Reset() { *m = Metadata{} } func (m *Metadata) String() string { return proto.CompactTextString(m) } func (*Metadata) ProtoMessage() {} func (*Metadata) Descriptor() ([]byte, []int) { - return fileDescriptor_types_f8fbcac97a7a4b42, []int{1} + return fileDescriptor_types_1f32999e8058ec6f, []int{1} } func (m *Metadata) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -160,7 +190,7 @@ type Rotation struct { func (m *Rotation) Reset() { *m = Rotation{} } func (*Rotation) ProtoMessage() {} func (*Rotation) Descriptor() ([]byte, []int) { - return fileDescriptor_types_f8fbcac97a7a4b42, []int{2} + return fileDescriptor_types_1f32999e8058ec6f, []int{2} } func (m *Rotation) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -207,7 +237,7 @@ func (m *RotationSchedule) Reset() { *m = RotationSchedule{} } func (m *RotationSchedule) String() string { return proto.CompactTextString(m) } func (*RotationSchedule) ProtoMessage() {} func (*RotationSchedule) Descriptor() ([]byte, []int) { - return fileDescriptor_types_f8fbcac97a7a4b42, []int{3} + return fileDescriptor_types_1f32999e8058ec6f, []int{3} } func (m *RotationSchedule) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -256,7 +286,7 @@ func (m *ResourceHeader) Reset() { *m = ResourceHeader{} } func (m *ResourceHeader) String() string { return proto.CompactTextString(m) } func (*ResourceHeader) ProtoMessage() {} func (*ResourceHeader) Descriptor() ([]byte, []int) { - return fileDescriptor_types_f8fbcac97a7a4b42, []int{4} + return fileDescriptor_types_1f32999e8058ec6f, []int{4} } func (m *ResourceHeader) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -305,7 +335,7 @@ type ServerV2 struct { func (m *ServerV2) Reset() { *m = ServerV2{} } func (*ServerV2) ProtoMessage() {} func (*ServerV2) Descriptor() ([]byte, []int) { - return fileDescriptor_types_f8fbcac97a7a4b42, []int{5} + return fileDescriptor_types_1f32999e8058ec6f, []int{5} } func (m *ServerV2) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -358,7 +388,7 @@ func (m *ServerSpecV2) Reset() { *m = ServerSpecV2{} } func (m *ServerSpecV2) String() string { return proto.CompactTextString(m) } func (*ServerSpecV2) ProtoMessage() {} func (*ServerSpecV2) Descriptor() ([]byte, []int) { - return fileDescriptor_types_f8fbcac97a7a4b42, []int{6} + return fileDescriptor_types_1f32999e8058ec6f, []int{6} } func (m *ServerSpecV2) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -405,7 +435,7 @@ func (m *CommandLabelV2) Reset() { *m = CommandLabelV2{} } func (m *CommandLabelV2) String() string { return proto.CompactTextString(m) } func (*CommandLabelV2) ProtoMessage() {} func (*CommandLabelV2) Descriptor() ([]byte, []int) { - return fileDescriptor_types_f8fbcac97a7a4b42, []int{7} + return fileDescriptor_types_1f32999e8058ec6f, []int{7} } func (m *CommandLabelV2) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -449,7 +479,7 @@ func (m *TLSKeyPair) Reset() { *m = TLSKeyPair{} } func (m *TLSKeyPair) String() string { return proto.CompactTextString(m) } func (*TLSKeyPair) ProtoMessage() {} func (*TLSKeyPair) Descriptor() ([]byte, []int) { - return fileDescriptor_types_f8fbcac97a7a4b42, []int{8} + return fileDescriptor_types_1f32999e8058ec6f, []int{8} } func (m *TLSKeyPair) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -498,7 +528,7 @@ type CertAuthorityV2 struct { func (m *CertAuthorityV2) Reset() { *m = CertAuthorityV2{} } func (*CertAuthorityV2) ProtoMessage() {} func (*CertAuthorityV2) Descriptor() ([]byte, []int) { - return fileDescriptor_types_f8fbcac97a7a4b42, []int{9} + return fileDescriptor_types_1f32999e8058ec6f, []int{9} } func (m *CertAuthorityV2) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -561,7 +591,7 @@ func (m *CertAuthoritySpecV2) Reset() { *m = CertAuthoritySpecV2{} } func (m *CertAuthoritySpecV2) String() string { return proto.CompactTextString(m) } func (*CertAuthoritySpecV2) ProtoMessage() {} func (*CertAuthoritySpecV2) Descriptor() ([]byte, []int) { - return fileDescriptor_types_f8fbcac97a7a4b42, []int{10} + return fileDescriptor_types_1f32999e8058ec6f, []int{10} } func (m *CertAuthoritySpecV2) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -606,7 +636,7 @@ func (m *RoleMapping) Reset() { *m = RoleMapping{} } func (m *RoleMapping) String() string { return proto.CompactTextString(m) } func (*RoleMapping) ProtoMessage() {} func (*RoleMapping) Descriptor() ([]byte, []int) { - return fileDescriptor_types_f8fbcac97a7a4b42, []int{11} + return fileDescriptor_types_1f32999e8058ec6f, []int{11} } func (m *RoleMapping) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -653,7 +683,7 @@ type ProvisionTokenV1 struct { func (m *ProvisionTokenV1) Reset() { *m = ProvisionTokenV1{} } func (*ProvisionTokenV1) ProtoMessage() {} func (*ProvisionTokenV1) Descriptor() ([]byte, []int) { - return fileDescriptor_types_f8fbcac97a7a4b42, []int{12} + return fileDescriptor_types_1f32999e8058ec6f, []int{12} } func (m *ProvisionTokenV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -702,7 +732,7 @@ type ProvisionTokenV2 struct { func (m *ProvisionTokenV2) Reset() { *m = ProvisionTokenV2{} } func (*ProvisionTokenV2) ProtoMessage() {} func (*ProvisionTokenV2) Descriptor() ([]byte, []int) { - return fileDescriptor_types_f8fbcac97a7a4b42, []int{13} + return fileDescriptor_types_1f32999e8058ec6f, []int{13} } func (m *ProvisionTokenV2) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -746,7 +776,7 @@ func (m *ProvisionTokenSpecV2) Reset() { *m = ProvisionTokenSpecV2{} } func (m *ProvisionTokenSpecV2) String() string { return proto.CompactTextString(m) } func (*ProvisionTokenSpecV2) ProtoMessage() {} func (*ProvisionTokenSpecV2) Descriptor() ([]byte, []int) { - return fileDescriptor_types_f8fbcac97a7a4b42, []int{14} + return fileDescriptor_types_1f32999e8058ec6f, []int{14} } func (m *ProvisionTokenSpecV2) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -795,7 +825,7 @@ type StaticTokensV2 struct { func (m *StaticTokensV2) Reset() { *m = StaticTokensV2{} } func (*StaticTokensV2) ProtoMessage() {} func (*StaticTokensV2) Descriptor() ([]byte, []int) { - return fileDescriptor_types_f8fbcac97a7a4b42, []int{15} + return fileDescriptor_types_1f32999e8058ec6f, []int{15} } func (m *StaticTokensV2) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -838,7 +868,7 @@ func (m *StaticTokensSpecV2) Reset() { *m = StaticTokensSpecV2{} } func (m *StaticTokensSpecV2) String() string { return proto.CompactTextString(m) } func (*StaticTokensSpecV2) ProtoMessage() {} func (*StaticTokensSpecV2) Descriptor() ([]byte, []int) { - return fileDescriptor_types_f8fbcac97a7a4b42, []int{16} + return fileDescriptor_types_1f32999e8058ec6f, []int{16} } func (m *StaticTokensSpecV2) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -887,7 +917,7 @@ type ClusterNameV2 struct { func (m *ClusterNameV2) Reset() { *m = ClusterNameV2{} } func (*ClusterNameV2) ProtoMessage() {} func (*ClusterNameV2) Descriptor() ([]byte, []int) { - return fileDescriptor_types_f8fbcac97a7a4b42, []int{17} + return fileDescriptor_types_1f32999e8058ec6f, []int{17} } func (m *ClusterNameV2) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -930,7 +960,7 @@ func (m *ClusterNameSpecV2) Reset() { *m = ClusterNameSpecV2{} } func (m *ClusterNameSpecV2) String() string { return proto.CompactTextString(m) } func (*ClusterNameSpecV2) ProtoMessage() {} func (*ClusterNameSpecV2) Descriptor() ([]byte, []int) { - return fileDescriptor_types_f8fbcac97a7a4b42, []int{18} + return fileDescriptor_types_1f32999e8058ec6f, []int{18} } func (m *ClusterNameSpecV2) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -979,7 +1009,7 @@ type ClusterConfigV3 struct { func (m *ClusterConfigV3) Reset() { *m = ClusterConfigV3{} } func (*ClusterConfigV3) ProtoMessage() {} func (*ClusterConfigV3) Descriptor() ([]byte, []int) { - return fileDescriptor_types_f8fbcac97a7a4b42, []int{19} + return fileDescriptor_types_1f32999e8058ec6f, []int{19} } func (m *ClusterConfigV3) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1042,7 +1072,7 @@ func (m *ClusterConfigSpecV3) Reset() { *m = ClusterConfigSpecV3{} } func (m *ClusterConfigSpecV3) String() string { return proto.CompactTextString(m) } func (*ClusterConfigSpecV3) ProtoMessage() {} func (*ClusterConfigSpecV3) Descriptor() ([]byte, []int) { - return fileDescriptor_types_f8fbcac97a7a4b42, []int{20} + return fileDescriptor_types_1f32999e8058ec6f, []int{20} } func (m *ClusterConfigSpecV3) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1095,7 +1125,7 @@ func (m *AuditConfig) Reset() { *m = AuditConfig{} } func (m *AuditConfig) String() string { return proto.CompactTextString(m) } func (*AuditConfig) ProtoMessage() {} func (*AuditConfig) Descriptor() ([]byte, []int) { - return fileDescriptor_types_f8fbcac97a7a4b42, []int{21} + return fileDescriptor_types_1f32999e8058ec6f, []int{21} } func (m *AuditConfig) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1145,7 +1175,7 @@ func (m *Namespace) Reset() { *m = Namespace{} } func (m *Namespace) String() string { return proto.CompactTextString(m) } func (*Namespace) ProtoMessage() {} func (*Namespace) Descriptor() ([]byte, []int) { - return fileDescriptor_types_f8fbcac97a7a4b42, []int{22} + return fileDescriptor_types_1f32999e8058ec6f, []int{22} } func (m *Namespace) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1185,7 +1215,7 @@ func (m *NamespaceSpec) Reset() { *m = NamespaceSpec{} } func (m *NamespaceSpec) String() string { return proto.CompactTextString(m) } func (*NamespaceSpec) ProtoMessage() {} func (*NamespaceSpec) Descriptor() ([]byte, []int) { - return fileDescriptor_types_f8fbcac97a7a4b42, []int{23} + return fileDescriptor_types_1f32999e8058ec6f, []int{23} } func (m *NamespaceSpec) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1214,6 +1244,151 @@ func (m *NamespaceSpec) XXX_DiscardUnknown() { var xxx_messageInfo_NamespaceSpec proto.InternalMessageInfo +// AccessRequest represents an access request resource specification +type AccessRequestV3 struct { + // Kind is a resource kind + Kind string `protobuf:"bytes,1,opt,name=Kind,proto3" json:"kind"` + // SubKind is an optional resource sub kind, used in some resources + SubKind string `protobuf:"bytes,2,opt,name=SubKind,proto3" json:"sub_kind,omitempty"` + // Version is version + Version string `protobuf:"bytes,3,opt,name=Version,proto3" json:"version"` + // Metadata is AccessRequest metadata + Metadata Metadata `protobuf:"bytes,4,opt,name=Metadata" json:"metadata"` + // Spec is an AccessReqeust specification + Spec AccessRequestSpecV3 `protobuf:"bytes,5,opt,name=Spec" json:"spec"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *AccessRequestV3) Reset() { *m = AccessRequestV3{} } +func (*AccessRequestV3) ProtoMessage() {} +func (*AccessRequestV3) Descriptor() ([]byte, []int) { + return fileDescriptor_types_1f32999e8058ec6f, []int{24} +} +func (m *AccessRequestV3) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *AccessRequestV3) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_AccessRequestV3.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalTo(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (dst *AccessRequestV3) XXX_Merge(src proto.Message) { + xxx_messageInfo_AccessRequestV3.Merge(dst, src) +} +func (m *AccessRequestV3) XXX_Size() int { + return m.Size() +} +func (m *AccessRequestV3) XXX_DiscardUnknown() { + xxx_messageInfo_AccessRequestV3.DiscardUnknown(m) +} + +var xxx_messageInfo_AccessRequestV3 proto.InternalMessageInfo + +// AccessRequestSpec is the specification for AccessRequest +type AccessRequestSpecV3 struct { + // User is the name of the user to whom the roles will be applied. + User string `protobuf:"bytes,1,opt,name=User,proto3" json:"user"` + // Roles is the name of the roles being requested. + Roles []string `protobuf:"bytes,2,rep,name=Roles" json:"roles"` + // State is the current state of this access request. + State RequestState `protobuf:"varint,3,opt,name=State,proto3,enum=services.RequestState" json:"state,omitempty"` + // Created encodes the time at which the request was registered with the auth server. + Created time.Time `protobuf:"bytes,4,opt,name=Created,stdtime" json:"created,omitempty"` + // Expires constrains the maximum lifetime of any login session for which this request is active. + Expires time.Time `protobuf:"bytes,5,opt,name=Expires,stdtime" json:"expires,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *AccessRequestSpecV3) Reset() { *m = AccessRequestSpecV3{} } +func (m *AccessRequestSpecV3) String() string { return proto.CompactTextString(m) } +func (*AccessRequestSpecV3) ProtoMessage() {} +func (*AccessRequestSpecV3) Descriptor() ([]byte, []int) { + return fileDescriptor_types_1f32999e8058ec6f, []int{25} +} +func (m *AccessRequestSpecV3) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *AccessRequestSpecV3) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_AccessRequestSpecV3.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalTo(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (dst *AccessRequestSpecV3) XXX_Merge(src proto.Message) { + xxx_messageInfo_AccessRequestSpecV3.Merge(dst, src) +} +func (m *AccessRequestSpecV3) XXX_Size() int { + return m.Size() +} +func (m *AccessRequestSpecV3) XXX_DiscardUnknown() { + xxx_messageInfo_AccessRequestSpecV3.DiscardUnknown(m) +} + +var xxx_messageInfo_AccessRequestSpecV3 proto.InternalMessageInfo + +// AccessRequestFilter encodes filter params for access requests. +type AccessRequestFilter struct { + // ID specifies a request ID if set. + ID string `protobuf:"bytes,1,opt,name=ID,proto3" json:"id"` + // User specifies a username if set. + User string `protobuf:"bytes,2,opt,name=User,proto3" json:"user"` + // RequestState filters for requests in a specific state. + State RequestState `protobuf:"varint,3,opt,name=State,proto3,enum=services.RequestState" json:"state"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *AccessRequestFilter) Reset() { *m = AccessRequestFilter{} } +func (m *AccessRequestFilter) String() string { return proto.CompactTextString(m) } +func (*AccessRequestFilter) ProtoMessage() {} +func (*AccessRequestFilter) Descriptor() ([]byte, []int) { + return fileDescriptor_types_1f32999e8058ec6f, []int{26} +} +func (m *AccessRequestFilter) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *AccessRequestFilter) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_AccessRequestFilter.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalTo(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (dst *AccessRequestFilter) XXX_Merge(src proto.Message) { + xxx_messageInfo_AccessRequestFilter.Merge(dst, src) +} +func (m *AccessRequestFilter) XXX_Size() int { + return m.Size() +} +func (m *AccessRequestFilter) XXX_DiscardUnknown() { + xxx_messageInfo_AccessRequestFilter.DiscardUnknown(m) +} + +var xxx_messageInfo_AccessRequestFilter proto.InternalMessageInfo + // RoleV3 represents role resource specification type RoleV3 struct { // Kind is a resource kind @@ -1234,7 +1409,7 @@ type RoleV3 struct { func (m *RoleV3) Reset() { *m = RoleV3{} } func (*RoleV3) ProtoMessage() {} func (*RoleV3) Descriptor() ([]byte, []int) { - return fileDescriptor_types_f8fbcac97a7a4b42, []int{24} + return fileDescriptor_types_1f32999e8058ec6f, []int{27} } func (m *RoleV3) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1280,7 +1455,7 @@ func (m *RoleSpecV3) Reset() { *m = RoleSpecV3{} } func (m *RoleSpecV3) String() string { return proto.CompactTextString(m) } func (*RoleSpecV3) ProtoMessage() {} func (*RoleSpecV3) Descriptor() ([]byte, []int) { - return fileDescriptor_types_f8fbcac97a7a4b42, []int{25} + return fileDescriptor_types_1f32999e8058ec6f, []int{28} } func (m *RoleSpecV3) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1337,7 +1512,7 @@ func (m *RoleOptions) Reset() { *m = RoleOptions{} } func (m *RoleOptions) String() string { return proto.CompactTextString(m) } func (*RoleOptions) ProtoMessage() {} func (*RoleOptions) Descriptor() ([]byte, []int) { - return fileDescriptor_types_f8fbcac97a7a4b42, []int{26} + return fileDescriptor_types_1f32999e8058ec6f, []int{29} } func (m *RoleOptions) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1380,17 +1555,18 @@ type RoleConditions struct { // construct used for access control. Rules []Rule `protobuf:"bytes,4,rep,name=Rules" json:"rules,omitempty"` // KubeGroups is a list of kubernetes groups - KubeGroups []string `protobuf:"bytes,5,rep,name=KubeGroups" json:"kubernetes_groups,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + KubeGroups []string `protobuf:"bytes,5,rep,name=KubeGroups" json:"kubernetes_groups,omitempty"` + Request *AccessRequestConditions `protobuf:"bytes,6,opt,name=Request" json:"request,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } func (m *RoleConditions) Reset() { *m = RoleConditions{} } func (m *RoleConditions) String() string { return proto.CompactTextString(m) } func (*RoleConditions) ProtoMessage() {} func (*RoleConditions) Descriptor() ([]byte, []int) { - return fileDescriptor_types_f8fbcac97a7a4b42, []int{27} + return fileDescriptor_types_1f32999e8058ec6f, []int{30} } func (m *RoleConditions) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1419,6 +1595,48 @@ func (m *RoleConditions) XXX_DiscardUnknown() { var xxx_messageInfo_RoleConditions proto.InternalMessageInfo +// AccessRequestConditions is a matcher for allow/deny restrictions on access-requests. +type AccessRequestConditions struct { + // Roles is the name of roles which will match the request rule. + Roles []string `protobuf:"bytes,1,rep,name=Roles" json:"roles,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *AccessRequestConditions) Reset() { *m = AccessRequestConditions{} } +func (m *AccessRequestConditions) String() string { return proto.CompactTextString(m) } +func (*AccessRequestConditions) ProtoMessage() {} +func (*AccessRequestConditions) Descriptor() ([]byte, []int) { + return fileDescriptor_types_1f32999e8058ec6f, []int{31} +} +func (m *AccessRequestConditions) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *AccessRequestConditions) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_AccessRequestConditions.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalTo(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (dst *AccessRequestConditions) XXX_Merge(src proto.Message) { + xxx_messageInfo_AccessRequestConditions.Merge(dst, src) +} +func (m *AccessRequestConditions) XXX_Size() int { + return m.Size() +} +func (m *AccessRequestConditions) XXX_DiscardUnknown() { + xxx_messageInfo_AccessRequestConditions.DiscardUnknown(m) +} + +var xxx_messageInfo_AccessRequestConditions proto.InternalMessageInfo + // Rule represents allow or deny rule that is executed to check // if user or service have access to resource type Rule struct { @@ -1439,7 +1657,7 @@ func (m *Rule) Reset() { *m = Rule{} } func (m *Rule) String() string { return proto.CompactTextString(m) } func (*Rule) ProtoMessage() {} func (*Rule) Descriptor() ([]byte, []int) { - return fileDescriptor_types_f8fbcac97a7a4b42, []int{28} + return fileDescriptor_types_1f32999e8058ec6f, []int{32} } func (m *Rule) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1481,7 +1699,7 @@ func (m *BoolValue) Reset() { *m = BoolValue{} } func (m *BoolValue) String() string { return proto.CompactTextString(m) } func (*BoolValue) ProtoMessage() {} func (*BoolValue) Descriptor() ([]byte, []int) { - return fileDescriptor_types_f8fbcac97a7a4b42, []int{29} + return fileDescriptor_types_1f32999e8058ec6f, []int{33} } func (m *BoolValue) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1530,7 +1748,7 @@ type UserV2 struct { func (m *UserV2) Reset() { *m = UserV2{} } func (*UserV2) ProtoMessage() {} func (*UserV2) Descriptor() ([]byte, []int) { - return fileDescriptor_types_f8fbcac97a7a4b42, []int{30} + return fileDescriptor_types_1f32999e8058ec6f, []int{34} } func (m *UserV2) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1593,7 +1811,7 @@ func (m *UserSpecV2) Reset() { *m = UserSpecV2{} } func (m *UserSpecV2) String() string { return proto.CompactTextString(m) } func (*UserSpecV2) ProtoMessage() {} func (*UserSpecV2) Descriptor() ([]byte, []int) { - return fileDescriptor_types_f8fbcac97a7a4b42, []int{31} + return fileDescriptor_types_1f32999e8058ec6f, []int{35} } func (m *UserSpecV2) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1638,7 +1856,7 @@ type ExternalIdentity struct { func (m *ExternalIdentity) Reset() { *m = ExternalIdentity{} } func (*ExternalIdentity) ProtoMessage() {} func (*ExternalIdentity) Descriptor() ([]byte, []int) { - return fileDescriptor_types_f8fbcac97a7a4b42, []int{32} + return fileDescriptor_types_1f32999e8058ec6f, []int{36} } func (m *ExternalIdentity) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1686,7 +1904,7 @@ func (m *LoginStatus) Reset() { *m = LoginStatus{} } func (m *LoginStatus) String() string { return proto.CompactTextString(m) } func (*LoginStatus) ProtoMessage() {} func (*LoginStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_types_f8fbcac97a7a4b42, []int{33} + return fileDescriptor_types_1f32999e8058ec6f, []int{37} } func (m *LoginStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1731,7 +1949,7 @@ type CreatedBy struct { func (m *CreatedBy) Reset() { *m = CreatedBy{} } func (*CreatedBy) ProtoMessage() {} func (*CreatedBy) Descriptor() ([]byte, []int) { - return fileDescriptor_types_f8fbcac97a7a4b42, []int{34} + return fileDescriptor_types_1f32999e8058ec6f, []int{38} } func (m *CreatedBy) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1777,7 +1995,7 @@ func (m *U2FRegistrationData) Reset() { *m = U2FRegistrationData{} } func (m *U2FRegistrationData) String() string { return proto.CompactTextString(m) } func (*U2FRegistrationData) ProtoMessage() {} func (*U2FRegistrationData) Descriptor() ([]byte, []int) { - return fileDescriptor_types_f8fbcac97a7a4b42, []int{35} + return fileDescriptor_types_1f32999e8058ec6f, []int{39} } func (m *U2FRegistrationData) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1825,7 +2043,7 @@ func (m *LocalAuthSecrets) Reset() { *m = LocalAuthSecrets{} } func (m *LocalAuthSecrets) String() string { return proto.CompactTextString(m) } func (*LocalAuthSecrets) ProtoMessage() {} func (*LocalAuthSecrets) Descriptor() ([]byte, []int) { - return fileDescriptor_types_f8fbcac97a7a4b42, []int{36} + return fileDescriptor_types_1f32999e8058ec6f, []int{40} } func (m *LocalAuthSecrets) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1871,7 +2089,7 @@ func (m *ConnectorRef) Reset() { *m = ConnectorRef{} } func (m *ConnectorRef) String() string { return proto.CompactTextString(m) } func (*ConnectorRef) ProtoMessage() {} func (*ConnectorRef) Descriptor() ([]byte, []int) { - return fileDescriptor_types_f8fbcac97a7a4b42, []int{37} + return fileDescriptor_types_1f32999e8058ec6f, []int{41} } func (m *ConnectorRef) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1913,7 +2131,7 @@ func (m *UserRef) Reset() { *m = UserRef{} } func (m *UserRef) String() string { return proto.CompactTextString(m) } func (*UserRef) ProtoMessage() {} func (*UserRef) Descriptor() ([]byte, []int) { - return fileDescriptor_types_f8fbcac97a7a4b42, []int{38} + return fileDescriptor_types_1f32999e8058ec6f, []int{42} } func (m *UserRef) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1963,7 +2181,7 @@ func (m *ReverseTunnelV2) Reset() { *m = ReverseTunnelV2{} } func (m *ReverseTunnelV2) String() string { return proto.CompactTextString(m) } func (*ReverseTunnelV2) ProtoMessage() {} func (*ReverseTunnelV2) Descriptor() ([]byte, []int) { - return fileDescriptor_types_f8fbcac97a7a4b42, []int{39} + return fileDescriptor_types_1f32999e8058ec6f, []int{43} } func (m *ReverseTunnelV2) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2010,7 +2228,7 @@ func (m *ReverseTunnelSpecV2) Reset() { *m = ReverseTunnelSpecV2{} } func (m *ReverseTunnelSpecV2) String() string { return proto.CompactTextString(m) } func (*ReverseTunnelSpecV2) ProtoMessage() {} func (*ReverseTunnelSpecV2) Descriptor() ([]byte, []int) { - return fileDescriptor_types_f8fbcac97a7a4b42, []int{40} + return fileDescriptor_types_1f32999e8058ec6f, []int{44} } func (m *ReverseTunnelSpecV2) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2059,7 +2277,7 @@ type TunnelConnectionV2 struct { func (m *TunnelConnectionV2) Reset() { *m = TunnelConnectionV2{} } func (*TunnelConnectionV2) ProtoMessage() {} func (*TunnelConnectionV2) Descriptor() ([]byte, []int) { - return fileDescriptor_types_f8fbcac97a7a4b42, []int{41} + return fileDescriptor_types_1f32999e8058ec6f, []int{45} } func (m *TunnelConnectionV2) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2107,7 +2325,7 @@ func (m *TunnelConnectionSpecV2) Reset() { *m = TunnelConnectionSpecV2{} func (m *TunnelConnectionSpecV2) String() string { return proto.CompactTextString(m) } func (*TunnelConnectionSpecV2) ProtoMessage() {} func (*TunnelConnectionSpecV2) Descriptor() ([]byte, []int) { - return fileDescriptor_types_f8fbcac97a7a4b42, []int{42} + return fileDescriptor_types_1f32999e8058ec6f, []int{46} } func (m *TunnelConnectionSpecV2) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2163,10 +2381,14 @@ func init() { proto.RegisterType((*AuditConfig)(nil), "services.AuditConfig") proto.RegisterType((*Namespace)(nil), "services.Namespace") proto.RegisterType((*NamespaceSpec)(nil), "services.NamespaceSpec") + proto.RegisterType((*AccessRequestV3)(nil), "services.AccessRequestV3") + proto.RegisterType((*AccessRequestSpecV3)(nil), "services.AccessRequestSpecV3") + proto.RegisterType((*AccessRequestFilter)(nil), "services.AccessRequestFilter") proto.RegisterType((*RoleV3)(nil), "services.RoleV3") proto.RegisterType((*RoleSpecV3)(nil), "services.RoleSpecV3") proto.RegisterType((*RoleOptions)(nil), "services.RoleOptions") proto.RegisterType((*RoleConditions)(nil), "services.RoleConditions") + proto.RegisterType((*AccessRequestConditions)(nil), "services.AccessRequestConditions") proto.RegisterType((*Rule)(nil), "services.Rule") proto.RegisterType((*BoolValue)(nil), "services.BoolValue") proto.RegisterType((*UserV2)(nil), "services.UserV2") @@ -2182,6 +2404,7 @@ func init() { proto.RegisterType((*ReverseTunnelSpecV2)(nil), "services.ReverseTunnelSpecV2") proto.RegisterType((*TunnelConnectionV2)(nil), "services.TunnelConnectionV2") proto.RegisterType((*TunnelConnectionSpecV2)(nil), "services.TunnelConnectionSpecV2") + proto.RegisterEnum("services.RequestState", RequestState_name, RequestState_value) } func (m *KeepAlive) Marshal() (dAtA []byte, err error) { size := m.Size() @@ -3456,7 +3679,7 @@ func (m *NamespaceSpec) MarshalTo(dAtA []byte) (int, error) { return i, nil } -func (m *RoleV3) Marshal() (dAtA []byte, err error) { +func (m *AccessRequestV3) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalTo(dAtA) @@ -3466,7 +3689,7 @@ func (m *RoleV3) Marshal() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *RoleV3) MarshalTo(dAtA []byte) (int, error) { +func (m *AccessRequestV3) MarshalTo(dAtA []byte) (int, error) { var i int _ = i var l int @@ -3511,7 +3734,7 @@ func (m *RoleV3) MarshalTo(dAtA []byte) (int, error) { return i, nil } -func (m *RoleSpecV3) Marshal() (dAtA []byte, err error) { +func (m *AccessRequestSpecV3) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalTo(dAtA) @@ -3521,42 +3744,60 @@ func (m *RoleSpecV3) Marshal() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *RoleSpecV3) MarshalTo(dAtA []byte) (int, error) { +func (m *AccessRequestSpecV3) MarshalTo(dAtA []byte) (int, error) { var i int _ = i var l int _ = l - dAtA[i] = 0xa + if len(m.User) > 0 { + dAtA[i] = 0xa + i++ + i = encodeVarintTypes(dAtA, i, uint64(len(m.User))) + i += copy(dAtA[i:], m.User) + } + if len(m.Roles) > 0 { + for _, s := range m.Roles { + dAtA[i] = 0x12 + i++ + l = len(s) + for l >= 1<<7 { + dAtA[i] = uint8(uint64(l)&0x7f | 0x80) + l >>= 7 + i++ + } + dAtA[i] = uint8(l) + i++ + i += copy(dAtA[i:], s) + } + } + if m.State != 0 { + dAtA[i] = 0x18 + i++ + i = encodeVarintTypes(dAtA, i, uint64(m.State)) + } + dAtA[i] = 0x22 i++ - i = encodeVarintTypes(dAtA, i, uint64(m.Options.Size())) - n32, err := m.Options.MarshalTo(dAtA[i:]) + i = encodeVarintTypes(dAtA, i, uint64(github_com_gogo_protobuf_types.SizeOfStdTime(m.Created))) + n32, err := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Created, dAtA[i:]) if err != nil { return 0, err } i += n32 - dAtA[i] = 0x12 + dAtA[i] = 0x2a i++ - i = encodeVarintTypes(dAtA, i, uint64(m.Allow.Size())) - n33, err := m.Allow.MarshalTo(dAtA[i:]) + i = encodeVarintTypes(dAtA, i, uint64(github_com_gogo_protobuf_types.SizeOfStdTime(m.Expires))) + n33, err := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Expires, dAtA[i:]) if err != nil { return 0, err } i += n33 - dAtA[i] = 0x1a - i++ - i = encodeVarintTypes(dAtA, i, uint64(m.Deny.Size())) - n34, err := m.Deny.MarshalTo(dAtA[i:]) - if err != nil { - return 0, err - } - i += n34 if m.XXX_unrecognized != nil { i += copy(dAtA[i:], m.XXX_unrecognized) } return i, nil } -func (m *RoleOptions) Marshal() (dAtA []byte, err error) { +func (m *AccessRequestFilter) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalTo(dAtA) @@ -3566,56 +3807,27 @@ func (m *RoleOptions) Marshal() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *RoleOptions) MarshalTo(dAtA []byte) (int, error) { +func (m *AccessRequestFilter) MarshalTo(dAtA []byte) (int, error) { var i int _ = i var l int _ = l - if m.ForwardAgent { - dAtA[i] = 0x8 - i++ - if m.ForwardAgent { - dAtA[i] = 1 - } else { - dAtA[i] = 0 - } - i++ - } - if m.MaxSessionTTL != 0 { - dAtA[i] = 0x10 - i++ - i = encodeVarintTypes(dAtA, i, uint64(m.MaxSessionTTL)) - } - if m.PortForwarding != nil { - dAtA[i] = 0x1a - i++ - i = encodeVarintTypes(dAtA, i, uint64(m.PortForwarding.Size())) - n35, err := m.PortForwarding.MarshalTo(dAtA[i:]) - if err != nil { - return 0, err - } - i += n35 - } - if len(m.CertificateFormat) > 0 { - dAtA[i] = 0x22 + if len(m.ID) > 0 { + dAtA[i] = 0xa i++ - i = encodeVarintTypes(dAtA, i, uint64(len(m.CertificateFormat))) - i += copy(dAtA[i:], m.CertificateFormat) + i = encodeVarintTypes(dAtA, i, uint64(len(m.ID))) + i += copy(dAtA[i:], m.ID) } - if m.ClientIdleTimeout != 0 { - dAtA[i] = 0x28 + if len(m.User) > 0 { + dAtA[i] = 0x12 i++ - i = encodeVarintTypes(dAtA, i, uint64(m.ClientIdleTimeout)) + i = encodeVarintTypes(dAtA, i, uint64(len(m.User))) + i += copy(dAtA[i:], m.User) } - if m.DisconnectExpiredCert { - dAtA[i] = 0x30 - i++ - if m.DisconnectExpiredCert { - dAtA[i] = 1 - } else { - dAtA[i] = 0 - } + if m.State != 0 { + dAtA[i] = 0x18 i++ + i = encodeVarintTypes(dAtA, i, uint64(m.State)) } if m.XXX_unrecognized != nil { i += copy(dAtA[i:], m.XXX_unrecognized) @@ -3623,7 +3835,7 @@ func (m *RoleOptions) MarshalTo(dAtA []byte) (int, error) { return i, nil } -func (m *RoleConditions) Marshal() (dAtA []byte, err error) { +func (m *RoleV3) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalTo(dAtA) @@ -3633,53 +3845,220 @@ func (m *RoleConditions) Marshal() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *RoleConditions) MarshalTo(dAtA []byte) (int, error) { +func (m *RoleV3) MarshalTo(dAtA []byte) (int, error) { var i int _ = i var l int _ = l - if len(m.Logins) > 0 { - for _, s := range m.Logins { - dAtA[i] = 0xa - i++ - l = len(s) - for l >= 1<<7 { - dAtA[i] = uint8(uint64(l)&0x7f | 0x80) - l >>= 7 - i++ - } - dAtA[i] = uint8(l) - i++ - i += copy(dAtA[i:], s) - } + if len(m.Kind) > 0 { + dAtA[i] = 0xa + i++ + i = encodeVarintTypes(dAtA, i, uint64(len(m.Kind))) + i += copy(dAtA[i:], m.Kind) } - if len(m.Namespaces) > 0 { - for _, s := range m.Namespaces { - dAtA[i] = 0x12 - i++ - l = len(s) - for l >= 1<<7 { - dAtA[i] = uint8(uint64(l)&0x7f | 0x80) - l >>= 7 - i++ - } - dAtA[i] = uint8(l) - i++ - i += copy(dAtA[i:], s) - } + if len(m.SubKind) > 0 { + dAtA[i] = 0x12 + i++ + i = encodeVarintTypes(dAtA, i, uint64(len(m.SubKind))) + i += copy(dAtA[i:], m.SubKind) } - dAtA[i] = 0x1a + if len(m.Version) > 0 { + dAtA[i] = 0x1a + i++ + i = encodeVarintTypes(dAtA, i, uint64(len(m.Version))) + i += copy(dAtA[i:], m.Version) + } + dAtA[i] = 0x22 i++ - i = encodeVarintTypes(dAtA, i, uint64(m.NodeLabels.Size())) - n36, err := m.NodeLabels.MarshalTo(dAtA[i:]) + i = encodeVarintTypes(dAtA, i, uint64(m.Metadata.Size())) + n34, err := m.Metadata.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n36 - if len(m.Rules) > 0 { - for _, msg := range m.Rules { - dAtA[i] = 0x22 - i++ + i += n34 + dAtA[i] = 0x2a + i++ + i = encodeVarintTypes(dAtA, i, uint64(m.Spec.Size())) + n35, err := m.Spec.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n35 + if m.XXX_unrecognized != nil { + i += copy(dAtA[i:], m.XXX_unrecognized) + } + return i, nil +} + +func (m *RoleSpecV3) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *RoleSpecV3) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + dAtA[i] = 0xa + i++ + i = encodeVarintTypes(dAtA, i, uint64(m.Options.Size())) + n36, err := m.Options.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n36 + dAtA[i] = 0x12 + i++ + i = encodeVarintTypes(dAtA, i, uint64(m.Allow.Size())) + n37, err := m.Allow.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n37 + dAtA[i] = 0x1a + i++ + i = encodeVarintTypes(dAtA, i, uint64(m.Deny.Size())) + n38, err := m.Deny.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n38 + if m.XXX_unrecognized != nil { + i += copy(dAtA[i:], m.XXX_unrecognized) + } + return i, nil +} + +func (m *RoleOptions) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *RoleOptions) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.ForwardAgent { + dAtA[i] = 0x8 + i++ + if m.ForwardAgent { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i++ + } + if m.MaxSessionTTL != 0 { + dAtA[i] = 0x10 + i++ + i = encodeVarintTypes(dAtA, i, uint64(m.MaxSessionTTL)) + } + if m.PortForwarding != nil { + dAtA[i] = 0x1a + i++ + i = encodeVarintTypes(dAtA, i, uint64(m.PortForwarding.Size())) + n39, err := m.PortForwarding.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n39 + } + if len(m.CertificateFormat) > 0 { + dAtA[i] = 0x22 + i++ + i = encodeVarintTypes(dAtA, i, uint64(len(m.CertificateFormat))) + i += copy(dAtA[i:], m.CertificateFormat) + } + if m.ClientIdleTimeout != 0 { + dAtA[i] = 0x28 + i++ + i = encodeVarintTypes(dAtA, i, uint64(m.ClientIdleTimeout)) + } + if m.DisconnectExpiredCert { + dAtA[i] = 0x30 + i++ + if m.DisconnectExpiredCert { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i++ + } + if m.XXX_unrecognized != nil { + i += copy(dAtA[i:], m.XXX_unrecognized) + } + return i, nil +} + +func (m *RoleConditions) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *RoleConditions) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if len(m.Logins) > 0 { + for _, s := range m.Logins { + dAtA[i] = 0xa + i++ + l = len(s) + for l >= 1<<7 { + dAtA[i] = uint8(uint64(l)&0x7f | 0x80) + l >>= 7 + i++ + } + dAtA[i] = uint8(l) + i++ + i += copy(dAtA[i:], s) + } + } + if len(m.Namespaces) > 0 { + for _, s := range m.Namespaces { + dAtA[i] = 0x12 + i++ + l = len(s) + for l >= 1<<7 { + dAtA[i] = uint8(uint64(l)&0x7f | 0x80) + l >>= 7 + i++ + } + dAtA[i] = uint8(l) + i++ + i += copy(dAtA[i:], s) + } + } + dAtA[i] = 0x1a + i++ + i = encodeVarintTypes(dAtA, i, uint64(m.NodeLabels.Size())) + n40, err := m.NodeLabels.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n40 + if len(m.Rules) > 0 { + for _, msg := range m.Rules { + dAtA[i] = 0x22 + i++ i = encodeVarintTypes(dAtA, i, uint64(msg.Size())) n, err := msg.MarshalTo(dAtA[i:]) if err != nil { @@ -3703,6 +4082,52 @@ func (m *RoleConditions) MarshalTo(dAtA []byte) (int, error) { i += copy(dAtA[i:], s) } } + if m.Request != nil { + dAtA[i] = 0x32 + i++ + i = encodeVarintTypes(dAtA, i, uint64(m.Request.Size())) + n41, err := m.Request.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n41 + } + if m.XXX_unrecognized != nil { + i += copy(dAtA[i:], m.XXX_unrecognized) + } + return i, nil +} + +func (m *AccessRequestConditions) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *AccessRequestConditions) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if len(m.Roles) > 0 { + for _, s := range m.Roles { + dAtA[i] = 0xa + i++ + l = len(s) + for l >= 1<<7 { + dAtA[i] = uint8(uint64(l)&0x7f | 0x80) + l >>= 7 + i++ + } + dAtA[i] = uint8(l) + i++ + i += copy(dAtA[i:], s) + } + } if m.XXX_unrecognized != nil { i += copy(dAtA[i:], m.XXX_unrecognized) } @@ -3848,19 +4273,19 @@ func (m *UserV2) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x22 i++ i = encodeVarintTypes(dAtA, i, uint64(m.Metadata.Size())) - n37, err := m.Metadata.MarshalTo(dAtA[i:]) + n42, err := m.Metadata.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n37 + i += n42 dAtA[i] = 0x2a i++ i = encodeVarintTypes(dAtA, i, uint64(m.Spec.Size())) - n38, err := m.Spec.MarshalTo(dAtA[i:]) + n43, err := m.Spec.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n38 + i += n43 if m.XXX_unrecognized != nil { i += copy(dAtA[i:], m.XXX_unrecognized) } @@ -3936,44 +4361,44 @@ func (m *UserSpecV2) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x2a i++ i = encodeVarintTypes(dAtA, i, uint64(m.Traits.Size())) - n39, err := m.Traits.MarshalTo(dAtA[i:]) + n44, err := m.Traits.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n39 + i += n44 dAtA[i] = 0x32 i++ i = encodeVarintTypes(dAtA, i, uint64(m.Status.Size())) - n40, err := m.Status.MarshalTo(dAtA[i:]) + n45, err := m.Status.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n40 + i += n45 dAtA[i] = 0x3a i++ i = encodeVarintTypes(dAtA, i, uint64(github_com_gogo_protobuf_types.SizeOfStdTime(m.Expires))) - n41, err := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Expires, dAtA[i:]) + n46, err := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Expires, dAtA[i:]) if err != nil { return 0, err } - i += n41 + i += n46 dAtA[i] = 0x42 i++ i = encodeVarintTypes(dAtA, i, uint64(m.CreatedBy.Size())) - n42, err := m.CreatedBy.MarshalTo(dAtA[i:]) + n47, err := m.CreatedBy.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n42 + i += n47 if m.LocalAuth != nil { dAtA[i] = 0x4a i++ i = encodeVarintTypes(dAtA, i, uint64(m.LocalAuth.Size())) - n43, err := m.LocalAuth.MarshalTo(dAtA[i:]) + n48, err := m.LocalAuth.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n43 + i += n48 } if m.XXX_unrecognized != nil { i += copy(dAtA[i:], m.XXX_unrecognized) @@ -4048,19 +4473,19 @@ func (m *LoginStatus) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x1a i++ i = encodeVarintTypes(dAtA, i, uint64(github_com_gogo_protobuf_types.SizeOfStdTime(m.LockedTime))) - n44, err := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.LockedTime, dAtA[i:]) + n49, err := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.LockedTime, dAtA[i:]) if err != nil { return 0, err } - i += n44 + i += n49 dAtA[i] = 0x22 i++ i = encodeVarintTypes(dAtA, i, uint64(github_com_gogo_protobuf_types.SizeOfStdTime(m.LockExpires))) - n45, err := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.LockExpires, dAtA[i:]) + n50, err := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.LockExpires, dAtA[i:]) if err != nil { return 0, err } - i += n45 + i += n50 if m.XXX_unrecognized != nil { i += copy(dAtA[i:], m.XXX_unrecognized) } @@ -4086,28 +4511,28 @@ func (m *CreatedBy) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintTypes(dAtA, i, uint64(m.Connector.Size())) - n46, err := m.Connector.MarshalTo(dAtA[i:]) + n51, err := m.Connector.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n46 + i += n51 } dAtA[i] = 0x12 i++ i = encodeVarintTypes(dAtA, i, uint64(github_com_gogo_protobuf_types.SizeOfStdTime(m.Time))) - n47, err := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Time, dAtA[i:]) + n52, err := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Time, dAtA[i:]) if err != nil { return 0, err } - i += n47 + i += n52 dAtA[i] = 0x1a i++ i = encodeVarintTypes(dAtA, i, uint64(m.User.Size())) - n48, err := m.User.MarshalTo(dAtA[i:]) + n53, err := m.User.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n48 + i += n53 if m.XXX_unrecognized != nil { i += copy(dAtA[i:], m.XXX_unrecognized) } @@ -4184,11 +4609,11 @@ func (m *LocalAuthSecrets) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x1a i++ i = encodeVarintTypes(dAtA, i, uint64(m.U2FRegistration.Size())) - n49, err := m.U2FRegistration.MarshalTo(dAtA[i:]) + n54, err := m.U2FRegistration.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n49 + i += n54 } if m.U2FCounter != 0 { dAtA[i] = 0x20 @@ -4303,19 +4728,19 @@ func (m *ReverseTunnelV2) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x22 i++ i = encodeVarintTypes(dAtA, i, uint64(m.Metadata.Size())) - n50, err := m.Metadata.MarshalTo(dAtA[i:]) + n55, err := m.Metadata.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n50 + i += n55 dAtA[i] = 0x2a i++ i = encodeVarintTypes(dAtA, i, uint64(m.Spec.Size())) - n51, err := m.Spec.MarshalTo(dAtA[i:]) + n56, err := m.Spec.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n51 + i += n56 if m.XXX_unrecognized != nil { i += copy(dAtA[i:], m.XXX_unrecognized) } @@ -4406,19 +4831,19 @@ func (m *TunnelConnectionV2) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x22 i++ i = encodeVarintTypes(dAtA, i, uint64(m.Metadata.Size())) - n52, err := m.Metadata.MarshalTo(dAtA[i:]) + n57, err := m.Metadata.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n52 + i += n57 dAtA[i] = 0x2a i++ i = encodeVarintTypes(dAtA, i, uint64(m.Spec.Size())) - n53, err := m.Spec.MarshalTo(dAtA[i:]) + n58, err := m.Spec.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n53 + i += n58 if m.XXX_unrecognized != nil { i += copy(dAtA[i:], m.XXX_unrecognized) } @@ -4455,11 +4880,11 @@ func (m *TunnelConnectionSpecV2) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x1a i++ i = encodeVarintTypes(dAtA, i, uint64(github_com_gogo_protobuf_types.SizeOfStdTime(m.LastHeartbeat))) - n54, err := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.LastHeartbeat, dAtA[i:]) + n59, err := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.LastHeartbeat, dAtA[i:]) if err != nil { return 0, err } - i += n54 + i += n59 if len(m.Type) > 0 { dAtA[i] = 0x22 i++ @@ -5068,7 +5493,7 @@ func (m *NamespaceSpec) Size() (n int) { return n } -func (m *RoleV3) Size() (n int) { +func (m *AccessRequestV3) Size() (n int) { var l int _ = l l = len(m.Kind) @@ -5093,14 +5518,25 @@ func (m *RoleV3) Size() (n int) { return n } -func (m *RoleSpecV3) Size() (n int) { +func (m *AccessRequestSpecV3) Size() (n int) { var l int _ = l - l = m.Options.Size() - n += 1 + l + sovTypes(uint64(l)) - l = m.Allow.Size() + l = len(m.User) + if l > 0 { + n += 1 + l + sovTypes(uint64(l)) + } + if len(m.Roles) > 0 { + for _, s := range m.Roles { + l = len(s) + n += 1 + l + sovTypes(uint64(l)) + } + } + if m.State != 0 { + n += 1 + sovTypes(uint64(m.State)) + } + l = github_com_gogo_protobuf_types.SizeOfStdTime(m.Created) n += 1 + l + sovTypes(uint64(l)) - l = m.Deny.Size() + l = github_com_gogo_protobuf_types.SizeOfStdTime(m.Expires) n += 1 + l + sovTypes(uint64(l)) if m.XXX_unrecognized != nil { n += len(m.XXX_unrecognized) @@ -5108,11 +5544,71 @@ func (m *RoleSpecV3) Size() (n int) { return n } -func (m *RoleOptions) Size() (n int) { +func (m *AccessRequestFilter) Size() (n int) { var l int _ = l - if m.ForwardAgent { - n += 2 + l = len(m.ID) + if l > 0 { + n += 1 + l + sovTypes(uint64(l)) + } + l = len(m.User) + if l > 0 { + n += 1 + l + sovTypes(uint64(l)) + } + if m.State != 0 { + n += 1 + sovTypes(uint64(m.State)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *RoleV3) Size() (n int) { + var l int + _ = l + l = len(m.Kind) + if l > 0 { + n += 1 + l + sovTypes(uint64(l)) + } + l = len(m.SubKind) + if l > 0 { + n += 1 + l + sovTypes(uint64(l)) + } + l = len(m.Version) + if l > 0 { + n += 1 + l + sovTypes(uint64(l)) + } + l = m.Metadata.Size() + n += 1 + l + sovTypes(uint64(l)) + l = m.Spec.Size() + n += 1 + l + sovTypes(uint64(l)) + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *RoleSpecV3) Size() (n int) { + var l int + _ = l + l = m.Options.Size() + n += 1 + l + sovTypes(uint64(l)) + l = m.Allow.Size() + n += 1 + l + sovTypes(uint64(l)) + l = m.Deny.Size() + n += 1 + l + sovTypes(uint64(l)) + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *RoleOptions) Size() (n int) { + var l int + _ = l + if m.ForwardAgent { + n += 2 } if m.MaxSessionTTL != 0 { n += 1 + sovTypes(uint64(m.MaxSessionTTL)) @@ -5166,6 +5662,25 @@ func (m *RoleConditions) Size() (n int) { n += 1 + l + sovTypes(uint64(l)) } } + if m.Request != nil { + l = m.Request.Size() + n += 1 + l + sovTypes(uint64(l)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *AccessRequestConditions) Size() (n int) { + var l int + _ = l + if len(m.Roles) > 0 { + for _, s := range m.Roles { + l = len(s) + n += 1 + l + sovTypes(uint64(l)) + } + } if m.XXX_unrecognized != nil { n += len(m.XXX_unrecognized) } @@ -9810,7 +10325,7 @@ func (m *NamespaceSpec) Unmarshal(dAtA []byte) error { } return nil } -func (m *RoleV3) Unmarshal(dAtA []byte) error { +func (m *AccessRequestV3) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -9833,10 +10348,10 @@ func (m *RoleV3) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: RoleV3: wiretype end group for non-group") + return fmt.Errorf("proto: AccessRequestV3: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: RoleV3: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: AccessRequestV3: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -10008,7 +10523,7 @@ func (m *RoleV3) Unmarshal(dAtA []byte) error { } return nil } -func (m *RoleSpecV3) Unmarshal(dAtA []byte) error { +func (m *AccessRequestSpecV3) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -10031,17 +10546,17 @@ func (m *RoleSpecV3) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: RoleSpecV3: wiretype end group for non-group") + return fmt.Errorf("proto: AccessRequestSpecV3: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: RoleSpecV3: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: AccessRequestSpecV3: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Options", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field User", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowTypes @@ -10051,25 +10566,72 @@ func (m *RoleSpecV3) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= (int(b) & 0x7F) << shift + stringLen |= (uint64(b) & 0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthTypes } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.Options.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } + m.User = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Allow", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Roles", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Roles = append(m.Roles, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field State", wireType) + } + m.State = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.State |= (RequestState(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Created", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -10093,13 +10655,13 @@ func (m *RoleSpecV3) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.Allow.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := github_com_gogo_protobuf_types.StdTimeUnmarshal(&m.Created, dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex - case 3: + case 5: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Deny", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Expires", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -10123,7 +10685,7 @@ func (m *RoleSpecV3) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.Deny.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := github_com_gogo_protobuf_types.StdTimeUnmarshal(&m.Expires, dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -10149,7 +10711,7 @@ func (m *RoleSpecV3) Unmarshal(dAtA []byte) error { } return nil } -func (m *RoleOptions) Unmarshal(dAtA []byte) error { +func (m *AccessRequestFilter) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -10172,56 +10734,17 @@ func (m *RoleOptions) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: RoleOptions: wiretype end group for non-group") + return fmt.Errorf("proto: AccessRequestFilter: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: RoleOptions: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: AccessRequestFilter: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field ForwardAgent", wireType) - } - var v int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTypes - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - v |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - m.ForwardAgent = Bool(v != 0) - case 2: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field MaxSessionTTL", wireType) - } - m.MaxSessionTTL = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTypes - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.MaxSessionTTL |= (Duration(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field PortForwarding", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ID", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowTypes @@ -10231,28 +10754,24 @@ func (m *RoleOptions) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= (int(b) & 0x7F) << shift + stringLen |= (uint64(b) & 0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthTypes } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex > l { return io.ErrUnexpectedEOF } - if m.PortForwarding == nil { - m.PortForwarding = &BoolOption{} - } - if err := m.PortForwarding.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } + m.ID = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 4: + case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field CertificateFormat", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field User", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -10277,32 +10796,13 @@ func (m *RoleOptions) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.CertificateFormat = string(dAtA[iNdEx:postIndex]) + m.User = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 5: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field ClientIdleTimeout", wireType) - } - m.ClientIdleTimeout = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTypes - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.ClientIdleTimeout |= (Duration(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - case 6: + case 3: if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field DisconnectExpiredCert", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field State", wireType) } - var v int + m.State = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowTypes @@ -10312,12 +10812,11 @@ func (m *RoleOptions) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - v |= (int(b) & 0x7F) << shift + m.State |= (RequestState(b) & 0x7F) << shift if b < 0x80 { break } } - m.DisconnectExpiredCert = Bool(v != 0) default: iNdEx = preIndex skippy, err := skipTypes(dAtA[iNdEx:]) @@ -10340,7 +10839,7 @@ func (m *RoleOptions) Unmarshal(dAtA []byte) error { } return nil } -func (m *RoleConditions) Unmarshal(dAtA []byte) error { +func (m *RoleV3) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -10363,15 +10862,15 @@ func (m *RoleConditions) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: RoleConditions: wiretype end group for non-group") + return fmt.Errorf("proto: RoleV3: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: RoleConditions: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: RoleV3: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Logins", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Kind", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -10396,11 +10895,11 @@ func (m *RoleConditions) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Logins = append(m.Logins, string(dAtA[iNdEx:postIndex])) + m.Kind = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Namespaces", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field SubKind", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -10425,13 +10924,13 @@ func (m *RoleConditions) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Namespaces = append(m.Namespaces, string(dAtA[iNdEx:postIndex])) + m.SubKind = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field NodeLabels", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Version", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowTypes @@ -10441,7 +10940,537 @@ func (m *RoleConditions) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= (int(b) & 0x7F) << shift + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Version = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Metadata", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Metadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Spec", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Spec.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTypes(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthTypes + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *RoleSpecV3) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: RoleSpecV3: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: RoleSpecV3: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Options", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Options.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Allow", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Allow.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Deny", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Deny.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTypes(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthTypes + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *RoleOptions) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: RoleOptions: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: RoleOptions: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field ForwardAgent", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.ForwardAgent = Bool(v != 0) + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field MaxSessionTTL", wireType) + } + m.MaxSessionTTL = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.MaxSessionTTL |= (Duration(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field PortForwarding", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.PortForwarding == nil { + m.PortForwarding = &BoolOption{} + } + if err := m.PortForwarding.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field CertificateFormat", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.CertificateFormat = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 5: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field ClientIdleTimeout", wireType) + } + m.ClientIdleTimeout = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.ClientIdleTimeout |= (Duration(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + case 6: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field DisconnectExpiredCert", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.DisconnectExpiredCert = Bool(v != 0) + default: + iNdEx = preIndex + skippy, err := skipTypes(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthTypes + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *RoleConditions) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: RoleConditions: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: RoleConditions: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Logins", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Logins = append(m.Logins, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Namespaces", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Namespaces = append(m.Namespaces, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field NodeLabels", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift if b < 0x80 { break } @@ -10517,6 +11546,119 @@ func (m *RoleConditions) Unmarshal(dAtA []byte) error { } m.KubeGroups = append(m.KubeGroups, string(dAtA[iNdEx:postIndex])) iNdEx = postIndex + case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Request", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Request == nil { + m.Request = &AccessRequestConditions{} + } + if err := m.Request.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTypes(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthTypes + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *AccessRequestConditions) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: AccessRequestConditions: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: AccessRequestConditions: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Roles", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Roles = append(m.Roles, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipTypes(dAtA[iNdEx:]) @@ -13046,226 +14188,239 @@ var ( ErrIntOverflowTypes = fmt.Errorf("proto: integer overflow") ) -func init() { proto.RegisterFile("types.proto", fileDescriptor_types_f8fbcac97a7a4b42) } - -var fileDescriptor_types_f8fbcac97a7a4b42 = []byte{ - // 3479 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xdc, 0x3a, 0x4d, 0x73, 0xdc, 0xc8, - 0x75, 0x9a, 0x2f, 0x72, 0xe6, 0x0d, 0x49, 0x51, 0x4d, 0x8a, 0x1a, 0x51, 0x5a, 0x81, 0x3b, 0xca, - 0xca, 0x52, 0x22, 0x93, 0x31, 0x95, 0x55, 0x59, 0x1b, 0x2b, 0xbb, 0x1c, 0x52, 0x1f, 0x34, 0x29, - 0x8b, 0x0b, 0x52, 0x74, 0xb9, 0xf2, 0x81, 0x60, 0x80, 0xe6, 0x10, 0x45, 0x0c, 0x30, 0x05, 0x34, - 0x28, 0xcd, 0xcd, 0x95, 0x1c, 0x52, 0x89, 0xab, 0x1c, 0xa7, 0x52, 0xae, 0x6c, 0x55, 0x72, 0xc8, - 0x35, 0x87, 0xe4, 0x9a, 0x43, 0x2a, 0xb7, 0x1c, 0x74, 0xf4, 0xd9, 0xe5, 0xc0, 0xc9, 0xe6, 0xe0, - 0xaa, 0xf9, 0x09, 0xba, 0x24, 0xd5, 0xaf, 0x1b, 0x40, 0x63, 0x66, 0x28, 0xce, 0x6e, 0x7c, 0xa1, - 0x4f, 0x1c, 0xbe, 0xaf, 0xee, 0xf7, 0xfa, 0xf5, 0xfb, 0x6a, 0x40, 0x9d, 0xf5, 0x7b, 0x34, 0x5c, - 0xed, 0x05, 0x3e, 0xf3, 0x49, 0x35, 0xa4, 0xc1, 0xa9, 0x63, 0xd1, 0x70, 0x79, 0xb1, 0xe3, 0x77, - 0x7c, 0x04, 0xae, 0xf1, 0x5f, 0x02, 0xbf, 0xac, 0x75, 0x7c, 0xbf, 0xe3, 0xd2, 0x35, 0xfc, 0xaf, - 0x1d, 0x1d, 0xad, 0x31, 0xa7, 0x4b, 0x43, 0x66, 0x76, 0x7b, 0x92, 0xe0, 0x71, 0xc7, 0x61, 0xc7, - 0x51, 0x7b, 0xd5, 0xf2, 0xbb, 0x6b, 0x9d, 0xc0, 0x3c, 0x75, 0x98, 0xc9, 0x1c, 0xdf, 0x33, 0xdd, - 0x35, 0x46, 0x5d, 0xda, 0xf3, 0x03, 0xb6, 0xe6, 0x3a, 0xed, 0xb5, 0xd7, 0x81, 0xd9, 0xeb, 0xd1, - 0x20, 0x4c, 0x7f, 0x08, 0xf6, 0xe6, 0x2f, 0x0a, 0x50, 0xdb, 0xa1, 0xb4, 0xb7, 0xe1, 0x3a, 0xa7, - 0x94, 0xac, 0x01, 0xec, 0xd3, 0xe0, 0x94, 0x06, 0xdf, 0x33, 0xbb, 0xb4, 0x51, 0x58, 0x29, 0xdc, - 0xad, 0xb5, 0x2e, 0x0f, 0x62, 0xad, 0x1e, 0x22, 0xd4, 0xf0, 0xcc, 0x2e, 0xd5, 0x15, 0x12, 0xf2, - 0x3b, 0x50, 0xe3, 0x7f, 0xc3, 0x9e, 0x69, 0xd1, 0x46, 0x11, 0xe9, 0x67, 0x07, 0xb1, 0x56, 0xf3, - 0x12, 0xa0, 0x9e, 0xe1, 0xc9, 0x1d, 0x98, 0xde, 0xa5, 0x66, 0x48, 0xb7, 0xb7, 0x1a, 0xa5, 0x95, - 0xc2, 0xdd, 0x52, 0x6b, 0x66, 0x10, 0x6b, 0x55, 0x97, 0x83, 0x0c, 0xc7, 0xd6, 0x13, 0x24, 0xd9, - 0x86, 0xe9, 0x27, 0x6f, 0x7a, 0x4e, 0x40, 0xc3, 0x46, 0x79, 0xa5, 0x70, 0xb7, 0xbe, 0xbe, 0xbc, - 0x2a, 0xac, 0xb0, 0x9a, 0x58, 0x61, 0xf5, 0x20, 0xb1, 0x42, 0x6b, 0xe1, 0x6d, 0xac, 0x5d, 0x1a, - 0xc4, 0xda, 0x34, 0x15, 0x2c, 0x3f, 0xf9, 0xa5, 0x56, 0xd0, 0x13, 0xfe, 0xe6, 0x5f, 0x95, 0xa0, - 0xfa, 0x82, 0x32, 0xd3, 0x36, 0x99, 0x49, 0x6e, 0x42, 0x59, 0xd1, 0xab, 0x3a, 0x88, 0xb5, 0x32, - 0x2a, 0x84, 0x50, 0x72, 0x7b, 0x54, 0x95, 0xca, 0x20, 0xd6, 0x0a, 0xdf, 0x54, 0x55, 0xf8, 0x7d, - 0xa8, 0x6f, 0xd1, 0xd0, 0x0a, 0x9c, 0x1e, 0x37, 0x32, 0xaa, 0x51, 0x6b, 0x5d, 0x1f, 0xc4, 0xda, - 0x55, 0x3b, 0x03, 0xdf, 0xf7, 0xbb, 0x0e, 0xa3, 0xdd, 0x1e, 0xeb, 0xeb, 0x2a, 0x35, 0xd9, 0x85, - 0xa9, 0x5d, 0xb3, 0x4d, 0xdd, 0xb0, 0x51, 0x59, 0x29, 0xdd, 0xad, 0xaf, 0xdf, 0x5a, 0x4d, 0x0e, - 0x7f, 0x35, 0xd9, 0xe3, 0xaa, 0x20, 0x78, 0xe2, 0xb1, 0xa0, 0xdf, 0x5a, 0x1c, 0xc4, 0xda, 0xbc, - 0x8b, 0x00, 0x45, 0xa4, 0x94, 0x41, 0xf6, 0x33, 0x2b, 0x4d, 0x9d, 0x6b, 0xa5, 0x0f, 0xde, 0xc6, - 0x5a, 0x61, 0x10, 0x6b, 0x57, 0xa4, 0x95, 0x32, 0x79, 0x39, 0x7b, 0x91, 0x15, 0x28, 0x6e, 0x6f, - 0x35, 0xa6, 0xf1, 0x74, 0xe6, 0x07, 0xb1, 0x36, 0xe3, 0xd8, 0xca, 0xd2, 0xc5, 0xed, 0xad, 0xe5, - 0x47, 0x50, 0x57, 0xf6, 0x48, 0xe6, 0xa1, 0x74, 0x42, 0xfb, 0xc2, 0xa4, 0x3a, 0xff, 0x49, 0x16, - 0xa1, 0x72, 0x6a, 0xba, 0x91, 0xb4, 0xa1, 0x2e, 0xfe, 0xf9, 0xa4, 0xf8, 0xed, 0x42, 0xf3, 0xa7, - 0x65, 0xa8, 0xea, 0xbe, 0xf0, 0x4f, 0x72, 0x0f, 0x2a, 0xfb, 0xcc, 0x64, 0xc9, 0x69, 0x2c, 0x0c, - 0x62, 0xed, 0x72, 0xc8, 0x01, 0xca, 0x7a, 0x82, 0x82, 0x93, 0xee, 0x1d, 0x9b, 0x61, 0x72, 0x2a, - 0x48, 0xda, 0xe3, 0x00, 0x95, 0x14, 0x29, 0xc8, 0x1d, 0x28, 0xbf, 0xf0, 0x6d, 0x2a, 0x0f, 0x86, - 0x0c, 0x62, 0x6d, 0xae, 0xeb, 0xdb, 0x2a, 0x21, 0xe2, 0xc9, 0x7d, 0xa8, 0x6d, 0x46, 0x41, 0x40, - 0x3d, 0xb6, 0xbd, 0x85, 0x4e, 0x56, 0x6b, 0xcd, 0x0d, 0x62, 0x0d, 0x2c, 0x01, 0xe4, 0xee, 0x98, - 0x11, 0x70, 0x53, 0xef, 0x33, 0x33, 0x60, 0xd4, 0x6e, 0x54, 0x26, 0x32, 0x35, 0x77, 0xc8, 0x2b, - 0xa1, 0x60, 0x19, 0x36, 0xb5, 0x94, 0x44, 0x9e, 0x43, 0xfd, 0x59, 0x60, 0x5a, 0x74, 0x8f, 0x06, - 0x8e, 0x6f, 0xe3, 0x19, 0x96, 0x5a, 0x77, 0x06, 0xb1, 0xb6, 0xd4, 0xe1, 0x60, 0xa3, 0x87, 0xf0, - 0x8c, 0xfb, 0x5d, 0xac, 0x55, 0xb7, 0xa2, 0x00, 0xad, 0xa7, 0xab, 0xac, 0xe4, 0x4f, 0xf9, 0x91, - 0x84, 0x0c, 0x4d, 0x4b, 0x6d, 0x3c, 0xbd, 0xf7, 0x6f, 0xb1, 0x29, 0xb7, 0xb8, 0xe4, 0x9a, 0x21, - 0x33, 0x02, 0xc1, 0x37, 0xb4, 0x4f, 0x55, 0x24, 0xd1, 0xa1, 0xba, 0x6f, 0x1d, 0x53, 0x3b, 0x72, - 0x69, 0xa3, 0x2a, 0xc5, 0xa7, 0xbe, 0x9b, 0x1c, 0x69, 0x42, 0xd1, 0x5a, 0x96, 0xe2, 0x49, 0x28, - 0x21, 0x8a, 0xf9, 0x53, 0x39, 0x9f, 0x54, 0xbf, 0xf8, 0x47, 0xed, 0xd2, 0x0f, 0x7f, 0xb1, 0x72, - 0xa9, 0xf9, 0xaf, 0x45, 0x98, 0x1f, 0x16, 0x42, 0x8e, 0x60, 0xf6, 0x55, 0xcf, 0x36, 0x19, 0xdd, - 0x74, 0x1d, 0xea, 0xb1, 0x10, 0xfd, 0xe4, 0xfd, 0x6a, 0xfd, 0x96, 0x5c, 0xb7, 0x11, 0x21, 0xa3, - 0x61, 0x09, 0xce, 0x21, 0xc5, 0xf2, 0x62, 0xb3, 0x75, 0x44, 0x54, 0x0b, 0xd1, 0xc9, 0xbe, 0xda, - 0x3a, 0x22, 0x38, 0x9e, 0xb1, 0x8e, 0x14, 0x2b, 0x7d, 0xc8, 0xb3, 0xdb, 0x7d, 0x74, 0xce, 0xc9, - 0x7d, 0x88, 0xb3, 0x8c, 0xf1, 0x21, 0x0e, 0x6e, 0xfe, 0xaa, 0x00, 0x73, 0x3a, 0x0d, 0xfd, 0x28, - 0xb0, 0xe8, 0x73, 0x6a, 0xda, 0x34, 0xe0, 0x37, 0x60, 0xc7, 0xf1, 0x6c, 0x79, 0xad, 0xf0, 0x06, - 0x9c, 0x38, 0x9e, 0x7a, 0x8b, 0x11, 0x4f, 0x7e, 0x17, 0xa6, 0xf7, 0xa3, 0x36, 0x92, 0x8a, 0x6b, - 0xb5, 0x84, 0x27, 0x16, 0xb5, 0x8d, 0x21, 0xf2, 0x84, 0x8c, 0xac, 0xc1, 0xf4, 0x21, 0x0d, 0xc2, - 0x2c, 0xee, 0x5d, 0xe5, 0x3b, 0x3c, 0x15, 0x20, 0x95, 0x41, 0x52, 0x91, 0xef, 0x66, 0xb1, 0x57, - 0x06, 0x72, 0x32, 0x1a, 0xf1, 0x32, 0x6f, 0xe9, 0x4a, 0x88, 0xea, 0x2d, 0x09, 0x55, 0xf3, 0x2f, - 0x8a, 0x50, 0x15, 0xa6, 0x3c, 0x5c, 0xe7, 0x81, 0x5c, 0xd1, 0x11, 0x03, 0x39, 0xdf, 0xf4, 0xd7, - 0xd6, 0xec, 0xa3, 0x61, 0xcd, 0xea, 0x3c, 0xa1, 0x48, 0xcd, 0x32, 0x7d, 0x3e, 0x9b, 0x48, 0x9f, - 0x79, 0xa9, 0x4f, 0x35, 0xd1, 0x27, 0xd3, 0x82, 0x7c, 0x1b, 0xca, 0xfb, 0x3d, 0x6a, 0xc9, 0x28, - 0xb2, 0x94, 0x71, 0x0b, 0xd5, 0x38, 0xee, 0x70, 0xbd, 0x35, 0x23, 0x25, 0x94, 0xc3, 0x1e, 0xb5, - 0x74, 0xe4, 0x50, 0x6e, 0xcb, 0xcf, 0x4a, 0x30, 0xa3, 0x92, 0x73, 0x6b, 0x6c, 0xd8, 0x76, 0xa0, - 0x5a, 0xc3, 0xb4, 0xed, 0x40, 0x47, 0x28, 0x79, 0x04, 0xb0, 0x17, 0xb5, 0x5d, 0xc7, 0x42, 0x9a, - 0x62, 0x96, 0xb0, 0x7a, 0x08, 0x35, 0x38, 0xa9, 0x62, 0x13, 0x85, 0x98, 0xdc, 0x85, 0xea, 0x73, - 0x3f, 0x64, 0x3c, 0x47, 0x4a, 0xbb, 0x60, 0xc2, 0x3e, 0x96, 0x30, 0x3d, 0xc5, 0x12, 0x13, 0x6a, - 0x9b, 0x5d, 0x5b, 0x26, 0xb7, 0x32, 0x26, 0xb7, 0x8f, 0xc6, 0x2b, 0xb7, 0x9a, 0xd2, 0x89, 0x1c, - 0x77, 0x53, 0xea, 0xba, 0x68, 0x75, 0x6d, 0x63, 0x24, 0xd7, 0x65, 0x52, 0xb9, 0x33, 0x25, 0x31, - 0x42, 0x9a, 0x8f, 0x8c, 0x86, 0xa0, 0xcc, 0x99, 0x02, 0x09, 0x51, 0x9d, 0x29, 0xcd, 0x3d, 0x0f, - 0xa1, 0xf6, 0x2a, 0xa4, 0x07, 0x91, 0xe7, 0x51, 0x17, 0x03, 0x6f, 0xb5, 0xd5, 0xe0, 0x7b, 0x88, - 0x42, 0x6a, 0x30, 0x84, 0xaa, 0x7b, 0x48, 0x49, 0x97, 0x0f, 0x61, 0x2e, 0xbf, 0xfd, 0x31, 0xe9, - 0x6f, 0x55, 0x4d, 0x7f, 0xf5, 0xf5, 0x46, 0xb6, 0xc9, 0x4d, 0xbf, 0xdb, 0x35, 0x3d, 0xc1, 0x7e, - 0xb8, 0xae, 0x26, 0xc6, 0x1f, 0x15, 0x60, 0x2e, 0x8f, 0x25, 0xab, 0x30, 0x25, 0x13, 0x43, 0x01, - 0x13, 0x03, 0xf7, 0xe1, 0x29, 0x91, 0x12, 0x72, 0x89, 0x40, 0x52, 0x71, 0x17, 0x96, 0x12, 0x1a, - 0xc5, 0x95, 0x52, 0xe2, 0xc2, 0x96, 0x00, 0xe9, 0x09, 0x8e, 0x34, 0x61, 0x4a, 0xa7, 0x61, 0xe4, - 0x32, 0x79, 0xa0, 0xc0, 0xc5, 0x06, 0x08, 0xd1, 0x25, 0xa6, 0xf9, 0x03, 0x80, 0x83, 0xdd, 0xfd, - 0x1d, 0xda, 0xdf, 0x33, 0x1d, 0x8c, 0x27, 0x9b, 0x34, 0x60, 0xb8, 0x8d, 0x19, 0x11, 0x4f, 0x2c, - 0x1a, 0x30, 0x35, 0x9e, 0x70, 0x3c, 0xb9, 0x0d, 0xa5, 0x1d, 0xda, 0x47, 0xad, 0x67, 0x5a, 0x57, - 0x06, 0xb1, 0x36, 0x7b, 0x42, 0x95, 0xb8, 0xa5, 0x73, 0x6c, 0xf3, 0xa7, 0x45, 0xb8, 0xcc, 0xa9, - 0x37, 0x22, 0x76, 0xec, 0x07, 0x0e, 0xeb, 0x5f, 0xe4, 0xcb, 0xfc, 0x69, 0xee, 0x32, 0x7f, 0xa0, - 0x1c, 0xb4, 0xaa, 0xe1, 0x44, 0x77, 0xfa, 0x2f, 0xcb, 0xb0, 0x30, 0x86, 0x8b, 0xdc, 0x87, 0xf2, - 0x41, 0xbf, 0x97, 0xd4, 0x48, 0xdc, 0x47, 0xcb, 0xbc, 0x79, 0x78, 0x17, 0x6b, 0x33, 0x09, 0x39, - 0xc7, 0xeb, 0x48, 0x45, 0xd6, 0xa1, 0xbe, 0xe9, 0x46, 0x21, 0x93, 0xe5, 0xbb, 0xb0, 0x17, 0x56, - 0x71, 0x96, 0x00, 0x8b, 0xfa, 0x5d, 0x25, 0x22, 0x1f, 0xc3, 0xcc, 0xe6, 0x31, 0xb5, 0x4e, 0x1c, - 0xaf, 0xb3, 0x43, 0xfb, 0x61, 0xa3, 0xb4, 0x52, 0x4a, 0xce, 0xcf, 0x92, 0x70, 0xe3, 0x84, 0xf6, - 0x43, 0x3d, 0x47, 0x46, 0xbe, 0x03, 0xf5, 0x7d, 0xa7, 0xe3, 0x25, 0x5c, 0x65, 0xe4, 0x5a, 0xe6, - 0x25, 0x45, 0x28, 0xc0, 0xc8, 0xa4, 0x16, 0xc2, 0x0a, 0x39, 0x2f, 0xe8, 0x74, 0xdf, 0xa5, 0xa2, - 0x0e, 0x96, 0x05, 0x5d, 0xc0, 0x01, 0x6a, 0x41, 0x87, 0x14, 0x64, 0x07, 0xa6, 0xf9, 0x8f, 0x17, - 0x66, 0xaf, 0x31, 0x85, 0x71, 0xe5, 0xaa, 0x7a, 0xeb, 0x11, 0xd1, 0x73, 0xbc, 0x8e, 0x7a, 0xf1, - 0x5d, 0x6a, 0x74, 0xcd, 0x9e, 0xea, 0x1a, 0x92, 0x90, 0x7c, 0x1f, 0xea, 0x99, 0x67, 0x87, 0x8d, - 0x69, 0x14, 0xb8, 0x98, 0x09, 0xcc, 0x90, 0x2d, 0x4d, 0xca, 0xbb, 0xc6, 0xdc, 0x90, 0xeb, 0x62, - 0xf4, 0x38, 0x8b, 0xaa, 0x90, 0x22, 0x29, 0x17, 0x9c, 0xaa, 0xef, 0x0d, 0x4e, 0x85, 0xf3, 0x82, - 0x53, 0x53, 0x87, 0xba, 0xa2, 0x98, 0xb8, 0xb1, 0x5d, 0x3f, 0x2d, 0x94, 0xe5, 0x8d, 0xe5, 0x10, - 0x5d, 0x62, 0x88, 0x06, 0x95, 0x5d, 0xdf, 0x32, 0x5d, 0x79, 0xf5, 0x6b, 0x83, 0x58, 0xab, 0xb8, - 0x1c, 0xa0, 0x0b, 0x78, 0xf3, 0x3f, 0x0b, 0x30, 0xbf, 0x17, 0xf8, 0xa7, 0x0e, 0x77, 0xfd, 0x03, - 0xff, 0x84, 0x7a, 0x87, 0xdf, 0x22, 0xdb, 0xc9, 0x29, 0x14, 0x90, 0xeb, 0x01, 0xe7, 0xc2, 0x53, - 0x78, 0x17, 0x6b, 0x77, 0xce, 0xed, 0x2a, 0xd1, 0xfa, 0xc9, 0x29, 0x29, 0xbd, 0x48, 0x71, 0xf2, - 0xe2, 0xe6, 0x9c, 0x5e, 0x44, 0x83, 0x0a, 0x6e, 0x55, 0x5e, 0x63, 0xd4, 0x8a, 0x71, 0x80, 0x2e, - 0xe0, 0xca, 0xfd, 0xf9, 0xbb, 0xe2, 0x88, 0x7e, 0x17, 0x38, 0xb0, 0x7c, 0x96, 0x0b, 0x2c, 0x4a, - 0x97, 0x98, 0x57, 0x71, 0xa2, 0xc8, 0x62, 0xc2, 0xe2, 0x38, 0xae, 0x5f, 0xe3, 0xe1, 0x37, 0xff, - 0xb6, 0x08, 0x73, 0xbc, 0x51, 0x73, 0x2c, 0x5c, 0x20, 0xbc, 0xc8, 0xa6, 0xff, 0x83, 0x9c, 0xe9, - 0x6f, 0x2a, 0x35, 0x8c, 0xa2, 0xe0, 0x44, 0x86, 0x3f, 0x01, 0x32, 0xca, 0x43, 0x5e, 0xc1, 0x8c, - 0x0a, 0x45, 0xeb, 0xe7, 0x9a, 0xa9, 0xe1, 0x5b, 0xda, 0xba, 0x2a, 0x57, 0x99, 0x0d, 0x91, 0xcf, - 0xc0, 0x1b, 0x10, 0xea, 0x39, 0x31, 0xcd, 0xbf, 0x29, 0xc2, 0xac, 0x12, 0xd5, 0x2f, 0xf2, 0x09, - 0x3c, 0xce, 0x9d, 0xc0, 0x0d, 0x25, 0xab, 0x66, 0xfa, 0x4d, 0x74, 0x00, 0xcf, 0xe0, 0xca, 0x08, - 0xcb, 0x70, 0x8a, 0x2c, 0x4c, 0x90, 0x22, 0x45, 0xd1, 0x22, 0xfe, 0xdf, 0xf4, 0xbd, 0x23, 0xa7, - 0x73, 0xf8, 0xe0, 0x37, 0xb1, 0x68, 0x51, 0x35, 0x44, 0x6b, 0x3d, 0x38, 0xc7, 0xc0, 0x7f, 0x5d, - 0x81, 0x85, 0x31, 0x5c, 0x64, 0x03, 0xe6, 0xf7, 0x69, 0x88, 0x1b, 0xa7, 0x96, 0x1f, 0xd8, 0x8e, - 0xd7, 0x91, 0x76, 0xc2, 0x86, 0x31, 0x14, 0x38, 0x23, 0x48, 0x90, 0xfa, 0x08, 0x39, 0x8e, 0x67, - 0x84, 0xe4, 0xed, 0x2d, 0x69, 0x42, 0x31, 0x9e, 0x91, 0x87, 0x84, 0xe3, 0x99, 0x84, 0x80, 0xec, - 0xc2, 0xc2, 0x5e, 0xe0, 0xbf, 0xe9, 0x63, 0x85, 0x12, 0xf2, 0xa6, 0x44, 0x96, 0x32, 0x9c, 0x0f, - 0x8b, 0x92, 0x1e, 0x47, 0x1b, 0x58, 0xd0, 0x84, 0x06, 0xef, 0x5f, 0x44, 0x4d, 0x33, 0x8e, 0x8d, - 0x7c, 0x02, 0x95, 0x8d, 0xc8, 0x76, 0x98, 0x34, 0xb0, 0x52, 0x6f, 0x20, 0x58, 0xa8, 0xda, 0x9a, - 0x95, 0xa6, 0xa9, 0x98, 0x1c, 0xa8, 0x0b, 0x16, 0xf2, 0x39, 0xf7, 0x39, 0x87, 0x7a, 0x6c, 0xdb, - 0x76, 0x29, 0xcf, 0x78, 0x7e, 0xc4, 0xd0, 0xd4, 0xa5, 0xd6, 0xed, 0x41, 0xac, 0x2d, 0x88, 0x89, - 0x84, 0xe1, 0xd8, 0x2e, 0x35, 0x98, 0x40, 0xe7, 0xaa, 0xf9, 0x51, 0x6e, 0xf2, 0x03, 0xb8, 0xba, - 0xe5, 0x84, 0x96, 0xef, 0x79, 0xd4, 0x62, 0x22, 0x35, 0xda, 0x58, 0x90, 0x8b, 0xbe, 0x85, 0x8b, - 0xbd, 0x66, 0xa7, 0x04, 0x86, 0xc8, 0xa9, 0xb6, 0xc1, 0x6b, 0xf4, 0x77, 0xb1, 0x56, 0x6e, 0xf9, - 0xbe, 0xab, 0x8f, 0x97, 0xc0, 0x77, 0x9b, 0x8e, 0x7e, 0xb7, 0x3d, 0x46, 0x83, 0x53, 0xd3, 0x95, - 0xb3, 0x3f, 0xdc, 0xed, 0x09, 0xa5, 0x3d, 0xc3, 0xe4, 0x58, 0xc3, 0x91, 0xe8, 0xfc, 0x6e, 0x47, - 0xb8, 0xc9, 0x53, 0x45, 0xe4, 0xa6, 0x1f, 0x79, 0xec, 0x85, 0xf9, 0x06, 0x2b, 0xa2, 0x92, 0xe8, - 0xb0, 0x14, 0x91, 0x16, 0x47, 0x1b, 0x5d, 0xf3, 0x8d, 0x3e, 0xca, 0x42, 0x7e, 0x0f, 0x6a, 0x58, - 0xb9, 0xf0, 0x0a, 0xb7, 0x51, 0x43, 0x4d, 0xf9, 0x1d, 0x02, 0xac, 0x6a, 0x0c, 0x33, 0x62, 0xc7, - 0xa9, 0x72, 0x19, 0x61, 0xf3, 0x8b, 0x12, 0xd4, 0x95, 0x43, 0xe2, 0xbd, 0x8b, 0x52, 0x3e, 0x63, - 0xef, 0xc2, 0xcb, 0x67, 0xb5, 0x77, 0xc1, 0xc2, 0xf9, 0x3e, 0xaf, 0xb1, 0x3a, 0xfc, 0xf2, 0x09, - 0x5f, 0xc3, 0xc1, 0x6b, 0x80, 0x10, 0x75, 0xf0, 0x2a, 0x68, 0xc8, 0x2e, 0xcc, 0xe3, 0x22, 0xd2, - 0x6b, 0xc3, 0x57, 0xfa, 0xb6, 0xf4, 0xb5, 0x95, 0x41, 0xac, 0xdd, 0x44, 0x87, 0x30, 0xa4, 0x97, - 0x87, 0x46, 0x14, 0x38, 0x8a, 0x8c, 0x11, 0x4e, 0xf2, 0x0f, 0x05, 0x98, 0x43, 0xe0, 0x93, 0x53, - 0xea, 0x31, 0x14, 0x56, 0x96, 0xd3, 0x81, 0x74, 0x54, 0xbf, 0xcf, 0x02, 0xc7, 0xeb, 0x1c, 0xf2, - 0x7e, 0x31, 0x6c, 0xfd, 0x11, 0xf7, 0xbc, 0x9f, 0xc7, 0xda, 0xc3, 0xaf, 0x36, 0xf8, 0x97, 0x42, - 0xc2, 0x41, 0xac, 0x2d, 0x8b, 0x2d, 0x52, 0x5c, 0x70, 0x68, 0x83, 0x43, 0x7b, 0x21, 0x4f, 0xe5, - 0xee, 0x0e, 0xcc, 0xb6, 0x4b, 0x31, 0x66, 0x56, 0x50, 0xd5, 0x5b, 0x99, 0x1c, 0xc6, 0x51, 0x18, - 0x37, 0x47, 0xe4, 0xa4, 0x5c, 0xcd, 0xff, 0x2d, 0x28, 0xe3, 0xf5, 0x8b, 0x1b, 0x3e, 0x1f, 0xe5, - 0xc2, 0xe7, 0xb5, 0x8c, 0x3b, 0xd5, 0x8d, 0xa3, 0xc7, 0x05, 0xce, 0xe6, 0x65, 0x98, 0xcd, 0x11, - 0x35, 0xff, 0xbc, 0x08, 0x53, 0xbc, 0x82, 0xba, 0xc8, 0xe9, 0xe4, 0x61, 0xce, 0x1e, 0x8b, 0xf9, - 0xde, 0x6c, 0xa2, 0x2c, 0xf2, 0xab, 0x02, 0x40, 0x46, 0x4c, 0xbe, 0x0b, 0xd3, 0x2f, 0xf1, 0xb5, - 0x24, 0x19, 0xf8, 0x0e, 0xf5, 0x7b, 0x12, 0xd9, 0xba, 0x9e, 0x34, 0x11, 0xbe, 0x00, 0xa8, 0x56, - 0x90, 0x34, 0xe4, 0x19, 0x54, 0x36, 0x5c, 0xd7, 0x7f, 0x3d, 0x3a, 0x8a, 0xe1, 0x92, 0x36, 0x7d, - 0xcf, 0x76, 0x84, 0xb0, 0x6b, 0x52, 0xd8, 0x65, 0x93, 0x93, 0xab, 0x4d, 0x28, 0xf2, 0x93, 0x2d, - 0x28, 0x6f, 0x51, 0x2f, 0x19, 0xdc, 0x9e, 0x2d, 0x67, 0x49, 0xca, 0x99, 0xb3, 0xa9, 0xa7, 0xce, - 0x3e, 0x90, 0xbb, 0xf9, 0x93, 0xb2, 0xe8, 0xec, 0x92, 0xed, 0x3d, 0x86, 0x99, 0xa7, 0x7e, 0xf0, - 0xda, 0x0c, 0xec, 0x8d, 0x0e, 0xf5, 0xc4, 0x84, 0xa5, 0x8a, 0xb3, 0xb9, 0xd9, 0x23, 0x01, 0x37, - 0x4c, 0x8e, 0x48, 0x23, 0x5d, 0x8e, 0x9c, 0xbc, 0x84, 0xd9, 0x17, 0xe6, 0x1b, 0x19, 0x4a, 0x0e, - 0x0e, 0x76, 0x51, 0xcb, 0x52, 0xeb, 0xde, 0x20, 0xd6, 0xae, 0x77, 0xcd, 0x37, 0x49, 0x04, 0x32, - 0x18, 0x73, 0xcf, 0x78, 0x44, 0xc8, 0xf3, 0x13, 0x17, 0xe6, 0xf6, 0xfc, 0x80, 0xc9, 0x45, 0x78, - 0xd6, 0x16, 0xfa, 0x2e, 0x64, 0xfa, 0xf2, 0x6d, 0x60, 0x18, 0x6a, 0xad, 0xf1, 0x5e, 0xf6, 0xe7, - 0xb1, 0x06, 0x1c, 0x24, 0x34, 0xe2, 0x0b, 0xf3, 0xb0, 0x63, 0x1c, 0xa5, 0x12, 0xd4, 0x80, 0x90, - 0x97, 0x4d, 0x1e, 0xc3, 0x15, 0x9e, 0x84, 0x9c, 0x23, 0xc7, 0x32, 0x19, 0x7d, 0xea, 0x07, 0x5d, - 0x93, 0xc9, 0x97, 0x18, 0x7c, 0x71, 0xe4, 0x09, 0x8c, 0x4b, 0xea, 0x9a, 0x4c, 0x1f, 0xa5, 0x24, - 0x7f, 0x78, 0x76, 0xa6, 0xfd, 0xe6, 0x20, 0xd6, 0x3e, 0x18, 0x93, 0x69, 0xcf, 0xb0, 0xc2, 0x98, - 0x9c, 0xdb, 0x79, 0x7f, 0xce, 0xfd, 0x96, 0xec, 0xe3, 0x3f, 0x3c, 0x23, 0xef, 0xe6, 0x16, 0x7a, - 0x5f, 0x06, 0x6e, 0xfe, 0x5b, 0x11, 0xe6, 0xf2, 0x3e, 0xc4, 0xfb, 0xfd, 0x5d, 0xbf, 0xe3, 0x78, - 0x49, 0x67, 0x86, 0xfd, 0xbe, 0x8b, 0x10, 0x5d, 0x62, 0xc8, 0x47, 0x00, 0x69, 0x28, 0x09, 0x65, - 0xd3, 0x2f, 0xdf, 0x2a, 0x15, 0x04, 0xf9, 0x13, 0x80, 0xef, 0xf9, 0x36, 0x95, 0x63, 0xd9, 0x92, - 0xbc, 0x4e, 0x69, 0x42, 0x10, 0xa3, 0x46, 0x91, 0x54, 0xbe, 0x21, 0x93, 0x8a, 0x7c, 0x5c, 0x1c, - 0xc4, 0xda, 0x55, 0xcf, 0xb7, 0xe9, 0xe8, 0x44, 0x56, 0x91, 0x48, 0x1e, 0x43, 0x45, 0x8f, 0x5c, - 0x9a, 0x4c, 0x7c, 0xe7, 0x94, 0x7b, 0x11, 0xb9, 0x34, 0xbb, 0x55, 0x41, 0x34, 0x3c, 0xda, 0xe1, - 0x00, 0xf2, 0x29, 0xc0, 0x4e, 0xd4, 0xa6, 0xcf, 0x02, 0x3f, 0xea, 0x25, 0xa3, 0x20, 0x6d, 0x10, - 0x6b, 0x37, 0x4e, 0xa2, 0x36, 0x0d, 0x3c, 0xca, 0x68, 0x68, 0x74, 0x10, 0xa9, 0xae, 0x9f, 0xb1, - 0x34, 0xff, 0xa3, 0x00, 0x65, 0x2e, 0x8a, 0x7c, 0x0c, 0xb5, 0xe4, 0x15, 0x24, 0x31, 0xdb, 0x35, - 0x5e, 0xc0, 0x04, 0x09, 0x50, 0x1d, 0xe7, 0xa6, 0x94, 0xe4, 0x1e, 0x54, 0x0e, 0x69, 0xd0, 0x4e, - 0x2c, 0x88, 0x63, 0xa8, 0x53, 0x0e, 0x50, 0xf7, 0x8a, 0x14, 0x9c, 0xf4, 0xfb, 0xc7, 0x34, 0x48, - 0xe6, 0xe0, 0x48, 0xfa, 0x9a, 0x03, 0x54, 0x52, 0xa4, 0x20, 0x6b, 0x30, 0xbd, 0x61, 0x89, 0x08, - 0x56, 0x46, 0xb9, 0x58, 0xf5, 0x9a, 0xd6, 0x48, 0x98, 0x92, 0x54, 0xcd, 0x0f, 0xa1, 0x96, 0xde, - 0x2b, 0xb2, 0x08, 0x15, 0xfc, 0x21, 0xa2, 0x81, 0x2e, 0xfe, 0xc1, 0x54, 0xf1, 0x2a, 0xbc, 0xd8, - 0x6f, 0x1f, 0x67, 0xa6, 0x0a, 0xae, 0xd8, 0x44, 0x1d, 0xdd, 0xbf, 0x4c, 0x01, 0x64, 0xc4, 0x84, - 0xc2, 0xdc, 0xcb, 0xed, 0xad, 0xcd, 0x6d, 0x9b, 0x7a, 0xcc, 0x61, 0x0e, 0x1d, 0xd3, 0x4d, 0x3f, - 0x79, 0xc3, 0x68, 0xe0, 0x99, 0xae, 0xa4, 0xe9, 0xb7, 0x3e, 0x94, 0x0b, 0x5c, 0xf7, 0x1d, 0xdb, - 0x32, 0x9c, 0x94, 0x55, 0x0d, 0x54, 0x79, 0xa1, 0x7c, 0x99, 0xfd, 0x8d, 0x17, 0xbb, 0xca, 0x32, - 0xc5, 0xc9, 0x97, 0x09, 0xcd, 0xae, 0x7b, 0xc6, 0x32, 0x79, 0xa1, 0xe4, 0x04, 0xe6, 0x9f, 0x61, - 0x41, 0xa7, 0x2c, 0x54, 0x3a, 0x77, 0xa1, 0xdb, 0x72, 0xa1, 0x1b, 0xa2, 0x18, 0x1c, 0xbf, 0xd4, - 0x88, 0xe0, 0x6c, 0x00, 0x5b, 0x3e, 0x77, 0x00, 0xfb, 0xc3, 0x02, 0x4c, 0x1d, 0x04, 0xa6, 0xc3, - 0x42, 0x79, 0x72, 0x67, 0x44, 0x90, 0xcf, 0x65, 0x04, 0xf9, 0xf8, 0x2b, 0x96, 0xa5, 0x42, 0x36, - 0x2f, 0xb8, 0x19, 0xfe, 0x52, 0x0b, 0x6e, 0x81, 0x23, 0xcf, 0x60, 0x6a, 0x9f, 0x99, 0x2c, 0x4a, - 0x3e, 0x74, 0x50, 0x4a, 0x02, 0x0c, 0x88, 0x02, 0xd9, 0x6a, 0x48, 0x5b, 0xcc, 0x87, 0xf8, 0xbf, - 0x2a, 0x48, 0x50, 0xa8, 0x1f, 0x96, 0x4c, 0xff, 0xff, 0x3e, 0x2c, 0x21, 0x2f, 0xa1, 0xb6, 0x19, - 0x50, 0x93, 0x51, 0xbb, 0xd5, 0x97, 0x23, 0x5f, 0x25, 0x4f, 0xa6, 0x28, 0xe5, 0x7d, 0x4b, 0x80, - 0x0c, 0xf5, 0x31, 0x57, 0xcf, 0x64, 0x10, 0x7d, 0xb8, 0xe3, 0xc9, 0x1d, 0x7c, 0x8a, 0xda, 0xa7, - 0x56, 0x40, 0x59, 0x28, 0xba, 0xa9, 0xac, 0x1b, 0x52, 0x65, 0x66, 0xfd, 0xd0, 0x8f, 0x0b, 0x30, - 0x3f, 0xec, 0x32, 0xe4, 0x3b, 0x50, 0xdf, 0x14, 0x99, 0xc8, 0xe7, 0xdd, 0x75, 0x21, 0xeb, 0x92, - 0xad, 0x04, 0x6c, 0xe4, 0xbe, 0xfa, 0x50, 0xc9, 0xc9, 0x3a, 0x54, 0xf9, 0x15, 0xf4, 0xb2, 0x07, - 0x06, 0x8c, 0x30, 0x91, 0x84, 0xa9, 0x13, 0xed, 0x84, 0x4e, 0xb9, 0xc1, 0xff, 0x5e, 0x84, 0xba, - 0x72, 0x64, 0xe4, 0x1e, 0x54, 0xb7, 0xc3, 0x5d, 0xdf, 0x3a, 0xa1, 0xb6, 0x2c, 0x7f, 0xf0, 0xeb, - 0x21, 0x27, 0x34, 0x5c, 0x04, 0xea, 0x29, 0x9a, 0xb4, 0x60, 0x56, 0xfc, 0x7a, 0x41, 0xc3, 0xd0, - 0xec, 0x24, 0xab, 0xdf, 0x1c, 0xc4, 0x5a, 0x43, 0x10, 0x1b, 0x5d, 0x81, 0x51, 0xf6, 0x90, 0x67, - 0x21, 0x7f, 0x0c, 0x20, 0x00, 0xfc, 0x94, 0x27, 0x78, 0x86, 0x4f, 0xae, 0xf1, 0x55, 0xb9, 0x00, - 0x2f, 0x24, 0x86, 0xa6, 0xd5, 0x8a, 0x40, 0xfc, 0x0e, 0xc3, 0xb7, 0x4e, 0x26, 0xff, 0x76, 0x29, - 0xfb, 0x0e, 0xc3, 0xb7, 0x4e, 0x8c, 0xf1, 0xe3, 0x70, 0x55, 0x64, 0xf3, 0x97, 0x05, 0xc5, 0xed, - 0xc8, 0xe7, 0x50, 0x4b, 0x8f, 0x46, 0x56, 0xcb, 0x4b, 0xea, 0x73, 0xa3, 0x44, 0xe9, 0xf4, 0xa8, - 0x75, 0x43, 0x96, 0x2c, 0x0b, 0xe9, 0x19, 0xe7, 0xbc, 0x30, 0x01, 0x92, 0xcf, 0xa0, 0x8c, 0xb6, - 0x39, 0x7f, 0x8a, 0x9f, 0x84, 0xfa, 0x32, 0x37, 0x0a, 0xee, 0x14, 0x39, 0xc9, 0x03, 0x28, 0xf3, - 0x83, 0x97, 0xd6, 0xbd, 0x92, 0x0f, 0xf3, 0x7c, 0x2b, 0x69, 0x8c, 0xe7, 0x3e, 0xa3, 0x23, 0xb1, - 0xe2, 0x21, 0x7f, 0x56, 0x80, 0x85, 0x57, 0xeb, 0x4f, 0x79, 0xab, 0x1d, 0x32, 0x51, 0xa1, 0x6d, - 0xf1, 0xec, 0x71, 0x1d, 0x4a, 0xba, 0xf9, 0x5a, 0xbe, 0x42, 0x4e, 0x0f, 0x62, 0xad, 0x14, 0x98, - 0xaf, 0x75, 0x0e, 0x23, 0xf7, 0xa1, 0xb6, 0x43, 0xfb, 0xcf, 0x4d, 0xcf, 0x76, 0xa9, 0x7c, 0x7f, - 0xc4, 0x61, 0xd1, 0x09, 0xed, 0x1b, 0xc7, 0x08, 0xd5, 0x33, 0x02, 0x5e, 0x5f, 0xed, 0x45, 0xed, - 0x1d, 0x2a, 0xaa, 0xf9, 0x19, 0x51, 0x5f, 0xf5, 0xa2, 0xf6, 0x09, 0xed, 0xeb, 0x12, 0xd3, 0xfc, - 0xa7, 0x22, 0xcc, 0x0f, 0xdf, 0x38, 0xf2, 0x29, 0xcc, 0xec, 0x99, 0x61, 0xf8, 0xda, 0x0f, 0xec, - 0xe7, 0x66, 0x78, 0x2c, 0xb7, 0x72, 0x63, 0x10, 0x6b, 0xd7, 0x7a, 0x12, 0x6e, 0x1c, 0x9b, 0xa1, - 0x7a, 0x15, 0x73, 0x0c, 0x3c, 0x37, 0x1f, 0xbc, 0x3c, 0xd8, 0x4b, 0x5e, 0x49, 0xe5, 0xcd, 0x61, - 0x3e, 0xeb, 0x19, 0xf9, 0xa7, 0xd2, 0x84, 0x8c, 0x74, 0xe0, 0xf2, 0x90, 0x2d, 0xa4, 0x59, 0x95, - 0xb9, 0xdd, 0x18, 0x63, 0x89, 0xe6, 0x3c, 0x5a, 0x3f, 0x32, 0x02, 0x05, 0xa3, 0x2c, 0x30, 0x2c, - 0x95, 0x3c, 0x02, 0x78, 0xb5, 0xfe, 0x14, 0xa7, 0x2f, 0x34, 0x40, 0xc7, 0x9d, 0x15, 0x1f, 0x09, - 0x70, 0x21, 0x96, 0x00, 0xab, 0x45, 0x58, 0x46, 0xdc, 0xf4, 0x60, 0x46, 0xf5, 0x34, 0x5e, 0x9f, - 0x28, 0x33, 0x97, 0x6a, 0xf2, 0x64, 0x29, 0x27, 0x2d, 0x4b, 0xf8, 0x7d, 0x99, 0x50, 0x7f, 0x6a, - 0x10, 0x6b, 0x45, 0xc7, 0xd6, 0x8b, 0xdb, 0x5b, 0xe4, 0x2e, 0x54, 0x93, 0x00, 0xa5, 0x7e, 0x6a, - 0x20, 0xd3, 0x59, 0x5f, 0x4f, 0xb1, 0xcd, 0x6f, 0xc0, 0xb4, 0xf4, 0xa4, 0xf7, 0x7f, 0xcf, 0xd7, - 0xfc, 0x51, 0x11, 0x2e, 0xeb, 0x94, 0x17, 0x32, 0xf2, 0xf9, 0xfe, 0x37, 0xf2, 0xad, 0x39, 0xa7, - 0xe1, 0xd9, 0x55, 0x54, 0xf3, 0x9f, 0x0b, 0xb0, 0x30, 0x86, 0xf6, 0xeb, 0x0c, 0xc4, 0xc9, 0x43, - 0xa8, 0x6d, 0x39, 0xa6, 0xbb, 0x61, 0xdb, 0x41, 0x52, 0x3b, 0x63, 0x3a, 0xb2, 0x1d, 0x9e, 0x8d, - 0x38, 0x54, 0x0d, 0x2e, 0x29, 0x29, 0xf9, 0x6d, 0xe9, 0x1a, 0xa5, 0xd4, 0xb8, 0xc9, 0x6b, 0x36, - 0x88, 0x3d, 0x65, 0x6f, 0xd9, 0xcd, 0xbf, 0x2f, 0x02, 0x11, 0x40, 0xe9, 0x5d, 0x8e, 0x7f, 0xa1, - 0xdf, 0xf4, 0x5a, 0xb9, 0x03, 0x5c, 0x51, 0xde, 0x9c, 0x87, 0x94, 0x9c, 0xa8, 0x12, 0xfe, 0x71, - 0x11, 0x96, 0xc6, 0x33, 0x7e, 0xad, 0x03, 0xbd, 0x0f, 0x35, 0x9c, 0x84, 0x2b, 0x9f, 0x0d, 0x60, - 0x04, 0x15, 0x63, 0x73, 0xa4, 0xcf, 0x08, 0xc8, 0x11, 0xcc, 0xee, 0x9a, 0x21, 0x7b, 0x4e, 0xcd, - 0x80, 0xb5, 0xa9, 0xc9, 0x26, 0x48, 0xa4, 0xe9, 0x17, 0x73, 0xf8, 0xc1, 0xe1, 0x71, 0xc2, 0x39, - 0xfc, 0xc5, 0x5c, 0x4e, 0x6c, 0xea, 0x2e, 0xe5, 0xf3, 0xdd, 0xa5, 0xb5, 0xf8, 0xf6, 0xbf, 0x6f, - 0x5d, 0x7a, 0xfb, 0xe5, 0xad, 0xc2, 0xcf, 0xbe, 0xbc, 0x55, 0xf8, 0xaf, 0x2f, 0x6f, 0x15, 0xbe, - 0xf8, 0x9f, 0x5b, 0x97, 0xda, 0x53, 0xb8, 0x95, 0x07, 0xff, 0x17, 0x00, 0x00, 0xff, 0xff, 0x48, - 0x41, 0xfc, 0xc5, 0x72, 0x2d, 0x00, 0x00, +func init() { proto.RegisterFile("types.proto", fileDescriptor_types_1f32999e8058ec6f) } + +var fileDescriptor_types_1f32999e8058ec6f = []byte{ + // 3693 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xdc, 0x3a, 0x4d, 0x73, 0x1c, 0xc7, + 0x75, 0xdc, 0x0f, 0x00, 0xbb, 0x6f, 0x01, 0x10, 0x6c, 0x80, 0xe4, 0xf2, 0x43, 0x1c, 0x68, 0x14, + 0xc9, 0x94, 0x43, 0x03, 0x31, 0x18, 0x29, 0x96, 0x62, 0x46, 0xc2, 0x62, 0x41, 0x12, 0x06, 0x48, + 0x42, 0x03, 0x10, 0x2e, 0x57, 0x3e, 0x26, 0x83, 0x99, 0xc6, 0x62, 0x0a, 0xb3, 0x33, 0x9b, 0x99, + 0x1e, 0x90, 0x7b, 0x73, 0x25, 0xa9, 0x4a, 0x25, 0xae, 0xb2, 0x9d, 0x4a, 0xb9, 0xa2, 0xaa, 0xe4, + 0x90, 0x6b, 0x0e, 0xc9, 0x35, 0xa7, 0x1c, 0x52, 0x95, 0x03, 0x8f, 0x3e, 0xbb, 0x9c, 0x71, 0xa2, + 0x1c, 0x5c, 0xb5, 0x3f, 0x41, 0x97, 0xa4, 0xfa, 0x75, 0xcf, 0x4c, 0xcf, 0xee, 0x82, 0x58, 0xc9, + 0xba, 0x40, 0xa7, 0x9d, 0x7d, 0x5f, 0xdd, 0xef, 0xf5, 0xeb, 0xf7, 0x5e, 0xbf, 0x6e, 0x68, 0xb0, + 0x7e, 0x8f, 0x46, 0x2b, 0xbd, 0x30, 0x60, 0x01, 0xa9, 0x45, 0x34, 0x3c, 0x75, 0x6d, 0x1a, 0xdd, + 0x5c, 0xea, 0x04, 0x9d, 0x00, 0x81, 0xab, 0xfc, 0x4b, 0xe0, 0x6f, 0x6a, 0x9d, 0x20, 0xe8, 0x78, + 0x74, 0x15, 0xff, 0x1d, 0xc6, 0x47, 0xab, 0xcc, 0xed, 0xd2, 0x88, 0x59, 0xdd, 0x9e, 0x24, 0x78, + 0xd0, 0x71, 0xd9, 0x71, 0x7c, 0xb8, 0x62, 0x07, 0xdd, 0xd5, 0x4e, 0x68, 0x9d, 0xba, 0xcc, 0x62, + 0x6e, 0xe0, 0x5b, 0xde, 0x2a, 0xa3, 0x1e, 0xed, 0x05, 0x21, 0x5b, 0xf5, 0xdc, 0xc3, 0xd5, 0x17, + 0xa1, 0xd5, 0xeb, 0xd1, 0x30, 0xca, 0x3e, 0x04, 0xbb, 0xfe, 0xcb, 0x12, 0xd4, 0xb7, 0x29, 0xed, + 0xad, 0x7b, 0xee, 0x29, 0x25, 0xab, 0x00, 0x7b, 0x34, 0x3c, 0xa5, 0xe1, 0x53, 0xab, 0x4b, 0x9b, + 0xa5, 0xe5, 0xd2, 0xdd, 0x7a, 0xeb, 0xf2, 0x20, 0xd1, 0x1a, 0x11, 0x42, 0x4d, 0xdf, 0xea, 0x52, + 0x43, 0x21, 0x21, 0xbf, 0x0d, 0x75, 0xfe, 0x1b, 0xf5, 0x2c, 0x9b, 0x36, 0xcb, 0x48, 0x3f, 0x37, + 0x48, 0xb4, 0xba, 0x9f, 0x02, 0x8d, 0x1c, 0x4f, 0xde, 0x81, 0x99, 0x1d, 0x6a, 0x45, 0x74, 0xab, + 0xdd, 0xac, 0x2c, 0x97, 0xee, 0x56, 0x5a, 0xb3, 0x83, 0x44, 0xab, 0x79, 0x1c, 0x64, 0xba, 0x8e, + 0x91, 0x22, 0xc9, 0x16, 0xcc, 0x6c, 0xbe, 0xec, 0xb9, 0x21, 0x8d, 0x9a, 0xd5, 0xe5, 0xd2, 0xdd, + 0xc6, 0xda, 0xcd, 0x15, 0x61, 0x85, 0x95, 0xd4, 0x0a, 0x2b, 0xfb, 0xa9, 0x15, 0x5a, 0x8b, 0xaf, + 0x12, 0xed, 0xd2, 0x20, 0xd1, 0x66, 0xa8, 0x60, 0xf9, 0xe9, 0xaf, 0xb4, 0x92, 0x91, 0xf2, 0xeb, + 0x7f, 0x53, 0x81, 0xda, 0x13, 0xca, 0x2c, 0xc7, 0x62, 0x16, 0xb9, 0x0d, 0x55, 0x45, 0xaf, 0xda, + 0x20, 0xd1, 0xaa, 0xa8, 0x10, 0x42, 0xc9, 0x5b, 0xa3, 0xaa, 0x4c, 0x0d, 0x12, 0xad, 0xf4, 0x2d, + 0x55, 0x85, 0xdf, 0x87, 0x46, 0x9b, 0x46, 0x76, 0xe8, 0xf6, 0xb8, 0x91, 0x51, 0x8d, 0x7a, 0xeb, + 0xc6, 0x20, 0xd1, 0xae, 0x3a, 0x39, 0xf8, 0x5e, 0xd0, 0x75, 0x19, 0xed, 0xf6, 0x58, 0xdf, 0x50, + 0xa9, 0xc9, 0x0e, 0x4c, 0xef, 0x58, 0x87, 0xd4, 0x8b, 0x9a, 0x53, 0xcb, 0x95, 0xbb, 0x8d, 0xb5, + 0x3b, 0x2b, 0xe9, 0xe2, 0xaf, 0xa4, 0x73, 0x5c, 0x11, 0x04, 0x9b, 0x3e, 0x0b, 0xfb, 0xad, 0xa5, + 0x41, 0xa2, 0x2d, 0x78, 0x08, 0x50, 0x44, 0x4a, 0x19, 0x64, 0x2f, 0xb7, 0xd2, 0xf4, 0xb9, 0x56, + 0x7a, 0xe3, 0x55, 0xa2, 0x95, 0x06, 0x89, 0x76, 0x45, 0x5a, 0x29, 0x97, 0x57, 0xb0, 0x17, 0x59, + 0x86, 0xf2, 0x56, 0xbb, 0x39, 0x83, 0xab, 0xb3, 0x30, 0x48, 0xb4, 0x59, 0xd7, 0x51, 0x86, 0x2e, + 0x6f, 0xb5, 0x6f, 0x7e, 0x00, 0x0d, 0x65, 0x8e, 0x64, 0x01, 0x2a, 0x27, 0xb4, 0x2f, 0x4c, 0x6a, + 0xf0, 0x4f, 0xb2, 0x04, 0x53, 0xa7, 0x96, 0x17, 0x4b, 0x1b, 0x1a, 0xe2, 0xcf, 0x87, 0xe5, 0xef, + 0x94, 0xf4, 0x9f, 0x55, 0xa1, 0x66, 0x04, 0xc2, 0x3f, 0xc9, 0xbb, 0x30, 0xb5, 0xc7, 0x2c, 0x96, + 0xae, 0xc6, 0xe2, 0x20, 0xd1, 0x2e, 0x47, 0x1c, 0xa0, 0x8c, 0x27, 0x28, 0x38, 0xe9, 0xee, 0xb1, + 0x15, 0xa5, 0xab, 0x82, 0xa4, 0x3d, 0x0e, 0x50, 0x49, 0x91, 0x82, 0xbc, 0x03, 0xd5, 0x27, 0x81, + 0x43, 0xe5, 0xc2, 0x90, 0x41, 0xa2, 0xcd, 0x77, 0x03, 0x47, 0x25, 0x44, 0x3c, 0xb9, 0x07, 0xf5, + 0x8d, 0x38, 0x0c, 0xa9, 0xcf, 0xb6, 0xda, 0xe8, 0x64, 0xf5, 0xd6, 0xfc, 0x20, 0xd1, 0xc0, 0x16, + 0x40, 0xee, 0x8e, 0x39, 0x01, 0x37, 0xf5, 0x1e, 0xb3, 0x42, 0x46, 0x9d, 0xe6, 0xd4, 0x44, 0xa6, + 0xe6, 0x0e, 0x79, 0x25, 0x12, 0x2c, 0xc3, 0xa6, 0x96, 0x92, 0xc8, 0x63, 0x68, 0x3c, 0x0a, 0x2d, + 0x9b, 0xee, 0xd2, 0xd0, 0x0d, 0x1c, 0x5c, 0xc3, 0x4a, 0xeb, 0x9d, 0x41, 0xa2, 0x5d, 0xeb, 0x70, + 0xb0, 0xd9, 0x43, 0x78, 0xce, 0xfd, 0x79, 0xa2, 0xd5, 0xda, 0x71, 0x88, 0xd6, 0x33, 0x54, 0x56, + 0xf2, 0xa7, 0x7c, 0x49, 0x22, 0x86, 0xa6, 0xa5, 0x0e, 0xae, 0xde, 0xeb, 0xa7, 0xa8, 0xcb, 0x29, + 0x5e, 0xf3, 0xac, 0x88, 0x99, 0xa1, 0xe0, 0x1b, 0x9a, 0xa7, 0x2a, 0x92, 0x18, 0x50, 0xdb, 0xb3, + 0x8f, 0xa9, 0x13, 0x7b, 0xb4, 0x59, 0x93, 0xe2, 0x33, 0xdf, 0x4d, 0x97, 0x34, 0xa5, 0x68, 0xdd, + 0x94, 0xe2, 0x49, 0x24, 0x21, 0x8a, 0xf9, 0x33, 0x39, 0x1f, 0xd6, 0x3e, 0xfd, 0x27, 0xed, 0xd2, + 0x0f, 0x7f, 0xb9, 0x7c, 0x49, 0xff, 0xb7, 0x32, 0x2c, 0x0c, 0x0b, 0x21, 0x47, 0x30, 0xf7, 0xbc, + 0xe7, 0x58, 0x8c, 0x6e, 0x78, 0x2e, 0xf5, 0x59, 0x84, 0x7e, 0xf2, 0x7a, 0xb5, 0x7e, 0x4b, 0x8e, + 0xdb, 0x8c, 0x91, 0xd1, 0xb4, 0x05, 0xe7, 0x90, 0x62, 0x45, 0xb1, 0xf9, 0x38, 0x22, 0xaa, 0x45, + 0xe8, 0x64, 0x5f, 0x6c, 0x1c, 0x11, 0x1c, 0xcf, 0x18, 0x47, 0x8a, 0x95, 0x3e, 0xe4, 0x3b, 0x87, + 0x7d, 0x74, 0xce, 0xc9, 0x7d, 0x88, 0xb3, 0x8c, 0xf1, 0x21, 0x0e, 0xd6, 0x7f, 0x5d, 0x82, 0x79, + 0x83, 0x46, 0x41, 0x1c, 0xda, 0xf4, 0x31, 0xb5, 0x1c, 0x1a, 0xf2, 0x1d, 0xb0, 0xed, 0xfa, 0x8e, + 0xdc, 0x56, 0xb8, 0x03, 0x4e, 0x5c, 0x5f, 0xdd, 0xc5, 0x88, 0x27, 0xbf, 0x03, 0x33, 0x7b, 0xf1, + 0x21, 0x92, 0x8a, 0x6d, 0x75, 0x0d, 0x57, 0x2c, 0x3e, 0x34, 0x87, 0xc8, 0x53, 0x32, 0xb2, 0x0a, + 0x33, 0x07, 0x34, 0x8c, 0xf2, 0xb8, 0x77, 0x95, 0xcf, 0xf0, 0x54, 0x80, 0x54, 0x06, 0x49, 0x45, + 0xbe, 0x97, 0xc7, 0x5e, 0x19, 0xc8, 0xc9, 0x68, 0xc4, 0xcb, 0xbd, 0xa5, 0x2b, 0x21, 0xaa, 0xb7, + 0xa4, 0x54, 0xfa, 0x5f, 0x95, 0xa1, 0x26, 0x4c, 0x79, 0xb0, 0xc6, 0x03, 0xb9, 0xa2, 0x23, 0x06, + 0x72, 0x3e, 0xe9, 0x2f, 0xad, 0xd9, 0xdb, 0xc3, 0x9a, 0x35, 0x78, 0x42, 0x91, 0x9a, 0xe5, 0xfa, + 0x7c, 0x3c, 0x91, 0x3e, 0x0b, 0x52, 0x9f, 0x5a, 0xaa, 0x4f, 0xae, 0x05, 0xf9, 0x0e, 0x54, 0xf7, + 0x7a, 0xd4, 0x96, 0x51, 0xe4, 0x5a, 0xce, 0x2d, 0x54, 0xe3, 0xb8, 0x83, 0xb5, 0xd6, 0xac, 0x94, + 0x50, 0x8d, 0x7a, 0xd4, 0x36, 0x90, 0x43, 0xd9, 0x2d, 0x3f, 0xaf, 0xc0, 0xac, 0x4a, 0xce, 0xad, + 0xb1, 0xee, 0x38, 0xa1, 0x6a, 0x0d, 0xcb, 0x71, 0x42, 0x03, 0xa1, 0xe4, 0x03, 0x80, 0xdd, 0xf8, + 0xd0, 0x73, 0x6d, 0xa4, 0x29, 0xe7, 0x09, 0xab, 0x87, 0x50, 0x93, 0x93, 0x2a, 0x36, 0x51, 0x88, + 0xc9, 0x5d, 0xa8, 0x3d, 0x0e, 0x22, 0xc6, 0x73, 0xa4, 0xb4, 0x0b, 0x26, 0xec, 0x63, 0x09, 0x33, + 0x32, 0x2c, 0xb1, 0xa0, 0xbe, 0xd1, 0x75, 0x64, 0x72, 0xab, 0x62, 0x72, 0x7b, 0x7b, 0xbc, 0x72, + 0x2b, 0x19, 0x9d, 0xc8, 0x71, 0xb7, 0xa5, 0xae, 0x4b, 0x76, 0xd7, 0x31, 0x47, 0x72, 0x5d, 0x2e, + 0x95, 0x3b, 0x53, 0x1a, 0x23, 0xa4, 0xf9, 0xc8, 0x68, 0x08, 0xca, 0x9d, 0x29, 0x94, 0x10, 0xd5, + 0x99, 0xb2, 0xdc, 0xf3, 0x3e, 0xd4, 0x9f, 0x47, 0x74, 0x3f, 0xf6, 0x7d, 0xea, 0x61, 0xe0, 0xad, + 0xb5, 0x9a, 0x7c, 0x0e, 0x71, 0x44, 0x4d, 0x86, 0x50, 0x75, 0x0e, 0x19, 0xe9, 0xcd, 0x03, 0x98, + 0x2f, 0x4e, 0x7f, 0x4c, 0xfa, 0x5b, 0x51, 0xd3, 0x5f, 0x63, 0xad, 0x99, 0x4f, 0x72, 0x23, 0xe8, + 0x76, 0x2d, 0x5f, 0xb0, 0x1f, 0xac, 0xa9, 0x89, 0xf1, 0x47, 0x25, 0x98, 0x2f, 0x62, 0xc9, 0x0a, + 0x4c, 0xcb, 0xc4, 0x50, 0xc2, 0xc4, 0xc0, 0x7d, 0x78, 0x5a, 0xa4, 0x84, 0x42, 0x22, 0x90, 0x54, + 0xdc, 0x85, 0xa5, 0x84, 0x66, 0x79, 0xb9, 0x92, 0xba, 0xb0, 0x2d, 0x40, 0x46, 0x8a, 0x23, 0x3a, + 0x4c, 0x1b, 0x34, 0x8a, 0x3d, 0x26, 0x17, 0x14, 0xb8, 0xd8, 0x10, 0x21, 0x86, 0xc4, 0xe8, 0x3f, + 0x00, 0xd8, 0xdf, 0xd9, 0xdb, 0xa6, 0xfd, 0x5d, 0xcb, 0xc5, 0x78, 0xb2, 0x41, 0x43, 0x86, 0xd3, + 0x98, 0x15, 0xf1, 0xc4, 0xa6, 0x21, 0x53, 0xe3, 0x09, 0xc7, 0x93, 0xb7, 0xa0, 0xb2, 0x4d, 0xfb, + 0xa8, 0xf5, 0x6c, 0xeb, 0xca, 0x20, 0xd1, 0xe6, 0x4e, 0xa8, 0x12, 0xb7, 0x0c, 0x8e, 0xd5, 0x7f, + 0x56, 0x86, 0xcb, 0x9c, 0x7a, 0x3d, 0x66, 0xc7, 0x41, 0xe8, 0xb2, 0xfe, 0x45, 0xde, 0xcc, 0x1f, + 0x15, 0x36, 0xf3, 0x1b, 0xca, 0x42, 0xab, 0x1a, 0x4e, 0xb4, 0xa7, 0xff, 0xba, 0x0a, 0x8b, 0x63, + 0xb8, 0xc8, 0x3d, 0xa8, 0xee, 0xf7, 0x7b, 0x69, 0x8d, 0xc4, 0x7d, 0xb4, 0xca, 0x0f, 0x0f, 0x9f, + 0x27, 0xda, 0x6c, 0x4a, 0xce, 0xf1, 0x06, 0x52, 0x91, 0x35, 0x68, 0x6c, 0x78, 0x71, 0xc4, 0x64, + 0xf9, 0x2e, 0xec, 0x85, 0x55, 0x9c, 0x2d, 0xc0, 0xa2, 0x7e, 0x57, 0x89, 0xc8, 0x7b, 0x30, 0xbb, + 0x71, 0x4c, 0xed, 0x13, 0xd7, 0xef, 0x6c, 0xd3, 0x7e, 0xd4, 0xac, 0x2c, 0x57, 0xd2, 0xf5, 0xb3, + 0x25, 0xdc, 0x3c, 0xa1, 0xfd, 0xc8, 0x28, 0x90, 0x91, 0xef, 0x42, 0x63, 0xcf, 0xed, 0xf8, 0x29, + 0x57, 0x15, 0xb9, 0x6e, 0xf2, 0x92, 0x22, 0x12, 0x60, 0x64, 0x52, 0x0b, 0x61, 0x85, 0x9c, 0x17, + 0x74, 0x46, 0xe0, 0x51, 0x51, 0x07, 0xcb, 0x82, 0x2e, 0xe4, 0x00, 0xb5, 0xa0, 0x43, 0x0a, 0xb2, + 0x0d, 0x33, 0xfc, 0xe3, 0x89, 0xd5, 0x6b, 0x4e, 0x63, 0x5c, 0xb9, 0xaa, 0xee, 0x7a, 0x44, 0xf4, + 0x5c, 0xbf, 0xa3, 0x6e, 0x7c, 0x8f, 0x9a, 0x5d, 0xab, 0xa7, 0xba, 0x86, 0x24, 0x24, 0xdf, 0x87, + 0x46, 0xee, 0xd9, 0x51, 0x73, 0x06, 0x05, 0x2e, 0xe5, 0x02, 0x73, 0x64, 0x4b, 0x93, 0xf2, 0xae, + 0x33, 0x2f, 0xe2, 0xba, 0x98, 0x3d, 0xce, 0xa2, 0x2a, 0xa4, 0x48, 0x2a, 0x04, 0xa7, 0xda, 0x6b, + 0x83, 0x53, 0xe9, 0xbc, 0xe0, 0xa4, 0x1b, 0xd0, 0x50, 0x14, 0x13, 0x3b, 0xb6, 0x1b, 0x64, 0x85, + 0xb2, 0xdc, 0xb1, 0x1c, 0x62, 0x48, 0x0c, 0xd1, 0x60, 0x6a, 0x27, 0xb0, 0x2d, 0x4f, 0x6e, 0xfd, + 0xfa, 0x20, 0xd1, 0xa6, 0x3c, 0x0e, 0x30, 0x04, 0x5c, 0xff, 0xaf, 0x12, 0x2c, 0xec, 0x86, 0xc1, + 0xa9, 0xcb, 0x5d, 0x7f, 0x3f, 0x38, 0xa1, 0xfe, 0xc1, 0xb7, 0xc9, 0x56, 0xba, 0x0a, 0x25, 0xe4, + 0xba, 0xcf, 0xb9, 0x70, 0x15, 0x3e, 0x4f, 0xb4, 0x77, 0xce, 0x3d, 0x55, 0xa2, 0xf5, 0xd3, 0x55, + 0x52, 0xce, 0x22, 0xe5, 0xc9, 0x8b, 0x9b, 0x73, 0xce, 0x22, 0x1a, 0x4c, 0xe1, 0x54, 0xe5, 0x36, + 0x46, 0xad, 0x18, 0x07, 0x18, 0x02, 0xae, 0xec, 0x9f, 0xbf, 0x2f, 0x8f, 0xe8, 0x77, 0x81, 0x03, + 0xcb, 0xc7, 0x85, 0xc0, 0xa2, 0x9c, 0x12, 0x8b, 0x2a, 0x4e, 0x14, 0x59, 0x2c, 0x58, 0x1a, 0xc7, + 0xf5, 0x15, 0x2e, 0xbe, 0xfe, 0x77, 0x65, 0x98, 0xe7, 0x07, 0x35, 0xd7, 0xc6, 0x01, 0xa2, 0x8b, + 0x6c, 0xfa, 0x3f, 0x28, 0x98, 0xfe, 0xb6, 0x52, 0xc3, 0x28, 0x0a, 0x4e, 0x64, 0xf8, 0x13, 0x20, + 0xa3, 0x3c, 0xe4, 0x39, 0xcc, 0xaa, 0x50, 0xb4, 0x7e, 0xe1, 0x30, 0x35, 0xbc, 0x4b, 0x5b, 0x57, + 0xe5, 0x28, 0x73, 0x11, 0xf2, 0x99, 0xb8, 0x03, 0x22, 0xa3, 0x20, 0x46, 0xff, 0xdb, 0x32, 0xcc, + 0x29, 0x51, 0xfd, 0x22, 0xaf, 0xc0, 0x83, 0xc2, 0x0a, 0xdc, 0x52, 0xb2, 0x6a, 0xae, 0xdf, 0x44, + 0x0b, 0xf0, 0x08, 0xae, 0x8c, 0xb0, 0x0c, 0xa7, 0xc8, 0xd2, 0x04, 0x29, 0x52, 0x14, 0x2d, 0xe2, + 0xff, 0x46, 0xe0, 0x1f, 0xb9, 0x9d, 0x83, 0xfb, 0x5f, 0xc7, 0xa2, 0x45, 0xd5, 0x10, 0xad, 0x75, + 0xff, 0x1c, 0x03, 0xff, 0x64, 0x0a, 0x16, 0xc7, 0x70, 0x91, 0x75, 0x58, 0xd8, 0xa3, 0x11, 0x4e, + 0x9c, 0xda, 0x41, 0xe8, 0xb8, 0x7e, 0x47, 0xda, 0x09, 0x0f, 0x8c, 0x91, 0xc0, 0x99, 0x61, 0x8a, + 0x34, 0x46, 0xc8, 0xb1, 0x3d, 0x23, 0x24, 0x6f, 0xb5, 0xa5, 0x09, 0x45, 0x7b, 0x46, 0x2e, 0x12, + 0xb6, 0x67, 0x52, 0x02, 0xb2, 0x03, 0x8b, 0xbb, 0x61, 0xf0, 0xb2, 0x8f, 0x15, 0x4a, 0xc4, 0x0f, + 0x25, 0xb2, 0x94, 0xe1, 0x7c, 0x58, 0x94, 0xf4, 0x38, 0xda, 0xc4, 0x82, 0x26, 0x32, 0xf9, 0xf9, + 0x45, 0xd4, 0x34, 0xe3, 0xd8, 0xc8, 0x87, 0x30, 0xb5, 0x1e, 0x3b, 0x2e, 0x93, 0x06, 0x56, 0xea, + 0x0d, 0x04, 0x0b, 0x55, 0x5b, 0x73, 0xd2, 0x34, 0x53, 0x16, 0x07, 0x1a, 0x82, 0x85, 0x7c, 0xc2, + 0x7d, 0xce, 0xa5, 0x3e, 0xdb, 0x72, 0x3c, 0xca, 0x33, 0x5e, 0x10, 0x33, 0x34, 0x75, 0xa5, 0xf5, + 0xd6, 0x20, 0xd1, 0x16, 0x45, 0x47, 0xc2, 0x74, 0x1d, 0x8f, 0x9a, 0x4c, 0xa0, 0x0b, 0xd5, 0xfc, + 0x28, 0x37, 0xf9, 0x01, 0x5c, 0x6d, 0xbb, 0x91, 0x1d, 0xf8, 0x3e, 0xb5, 0x99, 0x48, 0x8d, 0x0e, + 0x16, 0xe4, 0xe2, 0xdc, 0xc2, 0xc5, 0x5e, 0x77, 0x32, 0x02, 0x53, 0xe4, 0x54, 0xc7, 0xe4, 0x35, + 0xfa, 0xe7, 0x89, 0x56, 0x6d, 0x05, 0x81, 0x67, 0x8c, 0x97, 0xc0, 0x67, 0x9b, 0xb5, 0x7e, 0xb7, + 0x7c, 0x46, 0xc3, 0x53, 0xcb, 0x93, 0xbd, 0x3f, 0x9c, 0xed, 0x09, 0xa5, 0x3d, 0xd3, 0xe2, 0x58, + 0xd3, 0x95, 0xe8, 0xe2, 0x6c, 0x47, 0xb8, 0xc9, 0x43, 0x45, 0xe4, 0x46, 0x10, 0xfb, 0xec, 0x89, + 0xf5, 0x12, 0x2b, 0xa2, 0x8a, 0x38, 0x61, 0x29, 0x22, 0x6d, 0x8e, 0x36, 0xbb, 0xd6, 0x4b, 0x63, + 0x94, 0x85, 0xfc, 0x2e, 0xd4, 0xb1, 0x72, 0xe1, 0x15, 0x6e, 0xb3, 0x8e, 0x9a, 0xf2, 0x3d, 0x04, + 0x58, 0xd5, 0x98, 0x56, 0xcc, 0x8e, 0x33, 0xe5, 0x72, 0x42, 0xfd, 0xd3, 0x0a, 0x34, 0x94, 0x45, + 0xe2, 0x67, 0x17, 0xa5, 0x7c, 0xc6, 0xb3, 0x0b, 0x2f, 0x9f, 0xd5, 0xb3, 0x0b, 0x16, 0xce, 0xf7, + 0x78, 0x8d, 0xd5, 0xe1, 0x9b, 0x4f, 0xf8, 0x1a, 0x36, 0x5e, 0x43, 0x84, 0xa8, 0x8d, 0x57, 0x41, + 0x43, 0x76, 0x60, 0x01, 0x07, 0x91, 0x5e, 0x1b, 0x3d, 0x37, 0xb6, 0xa4, 0xaf, 0x2d, 0x0f, 0x12, + 0xed, 0x36, 0x3a, 0x84, 0x29, 0xbd, 0x3c, 0x32, 0xe3, 0xd0, 0x55, 0x64, 0x8c, 0x70, 0x92, 0x7f, + 0x2c, 0xc1, 0x3c, 0x02, 0x37, 0x4f, 0xa9, 0xcf, 0x50, 0x58, 0x55, 0x76, 0x07, 0xb2, 0x56, 0xfd, + 0x1e, 0x0b, 0x5d, 0xbf, 0x73, 0xc0, 0xcf, 0x8b, 0x51, 0xeb, 0x8f, 0xb8, 0xe7, 0xfd, 0x22, 0xd1, + 0xde, 0xff, 0x62, 0x8d, 0x7f, 0x29, 0x24, 0x1a, 0x24, 0xda, 0x4d, 0x31, 0x45, 0x8a, 0x03, 0x0e, + 0x4d, 0x70, 0x68, 0x2e, 0xe4, 0xa1, 0x9c, 0xdd, 0xbe, 0x75, 0xe8, 0x51, 0x8c, 0x99, 0x53, 0xa8, + 0xea, 0x9d, 0x5c, 0x0e, 0xe3, 0x28, 0x8c, 0x9b, 0x23, 0x72, 0x32, 0x2e, 0xfd, 0xff, 0x4a, 0x4a, + 0x7b, 0xfd, 0xe2, 0x86, 0xcf, 0x0f, 0x0a, 0xe1, 0xf3, 0x7a, 0xce, 0x9d, 0xe9, 0xc6, 0xd1, 0xe3, + 0x02, 0xa7, 0x7e, 0x19, 0xe6, 0x0a, 0x44, 0x98, 0x57, 0xd6, 0x6d, 0x9b, 0x46, 0x91, 0x41, 0xff, + 0x2c, 0xa6, 0x11, 0xfb, 0x5a, 0xe6, 0x95, 0x82, 0x86, 0x13, 0xe5, 0x95, 0xff, 0x28, 0xc3, 0xe2, + 0x18, 0x2e, 0x6e, 0x9b, 0xe7, 0x11, 0x2d, 0xf4, 0xb9, 0xe2, 0x88, 0x86, 0x06, 0x42, 0xf9, 0x69, + 0x41, 0x14, 0xb4, 0xca, 0x19, 0x08, 0x0b, 0xda, 0xf4, 0x8c, 0xb2, 0x9e, 0x5e, 0x38, 0x70, 0x43, + 0xcc, 0xab, 0xcd, 0xb7, 0x74, 0x18, 0x8e, 0x7d, 0xed, 0x45, 0xc4, 0x1e, 0xcc, 0x6c, 0x84, 0x14, + 0x9b, 0xec, 0xd5, 0xc9, 0x8f, 0x39, 0xb6, 0x60, 0x19, 0x3e, 0xe6, 0x48, 0x49, 0xea, 0xd9, 0x69, + 0xea, 0xab, 0x3a, 0x3b, 0xe9, 0x7f, 0x59, 0x1a, 0xb2, 0xe1, 0x43, 0xd7, 0x63, 0x34, 0x24, 0xd7, + 0xf0, 0x7e, 0x47, 0x58, 0x70, 0x7a, 0x90, 0x68, 0x65, 0xd7, 0x31, 0xca, 0x5b, 0xed, 0xcc, 0xb6, + 0xe5, 0xb1, 0xb6, 0xfd, 0xbd, 0xc9, 0x4c, 0x87, 0x36, 0x47, 0xd3, 0x49, 0x83, 0xe9, 0x7f, 0x51, + 0x86, 0x69, 0x6e, 0xfd, 0x8b, 0xec, 0xd9, 0xef, 0x17, 0x3c, 0x7b, 0xa9, 0xd8, 0x7e, 0x98, 0xc8, + 0xa1, 0x7f, 0x5d, 0x02, 0xc8, 0x89, 0xc9, 0xf7, 0x60, 0xe6, 0x19, 0x5e, 0x08, 0xa6, 0x77, 0x1a, + 0x43, 0x2d, 0x0d, 0x89, 0x6c, 0xdd, 0x48, 0xd7, 0x3a, 0x10, 0x00, 0xd5, 0x0a, 0x92, 0x86, 0x3c, + 0x82, 0xa9, 0x75, 0xcf, 0x0b, 0x5e, 0x8c, 0x76, 0x1b, 0xb9, 0xa4, 0x8d, 0xc0, 0x77, 0x5c, 0x21, + 0xec, 0xba, 0x14, 0x76, 0xd9, 0xe2, 0xe4, 0xaa, 0x6b, 0x23, 0x3f, 0x69, 0x43, 0xb5, 0x4d, 0xfd, + 0xf4, 0x6e, 0xe2, 0x6c, 0x39, 0xd7, 0xa4, 0x9c, 0x79, 0x87, 0xfa, 0x6a, 0x7b, 0x0f, 0xb9, 0xf5, + 0x9f, 0x56, 0x45, 0xf3, 0x22, 0x9d, 0xde, 0x03, 0x98, 0x7d, 0x18, 0x84, 0x2f, 0xac, 0xd0, 0x59, + 0xef, 0x50, 0x5f, 0x34, 0x11, 0x6b, 0xd8, 0x7e, 0x9e, 0x3b, 0x12, 0x70, 0xd3, 0xe2, 0x88, 0x2c, + 0x99, 0x17, 0xc8, 0xc9, 0x33, 0x98, 0x7b, 0x62, 0xbd, 0x94, 0xd9, 0x72, 0x7f, 0x7f, 0x07, 0xb5, + 0xac, 0xb4, 0xde, 0x1d, 0x24, 0xda, 0x8d, 0xae, 0xf5, 0x32, 0x4d, 0xb2, 0x26, 0x63, 0xde, 0x19, + 0xf7, 0x64, 0x45, 0x7e, 0xe2, 0xc1, 0xfc, 0x6e, 0x10, 0x32, 0x39, 0x08, 0x2f, 0x4c, 0x85, 0xbe, + 0x8b, 0xb9, 0xbe, 0x7c, 0x1a, 0x98, 0x69, 0x5b, 0xab, 0xaf, 0x12, 0xad, 0xf4, 0x8b, 0x44, 0x03, + 0x0e, 0x12, 0x1a, 0xf1, 0x81, 0x79, 0x66, 0x35, 0x8f, 0x32, 0x09, 0x6a, 0xce, 0x2b, 0xca, 0x26, + 0x0f, 0xe0, 0x0a, 0xaf, 0xb3, 0xdc, 0x23, 0xd7, 0xb6, 0x18, 0x7d, 0x18, 0x84, 0x5d, 0x8b, 0xc9, + 0xcb, 0x46, 0xbc, 0x54, 0xe7, 0x35, 0x1a, 0x97, 0xd4, 0xb5, 0x98, 0x31, 0x4a, 0x49, 0xfe, 0xf0, + 0xec, 0x62, 0xf2, 0x5b, 0x83, 0x44, 0x7b, 0x63, 0x4c, 0x31, 0x79, 0x86, 0x15, 0xc6, 0x94, 0x95, + 0x9d, 0xd7, 0x97, 0x95, 0xdf, 0x96, 0xad, 0xaa, 0x37, 0xcf, 0x28, 0x2d, 0x0b, 0x03, 0xbd, 0xae, + 0xc8, 0xd4, 0x7f, 0x52, 0x81, 0xf9, 0xa2, 0x0f, 0x11, 0x1d, 0xa6, 0x77, 0x82, 0x8e, 0xeb, 0xa7, + 0xcd, 0x07, 0x6c, 0x69, 0x79, 0x08, 0x31, 0x24, 0x86, 0xbc, 0x0d, 0x90, 0x65, 0xcb, 0x34, 0xa6, + 0xcb, 0xeb, 0x78, 0x05, 0x41, 0xfe, 0x04, 0xe0, 0x69, 0xe0, 0x50, 0x79, 0xf3, 0x50, 0x91, 0xdb, + 0x29, 0xab, 0x79, 0x44, 0x37, 0x5d, 0xd4, 0x4d, 0xdf, 0x90, 0x75, 0x93, 0xbc, 0x3f, 0x1f, 0x24, + 0xda, 0x55, 0x3f, 0x70, 0xe8, 0xe8, 0xa5, 0x83, 0x22, 0x91, 0x3c, 0x80, 0x29, 0x23, 0xf6, 0x68, + 0x7a, 0xa9, 0x31, 0xaf, 0xec, 0x8b, 0xd8, 0xa3, 0xf9, 0xae, 0x0a, 0xe3, 0xe1, 0xee, 0x25, 0x07, + 0x90, 0x8f, 0x00, 0xb6, 0xe3, 0x43, 0xfa, 0x28, 0x0c, 0xe2, 0x5e, 0xda, 0xed, 0xd4, 0x06, 0x89, + 0x76, 0xeb, 0x24, 0x3e, 0xa4, 0xa1, 0x4f, 0x19, 0x8d, 0xcc, 0x0e, 0x22, 0xd5, 0xf1, 0x73, 0x16, + 0x62, 0xc0, 0x8c, 0x0c, 0xb1, 0xf2, 0x92, 0xff, 0xcd, 0x33, 0x32, 0xab, 0xb2, 0x45, 0xf1, 0x94, + 0x15, 0x0a, 0x70, 0xa1, 0x0b, 0x2a, 0x40, 0x7a, 0x1b, 0xae, 0x9f, 0xc1, 0x9a, 0x37, 0x66, 0x4b, + 0xe7, 0x35, 0x66, 0xf5, 0xff, 0x2c, 0x41, 0x95, 0x2b, 0x49, 0xde, 0x83, 0x7a, 0x7a, 0x05, 0x99, + 0xf2, 0x5d, 0xe7, 0xa7, 0x87, 0x30, 0x05, 0xaa, 0x77, 0x29, 0x19, 0x25, 0x1f, 0xea, 0x80, 0x86, + 0x87, 0xe9, 0xda, 0xe2, 0x50, 0xa7, 0x1c, 0xa0, 0x0e, 0x85, 0x14, 0x9c, 0xf4, 0xfb, 0xc7, 0x34, + 0x4c, 0x2f, 0xa1, 0x90, 0xf4, 0x05, 0x07, 0xa8, 0xa4, 0x48, 0x41, 0x56, 0x61, 0x66, 0xdd, 0x16, + 0xb1, 0xb5, 0x8a, 0x72, 0xd1, 0x18, 0x96, 0x3d, 0x12, 0x40, 0x25, 0x95, 0xfe, 0x26, 0xd4, 0xb3, + 0x1d, 0x4f, 0x96, 0x60, 0x0a, 0x3f, 0x44, 0x9c, 0x32, 0xc4, 0x1f, 0x4c, 0x62, 0x3c, 0x0d, 0x5e, + 0xe4, 0xae, 0xca, 0x99, 0x49, 0x8c, 0x2b, 0x36, 0x51, 0x3b, 0xe5, 0x5f, 0xa7, 0x01, 0x72, 0x62, + 0x42, 0x61, 0xfe, 0xd9, 0x56, 0x7b, 0x63, 0xcb, 0xa1, 0x3e, 0x73, 0x99, 0x4b, 0xc7, 0xb4, 0xb2, + 0x36, 0x5f, 0x32, 0x1a, 0xfa, 0x96, 0x27, 0x69, 0xfa, 0xad, 0x37, 0xe5, 0x00, 0x37, 0x02, 0xd7, + 0xb1, 0x4d, 0x37, 0x63, 0x55, 0x43, 0x68, 0x51, 0x28, 0x1f, 0x66, 0x6f, 0xfd, 0xc9, 0x8e, 0x32, + 0x4c, 0x79, 0xf2, 0x61, 0x22, 0xab, 0xeb, 0x9d, 0x31, 0x4c, 0x51, 0x28, 0x39, 0x81, 0x85, 0x47, + 0x78, 0x9a, 0x52, 0x06, 0xaa, 0x9c, 0x3b, 0xd0, 0x5b, 0x72, 0xa0, 0x5b, 0xe2, 0x24, 0x36, 0x7e, + 0xa8, 0x11, 0xc1, 0xf9, 0x26, 0xab, 0x9e, 0x7b, 0xfb, 0xf1, 0xc3, 0x12, 0x4c, 0xef, 0x87, 0x96, + 0xcb, 0xd2, 0xda, 0xf0, 0x8c, 0xd8, 0xf6, 0x89, 0x8c, 0x6d, 0xef, 0x7d, 0xc1, 0x33, 0xa1, 0x90, + 0xcd, 0x4f, 0xbb, 0x0c, 0xbf, 0xd4, 0xd3, 0xae, 0xc0, 0x91, 0x47, 0x30, 0xcd, 0x6b, 0xb9, 0x38, + 0x7d, 0x65, 0xa4, 0x14, 0x2b, 0x18, 0xaa, 0x05, 0xb2, 0xd5, 0x94, 0xb6, 0x58, 0x88, 0xf0, 0xbf, + 0x2a, 0x48, 0x50, 0xa8, 0xaf, 0xba, 0x66, 0x7e, 0xb3, 0x57, 0x5d, 0xe4, 0x19, 0xd4, 0x65, 0xf5, + 0xdc, 0xea, 0xcb, 0xfb, 0x16, 0x25, 0x83, 0x67, 0x28, 0xe5, 0x72, 0x59, 0x80, 0x4c, 0xf5, 0x25, + 0x85, 0x91, 0xcb, 0x20, 0xc6, 0x70, 0xbb, 0xa1, 0xb0, 0xf0, 0x19, 0x6a, 0x8f, 0xda, 0x21, 0x65, + 0x91, 0x68, 0x65, 0xe4, 0xad, 0x08, 0x55, 0x66, 0xde, 0x8c, 0xf8, 0x71, 0x09, 0x16, 0x86, 0x5d, + 0x86, 0x7c, 0x17, 0x1a, 0x1b, 0x22, 0x47, 0x06, 0x61, 0x56, 0x88, 0x63, 0x8b, 0xca, 0x4e, 0xc1, + 0x66, 0xe1, 0xc9, 0x95, 0x4a, 0x4e, 0xd6, 0xa0, 0xc6, 0xb7, 0xa0, 0x9f, 0xdf, 0xee, 0x61, 0x84, + 0x89, 0x25, 0x4c, 0xbd, 0x4e, 0x4a, 0xe9, 0x94, 0x1d, 0xfc, 0xef, 0x65, 0x68, 0x28, 0x4b, 0x46, + 0xde, 0x85, 0xda, 0x56, 0xb4, 0x13, 0xd8, 0x27, 0xd4, 0x91, 0x85, 0x19, 0x3e, 0xdd, 0x73, 0x23, + 0xd3, 0x43, 0xa0, 0x91, 0xa1, 0x49, 0x0b, 0xe6, 0xc4, 0xd7, 0x13, 0x1a, 0x45, 0x56, 0x27, 0x1d, + 0xfd, 0xf6, 0x20, 0xd1, 0x9a, 0x82, 0xd8, 0xec, 0x0a, 0x8c, 0x32, 0x87, 0x22, 0x0b, 0xf9, 0x63, + 0x00, 0x01, 0xe0, 0xab, 0x3c, 0xc1, 0x1b, 0x98, 0x74, 0x1b, 0x5f, 0x95, 0x03, 0xf0, 0x12, 0x67, + 0xe8, 0xb8, 0xa3, 0x08, 0xc4, 0x47, 0x50, 0x81, 0x7d, 0x32, 0xf9, 0xc3, 0xc1, 0xfc, 0x11, 0x54, + 0x60, 0x9f, 0x98, 0xe3, 0xcf, 0x53, 0xaa, 0x48, 0xfd, 0x57, 0x25, 0xc5, 0xed, 0xc8, 0x27, 0x50, + 0xcf, 0x96, 0x46, 0xd6, 0xf1, 0xd7, 0xd4, 0xbb, 0x7e, 0x89, 0x32, 0xe8, 0x51, 0xeb, 0x96, 0x2c, + 0xa6, 0x16, 0xb3, 0x35, 0x2e, 0x78, 0x61, 0x0a, 0x24, 0x1f, 0x43, 0x15, 0x6d, 0x73, 0xfe, 0x15, + 0x5a, 0x1a, 0xea, 0xab, 0xdc, 0x28, 0x38, 0x53, 0xe4, 0x24, 0xf7, 0xe5, 0x31, 0x4e, 0x58, 0xf7, + 0x4a, 0x31, 0xcc, 0xf3, 0xa9, 0x64, 0x31, 0x3e, 0x3f, 0xdd, 0x29, 0x1e, 0xf2, 0xe7, 0x25, 0x58, + 0x7c, 0xbe, 0xf6, 0xd0, 0xa0, 0x1d, 0x37, 0x62, 0xa2, 0x76, 0x6c, 0xf3, 0xec, 0x71, 0x03, 0x2a, + 0x86, 0xf5, 0x42, 0x3e, 0x01, 0x98, 0x19, 0x24, 0x5a, 0x25, 0xb4, 0x5e, 0x18, 0x1c, 0x46, 0xee, + 0x41, 0x7d, 0x9b, 0xf6, 0x1f, 0x5b, 0xbe, 0xe3, 0x51, 0x79, 0xf9, 0x8f, 0x9d, 0xda, 0x13, 0xda, + 0x37, 0x8f, 0x11, 0x6a, 0xe4, 0x04, 0xbc, 0xf2, 0xdb, 0x8d, 0x0f, 0xb7, 0xa9, 0x38, 0x67, 0xcc, + 0x8a, 0xca, 0xaf, 0x17, 0x1f, 0x9e, 0xd0, 0xbe, 0x21, 0x31, 0xfa, 0x3f, 0x97, 0x61, 0x61, 0x78, + 0xc7, 0x91, 0x8f, 0x60, 0x76, 0xd7, 0x8a, 0xa2, 0x17, 0x41, 0xe8, 0x3c, 0xb6, 0xa2, 0x63, 0x39, + 0x95, 0x5b, 0x83, 0x44, 0xbb, 0xde, 0x93, 0x70, 0xf3, 0xd8, 0x8a, 0xd4, 0xad, 0x58, 0x60, 0xe0, + 0xb9, 0x79, 0xff, 0xd9, 0xfe, 0x6e, 0xfa, 0x44, 0x41, 0xee, 0x1c, 0x16, 0xb0, 0x9e, 0x59, 0x7c, + 0xa7, 0x90, 0x92, 0x91, 0x0e, 0x5c, 0x1e, 0xb2, 0x85, 0x34, 0xab, 0xd2, 0xdc, 0x18, 0x63, 0x2c, + 0xd1, 0x19, 0x8b, 0xd7, 0x8e, 0xcc, 0x50, 0xc1, 0x28, 0x03, 0x0c, 0x4b, 0x25, 0x1f, 0x00, 0x3c, + 0x5f, 0x7b, 0x88, 0xad, 0x4f, 0x1a, 0xa2, 0xe3, 0xce, 0x89, 0x17, 0x3a, 0x5c, 0x88, 0x2d, 0xc0, + 0x6a, 0x79, 0x98, 0x13, 0xeb, 0x3e, 0xcc, 0xaa, 0x9e, 0xc6, 0xeb, 0x13, 0xa5, 0xe1, 0x59, 0x4b, + 0xdf, 0x0b, 0xc8, 0x36, 0xa7, 0x38, 0xfc, 0x97, 0x47, 0x0e, 0xff, 0x77, 0xa1, 0x96, 0x06, 0x28, + 0xf5, 0x9d, 0x8f, 0x4c, 0x67, 0x7d, 0x23, 0xc3, 0xea, 0xdf, 0x80, 0x19, 0xe9, 0x49, 0xaf, 0x7f, + 0x4c, 0xab, 0xff, 0xa8, 0x0c, 0x97, 0x0d, 0xca, 0x0b, 0x19, 0xf9, 0x76, 0xe6, 0x6b, 0xf9, 0xd0, + 0xa3, 0xa0, 0xe1, 0xd9, 0x55, 0x94, 0xfe, 0x2f, 0x25, 0x58, 0x1c, 0x43, 0xfb, 0x65, 0x6e, 0xa3, + 0xc8, 0xfb, 0x50, 0x6f, 0xbb, 0x96, 0xb7, 0xee, 0x38, 0x61, 0x5a, 0x3b, 0x63, 0x3a, 0x72, 0x5c, + 0x9e, 0x8d, 0x38, 0x54, 0x0d, 0x2e, 0x19, 0x29, 0xf9, 0xa6, 0x74, 0x8d, 0x4a, 0x66, 0xdc, 0xf4, + 0x29, 0x09, 0x88, 0x39, 0xe5, 0x0f, 0x49, 0xf4, 0x7f, 0x28, 0x03, 0x11, 0x40, 0xe9, 0x5d, 0x6e, + 0x70, 0xa1, 0x2f, 0xd4, 0x5b, 0x85, 0x05, 0x5c, 0x56, 0x1e, 0x7c, 0x0c, 0x29, 0x39, 0x51, 0x25, + 0xfc, 0xe3, 0x32, 0x5c, 0x1b, 0xcf, 0xf8, 0xa5, 0x16, 0xf4, 0x1e, 0xd4, 0xf1, 0x1a, 0x4a, 0x79, + 0xb3, 0x83, 0x11, 0x54, 0xdc, 0x59, 0x21, 0x7d, 0x4e, 0x40, 0x8e, 0x60, 0x6e, 0xc7, 0x8a, 0xd8, + 0x63, 0x6a, 0x85, 0xec, 0x90, 0x5a, 0x6c, 0x82, 0x44, 0x9a, 0x3d, 0x57, 0xc5, 0xd7, 0xbe, 0xc7, + 0x29, 0xe7, 0xf0, 0x73, 0xd5, 0x82, 0xd8, 0xcc, 0x5d, 0xaa, 0xe7, 0xbb, 0xcb, 0x37, 0x3f, 0x82, + 0x59, 0xb5, 0x0f, 0x48, 0x6a, 0x50, 0x7d, 0xfa, 0xec, 0xe9, 0xe6, 0xc2, 0x25, 0xd2, 0x80, 0x99, + 0xdd, 0xcd, 0xa7, 0xed, 0xad, 0xa7, 0x8f, 0x16, 0x4a, 0x64, 0x16, 0x6a, 0xeb, 0xbb, 0xbb, 0xc6, + 0xb3, 0x83, 0xcd, 0xf6, 0x42, 0x99, 0x00, 0x4c, 0xb7, 0x37, 0x9f, 0x6e, 0x6d, 0xb6, 0x17, 0x2a, + 0xad, 0xa5, 0x57, 0xff, 0x73, 0xe7, 0xd2, 0xab, 0xcf, 0xee, 0x94, 0x7e, 0xfe, 0xd9, 0x9d, 0xd2, + 0x7f, 0x7f, 0x76, 0xa7, 0xf4, 0xe9, 0xff, 0xde, 0xb9, 0x74, 0x38, 0x8d, 0xba, 0xdc, 0xff, 0xff, + 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0xab, 0x4c, 0x93, 0x30, 0x31, 0x00, 0x00, } diff --git a/lib/services/types.proto b/lib/services/types.proto index 0c0c3654277bc..0badccfdb9e77 100644 --- a/lib/services/types.proto +++ b/lib/services/types.proto @@ -371,6 +371,55 @@ message Namespace { message NamespaceSpec { } +// AccessRequest represents an access request resource specification +message AccessRequestV3 { + option (gogoproto.goproto_stringer) = false; + option (gogoproto.stringer) = false; + + // Kind is a resource kind + string Kind = 1 [(gogoproto.jsontag) = "kind"]; + // SubKind is an optional resource sub kind, used in some resources + string SubKind = 2 [(gogoproto.jsontag) = "sub_kind,omitempty"]; + // Version is version + string Version = 3 [(gogoproto.jsontag) = "version"]; + // Metadata is AccessRequest metadata + Metadata Metadata = 4 [(gogoproto.nullable) = false, (gogoproto.jsontag) = "metadata"]; + // Spec is an AccessReqeust specification + AccessRequestSpecV3 Spec = 5 [(gogoproto.nullable) = false, (gogoproto.jsontag) = "spec"]; +} + +// RequestState represents the state of a request for escalated privilege. +enum RequestState { + NONE = 0; + PENDING = 1; + APPROVED = 2; + DENIED = 3; +} + +// AccessRequestSpec is the specification for AccessRequest +message AccessRequestSpecV3 { + // User is the name of the user to whom the roles will be applied. + string User = 1 [(gogoproto.jsontag) = "user"]; + // Roles is the name of the roles being requested. + repeated string Roles = 2 [(gogoproto.jsontag) = "roles"]; + // State is the current state of this access request. + RequestState State = 3 [(gogoproto.jsontag) = "state,omitempty"]; + // Created encodes the time at which the request was registered with the auth server. + google.protobuf.Timestamp Created = 4 [(gogoproto.stdtime) = true, (gogoproto.nullable) = false, (gogoproto.jsontag) = "created,omitempty"]; + // Expires constrains the maximum lifetime of any login session for which this request is active. + google.protobuf.Timestamp Expires = 5 [(gogoproto.stdtime) = true, (gogoproto.nullable) = false, (gogoproto.jsontag) = "expires,omitempty"]; +} + +// AccessRequestFilter encodes filter params for access requests. +message AccessRequestFilter { + // ID specifies a request ID if set. + string ID = 1 [(gogoproto.jsontag) = "id"]; + // User specifies a username if set. + string User = 2 [(gogoproto.jsontag) = "user"]; + // RequestState filters for requests in a specific state. + RequestState State = 3 [(gogoproto.jsontag) = "state"]; +} + // RoleV3 represents role resource specification message RoleV3 { option (gogoproto.goproto_stringer) = false; @@ -444,6 +493,14 @@ message RoleConditions { // KubeGroups is a list of kubernetes groups repeated string KubeGroups = 5 [(gogoproto.jsontag) = "kubernetes_groups,omitempty"]; + + AccessRequestConditions Request = 6 [(gogoproto.jsontag) = "request,omitempty"]; +} + +// AccessRequestConditions is a matcher for allow/deny restrictions on access-requests. +message AccessRequestConditions { + // Roles is the name of roles which will match the request rule. + repeated string Roles = 1 [(gogoproto.jsontag) = "roles,omitempty"]; } // Rule represents allow or deny rule that is executed to check diff --git a/tool/tctl/common/access_request_command.go b/tool/tctl/common/access_request_command.go new file mode 100644 index 0000000000000..df54e8932be6b --- /dev/null +++ b/tool/tctl/common/access_request_command.go @@ -0,0 +1,171 @@ +/* +Copyright 2019 Gravitational, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package common + +import ( + "encoding/json" + "fmt" + "os" + "strings" + "time" + + "github.com/gravitational/kingpin" + "github.com/gravitational/teleport" + "github.com/gravitational/teleport/lib/asciitable" + "github.com/gravitational/teleport/lib/auth" + "github.com/gravitational/teleport/lib/service" + "github.com/gravitational/teleport/lib/services" + "github.com/gravitational/trace" +) + +// AccessRequestCommand implements `tctl users` set of commands +// It implements CLICommand interface +type AccessRequestCommand struct { + config *service.Config + reqIDs string + + user string + roles string + // format is the output format, e.g. text or json + format string + + requestList *kingpin.CmdClause + requestApprove *kingpin.CmdClause + requestDeny *kingpin.CmdClause + requestCreate *kingpin.CmdClause + requestDelete *kingpin.CmdClause +} + +// Initialize allows AccessRequestCommand to plug itself into the CLI parser +func (c *AccessRequestCommand) Initialize(app *kingpin.Application, config *service.Config) { + c.config = config + requests := app.Command("requests", "Manage access requests").Alias("request") + + c.requestList = requests.Command("ls", "Show active access requests") + c.requestList.Flag("format", "Output format, 'text' or 'json'").Hidden().Default(teleport.Text).StringVar(&c.format) + + c.requestApprove = requests.Command("approve", "Approve pending access request") + c.requestApprove.Arg("request-id", "ID of target request(s)").Required().StringVar(&c.reqIDs) + + c.requestDeny = requests.Command("deny", "Deny pending access request") + c.requestDeny.Arg("request-id", "ID of target request(s)").Required().StringVar(&c.reqIDs) + + c.requestCreate = requests.Command("create", "Create pending access request") + c.requestCreate.Arg("username", "Name of target user").Required().StringVar(&c.user) + c.requestCreate.Flag("roles", "Roles to be requested").Required().StringVar(&c.roles) + + c.requestDelete = requests.Command("rm", "Delete an access request") + c.requestDelete.Arg("request-id", "ID of target request(s)").Required().StringVar(&c.reqIDs) +} + +// TryRun takes the CLI command as an argument (like "access-request list") and executes it. +func (c *AccessRequestCommand) TryRun(cmd string, client auth.ClientI) (match bool, err error) { + switch cmd { + case c.requestList.FullCommand(): + err = c.List(client) + case c.requestApprove.FullCommand(): + err = c.Approve(client) + case c.requestDeny.FullCommand(): + err = c.Deny(client) + case c.requestCreate.FullCommand(): + err = c.Create(client) + default: + return false, nil + } + return true, trace.Wrap(err) +} + +func (c *AccessRequestCommand) List(client auth.ClientI) error { + reqs, err := client.GetAccessRequests(services.AccessRequestFilter{}) + if err != nil { + return trace.Wrap(err) + } + if err := c.PrintAccessRequests(client, reqs, c.format); err != nil { + return trace.Wrap(err) + } + return nil +} + +func (c *AccessRequestCommand) Approve(client auth.ClientI) error { + for _, reqID := range strings.Split(c.reqIDs, ",") { + if err := client.SetAccessRequestState(reqID, services.RequestState_APPROVED); err != nil { + return trace.Wrap(err) + } + } + return nil +} + +func (c *AccessRequestCommand) Deny(client auth.ClientI) error { + for _, reqID := range strings.Split(c.reqIDs, ",") { + if err := client.SetAccessRequestState(reqID, services.RequestState_DENIED); err != nil { + return trace.Wrap(err) + } + } + return nil +} + +func (c *AccessRequestCommand) Create(client auth.ClientI) error { + roles := strings.Split(c.roles, ",") + req, err := services.NewAccessRequest(c.user, roles...) + if err != nil { + return trace.Wrap(err) + } + if err := client.CreateAccessRequest(req); err != nil { + return trace.Wrap(err) + } + fmt.Printf("%s\n", req.GetName()) + return nil +} + +func (c *AccessRequestCommand) Delete(client auth.ClientI) error { + for _, reqID := range strings.Split(c.reqIDs, ",") { + if err := client.DeleteAccessRequest(reqID); err != nil { + return trace.Wrap(err) + } + } + return nil +} + +// PrintAccessRequests prints access requests +func (c *AccessRequestCommand) PrintAccessRequests(client auth.ClientI, reqs []services.AccessRequest, format string) error { + if format == teleport.Text { + table := asciitable.MakeTable([]string{"Token", "Requestor", "Metadata", "Created At (UTC)", "Status"}) + now := time.Now() + for _, req := range reqs { + if now.After(req.GetAccessExpiry()) { + continue + } + params := fmt.Sprintf("roles=%s", strings.Join(req.GetRoles(), ",")) + table.AddRow([]string{ + req.GetName(), + req.GetUser(), + params, + req.GetCreationTime().Format(time.RFC822), + req.GetState().String(), + }) + } + _, err := table.AsBuffer().WriteTo(os.Stdout) + return trace.Wrap(err) + } else { + out, err := json.MarshalIndent(reqs, "", " ") + if err != nil { + return trace.Wrap(err, "failed to marshal requests") + } + fmt.Printf("%s\n", out) + } + return nil +} diff --git a/tool/tctl/common/auth_command.go b/tool/tctl/common/auth_command.go index ed97b36583676..5d0cc40738efc 100644 --- a/tool/tctl/common/auth_command.go +++ b/tool/tctl/common/auth_command.go @@ -70,7 +70,7 @@ func (a *AuthCommand) Initialize(app *kingpin.Application, config *service.Confi a.authSign.Flag("user", "Teleport user name").StringVar(&a.genUser) a.authSign.Flag("host", "Teleport host name").StringVar(&a.genHost) a.authSign.Flag("out", "identity output").Short('o').StringVar(&a.output) - a.authSign.Flag("format", fmt.Sprintf("identity format: %q (default) or %q", client.IdentityFormatFile, client.IdentityFormatOpenSSH)).Default(string(client.DefaultIdentityFormat)).StringVar((*string)(&a.outputFormat)) + a.authSign.Flag("format", fmt.Sprintf("identity format: %q (default), %q, or %q", client.IdentityFormatFile, client.IdentityFormatOpenSSH, client.IdentityFormatTLS)).Default(string(client.DefaultIdentityFormat)).StringVar((*string)(&a.outputFormat)) a.authSign.Flag("ttl", "TTL (time to live) for the generated certificate").Default(fmt.Sprintf("%v", defaults.CertDuration)).DurationVar(&a.genTTL) a.authSign.Flag("compat", "OpenSSH compatibility flag").StringVar(&a.compatibility) @@ -348,7 +348,7 @@ func (a *AuthCommand) generateUserKeys(clusterApi auth.ClientI) error { key.TLSCert = certs.TLS var certAuthorities []services.CertAuthority - if a.outputFormat == client.IdentityFormatFile { + if a.outputFormat != client.IdentityFormatOpenSSH { certAuthorities, err = clusterApi.GetCertAuthorities(services.HostCA, false) if err != nil { return trace.Wrap(err) diff --git a/tool/tctl/common/token_command.go b/tool/tctl/common/token_command.go index 98b98c8ca8268..142be64161c07 100644 --- a/tool/tctl/common/token_command.go +++ b/tool/tctl/common/token_command.go @@ -186,10 +186,13 @@ func (c *TokenCommand) List(client auth.ClientI) error { if c.format == teleport.Text { tokensView := func() string { table := asciitable.MakeTable([]string{"Token", "Type", "Expiry Time (UTC)"}) + now := time.Now() for _, t := range tokens { expiry := "never" if t.Expiry().Unix() > 0 { - expiry = t.Expiry().Format(time.RFC822) + exptime := t.Expiry().Format(time.RFC822) + expdur := t.Expiry().Sub(now).Round(time.Second) + expiry = fmt.Sprintf("%s (%s)", exptime, expdur.String()) } table.AddRow([]string{t.GetName(), t.GetRoles().String(), expiry}) } diff --git a/tool/tctl/main.go b/tool/tctl/main.go index f9d3f1a493b35..20f0e97025bc7 100644 --- a/tool/tctl/main.go +++ b/tool/tctl/main.go @@ -29,6 +29,7 @@ func main() { &common.ResourceCommand{}, &common.StatusCommand{}, &common.TopCommand{}, + &common.AccessRequestCommand{}, } common.Run(commands) } diff --git a/tool/tsh/tsh.go b/tool/tsh/tsh.go index 6b1c07b97f81a..6624446610d08 100644 --- a/tool/tsh/tsh.go +++ b/tool/tsh/tsh.go @@ -18,8 +18,11 @@ package main import ( "context" + "crypto/tls" + "crypto/x509" "fmt" "io" + "io/ioutil" "net" "os" "os/signal" @@ -34,6 +37,8 @@ import ( "github.com/gravitational/teleport" "github.com/gravitational/teleport/lib/asciitable" + "github.com/gravitational/teleport/lib/auth" + "github.com/gravitational/teleport/lib/backend" "github.com/gravitational/teleport/lib/client" "github.com/gravitational/teleport/lib/defaults" kubeclient "github.com/gravitational/teleport/lib/kube/client" @@ -61,6 +66,8 @@ type CLIConf struct { UserHost string // Commands to execute on a remote host RemoteCommand []string + // DesiredRoles indicates one or more roles which should be requested. + DesiredRoles string // Username is the Teleport user's username (to login into proxies) Username string // Proxy keeps the hostname:port of the SSH proxy to use @@ -262,6 +269,7 @@ func Run(args []string, underTest bool) { login.Flag("format", fmt.Sprintf("Identity format [%s] or %s (for OpenSSH compatibility)", client.DefaultIdentityFormat, client.IdentityFormatOpenSSH)).Default(string(client.DefaultIdentityFormat)).StringVar((*string)(&cf.IdentityFormat)) + login.Flag("request-roles", "Request one or more extra roles").StringVar(&cf.DesiredRoles) login.Arg("cluster", clusterHelp).StringVar(&cf.SiteName) login.Alias(loginUsageFooter) @@ -411,18 +419,23 @@ func onLogin(cf *CLIConf) { if profile != nil && !profile.IsExpired(clockwork.NewRealClock()) { switch { // in case if nothing is specified, print current status - case cf.Proxy == "" && cf.SiteName == "": + case cf.Proxy == "" && cf.SiteName == "" && cf.DesiredRoles == "": printProfiles(cf.Debug, profile, profiles) return // in case if parameters match, print current status - case host(cf.Proxy) == host(profile.ProxyURL.Host) && cf.SiteName == profile.Cluster: + case host(cf.Proxy) == host(profile.ProxyURL.Host) && cf.SiteName == profile.Cluster && cf.DesiredRoles == "": printProfiles(cf.Debug, profile, profiles) return // proxy is unspecified or the same as the currently provided proxy, // but cluster is specified, treat this as selecting a new cluster // for the same proxy case (cf.Proxy == "" || host(cf.Proxy) == host(profile.ProxyURL.Host)) && cf.SiteName != "": - if err := tc.GenerateCertsForCluster(cf.Context, cf.SiteName); err != nil { + // trigger reissue, preserving any active requests. + err = tc.ReissueUserCerts(cf.Context, client.ReissueParams{ + AccessRequests: profile.ActiveRequests.AccessRequests, + RouteToCluster: cf.SiteName, + }) + if err != nil { utils.FatalError(err) } tc.SaveProfile("", "") @@ -431,6 +444,12 @@ func onLogin(cf *CLIConf) { } onStatus(cf) return + // proxy is unspecified or the same as the currently provided proxy, + // but desired roles are specified, treat this as a privilege escalation + // request for the same login session. + case (cf.Proxy == "" || host(cf.Proxy) == host(profile.ProxyURL.Host)) && cf.DesiredRoles != "": + executeAccessRequest(cf) + return // otherwise just passthrough to standard login default: } @@ -477,7 +496,12 @@ func onLogin(cf *CLIConf) { // advertised settings are picked up. webProxyHost, _ := tc.WebProxyHostPort() cf.Proxy = webProxyHost - onStatus(cf) + if cf.DesiredRoles != "" { + fmt.Println("") // visually separate onRequestExecute output + executeAccessRequest(cf) + } else { + onStatus(cf) + } } // setupNoninteractiveClient sets up existing client to use @@ -665,6 +689,33 @@ func onListNodes(cf *CLIConf) { } } +func executeAccessRequest(cf *CLIConf) { + if cf.DesiredRoles == "" { + utils.FatalError(trace.BadParameter("one or more roles must be specified")) + } + roles := strings.Split(cf.DesiredRoles, ",") + tc, err := makeClient(cf, true) + if err != nil { + utils.FatalError(err) + } + if cf.Username == "" { + cf.Username = tc.Username + } + req, err := services.NewAccessRequest(cf.Username, roles...) + if err != nil { + utils.FatalError(err) + } + fmt.Fprintf(os.Stderr, "Seeking request approval... (id: %s)\n", req.GetName()) + if err := getRequestApproval(cf, tc, req); err != nil { + utils.FatalError(err) + } + fmt.Fprintf(os.Stderr, "Approval received, getting updated certificates...\n\n") + if err := reissueWithRequests(cf, tc, req.GetName()); err != nil { + utils.FatalError(err) + } + onStatus(cf) +} + // chunkLabels breaks labels into sized chunks. Used to improve readability // of "tsh ls". func chunkLabels(labels map[string]string, chunkSize int) [][]string { @@ -1028,6 +1079,104 @@ func refuseArgs(command string, args []string) { } } +// loadIdentity loads the private key + certificate from a file +// Returns: +// - client key: user's private key+cert +// - host auth callback: function to validate the host (may be null) +// - error, if somthing happens when reading the identityf file +// +// If the "host auth callback" is not returned, user will be prompted to +// trust the proxy server. +func loadIdentity(idFn string) (*client.Key, ssh.HostKeyCallback, error) { + log.Infof("Reading identity file: %v", idFn) + + f, err := os.Open(idFn) + if err != nil { + return nil, nil, trace.Wrap(err) + } + defer f.Close() + ident, err := client.DecodeIdentityFile(f) + if err != nil { + return nil, nil, trace.Wrap(err, "failed to parse identity file") + } + // did not find the certificate in the file? look in a separate file with + // -cert.pub prefix + if len(ident.Certs.SSH) == 0 { + certFn := idFn + "-cert.pub" + log.Infof("Certificate not found in %s. Looking in %s.", idFn, certFn) + ident.Certs.SSH, err = ioutil.ReadFile(certFn) + if err != nil { + return nil, nil, trace.Wrap(err) + } + } + // validate both by parsing them: + privKey, err := ssh.ParseRawPrivateKey(ident.PrivateKey) + if err != nil { + return nil, nil, trace.BadParameter("invalid identity: %s. %v", idFn, err) + } + signer, err := ssh.NewSignerFromKey(privKey) + if err != nil { + return nil, nil, trace.Wrap(err) + } + // validate TLS Cert (if present): + if len(ident.Certs.TLS) > 0 { + _, err := tls.X509KeyPair(ident.Certs.TLS, ident.PrivateKey) + if err != nil { + return nil, nil, trace.Wrap(err) + } + } + // Validate TLS CA certs (if present). + var trustedCA []auth.TrustedCerts + if len(ident.CACerts.TLS) > 0 { + var trustedCerts auth.TrustedCerts + pool := x509.NewCertPool() + for i, certPEM := range ident.CACerts.TLS { + if !pool.AppendCertsFromPEM(certPEM) { + return nil, nil, trace.BadParameter("identity file contains invalid TLS CA cert (#%v)", i+1) + } + trustedCerts.TLSCertificates = append(trustedCerts.TLSCertificates, certPEM) + } + trustedCA = []auth.TrustedCerts{trustedCerts} + } + var hostAuthFunc ssh.HostKeyCallback = nil + // validate CA (cluster) cert + if len(ident.CACerts.SSH) > 0 { + var trustedKeys []ssh.PublicKey + for _, caCert := range ident.CACerts.SSH { + _, _, publicKey, _, _, err := ssh.ParseKnownHosts(caCert) + if err != nil { + return nil, nil, trace.BadParameter("CA cert parsing error: %v. cert line :%v", + err.Error(), string(caCert)) + } + trustedKeys = append(trustedKeys, publicKey) + } + + // found CA cert in the indentity file? construct the host key checking function + // and return it: + hostAuthFunc = func(host string, a net.Addr, hostKey ssh.PublicKey) error { + clusterCert, ok := hostKey.(*ssh.Certificate) + if ok { + hostKey = clusterCert.SignatureKey + } + for _, trustedKey := range trustedKeys { + if sshutils.KeysEqual(trustedKey, hostKey) { + return nil + } + } + err = trace.AccessDenied("host %v is untrusted", host) + log.Error(err) + return err + } + } + return &client.Key{ + Priv: ident.PrivateKey, + Pub: signer.PublicKey().Marshal(), + Cert: ident.Certs.SSH, + TLSCert: ident.Certs.TLS, + TrustedCA: trustedCA, + }, hostAuthFunc, nil +} + // authFromIdentity returns a standard ssh.Authmethod for a given identity file func authFromIdentity(k *client.Key) (ssh.AuthMethod, error) { signer, err := sshutils.NewSigner(k.Priv, k.Cert) @@ -1147,3 +1296,80 @@ func host(in string) string { } return out } + +// getRequestApproval registers an access request with the auth server and waits for it to be approved. +func getRequestApproval(cf *CLIConf, tc *client.TeleportClient, req services.AccessRequest) error { + // set up request watcher before submitting the request to the admin server + // in order to avoid potential race. + filter := services.AccessRequestFilter{ + User: tc.Username, + } + watcher, err := tc.NewWatcher(cf.Context, services.Watch{ + Name: "await-request-approval", + Kinds: []services.WatchKind{ + services.WatchKind{ + Kind: services.KindAccessRequest, + Filter: filter.IntoMap(), + }, + }, + }) + if err != nil { + return trace.Wrap(err) + } + defer watcher.Close() + if err := tc.CreateAccessRequest(cf.Context, req); err != nil { + utils.FatalError(err) + } +Loop: + for { + select { + case event := <-watcher.Events(): + if event.Type != backend.OpPut { + continue Loop + } + r, ok := event.Resource.(*services.AccessRequestV3) + if !ok { + return trace.Errorf("unexpected resource type %T", event.Resource) + } + if r.GetName() != req.GetName() || r.GetState().IsPending() { + continue Loop + } + if !r.GetState().IsApproved() { + return trace.Errorf("request %s has been set to %s", r.GetName(), r.GetState().String()) + } + return nil + case <-watcher.Done(): + utils.FatalError(watcher.Error()) + } + } +} + +// reissueWithRequests handles a certificate reissue, applying new requests by ID, +// and saving the updated profile. +func reissueWithRequests(cf *CLIConf, tc *client.TeleportClient, reqIDs ...string) error { + profile, _, err := client.Status("", cf.Proxy) + if err != nil { + return trace.Wrap(err) + } + params := client.ReissueParams{ + AccessRequests: reqIDs, + RouteToCluster: cf.SiteName, + } + // if the certificate already had active requests, add them to our inputs parameters. + if len(profile.ActiveRequests.AccessRequests) > 0 { + params.AccessRequests = append(params.AccessRequests, profile.ActiveRequests.AccessRequests...) + } + if params.RouteToCluster == "" { + params.RouteToCluster = profile.Cluster + } + if err := tc.ReissueUserCerts(cf.Context, params); err != nil { + return trace.Wrap(err) + } + if err := tc.SaveProfile("", ""); err != nil { + return trace.Wrap(err) + } + if err := kubeclient.UpdateKubeconfig(tc); err != nil { + return trace.Wrap(err) + } + return nil +}