From df768bda9325a3879a3360ede6776b6eae95c1c7 Mon Sep 17 00:00:00 2001 From: Alan Parra Date: Fri, 5 Jul 2024 10:37:36 -0300 Subject: [PATCH 01/25] Add the device assertion protos (#43804) * Add the device assertion protos * Update generated protos --- .../go/teleport/devicetrust/v1/assert.pb.go | 544 ++++++ .../v1/authenticate_challenge.pb.go | 382 +++++ .../devicetrust/v1/devicetrust_service.pb.go | 1513 +++++++---------- .../teleport/devicetrust/v1/assert.proto | 74 + .../v1/authenticate_challenge.proto | 50 + .../devicetrust/v1/devicetrust_service.proto | 30 +- .../ts/teleport/devicetrust/v1/assert_pb.ts | 363 ++++ .../v1/authenticate_challenge_pb.ts | 274 +++ .../devicetrust/v1/devicetrust_service_pb.ts | 248 +-- 9 files changed, 2315 insertions(+), 1163 deletions(-) create mode 100644 api/gen/proto/go/teleport/devicetrust/v1/assert.pb.go create mode 100644 api/gen/proto/go/teleport/devicetrust/v1/authenticate_challenge.pb.go create mode 100644 api/proto/teleport/devicetrust/v1/assert.proto create mode 100644 api/proto/teleport/devicetrust/v1/authenticate_challenge.proto create mode 100644 gen/proto/ts/teleport/devicetrust/v1/assert_pb.ts create mode 100644 gen/proto/ts/teleport/devicetrust/v1/authenticate_challenge_pb.ts diff --git a/api/gen/proto/go/teleport/devicetrust/v1/assert.pb.go b/api/gen/proto/go/teleport/devicetrust/v1/assert.pb.go new file mode 100644 index 0000000000000..dbb3bd609b147 --- /dev/null +++ b/api/gen/proto/go/teleport/devicetrust/v1/assert.pb.go @@ -0,0 +1,544 @@ +// Copyright 2024 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. + +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.34.0 +// protoc (unknown) +// source: teleport/devicetrust/v1/assert.proto + +package devicetrustv1 + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// Request to assert an enrolled device. Assertion authenticates the device, +// regardless of the user driving the assertion. +// +// Assertion messages are meant to be included by other requests and responses, +// either streams or multi-stage RPCs. The ceremony is resolved by a co-located +// DeviceTrustService. +// +// See the lib/devicetrust/assert (client) and +// e/lib/devicetrust/devicetrustv1/assert (server) packages. +// +// Assertion ceremony flow: +// -> AssertDeviceInit (client) +// <- AssertDeviceChallenge (server) +// -> AssertDeviceChallengeResponse (client) +// <- DeviceAsserted (server) +// +// A successful ceremony signifies that the device is registered, enrolled and +// passed the authentication challenge. +type AssertDeviceRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Types that are assignable to Payload: + // + // *AssertDeviceRequest_Init + // *AssertDeviceRequest_ChallengeResponse + // *AssertDeviceRequest_TpmChallengeResponse + Payload isAssertDeviceRequest_Payload `protobuf_oneof:"payload"` +} + +func (x *AssertDeviceRequest) Reset() { + *x = AssertDeviceRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_teleport_devicetrust_v1_assert_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *AssertDeviceRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AssertDeviceRequest) ProtoMessage() {} + +func (x *AssertDeviceRequest) ProtoReflect() protoreflect.Message { + mi := &file_teleport_devicetrust_v1_assert_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AssertDeviceRequest.ProtoReflect.Descriptor instead. +func (*AssertDeviceRequest) Descriptor() ([]byte, []int) { + return file_teleport_devicetrust_v1_assert_proto_rawDescGZIP(), []int{0} +} + +func (m *AssertDeviceRequest) GetPayload() isAssertDeviceRequest_Payload { + if m != nil { + return m.Payload + } + return nil +} + +func (x *AssertDeviceRequest) GetInit() *AssertDeviceInit { + if x, ok := x.GetPayload().(*AssertDeviceRequest_Init); ok { + return x.Init + } + return nil +} + +func (x *AssertDeviceRequest) GetChallengeResponse() *AuthenticateDeviceChallengeResponse { + if x, ok := x.GetPayload().(*AssertDeviceRequest_ChallengeResponse); ok { + return x.ChallengeResponse + } + return nil +} + +func (x *AssertDeviceRequest) GetTpmChallengeResponse() *TPMAuthenticateDeviceChallengeResponse { + if x, ok := x.GetPayload().(*AssertDeviceRequest_TpmChallengeResponse); ok { + return x.TpmChallengeResponse + } + return nil +} + +type isAssertDeviceRequest_Payload interface { + isAssertDeviceRequest_Payload() +} + +type AssertDeviceRequest_Init struct { + Init *AssertDeviceInit `protobuf:"bytes,1,opt,name=init,proto3,oneof"` +} + +type AssertDeviceRequest_ChallengeResponse struct { + ChallengeResponse *AuthenticateDeviceChallengeResponse `protobuf:"bytes,2,opt,name=challenge_response,json=challengeResponse,proto3,oneof"` +} + +type AssertDeviceRequest_TpmChallengeResponse struct { + TpmChallengeResponse *TPMAuthenticateDeviceChallengeResponse `protobuf:"bytes,3,opt,name=tpm_challenge_response,json=tpmChallengeResponse,proto3,oneof"` +} + +func (*AssertDeviceRequest_Init) isAssertDeviceRequest_Payload() {} + +func (*AssertDeviceRequest_ChallengeResponse) isAssertDeviceRequest_Payload() {} + +func (*AssertDeviceRequest_TpmChallengeResponse) isAssertDeviceRequest_Payload() {} + +// Response of the device assertion ceremony. +// See [AssertDeviceRequest]. +type AssertDeviceResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Types that are assignable to Payload: + // + // *AssertDeviceResponse_Challenge + // *AssertDeviceResponse_TpmChallenge + // *AssertDeviceResponse_DeviceAsserted + Payload isAssertDeviceResponse_Payload `protobuf_oneof:"payload"` +} + +func (x *AssertDeviceResponse) Reset() { + *x = AssertDeviceResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_teleport_devicetrust_v1_assert_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *AssertDeviceResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AssertDeviceResponse) ProtoMessage() {} + +func (x *AssertDeviceResponse) ProtoReflect() protoreflect.Message { + mi := &file_teleport_devicetrust_v1_assert_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AssertDeviceResponse.ProtoReflect.Descriptor instead. +func (*AssertDeviceResponse) Descriptor() ([]byte, []int) { + return file_teleport_devicetrust_v1_assert_proto_rawDescGZIP(), []int{1} +} + +func (m *AssertDeviceResponse) GetPayload() isAssertDeviceResponse_Payload { + if m != nil { + return m.Payload + } + return nil +} + +func (x *AssertDeviceResponse) GetChallenge() *AuthenticateDeviceChallenge { + if x, ok := x.GetPayload().(*AssertDeviceResponse_Challenge); ok { + return x.Challenge + } + return nil +} + +func (x *AssertDeviceResponse) GetTpmChallenge() *TPMAuthenticateDeviceChallenge { + if x, ok := x.GetPayload().(*AssertDeviceResponse_TpmChallenge); ok { + return x.TpmChallenge + } + return nil +} + +func (x *AssertDeviceResponse) GetDeviceAsserted() *DeviceAsserted { + if x, ok := x.GetPayload().(*AssertDeviceResponse_DeviceAsserted); ok { + return x.DeviceAsserted + } + return nil +} + +type isAssertDeviceResponse_Payload interface { + isAssertDeviceResponse_Payload() +} + +type AssertDeviceResponse_Challenge struct { + Challenge *AuthenticateDeviceChallenge `protobuf:"bytes,1,opt,name=challenge,proto3,oneof"` +} + +type AssertDeviceResponse_TpmChallenge struct { + TpmChallenge *TPMAuthenticateDeviceChallenge `protobuf:"bytes,2,opt,name=tpm_challenge,json=tpmChallenge,proto3,oneof"` +} + +type AssertDeviceResponse_DeviceAsserted struct { + DeviceAsserted *DeviceAsserted `protobuf:"bytes,3,opt,name=device_asserted,json=deviceAsserted,proto3,oneof"` +} + +func (*AssertDeviceResponse_Challenge) isAssertDeviceResponse_Payload() {} + +func (*AssertDeviceResponse_TpmChallenge) isAssertDeviceResponse_Payload() {} + +func (*AssertDeviceResponse_DeviceAsserted) isAssertDeviceResponse_Payload() {} + +// AssertDeviceInit initiates the device assertion ceremony. +// See [AssertDeviceRequest]. +type AssertDeviceInit struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // ID of the enrolled device credential. + CredentialId string `protobuf:"bytes,1,opt,name=credential_id,json=credentialId,proto3" json:"credential_id,omitempty"` + // Device collected data. + // Matched against the device registration information and any previously + // collected data. + DeviceData *DeviceCollectedData `protobuf:"bytes,2,opt,name=device_data,json=deviceData,proto3" json:"device_data,omitempty"` +} + +func (x *AssertDeviceInit) Reset() { + *x = AssertDeviceInit{} + if protoimpl.UnsafeEnabled { + mi := &file_teleport_devicetrust_v1_assert_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *AssertDeviceInit) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AssertDeviceInit) ProtoMessage() {} + +func (x *AssertDeviceInit) ProtoReflect() protoreflect.Message { + mi := &file_teleport_devicetrust_v1_assert_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AssertDeviceInit.ProtoReflect.Descriptor instead. +func (*AssertDeviceInit) Descriptor() ([]byte, []int) { + return file_teleport_devicetrust_v1_assert_proto_rawDescGZIP(), []int{2} +} + +func (x *AssertDeviceInit) GetCredentialId() string { + if x != nil { + return x.CredentialId + } + return "" +} + +func (x *AssertDeviceInit) GetDeviceData() *DeviceCollectedData { + if x != nil { + return x.DeviceData + } + return nil +} + +// DeviceAsserted marks a successful device assertion ceremony. +// See [AssertDeviceRequest]. +type DeviceAsserted struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *DeviceAsserted) Reset() { + *x = DeviceAsserted{} + if protoimpl.UnsafeEnabled { + mi := &file_teleport_devicetrust_v1_assert_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DeviceAsserted) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DeviceAsserted) ProtoMessage() {} + +func (x *DeviceAsserted) ProtoReflect() protoreflect.Message { + mi := &file_teleport_devicetrust_v1_assert_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DeviceAsserted.ProtoReflect.Descriptor instead. +func (*DeviceAsserted) Descriptor() ([]byte, []int) { + return file_teleport_devicetrust_v1_assert_proto_rawDescGZIP(), []int{3} +} + +var File_teleport_devicetrust_v1_assert_proto protoreflect.FileDescriptor + +var file_teleport_devicetrust_v1_assert_proto_rawDesc = []byte{ + 0x0a, 0x24, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x64, 0x65, 0x76, 0x69, 0x63, + 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2f, 0x76, 0x31, 0x2f, 0x61, 0x73, 0x73, 0x65, 0x72, 0x74, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x17, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, + 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x1a, + 0x34, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, + 0x74, 0x72, 0x75, 0x73, 0x74, 0x2f, 0x76, 0x31, 0x2f, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, + 0x69, 0x63, 0x61, 0x74, 0x65, 0x5f, 0x63, 0x68, 0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x67, 0x65, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x33, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, + 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2f, 0x76, 0x31, 0x2f, 0x64, + 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x65, 0x64, 0x5f, + 0x64, 0x61, 0x74, 0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xc9, 0x02, 0x0a, 0x13, 0x41, + 0x73, 0x73, 0x65, 0x72, 0x74, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x12, 0x3f, 0x0a, 0x04, 0x69, 0x6e, 0x69, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x29, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, + 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x73, 0x73, 0x65, 0x72, + 0x74, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x49, 0x6e, 0x69, 0x74, 0x48, 0x00, 0x52, 0x04, 0x69, + 0x6e, 0x69, 0x74, 0x12, 0x6d, 0x0a, 0x12, 0x63, 0x68, 0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x67, 0x65, + 0x5f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x3c, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, + 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, + 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x43, 0x68, 0x61, 0x6c, + 0x6c, 0x65, 0x6e, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x48, 0x00, 0x52, + 0x11, 0x63, 0x68, 0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x77, 0x0a, 0x16, 0x74, 0x70, 0x6d, 0x5f, 0x63, 0x68, 0x61, 0x6c, 0x6c, 0x65, + 0x6e, 0x67, 0x65, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x3f, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, + 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x50, 0x4d, + 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x44, 0x65, 0x76, 0x69, + 0x63, 0x65, 0x43, 0x68, 0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x48, 0x00, 0x52, 0x14, 0x74, 0x70, 0x6d, 0x43, 0x68, 0x61, 0x6c, 0x6c, 0x65, + 0x6e, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x09, 0x0a, 0x07, 0x70, + 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x22, 0xab, 0x02, 0x0a, 0x14, 0x41, 0x73, 0x73, 0x65, 0x72, + 0x74, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x54, 0x0a, 0x09, 0x63, 0x68, 0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x34, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, + 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x75, 0x74, + 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x43, + 0x68, 0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x67, 0x65, 0x48, 0x00, 0x52, 0x09, 0x63, 0x68, 0x61, 0x6c, + 0x6c, 0x65, 0x6e, 0x67, 0x65, 0x12, 0x5e, 0x0a, 0x0d, 0x74, 0x70, 0x6d, 0x5f, 0x63, 0x68, 0x61, + 0x6c, 0x6c, 0x65, 0x6e, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x37, 0x2e, 0x74, + 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, + 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x50, 0x4d, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, + 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x43, 0x68, 0x61, 0x6c, + 0x6c, 0x65, 0x6e, 0x67, 0x65, 0x48, 0x00, 0x52, 0x0c, 0x74, 0x70, 0x6d, 0x43, 0x68, 0x61, 0x6c, + 0x6c, 0x65, 0x6e, 0x67, 0x65, 0x12, 0x52, 0x0a, 0x0f, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, + 0x61, 0x73, 0x73, 0x65, 0x72, 0x74, 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, + 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, + 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x41, + 0x73, 0x73, 0x65, 0x72, 0x74, 0x65, 0x64, 0x48, 0x00, 0x52, 0x0e, 0x64, 0x65, 0x76, 0x69, 0x63, + 0x65, 0x41, 0x73, 0x73, 0x65, 0x72, 0x74, 0x65, 0x64, 0x42, 0x09, 0x0a, 0x07, 0x70, 0x61, 0x79, + 0x6c, 0x6f, 0x61, 0x64, 0x22, 0x86, 0x01, 0x0a, 0x10, 0x41, 0x73, 0x73, 0x65, 0x72, 0x74, 0x44, + 0x65, 0x76, 0x69, 0x63, 0x65, 0x49, 0x6e, 0x69, 0x74, 0x12, 0x23, 0x0a, 0x0d, 0x63, 0x72, 0x65, + 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0c, 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x49, 0x64, 0x12, 0x4d, + 0x0a, 0x0b, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, + 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, + 0x76, 0x69, 0x63, 0x65, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x65, 0x64, 0x44, 0x61, 0x74, + 0x61, 0x52, 0x0a, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x44, 0x61, 0x74, 0x61, 0x22, 0x10, 0x0a, + 0x0e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x41, 0x73, 0x73, 0x65, 0x72, 0x74, 0x65, 0x64, 0x42, + 0x5a, 0x5a, 0x58, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x72, + 0x61, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x2f, 0x74, 0x65, 0x6c, 0x65, + 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x2f, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x64, + 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2f, 0x76, 0x31, 0x3b, 0x64, 0x65, + 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x33, +} + +var ( + file_teleport_devicetrust_v1_assert_proto_rawDescOnce sync.Once + file_teleport_devicetrust_v1_assert_proto_rawDescData = file_teleport_devicetrust_v1_assert_proto_rawDesc +) + +func file_teleport_devicetrust_v1_assert_proto_rawDescGZIP() []byte { + file_teleport_devicetrust_v1_assert_proto_rawDescOnce.Do(func() { + file_teleport_devicetrust_v1_assert_proto_rawDescData = protoimpl.X.CompressGZIP(file_teleport_devicetrust_v1_assert_proto_rawDescData) + }) + return file_teleport_devicetrust_v1_assert_proto_rawDescData +} + +var file_teleport_devicetrust_v1_assert_proto_msgTypes = make([]protoimpl.MessageInfo, 4) +var file_teleport_devicetrust_v1_assert_proto_goTypes = []interface{}{ + (*AssertDeviceRequest)(nil), // 0: teleport.devicetrust.v1.AssertDeviceRequest + (*AssertDeviceResponse)(nil), // 1: teleport.devicetrust.v1.AssertDeviceResponse + (*AssertDeviceInit)(nil), // 2: teleport.devicetrust.v1.AssertDeviceInit + (*DeviceAsserted)(nil), // 3: teleport.devicetrust.v1.DeviceAsserted + (*AuthenticateDeviceChallengeResponse)(nil), // 4: teleport.devicetrust.v1.AuthenticateDeviceChallengeResponse + (*TPMAuthenticateDeviceChallengeResponse)(nil), // 5: teleport.devicetrust.v1.TPMAuthenticateDeviceChallengeResponse + (*AuthenticateDeviceChallenge)(nil), // 6: teleport.devicetrust.v1.AuthenticateDeviceChallenge + (*TPMAuthenticateDeviceChallenge)(nil), // 7: teleport.devicetrust.v1.TPMAuthenticateDeviceChallenge + (*DeviceCollectedData)(nil), // 8: teleport.devicetrust.v1.DeviceCollectedData +} +var file_teleport_devicetrust_v1_assert_proto_depIdxs = []int32{ + 2, // 0: teleport.devicetrust.v1.AssertDeviceRequest.init:type_name -> teleport.devicetrust.v1.AssertDeviceInit + 4, // 1: teleport.devicetrust.v1.AssertDeviceRequest.challenge_response:type_name -> teleport.devicetrust.v1.AuthenticateDeviceChallengeResponse + 5, // 2: teleport.devicetrust.v1.AssertDeviceRequest.tpm_challenge_response:type_name -> teleport.devicetrust.v1.TPMAuthenticateDeviceChallengeResponse + 6, // 3: teleport.devicetrust.v1.AssertDeviceResponse.challenge:type_name -> teleport.devicetrust.v1.AuthenticateDeviceChallenge + 7, // 4: teleport.devicetrust.v1.AssertDeviceResponse.tpm_challenge:type_name -> teleport.devicetrust.v1.TPMAuthenticateDeviceChallenge + 3, // 5: teleport.devicetrust.v1.AssertDeviceResponse.device_asserted:type_name -> teleport.devicetrust.v1.DeviceAsserted + 8, // 6: teleport.devicetrust.v1.AssertDeviceInit.device_data:type_name -> teleport.devicetrust.v1.DeviceCollectedData + 7, // [7:7] is the sub-list for method output_type + 7, // [7:7] is the sub-list for method input_type + 7, // [7:7] is the sub-list for extension type_name + 7, // [7:7] is the sub-list for extension extendee + 0, // [0:7] is the sub-list for field type_name +} + +func init() { file_teleport_devicetrust_v1_assert_proto_init() } +func file_teleport_devicetrust_v1_assert_proto_init() { + if File_teleport_devicetrust_v1_assert_proto != nil { + return + } + file_teleport_devicetrust_v1_authenticate_challenge_proto_init() + file_teleport_devicetrust_v1_device_collected_data_proto_init() + if !protoimpl.UnsafeEnabled { + file_teleport_devicetrust_v1_assert_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*AssertDeviceRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_teleport_devicetrust_v1_assert_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*AssertDeviceResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_teleport_devicetrust_v1_assert_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*AssertDeviceInit); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_teleport_devicetrust_v1_assert_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DeviceAsserted); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + file_teleport_devicetrust_v1_assert_proto_msgTypes[0].OneofWrappers = []interface{}{ + (*AssertDeviceRequest_Init)(nil), + (*AssertDeviceRequest_ChallengeResponse)(nil), + (*AssertDeviceRequest_TpmChallengeResponse)(nil), + } + file_teleport_devicetrust_v1_assert_proto_msgTypes[1].OneofWrappers = []interface{}{ + (*AssertDeviceResponse_Challenge)(nil), + (*AssertDeviceResponse_TpmChallenge)(nil), + (*AssertDeviceResponse_DeviceAsserted)(nil), + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_teleport_devicetrust_v1_assert_proto_rawDesc, + NumEnums: 0, + NumMessages: 4, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_teleport_devicetrust_v1_assert_proto_goTypes, + DependencyIndexes: file_teleport_devicetrust_v1_assert_proto_depIdxs, + MessageInfos: file_teleport_devicetrust_v1_assert_proto_msgTypes, + }.Build() + File_teleport_devicetrust_v1_assert_proto = out.File + file_teleport_devicetrust_v1_assert_proto_rawDesc = nil + file_teleport_devicetrust_v1_assert_proto_goTypes = nil + file_teleport_devicetrust_v1_assert_proto_depIdxs = nil +} diff --git a/api/gen/proto/go/teleport/devicetrust/v1/authenticate_challenge.pb.go b/api/gen/proto/go/teleport/devicetrust/v1/authenticate_challenge.pb.go new file mode 100644 index 0000000000000..087fc953bf867 --- /dev/null +++ b/api/gen/proto/go/teleport/devicetrust/v1/authenticate_challenge.pb.go @@ -0,0 +1,382 @@ +// Copyright 2022 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. + +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.34.0 +// protoc (unknown) +// source: teleport/devicetrust/v1/authenticate_challenge.proto + +package devicetrustv1 + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// AuthenticateDeviceChallenge carries the authentication challenge. +type AuthenticateDeviceChallenge struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Randomly-generated, opaque challenge to be signed using the device key. + Challenge []byte `protobuf:"bytes,1,opt,name=challenge,proto3" json:"challenge,omitempty"` +} + +func (x *AuthenticateDeviceChallenge) Reset() { + *x = AuthenticateDeviceChallenge{} + if protoimpl.UnsafeEnabled { + mi := &file_teleport_devicetrust_v1_authenticate_challenge_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *AuthenticateDeviceChallenge) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AuthenticateDeviceChallenge) ProtoMessage() {} + +func (x *AuthenticateDeviceChallenge) ProtoReflect() protoreflect.Message { + mi := &file_teleport_devicetrust_v1_authenticate_challenge_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AuthenticateDeviceChallenge.ProtoReflect.Descriptor instead. +func (*AuthenticateDeviceChallenge) Descriptor() ([]byte, []int) { + return file_teleport_devicetrust_v1_authenticate_challenge_proto_rawDescGZIP(), []int{0} +} + +func (x *AuthenticateDeviceChallenge) GetChallenge() []byte { + if x != nil { + return x.Challenge + } + return nil +} + +// AuthenticateDeviceChallengeResponse carries the authentication challenge +// response. +type AuthenticateDeviceChallengeResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Signature over the challenge, using the device key. + Signature []byte `protobuf:"bytes,1,opt,name=signature,proto3" json:"signature,omitempty"` +} + +func (x *AuthenticateDeviceChallengeResponse) Reset() { + *x = AuthenticateDeviceChallengeResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_teleport_devicetrust_v1_authenticate_challenge_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *AuthenticateDeviceChallengeResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AuthenticateDeviceChallengeResponse) ProtoMessage() {} + +func (x *AuthenticateDeviceChallengeResponse) ProtoReflect() protoreflect.Message { + mi := &file_teleport_devicetrust_v1_authenticate_challenge_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AuthenticateDeviceChallengeResponse.ProtoReflect.Descriptor instead. +func (*AuthenticateDeviceChallengeResponse) Descriptor() ([]byte, []int) { + return file_teleport_devicetrust_v1_authenticate_challenge_proto_rawDescGZIP(), []int{1} +} + +func (x *AuthenticateDeviceChallengeResponse) GetSignature() []byte { + if x != nil { + return x.Signature + } + return nil +} + +// TPMAuthenticateDeviceChallenge carries the authentication challenge +// specific to TPMs. +type TPMAuthenticateDeviceChallenge struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Randomly-generated nonce to be used during platform attestation by the + // TPM. + AttestationNonce []byte `protobuf:"bytes,1,opt,name=attestation_nonce,json=attestationNonce,proto3" json:"attestation_nonce,omitempty"` +} + +func (x *TPMAuthenticateDeviceChallenge) Reset() { + *x = TPMAuthenticateDeviceChallenge{} + if protoimpl.UnsafeEnabled { + mi := &file_teleport_devicetrust_v1_authenticate_challenge_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *TPMAuthenticateDeviceChallenge) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*TPMAuthenticateDeviceChallenge) ProtoMessage() {} + +func (x *TPMAuthenticateDeviceChallenge) ProtoReflect() protoreflect.Message { + mi := &file_teleport_devicetrust_v1_authenticate_challenge_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use TPMAuthenticateDeviceChallenge.ProtoReflect.Descriptor instead. +func (*TPMAuthenticateDeviceChallenge) Descriptor() ([]byte, []int) { + return file_teleport_devicetrust_v1_authenticate_challenge_proto_rawDescGZIP(), []int{2} +} + +func (x *TPMAuthenticateDeviceChallenge) GetAttestationNonce() []byte { + if x != nil { + return x.AttestationNonce + } + return nil +} + +// TPMAuthenticateDeviceChallengeResponse carries the authentication challenge +// response specific to TPMs. +type TPMAuthenticateDeviceChallengeResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The result of the client's platform attestation with the nonce provided + // in `TPMAuthenticateDeviceChallenge`. + PlatformParameters *TPMPlatformParameters `protobuf:"bytes,1,opt,name=platform_parameters,json=platformParameters,proto3" json:"platform_parameters,omitempty"` +} + +func (x *TPMAuthenticateDeviceChallengeResponse) Reset() { + *x = TPMAuthenticateDeviceChallengeResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_teleport_devicetrust_v1_authenticate_challenge_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *TPMAuthenticateDeviceChallengeResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*TPMAuthenticateDeviceChallengeResponse) ProtoMessage() {} + +func (x *TPMAuthenticateDeviceChallengeResponse) ProtoReflect() protoreflect.Message { + mi := &file_teleport_devicetrust_v1_authenticate_challenge_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use TPMAuthenticateDeviceChallengeResponse.ProtoReflect.Descriptor instead. +func (*TPMAuthenticateDeviceChallengeResponse) Descriptor() ([]byte, []int) { + return file_teleport_devicetrust_v1_authenticate_challenge_proto_rawDescGZIP(), []int{3} +} + +func (x *TPMAuthenticateDeviceChallengeResponse) GetPlatformParameters() *TPMPlatformParameters { + if x != nil { + return x.PlatformParameters + } + return nil +} + +var File_teleport_devicetrust_v1_authenticate_challenge_proto protoreflect.FileDescriptor + +var file_teleport_devicetrust_v1_authenticate_challenge_proto_rawDesc = []byte{ + 0x0a, 0x34, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x64, 0x65, 0x76, 0x69, 0x63, + 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2f, 0x76, 0x31, 0x2f, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, + 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x5f, 0x63, 0x68, 0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x67, 0x65, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x17, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, + 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x1a, + 0x21, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, + 0x74, 0x72, 0x75, 0x73, 0x74, 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x70, 0x6d, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x22, 0x3b, 0x0a, 0x1b, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, + 0x74, 0x65, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x43, 0x68, 0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x67, + 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x68, 0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x67, 0x65, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x63, 0x68, 0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x67, 0x65, 0x22, + 0x43, 0x0a, 0x23, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x44, + 0x65, 0x76, 0x69, 0x63, 0x65, 0x43, 0x68, 0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x67, 0x65, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, + 0x75, 0x72, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, + 0x74, 0x75, 0x72, 0x65, 0x22, 0x4d, 0x0a, 0x1e, 0x54, 0x50, 0x4d, 0x41, 0x75, 0x74, 0x68, 0x65, + 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x43, 0x68, 0x61, + 0x6c, 0x6c, 0x65, 0x6e, 0x67, 0x65, 0x12, 0x2b, 0x0a, 0x11, 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0c, 0x52, 0x10, 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4e, 0x6f, + 0x6e, 0x63, 0x65, 0x22, 0x89, 0x01, 0x0a, 0x26, 0x54, 0x50, 0x4d, 0x41, 0x75, 0x74, 0x68, 0x65, + 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x43, 0x68, 0x61, + 0x6c, 0x6c, 0x65, 0x6e, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5f, + 0x0a, 0x13, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, + 0x65, 0x74, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x74, 0x65, + 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, + 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x50, 0x4d, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, + 0x6d, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x52, 0x12, 0x70, 0x6c, 0x61, + 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x42, + 0x5a, 0x5a, 0x58, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x72, + 0x61, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x2f, 0x74, 0x65, 0x6c, 0x65, + 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x2f, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x64, + 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2f, 0x76, 0x31, 0x3b, 0x64, 0x65, + 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x33, +} + +var ( + file_teleport_devicetrust_v1_authenticate_challenge_proto_rawDescOnce sync.Once + file_teleport_devicetrust_v1_authenticate_challenge_proto_rawDescData = file_teleport_devicetrust_v1_authenticate_challenge_proto_rawDesc +) + +func file_teleport_devicetrust_v1_authenticate_challenge_proto_rawDescGZIP() []byte { + file_teleport_devicetrust_v1_authenticate_challenge_proto_rawDescOnce.Do(func() { + file_teleport_devicetrust_v1_authenticate_challenge_proto_rawDescData = protoimpl.X.CompressGZIP(file_teleport_devicetrust_v1_authenticate_challenge_proto_rawDescData) + }) + return file_teleport_devicetrust_v1_authenticate_challenge_proto_rawDescData +} + +var file_teleport_devicetrust_v1_authenticate_challenge_proto_msgTypes = make([]protoimpl.MessageInfo, 4) +var file_teleport_devicetrust_v1_authenticate_challenge_proto_goTypes = []interface{}{ + (*AuthenticateDeviceChallenge)(nil), // 0: teleport.devicetrust.v1.AuthenticateDeviceChallenge + (*AuthenticateDeviceChallengeResponse)(nil), // 1: teleport.devicetrust.v1.AuthenticateDeviceChallengeResponse + (*TPMAuthenticateDeviceChallenge)(nil), // 2: teleport.devicetrust.v1.TPMAuthenticateDeviceChallenge + (*TPMAuthenticateDeviceChallengeResponse)(nil), // 3: teleport.devicetrust.v1.TPMAuthenticateDeviceChallengeResponse + (*TPMPlatformParameters)(nil), // 4: teleport.devicetrust.v1.TPMPlatformParameters +} +var file_teleport_devicetrust_v1_authenticate_challenge_proto_depIdxs = []int32{ + 4, // 0: teleport.devicetrust.v1.TPMAuthenticateDeviceChallengeResponse.platform_parameters:type_name -> teleport.devicetrust.v1.TPMPlatformParameters + 1, // [1:1] is the sub-list for method output_type + 1, // [1:1] is the sub-list for method input_type + 1, // [1:1] is the sub-list for extension type_name + 1, // [1:1] is the sub-list for extension extendee + 0, // [0:1] is the sub-list for field type_name +} + +func init() { file_teleport_devicetrust_v1_authenticate_challenge_proto_init() } +func file_teleport_devicetrust_v1_authenticate_challenge_proto_init() { + if File_teleport_devicetrust_v1_authenticate_challenge_proto != nil { + return + } + file_teleport_devicetrust_v1_tpm_proto_init() + if !protoimpl.UnsafeEnabled { + file_teleport_devicetrust_v1_authenticate_challenge_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*AuthenticateDeviceChallenge); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_teleport_devicetrust_v1_authenticate_challenge_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*AuthenticateDeviceChallengeResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_teleport_devicetrust_v1_authenticate_challenge_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*TPMAuthenticateDeviceChallenge); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_teleport_devicetrust_v1_authenticate_challenge_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*TPMAuthenticateDeviceChallengeResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_teleport_devicetrust_v1_authenticate_challenge_proto_rawDesc, + NumEnums: 0, + NumMessages: 4, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_teleport_devicetrust_v1_authenticate_challenge_proto_goTypes, + DependencyIndexes: file_teleport_devicetrust_v1_authenticate_challenge_proto_depIdxs, + MessageInfos: file_teleport_devicetrust_v1_authenticate_challenge_proto_msgTypes, + }.Build() + File_teleport_devicetrust_v1_authenticate_challenge_proto = out.File + file_teleport_devicetrust_v1_authenticate_challenge_proto_rawDesc = nil + file_teleport_devicetrust_v1_authenticate_challenge_proto_goTypes = nil + file_teleport_devicetrust_v1_authenticate_challenge_proto_depIdxs = nil +} diff --git a/api/gen/proto/go/teleport/devicetrust/v1/devicetrust_service.pb.go b/api/gen/proto/go/teleport/devicetrust/v1/devicetrust_service.pb.go index 30747ce844885..d9fd7b3a0217c 100644 --- a/api/gen/proto/go/teleport/devicetrust/v1/devicetrust_service.pb.go +++ b/api/gen/proto/go/teleport/devicetrust/v1/devicetrust_service.pb.go @@ -2035,207 +2035,6 @@ func (x *AuthenticateDeviceInit) GetDeviceWebToken() *DeviceWebToken { return nil } -// TPMAuthenticateDeviceChallenge carries the authentication challenge -// specific to TPMs. -type TPMAuthenticateDeviceChallenge struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // Randomly-generated nonce to be used during platform attestation by the - // TPM. - AttestationNonce []byte `protobuf:"bytes,1,opt,name=attestation_nonce,json=attestationNonce,proto3" json:"attestation_nonce,omitempty"` -} - -func (x *TPMAuthenticateDeviceChallenge) Reset() { - *x = TPMAuthenticateDeviceChallenge{} - if protoimpl.UnsafeEnabled { - mi := &file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[28] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *TPMAuthenticateDeviceChallenge) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*TPMAuthenticateDeviceChallenge) ProtoMessage() {} - -func (x *TPMAuthenticateDeviceChallenge) ProtoReflect() protoreflect.Message { - mi := &file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[28] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use TPMAuthenticateDeviceChallenge.ProtoReflect.Descriptor instead. -func (*TPMAuthenticateDeviceChallenge) Descriptor() ([]byte, []int) { - return file_teleport_devicetrust_v1_devicetrust_service_proto_rawDescGZIP(), []int{28} -} - -func (x *TPMAuthenticateDeviceChallenge) GetAttestationNonce() []byte { - if x != nil { - return x.AttestationNonce - } - return nil -} - -// TPMAuthenticateDeviceChallengeResponse carries the authentication challenge -// response specific to TPMs. -type TPMAuthenticateDeviceChallengeResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // The result of the client's platform attestation with the nonce provided - // in `TPMAuthenticateDeviceChallenge`. - PlatformParameters *TPMPlatformParameters `protobuf:"bytes,1,opt,name=platform_parameters,json=platformParameters,proto3" json:"platform_parameters,omitempty"` -} - -func (x *TPMAuthenticateDeviceChallengeResponse) Reset() { - *x = TPMAuthenticateDeviceChallengeResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[29] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *TPMAuthenticateDeviceChallengeResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*TPMAuthenticateDeviceChallengeResponse) ProtoMessage() {} - -func (x *TPMAuthenticateDeviceChallengeResponse) ProtoReflect() protoreflect.Message { - mi := &file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[29] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use TPMAuthenticateDeviceChallengeResponse.ProtoReflect.Descriptor instead. -func (*TPMAuthenticateDeviceChallengeResponse) Descriptor() ([]byte, []int) { - return file_teleport_devicetrust_v1_devicetrust_service_proto_rawDescGZIP(), []int{29} -} - -func (x *TPMAuthenticateDeviceChallengeResponse) GetPlatformParameters() *TPMPlatformParameters { - if x != nil { - return x.PlatformParameters - } - return nil -} - -// AuthenticateDeviceChallenge carries the authentication challenge. -type AuthenticateDeviceChallenge struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // Randomly-generated, opaque challenge to be signed using the device key. - Challenge []byte `protobuf:"bytes,1,opt,name=challenge,proto3" json:"challenge,omitempty"` -} - -func (x *AuthenticateDeviceChallenge) Reset() { - *x = AuthenticateDeviceChallenge{} - if protoimpl.UnsafeEnabled { - mi := &file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[30] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *AuthenticateDeviceChallenge) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*AuthenticateDeviceChallenge) ProtoMessage() {} - -func (x *AuthenticateDeviceChallenge) ProtoReflect() protoreflect.Message { - mi := &file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[30] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use AuthenticateDeviceChallenge.ProtoReflect.Descriptor instead. -func (*AuthenticateDeviceChallenge) Descriptor() ([]byte, []int) { - return file_teleport_devicetrust_v1_devicetrust_service_proto_rawDescGZIP(), []int{30} -} - -func (x *AuthenticateDeviceChallenge) GetChallenge() []byte { - if x != nil { - return x.Challenge - } - return nil -} - -// AuthenticateDeviceChallengeResponse carries the authentication challenge -// response. -type AuthenticateDeviceChallengeResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // Signature over the challenge, using the device key. - Signature []byte `protobuf:"bytes,1,opt,name=signature,proto3" json:"signature,omitempty"` -} - -func (x *AuthenticateDeviceChallengeResponse) Reset() { - *x = AuthenticateDeviceChallengeResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[31] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *AuthenticateDeviceChallengeResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*AuthenticateDeviceChallengeResponse) ProtoMessage() {} - -func (x *AuthenticateDeviceChallengeResponse) ProtoReflect() protoreflect.Message { - mi := &file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[31] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use AuthenticateDeviceChallengeResponse.ProtoReflect.Descriptor instead. -func (*AuthenticateDeviceChallengeResponse) Descriptor() ([]byte, []int) { - return file_teleport_devicetrust_v1_devicetrust_service_proto_rawDescGZIP(), []int{31} -} - -func (x *AuthenticateDeviceChallengeResponse) GetSignature() []byte { - if x != nil { - return x.Signature - } - return nil -} - // Request for ConfirmDeviceWebAuthentication. type ConfirmDeviceWebAuthenticationRequest struct { state protoimpl.MessageState @@ -2255,7 +2054,7 @@ type ConfirmDeviceWebAuthenticationRequest struct { func (x *ConfirmDeviceWebAuthenticationRequest) Reset() { *x = ConfirmDeviceWebAuthenticationRequest{} if protoimpl.UnsafeEnabled { - mi := &file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[32] + mi := &file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[28] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2268,7 +2067,7 @@ func (x *ConfirmDeviceWebAuthenticationRequest) String() string { func (*ConfirmDeviceWebAuthenticationRequest) ProtoMessage() {} func (x *ConfirmDeviceWebAuthenticationRequest) ProtoReflect() protoreflect.Message { - mi := &file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[32] + mi := &file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[28] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2281,7 +2080,7 @@ func (x *ConfirmDeviceWebAuthenticationRequest) ProtoReflect() protoreflect.Mess // Deprecated: Use ConfirmDeviceWebAuthenticationRequest.ProtoReflect.Descriptor instead. func (*ConfirmDeviceWebAuthenticationRequest) Descriptor() ([]byte, []int) { - return file_teleport_devicetrust_v1_devicetrust_service_proto_rawDescGZIP(), []int{32} + return file_teleport_devicetrust_v1_devicetrust_service_proto_rawDescGZIP(), []int{28} } func (x *ConfirmDeviceWebAuthenticationRequest) GetConfirmationToken() *DeviceConfirmationToken { @@ -2308,7 +2107,7 @@ type ConfirmDeviceWebAuthenticationResponse struct { func (x *ConfirmDeviceWebAuthenticationResponse) Reset() { *x = ConfirmDeviceWebAuthenticationResponse{} if protoimpl.UnsafeEnabled { - mi := &file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[33] + mi := &file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[29] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2321,7 +2120,7 @@ func (x *ConfirmDeviceWebAuthenticationResponse) String() string { func (*ConfirmDeviceWebAuthenticationResponse) ProtoMessage() {} func (x *ConfirmDeviceWebAuthenticationResponse) ProtoReflect() protoreflect.Message { - mi := &file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[33] + mi := &file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[29] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2334,7 +2133,7 @@ func (x *ConfirmDeviceWebAuthenticationResponse) ProtoReflect() protoreflect.Mes // Deprecated: Use ConfirmDeviceWebAuthenticationResponse.ProtoReflect.Descriptor instead. func (*ConfirmDeviceWebAuthenticationResponse) Descriptor() ([]byte, []int) { - return file_teleport_devicetrust_v1_devicetrust_service_proto_rawDescGZIP(), []int{33} + return file_teleport_devicetrust_v1_devicetrust_service_proto_rawDescGZIP(), []int{29} } // Request for SyncInventory. @@ -2370,7 +2169,7 @@ type SyncInventoryRequest struct { func (x *SyncInventoryRequest) Reset() { *x = SyncInventoryRequest{} if protoimpl.UnsafeEnabled { - mi := &file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[34] + mi := &file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[30] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2383,7 +2182,7 @@ func (x *SyncInventoryRequest) String() string { func (*SyncInventoryRequest) ProtoMessage() {} func (x *SyncInventoryRequest) ProtoReflect() protoreflect.Message { - mi := &file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[34] + mi := &file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[30] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2396,7 +2195,7 @@ func (x *SyncInventoryRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use SyncInventoryRequest.ProtoReflect.Descriptor instead. func (*SyncInventoryRequest) Descriptor() ([]byte, []int) { - return file_teleport_devicetrust_v1_devicetrust_service_proto_rawDescGZIP(), []int{34} + return file_teleport_devicetrust_v1_devicetrust_service_proto_rawDescGZIP(), []int{30} } func (m *SyncInventoryRequest) GetPayload() isSyncInventoryRequest_Payload { @@ -2479,7 +2278,7 @@ type SyncInventoryResponse struct { func (x *SyncInventoryResponse) Reset() { *x = SyncInventoryResponse{} if protoimpl.UnsafeEnabled { - mi := &file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[35] + mi := &file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[31] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2492,7 +2291,7 @@ func (x *SyncInventoryResponse) String() string { func (*SyncInventoryResponse) ProtoMessage() {} func (x *SyncInventoryResponse) ProtoReflect() protoreflect.Message { - mi := &file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[35] + mi := &file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[31] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2505,7 +2304,7 @@ func (x *SyncInventoryResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use SyncInventoryResponse.ProtoReflect.Descriptor instead. func (*SyncInventoryResponse) Descriptor() ([]byte, []int) { - return file_teleport_devicetrust_v1_devicetrust_service_proto_rawDescGZIP(), []int{35} + return file_teleport_devicetrust_v1_devicetrust_service_proto_rawDescGZIP(), []int{31} } func (m *SyncInventoryResponse) GetPayload() isSyncInventoryResponse_Payload { @@ -2579,7 +2378,7 @@ type SyncInventoryStart struct { func (x *SyncInventoryStart) Reset() { *x = SyncInventoryStart{} if protoimpl.UnsafeEnabled { - mi := &file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[36] + mi := &file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[32] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2592,7 +2391,7 @@ func (x *SyncInventoryStart) String() string { func (*SyncInventoryStart) ProtoMessage() {} func (x *SyncInventoryStart) ProtoReflect() protoreflect.Message { - mi := &file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[36] + mi := &file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[32] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2605,7 +2404,7 @@ func (x *SyncInventoryStart) ProtoReflect() protoreflect.Message { // Deprecated: Use SyncInventoryStart.ProtoReflect.Descriptor instead. func (*SyncInventoryStart) Descriptor() ([]byte, []int) { - return file_teleport_devicetrust_v1_devicetrust_service_proto_rawDescGZIP(), []int{36} + return file_teleport_devicetrust_v1_devicetrust_service_proto_rawDescGZIP(), []int{32} } func (x *SyncInventoryStart) GetSource() *DeviceSource { @@ -2633,7 +2432,7 @@ type SyncInventoryEnd struct { func (x *SyncInventoryEnd) Reset() { *x = SyncInventoryEnd{} if protoimpl.UnsafeEnabled { - mi := &file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[37] + mi := &file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[33] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2646,7 +2445,7 @@ func (x *SyncInventoryEnd) String() string { func (*SyncInventoryEnd) ProtoMessage() {} func (x *SyncInventoryEnd) ProtoReflect() protoreflect.Message { - mi := &file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[37] + mi := &file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[33] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2659,7 +2458,7 @@ func (x *SyncInventoryEnd) ProtoReflect() protoreflect.Message { // Deprecated: Use SyncInventoryEnd.ProtoReflect.Descriptor instead. func (*SyncInventoryEnd) Descriptor() ([]byte, []int) { - return file_teleport_devicetrust_v1_devicetrust_service_proto_rawDescGZIP(), []int{37} + return file_teleport_devicetrust_v1_devicetrust_service_proto_rawDescGZIP(), []int{33} } // SyncInventoryDevices transports devices to add/update/remove. @@ -2676,7 +2475,7 @@ type SyncInventoryDevices struct { func (x *SyncInventoryDevices) Reset() { *x = SyncInventoryDevices{} if protoimpl.UnsafeEnabled { - mi := &file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[38] + mi := &file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[34] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2689,7 +2488,7 @@ func (x *SyncInventoryDevices) String() string { func (*SyncInventoryDevices) ProtoMessage() {} func (x *SyncInventoryDevices) ProtoReflect() protoreflect.Message { - mi := &file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[38] + mi := &file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[34] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2702,7 +2501,7 @@ func (x *SyncInventoryDevices) ProtoReflect() protoreflect.Message { // Deprecated: Use SyncInventoryDevices.ProtoReflect.Descriptor instead. func (*SyncInventoryDevices) Descriptor() ([]byte, []int) { - return file_teleport_devicetrust_v1_devicetrust_service_proto_rawDescGZIP(), []int{38} + return file_teleport_devicetrust_v1_devicetrust_service_proto_rawDescGZIP(), []int{34} } func (x *SyncInventoryDevices) GetDevices() []*Device { @@ -2723,7 +2522,7 @@ type SyncInventoryAck struct { func (x *SyncInventoryAck) Reset() { *x = SyncInventoryAck{} if protoimpl.UnsafeEnabled { - mi := &file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[39] + mi := &file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[35] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2736,7 +2535,7 @@ func (x *SyncInventoryAck) String() string { func (*SyncInventoryAck) ProtoMessage() {} func (x *SyncInventoryAck) ProtoReflect() protoreflect.Message { - mi := &file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[39] + mi := &file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[35] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2749,7 +2548,7 @@ func (x *SyncInventoryAck) ProtoReflect() protoreflect.Message { // Deprecated: Use SyncInventoryAck.ProtoReflect.Descriptor instead. func (*SyncInventoryAck) Descriptor() ([]byte, []int) { - return file_teleport_devicetrust_v1_devicetrust_service_proto_rawDescGZIP(), []int{39} + return file_teleport_devicetrust_v1_devicetrust_service_proto_rawDescGZIP(), []int{35} } // SyncInventoryResult is the response for SyncInventoryDevices or @@ -2767,7 +2566,7 @@ type SyncInventoryResult struct { func (x *SyncInventoryResult) Reset() { *x = SyncInventoryResult{} if protoimpl.UnsafeEnabled { - mi := &file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[40] + mi := &file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[36] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2780,7 +2579,7 @@ func (x *SyncInventoryResult) String() string { func (*SyncInventoryResult) ProtoMessage() {} func (x *SyncInventoryResult) ProtoReflect() protoreflect.Message { - mi := &file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[40] + mi := &file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[36] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2793,7 +2592,7 @@ func (x *SyncInventoryResult) ProtoReflect() protoreflect.Message { // Deprecated: Use SyncInventoryResult.ProtoReflect.Descriptor instead. func (*SyncInventoryResult) Descriptor() ([]byte, []int) { - return file_teleport_devicetrust_v1_devicetrust_service_proto_rawDescGZIP(), []int{40} + return file_teleport_devicetrust_v1_devicetrust_service_proto_rawDescGZIP(), []int{36} } func (x *SyncInventoryResult) GetDevices() []*DeviceOrStatus { @@ -2825,7 +2624,7 @@ type SyncInventoryMissingDevices struct { func (x *SyncInventoryMissingDevices) Reset() { *x = SyncInventoryMissingDevices{} if protoimpl.UnsafeEnabled { - mi := &file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[41] + mi := &file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[37] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2838,7 +2637,7 @@ func (x *SyncInventoryMissingDevices) String() string { func (*SyncInventoryMissingDevices) ProtoMessage() {} func (x *SyncInventoryMissingDevices) ProtoReflect() protoreflect.Message { - mi := &file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[41] + mi := &file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[37] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2851,7 +2650,7 @@ func (x *SyncInventoryMissingDevices) ProtoReflect() protoreflect.Message { // Deprecated: Use SyncInventoryMissingDevices.ProtoReflect.Descriptor instead. func (*SyncInventoryMissingDevices) Descriptor() ([]byte, []int) { - return file_teleport_devicetrust_v1_devicetrust_service_proto_rawDescGZIP(), []int{41} + return file_teleport_devicetrust_v1_devicetrust_service_proto_rawDescGZIP(), []int{37} } func (x *SyncInventoryMissingDevices) GetDevices() []*Device { @@ -2871,7 +2670,7 @@ type GetDevicesUsageRequest struct { func (x *GetDevicesUsageRequest) Reset() { *x = GetDevicesUsageRequest{} if protoimpl.UnsafeEnabled { - mi := &file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[42] + mi := &file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[38] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2884,7 +2683,7 @@ func (x *GetDevicesUsageRequest) String() string { func (*GetDevicesUsageRequest) ProtoMessage() {} func (x *GetDevicesUsageRequest) ProtoReflect() protoreflect.Message { - mi := &file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[42] + mi := &file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[38] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2897,7 +2696,7 @@ func (x *GetDevicesUsageRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetDevicesUsageRequest.ProtoReflect.Descriptor instead. func (*GetDevicesUsageRequest) Descriptor() ([]byte, []int) { - return file_teleport_devicetrust_v1_devicetrust_service_proto_rawDescGZIP(), []int{42} + return file_teleport_devicetrust_v1_devicetrust_service_proto_rawDescGZIP(), []int{38} } var File_teleport_devicetrust_v1_devicetrust_service_proto protoreflect.FileDescriptor @@ -2915,537 +2714,519 @@ var file_teleport_devicetrust_v1_devicetrust_service_proto_rawDesc = []byte{ 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x17, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x72, 0x70, 0x63, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x24, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, - 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2f, 0x76, 0x31, 0x2f, 0x64, - 0x65, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x33, 0x74, 0x65, 0x6c, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x34, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, + 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2f, 0x76, 0x31, 0x2f, 0x61, + 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x5f, 0x63, 0x68, 0x61, 0x6c, + 0x6c, 0x65, 0x6e, 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x24, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, - 0x74, 0x2f, 0x76, 0x31, 0x2f, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x63, 0x6f, 0x6c, 0x6c, - 0x65, 0x63, 0x74, 0x65, 0x64, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x1a, 0x37, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x64, 0x65, 0x76, 0x69, 0x63, - 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2f, 0x76, 0x31, 0x2f, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, - 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x6f, - 0x6b, 0x65, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x31, 0x74, 0x65, 0x6c, 0x65, 0x70, - 0x6f, 0x72, 0x74, 0x2f, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2f, - 0x76, 0x31, 0x2f, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x65, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, - 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x2b, 0x74, 0x65, - 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, - 0x73, 0x74, 0x2f, 0x76, 0x31, 0x2f, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x73, 0x6f, 0x75, - 0x72, 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, - 0x6f, 0x72, 0x74, 0x2f, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2f, - 0x76, 0x31, 0x2f, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x77, 0x65, 0x62, 0x5f, 0x74, 0x6f, - 0x6b, 0x65, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x21, 0x74, 0x65, 0x6c, 0x65, 0x70, - 0x6f, 0x72, 0x74, 0x2f, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2f, - 0x76, 0x31, 0x2f, 0x74, 0x70, 0x6d, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x23, 0x74, 0x65, - 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, - 0x73, 0x74, 0x2f, 0x76, 0x31, 0x2f, 0x75, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x1a, 0x2f, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x64, 0x65, 0x76, 0x69, - 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2f, 0x76, 0x31, 0x2f, 0x75, 0x73, 0x65, 0x72, 0x5f, - 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x73, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x22, 0x81, 0x02, 0x0a, 0x13, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x44, 0x65, 0x76, - 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x37, 0x0a, 0x06, 0x64, 0x65, - 0x76, 0x69, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x74, 0x65, 0x6c, - 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, - 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, 0x06, 0x64, 0x65, 0x76, - 0x69, 0x63, 0x65, 0x12, 0x2e, 0x0a, 0x13, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x5f, 0x65, 0x6e, - 0x72, 0x6f, 0x6c, 0x6c, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, - 0x52, 0x11, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x54, 0x6f, - 0x6b, 0x65, 0x6e, 0x12, 0x2c, 0x0a, 0x12, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x5f, 0x61, 0x73, - 0x5f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, - 0x10, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, 0x73, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, - 0x65, 0x12, 0x53, 0x0a, 0x18, 0x65, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x5f, 0x74, 0x6f, 0x6b, 0x65, - 0x6e, 0x5f, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x04, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, - 0x15, 0x65, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x45, 0x78, 0x70, 0x69, - 0x72, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x22, 0x8b, 0x01, 0x0a, 0x13, 0x55, 0x70, 0x64, 0x61, 0x74, - 0x65, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x37, - 0x0a, 0x06, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, - 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, - 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, - 0x06, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x12, 0x3b, 0x0a, 0x0b, 0x75, 0x70, 0x64, 0x61, 0x74, - 0x65, 0x5f, 0x6d, 0x61, 0x73, 0x6b, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, - 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, - 0x69, 0x65, 0x6c, 0x64, 0x4d, 0x61, 0x73, 0x6b, 0x52, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, - 0x4d, 0x61, 0x73, 0x6b, 0x22, 0x7c, 0x0a, 0x13, 0x55, 0x70, 0x73, 0x65, 0x72, 0x74, 0x44, 0x65, - 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x37, 0x0a, 0x06, 0x64, - 0x65, 0x76, 0x69, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x74, 0x65, - 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, - 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, 0x06, 0x64, 0x65, - 0x76, 0x69, 0x63, 0x65, 0x12, 0x2c, 0x0a, 0x12, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x5f, 0x61, - 0x73, 0x5f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, - 0x52, 0x10, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, 0x73, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, - 0x63, 0x65, 0x22, 0x32, 0x0a, 0x13, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x44, 0x65, 0x76, 0x69, - 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x64, 0x65, 0x76, - 0x69, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x64, 0x65, - 0x76, 0x69, 0x63, 0x65, 0x49, 0x64, 0x22, 0x30, 0x0a, 0x12, 0x46, 0x69, 0x6e, 0x64, 0x44, 0x65, - 0x76, 0x69, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x09, - 0x69, 0x64, 0x5f, 0x6f, 0x72, 0x5f, 0x74, 0x61, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x07, 0x69, 0x64, 0x4f, 0x72, 0x54, 0x61, 0x67, 0x22, 0x50, 0x0a, 0x13, 0x46, 0x69, 0x6e, 0x64, - 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, - 0x39, 0x0a, 0x07, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, + 0x74, 0x2f, 0x76, 0x31, 0x2f, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x1a, 0x33, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x64, 0x65, 0x76, 0x69, + 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2f, 0x76, 0x31, 0x2f, 0x64, 0x65, 0x76, 0x69, 0x63, + 0x65, 0x5f, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x65, 0x64, 0x5f, 0x64, 0x61, 0x74, 0x61, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x37, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, + 0x2f, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2f, 0x76, 0x31, 0x2f, + 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, + 0x31, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, + 0x74, 0x72, 0x75, 0x73, 0x74, 0x2f, 0x76, 0x31, 0x2f, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, + 0x65, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x1a, 0x2b, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x64, 0x65, 0x76, + 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2f, 0x76, 0x31, 0x2f, 0x64, 0x65, 0x76, 0x69, + 0x63, 0x65, 0x5f, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, + 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, + 0x74, 0x72, 0x75, 0x73, 0x74, 0x2f, 0x76, 0x31, 0x2f, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, + 0x77, 0x65, 0x62, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, + 0x21, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, + 0x74, 0x72, 0x75, 0x73, 0x74, 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x70, 0x6d, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x1a, 0x23, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x64, 0x65, 0x76, + 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2f, 0x76, 0x31, 0x2f, 0x75, 0x73, 0x61, 0x67, + 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x2f, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, + 0x74, 0x2f, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2f, 0x76, 0x31, + 0x2f, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, + 0x65, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x81, 0x02, 0x0a, 0x13, 0x43, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x12, 0x37, 0x0a, 0x06, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x63, - 0x65, 0x52, 0x07, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x22, 0x2f, 0x0a, 0x10, 0x47, 0x65, - 0x74, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, - 0x0a, 0x09, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x08, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x49, 0x64, 0x22, 0x89, 0x01, 0x0a, 0x12, - 0x4c, 0x69, 0x73, 0x74, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x70, 0x61, 0x67, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x12, - 0x1d, 0x0a, 0x0a, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x09, 0x70, 0x61, 0x67, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x37, - 0x0a, 0x04, 0x76, 0x69, 0x65, 0x77, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x23, 0x2e, 0x74, - 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, - 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x56, 0x69, 0x65, - 0x77, 0x52, 0x04, 0x76, 0x69, 0x65, 0x77, 0x22, 0x78, 0x0a, 0x13, 0x4c, 0x69, 0x73, 0x74, 0x44, - 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x39, - 0x0a, 0x07, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x1f, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, - 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, - 0x52, 0x07, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x12, 0x26, 0x0a, 0x0f, 0x6e, 0x65, 0x78, - 0x74, 0x5f, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x0d, 0x6e, 0x65, 0x78, 0x74, 0x50, 0x61, 0x67, 0x65, 0x54, 0x6f, 0x6b, 0x65, - 0x6e, 0x22, 0x83, 0x01, 0x0a, 0x18, 0x42, 0x75, 0x6c, 0x6b, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, - 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x39, - 0x0a, 0x07, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x1f, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, - 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, - 0x52, 0x07, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x12, 0x2c, 0x0a, 0x12, 0x63, 0x72, 0x65, + 0x65, 0x52, 0x06, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x12, 0x2e, 0x0a, 0x13, 0x63, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x5f, 0x65, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x11, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x45, 0x6e, + 0x72, 0x6f, 0x6c, 0x6c, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x2c, 0x0a, 0x12, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x5f, 0x61, 0x73, 0x5f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, 0x73, 0x52, - 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x22, 0x5e, 0x0a, 0x19, 0x42, 0x75, 0x6c, 0x6b, 0x43, - 0x72, 0x65, 0x61, 0x74, 0x65, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x41, 0x0a, 0x07, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x18, - 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, - 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, - 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x4f, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x07, - 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x22, 0x66, 0x0a, 0x0e, 0x44, 0x65, 0x76, 0x69, 0x63, - 0x65, 0x4f, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x2a, 0x0a, 0x06, 0x73, 0x74, 0x61, - 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x6f, 0x6f, 0x67, - 0x6c, 0x65, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, - 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x64, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x22, - 0xc9, 0x01, 0x0a, 0x1e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, - 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x49, 0x64, 0x12, - 0x4d, 0x0a, 0x0b, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, + 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, 0x73, 0x52, + 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x53, 0x0a, 0x18, 0x65, 0x6e, 0x72, 0x6f, 0x6c, + 0x6c, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x5f, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x5f, 0x74, + 0x69, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, + 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x15, 0x65, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x54, 0x6f, 0x6b, + 0x65, 0x6e, 0x45, 0x78, 0x70, 0x69, 0x72, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x22, 0x8b, 0x01, 0x0a, + 0x13, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x12, 0x37, 0x0a, 0x06, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x44, - 0x65, 0x76, 0x69, 0x63, 0x65, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x65, 0x64, 0x44, 0x61, - 0x74, 0x61, 0x52, 0x0a, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x44, 0x61, 0x74, 0x61, 0x12, 0x3b, - 0x0a, 0x0b, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, - 0x0a, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x22, 0xc1, 0x02, 0x0a, 0x13, - 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x12, 0x3f, 0x0a, 0x04, 0x69, 0x6e, 0x69, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x29, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, - 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x6e, 0x72, 0x6f, - 0x6c, 0x6c, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x49, 0x6e, 0x69, 0x74, 0x48, 0x00, 0x52, 0x04, - 0x69, 0x6e, 0x69, 0x74, 0x12, 0x71, 0x0a, 0x18, 0x6d, 0x61, 0x63, 0x6f, 0x73, 0x5f, 0x63, 0x68, - 0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x67, 0x65, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x35, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, + 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, 0x06, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x12, 0x3b, 0x0a, + 0x0b, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x6d, 0x61, 0x73, 0x6b, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x4d, 0x61, 0x73, 0x6b, 0x52, 0x0a, + 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x61, 0x73, 0x6b, 0x22, 0x7c, 0x0a, 0x13, 0x55, 0x70, + 0x73, 0x65, 0x72, 0x74, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x12, 0x37, 0x0a, 0x06, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x1f, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, + 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x76, 0x69, + 0x63, 0x65, 0x52, 0x06, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x12, 0x2c, 0x0a, 0x12, 0x63, 0x72, + 0x65, 0x61, 0x74, 0x65, 0x5f, 0x61, 0x73, 0x5f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, 0x73, + 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x22, 0x32, 0x0a, 0x13, 0x44, 0x65, 0x6c, 0x65, + 0x74, 0x65, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x1b, 0x0a, 0x09, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x08, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x49, 0x64, 0x22, 0x30, 0x0a, 0x12, + 0x46, 0x69, 0x6e, 0x64, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x09, 0x69, 0x64, 0x5f, 0x6f, 0x72, 0x5f, 0x74, 0x61, 0x67, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x69, 0x64, 0x4f, 0x72, 0x54, 0x61, 0x67, 0x22, 0x50, + 0x0a, 0x13, 0x46, 0x69, 0x6e, 0x64, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x39, 0x0a, 0x07, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, + 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, - 0x2e, 0x4d, 0x61, 0x63, 0x4f, 0x53, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x43, 0x68, 0x61, 0x6c, - 0x6c, 0x65, 0x6e, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x48, 0x00, 0x52, - 0x16, 0x6d, 0x61, 0x63, 0x6f, 0x73, 0x43, 0x68, 0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x67, 0x65, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6b, 0x0a, 0x16, 0x74, 0x70, 0x6d, 0x5f, 0x63, - 0x68, 0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x67, 0x65, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x33, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, - 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, - 0x31, 0x2e, 0x54, 0x50, 0x4d, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x43, 0x68, 0x61, 0x6c, 0x6c, - 0x65, 0x6e, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x48, 0x00, 0x52, 0x14, - 0x74, 0x70, 0x6d, 0x43, 0x68, 0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x09, 0x0a, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x22, - 0x99, 0x02, 0x0a, 0x14, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x48, 0x0a, 0x07, 0x73, 0x75, 0x63, 0x63, - 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x74, 0x65, 0x6c, 0x65, - 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, - 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, - 0x53, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x48, 0x00, 0x52, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, - 0x73, 0x73, 0x12, 0x58, 0x0a, 0x0f, 0x6d, 0x61, 0x63, 0x6f, 0x73, 0x5f, 0x63, 0x68, 0x61, 0x6c, - 0x6c, 0x65, 0x6e, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x74, 0x65, + 0x2e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, 0x07, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, + 0x22, 0x2f, 0x0a, 0x10, 0x47, 0x65, 0x74, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x69, + 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x49, + 0x64, 0x22, 0x89, 0x01, 0x0a, 0x12, 0x4c, 0x69, 0x73, 0x74, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, + 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x70, 0x61, 0x67, 0x65, + 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x70, 0x61, 0x67, + 0x65, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x74, 0x6f, + 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x70, 0x61, 0x67, 0x65, 0x54, + 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x37, 0x0a, 0x04, 0x76, 0x69, 0x65, 0x77, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x0e, 0x32, 0x23, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, + 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x76, + 0x69, 0x63, 0x65, 0x56, 0x69, 0x65, 0x77, 0x52, 0x04, 0x76, 0x69, 0x65, 0x77, 0x22, 0x78, 0x0a, + 0x13, 0x4c, 0x69, 0x73, 0x74, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x39, 0x0a, 0x07, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x18, + 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, + 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, + 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, 0x07, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x12, + 0x26, 0x0a, 0x0f, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x74, 0x6f, 0x6b, + 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x6e, 0x65, 0x78, 0x74, 0x50, 0x61, + 0x67, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x83, 0x01, 0x0a, 0x18, 0x42, 0x75, 0x6c, 0x6b, + 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x12, 0x39, 0x0a, 0x07, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x18, + 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, + 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, + 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, 0x07, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x12, + 0x2c, 0x0a, 0x12, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x5f, 0x61, 0x73, 0x5f, 0x72, 0x65, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x63, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x41, 0x73, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x22, 0x5e, 0x0a, + 0x19, 0x42, 0x75, 0x6c, 0x6b, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x44, 0x65, 0x76, 0x69, 0x63, + 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x41, 0x0a, 0x07, 0x64, 0x65, + 0x76, 0x69, 0x63, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, - 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x61, 0x63, 0x4f, 0x53, 0x45, 0x6e, 0x72, 0x6f, 0x6c, - 0x6c, 0x43, 0x68, 0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x67, 0x65, 0x48, 0x00, 0x52, 0x0e, 0x6d, 0x61, - 0x63, 0x6f, 0x73, 0x43, 0x68, 0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x67, 0x65, 0x12, 0x52, 0x0a, 0x0d, - 0x74, 0x70, 0x6d, 0x5f, 0x63, 0x68, 0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x67, 0x65, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, - 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x50, - 0x4d, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x43, 0x68, 0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x67, 0x65, - 0x48, 0x00, 0x52, 0x0c, 0x74, 0x70, 0x6d, 0x43, 0x68, 0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x67, 0x65, - 0x42, 0x09, 0x0a, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x22, 0x9c, 0x02, 0x0a, 0x10, - 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x49, 0x6e, 0x69, 0x74, - 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x23, 0x0a, 0x0d, 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, - 0x74, 0x69, 0x61, 0x6c, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x63, - 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x49, 0x64, 0x12, 0x4d, 0x0a, 0x0b, 0x64, - 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x2c, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, - 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x63, - 0x65, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x65, 0x64, 0x44, 0x61, 0x74, 0x61, 0x52, 0x0a, - 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x44, 0x61, 0x74, 0x61, 0x12, 0x41, 0x0a, 0x05, 0x6d, 0x61, - 0x63, 0x6f, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x74, 0x65, 0x6c, 0x65, - 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, - 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x61, 0x63, 0x4f, 0x53, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x50, - 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x52, 0x05, 0x6d, 0x61, 0x63, 0x6f, 0x73, 0x12, 0x3b, 0x0a, - 0x03, 0x74, 0x70, 0x6d, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x74, 0x65, 0x6c, + 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x4f, 0x72, 0x53, 0x74, + 0x61, 0x74, 0x75, 0x73, 0x52, 0x07, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x22, 0x66, 0x0a, + 0x0e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x4f, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, + 0x2a, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x12, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x74, 0x61, + 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x0e, 0x0a, 0x02, 0x69, + 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x64, + 0x65, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x64, 0x65, + 0x6c, 0x65, 0x74, 0x65, 0x64, 0x22, 0xc9, 0x01, 0x0a, 0x1e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, + 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x54, 0x6f, 0x6b, 0x65, + 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x64, 0x65, 0x76, 0x69, + 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x64, 0x65, 0x76, + 0x69, 0x63, 0x65, 0x49, 0x64, 0x12, 0x4d, 0x0a, 0x0b, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, + 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, - 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x50, 0x4d, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x50, 0x61, - 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x52, 0x03, 0x74, 0x70, 0x6d, 0x22, 0x4e, 0x0a, 0x13, 0x45, 0x6e, - 0x72, 0x6f, 0x6c, 0x6c, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x53, 0x75, 0x63, 0x63, 0x65, 0x73, - 0x73, 0x12, 0x37, 0x0a, 0x06, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x1f, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, - 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x76, 0x69, - 0x63, 0x65, 0x52, 0x06, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x22, 0x3a, 0x0a, 0x12, 0x4d, 0x61, - 0x63, 0x4f, 0x53, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, - 0x12, 0x24, 0x0a, 0x0e, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x64, - 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0c, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, - 0x4b, 0x65, 0x79, 0x44, 0x65, 0x72, 0x22, 0x34, 0x0a, 0x14, 0x4d, 0x61, 0x63, 0x4f, 0x53, 0x45, - 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x43, 0x68, 0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x67, 0x65, 0x12, 0x1c, - 0x0a, 0x09, 0x63, 0x68, 0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0c, 0x52, 0x09, 0x63, 0x68, 0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x67, 0x65, 0x22, 0x3c, 0x0a, 0x1c, + 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x43, 0x6f, 0x6c, 0x6c, 0x65, + 0x63, 0x74, 0x65, 0x64, 0x44, 0x61, 0x74, 0x61, 0x52, 0x0a, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, + 0x44, 0x61, 0x74, 0x61, 0x12, 0x3b, 0x0a, 0x0b, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x5f, 0x74, + 0x69, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, + 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0a, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x54, 0x69, 0x6d, + 0x65, 0x22, 0xc1, 0x02, 0x0a, 0x13, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x44, 0x65, 0x76, 0x69, + 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3f, 0x0a, 0x04, 0x69, 0x6e, 0x69, + 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, + 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, + 0x31, 0x2e, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x49, 0x6e, + 0x69, 0x74, 0x48, 0x00, 0x52, 0x04, 0x69, 0x6e, 0x69, 0x74, 0x12, 0x71, 0x0a, 0x18, 0x6d, 0x61, + 0x63, 0x6f, 0x73, 0x5f, 0x63, 0x68, 0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x67, 0x65, 0x5f, 0x72, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x35, 0x2e, 0x74, + 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, + 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x61, 0x63, 0x4f, 0x53, 0x45, 0x6e, 0x72, 0x6f, + 0x6c, 0x6c, 0x43, 0x68, 0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x48, 0x00, 0x52, 0x16, 0x6d, 0x61, 0x63, 0x6f, 0x73, 0x43, 0x68, 0x61, 0x6c, + 0x6c, 0x65, 0x6e, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6b, 0x0a, + 0x16, 0x74, 0x70, 0x6d, 0x5f, 0x63, 0x68, 0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x67, 0x65, 0x5f, 0x72, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x33, 0x2e, + 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, + 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x50, 0x4d, 0x45, 0x6e, 0x72, 0x6f, 0x6c, + 0x6c, 0x43, 0x68, 0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x48, 0x00, 0x52, 0x14, 0x74, 0x70, 0x6d, 0x43, 0x68, 0x61, 0x6c, 0x6c, 0x65, 0x6e, + 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x09, 0x0a, 0x07, 0x70, 0x61, + 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x22, 0x99, 0x02, 0x0a, 0x14, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, + 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x48, + 0x0a, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x2c, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, + 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, + 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x53, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x48, 0x00, 0x52, + 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x12, 0x58, 0x0a, 0x0f, 0x6d, 0x61, 0x63, 0x6f, + 0x73, 0x5f, 0x63, 0x68, 0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x2d, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, + 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x61, 0x63, 0x4f, + 0x53, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x43, 0x68, 0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x67, 0x65, + 0x48, 0x00, 0x52, 0x0e, 0x6d, 0x61, 0x63, 0x6f, 0x73, 0x43, 0x68, 0x61, 0x6c, 0x6c, 0x65, 0x6e, + 0x67, 0x65, 0x12, 0x52, 0x0a, 0x0d, 0x74, 0x70, 0x6d, 0x5f, 0x63, 0x68, 0x61, 0x6c, 0x6c, 0x65, + 0x6e, 0x67, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x74, 0x65, 0x6c, 0x65, + 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, + 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x50, 0x4d, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x43, 0x68, 0x61, + 0x6c, 0x6c, 0x65, 0x6e, 0x67, 0x65, 0x48, 0x00, 0x52, 0x0c, 0x74, 0x70, 0x6d, 0x43, 0x68, 0x61, + 0x6c, 0x6c, 0x65, 0x6e, 0x67, 0x65, 0x42, 0x09, 0x0a, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, + 0x64, 0x22, 0x9c, 0x02, 0x0a, 0x10, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x44, 0x65, 0x76, 0x69, + 0x63, 0x65, 0x49, 0x6e, 0x69, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x23, 0x0a, 0x0d, + 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0c, 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x49, + 0x64, 0x12, 0x4d, 0x0a, 0x0b, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x64, 0x61, 0x74, 0x61, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, + 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, + 0x2e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x65, 0x64, + 0x44, 0x61, 0x74, 0x61, 0x52, 0x0a, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x44, 0x61, 0x74, 0x61, + 0x12, 0x41, 0x0a, 0x05, 0x6d, 0x61, 0x63, 0x6f, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x2b, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, + 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x61, 0x63, 0x4f, 0x53, 0x45, + 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x52, 0x05, 0x6d, 0x61, + 0x63, 0x6f, 0x73, 0x12, 0x3b, 0x0a, 0x03, 0x74, 0x70, 0x6d, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x29, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, + 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x50, 0x4d, 0x45, 0x6e, + 0x72, 0x6f, 0x6c, 0x6c, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x52, 0x03, 0x74, 0x70, 0x6d, + 0x22, 0x4e, 0x0a, 0x13, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, + 0x53, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x12, 0x37, 0x0a, 0x06, 0x64, 0x65, 0x76, 0x69, 0x63, + 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, + 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, + 0x31, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, 0x06, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, + 0x22, 0x3a, 0x0a, 0x12, 0x4d, 0x61, 0x63, 0x4f, 0x53, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x50, + 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x24, 0x0a, 0x0e, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, + 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x64, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0c, + 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x44, 0x65, 0x72, 0x22, 0x34, 0x0a, 0x14, 0x4d, 0x61, 0x63, 0x4f, 0x53, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x43, 0x68, 0x61, 0x6c, 0x6c, - 0x65, 0x6e, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1c, 0x0a, 0x09, - 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, - 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x22, 0xb6, 0x01, 0x0a, 0x10, 0x54, - 0x50, 0x4d, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x12, - 0x19, 0x0a, 0x07, 0x65, 0x6b, 0x5f, 0x63, 0x65, 0x72, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, - 0x48, 0x00, 0x52, 0x06, 0x65, 0x6b, 0x43, 0x65, 0x72, 0x74, 0x12, 0x17, 0x0a, 0x06, 0x65, 0x6b, - 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x48, 0x00, 0x52, 0x05, 0x65, 0x6b, - 0x4b, 0x65, 0x79, 0x12, 0x68, 0x0a, 0x16, 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x31, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, - 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x50, + 0x65, 0x6e, 0x67, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x68, 0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x67, + 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x63, 0x68, 0x61, 0x6c, 0x6c, 0x65, 0x6e, + 0x67, 0x65, 0x22, 0x3c, 0x0a, 0x1c, 0x4d, 0x61, 0x63, 0x4f, 0x53, 0x45, 0x6e, 0x72, 0x6f, 0x6c, + 0x6c, 0x43, 0x68, 0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, + 0x22, 0xb6, 0x01, 0x0a, 0x10, 0x54, 0x50, 0x4d, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x50, 0x61, + 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x19, 0x0a, 0x07, 0x65, 0x6b, 0x5f, 0x63, 0x65, 0x72, 0x74, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x48, 0x00, 0x52, 0x06, 0x65, 0x6b, 0x43, 0x65, 0x72, 0x74, + 0x12, 0x17, 0x0a, 0x06, 0x65, 0x6b, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, + 0x48, 0x00, 0x52, 0x05, 0x65, 0x6b, 0x4b, 0x65, 0x79, 0x12, 0x68, 0x0a, 0x16, 0x61, 0x74, 0x74, + 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, + 0x65, 0x72, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x31, 0x2e, 0x74, 0x65, 0x6c, 0x65, + 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, + 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x50, 0x4d, 0x41, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x52, 0x15, 0x61, 0x74, + 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, + 0x65, 0x72, 0x73, 0x42, 0x04, 0x0a, 0x02, 0x65, 0x6b, 0x22, 0xad, 0x01, 0x0a, 0x18, 0x54, 0x50, 0x4d, 0x41, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x61, 0x72, 0x61, - 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x52, 0x15, 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x42, 0x04, 0x0a, - 0x02, 0x65, 0x6b, 0x22, 0xad, 0x01, 0x0a, 0x18, 0x54, 0x50, 0x4d, 0x41, 0x74, 0x74, 0x65, 0x73, - 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, - 0x12, 0x16, 0x0a, 0x06, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, - 0x52, 0x06, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x12, 0x1f, 0x0a, 0x0b, 0x63, 0x72, 0x65, 0x61, - 0x74, 0x65, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x63, - 0x72, 0x65, 0x61, 0x74, 0x65, 0x44, 0x61, 0x74, 0x61, 0x12, 0x2d, 0x0a, 0x12, 0x63, 0x72, 0x65, - 0x61, 0x74, 0x65, 0x5f, 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x11, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, 0x74, 0x74, - 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x29, 0x0a, 0x10, 0x63, 0x72, 0x65, 0x61, - 0x74, 0x65, 0x5f, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x04, 0x20, 0x01, - 0x28, 0x0c, 0x52, 0x0f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, - 0x75, 0x72, 0x65, 0x22, 0xa5, 0x01, 0x0a, 0x12, 0x54, 0x50, 0x4d, 0x45, 0x6e, 0x72, 0x6f, 0x6c, - 0x6c, 0x43, 0x68, 0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x67, 0x65, 0x12, 0x62, 0x0a, 0x14, 0x65, 0x6e, - 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x5f, 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, - 0x61, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, - 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, - 0x76, 0x31, 0x2e, 0x54, 0x50, 0x4d, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x43, - 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x52, 0x13, 0x65, 0x6e, 0x63, 0x72, 0x79, - 0x70, 0x74, 0x65, 0x64, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x12, 0x2b, - 0x0a, 0x11, 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6e, 0x6f, - 0x6e, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x10, 0x61, 0x74, 0x74, 0x65, 0x73, - 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4e, 0x6f, 0x6e, 0x63, 0x65, 0x22, 0x59, 0x0a, 0x16, 0x54, - 0x50, 0x4d, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x43, 0x72, 0x65, 0x64, 0x65, - 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x12, 0x27, 0x0a, 0x0f, 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, - 0x69, 0x61, 0x6c, 0x5f, 0x62, 0x6c, 0x6f, 0x62, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0e, - 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x42, 0x6c, 0x6f, 0x62, 0x12, 0x16, - 0x0a, 0x06, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, - 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x22, 0x99, 0x01, 0x0a, 0x1a, 0x54, 0x50, 0x4d, 0x45, 0x6e, - 0x72, 0x6f, 0x6c, 0x6c, 0x43, 0x68, 0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x67, 0x65, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, - 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, - 0x6e, 0x12, 0x5f, 0x0a, 0x13, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x5f, 0x70, 0x61, - 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2e, - 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, - 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x50, 0x4d, 0x50, 0x6c, 0x61, 0x74, - 0x66, 0x6f, 0x72, 0x6d, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x52, 0x12, - 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, - 0x72, 0x73, 0x22, 0xd5, 0x02, 0x0a, 0x19, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, - 0x61, 0x74, 0x65, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x12, 0x45, 0x0a, 0x04, 0x69, 0x6e, 0x69, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2f, + 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x12, 0x1f, + 0x0a, 0x0b, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x44, 0x61, 0x74, 0x61, 0x12, + 0x2d, 0x0a, 0x12, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x5f, 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x11, 0x63, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x41, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x29, + 0x0a, 0x10, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x5f, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, + 0x72, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, + 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x22, 0xa5, 0x01, 0x0a, 0x12, 0x54, 0x50, + 0x4d, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x43, 0x68, 0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x67, 0x65, + 0x12, 0x62, 0x0a, 0x14, 0x65, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x5f, 0x63, 0x72, + 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, - 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, - 0x69, 0x63, 0x61, 0x74, 0x65, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x49, 0x6e, 0x69, 0x74, 0x48, - 0x00, 0x52, 0x04, 0x69, 0x6e, 0x69, 0x74, 0x12, 0x6d, 0x0a, 0x12, 0x63, 0x68, 0x61, 0x6c, 0x6c, - 0x65, 0x6e, 0x67, 0x65, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x3c, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, - 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x75, - 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, - 0x43, 0x68, 0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x48, 0x00, 0x52, 0x11, 0x63, 0x68, 0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x67, 0x65, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x77, 0x0a, 0x16, 0x74, 0x70, 0x6d, 0x5f, 0x63, 0x68, - 0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x67, 0x65, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x3f, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, + 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x50, 0x4d, 0x45, 0x6e, 0x63, 0x72, + 0x79, 0x70, 0x74, 0x65, 0x64, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x52, + 0x13, 0x65, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, + 0x74, 0x69, 0x61, 0x6c, 0x12, 0x2b, 0x0a, 0x11, 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x5f, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, + 0x10, 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4e, 0x6f, 0x6e, 0x63, + 0x65, 0x22, 0x59, 0x0a, 0x16, 0x54, 0x50, 0x4d, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, + 0x64, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x12, 0x27, 0x0a, 0x0f, 0x63, + 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x5f, 0x62, 0x6c, 0x6f, 0x62, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0e, 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, + 0x42, 0x6c, 0x6f, 0x62, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x22, 0x99, 0x01, 0x0a, + 0x1a, 0x54, 0x50, 0x4d, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x43, 0x68, 0x61, 0x6c, 0x6c, 0x65, + 0x6e, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x73, + 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x73, + 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x5f, 0x0a, 0x13, 0x70, 0x6c, 0x61, 0x74, 0x66, + 0x6f, 0x72, 0x6d, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, + 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x54, + 0x50, 0x4d, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, + 0x74, 0x65, 0x72, 0x73, 0x52, 0x12, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x50, 0x61, + 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x22, 0xd5, 0x02, 0x0a, 0x19, 0x41, 0x75, 0x74, + 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x45, 0x0a, 0x04, 0x69, 0x6e, 0x69, 0x74, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, + 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x41, + 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x44, 0x65, 0x76, 0x69, 0x63, + 0x65, 0x49, 0x6e, 0x69, 0x74, 0x48, 0x00, 0x52, 0x04, 0x69, 0x6e, 0x69, 0x74, 0x12, 0x6d, 0x0a, + 0x12, 0x63, 0x68, 0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x67, 0x65, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x3c, 0x2e, 0x74, 0x65, 0x6c, 0x65, + 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, + 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, + 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x43, 0x68, 0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x67, 0x65, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x48, 0x00, 0x52, 0x11, 0x63, 0x68, 0x61, 0x6c, 0x6c, + 0x65, 0x6e, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x77, 0x0a, 0x16, + 0x74, 0x70, 0x6d, 0x5f, 0x63, 0x68, 0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x67, 0x65, 0x5f, 0x72, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x3f, 0x2e, 0x74, + 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, + 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x50, 0x4d, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, + 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x43, 0x68, 0x61, 0x6c, + 0x6c, 0x65, 0x6e, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x48, 0x00, 0x52, + 0x14, 0x74, 0x70, 0x6d, 0x43, 0x68, 0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x67, 0x65, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x09, 0x0a, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, + 0x22, 0x9a, 0x03, 0x0a, 0x1a, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, + 0x65, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x54, 0x0a, 0x09, 0x63, 0x68, 0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x34, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, + 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x75, 0x74, + 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x43, + 0x68, 0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x67, 0x65, 0x48, 0x00, 0x52, 0x09, 0x63, 0x68, 0x61, 0x6c, + 0x6c, 0x65, 0x6e, 0x67, 0x65, 0x12, 0x58, 0x0a, 0x11, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x63, 0x65, + 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x29, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, + 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x43, + 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x73, 0x48, 0x00, 0x52, 0x10, 0x75, + 0x73, 0x65, 0x72, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x73, 0x12, + 0x5e, 0x0a, 0x0d, 0x74, 0x70, 0x6d, 0x5f, 0x63, 0x68, 0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x67, 0x65, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x37, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x50, 0x4d, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, - 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x43, 0x68, 0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x67, 0x65, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x48, 0x00, 0x52, 0x14, 0x74, 0x70, 0x6d, 0x43, 0x68, - 0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, - 0x09, 0x0a, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x22, 0x9a, 0x03, 0x0a, 0x1a, 0x41, - 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x44, 0x65, 0x76, 0x69, 0x63, - 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x54, 0x0a, 0x09, 0x63, 0x68, 0x61, - 0x6c, 0x6c, 0x65, 0x6e, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x34, 0x2e, 0x74, + 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x43, 0x68, 0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x67, 0x65, 0x48, + 0x00, 0x52, 0x0c, 0x74, 0x70, 0x6d, 0x43, 0x68, 0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x67, 0x65, 0x12, + 0x61, 0x0a, 0x12, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, + 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x74, 0x65, + 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, + 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x66, + 0x69, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x48, 0x00, 0x52, + 0x11, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x6f, 0x6b, + 0x65, 0x6e, 0x42, 0x09, 0x0a, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x22, 0xb7, 0x02, + 0x0a, 0x16, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x44, 0x65, + 0x76, 0x69, 0x63, 0x65, 0x49, 0x6e, 0x69, 0x74, 0x12, 0x56, 0x0a, 0x11, 0x75, 0x73, 0x65, 0x72, + 0x5f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x73, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, + 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x73, + 0x65, 0x72, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x73, 0x52, 0x10, + 0x75, 0x73, 0x65, 0x72, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x73, + 0x12, 0x23, 0x0a, 0x0d, 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x5f, 0x69, + 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, + 0x69, 0x61, 0x6c, 0x49, 0x64, 0x12, 0x4d, 0x0a, 0x0b, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, + 0x64, 0x61, 0x74, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x74, 0x65, 0x6c, + 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, + 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x43, 0x6f, 0x6c, 0x6c, 0x65, + 0x63, 0x74, 0x65, 0x64, 0x44, 0x61, 0x74, 0x61, 0x52, 0x0a, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, + 0x44, 0x61, 0x74, 0x61, 0x12, 0x51, 0x0a, 0x10, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x77, + 0x65, 0x62, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, + 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, + 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x57, + 0x65, 0x62, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x0e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x57, + 0x65, 0x62, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0xbd, 0x01, 0x0a, 0x25, 0x43, 0x6f, 0x6e, 0x66, + 0x69, 0x72, 0x6d, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x57, 0x65, 0x62, 0x41, 0x75, 0x74, 0x68, + 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x12, 0x5f, 0x0a, 0x12, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x30, 0x2e, + 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, + 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x43, 0x6f, + 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, + 0x11, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x6f, 0x6b, + 0x65, 0x6e, 0x12, 0x33, 0x0a, 0x16, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x77, 0x65, + 0x62, 0x5f, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x13, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x57, 0x65, 0x62, 0x53, 0x65, + 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x22, 0x28, 0x0a, 0x26, 0x43, 0x6f, 0x6e, 0x66, 0x69, + 0x72, 0x6d, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x57, 0x65, 0x62, 0x41, 0x75, 0x74, 0x68, 0x65, + 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x22, 0xdf, 0x02, 0x0a, 0x14, 0x53, 0x79, 0x6e, 0x63, 0x49, 0x6e, 0x76, 0x65, 0x6e, 0x74, + 0x6f, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x43, 0x0a, 0x05, 0x73, 0x74, + 0x61, 0x72, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x74, 0x65, 0x6c, 0x65, + 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, + 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x49, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, + 0x79, 0x53, 0x74, 0x61, 0x72, 0x74, 0x48, 0x00, 0x52, 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, 0x12, + 0x3d, 0x0a, 0x03, 0x65, 0x6e, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, - 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, - 0x61, 0x74, 0x65, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x43, 0x68, 0x61, 0x6c, 0x6c, 0x65, 0x6e, - 0x67, 0x65, 0x48, 0x00, 0x52, 0x09, 0x63, 0x68, 0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x67, 0x65, 0x12, - 0x58, 0x0a, 0x11, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, - 0x61, 0x74, 0x65, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x74, 0x65, 0x6c, + 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x49, 0x6e, 0x76, 0x65, 0x6e, + 0x74, 0x6f, 0x72, 0x79, 0x45, 0x6e, 0x64, 0x48, 0x00, 0x52, 0x03, 0x65, 0x6e, 0x64, 0x12, 0x5b, + 0x0a, 0x11, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x5f, 0x74, 0x6f, 0x5f, 0x75, 0x70, 0x73, + 0x65, 0x72, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x74, 0x65, 0x6c, 0x65, + 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, + 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x49, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, + 0x79, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x48, 0x00, 0x52, 0x0f, 0x64, 0x65, 0x76, 0x69, + 0x63, 0x65, 0x73, 0x54, 0x6f, 0x55, 0x70, 0x73, 0x65, 0x72, 0x74, 0x12, 0x5b, 0x0a, 0x11, 0x64, + 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x5f, 0x74, 0x6f, 0x5f, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, + 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, + 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x49, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x44, 0x65, + 0x76, 0x69, 0x63, 0x65, 0x73, 0x48, 0x00, 0x52, 0x0f, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, + 0x54, 0x6f, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x42, 0x09, 0x0a, 0x07, 0x70, 0x61, 0x79, 0x6c, + 0x6f, 0x61, 0x64, 0x22, 0x8a, 0x02, 0x0a, 0x15, 0x53, 0x79, 0x6e, 0x63, 0x49, 0x6e, 0x76, 0x65, + 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3d, 0x0a, + 0x03, 0x61, 0x63, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, - 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, - 0x63, 0x61, 0x74, 0x65, 0x73, 0x48, 0x00, 0x52, 0x10, 0x75, 0x73, 0x65, 0x72, 0x43, 0x65, 0x72, - 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x73, 0x12, 0x5e, 0x0a, 0x0d, 0x74, 0x70, 0x6d, - 0x5f, 0x63, 0x68, 0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x67, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x37, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, - 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x50, 0x4d, 0x41, 0x75, - 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, - 0x43, 0x68, 0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x67, 0x65, 0x48, 0x00, 0x52, 0x0c, 0x74, 0x70, 0x6d, - 0x43, 0x68, 0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x67, 0x65, 0x12, 0x61, 0x0a, 0x12, 0x63, 0x6f, 0x6e, - 0x66, 0x69, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, - 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, - 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, - 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x48, 0x00, 0x52, 0x11, 0x63, 0x6f, 0x6e, 0x66, 0x69, - 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x42, 0x09, 0x0a, 0x07, - 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x22, 0xb7, 0x02, 0x0a, 0x16, 0x41, 0x75, 0x74, 0x68, - 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x49, 0x6e, - 0x69, 0x74, 0x12, 0x56, 0x0a, 0x11, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x63, 0x65, 0x72, 0x74, 0x69, - 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e, + 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x49, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, + 0x72, 0x79, 0x41, 0x63, 0x6b, 0x48, 0x00, 0x52, 0x03, 0x61, 0x63, 0x6b, 0x12, 0x46, 0x0a, 0x06, + 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x74, + 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, + 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x49, 0x6e, 0x76, 0x65, 0x6e, + 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x48, 0x00, 0x52, 0x06, 0x72, 0x65, + 0x73, 0x75, 0x6c, 0x74, 0x12, 0x5f, 0x0a, 0x0f, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x5f, + 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x34, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, - 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x43, 0x65, 0x72, 0x74, - 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x73, 0x52, 0x10, 0x75, 0x73, 0x65, 0x72, 0x43, 0x65, - 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x63, 0x72, - 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x0c, 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x49, 0x64, 0x12, - 0x4d, 0x0a, 0x0b, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, + 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x49, 0x6e, 0x76, 0x65, + 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x4d, 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x44, 0x65, 0x76, 0x69, + 0x63, 0x65, 0x73, 0x48, 0x00, 0x52, 0x0e, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x44, 0x65, + 0x76, 0x69, 0x63, 0x65, 0x73, 0x42, 0x09, 0x0a, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, + 0x22, 0xac, 0x01, 0x0a, 0x12, 0x53, 0x79, 0x6e, 0x63, 0x49, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, + 0x72, 0x79, 0x53, 0x74, 0x61, 0x72, 0x74, 0x12, 0x3d, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, + 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, + 0x31, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x06, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x32, 0x0a, 0x15, 0x74, 0x72, 0x61, 0x63, 0x6b, 0x5f, + 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x5f, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x13, 0x74, 0x72, 0x61, 0x63, 0x6b, 0x4d, 0x69, 0x73, 0x73, + 0x69, 0x6e, 0x67, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x4a, 0x04, 0x08, 0x02, 0x10, 0x03, + 0x4a, 0x04, 0x08, 0x03, 0x10, 0x04, 0x52, 0x04, 0x6d, 0x6f, 0x64, 0x65, 0x52, 0x11, 0x6f, 0x6e, + 0x5f, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x5f, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, + 0x32, 0x0a, 0x10, 0x53, 0x79, 0x6e, 0x63, 0x49, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, + 0x45, 0x6e, 0x64, 0x4a, 0x04, 0x08, 0x01, 0x10, 0x02, 0x52, 0x18, 0x65, 0x78, 0x74, 0x65, 0x72, + 0x6e, 0x61, 0x6c, 0x5f, 0x73, 0x79, 0x6e, 0x63, 0x5f, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, + 0x66, 0x75, 0x6c, 0x22, 0x51, 0x0a, 0x14, 0x53, 0x79, 0x6e, 0x63, 0x49, 0x6e, 0x76, 0x65, 0x6e, + 0x74, 0x6f, 0x72, 0x79, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x12, 0x39, 0x0a, 0x07, 0x64, + 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x74, + 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, + 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, 0x07, 0x64, + 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x22, 0x12, 0x0a, 0x10, 0x53, 0x79, 0x6e, 0x63, 0x49, 0x6e, + 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x41, 0x63, 0x6b, 0x22, 0x58, 0x0a, 0x13, 0x53, 0x79, + 0x6e, 0x63, 0x49, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x73, 0x75, 0x6c, + 0x74, 0x12, 0x41, 0x0a, 0x07, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, + 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x76, + 0x69, 0x63, 0x65, 0x4f, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x07, 0x64, 0x65, 0x76, + 0x69, 0x63, 0x65, 0x73, 0x22, 0x58, 0x0a, 0x1b, 0x53, 0x79, 0x6e, 0x63, 0x49, 0x6e, 0x76, 0x65, + 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x4d, 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x44, 0x65, 0x76, 0x69, + 0x63, 0x65, 0x73, 0x12, 0x39, 0x0a, 0x07, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x18, 0x01, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x44, - 0x65, 0x76, 0x69, 0x63, 0x65, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x65, 0x64, 0x44, 0x61, - 0x74, 0x61, 0x52, 0x0a, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x44, 0x61, 0x74, 0x61, 0x12, 0x51, - 0x0a, 0x10, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x77, 0x65, 0x62, 0x5f, 0x74, 0x6f, 0x6b, - 0x65, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, + 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, 0x07, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x22, 0x18, + 0x0a, 0x16, 0x47, 0x65, 0x74, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x55, 0x73, 0x61, 0x67, + 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2a, 0x59, 0x0a, 0x0a, 0x44, 0x65, 0x76, 0x69, + 0x63, 0x65, 0x56, 0x69, 0x65, 0x77, 0x12, 0x1b, 0x0a, 0x17, 0x44, 0x45, 0x56, 0x49, 0x43, 0x45, + 0x5f, 0x56, 0x49, 0x45, 0x57, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, + 0x44, 0x10, 0x00, 0x12, 0x14, 0x0a, 0x10, 0x44, 0x45, 0x56, 0x49, 0x43, 0x45, 0x5f, 0x56, 0x49, + 0x45, 0x57, 0x5f, 0x4c, 0x49, 0x53, 0x54, 0x10, 0x01, 0x12, 0x18, 0x0a, 0x14, 0x44, 0x45, 0x56, + 0x49, 0x43, 0x45, 0x5f, 0x56, 0x49, 0x45, 0x57, 0x5f, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, + 0x45, 0x10, 0x02, 0x32, 0xad, 0x0c, 0x0a, 0x12, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x54, 0x72, + 0x75, 0x73, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x5d, 0x0a, 0x0c, 0x43, 0x72, + 0x65, 0x61, 0x74, 0x65, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x12, 0x2c, 0x2e, 0x74, 0x65, 0x6c, + 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, + 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x44, 0x65, 0x76, 0x69, 0x63, + 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, - 0x76, 0x31, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x57, 0x65, 0x62, 0x54, 0x6f, 0x6b, 0x65, - 0x6e, 0x52, 0x0e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x57, 0x65, 0x62, 0x54, 0x6f, 0x6b, 0x65, - 0x6e, 0x22, 0x4d, 0x0a, 0x1e, 0x54, 0x50, 0x4d, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, - 0x63, 0x61, 0x74, 0x65, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x43, 0x68, 0x61, 0x6c, 0x6c, 0x65, - 0x6e, 0x67, 0x65, 0x12, 0x2b, 0x0a, 0x11, 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x5f, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x10, - 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4e, 0x6f, 0x6e, 0x63, 0x65, - 0x22, 0x89, 0x01, 0x0a, 0x26, 0x54, 0x50, 0x4d, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, - 0x63, 0x61, 0x74, 0x65, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x43, 0x68, 0x61, 0x6c, 0x6c, 0x65, - 0x6e, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5f, 0x0a, 0x13, 0x70, - 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, - 0x72, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, + 0x76, 0x31, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x12, 0x5d, 0x0a, 0x0c, 0x55, 0x70, 0x64, + 0x61, 0x74, 0x65, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x12, 0x2c, 0x2e, 0x74, 0x65, 0x6c, 0x65, + 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, + 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, + 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, + 0x31, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x12, 0x5d, 0x0a, 0x0c, 0x55, 0x70, 0x73, 0x65, + 0x72, 0x74, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x12, 0x2c, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, - 0x76, 0x31, 0x2e, 0x54, 0x50, 0x4d, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x50, 0x61, - 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x52, 0x12, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, - 0x72, 0x6d, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x22, 0x3b, 0x0a, 0x1b, - 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x44, 0x65, 0x76, 0x69, - 0x63, 0x65, 0x43, 0x68, 0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x67, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x63, - 0x68, 0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, - 0x63, 0x68, 0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x67, 0x65, 0x22, 0x43, 0x0a, 0x23, 0x41, 0x75, 0x74, - 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x43, - 0x68, 0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x22, 0xbd, - 0x01, 0x0a, 0x25, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, - 0x57, 0x65, 0x62, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x5f, 0x0a, 0x12, 0x63, 0x6f, 0x6e, 0x66, - 0x69, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, - 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x44, - 0x65, 0x76, 0x69, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x11, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x33, 0x0a, 0x16, 0x63, 0x75, 0x72, - 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x77, 0x65, 0x62, 0x5f, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, - 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x13, 0x63, 0x75, 0x72, 0x72, 0x65, - 0x6e, 0x74, 0x57, 0x65, 0x62, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x22, 0x28, - 0x0a, 0x26, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x57, - 0x65, 0x62, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xdf, 0x02, 0x0a, 0x14, 0x53, 0x79, 0x6e, - 0x63, 0x49, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x12, 0x43, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x2b, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, - 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x49, - 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x53, 0x74, 0x61, 0x72, 0x74, 0x48, 0x00, 0x52, - 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, 0x12, 0x3d, 0x0a, 0x03, 0x65, 0x6e, 0x64, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, - 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x79, - 0x6e, 0x63, 0x49, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x45, 0x6e, 0x64, 0x48, 0x00, - 0x52, 0x03, 0x65, 0x6e, 0x64, 0x12, 0x5b, 0x0a, 0x11, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, - 0x5f, 0x74, 0x6f, 0x5f, 0x75, 0x70, 0x73, 0x65, 0x72, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x2d, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, - 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x49, - 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x48, - 0x00, 0x52, 0x0f, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x54, 0x6f, 0x55, 0x70, 0x73, 0x65, - 0x72, 0x74, 0x12, 0x5b, 0x0a, 0x11, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x5f, 0x74, 0x6f, - 0x5f, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2d, 0x2e, - 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, - 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x49, 0x6e, 0x76, 0x65, - 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x48, 0x00, 0x52, 0x0f, - 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x54, 0x6f, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x42, - 0x09, 0x0a, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x22, 0x8a, 0x02, 0x0a, 0x15, 0x53, - 0x79, 0x6e, 0x63, 0x49, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3d, 0x0a, 0x03, 0x61, 0x63, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x29, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, - 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x79, 0x6e, 0x63, - 0x49, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x41, 0x63, 0x6b, 0x48, 0x00, 0x52, 0x03, - 0x61, 0x63, 0x6b, 0x12, 0x46, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, - 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x79, - 0x6e, 0x63, 0x49, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x73, 0x75, 0x6c, - 0x74, 0x48, 0x00, 0x52, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x5f, 0x0a, 0x0f, 0x6d, - 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x5f, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x34, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, - 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x53, - 0x79, 0x6e, 0x63, 0x49, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x4d, 0x69, 0x73, 0x73, - 0x69, 0x6e, 0x67, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x48, 0x00, 0x52, 0x0e, 0x6d, 0x69, - 0x73, 0x73, 0x69, 0x6e, 0x67, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x42, 0x09, 0x0a, 0x07, - 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x22, 0xac, 0x01, 0x0a, 0x12, 0x53, 0x79, 0x6e, 0x63, - 0x49, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x53, 0x74, 0x61, 0x72, 0x74, 0x12, 0x3d, - 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, - 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, - 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x53, - 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x32, 0x0a, - 0x15, 0x74, 0x72, 0x61, 0x63, 0x6b, 0x5f, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x5f, 0x64, - 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x13, 0x74, 0x72, - 0x61, 0x63, 0x6b, 0x4d, 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, - 0x73, 0x4a, 0x04, 0x08, 0x02, 0x10, 0x03, 0x4a, 0x04, 0x08, 0x03, 0x10, 0x04, 0x52, 0x04, 0x6d, - 0x6f, 0x64, 0x65, 0x52, 0x11, 0x6f, 0x6e, 0x5f, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x5f, - 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x32, 0x0a, 0x10, 0x53, 0x79, 0x6e, 0x63, 0x49, 0x6e, - 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x45, 0x6e, 0x64, 0x4a, 0x04, 0x08, 0x01, 0x10, 0x02, - 0x52, 0x18, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x5f, 0x73, 0x79, 0x6e, 0x63, 0x5f, - 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x66, 0x75, 0x6c, 0x22, 0x51, 0x0a, 0x14, 0x53, 0x79, - 0x6e, 0x63, 0x49, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x44, 0x65, 0x76, 0x69, 0x63, - 0x65, 0x73, 0x12, 0x39, 0x0a, 0x07, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x18, 0x01, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, - 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, - 0x76, 0x69, 0x63, 0x65, 0x52, 0x07, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x22, 0x12, 0x0a, - 0x10, 0x53, 0x79, 0x6e, 0x63, 0x49, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x41, 0x63, - 0x6b, 0x22, 0x58, 0x0a, 0x13, 0x53, 0x79, 0x6e, 0x63, 0x49, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, - 0x72, 0x79, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x41, 0x0a, 0x07, 0x64, 0x65, 0x76, 0x69, - 0x63, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x74, 0x65, 0x6c, 0x65, + 0x76, 0x31, 0x2e, 0x55, 0x70, 0x73, 0x65, 0x72, 0x74, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, + 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, + 0x2e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x12, 0x54, 0x0a, 0x0c, 0x44, 0x65, 0x6c, 0x65, 0x74, + 0x65, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x12, 0x2c, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, + 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, + 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x68, 0x0a, + 0x0b, 0x46, 0x69, 0x6e, 0x64, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x12, 0x2b, 0x2e, 0x74, + 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, + 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x44, 0x65, 0x76, 0x69, 0x63, + 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, - 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x4f, 0x72, 0x53, 0x74, 0x61, 0x74, - 0x75, 0x73, 0x52, 0x07, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x22, 0x58, 0x0a, 0x1b, 0x53, - 0x79, 0x6e, 0x63, 0x49, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x4d, 0x69, 0x73, 0x73, - 0x69, 0x6e, 0x67, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x12, 0x39, 0x0a, 0x07, 0x64, 0x65, - 0x76, 0x69, 0x63, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x74, 0x65, - 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, - 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, 0x07, 0x64, 0x65, - 0x76, 0x69, 0x63, 0x65, 0x73, 0x22, 0x18, 0x0a, 0x16, 0x47, 0x65, 0x74, 0x44, 0x65, 0x76, 0x69, - 0x63, 0x65, 0x73, 0x55, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2a, - 0x59, 0x0a, 0x0a, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x56, 0x69, 0x65, 0x77, 0x12, 0x1b, 0x0a, - 0x17, 0x44, 0x45, 0x56, 0x49, 0x43, 0x45, 0x5f, 0x56, 0x49, 0x45, 0x57, 0x5f, 0x55, 0x4e, 0x53, - 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x14, 0x0a, 0x10, 0x44, 0x45, - 0x56, 0x49, 0x43, 0x45, 0x5f, 0x56, 0x49, 0x45, 0x57, 0x5f, 0x4c, 0x49, 0x53, 0x54, 0x10, 0x01, - 0x12, 0x18, 0x0a, 0x14, 0x44, 0x45, 0x56, 0x49, 0x43, 0x45, 0x5f, 0x56, 0x49, 0x45, 0x57, 0x5f, - 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x10, 0x02, 0x32, 0xad, 0x0c, 0x0a, 0x12, 0x44, - 0x65, 0x76, 0x69, 0x63, 0x65, 0x54, 0x72, 0x75, 0x73, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, - 0x65, 0x12, 0x5d, 0x0a, 0x0c, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x44, 0x65, 0x76, 0x69, 0x63, - 0x65, 0x12, 0x2c, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, - 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, - 0x74, 0x65, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x2e, 0x76, 0x31, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x57, 0x0a, 0x09, 0x47, 0x65, 0x74, 0x44, 0x65, + 0x76, 0x69, 0x63, 0x65, 0x12, 0x29, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, + 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x47, + 0x65, 0x74, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, - 0x12, 0x5d, 0x0a, 0x0c, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, - 0x12, 0x2c, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, - 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, - 0x65, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, + 0x12, 0x68, 0x0a, 0x0b, 0x4c, 0x69, 0x73, 0x74, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x12, + 0x2b, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, + 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x44, 0x65, + 0x76, 0x69, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x74, + 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, + 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x44, 0x65, 0x76, 0x69, 0x63, + 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x7a, 0x0a, 0x11, 0x42, 0x75, + 0x6c, 0x6b, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x12, + 0x31, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, + 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x75, 0x6c, 0x6b, 0x43, 0x72, + 0x65, 0x61, 0x74, 0x65, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x32, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, + 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x75, 0x6c, + 0x6b, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x7e, 0x0a, 0x17, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, + 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x54, 0x6f, 0x6b, 0x65, + 0x6e, 0x12, 0x37, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, + 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, + 0x74, 0x65, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x54, 0x6f, + 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2a, 0x2e, 0x74, 0x65, 0x6c, + 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, + 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x45, 0x6e, 0x72, 0x6f, 0x6c, + 0x6c, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x6f, 0x0a, 0x0c, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, + 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x12, 0x2c, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, + 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, + 0x2e, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2d, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, + 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x45, + 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x28, 0x01, 0x30, 0x01, 0x12, 0x81, 0x01, 0x0a, 0x12, 0x41, 0x75, 0x74, 0x68, + 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x12, 0x32, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, - 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x12, - 0x5d, 0x0a, 0x0c, 0x55, 0x70, 0x73, 0x65, 0x72, 0x74, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x12, - 0x2c, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, - 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x73, 0x65, 0x72, 0x74, - 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, - 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, - 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x12, 0x54, - 0x0a, 0x0c, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x12, 0x2c, + 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, + 0x69, 0x63, 0x61, 0x74, 0x65, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x33, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, + 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x75, 0x74, + 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x28, 0x01, 0x30, 0x01, 0x12, 0xa1, 0x01, 0x0a, 0x1e, + 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x57, 0x65, 0x62, + 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x3e, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, - 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x44, - 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, - 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, - 0x6d, 0x70, 0x74, 0x79, 0x12, 0x68, 0x0a, 0x0b, 0x46, 0x69, 0x6e, 0x64, 0x44, 0x65, 0x76, 0x69, - 0x63, 0x65, 0x73, 0x12, 0x2b, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, - 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x46, 0x69, - 0x6e, 0x64, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x2c, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, - 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x44, - 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x57, - 0x0a, 0x09, 0x47, 0x65, 0x74, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x12, 0x29, 0x2e, 0x74, 0x65, - 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, - 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, - 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, - 0x2e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x12, 0x68, 0x0a, 0x0b, 0x4c, 0x69, 0x73, 0x74, 0x44, - 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x12, 0x2b, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, - 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, - 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, - 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, - 0x73, 0x74, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x7a, 0x0a, 0x11, 0x42, 0x75, 0x6c, 0x6b, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x44, - 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x12, 0x31, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, + 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, + 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x57, 0x65, 0x62, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, + 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x3f, + 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, + 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, + 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x57, 0x65, 0x62, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, + 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x72, 0x0a, 0x0d, 0x53, 0x79, 0x6e, 0x63, 0x49, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, + 0x12, 0x2d, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, + 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x49, + 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x2e, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, + 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x49, 0x6e, + 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x28, + 0x01, 0x30, 0x01, 0x12, 0x6e, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, + 0x73, 0x55, 0x73, 0x61, 0x67, 0x65, 0x12, 0x2f, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, - 0x2e, 0x42, 0x75, 0x6c, 0x6b, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x44, 0x65, 0x76, 0x69, 0x63, - 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x32, 0x2e, 0x74, 0x65, 0x6c, 0x65, - 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, - 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x75, 0x6c, 0x6b, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x44, 0x65, - 0x76, 0x69, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x7e, 0x0a, - 0x17, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x45, 0x6e, 0x72, - 0x6f, 0x6c, 0x6c, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x37, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, - 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, - 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x45, - 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x2a, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, - 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x76, 0x69, - 0x63, 0x65, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x6f, 0x0a, - 0x0c, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x12, 0x2c, 0x2e, - 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, - 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x44, 0x65, - 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2d, 0x2e, 0x74, 0x65, - 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, - 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x44, 0x65, 0x76, 0x69, - 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x28, 0x01, 0x30, 0x01, 0x12, 0x81, - 0x01, 0x0a, 0x12, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x44, - 0x65, 0x76, 0x69, 0x63, 0x65, 0x12, 0x32, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, - 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, - 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x44, 0x65, 0x76, 0x69, - 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x33, 0x2e, 0x74, 0x65, 0x6c, 0x65, - 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, - 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, - 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x28, 0x01, - 0x30, 0x01, 0x12, 0xa1, 0x01, 0x0a, 0x1e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x44, 0x65, - 0x76, 0x69, 0x63, 0x65, 0x57, 0x65, 0x62, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x3e, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, - 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, - 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x57, 0x65, 0x62, - 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x3f, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, - 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, - 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x57, 0x65, 0x62, - 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x72, 0x0a, 0x0d, 0x53, 0x79, 0x6e, 0x63, 0x49, 0x6e, - 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x2d, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, + 0x2e, 0x47, 0x65, 0x74, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x55, 0x73, 0x61, 0x67, 0x65, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, - 0x31, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x49, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, - 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, - 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x49, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x28, 0x01, 0x30, 0x01, 0x12, 0x6e, 0x0a, 0x0f, 0x47, 0x65, - 0x74, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x55, 0x73, 0x61, 0x67, 0x65, 0x12, 0x2f, 0x2e, - 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, - 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x44, 0x65, 0x76, 0x69, 0x63, - 0x65, 0x73, 0x55, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, - 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, - 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, - 0x55, 0x73, 0x61, 0x67, 0x65, 0x22, 0x03, 0x88, 0x02, 0x01, 0x42, 0x5a, 0x5a, 0x58, 0x67, 0x69, - 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x72, 0x61, 0x76, 0x69, 0x74, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x2f, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, - 0x61, 0x70, 0x69, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, - 0x2f, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, - 0x74, 0x72, 0x75, 0x73, 0x74, 0x2f, 0x76, 0x31, 0x3b, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, - 0x72, 0x75, 0x73, 0x74, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x31, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x55, 0x73, 0x61, 0x67, 0x65, 0x22, 0x03, + 0x88, 0x02, 0x01, 0x42, 0x5a, 0x5a, 0x58, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, + 0x6d, 0x2f, 0x67, 0x72, 0x61, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x2f, + 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x67, 0x65, 0x6e, + 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x2f, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, + 0x72, 0x74, 0x2f, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2f, 0x76, + 0x31, 0x3b, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x76, 0x31, 0x62, + 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -3461,7 +3242,7 @@ func file_teleport_devicetrust_v1_devicetrust_service_proto_rawDescGZIP() []byte } var file_teleport_devicetrust_v1_devicetrust_service_proto_enumTypes = make([]protoimpl.EnumInfo, 1) -var file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes = make([]protoimpl.MessageInfo, 43) +var file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes = make([]protoimpl.MessageInfo, 39) var file_teleport_devicetrust_v1_devicetrust_service_proto_goTypes = []interface{}{ (DeviceView)(0), // 0: teleport.devicetrust.v1.DeviceView (*CreateDeviceRequest)(nil), // 1: teleport.devicetrust.v1.CreateDeviceRequest @@ -3492,28 +3273,28 @@ var file_teleport_devicetrust_v1_devicetrust_service_proto_goTypes = []interface (*AuthenticateDeviceRequest)(nil), // 26: teleport.devicetrust.v1.AuthenticateDeviceRequest (*AuthenticateDeviceResponse)(nil), // 27: teleport.devicetrust.v1.AuthenticateDeviceResponse (*AuthenticateDeviceInit)(nil), // 28: teleport.devicetrust.v1.AuthenticateDeviceInit - (*TPMAuthenticateDeviceChallenge)(nil), // 29: teleport.devicetrust.v1.TPMAuthenticateDeviceChallenge - (*TPMAuthenticateDeviceChallengeResponse)(nil), // 30: teleport.devicetrust.v1.TPMAuthenticateDeviceChallengeResponse - (*AuthenticateDeviceChallenge)(nil), // 31: teleport.devicetrust.v1.AuthenticateDeviceChallenge - (*AuthenticateDeviceChallengeResponse)(nil), // 32: teleport.devicetrust.v1.AuthenticateDeviceChallengeResponse - (*ConfirmDeviceWebAuthenticationRequest)(nil), // 33: teleport.devicetrust.v1.ConfirmDeviceWebAuthenticationRequest - (*ConfirmDeviceWebAuthenticationResponse)(nil), // 34: teleport.devicetrust.v1.ConfirmDeviceWebAuthenticationResponse - (*SyncInventoryRequest)(nil), // 35: teleport.devicetrust.v1.SyncInventoryRequest - (*SyncInventoryResponse)(nil), // 36: teleport.devicetrust.v1.SyncInventoryResponse - (*SyncInventoryStart)(nil), // 37: teleport.devicetrust.v1.SyncInventoryStart - (*SyncInventoryEnd)(nil), // 38: teleport.devicetrust.v1.SyncInventoryEnd - (*SyncInventoryDevices)(nil), // 39: teleport.devicetrust.v1.SyncInventoryDevices - (*SyncInventoryAck)(nil), // 40: teleport.devicetrust.v1.SyncInventoryAck - (*SyncInventoryResult)(nil), // 41: teleport.devicetrust.v1.SyncInventoryResult - (*SyncInventoryMissingDevices)(nil), // 42: teleport.devicetrust.v1.SyncInventoryMissingDevices - (*GetDevicesUsageRequest)(nil), // 43: teleport.devicetrust.v1.GetDevicesUsageRequest - (*Device)(nil), // 44: teleport.devicetrust.v1.Device - (*timestamppb.Timestamp)(nil), // 45: google.protobuf.Timestamp - (*fieldmaskpb.FieldMask)(nil), // 46: google.protobuf.FieldMask - (*status.Status)(nil), // 47: google.rpc.Status - (*DeviceCollectedData)(nil), // 48: teleport.devicetrust.v1.DeviceCollectedData - (*TPMPlatformParameters)(nil), // 49: teleport.devicetrust.v1.TPMPlatformParameters - (*UserCertificates)(nil), // 50: teleport.devicetrust.v1.UserCertificates + (*ConfirmDeviceWebAuthenticationRequest)(nil), // 29: teleport.devicetrust.v1.ConfirmDeviceWebAuthenticationRequest + (*ConfirmDeviceWebAuthenticationResponse)(nil), // 30: teleport.devicetrust.v1.ConfirmDeviceWebAuthenticationResponse + (*SyncInventoryRequest)(nil), // 31: teleport.devicetrust.v1.SyncInventoryRequest + (*SyncInventoryResponse)(nil), // 32: teleport.devicetrust.v1.SyncInventoryResponse + (*SyncInventoryStart)(nil), // 33: teleport.devicetrust.v1.SyncInventoryStart + (*SyncInventoryEnd)(nil), // 34: teleport.devicetrust.v1.SyncInventoryEnd + (*SyncInventoryDevices)(nil), // 35: teleport.devicetrust.v1.SyncInventoryDevices + (*SyncInventoryAck)(nil), // 36: teleport.devicetrust.v1.SyncInventoryAck + (*SyncInventoryResult)(nil), // 37: teleport.devicetrust.v1.SyncInventoryResult + (*SyncInventoryMissingDevices)(nil), // 38: teleport.devicetrust.v1.SyncInventoryMissingDevices + (*GetDevicesUsageRequest)(nil), // 39: teleport.devicetrust.v1.GetDevicesUsageRequest + (*Device)(nil), // 40: teleport.devicetrust.v1.Device + (*timestamppb.Timestamp)(nil), // 41: google.protobuf.Timestamp + (*fieldmaskpb.FieldMask)(nil), // 42: google.protobuf.FieldMask + (*status.Status)(nil), // 43: google.rpc.Status + (*DeviceCollectedData)(nil), // 44: teleport.devicetrust.v1.DeviceCollectedData + (*TPMPlatformParameters)(nil), // 45: teleport.devicetrust.v1.TPMPlatformParameters + (*AuthenticateDeviceChallengeResponse)(nil), // 46: teleport.devicetrust.v1.AuthenticateDeviceChallengeResponse + (*TPMAuthenticateDeviceChallengeResponse)(nil), // 47: teleport.devicetrust.v1.TPMAuthenticateDeviceChallengeResponse + (*AuthenticateDeviceChallenge)(nil), // 48: teleport.devicetrust.v1.AuthenticateDeviceChallenge + (*UserCertificates)(nil), // 49: teleport.devicetrust.v1.UserCertificates + (*TPMAuthenticateDeviceChallenge)(nil), // 50: teleport.devicetrust.v1.TPMAuthenticateDeviceChallenge (*DeviceConfirmationToken)(nil), // 51: teleport.devicetrust.v1.DeviceConfirmationToken (*DeviceWebToken)(nil), // 52: teleport.devicetrust.v1.DeviceWebToken (*DeviceSource)(nil), // 53: teleport.devicetrust.v1.DeviceSource @@ -3522,88 +3303,87 @@ var file_teleport_devicetrust_v1_devicetrust_service_proto_goTypes = []interface (*DevicesUsage)(nil), // 56: teleport.devicetrust.v1.DevicesUsage } var file_teleport_devicetrust_v1_devicetrust_service_proto_depIdxs = []int32{ - 44, // 0: teleport.devicetrust.v1.CreateDeviceRequest.device:type_name -> teleport.devicetrust.v1.Device - 45, // 1: teleport.devicetrust.v1.CreateDeviceRequest.enroll_token_expire_time:type_name -> google.protobuf.Timestamp - 44, // 2: teleport.devicetrust.v1.UpdateDeviceRequest.device:type_name -> teleport.devicetrust.v1.Device - 46, // 3: teleport.devicetrust.v1.UpdateDeviceRequest.update_mask:type_name -> google.protobuf.FieldMask - 44, // 4: teleport.devicetrust.v1.UpsertDeviceRequest.device:type_name -> teleport.devicetrust.v1.Device - 44, // 5: teleport.devicetrust.v1.FindDevicesResponse.devices:type_name -> teleport.devicetrust.v1.Device + 40, // 0: teleport.devicetrust.v1.CreateDeviceRequest.device:type_name -> teleport.devicetrust.v1.Device + 41, // 1: teleport.devicetrust.v1.CreateDeviceRequest.enroll_token_expire_time:type_name -> google.protobuf.Timestamp + 40, // 2: teleport.devicetrust.v1.UpdateDeviceRequest.device:type_name -> teleport.devicetrust.v1.Device + 42, // 3: teleport.devicetrust.v1.UpdateDeviceRequest.update_mask:type_name -> google.protobuf.FieldMask + 40, // 4: teleport.devicetrust.v1.UpsertDeviceRequest.device:type_name -> teleport.devicetrust.v1.Device + 40, // 5: teleport.devicetrust.v1.FindDevicesResponse.devices:type_name -> teleport.devicetrust.v1.Device 0, // 6: teleport.devicetrust.v1.ListDevicesRequest.view:type_name -> teleport.devicetrust.v1.DeviceView - 44, // 7: teleport.devicetrust.v1.ListDevicesResponse.devices:type_name -> teleport.devicetrust.v1.Device - 44, // 8: teleport.devicetrust.v1.BulkCreateDevicesRequest.devices:type_name -> teleport.devicetrust.v1.Device + 40, // 7: teleport.devicetrust.v1.ListDevicesResponse.devices:type_name -> teleport.devicetrust.v1.Device + 40, // 8: teleport.devicetrust.v1.BulkCreateDevicesRequest.devices:type_name -> teleport.devicetrust.v1.Device 12, // 9: teleport.devicetrust.v1.BulkCreateDevicesResponse.devices:type_name -> teleport.devicetrust.v1.DeviceOrStatus - 47, // 10: teleport.devicetrust.v1.DeviceOrStatus.status:type_name -> google.rpc.Status - 48, // 11: teleport.devicetrust.v1.CreateDeviceEnrollTokenRequest.device_data:type_name -> teleport.devicetrust.v1.DeviceCollectedData - 45, // 12: teleport.devicetrust.v1.CreateDeviceEnrollTokenRequest.expire_time:type_name -> google.protobuf.Timestamp + 43, // 10: teleport.devicetrust.v1.DeviceOrStatus.status:type_name -> google.rpc.Status + 44, // 11: teleport.devicetrust.v1.CreateDeviceEnrollTokenRequest.device_data:type_name -> teleport.devicetrust.v1.DeviceCollectedData + 41, // 12: teleport.devicetrust.v1.CreateDeviceEnrollTokenRequest.expire_time:type_name -> google.protobuf.Timestamp 16, // 13: teleport.devicetrust.v1.EnrollDeviceRequest.init:type_name -> teleport.devicetrust.v1.EnrollDeviceInit 20, // 14: teleport.devicetrust.v1.EnrollDeviceRequest.macos_challenge_response:type_name -> teleport.devicetrust.v1.MacOSEnrollChallengeResponse 25, // 15: teleport.devicetrust.v1.EnrollDeviceRequest.tpm_challenge_response:type_name -> teleport.devicetrust.v1.TPMEnrollChallengeResponse 17, // 16: teleport.devicetrust.v1.EnrollDeviceResponse.success:type_name -> teleport.devicetrust.v1.EnrollDeviceSuccess 19, // 17: teleport.devicetrust.v1.EnrollDeviceResponse.macos_challenge:type_name -> teleport.devicetrust.v1.MacOSEnrollChallenge 23, // 18: teleport.devicetrust.v1.EnrollDeviceResponse.tpm_challenge:type_name -> teleport.devicetrust.v1.TPMEnrollChallenge - 48, // 19: teleport.devicetrust.v1.EnrollDeviceInit.device_data:type_name -> teleport.devicetrust.v1.DeviceCollectedData + 44, // 19: teleport.devicetrust.v1.EnrollDeviceInit.device_data:type_name -> teleport.devicetrust.v1.DeviceCollectedData 18, // 20: teleport.devicetrust.v1.EnrollDeviceInit.macos:type_name -> teleport.devicetrust.v1.MacOSEnrollPayload 21, // 21: teleport.devicetrust.v1.EnrollDeviceInit.tpm:type_name -> teleport.devicetrust.v1.TPMEnrollPayload - 44, // 22: teleport.devicetrust.v1.EnrollDeviceSuccess.device:type_name -> teleport.devicetrust.v1.Device + 40, // 22: teleport.devicetrust.v1.EnrollDeviceSuccess.device:type_name -> teleport.devicetrust.v1.Device 22, // 23: teleport.devicetrust.v1.TPMEnrollPayload.attestation_parameters:type_name -> teleport.devicetrust.v1.TPMAttestationParameters 24, // 24: teleport.devicetrust.v1.TPMEnrollChallenge.encrypted_credential:type_name -> teleport.devicetrust.v1.TPMEncryptedCredential - 49, // 25: teleport.devicetrust.v1.TPMEnrollChallengeResponse.platform_parameters:type_name -> teleport.devicetrust.v1.TPMPlatformParameters + 45, // 25: teleport.devicetrust.v1.TPMEnrollChallengeResponse.platform_parameters:type_name -> teleport.devicetrust.v1.TPMPlatformParameters 28, // 26: teleport.devicetrust.v1.AuthenticateDeviceRequest.init:type_name -> teleport.devicetrust.v1.AuthenticateDeviceInit - 32, // 27: teleport.devicetrust.v1.AuthenticateDeviceRequest.challenge_response:type_name -> teleport.devicetrust.v1.AuthenticateDeviceChallengeResponse - 30, // 28: teleport.devicetrust.v1.AuthenticateDeviceRequest.tpm_challenge_response:type_name -> teleport.devicetrust.v1.TPMAuthenticateDeviceChallengeResponse - 31, // 29: teleport.devicetrust.v1.AuthenticateDeviceResponse.challenge:type_name -> teleport.devicetrust.v1.AuthenticateDeviceChallenge - 50, // 30: teleport.devicetrust.v1.AuthenticateDeviceResponse.user_certificates:type_name -> teleport.devicetrust.v1.UserCertificates - 29, // 31: teleport.devicetrust.v1.AuthenticateDeviceResponse.tpm_challenge:type_name -> teleport.devicetrust.v1.TPMAuthenticateDeviceChallenge + 46, // 27: teleport.devicetrust.v1.AuthenticateDeviceRequest.challenge_response:type_name -> teleport.devicetrust.v1.AuthenticateDeviceChallengeResponse + 47, // 28: teleport.devicetrust.v1.AuthenticateDeviceRequest.tpm_challenge_response:type_name -> teleport.devicetrust.v1.TPMAuthenticateDeviceChallengeResponse + 48, // 29: teleport.devicetrust.v1.AuthenticateDeviceResponse.challenge:type_name -> teleport.devicetrust.v1.AuthenticateDeviceChallenge + 49, // 30: teleport.devicetrust.v1.AuthenticateDeviceResponse.user_certificates:type_name -> teleport.devicetrust.v1.UserCertificates + 50, // 31: teleport.devicetrust.v1.AuthenticateDeviceResponse.tpm_challenge:type_name -> teleport.devicetrust.v1.TPMAuthenticateDeviceChallenge 51, // 32: teleport.devicetrust.v1.AuthenticateDeviceResponse.confirmation_token:type_name -> teleport.devicetrust.v1.DeviceConfirmationToken - 50, // 33: teleport.devicetrust.v1.AuthenticateDeviceInit.user_certificates:type_name -> teleport.devicetrust.v1.UserCertificates - 48, // 34: teleport.devicetrust.v1.AuthenticateDeviceInit.device_data:type_name -> teleport.devicetrust.v1.DeviceCollectedData + 49, // 33: teleport.devicetrust.v1.AuthenticateDeviceInit.user_certificates:type_name -> teleport.devicetrust.v1.UserCertificates + 44, // 34: teleport.devicetrust.v1.AuthenticateDeviceInit.device_data:type_name -> teleport.devicetrust.v1.DeviceCollectedData 52, // 35: teleport.devicetrust.v1.AuthenticateDeviceInit.device_web_token:type_name -> teleport.devicetrust.v1.DeviceWebToken - 49, // 36: teleport.devicetrust.v1.TPMAuthenticateDeviceChallengeResponse.platform_parameters:type_name -> teleport.devicetrust.v1.TPMPlatformParameters - 51, // 37: teleport.devicetrust.v1.ConfirmDeviceWebAuthenticationRequest.confirmation_token:type_name -> teleport.devicetrust.v1.DeviceConfirmationToken - 37, // 38: teleport.devicetrust.v1.SyncInventoryRequest.start:type_name -> teleport.devicetrust.v1.SyncInventoryStart - 38, // 39: teleport.devicetrust.v1.SyncInventoryRequest.end:type_name -> teleport.devicetrust.v1.SyncInventoryEnd - 39, // 40: teleport.devicetrust.v1.SyncInventoryRequest.devices_to_upsert:type_name -> teleport.devicetrust.v1.SyncInventoryDevices - 39, // 41: teleport.devicetrust.v1.SyncInventoryRequest.devices_to_remove:type_name -> teleport.devicetrust.v1.SyncInventoryDevices - 40, // 42: teleport.devicetrust.v1.SyncInventoryResponse.ack:type_name -> teleport.devicetrust.v1.SyncInventoryAck - 41, // 43: teleport.devicetrust.v1.SyncInventoryResponse.result:type_name -> teleport.devicetrust.v1.SyncInventoryResult - 42, // 44: teleport.devicetrust.v1.SyncInventoryResponse.missing_devices:type_name -> teleport.devicetrust.v1.SyncInventoryMissingDevices - 53, // 45: teleport.devicetrust.v1.SyncInventoryStart.source:type_name -> teleport.devicetrust.v1.DeviceSource - 44, // 46: teleport.devicetrust.v1.SyncInventoryDevices.devices:type_name -> teleport.devicetrust.v1.Device - 12, // 47: teleport.devicetrust.v1.SyncInventoryResult.devices:type_name -> teleport.devicetrust.v1.DeviceOrStatus - 44, // 48: teleport.devicetrust.v1.SyncInventoryMissingDevices.devices:type_name -> teleport.devicetrust.v1.Device - 1, // 49: teleport.devicetrust.v1.DeviceTrustService.CreateDevice:input_type -> teleport.devicetrust.v1.CreateDeviceRequest - 2, // 50: teleport.devicetrust.v1.DeviceTrustService.UpdateDevice:input_type -> teleport.devicetrust.v1.UpdateDeviceRequest - 3, // 51: teleport.devicetrust.v1.DeviceTrustService.UpsertDevice:input_type -> teleport.devicetrust.v1.UpsertDeviceRequest - 4, // 52: teleport.devicetrust.v1.DeviceTrustService.DeleteDevice:input_type -> teleport.devicetrust.v1.DeleteDeviceRequest - 5, // 53: teleport.devicetrust.v1.DeviceTrustService.FindDevices:input_type -> teleport.devicetrust.v1.FindDevicesRequest - 7, // 54: teleport.devicetrust.v1.DeviceTrustService.GetDevice:input_type -> teleport.devicetrust.v1.GetDeviceRequest - 8, // 55: teleport.devicetrust.v1.DeviceTrustService.ListDevices:input_type -> teleport.devicetrust.v1.ListDevicesRequest - 10, // 56: teleport.devicetrust.v1.DeviceTrustService.BulkCreateDevices:input_type -> teleport.devicetrust.v1.BulkCreateDevicesRequest - 13, // 57: teleport.devicetrust.v1.DeviceTrustService.CreateDeviceEnrollToken:input_type -> teleport.devicetrust.v1.CreateDeviceEnrollTokenRequest - 14, // 58: teleport.devicetrust.v1.DeviceTrustService.EnrollDevice:input_type -> teleport.devicetrust.v1.EnrollDeviceRequest - 26, // 59: teleport.devicetrust.v1.DeviceTrustService.AuthenticateDevice:input_type -> teleport.devicetrust.v1.AuthenticateDeviceRequest - 33, // 60: teleport.devicetrust.v1.DeviceTrustService.ConfirmDeviceWebAuthentication:input_type -> teleport.devicetrust.v1.ConfirmDeviceWebAuthenticationRequest - 35, // 61: teleport.devicetrust.v1.DeviceTrustService.SyncInventory:input_type -> teleport.devicetrust.v1.SyncInventoryRequest - 43, // 62: teleport.devicetrust.v1.DeviceTrustService.GetDevicesUsage:input_type -> teleport.devicetrust.v1.GetDevicesUsageRequest - 44, // 63: teleport.devicetrust.v1.DeviceTrustService.CreateDevice:output_type -> teleport.devicetrust.v1.Device - 44, // 64: teleport.devicetrust.v1.DeviceTrustService.UpdateDevice:output_type -> teleport.devicetrust.v1.Device - 44, // 65: teleport.devicetrust.v1.DeviceTrustService.UpsertDevice:output_type -> teleport.devicetrust.v1.Device - 54, // 66: teleport.devicetrust.v1.DeviceTrustService.DeleteDevice:output_type -> google.protobuf.Empty - 6, // 67: teleport.devicetrust.v1.DeviceTrustService.FindDevices:output_type -> teleport.devicetrust.v1.FindDevicesResponse - 44, // 68: teleport.devicetrust.v1.DeviceTrustService.GetDevice:output_type -> teleport.devicetrust.v1.Device - 9, // 69: teleport.devicetrust.v1.DeviceTrustService.ListDevices:output_type -> teleport.devicetrust.v1.ListDevicesResponse - 11, // 70: teleport.devicetrust.v1.DeviceTrustService.BulkCreateDevices:output_type -> teleport.devicetrust.v1.BulkCreateDevicesResponse - 55, // 71: teleport.devicetrust.v1.DeviceTrustService.CreateDeviceEnrollToken:output_type -> teleport.devicetrust.v1.DeviceEnrollToken - 15, // 72: teleport.devicetrust.v1.DeviceTrustService.EnrollDevice:output_type -> teleport.devicetrust.v1.EnrollDeviceResponse - 27, // 73: teleport.devicetrust.v1.DeviceTrustService.AuthenticateDevice:output_type -> teleport.devicetrust.v1.AuthenticateDeviceResponse - 34, // 74: teleport.devicetrust.v1.DeviceTrustService.ConfirmDeviceWebAuthentication:output_type -> teleport.devicetrust.v1.ConfirmDeviceWebAuthenticationResponse - 36, // 75: teleport.devicetrust.v1.DeviceTrustService.SyncInventory:output_type -> teleport.devicetrust.v1.SyncInventoryResponse - 56, // 76: teleport.devicetrust.v1.DeviceTrustService.GetDevicesUsage:output_type -> teleport.devicetrust.v1.DevicesUsage - 63, // [63:77] is the sub-list for method output_type - 49, // [49:63] is the sub-list for method input_type - 49, // [49:49] is the sub-list for extension type_name - 49, // [49:49] is the sub-list for extension extendee - 0, // [0:49] is the sub-list for field type_name + 51, // 36: teleport.devicetrust.v1.ConfirmDeviceWebAuthenticationRequest.confirmation_token:type_name -> teleport.devicetrust.v1.DeviceConfirmationToken + 33, // 37: teleport.devicetrust.v1.SyncInventoryRequest.start:type_name -> teleport.devicetrust.v1.SyncInventoryStart + 34, // 38: teleport.devicetrust.v1.SyncInventoryRequest.end:type_name -> teleport.devicetrust.v1.SyncInventoryEnd + 35, // 39: teleport.devicetrust.v1.SyncInventoryRequest.devices_to_upsert:type_name -> teleport.devicetrust.v1.SyncInventoryDevices + 35, // 40: teleport.devicetrust.v1.SyncInventoryRequest.devices_to_remove:type_name -> teleport.devicetrust.v1.SyncInventoryDevices + 36, // 41: teleport.devicetrust.v1.SyncInventoryResponse.ack:type_name -> teleport.devicetrust.v1.SyncInventoryAck + 37, // 42: teleport.devicetrust.v1.SyncInventoryResponse.result:type_name -> teleport.devicetrust.v1.SyncInventoryResult + 38, // 43: teleport.devicetrust.v1.SyncInventoryResponse.missing_devices:type_name -> teleport.devicetrust.v1.SyncInventoryMissingDevices + 53, // 44: teleport.devicetrust.v1.SyncInventoryStart.source:type_name -> teleport.devicetrust.v1.DeviceSource + 40, // 45: teleport.devicetrust.v1.SyncInventoryDevices.devices:type_name -> teleport.devicetrust.v1.Device + 12, // 46: teleport.devicetrust.v1.SyncInventoryResult.devices:type_name -> teleport.devicetrust.v1.DeviceOrStatus + 40, // 47: teleport.devicetrust.v1.SyncInventoryMissingDevices.devices:type_name -> teleport.devicetrust.v1.Device + 1, // 48: teleport.devicetrust.v1.DeviceTrustService.CreateDevice:input_type -> teleport.devicetrust.v1.CreateDeviceRequest + 2, // 49: teleport.devicetrust.v1.DeviceTrustService.UpdateDevice:input_type -> teleport.devicetrust.v1.UpdateDeviceRequest + 3, // 50: teleport.devicetrust.v1.DeviceTrustService.UpsertDevice:input_type -> teleport.devicetrust.v1.UpsertDeviceRequest + 4, // 51: teleport.devicetrust.v1.DeviceTrustService.DeleteDevice:input_type -> teleport.devicetrust.v1.DeleteDeviceRequest + 5, // 52: teleport.devicetrust.v1.DeviceTrustService.FindDevices:input_type -> teleport.devicetrust.v1.FindDevicesRequest + 7, // 53: teleport.devicetrust.v1.DeviceTrustService.GetDevice:input_type -> teleport.devicetrust.v1.GetDeviceRequest + 8, // 54: teleport.devicetrust.v1.DeviceTrustService.ListDevices:input_type -> teleport.devicetrust.v1.ListDevicesRequest + 10, // 55: teleport.devicetrust.v1.DeviceTrustService.BulkCreateDevices:input_type -> teleport.devicetrust.v1.BulkCreateDevicesRequest + 13, // 56: teleport.devicetrust.v1.DeviceTrustService.CreateDeviceEnrollToken:input_type -> teleport.devicetrust.v1.CreateDeviceEnrollTokenRequest + 14, // 57: teleport.devicetrust.v1.DeviceTrustService.EnrollDevice:input_type -> teleport.devicetrust.v1.EnrollDeviceRequest + 26, // 58: teleport.devicetrust.v1.DeviceTrustService.AuthenticateDevice:input_type -> teleport.devicetrust.v1.AuthenticateDeviceRequest + 29, // 59: teleport.devicetrust.v1.DeviceTrustService.ConfirmDeviceWebAuthentication:input_type -> teleport.devicetrust.v1.ConfirmDeviceWebAuthenticationRequest + 31, // 60: teleport.devicetrust.v1.DeviceTrustService.SyncInventory:input_type -> teleport.devicetrust.v1.SyncInventoryRequest + 39, // 61: teleport.devicetrust.v1.DeviceTrustService.GetDevicesUsage:input_type -> teleport.devicetrust.v1.GetDevicesUsageRequest + 40, // 62: teleport.devicetrust.v1.DeviceTrustService.CreateDevice:output_type -> teleport.devicetrust.v1.Device + 40, // 63: teleport.devicetrust.v1.DeviceTrustService.UpdateDevice:output_type -> teleport.devicetrust.v1.Device + 40, // 64: teleport.devicetrust.v1.DeviceTrustService.UpsertDevice:output_type -> teleport.devicetrust.v1.Device + 54, // 65: teleport.devicetrust.v1.DeviceTrustService.DeleteDevice:output_type -> google.protobuf.Empty + 6, // 66: teleport.devicetrust.v1.DeviceTrustService.FindDevices:output_type -> teleport.devicetrust.v1.FindDevicesResponse + 40, // 67: teleport.devicetrust.v1.DeviceTrustService.GetDevice:output_type -> teleport.devicetrust.v1.Device + 9, // 68: teleport.devicetrust.v1.DeviceTrustService.ListDevices:output_type -> teleport.devicetrust.v1.ListDevicesResponse + 11, // 69: teleport.devicetrust.v1.DeviceTrustService.BulkCreateDevices:output_type -> teleport.devicetrust.v1.BulkCreateDevicesResponse + 55, // 70: teleport.devicetrust.v1.DeviceTrustService.CreateDeviceEnrollToken:output_type -> teleport.devicetrust.v1.DeviceEnrollToken + 15, // 71: teleport.devicetrust.v1.DeviceTrustService.EnrollDevice:output_type -> teleport.devicetrust.v1.EnrollDeviceResponse + 27, // 72: teleport.devicetrust.v1.DeviceTrustService.AuthenticateDevice:output_type -> teleport.devicetrust.v1.AuthenticateDeviceResponse + 30, // 73: teleport.devicetrust.v1.DeviceTrustService.ConfirmDeviceWebAuthentication:output_type -> teleport.devicetrust.v1.ConfirmDeviceWebAuthenticationResponse + 32, // 74: teleport.devicetrust.v1.DeviceTrustService.SyncInventory:output_type -> teleport.devicetrust.v1.SyncInventoryResponse + 56, // 75: teleport.devicetrust.v1.DeviceTrustService.GetDevicesUsage:output_type -> teleport.devicetrust.v1.DevicesUsage + 62, // [62:76] is the sub-list for method output_type + 48, // [48:62] is the sub-list for method input_type + 48, // [48:48] is the sub-list for extension type_name + 48, // [48:48] is the sub-list for extension extendee + 0, // [0:48] is the sub-list for field type_name } func init() { file_teleport_devicetrust_v1_devicetrust_service_proto_init() } @@ -3611,6 +3391,7 @@ func file_teleport_devicetrust_v1_devicetrust_service_proto_init() { if File_teleport_devicetrust_v1_devicetrust_service_proto != nil { return } + file_teleport_devicetrust_v1_authenticate_challenge_proto_init() file_teleport_devicetrust_v1_device_proto_init() file_teleport_devicetrust_v1_device_collected_data_proto_init() file_teleport_devicetrust_v1_device_confirmation_token_proto_init() @@ -3958,54 +3739,6 @@ func file_teleport_devicetrust_v1_devicetrust_service_proto_init() { } } file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[28].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*TPMAuthenticateDeviceChallenge); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[29].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*TPMAuthenticateDeviceChallengeResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[30].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*AuthenticateDeviceChallenge); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[31].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*AuthenticateDeviceChallengeResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[32].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ConfirmDeviceWebAuthenticationRequest); i { case 0: return &v.state @@ -4017,7 +3750,7 @@ func file_teleport_devicetrust_v1_devicetrust_service_proto_init() { return nil } } - file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[33].Exporter = func(v interface{}, i int) interface{} { + file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[29].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ConfirmDeviceWebAuthenticationResponse); i { case 0: return &v.state @@ -4029,7 +3762,7 @@ func file_teleport_devicetrust_v1_devicetrust_service_proto_init() { return nil } } - file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[34].Exporter = func(v interface{}, i int) interface{} { + file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[30].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*SyncInventoryRequest); i { case 0: return &v.state @@ -4041,7 +3774,7 @@ func file_teleport_devicetrust_v1_devicetrust_service_proto_init() { return nil } } - file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[35].Exporter = func(v interface{}, i int) interface{} { + file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[31].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*SyncInventoryResponse); i { case 0: return &v.state @@ -4053,7 +3786,7 @@ func file_teleport_devicetrust_v1_devicetrust_service_proto_init() { return nil } } - file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[36].Exporter = func(v interface{}, i int) interface{} { + file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[32].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*SyncInventoryStart); i { case 0: return &v.state @@ -4065,7 +3798,7 @@ func file_teleport_devicetrust_v1_devicetrust_service_proto_init() { return nil } } - file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[37].Exporter = func(v interface{}, i int) interface{} { + file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[33].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*SyncInventoryEnd); i { case 0: return &v.state @@ -4077,7 +3810,7 @@ func file_teleport_devicetrust_v1_devicetrust_service_proto_init() { return nil } } - file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[38].Exporter = func(v interface{}, i int) interface{} { + file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[34].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*SyncInventoryDevices); i { case 0: return &v.state @@ -4089,7 +3822,7 @@ func file_teleport_devicetrust_v1_devicetrust_service_proto_init() { return nil } } - file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[39].Exporter = func(v interface{}, i int) interface{} { + file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[35].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*SyncInventoryAck); i { case 0: return &v.state @@ -4101,7 +3834,7 @@ func file_teleport_devicetrust_v1_devicetrust_service_proto_init() { return nil } } - file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[40].Exporter = func(v interface{}, i int) interface{} { + file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[36].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*SyncInventoryResult); i { case 0: return &v.state @@ -4113,7 +3846,7 @@ func file_teleport_devicetrust_v1_devicetrust_service_proto_init() { return nil } } - file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[41].Exporter = func(v interface{}, i int) interface{} { + file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[37].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*SyncInventoryMissingDevices); i { case 0: return &v.state @@ -4125,7 +3858,7 @@ func file_teleport_devicetrust_v1_devicetrust_service_proto_init() { return nil } } - file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[42].Exporter = func(v interface{}, i int) interface{} { + file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[38].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*GetDevicesUsageRequest); i { case 0: return &v.state @@ -4163,13 +3896,13 @@ func file_teleport_devicetrust_v1_devicetrust_service_proto_init() { (*AuthenticateDeviceResponse_TpmChallenge)(nil), (*AuthenticateDeviceResponse_ConfirmationToken)(nil), } - file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[34].OneofWrappers = []interface{}{ + file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[30].OneofWrappers = []interface{}{ (*SyncInventoryRequest_Start)(nil), (*SyncInventoryRequest_End)(nil), (*SyncInventoryRequest_DevicesToUpsert)(nil), (*SyncInventoryRequest_DevicesToRemove)(nil), } - file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[35].OneofWrappers = []interface{}{ + file_teleport_devicetrust_v1_devicetrust_service_proto_msgTypes[31].OneofWrappers = []interface{}{ (*SyncInventoryResponse_Ack)(nil), (*SyncInventoryResponse_Result)(nil), (*SyncInventoryResponse_MissingDevices)(nil), @@ -4180,7 +3913,7 @@ func file_teleport_devicetrust_v1_devicetrust_service_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_teleport_devicetrust_v1_devicetrust_service_proto_rawDesc, NumEnums: 1, - NumMessages: 43, + NumMessages: 39, NumExtensions: 0, NumServices: 1, }, diff --git a/api/proto/teleport/devicetrust/v1/assert.proto b/api/proto/teleport/devicetrust/v1/assert.proto new file mode 100644 index 0000000000000..79b869feb046b --- /dev/null +++ b/api/proto/teleport/devicetrust/v1/assert.proto @@ -0,0 +1,74 @@ +// Copyright 2024 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. + +syntax = "proto3"; + +package teleport.devicetrust.v1; + +import "teleport/devicetrust/v1/authenticate_challenge.proto"; +import "teleport/devicetrust/v1/device_collected_data.proto"; + +option go_package = "github.com/gravitational/teleport/api/gen/proto/go/teleport/devicetrust/v1;devicetrustv1"; + +// Request to assert an enrolled device. Assertion authenticates the device, +// regardless of the user driving the assertion. +// +// Assertion messages are meant to be included by other requests and responses, +// either streams or multi-stage RPCs. The ceremony is resolved by a co-located +// DeviceTrustService. +// +// See the lib/devicetrust/assert (client) and +// e/lib/devicetrust/devicetrustv1/assert (server) packages. +// +// Assertion ceremony flow: +// -> AssertDeviceInit (client) +// <- AssertDeviceChallenge (server) +// -> AssertDeviceChallengeResponse (client) +// <- DeviceAsserted (server) +// +// A successful ceremony signifies that the device is registered, enrolled and +// passed the authentication challenge. +message AssertDeviceRequest { + oneof payload { + AssertDeviceInit init = 1; + AuthenticateDeviceChallengeResponse challenge_response = 2; + TPMAuthenticateDeviceChallengeResponse tpm_challenge_response = 3; + } +} + +// Response of the device assertion ceremony. +// See [AssertDeviceRequest]. +message AssertDeviceResponse { + oneof payload { + AuthenticateDeviceChallenge challenge = 1; + TPMAuthenticateDeviceChallenge tpm_challenge = 2; + DeviceAsserted device_asserted = 3; + } +} + +// AssertDeviceInit initiates the device assertion ceremony. +// See [AssertDeviceRequest]. +message AssertDeviceInit { + // ID of the enrolled device credential. + string credential_id = 1; + + // Device collected data. + // Matched against the device registration information and any previously + // collected data. + DeviceCollectedData device_data = 2; +} + +// DeviceAsserted marks a successful device assertion ceremony. +// See [AssertDeviceRequest]. +message DeviceAsserted {} diff --git a/api/proto/teleport/devicetrust/v1/authenticate_challenge.proto b/api/proto/teleport/devicetrust/v1/authenticate_challenge.proto new file mode 100644 index 0000000000000..9f91a9046cae5 --- /dev/null +++ b/api/proto/teleport/devicetrust/v1/authenticate_challenge.proto @@ -0,0 +1,50 @@ +// Copyright 2022 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. + +syntax = "proto3"; + +package teleport.devicetrust.v1; + +import "teleport/devicetrust/v1/tpm.proto"; + +option go_package = "github.com/gravitational/teleport/api/gen/proto/go/teleport/devicetrust/v1;devicetrustv1"; + +// AuthenticateDeviceChallenge carries the authentication challenge. +message AuthenticateDeviceChallenge { + // Randomly-generated, opaque challenge to be signed using the device key. + bytes challenge = 1; +} + +// AuthenticateDeviceChallengeResponse carries the authentication challenge +// response. +message AuthenticateDeviceChallengeResponse { + // Signature over the challenge, using the device key. + bytes signature = 1; +} + +// TPMAuthenticateDeviceChallenge carries the authentication challenge +// specific to TPMs. +message TPMAuthenticateDeviceChallenge { + // Randomly-generated nonce to be used during platform attestation by the + // TPM. + bytes attestation_nonce = 1; +} + +// TPMAuthenticateDeviceChallengeResponse carries the authentication challenge +// response specific to TPMs. +message TPMAuthenticateDeviceChallengeResponse { + // The result of the client's platform attestation with the nonce provided + // in `TPMAuthenticateDeviceChallenge`. + TPMPlatformParameters platform_parameters = 1; +} diff --git a/api/proto/teleport/devicetrust/v1/devicetrust_service.proto b/api/proto/teleport/devicetrust/v1/devicetrust_service.proto index c807a46e290c4..fbf9df18666d6 100644 --- a/api/proto/teleport/devicetrust/v1/devicetrust_service.proto +++ b/api/proto/teleport/devicetrust/v1/devicetrust_service.proto @@ -20,6 +20,7 @@ import "google/protobuf/empty.proto"; import "google/protobuf/field_mask.proto"; import "google/protobuf/timestamp.proto"; import "google/rpc/status.proto"; +import "teleport/devicetrust/v1/authenticate_challenge.proto"; import "teleport/devicetrust/v1/device.proto"; import "teleport/devicetrust/v1/device_collected_data.proto"; import "teleport/devicetrust/v1/device_confirmation_token.proto"; @@ -535,35 +536,6 @@ message AuthenticateDeviceInit { DeviceWebToken device_web_token = 4; } -// TPMAuthenticateDeviceChallenge carries the authentication challenge -// specific to TPMs. -message TPMAuthenticateDeviceChallenge { - // Randomly-generated nonce to be used during platform attestation by the - // TPM. - bytes attestation_nonce = 1; -} - -// TPMAuthenticateDeviceChallengeResponse carries the authentication challenge -// response specific to TPMs. -message TPMAuthenticateDeviceChallengeResponse { - // The result of the client's platform attestation with the nonce provided - // in `TPMAuthenticateDeviceChallenge`. - TPMPlatformParameters platform_parameters = 1; -} - -// AuthenticateDeviceChallenge carries the authentication challenge. -message AuthenticateDeviceChallenge { - // Randomly-generated, opaque challenge to be signed using the device key. - bytes challenge = 1; -} - -// AuthenticateDeviceChallengeResponse carries the authentication challenge -// response. -message AuthenticateDeviceChallengeResponse { - // Signature over the challenge, using the device key. - bytes signature = 1; -} - // Request for ConfirmDeviceWebAuthentication. message ConfirmDeviceWebAuthenticationRequest { // Confirmation token to be spent. diff --git a/gen/proto/ts/teleport/devicetrust/v1/assert_pb.ts b/gen/proto/ts/teleport/devicetrust/v1/assert_pb.ts new file mode 100644 index 0000000000000..04371b0ae930c --- /dev/null +++ b/gen/proto/ts/teleport/devicetrust/v1/assert_pb.ts @@ -0,0 +1,363 @@ +/* eslint-disable */ +// @generated by protobuf-ts 2.9.3 with parameter eslint_disable,add_pb_suffix,server_grpc1,ts_nocheck +// @generated from protobuf file "teleport/devicetrust/v1/assert.proto" (package "teleport.devicetrust.v1", syntax proto3) +// tslint:disable +// @ts-nocheck +// +// Copyright 2024 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. +// +import type { BinaryWriteOptions } from "@protobuf-ts/runtime"; +import type { IBinaryWriter } from "@protobuf-ts/runtime"; +import { WireType } from "@protobuf-ts/runtime"; +import type { BinaryReadOptions } from "@protobuf-ts/runtime"; +import type { IBinaryReader } from "@protobuf-ts/runtime"; +import { UnknownFieldHandler } from "@protobuf-ts/runtime"; +import type { PartialMessage } from "@protobuf-ts/runtime"; +import { reflectionMergePartial } from "@protobuf-ts/runtime"; +import { MessageType } from "@protobuf-ts/runtime"; +import { DeviceCollectedData } from "./device_collected_data_pb"; +import { TPMAuthenticateDeviceChallenge } from "./authenticate_challenge_pb"; +import { AuthenticateDeviceChallenge } from "./authenticate_challenge_pb"; +import { TPMAuthenticateDeviceChallengeResponse } from "./authenticate_challenge_pb"; +import { AuthenticateDeviceChallengeResponse } from "./authenticate_challenge_pb"; +/** + * Request to assert an enrolled device. Assertion authenticates the device, + * regardless of the user driving the assertion. + * + * Assertion messages are meant to be included by other requests and responses, + * either streams or multi-stage RPCs. The ceremony is resolved by a co-located + * DeviceTrustService. + * + * See the lib/devicetrust/assert (client) and + * e/lib/devicetrust/devicetrustv1/assert (server) packages. + * + * Assertion ceremony flow: + * -> AssertDeviceInit (client) + * <- AssertDeviceChallenge (server) + * -> AssertDeviceChallengeResponse (client) + * <- DeviceAsserted (server) + * + * A successful ceremony signifies that the device is registered, enrolled and + * passed the authentication challenge. + * + * @generated from protobuf message teleport.devicetrust.v1.AssertDeviceRequest + */ +export interface AssertDeviceRequest { + /** + * @generated from protobuf oneof: payload + */ + payload: { + oneofKind: "init"; + /** + * @generated from protobuf field: teleport.devicetrust.v1.AssertDeviceInit init = 1; + */ + init: AssertDeviceInit; + } | { + oneofKind: "challengeResponse"; + /** + * @generated from protobuf field: teleport.devicetrust.v1.AuthenticateDeviceChallengeResponse challenge_response = 2; + */ + challengeResponse: AuthenticateDeviceChallengeResponse; + } | { + oneofKind: "tpmChallengeResponse"; + /** + * @generated from protobuf field: teleport.devicetrust.v1.TPMAuthenticateDeviceChallengeResponse tpm_challenge_response = 3; + */ + tpmChallengeResponse: TPMAuthenticateDeviceChallengeResponse; + } | { + oneofKind: undefined; + }; +} +/** + * Response of the device assertion ceremony. + * See [AssertDeviceRequest]. + * + * @generated from protobuf message teleport.devicetrust.v1.AssertDeviceResponse + */ +export interface AssertDeviceResponse { + /** + * @generated from protobuf oneof: payload + */ + payload: { + oneofKind: "challenge"; + /** + * @generated from protobuf field: teleport.devicetrust.v1.AuthenticateDeviceChallenge challenge = 1; + */ + challenge: AuthenticateDeviceChallenge; + } | { + oneofKind: "tpmChallenge"; + /** + * @generated from protobuf field: teleport.devicetrust.v1.TPMAuthenticateDeviceChallenge tpm_challenge = 2; + */ + tpmChallenge: TPMAuthenticateDeviceChallenge; + } | { + oneofKind: "deviceAsserted"; + /** + * @generated from protobuf field: teleport.devicetrust.v1.DeviceAsserted device_asserted = 3; + */ + deviceAsserted: DeviceAsserted; + } | { + oneofKind: undefined; + }; +} +/** + * AssertDeviceInit initiates the device assertion ceremony. + * See [AssertDeviceRequest]. + * + * @generated from protobuf message teleport.devicetrust.v1.AssertDeviceInit + */ +export interface AssertDeviceInit { + /** + * ID of the enrolled device credential. + * + * @generated from protobuf field: string credential_id = 1; + */ + credentialId: string; + /** + * Device collected data. + * Matched against the device registration information and any previously + * collected data. + * + * @generated from protobuf field: teleport.devicetrust.v1.DeviceCollectedData device_data = 2; + */ + deviceData?: DeviceCollectedData; +} +/** + * DeviceAsserted marks a successful device assertion ceremony. + * See [AssertDeviceRequest]. + * + * @generated from protobuf message teleport.devicetrust.v1.DeviceAsserted + */ +export interface DeviceAsserted { +} +// @generated message type with reflection information, may provide speed optimized methods +class AssertDeviceRequest$Type extends MessageType { + constructor() { + super("teleport.devicetrust.v1.AssertDeviceRequest", [ + { no: 1, name: "init", kind: "message", oneof: "payload", T: () => AssertDeviceInit }, + { no: 2, name: "challenge_response", kind: "message", oneof: "payload", T: () => AuthenticateDeviceChallengeResponse }, + { no: 3, name: "tpm_challenge_response", kind: "message", oneof: "payload", T: () => TPMAuthenticateDeviceChallengeResponse } + ]); + } + create(value?: PartialMessage): AssertDeviceRequest { + const message = globalThis.Object.create((this.messagePrototype!)); + message.payload = { oneofKind: undefined }; + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: AssertDeviceRequest): AssertDeviceRequest { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* teleport.devicetrust.v1.AssertDeviceInit init */ 1: + message.payload = { + oneofKind: "init", + init: AssertDeviceInit.internalBinaryRead(reader, reader.uint32(), options, (message.payload as any).init) + }; + break; + case /* teleport.devicetrust.v1.AuthenticateDeviceChallengeResponse challenge_response */ 2: + message.payload = { + oneofKind: "challengeResponse", + challengeResponse: AuthenticateDeviceChallengeResponse.internalBinaryRead(reader, reader.uint32(), options, (message.payload as any).challengeResponse) + }; + break; + case /* teleport.devicetrust.v1.TPMAuthenticateDeviceChallengeResponse tpm_challenge_response */ 3: + message.payload = { + oneofKind: "tpmChallengeResponse", + tpmChallengeResponse: TPMAuthenticateDeviceChallengeResponse.internalBinaryRead(reader, reader.uint32(), options, (message.payload as any).tpmChallengeResponse) + }; + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: AssertDeviceRequest, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* teleport.devicetrust.v1.AssertDeviceInit init = 1; */ + if (message.payload.oneofKind === "init") + AssertDeviceInit.internalBinaryWrite(message.payload.init, writer.tag(1, WireType.LengthDelimited).fork(), options).join(); + /* teleport.devicetrust.v1.AuthenticateDeviceChallengeResponse challenge_response = 2; */ + if (message.payload.oneofKind === "challengeResponse") + AuthenticateDeviceChallengeResponse.internalBinaryWrite(message.payload.challengeResponse, writer.tag(2, WireType.LengthDelimited).fork(), options).join(); + /* teleport.devicetrust.v1.TPMAuthenticateDeviceChallengeResponse tpm_challenge_response = 3; */ + if (message.payload.oneofKind === "tpmChallengeResponse") + TPMAuthenticateDeviceChallengeResponse.internalBinaryWrite(message.payload.tpmChallengeResponse, writer.tag(3, WireType.LengthDelimited).fork(), options).join(); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message teleport.devicetrust.v1.AssertDeviceRequest + */ +export const AssertDeviceRequest = new AssertDeviceRequest$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class AssertDeviceResponse$Type extends MessageType { + constructor() { + super("teleport.devicetrust.v1.AssertDeviceResponse", [ + { no: 1, name: "challenge", kind: "message", oneof: "payload", T: () => AuthenticateDeviceChallenge }, + { no: 2, name: "tpm_challenge", kind: "message", oneof: "payload", T: () => TPMAuthenticateDeviceChallenge }, + { no: 3, name: "device_asserted", kind: "message", oneof: "payload", T: () => DeviceAsserted } + ]); + } + create(value?: PartialMessage): AssertDeviceResponse { + const message = globalThis.Object.create((this.messagePrototype!)); + message.payload = { oneofKind: undefined }; + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: AssertDeviceResponse): AssertDeviceResponse { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* teleport.devicetrust.v1.AuthenticateDeviceChallenge challenge */ 1: + message.payload = { + oneofKind: "challenge", + challenge: AuthenticateDeviceChallenge.internalBinaryRead(reader, reader.uint32(), options, (message.payload as any).challenge) + }; + break; + case /* teleport.devicetrust.v1.TPMAuthenticateDeviceChallenge tpm_challenge */ 2: + message.payload = { + oneofKind: "tpmChallenge", + tpmChallenge: TPMAuthenticateDeviceChallenge.internalBinaryRead(reader, reader.uint32(), options, (message.payload as any).tpmChallenge) + }; + break; + case /* teleport.devicetrust.v1.DeviceAsserted device_asserted */ 3: + message.payload = { + oneofKind: "deviceAsserted", + deviceAsserted: DeviceAsserted.internalBinaryRead(reader, reader.uint32(), options, (message.payload as any).deviceAsserted) + }; + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: AssertDeviceResponse, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* teleport.devicetrust.v1.AuthenticateDeviceChallenge challenge = 1; */ + if (message.payload.oneofKind === "challenge") + AuthenticateDeviceChallenge.internalBinaryWrite(message.payload.challenge, writer.tag(1, WireType.LengthDelimited).fork(), options).join(); + /* teleport.devicetrust.v1.TPMAuthenticateDeviceChallenge tpm_challenge = 2; */ + if (message.payload.oneofKind === "tpmChallenge") + TPMAuthenticateDeviceChallenge.internalBinaryWrite(message.payload.tpmChallenge, writer.tag(2, WireType.LengthDelimited).fork(), options).join(); + /* teleport.devicetrust.v1.DeviceAsserted device_asserted = 3; */ + if (message.payload.oneofKind === "deviceAsserted") + DeviceAsserted.internalBinaryWrite(message.payload.deviceAsserted, writer.tag(3, WireType.LengthDelimited).fork(), options).join(); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message teleport.devicetrust.v1.AssertDeviceResponse + */ +export const AssertDeviceResponse = new AssertDeviceResponse$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class AssertDeviceInit$Type extends MessageType { + constructor() { + super("teleport.devicetrust.v1.AssertDeviceInit", [ + { no: 1, name: "credential_id", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, + { no: 2, name: "device_data", kind: "message", T: () => DeviceCollectedData } + ]); + } + create(value?: PartialMessage): AssertDeviceInit { + const message = globalThis.Object.create((this.messagePrototype!)); + message.credentialId = ""; + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: AssertDeviceInit): AssertDeviceInit { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* string credential_id */ 1: + message.credentialId = reader.string(); + break; + case /* teleport.devicetrust.v1.DeviceCollectedData device_data */ 2: + message.deviceData = DeviceCollectedData.internalBinaryRead(reader, reader.uint32(), options, message.deviceData); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: AssertDeviceInit, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* string credential_id = 1; */ + if (message.credentialId !== "") + writer.tag(1, WireType.LengthDelimited).string(message.credentialId); + /* teleport.devicetrust.v1.DeviceCollectedData device_data = 2; */ + if (message.deviceData) + DeviceCollectedData.internalBinaryWrite(message.deviceData, writer.tag(2, WireType.LengthDelimited).fork(), options).join(); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message teleport.devicetrust.v1.AssertDeviceInit + */ +export const AssertDeviceInit = new AssertDeviceInit$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class DeviceAsserted$Type extends MessageType { + constructor() { + super("teleport.devicetrust.v1.DeviceAsserted", []); + } + create(value?: PartialMessage): DeviceAsserted { + const message = globalThis.Object.create((this.messagePrototype!)); + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: DeviceAsserted): DeviceAsserted { + return target ?? this.create(); + } + internalBinaryWrite(message: DeviceAsserted, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message teleport.devicetrust.v1.DeviceAsserted + */ +export const DeviceAsserted = new DeviceAsserted$Type(); diff --git a/gen/proto/ts/teleport/devicetrust/v1/authenticate_challenge_pb.ts b/gen/proto/ts/teleport/devicetrust/v1/authenticate_challenge_pb.ts new file mode 100644 index 0000000000000..c2ad995034e85 --- /dev/null +++ b/gen/proto/ts/teleport/devicetrust/v1/authenticate_challenge_pb.ts @@ -0,0 +1,274 @@ +/* eslint-disable */ +// @generated by protobuf-ts 2.9.3 with parameter eslint_disable,add_pb_suffix,server_grpc1,ts_nocheck +// @generated from protobuf file "teleport/devicetrust/v1/authenticate_challenge.proto" (package "teleport.devicetrust.v1", syntax proto3) +// tslint:disable +// @ts-nocheck +// +// Copyright 2022 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. +// +import type { BinaryWriteOptions } from "@protobuf-ts/runtime"; +import type { IBinaryWriter } from "@protobuf-ts/runtime"; +import { WireType } from "@protobuf-ts/runtime"; +import type { BinaryReadOptions } from "@protobuf-ts/runtime"; +import type { IBinaryReader } from "@protobuf-ts/runtime"; +import { UnknownFieldHandler } from "@protobuf-ts/runtime"; +import type { PartialMessage } from "@protobuf-ts/runtime"; +import { reflectionMergePartial } from "@protobuf-ts/runtime"; +import { MessageType } from "@protobuf-ts/runtime"; +import { TPMPlatformParameters } from "./tpm_pb"; +/** + * AuthenticateDeviceChallenge carries the authentication challenge. + * + * @generated from protobuf message teleport.devicetrust.v1.AuthenticateDeviceChallenge + */ +export interface AuthenticateDeviceChallenge { + /** + * Randomly-generated, opaque challenge to be signed using the device key. + * + * @generated from protobuf field: bytes challenge = 1; + */ + challenge: Uint8Array; +} +/** + * AuthenticateDeviceChallengeResponse carries the authentication challenge + * response. + * + * @generated from protobuf message teleport.devicetrust.v1.AuthenticateDeviceChallengeResponse + */ +export interface AuthenticateDeviceChallengeResponse { + /** + * Signature over the challenge, using the device key. + * + * @generated from protobuf field: bytes signature = 1; + */ + signature: Uint8Array; +} +/** + * TPMAuthenticateDeviceChallenge carries the authentication challenge + * specific to TPMs. + * + * @generated from protobuf message teleport.devicetrust.v1.TPMAuthenticateDeviceChallenge + */ +export interface TPMAuthenticateDeviceChallenge { + /** + * Randomly-generated nonce to be used during platform attestation by the + * TPM. + * + * @generated from protobuf field: bytes attestation_nonce = 1; + */ + attestationNonce: Uint8Array; +} +/** + * TPMAuthenticateDeviceChallengeResponse carries the authentication challenge + * response specific to TPMs. + * + * @generated from protobuf message teleport.devicetrust.v1.TPMAuthenticateDeviceChallengeResponse + */ +export interface TPMAuthenticateDeviceChallengeResponse { + /** + * The result of the client's platform attestation with the nonce provided + * in `TPMAuthenticateDeviceChallenge`. + * + * @generated from protobuf field: teleport.devicetrust.v1.TPMPlatformParameters platform_parameters = 1; + */ + platformParameters?: TPMPlatformParameters; +} +// @generated message type with reflection information, may provide speed optimized methods +class AuthenticateDeviceChallenge$Type extends MessageType { + constructor() { + super("teleport.devicetrust.v1.AuthenticateDeviceChallenge", [ + { no: 1, name: "challenge", kind: "scalar", T: 12 /*ScalarType.BYTES*/ } + ]); + } + create(value?: PartialMessage): AuthenticateDeviceChallenge { + const message = globalThis.Object.create((this.messagePrototype!)); + message.challenge = new Uint8Array(0); + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: AuthenticateDeviceChallenge): AuthenticateDeviceChallenge { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* bytes challenge */ 1: + message.challenge = reader.bytes(); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: AuthenticateDeviceChallenge, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* bytes challenge = 1; */ + if (message.challenge.length) + writer.tag(1, WireType.LengthDelimited).bytes(message.challenge); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message teleport.devicetrust.v1.AuthenticateDeviceChallenge + */ +export const AuthenticateDeviceChallenge = new AuthenticateDeviceChallenge$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class AuthenticateDeviceChallengeResponse$Type extends MessageType { + constructor() { + super("teleport.devicetrust.v1.AuthenticateDeviceChallengeResponse", [ + { no: 1, name: "signature", kind: "scalar", T: 12 /*ScalarType.BYTES*/ } + ]); + } + create(value?: PartialMessage): AuthenticateDeviceChallengeResponse { + const message = globalThis.Object.create((this.messagePrototype!)); + message.signature = new Uint8Array(0); + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: AuthenticateDeviceChallengeResponse): AuthenticateDeviceChallengeResponse { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* bytes signature */ 1: + message.signature = reader.bytes(); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: AuthenticateDeviceChallengeResponse, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* bytes signature = 1; */ + if (message.signature.length) + writer.tag(1, WireType.LengthDelimited).bytes(message.signature); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message teleport.devicetrust.v1.AuthenticateDeviceChallengeResponse + */ +export const AuthenticateDeviceChallengeResponse = new AuthenticateDeviceChallengeResponse$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class TPMAuthenticateDeviceChallenge$Type extends MessageType { + constructor() { + super("teleport.devicetrust.v1.TPMAuthenticateDeviceChallenge", [ + { no: 1, name: "attestation_nonce", kind: "scalar", T: 12 /*ScalarType.BYTES*/ } + ]); + } + create(value?: PartialMessage): TPMAuthenticateDeviceChallenge { + const message = globalThis.Object.create((this.messagePrototype!)); + message.attestationNonce = new Uint8Array(0); + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: TPMAuthenticateDeviceChallenge): TPMAuthenticateDeviceChallenge { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* bytes attestation_nonce */ 1: + message.attestationNonce = reader.bytes(); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: TPMAuthenticateDeviceChallenge, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* bytes attestation_nonce = 1; */ + if (message.attestationNonce.length) + writer.tag(1, WireType.LengthDelimited).bytes(message.attestationNonce); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message teleport.devicetrust.v1.TPMAuthenticateDeviceChallenge + */ +export const TPMAuthenticateDeviceChallenge = new TPMAuthenticateDeviceChallenge$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class TPMAuthenticateDeviceChallengeResponse$Type extends MessageType { + constructor() { + super("teleport.devicetrust.v1.TPMAuthenticateDeviceChallengeResponse", [ + { no: 1, name: "platform_parameters", kind: "message", T: () => TPMPlatformParameters } + ]); + } + create(value?: PartialMessage): TPMAuthenticateDeviceChallengeResponse { + const message = globalThis.Object.create((this.messagePrototype!)); + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: TPMAuthenticateDeviceChallengeResponse): TPMAuthenticateDeviceChallengeResponse { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* teleport.devicetrust.v1.TPMPlatformParameters platform_parameters */ 1: + message.platformParameters = TPMPlatformParameters.internalBinaryRead(reader, reader.uint32(), options, message.platformParameters); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: TPMAuthenticateDeviceChallengeResponse, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* teleport.devicetrust.v1.TPMPlatformParameters platform_parameters = 1; */ + if (message.platformParameters) + TPMPlatformParameters.internalBinaryWrite(message.platformParameters, writer.tag(1, WireType.LengthDelimited).fork(), options).join(); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message teleport.devicetrust.v1.TPMAuthenticateDeviceChallengeResponse + */ +export const TPMAuthenticateDeviceChallengeResponse = new TPMAuthenticateDeviceChallengeResponse$Type(); diff --git a/gen/proto/ts/teleport/devicetrust/v1/devicetrust_service_pb.ts b/gen/proto/ts/teleport/devicetrust/v1/devicetrust_service_pb.ts index f0ec52d779113..50750c68b809a 100644 --- a/gen/proto/ts/teleport/devicetrust/v1/devicetrust_service_pb.ts +++ b/gen/proto/ts/teleport/devicetrust/v1/devicetrust_service_pb.ts @@ -34,7 +34,11 @@ import { MessageType } from "@protobuf-ts/runtime"; import { DeviceSource } from "./device_source_pb"; import { DeviceWebToken } from "./device_web_token_pb"; import { DeviceConfirmationToken } from "./device_confirmation_token_pb"; +import { TPMAuthenticateDeviceChallenge } from "./authenticate_challenge_pb"; import { UserCertificates } from "./user_certificates_pb"; +import { AuthenticateDeviceChallenge } from "./authenticate_challenge_pb"; +import { TPMAuthenticateDeviceChallengeResponse } from "./authenticate_challenge_pb"; +import { AuthenticateDeviceChallengeResponse } from "./authenticate_challenge_pb"; import { TPMPlatformParameters } from "./tpm_pb"; import { DeviceCollectedData } from "./device_collected_data_pb"; import { Status } from "../../../google/rpc/status_pb"; @@ -754,63 +758,6 @@ export interface AuthenticateDeviceInit { */ deviceWebToken?: DeviceWebToken; } -/** - * TPMAuthenticateDeviceChallenge carries the authentication challenge - * specific to TPMs. - * - * @generated from protobuf message teleport.devicetrust.v1.TPMAuthenticateDeviceChallenge - */ -export interface TPMAuthenticateDeviceChallenge { - /** - * Randomly-generated nonce to be used during platform attestation by the - * TPM. - * - * @generated from protobuf field: bytes attestation_nonce = 1; - */ - attestationNonce: Uint8Array; -} -/** - * TPMAuthenticateDeviceChallengeResponse carries the authentication challenge - * response specific to TPMs. - * - * @generated from protobuf message teleport.devicetrust.v1.TPMAuthenticateDeviceChallengeResponse - */ -export interface TPMAuthenticateDeviceChallengeResponse { - /** - * The result of the client's platform attestation with the nonce provided - * in `TPMAuthenticateDeviceChallenge`. - * - * @generated from protobuf field: teleport.devicetrust.v1.TPMPlatformParameters platform_parameters = 1; - */ - platformParameters?: TPMPlatformParameters; -} -/** - * AuthenticateDeviceChallenge carries the authentication challenge. - * - * @generated from protobuf message teleport.devicetrust.v1.AuthenticateDeviceChallenge - */ -export interface AuthenticateDeviceChallenge { - /** - * Randomly-generated, opaque challenge to be signed using the device key. - * - * @generated from protobuf field: bytes challenge = 1; - */ - challenge: Uint8Array; -} -/** - * AuthenticateDeviceChallengeResponse carries the authentication challenge - * response. - * - * @generated from protobuf message teleport.devicetrust.v1.AuthenticateDeviceChallengeResponse - */ -export interface AuthenticateDeviceChallengeResponse { - /** - * Signature over the challenge, using the device key. - * - * @generated from protobuf field: bytes signature = 1; - */ - signature: Uint8Array; -} /** * Request for ConfirmDeviceWebAuthentication. * @@ -2678,193 +2625,6 @@ class AuthenticateDeviceInit$Type extends MessageType { */ export const AuthenticateDeviceInit = new AuthenticateDeviceInit$Type(); // @generated message type with reflection information, may provide speed optimized methods -class TPMAuthenticateDeviceChallenge$Type extends MessageType { - constructor() { - super("teleport.devicetrust.v1.TPMAuthenticateDeviceChallenge", [ - { no: 1, name: "attestation_nonce", kind: "scalar", T: 12 /*ScalarType.BYTES*/ } - ]); - } - create(value?: PartialMessage): TPMAuthenticateDeviceChallenge { - const message = globalThis.Object.create((this.messagePrototype!)); - message.attestationNonce = new Uint8Array(0); - if (value !== undefined) - reflectionMergePartial(this, message, value); - return message; - } - internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: TPMAuthenticateDeviceChallenge): TPMAuthenticateDeviceChallenge { - let message = target ?? this.create(), end = reader.pos + length; - while (reader.pos < end) { - let [fieldNo, wireType] = reader.tag(); - switch (fieldNo) { - case /* bytes attestation_nonce */ 1: - message.attestationNonce = reader.bytes(); - break; - default: - let u = options.readUnknownField; - if (u === "throw") - throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); - let d = reader.skip(wireType); - if (u !== false) - (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); - } - } - return message; - } - internalBinaryWrite(message: TPMAuthenticateDeviceChallenge, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { - /* bytes attestation_nonce = 1; */ - if (message.attestationNonce.length) - writer.tag(1, WireType.LengthDelimited).bytes(message.attestationNonce); - let u = options.writeUnknownFields; - if (u !== false) - (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); - return writer; - } -} -/** - * @generated MessageType for protobuf message teleport.devicetrust.v1.TPMAuthenticateDeviceChallenge - */ -export const TPMAuthenticateDeviceChallenge = new TPMAuthenticateDeviceChallenge$Type(); -// @generated message type with reflection information, may provide speed optimized methods -class TPMAuthenticateDeviceChallengeResponse$Type extends MessageType { - constructor() { - super("teleport.devicetrust.v1.TPMAuthenticateDeviceChallengeResponse", [ - { no: 1, name: "platform_parameters", kind: "message", T: () => TPMPlatformParameters } - ]); - } - create(value?: PartialMessage): TPMAuthenticateDeviceChallengeResponse { - const message = globalThis.Object.create((this.messagePrototype!)); - if (value !== undefined) - reflectionMergePartial(this, message, value); - return message; - } - internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: TPMAuthenticateDeviceChallengeResponse): TPMAuthenticateDeviceChallengeResponse { - let message = target ?? this.create(), end = reader.pos + length; - while (reader.pos < end) { - let [fieldNo, wireType] = reader.tag(); - switch (fieldNo) { - case /* teleport.devicetrust.v1.TPMPlatformParameters platform_parameters */ 1: - message.platformParameters = TPMPlatformParameters.internalBinaryRead(reader, reader.uint32(), options, message.platformParameters); - break; - default: - let u = options.readUnknownField; - if (u === "throw") - throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); - let d = reader.skip(wireType); - if (u !== false) - (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); - } - } - return message; - } - internalBinaryWrite(message: TPMAuthenticateDeviceChallengeResponse, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { - /* teleport.devicetrust.v1.TPMPlatformParameters platform_parameters = 1; */ - if (message.platformParameters) - TPMPlatformParameters.internalBinaryWrite(message.platformParameters, writer.tag(1, WireType.LengthDelimited).fork(), options).join(); - let u = options.writeUnknownFields; - if (u !== false) - (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); - return writer; - } -} -/** - * @generated MessageType for protobuf message teleport.devicetrust.v1.TPMAuthenticateDeviceChallengeResponse - */ -export const TPMAuthenticateDeviceChallengeResponse = new TPMAuthenticateDeviceChallengeResponse$Type(); -// @generated message type with reflection information, may provide speed optimized methods -class AuthenticateDeviceChallenge$Type extends MessageType { - constructor() { - super("teleport.devicetrust.v1.AuthenticateDeviceChallenge", [ - { no: 1, name: "challenge", kind: "scalar", T: 12 /*ScalarType.BYTES*/ } - ]); - } - create(value?: PartialMessage): AuthenticateDeviceChallenge { - const message = globalThis.Object.create((this.messagePrototype!)); - message.challenge = new Uint8Array(0); - if (value !== undefined) - reflectionMergePartial(this, message, value); - return message; - } - internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: AuthenticateDeviceChallenge): AuthenticateDeviceChallenge { - let message = target ?? this.create(), end = reader.pos + length; - while (reader.pos < end) { - let [fieldNo, wireType] = reader.tag(); - switch (fieldNo) { - case /* bytes challenge */ 1: - message.challenge = reader.bytes(); - break; - default: - let u = options.readUnknownField; - if (u === "throw") - throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); - let d = reader.skip(wireType); - if (u !== false) - (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); - } - } - return message; - } - internalBinaryWrite(message: AuthenticateDeviceChallenge, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { - /* bytes challenge = 1; */ - if (message.challenge.length) - writer.tag(1, WireType.LengthDelimited).bytes(message.challenge); - let u = options.writeUnknownFields; - if (u !== false) - (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); - return writer; - } -} -/** - * @generated MessageType for protobuf message teleport.devicetrust.v1.AuthenticateDeviceChallenge - */ -export const AuthenticateDeviceChallenge = new AuthenticateDeviceChallenge$Type(); -// @generated message type with reflection information, may provide speed optimized methods -class AuthenticateDeviceChallengeResponse$Type extends MessageType { - constructor() { - super("teleport.devicetrust.v1.AuthenticateDeviceChallengeResponse", [ - { no: 1, name: "signature", kind: "scalar", T: 12 /*ScalarType.BYTES*/ } - ]); - } - create(value?: PartialMessage): AuthenticateDeviceChallengeResponse { - const message = globalThis.Object.create((this.messagePrototype!)); - message.signature = new Uint8Array(0); - if (value !== undefined) - reflectionMergePartial(this, message, value); - return message; - } - internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: AuthenticateDeviceChallengeResponse): AuthenticateDeviceChallengeResponse { - let message = target ?? this.create(), end = reader.pos + length; - while (reader.pos < end) { - let [fieldNo, wireType] = reader.tag(); - switch (fieldNo) { - case /* bytes signature */ 1: - message.signature = reader.bytes(); - break; - default: - let u = options.readUnknownField; - if (u === "throw") - throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); - let d = reader.skip(wireType); - if (u !== false) - (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); - } - } - return message; - } - internalBinaryWrite(message: AuthenticateDeviceChallengeResponse, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { - /* bytes signature = 1; */ - if (message.signature.length) - writer.tag(1, WireType.LengthDelimited).bytes(message.signature); - let u = options.writeUnknownFields; - if (u !== false) - (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); - return writer; - } -} -/** - * @generated MessageType for protobuf message teleport.devicetrust.v1.AuthenticateDeviceChallengeResponse - */ -export const AuthenticateDeviceChallengeResponse = new AuthenticateDeviceChallengeResponse$Type(); -// @generated message type with reflection information, may provide speed optimized methods class ConfirmDeviceWebAuthenticationRequest$Type extends MessageType { constructor() { super("teleport.devicetrust.v1.ConfirmDeviceWebAuthenticationRequest", [ From 29880216e54b717b0ec802998b086ed8c7044e80 Mon Sep 17 00:00:00 2001 From: Alan Parra Date: Wed, 10 Jul 2024 13:26:53 -0300 Subject: [PATCH 02/25] Add a client-side API to assert devices (#43890) * Add a client-side API to assert devices * Add a godoc to authnStreamAdapter --- lib/devicetrust/assert/assert.go | 183 ++++++++++++++++++++++++++ lib/devicetrust/assert/assert_test.go | 164 +++++++++++++++++++++++ 2 files changed, 347 insertions(+) create mode 100644 lib/devicetrust/assert/assert.go create mode 100644 lib/devicetrust/assert/assert_test.go diff --git a/lib/devicetrust/assert/assert.go b/lib/devicetrust/assert/assert.go new file mode 100644 index 0000000000000..f69fb67f671ef --- /dev/null +++ b/lib/devicetrust/assert/assert.go @@ -0,0 +1,183 @@ +// Teleport +// Copyright (C) 2024 Gravitational, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package assert + +import ( + "context" + + "github.com/gravitational/trace" + "google.golang.org/grpc" + + devicepb "github.com/gravitational/teleport/api/gen/proto/go/teleport/devicetrust/v1" + "github.com/gravitational/teleport/lib/devicetrust/authn" +) + +// AssertDeviceClientStream is the client-side device assertion stream. +type AssertDeviceClientStream interface { + Send(*devicepb.AssertDeviceRequest) error + Recv() (*devicepb.AssertDeviceResponse, error) +} + +// Ceremony implements the client-side assertion ceremony. +// +// See [devicepb.AssertDeviceRequest] for details. +type Ceremony struct { + // newAuthnCeremony defaults to authn.NewCeremony. + newAuthnCeremony func() *authn.Ceremony +} + +// CeremonyOpt is a creation option for [Ceremony]. +type CeremonyOpt func(*Ceremony) + +// WithNewAuthnCeremonyFunc overrides the default authn.Ceremony constructor, +// allowing callers to change the underlying assert implementation. +// +// Useful for testing. Avoid for production code. +func WithNewAuthnCeremonyFunc(f func() *authn.Ceremony) CeremonyOpt { + return func(c *Ceremony) { + c.newAuthnCeremony = f + } +} + +// NewCeremony creates a new [Ceremony], binding all native device trust +// methods. +func NewCeremony(opts ...CeremonyOpt) (*Ceremony, error) { + c := &Ceremony{ + newAuthnCeremony: authn.NewCeremony, + } + for _, opt := range opts { + opt(c) + } + return c, nil +} + +// Run runs the client-side device assertion ceremony. +// Requests and responses are consumed from the stream until the device is +// asserted or authentication fails. +func (c *Ceremony) Run(ctx context.Context, stream AssertDeviceClientStream) error { + newAuthn := c.newAuthnCeremony + if newAuthn == nil { + newAuthn = authn.NewCeremony + } + + devices := &devicesClientAdapter{ + stream: stream, + } + certs := &devicepb.UserCertificates{} // required but unused + + // Implement Assertion in terms of Authentication, so we borrow both the + // Secure Enclave and TPM branches from it. + // TODO(codingllama): Refactor so we don't need so many adapters? + _, err := newAuthn().Run(ctx, devices, certs) + return trace.Wrap(err) +} + +type devicesClientAdapter struct { + devicepb.DeviceTrustServiceClient + + stream AssertDeviceClientStream +} + +func (d *devicesClientAdapter) AuthenticateDevice(ctx context.Context, opts ...grpc.CallOption) (devicepb.DeviceTrustService_AuthenticateDeviceClient, error) { + return &authnStreamAdapter{ + ctx: ctx, + stream: d.stream, + }, nil +} + +// authnStreamAdapter adapts an [AssertDeviceClientStream] to a +// [devicepb.DeviceTrustService_AuthenticateDeviceClient] stream. This allows +// the assertion ceremony to borrow the [authn.Ceremony] logic for itself. +type authnStreamAdapter struct { + devicepb.DeviceTrustService_AuthenticateDeviceClient + + ctx context.Context + stream AssertDeviceClientStream +} + +func (s *authnStreamAdapter) CloseSend() error { + return nil +} + +func (s *authnStreamAdapter) Context() context.Context { + return s.ctx +} + +func (s *authnStreamAdapter) Recv() (*devicepb.AuthenticateDeviceResponse, error) { + resp, err := s.stream.Recv() + if err != nil { + return nil, trace.Wrap(err) + } + + if resp == nil || resp.Payload == nil { + return nil, trace.BadParameter("assertion response payload required") + } + + switch resp.Payload.(type) { + case *devicepb.AssertDeviceResponse_Challenge: + return &devicepb.AuthenticateDeviceResponse{ + Payload: &devicepb.AuthenticateDeviceResponse_Challenge{ + Challenge: resp.GetChallenge(), + }, + }, nil + case *devicepb.AssertDeviceResponse_TpmChallenge: + return &devicepb.AuthenticateDeviceResponse{ + Payload: &devicepb.AuthenticateDeviceResponse_TpmChallenge{ + TpmChallenge: resp.GetTpmChallenge(), + }, + }, nil + case *devicepb.AssertDeviceResponse_DeviceAsserted: + // Pass an empty UserCertificates to signify success. + return &devicepb.AuthenticateDeviceResponse{ + Payload: &devicepb.AuthenticateDeviceResponse_UserCertificates{ + UserCertificates: &devicepb.UserCertificates{}, + }, + }, nil + default: + return nil, trace.BadParameter("unexpected assertion response payload: %T", resp.Payload) + } +} + +func (s *authnStreamAdapter) Send(authnReq *devicepb.AuthenticateDeviceRequest) error { + if authnReq == nil || authnReq.Payload == nil { + return trace.BadParameter("authenticate request payload required") + } + + req := &devicepb.AssertDeviceRequest{} + switch authnReq.Payload.(type) { + case *devicepb.AuthenticateDeviceRequest_Init: + init := authnReq.GetInit() + req.Payload = &devicepb.AssertDeviceRequest_Init{ + Init: &devicepb.AssertDeviceInit{ + CredentialId: init.GetCredentialId(), + DeviceData: init.GetDeviceData(), + }, + } + case *devicepb.AuthenticateDeviceRequest_ChallengeResponse: + req.Payload = &devicepb.AssertDeviceRequest_ChallengeResponse{ + ChallengeResponse: authnReq.GetChallengeResponse(), + } + case *devicepb.AuthenticateDeviceRequest_TpmChallengeResponse: + req.Payload = &devicepb.AssertDeviceRequest_TpmChallengeResponse{ + TpmChallengeResponse: authnReq.GetTpmChallengeResponse(), + } + default: + return trace.BadParameter("unexpected authenticate request payload: %T", authnReq.Payload) + } + + return trace.Wrap(s.stream.Send(req)) +} diff --git a/lib/devicetrust/assert/assert_test.go b/lib/devicetrust/assert/assert_test.go new file mode 100644 index 0000000000000..273b71b814eb9 --- /dev/null +++ b/lib/devicetrust/assert/assert_test.go @@ -0,0 +1,164 @@ +// Teleport +// Copyright (C) 2024 Gravitational, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package assert_test + +import ( + "context" + "testing" + + "github.com/gravitational/trace" + "github.com/stretchr/testify/require" + + devicepb "github.com/gravitational/teleport/api/gen/proto/go/teleport/devicetrust/v1" + "github.com/gravitational/teleport/lib/devicetrust/assert" + "github.com/gravitational/teleport/lib/devicetrust/authn" + "github.com/gravitational/teleport/lib/devicetrust/enroll" + "github.com/gravitational/teleport/lib/devicetrust/testenv" +) + +func TestCeremony(t *testing.T) { + t.Parallel() + + env := testenv.MustNew( + testenv.WithAutoCreateDevice(true), + ) + + devicesClient := env.DevicesClient + ctx := context.Background() + + macDev, err := testenv.NewFakeMacOSDevice() + require.NoError(t, err, "NewFakeMacOSDevice errored") + + linuxDev := testenv.NewFakeLinuxDevice() + + tests := []struct { + name string + dev testenv.FakeDevice + }{ + { + name: "ok (macOs)", + dev: macDev, + }, + { + name: "ok (TPM)", + dev: linuxDev, + }, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + t.Parallel() + + // Enroll the device before we attempt authentication (auto creates device + // as part of ceremony) + dev := test.dev + enrollC := enroll.Ceremony{ + GetDeviceOSType: dev.GetDeviceOSType, + EnrollDeviceInit: dev.EnrollDeviceInit, + SignChallenge: dev.SignChallenge, + SolveTPMEnrollChallenge: dev.SolveTPMEnrollChallenge, + } + _, err := enrollC.Run(ctx, devicesClient, false, testenv.FakeEnrollmentToken) + require.NoError(t, err, "EnrollDevice errored") + + assertC, err := assert.NewCeremony(assert.WithNewAuthnCeremonyFunc(func() *authn.Ceremony { + return &authn.Ceremony{ + GetDeviceCredential: func() (*devicepb.DeviceCredential, error) { + return dev.GetDeviceCredential(), nil + }, + CollectDeviceData: dev.CollectDeviceData, + SignChallenge: dev.SignChallenge, + SolveTPMAuthnDeviceChallenge: dev.SolveTPMAuthnDeviceChallenge, + GetDeviceOSType: dev.GetDeviceOSType, + } + })) + require.NoError(t, err, "NewCeremony errored") + + authnStream, err := devicesClient.AuthenticateDevice(ctx) + require.NoError(t, err, "AuthenticateDevice errored") + + // Typically this would be some other, non-DeviceTrustService stream, but + // here this is a good way to test it (as it runs actual fake device + // authn) + if err := assertC.Run(ctx, &assertStreamAdapter{ + stream: authnStream, + }); err != nil { + t.Errorf("Run returned err=%q, want nil", err) + } + }) + } +} + +type assertStreamAdapter struct { + stream devicepb.DeviceTrustService_AuthenticateDeviceClient +} + +func (s *assertStreamAdapter) Recv() (*devicepb.AssertDeviceResponse, error) { + resp, err := s.stream.Recv() + if err != nil { + return nil, err + } + + switch resp.Payload.(type) { + case *devicepb.AuthenticateDeviceResponse_Challenge: + return &devicepb.AssertDeviceResponse{ + Payload: &devicepb.AssertDeviceResponse_Challenge{ + Challenge: resp.GetChallenge(), + }, + }, nil + case *devicepb.AuthenticateDeviceResponse_TpmChallenge: + return &devicepb.AssertDeviceResponse{ + Payload: &devicepb.AssertDeviceResponse_TpmChallenge{ + TpmChallenge: resp.GetTpmChallenge(), + }, + }, nil + case *devicepb.AuthenticateDeviceResponse_UserCertificates: + // UserCertificates means success. + return &devicepb.AssertDeviceResponse{ + Payload: &devicepb.AssertDeviceResponse_DeviceAsserted{ + DeviceAsserted: &devicepb.DeviceAsserted{}, + }, + }, nil + default: + return nil, trace.BadParameter("unexpected authenticate response payload: %T", resp.Payload) + } +} + +func (s *assertStreamAdapter) Send(req *devicepb.AssertDeviceRequest) error { + authnReq := &devicepb.AuthenticateDeviceRequest{} + switch req.Payload.(type) { + case *devicepb.AssertDeviceRequest_Init: + init := req.GetInit() + authnReq.Payload = &devicepb.AuthenticateDeviceRequest_Init{ + Init: &devicepb.AuthenticateDeviceInit{ + CredentialId: init.CredentialId, + DeviceData: init.DeviceData, + }, + } + case *devicepb.AssertDeviceRequest_ChallengeResponse: + authnReq.Payload = &devicepb.AuthenticateDeviceRequest_ChallengeResponse{ + ChallengeResponse: req.GetChallengeResponse(), + } + case *devicepb.AssertDeviceRequest_TpmChallengeResponse: + authnReq.Payload = &devicepb.AuthenticateDeviceRequest_TpmChallengeResponse{ + TpmChallengeResponse: req.GetTpmChallengeResponse(), + } + default: + return trace.BadParameter("unexpected assert request payload: %T", req.Payload) + } + + return s.stream.Send(authnReq) +} From 3ef73ba4a0369f72c3374b39857cfb70dabfc14c Mon Sep 17 00:00:00 2001 From: Alan Parra Date: Thu, 11 Jul 2024 10:13:47 -0300 Subject: [PATCH 03/25] Define server-side device assertion interfaces (#44036) * Define server-side device assertion interfaces * Update proto comments * Update generated protos --- .../go/teleport/devicetrust/v1/assert.pb.go | 4 +- .../teleport/devicetrust/v1/assert.proto | 4 +- .../ts/teleport/devicetrust/v1/assert_pb.ts | 4 +- lib/devicetrust/assertserver/assert.go | 50 +++++++++++++++++++ lib/devicetrust/assertserver/doc.go | 21 ++++++++ 5 files changed, 77 insertions(+), 6 deletions(-) create mode 100644 lib/devicetrust/assertserver/assert.go create mode 100644 lib/devicetrust/assertserver/doc.go diff --git a/api/gen/proto/go/teleport/devicetrust/v1/assert.pb.go b/api/gen/proto/go/teleport/devicetrust/v1/assert.pb.go index dbb3bd609b147..0efdc20200dfc 100644 --- a/api/gen/proto/go/teleport/devicetrust/v1/assert.pb.go +++ b/api/gen/proto/go/teleport/devicetrust/v1/assert.pb.go @@ -41,8 +41,8 @@ const ( // either streams or multi-stage RPCs. The ceremony is resolved by a co-located // DeviceTrustService. // -// See the lib/devicetrust/assert (client) and -// e/lib/devicetrust/devicetrustv1/assert (server) packages. +// See the lib/devicetrust/assert (client) and lib/devicetrust/assertserver +// (server) packages. // // Assertion ceremony flow: // -> AssertDeviceInit (client) diff --git a/api/proto/teleport/devicetrust/v1/assert.proto b/api/proto/teleport/devicetrust/v1/assert.proto index 79b869feb046b..5841c0a5c0519 100644 --- a/api/proto/teleport/devicetrust/v1/assert.proto +++ b/api/proto/teleport/devicetrust/v1/assert.proto @@ -28,8 +28,8 @@ option go_package = "github.com/gravitational/teleport/api/gen/proto/go/teleport // either streams or multi-stage RPCs. The ceremony is resolved by a co-located // DeviceTrustService. // -// See the lib/devicetrust/assert (client) and -// e/lib/devicetrust/devicetrustv1/assert (server) packages. +// See the lib/devicetrust/assert (client) and lib/devicetrust/assertserver +// (server) packages. // // Assertion ceremony flow: // -> AssertDeviceInit (client) diff --git a/gen/proto/ts/teleport/devicetrust/v1/assert_pb.ts b/gen/proto/ts/teleport/devicetrust/v1/assert_pb.ts index 04371b0ae930c..ef45d1cccdcdd 100644 --- a/gen/proto/ts/teleport/devicetrust/v1/assert_pb.ts +++ b/gen/proto/ts/teleport/devicetrust/v1/assert_pb.ts @@ -40,8 +40,8 @@ import { AuthenticateDeviceChallengeResponse } from "./authenticate_challenge_pb * either streams or multi-stage RPCs. The ceremony is resolved by a co-located * DeviceTrustService. * - * See the lib/devicetrust/assert (client) and - * e/lib/devicetrust/devicetrustv1/assert (server) packages. + * See the lib/devicetrust/assert (client) and lib/devicetrust/assertserver + * (server) packages. * * Assertion ceremony flow: * -> AssertDeviceInit (client) diff --git a/lib/devicetrust/assertserver/assert.go b/lib/devicetrust/assertserver/assert.go new file mode 100644 index 0000000000000..46047e465f3b3 --- /dev/null +++ b/lib/devicetrust/assertserver/assert.go @@ -0,0 +1,50 @@ +// Teleport +// Copyright (C) 2024 Gravitational, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package assertserver + +import ( + "context" + + devicepb "github.com/gravitational/teleport/api/gen/proto/go/teleport/devicetrust/v1" +) + +// AssertDeviceServerStream represents a server-side device assertion stream. +type AssertDeviceServerStream interface { + Send(*devicepb.AssertDeviceResponse) error + Recv() (*devicepb.AssertDeviceRequest, error) +} + +// Ceremony is the server-side device assertion ceremony. +// +// Device assertion is a light form of device authentication where the user +// isn't considered and no side-effects (like certificate issuance) happen. +// +// Assertion is meant to be embedded in RPCs or streams external to the +// DeviceTrustService itself. +// +// Implementations are provided by e/. +// See e/lib/devicetrustv1.Service.CreateAssertCeremony. +type Ceremony interface { + // AssertDevice runs the device assertion ceremonies. + // + // Requests and responses are consumed from the stream until the device is + // asserted or authentication fails. + // + // As long as any device information is acquired from the stream, a non-nil + // device is returned, even if the ceremony itself failed. + AssertDevice(ctx context.Context, stream AssertDeviceServerStream) (*devicepb.Device, error) +} diff --git a/lib/devicetrust/assertserver/doc.go b/lib/devicetrust/assertserver/doc.go new file mode 100644 index 0000000000000..eebdb97e81933 --- /dev/null +++ b/lib/devicetrust/assertserver/doc.go @@ -0,0 +1,21 @@ +// Teleport +// Copyright (C) 2024 Gravitational, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +// Package assertserver provides server-side assert interfaces for device trust. +// +// It explicitly does not depend on devicetrust/native or other client-side +// packages. All implementations are provided by e/. +package assertserver From 986419a103a60c1264c0b2d16bd1fcfb0fa64e8d Mon Sep 17 00:00:00 2001 From: Tiago Silva Date: Tue, 9 Jul 2024 09:56:47 +0100 Subject: [PATCH 04/25] [sec_scan][1] Add `teleport.access_graph.v1.SecretsScannerService` (#43462) This PR introduces the `teleport.access_graph.v1.SecretsScannerService`that will be used by Teleport SSH nodes to report `authorized_keys` and user's laptops to report secrets found on them. The `ReportAuthorizedKeys` uses node's TLS certs signed by HostCA for authentication while `ReportSecrets` leverages the device trust credentials (requires that the device is enrolled) to report secrets without requiring valid user credentials. handle Alan's feedback --- .../accessgraph/v1/authorized_key.pb.go | 307 +++++++++ .../teleport/accessgraph/v1/private_key.pb.go | 390 +++++++++++ .../accessgraph/v1/secrets_service.pb.go | 626 ++++++++++++++++++ .../accessgraph/v1/secrets_service_grpc.pb.go | 262 ++++++++ .../access_graph/v1/authorized_key.proto | 46 ++ .../access_graph/v1/private_key.proto | 67 ++ .../access_graph/v1/secrets_service.proto | 101 +++ buf.yaml | 1 + 8 files changed, 1800 insertions(+) create mode 100644 api/gen/proto/go/teleport/accessgraph/v1/authorized_key.pb.go create mode 100644 api/gen/proto/go/teleport/accessgraph/v1/private_key.pb.go create mode 100644 api/gen/proto/go/teleport/accessgraph/v1/secrets_service.pb.go create mode 100644 api/gen/proto/go/teleport/accessgraph/v1/secrets_service_grpc.pb.go create mode 100644 api/proto/teleport/access_graph/v1/authorized_key.proto create mode 100644 api/proto/teleport/access_graph/v1/private_key.proto create mode 100644 api/proto/teleport/access_graph/v1/secrets_service.proto diff --git a/api/gen/proto/go/teleport/accessgraph/v1/authorized_key.pb.go b/api/gen/proto/go/teleport/accessgraph/v1/authorized_key.pb.go new file mode 100644 index 0000000000000..4d7e460994779 --- /dev/null +++ b/api/gen/proto/go/teleport/accessgraph/v1/authorized_key.pb.go @@ -0,0 +1,307 @@ +// Copyright 2024 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. + +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.34.2 +// protoc (unknown) +// source: teleport/access_graph/v1/authorized_key.proto + +package accessgraphv1 + +import ( + v1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/header/v1" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// The `AuthorizedKey` message represents an authorized key entry for a specific local user. +// These authorized keys are generated by the server when a particular SSH AuthorizedKey is granted access to a user on the node. +type AuthorizedKey struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // metadata is the AuthorizedKey's metadata. + Metadata *v1.Metadata `protobuf:"bytes,1,opt,name=metadata,proto3" json:"metadata,omitempty"` + // kind is a resource kind. + Kind string `protobuf:"bytes,2,opt,name=kind,proto3" json:"kind,omitempty"` + // sub_kind is an optional resource sub kind, used in some resources. + SubKind string `protobuf:"bytes,3,opt,name=sub_kind,json=subKind,proto3" json:"sub_kind,omitempty"` + // version is version. + Version string `protobuf:"bytes,4,opt,name=version,proto3" json:"version,omitempty"` + // Spec is an AuthorizedKey specification. + Spec *AuthorizedKeySpec `protobuf:"bytes,5,opt,name=spec,proto3" json:"spec,omitempty"` +} + +func (x *AuthorizedKey) Reset() { + *x = AuthorizedKey{} + if protoimpl.UnsafeEnabled { + mi := &file_teleport_access_graph_v1_authorized_key_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *AuthorizedKey) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AuthorizedKey) ProtoMessage() {} + +func (x *AuthorizedKey) ProtoReflect() protoreflect.Message { + mi := &file_teleport_access_graph_v1_authorized_key_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AuthorizedKey.ProtoReflect.Descriptor instead. +func (*AuthorizedKey) Descriptor() ([]byte, []int) { + return file_teleport_access_graph_v1_authorized_key_proto_rawDescGZIP(), []int{0} +} + +func (x *AuthorizedKey) GetMetadata() *v1.Metadata { + if x != nil { + return x.Metadata + } + return nil +} + +func (x *AuthorizedKey) GetKind() string { + if x != nil { + return x.Kind + } + return "" +} + +func (x *AuthorizedKey) GetSubKind() string { + if x != nil { + return x.SubKind + } + return "" +} + +func (x *AuthorizedKey) GetVersion() string { + if x != nil { + return x.Version + } + return "" +} + +func (x *AuthorizedKey) GetSpec() *AuthorizedKeySpec { + if x != nil { + return x.Spec + } + return nil +} + +// AuthorizedKeySpec is the authorized key spec. +type AuthorizedKeySpec struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // host_id is the node identifier and must match the credentials used. + HostId string `protobuf:"bytes,1,opt,name=host_id,json=hostId,proto3" json:"host_id,omitempty"` + // key_fingerprint is the SHA256 SSH public key fingerprint. + KeyFingerprint string `protobuf:"bytes,2,opt,name=key_fingerprint,json=keyFingerprint,proto3" json:"key_fingerprint,omitempty"` + // host_user is the user who can be accessed using the fingerprint above. + HostUser string `protobuf:"bytes,3,opt,name=host_user,json=hostUser,proto3" json:"host_user,omitempty"` +} + +func (x *AuthorizedKeySpec) Reset() { + *x = AuthorizedKeySpec{} + if protoimpl.UnsafeEnabled { + mi := &file_teleport_access_graph_v1_authorized_key_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *AuthorizedKeySpec) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AuthorizedKeySpec) ProtoMessage() {} + +func (x *AuthorizedKeySpec) ProtoReflect() protoreflect.Message { + mi := &file_teleport_access_graph_v1_authorized_key_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AuthorizedKeySpec.ProtoReflect.Descriptor instead. +func (*AuthorizedKeySpec) Descriptor() ([]byte, []int) { + return file_teleport_access_graph_v1_authorized_key_proto_rawDescGZIP(), []int{1} +} + +func (x *AuthorizedKeySpec) GetHostId() string { + if x != nil { + return x.HostId + } + return "" +} + +func (x *AuthorizedKeySpec) GetKeyFingerprint() string { + if x != nil { + return x.KeyFingerprint + } + return "" +} + +func (x *AuthorizedKeySpec) GetHostUser() string { + if x != nil { + return x.HostUser + } + return "" +} + +var File_teleport_access_graph_v1_authorized_key_proto protoreflect.FileDescriptor + +var file_teleport_access_graph_v1_authorized_key_proto_rawDesc = []byte{ + 0x0a, 0x2d, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x61, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x5f, 0x67, 0x72, 0x61, 0x70, 0x68, 0x2f, 0x76, 0x31, 0x2f, 0x61, 0x75, 0x74, 0x68, 0x6f, + 0x72, 0x69, 0x7a, 0x65, 0x64, 0x5f, 0x6b, 0x65, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, + 0x18, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, + 0x5f, 0x67, 0x72, 0x61, 0x70, 0x68, 0x2e, 0x76, 0x31, 0x1a, 0x21, 0x74, 0x65, 0x6c, 0x65, 0x70, + 0x6f, 0x72, 0x74, 0x2f, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x2f, 0x76, 0x31, 0x2f, 0x6d, 0x65, + 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xd3, 0x01, 0x0a, + 0x0d, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x4b, 0x65, 0x79, 0x12, 0x38, + 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x1c, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x68, 0x65, 0x61, 0x64, + 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x08, + 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x12, 0x0a, 0x04, 0x6b, 0x69, 0x6e, 0x64, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x12, 0x19, 0x0a, 0x08, + 0x73, 0x75, 0x62, 0x5f, 0x6b, 0x69, 0x6e, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, + 0x73, 0x75, 0x62, 0x4b, 0x69, 0x6e, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, + 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, + 0x6e, 0x12, 0x3f, 0x0a, 0x04, 0x73, 0x70, 0x65, 0x63, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x2b, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x5f, 0x67, 0x72, 0x61, 0x70, 0x68, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x75, 0x74, 0x68, 0x6f, + 0x72, 0x69, 0x7a, 0x65, 0x64, 0x4b, 0x65, 0x79, 0x53, 0x70, 0x65, 0x63, 0x52, 0x04, 0x73, 0x70, + 0x65, 0x63, 0x22, 0x72, 0x0a, 0x11, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, + 0x4b, 0x65, 0x79, 0x53, 0x70, 0x65, 0x63, 0x12, 0x17, 0x0a, 0x07, 0x68, 0x6f, 0x73, 0x74, 0x5f, + 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x68, 0x6f, 0x73, 0x74, 0x49, 0x64, + 0x12, 0x27, 0x0a, 0x0f, 0x6b, 0x65, 0x79, 0x5f, 0x66, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, + 0x69, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x6b, 0x65, 0x79, 0x46, 0x69, + 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x68, 0x6f, 0x73, + 0x74, 0x5f, 0x75, 0x73, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x68, 0x6f, + 0x73, 0x74, 0x55, 0x73, 0x65, 0x72, 0x42, 0x5a, 0x5a, 0x58, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, + 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x72, 0x61, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x61, 0x6c, 0x2f, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x61, 0x70, 0x69, 0x2f, + 0x67, 0x65, 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x2f, 0x74, 0x65, 0x6c, + 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x67, 0x72, 0x61, 0x70, + 0x68, 0x2f, 0x76, 0x31, 0x3b, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x67, 0x72, 0x61, 0x70, 0x68, + 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_teleport_access_graph_v1_authorized_key_proto_rawDescOnce sync.Once + file_teleport_access_graph_v1_authorized_key_proto_rawDescData = file_teleport_access_graph_v1_authorized_key_proto_rawDesc +) + +func file_teleport_access_graph_v1_authorized_key_proto_rawDescGZIP() []byte { + file_teleport_access_graph_v1_authorized_key_proto_rawDescOnce.Do(func() { + file_teleport_access_graph_v1_authorized_key_proto_rawDescData = protoimpl.X.CompressGZIP(file_teleport_access_graph_v1_authorized_key_proto_rawDescData) + }) + return file_teleport_access_graph_v1_authorized_key_proto_rawDescData +} + +var file_teleport_access_graph_v1_authorized_key_proto_msgTypes = make([]protoimpl.MessageInfo, 2) +var file_teleport_access_graph_v1_authorized_key_proto_goTypes = []any{ + (*AuthorizedKey)(nil), // 0: teleport.access_graph.v1.AuthorizedKey + (*AuthorizedKeySpec)(nil), // 1: teleport.access_graph.v1.AuthorizedKeySpec + (*v1.Metadata)(nil), // 2: teleport.header.v1.Metadata +} +var file_teleport_access_graph_v1_authorized_key_proto_depIdxs = []int32{ + 2, // 0: teleport.access_graph.v1.AuthorizedKey.metadata:type_name -> teleport.header.v1.Metadata + 1, // 1: teleport.access_graph.v1.AuthorizedKey.spec:type_name -> teleport.access_graph.v1.AuthorizedKeySpec + 2, // [2:2] is the sub-list for method output_type + 2, // [2:2] is the sub-list for method input_type + 2, // [2:2] is the sub-list for extension type_name + 2, // [2:2] is the sub-list for extension extendee + 0, // [0:2] is the sub-list for field type_name +} + +func init() { file_teleport_access_graph_v1_authorized_key_proto_init() } +func file_teleport_access_graph_v1_authorized_key_proto_init() { + if File_teleport_access_graph_v1_authorized_key_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_teleport_access_graph_v1_authorized_key_proto_msgTypes[0].Exporter = func(v any, i int) any { + switch v := v.(*AuthorizedKey); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_teleport_access_graph_v1_authorized_key_proto_msgTypes[1].Exporter = func(v any, i int) any { + switch v := v.(*AuthorizedKeySpec); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_teleport_access_graph_v1_authorized_key_proto_rawDesc, + NumEnums: 0, + NumMessages: 2, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_teleport_access_graph_v1_authorized_key_proto_goTypes, + DependencyIndexes: file_teleport_access_graph_v1_authorized_key_proto_depIdxs, + MessageInfos: file_teleport_access_graph_v1_authorized_key_proto_msgTypes, + }.Build() + File_teleport_access_graph_v1_authorized_key_proto = out.File + file_teleport_access_graph_v1_authorized_key_proto_rawDesc = nil + file_teleport_access_graph_v1_authorized_key_proto_goTypes = nil + file_teleport_access_graph_v1_authorized_key_proto_depIdxs = nil +} diff --git a/api/gen/proto/go/teleport/accessgraph/v1/private_key.pb.go b/api/gen/proto/go/teleport/accessgraph/v1/private_key.pb.go new file mode 100644 index 0000000000000..26e65b85e5eed --- /dev/null +++ b/api/gen/proto/go/teleport/accessgraph/v1/private_key.pb.go @@ -0,0 +1,390 @@ +// Copyright 2024 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. + +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.34.2 +// protoc (unknown) +// source: teleport/access_graph/v1/private_key.proto + +package accessgraphv1 + +import ( + v1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/header/v1" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// PublicKeyMode is the mode of the public key. +// The public key can be derived from the private key, stored in a separate file, or the private key was password protected +// and we could not extract the public key from it or from the file. +type PublicKeyMode int32 + +const ( + // PUBLIC_KEY_MODE_UNSPECIFIED is an invalid state. + PublicKeyMode_PUBLIC_KEY_MODE_UNSPECIFIED PublicKeyMode = 0 + // PUBLIC_KEY_MODE_DERIVED is the state where the public key is derived from the private key. + PublicKeyMode_PUBLIC_KEY_MODE_DERIVED PublicKeyMode = 1 + // PUBLIC_KEY_MODE_PUB_FILE is a state where the public key is stored in a separate file from the private key. + // The private key is password protected and we could not extract the public key from it. + // This mode is used when the private key is password protected and there is a .pub file next to the private key + // that contains the public key. + PublicKeyMode_PUBLIC_KEY_MODE_PUB_FILE PublicKeyMode = 2 + // PUBLIC_KEY_MODE_PROTECTED is a state where the private key is password protected and we could not extract the public key from it + // or from the .pub file. + PublicKeyMode_PUBLIC_KEY_MODE_PROTECTED PublicKeyMode = 3 +) + +// Enum value maps for PublicKeyMode. +var ( + PublicKeyMode_name = map[int32]string{ + 0: "PUBLIC_KEY_MODE_UNSPECIFIED", + 1: "PUBLIC_KEY_MODE_DERIVED", + 2: "PUBLIC_KEY_MODE_PUB_FILE", + 3: "PUBLIC_KEY_MODE_PROTECTED", + } + PublicKeyMode_value = map[string]int32{ + "PUBLIC_KEY_MODE_UNSPECIFIED": 0, + "PUBLIC_KEY_MODE_DERIVED": 1, + "PUBLIC_KEY_MODE_PUB_FILE": 2, + "PUBLIC_KEY_MODE_PROTECTED": 3, + } +) + +func (x PublicKeyMode) Enum() *PublicKeyMode { + p := new(PublicKeyMode) + *p = x + return p +} + +func (x PublicKeyMode) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (PublicKeyMode) Descriptor() protoreflect.EnumDescriptor { + return file_teleport_access_graph_v1_private_key_proto_enumTypes[0].Descriptor() +} + +func (PublicKeyMode) Type() protoreflect.EnumType { + return &file_teleport_access_graph_v1_private_key_proto_enumTypes[0] +} + +func (x PublicKeyMode) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use PublicKeyMode.Descriptor instead. +func (PublicKeyMode) EnumDescriptor() ([]byte, []int) { + return file_teleport_access_graph_v1_private_key_proto_rawDescGZIP(), []int{0} +} + +// The `PrivateKey` message represents a private key entry for a specific local user. +// It serves as a reference to a private key located on a user's laptop. Note that it *NEVER* contains the private key itself. +// Instead, it stores metadata related to the key, including the fingerprint of the public key, the device trust identifier, and the public key mode. +// The Teleport Access Graph uses this metadata to assess whether a particular private key is authorized to access a user on the node without using Teleport. +type PrivateKey struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // metadata is the PrivateKey's metadata. + Metadata *v1.Metadata `protobuf:"bytes,1,opt,name=metadata,proto3" json:"metadata,omitempty"` + // kind is a resource kind. + Kind string `protobuf:"bytes,2,opt,name=kind,proto3" json:"kind,omitempty"` + // sub_kind is an optional resource sub kind, used in some resources. + SubKind string `protobuf:"bytes,3,opt,name=sub_kind,json=subKind,proto3" json:"sub_kind,omitempty"` + // version is version. + Version string `protobuf:"bytes,4,opt,name=version,proto3" json:"version,omitempty"` + // Spec is a PrivateKey specification. + Spec *PrivateKeySpec `protobuf:"bytes,5,opt,name=spec,proto3" json:"spec,omitempty"` +} + +func (x *PrivateKey) Reset() { + *x = PrivateKey{} + if protoimpl.UnsafeEnabled { + mi := &file_teleport_access_graph_v1_private_key_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PrivateKey) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PrivateKey) ProtoMessage() {} + +func (x *PrivateKey) ProtoReflect() protoreflect.Message { + mi := &file_teleport_access_graph_v1_private_key_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PrivateKey.ProtoReflect.Descriptor instead. +func (*PrivateKey) Descriptor() ([]byte, []int) { + return file_teleport_access_graph_v1_private_key_proto_rawDescGZIP(), []int{0} +} + +func (x *PrivateKey) GetMetadata() *v1.Metadata { + if x != nil { + return x.Metadata + } + return nil +} + +func (x *PrivateKey) GetKind() string { + if x != nil { + return x.Kind + } + return "" +} + +func (x *PrivateKey) GetSubKind() string { + if x != nil { + return x.SubKind + } + return "" +} + +func (x *PrivateKey) GetVersion() string { + if x != nil { + return x.Version + } + return "" +} + +func (x *PrivateKey) GetSpec() *PrivateKeySpec { + if x != nil { + return x.Spec + } + return nil +} + +// PrivateKeySpec is the private key spec. +type PrivateKeySpec struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // device_id is the device trust identifier of the device that owns the key. + DeviceId string `protobuf:"bytes,1,opt,name=device_id,json=deviceId,proto3" json:"device_id,omitempty"` + // public_key_fingerprint is the SHA256 of the SSH public key corresponding to + // the private key. + PublicKeyFingerprint string `protobuf:"bytes,2,opt,name=public_key_fingerprint,json=publicKeyFingerprint,proto3" json:"public_key_fingerprint,omitempty"` + // public_key_mode is the public key mode. + PublicKeyMode PublicKeyMode `protobuf:"varint,3,opt,name=public_key_mode,json=publicKeyMode,proto3,enum=teleport.access_graph.v1.PublicKeyMode" json:"public_key_mode,omitempty"` +} + +func (x *PrivateKeySpec) Reset() { + *x = PrivateKeySpec{} + if protoimpl.UnsafeEnabled { + mi := &file_teleport_access_graph_v1_private_key_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PrivateKeySpec) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PrivateKeySpec) ProtoMessage() {} + +func (x *PrivateKeySpec) ProtoReflect() protoreflect.Message { + mi := &file_teleport_access_graph_v1_private_key_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PrivateKeySpec.ProtoReflect.Descriptor instead. +func (*PrivateKeySpec) Descriptor() ([]byte, []int) { + return file_teleport_access_graph_v1_private_key_proto_rawDescGZIP(), []int{1} +} + +func (x *PrivateKeySpec) GetDeviceId() string { + if x != nil { + return x.DeviceId + } + return "" +} + +func (x *PrivateKeySpec) GetPublicKeyFingerprint() string { + if x != nil { + return x.PublicKeyFingerprint + } + return "" +} + +func (x *PrivateKeySpec) GetPublicKeyMode() PublicKeyMode { + if x != nil { + return x.PublicKeyMode + } + return PublicKeyMode_PUBLIC_KEY_MODE_UNSPECIFIED +} + +var File_teleport_access_graph_v1_private_key_proto protoreflect.FileDescriptor + +var file_teleport_access_graph_v1_private_key_proto_rawDesc = []byte{ + 0x0a, 0x2a, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x61, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x5f, 0x67, 0x72, 0x61, 0x70, 0x68, 0x2f, 0x76, 0x31, 0x2f, 0x70, 0x72, 0x69, 0x76, 0x61, + 0x74, 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x18, 0x74, 0x65, + 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x67, 0x72, + 0x61, 0x70, 0x68, 0x2e, 0x76, 0x31, 0x1a, 0x21, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, + 0x2f, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x2f, 0x76, 0x31, 0x2f, 0x6d, 0x65, 0x74, 0x61, 0x64, + 0x61, 0x74, 0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xcd, 0x01, 0x0a, 0x0a, 0x50, 0x72, + 0x69, 0x76, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x12, 0x38, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, + 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x74, 0x65, 0x6c, + 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, + 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, + 0x74, 0x61, 0x12, 0x12, 0x0a, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x73, 0x75, 0x62, 0x5f, 0x6b, 0x69, + 0x6e, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x75, 0x62, 0x4b, 0x69, 0x6e, + 0x64, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x3c, 0x0a, 0x04, 0x73, + 0x70, 0x65, 0x63, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x74, 0x65, 0x6c, 0x65, + 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x67, 0x72, 0x61, 0x70, + 0x68, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x53, + 0x70, 0x65, 0x63, 0x52, 0x04, 0x73, 0x70, 0x65, 0x63, 0x22, 0xb4, 0x01, 0x0a, 0x0e, 0x50, 0x72, + 0x69, 0x76, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x53, 0x70, 0x65, 0x63, 0x12, 0x1b, 0x0a, 0x09, + 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x08, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x49, 0x64, 0x12, 0x34, 0x0a, 0x16, 0x70, 0x75, 0x62, + 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x66, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, + 0x69, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x14, 0x70, 0x75, 0x62, 0x6c, 0x69, + 0x63, 0x4b, 0x65, 0x79, 0x46, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x12, + 0x4f, 0x0a, 0x0f, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x6d, 0x6f, + 0x64, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x27, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, + 0x6f, 0x72, 0x74, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x67, 0x72, 0x61, 0x70, 0x68, + 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x4d, 0x6f, 0x64, + 0x65, 0x52, 0x0d, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x4d, 0x6f, 0x64, 0x65, + 0x2a, 0x8a, 0x01, 0x0a, 0x0d, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x4d, 0x6f, + 0x64, 0x65, 0x12, 0x1f, 0x0a, 0x1b, 0x50, 0x55, 0x42, 0x4c, 0x49, 0x43, 0x5f, 0x4b, 0x45, 0x59, + 0x5f, 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, + 0x44, 0x10, 0x00, 0x12, 0x1b, 0x0a, 0x17, 0x50, 0x55, 0x42, 0x4c, 0x49, 0x43, 0x5f, 0x4b, 0x45, + 0x59, 0x5f, 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x44, 0x45, 0x52, 0x49, 0x56, 0x45, 0x44, 0x10, 0x01, + 0x12, 0x1c, 0x0a, 0x18, 0x50, 0x55, 0x42, 0x4c, 0x49, 0x43, 0x5f, 0x4b, 0x45, 0x59, 0x5f, 0x4d, + 0x4f, 0x44, 0x45, 0x5f, 0x50, 0x55, 0x42, 0x5f, 0x46, 0x49, 0x4c, 0x45, 0x10, 0x02, 0x12, 0x1d, + 0x0a, 0x19, 0x50, 0x55, 0x42, 0x4c, 0x49, 0x43, 0x5f, 0x4b, 0x45, 0x59, 0x5f, 0x4d, 0x4f, 0x44, + 0x45, 0x5f, 0x50, 0x52, 0x4f, 0x54, 0x45, 0x43, 0x54, 0x45, 0x44, 0x10, 0x03, 0x42, 0x5a, 0x5a, + 0x58, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x72, 0x61, 0x76, + 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x2f, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, + 0x72, 0x74, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x2f, 0x67, 0x6f, 0x2f, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x61, 0x63, 0x63, + 0x65, 0x73, 0x73, 0x67, 0x72, 0x61, 0x70, 0x68, 0x2f, 0x76, 0x31, 0x3b, 0x61, 0x63, 0x63, 0x65, + 0x73, 0x73, 0x67, 0x72, 0x61, 0x70, 0x68, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x33, +} + +var ( + file_teleport_access_graph_v1_private_key_proto_rawDescOnce sync.Once + file_teleport_access_graph_v1_private_key_proto_rawDescData = file_teleport_access_graph_v1_private_key_proto_rawDesc +) + +func file_teleport_access_graph_v1_private_key_proto_rawDescGZIP() []byte { + file_teleport_access_graph_v1_private_key_proto_rawDescOnce.Do(func() { + file_teleport_access_graph_v1_private_key_proto_rawDescData = protoimpl.X.CompressGZIP(file_teleport_access_graph_v1_private_key_proto_rawDescData) + }) + return file_teleport_access_graph_v1_private_key_proto_rawDescData +} + +var file_teleport_access_graph_v1_private_key_proto_enumTypes = make([]protoimpl.EnumInfo, 1) +var file_teleport_access_graph_v1_private_key_proto_msgTypes = make([]protoimpl.MessageInfo, 2) +var file_teleport_access_graph_v1_private_key_proto_goTypes = []any{ + (PublicKeyMode)(0), // 0: teleport.access_graph.v1.PublicKeyMode + (*PrivateKey)(nil), // 1: teleport.access_graph.v1.PrivateKey + (*PrivateKeySpec)(nil), // 2: teleport.access_graph.v1.PrivateKeySpec + (*v1.Metadata)(nil), // 3: teleport.header.v1.Metadata +} +var file_teleport_access_graph_v1_private_key_proto_depIdxs = []int32{ + 3, // 0: teleport.access_graph.v1.PrivateKey.metadata:type_name -> teleport.header.v1.Metadata + 2, // 1: teleport.access_graph.v1.PrivateKey.spec:type_name -> teleport.access_graph.v1.PrivateKeySpec + 0, // 2: teleport.access_graph.v1.PrivateKeySpec.public_key_mode:type_name -> teleport.access_graph.v1.PublicKeyMode + 3, // [3:3] is the sub-list for method output_type + 3, // [3:3] is the sub-list for method input_type + 3, // [3:3] is the sub-list for extension type_name + 3, // [3:3] is the sub-list for extension extendee + 0, // [0:3] is the sub-list for field type_name +} + +func init() { file_teleport_access_graph_v1_private_key_proto_init() } +func file_teleport_access_graph_v1_private_key_proto_init() { + if File_teleport_access_graph_v1_private_key_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_teleport_access_graph_v1_private_key_proto_msgTypes[0].Exporter = func(v any, i int) any { + switch v := v.(*PrivateKey); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_teleport_access_graph_v1_private_key_proto_msgTypes[1].Exporter = func(v any, i int) any { + switch v := v.(*PrivateKeySpec); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_teleport_access_graph_v1_private_key_proto_rawDesc, + NumEnums: 1, + NumMessages: 2, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_teleport_access_graph_v1_private_key_proto_goTypes, + DependencyIndexes: file_teleport_access_graph_v1_private_key_proto_depIdxs, + EnumInfos: file_teleport_access_graph_v1_private_key_proto_enumTypes, + MessageInfos: file_teleport_access_graph_v1_private_key_proto_msgTypes, + }.Build() + File_teleport_access_graph_v1_private_key_proto = out.File + file_teleport_access_graph_v1_private_key_proto_rawDesc = nil + file_teleport_access_graph_v1_private_key_proto_goTypes = nil + file_teleport_access_graph_v1_private_key_proto_depIdxs = nil +} diff --git a/api/gen/proto/go/teleport/accessgraph/v1/secrets_service.pb.go b/api/gen/proto/go/teleport/accessgraph/v1/secrets_service.pb.go new file mode 100644 index 0000000000000..0d2bd9af11f2b --- /dev/null +++ b/api/gen/proto/go/teleport/accessgraph/v1/secrets_service.pb.go @@ -0,0 +1,626 @@ +// Copyright 2024 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. + +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.34.2 +// protoc (unknown) +// source: teleport/access_graph/v1/secrets_service.proto + +package accessgraphv1 + +import ( + v1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/devicetrust/v1" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// OperationType is an enum that indicates the operation that the client wants to perform. +type OperationType int32 + +const ( + // OPERATION_TYPE_UNSPECIFIED is an unknown operation. + OperationType_OPERATION_TYPE_UNSPECIFIED OperationType = 0 + // OPERATION_TYPE_ADD is an operation that indicates that the client wants to add keys to the list. + OperationType_OPERATION_TYPE_ADD OperationType = 1 + // OPERATION_TYPE_SYNC is an operation that indicates that the client has sent all the keys and + // the server can proceed with the analysis. + OperationType_OPERATION_TYPE_SYNC OperationType = 2 +) + +// Enum value maps for OperationType. +var ( + OperationType_name = map[int32]string{ + 0: "OPERATION_TYPE_UNSPECIFIED", + 1: "OPERATION_TYPE_ADD", + 2: "OPERATION_TYPE_SYNC", + } + OperationType_value = map[string]int32{ + "OPERATION_TYPE_UNSPECIFIED": 0, + "OPERATION_TYPE_ADD": 1, + "OPERATION_TYPE_SYNC": 2, + } +) + +func (x OperationType) Enum() *OperationType { + p := new(OperationType) + *p = x + return p +} + +func (x OperationType) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (OperationType) Descriptor() protoreflect.EnumDescriptor { + return file_teleport_access_graph_v1_secrets_service_proto_enumTypes[0].Descriptor() +} + +func (OperationType) Type() protoreflect.EnumType { + return &file_teleport_access_graph_v1_secrets_service_proto_enumTypes[0] +} + +func (x OperationType) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use OperationType.Descriptor instead. +func (OperationType) EnumDescriptor() ([]byte, []int) { + return file_teleport_access_graph_v1_secrets_service_proto_rawDescGZIP(), []int{0} +} + +// ReportAuthorizedKeysRequest is used by Teleport nodes to report authorized keys +// that could be used to bypass Teleport. +type ReportAuthorizedKeysRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // keys is a list of authorized keys that could be used to bypass Teleport. + Keys []*AuthorizedKey `protobuf:"bytes,1,rep,name=keys,proto3" json:"keys,omitempty"` + // operation indicates the operation that the client wants to perform. + Operation OperationType `protobuf:"varint,2,opt,name=operation,proto3,enum=teleport.access_graph.v1.OperationType" json:"operation,omitempty"` +} + +func (x *ReportAuthorizedKeysRequest) Reset() { + *x = ReportAuthorizedKeysRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_teleport_access_graph_v1_secrets_service_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ReportAuthorizedKeysRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ReportAuthorizedKeysRequest) ProtoMessage() {} + +func (x *ReportAuthorizedKeysRequest) ProtoReflect() protoreflect.Message { + mi := &file_teleport_access_graph_v1_secrets_service_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ReportAuthorizedKeysRequest.ProtoReflect.Descriptor instead. +func (*ReportAuthorizedKeysRequest) Descriptor() ([]byte, []int) { + return file_teleport_access_graph_v1_secrets_service_proto_rawDescGZIP(), []int{0} +} + +func (x *ReportAuthorizedKeysRequest) GetKeys() []*AuthorizedKey { + if x != nil { + return x.Keys + } + return nil +} + +func (x *ReportAuthorizedKeysRequest) GetOperation() OperationType { + if x != nil { + return x.Operation + } + return OperationType_OPERATION_TYPE_UNSPECIFIED +} + +// ReportAuthorizedKeysResponse is the response from ReportAuthorizedKeys +// RPC method. +type ReportAuthorizedKeysResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *ReportAuthorizedKeysResponse) Reset() { + *x = ReportAuthorizedKeysResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_teleport_access_graph_v1_secrets_service_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ReportAuthorizedKeysResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ReportAuthorizedKeysResponse) ProtoMessage() {} + +func (x *ReportAuthorizedKeysResponse) ProtoReflect() protoreflect.Message { + mi := &file_teleport_access_graph_v1_secrets_service_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ReportAuthorizedKeysResponse.ProtoReflect.Descriptor instead. +func (*ReportAuthorizedKeysResponse) Descriptor() ([]byte, []int) { + return file_teleport_access_graph_v1_secrets_service_proto_rawDescGZIP(), []int{1} +} + +// ReportSecretsRequest is used by trusted devices to report secrets found on the host +// that could be used to bypass Teleport. +type ReportSecretsRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Types that are assignable to Payload: + // + // *ReportSecretsRequest_DeviceAssertion + // *ReportSecretsRequest_PrivateKeys + Payload isReportSecretsRequest_Payload `protobuf_oneof:"payload"` +} + +func (x *ReportSecretsRequest) Reset() { + *x = ReportSecretsRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_teleport_access_graph_v1_secrets_service_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ReportSecretsRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ReportSecretsRequest) ProtoMessage() {} + +func (x *ReportSecretsRequest) ProtoReflect() protoreflect.Message { + mi := &file_teleport_access_graph_v1_secrets_service_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ReportSecretsRequest.ProtoReflect.Descriptor instead. +func (*ReportSecretsRequest) Descriptor() ([]byte, []int) { + return file_teleport_access_graph_v1_secrets_service_proto_rawDescGZIP(), []int{2} +} + +func (m *ReportSecretsRequest) GetPayload() isReportSecretsRequest_Payload { + if m != nil { + return m.Payload + } + return nil +} + +func (x *ReportSecretsRequest) GetDeviceAssertion() *v1.AssertDeviceRequest { + if x, ok := x.GetPayload().(*ReportSecretsRequest_DeviceAssertion); ok { + return x.DeviceAssertion + } + return nil +} + +func (x *ReportSecretsRequest) GetPrivateKeys() *ReportPrivateKeys { + if x, ok := x.GetPayload().(*ReportSecretsRequest_PrivateKeys); ok { + return x.PrivateKeys + } + return nil +} + +type isReportSecretsRequest_Payload interface { + isReportSecretsRequest_Payload() +} + +type ReportSecretsRequest_DeviceAssertion struct { + // The device should initiate the device assertion ceremony by sending the + // AssertDeviceRequest. Please refer to the [teleport.devicetrust.v1.AssertDeviceRequest] + // message for more details. + DeviceAssertion *v1.AssertDeviceRequest `protobuf:"bytes,1,opt,name=device_assertion,json=deviceAssertion,proto3,oneof"` +} + +type ReportSecretsRequest_PrivateKeys struct { + // private_keys is a list of private keys that were found on the device. + PrivateKeys *ReportPrivateKeys `protobuf:"bytes,4,opt,name=private_keys,json=privateKeys,proto3,oneof"` +} + +func (*ReportSecretsRequest_DeviceAssertion) isReportSecretsRequest_Payload() {} + +func (*ReportSecretsRequest_PrivateKeys) isReportSecretsRequest_Payload() {} + +// ReportPrivateKeys is used by trusted devices to report private keys found on the host +// that could be used to bypass Teleport. +type ReportPrivateKeys struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // keys is a list of private keys that could be used to bypass Teleport. + Keys []*PrivateKey `protobuf:"bytes,1,rep,name=keys,proto3" json:"keys,omitempty"` +} + +func (x *ReportPrivateKeys) Reset() { + *x = ReportPrivateKeys{} + if protoimpl.UnsafeEnabled { + mi := &file_teleport_access_graph_v1_secrets_service_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ReportPrivateKeys) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ReportPrivateKeys) ProtoMessage() {} + +func (x *ReportPrivateKeys) ProtoReflect() protoreflect.Message { + mi := &file_teleport_access_graph_v1_secrets_service_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ReportPrivateKeys.ProtoReflect.Descriptor instead. +func (*ReportPrivateKeys) Descriptor() ([]byte, []int) { + return file_teleport_access_graph_v1_secrets_service_proto_rawDescGZIP(), []int{3} +} + +func (x *ReportPrivateKeys) GetKeys() []*PrivateKey { + if x != nil { + return x.Keys + } + return nil +} + +// ReportSecretsResponse is the response from the ReportSecrets +// RPC method. +type ReportSecretsResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Types that are assignable to Payload: + // + // *ReportSecretsResponse_DeviceAssertion + Payload isReportSecretsResponse_Payload `protobuf_oneof:"payload"` +} + +func (x *ReportSecretsResponse) Reset() { + *x = ReportSecretsResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_teleport_access_graph_v1_secrets_service_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ReportSecretsResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ReportSecretsResponse) ProtoMessage() {} + +func (x *ReportSecretsResponse) ProtoReflect() protoreflect.Message { + mi := &file_teleport_access_graph_v1_secrets_service_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ReportSecretsResponse.ProtoReflect.Descriptor instead. +func (*ReportSecretsResponse) Descriptor() ([]byte, []int) { + return file_teleport_access_graph_v1_secrets_service_proto_rawDescGZIP(), []int{4} +} + +func (m *ReportSecretsResponse) GetPayload() isReportSecretsResponse_Payload { + if m != nil { + return m.Payload + } + return nil +} + +func (x *ReportSecretsResponse) GetDeviceAssertion() *v1.AssertDeviceResponse { + if x, ok := x.GetPayload().(*ReportSecretsResponse_DeviceAssertion); ok { + return x.DeviceAssertion + } + return nil +} + +type isReportSecretsResponse_Payload interface { + isReportSecretsResponse_Payload() +} + +type ReportSecretsResponse_DeviceAssertion struct { + // device_assertion is the response from the device assertion ceremony. + // Please refer to the [teleport.devicetrust.v1.AssertDeviceResponse] + // message for more details + DeviceAssertion *v1.AssertDeviceResponse `protobuf:"bytes,1,opt,name=device_assertion,json=deviceAssertion,proto3,oneof"` +} + +func (*ReportSecretsResponse_DeviceAssertion) isReportSecretsResponse_Payload() {} + +var File_teleport_access_graph_v1_secrets_service_proto protoreflect.FileDescriptor + +var file_teleport_access_graph_v1_secrets_service_proto_rawDesc = []byte{ + 0x0a, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x61, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x5f, 0x67, 0x72, 0x61, 0x70, 0x68, 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x65, 0x63, 0x72, 0x65, + 0x74, 0x73, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x12, 0x18, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x5f, 0x67, 0x72, 0x61, 0x70, 0x68, 0x2e, 0x76, 0x31, 0x1a, 0x2d, 0x74, 0x65, 0x6c, 0x65, + 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x67, 0x72, 0x61, 0x70, + 0x68, 0x2f, 0x76, 0x31, 0x2f, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x5f, + 0x6b, 0x65, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x2a, 0x74, 0x65, 0x6c, 0x65, 0x70, + 0x6f, 0x72, 0x74, 0x2f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x67, 0x72, 0x61, 0x70, 0x68, + 0x2f, 0x76, 0x31, 0x2f, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x24, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, + 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2f, 0x76, 0x31, 0x2f, 0x61, + 0x73, 0x73, 0x65, 0x72, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xa1, 0x01, 0x0a, 0x1b, + 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, + 0x4b, 0x65, 0x79, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3b, 0x0a, 0x04, 0x6b, + 0x65, 0x79, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x74, 0x65, 0x6c, 0x65, + 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x67, 0x72, 0x61, 0x70, + 0x68, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x4b, + 0x65, 0x79, 0x52, 0x04, 0x6b, 0x65, 0x79, 0x73, 0x12, 0x45, 0x0a, 0x09, 0x6f, 0x70, 0x65, 0x72, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x27, 0x2e, 0x74, 0x65, + 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x67, 0x72, + 0x61, 0x70, 0x68, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x54, 0x79, 0x70, 0x65, 0x52, 0x09, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, + 0x1e, 0x0a, 0x1c, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, + 0x7a, 0x65, 0x64, 0x4b, 0x65, 0x79, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, + 0xce, 0x01, 0x0a, 0x14, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, + 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x59, 0x0a, 0x10, 0x64, 0x65, 0x76, 0x69, + 0x63, 0x65, 0x5f, 0x61, 0x73, 0x73, 0x65, 0x72, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, + 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x73, 0x73, + 0x65, 0x72, 0x74, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x48, 0x00, 0x52, 0x0f, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x41, 0x73, 0x73, 0x65, 0x72, 0x74, + 0x69, 0x6f, 0x6e, 0x12, 0x50, 0x0a, 0x0c, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x5f, 0x6b, + 0x65, 0x79, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x74, 0x65, 0x6c, 0x65, + 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x67, 0x72, 0x61, 0x70, + 0x68, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x50, 0x72, 0x69, 0x76, 0x61, + 0x74, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x48, 0x00, 0x52, 0x0b, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, + 0x65, 0x4b, 0x65, 0x79, 0x73, 0x42, 0x09, 0x0a, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, + 0x22, 0x4d, 0x0a, 0x11, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x50, 0x72, 0x69, 0x76, 0x61, 0x74, + 0x65, 0x4b, 0x65, 0x79, 0x73, 0x12, 0x38, 0x0a, 0x04, 0x6b, 0x65, 0x79, 0x73, 0x18, 0x01, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x61, + 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x67, 0x72, 0x61, 0x70, 0x68, 0x2e, 0x76, 0x31, 0x2e, 0x50, + 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x52, 0x04, 0x6b, 0x65, 0x79, 0x73, 0x22, + 0x7e, 0x0a, 0x15, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x73, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5a, 0x0a, 0x10, 0x64, 0x65, 0x76, 0x69, + 0x63, 0x65, 0x5f, 0x61, 0x73, 0x73, 0x65, 0x72, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, + 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x73, 0x73, + 0x65, 0x72, 0x74, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x48, 0x00, 0x52, 0x0f, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x41, 0x73, 0x73, 0x65, 0x72, + 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x09, 0x0a, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x2a, + 0x60, 0x0a, 0x0d, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, + 0x12, 0x1e, 0x0a, 0x1a, 0x4f, 0x50, 0x45, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x54, 0x59, + 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, + 0x12, 0x16, 0x0a, 0x12, 0x4f, 0x50, 0x45, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x54, 0x59, + 0x50, 0x45, 0x5f, 0x41, 0x44, 0x44, 0x10, 0x01, 0x12, 0x17, 0x0a, 0x13, 0x4f, 0x50, 0x45, 0x52, + 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x53, 0x59, 0x4e, 0x43, 0x10, + 0x02, 0x32, 0x9d, 0x02, 0x0a, 0x15, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x73, 0x53, 0x63, 0x61, + 0x6e, 0x6e, 0x65, 0x72, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x8b, 0x01, 0x0a, 0x14, + 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, + 0x4b, 0x65, 0x79, 0x73, 0x12, 0x35, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, + 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x67, 0x72, 0x61, 0x70, 0x68, 0x2e, 0x76, 0x31, 0x2e, + 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, + 0x4b, 0x65, 0x79, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x36, 0x2e, 0x74, 0x65, + 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x67, 0x72, + 0x61, 0x70, 0x68, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x41, 0x75, 0x74, + 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x4b, 0x65, 0x79, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x00, 0x28, 0x01, 0x30, 0x01, 0x12, 0x76, 0x0a, 0x0d, 0x52, 0x65, 0x70, + 0x6f, 0x72, 0x74, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x73, 0x12, 0x2e, 0x2e, 0x74, 0x65, 0x6c, + 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x67, 0x72, 0x61, + 0x70, 0x68, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x53, 0x65, 0x63, 0x72, + 0x65, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2f, 0x2e, 0x74, 0x65, 0x6c, + 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x67, 0x72, 0x61, + 0x70, 0x68, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x53, 0x65, 0x63, 0x72, + 0x65, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x28, 0x01, 0x30, + 0x01, 0x42, 0x5a, 0x5a, 0x58, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, + 0x67, 0x72, 0x61, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x2f, 0x74, 0x65, + 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x2f, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, + 0x2f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x67, 0x72, 0x61, 0x70, 0x68, 0x2f, 0x76, 0x31, 0x3b, + 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x67, 0x72, 0x61, 0x70, 0x68, 0x76, 0x31, 0x62, 0x06, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_teleport_access_graph_v1_secrets_service_proto_rawDescOnce sync.Once + file_teleport_access_graph_v1_secrets_service_proto_rawDescData = file_teleport_access_graph_v1_secrets_service_proto_rawDesc +) + +func file_teleport_access_graph_v1_secrets_service_proto_rawDescGZIP() []byte { + file_teleport_access_graph_v1_secrets_service_proto_rawDescOnce.Do(func() { + file_teleport_access_graph_v1_secrets_service_proto_rawDescData = protoimpl.X.CompressGZIP(file_teleport_access_graph_v1_secrets_service_proto_rawDescData) + }) + return file_teleport_access_graph_v1_secrets_service_proto_rawDescData +} + +var file_teleport_access_graph_v1_secrets_service_proto_enumTypes = make([]protoimpl.EnumInfo, 1) +var file_teleport_access_graph_v1_secrets_service_proto_msgTypes = make([]protoimpl.MessageInfo, 5) +var file_teleport_access_graph_v1_secrets_service_proto_goTypes = []any{ + (OperationType)(0), // 0: teleport.access_graph.v1.OperationType + (*ReportAuthorizedKeysRequest)(nil), // 1: teleport.access_graph.v1.ReportAuthorizedKeysRequest + (*ReportAuthorizedKeysResponse)(nil), // 2: teleport.access_graph.v1.ReportAuthorizedKeysResponse + (*ReportSecretsRequest)(nil), // 3: teleport.access_graph.v1.ReportSecretsRequest + (*ReportPrivateKeys)(nil), // 4: teleport.access_graph.v1.ReportPrivateKeys + (*ReportSecretsResponse)(nil), // 5: teleport.access_graph.v1.ReportSecretsResponse + (*AuthorizedKey)(nil), // 6: teleport.access_graph.v1.AuthorizedKey + (*v1.AssertDeviceRequest)(nil), // 7: teleport.devicetrust.v1.AssertDeviceRequest + (*PrivateKey)(nil), // 8: teleport.access_graph.v1.PrivateKey + (*v1.AssertDeviceResponse)(nil), // 9: teleport.devicetrust.v1.AssertDeviceResponse +} +var file_teleport_access_graph_v1_secrets_service_proto_depIdxs = []int32{ + 6, // 0: teleport.access_graph.v1.ReportAuthorizedKeysRequest.keys:type_name -> teleport.access_graph.v1.AuthorizedKey + 0, // 1: teleport.access_graph.v1.ReportAuthorizedKeysRequest.operation:type_name -> teleport.access_graph.v1.OperationType + 7, // 2: teleport.access_graph.v1.ReportSecretsRequest.device_assertion:type_name -> teleport.devicetrust.v1.AssertDeviceRequest + 4, // 3: teleport.access_graph.v1.ReportSecretsRequest.private_keys:type_name -> teleport.access_graph.v1.ReportPrivateKeys + 8, // 4: teleport.access_graph.v1.ReportPrivateKeys.keys:type_name -> teleport.access_graph.v1.PrivateKey + 9, // 5: teleport.access_graph.v1.ReportSecretsResponse.device_assertion:type_name -> teleport.devicetrust.v1.AssertDeviceResponse + 1, // 6: teleport.access_graph.v1.SecretsScannerService.ReportAuthorizedKeys:input_type -> teleport.access_graph.v1.ReportAuthorizedKeysRequest + 3, // 7: teleport.access_graph.v1.SecretsScannerService.ReportSecrets:input_type -> teleport.access_graph.v1.ReportSecretsRequest + 2, // 8: teleport.access_graph.v1.SecretsScannerService.ReportAuthorizedKeys:output_type -> teleport.access_graph.v1.ReportAuthorizedKeysResponse + 5, // 9: teleport.access_graph.v1.SecretsScannerService.ReportSecrets:output_type -> teleport.access_graph.v1.ReportSecretsResponse + 8, // [8:10] is the sub-list for method output_type + 6, // [6:8] is the sub-list for method input_type + 6, // [6:6] is the sub-list for extension type_name + 6, // [6:6] is the sub-list for extension extendee + 0, // [0:6] is the sub-list for field type_name +} + +func init() { file_teleport_access_graph_v1_secrets_service_proto_init() } +func file_teleport_access_graph_v1_secrets_service_proto_init() { + if File_teleport_access_graph_v1_secrets_service_proto != nil { + return + } + file_teleport_access_graph_v1_authorized_key_proto_init() + file_teleport_access_graph_v1_private_key_proto_init() + if !protoimpl.UnsafeEnabled { + file_teleport_access_graph_v1_secrets_service_proto_msgTypes[0].Exporter = func(v any, i int) any { + switch v := v.(*ReportAuthorizedKeysRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_teleport_access_graph_v1_secrets_service_proto_msgTypes[1].Exporter = func(v any, i int) any { + switch v := v.(*ReportAuthorizedKeysResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_teleport_access_graph_v1_secrets_service_proto_msgTypes[2].Exporter = func(v any, i int) any { + switch v := v.(*ReportSecretsRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_teleport_access_graph_v1_secrets_service_proto_msgTypes[3].Exporter = func(v any, i int) any { + switch v := v.(*ReportPrivateKeys); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_teleport_access_graph_v1_secrets_service_proto_msgTypes[4].Exporter = func(v any, i int) any { + switch v := v.(*ReportSecretsResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + file_teleport_access_graph_v1_secrets_service_proto_msgTypes[2].OneofWrappers = []any{ + (*ReportSecretsRequest_DeviceAssertion)(nil), + (*ReportSecretsRequest_PrivateKeys)(nil), + } + file_teleport_access_graph_v1_secrets_service_proto_msgTypes[4].OneofWrappers = []any{ + (*ReportSecretsResponse_DeviceAssertion)(nil), + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_teleport_access_graph_v1_secrets_service_proto_rawDesc, + NumEnums: 1, + NumMessages: 5, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_teleport_access_graph_v1_secrets_service_proto_goTypes, + DependencyIndexes: file_teleport_access_graph_v1_secrets_service_proto_depIdxs, + EnumInfos: file_teleport_access_graph_v1_secrets_service_proto_enumTypes, + MessageInfos: file_teleport_access_graph_v1_secrets_service_proto_msgTypes, + }.Build() + File_teleport_access_graph_v1_secrets_service_proto = out.File + file_teleport_access_graph_v1_secrets_service_proto_rawDesc = nil + file_teleport_access_graph_v1_secrets_service_proto_goTypes = nil + file_teleport_access_graph_v1_secrets_service_proto_depIdxs = nil +} diff --git a/api/gen/proto/go/teleport/accessgraph/v1/secrets_service_grpc.pb.go b/api/gen/proto/go/teleport/accessgraph/v1/secrets_service_grpc.pb.go new file mode 100644 index 0000000000000..bc1e09264f36a --- /dev/null +++ b/api/gen/proto/go/teleport/accessgraph/v1/secrets_service_grpc.pb.go @@ -0,0 +1,262 @@ +// Copyright 2024 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. + +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.4.0 +// - protoc (unknown) +// source: teleport/access_graph/v1/secrets_service.proto + +package accessgraphv1 + +import ( + context "context" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.62.0 or later. +const _ = grpc.SupportPackageIsVersion8 + +const ( + SecretsScannerService_ReportAuthorizedKeys_FullMethodName = "/teleport.access_graph.v1.SecretsScannerService/ReportAuthorizedKeys" + SecretsScannerService_ReportSecrets_FullMethodName = "/teleport.access_graph.v1.SecretsScannerService/ReportSecrets" +) + +// SecretsScannerServiceClient is the client API for SecretsScannerService service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +// +// SecretsScannerService provides methods for Access Graph Secret Scanner functionality. +type SecretsScannerServiceClient interface { + // ReportAuthorizedKeys is used by Teleport SSH nodes to report authorized keys + // that could be used to bypass Teleport. + // The client (Teleport SSH Node) should authenticate using the certificate-key pair signed by Teleport HostCA. + ReportAuthorizedKeys(ctx context.Context, opts ...grpc.CallOption) (SecretsScannerService_ReportAuthorizedKeysClient, error) + // ReportSecrets is used by trusted devices to report secrets found on the host that could be used to bypass Teleport. + // The client (device) should first authenticate using the [ReportSecretsRequest.device_assertion] flow. Please refer to + // the [teleport.devicetrust.v1.AssertDeviceRequest] and [teleport.devicetrust.v1.AssertDeviceResponse] messages for more details. + // + // Once the device is asserted, the client can send the secrets using the [ReportSecretsRequest.private_keys] field + // and then close the client side of the stream. + // + // -> ReportSecrets (client) [1 or more] + // -> CloseStream (client) + // <- TerminateStream (server) + // + // Any failure in the assertion ceremony will result in the stream being terminated by the server. All secrets + // reported by the client before the assertion terminates will be ignored and result in the stream being terminated. + ReportSecrets(ctx context.Context, opts ...grpc.CallOption) (SecretsScannerService_ReportSecretsClient, error) +} + +type secretsScannerServiceClient struct { + cc grpc.ClientConnInterface +} + +func NewSecretsScannerServiceClient(cc grpc.ClientConnInterface) SecretsScannerServiceClient { + return &secretsScannerServiceClient{cc} +} + +func (c *secretsScannerServiceClient) ReportAuthorizedKeys(ctx context.Context, opts ...grpc.CallOption) (SecretsScannerService_ReportAuthorizedKeysClient, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + stream, err := c.cc.NewStream(ctx, &SecretsScannerService_ServiceDesc.Streams[0], SecretsScannerService_ReportAuthorizedKeys_FullMethodName, cOpts...) + if err != nil { + return nil, err + } + x := &secretsScannerServiceReportAuthorizedKeysClient{ClientStream: stream} + return x, nil +} + +type SecretsScannerService_ReportAuthorizedKeysClient interface { + Send(*ReportAuthorizedKeysRequest) error + Recv() (*ReportAuthorizedKeysResponse, error) + grpc.ClientStream +} + +type secretsScannerServiceReportAuthorizedKeysClient struct { + grpc.ClientStream +} + +func (x *secretsScannerServiceReportAuthorizedKeysClient) Send(m *ReportAuthorizedKeysRequest) error { + return x.ClientStream.SendMsg(m) +} + +func (x *secretsScannerServiceReportAuthorizedKeysClient) Recv() (*ReportAuthorizedKeysResponse, error) { + m := new(ReportAuthorizedKeysResponse) + if err := x.ClientStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + +func (c *secretsScannerServiceClient) ReportSecrets(ctx context.Context, opts ...grpc.CallOption) (SecretsScannerService_ReportSecretsClient, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + stream, err := c.cc.NewStream(ctx, &SecretsScannerService_ServiceDesc.Streams[1], SecretsScannerService_ReportSecrets_FullMethodName, cOpts...) + if err != nil { + return nil, err + } + x := &secretsScannerServiceReportSecretsClient{ClientStream: stream} + return x, nil +} + +type SecretsScannerService_ReportSecretsClient interface { + Send(*ReportSecretsRequest) error + Recv() (*ReportSecretsResponse, error) + grpc.ClientStream +} + +type secretsScannerServiceReportSecretsClient struct { + grpc.ClientStream +} + +func (x *secretsScannerServiceReportSecretsClient) Send(m *ReportSecretsRequest) error { + return x.ClientStream.SendMsg(m) +} + +func (x *secretsScannerServiceReportSecretsClient) Recv() (*ReportSecretsResponse, error) { + m := new(ReportSecretsResponse) + if err := x.ClientStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + +// SecretsScannerServiceServer is the server API for SecretsScannerService service. +// All implementations must embed UnimplementedSecretsScannerServiceServer +// for forward compatibility +// +// SecretsScannerService provides methods for Access Graph Secret Scanner functionality. +type SecretsScannerServiceServer interface { + // ReportAuthorizedKeys is used by Teleport SSH nodes to report authorized keys + // that could be used to bypass Teleport. + // The client (Teleport SSH Node) should authenticate using the certificate-key pair signed by Teleport HostCA. + ReportAuthorizedKeys(SecretsScannerService_ReportAuthorizedKeysServer) error + // ReportSecrets is used by trusted devices to report secrets found on the host that could be used to bypass Teleport. + // The client (device) should first authenticate using the [ReportSecretsRequest.device_assertion] flow. Please refer to + // the [teleport.devicetrust.v1.AssertDeviceRequest] and [teleport.devicetrust.v1.AssertDeviceResponse] messages for more details. + // + // Once the device is asserted, the client can send the secrets using the [ReportSecretsRequest.private_keys] field + // and then close the client side of the stream. + // + // -> ReportSecrets (client) [1 or more] + // -> CloseStream (client) + // <- TerminateStream (server) + // + // Any failure in the assertion ceremony will result in the stream being terminated by the server. All secrets + // reported by the client before the assertion terminates will be ignored and result in the stream being terminated. + ReportSecrets(SecretsScannerService_ReportSecretsServer) error + mustEmbedUnimplementedSecretsScannerServiceServer() +} + +// UnimplementedSecretsScannerServiceServer must be embedded to have forward compatible implementations. +type UnimplementedSecretsScannerServiceServer struct { +} + +func (UnimplementedSecretsScannerServiceServer) ReportAuthorizedKeys(SecretsScannerService_ReportAuthorizedKeysServer) error { + return status.Errorf(codes.Unimplemented, "method ReportAuthorizedKeys not implemented") +} +func (UnimplementedSecretsScannerServiceServer) ReportSecrets(SecretsScannerService_ReportSecretsServer) error { + return status.Errorf(codes.Unimplemented, "method ReportSecrets not implemented") +} +func (UnimplementedSecretsScannerServiceServer) mustEmbedUnimplementedSecretsScannerServiceServer() {} + +// UnsafeSecretsScannerServiceServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to SecretsScannerServiceServer will +// result in compilation errors. +type UnsafeSecretsScannerServiceServer interface { + mustEmbedUnimplementedSecretsScannerServiceServer() +} + +func RegisterSecretsScannerServiceServer(s grpc.ServiceRegistrar, srv SecretsScannerServiceServer) { + s.RegisterService(&SecretsScannerService_ServiceDesc, srv) +} + +func _SecretsScannerService_ReportAuthorizedKeys_Handler(srv interface{}, stream grpc.ServerStream) error { + return srv.(SecretsScannerServiceServer).ReportAuthorizedKeys(&secretsScannerServiceReportAuthorizedKeysServer{ServerStream: stream}) +} + +type SecretsScannerService_ReportAuthorizedKeysServer interface { + Send(*ReportAuthorizedKeysResponse) error + Recv() (*ReportAuthorizedKeysRequest, error) + grpc.ServerStream +} + +type secretsScannerServiceReportAuthorizedKeysServer struct { + grpc.ServerStream +} + +func (x *secretsScannerServiceReportAuthorizedKeysServer) Send(m *ReportAuthorizedKeysResponse) error { + return x.ServerStream.SendMsg(m) +} + +func (x *secretsScannerServiceReportAuthorizedKeysServer) Recv() (*ReportAuthorizedKeysRequest, error) { + m := new(ReportAuthorizedKeysRequest) + if err := x.ServerStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + +func _SecretsScannerService_ReportSecrets_Handler(srv interface{}, stream grpc.ServerStream) error { + return srv.(SecretsScannerServiceServer).ReportSecrets(&secretsScannerServiceReportSecretsServer{ServerStream: stream}) +} + +type SecretsScannerService_ReportSecretsServer interface { + Send(*ReportSecretsResponse) error + Recv() (*ReportSecretsRequest, error) + grpc.ServerStream +} + +type secretsScannerServiceReportSecretsServer struct { + grpc.ServerStream +} + +func (x *secretsScannerServiceReportSecretsServer) Send(m *ReportSecretsResponse) error { + return x.ServerStream.SendMsg(m) +} + +func (x *secretsScannerServiceReportSecretsServer) Recv() (*ReportSecretsRequest, error) { + m := new(ReportSecretsRequest) + if err := x.ServerStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + +// SecretsScannerService_ServiceDesc is the grpc.ServiceDesc for SecretsScannerService service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var SecretsScannerService_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "teleport.access_graph.v1.SecretsScannerService", + HandlerType: (*SecretsScannerServiceServer)(nil), + Methods: []grpc.MethodDesc{}, + Streams: []grpc.StreamDesc{ + { + StreamName: "ReportAuthorizedKeys", + Handler: _SecretsScannerService_ReportAuthorizedKeys_Handler, + ServerStreams: true, + ClientStreams: true, + }, + { + StreamName: "ReportSecrets", + Handler: _SecretsScannerService_ReportSecrets_Handler, + ServerStreams: true, + ClientStreams: true, + }, + }, + Metadata: "teleport/access_graph/v1/secrets_service.proto", +} diff --git a/api/proto/teleport/access_graph/v1/authorized_key.proto b/api/proto/teleport/access_graph/v1/authorized_key.proto new file mode 100644 index 0000000000000..15d95228b4897 --- /dev/null +++ b/api/proto/teleport/access_graph/v1/authorized_key.proto @@ -0,0 +1,46 @@ +// Copyright 2024 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. + +syntax = "proto3"; + +package teleport.access_graph.v1; + +import "teleport/header/v1/metadata.proto"; + +option go_package = "github.com/gravitational/teleport/api/gen/proto/go/teleport/accessgraph/v1;accessgraphv1"; + +// The `AuthorizedKey` message represents an authorized key entry for a specific local user. +// These authorized keys are generated by the server when a particular SSH AuthorizedKey is granted access to a user on the node. +message AuthorizedKey { + // metadata is the AuthorizedKey's metadata. + teleport.header.v1.Metadata metadata = 1; + // kind is a resource kind. + string kind = 2; + // sub_kind is an optional resource sub kind, used in some resources. + string sub_kind = 3; + // version is version. + string version = 4; + // Spec is an AuthorizedKey specification. + AuthorizedKeySpec spec = 5; +} + +// AuthorizedKeySpec is the authorized key spec. +message AuthorizedKeySpec { + // host_id is the node identifier and must match the credentials used. + string host_id = 1; + // key_fingerprint is the SHA256 SSH public key fingerprint. + string key_fingerprint = 2; + // host_user is the user who can be accessed using the fingerprint above. + string host_user = 3; +} diff --git a/api/proto/teleport/access_graph/v1/private_key.proto b/api/proto/teleport/access_graph/v1/private_key.proto new file mode 100644 index 0000000000000..239c515d89044 --- /dev/null +++ b/api/proto/teleport/access_graph/v1/private_key.proto @@ -0,0 +1,67 @@ +// Copyright 2024 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. + +syntax = "proto3"; + +package teleport.access_graph.v1; + +import "teleport/header/v1/metadata.proto"; + +option go_package = "github.com/gravitational/teleport/api/gen/proto/go/teleport/accessgraph/v1;accessgraphv1"; + +// The `PrivateKey` message represents a private key entry for a specific local user. +// It serves as a reference to a private key located on a user's laptop. Note that it *NEVER* contains the private key itself. +// Instead, it stores metadata related to the key, including the fingerprint of the public key, the device trust identifier, and the public key mode. +// The Teleport Access Graph uses this metadata to assess whether a particular private key is authorized to access a user on the node without using Teleport. +message PrivateKey { + // metadata is the PrivateKey's metadata. + teleport.header.v1.Metadata metadata = 1; + // kind is a resource kind. + string kind = 2; + // sub_kind is an optional resource sub kind, used in some resources. + string sub_kind = 3; + // version is version. + string version = 4; + // Spec is a PrivateKey specification. + PrivateKeySpec spec = 5; +} + +// PrivateKeySpec is the private key spec. +message PrivateKeySpec { + // device_id is the device trust identifier of the device that owns the key. + string device_id = 1; + // public_key_fingerprint is the SHA256 of the SSH public key corresponding to + // the private key. + string public_key_fingerprint = 2; + // public_key_mode is the public key mode. + PublicKeyMode public_key_mode = 3; +} + +// PublicKeyMode is the mode of the public key. +// The public key can be derived from the private key, stored in a separate file, or the private key was password protected +// and we could not extract the public key from it or from the file. +enum PublicKeyMode { + // PUBLIC_KEY_MODE_UNSPECIFIED is an invalid state. + PUBLIC_KEY_MODE_UNSPECIFIED = 0; + // PUBLIC_KEY_MODE_DERIVED is the state where the public key is derived from the private key. + PUBLIC_KEY_MODE_DERIVED = 1; + // PUBLIC_KEY_MODE_PUB_FILE is a state where the public key is stored in a separate file from the private key. + // The private key is password protected and we could not extract the public key from it. + // This mode is used when the private key is password protected and there is a .pub file next to the private key + // that contains the public key. + PUBLIC_KEY_MODE_PUB_FILE = 2; + // PUBLIC_KEY_MODE_PROTECTED is a state where the private key is password protected and we could not extract the public key from it + // or from the .pub file. + PUBLIC_KEY_MODE_PROTECTED = 3; +} diff --git a/api/proto/teleport/access_graph/v1/secrets_service.proto b/api/proto/teleport/access_graph/v1/secrets_service.proto new file mode 100644 index 0000000000000..7c2b3d49e6e76 --- /dev/null +++ b/api/proto/teleport/access_graph/v1/secrets_service.proto @@ -0,0 +1,101 @@ +// Copyright 2024 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. + +syntax = "proto3"; + +package teleport.access_graph.v1; + +import "teleport/access_graph/v1/authorized_key.proto"; +import "teleport/access_graph/v1/private_key.proto"; +import "teleport/devicetrust/v1/assert.proto"; + +option go_package = "github.com/gravitational/teleport/api/gen/proto/go/teleport/accessgraph/v1;accessgraphv1"; + +// SecretsScannerService provides methods for Access Graph Secret Scanner functionality. +service SecretsScannerService { + // ReportAuthorizedKeys is used by Teleport SSH nodes to report authorized keys + // that could be used to bypass Teleport. + // The client (Teleport SSH Node) should authenticate using the certificate-key pair signed by Teleport HostCA. + rpc ReportAuthorizedKeys(stream ReportAuthorizedKeysRequest) returns (stream ReportAuthorizedKeysResponse) {} + + // ReportSecrets is used by trusted devices to report secrets found on the host that could be used to bypass Teleport. + // The client (device) should first authenticate using the [ReportSecretsRequest.device_assertion] flow. Please refer to + // the [teleport.devicetrust.v1.AssertDeviceRequest] and [teleport.devicetrust.v1.AssertDeviceResponse] messages for more details. + // + // Once the device is asserted, the client can send the secrets using the [ReportSecretsRequest.private_keys] field + // and then close the client side of the stream. + // + // -> ReportSecrets (client) [1 or more] + // -> CloseStream (client) + // <- TerminateStream (server) + // + // Any failure in the assertion ceremony will result in the stream being terminated by the server. All secrets + // reported by the client before the assertion terminates will be ignored and result in the stream being terminated. + rpc ReportSecrets(stream ReportSecretsRequest) returns (stream ReportSecretsResponse) {} +} + +// ReportAuthorizedKeysRequest is used by Teleport nodes to report authorized keys +// that could be used to bypass Teleport. +message ReportAuthorizedKeysRequest { + // keys is a list of authorized keys that could be used to bypass Teleport. + repeated teleport.access_graph.v1.AuthorizedKey keys = 1; + // operation indicates the operation that the client wants to perform. + OperationType operation = 2; +} + +// ReportAuthorizedKeysResponse is the response from ReportAuthorizedKeys +// RPC method. +message ReportAuthorizedKeysResponse {} + +// ReportSecretsRequest is used by trusted devices to report secrets found on the host +// that could be used to bypass Teleport. +message ReportSecretsRequest { + oneof payload { + // The device should initiate the device assertion ceremony by sending the + // AssertDeviceRequest. Please refer to the [teleport.devicetrust.v1.AssertDeviceRequest] + // message for more details. + teleport.devicetrust.v1.AssertDeviceRequest device_assertion = 1; + // private_keys is a list of private keys that were found on the device. + ReportPrivateKeys private_keys = 4; + } +} + +// ReportPrivateKeys is used by trusted devices to report private keys found on the host +// that could be used to bypass Teleport. +message ReportPrivateKeys { + // keys is a list of private keys that could be used to bypass Teleport. + repeated teleport.access_graph.v1.PrivateKey keys = 1; +} + +// ReportSecretsResponse is the response from the ReportSecrets +// RPC method. +message ReportSecretsResponse { + oneof payload { + // device_assertion is the response from the device assertion ceremony. + // Please refer to the [teleport.devicetrust.v1.AssertDeviceResponse] + // message for more details + teleport.devicetrust.v1.AssertDeviceResponse device_assertion = 1; + } +} + +// OperationType is an enum that indicates the operation that the client wants to perform. +enum OperationType { + // OPERATION_TYPE_UNSPECIFIED is an unknown operation. + OPERATION_TYPE_UNSPECIFIED = 0; + // OPERATION_TYPE_ADD is an operation that indicates that the client wants to add keys to the list. + OPERATION_TYPE_ADD = 1; + // OPERATION_TYPE_SYNC is an operation that indicates that the client has sent all the keys and + // the server can proceed with the analysis. + OPERATION_TYPE_SYNC = 2; +} diff --git a/buf.yaml b/buf.yaml index 9ad6bb4013935..31fc097117d56 100644 --- a/buf.yaml +++ b/buf.yaml @@ -68,6 +68,7 @@ lint: - api/proto/teleport/devicetrust/v1/devicetrust_service.proto - api/proto/teleport/legacy/client/proto/joinservice.proto - api/proto/teleport/transport/v1/transport_service.proto + - api/proto/teleport/access_graph/v1/secrets_service.proto - proto/accessgraph/v1alpha/access_graph_service.proto - proto/teleport/lib/teleterm/v1/service.proto disallow_comment_ignores: true From f95e4d8f7221e6825f11ca7e6cc9dd851fd9e280 Mon Sep 17 00:00:00 2001 From: Tiago Silva Date: Tue, 9 Jul 2024 10:33:23 +0100 Subject: [PATCH 05/25] [sec_scan][2] expose `ssh_scan_enabled` in `AccessGraphConfig` response (#43467) This PR exposes the configuration for nodes to be aware that they should report SSH Authorized keys to Teleport. Part of https://github.com/gravitational/access-graph/issues/637 Signed-off-by: Tiago Silva --- .../accessgraph/v1/authorized_key.pb.go | 8 +- .../teleport/accessgraph/v1/private_key.pb.go | 8 +- .../accessgraph/v1/secrets_service.pb.go | 18 +-- .../accessgraph/v1/secrets_service_grpc.pb.go | 24 ++-- .../clusterconfig/v1/access_graph.pb.go | 130 ++++++++++++++---- .../clusterconfig/v1/access_graph.proto | 8 ++ 6 files changed, 141 insertions(+), 55 deletions(-) diff --git a/api/gen/proto/go/teleport/accessgraph/v1/authorized_key.pb.go b/api/gen/proto/go/teleport/accessgraph/v1/authorized_key.pb.go index 4d7e460994779..6ecdbf0e7b9d8 100644 --- a/api/gen/proto/go/teleport/accessgraph/v1/authorized_key.pb.go +++ b/api/gen/proto/go/teleport/accessgraph/v1/authorized_key.pb.go @@ -14,7 +14,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.34.2 +// protoc-gen-go v1.34.0 // protoc (unknown) // source: teleport/access_graph/v1/authorized_key.proto @@ -240,7 +240,7 @@ func file_teleport_access_graph_v1_authorized_key_proto_rawDescGZIP() []byte { } var file_teleport_access_graph_v1_authorized_key_proto_msgTypes = make([]protoimpl.MessageInfo, 2) -var file_teleport_access_graph_v1_authorized_key_proto_goTypes = []any{ +var file_teleport_access_graph_v1_authorized_key_proto_goTypes = []interface{}{ (*AuthorizedKey)(nil), // 0: teleport.access_graph.v1.AuthorizedKey (*AuthorizedKeySpec)(nil), // 1: teleport.access_graph.v1.AuthorizedKeySpec (*v1.Metadata)(nil), // 2: teleport.header.v1.Metadata @@ -261,7 +261,7 @@ func file_teleport_access_graph_v1_authorized_key_proto_init() { return } if !protoimpl.UnsafeEnabled { - file_teleport_access_graph_v1_authorized_key_proto_msgTypes[0].Exporter = func(v any, i int) any { + file_teleport_access_graph_v1_authorized_key_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*AuthorizedKey); i { case 0: return &v.state @@ -273,7 +273,7 @@ func file_teleport_access_graph_v1_authorized_key_proto_init() { return nil } } - file_teleport_access_graph_v1_authorized_key_proto_msgTypes[1].Exporter = func(v any, i int) any { + file_teleport_access_graph_v1_authorized_key_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*AuthorizedKeySpec); i { case 0: return &v.state diff --git a/api/gen/proto/go/teleport/accessgraph/v1/private_key.pb.go b/api/gen/proto/go/teleport/accessgraph/v1/private_key.pb.go index 26e65b85e5eed..e2d33a704c7e0 100644 --- a/api/gen/proto/go/teleport/accessgraph/v1/private_key.pb.go +++ b/api/gen/proto/go/teleport/accessgraph/v1/private_key.pb.go @@ -14,7 +14,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.34.2 +// protoc-gen-go v1.34.0 // protoc (unknown) // source: teleport/access_graph/v1/private_key.proto @@ -320,7 +320,7 @@ func file_teleport_access_graph_v1_private_key_proto_rawDescGZIP() []byte { var file_teleport_access_graph_v1_private_key_proto_enumTypes = make([]protoimpl.EnumInfo, 1) var file_teleport_access_graph_v1_private_key_proto_msgTypes = make([]protoimpl.MessageInfo, 2) -var file_teleport_access_graph_v1_private_key_proto_goTypes = []any{ +var file_teleport_access_graph_v1_private_key_proto_goTypes = []interface{}{ (PublicKeyMode)(0), // 0: teleport.access_graph.v1.PublicKeyMode (*PrivateKey)(nil), // 1: teleport.access_graph.v1.PrivateKey (*PrivateKeySpec)(nil), // 2: teleport.access_graph.v1.PrivateKeySpec @@ -343,7 +343,7 @@ func file_teleport_access_graph_v1_private_key_proto_init() { return } if !protoimpl.UnsafeEnabled { - file_teleport_access_graph_v1_private_key_proto_msgTypes[0].Exporter = func(v any, i int) any { + file_teleport_access_graph_v1_private_key_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*PrivateKey); i { case 0: return &v.state @@ -355,7 +355,7 @@ func file_teleport_access_graph_v1_private_key_proto_init() { return nil } } - file_teleport_access_graph_v1_private_key_proto_msgTypes[1].Exporter = func(v any, i int) any { + file_teleport_access_graph_v1_private_key_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*PrivateKeySpec); i { case 0: return &v.state diff --git a/api/gen/proto/go/teleport/accessgraph/v1/secrets_service.pb.go b/api/gen/proto/go/teleport/accessgraph/v1/secrets_service.pb.go index 0d2bd9af11f2b..954ea18e6d5af 100644 --- a/api/gen/proto/go/teleport/accessgraph/v1/secrets_service.pb.go +++ b/api/gen/proto/go/teleport/accessgraph/v1/secrets_service.pb.go @@ -14,7 +14,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.34.2 +// protoc-gen-go v1.34.0 // protoc (unknown) // source: teleport/access_graph/v1/secrets_service.proto @@ -498,7 +498,7 @@ func file_teleport_access_graph_v1_secrets_service_proto_rawDescGZIP() []byte { var file_teleport_access_graph_v1_secrets_service_proto_enumTypes = make([]protoimpl.EnumInfo, 1) var file_teleport_access_graph_v1_secrets_service_proto_msgTypes = make([]protoimpl.MessageInfo, 5) -var file_teleport_access_graph_v1_secrets_service_proto_goTypes = []any{ +var file_teleport_access_graph_v1_secrets_service_proto_goTypes = []interface{}{ (OperationType)(0), // 0: teleport.access_graph.v1.OperationType (*ReportAuthorizedKeysRequest)(nil), // 1: teleport.access_graph.v1.ReportAuthorizedKeysRequest (*ReportAuthorizedKeysResponse)(nil), // 2: teleport.access_graph.v1.ReportAuthorizedKeysResponse @@ -536,7 +536,7 @@ func file_teleport_access_graph_v1_secrets_service_proto_init() { file_teleport_access_graph_v1_authorized_key_proto_init() file_teleport_access_graph_v1_private_key_proto_init() if !protoimpl.UnsafeEnabled { - file_teleport_access_graph_v1_secrets_service_proto_msgTypes[0].Exporter = func(v any, i int) any { + file_teleport_access_graph_v1_secrets_service_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ReportAuthorizedKeysRequest); i { case 0: return &v.state @@ -548,7 +548,7 @@ func file_teleport_access_graph_v1_secrets_service_proto_init() { return nil } } - file_teleport_access_graph_v1_secrets_service_proto_msgTypes[1].Exporter = func(v any, i int) any { + file_teleport_access_graph_v1_secrets_service_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ReportAuthorizedKeysResponse); i { case 0: return &v.state @@ -560,7 +560,7 @@ func file_teleport_access_graph_v1_secrets_service_proto_init() { return nil } } - file_teleport_access_graph_v1_secrets_service_proto_msgTypes[2].Exporter = func(v any, i int) any { + file_teleport_access_graph_v1_secrets_service_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ReportSecretsRequest); i { case 0: return &v.state @@ -572,7 +572,7 @@ func file_teleport_access_graph_v1_secrets_service_proto_init() { return nil } } - file_teleport_access_graph_v1_secrets_service_proto_msgTypes[3].Exporter = func(v any, i int) any { + file_teleport_access_graph_v1_secrets_service_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ReportPrivateKeys); i { case 0: return &v.state @@ -584,7 +584,7 @@ func file_teleport_access_graph_v1_secrets_service_proto_init() { return nil } } - file_teleport_access_graph_v1_secrets_service_proto_msgTypes[4].Exporter = func(v any, i int) any { + file_teleport_access_graph_v1_secrets_service_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ReportSecretsResponse); i { case 0: return &v.state @@ -597,11 +597,11 @@ func file_teleport_access_graph_v1_secrets_service_proto_init() { } } } - file_teleport_access_graph_v1_secrets_service_proto_msgTypes[2].OneofWrappers = []any{ + file_teleport_access_graph_v1_secrets_service_proto_msgTypes[2].OneofWrappers = []interface{}{ (*ReportSecretsRequest_DeviceAssertion)(nil), (*ReportSecretsRequest_PrivateKeys)(nil), } - file_teleport_access_graph_v1_secrets_service_proto_msgTypes[4].OneofWrappers = []any{ + file_teleport_access_graph_v1_secrets_service_proto_msgTypes[4].OneofWrappers = []interface{}{ (*ReportSecretsResponse_DeviceAssertion)(nil), } type x struct{} diff --git a/api/gen/proto/go/teleport/accessgraph/v1/secrets_service_grpc.pb.go b/api/gen/proto/go/teleport/accessgraph/v1/secrets_service_grpc.pb.go index bc1e09264f36a..f93b2d48d0bda 100644 --- a/api/gen/proto/go/teleport/accessgraph/v1/secrets_service_grpc.pb.go +++ b/api/gen/proto/go/teleport/accessgraph/v1/secrets_service_grpc.pb.go @@ -14,7 +14,7 @@ // Code generated by protoc-gen-go-grpc. DO NOT EDIT. // versions: -// - protoc-gen-go-grpc v1.4.0 +// - protoc-gen-go-grpc v1.3.0 // - protoc (unknown) // source: teleport/access_graph/v1/secrets_service.proto @@ -29,8 +29,8 @@ import ( // This is a compile-time assertion to ensure that this generated file // is compatible with the grpc package it is being compiled against. -// Requires gRPC-Go v1.62.0 or later. -const _ = grpc.SupportPackageIsVersion8 +// Requires gRPC-Go v1.32.0 or later. +const _ = grpc.SupportPackageIsVersion7 const ( SecretsScannerService_ReportAuthorizedKeys_FullMethodName = "/teleport.access_graph.v1.SecretsScannerService/ReportAuthorizedKeys" @@ -40,8 +40,6 @@ const ( // SecretsScannerServiceClient is the client API for SecretsScannerService service. // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. -// -// SecretsScannerService provides methods for Access Graph Secret Scanner functionality. type SecretsScannerServiceClient interface { // ReportAuthorizedKeys is used by Teleport SSH nodes to report authorized keys // that could be used to bypass Teleport. @@ -72,12 +70,11 @@ func NewSecretsScannerServiceClient(cc grpc.ClientConnInterface) SecretsScannerS } func (c *secretsScannerServiceClient) ReportAuthorizedKeys(ctx context.Context, opts ...grpc.CallOption) (SecretsScannerService_ReportAuthorizedKeysClient, error) { - cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) - stream, err := c.cc.NewStream(ctx, &SecretsScannerService_ServiceDesc.Streams[0], SecretsScannerService_ReportAuthorizedKeys_FullMethodName, cOpts...) + stream, err := c.cc.NewStream(ctx, &SecretsScannerService_ServiceDesc.Streams[0], SecretsScannerService_ReportAuthorizedKeys_FullMethodName, opts...) if err != nil { return nil, err } - x := &secretsScannerServiceReportAuthorizedKeysClient{ClientStream: stream} + x := &secretsScannerServiceReportAuthorizedKeysClient{stream} return x, nil } @@ -104,12 +101,11 @@ func (x *secretsScannerServiceReportAuthorizedKeysClient) Recv() (*ReportAuthori } func (c *secretsScannerServiceClient) ReportSecrets(ctx context.Context, opts ...grpc.CallOption) (SecretsScannerService_ReportSecretsClient, error) { - cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) - stream, err := c.cc.NewStream(ctx, &SecretsScannerService_ServiceDesc.Streams[1], SecretsScannerService_ReportSecrets_FullMethodName, cOpts...) + stream, err := c.cc.NewStream(ctx, &SecretsScannerService_ServiceDesc.Streams[1], SecretsScannerService_ReportSecrets_FullMethodName, opts...) if err != nil { return nil, err } - x := &secretsScannerServiceReportSecretsClient{ClientStream: stream} + x := &secretsScannerServiceReportSecretsClient{stream} return x, nil } @@ -138,8 +134,6 @@ func (x *secretsScannerServiceReportSecretsClient) Recv() (*ReportSecretsRespons // SecretsScannerServiceServer is the server API for SecretsScannerService service. // All implementations must embed UnimplementedSecretsScannerServiceServer // for forward compatibility -// -// SecretsScannerService provides methods for Access Graph Secret Scanner functionality. type SecretsScannerServiceServer interface { // ReportAuthorizedKeys is used by Teleport SSH nodes to report authorized keys // that could be used to bypass Teleport. @@ -186,7 +180,7 @@ func RegisterSecretsScannerServiceServer(s grpc.ServiceRegistrar, srv SecretsSca } func _SecretsScannerService_ReportAuthorizedKeys_Handler(srv interface{}, stream grpc.ServerStream) error { - return srv.(SecretsScannerServiceServer).ReportAuthorizedKeys(&secretsScannerServiceReportAuthorizedKeysServer{ServerStream: stream}) + return srv.(SecretsScannerServiceServer).ReportAuthorizedKeys(&secretsScannerServiceReportAuthorizedKeysServer{stream}) } type SecretsScannerService_ReportAuthorizedKeysServer interface { @@ -212,7 +206,7 @@ func (x *secretsScannerServiceReportAuthorizedKeysServer) Recv() (*ReportAuthori } func _SecretsScannerService_ReportSecrets_Handler(srv interface{}, stream grpc.ServerStream) error { - return srv.(SecretsScannerServiceServer).ReportSecrets(&secretsScannerServiceReportSecretsServer{ServerStream: stream}) + return srv.(SecretsScannerServiceServer).ReportSecrets(&secretsScannerServiceReportSecretsServer{stream}) } type SecretsScannerService_ReportSecretsServer interface { diff --git a/api/gen/proto/go/teleport/clusterconfig/v1/access_graph.pb.go b/api/gen/proto/go/teleport/clusterconfig/v1/access_graph.pb.go index e3eaae3aaa046..263c852cdf155 100644 --- a/api/gen/proto/go/teleport/clusterconfig/v1/access_graph.pb.go +++ b/api/gen/proto/go/teleport/clusterconfig/v1/access_graph.pb.go @@ -50,6 +50,8 @@ type AccessGraphConfig struct { // insecure is a flag that indicates whether the access graph service should // skip verifying the server's certificate chain and host name. Insecure bool `protobuf:"varint,4,opt,name=insecure,proto3" json:"insecure,omitempty"` + // secrets_scan_config is used to configure the parameters for the secrets scanning functionality. + SecretsScanConfig *AccessGraphSecretsScanConfiguration `protobuf:"bytes,5,opt,name=secrets_scan_config,json=secretsScanConfig,proto3" json:"secrets_scan_config,omitempty"` } func (x *AccessGraphConfig) Reset() { @@ -112,6 +114,62 @@ func (x *AccessGraphConfig) GetInsecure() bool { return false } +func (x *AccessGraphConfig) GetSecretsScanConfig() *AccessGraphSecretsScanConfiguration { + if x != nil { + return x.SecretsScanConfig + } + return nil +} + +// AccessGraphSecretsScanConfiguration controls the secrets scanning service parameters. +type AccessGraphSecretsScanConfiguration struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // ssh_scan_enabled indicates if the SSH scan feature is enabled for the cluster. + SshScanEnabled bool `protobuf:"varint,1,opt,name=ssh_scan_enabled,json=sshScanEnabled,proto3" json:"ssh_scan_enabled,omitempty"` +} + +func (x *AccessGraphSecretsScanConfiguration) Reset() { + *x = AccessGraphSecretsScanConfiguration{} + if protoimpl.UnsafeEnabled { + mi := &file_teleport_clusterconfig_v1_access_graph_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *AccessGraphSecretsScanConfiguration) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AccessGraphSecretsScanConfiguration) ProtoMessage() {} + +func (x *AccessGraphSecretsScanConfiguration) ProtoReflect() protoreflect.Message { + mi := &file_teleport_clusterconfig_v1_access_graph_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AccessGraphSecretsScanConfiguration.ProtoReflect.Descriptor instead. +func (*AccessGraphSecretsScanConfiguration) Descriptor() ([]byte, []int) { + return file_teleport_clusterconfig_v1_access_graph_proto_rawDescGZIP(), []int{1} +} + +func (x *AccessGraphSecretsScanConfiguration) GetSshScanEnabled() bool { + if x != nil { + return x.SshScanEnabled + } + return false +} + var File_teleport_clusterconfig_v1_access_graph_proto protoreflect.FileDescriptor var file_teleport_clusterconfig_v1_access_graph_proto_rawDesc = []byte{ @@ -119,21 +177,33 @@ var file_teleport_clusterconfig_v1_access_graph_proto_rawDesc = []byte{ 0x65, 0x72, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2f, 0x76, 0x31, 0x2f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x67, 0x72, 0x61, 0x70, 0x68, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x19, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, - 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x22, 0x73, 0x0a, 0x11, 0x41, 0x63, 0x63, - 0x65, 0x73, 0x73, 0x47, 0x72, 0x61, 0x70, 0x68, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x18, - 0x0a, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, - 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, - 0x65, 0x73, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, - 0x73, 0x73, 0x12, 0x0e, 0x0a, 0x02, 0x63, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x02, - 0x63, 0x61, 0x12, 0x1a, 0x0a, 0x08, 0x69, 0x6e, 0x73, 0x65, 0x63, 0x75, 0x72, 0x65, 0x18, 0x04, - 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x69, 0x6e, 0x73, 0x65, 0x63, 0x75, 0x72, 0x65, 0x42, 0x5e, - 0x5a, 0x5c, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x72, 0x61, - 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x2f, 0x74, 0x65, 0x6c, 0x65, 0x70, - 0x6f, 0x72, 0x74, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x2f, 0x67, 0x6f, 0x2f, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x63, 0x6c, - 0x75, 0x73, 0x74, 0x65, 0x72, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2f, 0x76, 0x31, 0x3b, 0x63, - 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x76, 0x31, 0x62, 0x06, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x22, 0xe3, 0x01, 0x0a, 0x11, 0x41, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x47, 0x72, 0x61, 0x70, 0x68, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, + 0x18, 0x0a, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x64, 0x64, + 0x72, 0x65, 0x73, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, + 0x65, 0x73, 0x73, 0x12, 0x0e, 0x0a, 0x02, 0x63, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, + 0x02, 0x63, 0x61, 0x12, 0x1a, 0x0a, 0x08, 0x69, 0x6e, 0x73, 0x65, 0x63, 0x75, 0x72, 0x65, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x69, 0x6e, 0x73, 0x65, 0x63, 0x75, 0x72, 0x65, 0x12, + 0x6e, 0x0a, 0x13, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x73, 0x5f, 0x73, 0x63, 0x61, 0x6e, 0x5f, + 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x3e, 0x2e, 0x74, + 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x63, + 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x47, + 0x72, 0x61, 0x70, 0x68, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x73, 0x53, 0x63, 0x61, 0x6e, 0x43, + 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x11, 0x73, 0x65, + 0x63, 0x72, 0x65, 0x74, 0x73, 0x53, 0x63, 0x61, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x22, + 0x4f, 0x0a, 0x23, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x47, 0x72, 0x61, 0x70, 0x68, 0x53, 0x65, + 0x63, 0x72, 0x65, 0x74, 0x73, 0x53, 0x63, 0x61, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, + 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x28, 0x0a, 0x10, 0x73, 0x73, 0x68, 0x5f, 0x73, 0x63, + 0x61, 0x6e, 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x0e, 0x73, 0x73, 0x68, 0x53, 0x63, 0x61, 0x6e, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, + 0x42, 0x5e, 0x5a, 0x5c, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, + 0x72, 0x61, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x2f, 0x74, 0x65, 0x6c, + 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x2f, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, + 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2f, 0x76, 0x31, + 0x3b, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x76, 0x31, + 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -148,16 +218,18 @@ func file_teleport_clusterconfig_v1_access_graph_proto_rawDescGZIP() []byte { return file_teleport_clusterconfig_v1_access_graph_proto_rawDescData } -var file_teleport_clusterconfig_v1_access_graph_proto_msgTypes = make([]protoimpl.MessageInfo, 1) +var file_teleport_clusterconfig_v1_access_graph_proto_msgTypes = make([]protoimpl.MessageInfo, 2) var file_teleport_clusterconfig_v1_access_graph_proto_goTypes = []interface{}{ - (*AccessGraphConfig)(nil), // 0: teleport.clusterconfig.v1.AccessGraphConfig + (*AccessGraphConfig)(nil), // 0: teleport.clusterconfig.v1.AccessGraphConfig + (*AccessGraphSecretsScanConfiguration)(nil), // 1: teleport.clusterconfig.v1.AccessGraphSecretsScanConfiguration } var file_teleport_clusterconfig_v1_access_graph_proto_depIdxs = []int32{ - 0, // [0:0] is the sub-list for method output_type - 0, // [0:0] is the sub-list for method input_type - 0, // [0:0] is the sub-list for extension type_name - 0, // [0:0] is the sub-list for extension extendee - 0, // [0:0] is the sub-list for field type_name + 1, // 0: teleport.clusterconfig.v1.AccessGraphConfig.secrets_scan_config:type_name -> teleport.clusterconfig.v1.AccessGraphSecretsScanConfiguration + 1, // [1:1] is the sub-list for method output_type + 1, // [1:1] is the sub-list for method input_type + 1, // [1:1] is the sub-list for extension type_name + 1, // [1:1] is the sub-list for extension extendee + 0, // [0:1] is the sub-list for field type_name } func init() { file_teleport_clusterconfig_v1_access_graph_proto_init() } @@ -178,6 +250,18 @@ func file_teleport_clusterconfig_v1_access_graph_proto_init() { return nil } } + file_teleport_clusterconfig_v1_access_graph_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*AccessGraphSecretsScanConfiguration); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } } type x struct{} out := protoimpl.TypeBuilder{ @@ -185,7 +269,7 @@ func file_teleport_clusterconfig_v1_access_graph_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_teleport_clusterconfig_v1_access_graph_proto_rawDesc, NumEnums: 0, - NumMessages: 1, + NumMessages: 2, NumExtensions: 0, NumServices: 0, }, diff --git a/api/proto/teleport/clusterconfig/v1/access_graph.proto b/api/proto/teleport/clusterconfig/v1/access_graph.proto index 525f88d030bac..147aa9261a07b 100644 --- a/api/proto/teleport/clusterconfig/v1/access_graph.proto +++ b/api/proto/teleport/clusterconfig/v1/access_graph.proto @@ -30,4 +30,12 @@ message AccessGraphConfig { // insecure is a flag that indicates whether the access graph service should // skip verifying the server's certificate chain and host name. bool insecure = 4; + // secrets_scan_config is used to configure the parameters for the secrets scanning functionality. + AccessGraphSecretsScanConfiguration secrets_scan_config = 5; +} + +// AccessGraphSecretsScanConfiguration controls the secrets scanning service parameters. +message AccessGraphSecretsScanConfiguration { + // ssh_scan_enabled indicates if the SSH scan feature is enabled for the cluster. + bool ssh_scan_enabled = 1; } From e60ed864793c595678cdf1b39971b9d18101bc1b Mon Sep 17 00:00:00 2001 From: Tiago Silva Date: Tue, 9 Jul 2024 10:51:59 +0100 Subject: [PATCH 06/25] [sec_scan][3] add `PrivateKey`, `AuthorizedKey` and `Device` to Access Graph resources (#43468) This PR extends the Access Graph resources to be able include the newly added `teleport.access_graph.v1.PrivateKey`, `teleport.access_graph.v1.AuthorizedKey` and existing device trust information `teleport.devicetrust.v1.Device`. Part of https://github.com/gravitational/access-graph/issues/637 Signed-off-by: Tiago Silva --- .../go/accessgraph/v1alpha/resources.pb.go | 261 ++++++++++++------ proto/accessgraph/v1alpha/resources.proto | 9 + 2 files changed, 178 insertions(+), 92 deletions(-) diff --git a/gen/proto/go/accessgraph/v1alpha/resources.pb.go b/gen/proto/go/accessgraph/v1alpha/resources.pb.go index 0003c92bfd3cf..e1629570d9666 100644 --- a/gen/proto/go/accessgraph/v1alpha/resources.pb.go +++ b/gen/proto/go/accessgraph/v1alpha/resources.pb.go @@ -24,9 +24,11 @@ package accessgraphv1alpha import ( + v14 "github.com/gravitational/teleport/api/gen/proto/go/teleport/accessgraph/v1" v1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/accesslist/v1" v11 "github.com/gravitational/teleport/api/gen/proto/go/teleport/crownjewel/v1" v12 "github.com/gravitational/teleport/api/gen/proto/go/teleport/dbobject/v1" + v13 "github.com/gravitational/teleport/api/gen/proto/go/teleport/devicetrust/v1" types "github.com/gravitational/teleport/api/types" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" @@ -309,6 +311,9 @@ type ResourceEntry struct { // *ResourceEntry_AccessList // *ResourceEntry_CrownJewel // *ResourceEntry_DatabaseObject + // *ResourceEntry_Device + // *ResourceEntry_PrivateKey + // *ResourceEntry_AuthorizedKey Resource isResourceEntry_Resource `protobuf_oneof:"resource"` } @@ -428,6 +433,27 @@ func (x *ResourceEntry) GetDatabaseObject() *v12.DatabaseObject { return nil } +func (x *ResourceEntry) GetDevice() *v13.Device { + if x, ok := x.GetResource().(*ResourceEntry_Device); ok { + return x.Device + } + return nil +} + +func (x *ResourceEntry) GetPrivateKey() *v14.PrivateKey { + if x, ok := x.GetResource().(*ResourceEntry_PrivateKey); ok { + return x.PrivateKey + } + return nil +} + +func (x *ResourceEntry) GetAuthorizedKey() *v14.AuthorizedKey { + if x, ok := x.GetResource().(*ResourceEntry_AuthorizedKey); ok { + return x.AuthorizedKey + } + return nil +} + type isResourceEntry_Resource interface { isResourceEntry_Resource() } @@ -487,6 +513,21 @@ type ResourceEntry_DatabaseObject struct { DatabaseObject *v12.DatabaseObject `protobuf:"bytes,11,opt,name=database_object,json=databaseObject,proto3,oneof"` } +type ResourceEntry_Device struct { + // device is a device trust resource. + Device *v13.Device `protobuf:"bytes,12,opt,name=device,proto3,oneof"` +} + +type ResourceEntry_PrivateKey struct { + // private_key represents a private key resource found in user's laptops. + PrivateKey *v14.PrivateKey `protobuf:"bytes,13,opt,name=private_key,json=privateKey,proto3,oneof"` +} + +type ResourceEntry_AuthorizedKey struct { + // authorized_key represents a authorized key for a server. + AuthorizedKey *v14.AuthorizedKey `protobuf:"bytes,14,opt,name=authorized_key,json=authorizedKey,proto3,oneof"` +} + func (*ResourceEntry_User) isResourceEntry_Resource() {} func (*ResourceEntry_Role) isResourceEntry_Resource() {} @@ -509,99 +550,126 @@ func (*ResourceEntry_CrownJewel) isResourceEntry_Resource() {} func (*ResourceEntry_DatabaseObject) isResourceEntry_Resource() {} +func (*ResourceEntry_Device) isResourceEntry_Resource() {} + +func (*ResourceEntry_PrivateKey) isResourceEntry_Resource() {} + +func (*ResourceEntry_AuthorizedKey) isResourceEntry_Resource() {} + var File_accessgraph_v1alpha_resources_proto protoreflect.FileDescriptor var file_accessgraph_v1alpha_resources_proto_rawDesc = []byte{ 0x0a, 0x23, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x67, 0x72, 0x61, 0x70, 0x68, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x13, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x67, 0x72, 0x61, - 0x70, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x1a, 0x27, 0x74, 0x65, 0x6c, 0x65, - 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x6c, 0x69, 0x73, 0x74, 0x2f, - 0x76, 0x31, 0x2f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x6c, 0x69, 0x73, 0x74, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x1a, 0x27, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x63, 0x72, - 0x6f, 0x77, 0x6e, 0x6a, 0x65, 0x77, 0x65, 0x6c, 0x2f, 0x76, 0x31, 0x2f, 0x63, 0x72, 0x6f, 0x77, - 0x6e, 0x6a, 0x65, 0x77, 0x65, 0x6c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x23, 0x74, 0x65, - 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x64, 0x62, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2f, - 0x76, 0x31, 0x2f, 0x64, 0x62, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x1a, 0x21, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x6c, 0x65, 0x67, 0x61, - 0x63, 0x79, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x50, 0x0a, 0x0c, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, - 0x4c, 0x69, 0x73, 0x74, 0x12, 0x40, 0x0a, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, - 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, - 0x67, 0x72, 0x61, 0x70, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x52, 0x65, - 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x09, 0x72, 0x65, 0x73, - 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x22, 0x49, 0x0a, 0x12, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, - 0x63, 0x65, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x33, 0x0a, 0x09, - 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x15, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, - 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x52, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, - 0x73, 0x22, 0x4e, 0x0a, 0x12, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x73, - 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x12, 0x38, 0x0a, 0x07, 0x6d, 0x65, 0x6d, 0x62, 0x65, - 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, - 0x6f, 0x72, 0x74, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x6c, 0x69, 0x73, 0x74, 0x2e, 0x76, - 0x31, 0x2e, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x07, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, - 0x73, 0x22, 0x63, 0x0a, 0x19, 0x45, 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x41, 0x63, 0x63, 0x65, - 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x73, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x12, 0x46, - 0x0a, 0x07, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x2c, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x67, 0x72, 0x61, 0x70, 0x68, 0x2e, 0x76, 0x31, - 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x45, 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x41, 0x63, 0x63, - 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x07, 0x6d, - 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x22, 0x56, 0x0a, 0x17, 0x45, 0x78, 0x63, 0x6c, 0x75, 0x64, - 0x65, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, - 0x72, 0x12, 0x1f, 0x0a, 0x0b, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x6c, 0x69, 0x73, 0x74, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, - 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0xb7, - 0x05, 0x0a, 0x0d, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, - 0x12, 0x23, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, - 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x56, 0x32, 0x48, 0x00, 0x52, - 0x04, 0x75, 0x73, 0x65, 0x72, 0x12, 0x23, 0x0a, 0x04, 0x72, 0x6f, 0x6c, 0x65, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x52, 0x6f, 0x6c, 0x65, - 0x56, 0x36, 0x48, 0x00, 0x52, 0x04, 0x72, 0x6f, 0x6c, 0x65, 0x12, 0x29, 0x0a, 0x06, 0x73, 0x65, - 0x72, 0x76, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x74, 0x79, 0x70, - 0x65, 0x73, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x56, 0x32, 0x48, 0x00, 0x52, 0x06, 0x73, - 0x65, 0x72, 0x76, 0x65, 0x72, 0x12, 0x3f, 0x0a, 0x0e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, - 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, - 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x56, 0x33, 0x48, 0x00, 0x52, 0x0d, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x48, 0x0a, 0x11, 0x6b, 0x75, 0x62, 0x65, 0x72, 0x6e, - 0x65, 0x74, 0x65, 0x73, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x19, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x4b, 0x75, 0x62, 0x65, 0x72, 0x6e, - 0x65, 0x74, 0x65, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x56, 0x33, 0x48, 0x00, 0x52, 0x10, - 0x6b, 0x75, 0x62, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x65, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, - 0x12, 0x33, 0x0a, 0x0a, 0x61, 0x70, 0x70, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x18, 0x06, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x41, 0x70, 0x70, - 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x56, 0x33, 0x48, 0x00, 0x52, 0x09, 0x61, 0x70, 0x70, 0x53, - 0x65, 0x72, 0x76, 0x65, 0x72, 0x12, 0x42, 0x0a, 0x0f, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, - 0x65, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, - 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x53, - 0x65, 0x72, 0x76, 0x65, 0x72, 0x56, 0x33, 0x48, 0x00, 0x52, 0x0e, 0x64, 0x61, 0x74, 0x61, 0x62, - 0x61, 0x73, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x12, 0x42, 0x0a, 0x0f, 0x77, 0x69, 0x6e, - 0x64, 0x6f, 0x77, 0x73, 0x5f, 0x64, 0x65, 0x73, 0x6b, 0x74, 0x6f, 0x70, 0x18, 0x08, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x57, 0x69, 0x6e, 0x64, 0x6f, - 0x77, 0x73, 0x44, 0x65, 0x73, 0x6b, 0x74, 0x6f, 0x70, 0x56, 0x33, 0x48, 0x00, 0x52, 0x0e, 0x77, - 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x73, 0x44, 0x65, 0x73, 0x6b, 0x74, 0x6f, 0x70, 0x12, 0x45, 0x0a, - 0x0b, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x18, 0x09, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x61, 0x63, - 0x63, 0x65, 0x73, 0x73, 0x6c, 0x69, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x63, 0x63, 0x65, - 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x48, 0x00, 0x52, 0x0a, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, - 0x4c, 0x69, 0x73, 0x74, 0x12, 0x45, 0x0a, 0x0b, 0x63, 0x72, 0x6f, 0x77, 0x6e, 0x5f, 0x6a, 0x65, - 0x77, 0x65, 0x6c, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x74, 0x65, 0x6c, 0x65, - 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x63, 0x72, 0x6f, 0x77, 0x6e, 0x6a, 0x65, 0x77, 0x65, 0x6c, 0x2e, - 0x76, 0x31, 0x2e, 0x43, 0x72, 0x6f, 0x77, 0x6e, 0x4a, 0x65, 0x77, 0x65, 0x6c, 0x48, 0x00, 0x52, - 0x0a, 0x63, 0x72, 0x6f, 0x77, 0x6e, 0x4a, 0x65, 0x77, 0x65, 0x6c, 0x12, 0x4f, 0x0a, 0x0f, 0x64, - 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x0b, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, - 0x64, 0x62, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x61, 0x74, 0x61, - 0x62, 0x61, 0x73, 0x65, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x48, 0x00, 0x52, 0x0e, 0x64, 0x61, - 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x42, 0x0a, 0x0a, 0x08, - 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x42, 0x57, 0x5a, 0x55, 0x67, 0x69, 0x74, 0x68, - 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x72, 0x61, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x61, 0x6c, 0x2f, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x67, 0x65, - 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x2f, 0x61, 0x63, 0x63, 0x65, 0x73, - 0x73, 0x67, 0x72, 0x61, 0x70, 0x68, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x3b, 0x61, - 0x63, 0x63, 0x65, 0x73, 0x73, 0x67, 0x72, 0x61, 0x70, 0x68, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, - 0x61, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x70, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x1a, 0x2d, 0x74, 0x65, 0x6c, 0x65, + 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x67, 0x72, 0x61, 0x70, + 0x68, 0x2f, 0x76, 0x31, 0x2f, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x5f, + 0x6b, 0x65, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x2a, 0x74, 0x65, 0x6c, 0x65, 0x70, + 0x6f, 0x72, 0x74, 0x2f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x67, 0x72, 0x61, 0x70, 0x68, + 0x2f, 0x76, 0x31, 0x2f, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x27, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, + 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x6c, 0x69, 0x73, 0x74, 0x2f, 0x76, 0x31, 0x2f, 0x61, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x6c, 0x69, 0x73, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x27, + 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x63, 0x72, 0x6f, 0x77, 0x6e, 0x6a, 0x65, + 0x77, 0x65, 0x6c, 0x2f, 0x76, 0x31, 0x2f, 0x63, 0x72, 0x6f, 0x77, 0x6e, 0x6a, 0x65, 0x77, 0x65, + 0x6c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x23, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, + 0x74, 0x2f, 0x64, 0x62, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2f, 0x76, 0x31, 0x2f, 0x64, 0x62, + 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x24, 0x74, 0x65, + 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, 0x72, 0x75, + 0x73, 0x74, 0x2f, 0x76, 0x31, 0x2f, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x1a, 0x21, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x6c, 0x65, 0x67, + 0x61, 0x63, 0x79, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x50, 0x0a, 0x0c, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x40, 0x0a, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x67, 0x72, 0x61, 0x70, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x52, + 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x09, 0x72, 0x65, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x22, 0x49, 0x0a, 0x12, 0x52, 0x65, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x33, 0x0a, + 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x15, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x52, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x73, 0x22, 0x4e, 0x0a, 0x12, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, + 0x73, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x12, 0x38, 0x0a, 0x07, 0x6d, 0x65, 0x6d, 0x62, + 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x74, 0x65, 0x6c, 0x65, + 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x6c, 0x69, 0x73, 0x74, 0x2e, + 0x76, 0x31, 0x2e, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x07, 0x6d, 0x65, 0x6d, 0x62, 0x65, + 0x72, 0x73, 0x22, 0x63, 0x0a, 0x19, 0x45, 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x41, 0x63, 0x63, + 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x73, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x12, + 0x46, 0x0a, 0x07, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x2c, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x67, 0x72, 0x61, 0x70, 0x68, 0x2e, 0x76, + 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x2e, 0x45, 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x41, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x07, + 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x22, 0x56, 0x0a, 0x17, 0x45, 0x78, 0x63, 0x6c, 0x75, + 0x64, 0x65, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x6d, 0x62, + 0x65, 0x72, 0x12, 0x1f, 0x0a, 0x0b, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x6c, 0x69, 0x73, + 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, + 0x69, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x22, + 0x8d, 0x07, 0x0a, 0x0d, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x45, 0x6e, 0x74, 0x72, + 0x79, 0x12, 0x23, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x0d, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x56, 0x32, 0x48, 0x00, + 0x52, 0x04, 0x75, 0x73, 0x65, 0x72, 0x12, 0x23, 0x0a, 0x04, 0x72, 0x6f, 0x6c, 0x65, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x52, 0x6f, 0x6c, + 0x65, 0x56, 0x36, 0x48, 0x00, 0x52, 0x04, 0x72, 0x6f, 0x6c, 0x65, 0x12, 0x29, 0x0a, 0x06, 0x73, + 0x65, 0x72, 0x76, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x74, 0x79, + 0x70, 0x65, 0x73, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x56, 0x32, 0x48, 0x00, 0x52, 0x06, + 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x12, 0x3f, 0x0a, 0x0e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, + 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, + 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x56, 0x33, 0x48, 0x00, 0x52, 0x0d, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x48, 0x0a, 0x11, 0x6b, 0x75, 0x62, 0x65, 0x72, + 0x6e, 0x65, 0x74, 0x65, 0x73, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x18, 0x05, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x4b, 0x75, 0x62, 0x65, 0x72, + 0x6e, 0x65, 0x74, 0x65, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x56, 0x33, 0x48, 0x00, 0x52, + 0x10, 0x6b, 0x75, 0x62, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x65, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, + 0x72, 0x12, 0x33, 0x0a, 0x0a, 0x61, 0x70, 0x70, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x18, + 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x41, 0x70, + 0x70, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x56, 0x33, 0x48, 0x00, 0x52, 0x09, 0x61, 0x70, 0x70, + 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x12, 0x42, 0x0a, 0x0f, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, + 0x73, 0x65, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x17, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, + 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x56, 0x33, 0x48, 0x00, 0x52, 0x0e, 0x64, 0x61, 0x74, 0x61, + 0x62, 0x61, 0x73, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x12, 0x42, 0x0a, 0x0f, 0x77, 0x69, + 0x6e, 0x64, 0x6f, 0x77, 0x73, 0x5f, 0x64, 0x65, 0x73, 0x6b, 0x74, 0x6f, 0x70, 0x18, 0x08, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x57, 0x69, 0x6e, 0x64, + 0x6f, 0x77, 0x73, 0x44, 0x65, 0x73, 0x6b, 0x74, 0x6f, 0x70, 0x56, 0x33, 0x48, 0x00, 0x52, 0x0e, + 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x73, 0x44, 0x65, 0x73, 0x6b, 0x74, 0x6f, 0x70, 0x12, 0x45, + 0x0a, 0x0b, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x18, 0x09, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x61, + 0x63, 0x63, 0x65, 0x73, 0x73, 0x6c, 0x69, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x63, 0x63, + 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x48, 0x00, 0x52, 0x0a, 0x61, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x45, 0x0a, 0x0b, 0x63, 0x72, 0x6f, 0x77, 0x6e, 0x5f, 0x6a, + 0x65, 0x77, 0x65, 0x6c, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x74, 0x65, 0x6c, + 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x63, 0x72, 0x6f, 0x77, 0x6e, 0x6a, 0x65, 0x77, 0x65, 0x6c, + 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x6f, 0x77, 0x6e, 0x4a, 0x65, 0x77, 0x65, 0x6c, 0x48, 0x00, + 0x52, 0x0a, 0x63, 0x72, 0x6f, 0x77, 0x6e, 0x4a, 0x65, 0x77, 0x65, 0x6c, 0x12, 0x4f, 0x0a, 0x0f, + 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x18, + 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, + 0x2e, 0x64, 0x62, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x61, 0x74, + 0x61, 0x62, 0x61, 0x73, 0x65, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x48, 0x00, 0x52, 0x0e, 0x64, + 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x39, 0x0a, + 0x06, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, + 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x74, + 0x72, 0x75, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x48, 0x00, + 0x52, 0x06, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x12, 0x47, 0x0a, 0x0b, 0x70, 0x72, 0x69, 0x76, + 0x61, 0x74, 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, + 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, + 0x67, 0x72, 0x61, 0x70, 0x68, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, + 0x4b, 0x65, 0x79, 0x48, 0x00, 0x52, 0x0a, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x4b, 0x65, + 0x79, 0x12, 0x50, 0x0a, 0x0e, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x5f, + 0x6b, 0x65, 0x79, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x74, 0x65, 0x6c, 0x65, + 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x67, 0x72, 0x61, 0x70, + 0x68, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x4b, + 0x65, 0x79, 0x48, 0x00, 0x52, 0x0d, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, + 0x4b, 0x65, 0x79, 0x42, 0x0a, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x42, + 0x57, 0x5a, 0x55, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x72, + 0x61, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x2f, 0x74, 0x65, 0x6c, 0x65, + 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, + 0x6f, 0x2f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x67, 0x72, 0x61, 0x70, 0x68, 0x2f, 0x76, 0x31, + 0x61, 0x6c, 0x70, 0x68, 0x61, 0x3b, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x67, 0x72, 0x61, 0x70, + 0x68, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -637,6 +705,9 @@ var file_accessgraph_v1alpha_resources_proto_goTypes = []interface{}{ (*v1.AccessList)(nil), // 16: teleport.accesslist.v1.AccessList (*v11.CrownJewel)(nil), // 17: teleport.crownjewel.v1.CrownJewel (*v12.DatabaseObject)(nil), // 18: teleport.dbobject.v1.DatabaseObject + (*v13.Device)(nil), // 19: teleport.devicetrust.v1.Device + (*v14.PrivateKey)(nil), // 20: teleport.access_graph.v1.PrivateKey + (*v14.AuthorizedKey)(nil), // 21: teleport.access_graph.v1.AuthorizedKey } var file_accessgraph_v1alpha_resources_proto_depIdxs = []int32{ 5, // 0: accessgraph.v1alpha.ResourceList.resources:type_name -> accessgraph.v1alpha.ResourceEntry @@ -654,11 +725,14 @@ var file_accessgraph_v1alpha_resources_proto_depIdxs = []int32{ 16, // 12: accessgraph.v1alpha.ResourceEntry.access_list:type_name -> teleport.accesslist.v1.AccessList 17, // 13: accessgraph.v1alpha.ResourceEntry.crown_jewel:type_name -> teleport.crownjewel.v1.CrownJewel 18, // 14: accessgraph.v1alpha.ResourceEntry.database_object:type_name -> teleport.dbobject.v1.DatabaseObject - 15, // [15:15] is the sub-list for method output_type - 15, // [15:15] is the sub-list for method input_type - 15, // [15:15] is the sub-list for extension type_name - 15, // [15:15] is the sub-list for extension extendee - 0, // [0:15] is the sub-list for field type_name + 19, // 15: accessgraph.v1alpha.ResourceEntry.device:type_name -> teleport.devicetrust.v1.Device + 20, // 16: accessgraph.v1alpha.ResourceEntry.private_key:type_name -> teleport.access_graph.v1.PrivateKey + 21, // 17: accessgraph.v1alpha.ResourceEntry.authorized_key:type_name -> teleport.access_graph.v1.AuthorizedKey + 18, // [18:18] is the sub-list for method output_type + 18, // [18:18] is the sub-list for method input_type + 18, // [18:18] is the sub-list for extension type_name + 18, // [18:18] is the sub-list for extension extendee + 0, // [0:18] is the sub-list for field type_name } func init() { file_accessgraph_v1alpha_resources_proto_init() } @@ -752,6 +826,9 @@ func file_accessgraph_v1alpha_resources_proto_init() { (*ResourceEntry_AccessList)(nil), (*ResourceEntry_CrownJewel)(nil), (*ResourceEntry_DatabaseObject)(nil), + (*ResourceEntry_Device)(nil), + (*ResourceEntry_PrivateKey)(nil), + (*ResourceEntry_AuthorizedKey)(nil), } type x struct{} out := protoimpl.TypeBuilder{ diff --git a/proto/accessgraph/v1alpha/resources.proto b/proto/accessgraph/v1alpha/resources.proto index 6fc35d0bdc0b6..a6febcc7fcdfc 100644 --- a/proto/accessgraph/v1alpha/resources.proto +++ b/proto/accessgraph/v1alpha/resources.proto @@ -20,9 +20,12 @@ syntax = "proto3"; package accessgraph.v1alpha; +import "teleport/access_graph/v1/authorized_key.proto"; +import "teleport/access_graph/v1/private_key.proto"; import "teleport/accesslist/v1/accesslist.proto"; import "teleport/crownjewel/v1/crownjewel.proto"; import "teleport/dbobject/v1/dbobject.proto"; +import "teleport/devicetrust/v1/device.proto"; import "teleport/legacy/types/types.proto"; option go_package = "github.com/gravitational/teleport/gen/proto/go/accessgraph/v1alpha;accessgraphv1alpha"; @@ -79,5 +82,11 @@ message ResourceEntry { teleport.crownjewel.v1.CrownJewel crown_jewel = 10; // database_object is a resource for database objects. teleport.dbobject.v1.DatabaseObject database_object = 11; + // device is a device trust resource. + teleport.devicetrust.v1.Device device = 12; + // private_key represents a private key resource found in user's laptops. + teleport.access_graph.v1.PrivateKey private_key = 13; + // authorized_key represents a authorized key for a server. + teleport.access_graph.v1.AuthorizedKey authorized_key = 14; } } From e1912f05b40a28df6c929408af37cc1d823de78f Mon Sep 17 00:00:00 2001 From: Tiago Silva Date: Tue, 9 Jul 2024 10:39:38 +0100 Subject: [PATCH 07/25] fix: fix `nextKey` values when using multiple prefixes (#43486) This PR makes `generic.Service` correctly implementing `List*` functions when multiple key prefixes are defined Signed-off-by: Tiago Silva --- lib/services/local/generic/generic.go | 39 ++++++++---- lib/services/local/generic/generic_test.go | 59 +++++++++++++++++++ lib/services/local/generic/generic_wrapper.go | 4 +- 3 files changed, 89 insertions(+), 13 deletions(-) diff --git a/lib/services/local/generic/generic.go b/lib/services/local/generic/generic.go index 02a7648d67f9e..123c1bfa34840 100644 --- a/lib/services/local/generic/generic.go +++ b/lib/services/local/generic/generic.go @@ -78,7 +78,6 @@ func (c *ServiceConfig[T]) CheckAndSetDefaults() error { if c.UnmarshalFunc == nil { return trace.BadParameter("unmarshal func is missing") } - return nil } @@ -167,17 +166,17 @@ func (s *Service[T]) GetResources(ctx context.Context) ([]T, error) { // ListResources returns a paginated list of resources. func (s *Service[T]) ListResources(ctx context.Context, pageSize int, pageToken string) ([]T, string, error) { - resources, next, err := s.ListResourcesReturnNextResource(ctx, pageSize, pageToken) - var nextKey string - if next != nil { - nextKey = backend.GetPaginationKey(*next) - } + resources, _, nextKey, err := s.listResourcesReturnNextResourceWithKey(ctx, pageSize, pageToken) return resources, nextKey, trace.Wrap(err) } // ListResourcesReturnNextResource returns a paginated list of resources. The next resource is returned, which allows consumers to construct // the next pagination key as appropriate. func (s *Service[T]) ListResourcesReturnNextResource(ctx context.Context, pageSize int, pageToken string) ([]T, *T, error) { + resources, next, _, err := s.listResourcesReturnNextResourceWithKey(ctx, pageSize, pageToken) + return resources, next, trace.Wrap(err) +} +func (s *Service[T]) listResourcesReturnNextResourceWithKey(ctx context.Context, pageSize int, pageToken string) ([]T, *T, string, error) { rangeStart := backend.Key(s.backendPrefix, pageToken) rangeEnd := backend.RangeEnd(backend.ExactKey(s.backendPrefix)) @@ -191,26 +190,32 @@ func (s *Service[T]) ListResourcesReturnNextResource(ctx context.Context, pageSi // no filter provided get the range directly result, err := s.backend.GetRange(ctx, rangeStart, rangeEnd, limit) if err != nil { - return nil, nil, trace.Wrap(err) + return nil, nil, "", trace.Wrap(err) } out := make([]T, 0, len(result.Items)) + var lastKey []byte for _, item := range result.Items { resource, err := s.unmarshalFunc(item.Value, services.WithRevision(item.Revision)) if err != nil { - return nil, nil, trace.Wrap(err) + return nil, nil, "", trace.Wrap(err) } out = append(out, resource) + lastKey = item.Key } - var next *T + var ( + next *T + nextKey string + ) if len(out) > pageSize { next = &out[pageSize] // Truncate the last item that was used to determine next row existence. out = out[:pageSize] + nextKey = trimLastKey(string(lastKey), s.backendPrefix) } - return out, next, nil + return out, next, nextKey, nil } // ListResourcesWithFilter returns a paginated list of resources that match the given filter. @@ -226,6 +231,7 @@ func (s *Service[T]) ListResourcesWithFilter(ctx context.Context, pageSize int, limit := pageSize + 1 var resources []T + var lastKey []byte if err := backend.IterateRange( ctx, s.backend, @@ -239,6 +245,7 @@ func (s *Service[T]) ListResourcesWithFilter(ctx context.Context, pageSize int, return false, trace.Wrap(err) } if matcher(resource) { + lastKey = item.Key resources = append(resources, resource) } if len(resources) == pageSize { @@ -252,7 +259,7 @@ func (s *Service[T]) ListResourcesWithFilter(ctx context.Context, pageSize int, var nextKey string if len(resources) > pageSize { - nextKey = backend.GetPaginationKey(resources[pageSize]) + nextKey = trimLastKey(string(lastKey), s.backendPrefix) // Truncate the last item that was used to determine next row existence. resources = resources[:pageSize] } @@ -454,3 +461,13 @@ func (s *Service[T]) RunWhileLocked(ctx context.Context, lockName string, ttl ti return fn(ctx, s.backend) })) } + +func trimLastKey(lastKey, prefix string) string { + if !strings.HasSuffix(prefix, string(backend.Separator)) { + prefix += string(backend.Separator) + } + if !strings.HasPrefix(prefix, string(backend.Separator)) { + prefix = string(backend.Separator) + prefix + } + return strings.TrimPrefix(lastKey, prefix) +} diff --git a/lib/services/local/generic/generic_test.go b/lib/services/local/generic/generic_test.go index 7dd43710ba98d..8501973555f87 100644 --- a/lib/services/local/generic/generic_test.go +++ b/lib/services/local/generic/generic_test.go @@ -330,6 +330,65 @@ func TestGenericListResourcesReturnNextResource(t *testing.T) { require.Nil(t, next) } +func TestGenericListResourcesWithMultiplePrefixes(t *testing.T) { + ctx := context.Background() + + memBackend, err := memory.New(memory.Config{ + Context: ctx, + Clock: clockwork.NewFakeClock(), + }) + require.NoError(t, err) + + service, err := NewService(&ServiceConfig[*testResource]{ + Backend: memBackend, + ResourceKind: "generic resource", + PageLimit: 200, + BackendPrefix: "generic_prefix", + UnmarshalFunc: unmarshalResource, + MarshalFunc: marshalResource, + }) + require.NoError(t, err) + + // Create a couple test resources. + r1 := newTestResource("r1") + r2 := newTestResource("r2") + + _, err = service.WithPrefix("a-unique-prefix").UpsertResource(ctx, r1) + require.NoError(t, err) + _, err = service.WithPrefix("another-unique-prefix").UpsertResource(ctx, r2) + require.NoError(t, err) + + page, next, err := service.ListResources(ctx, 1, "") + require.NoError(t, err) + require.Empty(t, cmp.Diff([]*testResource{r1}, page, + cmpopts.IgnoreFields(types.Metadata{}, "Revision"), + )) + require.Equal(t, next, "another-unique-prefix"+string(backend.Separator)+r2.GetName()) + + page, next, err = service.ListResources(ctx, 1, next) + require.NoError(t, err) + require.Empty(t, cmp.Diff([]*testResource{r2}, page, + cmpopts.IgnoreFields(types.Metadata{}, "Revision"), + )) + require.Empty(t, next) + + _, err = service.WithPrefix("a-unique-prefix").UpsertResource(ctx, r2) + require.NoError(t, err) + page, next, err = service.WithPrefix("a-unique-prefix").ListResources(ctx, 1, "") + require.NoError(t, err) + require.Empty(t, cmp.Diff([]*testResource{r1}, page, + cmpopts.IgnoreFields(types.Metadata{}, "Revision"), + )) + require.Equal(t, next, r2.GetName()) + + page, next, err = service.WithPrefix("a-unique-prefix").ListResources(ctx, 1, next) + require.NoError(t, err) + require.Empty(t, cmp.Diff([]*testResource{r2}, page, + cmpopts.IgnoreFields(types.Metadata{}, "Revision"), + )) + require.Empty(t, next) +} + func TestGenericListResourcesWithFilter(t *testing.T) { ctx := context.Background() diff --git a/lib/services/local/generic/generic_wrapper.go b/lib/services/local/generic/generic_wrapper.go index 3fa6fc1c1c418..6ccb9aafb40de 100644 --- a/lib/services/local/generic/generic_wrapper.go +++ b/lib/services/local/generic/generic_wrapper.go @@ -33,8 +33,8 @@ func NewServiceWrapper[T types.ResourceMetadata]( resourceKind string, backendPrefix string, marshalFunc MarshalFunc[T], - unmarshalFunc UnmarshalFunc[T]) (*ServiceWrapper[T], error) { - + unmarshalFunc UnmarshalFunc[T], +) (*ServiceWrapper[T], error) { cfg := &ServiceConfig[resourceMetadataAdapter[T]]{ Backend: backend, ResourceKind: resourceKind, From 63d25ee5ef5226ff3c79f8c9364103fa256b2126 Mon Sep 17 00:00:00 2001 From: Tiago Silva Date: Thu, 11 Jul 2024 09:40:24 +0100 Subject: [PATCH 08/25] [sec_scan][5] add secrets backend service (#43543) * [sec_scan][5] add secrets backend service This PR implements the backend service to support storing `authorized_keys` and `private_keys` into Teleport backend. Part of https://github.com/gravitational/access-graph/issues/637 Signed-off-by: Tiago Silva * handle feedback * handle nits --------- Signed-off-by: Tiago Silva --- api/types/accessgraph/authorized_key.go | 90 +++++++ api/types/accessgraph/authorized_key_test.go | 90 +++++++ api/types/accessgraph/private_key.go | 108 ++++++++ api/types/accessgraph/private_key_test.go | 119 +++++++++ api/types/constants.go | 8 + lib/services/access_graph.go | 68 +++++ lib/services/local/access_graph.go | 164 ++++++++++++ lib/services/local/access_graph_test.go | 247 +++++++++++++++++++ 8 files changed, 894 insertions(+) create mode 100644 api/types/accessgraph/authorized_key.go create mode 100644 api/types/accessgraph/authorized_key_test.go create mode 100644 api/types/accessgraph/private_key.go create mode 100644 api/types/accessgraph/private_key_test.go create mode 100644 lib/services/access_graph.go create mode 100644 lib/services/local/access_graph.go create mode 100644 lib/services/local/access_graph_test.go diff --git a/api/types/accessgraph/authorized_key.go b/api/types/accessgraph/authorized_key.go new file mode 100644 index 0000000000000..5532f39bc2775 --- /dev/null +++ b/api/types/accessgraph/authorized_key.go @@ -0,0 +1,90 @@ +/* +Copyright 2024 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 accessgraph + +import ( + "time" + + "github.com/gravitational/trace" + "google.golang.org/protobuf/types/known/timestamppb" + + accessgraphv1pb "github.com/gravitational/teleport/api/gen/proto/go/teleport/accessgraph/v1" + headerv1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/header/v1" + "github.com/gravitational/teleport/api/types" +) + +const ( + authorizedKeyDefaultKeyTTL = 8 * time.Hour +) + +// NewAuthorizedKey creates a new SSH authorized key resource. +func NewAuthorizedKey(spec *accessgraphv1pb.AuthorizedKeySpec) (*accessgraphv1pb.AuthorizedKey, error) { + name := authKeyHashNameKey(spec) + authKey := &accessgraphv1pb.AuthorizedKey{ + Kind: types.KindAccessGraphSecretAuthorizedKey, + Version: types.V1, + Metadata: &headerv1.Metadata{ + Name: name, + Expires: timestamppb.New( + time.Now().Add(authorizedKeyDefaultKeyTTL), + ), + }, + Spec: spec, + } + if err := ValidateAuthorizedKey(authKey); err != nil { + return nil, trace.Wrap(err) + } + + return authKey, nil +} + +// ValidateAuthorizedKey checks that required parameters are set +// for the specified AuthorizedKey +func ValidateAuthorizedKey(k *accessgraphv1pb.AuthorizedKey) error { + if k == nil { + return trace.BadParameter("AuthorizedKey is nil") + } + if k.Metadata == nil { + return trace.BadParameter("Metadata is nil") + } + if k.Spec == nil { + return trace.BadParameter("Spec is nil") + } + + if k.Spec.HostId == "" { + return trace.BadParameter("HostId is unset") + } + if k.Spec.HostUser == "" { + return trace.BadParameter("HostUser is unset") + } + if k.Spec.KeyFingerprint == "" { + return trace.BadParameter("KeyFingerprint is unset") + } + + if k.Metadata.Name == "" { + return trace.BadParameter("Name is unset") + } + if k.Metadata.Name != authKeyHashNameKey(k.Spec) { + return trace.BadParameter("Name must be derived from the key fields") + } + + return nil +} + +func authKeyHashNameKey(k *accessgraphv1pb.AuthorizedKeySpec) string { + return hashComp(k.HostId, k.HostUser, k.KeyFingerprint) +} diff --git a/api/types/accessgraph/authorized_key_test.go b/api/types/accessgraph/authorized_key_test.go new file mode 100644 index 0000000000000..d28d72ebd3e7e --- /dev/null +++ b/api/types/accessgraph/authorized_key_test.go @@ -0,0 +1,90 @@ +/* +Copyright 2024 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 accessgraph + +import ( + "testing" + + "github.com/google/go-cmp/cmp" + "github.com/google/uuid" + "github.com/stretchr/testify/require" + "google.golang.org/protobuf/testing/protocmp" + + accessgraphv1pb "github.com/gravitational/teleport/api/gen/proto/go/teleport/accessgraph/v1" +) + +func TestAuthorizedKey(t *testing.T) { + tests := []struct { + name string + spec *accessgraphv1pb.AuthorizedKeySpec + errValidation require.ErrorAssertionFunc + }{ + { + name: "valid", + spec: &accessgraphv1pb.AuthorizedKeySpec{ + HostId: uuid.New().String(), + KeyFingerprint: "fingerprint", + HostUser: "user", + }, + errValidation: require.NoError, + }, + { + name: "missing fingerprint", + spec: &accessgraphv1pb.AuthorizedKeySpec{ + HostId: uuid.New().String(), + KeyFingerprint: "", + HostUser: "user", + }, + errValidation: func(t require.TestingT, err error, i ...any) { + require.ErrorContains(t, err, "KeyFingerprint is unset") + }, + }, + { + name: "missing user", + spec: &accessgraphv1pb.AuthorizedKeySpec{ + HostId: uuid.New().String(), + KeyFingerprint: "fingerprint", + HostUser: "", + }, + errValidation: func(t require.TestingT, err error, i ...any) { + require.ErrorContains(t, err, "HostUser is unset") + }, + }, + { + name: "missing HostID", + spec: &accessgraphv1pb.AuthorizedKeySpec{ + KeyFingerprint: "fingerprint", + HostUser: "user", + }, + errValidation: func(t require.TestingT, err error, i ...any) { + require.ErrorContains(t, err, "HostId is unset") + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + privKey, err := NewAuthorizedKey(tt.spec) + tt.errValidation(t, err) + if err != nil { + return + } + require.NotEmpty(t, privKey.Metadata.Name) + require.Empty(t, cmp.Diff(tt.spec, privKey.Spec, protocmp.Transform())) + + }) + } +} diff --git a/api/types/accessgraph/private_key.go b/api/types/accessgraph/private_key.go new file mode 100644 index 0000000000000..57e0874ed040a --- /dev/null +++ b/api/types/accessgraph/private_key.go @@ -0,0 +1,108 @@ +/* +Copyright 2024 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 accessgraph + +import ( + "crypto/sha256" + "encoding/hex" + + "github.com/gravitational/trace" + + accessgraphv1pb "github.com/gravitational/teleport/api/gen/proto/go/teleport/accessgraph/v1" + headerv1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/header/v1" + "github.com/gravitational/teleport/api/types" +) + +// NewPrivateKey creates a new SSH Private key resource with a generated name based on the spec. +func NewPrivateKey(spec *accessgraphv1pb.PrivateKeySpec) (*accessgraphv1pb.PrivateKey, error) { + name := privKeyHashNameKey(spec) + v, err := NewPrivateKeyWithName(name, spec) + + return v, trace.Wrap(err) +} + +// NewPrivateKeyWithName creates a new SSH Private key resource. +func NewPrivateKeyWithName(name string, spec *accessgraphv1pb.PrivateKeySpec) (*accessgraphv1pb.PrivateKey, error) { + privKey := &accessgraphv1pb.PrivateKey{ + Kind: types.KindAccessGraphSecretPrivateKey, + Version: types.V1, + Metadata: &headerv1.Metadata{ + Name: name, + }, + Spec: spec, + } + if err := ValidatePrivateKey(privKey); err != nil { + return nil, trace.Wrap(err) + } + + return privKey, nil +} + +// ValidatePrivateKey checks that required parameters are set +// for the specified PrivateKey +func ValidatePrivateKey(k *accessgraphv1pb.PrivateKey) error { + if k == nil { + return trace.BadParameter("PrivateKey is nil") + } + if k.Metadata == nil { + return trace.BadParameter("Metadata is nil") + } + if k.Spec == nil { + return trace.BadParameter("Spec is nil") + } + + if k.Kind != types.KindAccessGraphSecretPrivateKey { + return trace.BadParameter("Kind is invalid") + } + + if k.Version != types.V1 { + return trace.BadParameter("Version is invalid") + } + + switch k.Spec.PublicKeyMode { + case accessgraphv1pb.PublicKeyMode_PUBLIC_KEY_MODE_PROTECTED, + accessgraphv1pb.PublicKeyMode_PUBLIC_KEY_MODE_PUB_FILE, + accessgraphv1pb.PublicKeyMode_PUBLIC_KEY_MODE_DERIVED: + default: + return trace.BadParameter("PublicKeyMode is invalid") + } + + if k.Spec.DeviceId == "" { + return trace.BadParameter("DeviceId is unset") + } + if k.Spec.PublicKeyFingerprint == "" && k.Spec.PublicKeyMode != accessgraphv1pb.PublicKeyMode_PUBLIC_KEY_MODE_PROTECTED { + return trace.BadParameter("PublicKeyFingerprint is unset") + } + + if k.Metadata.Name == "" { + return trace.BadParameter("Name is unset") + } + + return nil +} + +func privKeyHashNameKey(k *accessgraphv1pb.PrivateKeySpec) string { + return hashComp(k.DeviceId, k.PublicKeyFingerprint) +} + +func hashComp(values ...string) string { + h := sha256.New() + for _, value := range values { + h.Write([]byte(value)) + } + return hex.EncodeToString(h.Sum(nil)) +} diff --git a/api/types/accessgraph/private_key_test.go b/api/types/accessgraph/private_key_test.go new file mode 100644 index 0000000000000..c1c38bd21c49f --- /dev/null +++ b/api/types/accessgraph/private_key_test.go @@ -0,0 +1,119 @@ +/* +Copyright 2024 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 accessgraph + +import ( + "testing" + + "github.com/google/go-cmp/cmp" + "github.com/google/uuid" + "github.com/stretchr/testify/require" + "google.golang.org/protobuf/testing/protocmp" + + accessgraphv1pb "github.com/gravitational/teleport/api/gen/proto/go/teleport/accessgraph/v1" +) + +func TestPrivateKey(t *testing.T) { + tests := []struct { + name string + spec *accessgraphv1pb.PrivateKeySpec + errValidation require.ErrorAssertionFunc + }{ + { + name: "valid derived", + spec: &accessgraphv1pb.PrivateKeySpec{ + DeviceId: uuid.New().String(), + PublicKeyFingerprint: "fingerprint", + PublicKeyMode: accessgraphv1pb.PublicKeyMode_PUBLIC_KEY_MODE_DERIVED, + }, + errValidation: require.NoError, + }, + { + name: "valid file", + spec: &accessgraphv1pb.PrivateKeySpec{ + DeviceId: uuid.New().String(), + PublicKeyFingerprint: "fingerprint", + PublicKeyMode: accessgraphv1pb.PublicKeyMode_PUBLIC_KEY_MODE_PUB_FILE, + }, + errValidation: require.NoError, + }, + { + name: "missing fingerprint derived", + spec: &accessgraphv1pb.PrivateKeySpec{ + DeviceId: uuid.New().String(), + PublicKeyFingerprint: "", + PublicKeyMode: accessgraphv1pb.PublicKeyMode_PUBLIC_KEY_MODE_DERIVED, + }, + errValidation: func(t require.TestingT, err error, i ...any) { + require.ErrorContains(t, err, "PublicKeyFingerprint is unset") + }, + }, + { + name: "missing fingerprint file", + spec: &accessgraphv1pb.PrivateKeySpec{ + DeviceId: uuid.New().String(), + PublicKeyFingerprint: "", + PublicKeyMode: accessgraphv1pb.PublicKeyMode_PUBLIC_KEY_MODE_PUB_FILE, + }, + errValidation: func(t require.TestingT, err error, i ...any) { + require.ErrorContains(t, err, "PublicKeyFingerprint is unset") + }, + }, + { + name: "valid protected", + spec: &accessgraphv1pb.PrivateKeySpec{ + DeviceId: uuid.New().String(), + PublicKeyFingerprint: "", /* empty fingerprint */ + PublicKeyMode: accessgraphv1pb.PublicKeyMode_PUBLIC_KEY_MODE_PROTECTED, + }, + errValidation: require.NoError, + }, + { + name: "invalid public key ode", + spec: &accessgraphv1pb.PrivateKeySpec{ + DeviceId: uuid.New().String(), + PublicKeyFingerprint: "fingerprint", + PublicKeyMode: 500, + }, + errValidation: func(t require.TestingT, err error, i ...any) { + require.ErrorContains(t, err, "PublicKeyMode is invalid") + }, + }, + { + name: "missing DeviceId", + spec: &accessgraphv1pb.PrivateKeySpec{ + PublicKeyFingerprint: "fingerprint", + PublicKeyMode: accessgraphv1pb.PublicKeyMode_PUBLIC_KEY_MODE_PROTECTED, + }, + errValidation: func(t require.TestingT, err error, i ...any) { + require.ErrorContains(t, err, "DeviceId is unset") + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + privKey, err := NewPrivateKey(tt.spec) + tt.errValidation(t, err) + if err != nil { + return + } + require.NotEmpty(t, privKey.Metadata.Name) + require.Empty(t, cmp.Diff(tt.spec, privKey.Spec, protocmp.Transform())) + + }) + } +} diff --git a/api/types/constants.go b/api/types/constants.go index effe5f175a32d..3a0eff165449c 100644 --- a/api/types/constants.go +++ b/api/types/constants.go @@ -519,6 +519,14 @@ const ( // KindUserNotificationState is a resource which tracks whether a user has clicked on or dismissed a notification. KindUserNotificationState = "user_notification_state" + // KindAccessGraphSecretAuthorizedKey is a authorized key entry found in + // a Teleport SSH node type. + KindAccessGraphSecretAuthorizedKey = "access_graph_authorized_key" + + // KindAccessGraphSecretPrivateKey is a private key entry found in + // a managed device. + KindAccessGraphSecretPrivateKey = "access_graph_private_key" + // KindVnetConfig is a resource which holds cluster-wide configuration for VNet. KindVnetConfig = "vnet_config" diff --git a/lib/services/access_graph.go b/lib/services/access_graph.go new file mode 100644 index 0000000000000..6ff41221b5a37 --- /dev/null +++ b/lib/services/access_graph.go @@ -0,0 +1,68 @@ +/* + * Teleport + * Copyright (C) 2023 Gravitational, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package services + +import ( + "github.com/gravitational/trace" + + accessgraphsecretspb "github.com/gravitational/teleport/api/gen/proto/go/teleport/accessgraph/v1" + "github.com/gravitational/teleport/api/types/accessgraph" +) + +// MarshalAccessGraphAuthorizedKey marshals a [accessgraphsecretspb.AuthorizedKey] resource to JSON. +func MarshalAccessGraphAuthorizedKey(in *accessgraphsecretspb.AuthorizedKey, opts ...MarshalOption) ([]byte, error) { + if err := accessgraph.ValidateAuthorizedKey(in); err != nil { + return nil, trace.Wrap(err) + } + + return MarshalProtoResource(in, opts...) +} + +// UnmarshalAccessGraphAuthorizedKey unmarshals a [accessgraphsecretspb.AuthorizedKey] resource from JSON. +func UnmarshalAccessGraphAuthorizedKey(data []byte, opts ...MarshalOption) (*accessgraphsecretspb.AuthorizedKey, error) { + out, err := UnmarshalProtoResource[*accessgraphsecretspb.AuthorizedKey](data, opts...) + if err != nil { + return nil, trace.Wrap(err) + } + if err := accessgraph.ValidateAuthorizedKey(out); err != nil { + return nil, trace.Wrap(err) + } + return out, nil +} + +// MarshalAccessGraphPrivateKey marshals a [accessgraphsecretspb.PrivateKey] resource to JSON. +func MarshalAccessGraphPrivateKey(in *accessgraphsecretspb.PrivateKey, opts ...MarshalOption) ([]byte, error) { + if err := accessgraph.ValidatePrivateKey(in); err != nil { + return nil, trace.Wrap(err) + } + + return MarshalProtoResource(in, opts...) +} + +// UnmarshalAccessGraphPrivateKey unmarshals a [accessgraphsecretspb.PrivateKey] resource from JSON. +func UnmarshalAccessGraphPrivateKey(data []byte, opts ...MarshalOption) (*accessgraphsecretspb.PrivateKey, error) { + out, err := UnmarshalProtoResource[*accessgraphsecretspb.PrivateKey](data, opts...) + if err != nil { + return nil, trace.Wrap(err) + } + if err := accessgraph.ValidatePrivateKey(out); err != nil { + return nil, trace.Wrap(err) + } + return out, nil +} diff --git a/lib/services/local/access_graph.go b/lib/services/local/access_graph.go new file mode 100644 index 0000000000000..4be7ec74ec6c3 --- /dev/null +++ b/lib/services/local/access_graph.go @@ -0,0 +1,164 @@ +/* + * Teleport + * Copyright (C) 2024 Gravitational, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package local + +import ( + "context" + + "github.com/gravitational/trace" + + accessgraphsecretspb "github.com/gravitational/teleport/api/gen/proto/go/teleport/accessgraph/v1" + "github.com/gravitational/teleport/api/types" + "github.com/gravitational/teleport/lib/backend" + "github.com/gravitational/teleport/lib/services" + "github.com/gravitational/teleport/lib/services/local/generic" +) + +const ( + authorizedKeysPrefix = "access_graph_ssh_authorized_keys" + privateKeysPrefix = "access_graph_ssh_private_keys" +) + +// AccessGraphSecretsService manages secrets found on Teleport Nodes and +// enrolled devices. +type AccessGraphSecretsService struct { + authorizedKeysSvc *generic.ServiceWrapper[*accessgraphsecretspb.AuthorizedKey] + privateKeysSvc *generic.ServiceWrapper[*accessgraphsecretspb.PrivateKey] +} + +// NewAccessGraphSecretsService returns a new Access Graph Secrets service. +// This service in Teleport is used to keep track of secrets found in Teleport +// Nodes and on enrolled devices. Currently, it only stores secrets related with +// SSH Keys. Future implementations might extend them. +func NewAccessGraphSecretsService(backend backend.Backend) (*AccessGraphSecretsService, error) { + authorizedKeysSvc, err := generic.NewServiceWrapper( + backend, + types.KindAccessGraphSecretAuthorizedKey, + authorizedKeysPrefix, + services.MarshalAccessGraphAuthorizedKey, + services.UnmarshalAccessGraphAuthorizedKey, + ) + if err != nil { + return nil, trace.Wrap(err) + } + + privateKeysSvc, err := generic.NewServiceWrapper( + backend, + types.KindAccessGraphSecretPrivateKey, + privateKeysPrefix, + services.MarshalAccessGraphPrivateKey, + services.UnmarshalAccessGraphPrivateKey, + ) + if err != nil { + return nil, trace.Wrap(err) + } + + return &AccessGraphSecretsService{ + authorizedKeysSvc: authorizedKeysSvc, + privateKeysSvc: privateKeysSvc, + }, nil +} + +// ListAllAuthorizedKeys lists all authorized keys stored in the backend. +func (k *AccessGraphSecretsService) ListAllAuthorizedKeys(ctx context.Context, pageSize int, pageToken string) ([]*accessgraphsecretspb.AuthorizedKey, string, error) { + out, next, err := k.authorizedKeysSvc.ListResources(ctx, pageSize, pageToken) + if err != nil { + return nil, "", trace.Wrap(err) + } + return out, next, nil +} + +// ListAuthorizedKeysForServer lists all authorized keys for a given hostID. +func (k *AccessGraphSecretsService) ListAuthorizedKeysForServer(ctx context.Context, hostID string, pageSize int, pageToken string) ([]*accessgraphsecretspb.AuthorizedKey, string, error) { + if hostID == "" { + return nil, "", trace.BadParameter("server name is required") + } + svc := k.authorizedKeysSvc.WithPrefix(hostID) + out, next, err := svc.ListResources(ctx, pageSize, pageToken) + if err != nil { + return nil, "", trace.Wrap(err) + } + return out, next, nil +} + +// UpsertAuthorizedKey upserts a new authorized key. +func (k *AccessGraphSecretsService) UpsertAuthorizedKey(ctx context.Context, in *accessgraphsecretspb.AuthorizedKey) (*accessgraphsecretspb.AuthorizedKey, error) { + svc := k.authorizedKeysSvc.WithPrefix(in.Spec.HostId) + out, err := svc.UpsertResource(ctx, in) + if err != nil { + return nil, trace.Wrap(err) + } + + return out, nil +} + +// DeleteAuthorizedKey deletes a specific authorized key. +func (k *AccessGraphSecretsService) DeleteAuthorizedKey(ctx context.Context, hostID, name string) error { + svc := k.authorizedKeysSvc.WithPrefix(hostID) + return trace.Wrap(svc.DeleteResource(ctx, name)) +} + +// DeleteAllAuthorizedKeys deletes all authorized keys. +func (k *AccessGraphSecretsService) DeleteAllAuthorizedKeys(ctx context.Context) error { + return trace.Wrap(k.authorizedKeysSvc.DeleteAllResources(ctx)) +} + +// ListAllPrivateKeys lists all private keys stored in the backend. +func (k *AccessGraphSecretsService) ListAllPrivateKeys(ctx context.Context, pageSize int, pageToken string) ([]*accessgraphsecretspb.PrivateKey, string, error) { + out, next, err := k.privateKeysSvc.ListResources(ctx, pageSize, pageToken) + if err != nil { + return nil, "", trace.Wrap(err) + } + return out, next, nil +} + +// ListPrivateKeysForDevice lists all private keys for a given deviceID. +func (k *AccessGraphSecretsService) ListPrivateKeysForDevice(ctx context.Context, deviceID string, pageSize int, pageToken string) ([]*accessgraphsecretspb.PrivateKey, string, error) { + if deviceID == "" { + return nil, "", trace.BadParameter("server name is required") + } + svc := k.privateKeysSvc.WithPrefix(deviceID) + out, next, err := svc.ListResources(ctx, pageSize, pageToken) + if err != nil { + return nil, "", trace.Wrap(err) + } + return out, next, nil +} + +// UpsertPrivateKey upserts a new private key. +func (k *AccessGraphSecretsService) UpsertPrivateKey(ctx context.Context, in *accessgraphsecretspb.PrivateKey) (*accessgraphsecretspb.PrivateKey, error) { + svc := k.privateKeysSvc.WithPrefix(in.Spec.DeviceId) + out, err := svc.UpsertResource(ctx, in) + if err != nil { + return nil, trace.Wrap(err) + } + + return out, nil +} + +// DeletePrivateKey deletes a specific private key. +func (k *AccessGraphSecretsService) DeletePrivateKey(ctx context.Context, deviceID, name string) error { + svc := k.privateKeysSvc.WithPrefix(deviceID) + return trace.Wrap(svc.DeleteResource(ctx, name)) +} + +// DeleteAllPrivateKeys deletes all private keys. +func (k *AccessGraphSecretsService) DeleteAllPrivateKeys(ctx context.Context) error { + return trace.Wrap(k.privateKeysSvc.DeleteAllResources(ctx)) +} diff --git a/lib/services/local/access_graph_test.go b/lib/services/local/access_graph_test.go new file mode 100644 index 0000000000000..2eda122f8c045 --- /dev/null +++ b/lib/services/local/access_graph_test.go @@ -0,0 +1,247 @@ +/* + * Teleport + * Copyright (C) 2024 Gravitational, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package local + +import ( + "context" + "testing" + + "github.com/google/go-cmp/cmp" + "github.com/google/go-cmp/cmp/cmpopts" + "github.com/google/uuid" + "github.com/stretchr/testify/require" + "google.golang.org/protobuf/testing/protocmp" + + accessgraphsecretspb "github.com/gravitational/teleport/api/gen/proto/go/teleport/accessgraph/v1" + "github.com/gravitational/teleport/api/types/accessgraph" + "github.com/gravitational/teleport/lib/backend/memory" +) + +func TestAccessGraphAuthorizedKeys(t *testing.T) { + backend, err := memory.New(memory.Config{}) + require.NoError(t, err) + service, err := NewAccessGraphSecretsService(backend) + require.NoError(t, err) + + ctx := context.TODO() + pageSize := 10 + pageToken := "" + + // Test case 1: Empty list + keys, nextToken, err := service.ListAllAuthorizedKeys(ctx, pageSize, pageToken) + require.NoError(t, err) + require.Empty(t, keys) + require.Empty(t, nextToken) + + // Test case 2: Non-empty list + authorizedKeys := []*accessgraphsecretspb.AuthorizedKeySpec{ + { + HostId: "host1", + HostUser: "user1", + KeyFingerprint: "AAAAB3NzaC1yc2EAAAADAQABAAABAQC...", + }, + { + HostId: "host1", + HostUser: "user2", + KeyFingerprint: "AAAAB3NzaC1yc2EAAAADAQABAAABAQC...", + }, + { + HostId: "host2", + HostUser: "user1", + KeyFingerprint: "AAAAB3NzaC1yc2EAAAADAQABAAABAQC...", + }, + { + HostId: "host2", + HostUser: "user2", + KeyFingerprint: "AAAAB3NzaC1yc2EAAAADAQABAAABAQC...", + }, + } + var authKeys []*accessgraphsecretspb.AuthorizedKey + for _, key := range authorizedKeys { + authKey, err := accessgraph.NewAuthorizedKey(key) + require.NoError(t, err) + _, err = service.UpsertAuthorizedKey(ctx, authKey) + require.NoError(t, err) + authKeys = append(authKeys, authKey) + } + + keys, nextToken, err = service.ListAllAuthorizedKeys(ctx, pageSize, pageToken) + require.NoError(t, err) + require.Empty(t, cmp.Diff(authKeys, keys, + protocmp.Transform(), + cmpopts.SortSlices(func(a, b *accessgraphsecretspb.AuthorizedKey) bool { + return a.Metadata.Name < b.Metadata.Name + }))) + require.Empty(t, nextToken) + + // Test case 3: Pagination + pageSize = 2 + pageToken = "" + keys, nextToken, err = service.ListAllAuthorizedKeys(ctx, pageSize, pageToken) + require.NoError(t, err) + require.Len(t, keys, pageSize) + require.NotEmpty(t, nextToken) + + pageToken = nextToken + keys, nextToken, err = service.ListAllAuthorizedKeys(ctx, pageSize, pageToken) + require.NoError(t, err) + require.Len(t, keys, pageSize) + require.Empty(t, nextToken) + + // Test case 4: List authorized keys for server + pageToken = "" + keysHost1, nextToken, err := service.ListAuthorizedKeysForServer(ctx, "host1", pageSize, pageToken) + require.NoError(t, err) + require.Len(t, keys, 2) + require.Empty(t, nextToken) + keysHost2, nextToken, err := service.ListAuthorizedKeysForServer(ctx, "host2", pageSize, pageToken) + require.NoError(t, err) + require.Len(t, keys, 2) + require.Empty(t, nextToken) + require.NotEqual(t, keysHost1, keysHost2) + + // Test case 5: List authorized keys for server with pagination + pageToken = "" + pageSize = 1 + keys, nextToken, err = service.ListAuthorizedKeysForServer(ctx, "host1", pageSize, pageToken) + require.NoError(t, err) + require.Len(t, keys, 1) + require.NotEmpty(t, nextToken) + + pageToken = nextToken + keys, nextToken, err = service.ListAuthorizedKeysForServer(ctx, "host1", pageSize, pageToken) + require.NoError(t, err) + require.Len(t, keys, 1) + require.Empty(t, nextToken) + + // Test case 6: Delete all + err = service.DeleteAllAuthorizedKeys(ctx) + require.NoError(t, err) + keys, nextToken, err = service.ListAllAuthorizedKeys(ctx, pageSize, pageToken) + require.NoError(t, err) + require.Empty(t, keys) + require.Empty(t, nextToken) +} + +func TestAccessGraphPrivateKeys(t *testing.T) { + backend, err := memory.New(memory.Config{}) + require.NoError(t, err) + service, err := NewAccessGraphSecretsService(backend) + require.NoError(t, err) + + ctx := context.TODO() + pageSize := 10 + pageToken := "" + + // Test case 1: Empty list + keys, nextToken, err := service.ListAllPrivateKeys(ctx, pageSize, pageToken) + require.NoError(t, err) + require.Empty(t, keys) + require.Empty(t, nextToken) + + // Test case 2: Non-empty list + privateKeysSpec := []*accessgraphsecretspb.PrivateKeySpec{ + { + DeviceId: "device1", + PublicKeyMode: accessgraphsecretspb.PublicKeyMode_PUBLIC_KEY_MODE_DERIVED, + PublicKeyFingerprint: "AAAAB3NzaC1yc2EAAAADAQABAAABAQC...", + }, + { + DeviceId: "device1", + PublicKeyMode: accessgraphsecretspb.PublicKeyMode_PUBLIC_KEY_MODE_PUB_FILE, + PublicKeyFingerprint: "AAAAB3NzaC1yc2EAAAADAQABAAABAQC...", + }, + { + DeviceId: "device2", + PublicKeyMode: accessgraphsecretspb.PublicKeyMode_PUBLIC_KEY_MODE_DERIVED, + PublicKeyFingerprint: "AAAAB3NzaC1yc2EAAAADAQABAAABAQC...", + }, + { + DeviceId: "device2", + PublicKeyMode: accessgraphsecretspb.PublicKeyMode_PUBLIC_KEY_MODE_PUB_FILE, + PublicKeyFingerprint: "AAAAB3NzaC1yc2EAAAADAQABAAABAQC...", + }, + } + var authKeys []*accessgraphsecretspb.PrivateKey + for _, key := range privateKeysSpec { + name := uuid.New().String() + prvKey, err := accessgraph.NewPrivateKeyWithName(name, key) + require.NoError(t, err) + _, err = service.UpsertPrivateKey(ctx, prvKey) + require.NoError(t, err) + authKeys = append(authKeys, prvKey) + } + + keys, nextToken, err = service.ListAllPrivateKeys(ctx, pageSize, pageToken) + require.NoError(t, err) + require.Empty(t, cmp.Diff(authKeys, keys, + protocmp.Transform(), + cmpopts.SortSlices(func(a, b *accessgraphsecretspb.PrivateKey) bool { + return a.Metadata.Name < b.Metadata.Name + }))) + require.Empty(t, nextToken) + + // Test case 3: Pagination + pageSize = 2 + pageToken = "" + keys, nextToken, err = service.ListAllPrivateKeys(ctx, pageSize, pageToken) + require.NoError(t, err) + require.Len(t, keys, pageSize) + require.NotEmpty(t, nextToken) + + pageToken = nextToken + keys, nextToken, err = service.ListAllPrivateKeys(ctx, pageSize, pageToken) + require.NoError(t, err) + require.Len(t, keys, pageSize) + require.Empty(t, nextToken) + + // Test case 4: List private keys for device + pageToken = "" + keysHost1, nextToken, err := service.ListPrivateKeysForDevice(ctx, "device1", pageSize, pageToken) + require.NoError(t, err) + require.Len(t, keys, 2) + require.Empty(t, nextToken) + keysHost2, nextToken, err := service.ListPrivateKeysForDevice(ctx, "device2", pageSize, pageToken) + require.NoError(t, err) + require.Len(t, keys, 2) + require.Empty(t, nextToken) + require.NotEqual(t, keysHost1, keysHost2) + + // Test case 5: List private keys for device with pagination + pageToken = "" + pageSize = 1 + keys, nextToken, err = service.ListPrivateKeysForDevice(ctx, "device1", pageSize, pageToken) + require.NoError(t, err) + require.Len(t, keys, 1) + require.NotEmpty(t, nextToken) + + pageToken = nextToken + keys, nextToken, err = service.ListPrivateKeysForDevice(ctx, "device1", pageSize, pageToken) + require.NoError(t, err) + require.Len(t, keys, 1) + require.Empty(t, nextToken) + + // Test case 6: Delete all + err = service.DeleteAllPrivateKeys(ctx) + require.NoError(t, err) + keys, nextToken, err = service.ListAllPrivateKeys(ctx, pageSize, pageToken) + require.NoError(t, err) + require.Empty(t, keys) + require.Empty(t, nextToken) +} From 2874ca56b6daf7dda8f7ee926a4f283594b6338f Mon Sep 17 00:00:00 2001 From: Tiago Silva Date: Thu, 11 Jul 2024 11:27:54 +0100 Subject: [PATCH 09/25] [sec_scan][6] add device events (#43905) This PR adds the ability to watch for events for `*devicepb.Device` objects. Backend storage representation of `devicepb.Device` is achieved using an internal representation that lives in `e/lib/devicetrust/storage` and whose logic is internal to the package. To be able to expose the unmarshal logic necessary for events to work, this PR exposes a registration hook that `e/lib/devicetrust/storage` function must call during initialization to register the unmarshal function. Part of https://github.com/gravitational/access-graph/issues/637 Signed-off-by: Tiago Silva --- lib/devicetrust/keys_prefix.go | 24 +++++++++++++++++ lib/services/device.go | 35 +++++++++++++++++++++++++ lib/services/local/events.go | 47 ++++++++++++++++++++++++++++++++++ 3 files changed, 106 insertions(+) create mode 100644 lib/devicetrust/keys_prefix.go diff --git a/lib/devicetrust/keys_prefix.go b/lib/devicetrust/keys_prefix.go new file mode 100644 index 0000000000000..ed0817c5b06a1 --- /dev/null +++ b/lib/devicetrust/keys_prefix.go @@ -0,0 +1,24 @@ +/* + * Teleport + * Copyright (C) 2024 Gravitational, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package devicetrust + +var ( + // DevicesIDPrefix is the backend prefix used to store device resources. + DevicesIDPrefix = []string{"devices", "id"} +) diff --git a/lib/services/device.go b/lib/services/device.go index 65252a91b100a..319fe46bbc788 100644 --- a/lib/services/device.go +++ b/lib/services/device.go @@ -19,12 +19,20 @@ package services import ( + "context" + "github.com/gravitational/trace" + devicepb "github.com/gravitational/teleport/api/gen/proto/go/teleport/devicetrust/v1" "github.com/gravitational/teleport/api/types" + "github.com/gravitational/teleport/lib/backend" "github.com/gravitational/teleport/lib/utils" ) +type DevicesGetter interface { + ListDevices(ctx context.Context, pageSize int, pageToken string, view devicepb.DeviceView) (devices []*devicepb.Device, nextPageToken string, err error) +} + // UnmarshalDevice unmarshals a DeviceV1 resource and runs CheckAndSetDefaults. func UnmarshalDevice(raw []byte) (*types.DeviceV1, error) { dev := &types.DeviceV1{} @@ -42,3 +50,30 @@ func MarshalDevice(dev *types.DeviceV1) ([]byte, error) { } return devBytes, nil } + +var ( + // unmarshalDeviceFromBackendItemConv is a convenience function that converts + // a backend.Item to a *devicepb.Device. + // It's populated when e/lib/devicetrust/storage/ is initialized. + unmarshalDeviceFromBackendItemConv func(item backend.Item) (*devicepb.Device, error) +) + +// SetUnmarshalDeviceFromBackendItemConv allows to set a custom conversion function for +// unmarshaling a [devicepb.Device] from a [backend.Item]. +// This function must be called in the init() function of the package that owns the conversion logic. +// It's not safe to call this function concurrently. +func SetUnmarshalDeviceFromBackendItemConv(conv func(item backend.Item) (*devicepb.Device, error)) { + unmarshalDeviceFromBackendItemConv = conv +} + +// UnmarshalDeviceFromBackendItem unmarshals a devicepb.Device from a backend.Item. +// It's a convenience function that uses UnmarshalDeviceFromBackendItemConv because +// the storage package uses an internal representation of devicepb.Device when storing +// it in the backend. +func UnmarshalDeviceFromBackendItem(item backend.Item) (*devicepb.Device, error) { + if unmarshalDeviceFromBackendItemConv == nil { + return nil, trace.BadParameter("UnmarshalDeviceFromBackendItemConv is not set") + } + res, err := unmarshalDeviceFromBackendItemConv(item) + return res, trace.Wrap(err) +} diff --git a/lib/services/local/events.go b/lib/services/local/events.go index 30fbfb2adf0d6..f8ebebf028dc2 100644 --- a/lib/services/local/events.go +++ b/lib/services/local/events.go @@ -37,6 +37,7 @@ import ( "github.com/gravitational/teleport/api/types/kubewaitingcontainer" "github.com/gravitational/teleport/lib/backend" "github.com/gravitational/teleport/lib/defaults" + "github.com/gravitational/teleport/lib/devicetrust" "github.com/gravitational/teleport/lib/services" "github.com/gravitational/teleport/lib/services/local/generic" ) @@ -211,6 +212,8 @@ func (e *EventsService) NewWatcher(ctx context.Context, watch types.Watch) (type parser = newAccessMonitoringRuleParser() case types.KindInstance: parser = newInstanceParser() + case types.KindDevice: + parser = newDeviceParser() default: if watch.AllowPartialSuccess { continue @@ -2202,6 +2205,50 @@ func WaitForEvent(ctx context.Context, watcher types.Watcher, m EventMatcher, cl } } +func newDeviceParser() *deviceParser { + return &deviceParser{ + baseParser: newBaseParser(backend.Key(devicetrust.DevicesIDPrefix...)), + } +} + +type deviceParser struct { + baseParser +} + +func (p *deviceParser) parse(event backend.Event) (types.Resource, error) { + switch event.Type { + case types.OpDelete: + name, err := base(event.Item.Key, 0 /* offset */) + if err != nil { + return nil, trace.Wrap(err) + } + device := &types.DeviceV1{ + ResourceHeader: types.ResourceHeader{ + Kind: types.KindDevice, + Version: types.V1, + Metadata: types.Metadata{ + Name: string(name), + }, + }, + } + return device, nil + case types.OpPut: + device, err := services.UnmarshalDeviceFromBackendItem(event.Item) + if err != nil { + return nil, trace.Wrap(err) + } + // [devicepb.Device] doesn't satisfy types.Resource interface or Resource153 interface, + // so we need to convert it to types.DeviceV1 so it satisfy types.Resource interface. + dev := types.DeviceToResource(device) + // Set the expires and revision fields. + dev.SetExpiry(event.Item.Expires) + dev.SetRevision(event.Item.Revision) + return dev, nil + default: + return nil, trace.BadParameter("event %v is not supported", event.Type) + } +} + // Match matches the specified resource event by applying itself func (r EventMatcherFunc) Match(event types.Event) (types.Resource, error) { return r(event) From bf860949076fd5e7159bb535cfbaac097110cd1b Mon Sep 17 00:00:00 2001 From: Tiago Silva Date: Thu, 11 Jul 2024 13:55:54 +0100 Subject: [PATCH 10/25] [sec_scan][7] add authorizedKeys and privateKeys events support (#43906) This PR introduces the ability to watch for events related to `accessgraphsecretsv1pb.AuthorizedKey` and `accessgraphsecretsv1pb.PrivateKey` objects. This PR is part of https://github.com/gravitational/access-graph/issues/637. Signed-off-by: Tiago Silva --- lib/services/local/events.go | 93 ++++++++++++++++++++++++++++++++++++ 1 file changed, 93 insertions(+) diff --git a/lib/services/local/events.go b/lib/services/local/events.go index f8ebebf028dc2..44cbb744c5d56 100644 --- a/lib/services/local/events.go +++ b/lib/services/local/events.go @@ -29,6 +29,7 @@ import ( "github.com/gravitational/teleport" apidefaults "github.com/gravitational/teleport/api/defaults" + accessgraphsecretsv1pb "github.com/gravitational/teleport/api/gen/proto/go/teleport/accessgraph/v1" dbobjectv1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/dbobject/v1" headerv1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/header/v1" kubewaitingcontainerpb "github.com/gravitational/teleport/api/gen/proto/go/teleport/kubewaitingcontainer/v1" @@ -214,6 +215,10 @@ func (e *EventsService) NewWatcher(ctx context.Context, watch types.Watch) (type parser = newInstanceParser() case types.KindDevice: parser = newDeviceParser() + case types.KindAccessGraphSecretPrivateKey: + parser = newAccessGraphSecretPrivateKeyParser() + case types.KindAccessGraphSecretAuthorizedKey: + parser = newAccessGraphSecretAuthorizedKeyParser() default: if watch.AllowPartialSuccess { continue @@ -2249,6 +2254,94 @@ func (p *deviceParser) parse(event backend.Event) (types.Resource, error) { } } +func newAccessGraphSecretPrivateKeyParser() *accessGraphSecretPrivateKeyParser { + return &accessGraphSecretPrivateKeyParser{ + baseParser: newBaseParser(backend.Key(privateKeysPrefix)), + } +} + +type accessGraphSecretPrivateKeyParser struct { + baseParser +} + +func (p *accessGraphSecretPrivateKeyParser) parse(event backend.Event) (types.Resource, error) { + switch event.Type { + case types.OpDelete: + deviceID, name, err := baseTwoKeys(event.Item.Key) + if err != nil { + return nil, trace.Wrap(err) + } + + privateKey := &accessgraphsecretsv1pb.PrivateKey{ + Kind: types.KindAccessGraphSecretPrivateKey, + Version: types.V1, + Metadata: &headerv1.Metadata{ + Name: name, + }, + Spec: &accessgraphsecretsv1pb.PrivateKeySpec{ + DeviceId: deviceID, + }, + } + + return types.Resource153ToLegacy(privateKey), nil + case types.OpPut: + pk, err := services.UnmarshalAccessGraphPrivateKey( + event.Item.Value, + services.WithExpires(event.Item.Expires), + services.WithRevision(event.Item.Revision)) + if err != nil { + return nil, trace.Wrap(err) + } + return types.Resource153ToLegacy(pk), nil + default: + return nil, trace.BadParameter("event %v is not supported", event.Type) + } +} + +func newAccessGraphSecretAuthorizedKeyParser() *accessGraphSecretAuthorizedKeyParser { + return &accessGraphSecretAuthorizedKeyParser{ + baseParser: newBaseParser(backend.Key(authorizedKeysPrefix)), + } +} + +type accessGraphSecretAuthorizedKeyParser struct { + baseParser +} + +func (p *accessGraphSecretAuthorizedKeyParser) parse(event backend.Event) (types.Resource, error) { + switch event.Type { + case types.OpDelete: + hostID, name, err := baseTwoKeys(event.Item.Key) + if err != nil { + return nil, trace.Wrap(err) + } + + authorizedKey := &accessgraphsecretsv1pb.AuthorizedKey{ + Kind: types.KindAccessGraphSecretAuthorizedKey, + Version: types.V1, + Metadata: &headerv1.Metadata{ + Name: name, + }, + Spec: &accessgraphsecretsv1pb.AuthorizedKeySpec{ + HostId: hostID, + }, + } + + return types.Resource153ToLegacy(authorizedKey), nil + case types.OpPut: + ak, err := services.UnmarshalAccessGraphAuthorizedKey( + event.Item.Value, + services.WithExpires(event.Item.Expires), + services.WithRevision(event.Item.Revision)) + if err != nil { + return nil, trace.Wrap(err) + } + return types.Resource153ToLegacy(ak), nil + default: + return nil, trace.BadParameter("event %v is not supported", event.Type) + } +} + // Match matches the specified resource event by applying itself func (r EventMatcherFunc) Match(event types.Event) (types.Resource, error) { return r(event) From 559020c03856aa6408a54dca32d73578c3f9b62b Mon Sep 17 00:00:00 2001 From: Tiago Silva Date: Thu, 11 Jul 2024 11:11:36 +0100 Subject: [PATCH 11/25] [sec_scan][9] add `access_graph_settings` protobuf (#44010) This PR adds the `clusterconfigpbv1.AccessGraphSettings` resource that will be used to control the secrets scanning definition of Teleport. This resource will be a singleton and the only goal is to carry some settings related to access graph because on the cloud, users don't have access to fileconf. This PR is part of https://github.com/gravitational/access-graph/issues/637. Signed-off-by: Tiago Silva --- .../v1/access_graph_settings.pb.go | 359 ++++++++ .../v1/clusterconfig_service.pb.go | 816 +++++++++++++----- .../v1/clusterconfig_service_grpc.pb.go | 199 ++++- .../v1/access_graph_settings.proto | 51 ++ .../v1/clusterconfig_service.proto | 35 +- 5 files changed, 1238 insertions(+), 222 deletions(-) create mode 100644 api/gen/proto/go/teleport/clusterconfig/v1/access_graph_settings.pb.go create mode 100644 api/proto/teleport/clusterconfig/v1/access_graph_settings.proto diff --git a/api/gen/proto/go/teleport/clusterconfig/v1/access_graph_settings.pb.go b/api/gen/proto/go/teleport/clusterconfig/v1/access_graph_settings.pb.go new file mode 100644 index 0000000000000..93c3141620969 --- /dev/null +++ b/api/gen/proto/go/teleport/clusterconfig/v1/access_graph_settings.pb.go @@ -0,0 +1,359 @@ +// Copyright 2024 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. + +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.34.0 +// protoc (unknown) +// source: teleport/clusterconfig/v1/access_graph_settings.proto + +package clusterconfigv1 + +import ( + v1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/header/v1" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// AccessGraphSecretsScanConfig is used to configure the parameters for the secrets scanning functionality. +type AccessGraphSecretsScanConfig int32 + +const ( + // ACCESS_GRAPH_SECRETS_SCAN_CONFIG_UNSPECIFIED is an unknown secrets scan configuration. + AccessGraphSecretsScanConfig_ACCESS_GRAPH_SECRETS_SCAN_CONFIG_UNSPECIFIED AccessGraphSecretsScanConfig = 0 + // ACCESS_GRAPH_SECRETS_SCAN_CONFIG_DISABLED is a disabled secrets scan configuration. + AccessGraphSecretsScanConfig_ACCESS_GRAPH_SECRETS_SCAN_CONFIG_DISABLED AccessGraphSecretsScanConfig = 1 + // ACCESS_GRAPH_SECRETS_SCAN_CONFIG_ENABLED is an enabled secrets scan configuration. + AccessGraphSecretsScanConfig_ACCESS_GRAPH_SECRETS_SCAN_CONFIG_ENABLED AccessGraphSecretsScanConfig = 2 +) + +// Enum value maps for AccessGraphSecretsScanConfig. +var ( + AccessGraphSecretsScanConfig_name = map[int32]string{ + 0: "ACCESS_GRAPH_SECRETS_SCAN_CONFIG_UNSPECIFIED", + 1: "ACCESS_GRAPH_SECRETS_SCAN_CONFIG_DISABLED", + 2: "ACCESS_GRAPH_SECRETS_SCAN_CONFIG_ENABLED", + } + AccessGraphSecretsScanConfig_value = map[string]int32{ + "ACCESS_GRAPH_SECRETS_SCAN_CONFIG_UNSPECIFIED": 0, + "ACCESS_GRAPH_SECRETS_SCAN_CONFIG_DISABLED": 1, + "ACCESS_GRAPH_SECRETS_SCAN_CONFIG_ENABLED": 2, + } +) + +func (x AccessGraphSecretsScanConfig) Enum() *AccessGraphSecretsScanConfig { + p := new(AccessGraphSecretsScanConfig) + *p = x + return p +} + +func (x AccessGraphSecretsScanConfig) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (AccessGraphSecretsScanConfig) Descriptor() protoreflect.EnumDescriptor { + return file_teleport_clusterconfig_v1_access_graph_settings_proto_enumTypes[0].Descriptor() +} + +func (AccessGraphSecretsScanConfig) Type() protoreflect.EnumType { + return &file_teleport_clusterconfig_v1_access_graph_settings_proto_enumTypes[0] +} + +func (x AccessGraphSecretsScanConfig) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use AccessGraphSecretsScanConfig.Descriptor instead. +func (AccessGraphSecretsScanConfig) EnumDescriptor() ([]byte, []int) { + return file_teleport_clusterconfig_v1_access_graph_settings_proto_rawDescGZIP(), []int{0} +} + +// AccessGraphSettings holds dynamic configuration settings for the Access Graph service. +type AccessGraphSettings struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // kind is the kind of the resource. + Kind string `protobuf:"bytes,1,opt,name=kind,proto3" json:"kind,omitempty"` + // sub_kind is the sub kind of the resource. + SubKind string `protobuf:"bytes,2,opt,name=sub_kind,json=subKind,proto3" json:"sub_kind,omitempty"` + // version is the version of the resource. + Version string `protobuf:"bytes,3,opt,name=version,proto3" json:"version,omitempty"` + // metadata is the metadata of the resource. + Metadata *v1.Metadata `protobuf:"bytes,4,opt,name=metadata,proto3" json:"metadata,omitempty"` + // spec is the spec of the resource. + Spec *AccessGraphSettingsSpec `protobuf:"bytes,5,opt,name=spec,proto3" json:"spec,omitempty"` +} + +func (x *AccessGraphSettings) Reset() { + *x = AccessGraphSettings{} + if protoimpl.UnsafeEnabled { + mi := &file_teleport_clusterconfig_v1_access_graph_settings_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *AccessGraphSettings) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AccessGraphSettings) ProtoMessage() {} + +func (x *AccessGraphSettings) ProtoReflect() protoreflect.Message { + mi := &file_teleport_clusterconfig_v1_access_graph_settings_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AccessGraphSettings.ProtoReflect.Descriptor instead. +func (*AccessGraphSettings) Descriptor() ([]byte, []int) { + return file_teleport_clusterconfig_v1_access_graph_settings_proto_rawDescGZIP(), []int{0} +} + +func (x *AccessGraphSettings) GetKind() string { + if x != nil { + return x.Kind + } + return "" +} + +func (x *AccessGraphSettings) GetSubKind() string { + if x != nil { + return x.SubKind + } + return "" +} + +func (x *AccessGraphSettings) GetVersion() string { + if x != nil { + return x.Version + } + return "" +} + +func (x *AccessGraphSettings) GetMetadata() *v1.Metadata { + if x != nil { + return x.Metadata + } + return nil +} + +func (x *AccessGraphSettings) GetSpec() *AccessGraphSettingsSpec { + if x != nil { + return x.Spec + } + return nil +} + +// AccessGraphSettingsSpec is the spec for the Access Graph service configuration settings. +type AccessGraphSettingsSpec struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // secrets_scan_config is used to configure the parameters for the secrets scanning functionality. + SecretsScanConfig AccessGraphSecretsScanConfig `protobuf:"varint,1,opt,name=secrets_scan_config,json=secretsScanConfig,proto3,enum=teleport.clusterconfig.v1.AccessGraphSecretsScanConfig" json:"secrets_scan_config,omitempty"` +} + +func (x *AccessGraphSettingsSpec) Reset() { + *x = AccessGraphSettingsSpec{} + if protoimpl.UnsafeEnabled { + mi := &file_teleport_clusterconfig_v1_access_graph_settings_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *AccessGraphSettingsSpec) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AccessGraphSettingsSpec) ProtoMessage() {} + +func (x *AccessGraphSettingsSpec) ProtoReflect() protoreflect.Message { + mi := &file_teleport_clusterconfig_v1_access_graph_settings_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AccessGraphSettingsSpec.ProtoReflect.Descriptor instead. +func (*AccessGraphSettingsSpec) Descriptor() ([]byte, []int) { + return file_teleport_clusterconfig_v1_access_graph_settings_proto_rawDescGZIP(), []int{1} +} + +func (x *AccessGraphSettingsSpec) GetSecretsScanConfig() AccessGraphSecretsScanConfig { + if x != nil { + return x.SecretsScanConfig + } + return AccessGraphSecretsScanConfig_ACCESS_GRAPH_SECRETS_SCAN_CONFIG_UNSPECIFIED +} + +var File_teleport_clusterconfig_v1_access_graph_settings_proto protoreflect.FileDescriptor + +var file_teleport_clusterconfig_v1_access_graph_settings_proto_rawDesc = []byte{ + 0x0a, 0x35, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x63, 0x6c, 0x75, 0x73, 0x74, + 0x65, 0x72, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2f, 0x76, 0x31, 0x2f, 0x61, 0x63, 0x63, 0x65, + 0x73, 0x73, 0x5f, 0x67, 0x72, 0x61, 0x70, 0x68, 0x5f, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, + 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x19, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, + 0x74, 0x2e, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, + 0x76, 0x31, 0x1a, 0x21, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x68, 0x65, 0x61, + 0x64, 0x65, 0x72, 0x2f, 0x76, 0x31, 0x2f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xe0, 0x01, 0x0a, 0x13, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, + 0x47, 0x72, 0x61, 0x70, 0x68, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x12, 0x0a, + 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6b, 0x69, 0x6e, + 0x64, 0x12, 0x19, 0x0a, 0x08, 0x73, 0x75, 0x62, 0x5f, 0x6b, 0x69, 0x6e, 0x64, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x75, 0x62, 0x4b, 0x69, 0x6e, 0x64, 0x12, 0x18, 0x0a, 0x07, + 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, + 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x38, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, + 0x74, 0x61, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, + 0x6f, 0x72, 0x74, 0x2e, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x65, + 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, + 0x12, 0x46, 0x0a, 0x04, 0x73, 0x70, 0x65, 0x63, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x32, + 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, + 0x72, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x47, 0x72, 0x61, 0x70, 0x68, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x53, 0x70, + 0x65, 0x63, 0x52, 0x04, 0x73, 0x70, 0x65, 0x63, 0x22, 0x82, 0x01, 0x0a, 0x17, 0x41, 0x63, 0x63, + 0x65, 0x73, 0x73, 0x47, 0x72, 0x61, 0x70, 0x68, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, + 0x53, 0x70, 0x65, 0x63, 0x12, 0x67, 0x0a, 0x13, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x73, 0x5f, + 0x73, 0x63, 0x61, 0x6e, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0e, 0x32, 0x37, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x63, 0x6c, 0x75, + 0x73, 0x74, 0x65, 0x72, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x47, 0x72, 0x61, 0x70, 0x68, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x73, + 0x53, 0x63, 0x61, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x11, 0x73, 0x65, 0x63, 0x72, + 0x65, 0x74, 0x73, 0x53, 0x63, 0x61, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2a, 0xad, 0x01, + 0x0a, 0x1c, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x47, 0x72, 0x61, 0x70, 0x68, 0x53, 0x65, 0x63, + 0x72, 0x65, 0x74, 0x73, 0x53, 0x63, 0x61, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x30, + 0x0a, 0x2c, 0x41, 0x43, 0x43, 0x45, 0x53, 0x53, 0x5f, 0x47, 0x52, 0x41, 0x50, 0x48, 0x5f, 0x53, + 0x45, 0x43, 0x52, 0x45, 0x54, 0x53, 0x5f, 0x53, 0x43, 0x41, 0x4e, 0x5f, 0x43, 0x4f, 0x4e, 0x46, + 0x49, 0x47, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, + 0x12, 0x2d, 0x0a, 0x29, 0x41, 0x43, 0x43, 0x45, 0x53, 0x53, 0x5f, 0x47, 0x52, 0x41, 0x50, 0x48, + 0x5f, 0x53, 0x45, 0x43, 0x52, 0x45, 0x54, 0x53, 0x5f, 0x53, 0x43, 0x41, 0x4e, 0x5f, 0x43, 0x4f, + 0x4e, 0x46, 0x49, 0x47, 0x5f, 0x44, 0x49, 0x53, 0x41, 0x42, 0x4c, 0x45, 0x44, 0x10, 0x01, 0x12, + 0x2c, 0x0a, 0x28, 0x41, 0x43, 0x43, 0x45, 0x53, 0x53, 0x5f, 0x47, 0x52, 0x41, 0x50, 0x48, 0x5f, + 0x53, 0x45, 0x43, 0x52, 0x45, 0x54, 0x53, 0x5f, 0x53, 0x43, 0x41, 0x4e, 0x5f, 0x43, 0x4f, 0x4e, + 0x46, 0x49, 0x47, 0x5f, 0x45, 0x4e, 0x41, 0x42, 0x4c, 0x45, 0x44, 0x10, 0x02, 0x42, 0x5e, 0x5a, + 0x5c, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x72, 0x61, 0x76, + 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x2f, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, + 0x72, 0x74, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x2f, 0x67, 0x6f, 0x2f, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x63, 0x6c, 0x75, + 0x73, 0x74, 0x65, 0x72, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2f, 0x76, 0x31, 0x3b, 0x63, 0x6c, + 0x75, 0x73, 0x74, 0x65, 0x72, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x76, 0x31, 0x62, 0x06, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_teleport_clusterconfig_v1_access_graph_settings_proto_rawDescOnce sync.Once + file_teleport_clusterconfig_v1_access_graph_settings_proto_rawDescData = file_teleport_clusterconfig_v1_access_graph_settings_proto_rawDesc +) + +func file_teleport_clusterconfig_v1_access_graph_settings_proto_rawDescGZIP() []byte { + file_teleport_clusterconfig_v1_access_graph_settings_proto_rawDescOnce.Do(func() { + file_teleport_clusterconfig_v1_access_graph_settings_proto_rawDescData = protoimpl.X.CompressGZIP(file_teleport_clusterconfig_v1_access_graph_settings_proto_rawDescData) + }) + return file_teleport_clusterconfig_v1_access_graph_settings_proto_rawDescData +} + +var file_teleport_clusterconfig_v1_access_graph_settings_proto_enumTypes = make([]protoimpl.EnumInfo, 1) +var file_teleport_clusterconfig_v1_access_graph_settings_proto_msgTypes = make([]protoimpl.MessageInfo, 2) +var file_teleport_clusterconfig_v1_access_graph_settings_proto_goTypes = []interface{}{ + (AccessGraphSecretsScanConfig)(0), // 0: teleport.clusterconfig.v1.AccessGraphSecretsScanConfig + (*AccessGraphSettings)(nil), // 1: teleport.clusterconfig.v1.AccessGraphSettings + (*AccessGraphSettingsSpec)(nil), // 2: teleport.clusterconfig.v1.AccessGraphSettingsSpec + (*v1.Metadata)(nil), // 3: teleport.header.v1.Metadata +} +var file_teleport_clusterconfig_v1_access_graph_settings_proto_depIdxs = []int32{ + 3, // 0: teleport.clusterconfig.v1.AccessGraphSettings.metadata:type_name -> teleport.header.v1.Metadata + 2, // 1: teleport.clusterconfig.v1.AccessGraphSettings.spec:type_name -> teleport.clusterconfig.v1.AccessGraphSettingsSpec + 0, // 2: teleport.clusterconfig.v1.AccessGraphSettingsSpec.secrets_scan_config:type_name -> teleport.clusterconfig.v1.AccessGraphSecretsScanConfig + 3, // [3:3] is the sub-list for method output_type + 3, // [3:3] is the sub-list for method input_type + 3, // [3:3] is the sub-list for extension type_name + 3, // [3:3] is the sub-list for extension extendee + 0, // [0:3] is the sub-list for field type_name +} + +func init() { file_teleport_clusterconfig_v1_access_graph_settings_proto_init() } +func file_teleport_clusterconfig_v1_access_graph_settings_proto_init() { + if File_teleport_clusterconfig_v1_access_graph_settings_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_teleport_clusterconfig_v1_access_graph_settings_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*AccessGraphSettings); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_teleport_clusterconfig_v1_access_graph_settings_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*AccessGraphSettingsSpec); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_teleport_clusterconfig_v1_access_graph_settings_proto_rawDesc, + NumEnums: 1, + NumMessages: 2, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_teleport_clusterconfig_v1_access_graph_settings_proto_goTypes, + DependencyIndexes: file_teleport_clusterconfig_v1_access_graph_settings_proto_depIdxs, + EnumInfos: file_teleport_clusterconfig_v1_access_graph_settings_proto_enumTypes, + MessageInfos: file_teleport_clusterconfig_v1_access_graph_settings_proto_msgTypes, + }.Build() + File_teleport_clusterconfig_v1_access_graph_settings_proto = out.File + file_teleport_clusterconfig_v1_access_graph_settings_proto_rawDesc = nil + file_teleport_clusterconfig_v1_access_graph_settings_proto_goTypes = nil + file_teleport_clusterconfig_v1_access_graph_settings_proto_depIdxs = nil +} diff --git a/api/gen/proto/go/teleport/clusterconfig/v1/clusterconfig_service.pb.go b/api/gen/proto/go/teleport/clusterconfig/v1/clusterconfig_service.pb.go index 5800164fee0e4..16fd98fa757f8 100644 --- a/api/gen/proto/go/teleport/clusterconfig/v1/clusterconfig_service.pb.go +++ b/api/gen/proto/go/teleport/clusterconfig/v1/clusterconfig_service.pb.go @@ -684,6 +684,228 @@ func (x *GetClusterAccessGraphConfigResponse) GetAccessGraph() *AccessGraphConfi return nil } +// Request for GetAccessGraphSettings +type GetAccessGraphSettingsRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *GetAccessGraphSettingsRequest) Reset() { + *x = GetAccessGraphSettingsRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_teleport_clusterconfig_v1_clusterconfig_service_proto_msgTypes[15] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetAccessGraphSettingsRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetAccessGraphSettingsRequest) ProtoMessage() {} + +func (x *GetAccessGraphSettingsRequest) ProtoReflect() protoreflect.Message { + mi := &file_teleport_clusterconfig_v1_clusterconfig_service_proto_msgTypes[15] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetAccessGraphSettingsRequest.ProtoReflect.Descriptor instead. +func (*GetAccessGraphSettingsRequest) Descriptor() ([]byte, []int) { + return file_teleport_clusterconfig_v1_clusterconfig_service_proto_rawDescGZIP(), []int{15} +} + +// Request for CreateAccessGraphSettings +type CreateAccessGraphSettingsRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + AccessGraphSettings *AccessGraphSettings `protobuf:"bytes,1,opt,name=access_graph_settings,json=accessGraphSettings,proto3" json:"access_graph_settings,omitempty"` +} + +func (x *CreateAccessGraphSettingsRequest) Reset() { + *x = CreateAccessGraphSettingsRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_teleport_clusterconfig_v1_clusterconfig_service_proto_msgTypes[16] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CreateAccessGraphSettingsRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CreateAccessGraphSettingsRequest) ProtoMessage() {} + +func (x *CreateAccessGraphSettingsRequest) ProtoReflect() protoreflect.Message { + mi := &file_teleport_clusterconfig_v1_clusterconfig_service_proto_msgTypes[16] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CreateAccessGraphSettingsRequest.ProtoReflect.Descriptor instead. +func (*CreateAccessGraphSettingsRequest) Descriptor() ([]byte, []int) { + return file_teleport_clusterconfig_v1_clusterconfig_service_proto_rawDescGZIP(), []int{16} +} + +func (x *CreateAccessGraphSettingsRequest) GetAccessGraphSettings() *AccessGraphSettings { + if x != nil { + return x.AccessGraphSettings + } + return nil +} + +// Request for UpdateAccessGraphSettings +type UpdateAccessGraphSettingsRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + AccessGraphSettings *AccessGraphSettings `protobuf:"bytes,1,opt,name=access_graph_settings,json=accessGraphSettings,proto3" json:"access_graph_settings,omitempty"` +} + +func (x *UpdateAccessGraphSettingsRequest) Reset() { + *x = UpdateAccessGraphSettingsRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_teleport_clusterconfig_v1_clusterconfig_service_proto_msgTypes[17] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UpdateAccessGraphSettingsRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpdateAccessGraphSettingsRequest) ProtoMessage() {} + +func (x *UpdateAccessGraphSettingsRequest) ProtoReflect() protoreflect.Message { + mi := &file_teleport_clusterconfig_v1_clusterconfig_service_proto_msgTypes[17] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UpdateAccessGraphSettingsRequest.ProtoReflect.Descriptor instead. +func (*UpdateAccessGraphSettingsRequest) Descriptor() ([]byte, []int) { + return file_teleport_clusterconfig_v1_clusterconfig_service_proto_rawDescGZIP(), []int{17} +} + +func (x *UpdateAccessGraphSettingsRequest) GetAccessGraphSettings() *AccessGraphSettings { + if x != nil { + return x.AccessGraphSettings + } + return nil +} + +// Request for UpsertAccessGraphSettings +type UpsertAccessGraphSettingsRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + AccessGraphSettings *AccessGraphSettings `protobuf:"bytes,1,opt,name=access_graph_settings,json=accessGraphSettings,proto3" json:"access_graph_settings,omitempty"` +} + +func (x *UpsertAccessGraphSettingsRequest) Reset() { + *x = UpsertAccessGraphSettingsRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_teleport_clusterconfig_v1_clusterconfig_service_proto_msgTypes[18] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UpsertAccessGraphSettingsRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpsertAccessGraphSettingsRequest) ProtoMessage() {} + +func (x *UpsertAccessGraphSettingsRequest) ProtoReflect() protoreflect.Message { + mi := &file_teleport_clusterconfig_v1_clusterconfig_service_proto_msgTypes[18] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UpsertAccessGraphSettingsRequest.ProtoReflect.Descriptor instead. +func (*UpsertAccessGraphSettingsRequest) Descriptor() ([]byte, []int) { + return file_teleport_clusterconfig_v1_clusterconfig_service_proto_rawDescGZIP(), []int{18} +} + +func (x *UpsertAccessGraphSettingsRequest) GetAccessGraphSettings() *AccessGraphSettings { + if x != nil { + return x.AccessGraphSettings + } + return nil +} + +// Request for ResetAccessGraphSettings +type ResetAccessGraphSettingsRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *ResetAccessGraphSettingsRequest) Reset() { + *x = ResetAccessGraphSettingsRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_teleport_clusterconfig_v1_clusterconfig_service_proto_msgTypes[19] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ResetAccessGraphSettingsRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ResetAccessGraphSettingsRequest) ProtoMessage() {} + +func (x *ResetAccessGraphSettingsRequest) ProtoReflect() protoreflect.Message { + mi := &file_teleport_clusterconfig_v1_clusterconfig_service_proto_msgTypes[19] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ResetAccessGraphSettingsRequest.ProtoReflect.Descriptor instead. +func (*ResetAccessGraphSettingsRequest) Descriptor() ([]byte, []int) { + return file_teleport_clusterconfig_v1_clusterconfig_service_proto_rawDescGZIP(), []int{19} +} + var File_teleport_clusterconfig_v1_clusterconfig_service_proto protoreflect.FileDescriptor var file_teleport_clusterconfig_v1_clusterconfig_service_proto_rawDesc = []byte{ @@ -695,193 +917,269 @@ var file_teleport_clusterconfig_v1_clusterconfig_service_proto_rawDesc = []byte{ 0x76, 0x31, 0x1a, 0x2c, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2f, 0x76, 0x31, 0x2f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x67, 0x72, 0x61, 0x70, 0x68, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x1a, 0x21, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x6c, 0x65, 0x67, 0x61, 0x63, - 0x79, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x22, 0x23, 0x0a, 0x21, 0x47, 0x65, 0x74, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, - 0x72, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x66, 0x69, - 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x7e, 0x0a, 0x24, 0x55, 0x70, 0x64, 0x61, - 0x74, 0x65, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, - 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x12, 0x56, 0x0a, 0x16, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x5f, 0x6e, 0x65, 0x74, 0x77, - 0x6f, 0x72, 0x6b, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x20, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, - 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, - 0x56, 0x32, 0x52, 0x14, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x4e, 0x65, 0x74, 0x77, 0x6f, - 0x72, 0x6b, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x22, 0x7e, 0x0a, 0x24, 0x55, 0x70, 0x73, 0x65, - 0x72, 0x74, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, - 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x12, 0x56, 0x0a, 0x16, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x5f, 0x6e, 0x65, 0x74, 0x77, - 0x6f, 0x72, 0x6b, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x20, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, - 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, - 0x56, 0x32, 0x52, 0x14, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x4e, 0x65, 0x74, 0x77, 0x6f, - 0x72, 0x6b, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x22, 0x25, 0x0a, 0x23, 0x52, 0x65, 0x73, 0x65, + 0x1a, 0x35, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x63, 0x6c, 0x75, 0x73, 0x74, + 0x65, 0x72, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2f, 0x76, 0x31, 0x2f, 0x61, 0x63, 0x63, 0x65, + 0x73, 0x73, 0x5f, 0x67, 0x72, 0x61, 0x70, 0x68, 0x5f, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, + 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x21, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, + 0x74, 0x2f, 0x6c, 0x65, 0x67, 0x61, 0x63, 0x79, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2f, 0x74, + 0x79, 0x70, 0x65, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x23, 0x0a, 0x21, 0x47, 0x65, 0x74, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, - 0x22, 0x0a, 0x20, 0x47, 0x65, 0x74, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x63, - 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x22, 0x80, 0x01, 0x0a, 0x23, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x65, - 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x43, 0x6f, - 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x59, 0x0a, 0x18, 0x73, - 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x72, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x67, - 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, - 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x63, - 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x56, 0x32, 0x52, 0x16, - 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x67, - 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x22, 0x80, 0x01, 0x0a, 0x23, 0x55, 0x70, 0x73, 0x65, 0x72, - 0x74, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x69, 0x6e, - 0x67, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x59, - 0x0a, 0x18, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x72, 0x65, 0x63, 0x6f, 0x72, 0x64, - 0x69, 0x6e, 0x67, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x1f, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, - 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x56, - 0x32, 0x52, 0x16, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, - 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x22, 0x24, 0x0a, 0x22, 0x52, 0x65, 0x73, - 0x65, 0x74, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x69, - 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, - 0x1a, 0x0a, 0x18, 0x47, 0x65, 0x74, 0x41, 0x75, 0x74, 0x68, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, - 0x65, 0x6e, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x5f, 0x0a, 0x1b, 0x55, - 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x75, 0x74, 0x68, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, - 0x6e, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x40, 0x0a, 0x0f, 0x61, 0x75, - 0x74, 0x68, 0x5f, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x41, 0x75, 0x74, 0x68, - 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x56, 0x32, 0x52, 0x0e, 0x61, 0x75, - 0x74, 0x68, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x22, 0x5f, 0x0a, 0x1b, - 0x55, 0x70, 0x73, 0x65, 0x72, 0x74, 0x41, 0x75, 0x74, 0x68, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, - 0x65, 0x6e, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x40, 0x0a, 0x0f, 0x61, - 0x75, 0x74, 0x68, 0x5f, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x41, 0x75, 0x74, - 0x68, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x56, 0x32, 0x52, 0x0e, 0x61, - 0x75, 0x74, 0x68, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x22, 0x1c, 0x0a, - 0x1a, 0x52, 0x65, 0x73, 0x65, 0x74, 0x41, 0x75, 0x74, 0x68, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, - 0x65, 0x6e, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x1e, 0x0a, 0x1c, 0x47, - 0x65, 0x74, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x41, 0x75, 0x64, 0x69, 0x74, 0x43, 0x6f, - 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x24, 0x0a, 0x22, 0x47, - 0x65, 0x74, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x47, - 0x72, 0x61, 0x70, 0x68, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x22, 0x76, 0x0a, 0x23, 0x47, 0x65, 0x74, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x41, - 0x63, 0x63, 0x65, 0x73, 0x73, 0x47, 0x72, 0x61, 0x70, 0x68, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4f, 0x0a, 0x0c, 0x61, 0x63, 0x63, 0x65, - 0x73, 0x73, 0x5f, 0x67, 0x72, 0x61, 0x70, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2c, + 0x7e, 0x0a, 0x24, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, + 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x56, 0x0a, 0x16, 0x63, 0x6c, 0x75, 0x73, 0x74, + 0x65, 0x72, 0x5f, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, + 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, + 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x69, 0x6e, + 0x67, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x56, 0x32, 0x52, 0x14, 0x63, 0x6c, 0x75, 0x73, 0x74, + 0x65, 0x72, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x22, + 0x7e, 0x0a, 0x24, 0x55, 0x70, 0x73, 0x65, 0x72, 0x74, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, + 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x56, 0x0a, 0x16, 0x63, 0x6c, 0x75, 0x73, 0x74, + 0x65, 0x72, 0x5f, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, + 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, + 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x69, 0x6e, + 0x67, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x56, 0x32, 0x52, 0x14, 0x63, 0x6c, 0x75, 0x73, 0x74, + 0x65, 0x72, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x22, + 0x25, 0x0a, 0x23, 0x52, 0x65, 0x73, 0x65, 0x74, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x4e, + 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x22, 0x0a, 0x20, 0x47, 0x65, 0x74, 0x53, 0x65, 0x73, + 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, + 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x80, 0x01, 0x0a, 0x23, 0x55, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x63, 0x6f, + 0x72, 0x64, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x12, 0x59, 0x0a, 0x18, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x72, 0x65, + 0x63, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x53, 0x65, 0x73, + 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, + 0x66, 0x69, 0x67, 0x56, 0x32, 0x52, 0x16, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, + 0x63, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x22, 0x80, 0x01, + 0x0a, 0x23, 0x55, 0x70, 0x73, 0x65, 0x72, 0x74, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, + 0x65, 0x63, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x59, 0x0a, 0x18, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, + 0x5f, 0x72, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, + 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, + 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x67, + 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x56, 0x32, 0x52, 0x16, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, + 0x6e, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, + 0x22, 0x24, 0x0a, 0x22, 0x52, 0x65, 0x73, 0x65, 0x74, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, + 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x1a, 0x0a, 0x18, 0x47, 0x65, 0x74, 0x41, 0x75, 0x74, + 0x68, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x22, 0x5f, 0x0a, 0x1b, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x75, 0x74, 0x68, + 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x12, 0x40, 0x0a, 0x0f, 0x61, 0x75, 0x74, 0x68, 0x5f, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, + 0x65, 0x6e, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x79, 0x70, + 0x65, 0x73, 0x2e, 0x41, 0x75, 0x74, 0x68, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, + 0x65, 0x56, 0x32, 0x52, 0x0e, 0x61, 0x75, 0x74, 0x68, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, + 0x6e, 0x63, 0x65, 0x22, 0x5f, 0x0a, 0x1b, 0x55, 0x70, 0x73, 0x65, 0x72, 0x74, 0x41, 0x75, 0x74, + 0x68, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x12, 0x40, 0x0a, 0x0f, 0x61, 0x75, 0x74, 0x68, 0x5f, 0x70, 0x72, 0x65, 0x66, 0x65, + 0x72, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x79, + 0x70, 0x65, 0x73, 0x2e, 0x41, 0x75, 0x74, 0x68, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, + 0x63, 0x65, 0x56, 0x32, 0x52, 0x0e, 0x61, 0x75, 0x74, 0x68, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, + 0x65, 0x6e, 0x63, 0x65, 0x22, 0x1c, 0x0a, 0x1a, 0x52, 0x65, 0x73, 0x65, 0x74, 0x41, 0x75, 0x74, + 0x68, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x22, 0x1e, 0x0a, 0x1c, 0x47, 0x65, 0x74, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, + 0x41, 0x75, 0x64, 0x69, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x22, 0x24, 0x0a, 0x22, 0x47, 0x65, 0x74, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, + 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x47, 0x72, 0x61, 0x70, 0x68, 0x43, 0x6f, 0x6e, 0x66, 0x69, + 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x76, 0x0a, 0x23, 0x47, 0x65, 0x74, 0x43, + 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x47, 0x72, 0x61, 0x70, + 0x68, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x4f, 0x0a, 0x0c, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x67, 0x72, 0x61, 0x70, 0x68, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, + 0x2e, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, + 0x31, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x47, 0x72, 0x61, 0x70, 0x68, 0x43, 0x6f, 0x6e, + 0x66, 0x69, 0x67, 0x52, 0x0b, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x47, 0x72, 0x61, 0x70, 0x68, + 0x22, 0x1f, 0x0a, 0x1d, 0x47, 0x65, 0x74, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x47, 0x72, 0x61, + 0x70, 0x68, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x22, 0x86, 0x01, 0x0a, 0x20, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, 0x63, 0x63, 0x65, + 0x73, 0x73, 0x47, 0x72, 0x61, 0x70, 0x68, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x62, 0x0a, 0x15, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, + 0x5f, 0x67, 0x72, 0x61, 0x70, 0x68, 0x5f, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, + 0x2e, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, + 0x31, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x47, 0x72, 0x61, 0x70, 0x68, 0x53, 0x65, 0x74, + 0x74, 0x69, 0x6e, 0x67, 0x73, 0x52, 0x13, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x47, 0x72, 0x61, + 0x70, 0x68, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x22, 0x86, 0x01, 0x0a, 0x20, 0x55, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x47, 0x72, 0x61, 0x70, 0x68, + 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x62, 0x0a, 0x15, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x67, 0x72, 0x61, 0x70, 0x68, 0x5f, + 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, - 0x73, 0x47, 0x72, 0x61, 0x70, 0x68, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x0b, 0x61, 0x63, - 0x63, 0x65, 0x73, 0x73, 0x47, 0x72, 0x61, 0x70, 0x68, 0x32, 0xc7, 0x0d, 0x0a, 0x14, 0x43, 0x6c, - 0x75, 0x73, 0x74, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x53, 0x65, 0x72, 0x76, 0x69, - 0x63, 0x65, 0x12, 0x7c, 0x0a, 0x1a, 0x47, 0x65, 0x74, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, - 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, - 0x12, 0x3c, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x63, 0x6c, 0x75, 0x73, - 0x74, 0x65, 0x72, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, + 0x73, 0x47, 0x72, 0x61, 0x70, 0x68, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x52, 0x13, + 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x47, 0x72, 0x61, 0x70, 0x68, 0x53, 0x65, 0x74, 0x74, 0x69, + 0x6e, 0x67, 0x73, 0x22, 0x86, 0x01, 0x0a, 0x20, 0x55, 0x70, 0x73, 0x65, 0x72, 0x74, 0x41, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x47, 0x72, 0x61, 0x70, 0x68, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, + 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x62, 0x0a, 0x15, 0x61, 0x63, 0x63, 0x65, + 0x73, 0x73, 0x5f, 0x67, 0x72, 0x61, 0x70, 0x68, 0x5f, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, + 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, + 0x72, 0x74, 0x2e, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, + 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x47, 0x72, 0x61, 0x70, 0x68, 0x53, + 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x52, 0x13, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x47, + 0x72, 0x61, 0x70, 0x68, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x22, 0x21, 0x0a, 0x1f, + 0x52, 0x65, 0x73, 0x65, 0x74, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x47, 0x72, 0x61, 0x70, 0x68, + 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x32, + 0xf6, 0x12, 0x0a, 0x14, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, + 0x67, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x7c, 0x0a, 0x1a, 0x47, 0x65, 0x74, 0x43, + 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x69, 0x6e, 0x67, + 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x3c, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, + 0x74, 0x2e, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, + 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x4e, 0x65, 0x74, + 0x77, 0x6f, 0x72, 0x6b, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x43, 0x6c, 0x75, + 0x73, 0x74, 0x65, 0x72, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x69, 0x6e, 0x67, 0x43, 0x6f, + 0x6e, 0x66, 0x69, 0x67, 0x56, 0x32, 0x12, 0x82, 0x01, 0x0a, 0x1d, 0x55, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x69, + 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x3f, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, + 0x6f, 0x72, 0x74, 0x2e, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x63, 0x6f, 0x6e, 0x66, 0x69, + 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x6c, 0x75, 0x73, 0x74, + 0x65, 0x72, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x66, + 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x74, 0x79, 0x70, 0x65, + 0x73, 0x2e, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, + 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x56, 0x32, 0x12, 0x82, 0x01, 0x0a, 0x1d, + 0x55, 0x70, 0x73, 0x65, 0x72, 0x74, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x4e, 0x65, 0x74, + 0x77, 0x6f, 0x72, 0x6b, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x3f, 0x2e, + 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, + 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x73, 0x65, 0x72, 0x74, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x56, 0x32, - 0x12, 0x82, 0x01, 0x0a, 0x1d, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x6c, 0x75, 0x73, 0x74, - 0x65, 0x72, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x66, - 0x69, 0x67, 0x12, 0x3f, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x63, 0x6c, - 0x75, 0x73, 0x74, 0x65, 0x72, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x55, - 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x4e, 0x65, 0x74, 0x77, - 0x6f, 0x72, 0x6b, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x43, 0x6c, 0x75, 0x73, - 0x74, 0x65, 0x72, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, - 0x66, 0x69, 0x67, 0x56, 0x32, 0x12, 0x82, 0x01, 0x0a, 0x1d, 0x55, 0x70, 0x73, 0x65, 0x72, 0x74, - 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x69, 0x6e, - 0x67, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x3f, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, - 0x72, 0x74, 0x2e, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, - 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x73, 0x65, 0x72, 0x74, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, + 0x12, 0x80, 0x01, 0x0a, 0x1c, 0x52, 0x65, 0x73, 0x65, 0x74, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x66, 0x69, - 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, - 0x2e, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x69, - 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x56, 0x32, 0x12, 0x80, 0x01, 0x0a, 0x1c, 0x52, - 0x65, 0x73, 0x65, 0x74, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x4e, 0x65, 0x74, 0x77, 0x6f, - 0x72, 0x6b, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x3e, 0x2e, 0x74, 0x65, - 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x63, 0x6f, - 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x65, 0x74, 0x43, 0x6c, 0x75, - 0x73, 0x74, 0x65, 0x72, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x69, 0x6e, 0x67, 0x43, 0x6f, - 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x74, 0x79, - 0x70, 0x65, 0x73, 0x2e, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x4e, 0x65, 0x74, 0x77, 0x6f, - 0x72, 0x6b, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x56, 0x32, 0x12, 0x79, 0x0a, - 0x19, 0x47, 0x65, 0x74, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x63, 0x6f, 0x72, - 0x64, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x3b, 0x2e, 0x74, 0x65, 0x6c, - 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x63, 0x6f, 0x6e, - 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, + 0x67, 0x12, 0x3e, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x63, 0x6c, 0x75, + 0x73, 0x74, 0x65, 0x72, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, + 0x73, 0x65, 0x74, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, + 0x6b, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x20, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, + 0x72, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x66, 0x69, + 0x67, 0x56, 0x32, 0x12, 0x79, 0x0a, 0x19, 0x47, 0x65, 0x74, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, + 0x12, 0x3b, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x63, 0x6c, 0x75, 0x73, + 0x74, 0x65, 0x72, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x67, - 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x56, 0x32, 0x12, 0x7f, 0x0a, 0x1c, 0x55, 0x70, 0x64, 0x61, - 0x74, 0x65, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x69, - 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x3e, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, - 0x6f, 0x72, 0x74, 0x2e, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x63, 0x6f, 0x6e, 0x66, 0x69, - 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x65, 0x73, 0x73, 0x69, - 0x6f, 0x6e, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x66, 0x69, - 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, - 0x2e, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x69, 0x6e, - 0x67, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x56, 0x32, 0x12, 0x7f, 0x0a, 0x1c, 0x55, 0x70, 0x73, - 0x65, 0x72, 0x74, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, - 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x3e, 0x2e, 0x74, 0x65, 0x6c, 0x65, - 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x63, 0x6f, 0x6e, 0x66, - 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x73, 0x65, 0x72, 0x74, 0x53, 0x65, 0x73, 0x73, - 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x66, - 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x74, 0x79, 0x70, 0x65, - 0x73, 0x2e, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x69, - 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x56, 0x32, 0x12, 0x7d, 0x0a, 0x1b, 0x52, 0x65, - 0x73, 0x65, 0x74, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, - 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x3d, 0x2e, 0x74, 0x65, 0x6c, 0x65, - 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x63, 0x6f, 0x6e, 0x66, - 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x65, 0x74, 0x53, 0x65, 0x73, 0x73, 0x69, - 0x6f, 0x6e, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x66, 0x69, - 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, - 0x2e, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x69, 0x6e, - 0x67, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x56, 0x32, 0x12, 0x61, 0x0a, 0x11, 0x47, 0x65, 0x74, - 0x41, 0x75, 0x74, 0x68, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x33, + 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, + 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x63, + 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x56, 0x32, 0x12, 0x7f, + 0x0a, 0x1c, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, + 0x65, 0x63, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x3e, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, - 0x72, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x75, - 0x74, 0x68, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x41, 0x75, 0x74, 0x68, - 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x56, 0x32, 0x12, 0x67, 0x0a, 0x14, - 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x75, 0x74, 0x68, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, - 0x65, 0x6e, 0x63, 0x65, 0x12, 0x36, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, + 0x72, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x69, 0x6e, + 0x67, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, + 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, + 0x63, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x56, 0x32, 0x12, + 0x7f, 0x0a, 0x1c, 0x55, 0x70, 0x73, 0x65, 0x72, 0x74, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, + 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, + 0x3e, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x63, 0x6c, 0x75, 0x73, 0x74, + 0x65, 0x72, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x73, 0x65, + 0x72, 0x74, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x69, + 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x1f, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, + 0x65, 0x63, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x56, 0x32, + 0x12, 0x7d, 0x0a, 0x1b, 0x52, 0x65, 0x73, 0x65, 0x74, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, + 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, + 0x3d, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x63, 0x6c, 0x75, 0x73, 0x74, + 0x65, 0x72, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x65, + 0x74, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x69, 0x6e, + 0x67, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, + 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, + 0x63, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x56, 0x32, 0x12, + 0x61, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x41, 0x75, 0x74, 0x68, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, + 0x65, 0x6e, 0x63, 0x65, 0x12, 0x33, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, - 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x75, 0x74, 0x68, 0x50, 0x72, 0x65, 0x66, 0x65, - 0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x74, - 0x79, 0x70, 0x65, 0x73, 0x2e, 0x41, 0x75, 0x74, 0x68, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, - 0x6e, 0x63, 0x65, 0x56, 0x32, 0x12, 0x67, 0x0a, 0x14, 0x55, 0x70, 0x73, 0x65, 0x72, 0x74, 0x41, - 0x75, 0x74, 0x68, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x36, 0x2e, - 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, - 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x73, 0x65, 0x72, 0x74, - 0x41, 0x75, 0x74, 0x68, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x41, 0x75, - 0x74, 0x68, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x56, 0x32, 0x12, 0x65, - 0x0a, 0x13, 0x52, 0x65, 0x73, 0x65, 0x74, 0x41, 0x75, 0x74, 0x68, 0x50, 0x72, 0x65, 0x66, 0x65, - 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x35, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, - 0x2e, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, - 0x31, 0x2e, 0x52, 0x65, 0x73, 0x65, 0x74, 0x41, 0x75, 0x74, 0x68, 0x50, 0x72, 0x65, 0x66, 0x65, - 0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x74, - 0x79, 0x70, 0x65, 0x73, 0x2e, 0x41, 0x75, 0x74, 0x68, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, - 0x6e, 0x63, 0x65, 0x56, 0x32, 0x12, 0x6d, 0x0a, 0x15, 0x47, 0x65, 0x74, 0x43, 0x6c, 0x75, 0x73, - 0x74, 0x65, 0x72, 0x41, 0x75, 0x64, 0x69, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x37, + 0x2e, 0x47, 0x65, 0x74, 0x41, 0x75, 0x74, 0x68, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, + 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x74, 0x79, 0x70, 0x65, + 0x73, 0x2e, 0x41, 0x75, 0x74, 0x68, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, + 0x56, 0x32, 0x12, 0x67, 0x0a, 0x14, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x75, 0x74, 0x68, + 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x36, 0x2e, 0x74, 0x65, 0x6c, + 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x63, 0x6f, 0x6e, + 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x75, 0x74, + 0x68, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x41, 0x75, 0x74, 0x68, 0x50, + 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x56, 0x32, 0x12, 0x67, 0x0a, 0x14, 0x55, + 0x70, 0x73, 0x65, 0x72, 0x74, 0x41, 0x75, 0x74, 0x68, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, + 0x6e, 0x63, 0x65, 0x12, 0x36, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x63, + 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, + 0x55, 0x70, 0x73, 0x65, 0x72, 0x74, 0x41, 0x75, 0x74, 0x68, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, + 0x65, 0x6e, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x74, 0x79, + 0x70, 0x65, 0x73, 0x2e, 0x41, 0x75, 0x74, 0x68, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, + 0x63, 0x65, 0x56, 0x32, 0x12, 0x65, 0x0a, 0x13, 0x52, 0x65, 0x73, 0x65, 0x74, 0x41, 0x75, 0x74, + 0x68, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x35, 0x2e, 0x74, 0x65, + 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x63, 0x6f, + 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x65, 0x74, 0x41, 0x75, 0x74, + 0x68, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x41, 0x75, 0x74, 0x68, 0x50, + 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x56, 0x32, 0x12, 0x6d, 0x0a, 0x15, 0x47, + 0x65, 0x74, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x41, 0x75, 0x64, 0x69, 0x74, 0x43, 0x6f, + 0x6e, 0x66, 0x69, 0x67, 0x12, 0x37, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, + 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, + 0x2e, 0x47, 0x65, 0x74, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x41, 0x75, 0x64, 0x69, 0x74, + 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, + 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x41, 0x75, 0x64, + 0x69, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x56, 0x32, 0x12, 0x9c, 0x01, 0x0a, 0x1b, 0x47, + 0x65, 0x74, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x47, + 0x72, 0x61, 0x70, 0x68, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x3d, 0x2e, 0x74, 0x65, 0x6c, + 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x63, 0x6f, 0x6e, + 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, + 0x72, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x47, 0x72, 0x61, 0x70, 0x68, 0x43, 0x6f, 0x6e, 0x66, + 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x3e, 0x2e, 0x74, 0x65, 0x6c, 0x65, + 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x63, 0x6f, 0x6e, 0x66, + 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, + 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x47, 0x72, 0x61, 0x70, 0x68, 0x43, 0x6f, 0x6e, 0x66, 0x69, + 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x82, 0x01, 0x0a, 0x16, 0x47, 0x65, + 0x74, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x47, 0x72, 0x61, 0x70, 0x68, 0x53, 0x65, 0x74, 0x74, + 0x69, 0x6e, 0x67, 0x73, 0x12, 0x38, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, + 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, + 0x2e, 0x47, 0x65, 0x74, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x47, 0x72, 0x61, 0x70, 0x68, 0x53, + 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, - 0x72, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x6c, - 0x75, 0x73, 0x74, 0x65, 0x72, 0x41, 0x75, 0x64, 0x69, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, - 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x41, 0x75, 0x64, 0x69, 0x74, 0x43, 0x6f, 0x6e, 0x66, - 0x69, 0x67, 0x56, 0x32, 0x12, 0x9c, 0x01, 0x0a, 0x1b, 0x47, 0x65, 0x74, 0x43, 0x6c, 0x75, 0x73, - 0x74, 0x65, 0x72, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x47, 0x72, 0x61, 0x70, 0x68, 0x43, 0x6f, - 0x6e, 0x66, 0x69, 0x67, 0x12, 0x3d, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, + 0x72, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x47, 0x72, 0x61, 0x70, 0x68, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x88, + 0x01, 0x0a, 0x19, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x47, + 0x72, 0x61, 0x70, 0x68, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x3b, 0x2e, 0x74, + 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x63, + 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, + 0x63, 0x63, 0x65, 0x73, 0x73, 0x47, 0x72, 0x61, 0x70, 0x68, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, + 0x67, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x74, 0x65, 0x6c, 0x65, + 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x63, 0x6f, 0x6e, 0x66, + 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x47, 0x72, 0x61, 0x70, + 0x68, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x88, 0x01, 0x0a, 0x19, 0x55, 0x70, + 0x64, 0x61, 0x74, 0x65, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x47, 0x72, 0x61, 0x70, 0x68, 0x53, + 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x3b, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, + 0x72, 0x74, 0x2e, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, + 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, + 0x47, 0x72, 0x61, 0x70, 0x68, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, - 0x2e, 0x47, 0x65, 0x74, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x41, 0x63, 0x63, 0x65, 0x73, - 0x73, 0x47, 0x72, 0x61, 0x70, 0x68, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x3e, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x63, - 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, - 0x47, 0x65, 0x74, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, - 0x47, 0x72, 0x61, 0x70, 0x68, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x42, 0x5e, 0x5a, 0x5c, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, - 0x6d, 0x2f, 0x67, 0x72, 0x61, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x2f, - 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x67, 0x65, 0x6e, - 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x2f, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, - 0x72, 0x74, 0x2f, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, - 0x2f, 0x76, 0x31, 0x3b, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x63, 0x6f, 0x6e, 0x66, 0x69, - 0x67, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x47, 0x72, 0x61, 0x70, 0x68, 0x53, 0x65, 0x74, 0x74, + 0x69, 0x6e, 0x67, 0x73, 0x12, 0x88, 0x01, 0x0a, 0x19, 0x55, 0x70, 0x73, 0x65, 0x72, 0x74, 0x41, + 0x63, 0x63, 0x65, 0x73, 0x73, 0x47, 0x72, 0x61, 0x70, 0x68, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, + 0x67, 0x73, 0x12, 0x3b, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x63, 0x6c, + 0x75, 0x73, 0x74, 0x65, 0x72, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x55, + 0x70, 0x73, 0x65, 0x72, 0x74, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x47, 0x72, 0x61, 0x70, 0x68, + 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x2e, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x63, 0x6c, 0x75, 0x73, 0x74, + 0x65, 0x72, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x63, 0x63, 0x65, + 0x73, 0x73, 0x47, 0x72, 0x61, 0x70, 0x68, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x12, + 0x86, 0x01, 0x0a, 0x18, 0x52, 0x65, 0x73, 0x65, 0x74, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x47, + 0x72, 0x61, 0x70, 0x68, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x3a, 0x2e, 0x74, + 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x63, + 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x65, 0x74, 0x41, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x47, 0x72, 0x61, 0x70, 0x68, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, + 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, + 0x6f, 0x72, 0x74, 0x2e, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x63, 0x6f, 0x6e, 0x66, 0x69, + 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x47, 0x72, 0x61, 0x70, 0x68, + 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x42, 0x5e, 0x5a, 0x5c, 0x67, 0x69, 0x74, 0x68, + 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x72, 0x61, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x61, 0x6c, 0x2f, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x61, 0x70, + 0x69, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x2f, 0x74, + 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x63, + 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2f, 0x76, 0x31, 0x3b, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, + 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -896,7 +1194,7 @@ func file_teleport_clusterconfig_v1_clusterconfig_service_proto_rawDescGZIP() [] return file_teleport_clusterconfig_v1_clusterconfig_service_proto_rawDescData } -var file_teleport_clusterconfig_v1_clusterconfig_service_proto_msgTypes = make([]protoimpl.MessageInfo, 15) +var file_teleport_clusterconfig_v1_clusterconfig_service_proto_msgTypes = make([]protoimpl.MessageInfo, 20) var file_teleport_clusterconfig_v1_clusterconfig_service_proto_goTypes = []interface{}{ (*GetClusterNetworkingConfigRequest)(nil), // 0: teleport.clusterconfig.v1.GetClusterNetworkingConfigRequest (*UpdateClusterNetworkingConfigRequest)(nil), // 1: teleport.clusterconfig.v1.UpdateClusterNetworkingConfigRequest @@ -913,53 +1211,72 @@ var file_teleport_clusterconfig_v1_clusterconfig_service_proto_goTypes = []inter (*GetClusterAuditConfigRequest)(nil), // 12: teleport.clusterconfig.v1.GetClusterAuditConfigRequest (*GetClusterAccessGraphConfigRequest)(nil), // 13: teleport.clusterconfig.v1.GetClusterAccessGraphConfigRequest (*GetClusterAccessGraphConfigResponse)(nil), // 14: teleport.clusterconfig.v1.GetClusterAccessGraphConfigResponse - (*types.ClusterNetworkingConfigV2)(nil), // 15: types.ClusterNetworkingConfigV2 - (*types.SessionRecordingConfigV2)(nil), // 16: types.SessionRecordingConfigV2 - (*types.AuthPreferenceV2)(nil), // 17: types.AuthPreferenceV2 - (*AccessGraphConfig)(nil), // 18: teleport.clusterconfig.v1.AccessGraphConfig - (*types.ClusterAuditConfigV2)(nil), // 19: types.ClusterAuditConfigV2 + (*GetAccessGraphSettingsRequest)(nil), // 15: teleport.clusterconfig.v1.GetAccessGraphSettingsRequest + (*CreateAccessGraphSettingsRequest)(nil), // 16: teleport.clusterconfig.v1.CreateAccessGraphSettingsRequest + (*UpdateAccessGraphSettingsRequest)(nil), // 17: teleport.clusterconfig.v1.UpdateAccessGraphSettingsRequest + (*UpsertAccessGraphSettingsRequest)(nil), // 18: teleport.clusterconfig.v1.UpsertAccessGraphSettingsRequest + (*ResetAccessGraphSettingsRequest)(nil), // 19: teleport.clusterconfig.v1.ResetAccessGraphSettingsRequest + (*types.ClusterNetworkingConfigV2)(nil), // 20: types.ClusterNetworkingConfigV2 + (*types.SessionRecordingConfigV2)(nil), // 21: types.SessionRecordingConfigV2 + (*types.AuthPreferenceV2)(nil), // 22: types.AuthPreferenceV2 + (*AccessGraphConfig)(nil), // 23: teleport.clusterconfig.v1.AccessGraphConfig + (*AccessGraphSettings)(nil), // 24: teleport.clusterconfig.v1.AccessGraphSettings + (*types.ClusterAuditConfigV2)(nil), // 25: types.ClusterAuditConfigV2 } var file_teleport_clusterconfig_v1_clusterconfig_service_proto_depIdxs = []int32{ - 15, // 0: teleport.clusterconfig.v1.UpdateClusterNetworkingConfigRequest.cluster_network_config:type_name -> types.ClusterNetworkingConfigV2 - 15, // 1: teleport.clusterconfig.v1.UpsertClusterNetworkingConfigRequest.cluster_network_config:type_name -> types.ClusterNetworkingConfigV2 - 16, // 2: teleport.clusterconfig.v1.UpdateSessionRecordingConfigRequest.session_recording_config:type_name -> types.SessionRecordingConfigV2 - 16, // 3: teleport.clusterconfig.v1.UpsertSessionRecordingConfigRequest.session_recording_config:type_name -> types.SessionRecordingConfigV2 - 17, // 4: teleport.clusterconfig.v1.UpdateAuthPreferenceRequest.auth_preference:type_name -> types.AuthPreferenceV2 - 17, // 5: teleport.clusterconfig.v1.UpsertAuthPreferenceRequest.auth_preference:type_name -> types.AuthPreferenceV2 - 18, // 6: teleport.clusterconfig.v1.GetClusterAccessGraphConfigResponse.access_graph:type_name -> teleport.clusterconfig.v1.AccessGraphConfig - 0, // 7: teleport.clusterconfig.v1.ClusterConfigService.GetClusterNetworkingConfig:input_type -> teleport.clusterconfig.v1.GetClusterNetworkingConfigRequest - 1, // 8: teleport.clusterconfig.v1.ClusterConfigService.UpdateClusterNetworkingConfig:input_type -> teleport.clusterconfig.v1.UpdateClusterNetworkingConfigRequest - 2, // 9: teleport.clusterconfig.v1.ClusterConfigService.UpsertClusterNetworkingConfig:input_type -> teleport.clusterconfig.v1.UpsertClusterNetworkingConfigRequest - 3, // 10: teleport.clusterconfig.v1.ClusterConfigService.ResetClusterNetworkingConfig:input_type -> teleport.clusterconfig.v1.ResetClusterNetworkingConfigRequest - 4, // 11: teleport.clusterconfig.v1.ClusterConfigService.GetSessionRecordingConfig:input_type -> teleport.clusterconfig.v1.GetSessionRecordingConfigRequest - 5, // 12: teleport.clusterconfig.v1.ClusterConfigService.UpdateSessionRecordingConfig:input_type -> teleport.clusterconfig.v1.UpdateSessionRecordingConfigRequest - 6, // 13: teleport.clusterconfig.v1.ClusterConfigService.UpsertSessionRecordingConfig:input_type -> teleport.clusterconfig.v1.UpsertSessionRecordingConfigRequest - 7, // 14: teleport.clusterconfig.v1.ClusterConfigService.ResetSessionRecordingConfig:input_type -> teleport.clusterconfig.v1.ResetSessionRecordingConfigRequest - 8, // 15: teleport.clusterconfig.v1.ClusterConfigService.GetAuthPreference:input_type -> teleport.clusterconfig.v1.GetAuthPreferenceRequest - 9, // 16: teleport.clusterconfig.v1.ClusterConfigService.UpdateAuthPreference:input_type -> teleport.clusterconfig.v1.UpdateAuthPreferenceRequest - 10, // 17: teleport.clusterconfig.v1.ClusterConfigService.UpsertAuthPreference:input_type -> teleport.clusterconfig.v1.UpsertAuthPreferenceRequest - 11, // 18: teleport.clusterconfig.v1.ClusterConfigService.ResetAuthPreference:input_type -> teleport.clusterconfig.v1.ResetAuthPreferenceRequest - 12, // 19: teleport.clusterconfig.v1.ClusterConfigService.GetClusterAuditConfig:input_type -> teleport.clusterconfig.v1.GetClusterAuditConfigRequest - 13, // 20: teleport.clusterconfig.v1.ClusterConfigService.GetClusterAccessGraphConfig:input_type -> teleport.clusterconfig.v1.GetClusterAccessGraphConfigRequest - 15, // 21: teleport.clusterconfig.v1.ClusterConfigService.GetClusterNetworkingConfig:output_type -> types.ClusterNetworkingConfigV2 - 15, // 22: teleport.clusterconfig.v1.ClusterConfigService.UpdateClusterNetworkingConfig:output_type -> types.ClusterNetworkingConfigV2 - 15, // 23: teleport.clusterconfig.v1.ClusterConfigService.UpsertClusterNetworkingConfig:output_type -> types.ClusterNetworkingConfigV2 - 15, // 24: teleport.clusterconfig.v1.ClusterConfigService.ResetClusterNetworkingConfig:output_type -> types.ClusterNetworkingConfigV2 - 16, // 25: teleport.clusterconfig.v1.ClusterConfigService.GetSessionRecordingConfig:output_type -> types.SessionRecordingConfigV2 - 16, // 26: teleport.clusterconfig.v1.ClusterConfigService.UpdateSessionRecordingConfig:output_type -> types.SessionRecordingConfigV2 - 16, // 27: teleport.clusterconfig.v1.ClusterConfigService.UpsertSessionRecordingConfig:output_type -> types.SessionRecordingConfigV2 - 16, // 28: teleport.clusterconfig.v1.ClusterConfigService.ResetSessionRecordingConfig:output_type -> types.SessionRecordingConfigV2 - 17, // 29: teleport.clusterconfig.v1.ClusterConfigService.GetAuthPreference:output_type -> types.AuthPreferenceV2 - 17, // 30: teleport.clusterconfig.v1.ClusterConfigService.UpdateAuthPreference:output_type -> types.AuthPreferenceV2 - 17, // 31: teleport.clusterconfig.v1.ClusterConfigService.UpsertAuthPreference:output_type -> types.AuthPreferenceV2 - 17, // 32: teleport.clusterconfig.v1.ClusterConfigService.ResetAuthPreference:output_type -> types.AuthPreferenceV2 - 19, // 33: teleport.clusterconfig.v1.ClusterConfigService.GetClusterAuditConfig:output_type -> types.ClusterAuditConfigV2 - 14, // 34: teleport.clusterconfig.v1.ClusterConfigService.GetClusterAccessGraphConfig:output_type -> teleport.clusterconfig.v1.GetClusterAccessGraphConfigResponse - 21, // [21:35] is the sub-list for method output_type - 7, // [7:21] is the sub-list for method input_type - 7, // [7:7] is the sub-list for extension type_name - 7, // [7:7] is the sub-list for extension extendee - 0, // [0:7] is the sub-list for field type_name + 20, // 0: teleport.clusterconfig.v1.UpdateClusterNetworkingConfigRequest.cluster_network_config:type_name -> types.ClusterNetworkingConfigV2 + 20, // 1: teleport.clusterconfig.v1.UpsertClusterNetworkingConfigRequest.cluster_network_config:type_name -> types.ClusterNetworkingConfigV2 + 21, // 2: teleport.clusterconfig.v1.UpdateSessionRecordingConfigRequest.session_recording_config:type_name -> types.SessionRecordingConfigV2 + 21, // 3: teleport.clusterconfig.v1.UpsertSessionRecordingConfigRequest.session_recording_config:type_name -> types.SessionRecordingConfigV2 + 22, // 4: teleport.clusterconfig.v1.UpdateAuthPreferenceRequest.auth_preference:type_name -> types.AuthPreferenceV2 + 22, // 5: teleport.clusterconfig.v1.UpsertAuthPreferenceRequest.auth_preference:type_name -> types.AuthPreferenceV2 + 23, // 6: teleport.clusterconfig.v1.GetClusterAccessGraphConfigResponse.access_graph:type_name -> teleport.clusterconfig.v1.AccessGraphConfig + 24, // 7: teleport.clusterconfig.v1.CreateAccessGraphSettingsRequest.access_graph_settings:type_name -> teleport.clusterconfig.v1.AccessGraphSettings + 24, // 8: teleport.clusterconfig.v1.UpdateAccessGraphSettingsRequest.access_graph_settings:type_name -> teleport.clusterconfig.v1.AccessGraphSettings + 24, // 9: teleport.clusterconfig.v1.UpsertAccessGraphSettingsRequest.access_graph_settings:type_name -> teleport.clusterconfig.v1.AccessGraphSettings + 0, // 10: teleport.clusterconfig.v1.ClusterConfigService.GetClusterNetworkingConfig:input_type -> teleport.clusterconfig.v1.GetClusterNetworkingConfigRequest + 1, // 11: teleport.clusterconfig.v1.ClusterConfigService.UpdateClusterNetworkingConfig:input_type -> teleport.clusterconfig.v1.UpdateClusterNetworkingConfigRequest + 2, // 12: teleport.clusterconfig.v1.ClusterConfigService.UpsertClusterNetworkingConfig:input_type -> teleport.clusterconfig.v1.UpsertClusterNetworkingConfigRequest + 3, // 13: teleport.clusterconfig.v1.ClusterConfigService.ResetClusterNetworkingConfig:input_type -> teleport.clusterconfig.v1.ResetClusterNetworkingConfigRequest + 4, // 14: teleport.clusterconfig.v1.ClusterConfigService.GetSessionRecordingConfig:input_type -> teleport.clusterconfig.v1.GetSessionRecordingConfigRequest + 5, // 15: teleport.clusterconfig.v1.ClusterConfigService.UpdateSessionRecordingConfig:input_type -> teleport.clusterconfig.v1.UpdateSessionRecordingConfigRequest + 6, // 16: teleport.clusterconfig.v1.ClusterConfigService.UpsertSessionRecordingConfig:input_type -> teleport.clusterconfig.v1.UpsertSessionRecordingConfigRequest + 7, // 17: teleport.clusterconfig.v1.ClusterConfigService.ResetSessionRecordingConfig:input_type -> teleport.clusterconfig.v1.ResetSessionRecordingConfigRequest + 8, // 18: teleport.clusterconfig.v1.ClusterConfigService.GetAuthPreference:input_type -> teleport.clusterconfig.v1.GetAuthPreferenceRequest + 9, // 19: teleport.clusterconfig.v1.ClusterConfigService.UpdateAuthPreference:input_type -> teleport.clusterconfig.v1.UpdateAuthPreferenceRequest + 10, // 20: teleport.clusterconfig.v1.ClusterConfigService.UpsertAuthPreference:input_type -> teleport.clusterconfig.v1.UpsertAuthPreferenceRequest + 11, // 21: teleport.clusterconfig.v1.ClusterConfigService.ResetAuthPreference:input_type -> teleport.clusterconfig.v1.ResetAuthPreferenceRequest + 12, // 22: teleport.clusterconfig.v1.ClusterConfigService.GetClusterAuditConfig:input_type -> teleport.clusterconfig.v1.GetClusterAuditConfigRequest + 13, // 23: teleport.clusterconfig.v1.ClusterConfigService.GetClusterAccessGraphConfig:input_type -> teleport.clusterconfig.v1.GetClusterAccessGraphConfigRequest + 15, // 24: teleport.clusterconfig.v1.ClusterConfigService.GetAccessGraphSettings:input_type -> teleport.clusterconfig.v1.GetAccessGraphSettingsRequest + 16, // 25: teleport.clusterconfig.v1.ClusterConfigService.CreateAccessGraphSettings:input_type -> teleport.clusterconfig.v1.CreateAccessGraphSettingsRequest + 17, // 26: teleport.clusterconfig.v1.ClusterConfigService.UpdateAccessGraphSettings:input_type -> teleport.clusterconfig.v1.UpdateAccessGraphSettingsRequest + 18, // 27: teleport.clusterconfig.v1.ClusterConfigService.UpsertAccessGraphSettings:input_type -> teleport.clusterconfig.v1.UpsertAccessGraphSettingsRequest + 19, // 28: teleport.clusterconfig.v1.ClusterConfigService.ResetAccessGraphSettings:input_type -> teleport.clusterconfig.v1.ResetAccessGraphSettingsRequest + 20, // 29: teleport.clusterconfig.v1.ClusterConfigService.GetClusterNetworkingConfig:output_type -> types.ClusterNetworkingConfigV2 + 20, // 30: teleport.clusterconfig.v1.ClusterConfigService.UpdateClusterNetworkingConfig:output_type -> types.ClusterNetworkingConfigV2 + 20, // 31: teleport.clusterconfig.v1.ClusterConfigService.UpsertClusterNetworkingConfig:output_type -> types.ClusterNetworkingConfigV2 + 20, // 32: teleport.clusterconfig.v1.ClusterConfigService.ResetClusterNetworkingConfig:output_type -> types.ClusterNetworkingConfigV2 + 21, // 33: teleport.clusterconfig.v1.ClusterConfigService.GetSessionRecordingConfig:output_type -> types.SessionRecordingConfigV2 + 21, // 34: teleport.clusterconfig.v1.ClusterConfigService.UpdateSessionRecordingConfig:output_type -> types.SessionRecordingConfigV2 + 21, // 35: teleport.clusterconfig.v1.ClusterConfigService.UpsertSessionRecordingConfig:output_type -> types.SessionRecordingConfigV2 + 21, // 36: teleport.clusterconfig.v1.ClusterConfigService.ResetSessionRecordingConfig:output_type -> types.SessionRecordingConfigV2 + 22, // 37: teleport.clusterconfig.v1.ClusterConfigService.GetAuthPreference:output_type -> types.AuthPreferenceV2 + 22, // 38: teleport.clusterconfig.v1.ClusterConfigService.UpdateAuthPreference:output_type -> types.AuthPreferenceV2 + 22, // 39: teleport.clusterconfig.v1.ClusterConfigService.UpsertAuthPreference:output_type -> types.AuthPreferenceV2 + 22, // 40: teleport.clusterconfig.v1.ClusterConfigService.ResetAuthPreference:output_type -> types.AuthPreferenceV2 + 25, // 41: teleport.clusterconfig.v1.ClusterConfigService.GetClusterAuditConfig:output_type -> types.ClusterAuditConfigV2 + 14, // 42: teleport.clusterconfig.v1.ClusterConfigService.GetClusterAccessGraphConfig:output_type -> teleport.clusterconfig.v1.GetClusterAccessGraphConfigResponse + 24, // 43: teleport.clusterconfig.v1.ClusterConfigService.GetAccessGraphSettings:output_type -> teleport.clusterconfig.v1.AccessGraphSettings + 24, // 44: teleport.clusterconfig.v1.ClusterConfigService.CreateAccessGraphSettings:output_type -> teleport.clusterconfig.v1.AccessGraphSettings + 24, // 45: teleport.clusterconfig.v1.ClusterConfigService.UpdateAccessGraphSettings:output_type -> teleport.clusterconfig.v1.AccessGraphSettings + 24, // 46: teleport.clusterconfig.v1.ClusterConfigService.UpsertAccessGraphSettings:output_type -> teleport.clusterconfig.v1.AccessGraphSettings + 24, // 47: teleport.clusterconfig.v1.ClusterConfigService.ResetAccessGraphSettings:output_type -> teleport.clusterconfig.v1.AccessGraphSettings + 29, // [29:48] is the sub-list for method output_type + 10, // [10:29] is the sub-list for method input_type + 10, // [10:10] is the sub-list for extension type_name + 10, // [10:10] is the sub-list for extension extendee + 0, // [0:10] is the sub-list for field type_name } func init() { file_teleport_clusterconfig_v1_clusterconfig_service_proto_init() } @@ -968,6 +1285,7 @@ func file_teleport_clusterconfig_v1_clusterconfig_service_proto_init() { return } file_teleport_clusterconfig_v1_access_graph_proto_init() + file_teleport_clusterconfig_v1_access_graph_settings_proto_init() if !protoimpl.UnsafeEnabled { file_teleport_clusterconfig_v1_clusterconfig_service_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*GetClusterNetworkingConfigRequest); i { @@ -1149,6 +1467,66 @@ func file_teleport_clusterconfig_v1_clusterconfig_service_proto_init() { return nil } } + file_teleport_clusterconfig_v1_clusterconfig_service_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetAccessGraphSettingsRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_teleport_clusterconfig_v1_clusterconfig_service_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CreateAccessGraphSettingsRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_teleport_clusterconfig_v1_clusterconfig_service_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UpdateAccessGraphSettingsRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_teleport_clusterconfig_v1_clusterconfig_service_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UpsertAccessGraphSettingsRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_teleport_clusterconfig_v1_clusterconfig_service_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ResetAccessGraphSettingsRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } } type x struct{} out := protoimpl.TypeBuilder{ @@ -1156,7 +1534,7 @@ func file_teleport_clusterconfig_v1_clusterconfig_service_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_teleport_clusterconfig_v1_clusterconfig_service_proto_rawDesc, NumEnums: 0, - NumMessages: 15, + NumMessages: 20, NumExtensions: 0, NumServices: 1, }, diff --git a/api/gen/proto/go/teleport/clusterconfig/v1/clusterconfig_service_grpc.pb.go b/api/gen/proto/go/teleport/clusterconfig/v1/clusterconfig_service_grpc.pb.go index c2b5e02e4dc96..be97e6e13f93e 100644 --- a/api/gen/proto/go/teleport/clusterconfig/v1/clusterconfig_service_grpc.pb.go +++ b/api/gen/proto/go/teleport/clusterconfig/v1/clusterconfig_service_grpc.pb.go @@ -48,6 +48,11 @@ const ( ClusterConfigService_ResetAuthPreference_FullMethodName = "/teleport.clusterconfig.v1.ClusterConfigService/ResetAuthPreference" ClusterConfigService_GetClusterAuditConfig_FullMethodName = "/teleport.clusterconfig.v1.ClusterConfigService/GetClusterAuditConfig" ClusterConfigService_GetClusterAccessGraphConfig_FullMethodName = "/teleport.clusterconfig.v1.ClusterConfigService/GetClusterAccessGraphConfig" + ClusterConfigService_GetAccessGraphSettings_FullMethodName = "/teleport.clusterconfig.v1.ClusterConfigService/GetAccessGraphSettings" + ClusterConfigService_CreateAccessGraphSettings_FullMethodName = "/teleport.clusterconfig.v1.ClusterConfigService/CreateAccessGraphSettings" + ClusterConfigService_UpdateAccessGraphSettings_FullMethodName = "/teleport.clusterconfig.v1.ClusterConfigService/UpdateAccessGraphSettings" + ClusterConfigService_UpsertAccessGraphSettings_FullMethodName = "/teleport.clusterconfig.v1.ClusterConfigService/UpsertAccessGraphSettings" + ClusterConfigService_ResetAccessGraphSettings_FullMethodName = "/teleport.clusterconfig.v1.ClusterConfigService/ResetAccessGraphSettings" ) // ClusterConfigServiceClient is the client API for ClusterConfigService service. @@ -80,8 +85,18 @@ type ClusterConfigServiceClient interface { ResetAuthPreference(ctx context.Context, in *ResetAuthPreferenceRequest, opts ...grpc.CallOption) (*types.AuthPreferenceV2, error) // GetClusterAuditConfig retrieves the active cluster audit configuration. GetClusterAuditConfig(ctx context.Context, in *GetClusterAuditConfigRequest, opts ...grpc.CallOption) (*types.ClusterAuditConfigV2, error) - // GetClusterAccessGraphConfig retrieves the cluster Access Graph configuration from Auth service. + // GetClusterAccessGraphConfig retrieves the cluster Access Graph configuration from Auth server. GetClusterAccessGraphConfig(ctx context.Context, in *GetClusterAccessGraphConfigRequest, opts ...grpc.CallOption) (*GetClusterAccessGraphConfigResponse, error) + // GetAccessGraphSettings updates the cluster Access Graph configuration. + GetAccessGraphSettings(ctx context.Context, in *GetAccessGraphSettingsRequest, opts ...grpc.CallOption) (*AccessGraphSettings, error) + // CreateAccessGraphSettings creates the cluster Access Graph configuration. + CreateAccessGraphSettings(ctx context.Context, in *CreateAccessGraphSettingsRequest, opts ...grpc.CallOption) (*AccessGraphSettings, error) + // UpdateAccessGraphSettings updates the cluster Access Graph configuration. + UpdateAccessGraphSettings(ctx context.Context, in *UpdateAccessGraphSettingsRequest, opts ...grpc.CallOption) (*AccessGraphSettings, error) + // UpsertAccessGraphSettings overwrites the active cluster Access Graph configuration. + UpsertAccessGraphSettings(ctx context.Context, in *UpsertAccessGraphSettingsRequest, opts ...grpc.CallOption) (*AccessGraphSettings, error) + // ResetAccessGraphSettings restores the active cluster Access Graph to default settings. + ResetAccessGraphSettings(ctx context.Context, in *ResetAccessGraphSettingsRequest, opts ...grpc.CallOption) (*AccessGraphSettings, error) } type clusterConfigServiceClient struct { @@ -218,6 +233,51 @@ func (c *clusterConfigServiceClient) GetClusterAccessGraphConfig(ctx context.Con return out, nil } +func (c *clusterConfigServiceClient) GetAccessGraphSettings(ctx context.Context, in *GetAccessGraphSettingsRequest, opts ...grpc.CallOption) (*AccessGraphSettings, error) { + out := new(AccessGraphSettings) + err := c.cc.Invoke(ctx, ClusterConfigService_GetAccessGraphSettings_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *clusterConfigServiceClient) CreateAccessGraphSettings(ctx context.Context, in *CreateAccessGraphSettingsRequest, opts ...grpc.CallOption) (*AccessGraphSettings, error) { + out := new(AccessGraphSettings) + err := c.cc.Invoke(ctx, ClusterConfigService_CreateAccessGraphSettings_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *clusterConfigServiceClient) UpdateAccessGraphSettings(ctx context.Context, in *UpdateAccessGraphSettingsRequest, opts ...grpc.CallOption) (*AccessGraphSettings, error) { + out := new(AccessGraphSettings) + err := c.cc.Invoke(ctx, ClusterConfigService_UpdateAccessGraphSettings_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *clusterConfigServiceClient) UpsertAccessGraphSettings(ctx context.Context, in *UpsertAccessGraphSettingsRequest, opts ...grpc.CallOption) (*AccessGraphSettings, error) { + out := new(AccessGraphSettings) + err := c.cc.Invoke(ctx, ClusterConfigService_UpsertAccessGraphSettings_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *clusterConfigServiceClient) ResetAccessGraphSettings(ctx context.Context, in *ResetAccessGraphSettingsRequest, opts ...grpc.CallOption) (*AccessGraphSettings, error) { + out := new(AccessGraphSettings) + err := c.cc.Invoke(ctx, ClusterConfigService_ResetAccessGraphSettings_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + // ClusterConfigServiceServer is the server API for ClusterConfigService service. // All implementations must embed UnimplementedClusterConfigServiceServer // for forward compatibility @@ -248,8 +308,18 @@ type ClusterConfigServiceServer interface { ResetAuthPreference(context.Context, *ResetAuthPreferenceRequest) (*types.AuthPreferenceV2, error) // GetClusterAuditConfig retrieves the active cluster audit configuration. GetClusterAuditConfig(context.Context, *GetClusterAuditConfigRequest) (*types.ClusterAuditConfigV2, error) - // GetClusterAccessGraphConfig retrieves the cluster Access Graph configuration from Auth service. + // GetClusterAccessGraphConfig retrieves the cluster Access Graph configuration from Auth server. GetClusterAccessGraphConfig(context.Context, *GetClusterAccessGraphConfigRequest) (*GetClusterAccessGraphConfigResponse, error) + // GetAccessGraphSettings updates the cluster Access Graph configuration. + GetAccessGraphSettings(context.Context, *GetAccessGraphSettingsRequest) (*AccessGraphSettings, error) + // CreateAccessGraphSettings creates the cluster Access Graph configuration. + CreateAccessGraphSettings(context.Context, *CreateAccessGraphSettingsRequest) (*AccessGraphSettings, error) + // UpdateAccessGraphSettings updates the cluster Access Graph configuration. + UpdateAccessGraphSettings(context.Context, *UpdateAccessGraphSettingsRequest) (*AccessGraphSettings, error) + // UpsertAccessGraphSettings overwrites the active cluster Access Graph configuration. + UpsertAccessGraphSettings(context.Context, *UpsertAccessGraphSettingsRequest) (*AccessGraphSettings, error) + // ResetAccessGraphSettings restores the active cluster Access Graph to default settings. + ResetAccessGraphSettings(context.Context, *ResetAccessGraphSettingsRequest) (*AccessGraphSettings, error) mustEmbedUnimplementedClusterConfigServiceServer() } @@ -299,6 +369,21 @@ func (UnimplementedClusterConfigServiceServer) GetClusterAuditConfig(context.Con func (UnimplementedClusterConfigServiceServer) GetClusterAccessGraphConfig(context.Context, *GetClusterAccessGraphConfigRequest) (*GetClusterAccessGraphConfigResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method GetClusterAccessGraphConfig not implemented") } +func (UnimplementedClusterConfigServiceServer) GetAccessGraphSettings(context.Context, *GetAccessGraphSettingsRequest) (*AccessGraphSettings, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetAccessGraphSettings not implemented") +} +func (UnimplementedClusterConfigServiceServer) CreateAccessGraphSettings(context.Context, *CreateAccessGraphSettingsRequest) (*AccessGraphSettings, error) { + return nil, status.Errorf(codes.Unimplemented, "method CreateAccessGraphSettings not implemented") +} +func (UnimplementedClusterConfigServiceServer) UpdateAccessGraphSettings(context.Context, *UpdateAccessGraphSettingsRequest) (*AccessGraphSettings, error) { + return nil, status.Errorf(codes.Unimplemented, "method UpdateAccessGraphSettings not implemented") +} +func (UnimplementedClusterConfigServiceServer) UpsertAccessGraphSettings(context.Context, *UpsertAccessGraphSettingsRequest) (*AccessGraphSettings, error) { + return nil, status.Errorf(codes.Unimplemented, "method UpsertAccessGraphSettings not implemented") +} +func (UnimplementedClusterConfigServiceServer) ResetAccessGraphSettings(context.Context, *ResetAccessGraphSettingsRequest) (*AccessGraphSettings, error) { + return nil, status.Errorf(codes.Unimplemented, "method ResetAccessGraphSettings not implemented") +} func (UnimplementedClusterConfigServiceServer) mustEmbedUnimplementedClusterConfigServiceServer() {} // UnsafeClusterConfigServiceServer may be embedded to opt out of forward compatibility for this service. @@ -564,6 +649,96 @@ func _ClusterConfigService_GetClusterAccessGraphConfig_Handler(srv interface{}, return interceptor(ctx, in, info, handler) } +func _ClusterConfigService_GetAccessGraphSettings_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetAccessGraphSettingsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ClusterConfigServiceServer).GetAccessGraphSettings(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: ClusterConfigService_GetAccessGraphSettings_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ClusterConfigServiceServer).GetAccessGraphSettings(ctx, req.(*GetAccessGraphSettingsRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _ClusterConfigService_CreateAccessGraphSettings_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(CreateAccessGraphSettingsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ClusterConfigServiceServer).CreateAccessGraphSettings(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: ClusterConfigService_CreateAccessGraphSettings_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ClusterConfigServiceServer).CreateAccessGraphSettings(ctx, req.(*CreateAccessGraphSettingsRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _ClusterConfigService_UpdateAccessGraphSettings_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(UpdateAccessGraphSettingsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ClusterConfigServiceServer).UpdateAccessGraphSettings(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: ClusterConfigService_UpdateAccessGraphSettings_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ClusterConfigServiceServer).UpdateAccessGraphSettings(ctx, req.(*UpdateAccessGraphSettingsRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _ClusterConfigService_UpsertAccessGraphSettings_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(UpsertAccessGraphSettingsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ClusterConfigServiceServer).UpsertAccessGraphSettings(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: ClusterConfigService_UpsertAccessGraphSettings_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ClusterConfigServiceServer).UpsertAccessGraphSettings(ctx, req.(*UpsertAccessGraphSettingsRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _ClusterConfigService_ResetAccessGraphSettings_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ResetAccessGraphSettingsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ClusterConfigServiceServer).ResetAccessGraphSettings(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: ClusterConfigService_ResetAccessGraphSettings_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ClusterConfigServiceServer).ResetAccessGraphSettings(ctx, req.(*ResetAccessGraphSettingsRequest)) + } + return interceptor(ctx, in, info, handler) +} + // ClusterConfigService_ServiceDesc is the grpc.ServiceDesc for ClusterConfigService service. // It's only intended for direct use with grpc.RegisterService, // and not to be introspected or modified (even as a copy) @@ -627,6 +802,26 @@ var ClusterConfigService_ServiceDesc = grpc.ServiceDesc{ MethodName: "GetClusterAccessGraphConfig", Handler: _ClusterConfigService_GetClusterAccessGraphConfig_Handler, }, + { + MethodName: "GetAccessGraphSettings", + Handler: _ClusterConfigService_GetAccessGraphSettings_Handler, + }, + { + MethodName: "CreateAccessGraphSettings", + Handler: _ClusterConfigService_CreateAccessGraphSettings_Handler, + }, + { + MethodName: "UpdateAccessGraphSettings", + Handler: _ClusterConfigService_UpdateAccessGraphSettings_Handler, + }, + { + MethodName: "UpsertAccessGraphSettings", + Handler: _ClusterConfigService_UpsertAccessGraphSettings_Handler, + }, + { + MethodName: "ResetAccessGraphSettings", + Handler: _ClusterConfigService_ResetAccessGraphSettings_Handler, + }, }, Streams: []grpc.StreamDesc{}, Metadata: "teleport/clusterconfig/v1/clusterconfig_service.proto", diff --git a/api/proto/teleport/clusterconfig/v1/access_graph_settings.proto b/api/proto/teleport/clusterconfig/v1/access_graph_settings.proto new file mode 100644 index 0000000000000..3f0e99639f51e --- /dev/null +++ b/api/proto/teleport/clusterconfig/v1/access_graph_settings.proto @@ -0,0 +1,51 @@ +// Copyright 2024 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. + +syntax = "proto3"; + +package teleport.clusterconfig.v1; + +import "teleport/header/v1/metadata.proto"; + +option go_package = "github.com/gravitational/teleport/api/gen/proto/go/teleport/clusterconfig/v1;clusterconfigv1"; + +// AccessGraphSettings holds dynamic configuration settings for the Access Graph service. +message AccessGraphSettings { + // kind is the kind of the resource. + string kind = 1; + // sub_kind is the sub kind of the resource. + string sub_kind = 2; + // version is the version of the resource. + string version = 3; + // metadata is the metadata of the resource. + teleport.header.v1.Metadata metadata = 4; + // spec is the spec of the resource. + AccessGraphSettingsSpec spec = 5; +} + +// AccessGraphSettingsSpec is the spec for the Access Graph service configuration settings. +message AccessGraphSettingsSpec { + // secrets_scan_config is used to configure the parameters for the secrets scanning functionality. + AccessGraphSecretsScanConfig secrets_scan_config = 1; +} + +// AccessGraphSecretsScanConfig is used to configure the parameters for the secrets scanning functionality. +enum AccessGraphSecretsScanConfig { + // ACCESS_GRAPH_SECRETS_SCAN_CONFIG_UNSPECIFIED is an unknown secrets scan configuration. + ACCESS_GRAPH_SECRETS_SCAN_CONFIG_UNSPECIFIED = 0; + // ACCESS_GRAPH_SECRETS_SCAN_CONFIG_DISABLED is a disabled secrets scan configuration. + ACCESS_GRAPH_SECRETS_SCAN_CONFIG_DISABLED = 1; + // ACCESS_GRAPH_SECRETS_SCAN_CONFIG_ENABLED is an enabled secrets scan configuration. + ACCESS_GRAPH_SECRETS_SCAN_CONFIG_ENABLED = 2; +} diff --git a/api/proto/teleport/clusterconfig/v1/clusterconfig_service.proto b/api/proto/teleport/clusterconfig/v1/clusterconfig_service.proto index 3aa9517218280..dbd23a636c81b 100644 --- a/api/proto/teleport/clusterconfig/v1/clusterconfig_service.proto +++ b/api/proto/teleport/clusterconfig/v1/clusterconfig_service.proto @@ -17,6 +17,7 @@ syntax = "proto3"; package teleport.clusterconfig.v1; import "teleport/clusterconfig/v1/access_graph.proto"; +import "teleport/clusterconfig/v1/access_graph_settings.proto"; import "teleport/legacy/types/types.proto"; option go_package = "github.com/gravitational/teleport/api/gen/proto/go/teleport/clusterconfig/v1;clusterconfigv1"; @@ -53,8 +54,19 @@ service ClusterConfigService { // GetClusterAuditConfig retrieves the active cluster audit configuration. rpc GetClusterAuditConfig(GetClusterAuditConfigRequest) returns (types.ClusterAuditConfigV2); - // GetClusterAccessGraphConfig retrieves the cluster Access Graph configuration from Auth service. + // GetClusterAccessGraphConfig retrieves the cluster Access Graph configuration from Auth server. rpc GetClusterAccessGraphConfig(GetClusterAccessGraphConfigRequest) returns (GetClusterAccessGraphConfigResponse); + + // GetAccessGraphSettings updates the cluster Access Graph configuration. + rpc GetAccessGraphSettings(GetAccessGraphSettingsRequest) returns (teleport.clusterconfig.v1.AccessGraphSettings); + // CreateAccessGraphSettings creates the cluster Access Graph configuration. + rpc CreateAccessGraphSettings(CreateAccessGraphSettingsRequest) returns (teleport.clusterconfig.v1.AccessGraphSettings); + // UpdateAccessGraphSettings updates the cluster Access Graph configuration. + rpc UpdateAccessGraphSettings(UpdateAccessGraphSettingsRequest) returns (teleport.clusterconfig.v1.AccessGraphSettings); + // UpsertAccessGraphSettings overwrites the active cluster Access Graph configuration. + rpc UpsertAccessGraphSettings(UpsertAccessGraphSettingsRequest) returns (teleport.clusterconfig.v1.AccessGraphSettings); + // ResetAccessGraphSettings restores the active cluster Access Graph to default settings. + rpc ResetAccessGraphSettings(ResetAccessGraphSettingsRequest) returns (teleport.clusterconfig.v1.AccessGraphSettings); } // Request for GetClusterNetworkingConfig @@ -116,3 +128,24 @@ message GetClusterAccessGraphConfigResponse { // access_graph holds the information about Access Graph service. teleport.clusterconfig.v1.AccessGraphConfig access_graph = 1; } + +// Request for GetAccessGraphSettings +message GetAccessGraphSettingsRequest {} + +// Request for CreateAccessGraphSettings +message CreateAccessGraphSettingsRequest { + teleport.clusterconfig.v1.AccessGraphSettings access_graph_settings = 1; +} + +// Request for UpdateAccessGraphSettings +message UpdateAccessGraphSettingsRequest { + teleport.clusterconfig.v1.AccessGraphSettings access_graph_settings = 1; +} + +// Request for UpsertAccessGraphSettings +message UpsertAccessGraphSettingsRequest { + teleport.clusterconfig.v1.AccessGraphSettings access_graph_settings = 1; +} + +// Request for ResetAccessGraphSettings +message ResetAccessGraphSettingsRequest {} From 0c0ea0da3fd93c3163bb54d861496ee25db990e0 Mon Sep 17 00:00:00 2001 From: Tiago Silva Date: Fri, 12 Jul 2024 21:39:18 +0100 Subject: [PATCH 12/25] [sec_scan][10] add `AccessGraphSettingsUpdate` audit event (#44011) This PR adds the boilerplate code and proto definition for `AccessGraphSettingsUpdate` audit event. This PR is part of https://github.com/gravitational/access-graph/issues/637. Signed-off-by: Tiago Silva --- .../teleport/legacy/types/events/events.proto | 35 +- api/types/events/events.pb.go | 2503 +++++++++-------- api/types/events/oneof.go | 4 + lib/events/api.go | 2 + lib/events/codes.go | 2 + lib/events/dynamic.go | 2 + 6 files changed, 1370 insertions(+), 1178 deletions(-) diff --git a/api/proto/teleport/legacy/types/events/events.proto b/api/proto/teleport/legacy/types/events/events.proto index 5313e22e2d85b..ba30cd3128201 100644 --- a/api/proto/teleport/legacy/types/events/events.proto +++ b/api/proto/teleport/legacy/types/events/events.proto @@ -4441,9 +4441,7 @@ message OneOf { events.DiscoveryConfigUpdate DiscoveryConfigUpdate = 161; events.DiscoveryConfigDelete DiscoveryConfigDelete = 162; events.DiscoveryConfigDeleteAll DiscoveryConfigDeleteAll = 163; - events.IntegrationCreate IntegrationCreate = 165; - events.IntegrationUpdate IntegrationUpdate = 166; - events.IntegrationDelete IntegrationDelete = 167; + events.AccessGraphSettingsUpdate AccessGraphSettingsUpdate = 164; } } @@ -6618,3 +6616,34 @@ message SpannerRPC { (gogoproto.casttype) = "Struct" ]; } + +// AccessGraphSettingsUpdate is emitted when the Access Graph Settings config is updated. +message AccessGraphSettingsUpdate { + // Metadata is a common event metadata + Metadata Metadata = 1 [ + (gogoproto.nullable) = false, + (gogoproto.embed) = true, + (gogoproto.jsontag) = "" + ]; + + // Status indicates whether the update was successful. + Status Status = 2 [ + (gogoproto.nullable) = false, + (gogoproto.embed) = true, + (gogoproto.jsontag) = "" + ]; + + // User is a common user event metadata + UserMetadata User = 3 [ + (gogoproto.nullable) = false, + (gogoproto.embed) = true, + (gogoproto.jsontag) = "" + ]; + + // ConnectionMetadata holds information about the connection + ConnectionMetadata Connection = 4 [ + (gogoproto.nullable) = false, + (gogoproto.embed) = true, + (gogoproto.jsontag) = "" + ]; +} diff --git a/api/types/events/events.pb.go b/api/types/events/events.pb.go index c4118770f1efb..fe2856d4f16e3 100644 --- a/api/types/events/events.pb.go +++ b/api/types/events/events.pb.go @@ -7502,9 +7502,7 @@ type OneOf struct { // *OneOf_DiscoveryConfigUpdate // *OneOf_DiscoveryConfigDelete // *OneOf_DiscoveryConfigDeleteAll - // *OneOf_IntegrationCreate - // *OneOf_IntegrationUpdate - // *OneOf_IntegrationDelete + // *OneOf_AccessGraphSettingsUpdate Event isOneOf_Event `protobuf_oneof:"Event"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` @@ -8036,14 +8034,8 @@ type OneOf_DiscoveryConfigDelete struct { type OneOf_DiscoveryConfigDeleteAll struct { DiscoveryConfigDeleteAll *DiscoveryConfigDeleteAll `protobuf:"bytes,163,opt,name=DiscoveryConfigDeleteAll,proto3,oneof" json:"DiscoveryConfigDeleteAll,omitempty"` } -type OneOf_IntegrationCreate struct { - IntegrationCreate *IntegrationCreate `protobuf:"bytes,165,opt,name=IntegrationCreate,proto3,oneof" json:"IntegrationCreate,omitempty"` -} -type OneOf_IntegrationUpdate struct { - IntegrationUpdate *IntegrationUpdate `protobuf:"bytes,166,opt,name=IntegrationUpdate,proto3,oneof" json:"IntegrationUpdate,omitempty"` -} -type OneOf_IntegrationDelete struct { - IntegrationDelete *IntegrationDelete `protobuf:"bytes,167,opt,name=IntegrationDelete,proto3,oneof" json:"IntegrationDelete,omitempty"` +type OneOf_AccessGraphSettingsUpdate struct { + AccessGraphSettingsUpdate *AccessGraphSettingsUpdate `protobuf:"bytes,164,opt,name=AccessGraphSettingsUpdate,proto3,oneof" json:"AccessGraphSettingsUpdate,omitempty"` } func (*OneOf_UserLogin) isOneOf_Event() {} @@ -8208,9 +8200,7 @@ func (*OneOf_DiscoveryConfigCreate) isOneOf_Event() {} func (*OneOf_DiscoveryConfigUpdate) isOneOf_Event() {} func (*OneOf_DiscoveryConfigDelete) isOneOf_Event() {} func (*OneOf_DiscoveryConfigDeleteAll) isOneOf_Event() {} -func (*OneOf_IntegrationCreate) isOneOf_Event() {} -func (*OneOf_IntegrationUpdate) isOneOf_Event() {} -func (*OneOf_IntegrationDelete) isOneOf_Event() {} +func (*OneOf_AccessGraphSettingsUpdate) isOneOf_Event() {} func (m *OneOf) GetEvent() isOneOf_Event { if m != nil { @@ -9353,23 +9343,9 @@ func (m *OneOf) GetDiscoveryConfigDeleteAll() *DiscoveryConfigDeleteAll { return nil } -func (m *OneOf) GetIntegrationCreate() *IntegrationCreate { - if x, ok := m.GetEvent().(*OneOf_IntegrationCreate); ok { - return x.IntegrationCreate - } - return nil -} - -func (m *OneOf) GetIntegrationUpdate() *IntegrationUpdate { - if x, ok := m.GetEvent().(*OneOf_IntegrationUpdate); ok { - return x.IntegrationUpdate - } - return nil -} - -func (m *OneOf) GetIntegrationDelete() *IntegrationDelete { - if x, ok := m.GetEvent().(*OneOf_IntegrationDelete); ok { - return x.IntegrationDelete +func (m *OneOf) GetAccessGraphSettingsUpdate() *AccessGraphSettingsUpdate { + if x, ok := m.GetEvent().(*OneOf_AccessGraphSettingsUpdate); ok { + return x.AccessGraphSettingsUpdate } return nil } @@ -9539,9 +9515,7 @@ func (*OneOf) XXX_OneofWrappers() []interface{} { (*OneOf_DiscoveryConfigUpdate)(nil), (*OneOf_DiscoveryConfigDelete)(nil), (*OneOf_DiscoveryConfigDeleteAll)(nil), - (*OneOf_IntegrationCreate)(nil), - (*OneOf_IntegrationUpdate)(nil), - (*OneOf_IntegrationDelete)(nil), + (*OneOf_AccessGraphSettingsUpdate)(nil), } } @@ -13313,6 +13287,54 @@ func (m *SpannerRPC) XXX_DiscardUnknown() { var xxx_messageInfo_SpannerRPC proto.InternalMessageInfo +// AccessGraphSettingsUpdate is emitted when the Access Graph Settings config is updated. +type AccessGraphSettingsUpdate struct { + // Metadata is a common event metadata + Metadata `protobuf:"bytes,1,opt,name=Metadata,proto3,embedded=Metadata" json:""` + // Status indicates whether the update was successful. + Status `protobuf:"bytes,2,opt,name=Status,proto3,embedded=Status" json:""` + // User is a common user event metadata + UserMetadata `protobuf:"bytes,3,opt,name=User,proto3,embedded=User" json:""` + // ConnectionMetadata holds information about the connection + ConnectionMetadata `protobuf:"bytes,4,opt,name=Connection,proto3,embedded=Connection" json:""` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *AccessGraphSettingsUpdate) Reset() { *m = AccessGraphSettingsUpdate{} } +func (m *AccessGraphSettingsUpdate) String() string { return proto.CompactTextString(m) } +func (*AccessGraphSettingsUpdate) ProtoMessage() {} +func (*AccessGraphSettingsUpdate) Descriptor() ([]byte, []int) { + return fileDescriptor_007ba1c3d6266d56, []int{208} +} +func (m *AccessGraphSettingsUpdate) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *AccessGraphSettingsUpdate) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_AccessGraphSettingsUpdate.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *AccessGraphSettingsUpdate) XXX_Merge(src proto.Message) { + xxx_messageInfo_AccessGraphSettingsUpdate.Merge(m, src) +} +func (m *AccessGraphSettingsUpdate) XXX_Size() int { + return m.Size() +} +func (m *AccessGraphSettingsUpdate) XXX_DiscardUnknown() { + xxx_messageInfo_AccessGraphSettingsUpdate.DiscardUnknown(m) +} + +var xxx_messageInfo_AccessGraphSettingsUpdate proto.InternalMessageInfo + func init() { proto.RegisterEnum("events.UserKind", UserKind_name, UserKind_value) proto.RegisterEnum("events.EventAction", EventAction_name, EventAction_value) @@ -13545,6 +13567,7 @@ func init() { proto.RegisterType((*SessionRecordingConfigUpdate)(nil), "events.SessionRecordingConfigUpdate") proto.RegisterType((*AccessPathChanged)(nil), "events.AccessPathChanged") proto.RegisterType((*SpannerRPC)(nil), "events.SpannerRPC") + proto.RegisterType((*AccessGraphSettingsUpdate)(nil), "events.AccessGraphSettingsUpdate") } func init() { @@ -13552,980 +13575,980 @@ func init() { } var fileDescriptor_007ba1c3d6266d56 = []byte{ - // 15553 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0xbd, 0x6b, 0x74, 0x1c, 0xc9, - 0x75, 0x18, 0x8c, 0x79, 0x60, 0x00, 0x5c, 0x3c, 0x08, 0x14, 0x5f, 0xbd, 0x5c, 0x92, 0xb3, 0xdb, - 0xab, 0xa5, 0xc8, 0xd5, 0x2e, 0xa9, 0xe5, 0x72, 0x77, 0xb5, 0x2f, 0xed, 0x0e, 0x30, 0x00, 0x31, - 0x24, 0x5e, 0xdb, 0x03, 0x92, 0x5a, 0xbd, 0xc6, 0x8d, 0xe9, 0x02, 0xd0, 0xcb, 0x99, 0xee, 0x51, - 0x77, 0x0f, 0x41, 0xec, 0xf7, 0x25, 0xb1, 0x1c, 0x3f, 0x24, 0x47, 0x52, 0x14, 0x39, 0xb6, 0xec, - 0xd8, 0x89, 0x65, 0xfb, 0x38, 0x71, 0x7c, 0x1c, 0x3b, 0x4e, 0x72, 0x6c, 0x2b, 0x8e, 0x4e, 0xec, - 0x28, 0x8f, 0x75, 0x74, 0x9c, 0x63, 0x3b, 0x89, 0x8f, 0x4f, 0xe2, 0x40, 0x8e, 0x12, 0xe7, 0x07, - 0x4e, 0x72, 0xe2, 0x24, 0x3a, 0xb1, 0xe3, 0x38, 0x39, 0x39, 0x75, 0xab, 0xba, 0xbb, 0xfa, 0x31, - 0x83, 0xe7, 0x1a, 0x0b, 0x11, 0x7f, 0x48, 0xcc, 0xbd, 0xb7, 0x6e, 0x55, 0xdf, 0xba, 0x55, 0x75, - 0xab, 0xea, 0xd6, 0xbd, 0x70, 0xc9, 0xa3, 0x0d, 0xda, 0xb2, 0x1d, 0xef, 0x4a, 0x83, 0xae, 0xe8, - 0xf5, 0xf5, 0x2b, 0xde, 0x7a, 0x8b, 0xba, 0x57, 0xe8, 0x3d, 0x6a, 0x79, 0xfe, 0x7f, 0x97, 0x5b, - 0x8e, 0xed, 0xd9, 0xa4, 0xc0, 0x7f, 0x9d, 0x39, 0xb1, 0x62, 0xaf, 0xd8, 0x08, 0xba, 0xc2, 0xfe, - 0xe2, 0xd8, 0x33, 0x67, 0x57, 0x6c, 0x7b, 0xa5, 0x41, 0xaf, 0xe0, 0xaf, 0xa5, 0xf6, 0xf2, 0x15, - 0xd7, 0x73, 0xda, 0x75, 0x4f, 0x60, 0x8b, 0x71, 0xac, 0x67, 0x36, 0xa9, 0xeb, 0xe9, 0xcd, 0x96, - 0x20, 0x38, 0x1f, 0x27, 0x58, 0x73, 0xf4, 0x56, 0x8b, 0x3a, 0xa2, 0xf2, 0x33, 0x8f, 0xa6, 0xb7, - 0x13, 0xff, 0x15, 0x24, 0x4f, 0xa5, 0x93, 0xf8, 0x8c, 0x62, 0x1c, 0xd5, 0x2f, 0x64, 0xa1, 0x7f, - 0x96, 0x7a, 0xba, 0xa1, 0x7b, 0x3a, 0x39, 0x0b, 0xbd, 0x15, 0xcb, 0xa0, 0xf7, 0x95, 0xcc, 0x23, - 0x99, 0x8b, 0xb9, 0xf1, 0xc2, 0xe6, 0x46, 0x31, 0x4b, 0x4d, 0x8d, 0x03, 0xc9, 0x39, 0xc8, 0x2f, - 0xae, 0xb7, 0xa8, 0x92, 0x7d, 0x24, 0x73, 0x71, 0x60, 0x7c, 0x60, 0x73, 0xa3, 0xd8, 0x8b, 0xb2, - 0xd0, 0x10, 0x4c, 0x1e, 0x85, 0x6c, 0xa5, 0xac, 0xe4, 0x10, 0x39, 0xb6, 0xb9, 0x51, 0x1c, 0x6e, - 0x9b, 0xc6, 0x93, 0x76, 0xd3, 0xf4, 0x68, 0xb3, 0xe5, 0xad, 0x6b, 0xd9, 0x4a, 0x99, 0x5c, 0x80, - 0xfc, 0x84, 0x6d, 0x50, 0x25, 0x8f, 0x44, 0x64, 0x73, 0xa3, 0x38, 0x52, 0xb7, 0x0d, 0x2a, 0x51, - 0x21, 0x9e, 0xbc, 0x06, 0xf9, 0x45, 0xb3, 0x49, 0x95, 0xde, 0x47, 0x32, 0x17, 0x07, 0xaf, 0x9e, - 0xb9, 0xcc, 0xa5, 0x72, 0xd9, 0x97, 0xca, 0xe5, 0x45, 0x5f, 0x6c, 0xe3, 0xa3, 0x6f, 0x6f, 0x14, - 0x7b, 0x36, 0x37, 0x8a, 0x79, 0x26, 0xc9, 0xcf, 0x7f, 0xbd, 0x98, 0xd1, 0xb0, 0x24, 0x79, 0x19, - 0x06, 0x27, 0x1a, 0x6d, 0xd7, 0xa3, 0xce, 0x9c, 0xde, 0xa4, 0x4a, 0x01, 0x2b, 0x3c, 0xb3, 0xb9, - 0x51, 0x3c, 0x55, 0xe7, 0xe0, 0x9a, 0xa5, 0x37, 0xe5, 0x8a, 0x65, 0x72, 0xf5, 0x97, 0x32, 0x70, - 0xac, 0x4a, 0x5d, 0xd7, 0xb4, 0xad, 0x40, 0x36, 0x8f, 0xc3, 0x80, 0x00, 0x55, 0xca, 0x28, 0x9f, - 0x81, 0xf1, 0xbe, 0xcd, 0x8d, 0x62, 0xce, 0x35, 0x0d, 0x2d, 0xc4, 0x90, 0xf7, 0x43, 0xdf, 0x1d, - 0xd3, 0x5b, 0x9d, 0x9d, 0x2a, 0x09, 0x39, 0x9d, 0xda, 0xdc, 0x28, 0x92, 0x35, 0xd3, 0x5b, 0xad, - 0x35, 0x97, 0x75, 0xa9, 0x42, 0x9f, 0x8c, 0xcc, 0xc0, 0xe8, 0x82, 0x63, 0xde, 0xd3, 0x3d, 0x7a, - 0x93, 0xae, 0x2f, 0xd8, 0x0d, 0xb3, 0xbe, 0x2e, 0xa4, 0xf8, 0xc8, 0xe6, 0x46, 0xf1, 0x6c, 0x8b, - 0xe3, 0x6a, 0x77, 0xe9, 0x7a, 0xad, 0x85, 0x58, 0x89, 0x49, 0xa2, 0xa4, 0xfa, 0xd5, 0x5e, 0x18, - 0xba, 0xe5, 0x52, 0x27, 0x68, 0xf7, 0x05, 0xc8, 0xb3, 0xdf, 0xa2, 0xc9, 0x28, 0xf3, 0xb6, 0x4b, - 0x1d, 0x59, 0xe6, 0x0c, 0x4f, 0x2e, 0x41, 0xef, 0x8c, 0xbd, 0x62, 0x5a, 0xa2, 0xd9, 0xc7, 0x37, - 0x37, 0x8a, 0xc7, 0x1a, 0x0c, 0x20, 0x51, 0x72, 0x0a, 0xf2, 0x41, 0x18, 0xaa, 0x34, 0x99, 0x0e, - 0xd9, 0x96, 0xee, 0xd9, 0x8e, 0x68, 0x2d, 0x4a, 0xd7, 0x94, 0xe0, 0x52, 0xc1, 0x08, 0x3d, 0x79, - 0x11, 0xa0, 0x74, 0xa7, 0xaa, 0xd9, 0x0d, 0x5a, 0xd2, 0xe6, 0x84, 0x32, 0x60, 0x69, 0x7d, 0xcd, - 0xad, 0x39, 0x76, 0x83, 0xd6, 0x74, 0x47, 0xae, 0x56, 0xa2, 0x26, 0x93, 0x30, 0x52, 0xaa, 0xd7, - 0xa9, 0xeb, 0x6a, 0xf4, 0x13, 0x6d, 0xea, 0x7a, 0xae, 0xd2, 0xfb, 0x48, 0xee, 0xe2, 0xc0, 0xf8, - 0xb9, 0xcd, 0x8d, 0xe2, 0x43, 0x3a, 0x62, 0x6a, 0x8e, 0x40, 0x49, 0x2c, 0x62, 0x85, 0xc8, 0x38, - 0x0c, 0x97, 0xde, 0x6a, 0x3b, 0xb4, 0x62, 0x50, 0xcb, 0x33, 0xbd, 0x75, 0xa1, 0x21, 0x67, 0x37, - 0x37, 0x8a, 0x8a, 0xce, 0x10, 0x35, 0x53, 0x60, 0x24, 0x26, 0xd1, 0x22, 0x64, 0x1e, 0xc6, 0xae, - 0x4f, 0x2c, 0x54, 0xa9, 0x73, 0xcf, 0xac, 0xd3, 0x52, 0xbd, 0x6e, 0xb7, 0x2d, 0x4f, 0xe9, 0x43, - 0x3e, 0x8f, 0x6e, 0x6e, 0x14, 0xcf, 0xad, 0xd4, 0x5b, 0x35, 0x97, 0x63, 0x6b, 0x3a, 0x47, 0x4b, - 0xcc, 0x92, 0x65, 0xc9, 0x87, 0x61, 0x78, 0xd1, 0x61, 0x5a, 0x68, 0x94, 0x29, 0x83, 0x2b, 0xfd, - 0xa8, 0xff, 0xa7, 0x2e, 0x8b, 0x09, 0x88, 0x43, 0xfd, 0x9e, 0xe5, 0x8d, 0xf5, 0x78, 0x81, 0x9a, - 0x81, 0x38, 0xb9, 0xb1, 0x11, 0x56, 0x84, 0x82, 0xc2, 0x3e, 0xde, 0x74, 0xa8, 0x91, 0xd0, 0xb6, - 0x01, 0x6c, 0xf3, 0xa5, 0xcd, 0x8d, 0xe2, 0xe3, 0x8e, 0xa0, 0xa9, 0x75, 0x55, 0xbb, 0x8e, 0xac, - 0xc8, 0x24, 0xf4, 0x33, 0x6d, 0xba, 0x69, 0x5a, 0x86, 0x02, 0x8f, 0x64, 0x2e, 0x8e, 0x5c, 0x1d, - 0xf5, 0x5b, 0xef, 0xc3, 0xc7, 0x4f, 0x6f, 0x6e, 0x14, 0x8f, 0x33, 0x1d, 0xac, 0xdd, 0x35, 0x2d, - 0x79, 0x8a, 0x08, 0x8a, 0xaa, 0x7f, 0x98, 0x87, 0x11, 0x26, 0x1c, 0x49, 0x8f, 0x4b, 0x6c, 0x48, - 0x32, 0x08, 0x1b, 0xa1, 0x6e, 0x4b, 0xaf, 0x53, 0xa1, 0xd2, 0xc8, 0xce, 0xf2, 0x81, 0x12, 0xbb, - 0x38, 0x3d, 0xb9, 0x04, 0xfd, 0x1c, 0x54, 0x29, 0x0b, 0x2d, 0x1f, 0xde, 0xdc, 0x28, 0x0e, 0xb8, - 0x08, 0xab, 0x99, 0x86, 0x16, 0xa0, 0x99, 0x9a, 0xf1, 0xbf, 0xa7, 0x6d, 0xd7, 0x63, 0xcc, 0x85, - 0x92, 0xa3, 0x9a, 0x89, 0x02, 0xab, 0x02, 0x25, 0xab, 0x59, 0xb4, 0x10, 0x79, 0x01, 0x80, 0x43, - 0x4a, 0x86, 0xe1, 0x08, 0x4d, 0x7f, 0x68, 0x73, 0xa3, 0x78, 0x52, 0xb0, 0xd0, 0x0d, 0x43, 0x1e, - 0x26, 0x12, 0x31, 0x69, 0xc2, 0x10, 0xff, 0x35, 0xa3, 0x2f, 0xd1, 0x06, 0x57, 0xf3, 0xc1, 0xab, - 0x17, 0x7d, 0x69, 0x46, 0xa5, 0x73, 0x59, 0x26, 0x9d, 0xb4, 0x3c, 0x67, 0x7d, 0xbc, 0x28, 0x66, - 0xc6, 0xd3, 0xa2, 0xaa, 0x06, 0xe2, 0xe4, 0x31, 0x29, 0x97, 0x61, 0x13, 0xe6, 0x94, 0xed, 0xac, - 0xe9, 0x8e, 0x41, 0x8d, 0xf1, 0x75, 0x79, 0xc2, 0x5c, 0xf6, 0xc1, 0xb5, 0x25, 0x59, 0x07, 0x64, - 0x72, 0x32, 0x01, 0xc3, 0x9c, 0x5b, 0xb5, 0xbd, 0x84, 0x7d, 0xdf, 0x97, 0x90, 0x96, 0xdb, 0x5e, - 0x8a, 0xf7, 0x77, 0xb4, 0x0c, 0x1b, 0x93, 0x1c, 0x70, 0x9b, 0x3a, 0x6c, 0x36, 0x45, 0xf5, 0x17, - 0x63, 0x52, 0x30, 0xb9, 0xc7, 0x31, 0x49, 0x1e, 0xa2, 0xc8, 0x99, 0x57, 0x61, 0x2c, 0x21, 0x0a, - 0x32, 0x0a, 0xb9, 0xbb, 0x74, 0x9d, 0xab, 0x8b, 0xc6, 0xfe, 0x24, 0x27, 0xa0, 0xf7, 0x9e, 0xde, - 0x68, 0x8b, 0xb5, 0x4c, 0xe3, 0x3f, 0x5e, 0xcc, 0x7e, 0x20, 0xc3, 0xa6, 0x7e, 0x32, 0x61, 0x5b, - 0x16, 0xad, 0x7b, 0xf2, 0xec, 0xff, 0x1c, 0x0c, 0xcc, 0xd8, 0x75, 0xbd, 0x81, 0xfd, 0xc8, 0xf5, - 0x4e, 0xd9, 0xdc, 0x28, 0x9e, 0x60, 0x1d, 0x78, 0xb9, 0xc1, 0x30, 0x52, 0x9b, 0x42, 0x52, 0xa6, - 0x00, 0x1a, 0x6d, 0xda, 0x1e, 0xc5, 0x82, 0xd9, 0x50, 0x01, 0xb0, 0xa0, 0x83, 0x28, 0x59, 0x01, - 0x42, 0x62, 0x72, 0x05, 0xfa, 0x17, 0xd8, 0x82, 0x57, 0xb7, 0x1b, 0x42, 0xf9, 0x70, 0x4e, 0xc6, - 0x45, 0x50, 0x1e, 0x34, 0x3e, 0x91, 0x3a, 0x0d, 0x23, 0x13, 0x0d, 0x93, 0x5a, 0x9e, 0xdc, 0x6a, - 0x36, 0xa4, 0x4a, 0x2b, 0xd4, 0xf2, 0xe4, 0x56, 0xe3, 0xe0, 0xd3, 0x19, 0x54, 0x6e, 0x75, 0x40, - 0xaa, 0xfe, 0x8b, 0x1c, 0x3c, 0x74, 0xb3, 0xbd, 0x44, 0x1d, 0x8b, 0x7a, 0xd4, 0x15, 0x2b, 0x63, - 0xc0, 0x75, 0x0e, 0xc6, 0x12, 0x48, 0xc1, 0x1d, 0x57, 0xac, 0xbb, 0x01, 0xb2, 0x26, 0x16, 0x5b, - 0x79, 0xda, 0x4b, 0x14, 0x25, 0xd3, 0x70, 0x2c, 0x04, 0xb2, 0x46, 0xb8, 0x4a, 0x16, 0xe7, 0xf4, - 0xf3, 0x9b, 0x1b, 0xc5, 0x33, 0x12, 0x37, 0xd6, 0x6c, 0x59, 0x83, 0xe3, 0xc5, 0xc8, 0x4d, 0x18, - 0x0d, 0x41, 0xd7, 0x1d, 0xbb, 0xdd, 0x72, 0x95, 0x1c, 0xb2, 0x2a, 0x6e, 0x6e, 0x14, 0x1f, 0x96, - 0x58, 0xad, 0x20, 0x52, 0x5e, 0x49, 0xe3, 0x05, 0xc9, 0x77, 0x66, 0x64, 0x6e, 0x62, 0x14, 0xe6, - 0x71, 0x14, 0x3e, 0xef, 0x8f, 0xc2, 0x8e, 0x42, 0xba, 0x1c, 0x2f, 0x29, 0x06, 0x65, 0xac, 0x19, - 0x89, 0x41, 0x99, 0xa8, 0xf1, 0xcc, 0x04, 0x9c, 0x4c, 0xe5, 0xb5, 0x23, 0xad, 0xfe, 0xfd, 0x9c, - 0xcc, 0x65, 0xc1, 0x36, 0x82, 0xce, 0x9c, 0x97, 0x3b, 0x73, 0xc1, 0x36, 0xd0, 0x5c, 0xca, 0x84, - 0x8b, 0x98, 0xd4, 0xd8, 0x96, 0x6d, 0xc4, 0xad, 0xa6, 0x64, 0x59, 0xf2, 0x71, 0x38, 0x95, 0x00, - 0xf2, 0xe9, 0x9a, 0x6b, 0xff, 0x85, 0xcd, 0x8d, 0xa2, 0x9a, 0xc2, 0x35, 0x3e, 0x7b, 0x77, 0xe0, - 0x42, 0x74, 0x38, 0x2d, 0x49, 0xdd, 0xb6, 0x3c, 0xdd, 0xb4, 0x84, 0x95, 0xc7, 0x47, 0xc9, 0x7b, - 0x37, 0x37, 0x8a, 0x8f, 0xc9, 0x3a, 0xe8, 0xd3, 0xc4, 0x1b, 0xdf, 0x89, 0x0f, 0x31, 0x40, 0x49, - 0x41, 0x55, 0x9a, 0xfa, 0x8a, 0x6f, 0xba, 0x5e, 0xdc, 0xdc, 0x28, 0xbe, 0x27, 0xb5, 0x0e, 0x93, - 0x51, 0xc9, 0x4b, 0x65, 0x27, 0x4e, 0x44, 0x03, 0x12, 0xe2, 0xe6, 0x6c, 0x83, 0xe2, 0x37, 0xf4, - 0x22, 0x7f, 0x75, 0x73, 0xa3, 0x78, 0x5e, 0xe2, 0x6f, 0xd9, 0x06, 0x8d, 0x37, 0x3f, 0xa5, 0xb4, - 0xfa, 0x4b, 0x39, 0x38, 0x5f, 0x2d, 0xcd, 0xce, 0x54, 0x0c, 0xdf, 0xb6, 0x58, 0x70, 0xec, 0x7b, - 0xa6, 0x21, 0x8d, 0xde, 0x25, 0x38, 0x1d, 0x43, 0x4d, 0xa2, 0x39, 0x13, 0x58, 0xb5, 0xf8, 0x6d, - 0xbe, 0xdd, 0xd2, 0x12, 0x34, 0x35, 0x6e, 0xf3, 0xd4, 0x22, 0x26, 0x7d, 0x27, 0x46, 0xac, 0x8f, - 0x62, 0xa8, 0xea, 0xaa, 0xed, 0x78, 0xf5, 0xb6, 0x27, 0x94, 0x00, 0xfb, 0x28, 0x51, 0x87, 0x2b, - 0x88, 0xba, 0x54, 0xe1, 0xf3, 0x21, 0x9f, 0xce, 0xc0, 0x68, 0xc9, 0xf3, 0x1c, 0x73, 0xa9, 0xed, - 0xd1, 0x59, 0xbd, 0xd5, 0x32, 0xad, 0x15, 0x1c, 0xeb, 0x83, 0x57, 0x5f, 0x0e, 0xd6, 0xc8, 0xae, - 0x92, 0xb8, 0x1c, 0x2f, 0x2e, 0x0d, 0x51, 0xdd, 0x47, 0xd5, 0x9a, 0x1c, 0x27, 0x0f, 0xd1, 0x78, - 0x39, 0x36, 0x44, 0x53, 0x79, 0xed, 0x68, 0x88, 0x7e, 0x21, 0x07, 0x67, 0xe7, 0xef, 0x7a, 0xba, - 0x46, 0x5d, 0xbb, 0xed, 0xd4, 0xa9, 0x7b, 0xab, 0x65, 0xe8, 0x1e, 0x0d, 0x47, 0x6a, 0x11, 0x7a, - 0x4b, 0x86, 0x41, 0x0d, 0x64, 0xd7, 0xcb, 0xf7, 0x5f, 0x3a, 0x03, 0x68, 0x1c, 0x4e, 0x1e, 0x87, - 0x3e, 0x51, 0x06, 0xb9, 0xf7, 0x8e, 0x0f, 0x6e, 0x6e, 0x14, 0xfb, 0xda, 0x1c, 0xa4, 0xf9, 0x38, - 0x46, 0x56, 0xa6, 0x0d, 0xca, 0xc8, 0x72, 0x21, 0x99, 0xc1, 0x41, 0x9a, 0x8f, 0x23, 0xaf, 0xc3, - 0x08, 0xb2, 0x0d, 0xda, 0x23, 0xe6, 0xbe, 0x13, 0xbe, 0x74, 0xe5, 0xc6, 0xf2, 0xa5, 0x09, 0x5b, - 0x53, 0x73, 0xfc, 0x02, 0x5a, 0x8c, 0x01, 0xb9, 0x03, 0xa3, 0xa2, 0x11, 0x21, 0xd3, 0xde, 0x2e, - 0x4c, 0x4f, 0x6e, 0x6e, 0x14, 0xc7, 0x44, 0xfb, 0x25, 0xb6, 0x09, 0x26, 0x8c, 0xb1, 0x68, 0x76, - 0xc8, 0xb8, 0xb0, 0x15, 0x63, 0xf1, 0xc5, 0x32, 0xe3, 0x38, 0x13, 0xf5, 0x0d, 0x18, 0x92, 0x0b, - 0x92, 0x53, 0xb8, 0xc7, 0xe5, 0xe3, 0x04, 0x77, 0xc7, 0xa6, 0x81, 0x1b, 0xdb, 0xa7, 0x61, 0xb0, - 0x4c, 0xdd, 0xba, 0x63, 0xb6, 0x98, 0xd5, 0x20, 0x94, 0xfc, 0xd8, 0xe6, 0x46, 0x71, 0xd0, 0x08, - 0xc1, 0x9a, 0x4c, 0xa3, 0xfe, 0xcf, 0x0c, 0x9c, 0x62, 0xbc, 0x4b, 0xae, 0x6b, 0xae, 0x58, 0x4d, - 0x79, 0xd9, 0x7e, 0x12, 0x0a, 0x55, 0xac, 0x4f, 0xd4, 0x74, 0x62, 0x73, 0xa3, 0x38, 0xca, 0x5b, - 0x20, 0xe9, 0xa1, 0xa0, 0x09, 0x36, 0x78, 0xd9, 0x2d, 0x36, 0x78, 0xcc, 0xa4, 0xf5, 0x74, 0xc7, - 0x33, 0xad, 0x95, 0xaa, 0xa7, 0x7b, 0x6d, 0x37, 0x62, 0xd2, 0x0a, 0x4c, 0xcd, 0x45, 0x54, 0xc4, - 0xa4, 0x8d, 0x14, 0x22, 0xaf, 0xc2, 0xd0, 0xa4, 0x65, 0x84, 0x4c, 0xf8, 0x84, 0xf8, 0x30, 0xb3, - 0x34, 0x29, 0xc2, 0x93, 0x2c, 0x22, 0x05, 0xd4, 0xbf, 0x95, 0x01, 0x85, 0xef, 0xc6, 0x66, 0x4c, - 0xd7, 0x9b, 0xa5, 0xcd, 0x25, 0x69, 0x76, 0x9a, 0xf2, 0xb7, 0x77, 0x0c, 0x27, 0xad, 0x45, 0x68, - 0x0a, 0x88, 0xed, 0x5d, 0xc3, 0x74, 0xbd, 0xf8, 0x64, 0x18, 0x2b, 0x45, 0x2a, 0xd0, 0xc7, 0x39, - 0x73, 0x5b, 0x62, 0xf0, 0xaa, 0xe2, 0x2b, 0x42, 0xbc, 0x6a, 0xae, 0x0c, 0x4d, 0x4e, 0x2c, 0xef, - 0xcf, 0x45, 0x79, 0xf5, 0x6f, 0x67, 0x61, 0x34, 0x5e, 0x88, 0xdc, 0x81, 0xfe, 0x1b, 0xb6, 0x69, - 0x51, 0x63, 0xde, 0xc2, 0x16, 0x76, 0x3f, 0xa5, 0xf0, 0x6d, 0xf1, 0xe3, 0x6f, 0x62, 0x99, 0x9a, - 0x6c, 0xc1, 0xe2, 0xa1, 0x45, 0xc0, 0x8c, 0x7c, 0x18, 0x06, 0x98, 0x0d, 0x78, 0x0f, 0x39, 0x67, - 0xb7, 0xe4, 0xfc, 0x88, 0xe0, 0x7c, 0xc2, 0xe1, 0x85, 0x92, 0xac, 0x43, 0x76, 0x4c, 0xaf, 0x34, - 0xaa, 0xbb, 0xb6, 0x25, 0x7a, 0x1e, 0xf5, 0xca, 0x41, 0x88, 0xac, 0x57, 0x9c, 0x86, 0x99, 0xae, - 0xfc, 0x63, 0xb1, 0x1b, 0xa4, 0xbd, 0x0b, 0x97, 0x55, 0xbc, 0x07, 0x24, 0x62, 0xf5, 0xbb, 0xb3, - 0xf0, 0x54, 0x28, 0x32, 0x8d, 0xde, 0x33, 0xe9, 0x9a, 0x10, 0xe7, 0xaa, 0xd9, 0x12, 0x9b, 0x47, - 0xa6, 0xf2, 0xee, 0xc4, 0xaa, 0x6e, 0xad, 0x50, 0x83, 0x5c, 0x82, 0x5e, 0xb6, 0xc3, 0x77, 0x95, - 0x0c, 0x9a, 0x6b, 0x38, 0x9d, 0x38, 0x0c, 0x20, 0x9f, 0x3e, 0x20, 0x05, 0xb1, 0xa1, 0xb0, 0xe8, - 0xe8, 0xa6, 0xe7, 0xf7, 0x6c, 0x29, 0xd9, 0xb3, 0xdb, 0xa8, 0xf1, 0x32, 0xe7, 0xc1, 0xe7, 0x7c, - 0x14, 0x84, 0x87, 0x00, 0x59, 0x10, 0x9c, 0xe4, 0xcc, 0x0b, 0x30, 0x28, 0x11, 0xef, 0x68, 0x52, - 0xff, 0x72, 0x5e, 0xd6, 0x75, 0xbf, 0x59, 0x42, 0xd7, 0xaf, 0x30, 0x1d, 0x75, 0x5d, 0x66, 0x55, - 0x70, 0x25, 0x17, 0x9a, 0x88, 0xa0, 0xa8, 0x26, 0x22, 0x88, 0x3c, 0x03, 0xfd, 0x9c, 0x45, 0xb0, - 0x7f, 0xc5, 0xbd, 0xaf, 0x83, 0xb0, 0xe8, 0xd2, 0x1c, 0x10, 0x92, 0x9f, 0xce, 0xc0, 0xb9, 0xae, - 0x92, 0x40, 0x65, 0x18, 0xbc, 0xfa, 0xec, 0xae, 0xc4, 0x38, 0xfe, 0xd4, 0xe6, 0x46, 0xf1, 0x52, - 0x33, 0x20, 0xa9, 0x39, 0x12, 0x4d, 0xad, 0xce, 0x89, 0xa4, 0x76, 0x75, 0x6f, 0x0a, 0x33, 0x1e, - 0x79, 0xa5, 0x53, 0x78, 0x86, 0x63, 0xd5, 0xd7, 0xfd, 0x46, 0xe6, 0x43, 0xe3, 0x51, 0x7c, 0xef, - 0xb2, 0x4f, 0x92, 0x52, 0x4d, 0x07, 0x2e, 0xa4, 0x0e, 0xa7, 0x39, 0xa6, 0xac, 0xaf, 0xcf, 0x2f, - 0xcf, 0xda, 0x96, 0xb7, 0xea, 0x57, 0xd0, 0x2b, 0x1f, 0x82, 0x60, 0x05, 0x86, 0xbe, 0x5e, 0xb3, - 0x97, 0x6b, 0x4d, 0x46, 0x95, 0x52, 0x47, 0x27, 0x4e, 0x6c, 0xa2, 0x15, 0x63, 0xce, 0x9f, 0x82, - 0x0a, 0xe1, 0x11, 0x95, 0x3f, 0x4e, 0x93, 0x13, 0x4e, 0xac, 0x90, 0x5a, 0x81, 0xa1, 0x19, 0xbb, - 0x7e, 0x37, 0x50, 0x97, 0x17, 0xa0, 0xb0, 0xa8, 0x3b, 0x2b, 0xd4, 0x43, 0x59, 0x0c, 0x5e, 0x1d, - 0xbb, 0xcc, 0x8f, 0x7d, 0x19, 0x11, 0x47, 0x8c, 0x8f, 0x88, 0xd9, 0xa0, 0xe0, 0xe1, 0x6f, 0x4d, - 0x14, 0x50, 0xbf, 0xde, 0x0b, 0x43, 0xe2, 0x88, 0x12, 0x67, 0x73, 0xf2, 0x62, 0x78, 0xe8, 0x2b, - 0xa6, 0xaf, 0xe0, 0x98, 0x26, 0x38, 0x5e, 0x1a, 0x62, 0xcc, 0x7e, 0x63, 0xa3, 0x98, 0xd9, 0xdc, - 0x28, 0xf6, 0x68, 0xfd, 0xd2, 0xa6, 0x32, 0x5c, 0x6f, 0xa4, 0x05, 0x56, 0x3e, 0x74, 0x8c, 0x95, - 0xe5, 0xeb, 0xcf, 0xab, 0xd0, 0x27, 0xda, 0x20, 0x34, 0xee, 0x74, 0x78, 0x96, 0x11, 0x39, 0x6a, - 0x8d, 0x95, 0xf6, 0x4b, 0x91, 0x97, 0xa1, 0xc0, 0xf7, 0xf6, 0x42, 0x00, 0xa7, 0xd2, 0xcf, 0x42, - 0x62, 0xc5, 0x45, 0x19, 0x32, 0x0d, 0x10, 0xee, 0xeb, 0x83, 0x93, 0x65, 0xc1, 0x21, 0xb9, 0xe3, - 0x8f, 0x71, 0x91, 0xca, 0x92, 0xe7, 0x60, 0x68, 0x91, 0x3a, 0x4d, 0xd3, 0xd2, 0x1b, 0x55, 0xf3, - 0x2d, 0xff, 0x70, 0x19, 0x17, 0x5e, 0xd7, 0x7c, 0x4b, 0x1e, 0xb9, 0x11, 0x3a, 0xf2, 0xb1, 0xb4, - 0x7d, 0x73, 0x1f, 0x36, 0xe4, 0xd1, 0x2d, 0x37, 0x94, 0xb1, 0xf6, 0xa4, 0x6c, 0xa3, 0x5f, 0x87, - 0xe1, 0xc8, 0x96, 0x49, 0x9c, 0x1e, 0x9e, 0x4b, 0xb2, 0x96, 0xf6, 0x7f, 0x31, 0xb6, 0x51, 0x0e, - 0x4c, 0x93, 0x2b, 0x96, 0xe9, 0x99, 0x7a, 0x63, 0xc2, 0x6e, 0x36, 0x75, 0xcb, 0x50, 0x06, 0x42, - 0x4d, 0x36, 0x39, 0xa6, 0x56, 0xe7, 0x28, 0x59, 0x93, 0xa3, 0x85, 0xd8, 0xb6, 0x5c, 0xf4, 0xa1, - 0x46, 0xeb, 0xb6, 0xc3, 0x6c, 0x01, 0x3c, 0x1c, 0x14, 0xdb, 0x72, 0x97, 0xe3, 0x6a, 0x8e, 0x8f, - 0x94, 0x8d, 0xed, 0x78, 0xc1, 0x1b, 0xf9, 0xfe, 0xc1, 0xd1, 0xa1, 0xf8, 0x79, 0xae, 0xfa, 0x37, - 0x73, 0x30, 0x28, 0x48, 0xd9, 0x52, 0x7a, 0xa4, 0xe0, 0x7b, 0x51, 0xf0, 0x54, 0x45, 0x2d, 0xec, - 0x97, 0xa2, 0xaa, 0x9f, 0xc9, 0x06, 0xb3, 0xd1, 0x82, 0x63, 0x5a, 0x7b, 0x9b, 0x8d, 0x2e, 0x00, - 0x4c, 0xac, 0xb6, 0xad, 0xbb, 0xfc, 0xde, 0x2a, 0x1b, 0xde, 0x5b, 0xd5, 0x4d, 0x4d, 0xc2, 0x90, - 0x73, 0x90, 0x2f, 0x33, 0xfe, 0xac, 0x67, 0x86, 0xc6, 0x07, 0xde, 0xe6, 0x9c, 0x32, 0x4f, 0x69, - 0x08, 0x66, 0x9b, 0xab, 0xf1, 0x75, 0x8f, 0x72, 0x73, 0x36, 0xc7, 0x37, 0x57, 0x4b, 0x0c, 0xa0, - 0x71, 0x38, 0xb9, 0x06, 0x63, 0x65, 0xda, 0xd0, 0xd7, 0x67, 0xcd, 0x46, 0xc3, 0x74, 0x69, 0xdd, - 0xb6, 0x0c, 0x17, 0x85, 0x2c, 0xaa, 0x6b, 0xba, 0x5a, 0x92, 0x80, 0xa8, 0x50, 0x98, 0x5f, 0x5e, - 0x76, 0xa9, 0x87, 0xe2, 0xcb, 0x8d, 0x03, 0x9b, 0x9c, 0x6d, 0x84, 0x68, 0x02, 0xa3, 0xfe, 0x5c, - 0x86, 0xed, 0x5e, 0xdc, 0xbb, 0x9e, 0xdd, 0x0a, 0xb4, 0x7c, 0x4f, 0x22, 0xb9, 0x14, 0xda, 0x15, - 0x59, 0xfc, 0xda, 0x63, 0xe2, 0x6b, 0xfb, 0x84, 0x6d, 0x11, 0x5a, 0x14, 0xa9, 0x5f, 0x95, 0xdb, - 0xe2, 0xab, 0xd4, 0x3f, 0xc8, 0xc2, 0x69, 0xd1, 0xe2, 0x89, 0x86, 0xd9, 0x5a, 0xb2, 0x75, 0xc7, - 0xd0, 0x68, 0x9d, 0x9a, 0xf7, 0xe8, 0xe1, 0x1c, 0x78, 0xd1, 0xa1, 0x93, 0xdf, 0xc3, 0xd0, 0xb9, - 0x8a, 0x1b, 0x41, 0x26, 0x19, 0x3c, 0xf0, 0xe5, 0x46, 0xc5, 0xe8, 0xe6, 0x46, 0x71, 0xc8, 0xe0, - 0x60, 0x3c, 0xf2, 0xd7, 0x64, 0x22, 0xa6, 0x24, 0x33, 0xd4, 0x5a, 0xf1, 0x56, 0x51, 0x49, 0x7a, - 0xb9, 0x92, 0x34, 0x10, 0xa2, 0x09, 0x8c, 0xfa, 0x5f, 0xb2, 0x70, 0x22, 0x2e, 0xf2, 0x2a, 0xb5, - 0x8c, 0x23, 0x79, 0xbf, 0x33, 0xf2, 0xfe, 0x66, 0x0e, 0x1e, 0x16, 0x65, 0xaa, 0xab, 0xba, 0x43, - 0x8d, 0xb2, 0xe9, 0xd0, 0xba, 0x67, 0x3b, 0xeb, 0x87, 0xd8, 0x80, 0xda, 0x3f, 0xb1, 0x5f, 0x83, - 0x82, 0xd8, 0xfe, 0xf3, 0x75, 0x66, 0x24, 0x68, 0x09, 0x42, 0x13, 0x2b, 0x14, 0x3f, 0x3a, 0x88, - 0x75, 0x56, 0x61, 0x3b, 0x9d, 0xf5, 0x01, 0x18, 0x0e, 0x44, 0x8f, 0x1b, 0xd1, 0xbe, 0xd0, 0xda, - 0x32, 0x7c, 0x04, 0xee, 0x45, 0xb5, 0x28, 0x21, 0xd6, 0xe6, 0x03, 0x2a, 0x65, 0xb4, 0x86, 0x86, - 0x45, 0x6d, 0x41, 0x39, 0xd3, 0xd0, 0x64, 0x22, 0x75, 0x23, 0x0f, 0x67, 0xd2, 0xbb, 0x5d, 0xa3, - 0xba, 0x71, 0xd4, 0xeb, 0xdf, 0x92, 0xbd, 0x4e, 0x1e, 0x85, 0xfc, 0x82, 0xee, 0xad, 0x8a, 0x7b, - 0x70, 0xbc, 0x13, 0x5e, 0x36, 0x1b, 0xb4, 0xd6, 0xd2, 0xbd, 0x55, 0x0d, 0x51, 0xd2, 0x9c, 0x01, - 0xc8, 0x31, 0x65, 0xce, 0x90, 0x16, 0xfb, 0xc1, 0x47, 0x32, 0x17, 0xf3, 0xa9, 0x8b, 0xfd, 0xd7, - 0xf3, 0x9d, 0xe6, 0x95, 0x3b, 0x8e, 0xe9, 0xd1, 0x23, 0x0d, 0x3b, 0xd2, 0xb0, 0x3d, 0x6a, 0xd8, - 0x6f, 0x65, 0x61, 0x38, 0xd8, 0x34, 0xbd, 0x49, 0xeb, 0x07, 0xb3, 0x56, 0x85, 0x5b, 0x99, 0xdc, - 0x9e, 0xb7, 0x32, 0x7b, 0x51, 0x28, 0x35, 0x38, 0xf2, 0xe4, 0xa6, 0x01, 0x4a, 0x8c, 0x1f, 0x79, - 0x06, 0x07, 0x9d, 0x8f, 0x42, 0xdf, 0xac, 0x7e, 0xdf, 0x6c, 0xb6, 0x9b, 0xc2, 0x4a, 0x47, 0xbf, - 0xae, 0xa6, 0x7e, 0x5f, 0xf3, 0xe1, 0xea, 0xbf, 0xca, 0xc0, 0x88, 0x10, 0xaa, 0x60, 0xbe, 0x27, - 0xa9, 0x86, 0xd2, 0xc9, 0xee, 0x59, 0x3a, 0xb9, 0xdd, 0x4b, 0x47, 0xfd, 0x91, 0x1c, 0x28, 0x53, - 0x66, 0x83, 0x2e, 0x3a, 0xba, 0xe5, 0x2e, 0x53, 0x47, 0x6c, 0xa7, 0x27, 0x19, 0xab, 0x3d, 0x7d, - 0xa0, 0x34, 0xa5, 0x64, 0x77, 0x35, 0xa5, 0xbc, 0x0f, 0x06, 0x44, 0x63, 0x02, 0x9f, 0x42, 0x1c, - 0x35, 0x8e, 0x0f, 0xd4, 0x42, 0x3c, 0x23, 0x2e, 0xb5, 0x5a, 0x8e, 0x7d, 0x8f, 0x3a, 0xfc, 0x96, - 0x4a, 0x10, 0xeb, 0x3e, 0x50, 0x0b, 0xf1, 0x12, 0x67, 0xea, 0xdb, 0x8b, 0x32, 0x67, 0xea, 0x68, - 0x21, 0x9e, 0x5c, 0x84, 0xfe, 0x19, 0xbb, 0xae, 0xa3, 0xa0, 0xf9, 0xb4, 0x32, 0xb4, 0xb9, 0x51, - 0xec, 0x6f, 0x08, 0x98, 0x16, 0x60, 0x19, 0x65, 0xd9, 0x5e, 0xb3, 0x1a, 0xb6, 0xce, 0x9d, 0x5f, - 0xfa, 0x39, 0xa5, 0x21, 0x60, 0x5a, 0x80, 0x65, 0x94, 0x4c, 0xe6, 0xe8, 0x54, 0xd4, 0x1f, 0xf2, - 0x5c, 0x16, 0x30, 0x2d, 0xc0, 0xaa, 0x3f, 0x97, 0x67, 0xda, 0xeb, 0x9a, 0x6f, 0x3d, 0xf0, 0xeb, - 0x42, 0x38, 0x60, 0x7a, 0x77, 0x31, 0x60, 0x1e, 0x98, 0x03, 0x3b, 0xf5, 0x0f, 0xfb, 0x00, 0x84, - 0xf4, 0x27, 0x8f, 0x36, 0x87, 0x7b, 0xd3, 0x9a, 0x32, 0x8c, 0x4d, 0x5a, 0xab, 0xba, 0x55, 0xa7, - 0x46, 0x78, 0x6c, 0x59, 0xc0, 0xa1, 0x8d, 0x3e, 0xbd, 0x54, 0x20, 0xc3, 0x73, 0x4b, 0x2d, 0x59, - 0x80, 0x3c, 0x0d, 0x83, 0x15, 0xcb, 0xa3, 0x8e, 0x5e, 0xf7, 0xcc, 0x7b, 0x54, 0x4c, 0x0d, 0x78, - 0x33, 0x6c, 0x86, 0x60, 0x4d, 0xa6, 0x21, 0xd7, 0x60, 0x68, 0x41, 0x77, 0x3c, 0xb3, 0x6e, 0xb6, - 0x74, 0xcb, 0x73, 0x95, 0x7e, 0x9c, 0xd1, 0xd0, 0xc2, 0x68, 0x49, 0x70, 0x2d, 0x42, 0x45, 0x3e, - 0x06, 0x03, 0xb8, 0x35, 0x45, 0xc7, 0xe9, 0x81, 0x2d, 0x2f, 0x0e, 0x1f, 0x0b, 0xdd, 0x03, 0xf9, - 0xe9, 0x2b, 0xde, 0x00, 0xc7, 0xef, 0x0e, 0x03, 0x8e, 0xe4, 0x43, 0xd0, 0x37, 0x69, 0x19, 0xc8, - 0x1c, 0xb6, 0x64, 0xae, 0x0a, 0xe6, 0xa7, 0x42, 0xe6, 0x76, 0x2b, 0xc6, 0xdb, 0x67, 0x97, 0x3e, - 0xca, 0x06, 0xdf, 0xb9, 0x51, 0x36, 0xf4, 0x0e, 0x1c, 0x8b, 0x0f, 0xef, 0xd7, 0xb1, 0xf8, 0xc8, - 0x2e, 0x8f, 0xc5, 0xd5, 0xb7, 0x60, 0x70, 0x7c, 0x61, 0x2a, 0x18, 0xbd, 0x0f, 0x41, 0x6e, 0x41, - 0x78, 0x2a, 0xe4, 0xb9, 0x3d, 0xd3, 0x32, 0x0d, 0x8d, 0xc1, 0xc8, 0x25, 0xe8, 0x9f, 0x40, 0xf7, - 0x37, 0x71, 0x8b, 0x98, 0xe7, 0xeb, 0x5f, 0x1d, 0x61, 0xe8, 0x05, 0xeb, 0xa3, 0xc9, 0xe3, 0xd0, - 0xb7, 0xe0, 0xd8, 0x2b, 0x8e, 0xde, 0x14, 0x6b, 0x30, 0xba, 0x8a, 0xb4, 0x38, 0x48, 0xf3, 0x71, - 0xea, 0xf7, 0x65, 0x7c, 0xb3, 0x9d, 0x95, 0xa8, 0xb6, 0xf1, 0x68, 0x1e, 0xeb, 0xee, 0xe7, 0x25, - 0x5c, 0x0e, 0xd2, 0x7c, 0x1c, 0xb9, 0x04, 0xbd, 0x93, 0x8e, 0x63, 0x3b, 0xb2, 0xb3, 0x39, 0x65, - 0x00, 0xf9, 0xba, 0x17, 0x29, 0xc8, 0xf3, 0x30, 0xc8, 0xe7, 0x1c, 0x7e, 0xa2, 0x99, 0xeb, 0x76, - 0x53, 0x2a, 0x53, 0xaa, 0x5f, 0xcd, 0x49, 0x36, 0x1b, 0x97, 0xf8, 0x03, 0x78, 0x2b, 0xf0, 0x0c, - 0xe4, 0xc6, 0x17, 0xa6, 0xc4, 0x04, 0x78, 0xdc, 0x2f, 0x2a, 0xa9, 0x4a, 0xac, 0x1c, 0xa3, 0x26, - 0x67, 0x21, 0xbf, 0xc0, 0xd4, 0xa7, 0x80, 0xea, 0xd1, 0xbf, 0xb9, 0x51, 0xcc, 0xb7, 0x98, 0xfe, - 0x20, 0x14, 0xb1, 0x6c, 0x33, 0xc3, 0x77, 0x4c, 0x1c, 0x1b, 0xee, 0x63, 0xce, 0x42, 0xbe, 0xe4, - 0xac, 0xdc, 0x13, 0xb3, 0x16, 0x62, 0x75, 0x67, 0xe5, 0x9e, 0x86, 0x50, 0x72, 0x05, 0x40, 0xa3, - 0x5e, 0xdb, 0xb1, 0xf0, 0x1d, 0xc8, 0x00, 0x9e, 0xbf, 0xe1, 0x6c, 0xe8, 0x20, 0xb4, 0x56, 0xb7, - 0x0d, 0xaa, 0x49, 0x24, 0xea, 0x4f, 0x86, 0x17, 0x3b, 0x65, 0xd3, 0xbd, 0x7b, 0xd4, 0x85, 0x3b, - 0xe8, 0x42, 0x5d, 0x1c, 0x71, 0x26, 0x3b, 0xa9, 0x08, 0xbd, 0x53, 0x0d, 0x7d, 0xc5, 0xc5, 0x3e, - 0x14, 0xbe, 0x64, 0xcb, 0x0c, 0xa0, 0x71, 0x78, 0xac, 0x9f, 0xfa, 0xb7, 0xee, 0xa7, 0x2f, 0xf6, - 0x06, 0xa3, 0x6d, 0x8e, 0x7a, 0x6b, 0xb6, 0x73, 0xd4, 0x55, 0xdb, 0xed, 0xaa, 0x0b, 0xd0, 0x57, - 0x75, 0xea, 0xd2, 0xd1, 0x05, 0xee, 0x07, 0x5c, 0xa7, 0xce, 0x8f, 0x2d, 0x7c, 0x24, 0xa3, 0x2b, - 0xbb, 0x1e, 0xd2, 0xf5, 0x85, 0x74, 0x86, 0xeb, 0x09, 0x3a, 0x81, 0x14, 0x74, 0x0b, 0xb6, 0xe3, - 0x89, 0x8e, 0x0b, 0xe8, 0x5a, 0xb6, 0xe3, 0x69, 0x3e, 0x92, 0xbc, 0x0f, 0x60, 0x71, 0x62, 0xc1, - 0x77, 0xb6, 0x1f, 0x08, 0x7d, 0x01, 0x85, 0x97, 0xbd, 0x26, 0xa1, 0xc9, 0x22, 0x0c, 0xcc, 0xb7, - 0xa8, 0xc3, 0xb7, 0x42, 0xfc, 0x65, 0xc7, 0x7b, 0x63, 0xa2, 0x15, 0xfd, 0x7e, 0x59, 0xfc, 0x1f, - 0x90, 0xf3, 0xf5, 0xc5, 0xf6, 0x7f, 0x6a, 0x21, 0x23, 0xf2, 0x3c, 0x14, 0x4a, 0xdc, 0xce, 0x1b, - 0x44, 0x96, 0x81, 0xc8, 0x70, 0x0b, 0xca, 0x51, 0x7c, 0xcf, 0xae, 0xe3, 0xdf, 0x9a, 0x20, 0x57, - 0x2f, 0xc1, 0x68, 0xbc, 0x1a, 0x32, 0x08, 0x7d, 0x13, 0xf3, 0x73, 0x73, 0x93, 0x13, 0x8b, 0xa3, - 0x3d, 0xa4, 0x1f, 0xf2, 0xd5, 0xc9, 0xb9, 0xf2, 0x68, 0x46, 0xfd, 0x19, 0x69, 0x06, 0x61, 0xaa, - 0x75, 0x74, 0x35, 0xbc, 0xa7, 0xfb, 0x96, 0x51, 0xbc, 0x0f, 0xc5, 0x13, 0x83, 0xa6, 0xe9, 0x79, - 0xd4, 0x10, 0xab, 0x04, 0xde, 0x17, 0x7a, 0xf7, 0xb5, 0x04, 0x9e, 0x3c, 0x09, 0xc3, 0x08, 0x13, - 0x57, 0x84, 0x7c, 0x7f, 0x2c, 0x0a, 0x38, 0xf7, 0xb5, 0x28, 0x52, 0xfd, 0x5a, 0x78, 0x3b, 0x3c, - 0x43, 0xf5, 0xc3, 0x7a, 0xa3, 0xf8, 0x2e, 0xe9, 0x2f, 0xf5, 0x4f, 0xf2, 0xfc, 0x09, 0x08, 0x7f, - 0xb8, 0x77, 0x10, 0xa2, 0x0c, 0x8f, 0x74, 0x73, 0x3b, 0x38, 0xd2, 0x7d, 0x12, 0x0a, 0xb3, 0xd4, - 0x5b, 0xb5, 0x7d, 0xc7, 0x2f, 0xf4, 0xd0, 0x6b, 0x22, 0x44, 0xf6, 0xd0, 0xe3, 0x34, 0xe4, 0x2e, - 0x10, 0xff, 0x55, 0x5e, 0xe0, 0x88, 0xed, 0x1f, 0x21, 0x9f, 0x4e, 0xec, 0x53, 0xaa, 0xf8, 0x24, - 0x17, 0x7d, 0xec, 0x4f, 0x04, 0x8e, 0xde, 0x92, 0x27, 0xd6, 0x1f, 0x6f, 0x14, 0x0b, 0x9c, 0x46, - 0x4b, 0x61, 0x4b, 0x5e, 0x87, 0x81, 0xd9, 0xa9, 0x92, 0x78, 0xa1, 0xc7, 0xbd, 0x22, 0x1e, 0x0a, - 0xa4, 0xe8, 0x23, 0x02, 0x91, 0xe0, 0x7b, 0x9b, 0xe6, 0xb2, 0x9e, 0x7c, 0xa0, 0x17, 0x72, 0x61, - 0xda, 0xc2, 0x5f, 0xee, 0x88, 0xd3, 0x85, 0x40, 0x5b, 0xa2, 0xef, 0x79, 0xe2, 0xb2, 0xe2, 0xd8, - 0x98, 0xb6, 0xf4, 0xef, 0x61, 0x74, 0xcf, 0xc3, 0x58, 0xa9, 0xd5, 0x6a, 0x98, 0xd4, 0x40, 0x7d, - 0xd1, 0xda, 0x0d, 0xea, 0x0a, 0x97, 0x1f, 0x7c, 0x0c, 0xa2, 0x73, 0x64, 0x0d, 0xdf, 0x85, 0xd6, - 0x9c, 0x76, 0xd4, 0x3f, 0x33, 0x59, 0x56, 0xfd, 0x81, 0x2c, 0x9c, 0x9a, 0x70, 0xa8, 0xee, 0xd1, - 0xd9, 0xa9, 0x52, 0xa9, 0x8d, 0x3e, 0x72, 0x8d, 0x06, 0xb5, 0x56, 0x0e, 0x66, 0x58, 0xbf, 0x04, - 0x23, 0x41, 0x03, 0xaa, 0x75, 0xbb, 0x45, 0xe5, 0x87, 0x55, 0x75, 0x1f, 0x53, 0x73, 0x19, 0x4a, - 0x8b, 0x91, 0x92, 0x9b, 0x70, 0x3c, 0x80, 0x94, 0x1a, 0x0d, 0x7b, 0x4d, 0xa3, 0x6d, 0x97, 0x3b, - 0xc6, 0xf6, 0x73, 0xc7, 0xd8, 0x90, 0x83, 0xce, 0xf0, 0x35, 0x87, 0x11, 0x68, 0x69, 0xa5, 0xd4, - 0x2f, 0xe5, 0xe0, 0xf4, 0x6d, 0xbd, 0x61, 0x1a, 0xa1, 0x68, 0x34, 0xea, 0xb6, 0x6c, 0xcb, 0xa5, - 0x87, 0x68, 0x94, 0x46, 0x86, 0x42, 0x7e, 0x5f, 0x86, 0x42, 0xb2, 0x8b, 0x7a, 0xf7, 0xdc, 0x45, - 0x85, 0x5d, 0x75, 0xd1, 0x7f, 0xce, 0xc0, 0xa8, 0xef, 0xf8, 0x2f, 0xbf, 0xa6, 0x96, 0xbc, 0xd2, - 0xf1, 0x08, 0x31, 0xe6, 0x07, 0x8d, 0x78, 0x52, 0x85, 0xbe, 0xc9, 0xfb, 0x2d, 0xd3, 0xa1, 0xee, - 0x36, 0x9c, 0xb8, 0xcf, 0x89, 0xe3, 0x92, 0x31, 0xca, 0x8b, 0x24, 0x4e, 0x4a, 0x38, 0x18, 0x9f, - 0xf3, 0xf1, 0xa7, 0x0f, 0xe3, 0xfe, 0x13, 0x71, 0xfe, 0x9c, 0x4f, 0x3c, 0x91, 0x88, 0xbc, 0xcf, - 0x0c, 0x49, 0xc9, 0x63, 0x90, 0x5b, 0x5c, 0x9c, 0x11, 0x33, 0x29, 0x3e, 0xcd, 0xf7, 0x3c, 0xf9, - 0xbd, 0x22, 0xc3, 0xaa, 0xbf, 0x9b, 0x05, 0x60, 0xaa, 0xc0, 0x87, 0xeb, 0x81, 0x28, 0xe1, 0x38, - 0xf4, 0xfb, 0x02, 0x17, 0x6a, 0x18, 0x78, 0xed, 0xc7, 0x3b, 0x22, 0x5e, 0x77, 0xf0, 0x42, 0xa3, - 0xe8, 0x3b, 0x92, 0xf3, 0x7b, 0x00, 0xdc, 0xd9, 0xa0, 0x23, 0xb9, 0xef, 0x3e, 0xfe, 0x3e, 0x18, - 0x10, 0x33, 0x9e, 0x1d, 0x39, 0xff, 0xaf, 0xfb, 0x40, 0x2d, 0xc4, 0xc7, 0xa6, 0xd6, 0xc2, 0x1e, - 0x16, 0x62, 0x5f, 0xbc, 0xbc, 0x57, 0x8e, 0xc4, 0xbb, 0xcf, 0xe2, 0xfd, 0x9c, 0x10, 0x2f, 0x7f, - 0xc1, 0x73, 0x68, 0xc5, 0xbb, 0x6f, 0x67, 0xdf, 0xea, 0x6f, 0x65, 0x80, 0xb0, 0x66, 0x2d, 0xe8, - 0xae, 0xbb, 0x66, 0x3b, 0x06, 0x77, 0x4e, 0x3f, 0x10, 0xc1, 0xec, 0xdf, 0x7d, 0xe5, 0x57, 0xfb, - 0xe1, 0x78, 0xc4, 0xf1, 0xf7, 0x90, 0x4f, 0x56, 0x97, 0xa2, 0xa3, 0xa9, 0xdb, 0xab, 0x97, 0xf7, - 0xc8, 0x17, 0xa2, 0xbd, 0x91, 0x07, 0x68, 0xd2, 0x4d, 0xe8, 0x53, 0x30, 0x24, 0x7e, 0xb0, 0x15, - 0xda, 0xbf, 0xe9, 0xc2, 0x51, 0xea, 0x32, 0x80, 0x16, 0x41, 0x93, 0x67, 0x61, 0x80, 0x0d, 0x98, - 0x15, 0x8c, 0xe2, 0xd1, 0x17, 0xbe, 0x28, 0x31, 0x7c, 0xa0, 0xbc, 0x9e, 0x04, 0x94, 0xd2, 0x3b, - 0xa2, 0xfe, 0x6d, 0xbc, 0x23, 0xfa, 0x38, 0x0c, 0x96, 0x2c, 0xcb, 0xf6, 0x70, 0x93, 0xee, 0x8a, - 0xab, 0x89, 0x8e, 0x56, 0xf9, 0x63, 0xf8, 0x38, 0x3e, 0xa4, 0x4f, 0x35, 0xcb, 0x65, 0x86, 0xe4, - 0xaa, 0xff, 0x2a, 0x86, 0x3a, 0xc2, 0xab, 0x1c, 0xaf, 0x67, 0x1c, 0x01, 0x4b, 0x3e, 0x8a, 0xc1, - 0xce, 0x1b, 0x5e, 0x70, 0xec, 0x96, 0xed, 0x52, 0x83, 0x0b, 0x6a, 0x30, 0x0c, 0x35, 0xd0, 0x12, - 0x08, 0x7c, 0xc7, 0x16, 0x89, 0xa8, 0x11, 0x29, 0x42, 0x96, 0xe1, 0x84, 0x7f, 0x51, 0x1c, 0xbc, - 0x18, 0xac, 0x94, 0x5d, 0x65, 0x08, 0x5f, 0x25, 0x91, 0xb8, 0x32, 0x54, 0xca, 0xe3, 0xe7, 0xfd, - 0x6b, 0x11, 0xff, 0xc9, 0x61, 0xcd, 0x34, 0xe4, 0xae, 0x4e, 0xe5, 0x47, 0xbe, 0x0d, 0x06, 0x67, - 0xf5, 0xfb, 0xe5, 0xb6, 0x38, 0x7b, 0x19, 0xde, 0xfe, 0xed, 0x4b, 0x53, 0xbf, 0x5f, 0x33, 0x44, - 0xb9, 0x98, 0x4d, 0x21, 0xb3, 0x24, 0x35, 0x38, 0xb5, 0xe0, 0xd8, 0x4d, 0xdb, 0xa3, 0x46, 0xec, - 0xf1, 0xdd, 0xb1, 0xf0, 0xb5, 0x6e, 0x4b, 0x50, 0xd4, 0xba, 0xbc, 0xc2, 0xeb, 0xc0, 0x86, 0x34, - 0xe1, 0x58, 0xc9, 0x75, 0xdb, 0x4d, 0x1a, 0xde, 0x50, 0x8d, 0x6e, 0xf9, 0x19, 0xef, 0x15, 0x5e, - 0xcb, 0x0f, 0xeb, 0x58, 0x94, 0x5f, 0x50, 0xd5, 0x3c, 0x53, 0xae, 0x11, 0xbf, 0x25, 0xce, 0xfb, - 0x46, 0xbe, 0x7f, 0x64, 0xf4, 0x98, 0x76, 0x3a, 0xd9, 0x98, 0x45, 0xd3, 0x6b, 0x50, 0xf5, 0x2b, - 0x19, 0x80, 0x50, 0xc0, 0xe4, 0xa9, 0x68, 0xa8, 0xa0, 0x4c, 0x78, 0xd1, 0x21, 0xa2, 0x17, 0x44, - 0x62, 0x03, 0x91, 0xb3, 0x90, 0xc7, 0x08, 0x17, 0xd9, 0xf0, 0x60, 0xf5, 0xae, 0x69, 0x19, 0x1a, - 0x42, 0x19, 0x56, 0x7a, 0x8a, 0x8e, 0x58, 0xbc, 0xd4, 0xe7, 0x56, 0x61, 0x19, 0x8e, 0x55, 0xdb, - 0x4b, 0x7e, 0xdd, 0xd2, 0xbb, 0x3a, 0x0c, 0xb4, 0xe1, 0xb6, 0x97, 0x82, 0xc7, 0xa8, 0x91, 0x30, - 0x26, 0xd1, 0x22, 0xea, 0xcf, 0x65, 0x62, 0xb3, 0xe0, 0x01, 0x2e, 0x7a, 0xef, 0x49, 0xfa, 0x69, - 0x24, 0xa7, 0x25, 0xf5, 0x47, 0xb3, 0x30, 0xb8, 0x60, 0x3b, 0x9e, 0x08, 0x19, 0x72, 0xb8, 0x57, - 0x21, 0x69, 0xaf, 0x94, 0xdf, 0xc1, 0x5e, 0xe9, 0x2c, 0xe4, 0x25, 0x17, 0x65, 0x7e, 0x2f, 0x62, - 0x18, 0x8e, 0x86, 0x50, 0xf5, 0xdb, 0xb3, 0x00, 0x1f, 0x7a, 0xfa, 0xe9, 0x07, 0x58, 0x40, 0xea, - 0x0f, 0x67, 0xe0, 0x98, 0xb8, 0xa8, 0x93, 0x82, 0x6e, 0xf5, 0xf9, 0x57, 0xac, 0xf2, 0xb8, 0xe4, - 0x20, 0xcd, 0xc7, 0xb1, 0x25, 0x60, 0xf2, 0xbe, 0xe9, 0xe1, 0x5d, 0x85, 0x14, 0x75, 0x8b, 0x0a, - 0x98, 0xbc, 0x04, 0xf8, 0x74, 0xe4, 0x29, 0xff, 0x0a, 0x32, 0x17, 0xae, 0x7b, 0xac, 0xc0, 0x64, - 0xea, 0x35, 0xa4, 0xfa, 0x0b, 0x79, 0xc8, 0x4f, 0xde, 0xa7, 0xf5, 0x43, 0xde, 0x35, 0xd2, 0xc1, - 0x66, 0x7e, 0x8f, 0x07, 0x9b, 0xbb, 0xf1, 0xa9, 0x78, 0x35, 0xec, 0xcf, 0x42, 0xb4, 0xfa, 0x58, - 0xcf, 0xc7, 0xab, 0xf7, 0x7b, 0xfa, 0xf0, 0xb9, 0xe4, 0xfc, 0x93, 0x1c, 0xe4, 0xaa, 0x13, 0x0b, - 0x47, 0x7a, 0x73, 0xa0, 0x7a, 0xd3, 0xfd, 0xce, 0x5a, 0x0d, 0xae, 0xa1, 0xfa, 0x43, 0x2f, 0xd1, - 0xd8, 0x8d, 0xd3, 0x37, 0x73, 0x30, 0x52, 0x9d, 0x5a, 0x5c, 0x90, 0x4e, 0x82, 0x6f, 0x72, 0x4f, - 0x3e, 0xf4, 0x29, 0xe3, 0x5d, 0x7a, 0x36, 0x61, 0xcf, 0xdc, 0xaa, 0x58, 0xde, 0x73, 0xd7, 0x6e, - 0xeb, 0x8d, 0x36, 0xc5, 0xa3, 0x17, 0xee, 0xf7, 0xeb, 0x9a, 0x6f, 0xd1, 0x2f, 0xe1, 0xc3, 0x7f, - 0x9f, 0x01, 0x79, 0x09, 0x72, 0xb7, 0x84, 0x47, 0x46, 0x27, 0x3e, 0xcf, 0x5c, 0xe5, 0x7c, 0xd8, - 0x24, 0x98, 0x6b, 0x9b, 0x06, 0x72, 0x60, 0xa5, 0x58, 0xe1, 0xeb, 0x62, 0x01, 0xde, 0x56, 0xe1, - 0x15, 0xbf, 0xf0, 0xf5, 0x4a, 0x99, 0x54, 0x61, 0x70, 0x81, 0x3a, 0x4d, 0x13, 0x3b, 0xca, 0x9f, - 0xb3, 0xbb, 0x33, 0x61, 0x3b, 0x95, 0xc1, 0x56, 0x58, 0x08, 0x99, 0xc9, 0x5c, 0xc8, 0x1b, 0x00, - 0xdc, 0x46, 0xd9, 0x66, 0x20, 0xc7, 0x73, 0x68, 0xf7, 0x73, 0xd3, 0x32, 0xc5, 0xc6, 0x93, 0x98, - 0x91, 0xbb, 0x30, 0x3a, 0x6b, 0x1b, 0xe6, 0xb2, 0xc9, 0x5d, 0x2f, 0xb1, 0x82, 0xc2, 0xd6, 0x0e, - 0x4f, 0xcc, 0x94, 0x6c, 0x4a, 0xe5, 0xd2, 0xaa, 0x49, 0x30, 0x56, 0xff, 0x61, 0x2f, 0xe4, 0x59, - 0xb7, 0x1f, 0x8d, 0xdf, 0xbd, 0x8c, 0xdf, 0x12, 0x8c, 0xde, 0xb1, 0x9d, 0xbb, 0xa6, 0xb5, 0x12, - 0x78, 0xc5, 0x8b, 0xbd, 0x29, 0x7a, 0xf2, 0xac, 0x71, 0x5c, 0x2d, 0x70, 0xa0, 0xd7, 0x12, 0xe4, - 0x5b, 0x8c, 0xe0, 0x17, 0x00, 0xf8, 0x5b, 0x77, 0xa4, 0xe9, 0x0f, 0x83, 0x55, 0xf0, 0x97, 0xf0, - 0xe8, 0x68, 0x2f, 0x07, 0xab, 0x08, 0x89, 0xd9, 0x26, 0x9c, 0xfb, 0x42, 0x0c, 0xa0, 0xdf, 0x3d, - 0x6e, 0xc2, 0xd1, 0x17, 0x42, 0x36, 0x02, 0xb8, 0x57, 0xc4, 0x02, 0x80, 0x74, 0xbf, 0x04, 0x31, - 0x41, 0x44, 0x26, 0x07, 0x11, 0x1e, 0x2e, 0xe5, 0x7a, 0x49, 0x93, 0x78, 0x90, 0xe7, 0x62, 0x17, - 0xe0, 0x24, 0xc2, 0xad, 0xe3, 0xfd, 0x77, 0xe8, 0x40, 0x35, 0xb4, 0x95, 0x03, 0x95, 0xfa, 0x99, - 0x2c, 0x0c, 0x54, 0xdb, 0x4b, 0xee, 0xba, 0xeb, 0xd1, 0xe6, 0x21, 0x57, 0x63, 0x7f, 0x7b, 0x95, - 0x4f, 0xdd, 0x5e, 0x3d, 0xe6, 0x0b, 0x45, 0x3a, 0x77, 0x0c, 0x4c, 0x3a, 0x5f, 0x1c, 0x7f, 0x27, - 0x0b, 0xa3, 0xfc, 0xe2, 0xac, 0x6c, 0xba, 0xf5, 0x7d, 0x70, 0xe6, 0x3f, 0x78, 0xa9, 0xec, 0xed, - 0xb2, 0x79, 0x1b, 0x4f, 0x24, 0xd4, 0x4f, 0x66, 0x61, 0xb0, 0xd4, 0xf6, 0x56, 0x4b, 0x1e, 0xea, - 0xd6, 0x03, 0xb9, 0x3f, 0xf9, 0xb5, 0x0c, 0x1c, 0x63, 0x0d, 0x59, 0xb4, 0xef, 0x52, 0x6b, 0x1f, - 0x0e, 0x1e, 0xe5, 0x03, 0xc4, 0xec, 0x2e, 0x0f, 0x10, 0x7d, 0x59, 0xe6, 0x76, 0x26, 0x4b, 0x3c, - 0x2e, 0xd7, 0xec, 0x06, 0x3d, 0xdc, 0x9f, 0xb1, 0x8f, 0xc7, 0xe5, 0xbe, 0x40, 0xf6, 0xe1, 0x7a, - 0xe6, 0x5b, 0x4b, 0x20, 0xfb, 0x70, 0xb6, 0xf4, 0xad, 0x21, 0x90, 0xaf, 0x66, 0x60, 0x60, 0xdc, - 0xf6, 0x0e, 0xf9, 0xc0, 0x17, 0x5f, 0x71, 0xb8, 0xd5, 0xdc, 0xff, 0x8a, 0xc3, 0xad, 0x9b, 0xea, - 0x0f, 0x66, 0xe1, 0x84, 0x08, 0xd2, 0x2d, 0xce, 0x1f, 0x8e, 0xa6, 0x63, 0x31, 0xd8, 0x92, 0xa2, - 0x39, 0x9a, 0x87, 0x84, 0x68, 0x7e, 0x2a, 0x07, 0x27, 0x30, 0x94, 0x29, 0xdb, 0x96, 0x7d, 0x0b, - 0xd8, 0x22, 0xa4, 0x1e, 0xbd, 0x04, 0x9d, 0x4d, 0xb9, 0x04, 0xfd, 0xe3, 0x8d, 0xe2, 0x73, 0x2b, - 0xa6, 0xb7, 0xda, 0x5e, 0xba, 0x5c, 0xb7, 0x9b, 0x57, 0x56, 0x1c, 0xfd, 0x9e, 0xc9, 0xaf, 0xff, - 0xf4, 0xc6, 0x95, 0x20, 0xdf, 0x85, 0xde, 0x32, 0x45, 0x26, 0x8c, 0x2a, 0xee, 0x75, 0x18, 0x57, - 0xff, 0xfa, 0xd4, 0x05, 0xb8, 0x61, 0x9b, 0x96, 0xf0, 0x29, 0xe4, 0x86, 0x6e, 0x95, 0xed, 0x0f, - 0xdf, 0xb4, 0x4d, 0xab, 0x16, 0x77, 0x2c, 0xdc, 0x69, 0x7d, 0x21, 0x6b, 0x4d, 0xaa, 0x46, 0xfd, - 0x97, 0x19, 0x78, 0x28, 0xaa, 0xc5, 0xdf, 0x0a, 0xb6, 0xe3, 0x0f, 0x65, 0xe1, 0xe4, 0x75, 0x14, - 0x4e, 0xe0, 0xc8, 0x71, 0x34, 0x6f, 0x89, 0xc1, 0x99, 0x22, 0x9b, 0x23, 0x8b, 0xb2, 0xb3, 0x6c, - 0x8e, 0x26, 0x75, 0x21, 0x9b, 0x5f, 0xcf, 0xc0, 0xf1, 0xf9, 0x4a, 0x79, 0xe2, 0x5b, 0x64, 0x44, - 0x25, 0xbf, 0xe7, 0x90, 0x1b, 0x9c, 0x89, 0xef, 0x39, 0xe4, 0xa6, 0xe7, 0x17, 0xb2, 0x70, 0xbc, - 0x5a, 0x9a, 0x9d, 0xf9, 0x56, 0x99, 0xc1, 0x27, 0x64, 0xaf, 0x43, 0xff, 0x10, 0x4c, 0xd8, 0x02, - 0xf2, 0x67, 0xde, 0xbe, 0xda, 0xd9, 0x1b, 0x31, 0x29, 0x94, 0x43, 0x3e, 0x75, 0xef, 0x8b, 0x50, - 0x98, 0xe6, 0x47, 0xa8, 0x0f, 0xb9, 0xe6, 0xff, 0xe3, 0x02, 0x0c, 0xde, 0x6c, 0x2f, 0x51, 0xe1, - 0x9c, 0xf2, 0x40, 0x9f, 0xfc, 0x5e, 0x85, 0x41, 0x21, 0x06, 0xbc, 0x35, 0x91, 0x82, 0xe7, 0x89, - 0x60, 0x28, 0x3c, 0x3e, 0x91, 0x4c, 0x44, 0xce, 0x42, 0xfe, 0x36, 0x75, 0x96, 0xe4, 0x77, 0xa5, - 0xf7, 0xa8, 0xb3, 0xa4, 0x21, 0x94, 0xcc, 0x84, 0x2e, 0xf3, 0xa5, 0x85, 0x0a, 0x26, 0x52, 0x11, - 0x17, 0x36, 0x98, 0x19, 0x26, 0xf0, 0x7b, 0xd3, 0x5b, 0x26, 0x4f, 0xc1, 0x22, 0xbf, 0x69, 0x8f, - 0x97, 0x24, 0x73, 0x30, 0x26, 0x3b, 0x3e, 0xf1, 0x2c, 0x22, 0xfd, 0x29, 0xec, 0xd2, 0xf2, 0x87, - 0x24, 0x8b, 0x92, 0x57, 0x61, 0xc8, 0x07, 0xa2, 0x0b, 0xd7, 0x40, 0x18, 0xba, 0x3e, 0x60, 0x15, - 0x4b, 0x51, 0x14, 0x29, 0x20, 0x33, 0xc0, 0x6b, 0x08, 0x48, 0x61, 0x10, 0x73, 0x89, 0x8b, 0x14, - 0x20, 0xcf, 0x22, 0x03, 0x7c, 0xe6, 0x81, 0xce, 0x2a, 0x83, 0xf8, 0xe8, 0x12, 0x5d, 0xf2, 0x1d, - 0x01, 0xe7, 0x4f, 0x6b, 0x23, 0x64, 0x64, 0x1e, 0x20, 0x74, 0x2a, 0x10, 0x01, 0x0c, 0x76, 0xec, - 0xee, 0x20, 0xb1, 0x90, 0xaf, 0x03, 0x87, 0x77, 0x73, 0x1d, 0xa8, 0xfe, 0x66, 0x16, 0x06, 0x4b, - 0xad, 0x56, 0x30, 0x14, 0x9e, 0x82, 0x42, 0xa9, 0xd5, 0xba, 0xa5, 0x55, 0xe4, 0x50, 0xe6, 0x7a, - 0xab, 0x55, 0x6b, 0x3b, 0xa6, 0xec, 0x13, 0xca, 0x89, 0xc8, 0x04, 0x0c, 0x97, 0x5a, 0xad, 0x85, - 0xf6, 0x52, 0xc3, 0xac, 0x4b, 0x99, 0x91, 0x78, 0x12, 0xb7, 0x56, 0xab, 0xd6, 0x42, 0x4c, 0x3c, - 0x3d, 0x56, 0xb4, 0x0c, 0xf9, 0x38, 0x86, 0xfd, 0x11, 0x89, 0x79, 0x78, 0xea, 0x0f, 0x35, 0x08, - 0x62, 0x1e, 0xb6, 0xed, 0x72, 0x40, 0xc4, 0x83, 0xbd, 0x9f, 0xf5, 0x43, 0xe6, 0xb3, 0x8a, 0x12, - 0x09, 0x78, 0x42, 0x96, 0xe4, 0xfd, 0xd0, 0x57, 0x6a, 0xb5, 0xa4, 0xfb, 0x26, 0x74, 0x2a, 0x62, - 0xa5, 0x62, 0x7d, 0xec, 0x93, 0x9d, 0x79, 0x19, 0x46, 0xa2, 0x95, 0xed, 0x28, 0x58, 0xfc, 0x1f, - 0x65, 0xf0, 0x83, 0x0e, 0xb9, 0x4f, 0xf3, 0x33, 0x90, 0x2b, 0xb5, 0x5a, 0x62, 0x3e, 0x3a, 0x9e, - 0xd2, 0x1f, 0xf1, 0x27, 0xd0, 0xa5, 0x56, 0xcb, 0xff, 0xf4, 0x43, 0xfe, 0x38, 0x62, 0x57, 0x9f, - 0xfe, 0x55, 0xfe, 0xe9, 0x87, 0xfb, 0xe1, 0x82, 0xfa, 0x0b, 0x39, 0x38, 0x56, 0x6a, 0xb5, 0x8e, - 0x82, 0xcc, 0xef, 0xd7, 0x43, 0xeb, 0xa7, 0x01, 0xa4, 0xe9, 0xb1, 0x2f, 0x78, 0xba, 0x35, 0x28, - 0x4d, 0x8d, 0x4a, 0x46, 0x93, 0x88, 0x7c, 0xf5, 0xeb, 0xdf, 0x91, 0xfa, 0x7d, 0x32, 0x87, 0x53, - 0xf1, 0x61, 0x0f, 0x1a, 0xf5, 0x6e, 0xe9, 0x36, 0xd1, 0x07, 0x85, 0x1d, 0xf5, 0xc1, 0xaf, 0x46, - 0x06, 0x0f, 0x06, 0x2d, 0x3f, 0xea, 0x85, 0xde, 0x3d, 0x99, 0xc5, 0x23, 0xb2, 0x30, 0x45, 0x24, - 0x1b, 0x3f, 0x91, 0x92, 0x88, 0xab, 0x54, 0x67, 0xa8, 0x9a, 0x69, 0x68, 0x31, 0x5a, 0xbf, 0x0f, - 0xfb, 0x76, 0xd4, 0x87, 0x1b, 0x59, 0x7c, 0x3b, 0x1d, 0xc4, 0x65, 0xda, 0xfb, 0xee, 0xe2, 0x0a, - 0x00, 0xf7, 0x3c, 0x08, 0xdc, 0x9a, 0x87, 0x79, 0x08, 0x16, 0x9e, 0x5f, 0x49, 0x84, 0x60, 0x09, - 0x49, 0x02, 0x0f, 0xa9, 0x5c, 0xaa, 0x87, 0xd4, 0x25, 0xe8, 0xd7, 0xf4, 0xb5, 0xd7, 0xdb, 0xd4, - 0x59, 0x17, 0xe6, 0x0c, 0x0f, 0x7b, 0xa8, 0xaf, 0xd5, 0x3e, 0xc1, 0x80, 0x5a, 0x80, 0x26, 0x6a, - 0xf0, 0xf8, 0x5e, 0xf2, 0x08, 0xe1, 0x67, 0xe4, 0xc1, 0x93, 0xfb, 0xdd, 0x28, 0x3a, 0x79, 0x11, - 0x72, 0xa5, 0x3b, 0x55, 0x21, 0xd9, 0xa0, 0x6b, 0x4b, 0x77, 0xaa, 0x42, 0x5e, 0x1d, 0xcb, 0xde, - 0xa9, 0xaa, 0x9f, 0xcc, 0x02, 0x49, 0x52, 0x92, 0xe7, 0x60, 0x00, 0xa1, 0x2b, 0x4c, 0x67, 0xe4, - 0xc4, 0x9c, 0x6b, 0x6e, 0xcd, 0x41, 0x68, 0xc4, 0xb8, 0xf3, 0x49, 0xc9, 0x0b, 0x98, 0x83, 0x58, - 0xa4, 0x86, 0x8b, 0x24, 0xe6, 0x5c, 0x73, 0xfd, 0xac, 0xbd, 0xb1, 0x14, 0xc4, 0x82, 0x18, 0xed, - 0xc2, 0x3b, 0xd5, 0x69, 0xdb, 0xf5, 0x84, 0xa8, 0xb9, 0x5d, 0xb8, 0xe6, 0x62, 0x46, 0xd8, 0x88, - 0x5d, 0xc8, 0xc9, 0x30, 0xab, 0xd5, 0x9d, 0x2a, 0x7f, 0xa6, 0x62, 0x68, 0x76, 0xc3, 0x37, 0x28, - 0x79, 0x56, 0xab, 0x35, 0xb7, 0xc6, 0x9f, 0xb8, 0x18, 0x98, 0xfc, 0x38, 0x92, 0xd5, 0x2a, 0x52, - 0x4a, 0xfd, 0x6c, 0x3f, 0x8c, 0x96, 0x75, 0x4f, 0x5f, 0xd2, 0x5d, 0x2a, 0xed, 0xa6, 0x8f, 0xf9, - 0x30, 0xff, 0x73, 0x24, 0x39, 0x18, 0x4b, 0x29, 0x5f, 0x13, 0x2f, 0x40, 0x5e, 0x0a, 0xf9, 0x06, - 0x39, 0x47, 0xe5, 0x24, 0x66, 0x4b, 0xb5, 0x96, 0x00, 0x6b, 0x09, 0x42, 0xf2, 0x24, 0x0c, 0xfa, - 0x30, 0xb6, 0x01, 0xc8, 0x85, 0x3a, 0x63, 0x2c, 0x31, 0xfb, 0x5f, 0x93, 0xd1, 0xe4, 0x05, 0x18, - 0xf2, 0x7f, 0x4a, 0xa6, 0x35, 0xcf, 0xc8, 0xb6, 0x94, 0xd8, 0x3d, 0xc9, 0xa4, 0x72, 0x51, 0x9c, - 0xdf, 0x7a, 0x23, 0x45, 0x63, 0x49, 0xcf, 0x22, 0xa4, 0xe4, 0x13, 0x30, 0xe2, 0xff, 0x16, 0x1b, - 0x06, 0x9e, 0x1f, 0xee, 0xc9, 0x20, 0xb7, 0x72, 0x4c, 0xac, 0x97, 0xa3, 0xe4, 0x7c, 0xeb, 0xf0, - 0xb0, 0x9f, 0xc7, 0xcb, 0x58, 0x4a, 0xee, 0x1c, 0x62, 0x15, 0x90, 0x0a, 0x8c, 0xf9, 0x90, 0x50, - 0x43, 0xfb, 0xc2, 0x1d, 0xa3, 0xb1, 0x54, 0x4b, 0x55, 0xd2, 0x64, 0x29, 0xd2, 0x80, 0xb3, 0x11, - 0xa0, 0xe1, 0xae, 0x9a, 0xcb, 0x9e, 0xd8, 0xee, 0x89, 0x18, 0xc4, 0x22, 0x71, 0x63, 0xc0, 0x95, - 0xd3, 0xf8, 0x19, 0x58, 0xa3, 0xd9, 0xa1, 0xba, 0x72, 0x23, 0x55, 0x38, 0xe1, 0xe3, 0xaf, 0x4f, - 0x2c, 0x2c, 0x38, 0xf6, 0x9b, 0xb4, 0xee, 0x55, 0xca, 0x62, 0xbb, 0x8c, 0xb1, 0xe9, 0x8c, 0xa5, - 0xda, 0x4a, 0xbd, 0xc5, 0x94, 0x82, 0xe1, 0xa2, 0xcc, 0x53, 0x0b, 0x93, 0xdb, 0x70, 0x52, 0x82, - 0x57, 0x2c, 0xd7, 0xd3, 0xad, 0x3a, 0xad, 0x94, 0xc5, 0x1e, 0x1a, 0xf7, 0xf3, 0x82, 0xab, 0x29, - 0x90, 0x51, 0xb6, 0xe9, 0xc5, 0xc9, 0xcb, 0x30, 0xec, 0x23, 0xf8, 0x2d, 0xe2, 0x20, 0xde, 0x22, - 0xe2, 0x90, 0x34, 0x96, 0x6a, 0xf1, 0xd7, 0x94, 0x51, 0x62, 0x59, 0xa3, 0x30, 0xb5, 0xfd, 0x50, - 0x44, 0xa3, 0xbc, 0xf5, 0x56, 0xaa, 0x32, 0x62, 0xba, 0xfb, 0x57, 0x43, 0x8d, 0x9a, 0x77, 0xcc, - 0x15, 0x93, 0xef, 0xa4, 0xfd, 0x07, 0x94, 0x4b, 0x35, 0x1b, 0x81, 0x69, 0xfa, 0xc1, 0xc9, 0xcf, - 0x94, 0xe0, 0x78, 0x8a, 0x8e, 0xed, 0x68, 0xc7, 0xf8, 0x99, 0x6c, 0xd8, 0x88, 0x43, 0xbe, 0x6d, - 0x1c, 0x87, 0x7e, 0xff, 0x4b, 0x84, 0xf1, 0xa0, 0x74, 0x1a, 0x9a, 0x71, 0x1e, 0x3e, 0x3e, 0x22, - 0x8e, 0x43, 0xbe, 0x95, 0xdc, 0x0f, 0x71, 0xbc, 0x9d, 0x09, 0xc5, 0x71, 0xc8, 0xb7, 0x97, 0xbf, - 0x9e, 0x0b, 0xe7, 0xa4, 0xa3, 0x3d, 0xe6, 0x7e, 0x99, 0xc9, 0xa1, 0x1f, 0x6c, 0x61, 0x07, 0x0f, - 0x19, 0x65, 0xd5, 0xec, 0xdb, 0xa5, 0x6a, 0xfe, 0x76, 0xb2, 0x3f, 0xb9, 0xe9, 0x79, 0x28, 0xfb, - 0x73, 0x1f, 0x06, 0x2b, 0xb9, 0x1a, 0xae, 0x63, 0xdc, 0x46, 0xef, 0x95, 0x42, 0xfc, 0x2d, 0x09, - 0x13, 0x3d, 0x4a, 0x42, 0x3e, 0x02, 0xa7, 0x23, 0x80, 0x05, 0xdd, 0xd1, 0x9b, 0xd4, 0x0b, 0x33, - 0x0e, 0x62, 0xd0, 0x26, 0xbf, 0x74, 0xad, 0x15, 0xa0, 0xe5, 0x2c, 0x86, 0x1d, 0x38, 0x48, 0xca, - 0xd1, 0xb7, 0x03, 0x27, 0xe9, 0x2f, 0xe6, 0x42, 0x53, 0x25, 0x1a, 0x7c, 0x55, 0xa3, 0x6e, 0xbb, - 0xe1, 0x3d, 0xb8, 0x1d, 0xbc, 0xbb, 0xd4, 0x16, 0xd3, 0x70, 0xac, 0xb4, 0xbc, 0x4c, 0xeb, 0x9e, - 0x1f, 0x53, 0xda, 0x15, 0xe1, 0xf6, 0xf8, 0xd6, 0x41, 0xa0, 0x44, 0x8c, 0xe0, 0x48, 0x6e, 0xfc, - 0x58, 0x31, 0xf5, 0x77, 0xf2, 0xa0, 0x04, 0xa6, 0x7b, 0xf0, 0x50, 0xeb, 0x00, 0x97, 0xc9, 0x77, - 0x45, 0xaf, 0x98, 0x30, 0x16, 0x0a, 0xa3, 0xda, 0x6e, 0x36, 0x75, 0x1c, 0x7a, 0x6c, 0x6b, 0x50, - 0x8c, 0x33, 0x0b, 0x09, 0xf9, 0x6e, 0xe0, 0x8c, 0xd8, 0x0d, 0x90, 0xf0, 0x21, 0x5c, 0xcd, 0xe5, - 0x2c, 0xb4, 0x24, 0x57, 0xf2, 0xb9, 0x0c, 0x9c, 0xf0, 0x3b, 0x65, 0x7e, 0x89, 0x99, 0xc5, 0x13, - 0x76, 0xdb, 0xf2, 0xfc, 0x9d, 0xc8, 0x8b, 0x9d, 0xab, 0xe3, 0x9d, 0x74, 0x39, 0xad, 0x30, 0x6f, - 0x49, 0x10, 0x58, 0x22, 0x50, 0x08, 0x1b, 0x69, 0x6a, 0x75, 0x24, 0xd2, 0x52, 0xeb, 0x3d, 0x73, - 0x1d, 0x1e, 0xea, 0xc8, 0x72, 0x2b, 0x33, 0xb4, 0x57, 0x36, 0x43, 0xff, 0x75, 0x26, 0x9c, 0x88, - 0x62, 0x42, 0x22, 0x97, 0x01, 0x42, 0x90, 0xd8, 0x98, 0x8e, 0x6c, 0x6e, 0x14, 0x21, 0x14, 0x9a, - 0x26, 0x51, 0x90, 0x79, 0x28, 0x08, 0xb1, 0xf0, 0xec, 0xbe, 0xef, 0xdb, 0xa2, 0x17, 0x2e, 0xcb, - 0x72, 0xc0, 0x4d, 0xa7, 0xf8, 0x66, 0xc1, 0xe6, 0xcc, 0x0b, 0x30, 0xb8, 0xdb, 0xef, 0xfa, 0x5c, - 0x0e, 0x88, 0xbc, 0x8b, 0x3c, 0x40, 0x13, 0xfb, 0x10, 0x4f, 0x61, 0x17, 0xa1, 0x9f, 0x7d, 0x02, - 0xe6, 0xbb, 0x90, 0xe2, 0xdb, 0xb6, 0x05, 0x4c, 0x0b, 0xb0, 0x61, 0x70, 0xa9, 0xbe, 0xf4, 0xe0, - 0x52, 0xea, 0xf7, 0xe7, 0xe0, 0x94, 0xdc, 0x21, 0x65, 0x8a, 0x21, 0xf3, 0x8f, 0x3a, 0xe5, 0x1d, - 0xec, 0x14, 0x15, 0x0a, 0x7c, 0xf3, 0x20, 0x72, 0x17, 0xf0, 0x83, 0x1d, 0x84, 0x68, 0x02, 0xa3, - 0xfe, 0x87, 0x2c, 0x0c, 0x2f, 0xd8, 0xae, 0xb7, 0xe2, 0x50, 0x77, 0x41, 0x77, 0xdc, 0x07, 0xb8, - 0x3b, 0x3e, 0x00, 0xc3, 0x18, 0x1e, 0xa8, 0x49, 0x2d, 0x1e, 0x42, 0xa7, 0x57, 0x4a, 0x36, 0xe2, - 0x23, 0x44, 0x5e, 0xa9, 0x08, 0x21, 0xd3, 0x7e, 0x6e, 0xf9, 0x49, 0x41, 0x9b, 0xb8, 0xd9, 0xc7, - 0xe1, 0xea, 0x8f, 0xe7, 0x60, 0xc8, 0x97, 0xf2, 0xb8, 0x79, 0x58, 0x6f, 0x6a, 0x0e, 0x56, 0xc8, - 0x57, 0x00, 0x16, 0x6c, 0xc7, 0xd3, 0x1b, 0x73, 0xa1, 0xe6, 0xe3, 0x11, 0x67, 0x0b, 0xa1, 0xbc, - 0x8c, 0x44, 0x82, 0xeb, 0x57, 0x68, 0x56, 0xf3, 0x89, 0x89, 0xaf, 0x5f, 0x01, 0x54, 0x93, 0x28, - 0xd4, 0x5f, 0xce, 0xc2, 0x31, 0xbf, 0x93, 0x26, 0xef, 0xd3, 0x7a, 0xfb, 0x41, 0x9e, 0x9b, 0xa2, - 0xd2, 0xee, 0xdd, 0x52, 0xda, 0xea, 0xff, 0x90, 0x26, 0x92, 0x89, 0x86, 0x7d, 0x34, 0x91, 0xfc, - 0x69, 0xe8, 0xb8, 0xfa, 0x9d, 0x39, 0x38, 0xe1, 0x4b, 0x7d, 0xaa, 0x6d, 0xe1, 0xe1, 0xc0, 0x84, - 0xde, 0x68, 0x3c, 0xc8, 0xbb, 0xf1, 0x41, 0x5f, 0x10, 0xf3, 0x22, 0xde, 0x9e, 0xc8, 0xf1, 0xb7, - 0x2c, 0xc0, 0x35, 0xdb, 0x34, 0x34, 0x99, 0x88, 0xbc, 0x0a, 0x43, 0xfe, 0xcf, 0x92, 0xb3, 0xe2, - 0x6f, 0xc1, 0xf1, 0xa8, 0x3f, 0x28, 0xa4, 0x3b, 0x91, 0xb0, 0x02, 0x91, 0x02, 0xea, 0x7f, 0x2a, - 0xc0, 0x99, 0x3b, 0xa6, 0x65, 0xd8, 0x6b, 0xae, 0x9f, 0x22, 0xf2, 0xd0, 0x1f, 0x75, 0x1d, 0x74, - 0x6a, 0xc8, 0xd7, 0xe1, 0x64, 0x5c, 0xa4, 0x4e, 0x10, 0xb8, 0x5b, 0xf4, 0xce, 0x1a, 0x27, 0xa8, - 0xf9, 0xc9, 0x22, 0xc5, 0x7d, 0x99, 0x96, 0x5e, 0x32, 0x9e, 0x6d, 0xb2, 0x6f, 0x3b, 0xd9, 0x26, - 0x9f, 0x80, 0x42, 0xd9, 0x6e, 0xea, 0xa6, 0x1f, 0x60, 0x06, 0x47, 0x71, 0x50, 0x2f, 0x62, 0x34, - 0x41, 0xc1, 0xf8, 0x8b, 0x8a, 0xb1, 0xcb, 0x06, 0x42, 0xfe, 0x7e, 0x01, 0x66, 0xa5, 0x69, 0x32, - 0x11, 0xb1, 0x61, 0x58, 0x54, 0x27, 0x6e, 0xb7, 0x00, 0x37, 0x4f, 0xcf, 0xfa, 0x32, 0xea, 0xac, - 0x56, 0x97, 0x23, 0xe5, 0xf8, 0x36, 0x8a, 0x27, 0xc1, 0x14, 0x1f, 0xc3, 0xef, 0xb9, 0xb4, 0x28, - 0x7f, 0x49, 0x08, 0x38, 0xc9, 0x0c, 0x26, 0x85, 0x80, 0xb3, 0x8c, 0x4c, 0x44, 0x26, 0x61, 0x0c, - 0xc3, 0x2b, 0x07, 0x5b, 0x29, 0xa6, 0x12, 0x43, 0x68, 0x54, 0xe2, 0xa5, 0x09, 0x8f, 0xc8, 0xcc, - 0x3e, 0xae, 0x56, 0x17, 0x68, 0x2d, 0x59, 0xe2, 0xcc, 0x6b, 0x40, 0x92, 0x6d, 0xde, 0xd1, 0xb5, - 0xc9, 0x3f, 0x95, 0xf6, 0x75, 0x87, 0xdd, 0xf1, 0x65, 0x3f, 0x66, 0xbb, 0x48, 0xea, 0xb0, 0xde, - 0x77, 0x32, 0x75, 0x58, 0x61, 0x5f, 0x53, 0x87, 0xa9, 0x3f, 0x9b, 0x81, 0xb1, 0x44, 0x9c, 0x71, - 0xf2, 0x0c, 0x00, 0x87, 0x48, 0xf1, 0x1c, 0x31, 0x40, 0x4a, 0x18, 0x7b, 0x5c, 0xac, 0x81, 0x21, - 0x19, 0xb9, 0x02, 0xfd, 0xfc, 0x97, 0x88, 0xc1, 0x94, 0x2c, 0xd2, 0x6e, 0x9b, 0x86, 0x16, 0x10, - 0x85, 0xb5, 0xe0, 0xc5, 0x61, 0x2e, 0xb5, 0x88, 0xb7, 0xde, 0x0a, 0x6a, 0x61, 0x64, 0xea, 0x67, - 0xb3, 0x30, 0x14, 0x34, 0xb8, 0x64, 0x1c, 0x94, 0xce, 0x15, 0x44, 0xc8, 0xf6, 0xdc, 0x56, 0x21, - 0xdb, 0x63, 0x93, 0xaa, 0x88, 0xd1, 0xbe, 0x7f, 0xef, 0x9e, 0x3e, 0x9f, 0x85, 0x63, 0x41, 0xad, - 0x07, 0x78, 0x47, 0xf5, 0x2e, 0x12, 0xc9, 0xe7, 0x32, 0xa0, 0x8c, 0x9b, 0x8d, 0x86, 0x69, 0xad, - 0x54, 0xac, 0x65, 0xdb, 0x69, 0xe2, 0xac, 0x77, 0x70, 0xe7, 0xb4, 0xea, 0xf7, 0x64, 0x60, 0x4c, - 0x34, 0x68, 0x42, 0x77, 0x8c, 0x83, 0x3b, 0x04, 0x8b, 0xb7, 0xe4, 0xe0, 0xf4, 0x45, 0xfd, 0x72, - 0x16, 0x60, 0xc6, 0xae, 0xdf, 0x3d, 0xe4, 0xcf, 0xa6, 0x5e, 0x82, 0x02, 0x0f, 0x84, 0x25, 0x34, - 0x76, 0x4c, 0x3c, 0x0f, 0x62, 0x9f, 0xc6, 0x11, 0xe3, 0xa3, 0x62, 0x3e, 0x2e, 0xf0, 0x40, 0x5a, - 0x4a, 0x46, 0x13, 0x45, 0x58, 0xa5, 0x8c, 0x4e, 0x2c, 0x18, 0x41, 0xa5, 0x0c, 0x16, 0xad, 0x74, - 0x73, 0xa3, 0x98, 0x6f, 0xd8, 0xf5, 0xbb, 0x1a, 0xd2, 0xab, 0x7f, 0x92, 0xe1, 0xb2, 0x3b, 0xe4, - 0x8f, 0x3f, 0xfd, 0xcf, 0xcf, 0xef, 0xf0, 0xf3, 0xbf, 0x37, 0x03, 0x27, 0x34, 0x5a, 0xb7, 0xef, - 0x51, 0x67, 0x7d, 0xc2, 0x36, 0xe8, 0x75, 0x6a, 0x51, 0xe7, 0xa0, 0x46, 0xd4, 0x3f, 0xc0, 0x1c, - 0x17, 0x61, 0x63, 0x6e, 0xb9, 0xd4, 0x38, 0x3c, 0xf9, 0x47, 0xd4, 0xbf, 0xd7, 0x07, 0x4a, 0xaa, - 0x69, 0x7b, 0x68, 0xcd, 0xb9, 0x8e, 0xfb, 0x95, 0xfc, 0x7e, 0xed, 0x57, 0x7a, 0x77, 0xb6, 0x5f, - 0x29, 0xec, 0x74, 0xbf, 0xd2, 0xb7, 0x9d, 0xfd, 0x4a, 0x33, 0xbe, 0x5f, 0xe9, 0xc7, 0xfd, 0xca, - 0x33, 0x5d, 0xf7, 0x2b, 0x93, 0x96, 0xb1, 0xcb, 0xdd, 0xca, 0xa1, 0xcd, 0x8d, 0xbb, 0x9b, 0x6d, - 0xd6, 0x45, 0x36, 0x29, 0xd6, 0x6d, 0xc7, 0xa0, 0x86, 0xd8, 0x5d, 0xe1, 0xd1, 0xbe, 0x23, 0x60, - 0x5a, 0x80, 0x4d, 0x24, 0x1a, 0x1e, 0xde, 0x4e, 0xa2, 0xe1, 0x7d, 0xd8, 0x7f, 0x7d, 0x26, 0x0b, - 0x63, 0x13, 0xd4, 0xf1, 0x78, 0xa4, 0xcd, 0xfd, 0xf0, 0x5c, 0x2b, 0xc1, 0x31, 0x89, 0x21, 0x5a, - 0xe4, 0xd9, 0xd0, 0x1b, 0xaf, 0x4e, 0x1d, 0x2f, 0xee, 0xcc, 0x17, 0xa7, 0x67, 0xd5, 0xfb, 0xc9, - 0xbe, 0xc4, 0xd8, 0x0d, 0xaa, 0xf7, 0xe1, 0x5c, 0x90, 0xa6, 0xf8, 0xa5, 0x05, 0xf4, 0x52, 0xfe, - 0xae, 0xfc, 0xce, 0xf3, 0x77, 0xa9, 0x3f, 0x93, 0x81, 0x0b, 0x1a, 0xb5, 0xe8, 0x9a, 0xbe, 0xd4, - 0xa0, 0x52, 0xb3, 0xc4, 0xca, 0xc0, 0x66, 0x0d, 0xd3, 0x6d, 0xea, 0x5e, 0x7d, 0x75, 0x4f, 0x32, - 0x9a, 0x82, 0x21, 0x79, 0xfe, 0xda, 0xc1, 0xdc, 0x16, 0x29, 0xa7, 0xfe, 0xd7, 0x1c, 0xf4, 0x8d, - 0xdb, 0xde, 0x0d, 0x7b, 0x8f, 0x09, 0xe5, 0xc2, 0x29, 0x3f, 0xbb, 0x83, 0x03, 0x9d, 0xf7, 0x63, - 0xe5, 0x52, 0x8c, 0x7d, 0xf4, 0xf4, 0x5c, 0xb2, 0x13, 0xb9, 0x08, 0x7c, 0xb2, 0x1d, 0xa6, 0x92, - 0x7b, 0x0e, 0x06, 0x30, 0x48, 0x8b, 0x74, 0xe4, 0x8a, 0x7e, 0xd4, 0x1e, 0x03, 0xc6, 0xeb, 0x08, - 0x49, 0xc9, 0x47, 0x22, 0xa1, 0x41, 0x0b, 0x7b, 0x4f, 0x3d, 0x27, 0x47, 0x09, 0x7d, 0x86, 0xdf, - 0xd6, 0x61, 0x9b, 0xa4, 0x34, 0x1d, 0x78, 0x54, 0x12, 0x6b, 0x52, 0x40, 0xb8, 0x7f, 0x69, 0xe1, - 0xd4, 0x6f, 0xe6, 0x61, 0xc8, 0x77, 0xb9, 0x3d, 0xa0, 0x6e, 0x7f, 0x0a, 0x0a, 0xd3, 0xb6, 0x94, - 0x64, 0x00, 0x5d, 0x74, 0x57, 0x6d, 0x37, 0xe6, 0x7b, 0x2c, 0x88, 0x98, 0xc0, 0xe6, 0x6c, 0x43, - 0x76, 0x30, 0x47, 0x81, 0x59, 0xb6, 0x91, 0x78, 0xa0, 0x1b, 0x10, 0x92, 0x0b, 0x90, 0x47, 0xdf, - 0x7c, 0xe9, 0xa0, 0x3d, 0xe6, 0x8f, 0x8f, 0x78, 0x49, 0xa1, 0x0a, 0x3b, 0x55, 0xa8, 0xbe, 0xdd, - 0x2a, 0x54, 0xff, 0xfe, 0x2a, 0xd4, 0x1b, 0x30, 0x84, 0x35, 0xf9, 0x39, 0xca, 0xb6, 0x5e, 0x13, - 0x1f, 0x12, 0xcb, 0xd6, 0x30, 0x6f, 0xb7, 0xc8, 0x54, 0x86, 0xab, 0x55, 0x84, 0x55, 0x4c, 0xed, - 0x60, 0x0f, 0x6a, 0xf7, 0xdb, 0x19, 0xe8, 0xbb, 0x65, 0xdd, 0xb5, 0xec, 0xb5, 0xbd, 0x69, 0xdc, - 0x33, 0x30, 0x28, 0xd8, 0x48, 0x0b, 0x03, 0xbe, 0xb9, 0x6e, 0x73, 0x70, 0x0d, 0x39, 0x69, 0x32, - 0x15, 0x79, 0x39, 0x28, 0x84, 0xcf, 0x6f, 0x72, 0x61, 0x9a, 0x0e, 0xbf, 0x50, 0x3d, 0x9a, 0x59, - 0x40, 0x26, 0x27, 0x67, 0x21, 0x5f, 0x66, 0x4d, 0x95, 0xe2, 0xd4, 0xb2, 0xa6, 0x68, 0x08, 0x55, - 0x3f, 0x93, 0x87, 0x91, 0xd8, 0x99, 0xd5, 0x13, 0x30, 0x20, 0xce, 0x8c, 0x4c, 0x3f, 0xd5, 0x01, - 0x3e, 0xcf, 0x09, 0x80, 0x5a, 0x3f, 0xff, 0xb3, 0x62, 0x90, 0x0f, 0x42, 0x9f, 0xed, 0xe2, 0x7a, - 0x86, 0xdf, 0x32, 0x12, 0x0e, 0xa1, 0xf9, 0x2a, 0x6b, 0x3b, 0x1f, 0x1c, 0x82, 0x44, 0xd6, 0x48, - 0xdb, 0xc5, 0x4f, 0xbb, 0x06, 0x03, 0xba, 0xeb, 0x52, 0xaf, 0xe6, 0xe9, 0x2b, 0x72, 0xf6, 0x83, - 0x00, 0x28, 0x8f, 0x0e, 0x04, 0x2e, 0xea, 0x2b, 0xe4, 0x35, 0x18, 0xae, 0x3b, 0x14, 0x57, 0x3c, - 0xbd, 0xc1, 0x5a, 0x29, 0x59, 0xa4, 0x11, 0x84, 0x7c, 0xbf, 0x11, 0x22, 0x2a, 0x06, 0xb9, 0x0d, - 0xc3, 0xe2, 0x73, 0xb8, 0x6f, 0x3c, 0x0e, 0xb4, 0x91, 0x70, 0x05, 0xe2, 0x22, 0xe1, 0xde, 0xf1, - 0xe2, 0x89, 0x84, 0x4c, 0x2e, 0xf3, 0x35, 0x24, 0x52, 0x32, 0x0f, 0x64, 0x8d, 0x2e, 0xd5, 0xf4, - 0xb6, 0xb7, 0xca, 0xea, 0xe2, 0xc1, 0xbb, 0x45, 0xd2, 0x3f, 0x7c, 0x57, 0x90, 0xc4, 0xca, 0xcf, - 0x2d, 0xd6, 0xe8, 0x52, 0x29, 0x82, 0x24, 0x77, 0xe0, 0x64, 0xb2, 0x08, 0xfb, 0x64, 0x7e, 0x78, - 0xff, 0xd8, 0xe6, 0x46, 0xb1, 0x98, 0x4a, 0x20, 0xb1, 0x3d, 0x9e, 0x60, 0x5b, 0x31, 0x6e, 0xe4, - 0xfb, 0xfb, 0x46, 0xfb, 0xb5, 0x11, 0x56, 0xd6, 0xb7, 0xfe, 0x4c, 0x43, 0xfd, 0x5a, 0x86, 0x59, - 0x79, 0xec, 0x83, 0x30, 0xeb, 0x31, 0xd3, 0xf5, 0xe6, 0x0e, 0x75, 0xbd, 0x19, 0xe6, 0x27, 0x2c, - 0xb8, 0x5d, 0x66, 0x57, 0x4d, 0x60, 0xc9, 0x65, 0x28, 0x18, 0xf2, 0x81, 0xd7, 0xa9, 0x68, 0x27, - 0xf8, 0xf5, 0x68, 0x82, 0x8a, 0x5c, 0x84, 0x3c, 0x5b, 0x6d, 0xe2, 0xbb, 0x5d, 0xd9, 0x30, 0xd0, - 0x90, 0x42, 0xfd, 0xf6, 0x2c, 0x0c, 0x49, 0x5f, 0x73, 0x75, 0x4f, 0x9f, 0xf3, 0xe2, 0xf6, 0x9a, - 0xe9, 0x3b, 0xa5, 0xe0, 0x36, 0xc8, 0x6f, 0xf2, 0xb5, 0x40, 0x14, 0xdb, 0xba, 0x30, 0x12, 0x82, - 0x79, 0x4e, 0x7c, 0x68, 0x61, 0xfb, 0x3b, 0x3f, 0x46, 0x7f, 0x23, 0xdf, 0x9f, 0x1d, 0xcd, 0xdd, - 0xc8, 0xf7, 0xe7, 0x47, 0x7b, 0x31, 0xd2, 0x15, 0x06, 0x97, 0xe6, 0xdb, 0x6a, 0x6b, 0xd9, 0x5c, - 0x39, 0xe4, 0xaf, 0x33, 0xf6, 0x37, 0x0a, 0x58, 0x4c, 0x36, 0x87, 0xfc, 0xa9, 0xc6, 0x3b, 0x2a, - 0x9b, 0xa3, 0x7c, 0x86, 0x42, 0x36, 0xbf, 0x93, 0x01, 0x25, 0x55, 0x36, 0xa5, 0x03, 0xf2, 0x53, - 0xd8, 0xbf, 0xac, 0x86, 0xdf, 0xc8, 0xc2, 0x58, 0xc5, 0xf2, 0xe8, 0x0a, 0xdf, 0xec, 0x1d, 0xf2, - 0xa9, 0xe2, 0x26, 0x0c, 0x4a, 0x1f, 0x23, 0xfa, 0xfc, 0xe1, 0x60, 0x2b, 0x1d, 0xa2, 0x3a, 0x70, - 0x92, 0x4b, 0xef, 0x63, 0x22, 0xf4, 0x98, 0x90, 0x0f, 0xf9, 0x9c, 0x73, 0x38, 0x84, 0x7c, 0xc8, - 0x27, 0xaf, 0x77, 0xa9, 0x90, 0xff, 0x5b, 0x06, 0x8e, 0xa7, 0x54, 0x4e, 0x2e, 0x40, 0x5f, 0xb5, - 0xbd, 0x84, 0x81, 0xad, 0x32, 0xa1, 0x47, 0xaf, 0xdb, 0x5e, 0xc2, 0x98, 0x56, 0x9a, 0x8f, 0x24, - 0x8b, 0xf8, 0x7c, 0x7d, 0xbe, 0x52, 0x9e, 0x10, 0x52, 0x55, 0xa5, 0x87, 0xf8, 0x0c, 0x9c, 0xf6, - 0x65, 0xc1, 0x13, 0x77, 0xdb, 0x34, 0xea, 0xb1, 0x27, 0xee, 0xac, 0x0c, 0xf9, 0x28, 0x0c, 0x94, - 0xde, 0x6a, 0x3b, 0x14, 0xf9, 0x72, 0x89, 0xbf, 0x27, 0xe0, 0xeb, 0x23, 0xd2, 0x38, 0xf3, 0xd7, - 0xfa, 0x8c, 0x22, 0xce, 0x3b, 0x64, 0xa8, 0x7e, 0x36, 0x03, 0x67, 0x3a, 0xb7, 0x8e, 0xbc, 0x1f, - 0xfa, 0xd8, 0xce, 0xbc, 0xa4, 0xcd, 0x89, 0x4f, 0xe7, 0x19, 0x40, 0xed, 0x06, 0xad, 0xe9, 0x8e, - 0x6c, 0xec, 0xfb, 0x64, 0xe4, 0x15, 0x18, 0xac, 0xb8, 0x6e, 0x9b, 0x3a, 0xd5, 0x67, 0x6e, 0x69, - 0x15, 0xb1, 0x27, 0xc4, 0x3d, 0x87, 0x89, 0xe0, 0x9a, 0xfb, 0x4c, 0x2c, 0x74, 0x95, 0x4c, 0xaf, - 0x7e, 0x2a, 0x03, 0x67, 0xbb, 0x7d, 0x15, 0x79, 0x06, 0xfa, 0x17, 0xa9, 0xa5, 0x5b, 0x5e, 0xa5, - 0x2c, 0x9a, 0x84, 0x5b, 0x2c, 0x0f, 0x61, 0xd1, 0x9d, 0x42, 0x40, 0xc8, 0x0a, 0xf1, 0x23, 0xc1, - 0xc0, 0x07, 0x81, 0x1f, 0x5f, 0x22, 0x2c, 0x56, 0xc8, 0x27, 0x54, 0x7f, 0x45, 0x87, 0xde, 0x79, - 0x8b, 0xce, 0x2f, 0x93, 0xa7, 0x61, 0x80, 0xe9, 0x3e, 0xa6, 0xdf, 0x17, 0x03, 0x6d, 0x4c, 0x1e, - 0x30, 0x88, 0x98, 0xee, 0xd1, 0x42, 0x2a, 0x72, 0x4d, 0xce, 0xf9, 0x2d, 0xd4, 0x81, 0xc8, 0x65, - 0x38, 0x66, 0xba, 0x47, 0x93, 0x73, 0x83, 0x5f, 0x93, 0x73, 0x2d, 0x8b, 0xce, 0x8e, 0x94, 0xe2, - 0x18, 0xbf, 0x94, 0x98, 0x06, 0x66, 0xd2, 0x12, 0x12, 0xc7, 0x6d, 0x82, 0x24, 0xc5, 0x74, 0x8f, - 0x96, 0x9e, 0xc8, 0x78, 0x48, 0x76, 0x63, 0x8a, 0xdf, 0x42, 0xca, 0xb8, 0xe9, 0x1e, 0x2d, 0x42, - 0x4b, 0x9e, 0x87, 0x41, 0xf1, 0xfb, 0x86, 0x6d, 0x5a, 0xf1, 0x18, 0x16, 0x12, 0x6a, 0xba, 0x47, - 0x93, 0x29, 0xa5, 0x4a, 0x17, 0x1c, 0xd3, 0xf2, 0xc4, 0xcb, 0xb8, 0x78, 0xa5, 0x88, 0x93, 0x2a, - 0xc5, 0xdf, 0xe4, 0x15, 0x18, 0x0e, 0x82, 0x83, 0xbc, 0x49, 0xeb, 0x9e, 0x38, 0xd2, 0x39, 0x19, - 0x2b, 0xcc, 0x91, 0xd3, 0x3d, 0x5a, 0x94, 0x9a, 0x5c, 0x84, 0x82, 0x46, 0x5d, 0xf3, 0x2d, 0xff, - 0xfe, 0x62, 0x44, 0x9a, 0xce, 0xcc, 0xb7, 0x98, 0x94, 0x04, 0x9e, 0xf5, 0x4e, 0x78, 0x61, 0x22, - 0x0e, 0x60, 0x48, 0xac, 0x96, 0x49, 0xcb, 0x60, 0xbd, 0x23, 0xdd, 0x96, 0xbd, 0x16, 0x86, 0x4c, - 0x11, 0x89, 0xd6, 0x06, 0xe3, 0x6f, 0x53, 0x65, 0xec, 0x74, 0x8f, 0x16, 0xa3, 0x97, 0xa4, 0x5a, - 0x36, 0xdd, 0xbb, 0x22, 0x4a, 0x5d, 0x5c, 0xaa, 0x0c, 0x25, 0x49, 0x95, 0xfd, 0x94, 0xaa, 0x9e, - 0xa3, 0xde, 0x9a, 0xed, 0xdc, 0x15, 0x31, 0xe9, 0xe2, 0x55, 0x0b, 0xac, 0x54, 0xb5, 0x80, 0xc8, - 0x55, 0xb3, 0x45, 0x66, 0x24, 0xbd, 0x6a, 0xdd, 0xd3, 0xe5, 0xaa, 0xf9, 0xfe, 0xd2, 0xef, 0xa4, - 0x19, 0xaa, 0xdf, 0xe3, 0xf9, 0x6e, 0x93, 0x1d, 0x8a, 0x38, 0xa9, 0x43, 0xf1, 0x37, 0xab, 0x54, - 0xca, 0x69, 0x2a, 0x12, 0xda, 0x06, 0x95, 0x4a, 0x28, 0x56, 0xa9, 0x9c, 0xfd, 0xf4, 0x9a, 0x9c, - 0xea, 0x53, 0x19, 0x8b, 0x76, 0x50, 0x88, 0x61, 0x1d, 0x24, 0xa5, 0x04, 0x2d, 0x62, 0x1a, 0x41, - 0x85, 0x20, 0xf9, 0x60, 0xd0, 0xc2, 0x89, 0x85, 0xe9, 0x1e, 0x0d, 0x13, 0x0c, 0xaa, 0x3c, 0x41, - 0xa5, 0x72, 0x1c, 0x29, 0x86, 0x7c, 0x0a, 0x06, 0x9b, 0xee, 0xd1, 0x78, 0xf2, 0xca, 0xa7, 0xa5, - 0x54, 0x50, 0xca, 0x89, 0xe8, 0x14, 0x11, 0x20, 0xd8, 0x14, 0x11, 0x26, 0x8c, 0x9a, 0x4a, 0xa6, - 0x4b, 0x52, 0x4e, 0x46, 0x57, 0xd4, 0x38, 0x7e, 0xba, 0x47, 0x4b, 0xa6, 0x58, 0x7a, 0x3e, 0x92, - 0x41, 0x48, 0x39, 0x15, 0x0b, 0x1c, 0x13, 0xa2, 0x98, 0xb8, 0xe4, 0x5c, 0x43, 0xf3, 0xa9, 0x39, - 0xbf, 0x95, 0xd3, 0xd1, 0xe5, 0x38, 0x85, 0x64, 0xba, 0x47, 0x4b, 0xcd, 0x16, 0x3e, 0x91, 0xc8, - 0xe3, 0xa3, 0x28, 0xd1, 0xcb, 0xda, 0x18, 0x7a, 0xba, 0x47, 0x4b, 0x64, 0xfe, 0xb9, 0x26, 0x27, - 0xd0, 0x51, 0x1e, 0x8a, 0x76, 0x62, 0x88, 0x61, 0x9d, 0x28, 0x25, 0xda, 0xb9, 0x26, 0x27, 0x55, - 0x51, 0xce, 0x24, 0x4b, 0x85, 0x33, 0xa7, 0x94, 0x7c, 0x45, 0x4b, 0xcf, 0x13, 0xa1, 0x3c, 0x2c, - 0x32, 0xf5, 0x89, 0xf2, 0x69, 0x34, 0xd3, 0x3d, 0x5a, 0x7a, 0x8e, 0x09, 0x2d, 0x3d, 0xc1, 0x82, - 0x72, 0xb6, 0x1b, 0xcf, 0xa0, 0x75, 0xe9, 0xc9, 0x19, 0xf4, 0x2e, 0xe1, 0xee, 0x95, 0x73, 0xd1, - 0xa8, 0x95, 0x1d, 0x09, 0xa7, 0x7b, 0xb4, 0x2e, 0x41, 0xf3, 0x6f, 0x75, 0x88, 0x3d, 0xaf, 0x9c, - 0x8f, 0x26, 0xea, 0x4c, 0x25, 0x9a, 0xee, 0xd1, 0x3a, 0x44, 0xae, 0xbf, 0xd5, 0x21, 0x34, 0xb9, - 0x52, 0xec, 0xca, 0x36, 0x90, 0x47, 0x87, 0xc0, 0xe6, 0xf3, 0xa9, 0x51, 0xbd, 0x95, 0x47, 0xa2, - 0xaa, 0x9b, 0x42, 0xc2, 0x54, 0x37, 0x2d, 0x1e, 0xf8, 0x7c, 0x6a, 0x18, 0x6a, 0xe5, 0xd1, 0x2e, - 0x0c, 0x83, 0x36, 0xa6, 0x06, 0xb0, 0x9e, 0x4f, 0x8d, 0x03, 0xad, 0xa8, 0x51, 0x86, 0x29, 0x24, - 0x8c, 0x61, 0x5a, 0x04, 0xe9, 0xf9, 0xd4, 0x70, 0xc1, 0xca, 0x63, 0x5d, 0x18, 0x86, 0x2d, 0x4c, - 0x0b, 0x34, 0xfc, 0x7c, 0x24, 0x5e, 0xaf, 0xf2, 0x9e, 0xe8, 0xbc, 0x21, 0xa1, 0xd8, 0xbc, 0x21, - 0x47, 0xf6, 0x9d, 0x48, 0x44, 0x24, 0x54, 0x1e, 0x8f, 0x0e, 0xf3, 0x18, 0x9a, 0x0d, 0xf3, 0x78, - 0x0c, 0xc3, 0x89, 0x44, 0x64, 0x36, 0xe5, 0x42, 0x27, 0x26, 0x88, 0x8e, 0x32, 0xe1, 0xb1, 0xdc, - 0x2a, 0x29, 0xa1, 0xc1, 0x94, 0xf7, 0x46, 0x1d, 0x0d, 0x13, 0x04, 0xd3, 0x3d, 0x5a, 0x4a, 0x40, - 0x31, 0x2d, 0x3d, 0x0e, 0x86, 0x72, 0x31, 0x3a, 0x6c, 0xd3, 0x68, 0xd8, 0xb0, 0x4d, 0x8d, 0xa1, - 0x31, 0x93, 0xe6, 0x0d, 0xad, 0x5c, 0x8a, 0x1a, 0x66, 0x49, 0x0a, 0x66, 0x98, 0xa5, 0x78, 0x51, - 0x6b, 0xe9, 0x91, 0x1d, 0x94, 0x27, 0xba, 0xb6, 0x10, 0x69, 0x52, 0x5a, 0xc8, 0x03, 0x1d, 0x84, - 0xb6, 0xd3, 0xad, 0x56, 0xc3, 0xd6, 0x0d, 0xe5, 0x7d, 0xa9, 0xb6, 0x13, 0x47, 0x4a, 0xb6, 0x13, - 0x07, 0xb0, 0x55, 0x5e, 0x76, 0xba, 0x55, 0x9e, 0x8c, 0xae, 0xf2, 0x32, 0x8e, 0xad, 0xf2, 0x11, - 0x07, 0xdd, 0x89, 0x84, 0x83, 0xaa, 0xf2, 0x54, 0x54, 0x01, 0x62, 0x68, 0xa6, 0x00, 0x71, 0x97, - 0xd6, 0x8f, 0x77, 0x76, 0xe9, 0x54, 0x2e, 0x23, 0xb7, 0x47, 0x7c, 0x6e, 0x9d, 0xe8, 0xa6, 0x7b, - 0xb4, 0xce, 0x6e, 0xa1, 0x95, 0x14, 0x0f, 0x4d, 0xe5, 0x4a, 0x54, 0xc1, 0x12, 0x04, 0x4c, 0xc1, - 0x92, 0x7e, 0x9d, 0x95, 0x14, 0x17, 0x4b, 0xe5, 0xfd, 0x1d, 0x59, 0x05, 0xdf, 0x9c, 0xe2, 0x98, - 0x79, 0x4d, 0xf6, 0x91, 0x54, 0x9e, 0x8e, 0x2e, 0x76, 0x21, 0x86, 0x2d, 0x76, 0x92, 0x2f, 0xe5, - 0x35, 0xd9, 0x3b, 0x50, 0xb9, 0x9a, 0x2c, 0x15, 0x2e, 0x91, 0x92, 0x17, 0xa1, 0x96, 0xee, 0x54, - 0xa7, 0x3c, 0x13, 0xd5, 0xba, 0x34, 0x1a, 0xa6, 0x75, 0xa9, 0x0e, 0x79, 0x53, 0x49, 0xdf, 0x38, - 0xe5, 0x5a, 0xfc, 0x2c, 0x21, 0x8a, 0x67, 0x96, 0x4f, 0xc2, 0x9f, 0xee, 0xb5, 0x78, 0x90, 0x26, - 0xe5, 0xd9, 0xd8, 0x65, 0x46, 0x04, 0xcb, 0xec, 0xdb, 0x58, 0x50, 0xa7, 0xd7, 0xe2, 0x71, 0x8d, - 0x94, 0xe7, 0xd2, 0x39, 0x04, 0xba, 0x12, 0x8f, 0x83, 0xf4, 0x5a, 0x3c, 0x14, 0x90, 0xf2, 0x7c, - 0x3a, 0x87, 0x40, 0xba, 0xf1, 0xd0, 0x41, 0x4f, 0x4b, 0xc1, 0x89, 0x95, 0x0f, 0x44, 0x4d, 0xc7, - 0x00, 0xc1, 0x4c, 0xc7, 0x30, 0x84, 0xf1, 0xd3, 0x52, 0x50, 0x5f, 0xe5, 0x85, 0x44, 0x91, 0xa0, - 0xb1, 0x52, 0xe8, 0xdf, 0xa7, 0xa5, 0x60, 0xb8, 0xca, 0x8b, 0x89, 0x22, 0x41, 0xeb, 0xa4, 0x90, - 0xb9, 0x46, 0xb7, 0x57, 0x53, 0xca, 0x4b, 0xd1, 0x23, 0x8e, 0xce, 0x94, 0xd3, 0x3d, 0x5a, 0xb7, - 0xd7, 0x57, 0x1f, 0xef, 0xec, 0x69, 0xa8, 0xbc, 0x1c, 0x1d, 0xc2, 0x9d, 0xe8, 0xd8, 0x10, 0xee, - 0xe8, 0xad, 0xf8, 0x4a, 0xec, 0x05, 0xb5, 0xf2, 0x4a, 0x74, 0x8a, 0x8b, 0x20, 0xd9, 0x14, 0x17, - 0x7f, 0x6f, 0x1d, 0x79, 0x1a, 0xac, 0x7c, 0x30, 0x3a, 0xc5, 0xc9, 0x38, 0x36, 0xc5, 0x45, 0x9e, - 0x11, 0x4f, 0x24, 0x5e, 0xac, 0x2a, 0xaf, 0x46, 0xa7, 0xb8, 0x18, 0x9a, 0x4d, 0x71, 0xf1, 0x37, - 0xae, 0xaf, 0xc4, 0x1e, 0x6e, 0x2a, 0xaf, 0xa5, 0xb7, 0x1f, 0x91, 0x72, 0xfb, 0xf9, 0x33, 0x4f, - 0x2d, 0xfd, 0x05, 0xa2, 0x52, 0x8a, 0x8e, 0xdf, 0x34, 0x1a, 0x36, 0x7e, 0x53, 0x5f, 0x2f, 0xc6, - 0x37, 0x0e, 0x42, 0xab, 0xc6, 0xbb, 0x6c, 0x1c, 0x42, 0x53, 0x24, 0x05, 0x1c, 0xd9, 0x23, 0xf3, - 0x8d, 0xd0, 0x44, 0x87, 0x3d, 0xb2, 0xbf, 0x0d, 0x8a, 0xd1, 0xb3, 0xd9, 0x35, 0xe1, 0xf8, 0xa6, - 0x94, 0xa3, 0xb3, 0x6b, 0x82, 0x80, 0xcd, 0xae, 0x49, 0x77, 0xb9, 0x29, 0x18, 0x15, 0x5a, 0xc4, - 0xfd, 0xf9, 0x4c, 0x6b, 0x45, 0x99, 0x8c, 0x3d, 0x00, 0x8a, 0xe1, 0xd9, 0xec, 0x14, 0x87, 0xe1, - 0x7a, 0xcd, 0x61, 0x13, 0x0d, 0xb3, 0xb5, 0x64, 0xeb, 0x8e, 0x51, 0xa5, 0x96, 0xa1, 0x4c, 0xc5, - 0xd6, 0xeb, 0x14, 0x1a, 0x5c, 0xaf, 0x53, 0xe0, 0x18, 0x98, 0x28, 0x06, 0xd7, 0x68, 0x9d, 0x9a, - 0xf7, 0xa8, 0x72, 0x1d, 0xd9, 0x16, 0x3b, 0xb1, 0x15, 0x64, 0xd3, 0x3d, 0x5a, 0x27, 0x0e, 0xcc, - 0x56, 0x9f, 0x5d, 0xaf, 0xbe, 0x3e, 0x13, 0x3c, 0x7a, 0x5d, 0x70, 0x68, 0x4b, 0x77, 0xa8, 0x32, - 0x1d, 0xb5, 0xd5, 0x53, 0x89, 0x98, 0xad, 0x9e, 0x8a, 0x48, 0xb2, 0xf5, 0xc7, 0x42, 0xa5, 0x1b, - 0xdb, 0x70, 0x44, 0xa4, 0x97, 0x66, 0xb3, 0x53, 0x14, 0xc1, 0x04, 0x34, 0x63, 0x5b, 0x2b, 0x78, - 0x52, 0x71, 0x23, 0x3a, 0x3b, 0x75, 0xa6, 0x64, 0xb3, 0x53, 0x67, 0x2c, 0x53, 0xf5, 0x28, 0x96, - 0x8f, 0xc1, 0x9b, 0x51, 0x55, 0x4f, 0x21, 0x61, 0xaa, 0x9e, 0x02, 0x4e, 0x32, 0xd4, 0xa8, 0x4b, - 0x3d, 0x65, 0xa6, 0x1b, 0x43, 0x24, 0x49, 0x32, 0x44, 0x70, 0x92, 0xe1, 0x14, 0xf5, 0xea, 0xab, - 0xca, 0x6c, 0x37, 0x86, 0x48, 0x92, 0x64, 0x88, 0x60, 0xb6, 0xd9, 0x8c, 0x82, 0xc7, 0xdb, 0x8d, - 0xbb, 0x7e, 0x9f, 0xcd, 0x45, 0x37, 0x9b, 0x1d, 0x09, 0xd9, 0x66, 0xb3, 0x23, 0x92, 0x7c, 0x6a, - 0xdb, 0x8e, 0x99, 0xca, 0x3c, 0x56, 0x78, 0x39, 0xb4, 0x0b, 0xb6, 0x53, 0x6a, 0xba, 0x47, 0xdb, - 0xae, 0xe3, 0xe7, 0xfb, 0x02, 0x57, 0x28, 0x65, 0x01, 0xab, 0x3a, 0x16, 0x9c, 0x55, 0x70, 0xf0, - 0x74, 0x8f, 0x16, 0x38, 0x4b, 0x3d, 0x0f, 0x83, 0xf8, 0x51, 0x15, 0xcb, 0xf4, 0xca, 0xe3, 0xca, - 0xeb, 0xd1, 0x2d, 0x93, 0x84, 0x62, 0x5b, 0x26, 0xe9, 0x27, 0x9b, 0xc4, 0xf1, 0x27, 0x9f, 0x62, - 0xca, 0xe3, 0x8a, 0x16, 0x9d, 0xc4, 0x23, 0x48, 0x36, 0x89, 0x47, 0x00, 0x41, 0xbd, 0x65, 0xc7, - 0x6e, 0x95, 0xc7, 0x95, 0x6a, 0x4a, 0xbd, 0x1c, 0x15, 0xd4, 0xcb, 0x7f, 0x06, 0xf5, 0x56, 0x57, - 0xdb, 0x5e, 0x99, 0x7d, 0xe3, 0x62, 0x4a, 0xbd, 0x3e, 0x32, 0xa8, 0xd7, 0x07, 0xb0, 0xa9, 0x10, - 0x01, 0x0b, 0x8e, 0xcd, 0x26, 0xed, 0x9b, 0x66, 0xa3, 0xa1, 0xdc, 0x8a, 0x4e, 0x85, 0x71, 0x3c, - 0x9b, 0x0a, 0xe3, 0x30, 0x66, 0x7a, 0xf2, 0x56, 0xd1, 0xa5, 0xf6, 0x8a, 0x72, 0x3b, 0x6a, 0x7a, - 0x86, 0x18, 0x66, 0x7a, 0x86, 0xbf, 0x70, 0x77, 0xc1, 0x7e, 0x69, 0x74, 0xd9, 0xa1, 0xee, 0xaa, - 0x72, 0x27, 0xb6, 0xbb, 0x90, 0x70, 0xb8, 0xbb, 0x90, 0x7e, 0x93, 0x15, 0x78, 0x38, 0xb2, 0xd0, - 0xf8, 0x77, 0x4f, 0x55, 0xaa, 0x3b, 0xf5, 0x55, 0xe5, 0x43, 0xc8, 0xea, 0xb1, 0xd4, 0xa5, 0x2a, - 0x4a, 0x3a, 0xdd, 0xa3, 0x75, 0xe3, 0x84, 0xdb, 0xf2, 0xd7, 0x67, 0x78, 0x04, 0x41, 0x6d, 0x61, - 0xc2, 0xdf, 0x84, 0xbe, 0x11, 0xdb, 0x96, 0x27, 0x49, 0x70, 0x5b, 0x9e, 0x04, 0x93, 0x16, 0x9c, - 0x8f, 0x6d, 0xd5, 0x66, 0xf5, 0x06, 0xdb, 0x97, 0x50, 0x63, 0x41, 0xaf, 0xdf, 0xa5, 0x9e, 0xf2, - 0x61, 0xe4, 0x7d, 0xa1, 0xc3, 0x86, 0x2f, 0x46, 0x3d, 0xdd, 0xa3, 0x6d, 0xc1, 0x8f, 0xa8, 0x90, - 0xaf, 0x4e, 0x2d, 0x2e, 0x28, 0x1f, 0x89, 0x9e, 0x6f, 0x32, 0xd8, 0x74, 0x8f, 0x86, 0x38, 0x66, - 0xa5, 0xdd, 0x6a, 0xad, 0x38, 0xba, 0x41, 0xb9, 0xa1, 0x85, 0xb6, 0x9b, 0x30, 0x40, 0x3f, 0x1a, - 0xb5, 0xd2, 0x3a, 0xd1, 0x31, 0x2b, 0xad, 0x13, 0x8e, 0x29, 0x6a, 0x24, 0x58, 0xbe, 0xf2, 0xb1, - 0xa8, 0xa2, 0x46, 0x90, 0x4c, 0x51, 0xa3, 0xa1, 0xf5, 0x3f, 0x04, 0xa7, 0x82, 0xfd, 0xbc, 0x58, - 0x7f, 0x79, 0xa7, 0x29, 0x1f, 0x47, 0x3e, 0xe7, 0x13, 0x97, 0x01, 0x11, 0xaa, 0xe9, 0x1e, 0xad, - 0x43, 0x79, 0xb6, 0xe2, 0x26, 0xf2, 0xc0, 0x08, 0xf3, 0xe2, 0xdb, 0xa2, 0x2b, 0x6e, 0x07, 0x32, - 0xb6, 0xe2, 0x76, 0x40, 0xa5, 0x32, 0x17, 0x42, 0xd5, 0xb7, 0x60, 0x1e, 0xc8, 0xb4, 0x13, 0x87, - 0x54, 0xe6, 0xc2, 0x52, 0x5b, 0xda, 0x82, 0x79, 0x60, 0xad, 0x75, 0xe2, 0x40, 0x2e, 0x42, 0xa1, - 0x5a, 0x9d, 0xd5, 0xda, 0x96, 0x52, 0x8f, 0xf9, 0x80, 0x21, 0x74, 0xba, 0x47, 0x13, 0x78, 0x66, - 0x06, 0x4d, 0x36, 0x74, 0xd7, 0x33, 0xeb, 0x2e, 0x8e, 0x18, 0x7f, 0x84, 0x18, 0x51, 0x33, 0x28, - 0x8d, 0x86, 0x99, 0x41, 0x69, 0x70, 0x66, 0x2f, 0x4e, 0xe8, 0xae, 0xab, 0x5b, 0x86, 0xa3, 0x8f, - 0xe3, 0x32, 0x41, 0x63, 0xcf, 0x03, 0x22, 0x58, 0x66, 0x2f, 0x46, 0x21, 0x78, 0xf8, 0xee, 0x43, - 0x7c, 0x33, 0x67, 0x39, 0x76, 0xf8, 0x1e, 0xc3, 0xe3, 0xe1, 0x7b, 0x0c, 0x86, 0x76, 0xa7, 0x0f, - 0xd3, 0xe8, 0x8a, 0xc9, 0x44, 0xa4, 0xac, 0xc4, 0xec, 0xce, 0x38, 0x01, 0xda, 0x9d, 0x71, 0x60, - 0xa4, 0x49, 0xfe, 0x72, 0xbb, 0xda, 0xa1, 0x49, 0xe1, 0x2a, 0x9b, 0x28, 0xc3, 0xd6, 0xef, 0x70, - 0x70, 0x94, 0xd7, 0x2d, 0xbd, 0x69, 0x97, 0xc7, 0x7d, 0xa9, 0x9b, 0xd1, 0xf5, 0xbb, 0x23, 0x21, - 0x5b, 0xbf, 0x3b, 0x22, 0xd9, 0xec, 0xea, 0x6f, 0xb4, 0x56, 0x75, 0x87, 0x1a, 0x65, 0xd3, 0xc1, - 0x93, 0xc5, 0x75, 0xbe, 0x35, 0x7c, 0x33, 0x3a, 0xbb, 0x76, 0x21, 0x65, 0xb3, 0x6b, 0x17, 0x34, - 0x33, 0xf2, 0xd2, 0xd1, 0x1a, 0xd5, 0x0d, 0xe5, 0x6e, 0xd4, 0xc8, 0xeb, 0x4c, 0xc9, 0x8c, 0xbc, - 0xce, 0xd8, 0xce, 0x9f, 0x73, 0xc7, 0x31, 0x3d, 0xaa, 0x34, 0xb6, 0xf3, 0x39, 0x48, 0xda, 0xf9, - 0x73, 0x10, 0xcd, 0x36, 0x84, 0xf1, 0x0e, 0x69, 0x46, 0x37, 0x84, 0xc9, 0x6e, 0x88, 0x97, 0x60, - 0x16, 0x8b, 0x78, 0x25, 0xa2, 0x58, 0x51, 0x8b, 0x45, 0x80, 0x99, 0xc5, 0x12, 0xbe, 0x23, 0x89, - 0x3c, 0x30, 0x50, 0xec, 0xe8, 0x1a, 0x2a, 0xe3, 0xd8, 0x1a, 0x1a, 0x79, 0x8c, 0xf0, 0x7c, 0xc4, - 0x7b, 0x56, 0x69, 0x45, 0xad, 0x0e, 0x09, 0xc5, 0xac, 0x0e, 0xd9, 0xcf, 0x76, 0x02, 0x8e, 0xe1, - 0x2d, 0xb8, 0xd6, 0x0e, 0xee, 0x71, 0x3e, 0x11, 0xfd, 0xcc, 0x18, 0x9a, 0x7d, 0x66, 0x0c, 0x14, - 0x61, 0x22, 0xa6, 0x2d, 0xa7, 0x03, 0x93, 0xf0, 0x7c, 0x30, 0x06, 0x22, 0x33, 0x40, 0xaa, 0xa5, - 0xd9, 0x99, 0x8a, 0xb1, 0x20, 0x5f, 0x91, 0xb9, 0xd1, 0x13, 0xd8, 0x24, 0xc5, 0x74, 0x8f, 0x96, - 0x52, 0x8e, 0xbc, 0x09, 0x67, 0x05, 0x54, 0x3c, 0x01, 0xc4, 0x74, 0xd1, 0x46, 0xb0, 0x20, 0x78, - 0x51, 0xef, 0x8c, 0x6e, 0xb4, 0xd3, 0x3d, 0x5a, 0x57, 0x5e, 0x9d, 0xeb, 0x12, 0xeb, 0x43, 0x7b, - 0x3b, 0x75, 0x05, 0x8b, 0x44, 0x57, 0x5e, 0x9d, 0xeb, 0x12, 0x72, 0xbf, 0xb7, 0x9d, 0xba, 0x82, - 0x4e, 0xe8, 0xca, 0x8b, 0xb8, 0x50, 0xec, 0x86, 0x2f, 0x35, 0x1a, 0xca, 0x1a, 0x56, 0xf7, 0xde, - 0xed, 0x54, 0x57, 0x42, 0x83, 0x73, 0x2b, 0x8e, 0x6c, 0x96, 0x9e, 0x6f, 0x51, 0xab, 0x1a, 0x59, - 0x80, 0xee, 0x47, 0x67, 0xe9, 0x04, 0x01, 0x9b, 0xa5, 0x13, 0x40, 0x36, 0xa0, 0x64, 0x27, 0x6c, - 0x65, 0x3d, 0x3a, 0xa0, 0x64, 0x1c, 0x1b, 0x50, 0x11, 0x87, 0xed, 0x79, 0x38, 0x3e, 0x7f, 0xd7, - 0xd3, 0x7d, 0x0b, 0xd2, 0x15, 0x5d, 0xf9, 0x56, 0xec, 0x92, 0x29, 0x49, 0x82, 0x97, 0x4c, 0x49, - 0x30, 0x1b, 0x23, 0x0c, 0x5c, 0x5d, 0xb7, 0xea, 0x53, 0xba, 0xd9, 0x68, 0x3b, 0x54, 0xf9, 0xff, - 0xa2, 0x63, 0x24, 0x86, 0x66, 0x63, 0x24, 0x06, 0x62, 0x0b, 0x34, 0x03, 0x95, 0x5c, 0xd7, 0x5c, - 0xb1, 0xc4, 0xbe, 0xb2, 0xdd, 0xf0, 0x94, 0xff, 0x3f, 0xba, 0x40, 0xa7, 0xd1, 0xb0, 0x05, 0x3a, - 0x0d, 0x8e, 0xa7, 0x4e, 0x29, 0xa9, 0xd4, 0x95, 0x3f, 0x13, 0x3b, 0x75, 0x4a, 0xa1, 0xc1, 0x53, - 0xa7, 0xb4, 0x34, 0xec, 0x53, 0x30, 0xca, 0x6d, 0xb2, 0x19, 0x33, 0xb8, 0xab, 0xfe, 0xb3, 0xd1, - 0xf5, 0x31, 0x8e, 0x67, 0xeb, 0x63, 0x1c, 0x16, 0xe5, 0x23, 0xba, 0xe0, 0xcf, 0x75, 0xe2, 0x13, - 0xc8, 0x3f, 0x51, 0x86, 0x5c, 0x97, 0xf9, 0x88, 0x91, 0xf2, 0xed, 0x99, 0x4e, 0x8c, 0x82, 0xe1, - 0x91, 0x28, 0x14, 0x65, 0xa4, 0xd1, 0x7b, 0x26, 0x5d, 0x53, 0x3e, 0xd9, 0x91, 0x11, 0x27, 0x88, - 0x32, 0xe2, 0x30, 0xf2, 0x06, 0x9c, 0x0a, 0x61, 0xb3, 0xb4, 0xb9, 0x14, 0xcc, 0x4c, 0xdf, 0x91, - 0x89, 0x9a, 0xc1, 0xe9, 0x64, 0xcc, 0x0c, 0x4e, 0xc7, 0xa4, 0xb1, 0x16, 0xa2, 0xfb, 0xf3, 0x5b, - 0xb0, 0x0e, 0x24, 0xd8, 0x81, 0x41, 0x1a, 0x6b, 0x21, 0xcd, 0xef, 0xdc, 0x82, 0x75, 0x20, 0xd3, - 0x0e, 0x0c, 0xc8, 0xa7, 0x33, 0x70, 0x21, 0x1d, 0x55, 0x6a, 0x34, 0xa6, 0x6c, 0x27, 0xc4, 0x29, - 0xdf, 0x95, 0x89, 0x1e, 0x34, 0x6c, 0xaf, 0xd8, 0x74, 0x8f, 0xb6, 0xcd, 0x0a, 0xc8, 0x07, 0x61, - 0xb8, 0xd4, 0x36, 0x4c, 0x0f, 0x2f, 0xde, 0x98, 0xe1, 0xfc, 0xdd, 0x99, 0xd8, 0x16, 0x47, 0xc6, - 0xe2, 0x16, 0x47, 0x06, 0x90, 0x1b, 0x30, 0x56, 0xa5, 0xf5, 0xb6, 0x63, 0x7a, 0xeb, 0x1a, 0xa6, - 0xc9, 0x67, 0x3c, 0xbe, 0x27, 0x13, 0x9d, 0xc4, 0x12, 0x14, 0x6c, 0x12, 0x4b, 0x00, 0xc9, 0xed, - 0x0e, 0xc9, 0xd4, 0x95, 0x4f, 0x65, 0xba, 0x5e, 0xcb, 0x07, 0x7d, 0xd9, 0x21, 0x17, 0xfb, 0x42, - 0x6a, 0x72, 0x6a, 0xe5, 0xd3, 0x99, 0x2e, 0xd7, 0xe8, 0xd2, 0x0c, 0x97, 0x92, 0xd7, 0x7a, 0x21, - 0x35, 0x73, 0xb0, 0xf2, 0xbd, 0x99, 0x2e, 0xd7, 0xde, 0x21, 0xc7, 0xb4, 0xa4, 0xc3, 0xcf, 0x72, - 0x4f, 0x11, 0xc1, 0xe8, 0x2f, 0x64, 0x92, 0xae, 0x22, 0x41, 0x79, 0x89, 0x90, 0x15, 0xbb, 0xe5, - 0x06, 0x4a, 0xff, 0x99, 0x4c, 0xd2, 0x37, 0x2f, 0x2c, 0x16, 0xfe, 0x22, 0x14, 0xce, 0x4c, 0xde, - 0xf7, 0xa8, 0x63, 0xe9, 0x0d, 0xec, 0xce, 0xaa, 0x67, 0x3b, 0xfa, 0x0a, 0x9d, 0xb4, 0xf4, 0xa5, - 0x06, 0x55, 0x3e, 0x9b, 0x89, 0x5a, 0xb0, 0x9d, 0x49, 0x99, 0x05, 0xdb, 0x19, 0x4b, 0x56, 0xe1, - 0xe1, 0x34, 0x6c, 0xd9, 0x74, 0xb1, 0x9e, 0xcf, 0x65, 0xa2, 0x26, 0x6c, 0x17, 0x5a, 0x66, 0xc2, - 0x76, 0x41, 0x93, 0xab, 0x30, 0x30, 0x6e, 0xfb, 0xd3, 0xef, 0x5f, 0x8c, 0x39, 0x43, 0x06, 0x98, - 0xe9, 0x1e, 0x2d, 0x24, 0x13, 0x65, 0xc4, 0xa0, 0xfe, 0x7c, 0xb2, 0x4c, 0x78, 0xf9, 0x14, 0xfc, - 0x10, 0x65, 0x84, 0xb8, 0xff, 0x52, 0xb2, 0x4c, 0x78, 0xc7, 0x15, 0xfc, 0x60, 0x33, 0x09, 0xaf, - 0x71, 0x76, 0xaa, 0xc4, 0xec, 0xb6, 0x89, 0x55, 0xbd, 0xd1, 0xa0, 0xd6, 0x0a, 0x55, 0xbe, 0x10, - 0x9b, 0x49, 0xd2, 0xc9, 0xd8, 0x4c, 0x92, 0x8e, 0x21, 0x1f, 0x85, 0xd3, 0xb7, 0xf5, 0x86, 0x69, - 0x84, 0x38, 0x3f, 0x8f, 0xac, 0xf2, 0x7d, 0x99, 0xe8, 0x6e, 0xba, 0x03, 0x1d, 0xdb, 0x4d, 0x77, - 0x40, 0x91, 0x59, 0x20, 0xb8, 0x8c, 0x06, 0xb3, 0x05, 0x5b, 0x9f, 0x95, 0xbf, 0x9c, 0x89, 0xda, - 0xa9, 0x49, 0x12, 0x66, 0xa7, 0x26, 0xa1, 0xa4, 0xd6, 0x39, 0x20, 0xbd, 0xf2, 0xfd, 0x99, 0xe8, - 0x69, 0x4d, 0x27, 0xc2, 0xe9, 0x1e, 0xad, 0x73, 0x54, 0xfb, 0xeb, 0x30, 0x5a, 0x5d, 0xa8, 0x4c, - 0x4d, 0x4d, 0x56, 0x6f, 0x57, 0xca, 0xe8, 0xbe, 0x6b, 0x28, 0x3f, 0x10, 0x5b, 0xb1, 0xe2, 0x04, - 0x6c, 0xc5, 0x8a, 0xc3, 0xc8, 0x4b, 0x30, 0xc4, 0xda, 0xcf, 0x06, 0x0c, 0x7e, 0xf2, 0x17, 0x33, - 0x51, 0x73, 0x4a, 0x46, 0x32, 0x73, 0x4a, 0xfe, 0x4d, 0xaa, 0x70, 0x82, 0x49, 0x71, 0xc1, 0xa1, - 0xcb, 0xd4, 0xa1, 0x56, 0xdd, 0x1f, 0xd3, 0x3f, 0x98, 0x89, 0x5a, 0x19, 0x69, 0x44, 0xcc, 0xca, - 0x48, 0x83, 0x93, 0xbb, 0x70, 0x36, 0x7e, 0x12, 0x24, 0x3f, 0xa6, 0x52, 0x7e, 0x28, 0x13, 0x33, - 0x86, 0xbb, 0x10, 0xa3, 0x31, 0xdc, 0x05, 0x4f, 0x2c, 0x38, 0x27, 0x8e, 0x55, 0x84, 0xc3, 0x65, - 0xbc, 0xb6, 0xbf, 0xc2, 0x6b, 0x7b, 0x3c, 0x74, 0x08, 0xec, 0x42, 0x3d, 0xdd, 0xa3, 0x75, 0x67, - 0xc7, 0xf4, 0x2c, 0x19, 0x76, 0x5d, 0xf9, 0xe1, 0x4c, 0xba, 0x47, 0x4a, 0xc4, 0x4d, 0x39, 0x2d, - 0x5e, 0xfb, 0x1b, 0x9d, 0x82, 0x86, 0x2b, 0x3f, 0x12, 0x1b, 0x6f, 0xe9, 0x64, 0x6c, 0xbc, 0x75, - 0x88, 0x3a, 0x7e, 0x03, 0xc6, 0xb8, 0x52, 0x2f, 0xe8, 0x38, 0x0c, 0xad, 0x15, 0x6a, 0x28, 0x7f, - 0x35, 0xb6, 0xda, 0x25, 0x28, 0xd0, 0xb5, 0x27, 0x0e, 0x64, 0x53, 0x77, 0xb5, 0xa5, 0x5b, 0x16, - 0x1e, 0xb3, 0x2a, 0x7f, 0x2d, 0x36, 0x75, 0x87, 0x28, 0x74, 0xdc, 0x0d, 0x7e, 0x31, 0x4d, 0xe8, - 0x96, 0x70, 0x43, 0xf9, 0xd1, 0x98, 0x26, 0x74, 0x23, 0x66, 0x9a, 0xd0, 0x35, 0x7b, 0xc7, 0xed, - 0x0e, 0x0f, 0x1b, 0x95, 0x2f, 0xc5, 0x56, 0xe4, 0x54, 0x2a, 0xb6, 0x22, 0xa7, 0xbf, 0x8b, 0xbc, - 0xdd, 0xe1, 0x51, 0xa0, 0xf2, 0x63, 0xdd, 0xf9, 0x86, 0x2b, 0x7d, 0xfa, 0x9b, 0xc2, 0xdb, 0x1d, - 0x1e, 0xd4, 0x29, 0x3f, 0xde, 0x9d, 0x6f, 0xe8, 0xd8, 0x97, 0xfe, 0x1e, 0xaf, 0xd6, 0xf9, 0x31, - 0x9a, 0xf2, 0x13, 0xf1, 0xa9, 0xab, 0x03, 0x21, 0x4e, 0x5d, 0x9d, 0x5e, 0xb4, 0xdd, 0x48, 0x79, - 0x12, 0xa6, 0xfc, 0x64, 0x4c, 0xb1, 0x12, 0x14, 0x4c, 0xb1, 0x92, 0x2f, 0xc9, 0x6e, 0xa4, 0xbc, - 0x7c, 0x52, 0xfe, 0x7a, 0x67, 0x5e, 0x81, 0x50, 0x53, 0x1e, 0x4c, 0xdd, 0x48, 0x79, 0xe0, 0xa3, - 0xfc, 0x8d, 0xce, 0xbc, 0x42, 0xff, 0xa0, 0x04, 0x70, 0xbc, 0x0f, 0x7a, 0x71, 0xc7, 0xa9, 0x7e, - 0x29, 0x03, 0x43, 0x55, 0xcf, 0xa1, 0x7a, 0x53, 0x44, 0x7b, 0x38, 0x03, 0xfd, 0xdc, 0x75, 0xcb, - 0x7f, 0x3d, 0xa1, 0x05, 0xbf, 0xc9, 0x05, 0x18, 0x99, 0xd1, 0x5d, 0x0f, 0x4b, 0x56, 0x2c, 0x83, - 0xde, 0xc7, 0x67, 0x0b, 0x39, 0x2d, 0x06, 0x25, 0x33, 0x9c, 0x8e, 0x97, 0xc3, 0xd8, 0x3c, 0xb9, - 0x2d, 0x83, 0x1c, 0xf4, 0xbf, 0xbd, 0x51, 0xec, 0xc1, 0x98, 0x06, 0xb1, 0xb2, 0xea, 0xd7, 0x32, - 0x90, 0x70, 0x2a, 0xdb, 0xfd, 0xab, 0xa6, 0x79, 0x38, 0x16, 0x8b, 0x07, 0x25, 0xde, 0x5e, 0x6c, - 0x33, 0x5c, 0x54, 0xbc, 0x34, 0x79, 0x6f, 0xe0, 0xf3, 0x7f, 0x4b, 0x9b, 0x11, 0x01, 0x2c, 0xfa, - 0x36, 0x37, 0x8a, 0xb9, 0xb6, 0xd3, 0xd0, 0x24, 0x94, 0x78, 0xa0, 0xfc, 0x77, 0x47, 0xc3, 0x60, - 0x37, 0xe4, 0x82, 0x78, 0x62, 0x95, 0x09, 0xc3, 0x5e, 0xc4, 0x52, 0x29, 0xf2, 0x27, 0x55, 0x1f, - 0x84, 0xa1, 0x4a, 0xb3, 0x45, 0x1d, 0xd7, 0xb6, 0x74, 0xcf, 0xf6, 0x53, 0xb6, 0x63, 0x48, 0x04, - 0x53, 0x82, 0xcb, 0xcf, 0xf4, 0x65, 0x7a, 0x72, 0xc9, 0xcf, 0xee, 0x90, 0xc3, 0x30, 0x43, 0x18, - 0x2b, 0x33, 0x9e, 0x9e, 0x8f, 0x53, 0x30, 0xd2, 0x5b, 0xae, 0x8e, 0xaf, 0x43, 0x02, 0xd2, 0x36, - 0x03, 0xc8, 0xa4, 0x48, 0x41, 0x9e, 0x84, 0x02, 0x9e, 0xa6, 0xb9, 0x98, 0xb5, 0x45, 0x04, 0xe3, - 0x68, 0x20, 0x44, 0x0e, 0x7d, 0xc0, 0x69, 0xc8, 0x4d, 0x18, 0x0d, 0xaf, 0x0a, 0xae, 0x3b, 0x76, - 0xbb, 0xe5, 0xc7, 0x69, 0xc6, 0xb4, 0x86, 0x77, 0x03, 0x5c, 0x6d, 0x05, 0x91, 0x12, 0x8b, 0x44, - 0x41, 0x32, 0x0d, 0xc7, 0x42, 0x18, 0x13, 0x91, 0x1f, 0x1f, 0x1e, 0x73, 0xf3, 0x48, 0xbc, 0x98, - 0x38, 0x23, 0xb9, 0x79, 0x62, 0xc5, 0x48, 0x05, 0xfa, 0xfc, 0x48, 0x1c, 0xfd, 0x5b, 0x2a, 0xe9, - 0x71, 0x11, 0x89, 0xa3, 0x4f, 0x8e, 0xc1, 0xe1, 0x97, 0x27, 0x53, 0x30, 0xa2, 0xd9, 0x6d, 0x8f, - 0x2e, 0xda, 0x62, 0x8d, 0x15, 0x01, 0x84, 0xb1, 0x4d, 0x0e, 0xc3, 0xd4, 0x3c, 0xdb, 0xcf, 0x0a, - 0x29, 0x67, 0x27, 0x8c, 0x96, 0x22, 0x73, 0x30, 0x96, 0xb8, 0x54, 0x91, 0x73, 0x35, 0x4a, 0x9f, - 0x97, 0x64, 0x96, 0x2c, 0x4a, 0xbe, 0x3b, 0x03, 0x85, 0x45, 0x47, 0x37, 0x3d, 0x57, 0x3c, 0x2c, - 0x39, 0x79, 0x79, 0xcd, 0xd1, 0x5b, 0x4c, 0x3f, 0x2e, 0x63, 0x1c, 0xa9, 0xdb, 0x7a, 0xa3, 0x4d, - 0xdd, 0xf1, 0x3b, 0xec, 0xeb, 0xfe, 0xcd, 0x46, 0xf1, 0xa5, 0x15, 0xdc, 0xba, 0x5d, 0xae, 0xdb, - 0xcd, 0x2b, 0x2b, 0x8e, 0x7e, 0xcf, 0xf4, 0x70, 0xea, 0xd0, 0x1b, 0x57, 0x3c, 0xda, 0xc0, 0x1d, - 0xe2, 0x15, 0xbd, 0x65, 0x5e, 0xc1, 0x78, 0x85, 0x57, 0x02, 0x4e, 0xbc, 0x06, 0xa6, 0x02, 0x1e, - 0xfe, 0x25, 0xab, 0x00, 0xc7, 0x91, 0x39, 0xb6, 0xb1, 0xc2, 0x4f, 0x2d, 0xb5, 0x5a, 0xe2, 0x95, - 0x8a, 0xb4, 0xaf, 0xf2, 0x31, 0x5c, 0xb1, 0x03, 0x81, 0xe9, 0xad, 0x96, 0x9c, 0x0d, 0x36, 0xa4, - 0x63, 0x5a, 0xb0, 0x28, 0x5a, 0xe4, 0x8b, 0x69, 0x38, 0x94, 0xb8, 0xdf, 0xd8, 0x14, 0x21, 0xc5, - 0x8b, 0x91, 0x25, 0x38, 0x26, 0xf8, 0x06, 0x11, 0x7d, 0x47, 0xa2, 0xb3, 0x42, 0x0c, 0xcd, 0x95, - 0x36, 0x68, 0xa3, 0x21, 0xc0, 0x72, 0x1d, 0xb1, 0x12, 0x64, 0x3c, 0x4c, 0x33, 0x36, 0xa7, 0x37, - 0xa9, 0xab, 0x1c, 0x43, 0x8d, 0x3d, 0xbb, 0xb9, 0x51, 0x54, 0xfc, 0xf2, 0x18, 0x94, 0x26, 0x35, - 0x69, 0x26, 0x16, 0x91, 0x79, 0x70, 0xad, 0x1f, 0x4d, 0xe1, 0x11, 0xd7, 0xf9, 0x68, 0x11, 0x32, - 0x01, 0xc3, 0x81, 0x93, 0xec, 0xad, 0x5b, 0x95, 0x32, 0x3e, 0x83, 0x19, 0x18, 0x3f, 0xb7, 0xb9, - 0x51, 0x7c, 0x28, 0x16, 0x73, 0x57, 0x66, 0x12, 0x29, 0x23, 0xbd, 0x97, 0xe3, 0xef, 0x62, 0x62, - 0xef, 0xe5, 0x5a, 0x29, 0xef, 0xe5, 0x16, 0xc8, 0x2b, 0x30, 0x58, 0xba, 0x53, 0x15, 0xef, 0x00, - 0x5d, 0xe5, 0x78, 0x18, 0xa5, 0x1d, 0xf3, 0xa6, 0x8a, 0x37, 0x83, 0x72, 0xd3, 0x65, 0x7a, 0x32, - 0x09, 0x23, 0x91, 0x7b, 0x76, 0x57, 0x39, 0x81, 0x1c, 0xb0, 0xe5, 0x3a, 0x62, 0x6a, 0x8e, 0x40, - 0x45, 0x32, 0xf9, 0x46, 0x0a, 0x31, 0xad, 0x61, 0x5b, 0xd5, 0x46, 0xc3, 0x5e, 0xd3, 0x28, 0x3e, - 0x39, 0xc4, 0x47, 0x35, 0xfd, 0x5c, 0x6b, 0x0c, 0x81, 0xaa, 0x39, 0x1c, 0x17, 0x49, 0xdd, 0x1b, - 0x2d, 0x46, 0xde, 0x04, 0x82, 0x31, 0xb2, 0xa9, 0xe1, 0x1f, 0xbb, 0x56, 0xca, 0xae, 0x72, 0x0a, - 0xe3, 0xe9, 0x91, 0xf8, 0x9b, 0xd7, 0x4a, 0x79, 0xfc, 0x82, 0x98, 0x3e, 0xce, 0xeb, 0xbc, 0x54, - 0xcd, 0x11, 0xb8, 0x9a, 0x19, 0x49, 0x20, 0x96, 0xc2, 0x95, 0xac, 0xc1, 0xe9, 0x05, 0x87, 0xde, - 0x33, 0xed, 0xb6, 0xeb, 0x2f, 0x1f, 0xfe, 0xbc, 0x75, 0x7a, 0xcb, 0x79, 0xeb, 0x51, 0x51, 0xf1, - 0xc9, 0x96, 0x43, 0xef, 0xd5, 0xfc, 0x28, 0x6a, 0x91, 0x48, 0x42, 0x9d, 0xb8, 0x63, 0x1a, 0xb4, - 0xb7, 0xda, 0x0e, 0x15, 0x70, 0x93, 0xba, 0x8a, 0x12, 0x4e, 0xb5, 0xfc, 0xf5, 0xa8, 0x19, 0xe0, - 0x22, 0x69, 0xd0, 0xa2, 0xc5, 0x88, 0x06, 0xe4, 0xfa, 0x84, 0x7f, 0x04, 0x5f, 0xaa, 0xf3, 0x64, - 0x51, 0xca, 0x43, 0xc8, 0x4c, 0x65, 0x62, 0x59, 0xa9, 0x07, 0x11, 0x15, 0x6b, 0xba, 0xc0, 0xcb, - 0x62, 0x49, 0x96, 0x26, 0x33, 0x30, 0xba, 0xe0, 0xe0, 0x86, 0xe0, 0x26, 0x5d, 0x5f, 0xb0, 0x1b, - 0x66, 0x7d, 0x1d, 0xdf, 0xf6, 0x88, 0xa9, 0xb2, 0xc5, 0x71, 0xb5, 0xbb, 0x74, 0xbd, 0xd6, 0x42, - 0xac, 0xbc, 0xac, 0xc4, 0x4b, 0xca, 0x11, 0xce, 0x1e, 0xde, 0x5e, 0x84, 0x33, 0x0a, 0xa3, 0xe2, - 0x00, 0xff, 0xbe, 0x47, 0x2d, 0xb6, 0xd4, 0xbb, 0xe2, 0x1d, 0x8f, 0x12, 0x3b, 0xf0, 0x0f, 0xf0, - 0x22, 0x8d, 0x2f, 0x1f, 0x65, 0x34, 0x00, 0xcb, 0x0d, 0x8b, 0x17, 0x51, 0x3f, 0x97, 0x93, 0xa7, - 0x4e, 0x72, 0x16, 0xf2, 0x52, 0x80, 0x6d, 0x8c, 0x71, 0x84, 0xc1, 0x08, 0xf3, 0x22, 0xea, 0xda, - 0x80, 0x30, 0x3b, 0x82, 0xc7, 0xac, 0x98, 0x36, 0x25, 0x8c, 0x7b, 0xa3, 0x85, 0x04, 0x98, 0xb2, - 0xa2, 0xbd, 0xd4, 0x30, 0xeb, 0x18, 0xa2, 0x32, 0x27, 0xa5, 0xac, 0x40, 0x28, 0x8f, 0x50, 0x29, - 0x91, 0x90, 0xab, 0x30, 0xe8, 0xef, 0x21, 0xc3, 0x18, 0x5f, 0x18, 0xb9, 0xd0, 0x4f, 0x78, 0xcc, - 0x03, 0x23, 0x4a, 0x44, 0xe4, 0x45, 0x4c, 0xf9, 0xed, 0x3f, 0x14, 0xee, 0x0d, 0xcd, 0x17, 0x79, - 0xe0, 0xc7, 0x72, 0x7e, 0xfb, 0xef, 0x85, 0xc7, 0x61, 0x58, 0xd6, 0x24, 0x3f, 0x49, 0x0f, 0xce, - 0x79, 0x11, 0xf5, 0x93, 0xfb, 0x36, 0x5a, 0x84, 0xcc, 0xc3, 0x58, 0x42, 0x79, 0x44, 0x44, 0x30, - 0x4c, 0xd4, 0x98, 0xa2, 0x79, 0xf2, 0x9a, 0x9a, 0x28, 0xab, 0x7e, 0x47, 0x36, 0xb1, 0x62, 0x30, - 0xc1, 0x08, 0x2a, 0xa9, 0x73, 0x50, 0x30, 0x3e, 0x6b, 0x2e, 0x18, 0x89, 0x88, 0x5c, 0x84, 0xfe, - 0x58, 0xd6, 0x6f, 0x7c, 0x3a, 0x1e, 0xa4, 0xfc, 0x0e, 0xb0, 0xe4, 0xaa, 0x94, 0x36, 0x4a, 0x0a, - 0xbf, 0xe7, 0xa7, 0x8d, 0x8a, 0xc7, 0xa1, 0xc3, 0x04, 0x52, 0x57, 0x63, 0x11, 0xea, 0xfd, 0xe4, - 0xcc, 0xc9, 0xd5, 0x2a, 0x8c, 0x48, 0x1f, 0xd8, 0x8a, 0xbd, 0x5b, 0xd9, 0x8a, 0xea, 0xaf, 0x64, - 0x92, 0xda, 0x4f, 0xae, 0x25, 0xc3, 0x69, 0xf1, 0xbc, 0xcc, 0x3e, 0x50, 0xae, 0x35, 0x08, 0xac, - 0x15, 0x09, 0x8c, 0x95, 0xdd, 0x75, 0x60, 0xac, 0xdc, 0x0e, 0x03, 0x63, 0xa9, 0xff, 0x3b, 0xdf, - 0xd5, 0x0d, 0xec, 0x40, 0x02, 0x28, 0xbc, 0xc0, 0xf6, 0x3b, 0xac, 0xf6, 0x92, 0x9b, 0xb0, 0xda, - 0xb9, 0x97, 0x4b, 0x4d, 0xe7, 0xa3, 0xc6, 0xd5, 0xa2, 0x94, 0xe4, 0x55, 0x18, 0xf2, 0x3f, 0x00, - 0x03, 0xae, 0x49, 0x81, 0xc2, 0x82, 0xb5, 0x26, 0x9e, 0x5a, 0x5b, 0x2e, 0x40, 0x9e, 0x85, 0x01, - 0xb4, 0x34, 0x5a, 0x7a, 0xdd, 0x8f, 0xc6, 0xc7, 0xc3, 0xf7, 0xf9, 0x40, 0x39, 0x48, 0x40, 0x40, - 0x49, 0x3e, 0x06, 0x85, 0x48, 0x6e, 0xf7, 0x2b, 0xdb, 0xf0, 0x9b, 0xbb, 0x2c, 0x47, 0x92, 0xe5, - 0x7b, 0x87, 0x78, 0x5e, 0x77, 0xc1, 0x94, 0x2c, 0xc2, 0xf1, 0x05, 0x87, 0x1a, 0xe8, 0xa1, 0x39, - 0x79, 0xbf, 0xe5, 0x88, 0x38, 0xbf, 0x7c, 0x00, 0xe3, 0xd2, 0xd1, 0xf2, 0xd1, 0x6c, 0x51, 0x13, - 0x78, 0x39, 0x24, 0x58, 0x4a, 0x71, 0x66, 0x4f, 0xf0, 0x96, 0xdc, 0xa4, 0xeb, 0x6b, 0x98, 0xdf, - 0xb3, 0x3f, 0xb4, 0x27, 0x84, 0xa0, 0xef, 0x0a, 0x94, 0x6c, 0x4f, 0x44, 0x0b, 0x9d, 0x79, 0x01, - 0x06, 0x77, 0x1b, 0x8d, 0xf5, 0xe7, 0xb3, 0x1d, 0x1c, 0xaa, 0x1f, 0xdc, 0x84, 0x18, 0x41, 0x2a, - 0xb6, 0xde, 0x0e, 0xa9, 0xd8, 0xbe, 0x99, 0xed, 0xe0, 0x2d, 0xfe, 0x40, 0xa7, 0x4c, 0x0a, 0x84, - 0x11, 0x4d, 0x99, 0x14, 0x66, 0xab, 0x32, 0x0d, 0x4d, 0x26, 0x8a, 0x25, 0x57, 0x2b, 0x6c, 0x99, - 0x5c, 0xed, 0xa7, 0x72, 0xdd, 0xbc, 0xe9, 0x8f, 0x64, 0xbf, 0x13, 0xd9, 0x5f, 0x85, 0xc1, 0x40, - 0xb2, 0x95, 0x32, 0xda, 0x33, 0xc3, 0x41, 0xec, 0x67, 0x0e, 0xc6, 0x32, 0x12, 0x11, 0xb9, 0xc4, - 0xdb, 0x5a, 0x35, 0xdf, 0xe2, 0xa1, 0x4c, 0x87, 0x45, 0x90, 0x4a, 0xdd, 0xd3, 0x6b, 0xae, 0xf9, - 0x16, 0xd5, 0x02, 0xb4, 0xfa, 0x8f, 0xb2, 0xa9, 0x4f, 0x12, 0x8e, 0xfa, 0x68, 0x07, 0x7d, 0x94, - 0x22, 0x44, 0xfe, 0x98, 0xe2, 0x48, 0x88, 0x3b, 0x10, 0xe2, 0x1f, 0x64, 0x53, 0x9f, 0x9e, 0x1c, - 0x09, 0x71, 0x27, 0xb3, 0xc5, 0x93, 0x30, 0xa0, 0xd9, 0x6b, 0x2e, 0x66, 0x52, 0x16, 0x73, 0x05, - 0x4e, 0xd4, 0x8e, 0xbd, 0xe6, 0xf2, 0x2c, 0xd3, 0x5a, 0x48, 0xa0, 0xfe, 0x51, 0xb6, 0xcb, 0xe3, - 0x9c, 0x23, 0xc1, 0xbf, 0x93, 0x4b, 0xe4, 0x2f, 0x66, 0x23, 0x8f, 0x7f, 0x1e, 0xe8, 0xdc, 0xa3, - 0xd5, 0xfa, 0x2a, 0x6d, 0xea, 0xf1, 0xdc, 0xa3, 0x2e, 0x42, 0x45, 0x06, 0xb0, 0x90, 0x44, 0xfd, - 0x72, 0x36, 0xf6, 0xfa, 0xe9, 0x48, 0x76, 0xdb, 0x96, 0x5d, 0xa0, 0x75, 0xe2, 0x41, 0xd7, 0x91, - 0xe4, 0xb6, 0x2b, 0xb9, 0x4f, 0x65, 0x63, 0x6f, 0xdf, 0x1e, 0x58, 0xd9, 0xb1, 0x01, 0x98, 0x7c, - 0x93, 0xf7, 0xc0, 0x6a, 0xd2, 0x93, 0x30, 0x20, 0xe4, 0x10, 0x2c, 0x15, 0x7c, 0xde, 0xe7, 0x40, - 0x3c, 0x40, 0x0d, 0x08, 0xd4, 0xef, 0xca, 0x42, 0xf4, 0x4d, 0xe2, 0x03, 0xaa, 0x43, 0xbf, 0x98, - 0x8d, 0xbe, 0xc6, 0x7c, 0x70, 0xf5, 0xe7, 0x32, 0x40, 0xb5, 0xbd, 0x54, 0x17, 0xc1, 0xfc, 0x7a, - 0xa5, 0x13, 0xf8, 0x00, 0xaa, 0x49, 0x14, 0xea, 0xff, 0xc9, 0xa6, 0x3e, 0x11, 0x7d, 0x70, 0x05, - 0xf8, 0x0c, 0x9e, 0x8a, 0xd7, 0xad, 0x70, 0x22, 0xc7, 0x43, 0x48, 0x36, 0xfe, 0x12, 0x39, 0x44, - 0x7c, 0x42, 0xf2, 0x81, 0x14, 0x73, 0x0d, 0x23, 0x9c, 0x86, 0xe6, 0x9a, 0x7c, 0xc3, 0x20, 0x19, - 0x6e, 0xff, 0x3c, 0xbb, 0xd5, 0x8b, 0xda, 0x07, 0x79, 0x55, 0xed, 0x5b, 0xd0, 0xd7, 0x31, 0xf2, - 0x13, 0xeb, 0x89, 0x21, 0x9e, 0xe1, 0xa2, 0xc5, 0x41, 0xf2, 0x8d, 0x98, 0xa0, 0x52, 0x7f, 0xbf, - 0x37, 0xfd, 0x39, 0xe7, 0x83, 0x2b, 0xc2, 0xb3, 0x90, 0x5f, 0xd0, 0xbd, 0x55, 0xa1, 0xc9, 0x78, - 0x5b, 0xd7, 0xd2, 0xbd, 0x55, 0x0d, 0xa1, 0xe4, 0x12, 0xf4, 0x6b, 0xfa, 0x1a, 0x3f, 0xf3, 0x2c, - 0x84, 0xd9, 0x47, 0x1c, 0x7d, 0xad, 0xc6, 0xcf, 0x3d, 0x03, 0x34, 0x51, 0x83, 0xec, 0x37, 0xfc, - 0xe4, 0x1b, 0x53, 0x2f, 0xf0, 0xec, 0x37, 0x41, 0xce, 0x9b, 0xb3, 0x90, 0x1f, 0xb7, 0x8d, 0x75, - 0x74, 0x66, 0x19, 0xe2, 0x95, 0x2d, 0xd9, 0xc6, 0xba, 0x86, 0x50, 0xf2, 0xe9, 0x0c, 0xf4, 0x4d, - 0x53, 0xdd, 0x60, 0x23, 0x64, 0xa0, 0x9b, 0x2f, 0xc8, 0x87, 0xf6, 0xc7, 0x17, 0x64, 0x6c, 0x95, - 0x57, 0x26, 0x2b, 0x8a, 0xa8, 0x9f, 0x5c, 0x87, 0xfe, 0x09, 0xdd, 0xa3, 0x2b, 0xb6, 0xb3, 0x8e, - 0xde, 0x2d, 0x23, 0xa1, 0x4b, 0x60, 0x44, 0x7f, 0x7c, 0x22, 0x7e, 0x33, 0x56, 0x17, 0xbf, 0xb4, - 0xa0, 0x30, 0x13, 0x8b, 0x48, 0xa5, 0x39, 0x18, 0x8a, 0x85, 0xe7, 0xcc, 0x0c, 0x32, 0x66, 0x06, - 0xc7, 0xca, 0x43, 0xe9, 0xc7, 0xca, 0x68, 0x3d, 0xa2, 0x07, 0x1c, 0xe6, 0x9c, 0x19, 0xc6, 0x45, - 0x9f, 0x5b, 0x8f, 0x08, 0xc5, 0x94, 0x33, 0x9a, 0x44, 0xa2, 0x7e, 0xbd, 0x17, 0x52, 0x1f, 0x7f, - 0x1d, 0x29, 0xf9, 0x91, 0x92, 0x87, 0x4a, 0x5e, 0x4e, 0x28, 0xf9, 0x99, 0xe4, 0x73, 0xc2, 0x77, - 0xa9, 0x86, 0x7f, 0x31, 0x9f, 0x78, 0x8c, 0xfc, 0x60, 0xef, 0x2e, 0x43, 0xe9, 0xf5, 0x6e, 0x29, - 0xbd, 0x60, 0x40, 0x14, 0xb6, 0x1c, 0x10, 0x7d, 0xdb, 0x1d, 0x10, 0xfd, 0x1d, 0x07, 0x44, 0xa8, - 0x20, 0x03, 0x1d, 0x15, 0xa4, 0x22, 0x06, 0x0d, 0x74, 0xcf, 0x67, 0x76, 0x76, 0x73, 0xa3, 0x38, - 0xc2, 0x46, 0x53, 0x6a, 0x26, 0x33, 0x64, 0xa1, 0x7e, 0x2d, 0xdf, 0x25, 0x82, 0xc0, 0x81, 0xe8, - 0xc8, 0x33, 0x90, 0x2b, 0xb5, 0x5a, 0x42, 0x3f, 0x8e, 0x4b, 0xc1, 0x0b, 0x3a, 0x94, 0x62, 0xd4, - 0xe4, 0x45, 0xc8, 0x95, 0xee, 0x54, 0xe3, 0x71, 0xd0, 0x4b, 0x77, 0xaa, 0xe2, 0x4b, 0x3a, 0x96, - 0xbd, 0x53, 0x25, 0x2f, 0x87, 0x01, 0xc9, 0x56, 0xdb, 0xd6, 0x5d, 0xb1, 0x51, 0x14, 0x4e, 0xb0, - 0xbe, 0xa7, 0x4d, 0x9d, 0xa1, 0xd8, 0x76, 0x31, 0x46, 0x1b, 0xd3, 0xa6, 0xc2, 0xf6, 0xb5, 0xa9, - 0x6f, 0x4b, 0x6d, 0xea, 0xdf, 0xae, 0x36, 0x0d, 0x6c, 0x43, 0x9b, 0x60, 0x4b, 0x6d, 0x1a, 0xdc, - 0xbb, 0x36, 0xb5, 0xe0, 0x4c, 0x32, 0xea, 0x4b, 0xa0, 0x11, 0x1a, 0x90, 0x24, 0x56, 0x38, 0x96, - 0xe0, 0xd5, 0x7f, 0x9b, 0x63, 0x6b, 0x3c, 0xe5, 0x6d, 0x3c, 0x61, 0xac, 0x96, 0x52, 0x5a, 0xfd, - 0xf9, 0x6c, 0xe7, 0x60, 0x35, 0x87, 0x73, 0x8a, 0xfb, 0xb6, 0x54, 0x29, 0xe5, 0xa3, 0x8f, 0x07, - 0x3b, 0x4b, 0x39, 0xc6, 0x36, 0x4d, 0x66, 0x5f, 0xcd, 0x74, 0x8a, 0xa0, 0xb3, 0x27, 0x89, 0x3d, - 0x9e, 0x74, 0x56, 0x43, 0xef, 0x79, 0x37, 0xea, 0xa5, 0x16, 0xcf, 0xa0, 0x9a, 0xdb, 0x65, 0x06, - 0xd5, 0x5f, 0xc9, 0xc0, 0xf1, 0x9b, 0xed, 0x25, 0x2a, 0x9c, 0xd3, 0x82, 0x66, 0xbc, 0x09, 0xc0, - 0xc0, 0xc2, 0x89, 0x25, 0x83, 0x4e, 0x2c, 0xef, 0x93, 0xa3, 0xdf, 0xc4, 0x0a, 0x5c, 0x0e, 0xa9, - 0xb9, 0x03, 0xcb, 0x39, 0xdf, 0xc5, 0xf2, 0x6e, 0x7b, 0x89, 0xd6, 0x12, 0x9e, 0x2c, 0x12, 0xf7, - 0x33, 0xaf, 0x70, 0xe7, 0xf5, 0xdd, 0x3a, 0x8d, 0xfc, 0x6c, 0xb6, 0x63, 0xc0, 0xa1, 0x43, 0x9b, - 0xef, 0xe5, 0x23, 0xa9, 0xbd, 0x12, 0xcf, 0xfb, 0x92, 0x42, 0x12, 0xe3, 0x98, 0xc6, 0x25, 0x5d, - 0x60, 0x87, 0x3c, 0x0b, 0xd1, 0x3b, 0x2a, 0xb0, 0xdf, 0xcc, 0x74, 0x0c, 0x0c, 0x75, 0x58, 0x05, - 0xa6, 0xfe, 0xc7, 0x9c, 0x1f, 0x8f, 0x6a, 0x4f, 0x9f, 0xf0, 0x24, 0x0c, 0x88, 0x67, 0x79, 0x51, - 0xdf, 0x5a, 0x71, 0x94, 0x87, 0x47, 0xc3, 0x01, 0x01, 0x5b, 0xe6, 0xfd, 0x78, 0x39, 0x41, 0xfa, - 0x5c, 0x5c, 0xe6, 0x4d, 0x01, 0x65, 0xf4, 0x12, 0x09, 0x5b, 0xc8, 0x27, 0xef, 0x9b, 0x1e, 0x5a, - 0x05, 0xac, 0x2f, 0x73, 0x7c, 0x21, 0xa7, 0xf7, 0x4d, 0x8f, 0xdb, 0x04, 0x01, 0x9a, 0x2d, 0xd2, - 0xd5, 0x30, 0xc7, 0xa2, 0x58, 0xa4, 0x5d, 0x91, 0x6a, 0x52, 0x3c, 0xe6, 0x7a, 0x12, 0x06, 0x84, - 0xc3, 0xaa, 0x70, 0x33, 0x11, 0xad, 0x15, 0x2e, 0xae, 0xd8, 0xda, 0x80, 0x80, 0x71, 0xd4, 0xe8, - 0x4a, 0xe8, 0x58, 0x87, 0x1c, 0x1d, 0x84, 0x68, 0x02, 0x43, 0xae, 0xc2, 0x48, 0xd5, 0xd3, 0x2d, - 0x43, 0x77, 0x8c, 0xf9, 0xb6, 0xd7, 0x6a, 0x7b, 0xb2, 0x51, 0xea, 0x7a, 0x86, 0xdd, 0xf6, 0xb4, - 0x18, 0x05, 0x79, 0x3f, 0x0c, 0xfb, 0x90, 0x49, 0xc7, 0xb1, 0x1d, 0xd9, 0xf2, 0x70, 0x3d, 0x83, - 0x3a, 0x8e, 0x16, 0x25, 0x20, 0x1f, 0x80, 0xe1, 0x8a, 0x75, 0xcf, 0xe6, 0xc9, 0x3b, 0x6f, 0x69, - 0x33, 0xc2, 0x0e, 0xc1, 0x07, 0x52, 0x66, 0x80, 0xa8, 0xb5, 0x9d, 0x86, 0x16, 0x25, 0x54, 0x37, - 0xb3, 0xc9, 0xb0, 0x5d, 0x0f, 0xee, 0xa6, 0xe5, 0x52, 0xd4, 0x99, 0x0e, 0x3d, 0x48, 0xd1, 0x20, - 0x94, 0x7d, 0x79, 0xb9, 0x5d, 0x78, 0x15, 0xfa, 0x6f, 0xd2, 0x75, 0xee, 0xf7, 0x59, 0x08, 0x5d, - 0x85, 0xef, 0x0a, 0x98, 0x7c, 0xe2, 0xea, 0xd3, 0xa9, 0x5f, 0xc9, 0x26, 0x03, 0x92, 0x3d, 0xb8, - 0xc2, 0x7e, 0x3f, 0xf4, 0xa1, 0x28, 0x2b, 0xfe, 0x91, 0x3f, 0x0a, 0x10, 0xc5, 0x1d, 0xf5, 0x40, - 0xf6, 0xc9, 0xd4, 0x1f, 0x2b, 0xc4, 0xa3, 0xd4, 0x3d, 0xb8, 0xd2, 0x7b, 0x09, 0x06, 0x27, 0x6c, - 0xcb, 0x35, 0x5d, 0x8f, 0x5a, 0x75, 0x5f, 0x61, 0x1f, 0x62, 0x06, 0x55, 0x3d, 0x04, 0xcb, 0x2f, - 0x83, 0x24, 0xea, 0xdd, 0x28, 0x2f, 0x79, 0x0e, 0x06, 0x50, 0xe4, 0xe8, 0x27, 0x2d, 0x25, 0x07, - 0x5f, 0x62, 0xc0, 0xb8, 0x93, 0x74, 0x48, 0x4a, 0x6e, 0x41, 0xff, 0xc4, 0xaa, 0xd9, 0x30, 0x1c, - 0x6a, 0xa1, 0xbf, 0xb0, 0x14, 0x2b, 0x2f, 0xda, 0x97, 0x97, 0xf1, 0x5f, 0xa4, 0xe5, 0xcd, 0xa9, - 0x8b, 0x62, 0x91, 0xb7, 0x51, 0x02, 0x76, 0xe6, 0xfb, 0xb3, 0x00, 0x61, 0x01, 0xf2, 0x08, 0x64, - 0x83, 0xf4, 0x65, 0xe8, 0xa6, 0x12, 0xd1, 0xa0, 0x2c, 0x2e, 0x15, 0x62, 0x6c, 0x67, 0xb7, 0x1c, - 0xdb, 0xb7, 0xa0, 0xc0, 0x4f, 0xbc, 0xd0, 0x93, 0x5c, 0x0a, 0x9c, 0xd5, 0xb1, 0xc1, 0x97, 0x91, - 0x9e, 0x6f, 0x66, 0xd1, 0xf2, 0x8c, 0x78, 0x65, 0x73, 0x66, 0x67, 0xea, 0xd0, 0x8b, 0x7f, 0x91, - 0x0b, 0x90, 0x47, 0x29, 0x66, 0x70, 0x1f, 0x8b, 0xb3, 0x74, 0x4c, 0x7e, 0x88, 0x67, 0xdd, 0x34, - 0x61, 0x5b, 0x1e, 0xab, 0x1a, 0x5b, 0x3d, 0x24, 0xe4, 0x22, 0x60, 0x11, 0xb9, 0x08, 0x98, 0xfa, - 0xcf, 0xb2, 0x29, 0xf1, 0x13, 0x1f, 0xdc, 0x61, 0xf2, 0x02, 0x00, 0x3e, 0xb4, 0x66, 0xf2, 0xf4, - 0x9f, 0x68, 0xe0, 0x28, 0x41, 0x46, 0xa8, 0xb6, 0x91, 0x6d, 0x47, 0x48, 0xac, 0xfe, 0x5a, 0x26, - 0x11, 0x74, 0x6f, 0x4f, 0x72, 0x94, 0xad, 0xb2, 0xec, 0x2e, 0xcd, 0x58, 0xbf, 0x2f, 0x72, 0x3b, - 0xeb, 0x8b, 0xe8, 0xb7, 0xec, 0x83, 0x65, 0x7a, 0x90, 0xdf, 0xf2, 0xf5, 0x6c, 0x5a, 0x08, 0xc2, - 0xc3, 0xa9, 0xe2, 0xd7, 0x02, 0xa3, 0x34, 0xbf, 0x9d, 0xc4, 0xdf, 0xc2, 0x4c, 0xfd, 0x38, 0x1c, - 0x8b, 0x05, 0xe6, 0x13, 0x39, 0x05, 0x2f, 0x74, 0x8f, 0xf0, 0xd7, 0xf9, 0x89, 0x7e, 0x84, 0x4c, - 0xfd, 0xbf, 0x99, 0xee, 0x61, 0x19, 0x0f, 0x5c, 0x75, 0x52, 0x04, 0x90, 0xfb, 0xd3, 0x11, 0xc0, - 0x3e, 0x6c, 0x83, 0x0f, 0xb7, 0x00, 0xde, 0x25, 0x93, 0xc7, 0x3b, 0x2d, 0x80, 0x1f, 0xcb, 0x6c, - 0x19, 0x55, 0xf3, 0xa0, 0x65, 0xa0, 0xfe, 0xbb, 0x4c, 0x6a, 0xf4, 0xcb, 0x3d, 0xb5, 0xeb, 0x65, - 0x28, 0x70, 0xb7, 0x1a, 0xd1, 0x2a, 0x29, 0x5f, 0x08, 0x83, 0x76, 0x28, 0x2f, 0xca, 0x90, 0x19, - 0xe8, 0xe3, 0x6d, 0x30, 0xe2, 0x79, 0x75, 0x53, 0xda, 0x69, 0x74, 0x9a, 0x1c, 0x05, 0x5a, 0xfd, - 0xd5, 0x4c, 0x22, 0x18, 0xe7, 0x01, 0x7e, 0x5b, 0x38, 0x55, 0xe7, 0xb6, 0x3f, 0x55, 0xab, 0xbf, - 0x97, 0x4d, 0x8f, 0x05, 0x7a, 0x80, 0x1f, 0xb2, 0x1f, 0xc7, 0x69, 0xbb, 0x5b, 0xb7, 0x16, 0x61, - 0x24, 0x2a, 0x0b, 0xb1, 0x6c, 0x9d, 0x4f, 0x8f, 0x88, 0xda, 0xa1, 0x15, 0x31, 0x1e, 0xea, 0xdb, - 0x99, 0x64, 0x18, 0xd3, 0x03, 0x9f, 0x9f, 0x76, 0xa7, 0x2d, 0xd1, 0x4f, 0x79, 0x97, 0xac, 0x35, - 0xfb, 0xf1, 0x29, 0xef, 0x92, 0x55, 0x63, 0x77, 0x9f, 0xf2, 0xd3, 0xd9, 0x4e, 0x51, 0x60, 0x0f, - 0xfc, 0x83, 0x3e, 0x2c, 0x0b, 0x99, 0xb7, 0x4c, 0x7c, 0xda, 0x23, 0x9d, 0xc2, 0xae, 0x76, 0xe0, - 0x99, 0xe0, 0xb3, 0xbb, 0x31, 0x9e, 0x2a, 0xac, 0x77, 0x89, 0x22, 0x1f, 0x0e, 0x61, 0xbd, 0x4b, - 0x86, 0xca, 0xbb, 0x4f, 0x58, 0x7f, 0x3f, 0xbb, 0xdd, 0xd0, 0xc3, 0x47, 0xc2, 0x4b, 0x08, 0xef, - 0xf3, 0xd9, 0x64, 0x48, 0xec, 0x03, 0x17, 0xd3, 0x14, 0x14, 0x44, 0x70, 0xee, 0x8e, 0xc2, 0xe1, - 0xf8, 0x4e, 0x16, 0x8d, 0xf8, 0x8e, 0x6b, 0x20, 0x2e, 0x72, 0xb6, 0x27, 0x12, 0x4e, 0xab, 0xfe, - 0x51, 0x26, 0x16, 0x3f, 0xfa, 0x40, 0x8e, 0x10, 0x76, 0xb5, 0x24, 0x91, 0x57, 0xfc, 0xc3, 0xcc, - 0x7c, 0x2c, 0x7e, 0x67, 0xf0, 0x3d, 0x65, 0xea, 0xe9, 0x66, 0x23, 0x5e, 0x5e, 0xc4, 0x04, 0xf8, - 0x4a, 0x16, 0xc6, 0x12, 0xa4, 0xe4, 0x42, 0x24, 0x4a, 0x0e, 0x1e, 0x4b, 0xc6, 0x9c, 0xc7, 0x79, - 0xbc, 0x9c, 0x1d, 0x9c, 0xa4, 0x5e, 0x80, 0x7c, 0x59, 0x5f, 0xe7, 0xdf, 0xd6, 0xcb, 0x59, 0x1a, - 0xfa, 0xba, 0x7c, 0xe2, 0x86, 0x78, 0xb2, 0x04, 0x27, 0xf9, 0x7d, 0x88, 0x69, 0x5b, 0x8b, 0x66, - 0x93, 0x56, 0xac, 0x59, 0xb3, 0xd1, 0x30, 0x5d, 0x71, 0xa9, 0xf7, 0xe4, 0xe6, 0x46, 0xf1, 0xa2, - 0x67, 0x7b, 0x7a, 0xa3, 0x46, 0x7d, 0xb2, 0x9a, 0x67, 0x36, 0x69, 0xcd, 0xb4, 0x6a, 0x4d, 0xa4, - 0x94, 0x58, 0xa6, 0xb3, 0x22, 0x15, 0x1e, 0xaa, 0xb5, 0x5a, 0xd7, 0x2d, 0x8b, 0x1a, 0x15, 0x6b, - 0x7c, 0xdd, 0xa3, 0xfc, 0x32, 0x30, 0xc7, 0x8f, 0x04, 0xf9, 0xdb, 0x70, 0x8e, 0x66, 0x8c, 0x97, - 0x18, 0x81, 0x96, 0x52, 0x48, 0xfd, 0xe5, 0x7c, 0x4a, 0xe8, 0xf0, 0x43, 0xa4, 0x3e, 0x7e, 0x4f, - 0xe7, 0xb7, 0xe8, 0xe9, 0x2b, 0xd0, 0x77, 0x9b, 0x3a, 0x78, 0xbe, 0xc5, 0x2f, 0x18, 0xd0, 0x99, - 0xfd, 0x1e, 0x07, 0xc9, 0x37, 0x34, 0x82, 0x8a, 0x34, 0xe0, 0xcc, 0x22, 0xeb, 0xa6, 0xf4, 0xce, - 0x2c, 0xec, 0xa2, 0x33, 0xbb, 0xf0, 0x23, 0x6f, 0xc0, 0x69, 0xc4, 0xa6, 0x74, 0x6b, 0x1f, 0x56, - 0x85, 0x91, 0xa3, 0x78, 0x55, 0xe9, 0x9d, 0xdb, 0xa9, 0x3c, 0xf9, 0x30, 0x0c, 0x05, 0x03, 0xc4, - 0xa4, 0xae, 0xb8, 0xb9, 0xe8, 0x32, 0xce, 0x78, 0x58, 0x36, 0x06, 0x46, 0x17, 0xb2, 0x68, 0x68, - 0xaf, 0x08, 0x2f, 0xf5, 0xdf, 0x66, 0xba, 0x85, 0x30, 0x3f, 0xf0, 0x59, 0xf9, 0x15, 0xe8, 0x33, - 0xf8, 0x47, 0x09, 0x9d, 0xea, 0x1e, 0xe4, 0x9c, 0x93, 0x6a, 0x7e, 0x19, 0xf5, 0x77, 0x33, 0x5d, - 0x23, 0xa7, 0x1f, 0xf6, 0xcf, 0xfb, 0x7c, 0xae, 0xc3, 0xe7, 0x89, 0x49, 0xf4, 0x12, 0x8c, 0x9a, - 0x61, 0xf8, 0xd8, 0x5a, 0x18, 0x7e, 0x4a, 0x3b, 0x26, 0xc1, 0x71, 0x74, 0x5d, 0x83, 0x53, 0xbe, - 0xe3, 0xa3, 0xe3, 0x7b, 0x88, 0xb9, 0xb5, 0xb6, 0x63, 0xf2, 0x71, 0xa9, 0x9d, 0x70, 0x63, 0xee, - 0x63, 0xee, 0x2d, 0xc7, 0x64, 0x15, 0xe8, 0xde, 0x2a, 0xb5, 0xf4, 0xda, 0x9a, 0xed, 0xdc, 0xc5, - 0xd8, 0x9f, 0x7c, 0x70, 0x6a, 0xc7, 0x38, 0xfc, 0x8e, 0x0f, 0x26, 0x8f, 0xc1, 0xf0, 0x4a, 0xa3, - 0x4d, 0x83, 0x68, 0x8b, 0xfc, 0xae, 0x4f, 0x1b, 0x62, 0xc0, 0xe0, 0x86, 0xe4, 0x1c, 0x00, 0x12, - 0x79, 0x18, 0xd7, 0x1e, 0x2f, 0xf6, 0xb4, 0x01, 0x06, 0x59, 0x14, 0xdd, 0x75, 0x86, 0x6b, 0x35, - 0x17, 0x52, 0xad, 0x61, 0x5b, 0x2b, 0x35, 0x8f, 0x3a, 0x4d, 0x6c, 0x28, 0x3a, 0x33, 0x68, 0xa7, - 0x90, 0x02, 0xaf, 0x4e, 0xdc, 0x19, 0xdb, 0x5a, 0x59, 0xa4, 0x4e, 0x93, 0x35, 0xf5, 0x49, 0x20, - 0xa2, 0xa9, 0x0e, 0x1e, 0x7a, 0xf0, 0x8f, 0x43, 0x6f, 0x06, 0x4d, 0x7c, 0x04, 0x3f, 0x0d, 0xc1, - 0x0f, 0x2b, 0xc2, 0x20, 0x0f, 0x39, 0xc7, 0x85, 0x86, 0x2e, 0x0c, 0x1a, 0x70, 0x10, 0xca, 0xeb, - 0x14, 0x08, 0xef, 0x0a, 0xee, 0xd5, 0xad, 0x89, 0x5f, 0xea, 0x67, 0x72, 0x69, 0xc1, 0xde, 0xf7, - 0xa4, 0x68, 0xe1, 0xb4, 0x9a, 0xdd, 0xd1, 0xb4, 0x7a, 0xcc, 0x6a, 0x37, 0x6b, 0x7a, 0xab, 0x55, - 0x5b, 0x36, 0x1b, 0xf8, 0xac, 0x0a, 0x17, 0x3e, 0x6d, 0xd8, 0x6a, 0x37, 0x4b, 0xad, 0xd6, 0x14, - 0x07, 0x92, 0x27, 0x60, 0x8c, 0xd1, 0x61, 0x27, 0x05, 0x94, 0x79, 0xa4, 0x64, 0x0c, 0x30, 0x66, - 0xab, 0x4f, 0xfb, 0x10, 0xf4, 0x0b, 0x9e, 0x7c, 0xad, 0xea, 0xd5, 0xfa, 0x38, 0x33, 0x97, 0xf5, - 0x5c, 0xc0, 0x86, 0x4f, 0xae, 0xbd, 0xda, 0x80, 0x5f, 0x1e, 0x23, 0x13, 0x5b, 0xed, 0x26, 0x8f, - 0x88, 0xd5, 0x87, 0xc8, 0xe0, 0x37, 0xb9, 0x00, 0x23, 0x8c, 0x4b, 0x20, 0x30, 0x1e, 0xcc, 0xb5, - 0x57, 0x8b, 0x41, 0xc9, 0x55, 0x38, 0x11, 0x81, 0x70, 0x1b, 0x94, 0x3f, 0x13, 0xe8, 0xd5, 0x52, - 0x71, 0xea, 0x97, 0x73, 0xd1, 0x10, 0xf4, 0x07, 0xd0, 0x11, 0xa7, 0xa1, 0xcf, 0x76, 0x56, 0x6a, - 0x6d, 0xa7, 0x21, 0xc6, 0x5e, 0xc1, 0x76, 0x56, 0x6e, 0x39, 0x0d, 0x72, 0x12, 0x0a, 0xac, 0x77, - 0x4c, 0x43, 0x0c, 0xb1, 0x5e, 0xbd, 0xd5, 0xaa, 0x18, 0xa4, 0xc4, 0x3b, 0x04, 0x03, 0x81, 0xd6, - 0xea, 0xb8, 0xb5, 0xe7, 0x4e, 0x09, 0xbd, 0x7c, 0xc5, 0x4b, 0x20, 0xb1, 0x9f, 0x30, 0x3c, 0x28, - 0x3f, 0x08, 0x88, 0xb1, 0x30, 0x70, 0x5b, 0x62, 0xf0, 0x3e, 0x89, 0xb3, 0x10, 0xc8, 0x90, 0x05, - 0xdf, 0xc4, 0x18, 0xa4, 0x0c, 0x24, 0xa4, 0x6a, 0xda, 0x86, 0xb9, 0x6c, 0x52, 0xfe, 0xaa, 0xa3, - 0x97, 0x5f, 0xfc, 0x26, 0xb1, 0xda, 0xa8, 0xcf, 0x64, 0x56, 0x40, 0xc8, 0x4b, 0x5c, 0x09, 0x39, - 0x1d, 0xae, 0x7d, 0xbc, 0x6f, 0xb9, 0x9d, 0x16, 0x43, 0xa1, 0x66, 0x62, 0x79, 0x5c, 0x08, 0xd5, - 0xb7, 0x73, 0xc9, 0x3c, 0x04, 0x07, 0x62, 0xd7, 0x4c, 0x03, 0x88, 0x34, 0x23, 0xe1, 0xe5, 0x5a, - 0xe0, 0x71, 0x1e, 0x62, 0x3a, 0xf0, 0x90, 0xca, 0x92, 0x4b, 0xd0, 0xcf, 0xbf, 0xa8, 0x52, 0x16, - 0xf6, 0x0e, 0xba, 0x88, 0xb9, 0x2d, 0x73, 0x79, 0x19, 0xfd, 0xc9, 0x02, 0x34, 0xb9, 0x00, 0x7d, - 0xe5, 0xb9, 0x6a, 0xb5, 0x34, 0xe7, 0xdf, 0x14, 0xe3, 0xfb, 0x12, 0xc3, 0x72, 0x6b, 0xae, 0x6e, - 0xb9, 0x9a, 0x8f, 0x24, 0x8f, 0x41, 0xa1, 0xb2, 0x80, 0x64, 0xfc, 0xd5, 0xe4, 0xe0, 0xe6, 0x46, - 0xb1, 0xcf, 0x6c, 0x71, 0x2a, 0x81, 0xc2, 0x7a, 0x6f, 0x57, 0xca, 0x92, 0xbb, 0x04, 0xaf, 0xf7, - 0x9e, 0x69, 0xe0, 0xb5, 0xb3, 0x16, 0xa0, 0xc9, 0xb3, 0x30, 0x54, 0xa5, 0x8e, 0xa9, 0x37, 0xe6, - 0xda, 0xb8, 0x55, 0xe4, 0x2e, 0x62, 0x63, 0x9b, 0x1b, 0xc5, 0x61, 0x17, 0xe1, 0x35, 0x0b, 0x11, - 0x5a, 0x84, 0x8c, 0x9c, 0x85, 0xfc, 0xb4, 0x69, 0xf9, 0x4f, 0x18, 0xd0, 0xc7, 0x7d, 0xd5, 0xb4, - 0x3c, 0x0d, 0xa1, 0xea, 0x7f, 0xcf, 0xa6, 0x27, 0x73, 0x38, 0x80, 0xe1, 0xb8, 0xcb, 0x9b, 0xde, - 0x98, 0x12, 0xe4, 0xf7, 0xa0, 0x04, 0xcb, 0x70, 0xac, 0x64, 0x34, 0x4d, 0xab, 0x84, 0x3f, 0xdd, - 0xd9, 0xa9, 0x12, 0x0e, 0x6f, 0xe9, 0x09, 0x5d, 0x0c, 0x2d, 0xbe, 0x87, 0x87, 0xca, 0x65, 0xa8, - 0x9a, 0xce, 0x71, 0xb5, 0xe6, 0xb2, 0x5e, 0xab, 0xf3, 0x3c, 0x08, 0x5a, 0x9c, 0xa9, 0xfa, 0x7d, - 0xd9, 0x2d, 0xf2, 0x4f, 0x3c, 0x88, 0xd2, 0x57, 0xbf, 0x90, 0xed, 0x9e, 0x02, 0xe4, 0x81, 0x14, - 0xca, 0x1f, 0x64, 0x53, 0x12, 0x72, 0xec, 0x49, 0x12, 0x97, 0xa0, 0x9f, 0xb3, 0x09, 0x5c, 0x6d, - 0x71, 0xc6, 0xe1, 0xca, 0x8a, 0x33, 0x9d, 0x8f, 0x26, 0x73, 0x70, 0xa2, 0xb4, 0xbc, 0x4c, 0xeb, - 0x5e, 0x18, 0x34, 0x79, 0x2e, 0x0c, 0x94, 0xca, 0x23, 0xcd, 0x0a, 0x7c, 0x18, 0x74, 0x19, 0x03, - 0x82, 0xa4, 0x96, 0x23, 0x8b, 0x70, 0x2a, 0x0e, 0xaf, 0x72, 0x33, 0x3d, 0x2f, 0x05, 0x9f, 0x4d, - 0x70, 0xe4, 0xff, 0x69, 0x1d, 0xca, 0xa6, 0xb5, 0x12, 0xa7, 0xd3, 0xde, 0x6e, 0xad, 0xc4, 0xb9, - 0x35, 0xb5, 0x9c, 0xfa, 0x95, 0x9c, 0x9c, 0xb7, 0xe4, 0xc1, 0x75, 0x8a, 0xba, 0x16, 0x71, 0x85, - 0xde, 0xee, 0x90, 0x79, 0x56, 0x44, 0xf9, 0x30, 0xda, 0x8e, 0xef, 0x35, 0x18, 0x44, 0x19, 0x40, - 0xa0, 0xec, 0xff, 0x17, 0x50, 0x92, 0x0a, 0xe4, 0x4b, 0xce, 0x0a, 0x37, 0x41, 0xb7, 0x7a, 0xf8, - 0xa4, 0x3b, 0x2b, 0x6e, 0xfa, 0xc3, 0x27, 0xc6, 0xe2, 0x89, 0x59, 0x1e, 0xd2, 0xf7, 0xa6, 0x69, - 0x19, 0xe4, 0x21, 0x38, 0x79, 0xab, 0x3a, 0xa9, 0xd5, 0x6e, 0x56, 0xe6, 0xca, 0xb5, 0x5b, 0x73, - 0xd5, 0x85, 0xc9, 0x89, 0xca, 0x54, 0x65, 0xb2, 0x3c, 0xda, 0x43, 0x8e, 0xc3, 0xb1, 0x10, 0x35, - 0x7d, 0x6b, 0xb6, 0x34, 0x37, 0x9a, 0x21, 0x63, 0x30, 0x1c, 0x02, 0xc7, 0xe7, 0x17, 0x47, 0xb3, - 0x4f, 0xbc, 0x17, 0x06, 0x71, 0xcf, 0xc2, 0xe7, 0x6f, 0x32, 0x04, 0xfd, 0xf3, 0xe3, 0xd5, 0x49, - 0xed, 0x36, 0x32, 0x01, 0x28, 0x94, 0x27, 0xe7, 0x18, 0xc3, 0xcc, 0x13, 0xff, 0x2b, 0x03, 0x50, - 0x9d, 0x5a, 0x5c, 0x10, 0x84, 0x83, 0xd0, 0x57, 0x99, 0xbb, 0x5d, 0x9a, 0xa9, 0x30, 0xba, 0x7e, - 0xc8, 0xcf, 0x2f, 0x4c, 0xb2, 0x1a, 0x06, 0xa0, 0x77, 0x62, 0x66, 0xbe, 0x3a, 0x39, 0x9a, 0x65, - 0x40, 0x6d, 0xb2, 0x54, 0x1e, 0xcd, 0x31, 0xe0, 0x1d, 0xad, 0xb2, 0x38, 0x39, 0x9a, 0x67, 0x7f, - 0xce, 0x54, 0x17, 0x4b, 0x8b, 0xa3, 0xbd, 0xec, 0xcf, 0x29, 0xfc, 0xb3, 0xc0, 0x98, 0x55, 0x27, - 0x17, 0xf1, 0x47, 0x1f, 0x6b, 0xc2, 0x94, 0xff, 0xab, 0x9f, 0xa1, 0x18, 0xeb, 0x72, 0x45, 0x1b, - 0x1d, 0x60, 0x3f, 0x18, 0x4b, 0xf6, 0x03, 0x58, 0xe3, 0xb4, 0xc9, 0xd9, 0xf9, 0xdb, 0x93, 0xa3, - 0x83, 0x8c, 0xd7, 0xec, 0x4d, 0x06, 0x1e, 0x62, 0x7f, 0x6a, 0xb3, 0xec, 0xcf, 0x61, 0xc6, 0x49, - 0x9b, 0x2c, 0xcd, 0x2c, 0x94, 0x16, 0xa7, 0x47, 0x47, 0x58, 0x7b, 0x90, 0xe7, 0x31, 0x5e, 0x72, - 0xae, 0x34, 0x3b, 0x39, 0x3a, 0x2a, 0x68, 0xca, 0x33, 0x95, 0xb9, 0x9b, 0xa3, 0x63, 0xd8, 0x90, - 0x37, 0x66, 0xf1, 0x07, 0x61, 0x05, 0xf0, 0xaf, 0xe3, 0x4f, 0x7c, 0x14, 0x0a, 0xf3, 0x55, 0xb4, - 0x52, 0x4e, 0xc3, 0xf1, 0xf9, 0x6a, 0x6d, 0xf1, 0x8d, 0x85, 0xc9, 0x98, 0xbc, 0xc7, 0x60, 0xd8, - 0x47, 0xcc, 0x54, 0xe6, 0x6e, 0x7d, 0x88, 0x4b, 0xdb, 0x07, 0xcd, 0x96, 0x26, 0xe6, 0xab, 0xa3, - 0x59, 0xd6, 0x2b, 0x3e, 0xe8, 0x4e, 0x65, 0xae, 0x3c, 0x7f, 0xa7, 0x3a, 0x9a, 0x7b, 0xe2, 0x9e, - 0x9f, 0xfb, 0x73, 0xde, 0x31, 0x57, 0x4c, 0x8b, 0x9c, 0x83, 0x87, 0xca, 0x93, 0xb7, 0x2b, 0x13, - 0x93, 0xb5, 0x79, 0xad, 0x72, 0xbd, 0x32, 0x17, 0xab, 0xe9, 0x24, 0x8c, 0x45, 0xd1, 0xa5, 0x85, - 0xca, 0x68, 0x86, 0x9c, 0x02, 0x12, 0x05, 0xdf, 0x28, 0xcd, 0x4e, 0x8d, 0x66, 0x89, 0x02, 0x27, - 0xa2, 0xf0, 0xca, 0xdc, 0xe2, 0xad, 0xb9, 0xc9, 0xd1, 0xdc, 0x13, 0x3f, 0x91, 0x81, 0x93, 0xa9, - 0x8f, 0xe6, 0x89, 0x0a, 0xe7, 0x27, 0x67, 0x4a, 0xd5, 0xc5, 0xca, 0x44, 0x75, 0xb2, 0xa4, 0x4d, - 0x4c, 0xd7, 0x26, 0x4a, 0x8b, 0x93, 0xd7, 0xe7, 0xb5, 0x37, 0x6a, 0xd7, 0x27, 0xe7, 0x26, 0xb5, - 0xd2, 0xcc, 0x68, 0x0f, 0x79, 0x0c, 0x8a, 0x1d, 0x68, 0xaa, 0x93, 0x13, 0xb7, 0xb4, 0xca, 0xe2, - 0x1b, 0xa3, 0x19, 0xf2, 0x28, 0x9c, 0xeb, 0x48, 0xc4, 0x7e, 0x8f, 0x66, 0xc9, 0x79, 0x38, 0xd3, - 0x89, 0xe4, 0xf5, 0x99, 0xd1, 0xdc, 0x13, 0x3f, 0x98, 0x01, 0x92, 0x7c, 0xf5, 0x4c, 0x1e, 0x81, - 0xb3, 0x4c, 0x2f, 0x6a, 0x9d, 0x1b, 0xf8, 0x28, 0x9c, 0x4b, 0xa5, 0x90, 0x9a, 0x57, 0x84, 0x87, - 0x3b, 0x90, 0x88, 0xc6, 0x9d, 0x05, 0x25, 0x9d, 0x00, 0x9b, 0xf6, 0x0b, 0x19, 0x38, 0x99, 0x6a, - 0x32, 0x91, 0x8b, 0xf0, 0x9e, 0x52, 0x79, 0x96, 0xf5, 0xcd, 0xc4, 0x62, 0x65, 0x7e, 0xae, 0x5a, - 0x9b, 0x9d, 0x2a, 0xd5, 0x98, 0xf6, 0xdd, 0xaa, 0xc6, 0x7a, 0xf3, 0x02, 0xa8, 0x5d, 0x28, 0x27, - 0xa6, 0x4b, 0x73, 0xd7, 0xd9, 0xf0, 0x23, 0xef, 0x81, 0x47, 0x3a, 0xd2, 0x4d, 0xce, 0x95, 0xc6, - 0x67, 0x26, 0xcb, 0xa3, 0x59, 0xf2, 0x38, 0x3c, 0xda, 0x91, 0xaa, 0x5c, 0xa9, 0x72, 0xb2, 0xdc, - 0x78, 0xf9, 0xed, 0x7f, 0x7f, 0xbe, 0xe7, 0xed, 0x6f, 0x9c, 0xcf, 0xfc, 0xc6, 0x37, 0xce, 0x67, - 0x7e, 0xef, 0x1b, 0xe7, 0x33, 0x1f, 0xbe, 0xba, 0x93, 0xd7, 0xec, 0x7c, 0xa2, 0x5c, 0x2a, 0xe0, - 0xf4, 0xf5, 0xcc, 0xff, 0x0b, 0x00, 0x00, 0xff, 0xff, 0x42, 0xa5, 0x51, 0xd7, 0x8d, 0x55, 0x01, - 0x00, + // 15555 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0xbd, 0x6d, 0x70, 0x24, 0xc9, + 0x75, 0x20, 0x86, 0xfe, 0x40, 0x03, 0x78, 0xf8, 0x18, 0x20, 0xe7, 0xab, 0x66, 0x76, 0x66, 0x7a, + 0xb7, 0x96, 0x3b, 0x9c, 0x59, 0xee, 0xce, 0x70, 0x67, 0x67, 0x77, 0xb9, 0x5f, 0xdc, 0x6d, 0xa0, + 0x81, 0x41, 0xef, 0xe0, 0x6b, 0xab, 0x31, 0x33, 0x5c, 0x7e, 0x35, 0x0b, 0x5d, 0x89, 0x46, 0xed, + 0x74, 0x57, 0x35, 0xab, 0xaa, 0x07, 0x83, 0xf5, 0x97, 0x28, 0xeb, 0x83, 0x94, 0x49, 0x8a, 0xa6, + 0x2c, 0x51, 0xb2, 0x64, 0x8b, 0x92, 0xec, 0x08, 0x59, 0x21, 0x4b, 0x96, 0xed, 0x90, 0x44, 0xcb, + 0x0c, 0x4b, 0xa6, 0x3f, 0x56, 0x66, 0xc8, 0x21, 0xc9, 0xb6, 0x42, 0x61, 0xcb, 0xa0, 0x8e, 0x77, + 0xba, 0x1f, 0x88, 0xbb, 0x38, 0xdd, 0x1d, 0xe3, 0xa4, 0xd3, 0xe9, 0x2e, 0x2e, 0xf2, 0x65, 0x56, + 0x55, 0xd6, 0x47, 0x37, 0x80, 0x01, 0x56, 0x58, 0x70, 0xf0, 0x67, 0x06, 0xfd, 0xde, 0xcb, 0x97, + 0x59, 0x2f, 0x5f, 0x66, 0xbe, 0xcc, 0x7c, 0xf9, 0x1e, 0x5c, 0xf6, 0x68, 0x93, 0xb6, 0x6d, 0xc7, + 0xbb, 0xda, 0xa4, 0x0d, 0xbd, 0xbe, 0x71, 0xd5, 0xdb, 0x68, 0x53, 0xf7, 0x2a, 0xbd, 0x47, 0x2d, + 0xcf, 0xff, 0xef, 0x4a, 0xdb, 0xb1, 0x3d, 0x9b, 0x14, 0xf8, 0xaf, 0xb3, 0x27, 0x1a, 0x76, 0xc3, + 0x46, 0xd0, 0x55, 0xf6, 0x17, 0xc7, 0x9e, 0x3d, 0xd7, 0xb0, 0xed, 0x46, 0x93, 0x5e, 0xc5, 0x5f, + 0x2b, 0x9d, 0xd5, 0xab, 0xae, 0xe7, 0x74, 0xea, 0x9e, 0xc0, 0x16, 0xe3, 0x58, 0xcf, 0x6c, 0x51, + 0xd7, 0xd3, 0x5b, 0x6d, 0x41, 0x70, 0x21, 0x4e, 0xb0, 0xee, 0xe8, 0xed, 0x36, 0x75, 0x44, 0xe5, + 0x67, 0x1f, 0x4b, 0x6f, 0x27, 0xfe, 0x2b, 0x48, 0x9e, 0x4e, 0x27, 0xf1, 0x19, 0xc5, 0x38, 0xaa, + 0x5f, 0xcd, 0xc2, 0xe0, 0x3c, 0xf5, 0x74, 0x43, 0xf7, 0x74, 0x72, 0x0e, 0xfa, 0x2b, 0x96, 0x41, + 0xef, 0x2b, 0x99, 0x47, 0x33, 0x97, 0x72, 0x93, 0x85, 0xad, 0xcd, 0x62, 0x96, 0x9a, 0x1a, 0x07, + 0x92, 0xf3, 0x90, 0x5f, 0xde, 0x68, 0x53, 0x25, 0xfb, 0x68, 0xe6, 0xd2, 0xd0, 0xe4, 0xd0, 0xd6, + 0x66, 0xb1, 0x1f, 0x65, 0xa1, 0x21, 0x98, 0x3c, 0x06, 0xd9, 0x4a, 0x59, 0xc9, 0x21, 0x72, 0x62, + 0x6b, 0xb3, 0x38, 0xda, 0x31, 0x8d, 0xa7, 0xec, 0x96, 0xe9, 0xd1, 0x56, 0xdb, 0xdb, 0xd0, 0xb2, + 0x95, 0x32, 0xb9, 0x08, 0xf9, 0x29, 0xdb, 0xa0, 0x4a, 0x1e, 0x89, 0xc8, 0xd6, 0x66, 0x71, 0xac, + 0x6e, 0x1b, 0x54, 0xa2, 0x42, 0x3c, 0x79, 0x1d, 0xf2, 0xcb, 0x66, 0x8b, 0x2a, 0xfd, 0x8f, 0x66, + 0x2e, 0x0d, 0x5f, 0x3b, 0x7b, 0x85, 0x4b, 0xe5, 0x8a, 0x2f, 0x95, 0x2b, 0xcb, 0xbe, 0xd8, 0x26, + 0xc7, 0xdf, 0xdd, 0x2c, 0xf6, 0x6d, 0x6d, 0x16, 0xf3, 0x4c, 0x92, 0x5f, 0xf9, 0x4e, 0x31, 0xa3, + 0x61, 0x49, 0xf2, 0x0a, 0x0c, 0x4f, 0x35, 0x3b, 0xae, 0x47, 0x9d, 0x05, 0xbd, 0x45, 0x95, 0x02, + 0x56, 0x78, 0x76, 0x6b, 0xb3, 0x78, 0xaa, 0xce, 0xc1, 0x35, 0x4b, 0x6f, 0xc9, 0x15, 0xcb, 0xe4, + 0xea, 0x6f, 0x67, 0xe0, 0x58, 0x95, 0xba, 0xae, 0x69, 0x5b, 0x81, 0x6c, 0x9e, 0x80, 0x21, 0x01, + 0xaa, 0x94, 0x51, 0x3e, 0x43, 0x93, 0x03, 0x5b, 0x9b, 0xc5, 0x9c, 0x6b, 0x1a, 0x5a, 0x88, 0x21, + 0x1f, 0x86, 0x81, 0x3b, 0xa6, 0xb7, 0x36, 0x3f, 0x53, 0x12, 0x72, 0x3a, 0xb5, 0xb5, 0x59, 0x24, + 0xeb, 0xa6, 0xb7, 0x56, 0x6b, 0xad, 0xea, 0x52, 0x85, 0x3e, 0x19, 0x99, 0x83, 0xf1, 0x25, 0xc7, + 0xbc, 0xa7, 0x7b, 0xf4, 0x26, 0xdd, 0x58, 0xb2, 0x9b, 0x66, 0x7d, 0x43, 0x48, 0xf1, 0xd1, 0xad, + 0xcd, 0xe2, 0xb9, 0x36, 0xc7, 0xd5, 0xee, 0xd2, 0x8d, 0x5a, 0x1b, 0xb1, 0x12, 0x93, 0x44, 0x49, + 0xf5, 0x5b, 0xfd, 0x30, 0x72, 0xcb, 0xa5, 0x4e, 0xd0, 0xee, 0x8b, 0x90, 0x67, 0xbf, 0x45, 0x93, + 0x51, 0xe6, 0x1d, 0x97, 0x3a, 0xb2, 0xcc, 0x19, 0x9e, 0x5c, 0x86, 0xfe, 0x39, 0xbb, 0x61, 0x5a, + 0xa2, 0xd9, 0xc7, 0xb7, 0x36, 0x8b, 0xc7, 0x9a, 0x0c, 0x20, 0x51, 0x72, 0x0a, 0xf2, 0x51, 0x18, + 0xa9, 0xb4, 0x98, 0x0e, 0xd9, 0x96, 0xee, 0xd9, 0x8e, 0x68, 0x2d, 0x4a, 0xd7, 0x94, 0xe0, 0x52, + 0xc1, 0x08, 0x3d, 0x79, 0x09, 0xa0, 0x74, 0xa7, 0xaa, 0xd9, 0x4d, 0x5a, 0xd2, 0x16, 0x84, 0x32, + 0x60, 0x69, 0x7d, 0xdd, 0xad, 0x39, 0x76, 0x93, 0xd6, 0x74, 0x47, 0xae, 0x56, 0xa2, 0x26, 0xd3, + 0x30, 0x56, 0xaa, 0xd7, 0xa9, 0xeb, 0x6a, 0xf4, 0xb3, 0x1d, 0xea, 0x7a, 0xae, 0xd2, 0xff, 0x68, + 0xee, 0xd2, 0xd0, 0xe4, 0xf9, 0xad, 0xcd, 0xe2, 0x19, 0x1d, 0x31, 0x35, 0x47, 0xa0, 0x24, 0x16, + 0xb1, 0x42, 0x64, 0x12, 0x46, 0x4b, 0xef, 0x74, 0x1c, 0x5a, 0x31, 0xa8, 0xe5, 0x99, 0xde, 0x86, + 0xd0, 0x90, 0x73, 0x5b, 0x9b, 0x45, 0x45, 0x67, 0x88, 0x9a, 0x29, 0x30, 0x12, 0x93, 0x68, 0x11, + 0xb2, 0x08, 0x13, 0x37, 0xa6, 0x96, 0xaa, 0xd4, 0xb9, 0x67, 0xd6, 0x69, 0xa9, 0x5e, 0xb7, 0x3b, + 0x96, 0xa7, 0x0c, 0x20, 0x9f, 0xc7, 0xb6, 0x36, 0x8b, 0xe7, 0x1b, 0xf5, 0x76, 0xcd, 0xe5, 0xd8, + 0x9a, 0xce, 0xd1, 0x12, 0xb3, 0x64, 0x59, 0xf2, 0x71, 0x18, 0x5d, 0x76, 0x98, 0x16, 0x1a, 0x65, + 0xca, 0xe0, 0xca, 0x20, 0xea, 0xff, 0xa9, 0x2b, 0x62, 0x02, 0xe2, 0x50, 0xbf, 0x67, 0x79, 0x63, + 0x3d, 0x5e, 0xa0, 0x66, 0x20, 0x4e, 0x6e, 0x6c, 0x84, 0x15, 0xa1, 0xa0, 0xb0, 0x8f, 0x37, 0x1d, + 0x6a, 0x24, 0xb4, 0x6d, 0x08, 0xdb, 0x7c, 0x79, 0x6b, 0xb3, 0xf8, 0x84, 0x23, 0x68, 0x6a, 0x3d, + 0xd5, 0xae, 0x2b, 0x2b, 0x32, 0x0d, 0x83, 0x4c, 0x9b, 0x6e, 0x9a, 0x96, 0xa1, 0xc0, 0xa3, 0x99, + 0x4b, 0x63, 0xd7, 0xc6, 0xfd, 0xd6, 0xfb, 0xf0, 0xc9, 0xd3, 0x5b, 0x9b, 0xc5, 0xe3, 0x4c, 0x07, + 0x6b, 0x77, 0x4d, 0x4b, 0x9e, 0x22, 0x82, 0xa2, 0xea, 0x5f, 0xe5, 0x61, 0x8c, 0x09, 0x47, 0xd2, + 0xe3, 0x12, 0x1b, 0x92, 0x0c, 0xc2, 0x46, 0xa8, 0xdb, 0xd6, 0xeb, 0x54, 0xa8, 0x34, 0xb2, 0xb3, + 0x7c, 0xa0, 0xc4, 0x2e, 0x4e, 0x4f, 0x2e, 0xc3, 0x20, 0x07, 0x55, 0xca, 0x42, 0xcb, 0x47, 0xb7, + 0x36, 0x8b, 0x43, 0x2e, 0xc2, 0x6a, 0xa6, 0xa1, 0x05, 0x68, 0xa6, 0x66, 0xfc, 0xef, 0x59, 0xdb, + 0xf5, 0x18, 0x73, 0xa1, 0xe4, 0xa8, 0x66, 0xa2, 0xc0, 0x9a, 0x40, 0xc9, 0x6a, 0x16, 0x2d, 0x44, + 0x5e, 0x04, 0xe0, 0x90, 0x92, 0x61, 0x38, 0x42, 0xd3, 0xcf, 0x6c, 0x6d, 0x16, 0x4f, 0x0a, 0x16, + 0xba, 0x61, 0xc8, 0xc3, 0x44, 0x22, 0x26, 0x2d, 0x18, 0xe1, 0xbf, 0xe6, 0xf4, 0x15, 0xda, 0xe4, + 0x6a, 0x3e, 0x7c, 0xed, 0x92, 0x2f, 0xcd, 0xa8, 0x74, 0xae, 0xc8, 0xa4, 0xd3, 0x96, 0xe7, 0x6c, + 0x4c, 0x16, 0xc5, 0xcc, 0x78, 0x5a, 0x54, 0xd5, 0x44, 0x9c, 0x3c, 0x26, 0xe5, 0x32, 0x6c, 0xc2, + 0x9c, 0xb1, 0x9d, 0x75, 0xdd, 0x31, 0xa8, 0x31, 0xb9, 0x21, 0x4f, 0x98, 0xab, 0x3e, 0xb8, 0xb6, + 0x22, 0xeb, 0x80, 0x4c, 0x4e, 0xa6, 0x60, 0x94, 0x73, 0xab, 0x76, 0x56, 0xb0, 0xef, 0x07, 0x12, + 0xd2, 0x72, 0x3b, 0x2b, 0xf1, 0xfe, 0x8e, 0x96, 0x61, 0x63, 0x92, 0x03, 0x6e, 0x53, 0x87, 0xcd, + 0xa6, 0xa8, 0xfe, 0x62, 0x4c, 0x0a, 0x26, 0xf7, 0x38, 0x26, 0xc9, 0x43, 0x14, 0x39, 0xfb, 0x1a, + 0x4c, 0x24, 0x44, 0x41, 0xc6, 0x21, 0x77, 0x97, 0x6e, 0x70, 0x75, 0xd1, 0xd8, 0x9f, 0xe4, 0x04, + 0xf4, 0xdf, 0xd3, 0x9b, 0x1d, 0xb1, 0x96, 0x69, 0xfc, 0xc7, 0x4b, 0xd9, 0x8f, 0x64, 0xd8, 0xd4, + 0x4f, 0xa6, 0x6c, 0xcb, 0xa2, 0x75, 0x4f, 0x9e, 0xfd, 0x9f, 0x87, 0xa1, 0x39, 0xbb, 0xae, 0x37, + 0xb1, 0x1f, 0xb9, 0xde, 0x29, 0x5b, 0x9b, 0xc5, 0x13, 0xac, 0x03, 0xaf, 0x34, 0x19, 0x46, 0x6a, + 0x53, 0x48, 0xca, 0x14, 0x40, 0xa3, 0x2d, 0xdb, 0xa3, 0x58, 0x30, 0x1b, 0x2a, 0x00, 0x16, 0x74, + 0x10, 0x25, 0x2b, 0x40, 0x48, 0x4c, 0xae, 0xc2, 0xe0, 0x12, 0x5b, 0xf0, 0xea, 0x76, 0x53, 0x28, + 0x1f, 0xce, 0xc9, 0xb8, 0x08, 0xca, 0x83, 0xc6, 0x27, 0x52, 0x67, 0x61, 0x6c, 0xaa, 0x69, 0x52, + 0xcb, 0x93, 0x5b, 0xcd, 0x86, 0x54, 0xa9, 0x41, 0x2d, 0x4f, 0x6e, 0x35, 0x0e, 0x3e, 0x9d, 0x41, + 0xe5, 0x56, 0x07, 0xa4, 0xea, 0xff, 0x99, 0x83, 0x33, 0x37, 0x3b, 0x2b, 0xd4, 0xb1, 0xa8, 0x47, + 0x5d, 0xb1, 0x32, 0x06, 0x5c, 0x17, 0x60, 0x22, 0x81, 0x14, 0xdc, 0x71, 0xc5, 0xba, 0x1b, 0x20, + 0x6b, 0x62, 0xb1, 0x95, 0xa7, 0xbd, 0x44, 0x51, 0x32, 0x0b, 0xc7, 0x42, 0x20, 0x6b, 0x84, 0xab, + 0x64, 0x71, 0x4e, 0xbf, 0xb0, 0xb5, 0x59, 0x3c, 0x2b, 0x71, 0x63, 0xcd, 0x96, 0x35, 0x38, 0x5e, + 0x8c, 0xdc, 0x84, 0xf1, 0x10, 0x74, 0xc3, 0xb1, 0x3b, 0x6d, 0x57, 0xc9, 0x21, 0xab, 0xe2, 0xd6, + 0x66, 0xf1, 0x11, 0x89, 0x55, 0x03, 0x91, 0xf2, 0x4a, 0x1a, 0x2f, 0x48, 0x7e, 0x28, 0x23, 0x73, + 0x13, 0xa3, 0x30, 0x8f, 0xa3, 0xf0, 0x05, 0x7f, 0x14, 0x76, 0x15, 0xd2, 0x95, 0x78, 0x49, 0x31, + 0x28, 0x63, 0xcd, 0x48, 0x0c, 0xca, 0x44, 0x8d, 0x67, 0xa7, 0xe0, 0x64, 0x2a, 0xaf, 0x5d, 0x69, + 0xf5, 0x5f, 0xe4, 0x64, 0x2e, 0x4b, 0xb6, 0x11, 0x74, 0xe6, 0xa2, 0xdc, 0x99, 0x4b, 0xb6, 0x81, + 0xe6, 0x52, 0x26, 0x5c, 0xc4, 0xa4, 0xc6, 0xb6, 0x6d, 0x23, 0x6e, 0x35, 0x25, 0xcb, 0x92, 0x4f, + 0xc3, 0xa9, 0x04, 0x90, 0x4f, 0xd7, 0x5c, 0xfb, 0x2f, 0x6e, 0x6d, 0x16, 0xd5, 0x14, 0xae, 0xf1, + 0xd9, 0xbb, 0x0b, 0x17, 0xa2, 0xc3, 0x69, 0x49, 0xea, 0xb6, 0xe5, 0xe9, 0xa6, 0x25, 0xac, 0x3c, + 0x3e, 0x4a, 0x3e, 0xb8, 0xb5, 0x59, 0x7c, 0x5c, 0xd6, 0x41, 0x9f, 0x26, 0xde, 0xf8, 0x6e, 0x7c, + 0x88, 0x01, 0x4a, 0x0a, 0xaa, 0xd2, 0xd2, 0x1b, 0xbe, 0xe9, 0x7a, 0x69, 0x6b, 0xb3, 0xf8, 0x81, + 0xd4, 0x3a, 0x4c, 0x46, 0x25, 0x2f, 0x95, 0xdd, 0x38, 0x11, 0x0d, 0x48, 0x88, 0x5b, 0xb0, 0x0d, + 0x8a, 0xdf, 0xd0, 0x8f, 0xfc, 0xd5, 0xad, 0xcd, 0xe2, 0x05, 0x89, 0xbf, 0x65, 0x1b, 0x34, 0xde, + 0xfc, 0x94, 0xd2, 0xea, 0x6f, 0xe7, 0xe0, 0x42, 0xb5, 0x34, 0x3f, 0x57, 0x31, 0x7c, 0xdb, 0x62, + 0xc9, 0xb1, 0xef, 0x99, 0x86, 0x34, 0x7a, 0x57, 0xe0, 0x74, 0x0c, 0x35, 0x8d, 0xe6, 0x4c, 0x60, + 0xd5, 0xe2, 0xb7, 0xf9, 0x76, 0x4b, 0x5b, 0xd0, 0xd4, 0xb8, 0xcd, 0x53, 0x8b, 0x98, 0xf4, 0xdd, + 0x18, 0xb1, 0x3e, 0x8a, 0xa1, 0xaa, 0x6b, 0xb6, 0xe3, 0xd5, 0x3b, 0x9e, 0x50, 0x02, 0xec, 0xa3, + 0x44, 0x1d, 0xae, 0x20, 0xea, 0x51, 0x85, 0xcf, 0x87, 0x7c, 0x21, 0x03, 0xe3, 0x25, 0xcf, 0x73, + 0xcc, 0x95, 0x8e, 0x47, 0xe7, 0xf5, 0x76, 0xdb, 0xb4, 0x1a, 0x38, 0xd6, 0x87, 0xaf, 0xbd, 0x12, + 0xac, 0x91, 0x3d, 0x25, 0x71, 0x25, 0x5e, 0x5c, 0x1a, 0xa2, 0xba, 0x8f, 0xaa, 0xb5, 0x38, 0x4e, + 0x1e, 0xa2, 0xf1, 0x72, 0x6c, 0x88, 0xa6, 0xf2, 0xda, 0xd5, 0x10, 0xfd, 0x6a, 0x0e, 0xce, 0x2d, + 0xde, 0xf5, 0x74, 0x8d, 0xba, 0x76, 0xc7, 0xa9, 0x53, 0xf7, 0x56, 0xdb, 0xd0, 0x3d, 0x1a, 0x8e, + 0xd4, 0x22, 0xf4, 0x97, 0x0c, 0x83, 0x1a, 0xc8, 0xae, 0x9f, 0xef, 0xbf, 0x74, 0x06, 0xd0, 0x38, + 0x9c, 0x3c, 0x01, 0x03, 0xa2, 0x0c, 0x72, 0xef, 0x9f, 0x1c, 0xde, 0xda, 0x2c, 0x0e, 0x74, 0x38, + 0x48, 0xf3, 0x71, 0x8c, 0xac, 0x4c, 0x9b, 0x94, 0x91, 0xe5, 0x42, 0x32, 0x83, 0x83, 0x34, 0x1f, + 0x47, 0xde, 0x84, 0x31, 0x64, 0x1b, 0xb4, 0x47, 0xcc, 0x7d, 0x27, 0x7c, 0xe9, 0xca, 0x8d, 0xe5, + 0x4b, 0x13, 0xb6, 0xa6, 0xe6, 0xf8, 0x05, 0xb4, 0x18, 0x03, 0x72, 0x07, 0xc6, 0x45, 0x23, 0x42, + 0xa6, 0xfd, 0x3d, 0x98, 0x9e, 0xdc, 0xda, 0x2c, 0x4e, 0x88, 0xf6, 0x4b, 0x6c, 0x13, 0x4c, 0x18, + 0x63, 0xd1, 0xec, 0x90, 0x71, 0x61, 0x3b, 0xc6, 0xe2, 0x8b, 0x65, 0xc6, 0x71, 0x26, 0xea, 0x5b, + 0x30, 0x22, 0x17, 0x24, 0xa7, 0x70, 0x8f, 0xcb, 0xc7, 0x09, 0xee, 0x8e, 0x4d, 0x03, 0x37, 0xb6, + 0xcf, 0xc0, 0x70, 0x99, 0xba, 0x75, 0xc7, 0x6c, 0x33, 0xab, 0x41, 0x28, 0xf9, 0xb1, 0xad, 0xcd, + 0xe2, 0xb0, 0x11, 0x82, 0x35, 0x99, 0x46, 0xfd, 0x17, 0x19, 0x38, 0xc5, 0x78, 0x97, 0x5c, 0xd7, + 0x6c, 0x58, 0x2d, 0x79, 0xd9, 0x7e, 0x0a, 0x0a, 0x55, 0xac, 0x4f, 0xd4, 0x74, 0x62, 0x6b, 0xb3, + 0x38, 0xce, 0x5b, 0x20, 0xe9, 0xa1, 0xa0, 0x09, 0x36, 0x78, 0xd9, 0x6d, 0x36, 0x78, 0xcc, 0xa4, + 0xf5, 0x74, 0xc7, 0x33, 0xad, 0x46, 0xd5, 0xd3, 0xbd, 0x8e, 0x1b, 0x31, 0x69, 0x05, 0xa6, 0xe6, + 0x22, 0x2a, 0x62, 0xd2, 0x46, 0x0a, 0x91, 0xd7, 0x60, 0x64, 0xda, 0x32, 0x42, 0x26, 0x7c, 0x42, + 0x7c, 0x84, 0x59, 0x9a, 0x14, 0xe1, 0x49, 0x16, 0x91, 0x02, 0xea, 0x7f, 0x9d, 0x01, 0x85, 0xef, + 0xc6, 0xe6, 0x4c, 0xd7, 0x9b, 0xa7, 0xad, 0x15, 0x69, 0x76, 0x9a, 0xf1, 0xb7, 0x77, 0x0c, 0x27, + 0xad, 0x45, 0x68, 0x0a, 0x88, 0xed, 0x5d, 0xd3, 0x74, 0xbd, 0xf8, 0x64, 0x18, 0x2b, 0x45, 0x2a, + 0x30, 0xc0, 0x39, 0x73, 0x5b, 0x62, 0xf8, 0x9a, 0xe2, 0x2b, 0x42, 0xbc, 0x6a, 0xae, 0x0c, 0x2d, + 0x4e, 0x2c, 0xef, 0xcf, 0x45, 0x79, 0xf5, 0xbf, 0xc9, 0xc2, 0x78, 0xbc, 0x10, 0xb9, 0x03, 0x83, + 0x6f, 0xd8, 0xa6, 0x45, 0x8d, 0x45, 0x0b, 0x5b, 0xd8, 0xfb, 0x94, 0xc2, 0xb7, 0xc5, 0x8f, 0xbf, + 0x8d, 0x65, 0x6a, 0xb2, 0x05, 0x8b, 0x87, 0x16, 0x01, 0x33, 0xf2, 0x71, 0x18, 0x62, 0x36, 0xe0, + 0x3d, 0xe4, 0x9c, 0xdd, 0x96, 0xf3, 0xa3, 0x82, 0xf3, 0x09, 0x87, 0x17, 0x4a, 0xb2, 0x0e, 0xd9, + 0x31, 0xbd, 0xd2, 0xa8, 0xee, 0xda, 0x96, 0xe8, 0x79, 0xd4, 0x2b, 0x07, 0x21, 0xb2, 0x5e, 0x71, + 0x1a, 0x66, 0xba, 0xf2, 0x8f, 0xc5, 0x6e, 0x90, 0xf6, 0x2e, 0x5c, 0x56, 0xf1, 0x1e, 0x90, 0x88, + 0xd5, 0x1f, 0xc9, 0xc2, 0xd3, 0xa1, 0xc8, 0x34, 0x7a, 0xcf, 0xa4, 0xeb, 0x42, 0x9c, 0x6b, 0x66, + 0x5b, 0x6c, 0x1e, 0x99, 0xca, 0xbb, 0x53, 0x6b, 0xba, 0xd5, 0xa0, 0x06, 0xb9, 0x0c, 0xfd, 0x6c, + 0x87, 0xef, 0x2a, 0x19, 0x34, 0xd7, 0x70, 0x3a, 0x71, 0x18, 0x40, 0x3e, 0x7d, 0x40, 0x0a, 0x62, + 0x43, 0x61, 0xd9, 0xd1, 0x4d, 0xcf, 0xef, 0xd9, 0x52, 0xb2, 0x67, 0x77, 0x50, 0xe3, 0x15, 0xce, + 0x83, 0xcf, 0xf9, 0x28, 0x08, 0x0f, 0x01, 0xb2, 0x20, 0x38, 0xc9, 0xd9, 0x17, 0x61, 0x58, 0x22, + 0xde, 0xd5, 0xa4, 0xfe, 0x8d, 0xbc, 0xac, 0xeb, 0x7e, 0xb3, 0x84, 0xae, 0x5f, 0x65, 0x3a, 0xea, + 0xba, 0xcc, 0xaa, 0xe0, 0x4a, 0x2e, 0x34, 0x11, 0x41, 0x51, 0x4d, 0x44, 0x10, 0x79, 0x16, 0x06, + 0x39, 0x8b, 0x60, 0xff, 0x8a, 0x7b, 0x5f, 0x07, 0x61, 0xd1, 0xa5, 0x39, 0x20, 0x24, 0xbf, 0x92, + 0x81, 0xf3, 0x3d, 0x25, 0x81, 0xca, 0x30, 0x7c, 0xed, 0xb9, 0x07, 0x12, 0xe3, 0xe4, 0xd3, 0x5b, + 0x9b, 0xc5, 0xcb, 0xad, 0x80, 0xa4, 0xe6, 0x48, 0x34, 0xb5, 0x3a, 0x27, 0x92, 0xda, 0xd5, 0xbb, + 0x29, 0xcc, 0x78, 0xe4, 0x95, 0xce, 0xe0, 0x19, 0x8e, 0x55, 0xdf, 0xf0, 0x1b, 0x99, 0x0f, 0x8d, + 0x47, 0xf1, 0xbd, 0xab, 0x3e, 0x49, 0x4a, 0x35, 0x5d, 0xb8, 0x90, 0x3a, 0x9c, 0xe6, 0x98, 0xb2, + 0xbe, 0xb1, 0xb8, 0x3a, 0x6f, 0x5b, 0xde, 0x9a, 0x5f, 0x41, 0xbf, 0x7c, 0x08, 0x82, 0x15, 0x18, + 0xfa, 0x46, 0xcd, 0x5e, 0xad, 0xb5, 0x18, 0x55, 0x4a, 0x1d, 0xdd, 0x38, 0xb1, 0x89, 0x56, 0x8c, + 0x39, 0x7f, 0x0a, 0x2a, 0x84, 0x47, 0x54, 0xfe, 0x38, 0x4d, 0x4e, 0x38, 0xb1, 0x42, 0x6a, 0x05, + 0x46, 0xe6, 0xec, 0xfa, 0xdd, 0x40, 0x5d, 0x5e, 0x84, 0xc2, 0xb2, 0xee, 0x34, 0xa8, 0x87, 0xb2, + 0x18, 0xbe, 0x36, 0x71, 0x85, 0x1f, 0xfb, 0x32, 0x22, 0x8e, 0x98, 0x1c, 0x13, 0xb3, 0x41, 0xc1, + 0xc3, 0xdf, 0x9a, 0x28, 0xa0, 0x7e, 0xa7, 0x1f, 0x46, 0xc4, 0x11, 0x25, 0xce, 0xe6, 0xe4, 0xa5, + 0xf0, 0xd0, 0x57, 0x4c, 0x5f, 0xc1, 0x31, 0x4d, 0x70, 0xbc, 0x34, 0xc2, 0x98, 0xfd, 0xe1, 0x66, + 0x31, 0xb3, 0xb5, 0x59, 0xec, 0xd3, 0x06, 0xa5, 0x4d, 0x65, 0xb8, 0xde, 0x48, 0x0b, 0xac, 0x7c, + 0xe8, 0x18, 0x2b, 0xcb, 0xd7, 0x9f, 0xd7, 0x60, 0x40, 0xb4, 0x41, 0x68, 0xdc, 0xe9, 0xf0, 0x2c, + 0x23, 0x72, 0xd4, 0x1a, 0x2b, 0xed, 0x97, 0x22, 0xaf, 0x40, 0x81, 0xef, 0xed, 0x85, 0x00, 0x4e, + 0xa5, 0x9f, 0x85, 0xc4, 0x8a, 0x8b, 0x32, 0x64, 0x16, 0x20, 0xdc, 0xd7, 0x07, 0x27, 0xcb, 0x82, + 0x43, 0x72, 0xc7, 0x1f, 0xe3, 0x22, 0x95, 0x25, 0xcf, 0xc3, 0xc8, 0x32, 0x75, 0x5a, 0xa6, 0xa5, + 0x37, 0xab, 0xe6, 0x3b, 0xfe, 0xe1, 0x32, 0x2e, 0xbc, 0xae, 0xf9, 0x8e, 0x3c, 0x72, 0x23, 0x74, + 0xe4, 0x53, 0x69, 0xfb, 0xe6, 0x01, 0x6c, 0xc8, 0x63, 0xdb, 0x6e, 0x28, 0x63, 0xed, 0x49, 0xd9, + 0x46, 0xbf, 0x09, 0xa3, 0x91, 0x2d, 0x93, 0x38, 0x3d, 0x3c, 0x9f, 0x64, 0x2d, 0xed, 0xff, 0x62, + 0x6c, 0xa3, 0x1c, 0x98, 0x26, 0x57, 0x2c, 0xd3, 0x33, 0xf5, 0xe6, 0x94, 0xdd, 0x6a, 0xe9, 0x96, + 0xa1, 0x0c, 0x85, 0x9a, 0x6c, 0x72, 0x4c, 0xad, 0xce, 0x51, 0xb2, 0x26, 0x47, 0x0b, 0xb1, 0x6d, + 0xb9, 0xe8, 0x43, 0x8d, 0xd6, 0x6d, 0x87, 0xd9, 0x02, 0x78, 0x38, 0x28, 0xb6, 0xe5, 0x2e, 0xc7, + 0xd5, 0x1c, 0x1f, 0x29, 0x1b, 0xdb, 0xf1, 0x82, 0x6f, 0xe4, 0x07, 0x87, 0xc7, 0x47, 0xe2, 0xe7, + 0xb9, 0xea, 0x7f, 0x95, 0x83, 0x61, 0x41, 0xca, 0x96, 0xd2, 0x23, 0x05, 0xdf, 0x8b, 0x82, 0xa7, + 0x2a, 0x6a, 0x61, 0xbf, 0x14, 0x55, 0xfd, 0x62, 0x36, 0x98, 0x8d, 0x96, 0x1c, 0xd3, 0xda, 0xdb, + 0x6c, 0x74, 0x11, 0x60, 0x6a, 0xad, 0x63, 0xdd, 0xe5, 0xf7, 0x56, 0xd9, 0xf0, 0xde, 0xaa, 0x6e, + 0x6a, 0x12, 0x86, 0x9c, 0x87, 0x7c, 0x99, 0xf1, 0x67, 0x3d, 0x33, 0x32, 0x39, 0xf4, 0x2e, 0xe7, + 0x94, 0x79, 0x5a, 0x43, 0x30, 0xdb, 0x5c, 0x4d, 0x6e, 0x78, 0x94, 0x9b, 0xb3, 0x39, 0xbe, 0xb9, + 0x5a, 0x61, 0x00, 0x8d, 0xc3, 0xc9, 0x75, 0x98, 0x28, 0xd3, 0xa6, 0xbe, 0x31, 0x6f, 0x36, 0x9b, + 0xa6, 0x4b, 0xeb, 0xb6, 0x65, 0xb8, 0x28, 0x64, 0x51, 0x5d, 0xcb, 0xd5, 0x92, 0x04, 0x44, 0x85, + 0xc2, 0xe2, 0xea, 0xaa, 0x4b, 0x3d, 0x14, 0x5f, 0x6e, 0x12, 0xd8, 0xe4, 0x6c, 0x23, 0x44, 0x13, + 0x18, 0xf5, 0xd7, 0x33, 0x6c, 0xf7, 0xe2, 0xde, 0xf5, 0xec, 0x76, 0xa0, 0xe5, 0x7b, 0x12, 0xc9, + 0xe5, 0xd0, 0xae, 0xc8, 0xe2, 0xd7, 0x1e, 0x13, 0x5f, 0x3b, 0x20, 0x6c, 0x8b, 0xd0, 0xa2, 0x48, + 0xfd, 0xaa, 0xdc, 0x36, 0x5f, 0xa5, 0xfe, 0x65, 0x16, 0x4e, 0x8b, 0x16, 0x4f, 0x35, 0xcd, 0xf6, + 0x8a, 0xad, 0x3b, 0x86, 0x46, 0xeb, 0xd4, 0xbc, 0x47, 0x0f, 0xe7, 0xc0, 0x8b, 0x0e, 0x9d, 0xfc, + 0x1e, 0x86, 0xce, 0x35, 0xdc, 0x08, 0x32, 0xc9, 0xe0, 0x81, 0x2f, 0x37, 0x2a, 0xc6, 0xb7, 0x36, + 0x8b, 0x23, 0x06, 0x07, 0xe3, 0x91, 0xbf, 0x26, 0x13, 0x31, 0x25, 0x99, 0xa3, 0x56, 0xc3, 0x5b, + 0x43, 0x25, 0xe9, 0xe7, 0x4a, 0xd2, 0x44, 0x88, 0x26, 0x30, 0xea, 0x3f, 0xce, 0xc2, 0x89, 0xb8, + 0xc8, 0xab, 0xd4, 0x32, 0x8e, 0xe4, 0xfd, 0xde, 0xc8, 0xfb, 0x7b, 0x39, 0x78, 0x44, 0x94, 0xa9, + 0xae, 0xe9, 0x0e, 0x35, 0xca, 0xa6, 0x43, 0xeb, 0x9e, 0xed, 0x6c, 0x1c, 0x62, 0x03, 0x6a, 0xff, + 0xc4, 0x7e, 0x1d, 0x0a, 0x62, 0xfb, 0xcf, 0xd7, 0x99, 0xb1, 0xa0, 0x25, 0x08, 0x4d, 0xac, 0x50, + 0xfc, 0xe8, 0x20, 0xd6, 0x59, 0x85, 0x9d, 0x74, 0xd6, 0x47, 0x60, 0x34, 0x10, 0x3d, 0x6e, 0x44, + 0x07, 0x42, 0x6b, 0xcb, 0xf0, 0x11, 0xb8, 0x17, 0xd5, 0xa2, 0x84, 0x58, 0x9b, 0x0f, 0xa8, 0x94, + 0xd1, 0x1a, 0x1a, 0x15, 0xb5, 0x05, 0xe5, 0x4c, 0x43, 0x93, 0x89, 0xd4, 0xcd, 0x3c, 0x9c, 0x4d, + 0xef, 0x76, 0x8d, 0xea, 0xc6, 0x51, 0xaf, 0x7f, 0x5f, 0xf6, 0x3a, 0x79, 0x0c, 0xf2, 0x4b, 0xba, + 0xb7, 0x26, 0xee, 0xc1, 0xf1, 0x4e, 0x78, 0xd5, 0x6c, 0xd2, 0x5a, 0x5b, 0xf7, 0xd6, 0x34, 0x44, + 0x49, 0x73, 0x06, 0x20, 0xc7, 0x94, 0x39, 0x43, 0x5a, 0xec, 0x87, 0x1f, 0xcd, 0x5c, 0xca, 0xa7, + 0x2e, 0xf6, 0xdf, 0xc9, 0x77, 0x9b, 0x57, 0xee, 0x38, 0xa6, 0x47, 0x8f, 0x34, 0xec, 0x48, 0xc3, + 0xf6, 0xa8, 0x61, 0x7f, 0x9c, 0x85, 0xd1, 0x60, 0xd3, 0xf4, 0x36, 0xad, 0x1f, 0xcc, 0x5a, 0x15, + 0x6e, 0x65, 0x72, 0x7b, 0xde, 0xca, 0xec, 0x45, 0xa1, 0xd4, 0xe0, 0xc8, 0x93, 0x9b, 0x06, 0x28, + 0x31, 0x7e, 0xe4, 0x19, 0x1c, 0x74, 0x3e, 0x06, 0x03, 0xf3, 0xfa, 0x7d, 0xb3, 0xd5, 0x69, 0x09, + 0x2b, 0x1d, 0xfd, 0xba, 0x5a, 0xfa, 0x7d, 0xcd, 0x87, 0xab, 0xff, 0x77, 0x06, 0xc6, 0x84, 0x50, + 0x05, 0xf3, 0x3d, 0x49, 0x35, 0x94, 0x4e, 0x76, 0xcf, 0xd2, 0xc9, 0x3d, 0xb8, 0x74, 0xd4, 0x9f, + 0xcb, 0x81, 0x32, 0x63, 0x36, 0xe9, 0xb2, 0xa3, 0x5b, 0xee, 0x2a, 0x75, 0xc4, 0x76, 0x7a, 0x9a, + 0xb1, 0xda, 0xd3, 0x07, 0x4a, 0x53, 0x4a, 0xf6, 0x81, 0xa6, 0x94, 0x0f, 0xc1, 0x90, 0x68, 0x4c, + 0xe0, 0x53, 0x88, 0xa3, 0xc6, 0xf1, 0x81, 0x5a, 0x88, 0x67, 0xc4, 0xa5, 0x76, 0xdb, 0xb1, 0xef, + 0x51, 0x87, 0xdf, 0x52, 0x09, 0x62, 0xdd, 0x07, 0x6a, 0x21, 0x5e, 0xe2, 0x4c, 0x7d, 0x7b, 0x51, + 0xe6, 0x4c, 0x1d, 0x2d, 0xc4, 0x93, 0x4b, 0x30, 0x38, 0x67, 0xd7, 0x75, 0x14, 0x34, 0x9f, 0x56, + 0x46, 0xb6, 0x36, 0x8b, 0x83, 0x4d, 0x01, 0xd3, 0x02, 0x2c, 0xa3, 0x2c, 0xdb, 0xeb, 0x56, 0xd3, + 0xd6, 0xb9, 0xf3, 0xcb, 0x20, 0xa7, 0x34, 0x04, 0x4c, 0x0b, 0xb0, 0x8c, 0x92, 0xc9, 0x1c, 0x9d, + 0x8a, 0x06, 0x43, 0x9e, 0xab, 0x02, 0xa6, 0x05, 0x58, 0xf5, 0xd7, 0xf3, 0x4c, 0x7b, 0x5d, 0xf3, + 0x9d, 0x87, 0x7e, 0x5d, 0x08, 0x07, 0x4c, 0xff, 0x03, 0x0c, 0x98, 0x87, 0xe6, 0xc0, 0x4e, 0xfd, + 0xab, 0x01, 0x00, 0x21, 0xfd, 0xe9, 0xa3, 0xcd, 0xe1, 0xde, 0xb4, 0xa6, 0x0c, 0x13, 0xd3, 0xd6, + 0x9a, 0x6e, 0xd5, 0xa9, 0x11, 0x1e, 0x5b, 0x16, 0x70, 0x68, 0xa3, 0x4f, 0x2f, 0x15, 0xc8, 0xf0, + 0xdc, 0x52, 0x4b, 0x16, 0x20, 0xcf, 0xc0, 0x70, 0xc5, 0xf2, 0xa8, 0xa3, 0xd7, 0x3d, 0xf3, 0x1e, + 0x15, 0x53, 0x03, 0xde, 0x0c, 0x9b, 0x21, 0x58, 0x93, 0x69, 0xc8, 0x75, 0x18, 0x59, 0xd2, 0x1d, + 0xcf, 0xac, 0x9b, 0x6d, 0xdd, 0xf2, 0x5c, 0x65, 0x10, 0x67, 0x34, 0xb4, 0x30, 0xda, 0x12, 0x5c, + 0x8b, 0x50, 0x91, 0x4f, 0xc1, 0x10, 0x6e, 0x4d, 0xd1, 0x71, 0x7a, 0x68, 0xdb, 0x8b, 0xc3, 0xc7, + 0x43, 0xf7, 0x40, 0x7e, 0xfa, 0x8a, 0x37, 0xc0, 0xf1, 0xbb, 0xc3, 0x80, 0x23, 0xf9, 0x18, 0x0c, + 0x4c, 0x5b, 0x06, 0x32, 0x87, 0x6d, 0x99, 0xab, 0x82, 0xf9, 0xa9, 0x90, 0xb9, 0xdd, 0x8e, 0xf1, + 0xf6, 0xd9, 0xa5, 0x8f, 0xb2, 0xe1, 0xf7, 0x6e, 0x94, 0x8d, 0xbc, 0x07, 0xc7, 0xe2, 0xa3, 0xfb, + 0x75, 0x2c, 0x3e, 0xf6, 0x80, 0xc7, 0xe2, 0xea, 0x3b, 0x30, 0x3c, 0xb9, 0x34, 0x13, 0x8c, 0xde, + 0x33, 0x90, 0x5b, 0x12, 0x9e, 0x0a, 0x79, 0x6e, 0xcf, 0xb4, 0x4d, 0x43, 0x63, 0x30, 0x72, 0x19, + 0x06, 0xa7, 0xd0, 0xfd, 0x4d, 0xdc, 0x22, 0xe6, 0xf9, 0xfa, 0x57, 0x47, 0x18, 0x7a, 0xc1, 0xfa, + 0x68, 0xf2, 0x04, 0x0c, 0x2c, 0x39, 0x76, 0xc3, 0xd1, 0x5b, 0x62, 0x0d, 0x46, 0x57, 0x91, 0x36, + 0x07, 0x69, 0x3e, 0x4e, 0xfd, 0x89, 0x8c, 0x6f, 0xb6, 0xb3, 0x12, 0xd5, 0x0e, 0x1e, 0xcd, 0x63, + 0xdd, 0x83, 0xbc, 0x84, 0xcb, 0x41, 0x9a, 0x8f, 0x23, 0x97, 0xa1, 0x7f, 0xda, 0x71, 0x6c, 0x47, + 0x76, 0x36, 0xa7, 0x0c, 0x20, 0x5f, 0xf7, 0x22, 0x05, 0x79, 0x01, 0x86, 0xf9, 0x9c, 0xc3, 0x4f, + 0x34, 0x73, 0xbd, 0x6e, 0x4a, 0x65, 0x4a, 0xf5, 0x5b, 0x39, 0xc9, 0x66, 0xe3, 0x12, 0x7f, 0x08, + 0x6f, 0x05, 0x9e, 0x85, 0xdc, 0xe4, 0xd2, 0x8c, 0x98, 0x00, 0x8f, 0xfb, 0x45, 0x25, 0x55, 0x89, + 0x95, 0x63, 0xd4, 0xe4, 0x1c, 0xe4, 0x97, 0x98, 0xfa, 0x14, 0x50, 0x3d, 0x06, 0xb7, 0x36, 0x8b, + 0xf9, 0x36, 0xd3, 0x1f, 0x84, 0x22, 0x96, 0x6d, 0x66, 0xf8, 0x8e, 0x89, 0x63, 0xc3, 0x7d, 0xcc, + 0x39, 0xc8, 0x97, 0x9c, 0xc6, 0x3d, 0x31, 0x6b, 0x21, 0x56, 0x77, 0x1a, 0xf7, 0x34, 0x84, 0x92, + 0xab, 0x00, 0x1a, 0xf5, 0x3a, 0x8e, 0x85, 0xef, 0x40, 0x86, 0xf0, 0xfc, 0x0d, 0x67, 0x43, 0x07, + 0xa1, 0xb5, 0xba, 0x6d, 0x50, 0x4d, 0x22, 0x51, 0xff, 0xcb, 0xf0, 0x62, 0xa7, 0x6c, 0xba, 0x77, + 0x8f, 0xba, 0x70, 0x17, 0x5d, 0xa8, 0x8b, 0x23, 0xce, 0x64, 0x27, 0x15, 0xa1, 0x7f, 0xa6, 0xa9, + 0x37, 0x5c, 0xec, 0x43, 0xe1, 0x4b, 0xb6, 0xca, 0x00, 0x1a, 0x87, 0xc7, 0xfa, 0x69, 0x70, 0xfb, + 0x7e, 0xfa, 0x5a, 0x7f, 0x30, 0xda, 0x16, 0xa8, 0xb7, 0x6e, 0x3b, 0x47, 0x5d, 0xb5, 0xd3, 0xae, + 0xba, 0x08, 0x03, 0x55, 0xa7, 0x2e, 0x1d, 0x5d, 0xe0, 0x7e, 0xc0, 0x75, 0xea, 0xfc, 0xd8, 0xc2, + 0x47, 0x32, 0xba, 0xb2, 0xeb, 0x21, 0xdd, 0x40, 0x48, 0x67, 0xb8, 0x9e, 0xa0, 0x13, 0x48, 0x41, + 0xb7, 0x64, 0x3b, 0x9e, 0xe8, 0xb8, 0x80, 0xae, 0x6d, 0x3b, 0x9e, 0xe6, 0x23, 0xc9, 0x87, 0x00, + 0x96, 0xa7, 0x96, 0x7c, 0x67, 0xfb, 0xa1, 0xd0, 0x17, 0x50, 0x78, 0xd9, 0x6b, 0x12, 0x9a, 0x2c, + 0xc3, 0xd0, 0x62, 0x9b, 0x3a, 0x7c, 0x2b, 0xc4, 0x5f, 0x76, 0x7c, 0x30, 0x26, 0x5a, 0xd1, 0xef, + 0x57, 0xc4, 0xff, 0x01, 0x39, 0x5f, 0x5f, 0x6c, 0xff, 0xa7, 0x16, 0x32, 0x22, 0x2f, 0x40, 0xa1, + 0xc4, 0xed, 0xbc, 0x61, 0x64, 0x19, 0x88, 0x0c, 0xb7, 0xa0, 0x1c, 0xc5, 0xf7, 0xec, 0x3a, 0xfe, + 0xad, 0x09, 0x72, 0xf5, 0x32, 0x8c, 0xc7, 0xab, 0x21, 0xc3, 0x30, 0x30, 0xb5, 0xb8, 0xb0, 0x30, + 0x3d, 0xb5, 0x3c, 0xde, 0x47, 0x06, 0x21, 0x5f, 0x9d, 0x5e, 0x28, 0x8f, 0x67, 0xd4, 0x5f, 0x95, + 0x66, 0x10, 0xa6, 0x5a, 0x47, 0x57, 0xc3, 0x7b, 0xba, 0x6f, 0x19, 0xc7, 0xfb, 0x50, 0x3c, 0x31, + 0x68, 0x99, 0x9e, 0x47, 0x0d, 0xb1, 0x4a, 0xe0, 0x7d, 0xa1, 0x77, 0x5f, 0x4b, 0xe0, 0xc9, 0x53, + 0x30, 0x8a, 0x30, 0x71, 0x45, 0xc8, 0xf7, 0xc7, 0xa2, 0x80, 0x73, 0x5f, 0x8b, 0x22, 0xd5, 0x6f, + 0x87, 0xb7, 0xc3, 0x73, 0x54, 0x3f, 0xac, 0x37, 0x8a, 0xef, 0x93, 0xfe, 0x52, 0xff, 0x36, 0xcf, + 0x9f, 0x80, 0xf0, 0x87, 0x7b, 0x07, 0x21, 0xca, 0xf0, 0x48, 0x37, 0xb7, 0x8b, 0x23, 0xdd, 0xa7, + 0xa0, 0x30, 0x4f, 0xbd, 0x35, 0xdb, 0x77, 0xfc, 0x42, 0x0f, 0xbd, 0x16, 0x42, 0x64, 0x0f, 0x3d, + 0x4e, 0x43, 0xee, 0x02, 0xf1, 0x5f, 0xe5, 0x05, 0x8e, 0xd8, 0xfe, 0x11, 0xf2, 0xe9, 0xc4, 0x3e, + 0xa5, 0x8a, 0x4f, 0x72, 0xd1, 0xc7, 0xfe, 0x44, 0xe0, 0xe8, 0x2d, 0x79, 0x62, 0xfd, 0xcd, 0x66, + 0xb1, 0xc0, 0x69, 0xb4, 0x14, 0xb6, 0xe4, 0x4d, 0x18, 0x9a, 0x9f, 0x29, 0x89, 0x17, 0x7a, 0xdc, + 0x2b, 0xe2, 0x4c, 0x20, 0x45, 0x1f, 0x11, 0x88, 0x04, 0xdf, 0xdb, 0xb4, 0x56, 0xf5, 0xe4, 0x03, + 0xbd, 0x90, 0x0b, 0xd3, 0x16, 0xfe, 0x72, 0x47, 0x9c, 0x2e, 0x04, 0xda, 0x12, 0x7d, 0xcf, 0x13, + 0x97, 0x15, 0xc7, 0xc6, 0xb4, 0x65, 0x70, 0x0f, 0xa3, 0x7b, 0x11, 0x26, 0x4a, 0xed, 0x76, 0xd3, + 0xa4, 0x06, 0xea, 0x8b, 0xd6, 0x69, 0x52, 0x57, 0xb8, 0xfc, 0xe0, 0x63, 0x10, 0x9d, 0x23, 0x6b, + 0xf8, 0x2e, 0xb4, 0xe6, 0x74, 0xa2, 0xfe, 0x99, 0xc9, 0xb2, 0xea, 0x4f, 0x65, 0xe1, 0xd4, 0x94, + 0x43, 0x75, 0x8f, 0xce, 0xcf, 0x94, 0x4a, 0x1d, 0xf4, 0x91, 0x6b, 0x36, 0xa9, 0xd5, 0x38, 0x98, + 0x61, 0xfd, 0x32, 0x8c, 0x05, 0x0d, 0xa8, 0xd6, 0xed, 0x36, 0x95, 0x1f, 0x56, 0xd5, 0x7d, 0x4c, + 0xcd, 0x65, 0x28, 0x2d, 0x46, 0x4a, 0x6e, 0xc2, 0xf1, 0x00, 0x52, 0x6a, 0x36, 0xed, 0x75, 0x8d, + 0x76, 0x5c, 0xee, 0x18, 0x3b, 0xc8, 0x1d, 0x63, 0x43, 0x0e, 0x3a, 0xc3, 0xd7, 0x1c, 0x46, 0xa0, + 0xa5, 0x95, 0x52, 0xbf, 0x9e, 0x83, 0xd3, 0xb7, 0xf5, 0xa6, 0x69, 0x84, 0xa2, 0xd1, 0xa8, 0xdb, + 0xb6, 0x2d, 0x97, 0x1e, 0xa2, 0x51, 0x1a, 0x19, 0x0a, 0xf9, 0x7d, 0x19, 0x0a, 0xc9, 0x2e, 0xea, + 0xdf, 0x73, 0x17, 0x15, 0x1e, 0xa8, 0x8b, 0xfe, 0x51, 0x06, 0xc6, 0x7d, 0xc7, 0x7f, 0xf9, 0x35, + 0xb5, 0xe4, 0x95, 0x8e, 0x47, 0x88, 0x31, 0x3f, 0x68, 0xc4, 0x93, 0x2a, 0x0c, 0x4c, 0xdf, 0x6f, + 0x9b, 0x0e, 0x75, 0x77, 0xe0, 0xc4, 0x7d, 0x5e, 0x1c, 0x97, 0x4c, 0x50, 0x5e, 0x24, 0x71, 0x52, + 0xc2, 0xc1, 0xf8, 0x9c, 0x8f, 0x3f, 0x7d, 0x98, 0xf4, 0x9f, 0x88, 0xf3, 0xe7, 0x7c, 0xe2, 0x89, + 0x44, 0xe4, 0x7d, 0x66, 0x48, 0x4a, 0x1e, 0x87, 0xdc, 0xf2, 0xf2, 0x9c, 0x98, 0x49, 0xf1, 0x69, + 0xbe, 0xe7, 0xc9, 0xef, 0x15, 0x19, 0x56, 0xfd, 0xb3, 0x2c, 0x00, 0x53, 0x05, 0x3e, 0x5c, 0x0f, + 0x44, 0x09, 0x27, 0x61, 0xd0, 0x17, 0xb8, 0x50, 0xc3, 0xc0, 0x6b, 0x3f, 0xde, 0x11, 0xf1, 0xba, + 0x83, 0x17, 0x1a, 0x45, 0xdf, 0x91, 0x9c, 0xdf, 0x03, 0xe0, 0xce, 0x06, 0x1d, 0xc9, 0x7d, 0xf7, + 0xf1, 0x0f, 0xc1, 0x90, 0x98, 0xf1, 0xec, 0xc8, 0xf9, 0x7f, 0xdd, 0x07, 0x6a, 0x21, 0x3e, 0x36, + 0xb5, 0x16, 0xf6, 0xb0, 0x10, 0xfb, 0xe2, 0xe5, 0xbd, 0x72, 0x24, 0xde, 0x7d, 0x16, 0xef, 0x97, + 0x85, 0x78, 0xf9, 0x0b, 0x9e, 0x43, 0x2b, 0xde, 0x7d, 0x3b, 0xfb, 0x56, 0xff, 0x38, 0x03, 0x84, + 0x35, 0x6b, 0x49, 0x77, 0xdd, 0x75, 0xdb, 0x31, 0xb8, 0x73, 0xfa, 0x81, 0x08, 0x66, 0xff, 0xee, + 0x2b, 0xbf, 0x35, 0x08, 0xc7, 0x23, 0x8e, 0xbf, 0x87, 0x7c, 0xb2, 0xba, 0x1c, 0x1d, 0x4d, 0xbd, + 0x5e, 0xbd, 0x7c, 0x40, 0xbe, 0x10, 0xed, 0x8f, 0x3c, 0x40, 0x93, 0x6e, 0x42, 0x9f, 0x86, 0x11, + 0xf1, 0x83, 0xad, 0xd0, 0xfe, 0x4d, 0x17, 0x8e, 0x52, 0x97, 0x01, 0xb4, 0x08, 0x9a, 0x3c, 0x07, + 0x43, 0x6c, 0xc0, 0x34, 0x30, 0x8a, 0xc7, 0x40, 0xf8, 0xa2, 0xc4, 0xf0, 0x81, 0xf2, 0x7a, 0x12, + 0x50, 0x4a, 0xef, 0x88, 0x06, 0x77, 0xf0, 0x8e, 0xe8, 0xd3, 0x30, 0x5c, 0xb2, 0x2c, 0xdb, 0xc3, + 0x4d, 0xba, 0x2b, 0xae, 0x26, 0xba, 0x5a, 0xe5, 0x8f, 0xe3, 0xe3, 0xf8, 0x90, 0x3e, 0xd5, 0x2c, + 0x97, 0x19, 0x92, 0x6b, 0xfe, 0xab, 0x18, 0xea, 0x08, 0xaf, 0x72, 0xbc, 0x9e, 0x71, 0x04, 0x2c, + 0xf9, 0x28, 0x06, 0x3b, 0x6f, 0x74, 0xc9, 0xb1, 0xdb, 0xb6, 0x4b, 0x0d, 0x2e, 0xa8, 0xe1, 0x30, + 0xd4, 0x40, 0x5b, 0x20, 0xf0, 0x1d, 0x5b, 0x24, 0xa2, 0x46, 0xa4, 0x08, 0x59, 0x85, 0x13, 0xfe, + 0x45, 0x71, 0xf0, 0x62, 0xb0, 0x52, 0x76, 0x95, 0x11, 0x7c, 0x95, 0x44, 0xe2, 0xca, 0x50, 0x29, + 0x4f, 0x5e, 0xf0, 0xaf, 0x45, 0xfc, 0x27, 0x87, 0x35, 0xd3, 0x90, 0xbb, 0x3a, 0x95, 0x1f, 0xf9, + 0x0c, 0x0c, 0xcf, 0xeb, 0xf7, 0xcb, 0x1d, 0x71, 0xf6, 0x32, 0xba, 0xf3, 0xdb, 0x97, 0x96, 0x7e, + 0xbf, 0x66, 0x88, 0x72, 0x31, 0x9b, 0x42, 0x66, 0x49, 0x6a, 0x70, 0x6a, 0xc9, 0xb1, 0x5b, 0xb6, + 0x47, 0x8d, 0xd8, 0xe3, 0xbb, 0x63, 0xe1, 0x6b, 0xdd, 0xb6, 0xa0, 0xa8, 0xf5, 0x78, 0x85, 0xd7, + 0x85, 0x0d, 0x69, 0xc1, 0xb1, 0x92, 0xeb, 0x76, 0x5a, 0x34, 0xbc, 0xa1, 0x1a, 0xdf, 0xf6, 0x33, + 0x3e, 0x28, 0xbc, 0x96, 0x1f, 0xd1, 0xb1, 0x28, 0xbf, 0xa0, 0xaa, 0x79, 0xa6, 0x5c, 0x23, 0x7e, + 0x4b, 0x9c, 0xf7, 0x1b, 0xf9, 0xc1, 0xb1, 0xf1, 0x63, 0xda, 0xe9, 0x64, 0x63, 0x96, 0x4d, 0xaf, + 0x49, 0xd5, 0x6f, 0x66, 0x00, 0x42, 0x01, 0x93, 0xa7, 0xa3, 0xa1, 0x82, 0x32, 0xe1, 0x45, 0x87, + 0x88, 0x5e, 0x10, 0x89, 0x0d, 0x44, 0xce, 0x41, 0x1e, 0x23, 0x5c, 0x64, 0xc3, 0x83, 0xd5, 0xbb, + 0xa6, 0x65, 0x68, 0x08, 0x65, 0x58, 0xe9, 0x29, 0x3a, 0x62, 0xf1, 0x52, 0x9f, 0x5b, 0x85, 0x65, + 0x38, 0x56, 0xed, 0xac, 0xf8, 0x75, 0x4b, 0xef, 0xea, 0x30, 0xd0, 0x86, 0xdb, 0x59, 0x09, 0x1e, + 0xa3, 0x46, 0xc2, 0x98, 0x44, 0x8b, 0xa8, 0xbf, 0x9e, 0x89, 0xcd, 0x82, 0x07, 0xb8, 0xe8, 0x7d, + 0x20, 0xe9, 0xa7, 0x91, 0x9c, 0x96, 0xd4, 0x9f, 0xcf, 0xc2, 0xf0, 0x92, 0xed, 0x78, 0x22, 0x64, + 0xc8, 0xe1, 0x5e, 0x85, 0xa4, 0xbd, 0x52, 0x7e, 0x17, 0x7b, 0xa5, 0x73, 0x90, 0x97, 0x5c, 0x94, + 0xf9, 0xbd, 0x88, 0x61, 0x38, 0x1a, 0x42, 0xd5, 0x1f, 0xc8, 0x02, 0x7c, 0xec, 0x99, 0x67, 0x1e, + 0x62, 0x01, 0xa9, 0x3f, 0x9b, 0x81, 0x63, 0xe2, 0xa2, 0x4e, 0x0a, 0xba, 0x35, 0xe0, 0x5f, 0xb1, + 0xca, 0xe3, 0x92, 0x83, 0x34, 0x1f, 0xc7, 0x96, 0x80, 0xe9, 0xfb, 0xa6, 0x87, 0x77, 0x15, 0x52, + 0xd4, 0x2d, 0x2a, 0x60, 0xf2, 0x12, 0xe0, 0xd3, 0x91, 0xa7, 0xfd, 0x2b, 0xc8, 0x5c, 0xb8, 0xee, + 0xb1, 0x02, 0xd3, 0xa9, 0xd7, 0x90, 0xea, 0x6f, 0xe6, 0x21, 0x3f, 0x7d, 0x9f, 0xd6, 0x0f, 0x79, + 0xd7, 0x48, 0x07, 0x9b, 0xf9, 0x3d, 0x1e, 0x6c, 0x3e, 0x88, 0x4f, 0xc5, 0x6b, 0x61, 0x7f, 0x16, + 0xa2, 0xd5, 0xc7, 0x7a, 0x3e, 0x5e, 0xbd, 0xdf, 0xd3, 0x87, 0xcf, 0x25, 0xe7, 0x7f, 0xcd, 0x41, + 0xae, 0x3a, 0xb5, 0x74, 0xa4, 0x37, 0x07, 0xaa, 0x37, 0xbd, 0xef, 0xac, 0xd5, 0xe0, 0x1a, 0x6a, + 0x30, 0xf4, 0x12, 0x8d, 0xdd, 0x38, 0x7d, 0x2f, 0x07, 0x63, 0xd5, 0x99, 0xe5, 0x25, 0xe9, 0x24, + 0xf8, 0x26, 0xf7, 0xe4, 0x43, 0x9f, 0x32, 0xde, 0xa5, 0xe7, 0x12, 0xf6, 0xcc, 0xad, 0x8a, 0xe5, + 0x3d, 0x7f, 0xfd, 0xb6, 0xde, 0xec, 0x50, 0x3c, 0x7a, 0xe1, 0x7e, 0xbf, 0xae, 0xf9, 0x0e, 0xfd, + 0x3a, 0x3e, 0xfc, 0xf7, 0x19, 0x90, 0x97, 0x21, 0x77, 0x4b, 0x78, 0x64, 0x74, 0xe3, 0xf3, 0xec, + 0x35, 0xce, 0x87, 0x4d, 0x82, 0xb9, 0x8e, 0x69, 0x20, 0x07, 0x56, 0x8a, 0x15, 0xbe, 0x21, 0x16, + 0xe0, 0x1d, 0x15, 0x6e, 0xf8, 0x85, 0x6f, 0x54, 0xca, 0xa4, 0x0a, 0xc3, 0x4b, 0xd4, 0x69, 0x99, + 0xd8, 0x51, 0xfe, 0x9c, 0xdd, 0x9b, 0x09, 0xdb, 0xa9, 0x0c, 0xb7, 0xc3, 0x42, 0xc8, 0x4c, 0xe6, + 0x42, 0xde, 0x02, 0xe0, 0x36, 0xca, 0x0e, 0x03, 0x39, 0x9e, 0x47, 0xbb, 0x9f, 0x9b, 0x96, 0x29, + 0x36, 0x9e, 0xc4, 0x8c, 0xdc, 0x85, 0xf1, 0x79, 0xdb, 0x30, 0x57, 0x4d, 0xee, 0x7a, 0x89, 0x15, + 0x14, 0xb6, 0x77, 0x78, 0x62, 0xa6, 0x64, 0x4b, 0x2a, 0x97, 0x56, 0x4d, 0x82, 0xb1, 0xfa, 0x3f, + 0xf5, 0x43, 0x9e, 0x75, 0xfb, 0xd1, 0xf8, 0xdd, 0xcb, 0xf8, 0x2d, 0xc1, 0xf8, 0x1d, 0xdb, 0xb9, + 0x6b, 0x5a, 0x8d, 0xc0, 0x2b, 0x5e, 0xec, 0x4d, 0xd1, 0x93, 0x67, 0x9d, 0xe3, 0x6a, 0x81, 0x03, + 0xbd, 0x96, 0x20, 0xdf, 0x66, 0x04, 0xbf, 0x08, 0xc0, 0xdf, 0xba, 0x23, 0xcd, 0x60, 0x18, 0xac, + 0x82, 0xbf, 0x84, 0x47, 0x47, 0x7b, 0x39, 0x58, 0x45, 0x48, 0xcc, 0x36, 0xe1, 0xdc, 0x17, 0x62, + 0x08, 0xfd, 0xee, 0x71, 0x13, 0x8e, 0xbe, 0x10, 0xb2, 0x11, 0xc0, 0xbd, 0x22, 0x96, 0x00, 0xa4, + 0xfb, 0x25, 0x88, 0x09, 0x22, 0x32, 0x39, 0x88, 0xf0, 0x70, 0x29, 0xd7, 0x4b, 0x9a, 0xc4, 0x83, + 0x3c, 0x1f, 0xbb, 0x00, 0x27, 0x11, 0x6e, 0x5d, 0xef, 0xbf, 0x43, 0x07, 0xaa, 0x91, 0xed, 0x1c, + 0xa8, 0xd4, 0x2f, 0x66, 0x61, 0xa8, 0xda, 0x59, 0x71, 0x37, 0x5c, 0x8f, 0xb6, 0x0e, 0xb9, 0x1a, + 0xfb, 0xdb, 0xab, 0x7c, 0xea, 0xf6, 0xea, 0x71, 0x5f, 0x28, 0xd2, 0xb9, 0x63, 0x60, 0xd2, 0xf9, + 0xe2, 0xf8, 0x6f, 0xb3, 0x30, 0xce, 0x2f, 0xce, 0xca, 0xa6, 0x5b, 0xdf, 0x07, 0x67, 0xfe, 0x83, + 0x97, 0xca, 0xde, 0x2e, 0x9b, 0x77, 0xf0, 0x44, 0x42, 0xfd, 0x5c, 0x16, 0x86, 0x4b, 0x1d, 0x6f, + 0xad, 0xe4, 0xa1, 0x6e, 0x3d, 0x94, 0xfb, 0x93, 0xdf, 0xcf, 0xc0, 0x31, 0xd6, 0x90, 0x65, 0xfb, + 0x2e, 0xb5, 0xf6, 0xe1, 0xe0, 0x51, 0x3e, 0x40, 0xcc, 0x3e, 0xe0, 0x01, 0xa2, 0x2f, 0xcb, 0xdc, + 0xee, 0x64, 0x89, 0xc7, 0xe5, 0x9a, 0xdd, 0xa4, 0x87, 0xfb, 0x33, 0xf6, 0xf1, 0xb8, 0xdc, 0x17, + 0xc8, 0x3e, 0x5c, 0xcf, 0x7c, 0x7f, 0x09, 0x64, 0x1f, 0xce, 0x96, 0xbe, 0x3f, 0x04, 0xf2, 0xad, + 0x0c, 0x0c, 0x4d, 0xda, 0xde, 0x21, 0x1f, 0xf8, 0xe2, 0x2b, 0x0e, 0xb7, 0x9a, 0xfb, 0x5f, 0x71, + 0xb8, 0x75, 0x53, 0xfd, 0xe9, 0x2c, 0x9c, 0x10, 0x41, 0xba, 0xc5, 0xf9, 0xc3, 0xd1, 0x74, 0x2c, + 0x06, 0x5b, 0x52, 0x34, 0x47, 0xf3, 0x90, 0x10, 0xcd, 0x2f, 0xe7, 0xe0, 0x04, 0x86, 0x32, 0x65, + 0xdb, 0xb2, 0xef, 0x03, 0x5b, 0x84, 0xd4, 0xa3, 0x97, 0xa0, 0xf3, 0x29, 0x97, 0xa0, 0x7f, 0xb3, + 0x59, 0x7c, 0xbe, 0x61, 0x7a, 0x6b, 0x9d, 0x95, 0x2b, 0x75, 0xbb, 0x75, 0xb5, 0xe1, 0xe8, 0xf7, + 0x4c, 0x7e, 0xfd, 0xa7, 0x37, 0xaf, 0x06, 0xf9, 0x2e, 0xf4, 0xb6, 0x29, 0x32, 0x61, 0x54, 0x71, + 0xaf, 0xc3, 0xb8, 0xfa, 0xd7, 0xa7, 0x2e, 0xc0, 0x1b, 0xb6, 0x69, 0x09, 0x9f, 0x42, 0x6e, 0xe8, + 0x56, 0xd9, 0xfe, 0xf0, 0x6d, 0xdb, 0xb4, 0x6a, 0x71, 0xc7, 0xc2, 0xdd, 0xd6, 0x17, 0xb2, 0xd6, + 0xa4, 0x6a, 0xd4, 0xff, 0x2b, 0x03, 0x67, 0xa2, 0x5a, 0xfc, 0xfd, 0x60, 0x3b, 0xfe, 0x4c, 0x16, + 0x4e, 0xde, 0x40, 0xe1, 0x04, 0x8e, 0x1c, 0x47, 0xf3, 0x96, 0x18, 0x9c, 0x29, 0xb2, 0x39, 0xb2, + 0x28, 0xbb, 0xcb, 0xe6, 0x68, 0x52, 0x17, 0xb2, 0xf9, 0x83, 0x0c, 0x1c, 0x5f, 0xac, 0x94, 0xa7, + 0xbe, 0x4f, 0x46, 0x54, 0xf2, 0x7b, 0x0e, 0xb9, 0xc1, 0x99, 0xf8, 0x9e, 0x43, 0x6e, 0x7a, 0x7e, + 0x35, 0x0b, 0xc7, 0xab, 0xa5, 0xf9, 0xb9, 0xef, 0x97, 0x19, 0x7c, 0x4a, 0xf6, 0x3a, 0xf4, 0x0f, + 0xc1, 0x84, 0x2d, 0x20, 0x7f, 0xe6, 0xed, 0x6b, 0xdd, 0xbd, 0x11, 0x93, 0x42, 0x39, 0xe4, 0x53, + 0xf7, 0xbe, 0x08, 0x85, 0x69, 0x7e, 0x84, 0xfa, 0x90, 0x6b, 0xfe, 0xff, 0x52, 0x80, 0xe1, 0x9b, + 0x9d, 0x15, 0x2a, 0x9c, 0x53, 0x1e, 0xea, 0x93, 0xdf, 0x6b, 0x30, 0x2c, 0xc4, 0x80, 0xb7, 0x26, + 0x52, 0xf0, 0x3c, 0x11, 0x0c, 0x85, 0xc7, 0x27, 0x92, 0x89, 0xc8, 0x39, 0xc8, 0xdf, 0xa6, 0xce, + 0x8a, 0xfc, 0xae, 0xf4, 0x1e, 0x75, 0x56, 0x34, 0x84, 0x92, 0xb9, 0xd0, 0x65, 0xbe, 0xb4, 0x54, + 0xc1, 0x44, 0x2a, 0xe2, 0xc2, 0x06, 0x33, 0xc3, 0x04, 0x7e, 0x6f, 0x7a, 0xdb, 0xe4, 0x29, 0x58, + 0xe4, 0x37, 0xed, 0xf1, 0x92, 0x64, 0x01, 0x26, 0x64, 0xc7, 0x27, 0x9e, 0x45, 0x64, 0x30, 0x85, + 0x5d, 0x5a, 0xfe, 0x90, 0x64, 0x51, 0xf2, 0x1a, 0x8c, 0xf8, 0x40, 0x74, 0xe1, 0x1a, 0x0a, 0x43, + 0xd7, 0x07, 0xac, 0x62, 0x29, 0x8a, 0x22, 0x05, 0x64, 0x06, 0x78, 0x0d, 0x01, 0x29, 0x0c, 0x62, + 0x2e, 0x71, 0x91, 0x02, 0xe4, 0x39, 0x64, 0x80, 0xcf, 0x3c, 0xd0, 0x59, 0x65, 0x18, 0x1f, 0x5d, + 0xa2, 0x4b, 0xbe, 0x23, 0xe0, 0xfc, 0x69, 0x6d, 0x84, 0x8c, 0x2c, 0x02, 0x84, 0x4e, 0x05, 0x22, + 0x80, 0xc1, 0xae, 0xdd, 0x1d, 0x24, 0x16, 0xf2, 0x75, 0xe0, 0xe8, 0x83, 0x5c, 0x07, 0xaa, 0x7f, + 0x94, 0x85, 0xe1, 0x52, 0xbb, 0x1d, 0x0c, 0x85, 0xa7, 0xa1, 0x50, 0x6a, 0xb7, 0x6f, 0x69, 0x15, + 0x39, 0x94, 0xb9, 0xde, 0x6e, 0xd7, 0x3a, 0x8e, 0x29, 0xfb, 0x84, 0x72, 0x22, 0x32, 0x05, 0xa3, + 0xa5, 0x76, 0x7b, 0xa9, 0xb3, 0xd2, 0x34, 0xeb, 0x52, 0x66, 0x24, 0x9e, 0xc4, 0xad, 0xdd, 0xae, + 0xb5, 0x11, 0x13, 0x4f, 0x8f, 0x15, 0x2d, 0x43, 0x3e, 0x8d, 0x61, 0x7f, 0x44, 0x62, 0x1e, 0x9e, + 0xfa, 0x43, 0x0d, 0x82, 0x98, 0x87, 0x6d, 0xbb, 0x12, 0x10, 0xf1, 0x60, 0xef, 0xe7, 0xfc, 0x90, + 0xf9, 0xac, 0xa2, 0x44, 0x02, 0x9e, 0x90, 0x25, 0xf9, 0x30, 0x0c, 0x94, 0xda, 0x6d, 0xe9, 0xbe, + 0x09, 0x9d, 0x8a, 0x58, 0xa9, 0x58, 0x1f, 0xfb, 0x64, 0x67, 0x5f, 0x81, 0xb1, 0x68, 0x65, 0xbb, + 0x0a, 0x16, 0xff, 0xd7, 0x19, 0xfc, 0xa0, 0x43, 0xee, 0xd3, 0xfc, 0x2c, 0xe4, 0x4a, 0xed, 0xb6, + 0x98, 0x8f, 0x8e, 0xa7, 0xf4, 0x47, 0xfc, 0x09, 0x74, 0xa9, 0xdd, 0xf6, 0x3f, 0xfd, 0x90, 0x3f, + 0x8e, 0x78, 0xa0, 0x4f, 0xff, 0x16, 0xff, 0xf4, 0xc3, 0xfd, 0x70, 0x41, 0xfd, 0xcd, 0x1c, 0x1c, + 0x2b, 0xb5, 0xdb, 0x47, 0x41, 0xe6, 0xf7, 0xeb, 0xa1, 0xf5, 0x33, 0x00, 0xd2, 0xf4, 0x38, 0x10, + 0x3c, 0xdd, 0x1a, 0x96, 0xa6, 0x46, 0x25, 0xa3, 0x49, 0x44, 0xbe, 0xfa, 0x0d, 0xee, 0x4a, 0xfd, + 0x3e, 0x97, 0xc3, 0xa9, 0xf8, 0xb0, 0x07, 0x8d, 0x7a, 0xbf, 0x74, 0x9b, 0xe8, 0x83, 0xc2, 0xae, + 0xfa, 0xe0, 0xf7, 0x22, 0x83, 0x07, 0x83, 0x96, 0x1f, 0xf5, 0x42, 0xff, 0x9e, 0xcc, 0xe2, 0x31, + 0x59, 0x98, 0x22, 0x92, 0x8d, 0x9f, 0x48, 0x49, 0xc4, 0x55, 0xaa, 0x33, 0x54, 0xcd, 0x34, 0xb4, + 0x18, 0xad, 0xdf, 0x87, 0x03, 0xbb, 0xea, 0xc3, 0xcd, 0x2c, 0xbe, 0x9d, 0x0e, 0xe2, 0x32, 0xed, + 0x7d, 0x77, 0x71, 0x15, 0x80, 0x7b, 0x1e, 0x04, 0x6e, 0xcd, 0xa3, 0x3c, 0x04, 0x0b, 0xcf, 0xaf, + 0x24, 0x42, 0xb0, 0x84, 0x24, 0x81, 0x87, 0x54, 0x2e, 0xd5, 0x43, 0xea, 0x32, 0x0c, 0x6a, 0xfa, + 0xfa, 0x9b, 0x1d, 0xea, 0x6c, 0x08, 0x73, 0x86, 0x87, 0x3d, 0xd4, 0xd7, 0x6b, 0x9f, 0x65, 0x40, + 0x2d, 0x40, 0x13, 0x35, 0x78, 0x7c, 0x2f, 0x79, 0x84, 0xf0, 0x33, 0xf2, 0xe0, 0xc9, 0xfd, 0x83, + 0x28, 0x3a, 0x79, 0x09, 0x72, 0xa5, 0x3b, 0x55, 0x21, 0xd9, 0xa0, 0x6b, 0x4b, 0x77, 0xaa, 0x42, + 0x5e, 0x5d, 0xcb, 0xde, 0xa9, 0xaa, 0x9f, 0xcb, 0x02, 0x49, 0x52, 0x92, 0xe7, 0x61, 0x08, 0xa1, + 0x0d, 0xa6, 0x33, 0x72, 0x62, 0xce, 0x75, 0xb7, 0xe6, 0x20, 0x34, 0x62, 0xdc, 0xf9, 0xa4, 0xe4, + 0x45, 0xcc, 0x41, 0x2c, 0x52, 0xc3, 0x45, 0x12, 0x73, 0xae, 0xbb, 0x7e, 0xd6, 0xde, 0x58, 0x0a, + 0x62, 0x41, 0x8c, 0x76, 0xe1, 0x9d, 0xea, 0xac, 0xed, 0x7a, 0x42, 0xd4, 0xdc, 0x2e, 0x5c, 0x77, + 0x31, 0x23, 0x6c, 0xc4, 0x2e, 0xe4, 0x64, 0x98, 0xd5, 0xea, 0x4e, 0x95, 0x3f, 0x53, 0x31, 0x34, + 0xbb, 0xe9, 0x1b, 0x94, 0x3c, 0xab, 0xd5, 0xba, 0x5b, 0xe3, 0x4f, 0x5c, 0x0c, 0x4c, 0x7e, 0x1c, + 0xc9, 0x6a, 0x15, 0x29, 0xa5, 0x7e, 0x69, 0x10, 0xc6, 0xcb, 0xba, 0xa7, 0xaf, 0xe8, 0x2e, 0x95, + 0x76, 0xd3, 0xc7, 0x7c, 0x98, 0xff, 0x39, 0x92, 0x1c, 0x8c, 0x95, 0x94, 0xaf, 0x89, 0x17, 0x20, + 0x2f, 0x87, 0x7c, 0x83, 0x9c, 0xa3, 0x72, 0x12, 0xb3, 0x95, 0x5a, 0x5b, 0x80, 0xb5, 0x04, 0x21, + 0x79, 0x0a, 0x86, 0x7d, 0x18, 0xdb, 0x00, 0xe4, 0x42, 0x9d, 0x31, 0x56, 0x98, 0xfd, 0xaf, 0xc9, + 0x68, 0xf2, 0x22, 0x8c, 0xf8, 0x3f, 0x25, 0xd3, 0x9a, 0x67, 0x64, 0x5b, 0x49, 0xec, 0x9e, 0x64, + 0x52, 0xb9, 0x28, 0xce, 0x6f, 0xfd, 0x91, 0xa2, 0xb1, 0xa4, 0x67, 0x11, 0x52, 0xf2, 0x59, 0x18, + 0xf3, 0x7f, 0x8b, 0x0d, 0x03, 0xcf, 0x0f, 0xf7, 0x54, 0x90, 0x5b, 0x39, 0x26, 0xd6, 0x2b, 0x51, + 0x72, 0xbe, 0x75, 0x78, 0xc4, 0xcf, 0xe3, 0x65, 0xac, 0x24, 0x77, 0x0e, 0xb1, 0x0a, 0x48, 0x05, + 0x26, 0x7c, 0x48, 0xa8, 0xa1, 0x03, 0xe1, 0x8e, 0xd1, 0x58, 0xa9, 0xa5, 0x2a, 0x69, 0xb2, 0x14, + 0x69, 0xc2, 0xb9, 0x08, 0xd0, 0x70, 0xd7, 0xcc, 0x55, 0x4f, 0x6c, 0xf7, 0x44, 0x0c, 0x62, 0x91, + 0xb8, 0x31, 0xe0, 0xca, 0x69, 0xfc, 0x0c, 0xac, 0xd1, 0xec, 0x50, 0x3d, 0xb9, 0x91, 0x2a, 0x9c, + 0xf0, 0xf1, 0x37, 0xa6, 0x96, 0x96, 0x1c, 0xfb, 0x6d, 0x5a, 0xf7, 0x2a, 0x65, 0xb1, 0x5d, 0xc6, + 0xd8, 0x74, 0xc6, 0x4a, 0xad, 0x51, 0x6f, 0x33, 0xa5, 0x60, 0xb8, 0x28, 0xf3, 0xd4, 0xc2, 0xe4, + 0x36, 0x9c, 0x94, 0xe0, 0x15, 0xcb, 0xf5, 0x74, 0xab, 0x4e, 0x2b, 0x65, 0xb1, 0x87, 0xc6, 0xfd, + 0xbc, 0xe0, 0x6a, 0x0a, 0x64, 0x94, 0x6d, 0x7a, 0x71, 0xf2, 0x0a, 0x8c, 0xfa, 0x08, 0x7e, 0x8b, + 0x38, 0x8c, 0xb7, 0x88, 0x38, 0x24, 0x8d, 0x95, 0x5a, 0xfc, 0x35, 0x65, 0x94, 0x58, 0xd6, 0x28, + 0x4c, 0x6d, 0x3f, 0x12, 0xd1, 0x28, 0x6f, 0xa3, 0x9d, 0xaa, 0x8c, 0x98, 0xee, 0xfe, 0xb5, 0x50, + 0xa3, 0x16, 0x1d, 0xb3, 0x61, 0xf2, 0x9d, 0xb4, 0xff, 0x80, 0x72, 0xa5, 0x66, 0x23, 0x30, 0x4d, + 0x3f, 0x38, 0xf9, 0xd9, 0x12, 0x1c, 0x4f, 0xd1, 0xb1, 0x5d, 0xed, 0x18, 0xbf, 0x98, 0x0d, 0x1b, + 0x71, 0xc8, 0xb7, 0x8d, 0x93, 0x30, 0xe8, 0x7f, 0x89, 0x30, 0x1e, 0x94, 0x6e, 0x43, 0x33, 0xce, + 0xc3, 0xc7, 0x47, 0xc4, 0x71, 0xc8, 0xb7, 0x92, 0xfb, 0x21, 0x8e, 0x77, 0x33, 0xa1, 0x38, 0x0e, + 0xf9, 0xf6, 0xf2, 0x0f, 0x72, 0xe1, 0x9c, 0x74, 0xb4, 0xc7, 0xdc, 0x2f, 0x33, 0x39, 0xf4, 0x83, + 0x2d, 0xec, 0xe2, 0x21, 0xa3, 0xac, 0x9a, 0x03, 0x0f, 0xa8, 0x9a, 0x7f, 0x92, 0xec, 0x4f, 0x6e, + 0x7a, 0x1e, 0xca, 0xfe, 0xdc, 0x87, 0xc1, 0x4a, 0xae, 0x85, 0xeb, 0x18, 0xb7, 0xd1, 0xfb, 0xa5, + 0x10, 0x7f, 0x2b, 0xc2, 0x44, 0x8f, 0x92, 0x90, 0x4f, 0xc0, 0xe9, 0x08, 0x60, 0x49, 0x77, 0xf4, + 0x16, 0xf5, 0xc2, 0x8c, 0x83, 0x18, 0xb4, 0xc9, 0x2f, 0x5d, 0x6b, 0x07, 0x68, 0x39, 0x8b, 0x61, + 0x17, 0x0e, 0x92, 0x72, 0x0c, 0xec, 0xc2, 0x49, 0xfa, 0x6b, 0xb9, 0xd0, 0x54, 0x89, 0x06, 0x5f, + 0xd5, 0xa8, 0xdb, 0x69, 0x7a, 0x0f, 0x6f, 0x07, 0x3f, 0x58, 0x6a, 0x8b, 0x59, 0x38, 0x56, 0x5a, + 0x5d, 0xa5, 0x75, 0xcf, 0x8f, 0x29, 0xed, 0x8a, 0x70, 0x7b, 0x7c, 0xeb, 0x20, 0x50, 0x22, 0x46, + 0x70, 0x24, 0x37, 0x7e, 0xac, 0x98, 0xfa, 0xa7, 0x79, 0x50, 0x02, 0xd3, 0x3d, 0x78, 0xa8, 0x75, + 0x80, 0xcb, 0xe4, 0xfb, 0xa2, 0x57, 0x4c, 0x98, 0x08, 0x85, 0x51, 0xed, 0xb4, 0x5a, 0x3a, 0x0e, + 0x3d, 0xb6, 0x35, 0x28, 0xc6, 0x99, 0x85, 0x84, 0x7c, 0x37, 0x70, 0x56, 0xec, 0x06, 0x48, 0xf8, + 0x10, 0xae, 0xe6, 0x72, 0x16, 0x5a, 0x92, 0x2b, 0xf9, 0x72, 0x06, 0x4e, 0xf8, 0x9d, 0xb2, 0xb8, + 0xc2, 0xcc, 0xe2, 0x29, 0xbb, 0x63, 0x79, 0xfe, 0x4e, 0xe4, 0xa5, 0xee, 0xd5, 0xf1, 0x4e, 0xba, + 0x92, 0x56, 0x98, 0xb7, 0x24, 0x08, 0x2c, 0x11, 0x28, 0x84, 0x8d, 0x34, 0xb5, 0x3a, 0x12, 0x69, + 0xa9, 0xf5, 0x9e, 0xbd, 0x01, 0x67, 0xba, 0xb2, 0xdc, 0xce, 0x0c, 0xed, 0x97, 0xcd, 0xd0, 0xff, + 0x27, 0x13, 0x4e, 0x44, 0x31, 0x21, 0x91, 0x2b, 0x00, 0x21, 0x48, 0x6c, 0x4c, 0xc7, 0xb6, 0x36, + 0x8b, 0x10, 0x0a, 0x4d, 0x93, 0x28, 0xc8, 0x22, 0x14, 0x84, 0x58, 0x78, 0x76, 0xdf, 0x0f, 0x6d, + 0xd3, 0x0b, 0x57, 0x64, 0x39, 0xe0, 0xa6, 0x53, 0x7c, 0xb3, 0x60, 0x73, 0xf6, 0x45, 0x18, 0x7e, + 0xd0, 0xef, 0xfa, 0x72, 0x0e, 0x88, 0xbc, 0x8b, 0x3c, 0x40, 0x13, 0xfb, 0x10, 0x4f, 0x61, 0x97, + 0x60, 0x90, 0x7d, 0x02, 0xe6, 0xbb, 0x90, 0xe2, 0xdb, 0x76, 0x04, 0x4c, 0x0b, 0xb0, 0x61, 0x70, + 0xa9, 0x81, 0xf4, 0xe0, 0x52, 0xea, 0x4f, 0xe6, 0xe0, 0x94, 0xdc, 0x21, 0x65, 0x8a, 0x21, 0xf3, + 0x8f, 0x3a, 0xe5, 0x3d, 0xec, 0x14, 0x15, 0x0a, 0x7c, 0xf3, 0x20, 0x72, 0x17, 0xf0, 0x83, 0x1d, + 0x84, 0x68, 0x02, 0xa3, 0xfe, 0xfd, 0x2c, 0x8c, 0x2e, 0xd9, 0xae, 0xd7, 0x70, 0xa8, 0xbb, 0xa4, + 0x3b, 0xee, 0x43, 0xdc, 0x1d, 0x1f, 0x81, 0x51, 0x0c, 0x0f, 0xd4, 0xa2, 0x16, 0x0f, 0xa1, 0xd3, + 0x2f, 0x25, 0x1b, 0xf1, 0x11, 0x22, 0xaf, 0x54, 0x84, 0x90, 0x69, 0x3f, 0xb7, 0xfc, 0xa4, 0xa0, + 0x4d, 0xdc, 0xec, 0xe3, 0x70, 0xf5, 0x17, 0x73, 0x30, 0xe2, 0x4b, 0x79, 0xd2, 0x3c, 0xac, 0x37, + 0x35, 0x07, 0x2b, 0xe4, 0xab, 0x00, 0x4b, 0xb6, 0xe3, 0xe9, 0xcd, 0x85, 0x50, 0xf3, 0xf1, 0x88, + 0xb3, 0x8d, 0x50, 0x5e, 0x46, 0x22, 0xc1, 0xf5, 0x2b, 0x34, 0xab, 0xf9, 0xc4, 0xc4, 0xd7, 0xaf, + 0x00, 0xaa, 0x49, 0x14, 0xea, 0xef, 0x64, 0xe1, 0x98, 0xdf, 0x49, 0xd3, 0xf7, 0x69, 0xbd, 0xf3, + 0x30, 0xcf, 0x4d, 0x51, 0x69, 0xf7, 0x6f, 0x2b, 0x6d, 0xf5, 0x9f, 0x4b, 0x13, 0xc9, 0x54, 0xd3, + 0x3e, 0x9a, 0x48, 0xfe, 0x2e, 0x74, 0x5c, 0xfd, 0xa1, 0x1c, 0x9c, 0xf0, 0xa5, 0x3e, 0xd3, 0xb1, + 0xf0, 0x70, 0x60, 0x4a, 0x6f, 0x36, 0x1f, 0xe6, 0xdd, 0xf8, 0xb0, 0x2f, 0x88, 0x45, 0x11, 0x6f, + 0x4f, 0xe4, 0xf8, 0x5b, 0x15, 0xe0, 0x9a, 0x6d, 0x1a, 0x9a, 0x4c, 0x44, 0x5e, 0x83, 0x11, 0xff, + 0x67, 0xc9, 0x69, 0xf8, 0x5b, 0x70, 0x3c, 0xea, 0x0f, 0x0a, 0xe9, 0x4e, 0x24, 0xac, 0x40, 0xa4, + 0x80, 0xfa, 0x0f, 0x0b, 0x70, 0xf6, 0x8e, 0x69, 0x19, 0xf6, 0xba, 0xeb, 0xa7, 0x88, 0x3c, 0xf4, + 0x47, 0x5d, 0x07, 0x9d, 0x1a, 0xf2, 0x4d, 0x38, 0x19, 0x17, 0xa9, 0x13, 0x04, 0xee, 0x16, 0xbd, + 0xb3, 0xce, 0x09, 0x6a, 0x7e, 0xb2, 0x48, 0x71, 0x5f, 0xa6, 0xa5, 0x97, 0x8c, 0x67, 0x9b, 0x1c, + 0xd8, 0x49, 0xb6, 0xc9, 0x27, 0xa1, 0x50, 0xb6, 0x5b, 0xba, 0xe9, 0x07, 0x98, 0xc1, 0x51, 0x1c, + 0xd4, 0x8b, 0x18, 0x4d, 0x50, 0x30, 0xfe, 0xa2, 0x62, 0xec, 0xb2, 0xa1, 0x90, 0xbf, 0x5f, 0x80, + 0x59, 0x69, 0x9a, 0x4c, 0x44, 0x6c, 0x18, 0x15, 0xd5, 0x89, 0xdb, 0x2d, 0xc0, 0xcd, 0xd3, 0x73, + 0xbe, 0x8c, 0xba, 0xab, 0xd5, 0x95, 0x48, 0x39, 0xbe, 0x8d, 0xe2, 0x49, 0x30, 0xc5, 0xc7, 0xf0, + 0x7b, 0x2e, 0x2d, 0xca, 0x5f, 0x12, 0x02, 0x4e, 0x32, 0xc3, 0x49, 0x21, 0xe0, 0x2c, 0x23, 0x13, + 0x91, 0x69, 0x98, 0xc0, 0xf0, 0xca, 0xc1, 0x56, 0x8a, 0xa9, 0xc4, 0x08, 0x1a, 0x95, 0x78, 0x69, + 0xc2, 0x23, 0x32, 0xb3, 0x8f, 0xab, 0xd5, 0x05, 0x5a, 0x4b, 0x96, 0x38, 0xfb, 0x3a, 0x90, 0x64, + 0x9b, 0x77, 0x75, 0x6d, 0xf2, 0xbf, 0x49, 0xfb, 0xba, 0xc3, 0xee, 0xf8, 0xb2, 0x1f, 0xb3, 0x5d, + 0x24, 0x75, 0x58, 0xff, 0x7b, 0x99, 0x3a, 0xac, 0xb0, 0xaf, 0xa9, 0xc3, 0xd4, 0x5f, 0xcb, 0xc0, + 0x44, 0x22, 0xce, 0x38, 0x79, 0x16, 0x80, 0x43, 0xa4, 0x78, 0x8e, 0x18, 0x20, 0x25, 0x8c, 0x3d, + 0x2e, 0xd6, 0xc0, 0x90, 0x8c, 0x5c, 0x85, 0x41, 0xfe, 0x4b, 0xc4, 0x60, 0x4a, 0x16, 0xe9, 0x74, + 0x4c, 0x43, 0x0b, 0x88, 0xc2, 0x5a, 0xf0, 0xe2, 0x30, 0x97, 0x5a, 0xc4, 0xdb, 0x68, 0x07, 0xb5, + 0x30, 0x32, 0xf5, 0x4b, 0x59, 0x18, 0x09, 0x1a, 0x5c, 0x32, 0x0e, 0x4a, 0xe7, 0x0a, 0x22, 0x64, + 0x7b, 0x6e, 0xbb, 0x90, 0xed, 0xb1, 0x49, 0x55, 0xc4, 0x68, 0xdf, 0xbf, 0x77, 0x4f, 0x5f, 0xc9, + 0xc2, 0xb1, 0xa0, 0xd6, 0x03, 0xbc, 0xa3, 0x7a, 0x1f, 0x89, 0xe4, 0xcb, 0x19, 0x50, 0x26, 0xcd, + 0x66, 0xd3, 0xb4, 0x1a, 0x15, 0x6b, 0xd5, 0x76, 0x5a, 0x38, 0xeb, 0x1d, 0xdc, 0x39, 0xad, 0xfa, + 0xa3, 0x19, 0x98, 0x10, 0x0d, 0x9a, 0xd2, 0x1d, 0xe3, 0xe0, 0x0e, 0xc1, 0xe2, 0x2d, 0x39, 0x38, + 0x7d, 0x51, 0xbf, 0x91, 0x05, 0x98, 0xb3, 0xeb, 0x77, 0x0f, 0xf9, 0xb3, 0xa9, 0x97, 0xa1, 0xc0, + 0x03, 0x61, 0x09, 0x8d, 0x9d, 0x10, 0xcf, 0x83, 0xd8, 0xa7, 0x71, 0xc4, 0xe4, 0xb8, 0x98, 0x8f, + 0x0b, 0x3c, 0x90, 0x96, 0x92, 0xd1, 0x44, 0x11, 0x56, 0x29, 0xa3, 0x13, 0x0b, 0x46, 0x50, 0x29, + 0x83, 0x45, 0x2b, 0xdd, 0xda, 0x2c, 0xe6, 0x9b, 0x76, 0xfd, 0xae, 0x86, 0xf4, 0xea, 0xdf, 0x66, + 0xb8, 0xec, 0x0e, 0xf9, 0xe3, 0x4f, 0xff, 0xf3, 0xf3, 0xbb, 0xfc, 0xfc, 0x1f, 0xcb, 0xc0, 0x09, + 0x8d, 0xd6, 0xed, 0x7b, 0xd4, 0xd9, 0x98, 0xb2, 0x0d, 0x7a, 0x83, 0x5a, 0xd4, 0x39, 0xa8, 0x11, + 0xf5, 0x3f, 0x62, 0x8e, 0x8b, 0xb0, 0x31, 0xb7, 0x5c, 0x6a, 0x1c, 0x9e, 0xfc, 0x23, 0xea, 0x7f, + 0x3f, 0x00, 0x4a, 0xaa, 0x69, 0x7b, 0x68, 0xcd, 0xb9, 0xae, 0xfb, 0x95, 0xfc, 0x7e, 0xed, 0x57, + 0xfa, 0x77, 0xb7, 0x5f, 0x29, 0xec, 0x76, 0xbf, 0x32, 0xb0, 0x93, 0xfd, 0x4a, 0x2b, 0xbe, 0x5f, + 0x19, 0xc4, 0xfd, 0xca, 0xb3, 0x3d, 0xf7, 0x2b, 0xd3, 0x96, 0xf1, 0x80, 0xbb, 0x95, 0x43, 0x9b, + 0x1b, 0xf7, 0x41, 0xb6, 0x59, 0x97, 0xd8, 0xa4, 0x58, 0xb7, 0x1d, 0x83, 0x1a, 0x62, 0x77, 0x85, + 0x47, 0xfb, 0x8e, 0x80, 0x69, 0x01, 0x36, 0x91, 0x68, 0x78, 0x74, 0x27, 0x89, 0x86, 0xf7, 0x61, + 0xff, 0xf5, 0xc5, 0x2c, 0x4c, 0x4c, 0x51, 0xc7, 0xe3, 0x91, 0x36, 0xf7, 0xc3, 0x73, 0xad, 0x04, + 0xc7, 0x24, 0x86, 0x68, 0x91, 0x67, 0x43, 0x6f, 0xbc, 0x3a, 0x75, 0xbc, 0xb8, 0x33, 0x5f, 0x9c, + 0x9e, 0x55, 0xef, 0x27, 0xfb, 0x12, 0x63, 0x37, 0xa8, 0xde, 0x87, 0x73, 0x41, 0x9a, 0xe2, 0x97, + 0x16, 0xd0, 0x4b, 0xf9, 0xbb, 0xf2, 0xbb, 0xcf, 0xdf, 0xa5, 0xfe, 0x6a, 0x06, 0x2e, 0x6a, 0xd4, + 0xa2, 0xeb, 0xfa, 0x4a, 0x93, 0x4a, 0xcd, 0x12, 0x2b, 0x03, 0x9b, 0x35, 0x4c, 0xb7, 0xa5, 0x7b, + 0xf5, 0xb5, 0x3d, 0xc9, 0x68, 0x06, 0x46, 0xe4, 0xf9, 0x6b, 0x17, 0x73, 0x5b, 0xa4, 0x9c, 0xfa, + 0x4f, 0x72, 0x30, 0x30, 0x69, 0x7b, 0x6f, 0xd8, 0x7b, 0x4c, 0x28, 0x17, 0x4e, 0xf9, 0xd9, 0x5d, + 0x1c, 0xe8, 0x7c, 0x18, 0x2b, 0x97, 0x62, 0xec, 0xa3, 0xa7, 0xe7, 0x8a, 0x9d, 0xc8, 0x45, 0xe0, + 0x93, 0xed, 0x32, 0x95, 0xdc, 0xf3, 0x30, 0x84, 0x41, 0x5a, 0xa4, 0x23, 0x57, 0xf4, 0xa3, 0xf6, + 0x18, 0x30, 0x5e, 0x47, 0x48, 0x4a, 0x3e, 0x11, 0x09, 0x0d, 0x5a, 0xd8, 0x7b, 0xea, 0x39, 0x39, + 0x4a, 0xe8, 0xb3, 0xfc, 0xb6, 0x0e, 0xdb, 0x24, 0xa5, 0xe9, 0xc0, 0xa3, 0x92, 0x58, 0x93, 0x02, + 0xc2, 0xfd, 0x4b, 0x0b, 0xa7, 0x7e, 0x2f, 0x0f, 0x23, 0xbe, 0xcb, 0xed, 0x01, 0x75, 0xfb, 0xd3, + 0x50, 0x98, 0xb5, 0xa5, 0x24, 0x03, 0xe8, 0xa2, 0xbb, 0x66, 0xbb, 0x31, 0xdf, 0x63, 0x41, 0xc4, + 0x04, 0xb6, 0x60, 0x1b, 0xb2, 0x83, 0x39, 0x0a, 0xcc, 0xb2, 0x8d, 0xc4, 0x03, 0xdd, 0x80, 0x90, + 0x5c, 0x84, 0x3c, 0xfa, 0xe6, 0x4b, 0x07, 0xed, 0x31, 0x7f, 0x7c, 0xc4, 0x4b, 0x0a, 0x55, 0xd8, + 0xad, 0x42, 0x0d, 0x3c, 0xa8, 0x42, 0x0d, 0xee, 0xaf, 0x42, 0xbd, 0x05, 0x23, 0x58, 0x93, 0x9f, + 0xa3, 0x6c, 0xfb, 0x35, 0xf1, 0x8c, 0x58, 0xb6, 0x46, 0x79, 0xbb, 0x45, 0xa6, 0x32, 0x5c, 0xad, + 0x22, 0xac, 0x62, 0x6a, 0x07, 0x7b, 0x50, 0xbb, 0x3f, 0xc9, 0xc0, 0xc0, 0x2d, 0xeb, 0xae, 0x65, + 0xaf, 0xef, 0x4d, 0xe3, 0x9e, 0x85, 0x61, 0xc1, 0x46, 0x5a, 0x18, 0xf0, 0xcd, 0x75, 0x87, 0x83, + 0x6b, 0xc8, 0x49, 0x93, 0xa9, 0xc8, 0x2b, 0x41, 0x21, 0x7c, 0x7e, 0x93, 0x0b, 0xd3, 0x74, 0xf8, + 0x85, 0xea, 0xd1, 0xcc, 0x02, 0x32, 0x39, 0x39, 0x07, 0xf9, 0x32, 0x6b, 0xaa, 0x14, 0xa7, 0x96, + 0x35, 0x45, 0x43, 0xa8, 0xfa, 0xc5, 0x3c, 0x8c, 0xc5, 0xce, 0xac, 0x9e, 0x84, 0x21, 0x71, 0x66, + 0x64, 0xfa, 0xa9, 0x0e, 0xf0, 0x79, 0x4e, 0x00, 0xd4, 0x06, 0xf9, 0x9f, 0x15, 0x83, 0x7c, 0x14, + 0x06, 0x6c, 0x17, 0xd7, 0x33, 0xfc, 0x96, 0xb1, 0x70, 0x08, 0x2d, 0x56, 0x59, 0xdb, 0xf9, 0xe0, + 0x10, 0x24, 0xb2, 0x46, 0xda, 0x2e, 0x7e, 0xda, 0x75, 0x18, 0xd2, 0x5d, 0x97, 0x7a, 0x35, 0x4f, + 0x6f, 0xc8, 0xd9, 0x0f, 0x02, 0xa0, 0x3c, 0x3a, 0x10, 0xb8, 0xac, 0x37, 0xc8, 0xeb, 0x30, 0x5a, + 0x77, 0x28, 0xae, 0x78, 0x7a, 0x93, 0xb5, 0x52, 0xb2, 0x48, 0x23, 0x08, 0xf9, 0x7e, 0x23, 0x44, + 0x54, 0x0c, 0x72, 0x1b, 0x46, 0xc5, 0xe7, 0x70, 0xdf, 0x78, 0x1c, 0x68, 0x63, 0xe1, 0x0a, 0xc4, + 0x45, 0xc2, 0xbd, 0xe3, 0xc5, 0x13, 0x09, 0x99, 0x5c, 0xe6, 0x6b, 0x48, 0xa4, 0x64, 0x11, 0xc8, + 0x3a, 0x5d, 0xa9, 0xe9, 0x1d, 0x6f, 0x8d, 0xd5, 0xc5, 0x83, 0x77, 0x8b, 0xa4, 0x7f, 0xf8, 0xae, + 0x20, 0x89, 0x95, 0x9f, 0x5b, 0xac, 0xd3, 0x95, 0x52, 0x04, 0x49, 0xee, 0xc0, 0xc9, 0x64, 0x11, + 0xf6, 0xc9, 0xfc, 0xf0, 0xfe, 0xf1, 0xad, 0xcd, 0x62, 0x31, 0x95, 0x40, 0x62, 0x7b, 0x3c, 0xc1, + 0xb6, 0x62, 0xbc, 0x91, 0x1f, 0x1c, 0x18, 0x1f, 0xd4, 0xc6, 0x58, 0x59, 0xdf, 0xfa, 0x33, 0x0d, + 0xf5, 0xdb, 0x19, 0x66, 0xe5, 0xb1, 0x0f, 0xc2, 0xac, 0xc7, 0x4c, 0xd7, 0x5b, 0xbb, 0xd4, 0xf5, + 0x56, 0x98, 0x9f, 0xb0, 0xe0, 0xf6, 0x98, 0x5d, 0x35, 0x81, 0x25, 0x57, 0xa0, 0x60, 0xc8, 0x07, + 0x5e, 0xa7, 0xa2, 0x9d, 0xe0, 0xd7, 0xa3, 0x09, 0x2a, 0x72, 0x09, 0xf2, 0x6c, 0xb5, 0x89, 0xef, + 0x76, 0x65, 0xc3, 0x40, 0x43, 0x0a, 0xf5, 0x07, 0xb2, 0x30, 0x22, 0x7d, 0xcd, 0xb5, 0x3d, 0x7d, + 0xce, 0x4b, 0x3b, 0x6b, 0xa6, 0xef, 0x94, 0x82, 0xdb, 0x20, 0xbf, 0xc9, 0xd7, 0x03, 0x51, 0xec, + 0xe8, 0xc2, 0x48, 0x08, 0xe6, 0x79, 0xf1, 0xa1, 0x85, 0x9d, 0xef, 0xfc, 0x18, 0xfd, 0x1b, 0xf9, + 0xc1, 0xec, 0x78, 0xee, 0x8d, 0xfc, 0x60, 0x7e, 0xbc, 0x1f, 0x23, 0x5d, 0x61, 0x70, 0x69, 0xbe, + 0xad, 0xb6, 0x56, 0xcd, 0xc6, 0x21, 0x7f, 0x9d, 0xb1, 0xbf, 0x51, 0xc0, 0x62, 0xb2, 0x39, 0xe4, + 0x4f, 0x35, 0xde, 0x53, 0xd9, 0x1c, 0xe5, 0x33, 0x14, 0xb2, 0xf9, 0xd3, 0x0c, 0x28, 0xa9, 0xb2, + 0x29, 0x1d, 0x90, 0x9f, 0xc2, 0xfe, 0x65, 0x35, 0xfc, 0x6e, 0x16, 0x26, 0x2a, 0x96, 0x47, 0x1b, + 0x7c, 0xb3, 0x77, 0xc8, 0xa7, 0x8a, 0x9b, 0x30, 0x2c, 0x7d, 0x8c, 0xe8, 0xf3, 0x47, 0x82, 0xad, + 0x74, 0x88, 0xea, 0xc2, 0x49, 0x2e, 0xbd, 0x8f, 0x89, 0xd0, 0x63, 0x42, 0x3e, 0xe4, 0x73, 0xce, + 0xe1, 0x10, 0xf2, 0x21, 0x9f, 0xbc, 0xde, 0xa7, 0x42, 0xfe, 0xa7, 0x19, 0x38, 0x9e, 0x52, 0x39, + 0xb9, 0x08, 0x03, 0xd5, 0xce, 0x0a, 0x06, 0xb6, 0xca, 0x84, 0x1e, 0xbd, 0x6e, 0x67, 0x05, 0x63, + 0x5a, 0x69, 0x3e, 0x92, 0x2c, 0xe3, 0xf3, 0xf5, 0xc5, 0x4a, 0x79, 0x4a, 0x48, 0x55, 0x95, 0x1e, + 0xe2, 0x33, 0x70, 0xda, 0x97, 0x05, 0x4f, 0xdc, 0x6d, 0xd3, 0xa8, 0xc7, 0x9e, 0xb8, 0xb3, 0x32, + 0xe4, 0x93, 0x30, 0x54, 0x7a, 0xa7, 0xe3, 0x50, 0xe4, 0xcb, 0x25, 0xfe, 0x81, 0x80, 0xaf, 0x8f, + 0x48, 0xe3, 0xcc, 0x5f, 0xeb, 0x33, 0x8a, 0x38, 0xef, 0x90, 0xa1, 0xfa, 0xa5, 0x0c, 0x9c, 0xed, + 0xde, 0x3a, 0xf2, 0x61, 0x18, 0x60, 0x3b, 0xf3, 0x92, 0xb6, 0x20, 0x3e, 0x9d, 0x67, 0x00, 0xb5, + 0x9b, 0xb4, 0xa6, 0x3b, 0xb2, 0xb1, 0xef, 0x93, 0x91, 0x57, 0x61, 0xb8, 0xe2, 0xba, 0x1d, 0xea, + 0x54, 0x9f, 0xbd, 0xa5, 0x55, 0xc4, 0x9e, 0x10, 0xf7, 0x1c, 0x26, 0x82, 0x6b, 0xee, 0xb3, 0xb1, + 0xd0, 0x55, 0x32, 0xbd, 0xfa, 0xf9, 0x0c, 0x9c, 0xeb, 0xf5, 0x55, 0xe4, 0x59, 0x18, 0x5c, 0xa6, + 0x96, 0x6e, 0x79, 0x95, 0xb2, 0x68, 0x12, 0x6e, 0xb1, 0x3c, 0x84, 0x45, 0x77, 0x0a, 0x01, 0x21, + 0x2b, 0xc4, 0x8f, 0x04, 0x03, 0x1f, 0x04, 0x7e, 0x7c, 0x89, 0xb0, 0x58, 0x21, 0x9f, 0x50, 0xfd, + 0xdd, 0xcf, 0x40, 0xff, 0xa2, 0x45, 0x17, 0x57, 0xc9, 0x33, 0x30, 0xc4, 0x74, 0x1f, 0xd3, 0xef, + 0x8b, 0x81, 0x36, 0x21, 0x0f, 0x18, 0x44, 0xcc, 0xf6, 0x69, 0x21, 0x15, 0xb9, 0x2e, 0xe7, 0xfc, + 0x16, 0xea, 0x40, 0xe4, 0x32, 0x1c, 0x33, 0xdb, 0xa7, 0xc9, 0xb9, 0xc1, 0xaf, 0xcb, 0xb9, 0x96, + 0x45, 0x67, 0x47, 0x4a, 0x71, 0x8c, 0x5f, 0x4a, 0x4c, 0x03, 0x73, 0x69, 0x09, 0x89, 0xe3, 0x36, + 0x41, 0x92, 0x62, 0xb6, 0x4f, 0x4b, 0x4f, 0x64, 0x3c, 0x22, 0xbb, 0x31, 0xc5, 0x6f, 0x21, 0x65, + 0xdc, 0x6c, 0x9f, 0x16, 0xa1, 0x25, 0x2f, 0xc0, 0xb0, 0xf8, 0xfd, 0x86, 0x6d, 0x5a, 0xf1, 0x18, + 0x16, 0x12, 0x6a, 0xb6, 0x4f, 0x93, 0x29, 0xa5, 0x4a, 0x97, 0x1c, 0xd3, 0xf2, 0xc4, 0xcb, 0xb8, + 0x78, 0xa5, 0x88, 0x93, 0x2a, 0xc5, 0xdf, 0xe4, 0x55, 0x18, 0x0d, 0x82, 0x83, 0xbc, 0x4d, 0xeb, + 0x9e, 0x38, 0xd2, 0x39, 0x19, 0x2b, 0xcc, 0x91, 0xb3, 0x7d, 0x5a, 0x94, 0x9a, 0x5c, 0x82, 0x82, + 0x46, 0x5d, 0xf3, 0x1d, 0xff, 0xfe, 0x62, 0x4c, 0x9a, 0xce, 0xcc, 0x77, 0x98, 0x94, 0x04, 0x9e, + 0xf5, 0x4e, 0x78, 0x61, 0x22, 0x0e, 0x60, 0x48, 0xac, 0x96, 0x69, 0xcb, 0x60, 0xbd, 0x23, 0xdd, + 0x96, 0xbd, 0x1e, 0x86, 0x4c, 0x11, 0x89, 0xd6, 0x86, 0xe3, 0x6f, 0x53, 0x65, 0xec, 0x6c, 0x9f, + 0x16, 0xa3, 0x97, 0xa4, 0x5a, 0x36, 0xdd, 0xbb, 0x22, 0x4a, 0x5d, 0x5c, 0xaa, 0x0c, 0x25, 0x49, + 0x95, 0xfd, 0x94, 0xaa, 0x5e, 0xa0, 0xde, 0xba, 0xed, 0xdc, 0x15, 0x31, 0xe9, 0xe2, 0x55, 0x0b, + 0xac, 0x54, 0xb5, 0x80, 0xc8, 0x55, 0xb3, 0x45, 0x66, 0x2c, 0xbd, 0x6a, 0xdd, 0xd3, 0xe5, 0xaa, + 0xf9, 0xfe, 0xd2, 0xef, 0xa4, 0x39, 0xaa, 0xdf, 0xe3, 0xf9, 0x6e, 0x93, 0x1d, 0x8a, 0x38, 0xa9, + 0x43, 0xf1, 0x37, 0xab, 0x54, 0xca, 0x69, 0x2a, 0x12, 0xda, 0x06, 0x95, 0x4a, 0x28, 0x56, 0xa9, + 0x9c, 0xfd, 0xf4, 0xba, 0x9c, 0xea, 0x53, 0x99, 0x88, 0x76, 0x50, 0x88, 0x61, 0x1d, 0x24, 0xa5, + 0x04, 0x2d, 0x62, 0x1a, 0x41, 0x85, 0x20, 0xf9, 0x70, 0xd0, 0xc2, 0xa9, 0xa5, 0xd9, 0x3e, 0x0d, + 0x13, 0x0c, 0xaa, 0x3c, 0x41, 0xa5, 0x72, 0x1c, 0x29, 0x46, 0x7c, 0x0a, 0x06, 0x9b, 0xed, 0xd3, + 0x78, 0xf2, 0xca, 0x67, 0xa4, 0x54, 0x50, 0xca, 0x89, 0xe8, 0x14, 0x11, 0x20, 0xd8, 0x14, 0x11, + 0x26, 0x8c, 0x9a, 0x49, 0xa6, 0x4b, 0x52, 0x4e, 0x46, 0x57, 0xd4, 0x38, 0x7e, 0xb6, 0x4f, 0x4b, + 0xa6, 0x58, 0x7a, 0x21, 0x92, 0x41, 0x48, 0x39, 0x15, 0x0b, 0x1c, 0x13, 0xa2, 0x98, 0xb8, 0xe4, + 0x5c, 0x43, 0x8b, 0xa9, 0x39, 0xbf, 0x95, 0xd3, 0xd1, 0xe5, 0x38, 0x85, 0x64, 0xb6, 0x4f, 0x4b, + 0xcd, 0x16, 0x3e, 0x95, 0xc8, 0xe3, 0xa3, 0x28, 0xd1, 0xcb, 0xda, 0x18, 0x7a, 0xb6, 0x4f, 0x4b, + 0x64, 0xfe, 0xb9, 0x2e, 0x27, 0xd0, 0x51, 0xce, 0x44, 0x3b, 0x31, 0xc4, 0xb0, 0x4e, 0x94, 0x12, + 0xed, 0x5c, 0x97, 0x93, 0xaa, 0x28, 0x67, 0x93, 0xa5, 0xc2, 0x99, 0x53, 0x4a, 0xbe, 0xa2, 0xa5, + 0xe7, 0x89, 0x50, 0x1e, 0x11, 0x99, 0xfa, 0x44, 0xf9, 0x34, 0x9a, 0xd9, 0x3e, 0x2d, 0x3d, 0xc7, + 0x84, 0x96, 0x9e, 0x60, 0x41, 0x39, 0xd7, 0x8b, 0x67, 0xd0, 0xba, 0xf4, 0xe4, 0x0c, 0x7a, 0x8f, + 0x70, 0xf7, 0xca, 0xf9, 0x68, 0xd4, 0xca, 0xae, 0x84, 0xb3, 0x7d, 0x5a, 0x8f, 0xa0, 0xf9, 0xb7, + 0xba, 0xc4, 0x9e, 0x57, 0x2e, 0x44, 0x13, 0x75, 0xa6, 0x12, 0xcd, 0xf6, 0x69, 0x5d, 0x22, 0xd7, + 0xdf, 0xea, 0x12, 0x9a, 0x5c, 0x29, 0xf6, 0x64, 0x1b, 0xc8, 0xa3, 0x4b, 0x60, 0xf3, 0xc5, 0xd4, + 0xa8, 0xde, 0xca, 0xa3, 0x51, 0xd5, 0x4d, 0x21, 0x61, 0xaa, 0x9b, 0x16, 0x0f, 0x7c, 0x31, 0x35, + 0x0c, 0xb5, 0xf2, 0x58, 0x0f, 0x86, 0x41, 0x1b, 0x53, 0x03, 0x58, 0x2f, 0xa6, 0xc6, 0x81, 0x56, + 0xd4, 0x28, 0xc3, 0x14, 0x12, 0xc6, 0x30, 0x2d, 0x82, 0xf4, 0x62, 0x6a, 0xb8, 0x60, 0xe5, 0xf1, + 0x1e, 0x0c, 0xc3, 0x16, 0xa6, 0x05, 0x1a, 0x7e, 0x21, 0x12, 0xaf, 0x57, 0xf9, 0x40, 0x74, 0xde, + 0x90, 0x50, 0x6c, 0xde, 0x90, 0x23, 0xfb, 0x4e, 0x25, 0x22, 0x12, 0x2a, 0x4f, 0x44, 0x87, 0x79, + 0x0c, 0xcd, 0x86, 0x79, 0x3c, 0x86, 0xe1, 0x54, 0x22, 0x32, 0x9b, 0x72, 0xb1, 0x1b, 0x13, 0x44, + 0x47, 0x99, 0xf0, 0x58, 0x6e, 0x95, 0x94, 0xd0, 0x60, 0xca, 0x07, 0xa3, 0x8e, 0x86, 0x09, 0x82, + 0xd9, 0x3e, 0x2d, 0x25, 0xa0, 0x98, 0x96, 0x1e, 0x07, 0x43, 0xb9, 0x14, 0x1d, 0xb6, 0x69, 0x34, + 0x6c, 0xd8, 0xa6, 0xc6, 0xd0, 0x98, 0x4b, 0xf3, 0x86, 0x56, 0x2e, 0x47, 0x0d, 0xb3, 0x24, 0x05, + 0x33, 0xcc, 0x52, 0xbc, 0xa8, 0xb5, 0xf4, 0xc8, 0x0e, 0xca, 0x93, 0x3d, 0x5b, 0x88, 0x34, 0x29, + 0x2d, 0xe4, 0x81, 0x0e, 0x42, 0xdb, 0xe9, 0x56, 0xbb, 0x69, 0xeb, 0x86, 0xf2, 0xa1, 0x54, 0xdb, + 0x89, 0x23, 0x25, 0xdb, 0x89, 0x03, 0xd8, 0x2a, 0x2f, 0x3b, 0xdd, 0x2a, 0x4f, 0x45, 0x57, 0x79, + 0x19, 0xc7, 0x56, 0xf9, 0x88, 0x83, 0xee, 0x54, 0xc2, 0x41, 0x55, 0x79, 0x3a, 0xaa, 0x00, 0x31, + 0x34, 0x53, 0x80, 0xb8, 0x4b, 0xeb, 0xa7, 0xbb, 0xbb, 0x74, 0x2a, 0x57, 0x90, 0xdb, 0xa3, 0x3e, + 0xb7, 0x6e, 0x74, 0xb3, 0x7d, 0x5a, 0x77, 0xb7, 0xd0, 0x4a, 0x8a, 0x87, 0xa6, 0x72, 0x35, 0xaa, + 0x60, 0x09, 0x02, 0xa6, 0x60, 0x49, 0xbf, 0xce, 0x4a, 0x8a, 0x8b, 0xa5, 0xf2, 0xe1, 0xae, 0xac, + 0x82, 0x6f, 0x4e, 0x71, 0xcc, 0xbc, 0x2e, 0xfb, 0x48, 0x2a, 0xcf, 0x44, 0x17, 0xbb, 0x10, 0xc3, + 0x16, 0x3b, 0xc9, 0x97, 0xf2, 0xba, 0xec, 0x1d, 0xa8, 0x5c, 0x4b, 0x96, 0x0a, 0x97, 0x48, 0xc9, + 0x8b, 0x50, 0x4b, 0x77, 0xaa, 0x53, 0x9e, 0x8d, 0x6a, 0x5d, 0x1a, 0x0d, 0xd3, 0xba, 0x54, 0x87, + 0xbc, 0x99, 0xa4, 0x6f, 0x9c, 0x72, 0x3d, 0x7e, 0x96, 0x10, 0xc5, 0x33, 0xcb, 0x27, 0xe1, 0x4f, + 0xf7, 0x7a, 0x3c, 0x48, 0x93, 0xf2, 0x5c, 0xec, 0x32, 0x23, 0x82, 0x65, 0xf6, 0x6d, 0x2c, 0xa8, + 0xd3, 0xeb, 0xf1, 0xb8, 0x46, 0xca, 0xf3, 0xe9, 0x1c, 0x02, 0x5d, 0x89, 0xc7, 0x41, 0x7a, 0x3d, + 0x1e, 0x0a, 0x48, 0x79, 0x21, 0x9d, 0x43, 0x20, 0xdd, 0x78, 0xe8, 0xa0, 0x67, 0xa4, 0xe0, 0xc4, + 0xca, 0x47, 0xa2, 0xa6, 0x63, 0x80, 0x60, 0xa6, 0x63, 0x18, 0xc2, 0xf8, 0x19, 0x29, 0xa8, 0xaf, + 0xf2, 0x62, 0xa2, 0x48, 0xd0, 0x58, 0x29, 0xf4, 0xef, 0x33, 0x52, 0x30, 0x5c, 0xe5, 0xa5, 0x44, + 0x91, 0xa0, 0x75, 0x52, 0xc8, 0x5c, 0xa3, 0xd7, 0xab, 0x29, 0xe5, 0xe5, 0xe8, 0x11, 0x47, 0x77, + 0xca, 0xd9, 0x3e, 0xad, 0xd7, 0xeb, 0xab, 0x4f, 0x77, 0xf7, 0x34, 0x54, 0x5e, 0x89, 0x0e, 0xe1, + 0x6e, 0x74, 0x6c, 0x08, 0x77, 0xf5, 0x56, 0x7c, 0x35, 0xf6, 0x82, 0x5a, 0x79, 0x35, 0x3a, 0xc5, + 0x45, 0x90, 0x6c, 0x8a, 0x8b, 0xbf, 0xb7, 0x8e, 0x3c, 0x0d, 0x56, 0x3e, 0x1a, 0x9d, 0xe2, 0x64, + 0x1c, 0x9b, 0xe2, 0x22, 0xcf, 0x88, 0xa7, 0x12, 0x2f, 0x56, 0x95, 0xd7, 0xa2, 0x53, 0x5c, 0x0c, + 0xcd, 0xa6, 0xb8, 0xf8, 0x1b, 0xd7, 0x57, 0x63, 0x0f, 0x37, 0x95, 0xd7, 0xd3, 0xdb, 0x8f, 0x48, + 0xb9, 0xfd, 0xfc, 0x99, 0xa7, 0x96, 0xfe, 0x02, 0x51, 0x29, 0x45, 0xc7, 0x6f, 0x1a, 0x0d, 0x1b, + 0xbf, 0xa9, 0xaf, 0x17, 0xe3, 0x1b, 0x07, 0xa1, 0x55, 0x93, 0x3d, 0x36, 0x0e, 0xa1, 0x29, 0x92, + 0x02, 0x8e, 0xec, 0x91, 0xf9, 0x46, 0x68, 0xaa, 0xcb, 0x1e, 0xd9, 0xdf, 0x06, 0xc5, 0xe8, 0xd9, + 0xec, 0x9a, 0x70, 0x7c, 0x53, 0xca, 0xd1, 0xd9, 0x35, 0x41, 0xc0, 0x66, 0xd7, 0xa4, 0xbb, 0xdc, + 0x0c, 0x8c, 0x0b, 0x2d, 0xe2, 0xfe, 0x7c, 0xa6, 0xd5, 0x50, 0xa6, 0x63, 0x0f, 0x80, 0x62, 0x78, + 0x36, 0x3b, 0xc5, 0x61, 0xb8, 0x5e, 0x73, 0xd8, 0x54, 0xd3, 0x6c, 0xaf, 0xd8, 0xba, 0x63, 0x54, + 0xa9, 0x65, 0x28, 0x33, 0xb1, 0xf5, 0x3a, 0x85, 0x06, 0xd7, 0xeb, 0x14, 0x38, 0x06, 0x26, 0x8a, + 0xc1, 0x35, 0x5a, 0xa7, 0xe6, 0x3d, 0xaa, 0xdc, 0x40, 0xb6, 0xc5, 0x6e, 0x6c, 0x05, 0xd9, 0x6c, + 0x9f, 0xd6, 0x8d, 0x03, 0xb3, 0xd5, 0xe7, 0x37, 0xaa, 0x6f, 0xce, 0x05, 0x8f, 0x5e, 0x97, 0x1c, + 0xda, 0xd6, 0x1d, 0xaa, 0xcc, 0x46, 0x6d, 0xf5, 0x54, 0x22, 0x66, 0xab, 0xa7, 0x22, 0x92, 0x6c, + 0xfd, 0xb1, 0x50, 0xe9, 0xc5, 0x36, 0x1c, 0x11, 0xe9, 0xa5, 0xd9, 0xec, 0x14, 0x45, 0x30, 0x01, + 0xcd, 0xd9, 0x56, 0x03, 0x4f, 0x2a, 0xde, 0x88, 0xce, 0x4e, 0xdd, 0x29, 0xd9, 0xec, 0xd4, 0x1d, + 0xcb, 0x54, 0x3d, 0x8a, 0xe5, 0x63, 0xf0, 0x66, 0x54, 0xd5, 0x53, 0x48, 0x98, 0xaa, 0xa7, 0x80, + 0x93, 0x0c, 0x35, 0xea, 0x52, 0x4f, 0x99, 0xeb, 0xc5, 0x10, 0x49, 0x92, 0x0c, 0x11, 0x9c, 0x64, + 0x38, 0x43, 0xbd, 0xfa, 0x9a, 0x32, 0xdf, 0x8b, 0x21, 0x92, 0x24, 0x19, 0x22, 0x98, 0x6d, 0x36, + 0xa3, 0xe0, 0xc9, 0x4e, 0xf3, 0xae, 0xdf, 0x67, 0x0b, 0xd1, 0xcd, 0x66, 0x57, 0x42, 0xb6, 0xd9, + 0xec, 0x8a, 0x24, 0x9f, 0xdf, 0xb1, 0x63, 0xa6, 0xb2, 0x88, 0x15, 0x5e, 0x09, 0xed, 0x82, 0x9d, + 0x94, 0x9a, 0xed, 0xd3, 0x76, 0xea, 0xf8, 0xf9, 0xa1, 0xc0, 0x15, 0x4a, 0x59, 0xc2, 0xaa, 0x8e, + 0x05, 0x67, 0x15, 0x1c, 0x3c, 0xdb, 0xa7, 0x05, 0xce, 0x52, 0x2f, 0xc0, 0x30, 0x7e, 0x54, 0xc5, + 0x32, 0xbd, 0xf2, 0xa4, 0xf2, 0x66, 0x74, 0xcb, 0x24, 0xa1, 0xd8, 0x96, 0x49, 0xfa, 0xc9, 0x26, + 0x71, 0xfc, 0xc9, 0xa7, 0x98, 0xf2, 0xa4, 0xa2, 0x45, 0x27, 0xf1, 0x08, 0x92, 0x4d, 0xe2, 0x11, + 0x40, 0x50, 0x6f, 0xd9, 0xb1, 0xdb, 0xe5, 0x49, 0xa5, 0x9a, 0x52, 0x2f, 0x47, 0x05, 0xf5, 0xf2, + 0x9f, 0x41, 0xbd, 0xd5, 0xb5, 0x8e, 0x57, 0x66, 0xdf, 0xb8, 0x9c, 0x52, 0xaf, 0x8f, 0x0c, 0xea, + 0xf5, 0x01, 0x6c, 0x2a, 0x44, 0xc0, 0x92, 0x63, 0xb3, 0x49, 0xfb, 0xa6, 0xd9, 0x6c, 0x2a, 0xb7, + 0xa2, 0x53, 0x61, 0x1c, 0xcf, 0xa6, 0xc2, 0x38, 0x8c, 0x99, 0x9e, 0xbc, 0x55, 0x74, 0xa5, 0xd3, + 0x50, 0x6e, 0x47, 0x4d, 0xcf, 0x10, 0xc3, 0x4c, 0xcf, 0xf0, 0x17, 0xee, 0x2e, 0xd8, 0x2f, 0x8d, + 0xae, 0x3a, 0xd4, 0x5d, 0x53, 0xee, 0xc4, 0x76, 0x17, 0x12, 0x0e, 0x77, 0x17, 0xd2, 0x6f, 0xd2, + 0x80, 0x47, 0x22, 0x0b, 0x8d, 0x7f, 0xf7, 0x54, 0xa5, 0xba, 0x53, 0x5f, 0x53, 0x3e, 0x86, 0xac, + 0x1e, 0x4f, 0x5d, 0xaa, 0xa2, 0xa4, 0xb3, 0x7d, 0x5a, 0x2f, 0x4e, 0xb8, 0x2d, 0x7f, 0x73, 0x8e, + 0x47, 0x10, 0xd4, 0x96, 0xa6, 0xfc, 0x4d, 0xe8, 0x5b, 0xb1, 0x6d, 0x79, 0x92, 0x04, 0xb7, 0xe5, + 0x49, 0x30, 0x69, 0xc3, 0x85, 0xd8, 0x56, 0x6d, 0x5e, 0x6f, 0xb2, 0x7d, 0x09, 0x35, 0x96, 0xf4, + 0xfa, 0x5d, 0xea, 0x29, 0x1f, 0x47, 0xde, 0x17, 0xbb, 0x6c, 0xf8, 0x62, 0xd4, 0xb3, 0x7d, 0xda, + 0x36, 0xfc, 0x88, 0x0a, 0xf9, 0xea, 0xcc, 0xf2, 0x92, 0xf2, 0x89, 0xe8, 0xf9, 0x26, 0x83, 0xcd, + 0xf6, 0x69, 0x88, 0x63, 0x56, 0xda, 0xad, 0x76, 0xc3, 0xd1, 0x0d, 0xca, 0x0d, 0x2d, 0xb4, 0xdd, + 0x84, 0x01, 0xfa, 0xc9, 0xa8, 0x95, 0xd6, 0x8d, 0x8e, 0x59, 0x69, 0xdd, 0x70, 0x4c, 0x51, 0x23, + 0xc1, 0xf2, 0x95, 0x4f, 0x45, 0x15, 0x35, 0x82, 0x64, 0x8a, 0x1a, 0x0d, 0xad, 0xff, 0x31, 0x38, + 0x15, 0xec, 0xe7, 0xc5, 0xfa, 0xcb, 0x3b, 0x4d, 0xf9, 0x34, 0xf2, 0xb9, 0x90, 0xb8, 0x0c, 0x88, + 0x50, 0xcd, 0xf6, 0x69, 0x5d, 0xca, 0xb3, 0x15, 0x37, 0x91, 0x07, 0x46, 0x98, 0x17, 0x9f, 0x89, + 0xae, 0xb8, 0x5d, 0xc8, 0xd8, 0x8a, 0xdb, 0x05, 0x95, 0xca, 0x5c, 0x08, 0x55, 0xdf, 0x86, 0x79, + 0x20, 0xd3, 0x6e, 0x1c, 0x52, 0x99, 0x0b, 0x4b, 0x6d, 0x65, 0x1b, 0xe6, 0x81, 0xb5, 0xd6, 0x8d, + 0x03, 0xb9, 0x04, 0x85, 0x6a, 0x75, 0x5e, 0xeb, 0x58, 0x4a, 0x3d, 0xe6, 0x03, 0x86, 0xd0, 0xd9, + 0x3e, 0x4d, 0xe0, 0x99, 0x19, 0x34, 0xdd, 0xd4, 0x5d, 0xcf, 0xac, 0xbb, 0x38, 0x62, 0xfc, 0x11, + 0x62, 0x44, 0xcd, 0xa0, 0x34, 0x1a, 0x66, 0x06, 0xa5, 0xc1, 0x99, 0xbd, 0x38, 0xa5, 0xbb, 0xae, + 0x6e, 0x19, 0x8e, 0x3e, 0x89, 0xcb, 0x04, 0x8d, 0x3d, 0x0f, 0x88, 0x60, 0x99, 0xbd, 0x18, 0x85, + 0xe0, 0xe1, 0xbb, 0x0f, 0xf1, 0xcd, 0x9c, 0xd5, 0xd8, 0xe1, 0x7b, 0x0c, 0x8f, 0x87, 0xef, 0x31, + 0x18, 0xda, 0x9d, 0x3e, 0x4c, 0xa3, 0x0d, 0x93, 0x89, 0x48, 0x69, 0xc4, 0xec, 0xce, 0x38, 0x01, + 0xda, 0x9d, 0x71, 0x60, 0xa4, 0x49, 0xfe, 0x72, 0xbb, 0xd6, 0xa5, 0x49, 0xe1, 0x2a, 0x9b, 0x28, + 0xc3, 0xd6, 0xef, 0x70, 0x70, 0x94, 0x37, 0x2c, 0xbd, 0x65, 0x97, 0x27, 0x7d, 0xa9, 0x9b, 0xd1, + 0xf5, 0xbb, 0x2b, 0x21, 0x5b, 0xbf, 0xbb, 0x22, 0xd9, 0xec, 0xea, 0x6f, 0xb4, 0xd6, 0x74, 0x87, + 0x1a, 0x65, 0xd3, 0xc1, 0x93, 0xc5, 0x0d, 0xbe, 0x35, 0x7c, 0x3b, 0x3a, 0xbb, 0xf6, 0x20, 0x65, + 0xb3, 0x6b, 0x0f, 0x34, 0x33, 0xf2, 0xd2, 0xd1, 0x1a, 0xd5, 0x0d, 0xe5, 0x6e, 0xd4, 0xc8, 0xeb, + 0x4e, 0xc9, 0x8c, 0xbc, 0xee, 0xd8, 0xee, 0x9f, 0x73, 0xc7, 0x31, 0x3d, 0xaa, 0x34, 0x77, 0xf2, + 0x39, 0x48, 0xda, 0xfd, 0x73, 0x10, 0xcd, 0x36, 0x84, 0xf1, 0x0e, 0x69, 0x45, 0x37, 0x84, 0xc9, + 0x6e, 0x88, 0x97, 0x60, 0x16, 0x8b, 0x78, 0x25, 0xa2, 0x58, 0x51, 0x8b, 0x45, 0x80, 0x99, 0xc5, + 0x12, 0xbe, 0x23, 0x89, 0x3c, 0x30, 0x50, 0xec, 0xe8, 0x1a, 0x2a, 0xe3, 0xd8, 0x1a, 0x1a, 0x79, + 0x8c, 0xf0, 0x42, 0xc4, 0x7b, 0x56, 0x69, 0x47, 0xad, 0x0e, 0x09, 0xc5, 0xac, 0x0e, 0xd9, 0xcf, + 0x76, 0x0a, 0x8e, 0xe1, 0x2d, 0xb8, 0xd6, 0x09, 0xee, 0x71, 0x3e, 0x1b, 0xfd, 0xcc, 0x18, 0x9a, + 0x7d, 0x66, 0x0c, 0x14, 0x61, 0x22, 0xa6, 0x2d, 0xa7, 0x0b, 0x93, 0xf0, 0x7c, 0x30, 0x06, 0x22, + 0x73, 0x40, 0xaa, 0xa5, 0xf9, 0xb9, 0x8a, 0xb1, 0x24, 0x5f, 0x91, 0xb9, 0xd1, 0x13, 0xd8, 0x24, + 0xc5, 0x6c, 0x9f, 0x96, 0x52, 0x8e, 0xbc, 0x0d, 0xe7, 0x04, 0x54, 0x3c, 0x01, 0xc4, 0x74, 0xd1, + 0x46, 0xb0, 0x20, 0x78, 0x51, 0xef, 0x8c, 0x5e, 0xb4, 0xb3, 0x7d, 0x5a, 0x4f, 0x5e, 0xdd, 0xeb, + 0x12, 0xeb, 0x43, 0x67, 0x27, 0x75, 0x05, 0x8b, 0x44, 0x4f, 0x5e, 0xdd, 0xeb, 0x12, 0x72, 0xbf, + 0xb7, 0x93, 0xba, 0x82, 0x4e, 0xe8, 0xc9, 0x8b, 0xb8, 0x50, 0xec, 0x85, 0x2f, 0x35, 0x9b, 0xca, + 0x3a, 0x56, 0xf7, 0xc1, 0x9d, 0x54, 0x57, 0x42, 0x83, 0x73, 0x3b, 0x8e, 0x6c, 0x96, 0x5e, 0x6c, + 0x53, 0xab, 0x1a, 0x59, 0x80, 0xee, 0x47, 0x67, 0xe9, 0x04, 0x01, 0x9b, 0xa5, 0x13, 0x40, 0x36, + 0xa0, 0x64, 0x27, 0x6c, 0x65, 0x23, 0x3a, 0xa0, 0x64, 0x1c, 0x1b, 0x50, 0x11, 0x87, 0xed, 0x45, + 0x38, 0xbe, 0x78, 0xd7, 0xd3, 0x7d, 0x0b, 0xd2, 0x15, 0x5d, 0xf9, 0x4e, 0xec, 0x92, 0x29, 0x49, + 0x82, 0x97, 0x4c, 0x49, 0x30, 0x1b, 0x23, 0x0c, 0x5c, 0xdd, 0xb0, 0xea, 0x33, 0xba, 0xd9, 0xec, + 0x38, 0x54, 0xf9, 0x77, 0xa2, 0x63, 0x24, 0x86, 0x66, 0x63, 0x24, 0x06, 0x62, 0x0b, 0x34, 0x03, + 0x95, 0x5c, 0xd7, 0x6c, 0x58, 0x62, 0x5f, 0xd9, 0x69, 0x7a, 0xca, 0xbf, 0x1b, 0x5d, 0xa0, 0xd3, + 0x68, 0xd8, 0x02, 0x9d, 0x06, 0xc7, 0x53, 0xa7, 0x94, 0x54, 0xea, 0xca, 0xbf, 0x17, 0x3b, 0x75, + 0x4a, 0xa1, 0xc1, 0x53, 0xa7, 0xb4, 0x34, 0xec, 0x33, 0x30, 0xce, 0x6d, 0xb2, 0x39, 0x33, 0xb8, + 0xab, 0xfe, 0xf7, 0xa3, 0xeb, 0x63, 0x1c, 0xcf, 0xd6, 0xc7, 0x38, 0x2c, 0xca, 0x47, 0x74, 0xc1, + 0x7f, 0xd0, 0x8d, 0x4f, 0x20, 0xff, 0x44, 0x19, 0x72, 0x43, 0xe6, 0x23, 0x46, 0xca, 0x0f, 0x64, + 0xba, 0x31, 0x0a, 0x86, 0x47, 0xa2, 0x50, 0x94, 0x91, 0x46, 0xef, 0x99, 0x74, 0x5d, 0xf9, 0x5c, + 0x57, 0x46, 0x9c, 0x20, 0xca, 0x88, 0xc3, 0xc8, 0x5b, 0x70, 0x2a, 0x84, 0xcd, 0xd3, 0xd6, 0x4a, + 0x30, 0x33, 0xfd, 0x60, 0x26, 0x6a, 0x06, 0xa7, 0x93, 0x31, 0x33, 0x38, 0x1d, 0x93, 0xc6, 0x5a, + 0x88, 0xee, 0x3f, 0xdc, 0x86, 0x75, 0x20, 0xc1, 0x2e, 0x0c, 0xd2, 0x58, 0x0b, 0x69, 0xfe, 0xd0, + 0x36, 0xac, 0x03, 0x99, 0x76, 0x61, 0x40, 0xbe, 0x90, 0x81, 0x8b, 0xe9, 0xa8, 0x52, 0xb3, 0x39, + 0x63, 0x3b, 0x21, 0x4e, 0xf9, 0xe1, 0x4c, 0xf4, 0xa0, 0x61, 0x67, 0xc5, 0x66, 0xfb, 0xb4, 0x1d, + 0x56, 0x40, 0x3e, 0x0a, 0xa3, 0xa5, 0x8e, 0x61, 0x7a, 0x78, 0xf1, 0xc6, 0x0c, 0xe7, 0x1f, 0xc9, + 0xc4, 0xb6, 0x38, 0x32, 0x16, 0xb7, 0x38, 0x32, 0x80, 0xbc, 0x01, 0x13, 0x55, 0x5a, 0xef, 0x38, + 0xa6, 0xb7, 0xa1, 0x61, 0x9a, 0x7c, 0xc6, 0xe3, 0x47, 0x33, 0xd1, 0x49, 0x2c, 0x41, 0xc1, 0x26, + 0xb1, 0x04, 0x90, 0xdc, 0xee, 0x92, 0x4c, 0x5d, 0xf9, 0x7c, 0xa6, 0xe7, 0xb5, 0x7c, 0xd0, 0x97, + 0x5d, 0x72, 0xb1, 0x2f, 0xa5, 0x26, 0xa7, 0x56, 0xbe, 0x90, 0xe9, 0x71, 0x8d, 0x2e, 0xcd, 0x70, + 0x29, 0x79, 0xad, 0x97, 0x52, 0x33, 0x07, 0x2b, 0x3f, 0x96, 0xe9, 0x71, 0xed, 0x1d, 0x72, 0x4c, + 0x4b, 0x3a, 0xfc, 0x1c, 0xf7, 0x14, 0x11, 0x8c, 0xfe, 0xa3, 0x4c, 0xd2, 0x55, 0x24, 0x28, 0x2f, + 0x11, 0xb2, 0x62, 0xb7, 0xdc, 0x40, 0xe9, 0xbf, 0x98, 0x49, 0xfa, 0xe6, 0x85, 0xc5, 0xc2, 0x5f, + 0x84, 0xc2, 0xd9, 0xe9, 0xfb, 0x1e, 0x75, 0x2c, 0xbd, 0x89, 0xdd, 0x59, 0xf5, 0x6c, 0x47, 0x6f, + 0xd0, 0x69, 0x4b, 0x5f, 0x69, 0x52, 0xe5, 0x4b, 0x99, 0xa8, 0x05, 0xdb, 0x9d, 0x94, 0x59, 0xb0, + 0xdd, 0xb1, 0x64, 0x0d, 0x1e, 0x49, 0xc3, 0x96, 0x4d, 0x17, 0xeb, 0xf9, 0x72, 0x26, 0x6a, 0xc2, + 0xf6, 0xa0, 0x65, 0x26, 0x6c, 0x0f, 0x34, 0xb9, 0x06, 0x43, 0x93, 0xb6, 0x3f, 0xfd, 0xfe, 0x78, + 0xcc, 0x19, 0x32, 0xc0, 0xcc, 0xf6, 0x69, 0x21, 0x99, 0x28, 0x23, 0x06, 0xf5, 0x57, 0x92, 0x65, + 0xc2, 0xcb, 0xa7, 0xe0, 0x87, 0x28, 0x23, 0xc4, 0xfd, 0x1f, 0x27, 0xcb, 0x84, 0x77, 0x5c, 0xc1, + 0x0f, 0x36, 0x93, 0xf0, 0x1a, 0xe7, 0x67, 0x4a, 0xcc, 0x6e, 0x9b, 0x5a, 0xd3, 0x9b, 0x4d, 0x6a, + 0x35, 0xa8, 0xf2, 0xd5, 0xd8, 0x4c, 0x92, 0x4e, 0xc6, 0x66, 0x92, 0x74, 0x0c, 0xf9, 0x24, 0x9c, + 0xbe, 0xad, 0x37, 0x4d, 0x23, 0xc4, 0xf9, 0x79, 0x64, 0x95, 0x9f, 0xc8, 0x44, 0x77, 0xd3, 0x5d, + 0xe8, 0xd8, 0x6e, 0xba, 0x0b, 0x8a, 0xcc, 0x03, 0xc1, 0x65, 0x34, 0x98, 0x2d, 0xd8, 0xfa, 0xac, + 0xfc, 0x27, 0x99, 0xa8, 0x9d, 0x9a, 0x24, 0x61, 0x76, 0x6a, 0x12, 0x4a, 0x6a, 0xdd, 0x03, 0xd2, + 0x2b, 0x3f, 0x99, 0x89, 0x9e, 0xd6, 0x74, 0x23, 0x9c, 0xed, 0xd3, 0xba, 0x47, 0xb5, 0xbf, 0x01, + 0xe3, 0xd5, 0xa5, 0xca, 0xcc, 0xcc, 0x74, 0xf5, 0x76, 0xa5, 0x8c, 0xee, 0xbb, 0x86, 0xf2, 0x53, + 0xb1, 0x15, 0x2b, 0x4e, 0xc0, 0x56, 0xac, 0x38, 0x8c, 0xbc, 0x0c, 0x23, 0xac, 0xfd, 0x6c, 0xc0, + 0xe0, 0x27, 0x7f, 0x2d, 0x13, 0x35, 0xa7, 0x64, 0x24, 0x33, 0xa7, 0xe4, 0xdf, 0xa4, 0x0a, 0x27, + 0x98, 0x14, 0x97, 0x1c, 0xba, 0x4a, 0x1d, 0x6a, 0xd5, 0xfd, 0x31, 0xfd, 0xd3, 0x99, 0xa8, 0x95, + 0x91, 0x46, 0xc4, 0xac, 0x8c, 0x34, 0x38, 0xb9, 0x0b, 0xe7, 0xe2, 0x27, 0x41, 0xf2, 0x63, 0x2a, + 0xe5, 0x67, 0x32, 0x31, 0x63, 0xb8, 0x07, 0x31, 0x1a, 0xc3, 0x3d, 0xf0, 0xc4, 0x82, 0xf3, 0xe2, + 0x58, 0x45, 0x38, 0x5c, 0xc6, 0x6b, 0xfb, 0x4f, 0x79, 0x6d, 0x4f, 0x84, 0x0e, 0x81, 0x3d, 0xa8, + 0x67, 0xfb, 0xb4, 0xde, 0xec, 0x98, 0x9e, 0x25, 0xc3, 0xae, 0x2b, 0x3f, 0x9b, 0x49, 0xf7, 0x48, + 0x89, 0xb8, 0x29, 0xa7, 0xc5, 0x6b, 0x7f, 0xab, 0x5b, 0xd0, 0x70, 0xe5, 0xe7, 0x62, 0xe3, 0x2d, + 0x9d, 0x8c, 0x8d, 0xb7, 0x2e, 0x51, 0xc7, 0xdf, 0x80, 0x09, 0xae, 0xd4, 0x4b, 0x3a, 0x0e, 0x43, + 0xab, 0x41, 0x0d, 0xe5, 0x3f, 0x8b, 0xad, 0x76, 0x09, 0x0a, 0x74, 0xed, 0x89, 0x03, 0xd9, 0xd4, + 0x5d, 0x6d, 0xeb, 0x96, 0x85, 0xc7, 0xac, 0xca, 0x7f, 0x1e, 0x9b, 0xba, 0x43, 0x14, 0x3a, 0xee, + 0x06, 0xbf, 0x98, 0x26, 0xf4, 0x4a, 0xb8, 0xa1, 0xfc, 0x7c, 0x4c, 0x13, 0x7a, 0x11, 0x33, 0x4d, + 0xe8, 0x99, 0xbd, 0xe3, 0x76, 0x97, 0x87, 0x8d, 0xca, 0xd7, 0x63, 0x2b, 0x72, 0x2a, 0x15, 0x5b, + 0x91, 0xd3, 0xdf, 0x45, 0xde, 0xee, 0xf2, 0x28, 0x50, 0xf9, 0x85, 0xde, 0x7c, 0xc3, 0x95, 0x3e, + 0xfd, 0x4d, 0xe1, 0xed, 0x2e, 0x0f, 0xea, 0x94, 0x5f, 0xec, 0xcd, 0x37, 0x74, 0xec, 0x4b, 0x7f, + 0x8f, 0x57, 0xeb, 0xfe, 0x18, 0x4d, 0xf9, 0xa5, 0xf8, 0xd4, 0xd5, 0x85, 0x10, 0xa7, 0xae, 0x6e, + 0x2f, 0xda, 0x56, 0xe0, 0x0c, 0xd7, 0x90, 0x1b, 0x8e, 0xde, 0x5e, 0xab, 0x52, 0xcf, 0x33, 0xad, + 0x86, 0xbf, 0x13, 0xfb, 0x2f, 0x32, 0xb1, 0xe3, 0xb1, 0x6e, 0x94, 0x78, 0x3c, 0xd6, 0x0d, 0x39, + 0x39, 0x00, 0xfd, 0xb8, 0xe3, 0x53, 0xbf, 0x9e, 0x81, 0x91, 0xaa, 0xe7, 0x50, 0xbd, 0x25, 0xa2, + 0x2d, 0x9c, 0x85, 0x41, 0xee, 0x3a, 0xe5, 0xbf, 0x5e, 0xd0, 0x82, 0xdf, 0xe4, 0x22, 0x8c, 0xcd, + 0xe9, 0xae, 0x87, 0x25, 0x2b, 0x96, 0x41, 0xef, 0xe3, 0xb3, 0x81, 0x9c, 0x16, 0x83, 0x92, 0x39, + 0x4e, 0xc7, 0xcb, 0x61, 0x6c, 0x9c, 0xdc, 0xb6, 0x41, 0x06, 0x06, 0xdf, 0xdd, 0x2c, 0xf6, 0x61, + 0x4c, 0x81, 0x58, 0x59, 0xf5, 0xdb, 0x19, 0x48, 0x38, 0x75, 0x3d, 0xf8, 0xab, 0xa2, 0x45, 0x38, + 0x16, 0x8b, 0xc7, 0x24, 0xde, 0x3e, 0xec, 0x30, 0x5c, 0x53, 0xbc, 0x34, 0xf9, 0x60, 0xe0, 0x73, + 0x7f, 0x4b, 0x9b, 0x13, 0x01, 0x24, 0x06, 0xb6, 0x36, 0x8b, 0xb9, 0x8e, 0xd3, 0xd4, 0x24, 0x94, + 0x78, 0x20, 0xfc, 0xdf, 0x8d, 0x87, 0xc1, 0x66, 0xc8, 0x45, 0xf1, 0xc4, 0x29, 0x13, 0x86, 0x9d, + 0x88, 0xa5, 0x32, 0xe4, 0x4f, 0x9a, 0x3e, 0x0a, 0x23, 0x95, 0x56, 0x9b, 0x3a, 0xae, 0x6d, 0xe9, + 0x9e, 0xed, 0xa7, 0x4c, 0xc7, 0x90, 0x04, 0xa6, 0x04, 0x97, 0x9f, 0xc9, 0xcb, 0xf4, 0xe4, 0xb2, + 0x9f, 0x5d, 0x21, 0x87, 0x61, 0x7e, 0x30, 0x56, 0x65, 0x3c, 0x3d, 0x1e, 0xa7, 0x60, 0xa4, 0xb7, + 0x5c, 0x1d, 0x5f, 0x67, 0x04, 0xa4, 0x1d, 0x06, 0x90, 0x49, 0x91, 0x82, 0x3c, 0x05, 0x05, 0x3c, + 0xcd, 0x72, 0x31, 0x6b, 0x8a, 0x08, 0x86, 0xd1, 0x44, 0x88, 0x1c, 0x7a, 0x80, 0xd3, 0x90, 0x9b, + 0x30, 0x1e, 0x1e, 0xd5, 0x63, 0x92, 0x7f, 0x3f, 0x4e, 0x32, 0xa6, 0x15, 0xbc, 0x1b, 0xe0, 0x6a, + 0x0d, 0x44, 0x4a, 0x2c, 0x12, 0x05, 0xc9, 0x2c, 0x1c, 0x0b, 0x61, 0x4c, 0x44, 0x7e, 0x7c, 0x76, + 0xcc, 0x8d, 0x23, 0xf1, 0x62, 0xe2, 0x8c, 0xe4, 0xc6, 0x89, 0x15, 0x23, 0x15, 0x18, 0xf0, 0x23, + 0x61, 0x0c, 0x6e, 0xab, 0xa4, 0xc7, 0x45, 0x24, 0x8c, 0x01, 0x39, 0x06, 0x86, 0x5f, 0x9e, 0xcc, + 0xc0, 0x98, 0x66, 0x77, 0x3c, 0xba, 0x6c, 0x8b, 0x35, 0x4e, 0x04, 0xf0, 0xc5, 0x36, 0x39, 0x0c, + 0x53, 0xf3, 0x6c, 0x3f, 0x2b, 0xa3, 0x9c, 0x1d, 0x30, 0x5a, 0x8a, 0x2c, 0xc0, 0x44, 0xe2, 0x52, + 0x43, 0xce, 0x95, 0x28, 0x7d, 0x5e, 0x92, 0x59, 0xb2, 0x28, 0xf9, 0x91, 0x0c, 0x14, 0x96, 0x1d, + 0xdd, 0xf4, 0x5c, 0xf1, 0xb0, 0xe3, 0xe4, 0x95, 0x75, 0x47, 0x6f, 0x33, 0xfd, 0xb8, 0x82, 0x71, + 0x9c, 0x6e, 0xeb, 0xcd, 0x0e, 0x75, 0x27, 0xef, 0xb0, 0xaf, 0xfb, 0x7f, 0x37, 0x8b, 0x2f, 0x37, + 0x70, 0xeb, 0x74, 0xa5, 0x6e, 0xb7, 0xae, 0x36, 0x1c, 0xfd, 0x9e, 0xe9, 0xe1, 0x85, 0xb4, 0xde, + 0xbc, 0xea, 0xd1, 0x26, 0xee, 0xd0, 0xae, 0xea, 0x6d, 0xf3, 0x2a, 0xc6, 0x0b, 0xbc, 0x1a, 0x70, + 0xe2, 0x35, 0x30, 0x15, 0xf0, 0xf0, 0x2f, 0x59, 0x05, 0x38, 0x8e, 0x2c, 0xb0, 0x8d, 0x0d, 0x7e, + 0x6a, 0xa9, 0xdd, 0x16, 0xaf, 0x44, 0xa4, 0x7d, 0x8d, 0x8f, 0xe1, 0x8a, 0x1d, 0x08, 0x4c, 0x6f, + 0xb7, 0xe5, 0x6c, 0xac, 0x21, 0x1d, 0xd3, 0x82, 0x65, 0xd1, 0x22, 0x5f, 0x4c, 0xa3, 0xa1, 0xc4, + 0xfd, 0xc6, 0xa6, 0x08, 0x29, 0x5e, 0x8c, 0xac, 0xc0, 0x31, 0xc1, 0x37, 0x88, 0xa8, 0x3b, 0x16, + 0x9d, 0x15, 0x62, 0x68, 0xae, 0xb4, 0x41, 0x1b, 0x0d, 0x01, 0x96, 0xeb, 0x88, 0x95, 0x20, 0x93, + 0x61, 0x9a, 0xaf, 0x05, 0xbd, 0x45, 0x5d, 0xe5, 0x18, 0x6a, 0xec, 0xb9, 0xad, 0xcd, 0xa2, 0xe2, + 0x97, 0xc7, 0xa0, 0x30, 0xa9, 0x49, 0x2b, 0xb1, 0x88, 0xcc, 0x83, 0x6b, 0xfd, 0x78, 0x0a, 0x8f, + 0xb8, 0xce, 0x47, 0x8b, 0x90, 0x29, 0x18, 0x0d, 0x9c, 0x54, 0x6f, 0xdd, 0xaa, 0x94, 0xf1, 0x19, + 0xca, 0xd0, 0xe4, 0xf9, 0xad, 0xcd, 0xe2, 0x99, 0x58, 0xcc, 0x5b, 0x99, 0x49, 0xa4, 0x8c, 0xf4, + 0x5e, 0x8d, 0xbf, 0x4b, 0x89, 0xbd, 0x57, 0x6b, 0xa7, 0xbc, 0x57, 0x5b, 0x22, 0xaf, 0xc2, 0x70, + 0xe9, 0x4e, 0x55, 0xbc, 0xc3, 0x73, 0x95, 0xe3, 0x61, 0x94, 0x74, 0xcc, 0x5b, 0x2a, 0xde, 0xec, + 0xc9, 0x4d, 0x97, 0xe9, 0xc9, 0x34, 0x8c, 0x45, 0xee, 0xb9, 0x5d, 0xe5, 0x04, 0x72, 0xc0, 0x96, + 0xeb, 0x88, 0xa9, 0x39, 0x02, 0x15, 0xc9, 0xa4, 0x1b, 0x29, 0xc4, 0xb4, 0x86, 0x6d, 0x15, 0x9b, + 0x4d, 0x7b, 0x5d, 0xa3, 0xf8, 0xe4, 0x0f, 0x1f, 0xb5, 0x0c, 0x72, 0xad, 0x31, 0x04, 0xaa, 0xe6, + 0x70, 0x5c, 0x24, 0x75, 0x6e, 0xb4, 0x18, 0x79, 0x1b, 0x08, 0xc6, 0xa8, 0xa6, 0x86, 0x7f, 0xec, + 0x59, 0x29, 0xbb, 0xca, 0x29, 0x8c, 0x67, 0x47, 0xe2, 0x6f, 0x4e, 0x2b, 0xe5, 0xc9, 0x8b, 0x62, + 0xfa, 0xb8, 0xa0, 0xf3, 0x52, 0x35, 0x47, 0xe0, 0x6a, 0x66, 0x24, 0x81, 0x57, 0x0a, 0x57, 0xb2, + 0x0e, 0xa7, 0x97, 0x1c, 0x7a, 0xcf, 0xb4, 0x3b, 0xae, 0xbf, 0x7c, 0xf8, 0xf3, 0xd6, 0xe9, 0x6d, + 0xe7, 0xad, 0xc7, 0x44, 0xc5, 0x27, 0xdb, 0x0e, 0xbd, 0x57, 0xf3, 0xa3, 0x98, 0x45, 0x22, 0xf9, + 0x74, 0xe3, 0x8e, 0x69, 0xc8, 0xde, 0xe9, 0x38, 0x54, 0xc0, 0x4d, 0xea, 0x2a, 0x4a, 0x38, 0xd5, + 0xf2, 0xd7, 0x9b, 0x66, 0x80, 0x8b, 0xa4, 0x21, 0x8b, 0x16, 0x23, 0x1a, 0x90, 0x1b, 0x53, 0xfe, + 0x11, 0x78, 0xa9, 0xce, 0x93, 0x35, 0x29, 0x67, 0x90, 0x99, 0xca, 0xc4, 0xd2, 0xa8, 0x07, 0x11, + 0x0d, 0x6b, 0xba, 0xc0, 0xcb, 0x62, 0x49, 0x96, 0x26, 0x73, 0x30, 0xbe, 0xe4, 0xa0, 0x41, 0x7e, + 0x93, 0x6e, 0x2c, 0xd9, 0x4d, 0xb3, 0xbe, 0x81, 0x6f, 0x6b, 0xc4, 0x54, 0xd9, 0xe6, 0xb8, 0xda, + 0x5d, 0xba, 0x51, 0x6b, 0x23, 0x56, 0x5e, 0x56, 0xe2, 0x25, 0xe5, 0x08, 0x63, 0x8f, 0xec, 0x2c, + 0xc2, 0x18, 0x85, 0x71, 0x71, 0x80, 0x7e, 0xdf, 0xa3, 0x16, 0x5b, 0xea, 0x5d, 0xf1, 0x8e, 0x46, + 0x89, 0x1d, 0xb8, 0x07, 0x78, 0x91, 0x46, 0x97, 0x8f, 0x32, 0x1a, 0x80, 0xe5, 0x86, 0xc5, 0x8b, + 0xa8, 0x5f, 0xce, 0xc9, 0x53, 0x27, 0x39, 0x07, 0x79, 0x29, 0xc0, 0x35, 0xc6, 0x18, 0xc2, 0x60, + 0x80, 0x79, 0x11, 0xf5, 0x6c, 0x48, 0x98, 0x1d, 0xc1, 0x63, 0x52, 0x4c, 0x5b, 0x12, 0xc6, 0x9d, + 0xd1, 0x42, 0x02, 0x4c, 0x19, 0xd1, 0x59, 0x69, 0x9a, 0x75, 0x0c, 0x11, 0x99, 0x93, 0x52, 0x46, + 0x20, 0x94, 0x47, 0x88, 0x94, 0x48, 0xc8, 0x35, 0x18, 0xf6, 0xf7, 0x70, 0x61, 0x8c, 0x2d, 0x8c, + 0x1c, 0xe8, 0x27, 0x1c, 0xe6, 0x81, 0x09, 0x25, 0x22, 0xf2, 0x12, 0xa6, 0xdc, 0xf6, 0x1f, 0xea, + 0xf6, 0x87, 0xe6, 0x8b, 0x3c, 0xf0, 0x63, 0x39, 0xb7, 0xfd, 0xf7, 0xba, 0x93, 0x30, 0x2a, 0x6b, + 0x92, 0x9f, 0x24, 0x07, 0xe7, 0xbc, 0x88, 0xfa, 0xc9, 0x7d, 0x1b, 0x2d, 0x42, 0x16, 0x61, 0x22, + 0xa1, 0x3c, 0x22, 0x22, 0x17, 0x26, 0x4a, 0x4c, 0xd1, 0x3c, 0x79, 0x4d, 0x4d, 0x94, 0x55, 0x7f, + 0x30, 0x9b, 0x58, 0x31, 0x98, 0x60, 0x04, 0x95, 0xd4, 0x39, 0x28, 0x18, 0x9f, 0x35, 0x17, 0x8c, + 0x44, 0x44, 0x2e, 0xc1, 0x60, 0x2c, 0xeb, 0x36, 0x3e, 0xdd, 0x0e, 0x52, 0x6e, 0x07, 0x58, 0x72, + 0x4d, 0x4a, 0xdb, 0x24, 0x85, 0xbf, 0xf3, 0xd3, 0x36, 0xc5, 0xe3, 0xc0, 0x61, 0x02, 0xa7, 0x6b, + 0xb1, 0x08, 0xf1, 0x7e, 0x72, 0xe4, 0xe4, 0x6a, 0x15, 0x46, 0x84, 0x0f, 0x6c, 0xc5, 0xfe, 0xed, + 0x6c, 0x45, 0xf5, 0x77, 0x33, 0x49, 0xed, 0x27, 0xd7, 0x93, 0xe1, 0xac, 0x78, 0x5e, 0x64, 0x1f, + 0x28, 0xd7, 0x1a, 0x04, 0xb6, 0x8a, 0x04, 0xa6, 0xca, 0x3e, 0x70, 0x60, 0xaa, 0xdc, 0x2e, 0x03, + 0x53, 0xa9, 0xff, 0x2a, 0xdf, 0xd3, 0x0d, 0xeb, 0x40, 0x02, 0x18, 0xbc, 0xc8, 0xf6, 0x3b, 0xac, + 0xf6, 0x92, 0x9b, 0xb0, 0xda, 0xb9, 0x97, 0x49, 0x4d, 0xe7, 0xa3, 0xc6, 0xd5, 0xa2, 0x94, 0xe4, + 0x35, 0x18, 0xf1, 0x3f, 0x00, 0x03, 0x9e, 0x49, 0x81, 0xba, 0x82, 0xb5, 0x26, 0x9e, 0xda, 0x5a, + 0x2e, 0x40, 0x9e, 0x83, 0x21, 0xb4, 0x34, 0xda, 0x7a, 0xdd, 0x8f, 0x86, 0xc7, 0xc3, 0xe7, 0xf9, + 0x40, 0xf9, 0x91, 0x7e, 0x40, 0x49, 0x3e, 0x05, 0x85, 0x48, 0x6e, 0xf5, 0xab, 0x3b, 0xf0, 0x5b, + 0xbb, 0x22, 0x47, 0x72, 0xe5, 0x7b, 0x87, 0x78, 0x5e, 0x75, 0xc1, 0x94, 0x2c, 0xc3, 0xf1, 0x25, + 0x87, 0x1a, 0xe8, 0x21, 0x39, 0x7d, 0xbf, 0xed, 0x88, 0x38, 0xbb, 0x7c, 0x00, 0xe3, 0xd2, 0xd1, + 0xf6, 0xd1, 0x6c, 0x51, 0x13, 0x78, 0x39, 0x24, 0x57, 0x4a, 0x71, 0x66, 0x4f, 0xf0, 0x96, 0xdc, + 0xa4, 0x1b, 0xeb, 0x98, 0x5f, 0x73, 0x30, 0xb4, 0x27, 0x84, 0xa0, 0xef, 0x0a, 0x94, 0x6c, 0x4f, + 0x44, 0x0b, 0x9d, 0x7d, 0x11, 0x86, 0x1f, 0x34, 0x1a, 0xea, 0x6f, 0x64, 0xbb, 0x38, 0x34, 0x3f, + 0xbc, 0x09, 0x29, 0x82, 0x54, 0x68, 0xfd, 0x5d, 0x52, 0xa1, 0x7d, 0x2f, 0xdb, 0xc5, 0x5b, 0xfb, + 0xa1, 0x4e, 0x59, 0x14, 0x08, 0x23, 0x9a, 0xb2, 0x28, 0xcc, 0x16, 0x65, 0x1a, 0x9a, 0x4c, 0x14, + 0x4b, 0x6e, 0x56, 0xd8, 0x36, 0xb9, 0xd9, 0x2f, 0xe7, 0x7a, 0x79, 0xb3, 0x1f, 0xc9, 0x7e, 0x37, + 0xb2, 0xbf, 0x06, 0xc3, 0x81, 0x64, 0x2b, 0x65, 0xb4, 0x67, 0x46, 0x83, 0xd8, 0xcb, 0x1c, 0x8c, + 0x65, 0x24, 0x22, 0x72, 0x99, 0xb7, 0xb5, 0x6a, 0xbe, 0xc3, 0x43, 0x89, 0x8e, 0x8a, 0x20, 0x91, + 0xba, 0xa7, 0xd7, 0x5c, 0xf3, 0x1d, 0xaa, 0x05, 0x68, 0xf5, 0x7f, 0xce, 0xa6, 0x3e, 0x09, 0x38, + 0xea, 0xa3, 0x5d, 0xf4, 0x51, 0x8a, 0x10, 0xf9, 0x63, 0x86, 0x23, 0x21, 0xee, 0x42, 0x88, 0x7f, + 0x99, 0x4d, 0x7d, 0xfa, 0x71, 0x24, 0xc4, 0xdd, 0xcc, 0x16, 0x4f, 0xc1, 0x90, 0x66, 0xaf, 0xbb, + 0x98, 0xc9, 0x58, 0xcc, 0x15, 0x38, 0x51, 0x3b, 0xf6, 0xba, 0xcb, 0xb3, 0x3c, 0x6b, 0x21, 0x81, + 0xfa, 0xd7, 0xd9, 0x1e, 0x8f, 0x63, 0x8e, 0x04, 0xff, 0x5e, 0x2e, 0x91, 0xbf, 0x95, 0x8d, 0x3c, + 0xbe, 0x79, 0xa8, 0x73, 0x7f, 0x56, 0xeb, 0x6b, 0xb4, 0xa5, 0xc7, 0x73, 0x7f, 0xba, 0x08, 0x15, + 0x19, 0xb8, 0x42, 0x12, 0xf5, 0x1b, 0xd9, 0xd8, 0xeb, 0xa3, 0x23, 0xd9, 0xed, 0x58, 0x76, 0x81, + 0xd6, 0x89, 0x07, 0x55, 0x47, 0x92, 0xdb, 0xa9, 0xe4, 0x3e, 0x9f, 0x8d, 0xbd, 0x3d, 0x7b, 0x68, + 0x65, 0xc7, 0x06, 0x60, 0xf2, 0x4d, 0xdc, 0x43, 0xab, 0x49, 0x4f, 0xc1, 0x90, 0x90, 0x43, 0xb0, + 0x54, 0xf0, 0x79, 0x9f, 0x03, 0xf1, 0x00, 0x35, 0x20, 0x50, 0x7f, 0x38, 0x0b, 0xd1, 0x37, 0x81, + 0x0f, 0xa9, 0x0e, 0xfd, 0x56, 0x36, 0xfa, 0x1a, 0xf2, 0xe1, 0xd5, 0x9f, 0x2b, 0x00, 0xd5, 0xce, + 0x4a, 0x5d, 0x04, 0xd3, 0xeb, 0x97, 0x4e, 0xe0, 0x03, 0xa8, 0x26, 0x51, 0xa8, 0xff, 0x3a, 0x9b, + 0xfa, 0x44, 0xf3, 0xe1, 0x15, 0xe0, 0xb3, 0x78, 0x2a, 0x5e, 0xb7, 0xc2, 0x89, 0x1c, 0x0f, 0x21, + 0xd9, 0xf8, 0x4b, 0xe4, 0xf0, 0xf0, 0x09, 0xc9, 0x47, 0x52, 0xcc, 0x35, 0x8c, 0x30, 0x1a, 0x9a, + 0x6b, 0xf2, 0x0d, 0x83, 0x64, 0xb8, 0xfd, 0x1f, 0xd9, 0xed, 0x5e, 0xb4, 0x3e, 0xcc, 0xab, 0xea, + 0xc0, 0x92, 0xbe, 0x81, 0x91, 0x97, 0x58, 0x4f, 0x8c, 0xf0, 0x0c, 0x13, 0x6d, 0x0e, 0x92, 0x6f, + 0xc4, 0x04, 0x95, 0xfa, 0x17, 0xfd, 0xe9, 0xcf, 0x29, 0x1f, 0x5e, 0x11, 0x9e, 0x83, 0xfc, 0x92, + 0xee, 0xad, 0x09, 0x4d, 0xc6, 0xdb, 0xba, 0xb6, 0xee, 0xad, 0x69, 0x08, 0x25, 0x97, 0x61, 0x50, + 0xd3, 0xd7, 0xf9, 0x99, 0x67, 0x21, 0xcc, 0xfe, 0xe1, 0xe8, 0xeb, 0x35, 0x7e, 0xee, 0x19, 0xa0, + 0x89, 0x1a, 0x64, 0x9f, 0xe1, 0x27, 0xdf, 0x98, 0xfa, 0x80, 0x67, 0x9f, 0x09, 0x72, 0xce, 0x9c, + 0x83, 0xfc, 0xa4, 0x6d, 0x6c, 0xa0, 0x33, 0xcb, 0x08, 0xaf, 0x6c, 0xc5, 0x36, 0x36, 0x34, 0x84, + 0x92, 0x2f, 0x64, 0x60, 0x60, 0x96, 0xea, 0x06, 0x1b, 0x21, 0x43, 0xbd, 0x7c, 0x41, 0x3e, 0xb6, + 0x3f, 0xbe, 0x20, 0x13, 0x6b, 0xbc, 0x32, 0x59, 0x51, 0x44, 0xfd, 0xe4, 0x06, 0x0c, 0x4e, 0xe9, + 0x1e, 0x6d, 0xd8, 0xce, 0x06, 0x7a, 0xb7, 0x8c, 0x85, 0x2e, 0x79, 0x11, 0xfd, 0xf1, 0x89, 0xf8, + 0xcd, 0x58, 0x5d, 0xfc, 0xd2, 0x82, 0xc2, 0x4c, 0x2c, 0x22, 0x95, 0xe5, 0x70, 0x28, 0x16, 0x9e, + 0xb3, 0x32, 0xc8, 0x58, 0x19, 0x1c, 0x2b, 0x8f, 0xa4, 0x1f, 0x2b, 0xa3, 0xf5, 0x88, 0x1e, 0x70, + 0x98, 0xf3, 0x65, 0x14, 0x17, 0x7d, 0x6e, 0x3d, 0x22, 0x14, 0x53, 0xbe, 0x68, 0x12, 0x89, 0xfa, + 0x9d, 0x7e, 0x48, 0x7d, 0x7c, 0x75, 0xa4, 0xe4, 0x47, 0x4a, 0x1e, 0x2a, 0x79, 0x39, 0xa1, 0xe4, + 0x67, 0x93, 0xcf, 0xf9, 0xde, 0xa7, 0x1a, 0xfe, 0xb5, 0x7c, 0xe2, 0x31, 0xf0, 0xc3, 0xbd, 0xbb, + 0x0c, 0xa5, 0xd7, 0xbf, 0xad, 0xf4, 0x82, 0x01, 0x51, 0xd8, 0x76, 0x40, 0x0c, 0xec, 0x74, 0x40, + 0x0c, 0x76, 0x1d, 0x10, 0xa1, 0x82, 0x0c, 0x75, 0x55, 0x90, 0x8a, 0x18, 0x34, 0xd0, 0x3b, 0x9f, + 0xd8, 0xb9, 0xad, 0xcd, 0xe2, 0x18, 0x1b, 0x4d, 0xa9, 0x99, 0xc4, 0x90, 0x85, 0xfa, 0xed, 0x7c, + 0x8f, 0x17, 0xfc, 0x07, 0xa2, 0x23, 0xcf, 0x42, 0xae, 0xd4, 0x6e, 0x0b, 0xfd, 0x38, 0x2e, 0x05, + 0x0f, 0xe8, 0x52, 0x8a, 0x51, 0x93, 0x97, 0x20, 0x57, 0xba, 0x53, 0x8d, 0xc7, 0x21, 0x2f, 0xdd, + 0xa9, 0x8a, 0x2f, 0xe9, 0x5a, 0xf6, 0x4e, 0x95, 0xbc, 0x12, 0x06, 0x04, 0x5b, 0xeb, 0x58, 0x77, + 0xc5, 0x46, 0x51, 0x38, 0xc1, 0xfa, 0x9e, 0x36, 0x75, 0x86, 0x62, 0xdb, 0xc5, 0x18, 0x6d, 0x4c, + 0x9b, 0x0a, 0x3b, 0xd7, 0xa6, 0x81, 0x6d, 0xb5, 0x69, 0x70, 0xa7, 0xda, 0x34, 0xb4, 0x03, 0x6d, + 0x82, 0x6d, 0xb5, 0x69, 0x78, 0xef, 0xda, 0xd4, 0x86, 0xb3, 0xc9, 0xa8, 0x2b, 0x81, 0x46, 0x68, + 0x40, 0x92, 0x58, 0xe1, 0x58, 0x82, 0x57, 0xff, 0x1d, 0x8e, 0xad, 0xf1, 0x94, 0xb3, 0xf1, 0x84, + 0xad, 0x5a, 0x4a, 0x69, 0xf5, 0x37, 0xb2, 0xdd, 0x83, 0xc5, 0x1c, 0xce, 0x29, 0xee, 0x33, 0xa9, + 0x52, 0xca, 0x47, 0x1f, 0xef, 0x75, 0x97, 0x72, 0x8c, 0x6d, 0x9a, 0xcc, 0xbe, 0x95, 0xe9, 0x16, + 0xc1, 0x66, 0x4f, 0x12, 0x7b, 0x22, 0xe9, 0xac, 0x86, 0xde, 0xf3, 0x6e, 0xd4, 0x4b, 0x2d, 0x9e, + 0xc1, 0x34, 0xf7, 0x80, 0x19, 0x4c, 0x7f, 0x37, 0x03, 0xc7, 0x6f, 0x76, 0x56, 0xa8, 0x70, 0x4e, + 0x0b, 0x9a, 0xf1, 0x36, 0x00, 0x03, 0x0b, 0x27, 0x96, 0x0c, 0x3a, 0xb1, 0x7c, 0x48, 0x8e, 0x3e, + 0x13, 0x2b, 0x70, 0x25, 0xa4, 0xe6, 0x0e, 0x2c, 0xe7, 0x7d, 0x17, 0xcb, 0xbb, 0x9d, 0x15, 0x5a, + 0x4b, 0x78, 0xb2, 0x48, 0xdc, 0xcf, 0xbe, 0xca, 0x9d, 0xd7, 0x1f, 0xd4, 0x69, 0xe4, 0xd7, 0xb2, + 0x5d, 0x03, 0xfe, 0x1c, 0xda, 0x7c, 0x2b, 0x9f, 0x48, 0xed, 0x95, 0x78, 0xde, 0x95, 0x14, 0x92, + 0x18, 0xc7, 0x34, 0x2e, 0xe9, 0x02, 0x3b, 0xe4, 0x59, 0x80, 0xde, 0x53, 0x81, 0xfd, 0x51, 0xa6, + 0x6b, 0x60, 0xa6, 0xc3, 0x2a, 0x30, 0xf5, 0x1f, 0xe4, 0xfc, 0x78, 0x50, 0x7b, 0xfa, 0x84, 0xa7, + 0x60, 0x48, 0x3c, 0x8b, 0x8b, 0xfa, 0xd6, 0x8a, 0xa3, 0x3c, 0x3c, 0x1a, 0x0e, 0x08, 0xd8, 0x32, + 0xef, 0xc7, 0xab, 0x09, 0xd2, 0xd7, 0xe2, 0x32, 0x6f, 0x0a, 0x28, 0xa3, 0x97, 0x48, 0xd8, 0x42, + 0x3e, 0x7d, 0xdf, 0xf4, 0xd0, 0x2a, 0x60, 0x7d, 0x99, 0xe3, 0x0b, 0x39, 0xbd, 0x6f, 0x7a, 0xdc, + 0x26, 0x08, 0xd0, 0x6c, 0x91, 0xae, 0x86, 0x39, 0x0e, 0xc5, 0x22, 0xed, 0x8a, 0x54, 0x8f, 0xe2, + 0x31, 0xd7, 0x53, 0x30, 0x24, 0x1c, 0x56, 0x85, 0x9b, 0x89, 0x68, 0xad, 0x70, 0x71, 0xc5, 0xd6, + 0x06, 0x04, 0x8c, 0xa3, 0x46, 0x1b, 0xa1, 0x63, 0x1d, 0x72, 0x74, 0x10, 0xa2, 0x09, 0x0c, 0xb9, + 0x06, 0x63, 0x55, 0x4f, 0xb7, 0x0c, 0xdd, 0x31, 0x16, 0x3b, 0x5e, 0xbb, 0xe3, 0xc9, 0x46, 0xa9, + 0xeb, 0x19, 0x76, 0xc7, 0xd3, 0x62, 0x14, 0xe4, 0xc3, 0x30, 0xea, 0x43, 0xa6, 0x1d, 0xc7, 0x76, + 0x64, 0xcb, 0xc3, 0xf5, 0x0c, 0xea, 0x38, 0x5a, 0x94, 0x80, 0x7c, 0x04, 0x46, 0x2b, 0xd6, 0x3d, + 0x9b, 0x27, 0xcf, 0xbc, 0xa5, 0xcd, 0x09, 0x3b, 0x04, 0x1f, 0x48, 0x99, 0x01, 0xa2, 0xd6, 0x71, + 0x9a, 0x5a, 0x94, 0x50, 0xdd, 0xca, 0x26, 0xc3, 0x66, 0x3d, 0xbc, 0x9b, 0x96, 0xcb, 0x51, 0x67, + 0x3a, 0xf4, 0x20, 0x45, 0x83, 0x50, 0xf6, 0xe5, 0xe5, 0x76, 0xe1, 0x35, 0x18, 0xbc, 0x49, 0x37, + 0xb8, 0xdf, 0x67, 0x21, 0x74, 0x15, 0xbe, 0x2b, 0x60, 0xf2, 0x89, 0xab, 0x4f, 0xa7, 0x7e, 0x33, + 0x9b, 0x0c, 0x08, 0xf6, 0xf0, 0x0a, 0xfb, 0xc3, 0x30, 0x80, 0xa2, 0xac, 0xf8, 0x47, 0xfe, 0x28, + 0x40, 0x14, 0x77, 0xd4, 0x03, 0xd9, 0x27, 0x53, 0x7f, 0xa1, 0x10, 0x8f, 0x12, 0xf7, 0xf0, 0x4a, + 0xef, 0x65, 0x18, 0x9e, 0xb2, 0x2d, 0xd7, 0x74, 0x3d, 0x6a, 0xd5, 0x7d, 0x85, 0x3d, 0xc3, 0x0c, + 0xaa, 0x7a, 0x08, 0x96, 0x5f, 0x06, 0x49, 0xd4, 0x0f, 0xa2, 0xbc, 0xe4, 0x79, 0x18, 0x42, 0x91, + 0xa3, 0x9f, 0xb4, 0x94, 0x9c, 0x7b, 0x85, 0x01, 0xe3, 0x4e, 0xd2, 0x21, 0x29, 0xb9, 0x05, 0x83, + 0x53, 0x6b, 0x66, 0xd3, 0x70, 0xa8, 0x85, 0xfe, 0xc2, 0xd2, 0x63, 0xdc, 0x68, 0x5f, 0x5e, 0xc1, + 0x7f, 0x91, 0x96, 0x37, 0xa7, 0x2e, 0x8a, 0x45, 0xde, 0x46, 0x09, 0xd8, 0xd9, 0x9f, 0xcc, 0x02, + 0x84, 0x05, 0xc8, 0xa3, 0x90, 0x0d, 0xd2, 0x87, 0xa1, 0x9b, 0x4a, 0x44, 0x83, 0xb2, 0xb8, 0x54, + 0x88, 0xb1, 0x9d, 0xdd, 0x76, 0x6c, 0xdf, 0x82, 0x02, 0x3f, 0xf1, 0x42, 0x4f, 0x72, 0x29, 0x70, + 0x55, 0xd7, 0x06, 0x5f, 0x41, 0x7a, 0xbe, 0x99, 0x45, 0xcb, 0x33, 0xe2, 0x95, 0xcd, 0x99, 0x9d, + 0xad, 0x43, 0x3f, 0xfe, 0x45, 0x2e, 0x42, 0x1e, 0xa5, 0x98, 0xc1, 0x7d, 0x2c, 0xce, 0xd2, 0x31, + 0xf9, 0x21, 0x9e, 0x75, 0xd3, 0x94, 0x6d, 0x79, 0xac, 0x6a, 0x6c, 0xf5, 0x88, 0x90, 0x8b, 0x80, + 0x45, 0xe4, 0x22, 0x60, 0xea, 0xff, 0x9e, 0x4d, 0x89, 0x5f, 0xf8, 0xf0, 0x0e, 0x93, 0x17, 0x01, + 0xf0, 0xa1, 0x35, 0x93, 0xa7, 0xff, 0x44, 0x03, 0x47, 0x09, 0x32, 0x42, 0xb5, 0x8d, 0x6c, 0x3b, + 0x42, 0x62, 0xf5, 0xf7, 0x33, 0x89, 0xa0, 0x77, 0x7b, 0x92, 0xa3, 0x6c, 0x95, 0x65, 0x1f, 0xd0, + 0x8c, 0xf5, 0xfb, 0x22, 0xb7, 0xbb, 0xbe, 0x88, 0x7e, 0xcb, 0x3e, 0x58, 0xa6, 0x07, 0xf9, 0x2d, + 0xdf, 0xc9, 0xa6, 0x85, 0x00, 0x3c, 0x9c, 0x2a, 0x7e, 0x3d, 0x30, 0x4a, 0xf3, 0x3b, 0x49, 0xbc, + 0x2d, 0xcc, 0xd4, 0x4f, 0xc3, 0xb1, 0x58, 0x60, 0x3c, 0x91, 0xd3, 0xef, 0x62, 0xef, 0x08, 0x7b, + 0xdd, 0x9f, 0xe8, 0x47, 0xc8, 0xd4, 0x7f, 0x93, 0xe9, 0x1d, 0x16, 0xf1, 0xc0, 0x55, 0x27, 0x45, + 0x00, 0xb9, 0xbf, 0x1b, 0x01, 0xec, 0xc3, 0x36, 0xf8, 0x70, 0x0b, 0xe0, 0x7d, 0x32, 0x79, 0xbc, + 0xd7, 0x02, 0xf8, 0x85, 0xcc, 0xb6, 0x51, 0x2d, 0x0f, 0x5a, 0x06, 0xea, 0xff, 0x9f, 0x49, 0x8d, + 0x3e, 0xb9, 0xa7, 0x76, 0xbd, 0x02, 0x05, 0xee, 0x56, 0x23, 0x5a, 0x25, 0xe5, 0xeb, 0x60, 0xd0, + 0x2e, 0xe5, 0x45, 0x19, 0x32, 0x07, 0x03, 0xbc, 0x0d, 0x46, 0x3c, 0xaf, 0x6d, 0x4a, 0x3b, 0x8d, + 0x6e, 0x93, 0xa3, 0x40, 0xab, 0xbf, 0x97, 0x49, 0x04, 0xc3, 0x3c, 0xc0, 0x6f, 0x0b, 0xa7, 0xea, + 0xdc, 0xce, 0xa7, 0x6a, 0xf5, 0xcf, 0xb3, 0xe9, 0xb1, 0x38, 0x0f, 0xf0, 0x43, 0xf6, 0xe3, 0x38, + 0xed, 0xc1, 0xd6, 0xad, 0x65, 0x18, 0x8b, 0xca, 0x42, 0x2c, 0x5b, 0x17, 0xd2, 0x23, 0x92, 0x76, + 0x69, 0x45, 0x8c, 0x87, 0xfa, 0x6e, 0x26, 0x19, 0x46, 0xf4, 0xc0, 0xe7, 0xa7, 0x07, 0xd3, 0x96, + 0xe8, 0xa7, 0xbc, 0x4f, 0xd6, 0x9a, 0xfd, 0xf8, 0x94, 0xf7, 0xc9, 0xaa, 0xf1, 0x60, 0x9f, 0xf2, + 0x2b, 0xd9, 0x6e, 0x51, 0x58, 0x0f, 0xfc, 0x83, 0x3e, 0x2e, 0x0b, 0x99, 0xb7, 0x4c, 0x7c, 0xda, + 0xa3, 0xdd, 0xc2, 0x9e, 0x76, 0xe1, 0x99, 0xe0, 0xf3, 0x60, 0x63, 0x3c, 0x55, 0x58, 0xef, 0x13, + 0x45, 0x3e, 0x1c, 0xc2, 0x7a, 0x9f, 0x0c, 0x95, 0xf7, 0x9f, 0xb0, 0xfe, 0x87, 0xec, 0x4e, 0x43, + 0xff, 0x1e, 0x09, 0x2f, 0x21, 0xbc, 0xaf, 0x64, 0x93, 0x21, 0xa9, 0x0f, 0x5c, 0x4c, 0x33, 0x50, + 0x10, 0xc1, 0xb1, 0xbb, 0x0a, 0x87, 0xe3, 0xbb, 0x59, 0x34, 0xe2, 0x3b, 0xae, 0x83, 0xb8, 0xc8, + 0xd9, 0x99, 0x48, 0x38, 0xad, 0xfa, 0xd7, 0x99, 0x58, 0xfc, 0xe6, 0x03, 0x39, 0x42, 0x78, 0xa0, + 0x25, 0x89, 0xbc, 0xea, 0x1f, 0x66, 0xe6, 0x63, 0xf1, 0x33, 0x83, 0xef, 0x29, 0x53, 0x4f, 0x37, + 0x9b, 0xf1, 0xf2, 0x22, 0x26, 0xc0, 0x37, 0xb3, 0x30, 0x91, 0x20, 0x25, 0x17, 0x23, 0x51, 0x72, + 0xf0, 0x58, 0x32, 0xe6, 0x3c, 0xce, 0xe3, 0xe5, 0xec, 0xe2, 0x24, 0xf5, 0x22, 0xe4, 0xcb, 0xfa, + 0x06, 0xff, 0xb6, 0x7e, 0xce, 0xd2, 0xd0, 0x37, 0xe4, 0x13, 0x37, 0xc4, 0x93, 0x15, 0x38, 0xc9, + 0xef, 0x43, 0x4c, 0xdb, 0x5a, 0x36, 0x5b, 0xb4, 0x62, 0xcd, 0x9b, 0xcd, 0xa6, 0xe9, 0x8a, 0x4b, + 0xbd, 0xa7, 0xb6, 0x36, 0x8b, 0x97, 0x3c, 0xdb, 0xd3, 0x9b, 0x35, 0xea, 0x93, 0xd5, 0x3c, 0xb3, + 0x45, 0x6b, 0xa6, 0x55, 0x6b, 0x21, 0xa5, 0xc4, 0x32, 0x9d, 0x15, 0xa9, 0xf0, 0x50, 0xa9, 0xd5, + 0xba, 0x6e, 0x59, 0xd4, 0xa8, 0x58, 0x93, 0x1b, 0x1e, 0xe5, 0x97, 0x81, 0x39, 0x7e, 0x24, 0xc8, + 0xdf, 0x86, 0x73, 0x34, 0x63, 0xbc, 0xc2, 0x08, 0xb4, 0x94, 0x42, 0xea, 0xef, 0xe4, 0x53, 0x42, + 0x77, 0x1f, 0x22, 0xf5, 0xf1, 0x7b, 0x3a, 0xbf, 0x4d, 0x4f, 0x5f, 0x85, 0x81, 0xdb, 0xd4, 0xc1, + 0xf3, 0x2d, 0x7e, 0xc1, 0x80, 0xce, 0xec, 0xf7, 0x38, 0x48, 0xbe, 0xa1, 0x11, 0x54, 0xa4, 0x09, + 0x67, 0x97, 0x59, 0x37, 0xa5, 0x77, 0x66, 0xe1, 0x01, 0x3a, 0xb3, 0x07, 0x3f, 0xf2, 0x16, 0x9c, + 0x46, 0x6c, 0x4a, 0xb7, 0x0e, 0x60, 0x55, 0x18, 0x39, 0x8a, 0x57, 0x95, 0xde, 0xb9, 0xdd, 0xca, + 0x93, 0x8f, 0xc3, 0x48, 0x30, 0x40, 0x4c, 0xea, 0x8a, 0x9b, 0x8b, 0x1e, 0xe3, 0x8c, 0x87, 0x65, + 0x63, 0x60, 0x74, 0x21, 0x8b, 0x86, 0xf6, 0x8a, 0xf0, 0x52, 0xff, 0xbf, 0x4c, 0xaf, 0x10, 0xe2, + 0x07, 0x3e, 0x2b, 0xbf, 0x0a, 0x03, 0x06, 0xff, 0x28, 0xa1, 0x53, 0xbd, 0x83, 0x8c, 0x73, 0x52, + 0xcd, 0x2f, 0xa3, 0xfe, 0x59, 0xa6, 0x67, 0xe4, 0xf2, 0xc3, 0xfe, 0x79, 0x5f, 0xc9, 0x75, 0xf9, + 0x3c, 0x31, 0x89, 0x5e, 0x86, 0x71, 0xd3, 0xf2, 0x68, 0x83, 0x27, 0x25, 0xac, 0x85, 0xe1, 0xa7, + 0xb4, 0x63, 0x12, 0x1c, 0x47, 0xd7, 0x75, 0x38, 0xe5, 0x3b, 0x3e, 0x3a, 0xbe, 0x87, 0x98, 0x5b, + 0xeb, 0x38, 0x26, 0x1f, 0x97, 0xda, 0x09, 0x37, 0xe6, 0x3e, 0xe6, 0xde, 0x72, 0x4c, 0x56, 0x81, + 0xee, 0xad, 0x51, 0x4b, 0xaf, 0xad, 0xdb, 0xce, 0x5d, 0x8c, 0xfd, 0xc9, 0x07, 0xa7, 0x76, 0x8c, + 0xc3, 0xef, 0xf8, 0x60, 0xf2, 0x38, 0x8c, 0x36, 0x9a, 0x1d, 0x1a, 0x44, 0x5b, 0xe4, 0x77, 0x7d, + 0xda, 0x08, 0x03, 0x06, 0x37, 0x24, 0xe7, 0x01, 0x90, 0xc8, 0xc3, 0xb8, 0xf2, 0x78, 0xb1, 0xa7, + 0x0d, 0x31, 0xc8, 0xb2, 0xe8, 0xae, 0xb3, 0x5c, 0xab, 0xb9, 0x90, 0x6a, 0x4d, 0xdb, 0x6a, 0xd4, + 0x3c, 0xea, 0xb4, 0xb0, 0xa1, 0xe8, 0xcc, 0xa0, 0x9d, 0x42, 0x0a, 0xbc, 0x3a, 0x71, 0xe7, 0x6c, + 0xab, 0xb1, 0x4c, 0x9d, 0x16, 0x6b, 0xea, 0x53, 0x40, 0x44, 0x53, 0x1d, 0x3c, 0xf4, 0xe0, 0x1f, + 0x87, 0xde, 0x0c, 0x9a, 0xf8, 0x08, 0x7e, 0x1a, 0x82, 0x1f, 0x56, 0x84, 0x61, 0x1e, 0x72, 0x8e, + 0x0b, 0x0d, 0x5d, 0x18, 0x34, 0xe0, 0x20, 0x94, 0xd7, 0x29, 0x10, 0xde, 0x15, 0xdc, 0xab, 0x5b, + 0x13, 0xbf, 0xd4, 0x2f, 0xe6, 0xd2, 0x82, 0xad, 0xef, 0x49, 0xd1, 0xc2, 0x69, 0x35, 0xbb, 0xab, + 0x69, 0xf5, 0x98, 0xd5, 0x69, 0xd5, 0xf4, 0x76, 0xbb, 0xb6, 0x6a, 0x36, 0xf1, 0x59, 0x15, 0x2e, + 0x7c, 0xda, 0xa8, 0xd5, 0x69, 0x95, 0xda, 0xed, 0x19, 0x0e, 0x24, 0x4f, 0xc2, 0x04, 0xa3, 0xc3, + 0x4e, 0x0a, 0x28, 0xf3, 0x48, 0xc9, 0x18, 0x60, 0xcc, 0x56, 0x9f, 0xf6, 0x0c, 0x0c, 0x0a, 0x9e, + 0x7c, 0xad, 0xea, 0xd7, 0x06, 0x38, 0x33, 0x97, 0xf5, 0x5c, 0xc0, 0x86, 0x4f, 0xae, 0xfd, 0xda, + 0x90, 0x5f, 0x1e, 0x23, 0x13, 0x5b, 0x9d, 0x16, 0x8f, 0x88, 0x35, 0x80, 0xc8, 0xe0, 0x37, 0xb9, + 0x08, 0x63, 0x8c, 0x4b, 0x20, 0x30, 0x1e, 0xcc, 0xb5, 0x5f, 0x8b, 0x41, 0xc9, 0x35, 0x38, 0x11, + 0x81, 0x70, 0x1b, 0x94, 0x3f, 0x13, 0xe8, 0xd7, 0x52, 0x71, 0xea, 0x37, 0x72, 0xd1, 0x10, 0xf0, + 0x07, 0xd0, 0x11, 0xa7, 0x61, 0xc0, 0x76, 0x1a, 0xb5, 0x8e, 0xd3, 0x14, 0x63, 0xaf, 0x60, 0x3b, + 0x8d, 0x5b, 0x4e, 0x93, 0x9c, 0x84, 0x02, 0xeb, 0x1d, 0xd3, 0x10, 0x43, 0xac, 0x5f, 0x6f, 0xb7, + 0x2b, 0x06, 0x29, 0xf1, 0x0e, 0xc1, 0x40, 0xa0, 0xb5, 0x3a, 0x6e, 0xed, 0xb9, 0x53, 0x42, 0x3f, + 0x5f, 0xf1, 0x12, 0x48, 0xec, 0x27, 0x0c, 0x0f, 0xca, 0x0f, 0x02, 0x62, 0x2c, 0x0c, 0xdc, 0x96, + 0x18, 0xbc, 0x4f, 0xe2, 0x2c, 0x04, 0x32, 0x64, 0xc1, 0x37, 0x31, 0x06, 0x29, 0x03, 0x09, 0xa9, + 0x5a, 0xb6, 0x61, 0xae, 0x9a, 0x94, 0xbf, 0xea, 0xe8, 0xe7, 0x17, 0xbf, 0x49, 0xac, 0x36, 0xee, + 0x33, 0x99, 0x17, 0x10, 0xf2, 0x32, 0x57, 0x42, 0x4e, 0x87, 0x6b, 0x1f, 0xef, 0x5b, 0x6e, 0xa7, + 0xc5, 0x50, 0xa8, 0x99, 0x58, 0x1e, 0x17, 0x42, 0xf5, 0xdd, 0x5c, 0x32, 0x0f, 0xc0, 0x81, 0xd8, + 0x35, 0xb3, 0x00, 0x22, 0xcd, 0x47, 0x78, 0xb9, 0x16, 0x78, 0x9c, 0x87, 0x98, 0x2e, 0x3c, 0xa4, + 0xb2, 0xe4, 0x32, 0x0c, 0xf2, 0x2f, 0xaa, 0x94, 0x85, 0xbd, 0x83, 0x2e, 0x62, 0x6e, 0xdb, 0x5c, + 0x5d, 0x45, 0x7f, 0xb2, 0x00, 0x4d, 0x2e, 0xc2, 0x40, 0x79, 0xa1, 0x5a, 0x2d, 0x2d, 0xf8, 0x37, + 0xc5, 0xf8, 0xbe, 0xc4, 0xb0, 0xdc, 0x9a, 0xab, 0x5b, 0xae, 0xe6, 0x23, 0xc9, 0xe3, 0x50, 0xa8, + 0x2c, 0x21, 0x19, 0x7f, 0x35, 0x39, 0xbc, 0xb5, 0x59, 0x1c, 0x30, 0xdb, 0x9c, 0x4a, 0xa0, 0xb0, + 0xde, 0xdb, 0x95, 0xb2, 0xe4, 0x2e, 0xc1, 0xeb, 0xbd, 0x67, 0x1a, 0x78, 0xed, 0xac, 0x05, 0x68, + 0xf2, 0x1c, 0x8c, 0x54, 0xa9, 0x63, 0xea, 0xcd, 0x85, 0x0e, 0x6e, 0x15, 0xb9, 0x8b, 0xd8, 0xc4, + 0xd6, 0x66, 0x71, 0xd4, 0x45, 0x78, 0xcd, 0x42, 0x84, 0x16, 0x21, 0x23, 0xe7, 0x20, 0x3f, 0x6b, + 0x5a, 0xfe, 0x13, 0x06, 0xf4, 0x71, 0x5f, 0x33, 0x2d, 0x4f, 0x43, 0xa8, 0xfa, 0xcf, 0xb2, 0xe9, + 0xc9, 0x14, 0x0e, 0x60, 0x38, 0x3e, 0xe0, 0x4d, 0x6f, 0x4c, 0x09, 0xf2, 0x7b, 0x50, 0x82, 0x55, + 0x38, 0x56, 0x32, 0x5a, 0xa6, 0x55, 0xc2, 0x9f, 0xee, 0xfc, 0x4c, 0x09, 0x87, 0xb7, 0xf4, 0x84, + 0x2e, 0x86, 0x16, 0xdf, 0xc3, 0x43, 0xe5, 0x32, 0x54, 0x4d, 0xe7, 0xb8, 0x5a, 0x6b, 0x55, 0xaf, + 0xd5, 0x79, 0x1e, 0x02, 0x2d, 0xce, 0x54, 0xfd, 0x89, 0xec, 0x36, 0xf9, 0x1f, 0x1e, 0x46, 0xe9, + 0xab, 0x5f, 0xcd, 0xf6, 0x4e, 0xc1, 0xf1, 0x50, 0x0a, 0xe5, 0x2f, 0xb3, 0x29, 0x09, 0x31, 0xf6, + 0x24, 0x89, 0xcb, 0x30, 0xc8, 0xd9, 0x04, 0xae, 0xb6, 0x38, 0xe3, 0x70, 0x65, 0xc5, 0x99, 0xce, + 0x47, 0x93, 0x05, 0x38, 0x51, 0x5a, 0x5d, 0xa5, 0x75, 0x2f, 0x0c, 0x9a, 0xbc, 0x10, 0x06, 0x4a, + 0xe5, 0x91, 0x66, 0x05, 0x3e, 0x0c, 0xba, 0x8c, 0x01, 0x41, 0x52, 0xcb, 0x91, 0x65, 0x38, 0x15, + 0x87, 0x57, 0xb9, 0x99, 0x9e, 0x97, 0x82, 0xcf, 0x26, 0x38, 0xf2, 0xff, 0xb4, 0x2e, 0x65, 0xd3, + 0x5a, 0x89, 0xd3, 0x69, 0x7f, 0xaf, 0x56, 0xe2, 0xdc, 0x9a, 0x5a, 0x4e, 0xfd, 0x66, 0x4e, 0xce, + 0x1b, 0xf2, 0xf0, 0x3a, 0x45, 0x5d, 0x8f, 0xb8, 0x42, 0xef, 0x74, 0xc8, 0x3c, 0x27, 0xa2, 0x7c, + 0x18, 0x1d, 0xc7, 0xf7, 0x1a, 0x0c, 0xa2, 0x0c, 0x20, 0x50, 0xf6, 0xff, 0x0b, 0x28, 0x49, 0x05, + 0xf2, 0x25, 0xa7, 0xc1, 0x4d, 0xd0, 0xed, 0x1e, 0x3e, 0xe9, 0x4e, 0xc3, 0x4d, 0x7f, 0xf8, 0xc4, + 0x58, 0xa8, 0x3f, 0x9e, 0xed, 0x91, 0xea, 0xe3, 0x61, 0x9c, 0x44, 0x9e, 0x9c, 0xe7, 0x41, 0x8e, + 0x6f, 0x9a, 0x96, 0x41, 0xce, 0xc0, 0xc9, 0x5b, 0xd5, 0x69, 0xad, 0x76, 0xb3, 0xb2, 0x50, 0xae, + 0xdd, 0x5a, 0xa8, 0x2e, 0x4d, 0x4f, 0x55, 0x66, 0x2a, 0xd3, 0xe5, 0xf1, 0x3e, 0x72, 0x1c, 0x8e, + 0x85, 0xa8, 0xd9, 0x5b, 0xf3, 0xa5, 0x85, 0xf1, 0x0c, 0x99, 0x80, 0xd1, 0x10, 0x38, 0xb9, 0xb8, + 0x3c, 0x9e, 0x7d, 0xf2, 0x83, 0x30, 0x8c, 0xbb, 0x38, 0xbe, 0xa2, 0x91, 0x11, 0x18, 0x5c, 0x9c, + 0xac, 0x4e, 0x6b, 0xb7, 0x91, 0x09, 0x40, 0xa1, 0x3c, 0xbd, 0xc0, 0x18, 0x66, 0x9e, 0xfc, 0x97, + 0x19, 0x80, 0xea, 0xcc, 0xf2, 0x92, 0x20, 0x1c, 0x86, 0x81, 0xca, 0xc2, 0xed, 0xd2, 0x5c, 0x85, + 0xd1, 0x0d, 0x42, 0x7e, 0x71, 0x69, 0x9a, 0xd5, 0x30, 0x04, 0xfd, 0x53, 0x73, 0x8b, 0xd5, 0xe9, + 0xf1, 0x2c, 0x03, 0x6a, 0xd3, 0xa5, 0xf2, 0x78, 0x8e, 0x01, 0xef, 0x68, 0x95, 0xe5, 0xe9, 0xf1, + 0x3c, 0xfb, 0x73, 0xae, 0xba, 0x5c, 0x5a, 0x1e, 0xef, 0x67, 0x7f, 0xce, 0xe0, 0x9f, 0x05, 0xc6, + 0xac, 0x3a, 0xbd, 0x8c, 0x3f, 0x06, 0x58, 0x13, 0x66, 0xfc, 0x5f, 0x83, 0x0c, 0xc5, 0x58, 0x97, + 0x2b, 0xda, 0xf8, 0x10, 0xfb, 0xc1, 0x58, 0xb2, 0x1f, 0xc0, 0x1a, 0xa7, 0x4d, 0xcf, 0x2f, 0xde, + 0x9e, 0x1e, 0x1f, 0x66, 0xbc, 0xe6, 0x6f, 0x32, 0xf0, 0x08, 0xfb, 0x53, 0x9b, 0x67, 0x7f, 0x8e, + 0x32, 0x4e, 0xda, 0x74, 0x69, 0x6e, 0xa9, 0xb4, 0x3c, 0x3b, 0x3e, 0xc6, 0xda, 0x83, 0x3c, 0x8f, + 0xf1, 0x92, 0x0b, 0xa5, 0xf9, 0xe9, 0xf1, 0x71, 0x41, 0x53, 0x9e, 0xab, 0x2c, 0xdc, 0x1c, 0x9f, + 0xc0, 0x86, 0xbc, 0x35, 0x8f, 0x3f, 0x08, 0x2b, 0x80, 0x7f, 0x1d, 0x7f, 0xf2, 0x93, 0x50, 0x58, + 0xac, 0xa2, 0xdd, 0x76, 0x1a, 0x8e, 0x2f, 0x56, 0x6b, 0xcb, 0x6f, 0x2d, 0x4d, 0xc7, 0xe4, 0x3d, + 0x01, 0xa3, 0x3e, 0x62, 0xae, 0xb2, 0x70, 0xeb, 0x63, 0x5c, 0xda, 0x3e, 0x68, 0xbe, 0x34, 0xb5, + 0x58, 0x1d, 0xcf, 0xb2, 0x5e, 0xf1, 0x41, 0x77, 0x2a, 0x0b, 0xe5, 0xc5, 0x3b, 0xd5, 0xf1, 0xdc, + 0x93, 0xf7, 0xfc, 0x6c, 0xa4, 0x8b, 0x8e, 0xd9, 0x30, 0x2d, 0x72, 0x1e, 0xce, 0x94, 0xa7, 0x6f, + 0x57, 0xa6, 0xa6, 0x6b, 0x8b, 0x5a, 0xe5, 0x46, 0x65, 0x21, 0x56, 0xd3, 0x49, 0x98, 0x88, 0xa2, + 0x4b, 0x4b, 0x95, 0xf1, 0x0c, 0x39, 0x05, 0x24, 0x0a, 0x7e, 0xa3, 0x34, 0x3f, 0x33, 0x9e, 0x25, + 0x0a, 0x9c, 0x88, 0xc2, 0x2b, 0x0b, 0xcb, 0xb7, 0x16, 0xa6, 0xc7, 0x73, 0x4f, 0xfe, 0x52, 0x06, + 0x4e, 0xa6, 0x86, 0x11, 0x20, 0x2a, 0x5c, 0x98, 0x9e, 0x2b, 0x55, 0x97, 0x2b, 0x53, 0xd5, 0xe9, + 0x92, 0x36, 0x35, 0x5b, 0x9b, 0x2a, 0x2d, 0x4f, 0xdf, 0x58, 0xd4, 0xde, 0xaa, 0xdd, 0x98, 0x5e, + 0x98, 0xd6, 0x4a, 0x73, 0xe3, 0x7d, 0xe4, 0x71, 0x28, 0x76, 0xa1, 0xa9, 0x4e, 0x4f, 0xdd, 0xd2, + 0x2a, 0xcb, 0x6f, 0x8d, 0x67, 0xc8, 0x63, 0x70, 0xbe, 0x2b, 0x11, 0xfb, 0x3d, 0x9e, 0x25, 0x17, + 0xe0, 0x6c, 0x37, 0x92, 0x37, 0xe7, 0xc6, 0x73, 0x4f, 0xfe, 0x74, 0x06, 0x48, 0xf2, 0x1d, 0x38, + 0x79, 0x14, 0xce, 0x31, 0xbd, 0xa8, 0x75, 0x6f, 0xe0, 0x63, 0x70, 0x3e, 0x95, 0x42, 0x6a, 0x5e, + 0x11, 0x1e, 0xe9, 0x42, 0x22, 0x1a, 0x77, 0x0e, 0x94, 0x74, 0x02, 0x6c, 0xda, 0x6f, 0x66, 0xe0, + 0x64, 0xaa, 0x11, 0x49, 0x2e, 0xc1, 0x07, 0x4a, 0xe5, 0x79, 0xd6, 0x37, 0x53, 0xcb, 0x95, 0xc5, + 0x85, 0x6a, 0x6d, 0x7e, 0xa6, 0x54, 0x63, 0xda, 0x77, 0xab, 0x1a, 0xeb, 0xcd, 0x8b, 0xa0, 0xf6, + 0xa0, 0x9c, 0x9a, 0x2d, 0x2d, 0xdc, 0x60, 0xc3, 0x8f, 0x7c, 0x00, 0x1e, 0xed, 0x4a, 0x37, 0xbd, + 0x50, 0x9a, 0x9c, 0x9b, 0x2e, 0x8f, 0x67, 0xc9, 0x13, 0xf0, 0x58, 0x57, 0xaa, 0x72, 0xa5, 0xca, + 0xc9, 0x72, 0x93, 0xe5, 0x77, 0xff, 0xde, 0x85, 0xbe, 0x77, 0xbf, 0x7b, 0x21, 0xf3, 0x87, 0xdf, + 0xbd, 0x90, 0xf9, 0xf3, 0xef, 0x5e, 0xc8, 0x7c, 0xfc, 0xda, 0x6e, 0xde, 0xf7, 0xf3, 0x69, 0x6b, + 0xa5, 0x80, 0x13, 0xfa, 0xb3, 0xff, 0x36, 0x00, 0x00, 0xff, 0xff, 0xc2, 0xf0, 0xa8, 0xb4, 0x1f, + 0x56, 0x01, 0x00, } func (m *Metadata) Marshal() (dAtA []byte, err error) { @@ -28436,16 +28459,16 @@ func (m *OneOf_DiscoveryConfigDeleteAll) MarshalToSizedBuffer(dAtA []byte) (int, } return len(dAtA) - i, nil } -func (m *OneOf_IntegrationCreate) MarshalTo(dAtA []byte) (int, error) { +func (m *OneOf_AccessGraphSettingsUpdate) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *OneOf_IntegrationCreate) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *OneOf_AccessGraphSettingsUpdate) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) - if m.IntegrationCreate != nil { + if m.AccessGraphSettingsUpdate != nil { { - size, err := m.IntegrationCreate.MarshalToSizedBuffer(dAtA[:i]) + size, err := m.AccessGraphSettingsUpdate.MarshalToSizedBuffer(dAtA[:i]) if err != nil { return 0, err } @@ -28455,53 +28478,7 @@ func (m *OneOf_IntegrationCreate) MarshalToSizedBuffer(dAtA []byte) (int, error) i-- dAtA[i] = 0xa i-- - dAtA[i] = 0xaa - } - return len(dAtA) - i, nil -} -func (m *OneOf_IntegrationUpdate) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *OneOf_IntegrationUpdate) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - if m.IntegrationUpdate != nil { - { - size, err := m.IntegrationUpdate.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintEvents(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0xa - i-- - dAtA[i] = 0xb2 - } - return len(dAtA) - i, nil -} -func (m *OneOf_IntegrationDelete) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *OneOf_IntegrationDelete) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - if m.IntegrationDelete != nil { - { - size, err := m.IntegrationDelete.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintEvents(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0xa - i-- - dAtA[i] = 0xba + dAtA[i] = 0xa2 } return len(dAtA) - i, nil } @@ -28529,12 +28506,12 @@ func (m *StreamStatus) MarshalToSizedBuffer(dAtA []byte) (int, error) { i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } - n611, err611 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.LastUploadTime, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.LastUploadTime):]) - if err611 != nil { - return 0, err611 + n609, err609 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.LastUploadTime, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.LastUploadTime):]) + if err609 != nil { + return 0, err609 } - i -= n611 - i = encodeVarintEvents(dAtA, i, uint64(n611)) + i -= n609 + i = encodeVarintEvents(dAtA, i, uint64(n609)) i-- dAtA[i] = 0x1a if m.LastEventIndex != 0 { @@ -28684,12 +28661,12 @@ func (m *Identity) MarshalToSizedBuffer(dAtA []byte) (int, error) { dAtA[i] = 0xc2 } } - n615, err615 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.PreviousIdentityExpires, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.PreviousIdentityExpires):]) - if err615 != nil { - return 0, err615 + n613, err613 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.PreviousIdentityExpires, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.PreviousIdentityExpires):]) + if err613 != nil { + return 0, err613 } - i -= n615 - i = encodeVarintEvents(dAtA, i, uint64(n615)) + i -= n613 + i = encodeVarintEvents(dAtA, i, uint64(n613)) i-- dAtA[i] = 0x1 i-- @@ -28837,12 +28814,12 @@ func (m *Identity) MarshalToSizedBuffer(dAtA []byte) (int, error) { i-- dAtA[i] = 0x4a } - n619, err619 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Expires, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Expires):]) - if err619 != nil { - return 0, err619 + n617, err617 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Expires, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Expires):]) + if err617 != nil { + return 0, err617 } - i -= n619 - i = encodeVarintEvents(dAtA, i, uint64(n619)) + i -= n617 + i = encodeVarintEvents(dAtA, i, uint64(n617)) i-- dAtA[i] = 0x42 if len(m.KubernetesUsers) > 0 { @@ -33969,6 +33946,73 @@ func (m *SpannerRPC) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *AccessGraphSettingsUpdate) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *AccessGraphSettingsUpdate) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *AccessGraphSettingsUpdate) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.XXX_unrecognized != nil { + i -= len(m.XXX_unrecognized) + copy(dAtA[i:], m.XXX_unrecognized) + } + { + size, err := m.ConnectionMetadata.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintEvents(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x22 + { + size, err := m.UserMetadata.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintEvents(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + { + size, err := m.Status.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintEvents(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + { + size, err := m.Metadata.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintEvents(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + func encodeVarintEvents(dAtA []byte, offset int, v uint64) int { offset -= sovEvents(v) base := offset @@ -39635,38 +39679,14 @@ func (m *OneOf_DiscoveryConfigDeleteAll) Size() (n int) { } return n } -func (m *OneOf_IntegrationCreate) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if m.IntegrationCreate != nil { - l = m.IntegrationCreate.Size() - n += 2 + l + sovEvents(uint64(l)) - } - return n -} -func (m *OneOf_IntegrationUpdate) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if m.IntegrationUpdate != nil { - l = m.IntegrationUpdate.Size() - n += 2 + l + sovEvents(uint64(l)) - } - return n -} -func (m *OneOf_IntegrationDelete) Size() (n int) { +func (m *OneOf_AccessGraphSettingsUpdate) Size() (n int) { if m == nil { return 0 } var l int _ = l - if m.IntegrationDelete != nil { - l = m.IntegrationDelete.Size() + if m.AccessGraphSettingsUpdate != nil { + l = m.AccessGraphSettingsUpdate.Size() n += 2 + l + sovEvents(uint64(l)) } return n @@ -41690,6 +41710,26 @@ func (m *SpannerRPC) Size() (n int) { return n } +func (m *AccessGraphSettingsUpdate) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.Metadata.Size() + n += 1 + l + sovEvents(uint64(l)) + l = m.Status.Size() + n += 1 + l + sovEvents(uint64(l)) + l = m.UserMetadata.Size() + n += 1 + l + sovEvents(uint64(l)) + l = m.ConnectionMetadata.Size() + n += 1 + l + sovEvents(uint64(l)) + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + func sovEvents(x uint64) (n int) { return (math_bits.Len64(x|1) + 6) / 7 } @@ -78029,9 +78069,9 @@ func (m *OneOf) Unmarshal(dAtA []byte) error { } m.Event = &OneOf_DiscoveryConfigDeleteAll{v} iNdEx = postIndex - case 165: + case 164: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field IntegrationCreate", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field AccessGraphSettingsUpdate", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -78058,81 +78098,11 @@ func (m *OneOf) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - v := &IntegrationCreate{} + v := &AccessGraphSettingsUpdate{} if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } - m.Event = &OneOf_IntegrationCreate{v} - iNdEx = postIndex - case 166: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field IntegrationUpdate", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowEvents - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthEvents - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthEvents - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - v := &IntegrationUpdate{} - if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - m.Event = &OneOf_IntegrationUpdate{v} - iNdEx = postIndex - case 167: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field IntegrationDelete", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowEvents - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthEvents - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthEvents - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - v := &IntegrationDelete{} - if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - m.Event = &OneOf_IntegrationDelete{v} + m.Event = &OneOf_AccessGraphSettingsUpdate{v} iNdEx = postIndex default: iNdEx = preIndex @@ -94403,6 +94373,189 @@ func (m *SpannerRPC) Unmarshal(dAtA []byte) error { } return nil } +func (m *AccessGraphSettingsUpdate) 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 ErrIntOverflowEvents + } + 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: AccessGraphSettingsUpdate: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: AccessGraphSettingsUpdate: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + 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 ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthEvents + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Metadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Status", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthEvents + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Status.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field UserMetadata", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthEvents + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.UserMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ConnectionMetadata", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthEvents + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.ConnectionMetadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipEvents(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthEvents + } + 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 skipEvents(dAtA []byte) (n int, err error) { l := len(dAtA) iNdEx := 0 diff --git a/api/types/events/oneof.go b/api/types/events/oneof.go index a713feb1bf492..76c0f408c3437 100644 --- a/api/types/events/oneof.go +++ b/api/types/events/oneof.go @@ -652,6 +652,10 @@ func ToOneOf(in AuditEvent) (*OneOf, error) { out.Event = &OneOf_SessionRecordingConfigUpdate{ SessionRecordingConfigUpdate: e, } + case *AccessGraphSettingsUpdate: + out.Event = &OneOf_AccessGraphSettingsUpdate{ + AccessGraphSettingsUpdate: e, + } case *DatabaseUserCreate: out.Event = &OneOf_DatabaseUserCreate{ DatabaseUserCreate: e, diff --git a/lib/events/api.go b/lib/events/api.go index 9a700529da890..8ac05d415ddde 100644 --- a/lib/events/api.go +++ b/lib/events/api.go @@ -764,6 +764,8 @@ const ( ClusterNetworkingConfigUpdateEvent = "cluster_networking_config.update" // SessionRecordingConfigUpdateEvent is emitted when a user updates the cluster session recording configuration. SessionRecordingConfigUpdateEvent = "session_recording_config.update" + // AccessGraphSettingsUpdateEvent is emitted when a user updates the access graph settings configuration. + AccessGraphSettingsUpdateEvent = "access_graph_settings.update" // AccessGraphAccessPathChangedEvent is emitted when an access path is changed in the access graph // and an identity/resource is affected. diff --git a/lib/events/codes.go b/lib/events/codes.go index dd804ed38f749..50f0d56147a93 100644 --- a/lib/events/codes.go +++ b/lib/events/codes.go @@ -616,6 +616,8 @@ const ( ClusterNetworkingConfigUpdateCode = "TCNET002I" // SessionRecordingConfigUpdateCode is the session recording config updated event code. SessionRecordingConfigUpdateCode = "TCREC003I" + // AccessGraphSettingsUpdateCode is the access graph settings updated event code. + AccessGraphSettingsUpdateCode = "TCAGC003I" // AccessGraphAccessPathChangedCode is the access graph access path changed event code. AccessGraphAccessPathChangedCode = "TAG001I" diff --git a/lib/events/dynamic.go b/lib/events/dynamic.go index c23bf5527568f..bac9b583b46fc 100644 --- a/lib/events/dynamic.go +++ b/lib/events/dynamic.go @@ -378,6 +378,8 @@ func FromEventFields(fields EventFields) (events.AuditEvent, error) { e = &events.ClusterNetworkingConfigUpdate{} case SessionRecordingConfigUpdateEvent: e = &events.SessionRecordingConfigUpdate{} + case AccessGraphSettingsUpdateEvent: + e = &events.AccessGraphSettingsUpdate{} case DatabaseSessionSpannerRPCEvent: e = &events.SpannerRPC{} case UnknownEvent: From 58161ff990999414ddc80da05918565b2aa2e780 Mon Sep 17 00:00:00 2001 From: Tiago Silva Date: Wed, 17 Jul 2024 16:30:27 +0100 Subject: [PATCH 13/25] [sec_scan][11] add `AccessGraphSettings` backend service (#44014) This PR adds the backend service to be able to create, update and retrieve access graph configurations from Teleport backend. This PR is part of https://github.com/gravitational/access-graph/issues/637. --- .../clusterconfig/access_graph_settings.go | 79 ++++++++++++ .../access_graph_settings_test.go | 93 ++++++++++++++ api/types/constants.go | 7 + lib/auth/authclient/clt.go | 25 ++++ lib/services/access_graph_settings.go | 37 ++++++ lib/services/configuration.go | 12 ++ lib/services/local/configuration.go | 121 ++++++++++++++++-- lib/services/local/configuration_test.go | 12 ++ lib/services/suite/suite.go | 37 ++++++ 9 files changed, 410 insertions(+), 13 deletions(-) create mode 100644 api/types/clusterconfig/access_graph_settings.go create mode 100644 api/types/clusterconfig/access_graph_settings_test.go create mode 100644 lib/services/access_graph_settings.go diff --git a/api/types/clusterconfig/access_graph_settings.go b/api/types/clusterconfig/access_graph_settings.go new file mode 100644 index 0000000000000..87721a88939e3 --- /dev/null +++ b/api/types/clusterconfig/access_graph_settings.go @@ -0,0 +1,79 @@ +/* +Copyright 2024 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 clusterconfig + +import ( + "github.com/gravitational/trace" + + clusterconfigpb "github.com/gravitational/teleport/api/gen/proto/go/teleport/clusterconfig/v1" + headerv1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/header/v1" + "github.com/gravitational/teleport/api/types" +) + +// NewAccessGraphSettings creates a new AccessGraphSettings resource. +func NewAccessGraphSettings(spec *clusterconfigpb.AccessGraphSettingsSpec) (*clusterconfigpb.AccessGraphSettings, error) { + settings := &clusterconfigpb.AccessGraphSettings{ + Kind: types.KindAccessGraphSettings, + Version: types.V1, + Metadata: &headerv1.Metadata{ + Name: types.MetaNameAccessGraphSettings, + }, + Spec: spec, + } + if err := ValidateAccessGraphSettings(settings); err != nil { + return nil, trace.Wrap(err) + } + + return settings, nil + +} + +// ValidateAccessGraphSettings checks that required parameters are set +func ValidateAccessGraphSettings(s *clusterconfigpb.AccessGraphSettings) error { + if s == nil { + return trace.BadParameter("AccessGraphSettings is nil") + } + if s.Metadata == nil { + return trace.BadParameter("Metadata is nil") + } + if s.Spec == nil { + return trace.BadParameter("Spec is nil") + } + + if s.Metadata.Name == "" { + return trace.BadParameter("Name is unset") + } + + if s.Metadata.Name != types.MetaNameAccessGraphSettings { + return trace.BadParameter("Name is not %s", types.MetaNameAccessGraphSettings) + } + + if s.Kind != types.KindAccessGraphSettings { + return trace.BadParameter("Kind is not AccessGraphSettings") + } + if s.Version != types.V1 { + return trace.BadParameter("Version is not V1") + } + + switch s.Spec.GetSecretsScanConfig() { + case clusterconfigpb.AccessGraphSecretsScanConfig_ACCESS_GRAPH_SECRETS_SCAN_CONFIG_ENABLED, clusterconfigpb.AccessGraphSecretsScanConfig_ACCESS_GRAPH_SECRETS_SCAN_CONFIG_DISABLED: + default: + return trace.BadParameter("SecretsScanConfig is invalid") + } + + return nil +} diff --git a/api/types/clusterconfig/access_graph_settings_test.go b/api/types/clusterconfig/access_graph_settings_test.go new file mode 100644 index 0000000000000..82f7a4e6dc9d7 --- /dev/null +++ b/api/types/clusterconfig/access_graph_settings_test.go @@ -0,0 +1,93 @@ +/* +Copyright 2024 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 clusterconfig + +import ( + "testing" + + "github.com/google/go-cmp/cmp" + "github.com/stretchr/testify/require" + "google.golang.org/protobuf/testing/protocmp" + + clusterconfigpb "github.com/gravitational/teleport/api/gen/proto/go/teleport/clusterconfig/v1" + headerv1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/header/v1" + "github.com/gravitational/teleport/api/types" +) + +func TestNewAccessGraphSettings(t *testing.T) { + tests := []struct { + name string + spec *clusterconfigpb.AccessGraphSettingsSpec + want *clusterconfigpb.AccessGraphSettings + assertErr func(*testing.T, error, ...any) + }{ + { + name: "success disabled", + spec: &clusterconfigpb.AccessGraphSettingsSpec{ + SecretsScanConfig: clusterconfigpb.AccessGraphSecretsScanConfig_ACCESS_GRAPH_SECRETS_SCAN_CONFIG_DISABLED, + }, + assertErr: func(t *testing.T, err error, a ...any) { + require.NoError(t, err) + }, + want: &clusterconfigpb.AccessGraphSettings{ + Kind: types.KindAccessGraphSettings, + Version: types.V1, + Metadata: &headerv1.Metadata{ + Name: types.MetaNameAccessGraphSettings, + }, + Spec: &clusterconfigpb.AccessGraphSettingsSpec{ + SecretsScanConfig: clusterconfigpb.AccessGraphSecretsScanConfig_ACCESS_GRAPH_SECRETS_SCAN_CONFIG_DISABLED, + }, + }, + }, + { + name: "success enabled", + spec: &clusterconfigpb.AccessGraphSettingsSpec{ + SecretsScanConfig: clusterconfigpb.AccessGraphSecretsScanConfig_ACCESS_GRAPH_SECRETS_SCAN_CONFIG_ENABLED, + }, + assertErr: func(t *testing.T, err error, a ...any) { + require.NoError(t, err) + }, + want: &clusterconfigpb.AccessGraphSettings{ + Kind: types.KindAccessGraphSettings, + Version: types.V1, + Metadata: &headerv1.Metadata{ + Name: types.MetaNameAccessGraphSettings, + }, + Spec: &clusterconfigpb.AccessGraphSettingsSpec{ + SecretsScanConfig: clusterconfigpb.AccessGraphSecretsScanConfig_ACCESS_GRAPH_SECRETS_SCAN_CONFIG_ENABLED, + }, + }, + }, + { + name: "invalid", + spec: &clusterconfigpb.AccessGraphSettingsSpec{ + SecretsScanConfig: 10, + }, + assertErr: func(t *testing.T, err error, a ...any) { + require.ErrorContains(t, err, "SecretsScanConfig is invalid") + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := NewAccessGraphSettings(tt.spec) + tt.assertErr(t, err) + require.Empty(t, cmp.Diff(got, tt.want, protocmp.Transform())) + }) + } +} diff --git a/api/types/constants.go b/api/types/constants.go index 3a0eff165449c..4554879289890 100644 --- a/api/types/constants.go +++ b/api/types/constants.go @@ -530,6 +530,13 @@ const ( // KindVnetConfig is a resource which holds cluster-wide configuration for VNet. KindVnetConfig = "vnet_config" + // KindAccessGraphSettings is a resource which holds cluster-wide configuration for dynamic access graph settings. + KindAccessGraphSettings = "access_graph_settings" + + // MetaNameAccessGraphSettings is the exact name of the singleton resource holding + // access graph settings. + MetaNameAccessGraphSettings = "access-graph-settings" + // V7 is the seventh version of resources. V7 = "v7" diff --git a/lib/auth/authclient/clt.go b/lib/auth/authclient/clt.go index d3faeac1b1ac7..6604e7c93e660 100644 --- a/lib/auth/authclient/clt.go +++ b/lib/auth/authclient/clt.go @@ -789,6 +789,31 @@ func (c *Client) UpsertUserNotification(ctx context.Context, notification *notif return nil, trace.NotImplemented(notImplementedMessage) } +// GetAccessGraphSettings gets the access graph settings from the backend. +func (c *Client) GetAccessGraphSettings(context.Context) (*clusterconfigpb.AccessGraphSettings, error) { + return nil, trace.NotImplemented(notImplementedMessage) +} + +// CreateAccessGraphSettings creates the access graph settings in the backend. +func (c *Client) CreateAccessGraphSettings(context.Context, *clusterconfigpb.AccessGraphSettings) (*clusterconfigpb.AccessGraphSettings, error) { + return nil, trace.NotImplemented(notImplementedMessage) +} + +// UpdateAccessGraphSettings updates the access graph settings in the backend. +func (c *Client) UpdateAccessGraphSettings(context.Context, *clusterconfigpb.AccessGraphSettings) (*clusterconfigpb.AccessGraphSettings, error) { + return nil, trace.NotImplemented(notImplementedMessage) +} + +// UpsertAccessGraphSettings creates or updates the access graph settings in the backend. +func (c *Client) UpsertAccessGraphSettings(context.Context, *clusterconfigpb.AccessGraphSettings) (*clusterconfigpb.AccessGraphSettings, error) { + return nil, trace.NotImplemented(notImplementedMessage) +} + +// DeleteAccessGraphSettings deletes the access graph settings from the backend. +func (c *Client) DeleteAccessGraphSettings(context.Context) error { + return trace.NotImplemented(notImplementedMessage) +} + type WebSessionReq struct { // User is the user name associated with the session id. User string `json:"user"` diff --git a/lib/services/access_graph_settings.go b/lib/services/access_graph_settings.go new file mode 100644 index 0000000000000..9454b60b4847e --- /dev/null +++ b/lib/services/access_graph_settings.go @@ -0,0 +1,37 @@ +/* + * Teleport + * Copyright (C) 2024 Gravitational, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package services + +import ( + "github.com/gravitational/trace" + + clusterconfigpb "github.com/gravitational/teleport/api/gen/proto/go/teleport/clusterconfig/v1" +) + +// UnmarshalAccessGraphSettings unmarshals the AccessGraphSettings resource from JSON. +func UnmarshalAccessGraphSettings(data []byte, opts ...MarshalOption) (*clusterconfigpb.AccessGraphSettings, error) { + out, err := UnmarshalProtoResource[*clusterconfigpb.AccessGraphSettings](data, opts...) + return out, trace.Wrap(err) +} + +// MarshalAccessGraphSettings marshals the AccessGraphSettings resource to JSON. +func MarshalAccessGraphSettings(c *clusterconfigpb.AccessGraphSettings, opts ...MarshalOption) ([]byte, error) { + bytes, err := MarshalProtoResource(c, opts...) + return bytes, trace.Wrap(err) +} diff --git a/lib/services/configuration.go b/lib/services/configuration.go index 0ffd95f9a9672..55477eaae9906 100644 --- a/lib/services/configuration.go +++ b/lib/services/configuration.go @@ -21,6 +21,7 @@ package services import ( "context" + clusterconfigpb "github.com/gravitational/teleport/api/gen/proto/go/teleport/clusterconfig/v1" "github.com/gravitational/teleport/api/types" ) @@ -115,4 +116,15 @@ type ClusterConfiguration interface { UpdateClusterMaintenanceConfig(ctx context.Context, cfg types.ClusterMaintenanceConfig) error // DeleteClusterMaintenanceConfig deletes the maintenance config singleton. DeleteClusterMaintenanceConfig(ctx context.Context) error + + // GetAccessGraphSettings gets the access graph settings from the backend. + GetAccessGraphSettings(context.Context) (*clusterconfigpb.AccessGraphSettings, error) + // CreateAccessGraphSettings creates the access graph settings in the backend. + CreateAccessGraphSettings(context.Context, *clusterconfigpb.AccessGraphSettings) (*clusterconfigpb.AccessGraphSettings, error) + // UpdateAccessGraphSettings updates the access graph settings in the backend. + UpdateAccessGraphSettings(context.Context, *clusterconfigpb.AccessGraphSettings) (*clusterconfigpb.AccessGraphSettings, error) + // UpsertAccessGraphSettings creates or updates the access graph settings in the backend. + UpsertAccessGraphSettings(context.Context, *clusterconfigpb.AccessGraphSettings) (*clusterconfigpb.AccessGraphSettings, error) + // DeleteAccessGraphSettings deletes the access graph settings from the backend. + DeleteAccessGraphSettings(context.Context) error } diff --git a/lib/services/local/configuration.go b/lib/services/local/configuration.go index fc2d6e2759279..38865478326cc 100644 --- a/lib/services/local/configuration.go +++ b/lib/services/local/configuration.go @@ -26,6 +26,7 @@ import ( "github.com/prometheus/client_golang/prometheus" "github.com/gravitational/teleport" + clusterconfigpb "github.com/gravitational/teleport/api/gen/proto/go/teleport/clusterconfig/v1" "github.com/gravitational/teleport/api/types" "github.com/gravitational/teleport/lib/backend" "github.com/gravitational/teleport/lib/modules" @@ -721,18 +722,112 @@ func (s *ClusterConfigurationService) DeleteClusterMaintenanceConfig(ctx context return nil } +// GetAccessGraphSettings fetches the cluster *clusterconfigpb.AccessGraphSettings from the backend and return them. +func (s *ClusterConfigurationService) GetAccessGraphSettings(ctx context.Context) (*clusterconfigpb.AccessGraphSettings, error) { + item, err := s.Get(ctx, backend.Key(clusterConfigPrefix, accessGraphSettingsPrefix)) + if err != nil { + if trace.IsNotFound(err) { + return nil, trace.NotFound("AccessGraphSettings preference not found") + } + return nil, trace.Wrap(err) + } + return services.UnmarshalAccessGraphSettings(item.Value, + services.WithExpires(item.Expires), services.WithRevision(item.Revision)) +} + +// CreateAccessGraphSettings creates an *clusterconfigpb.AccessGraphSettings if it does not already exist. +func (s *ClusterConfigurationService) CreateAccessGraphSettings(ctx context.Context, set *clusterconfigpb.AccessGraphSettings) (*clusterconfigpb.AccessGraphSettings, error) { + value, err := services.MarshalAccessGraphSettings(set) + if err != nil { + return nil, trace.Wrap(err) + } + + item := backend.Item{ + Key: backend.Key(clusterConfigPrefix, accessGraphSettingsPrefix), + Value: value, + } + + lease, err := s.Backend.Create(ctx, item) + if err != nil { + return nil, trace.Wrap(err) + } + + set.Metadata.Revision = lease.Revision + return set, nil +} + +// UpdateAccessGraphSettings updates an existing *clusterconfigpb.AccessGraphSettings. +func (s *ClusterConfigurationService) UpdateAccessGraphSettings(ctx context.Context, set *clusterconfigpb.AccessGraphSettings) (*clusterconfigpb.AccessGraphSettings, error) { + rev := set.GetMetadata().GetRevision() + + value, err := services.MarshalAccessGraphSettings(set) + if err != nil { + return nil, trace.Wrap(err) + } + + item := backend.Item{ + Key: backend.Key(clusterConfigPrefix, accessGraphSettingsPrefix), + Value: value, + Revision: rev, + } + + lease, err := s.ConditionalUpdate(ctx, item) + if err != nil { + return nil, trace.Wrap(err) + } + + set.Metadata.Revision = lease.Revision + return set, nil +} + +// UpsertAccessGraphSettings creates or overwrites an *clusterconfigpb.AccessGraphSettings. +func (s *ClusterConfigurationService) UpsertAccessGraphSettings(ctx context.Context, set *clusterconfigpb.AccessGraphSettings) (*clusterconfigpb.AccessGraphSettings, error) { + rev := set.GetMetadata().GetRevision() + value, err := services.MarshalAccessGraphSettings(set) + if err != nil { + return nil, trace.Wrap(err) + } + + item := backend.Item{ + Key: backend.Key(clusterConfigPrefix, accessGraphSettingsPrefix), + Value: value, + Revision: rev, + } + + lease, err := s.Put(ctx, item) + if err != nil { + return nil, trace.Wrap(err) + } + + set.Metadata.Revision = lease.Revision + return set, nil +} + +// DeleteAccessGraphSettings deletes *clusterconfigpb.AccessGraphSettings from the backend. +func (s *ClusterConfigurationService) DeleteAccessGraphSettings(ctx context.Context) error { + err := s.Delete(ctx, backend.Key(clusterConfigPrefix, accessGraphSettingsPrefix)) + if err != nil { + if trace.IsNotFound(err) { + return trace.NotFound("access graph settings not found") + } + return trace.Wrap(err) + } + return nil +} + const ( - clusterConfigPrefix = "cluster_configuration" - namePrefix = "name" - staticTokensPrefix = "static_tokens" - authPrefix = "authentication" - preferencePrefix = "preference" - generalPrefix = "general" - auditPrefix = "audit" - networkingPrefix = "networking" - sessionRecordingPrefix = "session_recording" - scriptsPrefix = "scripts" - uiPrefix = "ui" - installerPrefix = "installer" - maintenancePrefix = "maintenance" + clusterConfigPrefix = "cluster_configuration" + namePrefix = "name" + staticTokensPrefix = "static_tokens" + authPrefix = "authentication" + preferencePrefix = "preference" + generalPrefix = "general" + auditPrefix = "audit" + networkingPrefix = "networking" + sessionRecordingPrefix = "session_recording" + scriptsPrefix = "scripts" + uiPrefix = "ui" + installerPrefix = "installer" + maintenancePrefix = "maintenance" + accessGraphSettingsPrefix = "access_graph_settings" ) diff --git a/lib/services/local/configuration_test.go b/lib/services/local/configuration_test.go index fd1f60a402619..22adc28b16977 100644 --- a/lib/services/local/configuration_test.go +++ b/lib/services/local/configuration_test.go @@ -70,6 +70,18 @@ func TestAuthPreference(t *testing.T) { suite.AuthPreference(t) } +func TestAccessGraphSettings(t *testing.T) { + tt := setupConfigContext(context.Background(), t) + + clusterConfig, err := NewClusterConfigurationService(tt.bk) + require.NoError(t, err) + + suite := &suite.ServicesTestSuite{ + ConfigS: clusterConfig, + } + suite.AccessGraphSettings(t) +} + func TestClusterName(t *testing.T) { tt := setupConfigContext(context.Background(), t) diff --git a/lib/services/suite/suite.go b/lib/services/suite/suite.go index b41022f409801..0a36b1a17b712 100644 --- a/lib/services/suite/suite.go +++ b/lib/services/suite/suite.go @@ -38,11 +38,15 @@ import ( "github.com/stretchr/testify/require" "golang.org/x/crypto/bcrypt" "golang.org/x/crypto/ssh" + protobuf "google.golang.org/protobuf/proto" + "google.golang.org/protobuf/testing/protocmp" "github.com/gravitational/teleport" "github.com/gravitational/teleport/api/constants" apidefaults "github.com/gravitational/teleport/api/defaults" + clusterconfigpb "github.com/gravitational/teleport/api/gen/proto/go/teleport/clusterconfig/v1" "github.com/gravitational/teleport/api/types" + "github.com/gravitational/teleport/api/types/clusterconfig" "github.com/gravitational/teleport/api/utils" "github.com/gravitational/teleport/lib/auth/testauthority" "github.com/gravitational/teleport/lib/backend" @@ -1202,6 +1206,39 @@ func (s *ServicesTestSuite) AuthPreference(t *testing.T) { require.Empty(t, cmp.Diff(upserted, gotAP), cmpopts.IgnoreFields(types.Metadata{}, "Revision")) } +// AccessGraphSettings tests access graph settings service +func (s *ServicesTestSuite) AccessGraphSettings(t *testing.T) { + ctx := context.Background() + ap, err := clusterconfig.NewAccessGraphSettings( + &clusterconfigpb.AccessGraphSettingsSpec{ + SecretsScanConfig: clusterconfigpb.AccessGraphSecretsScanConfig_ACCESS_GRAPH_SECRETS_SCAN_CONFIG_DISABLED, + }, + ) + require.NoError(t, err) + + created, err := s.ConfigS.CreateAccessGraphSettings(ctx, ap) + require.NoError(t, err) + require.NotEmpty(t, created.GetMetadata().GetRevision()) + + // Validate the created preference matches the retrieve preference. + got, err := s.ConfigS.GetAccessGraphSettings(ctx) + require.NoError(t, err) + require.Empty(t, cmp.Diff(ap, got, protocmp.Transform())) + + // Validate that update only works if the revision matches. + got.Metadata.Revision = "123" + _, err = s.ConfigS.UpdateAccessGraphSettings(ctx, got) + require.True(t, trace.IsCompareFailed(err)) + + // Validate that upserting overwrites the value regardless of the revision. + upserted, err := s.ConfigS.UpsertAccessGraphSettings(ctx, protobuf.Clone(got).(*clusterconfigpb.AccessGraphSettings)) + require.NoError(t, err) + require.NotEmpty(t, upserted.GetMetadata().GetRevision()) + upserted.Metadata.Revision = "" + got.Metadata.Revision = "" + require.Empty(t, cmp.Diff(upserted, got, protocmp.Transform())) +} + // SessionRecordingConfig tests session recording configuration. func (s *ServicesTestSuite) SessionRecordingConfig(t *testing.T) { ctx := context.Background() From b2662604576fcd5a96bfc611b2dd703736f94269 Mon Sep 17 00:00:00 2001 From: Tiago Silva Date: Wed, 17 Jul 2024 19:53:58 +0100 Subject: [PATCH 14/25] [sec_scan][12] add cache and events support for `AccessGraphSettings` (#44016) * [sec_scan][12] add cache and events support for `AccessGraphSettings` This PR adds the cache and events support for the new resource `AccessGraphSettings`. This PR is part of https://github.com/gravitational/access-graph/issues/637. Signed-off-by: Tiago Silva * add tests --------- Signed-off-by: Tiago Silva --- api/client/events.go | 8 + api/client/proto/event.pb.go | 583 +++++++++--------- .../teleport/legacy/client/proto/event.proto | 3 + lib/auth/authclient/api.go | 4 + .../clusterconfig/clusterconfigv1/service.go | 2 + lib/authz/permissions.go | 12 +- lib/cache/cache.go | 28 + lib/cache/cache_test.go | 13 + lib/cache/collections.go | 50 ++ lib/services/local/events.go | 36 ++ lib/services/readonly/cache.go | 15 + lib/services/readonly/readonly.go | 32 + lib/services/readonly/readonly_test.go | 46 +- 13 files changed, 551 insertions(+), 281 deletions(-) diff --git a/api/client/events.go b/api/client/events.go index 99a75f72f354b..33afdff4c526e 100644 --- a/api/client/events.go +++ b/api/client/events.go @@ -19,6 +19,7 @@ import ( "github.com/gravitational/teleport/api/client/proto" accessmonitoringrulesv1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/accessmonitoringrules/v1" + clusterconfigpb "github.com/gravitational/teleport/api/gen/proto/go/teleport/clusterconfig/v1" crownjewelv1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/crownjewel/v1" dbobjectv1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/dbobject/v1" kubewaitingcontainerpb "github.com/gravitational/teleport/api/gen/proto/go/teleport/kubewaitingcontainer/v1" @@ -80,6 +81,10 @@ func EventToGRPC(in types.Event) (*proto.Event, error) { out.Resource = &proto.Event_DatabaseObject{ DatabaseObject: r, } + case *clusterconfigpb.AccessGraphSettings: + out.Resource = &proto.Event_AccessGraphSettings{ + AccessGraphSettings: r, + } default: return nil, trace.BadParameter("resource type %T is not supported", r) } @@ -511,6 +516,9 @@ func EventFromGRPC(in *proto.Event) (*types.Event, error) { } else if r := in.GetDatabaseObject(); r != nil { out.Resource = types.Resource153ToLegacy(r) return &out, nil + } else if r := in.GetAccessGraphSettings(); r != nil { + out.Resource = types.Resource153ToLegacy(r) + return &out, nil } else { return nil, trace.BadParameter("received unsupported resource %T", in.Resource) } diff --git a/api/client/proto/event.pb.go b/api/client/proto/event.pb.go index d32153e584f57..7276f2ec076c3 100644 --- a/api/client/proto/event.pb.go +++ b/api/client/proto/event.pb.go @@ -23,6 +23,7 @@ package proto import ( v1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/accesslist/v1" v14 "github.com/gravitational/teleport/api/gen/proto/go/teleport/accessmonitoringrules/v1" + v19 "github.com/gravitational/teleport/api/gen/proto/go/teleport/clusterconfig/v1" v17 "github.com/gravitational/teleport/api/gen/proto/go/teleport/crownjewel/v1" v18 "github.com/gravitational/teleport/api/gen/proto/go/teleport/dbobject/v1" v12 "github.com/gravitational/teleport/api/gen/proto/go/teleport/discoveryconfig/v1" @@ -166,6 +167,7 @@ type Event struct { // *Event_GlobalNotification // *Event_CrownJewel // *Event_DatabaseObject + // *Event_AccessGraphSettings Resource isEvent_Resource `protobuf_oneof:"Resource"` } @@ -607,6 +609,13 @@ func (x *Event) GetDatabaseObject() *v18.DatabaseObject { return nil } +func (x *Event) GetAccessGraphSettings() *v19.AccessGraphSettings { + if x, ok := x.GetResource().(*Event_AccessGraphSettings); ok { + return x.AccessGraphSettings + } + return nil +} + type isEvent_Resource interface { isEvent_Resource() } @@ -894,6 +903,11 @@ type Event_DatabaseObject struct { DatabaseObject *v18.DatabaseObject `protobuf:"bytes,59,opt,name=DatabaseObject,proto3,oneof"` } +type Event_AccessGraphSettings struct { + // AccessGraphSettings is a resource for access graph settings. + AccessGraphSettings *v19.AccessGraphSettings `protobuf:"bytes,61,opt,name=AccessGraphSettings,proto3,oneof"` +} + func (*Event_ResourceHeader) isEvent_Resource() {} func (*Event_CertAuthority) isEvent_Resource() {} @@ -1006,6 +1020,8 @@ func (*Event_CrownJewel) isEvent_Resource() {} func (*Event_DatabaseObject) isEvent_Resource() {} +func (*Event_AccessGraphSettings) isEvent_Resource() {} + var File_teleport_legacy_client_proto_event_proto protoreflect.FileDescriptor var file_teleport_legacy_client_proto_event_proto_rawDesc = []byte{ @@ -1018,281 +1034,291 @@ var file_teleport_legacy_client_proto_event_proto_rawDesc = []byte{ 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x2f, 0x76, 0x31, 0x2f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x5f, - 0x72, 0x75, 0x6c, 0x65, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x27, 0x74, 0x65, 0x6c, - 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x63, 0x72, 0x6f, 0x77, 0x6e, 0x6a, 0x65, 0x77, 0x65, 0x6c, - 0x2f, 0x76, 0x31, 0x2f, 0x63, 0x72, 0x6f, 0x77, 0x6e, 0x6a, 0x65, 0x77, 0x65, 0x6c, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x23, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x64, - 0x62, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2f, 0x76, 0x31, 0x2f, 0x64, 0x62, 0x6f, 0x62, 0x6a, - 0x65, 0x63, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x31, 0x74, 0x65, 0x6c, 0x65, 0x70, - 0x6f, 0x72, 0x74, 0x2f, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0x63, 0x6f, 0x6e, - 0x66, 0x69, 0x67, 0x2f, 0x76, 0x31, 0x2f, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, - 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x3b, 0x74, 0x65, - 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x6b, 0x75, 0x62, 0x65, 0x77, 0x61, 0x69, 0x74, 0x69, - 0x6e, 0x67, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x2f, 0x76, 0x31, 0x2f, 0x6b, - 0x75, 0x62, 0x65, 0x77, 0x61, 0x69, 0x74, 0x69, 0x6e, 0x67, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, - 0x6e, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x21, 0x74, 0x65, 0x6c, 0x65, 0x70, - 0x6f, 0x72, 0x74, 0x2f, 0x6c, 0x65, 0x67, 0x61, 0x63, 0x79, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x73, - 0x2f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x2d, 0x74, 0x65, - 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x76, 0x31, 0x2f, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x27, 0x74, 0x65, 0x6c, - 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x73, 0x65, 0x63, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, - 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x65, 0x63, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x2f, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x75, - 0x73, 0x65, 0x72, 0x6c, 0x6f, 0x67, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2f, 0x76, 0x31, - 0x2f, 0x75, 0x73, 0x65, 0x72, 0x6c, 0x6f, 0x67, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xc6, 0x1e, 0x0a, 0x05, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, - 0x24, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x10, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, - 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x3f, 0x0a, 0x0e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, - 0x65, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, - 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x48, 0x65, - 0x61, 0x64, 0x65, 0x72, 0x48, 0x00, 0x52, 0x0e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, - 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x12, 0x3e, 0x0a, 0x0d, 0x43, 0x65, 0x72, 0x74, 0x41, 0x75, - 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, - 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x43, 0x65, 0x72, 0x74, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, - 0x69, 0x74, 0x79, 0x56, 0x32, 0x48, 0x00, 0x52, 0x0d, 0x43, 0x65, 0x72, 0x74, 0x41, 0x75, 0x74, - 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x12, 0x3b, 0x0a, 0x0c, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, - 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, - 0x79, 0x70, 0x65, 0x73, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x54, 0x6f, 0x6b, 0x65, 0x6e, - 0x73, 0x56, 0x32, 0x48, 0x00, 0x52, 0x0c, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x54, 0x6f, 0x6b, - 0x65, 0x6e, 0x73, 0x12, 0x41, 0x0a, 0x0e, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, - 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x79, - 0x70, 0x65, 0x73, 0x2e, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x54, 0x6f, 0x6b, - 0x65, 0x6e, 0x56, 0x32, 0x48, 0x00, 0x52, 0x0e, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, - 0x6e, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x38, 0x0a, 0x0b, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, - 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x74, 0x79, - 0x70, 0x65, 0x73, 0x2e, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x56, - 0x32, 0x48, 0x00, 0x52, 0x0b, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, - 0x12, 0x23, 0x0a, 0x04, 0x55, 0x73, 0x65, 0x72, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, - 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x56, 0x32, 0x48, 0x00, 0x52, - 0x04, 0x55, 0x73, 0x65, 0x72, 0x12, 0x23, 0x0a, 0x04, 0x52, 0x6f, 0x6c, 0x65, 0x18, 0x09, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x52, 0x6f, 0x6c, 0x65, - 0x56, 0x36, 0x48, 0x00, 0x52, 0x04, 0x52, 0x6f, 0x6c, 0x65, 0x12, 0x30, 0x0a, 0x09, 0x4e, 0x61, - 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, - 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x48, - 0x00, 0x52, 0x09, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x29, 0x0a, 0x06, - 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x74, - 0x79, 0x70, 0x65, 0x73, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x56, 0x32, 0x48, 0x00, 0x52, - 0x06, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x12, 0x3e, 0x0a, 0x0d, 0x52, 0x65, 0x76, 0x65, 0x72, - 0x73, 0x65, 0x54, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, - 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x52, 0x65, 0x76, 0x65, 0x72, 0x73, 0x65, 0x54, 0x75, - 0x6e, 0x6e, 0x65, 0x6c, 0x56, 0x32, 0x48, 0x00, 0x52, 0x0d, 0x52, 0x65, 0x76, 0x65, 0x72, 0x73, - 0x65, 0x54, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x12, 0x47, 0x0a, 0x10, 0x54, 0x75, 0x6e, 0x6e, 0x65, - 0x6c, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x0d, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x19, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x54, 0x75, 0x6e, 0x6e, 0x65, 0x6c, - 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x56, 0x32, 0x48, 0x00, 0x52, 0x10, - 0x54, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, - 0x12, 0x3e, 0x0a, 0x0d, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, - 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x56, 0x33, 0x48, - 0x00, 0x52, 0x0d, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x12, 0x35, 0x0a, 0x0a, 0x41, 0x70, 0x70, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x0f, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x57, 0x65, 0x62, - 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x56, 0x32, 0x48, 0x00, 0x52, 0x0a, 0x41, 0x70, 0x70, - 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x3e, 0x0a, 0x0d, 0x52, 0x65, 0x6d, 0x6f, 0x74, - 0x65, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x18, 0x10, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, - 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x43, 0x6c, 0x75, - 0x73, 0x74, 0x65, 0x72, 0x56, 0x33, 0x48, 0x00, 0x52, 0x0d, 0x52, 0x65, 0x6d, 0x6f, 0x74, 0x65, - 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x12, 0x41, 0x0a, 0x0e, 0x44, 0x61, 0x74, 0x61, 0x62, - 0x61, 0x73, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x18, 0x11, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x17, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, - 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x56, 0x33, 0x48, 0x00, 0x52, 0x0e, 0x44, 0x61, 0x74, 0x61, - 0x62, 0x61, 0x73, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x12, 0x35, 0x0a, 0x0a, 0x57, 0x65, - 0x62, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x12, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, - 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x57, 0x65, 0x62, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, - 0x6e, 0x56, 0x32, 0x48, 0x00, 0x52, 0x0a, 0x57, 0x65, 0x62, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, - 0x6e, 0x12, 0x2f, 0x0a, 0x08, 0x57, 0x65, 0x62, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x13, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x57, 0x65, 0x62, 0x54, - 0x6f, 0x6b, 0x65, 0x6e, 0x56, 0x33, 0x48, 0x00, 0x52, 0x08, 0x57, 0x65, 0x62, 0x54, 0x6f, 0x6b, - 0x65, 0x6e, 0x12, 0x5c, 0x0a, 0x17, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x4e, 0x65, 0x74, - 0x77, 0x6f, 0x72, 0x6b, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x14, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x43, 0x6c, 0x75, 0x73, - 0x74, 0x65, 0x72, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, - 0x66, 0x69, 0x67, 0x56, 0x32, 0x48, 0x00, 0x52, 0x17, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, - 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, - 0x12, 0x59, 0x0a, 0x16, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x63, 0x6f, 0x72, - 0x64, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x15, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x1f, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, - 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x56, - 0x32, 0x48, 0x00, 0x52, 0x16, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x63, 0x6f, - 0x72, 0x64, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x41, 0x0a, 0x0e, 0x41, - 0x75, 0x74, 0x68, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x16, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x41, 0x75, 0x74, 0x68, - 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x56, 0x32, 0x48, 0x00, 0x52, 0x0e, - 0x41, 0x75, 0x74, 0x68, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x4d, - 0x0a, 0x12, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x41, 0x75, 0x64, 0x69, 0x74, 0x43, 0x6f, - 0x6e, 0x66, 0x69, 0x67, 0x18, 0x17, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x74, 0x79, 0x70, - 0x65, 0x73, 0x2e, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x41, 0x75, 0x64, 0x69, 0x74, 0x43, - 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x56, 0x32, 0x48, 0x00, 0x52, 0x12, 0x43, 0x6c, 0x75, 0x73, 0x74, - 0x65, 0x72, 0x41, 0x75, 0x64, 0x69, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x23, 0x0a, - 0x04, 0x4c, 0x6f, 0x63, 0x6b, 0x18, 0x18, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x74, 0x79, - 0x70, 0x65, 0x73, 0x2e, 0x4c, 0x6f, 0x63, 0x6b, 0x56, 0x32, 0x48, 0x00, 0x52, 0x04, 0x4c, 0x6f, - 0x63, 0x6b, 0x12, 0x50, 0x0a, 0x13, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x52, 0x65, 0x73, - 0x74, 0x72, 0x69, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x19, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x1c, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x52, - 0x65, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x56, 0x34, 0x48, 0x00, 0x52, - 0x13, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x52, 0x65, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, - 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x56, 0x0a, 0x15, 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x73, 0x44, - 0x65, 0x73, 0x6b, 0x74, 0x6f, 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x18, 0x1a, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x57, 0x69, 0x6e, 0x64, - 0x6f, 0x77, 0x73, 0x44, 0x65, 0x73, 0x6b, 0x74, 0x6f, 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, - 0x65, 0x56, 0x33, 0x48, 0x00, 0x52, 0x15, 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x73, 0x44, 0x65, - 0x73, 0x6b, 0x74, 0x6f, 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x41, 0x0a, 0x0e, - 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x73, 0x44, 0x65, 0x73, 0x6b, 0x74, 0x6f, 0x70, 0x18, 0x1b, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x57, 0x69, 0x6e, - 0x64, 0x6f, 0x77, 0x73, 0x44, 0x65, 0x73, 0x6b, 0x74, 0x6f, 0x70, 0x56, 0x33, 0x48, 0x00, 0x52, - 0x0e, 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x73, 0x44, 0x65, 0x73, 0x6b, 0x74, 0x6f, 0x70, 0x12, - 0x2f, 0x0a, 0x08, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x18, 0x1c, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x11, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, - 0x73, 0x65, 0x56, 0x33, 0x48, 0x00, 0x52, 0x08, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, - 0x12, 0x32, 0x0a, 0x09, 0x41, 0x70, 0x70, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x18, 0x1d, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x41, 0x70, 0x70, 0x53, - 0x65, 0x72, 0x76, 0x65, 0x72, 0x56, 0x33, 0x48, 0x00, 0x52, 0x09, 0x41, 0x70, 0x70, 0x53, 0x65, - 0x72, 0x76, 0x65, 0x72, 0x12, 0x20, 0x0a, 0x03, 0x41, 0x70, 0x70, 0x18, 0x1e, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x0c, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x41, 0x70, 0x70, 0x56, 0x33, 0x48, - 0x00, 0x52, 0x03, 0x41, 0x70, 0x70, 0x12, 0x41, 0x0a, 0x10, 0x53, 0x6e, 0x6f, 0x77, 0x66, 0x6c, - 0x61, 0x6b, 0x65, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x1f, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x13, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x57, 0x65, 0x62, 0x53, 0x65, 0x73, 0x73, - 0x69, 0x6f, 0x6e, 0x56, 0x32, 0x48, 0x00, 0x52, 0x10, 0x53, 0x6e, 0x6f, 0x77, 0x66, 0x6c, 0x61, - 0x6b, 0x65, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x47, 0x0a, 0x10, 0x4b, 0x75, 0x62, - 0x65, 0x72, 0x6e, 0x65, 0x74, 0x65, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x18, 0x20, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x4b, 0x75, 0x62, 0x65, - 0x72, 0x6e, 0x65, 0x74, 0x65, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x56, 0x33, 0x48, 0x00, - 0x52, 0x10, 0x4b, 0x75, 0x62, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x65, 0x73, 0x53, 0x65, 0x72, 0x76, - 0x65, 0x72, 0x12, 0x4a, 0x0a, 0x11, 0x4b, 0x75, 0x62, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x65, 0x73, - 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x18, 0x21, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, - 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x4b, 0x75, 0x62, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x65, 0x73, - 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x56, 0x33, 0x48, 0x00, 0x52, 0x11, 0x4b, 0x75, 0x62, - 0x65, 0x72, 0x6e, 0x65, 0x74, 0x65, 0x73, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x12, 0x32, - 0x0a, 0x09, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x18, 0x22, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x12, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, - 0x6c, 0x65, 0x72, 0x56, 0x31, 0x48, 0x00, 0x52, 0x09, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, - 0x65, 0x72, 0x12, 0x44, 0x0a, 0x0f, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x53, 0x65, - 0x72, 0x76, 0x69, 0x63, 0x65, 0x18, 0x23, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x74, 0x79, - 0x70, 0x65, 0x73, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x53, 0x65, 0x72, 0x76, - 0x69, 0x63, 0x65, 0x56, 0x31, 0x48, 0x00, 0x52, 0x0f, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, - 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x59, 0x0a, 0x16, 0x53, 0x41, 0x4d, 0x4c, - 0x49, 0x64, 0x50, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, - 0x65, 0x72, 0x18, 0x24, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, - 0x2e, 0x53, 0x41, 0x4d, 0x4c, 0x49, 0x64, 0x50, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x50, - 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x56, 0x31, 0x48, 0x00, 0x52, 0x16, 0x53, 0x41, 0x4d, - 0x4c, 0x49, 0x64, 0x50, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x50, 0x72, 0x6f, 0x76, 0x69, - 0x64, 0x65, 0x72, 0x12, 0x3d, 0x0a, 0x0e, 0x53, 0x41, 0x4d, 0x4c, 0x49, 0x64, 0x50, 0x53, 0x65, - 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x25, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x74, 0x79, + 0x72, 0x75, 0x6c, 0x65, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x35, 0x74, 0x65, 0x6c, + 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x63, 0x6f, 0x6e, + 0x66, 0x69, 0x67, 0x2f, 0x76, 0x31, 0x2f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x67, 0x72, + 0x61, 0x70, 0x68, 0x5f, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x1a, 0x27, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x63, 0x72, 0x6f, + 0x77, 0x6e, 0x6a, 0x65, 0x77, 0x65, 0x6c, 0x2f, 0x76, 0x31, 0x2f, 0x63, 0x72, 0x6f, 0x77, 0x6e, + 0x6a, 0x65, 0x77, 0x65, 0x6c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x23, 0x74, 0x65, 0x6c, + 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x64, 0x62, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2f, 0x76, + 0x31, 0x2f, 0x64, 0x62, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x1a, 0x31, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x64, 0x69, 0x73, 0x63, 0x6f, + 0x76, 0x65, 0x72, 0x79, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2f, 0x76, 0x31, 0x2f, 0x64, 0x69, + 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x1a, 0x3b, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x6b, 0x75, + 0x62, 0x65, 0x77, 0x61, 0x69, 0x74, 0x69, 0x6e, 0x67, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, + 0x65, 0x72, 0x2f, 0x76, 0x31, 0x2f, 0x6b, 0x75, 0x62, 0x65, 0x77, 0x61, 0x69, 0x74, 0x69, 0x6e, + 0x67, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x1a, 0x21, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x6c, 0x65, 0x67, 0x61, 0x63, + 0x79, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x1a, 0x2d, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x6e, 0x6f, + 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x76, 0x31, 0x2f, 0x6e, + 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x1a, 0x27, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x73, 0x65, 0x63, + 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x65, 0x63, 0x72, 0x65, + 0x70, 0x6f, 0x72, 0x74, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x2f, 0x74, 0x65, 0x6c, + 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x75, 0x73, 0x65, 0x72, 0x6c, 0x6f, 0x67, 0x69, 0x6e, 0x73, + 0x74, 0x61, 0x74, 0x65, 0x2f, 0x76, 0x31, 0x2f, 0x75, 0x73, 0x65, 0x72, 0x6c, 0x6f, 0x67, 0x69, + 0x6e, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xaa, 0x1f, 0x0a, + 0x05, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x24, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0e, 0x32, 0x10, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x4f, 0x70, 0x65, + 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x3f, 0x0a, 0x0e, + 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x52, 0x65, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x48, 0x00, 0x52, 0x0e, 0x52, + 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x12, 0x3e, 0x0a, + 0x0d, 0x43, 0x65, 0x72, 0x74, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x43, 0x65, 0x72, + 0x74, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x56, 0x32, 0x48, 0x00, 0x52, 0x0d, + 0x43, 0x65, 0x72, 0x74, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x12, 0x3b, 0x0a, + 0x0c, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x53, 0x74, 0x61, 0x74, + 0x69, 0x63, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x56, 0x32, 0x48, 0x00, 0x52, 0x0c, 0x53, 0x74, + 0x61, 0x74, 0x69, 0x63, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x12, 0x41, 0x0a, 0x0e, 0x50, 0x72, + 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x05, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x50, 0x72, 0x6f, 0x76, 0x69, + 0x73, 0x69, 0x6f, 0x6e, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x56, 0x32, 0x48, 0x00, 0x52, 0x0e, 0x50, + 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x38, 0x0a, + 0x0b, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x43, 0x6c, 0x75, 0x73, 0x74, + 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x56, 0x32, 0x48, 0x00, 0x52, 0x0b, 0x43, 0x6c, 0x75, 0x73, + 0x74, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x23, 0x0a, 0x04, 0x55, 0x73, 0x65, 0x72, 0x18, + 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x55, 0x73, + 0x65, 0x72, 0x56, 0x32, 0x48, 0x00, 0x52, 0x04, 0x55, 0x73, 0x65, 0x72, 0x12, 0x23, 0x0a, 0x04, + 0x52, 0x6f, 0x6c, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x74, 0x79, 0x70, + 0x65, 0x73, 0x2e, 0x52, 0x6f, 0x6c, 0x65, 0x56, 0x36, 0x48, 0x00, 0x52, 0x04, 0x52, 0x6f, 0x6c, + 0x65, 0x12, 0x30, 0x0a, 0x09, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x0a, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x4e, 0x61, 0x6d, + 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x48, 0x00, 0x52, 0x09, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, + 0x61, 0x63, 0x65, 0x12, 0x29, 0x0a, 0x06, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x18, 0x0b, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x53, 0x65, 0x72, 0x76, + 0x65, 0x72, 0x56, 0x32, 0x48, 0x00, 0x52, 0x06, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x12, 0x3e, + 0x0a, 0x0d, 0x52, 0x65, 0x76, 0x65, 0x72, 0x73, 0x65, 0x54, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x18, + 0x0c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x52, 0x65, + 0x76, 0x65, 0x72, 0x73, 0x65, 0x54, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x56, 0x32, 0x48, 0x00, 0x52, + 0x0d, 0x52, 0x65, 0x76, 0x65, 0x72, 0x73, 0x65, 0x54, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x12, 0x47, + 0x0a, 0x10, 0x54, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, + 0x2e, 0x54, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x56, 0x32, 0x48, 0x00, 0x52, 0x10, 0x54, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x43, 0x6f, 0x6e, + 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x3e, 0x0a, 0x0d, 0x41, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, + 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x56, 0x33, 0x48, 0x00, 0x52, 0x0d, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x35, 0x0a, 0x0a, 0x41, 0x70, 0x70, 0x53, 0x65, + 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x57, 0x65, 0x62, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x56, 0x32, - 0x48, 0x00, 0x52, 0x0e, 0x53, 0x41, 0x4d, 0x4c, 0x49, 0x64, 0x50, 0x53, 0x65, 0x73, 0x73, 0x69, - 0x6f, 0x6e, 0x12, 0x32, 0x0a, 0x09, 0x55, 0x73, 0x65, 0x72, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x18, - 0x26, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x55, 0x73, - 0x65, 0x72, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x56, 0x31, 0x48, 0x00, 0x52, 0x09, 0x55, 0x73, 0x65, - 0x72, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x2f, 0x0a, 0x08, 0x55, 0x49, 0x43, 0x6f, 0x6e, 0x66, - 0x69, 0x67, 0x18, 0x27, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, - 0x2e, 0x55, 0x49, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x56, 0x31, 0x48, 0x00, 0x52, 0x08, 0x55, - 0x49, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x41, 0x0a, 0x0e, 0x4f, 0x6b, 0x74, 0x61, 0x49, - 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x75, 0x6c, 0x65, 0x18, 0x28, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x17, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x4f, 0x6b, 0x74, 0x61, 0x49, 0x6d, 0x70, 0x6f, - 0x72, 0x74, 0x52, 0x75, 0x6c, 0x65, 0x56, 0x31, 0x48, 0x00, 0x52, 0x0e, 0x4f, 0x6b, 0x74, 0x61, - 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x75, 0x6c, 0x65, 0x12, 0x41, 0x0a, 0x0e, 0x4f, 0x6b, - 0x74, 0x61, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x18, 0x29, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x4f, 0x6b, 0x74, 0x61, 0x41, - 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x56, 0x31, 0x48, 0x00, 0x52, 0x0e, 0x4f, - 0x6b, 0x74, 0x61, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x38, 0x0a, - 0x0b, 0x49, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x2a, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x67, - 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x56, 0x31, 0x48, 0x00, 0x52, 0x0b, 0x49, 0x6e, 0x74, 0x65, - 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x38, 0x0a, 0x0b, 0x57, 0x61, 0x74, 0x63, 0x68, - 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x2b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x74, - 0x79, 0x70, 0x65, 0x73, 0x2e, 0x57, 0x61, 0x74, 0x63, 0x68, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, - 0x56, 0x31, 0x48, 0x00, 0x52, 0x0b, 0x57, 0x61, 0x74, 0x63, 0x68, 0x53, 0x74, 0x61, 0x74, 0x75, - 0x73, 0x12, 0x57, 0x0a, 0x16, 0x48, 0x65, 0x61, 0x64, 0x6c, 0x65, 0x73, 0x73, 0x41, 0x75, 0x74, - 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x2c, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x1d, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x48, 0x65, 0x61, 0x64, 0x6c, 0x65, - 0x73, 0x73, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x48, 0x00, 0x52, 0x16, 0x48, 0x65, 0x61, 0x64, 0x6c, 0x65, 0x73, 0x73, 0x41, 0x75, 0x74, 0x68, - 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x44, 0x0a, 0x0a, 0x41, 0x63, - 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x18, 0x2d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, - 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, - 0x6c, 0x69, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, - 0x73, 0x74, 0x48, 0x00, 0x52, 0x0a, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, - 0x12, 0x54, 0x0a, 0x0e, 0x55, 0x73, 0x65, 0x72, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x53, 0x74, 0x61, - 0x74, 0x65, 0x18, 0x2e, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, - 0x6f, 0x72, 0x74, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x6c, 0x6f, 0x67, 0x69, 0x6e, 0x73, 0x74, 0x61, - 0x74, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x53, - 0x74, 0x61, 0x74, 0x65, 0x48, 0x00, 0x52, 0x0e, 0x55, 0x73, 0x65, 0x72, 0x4c, 0x6f, 0x67, 0x69, - 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x4c, 0x0a, 0x10, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, - 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x2f, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x1e, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x61, 0x63, 0x63, 0x65, - 0x73, 0x73, 0x6c, 0x69, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, - 0x48, 0x00, 0x52, 0x10, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, - 0x6d, 0x62, 0x65, 0x72, 0x12, 0x58, 0x0a, 0x0f, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, - 0x79, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x30, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2c, 0x2e, - 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, - 0x72, 0x79, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x69, 0x73, 0x63, - 0x6f, 0x76, 0x65, 0x72, 0x79, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x48, 0x00, 0x52, 0x0f, 0x44, - 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x44, - 0x0a, 0x0a, 0x41, 0x75, 0x64, 0x69, 0x74, 0x51, 0x75, 0x65, 0x72, 0x79, 0x18, 0x32, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x73, 0x65, - 0x63, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x75, 0x64, 0x69, - 0x74, 0x51, 0x75, 0x65, 0x72, 0x79, 0x48, 0x00, 0x52, 0x0a, 0x41, 0x75, 0x64, 0x69, 0x74, 0x51, - 0x75, 0x65, 0x72, 0x79, 0x12, 0x38, 0x0a, 0x06, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x33, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, - 0x73, 0x65, 0x63, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, - 0x70, 0x6f, 0x72, 0x74, 0x48, 0x00, 0x52, 0x06, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x47, - 0x0a, 0x0b, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x18, 0x34, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x73, - 0x65, 0x63, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x70, - 0x6f, 0x72, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x48, 0x00, 0x52, 0x0b, 0x52, 0x65, 0x70, 0x6f, - 0x72, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x4c, 0x0a, 0x10, 0x41, 0x63, 0x63, 0x65, 0x73, - 0x73, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x76, 0x69, 0x65, 0x77, 0x18, 0x35, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x1e, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x61, 0x63, 0x63, - 0x65, 0x73, 0x73, 0x6c, 0x69, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x76, 0x69, 0x65, - 0x77, 0x48, 0x00, 0x52, 0x10, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x52, - 0x65, 0x76, 0x69, 0x65, 0x77, 0x12, 0x6d, 0x0a, 0x14, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4d, - 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x18, 0x36, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x37, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x61, - 0x63, 0x63, 0x65, 0x73, 0x73, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x72, - 0x75, 0x6c, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4d, 0x6f, - 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x48, 0x00, 0x52, 0x14, + 0x48, 0x00, 0x52, 0x0a, 0x41, 0x70, 0x70, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x3e, + 0x0a, 0x0d, 0x52, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x18, + 0x10, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x52, 0x65, + 0x6d, 0x6f, 0x74, 0x65, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x56, 0x33, 0x48, 0x00, 0x52, + 0x0d, 0x52, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x12, 0x41, + 0x0a, 0x0e, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, + 0x18, 0x11, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x44, + 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x56, 0x33, 0x48, + 0x00, 0x52, 0x0e, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, + 0x72, 0x12, 0x35, 0x0a, 0x0a, 0x57, 0x65, 0x62, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x18, + 0x12, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x57, 0x65, + 0x62, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x56, 0x32, 0x48, 0x00, 0x52, 0x0a, 0x57, 0x65, + 0x62, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x2f, 0x0a, 0x08, 0x57, 0x65, 0x62, 0x54, + 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x13, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x74, 0x79, 0x70, + 0x65, 0x73, 0x2e, 0x57, 0x65, 0x62, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x56, 0x33, 0x48, 0x00, 0x52, + 0x08, 0x57, 0x65, 0x62, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x5c, 0x0a, 0x17, 0x43, 0x6c, 0x75, + 0x73, 0x74, 0x65, 0x72, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x69, 0x6e, 0x67, 0x43, 0x6f, + 0x6e, 0x66, 0x69, 0x67, 0x18, 0x14, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x74, 0x79, 0x70, + 0x65, 0x73, 0x2e, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, + 0x6b, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x56, 0x32, 0x48, 0x00, 0x52, 0x17, + 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x69, 0x6e, + 0x67, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x59, 0x0a, 0x16, 0x53, 0x65, 0x73, 0x73, 0x69, + 0x6f, 0x6e, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x66, 0x69, + 0x67, 0x18, 0x15, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, + 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x67, + 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x56, 0x32, 0x48, 0x00, 0x52, 0x16, 0x53, 0x65, 0x73, 0x73, + 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x66, + 0x69, 0x67, 0x12, 0x41, 0x0a, 0x0e, 0x41, 0x75, 0x74, 0x68, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, + 0x65, 0x6e, 0x63, 0x65, 0x18, 0x16, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x79, 0x70, + 0x65, 0x73, 0x2e, 0x41, 0x75, 0x74, 0x68, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, + 0x65, 0x56, 0x32, 0x48, 0x00, 0x52, 0x0e, 0x41, 0x75, 0x74, 0x68, 0x50, 0x72, 0x65, 0x66, 0x65, + 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x4d, 0x0a, 0x12, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, + 0x41, 0x75, 0x64, 0x69, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x17, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x1b, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, + 0x72, 0x41, 0x75, 0x64, 0x69, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x56, 0x32, 0x48, 0x00, + 0x52, 0x12, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x41, 0x75, 0x64, 0x69, 0x74, 0x43, 0x6f, + 0x6e, 0x66, 0x69, 0x67, 0x12, 0x23, 0x0a, 0x04, 0x4c, 0x6f, 0x63, 0x6b, 0x18, 0x18, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x4c, 0x6f, 0x63, 0x6b, 0x56, + 0x32, 0x48, 0x00, 0x52, 0x04, 0x4c, 0x6f, 0x63, 0x6b, 0x12, 0x50, 0x0a, 0x13, 0x4e, 0x65, 0x74, + 0x77, 0x6f, 0x72, 0x6b, 0x52, 0x65, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x18, 0x19, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x4e, + 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x52, 0x65, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x56, 0x34, 0x48, 0x00, 0x52, 0x13, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x52, + 0x65, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x56, 0x0a, 0x15, 0x57, + 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x73, 0x44, 0x65, 0x73, 0x6b, 0x74, 0x6f, 0x70, 0x53, 0x65, 0x72, + 0x76, 0x69, 0x63, 0x65, 0x18, 0x1a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x74, 0x79, 0x70, + 0x65, 0x73, 0x2e, 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x73, 0x44, 0x65, 0x73, 0x6b, 0x74, 0x6f, + 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x56, 0x33, 0x48, 0x00, 0x52, 0x15, 0x57, 0x69, + 0x6e, 0x64, 0x6f, 0x77, 0x73, 0x44, 0x65, 0x73, 0x6b, 0x74, 0x6f, 0x70, 0x53, 0x65, 0x72, 0x76, + 0x69, 0x63, 0x65, 0x12, 0x41, 0x0a, 0x0e, 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x73, 0x44, 0x65, + 0x73, 0x6b, 0x74, 0x6f, 0x70, 0x18, 0x1b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x79, + 0x70, 0x65, 0x73, 0x2e, 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x73, 0x44, 0x65, 0x73, 0x6b, 0x74, + 0x6f, 0x70, 0x56, 0x33, 0x48, 0x00, 0x52, 0x0e, 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x73, 0x44, + 0x65, 0x73, 0x6b, 0x74, 0x6f, 0x70, 0x12, 0x2f, 0x0a, 0x08, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, + 0x73, 0x65, 0x18, 0x1c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, + 0x2e, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x56, 0x33, 0x48, 0x00, 0x52, 0x08, 0x44, + 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x12, 0x32, 0x0a, 0x09, 0x41, 0x70, 0x70, 0x53, 0x65, + 0x72, 0x76, 0x65, 0x72, 0x18, 0x1d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x74, 0x79, 0x70, + 0x65, 0x73, 0x2e, 0x41, 0x70, 0x70, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x56, 0x33, 0x48, 0x00, + 0x52, 0x09, 0x41, 0x70, 0x70, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x12, 0x20, 0x0a, 0x03, 0x41, + 0x70, 0x70, 0x18, 0x1e, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, + 0x2e, 0x41, 0x70, 0x70, 0x56, 0x33, 0x48, 0x00, 0x52, 0x03, 0x41, 0x70, 0x70, 0x12, 0x41, 0x0a, + 0x10, 0x53, 0x6e, 0x6f, 0x77, 0x66, 0x6c, 0x61, 0x6b, 0x65, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, + 0x6e, 0x18, 0x1f, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, + 0x57, 0x65, 0x62, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x56, 0x32, 0x48, 0x00, 0x52, 0x10, + 0x53, 0x6e, 0x6f, 0x77, 0x66, 0x6c, 0x61, 0x6b, 0x65, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, + 0x12, 0x47, 0x0a, 0x10, 0x4b, 0x75, 0x62, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x65, 0x73, 0x53, 0x65, + 0x72, 0x76, 0x65, 0x72, 0x18, 0x20, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x74, 0x79, 0x70, + 0x65, 0x73, 0x2e, 0x4b, 0x75, 0x62, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x65, 0x73, 0x53, 0x65, 0x72, + 0x76, 0x65, 0x72, 0x56, 0x33, 0x48, 0x00, 0x52, 0x10, 0x4b, 0x75, 0x62, 0x65, 0x72, 0x6e, 0x65, + 0x74, 0x65, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x12, 0x4a, 0x0a, 0x11, 0x4b, 0x75, 0x62, + 0x65, 0x72, 0x6e, 0x65, 0x74, 0x65, 0x73, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x18, 0x21, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x4b, 0x75, 0x62, + 0x65, 0x72, 0x6e, 0x65, 0x74, 0x65, 0x73, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x56, 0x33, + 0x48, 0x00, 0x52, 0x11, 0x4b, 0x75, 0x62, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x65, 0x73, 0x43, 0x6c, + 0x75, 0x73, 0x74, 0x65, 0x72, 0x12, 0x32, 0x0a, 0x09, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, + 0x65, 0x72, 0x18, 0x22, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, + 0x2e, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x56, 0x31, 0x48, 0x00, 0x52, 0x09, + 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x12, 0x44, 0x0a, 0x0f, 0x44, 0x61, 0x74, + 0x61, 0x62, 0x61, 0x73, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x18, 0x23, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x62, + 0x61, 0x73, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x56, 0x31, 0x48, 0x00, 0x52, 0x0f, + 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, + 0x59, 0x0a, 0x16, 0x53, 0x41, 0x4d, 0x4c, 0x49, 0x64, 0x50, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, + 0x65, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x18, 0x24, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x1f, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x53, 0x41, 0x4d, 0x4c, 0x49, 0x64, 0x50, 0x53, + 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x56, 0x31, + 0x48, 0x00, 0x52, 0x16, 0x53, 0x41, 0x4d, 0x4c, 0x49, 0x64, 0x50, 0x53, 0x65, 0x72, 0x76, 0x69, + 0x63, 0x65, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x12, 0x3d, 0x0a, 0x0e, 0x53, 0x41, + 0x4d, 0x4c, 0x49, 0x64, 0x50, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x25, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x57, 0x65, 0x62, 0x53, 0x65, + 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x56, 0x32, 0x48, 0x00, 0x52, 0x0e, 0x53, 0x41, 0x4d, 0x4c, 0x49, + 0x64, 0x50, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x32, 0x0a, 0x09, 0x55, 0x73, 0x65, + 0x72, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x18, 0x26, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x74, + 0x79, 0x70, 0x65, 0x73, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x56, 0x31, + 0x48, 0x00, 0x52, 0x09, 0x55, 0x73, 0x65, 0x72, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x2f, 0x0a, + 0x08, 0x55, 0x49, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x27, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x11, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x55, 0x49, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, + 0x56, 0x31, 0x48, 0x00, 0x52, 0x08, 0x55, 0x49, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x41, + 0x0a, 0x0e, 0x4f, 0x6b, 0x74, 0x61, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x75, 0x6c, 0x65, + 0x18, 0x28, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x4f, + 0x6b, 0x74, 0x61, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x75, 0x6c, 0x65, 0x56, 0x31, 0x48, + 0x00, 0x52, 0x0e, 0x4f, 0x6b, 0x74, 0x61, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x75, 0x6c, + 0x65, 0x12, 0x41, 0x0a, 0x0e, 0x4f, 0x6b, 0x74, 0x61, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, + 0x65, 0x6e, 0x74, 0x18, 0x29, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x79, 0x70, 0x65, + 0x73, 0x2e, 0x4f, 0x6b, 0x74, 0x61, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, + 0x56, 0x31, 0x48, 0x00, 0x52, 0x0e, 0x4f, 0x6b, 0x74, 0x61, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, + 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x38, 0x0a, 0x0b, 0x49, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x18, 0x2a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x74, 0x79, 0x70, 0x65, + 0x73, 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x56, 0x31, 0x48, + 0x00, 0x52, 0x0b, 0x49, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x38, + 0x0a, 0x0b, 0x57, 0x61, 0x74, 0x63, 0x68, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x2b, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x57, 0x61, 0x74, 0x63, + 0x68, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x56, 0x31, 0x48, 0x00, 0x52, 0x0b, 0x57, 0x61, 0x74, + 0x63, 0x68, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x57, 0x0a, 0x16, 0x48, 0x65, 0x61, 0x64, + 0x6c, 0x65, 0x73, 0x73, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x18, 0x2c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, + 0x2e, 0x48, 0x65, 0x61, 0x64, 0x6c, 0x65, 0x73, 0x73, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, + 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x00, 0x52, 0x16, 0x48, 0x65, 0x61, 0x64, 0x6c, + 0x65, 0x73, 0x73, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x12, 0x44, 0x0a, 0x0a, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x18, + 0x2d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, + 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x6c, 0x69, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x41, + 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x48, 0x00, 0x52, 0x0a, 0x41, 0x63, 0x63, + 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x54, 0x0a, 0x0e, 0x55, 0x73, 0x65, 0x72, 0x4c, + 0x6f, 0x67, 0x69, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x18, 0x2e, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x2a, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x6c, + 0x6f, 0x67, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x73, 0x65, + 0x72, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x48, 0x00, 0x52, 0x0e, 0x55, + 0x73, 0x65, 0x72, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x4c, 0x0a, + 0x10, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, + 0x72, 0x18, 0x2f, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, + 0x72, 0x74, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x6c, 0x69, 0x73, 0x74, 0x2e, 0x76, 0x31, + 0x2e, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x48, 0x00, 0x52, 0x10, 0x41, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x58, 0x0a, 0x0f, 0x44, + 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x30, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, + 0x64, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, + 0x76, 0x31, 0x2e, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0x43, 0x6f, 0x6e, 0x66, + 0x69, 0x67, 0x48, 0x00, 0x52, 0x0f, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0x43, + 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x44, 0x0a, 0x0a, 0x41, 0x75, 0x64, 0x69, 0x74, 0x51, 0x75, + 0x65, 0x72, 0x79, 0x18, 0x32, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x74, 0x65, 0x6c, 0x65, + 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x73, 0x65, 0x63, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x2e, + 0x76, 0x31, 0x2e, 0x41, 0x75, 0x64, 0x69, 0x74, 0x51, 0x75, 0x65, 0x72, 0x79, 0x48, 0x00, 0x52, + 0x0a, 0x41, 0x75, 0x64, 0x69, 0x74, 0x51, 0x75, 0x65, 0x72, 0x79, 0x12, 0x38, 0x0a, 0x06, 0x52, + 0x65, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x33, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x74, 0x65, + 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x73, 0x65, 0x63, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, + 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x48, 0x00, 0x52, 0x06, 0x52, + 0x65, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x47, 0x0a, 0x0b, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x53, + 0x74, 0x61, 0x74, 0x65, 0x18, 0x34, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x74, 0x65, 0x6c, + 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x73, 0x65, 0x63, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, + 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x48, + 0x00, 0x52, 0x0b, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x4c, + 0x0a, 0x10, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x76, 0x69, + 0x65, 0x77, 0x18, 0x35, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, + 0x6f, 0x72, 0x74, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x6c, 0x69, 0x73, 0x74, 0x2e, 0x76, + 0x31, 0x2e, 0x52, 0x65, 0x76, 0x69, 0x65, 0x77, 0x48, 0x00, 0x52, 0x10, 0x41, 0x63, 0x63, 0x65, + 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x76, 0x69, 0x65, 0x77, 0x12, 0x6d, 0x0a, 0x14, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, - 0x52, 0x75, 0x6c, 0x65, 0x12, 0x7e, 0x0a, 0x1a, 0x4b, 0x75, 0x62, 0x65, 0x72, 0x6e, 0x65, 0x74, - 0x65, 0x73, 0x57, 0x61, 0x69, 0x74, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, - 0x65, 0x72, 0x18, 0x37, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x3c, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, - 0x6f, 0x72, 0x74, 0x2e, 0x6b, 0x75, 0x62, 0x65, 0x77, 0x61, 0x69, 0x74, 0x69, 0x6e, 0x67, 0x63, - 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4b, 0x75, 0x62, 0x65, - 0x72, 0x6e, 0x65, 0x74, 0x65, 0x73, 0x57, 0x61, 0x69, 0x74, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, - 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x48, 0x00, 0x52, 0x1a, 0x4b, 0x75, 0x62, 0x65, 0x72, 0x6e, - 0x65, 0x74, 0x65, 0x73, 0x57, 0x61, 0x69, 0x74, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x74, 0x61, - 0x69, 0x6e, 0x65, 0x72, 0x12, 0x55, 0x0a, 0x10, 0x55, 0x73, 0x65, 0x72, 0x4e, 0x6f, 0x74, 0x69, - 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x38, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, + 0x52, 0x75, 0x6c, 0x65, 0x18, 0x36, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x37, 0x2e, 0x74, 0x65, 0x6c, + 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x6d, 0x6f, 0x6e, 0x69, + 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x41, + 0x63, 0x63, 0x65, 0x73, 0x73, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x52, + 0x75, 0x6c, 0x65, 0x48, 0x00, 0x52, 0x14, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4d, 0x6f, 0x6e, + 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x12, 0x7e, 0x0a, 0x1a, 0x4b, + 0x75, 0x62, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x65, 0x73, 0x57, 0x61, 0x69, 0x74, 0x69, 0x6e, 0x67, + 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x18, 0x37, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x3c, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x6b, 0x75, 0x62, 0x65, 0x77, + 0x61, 0x69, 0x74, 0x69, 0x6e, 0x67, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x2e, + 0x76, 0x31, 0x2e, 0x4b, 0x75, 0x62, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x65, 0x73, 0x57, 0x61, 0x69, + 0x74, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x48, 0x00, 0x52, + 0x1a, 0x4b, 0x75, 0x62, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x65, 0x73, 0x57, 0x61, 0x69, 0x74, 0x69, + 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x12, 0x55, 0x0a, 0x10, 0x55, + 0x73, 0x65, 0x72, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, + 0x38, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, + 0x2e, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x76, + 0x31, 0x2e, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x00, + 0x52, 0x10, 0x55, 0x73, 0x65, 0x72, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x12, 0x5f, 0x0a, 0x12, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x4e, 0x6f, 0x74, 0x69, + 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x39, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x69, - 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x4e, 0x6f, 0x74, 0x69, 0x66, - 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x00, 0x52, 0x10, 0x55, 0x73, 0x65, 0x72, 0x4e, - 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x5f, 0x0a, 0x12, 0x47, - 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x18, 0x39, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, - 0x72, 0x74, 0x2e, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, - 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, - 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x00, 0x52, 0x12, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, - 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x44, 0x0a, 0x0a, - 0x43, 0x72, 0x6f, 0x77, 0x6e, 0x4a, 0x65, 0x77, 0x65, 0x6c, 0x18, 0x3a, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x22, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x63, 0x72, 0x6f, 0x77, - 0x6e, 0x6a, 0x65, 0x77, 0x65, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x6f, 0x77, 0x6e, 0x4a, - 0x65, 0x77, 0x65, 0x6c, 0x48, 0x00, 0x52, 0x0a, 0x43, 0x72, 0x6f, 0x77, 0x6e, 0x4a, 0x65, 0x77, - 0x65, 0x6c, 0x12, 0x4e, 0x0a, 0x0e, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x4f, 0x62, - 0x6a, 0x65, 0x63, 0x74, 0x18, 0x3b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x74, 0x65, 0x6c, - 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x62, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e, 0x76, - 0x31, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, - 0x48, 0x00, 0x52, 0x0e, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x4f, 0x62, 0x6a, 0x65, - 0x63, 0x74, 0x42, 0x0a, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4a, 0x04, - 0x08, 0x07, 0x10, 0x08, 0x4a, 0x04, 0x08, 0x31, 0x10, 0x32, 0x52, 0x12, 0x45, 0x78, 0x74, 0x65, - 0x72, 0x6e, 0x61, 0x6c, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x41, 0x75, 0x64, 0x69, 0x74, 0x2a, 0x2a, - 0x0a, 0x09, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x08, 0x0a, 0x04, 0x49, - 0x4e, 0x49, 0x54, 0x10, 0x00, 0x12, 0x07, 0x0a, 0x03, 0x50, 0x55, 0x54, 0x10, 0x01, 0x12, 0x0a, - 0x0a, 0x06, 0x44, 0x45, 0x4c, 0x45, 0x54, 0x45, 0x10, 0x02, 0x42, 0x34, 0x5a, 0x32, 0x67, 0x69, - 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x72, 0x61, 0x76, 0x69, 0x74, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x2f, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, - 0x61, 0x70, 0x69, 0x2f, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x6c, 0x6f, 0x62, 0x61, + 0x6c, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x00, 0x52, + 0x12, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x12, 0x44, 0x0a, 0x0a, 0x43, 0x72, 0x6f, 0x77, 0x6e, 0x4a, 0x65, 0x77, 0x65, + 0x6c, 0x18, 0x3a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, + 0x72, 0x74, 0x2e, 0x63, 0x72, 0x6f, 0x77, 0x6e, 0x6a, 0x65, 0x77, 0x65, 0x6c, 0x2e, 0x76, 0x31, + 0x2e, 0x43, 0x72, 0x6f, 0x77, 0x6e, 0x4a, 0x65, 0x77, 0x65, 0x6c, 0x48, 0x00, 0x52, 0x0a, 0x43, + 0x72, 0x6f, 0x77, 0x6e, 0x4a, 0x65, 0x77, 0x65, 0x6c, 0x12, 0x4e, 0x0a, 0x0e, 0x44, 0x61, 0x74, + 0x61, 0x62, 0x61, 0x73, 0x65, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x3b, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x24, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x64, 0x62, 0x6f, + 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, + 0x65, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x48, 0x00, 0x52, 0x0e, 0x44, 0x61, 0x74, 0x61, 0x62, + 0x61, 0x73, 0x65, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x62, 0x0a, 0x13, 0x41, 0x63, 0x63, + 0x65, 0x73, 0x73, 0x47, 0x72, 0x61, 0x70, 0x68, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, + 0x18, 0x3d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, + 0x74, 0x2e, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, + 0x76, 0x31, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x47, 0x72, 0x61, 0x70, 0x68, 0x53, 0x65, + 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x48, 0x00, 0x52, 0x13, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, + 0x47, 0x72, 0x61, 0x70, 0x68, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x42, 0x0a, 0x0a, + 0x08, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4a, 0x04, 0x08, 0x07, 0x10, 0x08, 0x4a, + 0x04, 0x08, 0x31, 0x10, 0x32, 0x52, 0x12, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x43, + 0x6c, 0x6f, 0x75, 0x64, 0x41, 0x75, 0x64, 0x69, 0x74, 0x2a, 0x2a, 0x0a, 0x09, 0x4f, 0x70, 0x65, + 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x08, 0x0a, 0x04, 0x49, 0x4e, 0x49, 0x54, 0x10, 0x00, + 0x12, 0x07, 0x0a, 0x03, 0x50, 0x55, 0x54, 0x10, 0x01, 0x12, 0x0a, 0x0a, 0x06, 0x44, 0x45, 0x4c, + 0x45, 0x54, 0x45, 0x10, 0x02, 0x42, 0x34, 0x5a, 0x32, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, + 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x72, 0x61, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x61, + 0x6c, 0x2f, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x63, + 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x33, } var ( @@ -1365,6 +1391,7 @@ var file_teleport_legacy_client_proto_event_proto_goTypes = []interface{}{ (*v16.GlobalNotification)(nil), // 52: teleport.notifications.v1.GlobalNotification (*v17.CrownJewel)(nil), // 53: teleport.crownjewel.v1.CrownJewel (*v18.DatabaseObject)(nil), // 54: teleport.dbobject.v1.DatabaseObject + (*v19.AccessGraphSettings)(nil), // 55: teleport.clusterconfig.v1.AccessGraphSettings } var file_teleport_legacy_client_proto_event_proto_depIdxs = []int32{ 0, // 0: proto.Event.Type:type_name -> proto.Operation @@ -1424,11 +1451,12 @@ var file_teleport_legacy_client_proto_event_proto_depIdxs = []int32{ 52, // 54: proto.Event.GlobalNotification:type_name -> teleport.notifications.v1.GlobalNotification 53, // 55: proto.Event.CrownJewel:type_name -> teleport.crownjewel.v1.CrownJewel 54, // 56: proto.Event.DatabaseObject:type_name -> teleport.dbobject.v1.DatabaseObject - 57, // [57:57] is the sub-list for method output_type - 57, // [57:57] is the sub-list for method input_type - 57, // [57:57] is the sub-list for extension type_name - 57, // [57:57] is the sub-list for extension extendee - 0, // [0:57] is the sub-list for field type_name + 55, // 57: proto.Event.AccessGraphSettings:type_name -> teleport.clusterconfig.v1.AccessGraphSettings + 58, // [58:58] is the sub-list for method output_type + 58, // [58:58] is the sub-list for method input_type + 58, // [58:58] is the sub-list for extension type_name + 58, // [58:58] is the sub-list for extension extendee + 0, // [0:58] is the sub-list for field type_name } func init() { file_teleport_legacy_client_proto_event_proto_init() } @@ -1507,6 +1535,7 @@ func file_teleport_legacy_client_proto_event_proto_init() { (*Event_GlobalNotification)(nil), (*Event_CrownJewel)(nil), (*Event_DatabaseObject)(nil), + (*Event_AccessGraphSettings)(nil), } type x struct{} out := protoimpl.TypeBuilder{ diff --git a/api/proto/teleport/legacy/client/proto/event.proto b/api/proto/teleport/legacy/client/proto/event.proto index 0b79460b94dab..c85566ed28a2d 100644 --- a/api/proto/teleport/legacy/client/proto/event.proto +++ b/api/proto/teleport/legacy/client/proto/event.proto @@ -18,6 +18,7 @@ package proto; import "teleport/accesslist/v1/accesslist.proto"; import "teleport/accessmonitoringrules/v1/access_monitoring_rules.proto"; +import "teleport/clusterconfig/v1/access_graph_settings.proto"; import "teleport/crownjewel/v1/crownjewel.proto"; import "teleport/dbobject/v1/dbobject.proto"; import "teleport/discoveryconfig/v1/discoveryconfig.proto"; @@ -165,5 +166,7 @@ message Event { teleport.crownjewel.v1.CrownJewel CrownJewel = 58; // DatabaseObject is a database object resource. teleport.dbobject.v1.DatabaseObject DatabaseObject = 59; + // AccessGraphSettings is a resource for access graph settings. + teleport.clusterconfig.v1.AccessGraphSettings AccessGraphSettings = 61; } } diff --git a/lib/auth/authclient/api.go b/lib/auth/authclient/api.go index 680fd3aeead6a..7f0f89ab4e81b 100644 --- a/lib/auth/authclient/api.go +++ b/lib/auth/authclient/api.go @@ -28,6 +28,7 @@ import ( "github.com/gravitational/teleport/api/client/proto" accessmonitoringrules "github.com/gravitational/teleport/api/gen/proto/go/teleport/accessmonitoringrules/v1" + clusterconfigpb "github.com/gravitational/teleport/api/gen/proto/go/teleport/clusterconfig/v1" crownjewelv1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/crownjewel/v1" integrationpb "github.com/gravitational/teleport/api/gen/proto/go/teleport/integration/v1" kubewaitingcontainerpb "github.com/gravitational/teleport/api/gen/proto/go/teleport/kubewaitingcontainer/v1" @@ -1172,6 +1173,9 @@ type Cache interface { // DatabaseObjectsGetter defines methods for fetching database objects. services.DatabaseObjectsGetter + + // GetAccessGraphSettings returns the access graph settings. + GetAccessGraphSettings(context.Context) (*clusterconfigpb.AccessGraphSettings, error) } type NodeWrapper struct { diff --git a/lib/auth/clusterconfig/clusterconfigv1/service.go b/lib/auth/clusterconfig/clusterconfigv1/service.go index d990155b4eb83..d7ff4004f223b 100644 --- a/lib/auth/clusterconfig/clusterconfigv1/service.go +++ b/lib/auth/clusterconfig/clusterconfigv1/service.go @@ -38,6 +38,7 @@ type Cache interface { GetAuthPreference(context.Context) (types.AuthPreference, error) GetClusterNetworkingConfig(ctx context.Context) (types.ClusterNetworkingConfig, error) GetSessionRecordingConfig(ctx context.Context) (types.SessionRecordingConfig, error) + GetAccessGraphSettings(context.Context) (*clusterconfigpb.AccessGraphSettings, error) } // ReadOnlyCache abstracts over the required methods of [readonly.Cache]. @@ -45,6 +46,7 @@ type ReadOnlyCache interface { GetReadOnlyAuthPreference(context.Context) (readonly.AuthPreference, error) GetReadOnlyClusterNetworkingConfig(ctx context.Context) (readonly.ClusterNetworkingConfig, error) GetReadOnlySessionRecordingConfig(ctx context.Context) (readonly.SessionRecordingConfig, error) + GetReadOnlyAccessGraphSettings(context.Context) (readonly.AccessGraphSettings, error) } // Backend is used by the [Service] to mutate cluster config resources. diff --git a/lib/authz/permissions.go b/lib/authz/permissions.go index 60249667710d8..fc16841e602c5 100644 --- a/lib/authz/permissions.go +++ b/lib/authz/permissions.go @@ -36,6 +36,7 @@ import ( "github.com/gravitational/teleport" "github.com/gravitational/teleport/api/client/proto" "github.com/gravitational/teleport/api/defaults" + clusterconfigpb "github.com/gravitational/teleport/api/gen/proto/go/teleport/clusterconfig/v1" mfav1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/mfa/v1" "github.com/gravitational/teleport/api/mfa" "github.com/gravitational/teleport/api/types" @@ -113,7 +114,7 @@ func NewAuthorizer(opts AuthorizerOpts) (Authorizer, error) { // cannot handle caching, and will fail if caching is enabled. var err error opts.ReadOnlyAccessPoint, err = readonly.NewCache(readonly.CacheConfig{ - Upstream: opts.AccessPoint, + Upstream: accessPointWrapper{opts.AccessPoint}, Disabled: !opts.PermitCaching, }) if err != nil { @@ -133,6 +134,15 @@ func NewAuthorizer(opts AuthorizerOpts) (Authorizer, error) { }, nil } +type accessPointWrapper struct { + AuthorizerAccessPoint +} + +// GetAccessGraphSettings returns the access graph settings. +func (accessPointWrapper) GetAccessGraphSettings(ctx context.Context) (*clusterconfigpb.AccessGraphSettings, error) { + return nil, trace.NotImplemented("GetAccessGraphSettings is not implemented") +} + // Authorizer authorizes identity and returns auth context type Authorizer interface { // Authorize authorizes user based on identity supplied via context diff --git a/lib/cache/cache.go b/lib/cache/cache.go index 5292ced456180..a744ea0df5f25 100644 --- a/lib/cache/cache.go +++ b/lib/cache/cache.go @@ -32,11 +32,13 @@ import ( "go.opentelemetry.io/otel/attribute" oteltrace "go.opentelemetry.io/otel/trace" "golang.org/x/sync/errgroup" + protobuf "google.golang.org/protobuf/proto" "github.com/gravitational/teleport" "github.com/gravitational/teleport/api/client/proto" apidefaults "github.com/gravitational/teleport/api/defaults" accessmonitoringrulesv1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/accessmonitoringrules/v1" + clusterconfigpb "github.com/gravitational/teleport/api/gen/proto/go/teleport/clusterconfig/v1" crownjewelv1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/crownjewel/v1" dbobjectv1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/dbobject/v1" kubewaitingcontainerpb "github.com/gravitational/teleport/api/gen/proto/go/teleport/kubewaitingcontainer/v1" @@ -179,6 +181,7 @@ func ForAuth(cfg Config) Config { {Kind: types.KindGlobalNotification}, {Kind: types.KindAccessMonitoringRule}, {Kind: types.KindDatabaseObject}, + {Kind: types.KindAccessGraphSettings}, } cfg.QueueSize = defaults.AuthQueueSize // We don't want to enable partial health for auth cache because auth uses an event stream @@ -3261,3 +3264,28 @@ func (c *Cache) ListResources(ctx context.Context, req proto.ListResourcesReques return rg.reader.ListResources(ctx, req) } + +// GetAccessGraphSettings gets AccessGraphSettings from the backend. +func (c *Cache) GetAccessGraphSettings(ctx context.Context) (*clusterconfigpb.AccessGraphSettings, error) { + ctx, span := c.Tracer.Start(ctx, "cache/GetAccessGraphSettings") + defer span.End() + + rg, err := readCollectionCache(c, c.collections.accessGraphSettings) + if err != nil { + return nil, trace.Wrap(err) + } + defer rg.Release() + if !rg.IsCacheRead() { + cachedCfg, err := utils.FnCacheGet(ctx, c.fnCache, clusterConfigCacheKey{"access_graph_settings"}, func(ctx context.Context) (*clusterconfigpb.AccessGraphSettings, error) { + cfg, err := rg.reader.GetAccessGraphSettings(ctx) + return cfg, err + }) + if err != nil { + return nil, trace.Wrap(err) + } + + clone := protobuf.Clone(cachedCfg).(*clusterconfigpb.AccessGraphSettings) + return clone, nil + } + return rg.reader.GetAccessGraphSettings(ctx) +} diff --git a/lib/cache/cache_test.go b/lib/cache/cache_test.go index 50a0717693753..981eb343dc13a 100644 --- a/lib/cache/cache_test.go +++ b/lib/cache/cache_test.go @@ -43,6 +43,7 @@ import ( "github.com/gravitational/teleport/api/client/proto" apidefaults "github.com/gravitational/teleport/api/defaults" accessmonitoringrulesv1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/accessmonitoringrules/v1" + clusterconfigpb "github.com/gravitational/teleport/api/gen/proto/go/teleport/clusterconfig/v1" crownjewelv1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/crownjewel/v1" dbobjectv1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/dbobject/v1" headerv1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/header/v1" @@ -50,6 +51,7 @@ import ( notificationsv1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/notifications/v1" "github.com/gravitational/teleport/api/types" "github.com/gravitational/teleport/api/types/accesslist" + "github.com/gravitational/teleport/api/types/clusterconfig" "github.com/gravitational/teleport/api/types/discoveryconfig" "github.com/gravitational/teleport/api/types/header" "github.com/gravitational/teleport/api/types/kubewaitingcontainer" @@ -3217,6 +3219,7 @@ func TestCacheWatchKindExistsInEvents(t *testing.T) { types.KindAccessMonitoringRule: types.Resource153ToLegacy(newAccessMonitoringRule(t)), types.KindCrownJewel: types.Resource153ToLegacy(newCrownJewel(t, "test")), types.KindDatabaseObject: types.Resource153ToLegacy(newDatabaseObject(t, "test")), + types.KindAccessGraphSettings: types.Resource153ToLegacy(newAccessGraphSettings(t)), } for name, cfg := range cases { @@ -3689,6 +3692,16 @@ func newDatabaseObject(t *testing.T, name string) *dbobjectv1.DatabaseObject { return r } +func newAccessGraphSettings(t *testing.T) *clusterconfigpb.AccessGraphSettings { + t.Helper() + + r, err := clusterconfig.NewAccessGraphSettings(&clusterconfigpb.AccessGraphSettingsSpec{ + SecretsScanConfig: clusterconfigpb.AccessGraphSecretsScanConfig_ACCESS_GRAPH_SECRETS_SCAN_CONFIG_ENABLED, + }) + require.NoError(t, err) + return r +} + func newUserNotification(t *testing.T, name string) *notificationsv1.Notification { t.Helper() diff --git a/lib/cache/collections.go b/lib/cache/collections.go index f4a2350d162a8..f4e8592c53d85 100644 --- a/lib/cache/collections.go +++ b/lib/cache/collections.go @@ -29,6 +29,7 @@ import ( "github.com/gravitational/teleport/api/client/proto" apidefaults "github.com/gravitational/teleport/api/defaults" accessmonitoringrulesv1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/accessmonitoringrules/v1" + clusterconfigpb "github.com/gravitational/teleport/api/gen/proto/go/teleport/clusterconfig/v1" crownjewelv1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/crownjewel/v1" dbobjectv1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/dbobject/v1" kubewaitingcontainerpb "github.com/gravitational/teleport/api/gen/proto/go/teleport/kubewaitingcontainer/v1" @@ -246,6 +247,7 @@ type cacheCollections struct { windowsDesktops collectionReader[windowsDesktopsGetter] windowsDesktopServices collectionReader[windowsDesktopServiceGetter] userNotifications collectionReader[notificationGetter] + accessGraphSettings collectionReader[accessGraphSettingsGetter] globalNotifications collectionReader[notificationGetter] accessMonitoringRules collectionReader[accessMonitoringRuleGetter] } @@ -731,6 +733,15 @@ func setupCollections(c *Cache, watches []types.WatchKind) (*cacheCollections, e } collections.accessMonitoringRules = &genericCollection[*accessmonitoringrulesv1.AccessMonitoringRule, accessMonitoringRuleGetter, accessMonitoringRulesExecutor]{cache: c, watch: watch} collections.byKind[resourceKind] = collections.accessMonitoringRules + case types.KindAccessGraphSettings: + if c.ClusterConfig == nil { + return nil, trace.BadParameter("missing parameter ClusterConfig") + } + collections.accessGraphSettings = &genericCollection[*clusterconfigpb.AccessGraphSettings, accessGraphSettingsGetter, accessGraphSettingsExecutor]{ + cache: c, + watch: watch, + } + collections.byKind[resourceKind] = collections.accessGraphSettings default: return nil, trace.BadParameter("resource %q is not supported", watch.Kind) } @@ -3228,3 +3239,42 @@ type accessMonitoringRuleGetter interface { ListAccessMonitoringRules(ctx context.Context, limit int, startKey string) ([]*accessmonitoringrulesv1.AccessMonitoringRule, string, error) ListAccessMonitoringRulesWithFilter(ctx context.Context, pageSize int, nextToken string, subjects []string, notificationName string) ([]*accessmonitoringrulesv1.AccessMonitoringRule, string, error) } + +type accessGraphSettingsExecutor struct{} + +func (accessGraphSettingsExecutor) getAll(ctx context.Context, cache *Cache, _ bool) ([]*clusterconfigpb.AccessGraphSettings, error) { + set, err := cache.ClusterConfig.GetAccessGraphSettings(ctx) + if err != nil { + return nil, trace.Wrap(err) + } + + return []*clusterconfigpb.AccessGraphSettings{set}, nil +} + +func (accessGraphSettingsExecutor) upsert(ctx context.Context, cache *Cache, resource *clusterconfigpb.AccessGraphSettings) error { + _, err := cache.clusterConfigCache.UpsertAccessGraphSettings(ctx, resource) + return trace.Wrap(err) +} + +func (accessGraphSettingsExecutor) deleteAll(ctx context.Context, cache *Cache) error { + return trace.Wrap(cache.clusterConfigCache.DeleteAccessGraphSettings(ctx)) +} + +func (accessGraphSettingsExecutor) delete(ctx context.Context, cache *Cache, resource types.Resource) error { + return trace.Wrap(cache.clusterConfigCache.DeleteAccessGraphSettings(ctx)) +} + +func (accessGraphSettingsExecutor) isSingleton() bool { return false } + +func (accessGraphSettingsExecutor) getReader(cache *Cache, cacheOK bool) accessGraphSettingsGetter { + if cacheOK { + return cache.clusterConfigCache + } + return cache.Config.ClusterConfig +} + +type accessGraphSettingsGetter interface { + GetAccessGraphSettings(context.Context) (*clusterconfigpb.AccessGraphSettings, error) +} + +var _ executor[*clusterconfigpb.AccessGraphSettings, accessGraphSettingsGetter] = accessGraphSettingsExecutor{} diff --git a/lib/services/local/events.go b/lib/services/local/events.go index 44cbb744c5d56..3bdf2e1682b4d 100644 --- a/lib/services/local/events.go +++ b/lib/services/local/events.go @@ -219,6 +219,8 @@ func (e *EventsService) NewWatcher(ctx context.Context, watch types.Watch) (type parser = newAccessGraphSecretPrivateKeyParser() case types.KindAccessGraphSecretAuthorizedKey: parser = newAccessGraphSecretAuthorizedKeyParser() + case types.KindAccessGraphSettings: + parser = newAccessGraphSettingsParser() default: if watch.AllowPartialSuccess { continue @@ -2377,3 +2379,37 @@ func baseTwoKeys(key []byte) (string, string, error) { } return string(parts[len(parts)-2]), string(parts[len(parts)-1]), nil } + +func newAccessGraphSettingsParser() *accessGraphSettingsParser { + return &accessGraphSettingsParser{ + baseParser: newBaseParser(backend.Key(clusterConfigPrefix, accessGraphSettingsPrefix)), + } +} + +type accessGraphSettingsParser struct { + baseParser +} + +func (p *accessGraphSettingsParser) parse(event backend.Event) (types.Resource, error) { + switch event.Type { + case types.OpDelete: + h, err := resourceHeader(event, types.KindAccessGraphSettings, types.V1, 0) + if err != nil { + return nil, trace.Wrap(err) + } + h.SetName(types.MetaNameAccessGraphSettings) + return h, nil + case types.OpPut: + settings, err := services.UnmarshalAccessGraphSettings( + event.Item.Value, + services.WithExpires(event.Item.Expires), + services.WithRevision(event.Item.Revision), + ) + if err != nil { + return nil, trace.Wrap(err) + } + return types.Resource153ToLegacy(settings), nil + default: + return nil, trace.BadParameter("event %v is not supported", event.Type) + } +} diff --git a/lib/services/readonly/cache.go b/lib/services/readonly/cache.go index 503018f75b553..f553ba2089196 100644 --- a/lib/services/readonly/cache.go +++ b/lib/services/readonly/cache.go @@ -24,6 +24,7 @@ import ( "github.com/gravitational/trace" + clusterconfigpb "github.com/gravitational/teleport/api/gen/proto/go/teleport/clusterconfig/v1" "github.com/gravitational/teleport/api/types" "github.com/gravitational/teleport/lib/utils" ) @@ -33,6 +34,7 @@ type Upstream interface { GetAuthPreference(ctx context.Context) (types.AuthPreference, error) GetClusterNetworkingConfig(ctx context.Context) (types.ClusterNetworkingConfig, error) GetSessionRecordingConfig(ctx context.Context) (types.SessionRecordingConfig, error) + GetAccessGraphSettings(ctx context.Context) (*clusterconfigpb.AccessGraphSettings, error) } // Cache provides simple ttl-based in-memory caching for select resources that are frequently accessed @@ -123,3 +125,16 @@ func (c *Cache) GetReadOnlySessionRecordingConfig(ctx context.Context) (SessionR }) return cfg, trace.Wrap(err) } + +// GetReadOnlyAccessGraphSettings returns a read-only shared reference to the dynamic access graph settings resource. +func (c *Cache) GetReadOnlyAccessGraphSettings(ctx context.Context) (AccessGraphSettings, error) { + if c.cfg.Disabled { + cfg, err := c.cfg.Upstream.GetAccessGraphSettings(ctx) + return sealAccessGraphSettings(cfg), trace.Wrap(err) + } + cfg, err := utils.FnCacheGet(ctx, c.ttlCache, ttlCacheKey{kind: types.KindAccessGraphSettings}, func(ctx context.Context) (AccessGraphSettings, error) { + cfg, err := c.cfg.Upstream.GetAccessGraphSettings(ctx) + return sealAccessGraphSettings(cfg), trace.Wrap(err) + }) + return cfg, trace.Wrap(err) +} diff --git a/lib/services/readonly/readonly.go b/lib/services/readonly/readonly.go index 71462dd9f01b7..47e60ec9c4daf 100644 --- a/lib/services/readonly/readonly.go +++ b/lib/services/readonly/readonly.go @@ -21,7 +21,10 @@ package readonly import ( "time" + protobuf "google.golang.org/protobuf/proto" + "github.com/gravitational/teleport/api/constants" + clusterconfigpb "github.com/gravitational/teleport/api/gen/proto/go/teleport/clusterconfig/v1" "github.com/gravitational/teleport/api/types" "github.com/gravitational/teleport/api/utils/keys" ) @@ -103,3 +106,32 @@ func sealSessionRecordingConfig(c SessionRecordingConfig) SessionRecordingConfig } return sealedSessionRecordingConfig{SessionRecordingConfig: c} } + +// AccessGraphSettings is a read-only subset of clusterconfigpb.AccessGraphSettings used on certain hot paths +// to ensure that we do not modify the underlying AccessGraphSettings as it may be shared across +// multiple goroutines. +type AccessGraphSettings interface { + SecretsScanConfig() clusterconfigpb.AccessGraphSecretsScanConfig + Clone() *clusterconfigpb.AccessGraphSettings +} + +type sealedAccessGraphSettings struct { + *clusterconfigpb.AccessGraphSettings +} + +// sealAccessGraphSettings returns a read-only version of the SessionRecordingConfig. +func sealAccessGraphSettings(c *clusterconfigpb.AccessGraphSettings) AccessGraphSettings { + if c == nil { + // preserving nils simplifies error flow-control + return nil + } + return sealedAccessGraphSettings{c} +} + +func (a sealedAccessGraphSettings) SecretsScanConfig() clusterconfigpb.AccessGraphSecretsScanConfig { + return a.GetSpec().GetSecretsScanConfig() +} + +func (a sealedAccessGraphSettings) Clone() *clusterconfigpb.AccessGraphSettings { + return protobuf.Clone(a.AccessGraphSettings).(*clusterconfigpb.AccessGraphSettings) +} diff --git a/lib/services/readonly/readonly_test.go b/lib/services/readonly/readonly_test.go index 8876f27a7b64b..61bd34c346955 100644 --- a/lib/services/readonly/readonly_test.go +++ b/lib/services/readonly/readonly_test.go @@ -24,14 +24,18 @@ import ( "time" "github.com/stretchr/testify/require" + protobuf "google.golang.org/protobuf/proto" + clusterconfigpb "github.com/gravitational/teleport/api/gen/proto/go/teleport/clusterconfig/v1" + headerv1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/header/v1" "github.com/gravitational/teleport/api/types" ) type testUpstream struct { - auth types.AuthPreference - networking types.ClusterNetworkingConfig - recording types.SessionRecordingConfig + auth types.AuthPreference + networking types.ClusterNetworkingConfig + recording types.SessionRecordingConfig + accessGraphSettings *clusterconfigpb.AccessGraphSettings } func (u *testUpstream) GetAuthPreference(ctx context.Context) (types.AuthPreference, error) { @@ -46,6 +50,10 @@ func (u *testUpstream) GetSessionRecordingConfig(ctx context.Context) (types.Ses return u.recording.Clone(), nil } +func (u *testUpstream) GetAccessGraphSettings(ctx context.Context) (*clusterconfigpb.AccessGraphSettings, error) { + return protobuf.Clone(u.accessGraphSettings).(*clusterconfigpb.AccessGraphSettings), nil +} + // TestAuthPreference tests the GetReadOnlyAuthPreference method and verifies the read-only protections // on the returned resource. func TestAuthPreference(t *testing.T) { @@ -141,6 +149,38 @@ func TestCloneBreaksEquality(t *testing.T) { require.False(t, pointersEqual(recording, recording.Clone())) } +func TestAccessGraphSettings(t *testing.T) { + // Create a new cache instance. + cache, err := NewCache(CacheConfig{ + Upstream: &testUpstream{ + accessGraphSettings: &clusterconfigpb.AccessGraphSettings{ + Kind: types.KindAccessGraphSettings, + Metadata: &headerv1.Metadata{ + Name: "access-graph-settings", + }, + }, + }, + TTL: time.Hour, + }) + require.NoError(t, err) + + // Get the session recording config resource. + ag, err := cache.GetReadOnlyAccessGraphSettings(context.Background()) + require.NoError(t, err) + + // Verify that the access graph settings resource cannot be cast back to a write-supporting interface. + // We do this by checking if the resource is of the sealedAccessGraphSettings type, which is a read-only + // wrapper around the original resource and should not be directly castable back to the original type. + _, ok := ag.(sealedAccessGraphSettings) + require.True(t, ok) + + ag2, err := cache.GetReadOnlyAccessGraphSettings(context.Background()) + require.NoError(t, err) + + // verify pointer equality (i.e. that subsequent reads return the same shared resource). + require.True(t, pointersEqual(ag, ag2)) +} + // pointersEqual is a helper function that compares two pointers for equality. used to improve readability // and avoid incorrect lints. func pointersEqual(a, b interface{}) bool { From 72018c9ab825eb7023bb9e777b7e9233f64ba980 Mon Sep 17 00:00:00 2001 From: Tiago Silva Date: Fri, 19 Jul 2024 12:39:57 +0100 Subject: [PATCH 15/25] [sec_scan][13] add `AccessGraphSettings` gRPC implementation (#44021) This PR introduces the gRPC implementation for the CRUD operations related to `AccessGraphSettings`. This PR is part of https://github.com/gravitational/access-graph/issues/637. Signed-off-by: Tiago Silva --- .../clusterconfig/clusterconfigv1/service.go | 207 ++++++++ .../clusterconfigv1/service_test.go | 494 ++++++++++++++++-- lib/auth/grpcserver_test.go | 7 +- 3 files changed, 675 insertions(+), 33 deletions(-) diff --git a/lib/auth/clusterconfig/clusterconfigv1/service.go b/lib/auth/clusterconfig/clusterconfigv1/service.go index d7ff4004f223b..8a98b855996cd 100644 --- a/lib/auth/clusterconfig/clusterconfigv1/service.go +++ b/lib/auth/clusterconfig/clusterconfigv1/service.go @@ -25,6 +25,7 @@ import ( "github.com/gravitational/teleport/api/constants" clusterconfigpb "github.com/gravitational/teleport/api/gen/proto/go/teleport/clusterconfig/v1" "github.com/gravitational/teleport/api/types" + "github.com/gravitational/teleport/api/types/clusterconfig" apievents "github.com/gravitational/teleport/api/types/events" "github.com/gravitational/teleport/lib/authz" dtconfig "github.com/gravitational/teleport/lib/devicetrust/config" @@ -62,6 +63,10 @@ type Backend interface { CreateSessionRecordingConfig(ctx context.Context, preference types.SessionRecordingConfig) (types.SessionRecordingConfig, error) UpdateSessionRecordingConfig(ctx context.Context, preference types.SessionRecordingConfig) (types.SessionRecordingConfig, error) UpsertSessionRecordingConfig(ctx context.Context, preference types.SessionRecordingConfig) (types.SessionRecordingConfig, error) + + CreateAccessGraphSettings(context.Context, *clusterconfigpb.AccessGraphSettings) (*clusterconfigpb.AccessGraphSettings, error) + UpdateAccessGraphSettings(context.Context, *clusterconfigpb.AccessGraphSettings) (*clusterconfigpb.AccessGraphSettings, error) + UpsertAccessGraphSettings(context.Context, *clusterconfigpb.AccessGraphSettings) (*clusterconfigpb.AccessGraphSettings, error) } // ServiceConfig contain dependencies required to create a [Service]. @@ -932,12 +937,214 @@ func (s *Service) GetClusterAccessGraphConfig(ctx context.Context, _ *clustercon }, nil } + var sshScanEnabled bool + switch obj, err := s.readOnlyCache.GetReadOnlyAccessGraphSettings(ctx); { + case err != nil && !trace.IsNotFound(err): + return nil, trace.Wrap(err) + case err == nil: + sshScanEnabled = obj.SecretsScanConfig() == clusterconfigpb.AccessGraphSecretsScanConfig_ACCESS_GRAPH_SECRETS_SCAN_CONFIG_ENABLED + } + return &clusterconfigpb.GetClusterAccessGraphConfigResponse{ AccessGraph: &clusterconfigpb.AccessGraphConfig{ Enabled: s.accessGraph.Enabled, Address: s.accessGraph.Address, Ca: s.accessGraph.CA, Insecure: s.accessGraph.Insecure, + SecretsScanConfig: &clusterconfigpb.AccessGraphSecretsScanConfiguration{ + SshScanEnabled: sshScanEnabled, + }, }, }, nil } + +func (s *Service) GetAccessGraphSettings(ctx context.Context, _ *clusterconfigpb.GetAccessGraphSettingsRequest) (*clusterconfigpb.AccessGraphSettings, error) { + authzCtx, err := s.authorizer.Authorize(ctx) + if err != nil { + return nil, trace.Wrap(err) + } + + if err := authzCtx.CheckAccessToKind(types.KindAccessGraphSettings, types.VerbRead); err != nil { + return nil, trace.Wrap(err) + } + + cfg, err := s.readOnlyCache.GetReadOnlyAccessGraphSettings(ctx) + if err != nil { + return nil, trace.Wrap(err) + } + + return cfg.Clone(), nil +} + +func (s *Service) CreateAccessGraphSettings(ctx context.Context, req *clusterconfigpb.CreateAccessGraphSettingsRequest) (*clusterconfigpb.AccessGraphSettings, error) { + authzCtx, err := s.authorizer.Authorize(ctx) + if err != nil { + return nil, trace.Wrap(err) + } + + if err := authzCtx.CheckAccessToKind(types.KindAccessGraphSettings, types.VerbCreate); err != nil { + return nil, trace.Wrap(err) + } + + if !authz.HasBuiltinRole(*authzCtx, string(types.RoleAuth)) { + return nil, trace.AccessDenied("this request can be only executed by an auth server") + } + + cfg := req.GetAccessGraphSettings() + if err := clusterconfig.ValidateAccessGraphSettings(cfg); err != nil { + return nil, trace.Wrap(err) + } + + created, err := s.backend.CreateAccessGraphSettings(ctx, cfg) + if auditErr := s.emitter.EmitAuditEvent(ctx, &apievents.AccessGraphSettingsUpdate{ + Metadata: apievents.Metadata{ + Type: events.AccessGraphSettingsUpdateEvent, + Code: events.AccessGraphSettingsUpdateCode, + }, + UserMetadata: authzCtx.GetUserMetadata(), + ConnectionMetadata: authz.ConnectionMetadata(ctx), + Status: eventStatus(err), + }); auditErr != nil { + slog.WarnContext(ctx, "Failed to emit AccessGraphSettings update event.", "error", auditErr) + } + + // don't handle the update error until after we emit an audit event + if err != nil { + return nil, trace.Wrap(err) + } + + return created, nil +} + +func (s *Service) UpdateAccessGraphSettings(ctx context.Context, req *clusterconfigpb.UpdateAccessGraphSettingsRequest) (*clusterconfigpb.AccessGraphSettings, error) { + authzCtx, err := s.authorizer.Authorize(ctx) + if err != nil { + return nil, trace.Wrap(err) + } + + if err := authzCtx.CheckAccessToKind(types.KindAccessGraphSettings, types.VerbUpdate); err != nil { + return nil, trace.Wrap(err) + } + + if err := authzCtx.AuthorizeAdminActionAllowReusedMFA(); err != nil { + return nil, trace.Wrap(err) + } + + if !modules.GetModules().Features().GetEntitlement(entitlements.Policy).Enabled && !modules.GetModules().Features().AccessGraph { + return nil, trace.AccessDenied("access graph is feature isn't enabled") + } + + cfg := req.GetAccessGraphSettings() + if err := clusterconfig.ValidateAccessGraphSettings(cfg); err != nil { + return nil, trace.Wrap(err) + } + + rsp, err := s.backend.UpdateAccessGraphSettings(ctx, cfg) + + if auditErr := s.emitter.EmitAuditEvent(ctx, &apievents.AccessGraphSettingsUpdate{ + Metadata: apievents.Metadata{ + Type: events.AccessGraphSettingsUpdateEvent, + Code: events.AccessGraphSettingsUpdateCode, + }, + UserMetadata: authzCtx.GetUserMetadata(), + ConnectionMetadata: authz.ConnectionMetadata(ctx), + Status: eventStatus(err), + }); auditErr != nil { + slog.WarnContext(ctx, "Failed to emit AccessGraphSettings update event.", "error", auditErr) + } + + if err != nil { + return nil, trace.Wrap(err) + } + + return rsp, nil +} + +func (s *Service) UpsertAccessGraphSettings(ctx context.Context, req *clusterconfigpb.UpsertAccessGraphSettingsRequest) (*clusterconfigpb.AccessGraphSettings, error) { + authzCtx, err := s.authorizer.Authorize(ctx) + if err != nil { + return nil, trace.Wrap(err) + } + + if err := authzCtx.CheckAccessToKind(types.KindAccessGraphSettings, types.VerbCreate, types.VerbUpdate); err != nil { + return nil, trace.Wrap(err) + } + + if err := authzCtx.AuthorizeAdminActionAllowReusedMFA(); err != nil { + return nil, trace.Wrap(err) + } + + if !modules.GetModules().Features().GetEntitlement(entitlements.Policy).Enabled && !modules.GetModules().Features().AccessGraph { + return nil, trace.AccessDenied("access graph is feature isn't enabled") + } + + cfg := req.GetAccessGraphSettings() + if err := clusterconfig.ValidateAccessGraphSettings(cfg); err != nil { + return nil, trace.Wrap(err) + } + + rsp, err := s.backend.UpsertAccessGraphSettings(ctx, cfg) + + if auditErr := s.emitter.EmitAuditEvent(ctx, &apievents.AccessGraphSettingsUpdate{ + Metadata: apievents.Metadata{ + Type: events.AccessGraphSettingsUpdateEvent, + Code: events.AccessGraphSettingsUpdateCode, + }, + UserMetadata: authzCtx.GetUserMetadata(), + ConnectionMetadata: authz.ConnectionMetadata(ctx), + Status: eventStatus(err), + }); auditErr != nil { + slog.WarnContext(ctx, "Failed to emit AccessGraphSettings update event.", "error", auditErr) + } + + if err != nil { + return nil, trace.Wrap(err) + } + + return rsp, nil +} + +func (s *Service) ResetAccessGraphSettings(ctx context.Context, _ *clusterconfigpb.ResetAccessGraphSettingsRequest) (*clusterconfigpb.AccessGraphSettings, error) { + authzCtx, err := s.authorizer.Authorize(ctx) + if err != nil { + return nil, trace.Wrap(err) + } + + if err := authzCtx.CheckAccessToKind(types.KindAccessGraphSettings, types.VerbUpdate); err != nil { + return nil, trace.Wrap(err) + } + + if err := authzCtx.AuthorizeAdminActionAllowReusedMFA(); err != nil { + return nil, trace.Wrap(err) + } + + if !modules.GetModules().Features().GetEntitlement(entitlements.Policy).Enabled && !modules.GetModules().Features().AccessGraph { + return nil, trace.AccessDenied("access graph is feature isn't enabled") + } + + obj, err := clusterconfig.NewAccessGraphSettings(&clusterconfigpb.AccessGraphSettingsSpec{ + SecretsScanConfig: clusterconfigpb.AccessGraphSecretsScanConfig_ACCESS_GRAPH_SECRETS_SCAN_CONFIG_DISABLED, + }) + if err != nil { + return nil, trace.Wrap(err) + } + rsp, err := s.backend.UpsertAccessGraphSettings(ctx, obj) + + if auditErr := s.emitter.EmitAuditEvent(ctx, &apievents.AccessGraphSettingsUpdate{ + Metadata: apievents.Metadata{ + Type: events.AccessGraphSettingsUpdateEvent, + Code: events.AccessGraphSettingsUpdateCode, + }, + UserMetadata: authzCtx.GetUserMetadata(), + ConnectionMetadata: authz.ConnectionMetadata(ctx), + Status: eventStatus(err), + }); auditErr != nil { + slog.WarnContext(ctx, "Failed to emit AccessGraphSettings update event.", "error", auditErr) + } + + if err != nil { + return nil, trace.Wrap(err) + } + + return rsp, nil +} diff --git a/lib/auth/clusterconfig/clusterconfigv1/service_test.go b/lib/auth/clusterconfig/clusterconfigv1/service_test.go index 7bda35fabc733..714567f3fb505 100644 --- a/lib/auth/clusterconfig/clusterconfigv1/service_test.go +++ b/lib/auth/clusterconfig/clusterconfigv1/service_test.go @@ -32,6 +32,7 @@ import ( "github.com/gravitational/teleport/api/constants" clusterconfigpb "github.com/gravitational/teleport/api/gen/proto/go/teleport/clusterconfig/v1" "github.com/gravitational/teleport/api/types" + "github.com/gravitational/teleport/api/types/clusterconfig" apievents "github.com/gravitational/teleport/api/types/events" "github.com/gravitational/teleport/lib/auth/clusterconfig/clusterconfigv1" "github.com/gravitational/teleport/lib/authz" @@ -77,7 +78,7 @@ func TestCreateAuthPreference(t *testing.T) { return authRoleContext, nil }), assertion: func(t *testing.T, created types.AuthPreference, err error) { - require.NoError(t, err, "got (%v), expected auth role to create auth preference", err) + require.NoError(t, err, "got (%v), expected auth role to create auth mutator", err) require.NotNil(t, created) }, }, @@ -106,7 +107,7 @@ func TestCreateAuthPreference(t *testing.T) { pp.Spec.RequireMFAType = types.RequireMFAType_HARDWARE_KEY_PIN }, assertion: func(t *testing.T, created types.AuthPreference, err error) { - require.NoError(t, err, "got (%v), expected auth role to create auth preference", err) + require.NoError(t, err, "got (%v), expected auth role to create auth mutator", err) require.NotNil(t, created) }, }, @@ -1673,13 +1674,14 @@ func (f fakeChecker) CheckAccessToRule(context services.RuleContext, namespace s } type envConfig struct { - authorizer authz.Authorizer - emitter apievents.Emitter - defaultAuthPreference types.AuthPreference - defaultNetworkingConfig types.ClusterNetworkingConfig - defaultRecordingConfig types.SessionRecordingConfig - service services.ClusterConfiguration - accessGraphConfig clusterconfigv1.AccessGraphConfig + authorizer authz.Authorizer + emitter apievents.Emitter + defaultAuthPreference types.AuthPreference + defaultNetworkingConfig types.ClusterNetworkingConfig + defaultRecordingConfig types.SessionRecordingConfig + service services.ClusterConfiguration + accessGraphConfig clusterconfigv1.AccessGraphConfig + defaultAccessGraphSettings *clusterconfigpb.AccessGraphSettings } type serviceOpt = func(config *envConfig) @@ -1719,12 +1721,19 @@ func withAccessGraphConfig(cfg clusterconfigv1.AccessGraphConfig) serviceOpt { } } +func withAccessGraphSettings(cfg *clusterconfigpb.AccessGraphSettings) serviceOpt { + return func(config *envConfig) { + config.defaultAccessGraphSettings = cfg + } +} + type env struct { *clusterconfigv1.Service - emitter *eventstest.ChannelEmitter - defaultPreference types.AuthPreference - defaultNetworkingConfig types.ClusterNetworkingConfig - defaultRecordingConfig types.SessionRecordingConfig + emitter *eventstest.ChannelEmitter + defaultPreference types.AuthPreference + defaultNetworkingConfig types.ClusterNetworkingConfig + defaultRecordingConfig types.SessionRecordingConfig + defaultAccessGraphSettings *clusterconfigpb.AccessGraphSettings } func newTestEnv(opts ...serviceOpt) (*env, error) { @@ -1763,7 +1772,7 @@ func newTestEnv(opts ...serviceOpt) (*env, error) { if cfg.defaultAuthPreference != nil { defaultPreference, err = cfg.service.CreateAuthPreference(ctx, cfg.defaultAuthPreference) if err != nil { - return nil, trace.Wrap(err, "creating default auth preference") + return nil, trace.Wrap(err, "creating default auth mutator") } } @@ -1783,16 +1792,33 @@ func newTestEnv(opts ...serviceOpt) (*env, error) { } } + var defaultAccessGraphSettings *clusterconfigpb.AccessGraphSettings + if cfg.defaultAccessGraphSettings != nil { + defaultAccessGraphSettings, err = cfg.service.CreateAccessGraphSettings(ctx, cfg.defaultAccessGraphSettings) + if err != nil { + return nil, trace.Wrap(err, "creating access graph settings") + } + } + return &env{ - Service: svc, - defaultPreference: defaultPreference, - defaultNetworkingConfig: defaultNetworkingConfig, - defaultRecordingConfig: defaultSessionRecordingConfig, - emitter: emitter, + Service: svc, + defaultPreference: defaultPreference, + defaultNetworkingConfig: defaultNetworkingConfig, + defaultRecordingConfig: defaultSessionRecordingConfig, + defaultAccessGraphSettings: defaultAccessGraphSettings, + emitter: emitter, }, nil } func TestGetAccessGraphConfig(t *testing.T) { + + settings, err := clusterconfig.NewAccessGraphSettings( + &clusterconfigpb.AccessGraphSettingsSpec{ + SecretsScanConfig: clusterconfigpb.AccessGraphSecretsScanConfig_ACCESS_GRAPH_SECRETS_SCAN_CONFIG_ENABLED, + }, + ) + require.NoError(t, err) + cfgEnabled := clusterconfigv1.AccessGraphConfig{ Enabled: true, Address: "address", @@ -1800,12 +1826,13 @@ func TestGetAccessGraphConfig(t *testing.T) { Insecure: true, } cases := []struct { - name string - accessGraphConfig clusterconfigv1.AccessGraphConfig - role types.SystemRole - testSetup func(*testing.T) - errorAssertion require.ErrorAssertionFunc - responseAssertion *clusterconfigpb.GetClusterAccessGraphConfigResponse + name string + accessGraphConfig clusterconfigv1.AccessGraphConfig + role types.SystemRole + testSetup func(*testing.T) + errorAssertion require.ErrorAssertionFunc + responseAssertion *clusterconfigpb.GetClusterAccessGraphConfigResponse + accessGraphSettings *clusterconfigpb.AccessGraphSettings }{ { name: "authorized proxy with non empty access graph config; Policy module is disabled", @@ -1836,10 +1863,11 @@ func TestGetAccessGraphConfig(t *testing.T) { errorAssertion: require.NoError, responseAssertion: &clusterconfigpb.GetClusterAccessGraphConfigResponse{ AccessGraph: &clusterconfigpb.AccessGraphConfig{ - Enabled: true, - Insecure: true, - Address: "address", - Ca: []byte("ca"), + Enabled: true, + Insecure: true, + Address: "address", + Ca: []byte("ca"), + SecretsScanConfig: &clusterconfigpb.AccessGraphSecretsScanConfiguration{}, }, }, }, @@ -1858,12 +1886,41 @@ func TestGetAccessGraphConfig(t *testing.T) { }, accessGraphConfig: cfgEnabled, errorAssertion: require.NoError, + responseAssertion: &clusterconfigpb.GetClusterAccessGraphConfigResponse{ + AccessGraph: &clusterconfigpb.AccessGraphConfig{ + Enabled: true, + Insecure: true, + Address: "address", + Ca: []byte("ca"), + SecretsScanConfig: &clusterconfigpb.AccessGraphSecretsScanConfiguration{}, + }, + }, + }, + { + name: "Policy module is enabled with secrets scan option", + role: types.RoleDiscovery, + testSetup: func(t *testing.T) { + m := modules.TestModules{ + TestFeatures: modules.Features{ + Entitlements: map[entitlements.EntitlementKind]modules.EntitlementInfo{ + entitlements.Policy: {Enabled: true}, + }, + }, + } + modules.SetTestModules(t, &m) + }, + accessGraphConfig: cfgEnabled, + accessGraphSettings: settings, + errorAssertion: require.NoError, responseAssertion: &clusterconfigpb.GetClusterAccessGraphConfigResponse{ AccessGraph: &clusterconfigpb.AccessGraphConfig{ Enabled: true, Insecure: true, Address: "address", Ca: []byte("ca"), + SecretsScanConfig: &clusterconfigpb.AccessGraphSecretsScanConfiguration{ + SshScanEnabled: true, + }, }, }, }, @@ -1881,7 +1938,8 @@ func TestGetAccessGraphConfig(t *testing.T) { authorizer := authz.AuthorizerFunc(func(ctx context.Context) (*authz.Context, error) { return authRoleContext, nil }) - env, err := newTestEnv(withAuthorizer(authorizer), withAccessGraphConfig(test.accessGraphConfig)) + + env, err := newTestEnv(withAuthorizer(authorizer), withAccessGraphConfig(test.accessGraphConfig), withAccessGraphSettings(test.accessGraphSettings)) require.NoError(t, err, "creating test service") got, err := env.GetClusterAccessGraphConfig(context.Background(), &clusterconfigpb.GetClusterAccessGraphConfigRequest{}) @@ -1891,3 +1949,379 @@ func TestGetAccessGraphConfig(t *testing.T) { }) } } + +func TestGetAccessGraphSettings(t *testing.T) { + cases := []struct { + name string + authorizer authz.Authorizer + assertion func(t *testing.T, err error) + }{ + { + name: "unauthorized", + authorizer: authz.AuthorizerFunc(func(ctx context.Context) (*authz.Context, error) { + return &authz.Context{ + Checker: fakeChecker{}, + }, nil + }), + assertion: func(t *testing.T, err error) { + require.True(t, trace.IsAccessDenied(err), "got (%v), expected unauthorized user to be prevented from getting access graph settings", err) + }, + }, { + name: "authorized", + authorizer: authz.AuthorizerFunc(func(ctx context.Context) (*authz.Context, error) { + return &authz.Context{ + Checker: fakeChecker{ + rules: map[string][]string{types.KindAccessGraphSettings: {types.VerbRead}}, + }, + }, nil + }), + assertion: func(t *testing.T, err error) { + require.NoError(t, err) + }, + }, + } + + for _, test := range cases { + t.Run(test.name, func(t *testing.T) { + settings, err := clusterconfig.NewAccessGraphSettings( + &clusterconfigpb.AccessGraphSettingsSpec{ + SecretsScanConfig: clusterconfigpb.AccessGraphSecretsScanConfig_ACCESS_GRAPH_SECRETS_SCAN_CONFIG_DISABLED, + }, + ) + require.NoError(t, err) + env, err := newTestEnv(withAuthorizer(test.authorizer), withAccessGraphSettings(settings)) + require.NoError(t, err, "creating test service") + + got, err := env.GetAccessGraphSettings(context.Background(), &clusterconfigpb.GetAccessGraphSettingsRequest{}) + test.assertion(t, err) + if err == nil { + require.Empty(t, cmp.Diff(settings, got, cmpopts.IgnoreFields(types.Metadata{}, "Revision"), protocmp.Transform())) + } + }) + } +} + +func TestUpdateAccessGraphSettings(t *testing.T) { + cases := []struct { + name string + mutator func(p *clusterconfigpb.AccessGraphSettings) + authorizer authz.Authorizer + testSetup func(*testing.T) + assertion func(t *testing.T, updated *clusterconfigpb.AccessGraphSettings, err error) + }{ + { + name: "unauthorized", + authorizer: authz.AuthorizerFunc(func(ctx context.Context) (*authz.Context, error) { + return &authz.Context{ + Checker: fakeChecker{}, + }, nil + }), + assertion: func(t *testing.T, updated *clusterconfigpb.AccessGraphSettings, err error) { + require.True(t, trace.IsAccessDenied(err), "got (%v), expected unauthorized user to prevent updating access graph settings", err) + }, + }, + { + name: "no admin action", + authorizer: authz.AuthorizerFunc(func(ctx context.Context) (*authz.Context, error) { + return &authz.Context{ + Checker: fakeChecker{ + rules: map[string][]string{types.KindAccessGraphSettings: {types.VerbUpdate}}, + }, + }, nil + }), + assertion: func(t *testing.T, updated *clusterconfigpb.AccessGraphSettings, err error) { + require.True(t, trace.IsAccessDenied(err), "got (%v), expected lack of admin action to prevent updating access graph settings", err) + }, + }, + { + name: "update without access graph being enabled", + + authorizer: authz.AuthorizerFunc(func(ctx context.Context) (*authz.Context, error) { + return &authz.Context{ + Checker: fakeChecker{ + rules: map[string][]string{types.KindAccessGraphSettings: {types.VerbUpdate}}, + }, + AdminActionAuthState: authz.AdminActionAuthMFAVerified, + Identity: authz.LocalUser{ + Username: "llama", + Identity: tlsca.Identity{Username: "llama"}, + }, + }, nil + }), + mutator: func(p *clusterconfigpb.AccessGraphSettings) { + p.Spec.SecretsScanConfig = clusterconfigpb.AccessGraphSecretsScanConfig_ACCESS_GRAPH_SECRETS_SCAN_CONFIG_ENABLED + }, + assertion: func(t *testing.T, updated *clusterconfigpb.AccessGraphSettings, err error) { + require.Error(t, err) + }, + }, + { + name: "updated", + testSetup: func(t *testing.T) { + m := modules.TestModules{ + TestFeatures: modules.Features{ + Entitlements: map[entitlements.EntitlementKind]modules.EntitlementInfo{ + entitlements.Policy: {Enabled: true}, + }, + }, + } + modules.SetTestModules(t, &m) + }, + authorizer: authz.AuthorizerFunc(func(ctx context.Context) (*authz.Context, error) { + return &authz.Context{ + Checker: fakeChecker{ + rules: map[string][]string{types.KindAccessGraphSettings: {types.VerbUpdate}}, + }, + AdminActionAuthState: authz.AdminActionAuthMFAVerified, + Identity: authz.LocalUser{ + Username: "llama", + Identity: tlsca.Identity{Username: "llama"}, + }, + }, nil + }), + mutator: func(p *clusterconfigpb.AccessGraphSettings) { + p.Spec.SecretsScanConfig = clusterconfigpb.AccessGraphSecretsScanConfig_ACCESS_GRAPH_SECRETS_SCAN_CONFIG_ENABLED + }, + assertion: func(t *testing.T, updated *clusterconfigpb.AccessGraphSettings, err error) { + require.NoError(t, err) + require.Equal(t, clusterconfigpb.AccessGraphSecretsScanConfig_ACCESS_GRAPH_SECRETS_SCAN_CONFIG_ENABLED, updated.GetSpec().GetSecretsScanConfig()) + }, + }, + } + + for _, test := range cases { + t.Run(test.name, func(t *testing.T) { + if test.testSetup != nil { + test.testSetup(t) + } + settings, err := clusterconfig.NewAccessGraphSettings( + &clusterconfigpb.AccessGraphSettingsSpec{ + SecretsScanConfig: clusterconfigpb.AccessGraphSecretsScanConfig_ACCESS_GRAPH_SECRETS_SCAN_CONFIG_ENABLED, + }, + ) + require.NoError(t, err) + env, err := newTestEnv(withAuthorizer(test.authorizer), withAccessGraphSettings(settings)) + require.NoError(t, err, "creating test service") + + // Set revisions to allow the update to succeed. + pref := env.defaultAccessGraphSettings + if test.mutator != nil { + test.mutator(pref) + } + + updated, err := env.UpdateAccessGraphSettings(context.Background(), &clusterconfigpb.UpdateAccessGraphSettingsRequest{AccessGraphSettings: pref}) + test.assertion(t, updated, err) + }) + } +} + +func TestUpsertAccessGraphSettings(t *testing.T) { + cases := []struct { + name string + testSetup func(*testing.T) + mutator func(p *clusterconfigpb.AccessGraphSettings) + authorizer authz.Authorizer + assertion func(t *testing.T, updated *clusterconfigpb.AccessGraphSettings, err error) + }{ + { + name: "unauthorized", + authorizer: authz.AuthorizerFunc(func(ctx context.Context) (*authz.Context, error) { + return &authz.Context{ + Checker: fakeChecker{}, + }, nil + }), + assertion: func(t *testing.T, updated *clusterconfigpb.AccessGraphSettings, err error) { + require.True(t, trace.IsAccessDenied(err), "got (%v), expected unauthorized user to prevent upserting access graph settings", err) + }, + }, + { + name: "access prevented", + authorizer: authz.AuthorizerFunc(func(ctx context.Context) (*authz.Context, error) { + return &authz.Context{ + Checker: fakeChecker{ + rules: map[string][]string{types.KindAccessGraphSettings: {types.VerbUpdate}}, + }, + AdminActionAuthState: authz.AdminActionAuthUnauthorized, + }, nil + }), + assertion: func(t *testing.T, updated *clusterconfigpb.AccessGraphSettings, err error) { + require.True(t, trace.IsAccessDenied(err), "got (%v), expected lack of admin action to prevent upserting access graph settings", err) + }, + }, + { + name: "no admin action", + authorizer: authz.AuthorizerFunc(func(ctx context.Context) (*authz.Context, error) { + return &authz.Context{ + Checker: fakeChecker{ + rules: map[string][]string{types.KindAccessGraphSettings: {types.VerbCreate, types.VerbUpdate}}, + }, + AdminActionAuthState: authz.AdminActionAuthUnauthorized, + }, nil + }), + assertion: func(t *testing.T, updated *clusterconfigpb.AccessGraphSettings, err error) { + require.True(t, trace.IsAccessDenied(err), "got (%v), expected lack of admin action to prevent upserting access graph settings", err) + }, + }, + { + name: "policy not enabled", + authorizer: authz.AuthorizerFunc(func(ctx context.Context) (*authz.Context, error) { + return &authz.Context{ + Checker: fakeChecker{ + rules: map[string][]string{types.KindAccessGraphSettings: {types.VerbCreate, types.VerbUpdate}}, + }, + AdminActionAuthState: authz.AdminActionAuthMFAVerified, + }, nil + }), + mutator: func(p *clusterconfigpb.AccessGraphSettings) { + + }, + assertion: func(t *testing.T, updated *clusterconfigpb.AccessGraphSettings, err error) { + require.True(t, trace.IsAccessDenied(err), "got (%v), upserting access graph settings must fail when policy isn't enabled", err) + }, + }, + + { + name: "upserted", + testSetup: func(t *testing.T) { + m := modules.TestModules{ + TestFeatures: modules.Features{ + Entitlements: map[entitlements.EntitlementKind]modules.EntitlementInfo{ + entitlements.Policy: {Enabled: true}, + }, + }, + } + modules.SetTestModules(t, &m) + }, + authorizer: authz.AuthorizerFunc(func(ctx context.Context) (*authz.Context, error) { + return &authz.Context{ + Checker: fakeChecker{ + rules: map[string][]string{types.KindAccessGraphSettings: {types.VerbUpdate, types.VerbCreate}}, + }, + AdminActionAuthState: authz.AdminActionAuthMFAVerified, + Identity: authz.LocalUser{ + Username: "llama", + Identity: tlsca.Identity{Username: "llama"}, + }, + }, nil + }), + mutator: func(p *clusterconfigpb.AccessGraphSettings) { + p.Spec.SecretsScanConfig = clusterconfigpb.AccessGraphSecretsScanConfig_ACCESS_GRAPH_SECRETS_SCAN_CONFIG_ENABLED + }, + assertion: func(t *testing.T, updated *clusterconfigpb.AccessGraphSettings, err error) { + require.NoError(t, err) + require.Equal(t, clusterconfigpb.AccessGraphSecretsScanConfig_ACCESS_GRAPH_SECRETS_SCAN_CONFIG_ENABLED, updated.Spec.SecretsScanConfig) + }, + }, + } + + for _, test := range cases { + t.Run(test.name, func(t *testing.T) { + if test.testSetup != nil { + test.testSetup(t) + } + settings, err := clusterconfig.NewAccessGraphSettings( + &clusterconfigpb.AccessGraphSettingsSpec{ + SecretsScanConfig: clusterconfigpb.AccessGraphSecretsScanConfig_ACCESS_GRAPH_SECRETS_SCAN_CONFIG_DISABLED, + }) + + require.NoError(t, err) + + env, err := newTestEnv(withAuthorizer(test.authorizer), withAccessGraphSettings(settings)) + require.NoError(t, err, "creating test service") + + // Discard revisions to allow the update to succeed. + pref := settings + if test.mutator != nil { + test.mutator(pref) + } + + updated, err := env.UpsertAccessGraphSettings(context.Background(), &clusterconfigpb.UpsertAccessGraphSettingsRequest{AccessGraphSettings: pref}) + test.assertion(t, updated, err) + }) + } +} + +func TestResetAccessGraphSettings(t *testing.T) { + cases := []struct { + name string + authorizer authz.Authorizer + testSetup func(*testing.T) + assertion func(t *testing.T, reset *clusterconfigpb.AccessGraphSettings, err error) + }{ + { + name: "unauthorized", + authorizer: authz.AuthorizerFunc(func(ctx context.Context) (*authz.Context, error) { + return &authz.Context{ + Checker: fakeChecker{}, + }, nil + }), + assertion: func(t *testing.T, reset *clusterconfigpb.AccessGraphSettings, err error) { + assert.Nil(t, reset) + require.True(t, trace.IsAccessDenied(err), "got (%v), expected unauthorized user to prevent resetting access graph settings", err) + }, + }, + { + name: "no admin action", + authorizer: authz.AuthorizerFunc(func(ctx context.Context) (*authz.Context, error) { + return &authz.Context{ + Checker: fakeChecker{ + rules: map[string][]string{types.KindAccessGraphSettings: {types.VerbUpdate}}, + }, + }, nil + }), + assertion: func(t *testing.T, reset *clusterconfigpb.AccessGraphSettings, err error) { + assert.Nil(t, reset) + require.True(t, trace.IsAccessDenied(err), "got (%v), expected lack of admin action to prevent resetting access graph settings", err) + }, + }, + { + name: "reset", + testSetup: func(t *testing.T) { + m := modules.TestModules{ + TestFeatures: modules.Features{ + Entitlements: map[entitlements.EntitlementKind]modules.EntitlementInfo{ + entitlements.Policy: {Enabled: true}, + }, + }, + } + modules.SetTestModules(t, &m) + }, + authorizer: authz.AuthorizerFunc(func(ctx context.Context) (*authz.Context, error) { + return &authz.Context{ + Checker: fakeChecker{ + rules: map[string][]string{types.KindAccessGraphSettings: {types.VerbUpdate, types.VerbCreate}}, + }, + AdminActionAuthState: authz.AdminActionAuthMFAVerified, + Identity: authz.LocalUser{ + Username: "llama", + Identity: tlsca.Identity{Username: "llama"}, + }, + }, nil + }), + assertion: func(t *testing.T, reset *clusterconfigpb.AccessGraphSettings, err error) { + require.NoError(t, err) + require.Equal(t, clusterconfigpb.AccessGraphSecretsScanConfig_ACCESS_GRAPH_SECRETS_SCAN_CONFIG_DISABLED, reset.GetSpec().GetSecretsScanConfig()) + }, + }, + } + + for _, test := range cases { + t.Run(test.name, func(t *testing.T) { + if test.testSetup != nil { + test.testSetup(t) + } + settings, err := clusterconfig.NewAccessGraphSettings( + &clusterconfigpb.AccessGraphSettingsSpec{ + SecretsScanConfig: clusterconfigpb.AccessGraphSecretsScanConfig_ACCESS_GRAPH_SECRETS_SCAN_CONFIG_DISABLED, + }) + + require.NoError(t, err) + + env, err := newTestEnv(withAuthorizer(test.authorizer), withAccessGraphSettings(settings)) + require.NoError(t, err, "creating test service") + + reset, err := env.ResetAccessGraphSettings(context.Background(), &clusterconfigpb.ResetAccessGraphSettingsRequest{}) + test.assertion(t, reset, err) + }) + } +} diff --git a/lib/auth/grpcserver_test.go b/lib/auth/grpcserver_test.go index 3a5d98f284365..e74fba8ffbe58 100644 --- a/lib/auth/grpcserver_test.go +++ b/lib/auth/grpcserver_test.go @@ -4475,9 +4475,10 @@ func TestGetAccessGraphConfig(t *testing.T) { user, _, err := CreateUserAndRole(server.Auth(), "test", []string{"role"}, nil) require.NoError(t, err) positiveResponse := &clusterconfigpb.AccessGraphConfig{ - Enabled: true, - Ca: []byte("ca"), - Address: "addr", + Enabled: true, + Ca: []byte("ca"), + Address: "addr", + SecretsScanConfig: &clusterconfigpb.AccessGraphSecretsScanConfiguration{}, } tests := []struct { From fe41289ee39f9236c7bc3c994a62b16f146a5a35 Mon Sep 17 00:00:00 2001 From: Tiago Silva Date: Mon, 22 Jul 2024 10:17:14 +0100 Subject: [PATCH 16/25] [sec_scan][14] create `AccessGraphSettings` on first auth init (#44032) * [sec_scan][14] create `AccessGraphSettings` on first auth init This PR adds a init script that sets `AccessGraphSettings` into Teleport backend when auth first inits and there is no `AccessGraphSettings`. This PR is part of https://github.com/gravitational/access-graph/issues/637. Signed-off-by: Tiago Silva * remove iterations --------- Signed-off-by: Tiago Silva --- lib/auth/init.go | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/lib/auth/init.go b/lib/auth/init.go index 64cf79285a71b..dec529f7fa874 100644 --- a/lib/auth/init.go +++ b/lib/auth/init.go @@ -43,9 +43,11 @@ import ( "github.com/gravitational/teleport" "github.com/gravitational/teleport/api/client/proto" apidefaults "github.com/gravitational/teleport/api/defaults" + clusterconfigpb "github.com/gravitational/teleport/api/gen/proto/go/teleport/clusterconfig/v1" dbobjectimportrulev1pb "github.com/gravitational/teleport/api/gen/proto/go/teleport/dbobjectimportrule/v1" machineidv1pb "github.com/gravitational/teleport/api/gen/proto/go/teleport/machineid/v1" "github.com/gravitational/teleport/api/types" + "github.com/gravitational/teleport/api/types/clusterconfig" apievents "github.com/gravitational/teleport/api/types/events" "github.com/gravitational/teleport/lib" "github.com/gravitational/teleport/lib/auth/dbobjectimportrule/dbobjectimportrulev1" @@ -434,6 +436,12 @@ func initCluster(ctx context.Context, cfg InitConfig, asrv *Server) error { return trace.Wrap(initializeSessionRecordingConfig(ctx, asrv, cfg.SessionRecordingConfig)) }) + g.Go(func() error { + ctx, span := cfg.Tracer.Start(gctx, "auth/InitializeAccessGraphSettings") + defer span.End() + return trace.Wrap(initializeAccessGraphSettings(ctx, asrv)) + }) + g.Go(func() error { ctx, span := cfg.Tracer.Start(gctx, "auth/initializeAuthPreference") defer span.End() @@ -857,6 +865,31 @@ func initializeSessionRecordingConfig(ctx context.Context, asrv *Server, newRecC return trace.LimitExceeded("failed to initialize session recording config in %v iterations", iterationLimit) } +func initializeAccessGraphSettings(ctx context.Context, asrv *Server) error { + stored, err := asrv.Services.GetAccessGraphSettings(ctx) + if err != nil && !trace.IsNotFound(err) { + return trace.Wrap(err) + } + if stored != nil { + return nil + } + + stored, err = clusterconfig.NewAccessGraphSettings(&clusterconfigpb.AccessGraphSettingsSpec{ + SecretsScanConfig: clusterconfigpb.AccessGraphSecretsScanConfig_ACCESS_GRAPH_SECRETS_SCAN_CONFIG_DISABLED, + }) + if err != nil { + return trace.Wrap(err) + } + + log.Infof("Creating access graph settings: %v.", stored) + _, err = asrv.CreateAccessGraphSettings(ctx, stored) + if trace.IsAlreadyExists(err) { + return nil + } + + return trace.Wrap(err) +} + // shouldInitReplaceResourceWithOrigin determines whether the candidate // resource should be used to replace the stored resource during auth server // initialization. Dynamically configured resources must not be overwritten From 57ed57d2ace757a4e16ab5d502ed912252c77935 Mon Sep 17 00:00:00 2001 From: Tiago Silva Date: Tue, 23 Jul 2024 09:40:05 +0100 Subject: [PATCH 17/25] [sec_scan][15] add support for edits to `AccessGraphSettings` via `tctl` (#44055) This PR allows any cluster admin to edit `access_graph_settings` objects via `tctl`. This PR is part of https://github.com/gravitational/access-graph/issues/637. Signed-off-by: Tiago Silva --- api/types/header/convert/legacy/header.go | 18 ++ lib/services/presets.go | 1 + lib/services/resource.go | 2 + .../clusterconfig/accessgraphsettings.go | 148 ++++++++++ .../clusterconfig/accessgraphsettings_test.go | 269 ++++++++++++++++++ tool/tctl/common/collection.go | 18 ++ tool/tctl/common/resource_command.go | 41 +++ 7 files changed, 497 insertions(+) create mode 100644 tool/tctl/common/clusterconfig/accessgraphsettings.go create mode 100644 tool/tctl/common/clusterconfig/accessgraphsettings_test.go diff --git a/api/types/header/convert/legacy/header.go b/api/types/header/convert/legacy/header.go index de607fb64140f..c2bd91ea5350d 100644 --- a/api/types/header/convert/legacy/header.go +++ b/api/types/header/convert/legacy/header.go @@ -17,6 +17,8 @@ limitations under the License. package legacy import ( + "time" + "github.com/gravitational/teleport/api/types" "github.com/gravitational/teleport/api/types/header" ) @@ -32,3 +34,19 @@ func FromHeaderMetadata(metadata header.Metadata) types.Metadata { Revision: metadata.Revision, } } + +// ToHeaderMetadata will convert a types.Metadata object to this metadata object. +// TODO: Remove this once we get rid of the old Metadata object. +func ToHeaderMetadata(metadata types.Metadata) header.Metadata { + var expires time.Time + if metadata.Expires != nil { + expires = *metadata.Expires + } + return header.Metadata{ + Name: metadata.Name, + Expires: expires, + Description: metadata.Description, + Labels: metadata.Labels, + Revision: metadata.Revision, + } +} diff --git a/lib/services/presets.go b/lib/services/presets.go index 1ca83f0d6377a..f66b442934f93 100644 --- a/lib/services/presets.go +++ b/lib/services/presets.go @@ -176,6 +176,7 @@ func NewPresetEditorRole() types.Role { types.NewRule(types.KindAccessMonitoringRule, RW()), types.NewRule(types.KindAppServer, RW()), types.NewRule(types.KindVnetConfig, RW()), + types.NewRule(types.KindAccessGraphSettings, RW()), }, }, }, diff --git a/lib/services/resource.go b/lib/services/resource.go index 48ed0a566d506..ba02befb56c85 100644 --- a/lib/services/resource.go +++ b/lib/services/resource.go @@ -237,6 +237,8 @@ func ParseShortcut(in string) (string, error) { return types.KindAccessRequest, nil case types.KindPlugin, types.KindPlugin + "s": return types.KindPlugin, nil + case types.KindAccessGraphSettings, "ags": + return types.KindAccessGraphSettings, nil } return "", trace.BadParameter("unsupported resource: %q - resources should be expressed as 'type/name', for example 'connector/github'", in) } diff --git a/tool/tctl/common/clusterconfig/accessgraphsettings.go b/tool/tctl/common/clusterconfig/accessgraphsettings.go new file mode 100644 index 0000000000000..939b8ae23efc0 --- /dev/null +++ b/tool/tctl/common/clusterconfig/accessgraphsettings.go @@ -0,0 +1,148 @@ +/* + * Teleport + * Copyright (C) 2024 Gravitational, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package clusterconfig + +import ( + "github.com/gravitational/trace" + + clusterconfigpb "github.com/gravitational/teleport/api/gen/proto/go/teleport/clusterconfig/v1" + "github.com/gravitational/teleport/api/types" + "github.com/gravitational/teleport/api/types/header/convert/legacy" + headerv1 "github.com/gravitational/teleport/api/types/header/convert/v1" + "github.com/gravitational/teleport/lib/utils" +) + +// AccessGraphSettings is a type to represent [clusterconfigpb.AcccessGraphSettings] +// which implements types.Resource and custom YAML (un)marshaling. +// This satisfies the expected YAML format for // the resource, which would be +// hard/impossible to do for the proto resource directly +type AccessGraphSettings struct { + // ResourceHeader is embedded to implement types.Resource + types.ResourceHeader + // Spec is the specification + Spec accessGraphSettingsSpec `json:"spec"` +} + +// accessGraphSettingsSpec holds the AccessGraphSettings properties. +type accessGraphSettingsSpec struct { + SecretsScanConfig string `json:"secrets_scan_config"` +} + +// CheckAndSetDefaults sanity checks AccessGraphSettings fields to catch simple errors, and +// sets default values for all fields with defaults. +func (r *AccessGraphSettings) CheckAndSetDefaults() error { + if err := r.Metadata.CheckAndSetDefaults(); err != nil { + return trace.Wrap(err) + } + if r.Kind == "" { + r.Kind = types.KindAccessGraphSettings + } else if r.Kind != types.KindAccessGraphSettings { + return trace.BadParameter("unexpected resource kind %q, must be %q", r.Kind, types.KindAccessGraphSettings) + } + if r.Version == "" { + r.Version = types.V1 + } else if r.Version != types.V1 { + return trace.BadParameter("unsupported resource version %q, %q is currently the only supported version", r.Version, types.V1) + } + if r.Metadata.Name == "" { + r.Metadata.Name = types.MetaNameAccessGraphSettings + } else if r.Metadata.Name != types.MetaNameAccessGraphSettings { + return trace.BadParameter("access graph settings must have a name %q", types.MetaNameAccessGraphSettings) + } + + if _, err := stringToSecretsScanConfig(r.Spec.SecretsScanConfig); err != nil { + return trace.BadParameter("secrets_scan_config must be one of [enabled, disabled]") + } + + return nil +} + +// UnmarshalAccessGraphSettings parses a [*clusterconfigpb.AccessGraphSettings] in the [AccessGraphSettings] +// format which matches the expected YAML format for Teleport resources, sets default values, and +// converts to [*clusterconfigpb.AccessGraphSettings]. +func UnmarshalAccessGraphSettings(raw []byte) (*clusterconfigpb.AccessGraphSettings, error) { + var resource AccessGraphSettings + if err := utils.FastUnmarshal(raw, &resource); err != nil { + return nil, trace.Wrap(err) + } + if err := resource.CheckAndSetDefaults(); err != nil { + return nil, trace.Wrap(err) + } + rec, err := resourceToProto(&resource) + return rec, trace.Wrap(err) +} + +// ProtoToResource converts a [*clusterconfigpb.AccessGraphSettings] into a [*AccessGraphSettings] which +// implements types.Resource and can be marshaled to YAML or JSON in a +// human-friendly format. +func ProtoToResource(set *clusterconfigpb.AccessGraphSettings) (*AccessGraphSettings, error) { + conf, err := secretsScanConfigToString(set.Spec.SecretsScanConfig) + if err != nil { + return nil, trace.Wrap(err) + } + r := &AccessGraphSettings{ + ResourceHeader: types.ResourceHeader{ + Kind: set.Kind, + Version: set.Version, + Metadata: legacy.FromHeaderMetadata(headerv1.FromMetadataProto(set.Metadata)), + }, + Spec: accessGraphSettingsSpec{ + SecretsScanConfig: conf, + }, + } + return r, nil +} + +func resourceToProto(r *AccessGraphSettings) (*clusterconfigpb.AccessGraphSettings, error) { + secretsScanConfig, err := stringToSecretsScanConfig(r.Spec.SecretsScanConfig) + if err != nil { + return nil, trace.Wrap(err) + } + return &clusterconfigpb.AccessGraphSettings{ + Kind: r.Kind, + SubKind: r.SubKind, + Version: r.Version, + Metadata: headerv1.ToMetadataProto(legacy.ToHeaderMetadata(r.Metadata)), + Spec: &clusterconfigpb.AccessGraphSettingsSpec{ + SecretsScanConfig: secretsScanConfig, + }, + }, nil +} + +func secretsScanConfigToString(secretsScanConfig clusterconfigpb.AccessGraphSecretsScanConfig) (string, error) { + switch secretsScanConfig { + case clusterconfigpb.AccessGraphSecretsScanConfig_ACCESS_GRAPH_SECRETS_SCAN_CONFIG_DISABLED: + return "disabled", nil + case clusterconfigpb.AccessGraphSecretsScanConfig_ACCESS_GRAPH_SECRETS_SCAN_CONFIG_ENABLED: + return "enabled", nil + default: + return "", trace.BadParameter("unexpected secrets scan config %q", secretsScanConfig) + } +} + +func stringToSecretsScanConfig(secretsScanConfig string) (clusterconfigpb.AccessGraphSecretsScanConfig, error) { + switch secretsScanConfig { + case "disabled", "off": + return clusterconfigpb.AccessGraphSecretsScanConfig_ACCESS_GRAPH_SECRETS_SCAN_CONFIG_DISABLED, nil + case "enabled", "on": + return clusterconfigpb.AccessGraphSecretsScanConfig_ACCESS_GRAPH_SECRETS_SCAN_CONFIG_ENABLED, nil + default: + return clusterconfigpb.AccessGraphSecretsScanConfig_ACCESS_GRAPH_SECRETS_SCAN_CONFIG_UNSPECIFIED, trace.BadParameter("secrets scan config must be one of [enabled, disabled]") + } +} diff --git a/tool/tctl/common/clusterconfig/accessgraphsettings_test.go b/tool/tctl/common/clusterconfig/accessgraphsettings_test.go new file mode 100644 index 0000000000000..01a1a7e3f4366 --- /dev/null +++ b/tool/tctl/common/clusterconfig/accessgraphsettings_test.go @@ -0,0 +1,269 @@ +/* + * Teleport + * Copyright (C) 2023 Gravitational, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package clusterconfig + +import ( + "strings" + "testing" + + "github.com/google/go-cmp/cmp" + "github.com/stretchr/testify/require" + "google.golang.org/protobuf/testing/protocmp" + kyaml "k8s.io/apimachinery/pkg/util/yaml" + + clusterconfigpb "github.com/gravitational/teleport/api/gen/proto/go/teleport/clusterconfig/v1" + headerv1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/header/v1" + "github.com/gravitational/teleport/api/types" + "github.com/gravitational/teleport/lib/defaults" + "github.com/gravitational/teleport/lib/services" +) + +func TestUnmarshalAccessGraphSettings(t *testing.T) { + t.Parallel() + for _, tc := range []struct { + desc string + input string + errorContains string + expected *clusterconfigpb.AccessGraphSettings + }{ + { + desc: "disabled", + input: `--- +kind: access_graph_settings +version: v1 +metadata: + name: access-graph-settings +spec: + secrets_scan_config: "disabled" +`, + expected: &clusterconfigpb.AccessGraphSettings{ + Version: types.V1, + Kind: types.KindAccessGraphSettings, + Metadata: &headerv1.Metadata{ + Name: types.MetaNameAccessGraphSettings, + }, + Spec: &clusterconfigpb.AccessGraphSettingsSpec{ + SecretsScanConfig: clusterconfigpb.AccessGraphSecretsScanConfig_ACCESS_GRAPH_SECRETS_SCAN_CONFIG_DISABLED, + }, + }, + }, + { + desc: "off", + input: `--- +kind: access_graph_settings +version: v1 +metadata: + name: access-graph-settings +spec: + secrets_scan_config: "off" +`, + expected: &clusterconfigpb.AccessGraphSettings{ + Version: types.V1, + Kind: types.KindAccessGraphSettings, + Metadata: &headerv1.Metadata{ + Name: types.MetaNameAccessGraphSettings, + }, + Spec: &clusterconfigpb.AccessGraphSettingsSpec{ + SecretsScanConfig: clusterconfigpb.AccessGraphSecretsScanConfig_ACCESS_GRAPH_SECRETS_SCAN_CONFIG_DISABLED, + }, + }, + }, + { + desc: "enabled", + input: `--- +kind: access_graph_settings +version: v1 +metadata: + name: access-graph-settings +spec: + secrets_scan_config: "enabled" +`, + expected: &clusterconfigpb.AccessGraphSettings{ + Version: types.V1, + Kind: types.KindAccessGraphSettings, + Metadata: &headerv1.Metadata{ + Name: types.MetaNameAccessGraphSettings, + }, + Spec: &clusterconfigpb.AccessGraphSettingsSpec{ + SecretsScanConfig: clusterconfigpb.AccessGraphSecretsScanConfig_ACCESS_GRAPH_SECRETS_SCAN_CONFIG_ENABLED, + }, + }, + }, + { + desc: "on", + input: `--- +kind: access_graph_settings +version: v1 +metadata: + name: access-graph-settings +spec: + secrets_scan_config: "on" +`, + expected: &clusterconfigpb.AccessGraphSettings{ + Version: types.V1, + Kind: types.KindAccessGraphSettings, + Metadata: &headerv1.Metadata{ + Name: types.MetaNameAccessGraphSettings, + }, + Spec: &clusterconfigpb.AccessGraphSettingsSpec{ + SecretsScanConfig: clusterconfigpb.AccessGraphSecretsScanConfig_ACCESS_GRAPH_SECRETS_SCAN_CONFIG_ENABLED, + }, + }, + }, + { + desc: "invalid settings", + input: `--- +kind: access_graph_settings +version: v1 +metadata: + name: access-graph-settings +spec: + secrets_scan_config: "invalidasd" +`, + errorContains: "secrets_scan_config must be one of [enabled, disabled]", + }, + { + desc: "wrong name", + input: `--- +kind: access_graph_settings +version: v1 +metadata: + name: access +spec: + secrets_scan_config: "on" +`, + errorContains: "access graph settings must have a name \"access-graph-settings\"", + }, + { + desc: "wrong version", + input: `--- +kind: access_graph_settings +version: v2 +metadata: + name: access-graph-settings +spec: + secrets_scan_config: "on" +`, + errorContains: "unsupported resource version", + }, + } { + t.Run(tc.desc, func(t *testing.T) { + // Mimic tctl resource command by using the same decoder and + // initially unmarshalling into services.UnknownResource + reader := strings.NewReader(tc.input) + decoder := kyaml.NewYAMLOrJSONDecoder(reader, defaults.LookaheadBufSize) + var raw services.UnknownResource + err := decoder.Decode(&raw) + require.NoError(t, err) + require.Equal(t, types.KindAccessGraphSettings, raw.Kind) + + out, err := UnmarshalAccessGraphSettings(raw.Raw) + if tc.errorContains != "" { + require.ErrorContains(t, err, tc.errorContains, "error from UnmarshalAccessGraphSettings does not contain the expected string") + return + } + require.NoError(t, err, "UnmarshalAccessGraphSettings returned unexpected error") + + require.Empty(t, cmp.Diff(tc.expected, out, protocmp.Transform()), "unmarshalled data does not match what was expected") + }) + } +} + +func TestProtoToResource(t *testing.T) { + t.Parallel() + for _, tc := range []struct { + desc string + expected *AccessGraphSettings + errorContains string + input *clusterconfigpb.AccessGraphSettings + }{ + { + desc: "disabled", + expected: &AccessGraphSettings{ + ResourceHeader: types.ResourceHeader{ + Kind: types.KindAccessGraphSettings, + Version: types.V1, + Metadata: types.Metadata{Name: types.MetaNameAccessGraphSettings}, + }, + Spec: accessGraphSettingsSpec{ + SecretsScanConfig: "disabled", + }, + }, + input: &clusterconfigpb.AccessGraphSettings{ + Version: types.V1, + Kind: types.KindAccessGraphSettings, + Metadata: &headerv1.Metadata{ + Name: types.MetaNameAccessGraphSettings, + }, + Spec: &clusterconfigpb.AccessGraphSettingsSpec{ + SecretsScanConfig: clusterconfigpb.AccessGraphSecretsScanConfig_ACCESS_GRAPH_SECRETS_SCAN_CONFIG_DISABLED, + }, + }, + }, + { + desc: "enabled", + expected: &AccessGraphSettings{ + ResourceHeader: types.ResourceHeader{ + Kind: types.KindAccessGraphSettings, + Version: types.V1, + Metadata: types.Metadata{Name: types.MetaNameAccessGraphSettings}, + }, + Spec: accessGraphSettingsSpec{ + SecretsScanConfig: "enabled", + }, + }, + input: &clusterconfigpb.AccessGraphSettings{ + Version: types.V1, + Kind: types.KindAccessGraphSettings, + Metadata: &headerv1.Metadata{ + Name: types.MetaNameAccessGraphSettings, + }, + Spec: &clusterconfigpb.AccessGraphSettingsSpec{ + SecretsScanConfig: clusterconfigpb.AccessGraphSecretsScanConfig_ACCESS_GRAPH_SECRETS_SCAN_CONFIG_ENABLED, + }, + }, + }, + { + desc: "incorrect data", + errorContains: "unexpected secrets scan config", + input: &clusterconfigpb.AccessGraphSettings{ + Version: types.V1, + Kind: types.KindAccessGraphSettings, + Metadata: &headerv1.Metadata{ + Name: types.MetaNameAccessGraphSettings, + }, + Spec: &clusterconfigpb.AccessGraphSettingsSpec{ + SecretsScanConfig: 5, + }, + }, + }, + } { + t.Run(tc.desc, func(t *testing.T) { + + out, err := ProtoToResource(tc.input) + if tc.errorContains != "" { + require.ErrorContains(t, err, tc.errorContains, "error from ProtoToResource does not contain the expected string") + return + } + require.NoError(t, err, "ProtoToResource returned unexpected error") + + require.Empty(t, cmp.Diff(tc.expected, out, protocmp.Transform())) + }) + } +} diff --git a/tool/tctl/common/collection.go b/tool/tctl/common/collection.go index 45f95f699dfa4..838e151b99b9d 100644 --- a/tool/tctl/common/collection.go +++ b/tool/tctl/common/collection.go @@ -49,6 +49,7 @@ import ( "github.com/gravitational/teleport/lib/sshutils" "github.com/gravitational/teleport/lib/utils" "github.com/gravitational/teleport/tool/common" + clusterconfigrec "github.com/gravitational/teleport/tool/tctl/common/clusterconfig" "github.com/gravitational/teleport/tool/tctl/common/databaseobject" "github.com/gravitational/teleport/tool/tctl/common/databaseobjectimportrule" "github.com/gravitational/teleport/tool/tctl/common/loginrule" @@ -1489,6 +1490,23 @@ func (c *vnetConfigCollection) writeText(w io.Writer, verbose bool) error { return trace.Wrap(err) } +type accessGraphSettings struct { + accessGraphSettings *clusterconfigrec.AccessGraphSettings +} + +func (c *accessGraphSettings) resources() []types.Resource { + return []types.Resource{c.accessGraphSettings} +} + +func (c *accessGraphSettings) writeText(w io.Writer, verbose bool) error { + t := asciitable.MakeTable([]string{"SSH Keys Scan"}) + t.AddRow([]string{ + c.accessGraphSettings.Spec.SecretsScanConfig, + }) + _, err := t.AsBuffer().WriteTo(w) + return trace.Wrap(err) +} + type accessRequestCollection struct { accessRequests []types.AccessRequest } diff --git a/tool/tctl/common/resource_command.go b/tool/tctl/common/resource_command.go index ab0a1fbedf038..4cc2e32a90a38 100644 --- a/tool/tctl/common/resource_command.go +++ b/tool/tctl/common/resource_command.go @@ -42,6 +42,7 @@ import ( apiclient "github.com/gravitational/teleport/api/client" "github.com/gravitational/teleport/api/client/proto" apidefaults "github.com/gravitational/teleport/api/defaults" + clusterconfigpb "github.com/gravitational/teleport/api/gen/proto/go/teleport/clusterconfig/v1" crownjewelv1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/crownjewel/v1" dbobjectv1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/dbobject/v1" dbobjectimportrulev1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/dbobjectimportrule/v1" @@ -65,6 +66,7 @@ import ( "github.com/gravitational/teleport/lib/service/servicecfg" "github.com/gravitational/teleport/lib/services" "github.com/gravitational/teleport/lib/utils" + clusterconfigrec "github.com/gravitational/teleport/tool/tctl/common/clusterconfig" "github.com/gravitational/teleport/tool/tctl/common/databaseobject" "github.com/gravitational/teleport/tool/tctl/common/databaseobjectimportrule" "github.com/gravitational/teleport/tool/tctl/common/loginrule" @@ -161,6 +163,7 @@ func (rc *ResourceCommand) Initialize(app *kingpin.Application, config *servicec types.KindAccessMonitoringRule: rc.createAccessMonitoringRule, types.KindCrownJewel: rc.createCrownJewel, types.KindVnetConfig: rc.createVnetConfig, + types.KindAccessGraphSettings: rc.upsertAccessGraphSettings, types.KindPlugin: rc.createPlugin, } rc.UpdateHandlers = map[ResourceKind]ResourceCreateHandler{ @@ -175,6 +178,7 @@ func (rc *ResourceCommand) Initialize(app *kingpin.Application, config *servicec types.KindAccessMonitoringRule: rc.updateAccessMonitoringRule, types.KindCrownJewel: rc.updateCrownJewel, types.KindVnetConfig: rc.updateVnetConfig, + types.KindAccessGraphSettings: rc.updateAccessGraphSettings, types.KindPlugin: rc.updatePlugin, } rc.config = config @@ -2819,6 +2823,16 @@ func (rc *ResourceCommand) getCollection(ctx context.Context, client *authclient startKey = resp.NextKey } return &pluginCollection{plugins: plugins}, nil + case types.KindAccessGraphSettings: + settings, err := client.ClusterConfigClient().GetAccessGraphSettings(ctx, &clusterconfigpb.GetAccessGraphSettingsRequest{}) + if err != nil { + return nil, trace.Wrap(err) + } + rec, err := clusterconfigrec.ProtoToResource(settings) + if err != nil { + return nil, trace.Wrap(err) + } + return &accessGraphSettings{accessGraphSettings: rec}, nil } return nil, trace.BadParameter("getting %q is not supported", rc.ref.String()) } @@ -3137,3 +3151,30 @@ func (rc *ResourceCommand) createPlugin(ctx context.Context, client *authclient. fmt.Printf("plugin %q has been updated\n", item.GetName()) return nil } + +func (rc *ResourceCommand) upsertAccessGraphSettings(ctx context.Context, client *authclient.Client, raw services.UnknownResource) error { + settings, err := clusterconfigrec.UnmarshalAccessGraphSettings(raw.Raw) + if err != nil { + return trace.Wrap(err) + } + + if _, err = client.ClusterConfigClient().UpsertAccessGraphSettings(ctx, &clusterconfigpb.UpsertAccessGraphSettingsRequest{AccessGraphSettings: settings}); err != nil { + return trace.Wrap(err) + } + + fmt.Println("access_graph_settings has been upserted") + return nil +} + +func (rc *ResourceCommand) updateAccessGraphSettings(ctx context.Context, client *authclient.Client, raw services.UnknownResource) error { + settings, err := clusterconfigrec.UnmarshalAccessGraphSettings(raw.Raw) + if err != nil { + return trace.Wrap(err) + } + + if _, err = client.ClusterConfigClient().UpdateAccessGraphSettings(ctx, &clusterconfigpb.UpdateAccessGraphSettingsRequest{AccessGraphSettings: settings}); err != nil { + return trace.Wrap(err) + } + fmt.Println("access_graph_settings has been updated") + return nil +} From a42ee9e4e09ee1dfe920b9cbf6b429a60e9f4d01 Mon Sep 17 00:00:00 2001 From: Tiago Silva Date: Mon, 15 Jul 2024 09:30:36 +0100 Subject: [PATCH 18/25] [sec_scan][16] add methods to store/retrieve device assertion functions (#44081) This PR adds methods to store/retrieve functions defined by different teleport services. This PR is part of https://github.com/gravitational/access-graph/issues/637. Signed-off-by: Tiago Silva --- lib/auth/auth.go | 56 ++++++++++++++++++++++++++++++++++++ lib/auth/authclient/clt.go | 7 +++++ lib/services/access_graph.go | 14 +++++++++ lib/services/device.go | 1 + 4 files changed, 78 insertions(+) diff --git a/lib/auth/auth.go b/lib/auth/auth.go index dd13e284b2f32..a806f8c9fe8a5 100644 --- a/lib/auth/auth.go +++ b/lib/auth/auth.go @@ -91,6 +91,7 @@ import ( "github.com/gravitational/teleport/lib/circleci" "github.com/gravitational/teleport/lib/cloud" "github.com/gravitational/teleport/lib/defaults" + "github.com/gravitational/teleport/lib/devicetrust/assertserver" "github.com/gravitational/teleport/lib/events" "github.com/gravitational/teleport/lib/gcp" "github.com/gravitational/teleport/lib/githubactions" @@ -604,6 +605,8 @@ type Services struct { services.KubeWaitingContainer services.AccessMonitoringRules services.CrownJewels + services.AccessGraphSecretsGetter + services.DevicesGetter } // SecReportsClient returns the security reports client. @@ -676,6 +679,16 @@ func (r *Services) DatabaseObjectsClient() services.DatabaseObjects { return r } +// GetAccessGraphSecretsGetter returns the AccessGraph secrets service. +func (r *Services) GetAccessGraphSecretsGetter() services.AccessGraphSecretsGetter { + return r.AccessGraphSecretsGetter +} + +// GetDevicesGetter returns the trusted devices service. +func (r *Services) GetDevicesGetter() services.DevicesGetter { + return r.DevicesGetter +} + var ( generateRequestsCount = prometheus.NewCounter( prometheus.CounterOpts{ @@ -820,6 +833,10 @@ type LoginHook func(context.Context, types.User) error // the user has no suitable trusted device. type CreateDeviceWebTokenFunc func(context.Context, *devicepb.DeviceWebToken) (*devicepb.DeviceWebToken, error) +// CreateDeviceAssertionFunc creates a new device assertion ceremony to authenticate +// a trusted device. +type CreateDeviceAssertionFunc func() (assertserver.Ceremony, error) + // ReadOnlyCache is a type alias used to assist with embedding [readonly.Cache] in places // where it would have a naming conflict with other types named Cache. type ReadOnlyCache = readonly.Cache @@ -996,6 +1013,15 @@ type Server struct { // Is nil on OSS clusters. createDeviceWebTokenFunc CreateDeviceWebTokenFunc + // deviceAssertionServer holds the server-side implementation of device assertions. + // + // It is used to authenticate devices previously enrolled in the cluster. The goal + // is to provide an API for devices to authenticate with the cluster without the need + // for valid user credentials, e.g. when running `tsh scan keys`. + // + // The value is nil on OSS clusters. + deviceAssertionServer CreateDeviceAssertionFunc + // bcryptCostOverride overrides the bcrypt cost for operations executed // directly by [Server]. // Used for testing. @@ -1144,6 +1170,26 @@ func (a *Server) SetHeadlessAuthenticationWatcher(headlessAuthenticationWatcher a.headlessAuthenticationWatcher = headlessAuthenticationWatcher } +// SetDeviceAssertionServer sets the device assertion implementation. +func (a *Server) SetDeviceAssertionServer(f CreateDeviceAssertionFunc) { + a.lock.Lock() + a.deviceAssertionServer = f + a.lock.Unlock() +} + +// GetDeviceAssertionServer returns the device assertion implementation. +// On OSS clusters, this will return a non nil function that returns an error. +func (a *Server) GetDeviceAssertionServer() CreateDeviceAssertionFunc { + a.lock.RLock() + defer a.lock.RUnlock() + if a.deviceAssertionServer == nil { + return func() (assertserver.Ceremony, error) { + return nil, trace.NotImplemented("device assertions are not supported on OSS clusters") + } + } + return a.deviceAssertionServer +} + func (a *Server) SetCreateDeviceWebTokenFunc(f CreateDeviceWebTokenFunc) { a.lock.Lock() a.createDeviceWebTokenFunc = f @@ -1761,6 +1807,16 @@ func (a *Server) SetSCIMService(scim services.SCIM) { a.Services.SCIM = scim } +// SetAccessGraphSecretService sets the server's access graph secret service +func (a *Server) SetAccessGraphSecretService(s services.AccessGraphSecretsGetter) { + a.Services.AccessGraphSecretsGetter = s +} + +// SetDevicesGetter sets the server's device service +func (a *Server) SetDevicesGetter(s services.DevicesGetter) { + a.Services.DevicesGetter = s +} + // SetAuditLog sets the server's audit log func (a *Server) SetAuditLog(auditLog events.AuditLogSessionStreamer) { a.Services.AuditLogSessionStreamer = auditLog diff --git a/lib/auth/authclient/clt.go b/lib/auth/authclient/clt.go index 6604e7c93e660..8be2817fd9af1 100644 --- a/lib/auth/authclient/clt.go +++ b/lib/auth/authclient/clt.go @@ -37,6 +37,7 @@ import ( "github.com/gravitational/teleport/api/client/proto" "github.com/gravitational/teleport/api/client/secreport" apidefaults "github.com/gravitational/teleport/api/defaults" + accessgraphsecretsv1pb "github.com/gravitational/teleport/api/gen/proto/go/teleport/accessgraph/v1" clusterconfigpb "github.com/gravitational/teleport/api/gen/proto/go/teleport/clusterconfig/v1" dbobjectimportrulev1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/dbobjectimportrule/v1" devicepb "github.com/gravitational/teleport/api/gen/proto/go/teleport/devicetrust/v1" @@ -652,6 +653,10 @@ func (c *Client) AccessGraphClient() accessgraphv1.AccessGraphServiceClient { return accessgraphv1.NewAccessGraphServiceClient(c.APIClient.GetConnection()) } +func (c *Client) AccessGraphSecretsScannerClient() accessgraphsecretsv1pb.SecretsScannerServiceClient { + return accessgraphsecretsv1pb.NewSecretsScannerServiceClient(c.APIClient.GetConnection()) +} + func (c *Client) IntegrationAWSOIDCClient() integrationv1.AWSOIDCServiceClient { return integrationv1.NewAWSOIDCServiceClient(c.APIClient.GetConnection()) } @@ -1481,6 +1486,8 @@ type ClientI interface { // AccessGraphClient returns a client to the Access Graph gRPC service. AccessGraphClient() accessgraphv1.AccessGraphServiceClient + AccessGraphSecretsScannerClient() accessgraphsecretsv1pb.SecretsScannerServiceClient + // IntegrationAWSOIDCClient returns a client to the Integration AWS OIDC gRPC service. IntegrationAWSOIDCClient() integrationv1.AWSOIDCServiceClient diff --git a/lib/services/access_graph.go b/lib/services/access_graph.go index 6ff41221b5a37..aef36297c8128 100644 --- a/lib/services/access_graph.go +++ b/lib/services/access_graph.go @@ -19,12 +19,26 @@ package services import ( + "context" + "github.com/gravitational/trace" accessgraphsecretspb "github.com/gravitational/teleport/api/gen/proto/go/teleport/accessgraph/v1" "github.com/gravitational/teleport/api/types/accessgraph" ) +// AccessGraphSecretsGetter is an interface for getting access graph secrets. +type AccessGraphSecretsGetter interface { + // ListAllAuthorizedKeys lists all authorized keys stored in the backend. + ListAllAuthorizedKeys(ctx context.Context, pageSize int, pageToken string) ([]*accessgraphsecretspb.AuthorizedKey, string, error) + // ListAuthorizedKeysForServer lists all authorized keys for a given hostID. + ListAuthorizedKeysForServer(ctx context.Context, hostID string, pageSize int, pageToken string) ([]*accessgraphsecretspb.AuthorizedKey, string, error) + // ListAllPrivateKeys lists all private keys stored in the backend. + ListAllPrivateKeys(ctx context.Context, pageSize int, pageToken string) ([]*accessgraphsecretspb.PrivateKey, string, error) + // ListPrivateKeysForDevice lists all private keys for a given deviceID. + ListPrivateKeysForDevice(ctx context.Context, deviceID string, pageSize int, pageToken string) ([]*accessgraphsecretspb.PrivateKey, string, error) +} + // MarshalAccessGraphAuthorizedKey marshals a [accessgraphsecretspb.AuthorizedKey] resource to JSON. func MarshalAccessGraphAuthorizedKey(in *accessgraphsecretspb.AuthorizedKey, opts ...MarshalOption) ([]byte, error) { if err := accessgraph.ValidateAuthorizedKey(in); err != nil { diff --git a/lib/services/device.go b/lib/services/device.go index 319fe46bbc788..1456d39324a64 100644 --- a/lib/services/device.go +++ b/lib/services/device.go @@ -29,6 +29,7 @@ import ( "github.com/gravitational/teleport/lib/utils" ) +// DevicesGetter allows to list all registered devices from storage. type DevicesGetter interface { ListDevices(ctx context.Context, pageSize int, pageToken string, view devicepb.DeviceView) (devices []*devicepb.Device, nextPageToken string, err error) } From 5353c6bca2f756a804d5529df211eb0554cfe357 Mon Sep 17 00:00:00 2001 From: Tiago Silva Date: Mon, 15 Jul 2024 10:11:09 +0100 Subject: [PATCH 19/25] [sec_scan][17] add `AssertDevice` to `FakeDeviceService` (#44159) * [sec_scan][17] add `AssertDevice` to `FakeDeviceService` This PR introduces a `AssertDevice` logic into `FakeDeviceService` to authenticate devices during unit tests using device trust credentials. This PR is part of https://github.com/gravitational/access-graph/issues/637. Signed-off-by: Tiago Silva * simplify assert tests * Update lib/devicetrust/assert/assert_test.go Co-authored-by: Alan Parra --------- Signed-off-by: Tiago Silva Co-authored-by: Alan Parra --- lib/devicetrust/assert/assert_test.go | 155 +++++++++--------- .../testenv/fake_device_service.go | 118 ++++++++++++- lib/devicetrust/testenv/testenv.go | 57 +++++++ 3 files changed, 252 insertions(+), 78 deletions(-) diff --git a/lib/devicetrust/assert/assert_test.go b/lib/devicetrust/assert/assert_test.go index 273b71b814eb9..b9068b222df2e 100644 --- a/lib/devicetrust/assert/assert_test.go +++ b/lib/devicetrust/assert/assert_test.go @@ -20,24 +20,22 @@ import ( "context" "testing" + "github.com/google/uuid" "github.com/gravitational/trace" "github.com/stretchr/testify/require" + "golang.org/x/sync/errgroup" devicepb "github.com/gravitational/teleport/api/gen/proto/go/teleport/devicetrust/v1" "github.com/gravitational/teleport/lib/devicetrust/assert" "github.com/gravitational/teleport/lib/devicetrust/authn" - "github.com/gravitational/teleport/lib/devicetrust/enroll" "github.com/gravitational/teleport/lib/devicetrust/testenv" ) func TestCeremony(t *testing.T) { t.Parallel() - env := testenv.MustNew( - testenv.WithAutoCreateDevice(true), - ) + deviceID := uuid.NewString() - devicesClient := env.DevicesClient ctx := context.Background() macDev, err := testenv.NewFakeMacOSDevice() @@ -62,17 +60,17 @@ func TestCeremony(t *testing.T) { t.Run(test.name, func(t *testing.T) { t.Parallel() - // Enroll the device before we attempt authentication (auto creates device - // as part of ceremony) dev := test.dev - enrollC := enroll.Ceremony{ - GetDeviceOSType: dev.GetDeviceOSType, - EnrollDeviceInit: dev.EnrollDeviceInit, - SignChallenge: dev.SignChallenge, - SolveTPMEnrollChallenge: dev.SolveTPMEnrollChallenge, - } - _, err := enrollC.Run(ctx, devicesClient, false, testenv.FakeEnrollmentToken) - require.NoError(t, err, "EnrollDevice errored") + + // Create an enrolled device. + devpb, pubKey, err := testenv.CreateEnrolledDevice(deviceID, dev) + require.NoError(t, err, "CreateEnrolledDevice errored") + + env := testenv.MustNew( + testenv.WithAutoCreateDevice(true), + // Register the enrolled device with the service. + testenv.WithPreEnrolledDevice(devpb, pubKey), + ) assertC, err := assert.NewCeremony(assert.WithNewAuthnCeremonyFunc(func() *authn.Ceremony { return &authn.Ceremony{ @@ -87,78 +85,83 @@ func TestCeremony(t *testing.T) { })) require.NoError(t, err, "NewCeremony errored") - authnStream, err := devicesClient.AuthenticateDevice(ctx) - require.NoError(t, err, "AuthenticateDevice errored") - - // Typically this would be some other, non-DeviceTrustService stream, but - // here this is a good way to test it (as it runs actual fake device - // authn) - if err := assertC.Run(ctx, &assertStreamAdapter{ - stream: authnStream, - }); err != nil { - t.Errorf("Run returned err=%q, want nil", err) - } + clientToServer := make(chan *devicepb.AssertDeviceRequest) + serverToClient := make(chan *devicepb.AssertDeviceResponse) + + group, ctx := errgroup.WithContext(ctx) + + // Run the client side of the ceremony. + group.Go(func() error { + err := assertC.Run(ctx, &assertStreamClientAdapter{ + ctx: ctx, + clientToServer: clientToServer, + serverToClient: serverToClient, + }) + return trace.Wrap(err, "server AssertDevice errored") + }) + + serverAssertC, err := env.Service.CreateAssertCeremony() + require.NoError(t, err, "CreateAssertCeremony errored") + // Run the server side of the ceremony. + group.Go(func() error { + _, err := serverAssertC.AssertDevice(ctx, &assertStreamServerAdapter{ + ctx: ctx, + clientToServer: clientToServer, + serverToClient: serverToClient, + }) + return trace.Wrap(err, "server AssertDevice errored") + }) + + err = group.Wait() + require.NoError(t, err, "group.Wait errored") }) } } -type assertStreamAdapter struct { - stream devicepb.DeviceTrustService_AuthenticateDeviceClient +type assertStreamClientAdapter struct { + ctx context.Context + clientToServer chan *devicepb.AssertDeviceRequest + serverToClient chan *devicepb.AssertDeviceResponse } -func (s *assertStreamAdapter) Recv() (*devicepb.AssertDeviceResponse, error) { - resp, err := s.stream.Recv() - if err != nil { - return nil, err +func (s *assertStreamClientAdapter) Recv() (*devicepb.AssertDeviceResponse, error) { + select { + case resp := <-s.serverToClient: + return resp, nil + case <-s.ctx.Done(): + return nil, trace.Wrap(s.ctx.Err()) } +} - switch resp.Payload.(type) { - case *devicepb.AuthenticateDeviceResponse_Challenge: - return &devicepb.AssertDeviceResponse{ - Payload: &devicepb.AssertDeviceResponse_Challenge{ - Challenge: resp.GetChallenge(), - }, - }, nil - case *devicepb.AuthenticateDeviceResponse_TpmChallenge: - return &devicepb.AssertDeviceResponse{ - Payload: &devicepb.AssertDeviceResponse_TpmChallenge{ - TpmChallenge: resp.GetTpmChallenge(), - }, - }, nil - case *devicepb.AuthenticateDeviceResponse_UserCertificates: - // UserCertificates means success. - return &devicepb.AssertDeviceResponse{ - Payload: &devicepb.AssertDeviceResponse_DeviceAsserted{ - DeviceAsserted: &devicepb.DeviceAsserted{}, - }, - }, nil - default: - return nil, trace.BadParameter("unexpected authenticate response payload: %T", resp.Payload) +func (s *assertStreamClientAdapter) Send(req *devicepb.AssertDeviceRequest) error { + select { + case s.clientToServer <- req: + return nil + case <-s.ctx.Done(): + return trace.Wrap(s.ctx.Err()) } } -func (s *assertStreamAdapter) Send(req *devicepb.AssertDeviceRequest) error { - authnReq := &devicepb.AuthenticateDeviceRequest{} - switch req.Payload.(type) { - case *devicepb.AssertDeviceRequest_Init: - init := req.GetInit() - authnReq.Payload = &devicepb.AuthenticateDeviceRequest_Init{ - Init: &devicepb.AuthenticateDeviceInit{ - CredentialId: init.CredentialId, - DeviceData: init.DeviceData, - }, - } - case *devicepb.AssertDeviceRequest_ChallengeResponse: - authnReq.Payload = &devicepb.AuthenticateDeviceRequest_ChallengeResponse{ - ChallengeResponse: req.GetChallengeResponse(), - } - case *devicepb.AssertDeviceRequest_TpmChallengeResponse: - authnReq.Payload = &devicepb.AuthenticateDeviceRequest_TpmChallengeResponse{ - TpmChallengeResponse: req.GetTpmChallengeResponse(), - } - default: - return trace.BadParameter("unexpected assert request payload: %T", req.Payload) +type assertStreamServerAdapter struct { + ctx context.Context + clientToServer chan *devicepb.AssertDeviceRequest + serverToClient chan *devicepb.AssertDeviceResponse +} + +func (s *assertStreamServerAdapter) Recv() (*devicepb.AssertDeviceRequest, error) { + select { + case req := <-s.clientToServer: + return req, nil + case <-s.ctx.Done(): + return nil, trace.Wrap(s.ctx.Err()) } +} - return s.stream.Send(authnReq) +func (s *assertStreamServerAdapter) Send(resp *devicepb.AssertDeviceResponse) error { + select { + case s.serverToClient <- resp: + return nil + case <-s.ctx.Done(): + return trace.Wrap(s.ctx.Err()) + } } diff --git a/lib/devicetrust/testenv/fake_device_service.go b/lib/devicetrust/testenv/fake_device_service.go index f9ee9bc63e14a..346830b77178c 100644 --- a/lib/devicetrust/testenv/fake_device_service.go +++ b/lib/devicetrust/testenv/fake_device_service.go @@ -35,6 +35,7 @@ import ( "google.golang.org/protobuf/types/known/timestamppb" devicepb "github.com/gravitational/teleport/api/gen/proto/go/teleport/devicetrust/v1" + "github.com/gravitational/teleport/lib/devicetrust/assertserver" ) // FakeEnrollmentToken is a "free", never spent enrollment token. @@ -483,6 +484,58 @@ func enrollMacOS(stream devicepb.DeviceTrustService_EnrollDeviceServer, initReq }, ecPubKey, nil } +// CreateAssertCeremony creates a fake, server-side device assertion ceremony. +func (s *FakeDeviceService) CreateAssertCeremony() (assertserver.Ceremony, error) { + return s, nil +} + +// AssertDevice implements a fake, server-side device assertion ceremony. +// +// AssertDevice requires an enrolled device, so the challenge signature +// can be verified. +func (s *FakeDeviceService) AssertDevice(ctx context.Context, stream assertserver.AssertDeviceServerStream) (*devicepb.Device, error) { + // 1. Init. + req, err := stream.Recv() + if err != nil { + return nil, trace.Wrap(err) + } + initReq := req.GetInit() + switch { + case initReq == nil: + return nil, trace.BadParameter("init required") + case initReq.CredentialId == "": + return nil, trace.BadParameter("credential ID required") + } + if err := validateCollectedData(initReq.DeviceData); err != nil { + return nil, trace.Wrap(err) + } + + s.mu.Lock() + defer s.mu.Unlock() + + dev, err := s.findDeviceByCredential(initReq.DeviceData, initReq.CredentialId) + if err != nil { + return nil, trace.Wrap(err) + } + + switch dev.pb.OsType { + case devicepb.OSType_OS_TYPE_MACOS: + err = authenticateDeviceMacOS(dev, assertStreamAdapter{stream: stream}) + case devicepb.OSType_OS_TYPE_LINUX, devicepb.OSType_OS_TYPE_WINDOWS: + err = authenticateDeviceTPM(assertStreamAdapter{stream: stream}) + default: + err = fmt.Errorf("unrecognized os type %q", dev.pb.OsType) + } + if err != nil { + return nil, trace.Wrap(err) + } + + // Success. + return dev.pb, trace.Wrap(stream.Send(&devicepb.AssertDeviceResponse{ + Payload: &devicepb.AssertDeviceResponse_DeviceAsserted{}, + })) +} + // AuthenticateDevice implements a fake, server-side device authentication // ceremony. // @@ -592,7 +645,7 @@ func (s *FakeDeviceService) spendDeviceWebToken(webToken *devicepb.DeviceWebToke return nil, trace.AccessDenied(invalidWebTokenMessage) } -func authenticateDeviceMacOS(dev *storedDevice, stream devicepb.DeviceTrustService_AuthenticateDeviceServer) error { +func authenticateDeviceMacOS(dev *storedDevice, stream authenticateDeviceStream) error { // 2. Challenge. chal, err := newChallenge() if err != nil { @@ -623,7 +676,7 @@ func authenticateDeviceMacOS(dev *storedDevice, stream devicepb.DeviceTrustServi return trace.Wrap(verifyChallenge(chal, chalResp.Signature, dev.pub)) } -func authenticateDeviceTPM(stream devicepb.DeviceTrustService_AuthenticateDeviceServer) error { +func authenticateDeviceTPM(stream authenticateDeviceStream) error { // Produce a nonce we can send in the challenge that we expect to see in // the EventLog field of the challenge response. nonce, err := randomBytes() @@ -718,3 +771,64 @@ func verifyChallenge(chal, sig []byte, pub *ecdsa.PublicKey) error { } return nil } + +type authenticateDeviceStream interface { + Recv() (*devicepb.AuthenticateDeviceRequest, error) + Send(*devicepb.AuthenticateDeviceResponse) error +} + +// assertStreamAdapter adapts an [assertserver.AssertDeviceServerStream] to an +// [authenticateDeviceStream]. +type assertStreamAdapter struct { + stream assertserver.AssertDeviceServerStream +} + +func (s assertStreamAdapter) Recv() (*devicepb.AuthenticateDeviceRequest, error) { + req, err := s.stream.Recv() + if err != nil { + return nil, trace.Wrap(err) + } + + // Convert AssertDeviceRequest to AuthenticateDeviceRequest. + if req == nil || req.Payload == nil { + return nil, trace.BadParameter("assert request payload required") + } + authnReq := &devicepb.AuthenticateDeviceRequest{} + switch req.Payload.(type) { + case *devicepb.AssertDeviceRequest_ChallengeResponse: + authnReq.Payload = &devicepb.AuthenticateDeviceRequest_ChallengeResponse{ + ChallengeResponse: req.GetChallengeResponse(), + } + case *devicepb.AssertDeviceRequest_TpmChallengeResponse: + authnReq.Payload = &devicepb.AuthenticateDeviceRequest_TpmChallengeResponse{ + TpmChallengeResponse: req.GetTpmChallengeResponse(), + } + default: + return nil, trace.BadParameter("unexpected assert request payload: %T", req.Payload) + } + + return authnReq, nil +} + +func (s assertStreamAdapter) Send(authnResp *devicepb.AuthenticateDeviceResponse) error { + if authnResp == nil || authnResp.Payload == nil { + return trace.BadParameter("authenticate response payload required") + } + + // Convert AuthenticateDeviceResponse to AssertDeviceResponse. + resp := &devicepb.AssertDeviceResponse{} + switch authnResp.Payload.(type) { + case *devicepb.AuthenticateDeviceResponse_Challenge: + resp.Payload = &devicepb.AssertDeviceResponse_Challenge{ + Challenge: authnResp.GetChallenge(), + } + case *devicepb.AuthenticateDeviceResponse_TpmChallenge: + resp.Payload = &devicepb.AssertDeviceResponse_TpmChallenge{ + TpmChallenge: authnResp.GetTpmChallenge(), + } + default: + return trace.BadParameter("unexpected authentication response payload: %T", authnResp.Payload) + } + + return trace.Wrap(s.stream.Send(resp)) +} diff --git a/lib/devicetrust/testenv/testenv.go b/lib/devicetrust/testenv/testenv.go index 7dae3c97a07cb..a0226ee030b0e 100644 --- a/lib/devicetrust/testenv/testenv.go +++ b/lib/devicetrust/testenv/testenv.go @@ -20,6 +20,8 @@ package testenv import ( "context" + "crypto/ecdsa" + "crypto/x509" "net" "time" @@ -27,6 +29,7 @@ import ( "google.golang.org/grpc" "google.golang.org/grpc/credentials/insecure" "google.golang.org/grpc/test/bufconn" + "google.golang.org/protobuf/types/known/timestamppb" devicepb "github.com/gravitational/teleport/api/gen/proto/go/teleport/devicetrust/v1" "github.com/gravitational/teleport/api/utils/grpc/interceptors" @@ -45,6 +48,24 @@ func WithAutoCreateDevice(b bool) Opt { } } +// WithPreEnrolledDevice registers a device with the service without having to enroll it. +// This is useful for testing device authentication flows. +// [pub] is the public key of the macOS device and is used to verify the device. TPM devices +// do not require a public key and should pass nil. +func WithPreEnrolledDevice(dev *devicepb.Device, pub *ecdsa.PublicKey) Opt { + return func(e *E) { + e.Service.mu.Lock() + defer e.Service.mu.Unlock() + e.Service.devices = append(e.Service.devices, + storedDevice{ + pb: dev, + enrollToken: FakeEnrollmentToken, + pub: pub, + }, + ) + } +} + // E is an integrated test environment for device trust. type E struct { DevicesClient devicepb.DeviceTrustServiceClient @@ -150,3 +171,39 @@ type FakeDevice interface { SolveTPMAuthnDeviceChallenge(challenge *devicepb.TPMAuthenticateDeviceChallenge) (*devicepb.TPMAuthenticateDeviceChallengeResponse, error) GetDeviceCredential() *devicepb.DeviceCredential } + +// CreateEnrolledDevice converts a FakeDevice into a [*devicepb.Device] whose EnrollStatus is +// DEVICE_ENROLL_STATUS_ENROLLED and Id set to deviceID. It also returns the public key of the +// device if the device is a macOS device, otherwise it returns nil. +func CreateEnrolledDevice(deviceID string, d FakeDevice) (*devicepb.Device, *ecdsa.PublicKey, error) { + now := timestamppb.Now() + initReq, err := d.EnrollDeviceInit() + if err != nil { + return nil, nil, trace.Wrap(err) + } + + var pub *ecdsa.PublicKey + if d.GetDeviceOSType() == devicepb.OSType_OS_TYPE_MACOS { + pubKey, err := x509.ParsePKIXPublicKey(initReq.Macos.PublicKeyDer) + if err != nil { + return nil, nil, trace.Wrap(err) + } + var ok bool + pub, ok = pubKey.(*ecdsa.PublicKey) + if !ok { + return nil, nil, trace.BadParameter("expected ECDSA public key, got %T", pubKey) + } + } + + dev := &devicepb.Device{ + ApiVersion: "v1", + Id: deviceID, + OsType: d.GetDeviceOSType(), + AssetTag: initReq.DeviceData.SerialNumber, + CreateTime: now, + UpdateTime: now, + Credential: d.GetDeviceCredential(), + EnrollStatus: devicepb.DeviceEnrollStatus_DEVICE_ENROLL_STATUS_ENROLLED, + } + return dev, pub, nil +} From a1f40415180b30b762cc1ab35c192c24df176ecb Mon Sep 17 00:00:00 2001 From: Tiago Silva Date: Thu, 18 Jul 2024 17:05:08 +0100 Subject: [PATCH 20/25] [sec_scan][20] add `ReportSecrets` forwarder to proxy's gRPC insecure server (#44324) * [sec_scan][20] add `ReportSecrets` forwarder to proxy's gRPC insecure server This PR implements a `ReportSecrets` forwarder from Proxy server to Auth server. The goal is to allow clients to hit the proxy insecure gRPC server (credentialless) and proxy will forward requests to the AuthServer on behalf of the client. This is required because the client doesn't have valid credentials and it wasn't possible for it to reach auth server via reversetunnel when the cluster uses `separate` mode. This PR is part of https://github.com/gravitational/access-graph/issues/637. Signed-off-by: Tiago Silva * add comments * move dial to lib/client/proxy/insecure --------- Signed-off-by: Tiago Silva --- lib/auth/join/join.go | 90 +-------- lib/auth/join/join_test.go | 47 ----- lib/client/proxy/insecure/insecure.go | 136 +++++++++++++ lib/client/proxy/insecure/insecure_test.go | 157 +++++++++++++++ lib/secretsscanner/client/client.go | 109 ++++++++++ lib/secretsscanner/proxy/proxy.go | 134 +++++++++++++ lib/secretsscanner/proxy/proxy_test.go | 221 +++++++++++++++++++++ lib/service/service.go | 26 ++- lib/service/service_test.go | 3 +- 9 files changed, 791 insertions(+), 132 deletions(-) create mode 100644 lib/client/proxy/insecure/insecure.go create mode 100644 lib/client/proxy/insecure/insecure_test.go create mode 100644 lib/secretsscanner/client/client.go create mode 100644 lib/secretsscanner/proxy/proxy.go create mode 100644 lib/secretsscanner/proxy/proxy_test.go diff --git a/lib/auth/join/join.go b/lib/auth/join/join.go index 367b091612ac5..d5d6b8f3b96c9 100644 --- a/lib/auth/join/join.go +++ b/lib/auth/join/join.go @@ -18,28 +18,20 @@ package join import ( "context" - "crypto/tls" "crypto/x509" "log/slog" "os" - "slices" "time" "github.com/gravitational/trace" "github.com/jonboulle/clockwork" log "github.com/sirupsen/logrus" "go.opentelemetry.io/otel" - "golang.org/x/net/http2" - "google.golang.org/grpc" - "google.golang.org/grpc/credentials" "github.com/gravitational/teleport" "github.com/gravitational/teleport/api/breaker" "github.com/gravitational/teleport/api/client" "github.com/gravitational/teleport/api/client/proto" - "github.com/gravitational/teleport/api/constants" - apidefaults "github.com/gravitational/teleport/api/defaults" - "github.com/gravitational/teleport/api/metadata" "github.com/gravitational/teleport/api/observability/tracing" "github.com/gravitational/teleport/api/types" "github.com/gravitational/teleport/api/utils/aws" @@ -47,6 +39,7 @@ import ( "github.com/gravitational/teleport/lib/auth/join/iam" "github.com/gravitational/teleport/lib/auth/state" "github.com/gravitational/teleport/lib/circleci" + proxyinsecureclient "github.com/gravitational/teleport/lib/client/proxy/insecure" "github.com/gravitational/teleport/lib/cloud/imds/azure" "github.com/gravitational/teleport/lib/cloud/imds/gcp" "github.com/gravitational/teleport/lib/defaults" @@ -54,7 +47,6 @@ import ( "github.com/gravitational/teleport/lib/gitlab" "github.com/gravitational/teleport/lib/kubernetestoken" "github.com/gravitational/teleport/lib/spacelift" - "github.com/gravitational/teleport/lib/srv/alpnproxy/common" "github.com/gravitational/teleport/lib/tlsca" "github.com/gravitational/teleport/lib/tpm" "github.com/gravitational/teleport/lib/utils" @@ -292,7 +284,16 @@ func registerThroughProxy( switch params.JoinMethod { case types.JoinMethodIAM, types.JoinMethodAzure, types.JoinMethodTPM: // IAM and Azure join methods require gRPC client - conn, err := proxyJoinServiceConn(ctx, params, params.Insecure) + conn, err := proxyinsecureclient.NewConnection( + ctx, + proxyinsecureclient.ConnectionConfig{ + ProxyServer: getHostAddresses(params)[0], + CipherSuites: params.CipherSuites, + Clock: params.Clock, + Insecure: params.Insecure, + Log: slog.Default(), + }, + ) if err != nil { return nil, trace.Wrap(err) } @@ -401,56 +402,6 @@ func registerThroughAuth( return certs, trace.Wrap(err) } -// proxyJoinServiceConn attempts to connect to the join service running on the -// proxy. The Proxy's TLS cert will be verified using the host's root CA pool -// (PKI) unless the --insecure flag was passed. -func proxyJoinServiceConn( - ctx context.Context, params RegisterParams, insecure bool, -) (*grpc.ClientConn, error) { - tlsConfig := utils.TLSConfig(params.CipherSuites) - tlsConfig.Time = params.Clock.Now - // set NextProtos for TLS routing, the actual protocol will be h2 - tlsConfig.NextProtos = []string{string(common.ProtocolProxyGRPCInsecure), http2.NextProtoTLS} - - if insecure { - tlsConfig.InsecureSkipVerify = true - log.Warnf("Joining cluster without validating the identity of the Proxy Server.") - } - - // Check if proxy is behind a load balancer. If so, the connection upgrade - // will verify the load balancer's cert using system cert pool. This - // provides the same level of security as the client only verifies Proxy's - // web cert against system cert pool when connection upgrade is not - // required. - // - // With the ALPN connection upgrade, the tunneled TLS Routing request will - // skip verify as the Proxy server will present its host cert which is not - // fully verifiable at this point since the client does not have the host - // CAs yet before completing registration. - alpnConnUpgrade := client.IsALPNConnUpgradeRequired(ctx, getHostAddresses(params)[0], insecure) - if alpnConnUpgrade && !insecure { - tlsConfig.InsecureSkipVerify = true - tlsConfig.VerifyConnection = verifyALPNUpgradedConn(params.Clock) - } - - dialer := client.NewDialer( - ctx, - apidefaults.DefaultIdleTimeout, - apidefaults.DefaultIOTimeout, - client.WithInsecureSkipVerify(insecure), - client.WithALPNConnUpgrade(alpnConnUpgrade), - ) - - conn, err := grpc.Dial( - getHostAddresses(params)[0], - grpc.WithContextDialer(client.GRPCContextDialer(dialer)), - grpc.WithUnaryInterceptor(metadata.UnaryClientInterceptor), - grpc.WithStreamInterceptor(metadata.StreamClientInterceptor), - grpc.WithTransportCredentials(credentials.NewTLS(tlsConfig)), - ) - return conn, trace.Wrap(err) -} - func getHostAddresses(params RegisterParams) []string { if !params.ProxyServer.IsEmpty() { return []string{params.ProxyServer.String()} @@ -459,25 +410,6 @@ func getHostAddresses(params RegisterParams) []string { return utils.NetAddrsToStrings(params.AuthServers) } -// verifyALPNUpgradedConn is a tls.Config.VerifyConnection callback function -// used by the tunneled TLS Routing request to verify the host cert of a Proxy -// behind a L7 load balancer. -// -// Since the client has not obtained the cluster CAs at this point, the -// presented cert cannot be fully verified yet. For now, this function only -// checks if "teleport.cluster.local" is present as one of the DNS names and -// verifies the cert is not expired. -func verifyALPNUpgradedConn(clock clockwork.Clock) func(tls.ConnectionState) error { - return func(server tls.ConnectionState) error { - for _, cert := range server.PeerCertificates { - if slices.Contains(cert.DNSNames, constants.APIDomain) && clock.Now().Before(cert.NotAfter) { - return nil - } - } - return trace.AccessDenied("server is not a Teleport proxy or server certificate is expired") - } -} - // insecureRegisterClient attempts to connects to the Auth Server using the // CA on disk. If no CA is found on disk, Teleport will not verify the Auth // Server it is connecting to. diff --git a/lib/auth/join/join_test.go b/lib/auth/join/join_test.go index 7e32eb55438c2..8ccbdaba79c2e 100644 --- a/lib/auth/join/join_test.go +++ b/lib/auth/join/join_test.go @@ -18,7 +18,6 @@ package join import ( "context" - "crypto/tls" "errors" "net" "os" @@ -40,7 +39,6 @@ import ( "github.com/gravitational/teleport/lib/auth/testauthority" "github.com/gravitational/teleport/lib/defaults" "github.com/gravitational/teleport/lib/events" - "github.com/gravitational/teleport/lib/fixtures" "github.com/gravitational/teleport/lib/modules" "github.com/gravitational/teleport/lib/tlsca" "github.com/gravitational/teleport/lib/utils" @@ -281,48 +279,3 @@ func newBotToken(t *testing.T, tokenName, botName string, role types.SystemRole, require.NoError(t, err, "could not create bot token") return token } - -func TestVerifyALPNUpgradedConn(t *testing.T) { - t.Parallel() - - srv := newTestTLSServer(t) - proxy, err := auth.NewServerIdentity(srv.Auth(), "test-proxy", types.RoleProxy) - require.NoError(t, err) - - tests := []struct { - name string - serverCert []byte - clock clockwork.Clock - checkError require.ErrorAssertionFunc - }{ - { - name: "proxy verified", - serverCert: proxy.TLSCertBytes, - clock: srv.Clock(), - checkError: require.NoError, - }, - { - name: "proxy expired", - serverCert: proxy.TLSCertBytes, - clock: clockwork.NewFakeClockAt(srv.Clock().Now().Add(defaults.CATTL + time.Hour)), - checkError: require.Error, - }, - { - name: "not proxy", - serverCert: []byte(fixtures.TLSCACertPEM), - clock: srv.Clock(), - checkError: require.Error, - }, - } - - for _, test := range tests { - t.Run(test.name, func(t *testing.T) { - serverCert, err := utils.ReadCertificates(test.serverCert) - require.NoError(t, err) - - test.checkError(t, verifyALPNUpgradedConn(test.clock)(tls.ConnectionState{ - PeerCertificates: serverCert, - })) - }) - } -} diff --git a/lib/client/proxy/insecure/insecure.go b/lib/client/proxy/insecure/insecure.go new file mode 100644 index 0000000000000..97f7414be6101 --- /dev/null +++ b/lib/client/proxy/insecure/insecure.go @@ -0,0 +1,136 @@ +// Copyright 2024 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 insecure creates a client that access the proxy unauthenticated gRPC service. +package insecure + +import ( + "context" + "crypto/tls" + "log/slog" + "slices" + + "github.com/gravitational/trace" + "github.com/jonboulle/clockwork" + "golang.org/x/net/http2" + "google.golang.org/grpc" + "google.golang.org/grpc/credentials" + + "github.com/gravitational/teleport/api/client" + "github.com/gravitational/teleport/api/constants" + apidefaults "github.com/gravitational/teleport/api/defaults" + "github.com/gravitational/teleport/api/metadata" + "github.com/gravitational/teleport/lib/srv/alpnproxy/common" + "github.com/gravitational/teleport/lib/utils" +) + +// ConnectionConfig specifies parameters for the client to dial credentialless via the proxy. +type ConnectionConfig struct { + // ProxyServer is the address of the proxy server + ProxyServer string + // CipherSuites is a list of cipher suites to use for TLS client connection + CipherSuites []uint16 + // Clock specifies the time provider. Will be used to override the time anchor + // for TLS certificate verification. + // Defaults to real clock if unspecified + Clock clockwork.Clock + // Insecure trusts the certificates from the Auth Server or Proxy during registration without verification. + Insecure bool + // Log is the logger. + Log *slog.Logger +} + +// NewConnection attempts to connect to the proxy insecure grpc server. +// The Proxy's TLS cert will be verified using the host's root CA pool +// (PKI) unless the insecure flag was passed. +func NewConnection( + ctx context.Context, params ConnectionConfig, +) (*grpc.ClientConn, error) { + if params.ProxyServer == "" { + return nil, trace.BadParameter("missing ProxyServer") + } + if params.Clock == nil { + params.Clock = clockwork.NewRealClock() + } + if params.Log == nil { + params.Log = slog.Default() + } + + tlsConfig, alpnConnUpgrade := buildTLSConfig(ctx, params) + + dialer := client.NewDialer( + ctx, + apidefaults.DefaultIdleTimeout, + apidefaults.DefaultIOTimeout, + client.WithInsecureSkipVerify(params.Insecure), + client.WithALPNConnUpgrade(alpnConnUpgrade), + ) + + conn, err := grpc.NewClient( + params.ProxyServer, + grpc.WithContextDialer(client.GRPCContextDialer(dialer)), + grpc.WithUnaryInterceptor(metadata.UnaryClientInterceptor), + grpc.WithStreamInterceptor(metadata.StreamClientInterceptor), + grpc.WithTransportCredentials(credentials.NewTLS(tlsConfig)), + ) + return conn, trace.Wrap(err) +} + +// verifyALPNUpgradedConn is a tls.Config.VerifyConnection callback function +// used by the tunneled TLS Routing request to verify the host cert of a Proxy +// behind a L7 load balancer. +// +// Since the client has not obtained the cluster CAs at this point, the +// presented cert cannot be fully verified yet. For now, this function only +// checks if "teleport.cluster.local" is present as one of the DNS names and +// verifies the cert is not expired. +func verifyALPNUpgradedConn(clock clockwork.Clock) func(tls.ConnectionState) error { + return func(server tls.ConnectionState) error { + for _, cert := range server.PeerCertificates { + if slices.Contains(cert.DNSNames, constants.APIDomain) && clock.Now().Before(cert.NotAfter) { + return nil + } + } + return trace.AccessDenied("server is not a Teleport proxy or server certificate is expired") + } +} + +func buildTLSConfig(ctx context.Context, params ConnectionConfig) (*tls.Config, bool) { + tlsConfig := utils.TLSConfig(params.CipherSuites) + tlsConfig.Time = params.Clock.Now + // set NextProtos for TLS routing, the actual protocol will be h2 + tlsConfig.NextProtos = []string{string(common.ProtocolProxyGRPCInsecure), http2.NextProtoTLS} + + if params.Insecure { + tlsConfig.InsecureSkipVerify = true + params.Log.WarnContext(ctx, "Connecting to the cluster without validating the identity of the Proxy Server.") + } + + // Check if proxy is behind a load balancer. If so, the connection upgrade + // will verify the load balancer's cert using system cert pool. This + // provides the same level of security as the client only verifies Proxy's + // web cert against system cert pool when connection upgrade is not + // required. + // + // With the ALPN connection upgrade, the tunneled TLS Routing request will + // skip verify as the Proxy server will present its host cert which is not + // fully verifiable at this point since the client does not have the host + // CAs yet before completing registration. + alpnConnUpgrade := client.IsALPNConnUpgradeRequired(ctx, params.ProxyServer, params.Insecure) + if alpnConnUpgrade && !params.Insecure { + tlsConfig.InsecureSkipVerify = true + tlsConfig.VerifyConnection = verifyALPNUpgradedConn(params.Clock) + } + return tlsConfig, alpnConnUpgrade +} diff --git a/lib/client/proxy/insecure/insecure_test.go b/lib/client/proxy/insecure/insecure_test.go new file mode 100644 index 0000000000000..9d60425d8b69a --- /dev/null +++ b/lib/client/proxy/insecure/insecure_test.go @@ -0,0 +1,157 @@ +// Copyright 2024 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 insecure + +import ( + "context" + "crypto/tls" + "errors" + "log/slog" + "net" + "os" + "strconv" + "testing" + "time" + + "github.com/jonboulle/clockwork" + "github.com/stretchr/testify/require" + + apidefaults "github.com/gravitational/teleport/api/defaults" + "github.com/gravitational/teleport/api/fixtures" + "github.com/gravitational/teleport/api/types" + "github.com/gravitational/teleport/lib/auth" + "github.com/gravitational/teleport/lib/defaults" + "github.com/gravitational/teleport/lib/modules" + "github.com/gravitational/teleport/lib/srv/alpnproxy/common" + "github.com/gravitational/teleport/lib/utils" +) + +func TestMain(m *testing.M) { + modules.SetInsecureTestMode(true) + os.Exit(m.Run()) +} + +func TestVerifyALPNUpgradedConn(t *testing.T) { + t.Parallel() + + srv := newTestTLSServer(t) + proxy, err := auth.NewServerIdentity(srv.Auth(), "test-proxy", types.RoleProxy) + require.NoError(t, err) + + tests := []struct { + name string + serverCert []byte + clock clockwork.Clock + checkError require.ErrorAssertionFunc + }{ + { + name: "proxy verified", + serverCert: proxy.TLSCertBytes, + clock: srv.Clock(), + checkError: require.NoError, + }, + { + name: "proxy expired", + serverCert: proxy.TLSCertBytes, + clock: clockwork.NewFakeClockAt(srv.Clock().Now().Add(defaults.CATTL + time.Hour)), + checkError: require.Error, + }, + { + name: "not proxy", + serverCert: []byte(fixtures.TLSCACertPEM), + clock: srv.Clock(), + checkError: require.Error, + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + serverCert, err := utils.ReadCertificates(test.serverCert) + require.NoError(t, err) + + test.checkError(t, verifyALPNUpgradedConn(test.clock)(tls.ConnectionState{ + PeerCertificates: serverCert, + })) + }) + } +} + +func newTestTLSServer(t testing.TB) *auth.TestTLSServer { + as, err := auth.NewTestAuthServer(auth.TestAuthServerConfig{ + Dir: t.TempDir(), + Clock: clockwork.NewFakeClockAt(time.Now().Round(time.Second).UTC()), + }) + require.NoError(t, err) + + srv, err := as.NewTestTLSServer() + require.NoError(t, err) + + t.Cleanup(func() { + err := srv.Close() + if errors.Is(err, net.ErrClosed) { + return + } + require.NoError(t, err) + }) + + return srv +} + +func TestBuildTLSConfig(t *testing.T) { + tests := []struct { + name string + proxyAddr string + alpnEnvValue bool + insecure bool + expectInsecure bool + }{ + { + name: "insecure", + proxyAddr: "localhost:1234", + alpnEnvValue: false, + insecure: true, + expectInsecure: true, + }, + { + name: "secure", + proxyAddr: "localhost:1234", + alpnEnvValue: false, + insecure: false, + expectInsecure: false, + }, + { + name: "alpn upgrade required", + proxyAddr: "localhost:1234", + alpnEnvValue: true, + insecure: false, + expectInsecure: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + t.Setenv(apidefaults.TLSRoutingConnUpgradeEnvVar, strconv.FormatBool(tt.alpnEnvValue)) + tlsConfig, alpnUpgrade := buildTLSConfig(context.Background(), ConnectionConfig{ + ProxyServer: tt.proxyAddr, + Insecure: tt.insecure, + Log: slog.Default(), + Clock: clockwork.NewRealClock(), + }) + require.Equal(t, alpnUpgrade, tt.alpnEnvValue) + require.Equal(t, tlsConfig.InsecureSkipVerify, tt.expectInsecure) + require.Contains(t, tlsConfig.NextProtos, string(common.ProtocolProxyGRPCInsecure)) + }) + } +} diff --git a/lib/secretsscanner/client/client.go b/lib/secretsscanner/client/client.go new file mode 100644 index 0000000000000..1ea24ec1ff97f --- /dev/null +++ b/lib/secretsscanner/client/client.go @@ -0,0 +1,109 @@ +/* + * Teleport + * Copyright (C) 2024 Gravitational, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package client + +import ( + "context" + "log/slog" + + "github.com/gravitational/trace" + "github.com/jonboulle/clockwork" + "google.golang.org/grpc" + + accessgraphsecretsv1pb "github.com/gravitational/teleport/api/gen/proto/go/teleport/accessgraph/v1" + proxyinsecureclient "github.com/gravitational/teleport/lib/client/proxy/insecure" +) + +// Client is a client for the SecretsScannerService. +type Client interface { + // ReportSecrets is used by trusted devices to report secrets found on the host that could be used to bypass Teleport. + // The client (device) should first authenticate using the [ReportSecretsRequest.device_assertion] flow. Please refer to + // the [teleport.devicetrust.v1.AssertDeviceRequest] and [teleport.devicetrust.v1.AssertDeviceResponse] messages for more details. + // + // Once the device is asserted, the client can send the secrets using the [ReportSecretsRequest.private_keys] field + // and then close the client side of the stream. + // + // -> ReportSecrets (client) [1 or more] + // -> CloseStream (client) + // <- TerminateStream (server) + // + // Any failure in the assertion ceremony will result in the stream being terminated by the server. All secrets + // reported by the client before the assertion terminates will be ignored and result in the stream being terminated. + ReportSecrets(ctx context.Context, opts ...grpc.CallOption) (accessgraphsecretsv1pb.SecretsScannerService_ReportSecretsClient, error) + // Close closes the client connection. + Close() error +} + +// ClientConfig specifies parameters for the client to dial credentialless via the proxy. +type ClientConfig struct { + // ProxyServer is the address of the proxy server + ProxyServer string + // CipherSuites is a list of cipher suites to use for TLS client connection + CipherSuites []uint16 + // Clock specifies the time provider. Will be used to override the time anchor + // for TLS certificate verification. + // Defaults to real clock if unspecified + Clock clockwork.Clock + // Insecure trusts the certificates from the Auth Server or Proxy during registration without verification. + Insecure bool + // Log is the logger. + Log *slog.Logger +} + +// NewSecretsScannerServiceClient creates a new SecretsScannerServiceClient that connects to the proxy +// gRPC server that does not require authentication (credentialless) to report secrets found during scanning. +func NewSecretsScannerServiceClient(ctx context.Context, cfg ClientConfig) (Client, error) { + if cfg.ProxyServer == "" { + return nil, trace.BadParameter("missing ProxyServer") + } + if cfg.Clock == nil { + cfg.Clock = clockwork.NewRealClock() + } + if cfg.Log == nil { + cfg.Log = slog.Default() + } + + grpcConn, err := proxyinsecureclient.NewConnection( + ctx, + proxyinsecureclient.ConnectionConfig{ + ProxyServer: cfg.ProxyServer, + CipherSuites: cfg.CipherSuites, + Clock: cfg.Clock, + Insecure: cfg.Insecure, + Log: cfg.Log, + }, + ) + if err != nil { + return nil, trace.Wrap(err, "failed to connect to the proxy") + } + + return &secretsSvcClient{ + SecretsScannerServiceClient: accessgraphsecretsv1pb.NewSecretsScannerServiceClient(grpcConn), + conn: grpcConn, + }, nil +} + +type secretsSvcClient struct { + accessgraphsecretsv1pb.SecretsScannerServiceClient + conn *grpc.ClientConn +} + +func (c *secretsSvcClient) Close() error { + return c.conn.Close() +} diff --git a/lib/secretsscanner/proxy/proxy.go b/lib/secretsscanner/proxy/proxy.go new file mode 100644 index 0000000000000..c9888f9b5910c --- /dev/null +++ b/lib/secretsscanner/proxy/proxy.go @@ -0,0 +1,134 @@ +/* + * Teleport + * Copyright (C) 2024 Gravitational, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +// Package proxy implements a proxy service that proxies requests from the proxy unauthenticated +// gRPC service to the Auth's secret service. +package proxy + +import ( + "context" + "errors" + "io" + "log/slog" + + "github.com/gravitational/trace" + + accessgraphsecretsv1pb "github.com/gravitational/teleport/api/gen/proto/go/teleport/accessgraph/v1" +) + +// AuthClient is a subset of the full Auth API that must be connected +type AuthClient interface { + AccessGraphSecretsScannerClient() accessgraphsecretsv1pb.SecretsScannerServiceClient +} + +// ServiceConfig is the configuration for the Service. +type ServiceConfig struct { + // AuthClient is the client to the Auth service. + AuthClient AuthClient + // Log is the logger. + Log *slog.Logger +} + +// New creates a new Service. +func New(cfg ServiceConfig) (*Service, error) { + if cfg.AuthClient == nil { + return nil, trace.BadParameter("missing AuthClient") + } + if cfg.Log == nil { + cfg.Log = slog.Default() + } + return &Service{ + authClient: cfg.AuthClient, + log: cfg.Log, + }, nil +} + +// Service is a service that proxies requests from the proxy to the Auth's secret service. +// It only implements the ReportSecrets method of the SecretsScannerService because it is the only method that needs to be proxied +// from the proxy to the Auth's secret service. +type Service struct { + accessgraphsecretsv1pb.UnimplementedSecretsScannerServiceServer + // authClient is the client to the Auth service. + authClient AuthClient + + log *slog.Logger +} + +// ReportSecrets proxies the ReportSecrets method from the proxy to the Auth's secret service. +func (s *Service) ReportSecrets(client accessgraphsecretsv1pb.SecretsScannerService_ReportSecretsServer) error { + ctx, cancel := context.WithCancel(client.Context()) + defer cancel() + upstream, err := s.authClient.AccessGraphSecretsScannerClient().ReportSecrets(ctx) + if err != nil { + return trace.Wrap(err) + } + + errCh := make(chan error, 1) + go func() { + err := trace.Wrap(s.forwardClientToServer(ctx, client, upstream)) + if err != nil { + cancel() + } + errCh <- err + }() + + err = s.forwardServerToClient(ctx, client, upstream) + return trace.NewAggregate(err, <-errCh) +} + +func (s *Service) forwardClientToServer(ctx context.Context, + client accessgraphsecretsv1pb.SecretsScannerService_ReportSecretsServer, + server accessgraphsecretsv1pb.SecretsScannerService_ReportSecretsClient) (err error) { + for { + req, err := client.Recv() + if errors.Is(err, io.EOF) { + if err := server.CloseSend(); err != nil { + s.log.WarnContext(ctx, "Failed to close upstream stream", "error", err) + } + break + } + if err != nil { + s.log.WarnContext(ctx, "Failed to receive from client stream", "error", err) + return trace.Wrap(err) + } + if err := server.Send(req); err != nil { + s.log.WarnContext(ctx, "Failed to send to upstream stream", "error", err) + return trace.Wrap(err) + } + } + return nil +} + +func (s *Service) forwardServerToClient(ctx context.Context, + client accessgraphsecretsv1pb.SecretsScannerService_ReportSecretsServer, + server accessgraphsecretsv1pb.SecretsScannerService_ReportSecretsClient) (err error) { + for { + out, err := server.Recv() + if errors.Is(err, io.EOF) { + return nil + } + if err != nil { + s.log.WarnContext(ctx, "Failed to receive from upstream stream", "error", err) + return trace.Wrap(err) + } + if err := client.Send(out); err != nil { + s.log.WarnContext(ctx, "Failed to send to client stream", "error", err) + return trace.Wrap(err) + } + } +} diff --git a/lib/secretsscanner/proxy/proxy_test.go b/lib/secretsscanner/proxy/proxy_test.go new file mode 100644 index 0000000000000..91be3288fef85 --- /dev/null +++ b/lib/secretsscanner/proxy/proxy_test.go @@ -0,0 +1,221 @@ +/* + * Teleport + * Copyright (C) 2024 Gravitational, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package proxy + +import ( + "context" + "crypto/tls" + "errors" + "io" + "net" + "testing" + + "github.com/gravitational/trace" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "google.golang.org/grpc" + "google.golang.org/grpc/credentials" + "google.golang.org/grpc/credentials/insecure" + + "github.com/gravitational/teleport/api/defaults" + accessgraphsecretsv1pb "github.com/gravitational/teleport/api/gen/proto/go/teleport/accessgraph/v1" + devicepb "github.com/gravitational/teleport/api/gen/proto/go/teleport/devicetrust/v1" + "github.com/gravitational/teleport/lib/fixtures" + secretscannerclient "github.com/gravitational/teleport/lib/secretsscanner/client" +) + +func TestProxy(t *testing.T) { + // Disable the TLS routing connection upgrade + t.Setenv(defaults.TLSRoutingConnUpgradeEnvVar, "false") + + authClient := newFakefakeSecretsScannerSvc(t) + + lis, err := net.Listen("tcp", "localhost:0") + require.NoError(t, err) + + newProxyService(t, lis, authClient) + ctx := context.Background() + + client, err := secretscannerclient.NewSecretsScannerServiceClient(ctx, secretscannerclient.ClientConfig{ + ProxyServer: lis.Addr().String(), + Insecure: true, + }) + require.NoError(t, err) + + stream, err := client.ReportSecrets(ctx) + require.NoError(t, err) + + // Send the device assertion init message + err = stream.Send(&accessgraphsecretsv1pb.ReportSecretsRequest{ + Payload: &accessgraphsecretsv1pb.ReportSecretsRequest_DeviceAssertion{ + DeviceAssertion: &devicepb.AssertDeviceRequest{ + Payload: &devicepb.AssertDeviceRequest_Init{ + Init: &devicepb.AssertDeviceInit{}, + }, + }, + }, + }) + require.NoError(t, err) + + // Receive the device assertion challenge message + msg, err := stream.Recv() + require.NoError(t, err) + assert.NotNil(t, msg.GetDeviceAssertion().GetChallenge()) + + // Send the device assertion challenge response message + err = stream.Send(&accessgraphsecretsv1pb.ReportSecretsRequest{ + Payload: &accessgraphsecretsv1pb.ReportSecretsRequest_DeviceAssertion{ + DeviceAssertion: &devicepb.AssertDeviceRequest{ + Payload: &devicepb.AssertDeviceRequest_ChallengeResponse{ + ChallengeResponse: &devicepb.AuthenticateDeviceChallengeResponse{Signature: []byte("response")}, + }, + }, + }, + }) + require.NoError(t, err) + + // Receive the device assertion response message + msg, err = stream.Recv() + require.NoError(t, err) + assert.NotNil(t, msg.GetDeviceAssertion().GetDeviceAsserted()) + + // Send close message + err = stream.CloseSend() + require.NoError(t, err) + + // Receive the termination message + _, err = stream.Recv() + require.ErrorIs(t, err, io.EOF) + +} + +func newFakefakeSecretsScannerSvc(t *testing.T) *fakeSecretsClient { + lis, err := net.Listen("tcp", "localhost:0") + require.NoError(t, err) + + server := grpc.NewServer() + accessgraphsecretsv1pb.RegisterSecretsScannerServiceServer(server, &fakeSecretsScannerSvc{}) + go func() { + err := server.Serve(lis) + assert.NoError(t, err) + }() + t.Cleanup(server.GracefulStop) + + client, err := grpc.NewClient(lis.Addr().String(), grpc.WithTransportCredentials(insecure.NewCredentials())) + require.NoError(t, err) + + return &fakeSecretsClient{ + SecretsScannerServiceClient: accessgraphsecretsv1pb.NewSecretsScannerServiceClient(client), + } + +} + +type fakeSecretsClient struct { + accessgraphsecretsv1pb.SecretsScannerServiceClient +} + +func (s *fakeSecretsClient) AccessGraphSecretsScannerClient() accessgraphsecretsv1pb.SecretsScannerServiceClient { + return s +} + +type fakeSecretsScannerSvc struct { + accessgraphsecretsv1pb.UnimplementedSecretsScannerServiceServer +} + +func (f *fakeSecretsScannerSvc) ReportSecrets(in accessgraphsecretsv1pb.SecretsScannerService_ReportSecretsServer) error { + msg, err := in.Recv() + if err != nil { + return trace.Wrap(err) + } + + if msg.GetDeviceAssertion().GetInit() == nil { + return trace.BadParameter("missing device init") + } + + err = in.Send(&accessgraphsecretsv1pb.ReportSecretsResponse{ + Payload: &accessgraphsecretsv1pb.ReportSecretsResponse_DeviceAssertion{ + DeviceAssertion: &devicepb.AssertDeviceResponse{ + Payload: &devicepb.AssertDeviceResponse_Challenge{ + Challenge: &devicepb.AuthenticateDeviceChallenge{Challenge: []byte("challenge")}, + }, + }, + }, + }) + if err != nil { + return trace.Wrap(err) + } + msg, err = in.Recv() + if err != nil { + return trace.Wrap(err) + } + + if msg.GetDeviceAssertion().GetChallengeResponse() == nil { + return trace.BadParameter("missing device challenge") + } + + err = in.Send(&accessgraphsecretsv1pb.ReportSecretsResponse{ + Payload: &accessgraphsecretsv1pb.ReportSecretsResponse_DeviceAssertion{ + DeviceAssertion: &devicepb.AssertDeviceResponse{ + Payload: &devicepb.AssertDeviceResponse_DeviceAsserted{ + DeviceAsserted: &devicepb.DeviceAsserted{}, + }, + }, + }, + }) + if err != nil { + return trace.Wrap(err) + } + + _, err = in.Recv() + if errors.Is(err, io.EOF) { + return nil + } + return trace.BadParameter("unexpected message") +} + +func newProxyService(t *testing.T, lis net.Listener, authClient AuthClient) { + localTLSConfig, err := fixtures.LocalTLSConfig() + require.NoError(t, err) + + tlsConfig := localTLSConfig.TLS.Clone() + tlsConfig.InsecureSkipVerify = true + tlsConfig.ClientAuth = tls.RequestClientCert + tlsConfig.RootCAs = nil + + s := grpc.NewServer( + grpc.Creds( + credentials.NewTLS(tlsConfig), + ), + ) + t.Cleanup(s.GracefulStop) + + proxy, err := New(ServiceConfig{ + AuthClient: authClient, + }, + ) + require.NoError(t, err) + + accessgraphsecretsv1pb.RegisterSecretsScannerServiceServer(s, proxy) + + go func() { + err := s.Serve(lis) + assert.NoError(t, err) + }() + +} diff --git a/lib/service/service.go b/lib/service/service.go index aa17b12ab6639..b61155dd001ac 100644 --- a/lib/service/service.go +++ b/lib/service/service.go @@ -70,6 +70,7 @@ import ( "github.com/gravitational/teleport/api/client/webclient" "github.com/gravitational/teleport/api/constants" apidefaults "github.com/gravitational/teleport/api/defaults" + accessgraphsecretsv1pb "github.com/gravitational/teleport/api/gen/proto/go/teleport/accessgraph/v1" integrationpb "github.com/gravitational/teleport/api/gen/proto/go/teleport/integration/v1" kubeproto "github.com/gravitational/teleport/api/gen/proto/go/teleport/kube/v1" transportpb "github.com/gravitational/teleport/api/gen/proto/go/teleport/transport/v1" @@ -137,6 +138,7 @@ import ( "github.com/gravitational/teleport/lib/resumption" "github.com/gravitational/teleport/lib/reversetunnel" "github.com/gravitational/teleport/lib/reversetunnelclient" + secretsscannerproxy "github.com/gravitational/teleport/lib/secretsscanner/proxy" "github.com/gravitational/teleport/lib/service/servicecfg" "github.com/gravitational/teleport/lib/services" "github.com/gravitational/teleport/lib/services/local" @@ -4092,7 +4094,6 @@ func (process *TeleportProcess) initProxyEndpoint(conn *Connector) error { return trace.Wrap(err) } alpnRouter, reverseTunnelALPNRouter := setupALPNRouter(listeners, serverTLSConfig, cfg) - alpnAddr := "" if listeners.alpn != nil { alpnAddr = listeners.alpn.Addr().String() @@ -4943,8 +4944,10 @@ func (process *TeleportProcess) initProxyEndpoint(conn *Connector) error { grpcServerMTLS *grpc.Server ) if alpnRouter != nil { - grpcServerPublic = process.initPublicGRPCServer(proxyLimiter, conn, listeners.grpcPublic) - + grpcServerPublic, err = process.initPublicGRPCServer(proxyLimiter, conn, listeners.grpcPublic) + if err != nil { + return trace.Wrap(err) + } grpcServerMTLS, err = process.initSecureGRPCServer( initSecureGRPCServerCfg{ limiter: proxyLimiter, @@ -6291,7 +6294,7 @@ func (process *TeleportProcess) initPublicGRPCServer( limiter *limiter.Limiter, conn *Connector, listener net.Listener, -) *grpc.Server { +) (*grpc.Server, error) { server := grpc.NewServer( grpc.ChainUnaryInterceptor( interceptors.GRPCServerUnaryErrorInterceptor, @@ -6322,11 +6325,24 @@ func (process *TeleportProcess) initPublicGRPCServer( ) joinServiceServer := joinserver.NewJoinServiceGRPCServer(conn.Client) proto.RegisterJoinServiceServer(server, joinServiceServer) + + accessGraphProxySvc, err := secretsscannerproxy.New( + secretsscannerproxy.ServiceConfig{ + AuthClient: conn.Client, + Log: process.logger, + }) + if err != nil { + return nil, trace.Wrap(err) + + } + + accessgraphsecretsv1pb.RegisterSecretsScannerServiceServer(server, accessGraphProxySvc) + process.RegisterCriticalFunc("proxy.grpc.public", func() error { process.logger.InfoContext(process.ExitContext(), "Starting proxy gRPC server.", "listen_address", listener.Addr()) return trace.Wrap(server.Serve(listener)) }) - return server + return server, nil } // initSecureGRPCServer creates and registers a gRPC server that uses mTLS for diff --git a/lib/service/service_test.go b/lib/service/service_test.go index f1c4e37d43489..325a4d148fc6f 100644 --- a/lib/service/service_test.go +++ b/lib/service/service_test.go @@ -1294,7 +1294,8 @@ func TestProxyGRPCServers(t *testing.T) { }) // Insecure gRPC server. - insecureGRPC := process.initPublicGRPCServer(limiter, testConnector, insecureListener) + insecureGRPC, err := process.initPublicGRPCServer(limiter, testConnector, insecureListener) + require.NoError(t, err) t.Cleanup(insecureGRPC.GracefulStop) proxyLockWatcher, err := services.NewLockWatcher(context.Background(), services.LockWatcherConfig{ From 1ea66feb9fe87ad74a95bd50b2a4cdba9bf4db9b Mon Sep 17 00:00:00 2001 From: Tiago Silva Date: Thu, 25 Jul 2024 16:20:29 +0100 Subject: [PATCH 21/25] [sec_scan][19] add `tsh scan keys` implementation (#44220) * [sec_scan][19] add `tsh scan keys` implementation This PR introduces the required code to transverse a directory(es), finding all the SSH private keys and report them back to the cluster using the device security enclave as authentication mechanism. This PR is part of https://github.com/gravitational/access-graph/issues/637. Signed-off-by: Tiago Silva * handle code review * fix message * handle code review * fork ssh private keys * add skip dirs support * handle code review --------- Signed-off-by: Tiago Silva --- api/types/accessgraph/private_key.go | 15 + lib/secretsscanner/reporter/env_test.go | 199 ++++++++++++ lib/secretsscanner/reporter/report.go | 195 ++++++++++++ lib/secretsscanner/reporter/report_test.go | 157 +++++++++ lib/secretsscanner/scaner/scan.go | 298 ++++++++++++++++++ lib/secretsscanner/scaner/scan_test.go | 237 ++++++++++++++ .../scaner/testdata/invalid_keys.go | 50 +++ .../scaner/testdata/ssh_keys.go | 290 +++++++++++++++++ tool/tsh/common/scan.go | 170 ++++++++++ tool/tsh/common/tsh.go | 5 +- 10 files changed, 1615 insertions(+), 1 deletion(-) create mode 100644 lib/secretsscanner/reporter/env_test.go create mode 100644 lib/secretsscanner/reporter/report.go create mode 100644 lib/secretsscanner/reporter/report_test.go create mode 100644 lib/secretsscanner/scaner/scan.go create mode 100644 lib/secretsscanner/scaner/scan_test.go create mode 100644 lib/secretsscanner/scaner/testdata/invalid_keys.go create mode 100644 lib/secretsscanner/scaner/testdata/ssh_keys.go create mode 100644 tool/tsh/common/scan.go diff --git a/api/types/accessgraph/private_key.go b/api/types/accessgraph/private_key.go index 57e0874ed040a..a8730685f8d3c 100644 --- a/api/types/accessgraph/private_key.go +++ b/api/types/accessgraph/private_key.go @@ -106,3 +106,18 @@ func hashComp(values ...string) string { } return hex.EncodeToString(h.Sum(nil)) } + +// DescribePublicKeyMode returns a human-readable description of the public key mode. +func DescribePublicKeyMode(mode accessgraphv1pb.PublicKeyMode) string { + switch mode { + case accessgraphv1pb.PublicKeyMode_PUBLIC_KEY_MODE_PUB_FILE: + return "used public key file" + case accessgraphv1pb.PublicKeyMode_PUBLIC_KEY_MODE_PROTECTED: + return "protected private key" + case accessgraphv1pb.PublicKeyMode_PUBLIC_KEY_MODE_DERIVED: + return "derived from private key" + default: + return "unknown" + } + +} diff --git a/lib/secretsscanner/reporter/env_test.go b/lib/secretsscanner/reporter/env_test.go new file mode 100644 index 0000000000000..04ffebb5c6711 --- /dev/null +++ b/lib/secretsscanner/reporter/env_test.go @@ -0,0 +1,199 @@ +/* + * Teleport + * Copyright (C) 2024 Gravitational, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package reporter_test + +import ( + "errors" + "io" + "net" + "testing" + + "github.com/gravitational/trace" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "google.golang.org/grpc" + "google.golang.org/grpc/credentials" + + accessgraphsecretsv1pb "github.com/gravitational/teleport/api/gen/proto/go/teleport/accessgraph/v1" + devicepb "github.com/gravitational/teleport/api/gen/proto/go/teleport/devicetrust/v1" + dttestenv "github.com/gravitational/teleport/lib/devicetrust/testenv" + "github.com/gravitational/teleport/lib/fixtures" +) + +type env struct { + secretsScannerAddr string + service *serviceFake +} + +type opts struct { + device *device + preReconcileError error +} + +type device struct { + device dttestenv.FakeDevice + id string +} + +type option func(*opts) + +func withDevice(deviceID string, dev dttestenv.FakeDevice) option { + return func(o *opts) { + o.device = &device{ + device: dev, + id: deviceID, + } + } +} + +func withPreReconcileError(err error) option { + return func(o *opts) { + o.preReconcileError = err + } +} + +func setup(t *testing.T, ops ...option) env { + t.Helper() + + o := opts{} + for _, op := range ops { + op(&o) + } + + var opts []dttestenv.Opt + if o.device != nil { + dev, pubKey, err := dttestenv.CreateEnrolledDevice(o.device.id, o.device.device) + require.NoError(t, err) + opts = append(opts, dttestenv.WithPreEnrolledDevice(dev, pubKey)) + } + dtFakeSvc, err := dttestenv.New(opts...) + require.NoError(t, err) + t.Cleanup(func() { + err := dtFakeSvc.Close() + assert.NoError(t, err) + }) + + svc := newServiceFake(dtFakeSvc.Service) + svc.preReconcileError = o.preReconcileError + + tlsConfig, err := fixtures.LocalTLSConfig() + require.NoError(t, err) + + grpcServer := grpc.NewServer( + grpc.Creds( + credentials.NewTLS(tlsConfig.TLS), + ), + ) + accessgraphsecretsv1pb.RegisterSecretsScannerServiceServer(grpcServer, svc) + + lis, err := net.Listen("tcp", "127.0.0.1:0") + require.NoError(t, err) + go func() { + err := grpcServer.Serve(lis) + assert.NoError(t, err) + }() + t.Cleanup(func() { + grpcServer.Stop() + _ = lis.Close() + }) + + return env{ + service: svc, + secretsScannerAddr: lis.Addr().String(), + } +} + +func newServiceFake(deviceTrustSvc *dttestenv.FakeDeviceService) *serviceFake { + return &serviceFake{ + deviceTrustSvc: deviceTrustSvc, + } +} + +type serviceFake struct { + accessgraphsecretsv1pb.UnimplementedSecretsScannerServiceServer + privateKeysReported []*accessgraphsecretsv1pb.PrivateKey + deviceTrustSvc *dttestenv.FakeDeviceService + preReconcileError error +} + +func (s *serviceFake) ReportSecrets(in accessgraphsecretsv1pb.SecretsScannerService_ReportSecretsServer) error { + // Step 1. Assert the device. + if _, err := s.deviceTrustSvc.AssertDevice(in.Context(), streamAdapter{stream: in}); err != nil { + return trace.Wrap(err) + } + // Step 2. Collect the private keys into a temporary slice. + var collectedKeys []*accessgraphsecretsv1pb.PrivateKey + for { + msg, err := in.Recv() + // Step 4. When the client closes his side of the stream, we break the loop + // and collect the private keys. + if errors.Is(err, io.EOF) { + break + } else if err != nil { + return trace.Wrap(err) + } + + if msg.GetPrivateKeys() == nil { + return trace.BadParameter("unexpected assert request payload: %T", msg.GetPayload()) + } + // Step 3. Collect the private keys into a temporary slice. + collectedKeys = append(collectedKeys, msg.GetPrivateKeys().GetKeys()...) + + } + + if s.preReconcileError != nil { + return s.preReconcileError + } + + // Step 5. Store the collected private keys. + // This only happens when the client closes his side of the stream. + s.privateKeysReported = collectedKeys + return nil +} + +// streamAdapter is a helper struct that adapts the [accessgraphsecretsv1pb.SecretsScannerService_ReportSecretsServer] +// stream to the device trust assertion stream [assertserver.AssertDeviceServerStream]. +// This is needed because we need to extract the [*devicepb.AssertDeviceRequest] from the stream +// and return the [*devicepb.AssertDeviceResponse] to the stream. +type streamAdapter struct { + stream accessgraphsecretsv1pb.SecretsScannerService_ReportSecretsServer +} + +func (s streamAdapter) Send(rsp *devicepb.AssertDeviceResponse) error { + msg := &accessgraphsecretsv1pb.ReportSecretsResponse{ + Payload: &accessgraphsecretsv1pb.ReportSecretsResponse_DeviceAssertion{ + DeviceAssertion: rsp, + }, + } + err := s.stream.Send(msg) + return trace.Wrap(err) +} + +func (s streamAdapter) Recv() (*devicepb.AssertDeviceRequest, error) { + msg, err := s.stream.Recv() + if err != nil { + return nil, trace.Wrap(err) + } + + if msg.GetDeviceAssertion() == nil { + return nil, trace.BadParameter("unexpected assert request payload: %T", msg.GetPayload()) + } + + return msg.GetDeviceAssertion(), nil +} diff --git a/lib/secretsscanner/reporter/report.go b/lib/secretsscanner/reporter/report.go new file mode 100644 index 0000000000000..22dd8c22b9d3b --- /dev/null +++ b/lib/secretsscanner/reporter/report.go @@ -0,0 +1,195 @@ +/* + * Teleport + * Copyright (C) 2024 Gravitational, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package reporter + +import ( + "context" + "errors" + "io" + "log/slog" + + "github.com/gravitational/trace" + + accessgraphsecretsv1pb "github.com/gravitational/teleport/api/gen/proto/go/teleport/accessgraph/v1" + devicepb "github.com/gravitational/teleport/api/gen/proto/go/teleport/devicetrust/v1" + dtassert "github.com/gravitational/teleport/lib/devicetrust/assert" + secretsscannerclient "github.com/gravitational/teleport/lib/secretsscanner/client" +) + +// AssertCeremonyBuilderFunc is a function that builds the device authentication ceremony. +type AssertCeremonyBuilderFunc func() (*dtassert.Ceremony, error) + +// Config specifies the configuration for the reporter. +type Config struct { + // Client is a client for the SecretsScannerService. + Client secretsscannerclient.Client + // Log is the logger. + Log *slog.Logger + // BatchSize is the number of secrets to send in a single batch. Defaults to [defaultBatchSize] if not set. + BatchSize int + // AssertCeremonyBuilder is the device authentication ceremony builder. + // If not set, the default device authentication ceremony will be used. + // Used for testing, avoid in production code. + AssertCeremonyBuilder AssertCeremonyBuilderFunc +} + +// Reporter reports secrets to the Teleport Proxy. +type Reporter struct { + client secretsscannerclient.Client + log *slog.Logger + batchSize int + assertCeremonyBuilder AssertCeremonyBuilderFunc +} + +// New creates a new reporter instance. +func New(cfg Config) (*Reporter, error) { + if cfg.Client == nil { + return nil, trace.BadParameter("missing client") + } + if cfg.Log == nil { + cfg.Log = slog.Default() + } + if cfg.BatchSize == 0 { + const defaultBatchSize = 100 + cfg.BatchSize = defaultBatchSize + } + if cfg.AssertCeremonyBuilder == nil { + cfg.AssertCeremonyBuilder = func() (*dtassert.Ceremony, error) { + return dtassert.NewCeremony() + } + } + return &Reporter{ + client: cfg.Client, + log: cfg.Log, + batchSize: cfg.BatchSize, + assertCeremonyBuilder: cfg.AssertCeremonyBuilder, + }, nil +} + +// ReportPrivateKeys reports the private keys to the Teleport server. +// This function performs the following steps: +// 1. Create a new gRPC client to the Teleport Proxy. +// 2. Run the device assertion ceremony. +// 3. Report the private keys to the Teleport cluster. +// 4. Wait for the server to acknowledge the report. +func (r *Reporter) ReportPrivateKeys(ctx context.Context, pks []*accessgraphsecretsv1pb.PrivateKey) error { + + stream, err := r.client.ReportSecrets(ctx) + if err != nil { + return trace.Wrap(err, "failed to create client") + } + + if err := r.runAssertionCeremony(ctx, stream); err != nil { + return trace.Wrap(err, "failed to run assertion ceremony") + } + + if err := r.reportPrivateKeys(stream, pks); err != nil { + return trace.Wrap(err, "failed to report private keys") + } + + return trace.Wrap(r.terminateAndWaitAcknowledge(stream), "server failed to acknowledge the report") +} + +// runAssertionCeremony runs the device assertion ceremony. +func (r *Reporter) runAssertionCeremony(ctx context.Context, stream accessgraphsecretsv1pb.SecretsScannerService_ReportSecretsClient) error { + // Create a new device authentication ceremony. + assertCeremony, err := r.assertCeremonyBuilder() + if err != nil { + return trace.Wrap(err, "failed to create assertCeremony") + } + + // Run the device authentication ceremony. + // If successful, the device will be authenticated and the device can report its secrets. + err = assertCeremony.Run( + ctx, + reportToAssertStreamAdapter{stream}, + ) + return trace.Wrap(err, "failed to run device authentication ceremony") +} + +// reportPrivateKeys reports the private keys to the Teleport server in batches of size [r.batchSize] using the given stream. +func (r *Reporter) reportPrivateKeys(stream accessgraphsecretsv1pb.SecretsScannerService_ReportSecretsClient, privateKeys []*accessgraphsecretsv1pb.PrivateKey) error { + batchSize := r.batchSize + for i := 0; len(privateKeys) > i; i += batchSize { + start := i + end := i + batchSize + if end > len(privateKeys) { + end = len(privateKeys) + } + if err := stream.Send(&accessgraphsecretsv1pb.ReportSecretsRequest{ + Payload: &accessgraphsecretsv1pb.ReportSecretsRequest_PrivateKeys{ + PrivateKeys: &accessgraphsecretsv1pb.ReportPrivateKeys{ + Keys: privateKeys[start:end], + }, + }, + }); err != nil { + return trace.Wrap(err, "failed to send private keys") + } + } + return nil +} + +// terminateAndWaitAcknowledge terminates the client side of the stream and waits for the server to acknowledge the report. +func (r *Reporter) terminateAndWaitAcknowledge(stream accessgraphsecretsv1pb.SecretsScannerService_ReportSecretsClient) error { + // Inform the server that there are no more private keys to report. + if err := stream.CloseSend(); err != nil { + return trace.Wrap(err, "failed to close send") + } + + // Wait for the server to acknowledge the report. + if _, err := stream.Recv(); err != nil && !errors.Is(err, io.EOF) { + return trace.Wrap(err, "error closing the stream") + } + return nil +} + +// reportToAssertStreamAdapter is a wrapper for the [accessgraphsecretsv1pb.SecretsScannerService_ReportSecretsClient] that implements the +// [assert.AssertDeviceClientStream] interface. +// +// This adapter allows the [accessgraphsecretsv1pb.SecretsScannerService_ReportSecretsClient] to be used with the [assert.AssertDeviceClientStream] +// interface, which is essential for the [assert.Ceremony] in executing the device authentication process. It handles the extraction and insertion +// of device assertion messages from and into the [accessgraphsecretsv1pb.ReportSecretsRequest] and [accessgraphsecretsv1pb.ReportSecretsResponse] messages. +type reportToAssertStreamAdapter struct { + stream accessgraphsecretsv1pb.SecretsScannerService_ReportSecretsClient +} + +func (s reportToAssertStreamAdapter) Send(request *devicepb.AssertDeviceRequest) error { + return trace.Wrap( + s.stream.Send( + &accessgraphsecretsv1pb.ReportSecretsRequest{ + Payload: &accessgraphsecretsv1pb.ReportSecretsRequest_DeviceAssertion{ + DeviceAssertion: request, + }, + }, + ), + ) +} + +func (s reportToAssertStreamAdapter) Recv() (*devicepb.AssertDeviceResponse, error) { + in, err := s.stream.Recv() + if err != nil { + return nil, trace.Wrap(err) + } + + if in.GetDeviceAssertion() == nil { + return nil, trace.BadParameter("unsupported response type: expected DeviceAssertion, got %T", in.Payload) + } + + return in.GetDeviceAssertion(), nil +} diff --git a/lib/secretsscanner/reporter/report_test.go b/lib/secretsscanner/reporter/report_test.go new file mode 100644 index 0000000000000..76c2d661cd116 --- /dev/null +++ b/lib/secretsscanner/reporter/report_test.go @@ -0,0 +1,157 @@ +/* + * Teleport + * Copyright (C) 2024 Gravitational, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package reporter_test + +import ( + "context" + "errors" + "log/slog" + "sort" + "strconv" + "testing" + + "github.com/google/go-cmp/cmp" + "github.com/google/uuid" + "github.com/stretchr/testify/require" + "google.golang.org/protobuf/testing/protocmp" + + "github.com/gravitational/teleport/api/defaults" + accessgraphsecretsv1pb "github.com/gravitational/teleport/api/gen/proto/go/teleport/accessgraph/v1" + devicepb "github.com/gravitational/teleport/api/gen/proto/go/teleport/devicetrust/v1" + "github.com/gravitational/teleport/api/types/accessgraph" + dtassert "github.com/gravitational/teleport/lib/devicetrust/assert" + dtauthn "github.com/gravitational/teleport/lib/devicetrust/authn" + dttestenv "github.com/gravitational/teleport/lib/devicetrust/testenv" + secretsscannerclient "github.com/gravitational/teleport/lib/secretsscanner/client" + "github.com/gravitational/teleport/lib/secretsscanner/reporter" +) + +func TestReporter(t *testing.T) { + // disable TLS routing check for tests + t.Setenv(defaults.TLSRoutingConnUpgradeEnvVar, "false") + deviceID := uuid.NewString() + device, err := dttestenv.NewFakeMacOSDevice() + require.NoError(t, err) + + tests := []struct { + name string + preReconcileError error + assertErr require.ErrorAssertionFunc + report []*accessgraphsecretsv1pb.PrivateKey + want []*accessgraphsecretsv1pb.PrivateKey + }{ + { + name: "success", + report: newPrivateKeys(t, deviceID), + want: newPrivateKeys(t, deviceID), + assertErr: require.NoError, + }, + { + name: "pre-reconcile error", + preReconcileError: errors.New("pre-reconcile error"), + report: newPrivateKeys(t, deviceID), + assertErr: func(t require.TestingT, err error, _ ...any) { + require.ErrorContains(t, err, "pre-reconcile error") + }, + }, + } + + for _, tt := range tests { + tt := tt + t.Run(tt.name, func(t *testing.T) { + t.Parallel() + e := setup( + t, + withDevice(deviceID, device), + withPreReconcileError(tt.preReconcileError), + ) + + ctx := context.Background() + + client, err := secretsscannerclient.NewSecretsScannerServiceClient(ctx, + secretsscannerclient.ClientConfig{ + ProxyServer: e.secretsScannerAddr, + Insecure: true, + }, + ) + require.NoError(t, err) + + r, err := reporter.New( + reporter.Config{ + Log: slog.Default(), + Client: client, + BatchSize: 1, /* batch size for tests */ + AssertCeremonyBuilder: func() (*dtassert.Ceremony, error) { + return dtassert.NewCeremony( + dtassert.WithNewAuthnCeremonyFunc( + func() *dtauthn.Ceremony { + return &dtauthn.Ceremony{ + GetDeviceCredential: func() (*devicepb.DeviceCredential, error) { + return device.GetDeviceCredential(), nil + }, + CollectDeviceData: device.CollectDeviceData, + SignChallenge: device.SignChallenge, + SolveTPMAuthnDeviceChallenge: device.SolveTPMAuthnDeviceChallenge, + GetDeviceOSType: device.GetDeviceOSType, + } + }, + ), + ) + }, + }, + ) + require.NoError(t, err) + + err = r.ReportPrivateKeys(ctx, tt.report) + tt.assertErr(t, err) + + got := e.service.privateKeysReported + sortPrivateKeys(got) + sortPrivateKeys(tt.want) + + diff := cmp.Diff(tt.want, got, protocmp.Transform()) + require.Empty(t, diff, "ReportPrivateKeys keys mismatch (-got +want)") + + }) + } +} + +func sortPrivateKeys(keys []*accessgraphsecretsv1pb.PrivateKey) { + sort.Slice(keys, func(i, j int) bool { + return keys[i].Metadata.Name < keys[j].Metadata.Name + }) +} + +func newPrivateKeys(t *testing.T, deviceID string) []*accessgraphsecretsv1pb.PrivateKey { + t.Helper() + var pks []*accessgraphsecretsv1pb.PrivateKey + for i := 0; i < 10; i++ { + pk, err := accessgraph.NewPrivateKey( + &accessgraphsecretsv1pb.PrivateKeySpec{ + PublicKeyFingerprint: "key" + strconv.Itoa(i), + DeviceId: deviceID, + PublicKeyMode: accessgraphsecretsv1pb.PublicKeyMode_PUBLIC_KEY_MODE_DERIVED, + }, + ) + require.NoError(t, err) + pks = append(pks, pk) + } + + return pks +} diff --git a/lib/secretsscanner/scaner/scan.go b/lib/secretsscanner/scaner/scan.go new file mode 100644 index 0000000000000..664b6fcef8e67 --- /dev/null +++ b/lib/secretsscanner/scaner/scan.go @@ -0,0 +1,298 @@ +/* + * Teleport + * Copyright (C) 2024 Gravitational, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package scanner + +import ( + "bytes" + "context" + "crypto/sha256" + "encoding/hex" + "errors" + "io" + "io/fs" + "log/slog" + "os" + "path/filepath" + + "github.com/gravitational/trace" + "golang.org/x/crypto/ssh" + + accessgraphsecretsv1pb "github.com/gravitational/teleport/api/gen/proto/go/teleport/accessgraph/v1" + "github.com/gravitational/teleport/api/types/accessgraph" +) + +// Config specifies parameters for the scanner. +type Config struct { + // Dirs is a list of directories to scan. + Dirs []string + // SkipPaths is a list of paths to skip. + // It supports glob patterns (e.g. "/etc/*/"). + // Please refer to the [filepath.Match] documentation for more information. + SkipPaths []string + // Log is the logger. + Log *slog.Logger +} + +// New creates a new scanner. +func New(cfg Config) (*Scanner, error) { + if len(cfg.Dirs) == 0 { + return nil, trace.BadParameter("missing dirs") + } + if cfg.Log == nil { + cfg.Log = slog.Default() + } + + // expand the glob patterns in the skipPaths list. + // we expand the glob patterns here to avoid expanding them for each file during the scan. + // only the directories matched by the glob patterns will be skipped. + skippedPaths, err := expandSkipPaths(cfg.SkipPaths) + if err != nil { + return nil, trace.Wrap(err) + } + + return &Scanner{ + dirs: cfg.Dirs, + log: cfg.Log, + skippedPaths: skippedPaths, + }, nil +} + +// Scanner is a scanner that scans directories for secrets. +type Scanner struct { + dirs []string + log *slog.Logger + skippedPaths map[string]struct{} +} + +// ScanPrivateKeys scans directories for SSH private keys. +func (s *Scanner) ScanPrivateKeys(ctx context.Context, deviceID string) []SSHPrivateKey { + // privateKeys is a map of private keys found during the scan. + // The key is the path to the private key file and the value is the private key representation. + privateKeysMap := make(map[string]*accessgraphsecretsv1pb.PrivateKey) + for _, dir := range s.dirs { + s.findPrivateKeys(ctx, dir, deviceID, privateKeysMap) + } + + keys := make([]SSHPrivateKey, 0, len(privateKeysMap)) + for path, key := range privateKeysMap { + keys = append(keys, SSHPrivateKey{ + Path: path, + Key: key, + }) + } + return keys +} + +// SSHPrivateKey represents an SSH private key found during the scan. +type SSHPrivateKey struct { + // Path is the absolute path to the private key file. + Path string + // Key is the private key representation. + Key *accessgraphsecretsv1pb.PrivateKey +} + +// findPrivateKeys walks through all files in a directory and its subdirectories +// and checks if they are SSH private keys. +func (s *Scanner) findPrivateKeys(ctx context.Context, root, deviceID string, privateKeysMap map[string]*accessgraphsecretsv1pb.PrivateKey) { + logger := s.log.With("root", root) + + err := filepath.WalkDir(root, func(path string, info fs.DirEntry, err error) error { + if err != nil { + logger.DebugContext(ctx, "error walking directory", "path", path, "error", err) + return fs.SkipDir + } + if info.IsDir() { + if _, ok := s.skippedPaths[path]; ok { + logger.DebugContext(ctx, "skipping directory", "path", path) + return fs.SkipDir + } + return nil + } + + if _, ok := s.skippedPaths[path]; ok { + logger.DebugContext(ctx, "skipping file", "path", path) + return nil + } + + switch fileData, isKey, err := s.readFileIfSSHPrivateKey(ctx, path); { + case err != nil: + logger.DebugContext(ctx, "error reading file", "path", path, "error", err) + case isKey: + key, err := extractSSHKey(ctx, path, deviceID, fileData) + if err != nil { + logger.DebugContext(ctx, "error extracting private key", "path", path, "error", err) + } else { + privateKeysMap[path] = key + } + } + return nil + }) + + if err != nil { + logger.WarnContext(ctx, "error walking directory", "root", root, "error", err) + } +} + +var ( + supportedPrivateKeyHeaders = [][]byte{ + []byte("RSA PRIVATE KEY"), + []byte("PRIVATE KEY"), + []byte("EC PRIVATE KEY"), + []byte("DSA PRIVATE KEY"), + []byte("OPENSSH PRIVATE KEY"), + } +) + +// readFileIfSSHPrivateKey checks if a file is an OpenSSH private key +func (s *Scanner) readFileIfSSHPrivateKey(ctx context.Context, filePath string) ([]byte, bool, error) { + file, err := os.Open(filePath) + if err != nil { + return nil, false, err + } + defer func() { + if err = file.Close(); err != nil { + s.log.DebugContext(ctx, "failed to close file", "path", filePath, "error", err) + } + }() + + // read the first bytes of the file to check if it's an OpenSSH private key. + // 40 bytes is the maximum length of the header of an OpenSSH private key. + var buf [40]byte + n, err := file.Read(buf[:]) + if errors.Is(err, io.EOF) || n < len(buf) { + return nil, false, nil + } else if err != nil { + return nil, false, trace.Wrap(err, "failed to read file") + } + + isPrivateKey := false + for _, header := range supportedPrivateKeyHeaders { + if bytes.Contains(buf[:], header) { + isPrivateKey = true + break + } + } + if !isPrivateKey { + return nil, false, nil + } + + // read the entire file + data, err := io.ReadAll(file) + if err != nil { + return nil, false, trace.Wrap(err, "failed to read file") + } + return append(buf[:], data...), true, nil +} + +func extractSSHKey(ctx context.Context, path, deviceID string, fileData []byte) (*accessgraphsecretsv1pb.PrivateKey, error) { + logger := slog.Default().With("private_key_file", path, "device_id", deviceID) + + var publicKey ssh.PublicKey + var mode accessgraphsecretsv1pb.PublicKeyMode + var pme *ssh.PassphraseMissingError + switch pk, err := ssh.ParsePrivateKey(fileData); { + case errors.As(err, &pme): + if pme.PublicKey != nil { + // If the key is a OpenSSH private key whose public key is embedded in the header, it will return the public key. This is + // a special case for OpenSSH private keys that have the public key embedded in the header, for more information see + // OpenSSH's ssh key format: https://github.com/openssh/openssh-portable/blob/master/PROTOCOL.key + publicKey = pme.PublicKey + mode = accessgraphsecretsv1pb.PublicKeyMode_PUBLIC_KEY_MODE_DERIVED + break + } + const pubKeyFileSuffix = ".pub" + publicKey, mode = tryParsingPublicKeyFromPublicFilePath(ctx, logger, path+pubKeyFileSuffix) + case err != nil: + return nil, trace.Wrap(err) + default: + publicKey = pk.PublicKey() + mode = accessgraphsecretsv1pb.PublicKeyMode_PUBLIC_KEY_MODE_DERIVED + } + var fingerprint string + if publicKey != nil { + fingerprint = ssh.FingerprintSHA256(publicKey) + } + + key, err := accessgraph.NewPrivateKeyWithName( + privateKeyNameGen(path, deviceID, fingerprint), + &accessgraphsecretsv1pb.PrivateKeySpec{ + PublicKeyFingerprint: fingerprint, + DeviceId: deviceID, + PublicKeyMode: mode, + }, + ) + return key, trace.Wrap(err) +} + +// tryParsingPublicKeyFromPublicFilePath tries to read the public key from the public key file if the private key is password protected. +// If the public key file doesn't exist, it will return mode accessgraphsecretsv1pb.PublicKeyMode_PUBLIC_KEY_MODE_PROTECTED +// identifying that the private key is password protected and the public key could not be extracted. +func tryParsingPublicKeyFromPublicFilePath(ctx context.Context, logger *slog.Logger, pubPath string) (ssh.PublicKey, accessgraphsecretsv1pb.PublicKeyMode) { + logger = logger.With("public_key_file", pubPath) + logger.DebugContext(ctx, "PrivateKey is password protected. Fallback to public key file.") + + pubData, err := os.ReadFile(pubPath) + if err != nil { + logger.DebugContext(ctx, "Unable to read public key file.", "err", err) + return nil, accessgraphsecretsv1pb.PublicKeyMode_PUBLIC_KEY_MODE_PROTECTED + } + + logger.DebugContext(ctx, "Trying to parse public key as authorized key data.") + pub, _, _, _, err := ssh.ParseAuthorizedKey(pubData) + if err == nil { + return pub, accessgraphsecretsv1pb.PublicKeyMode_PUBLIC_KEY_MODE_PUB_FILE + } + logger.DebugContext(ctx, "Unable to parse ssh public key file.", "err", err) + + logger.DebugContext(ctx, "Trying to parse public key directly.") + + pub, err = ssh.ParsePublicKey(pubData) + if err == nil { + return pub, accessgraphsecretsv1pb.PublicKeyMode_PUBLIC_KEY_MODE_PUB_FILE + } + + logger.DebugContext(ctx, "Unable to parse ssh public key file.", "err", err) + + return nil, accessgraphsecretsv1pb.PublicKeyMode_PUBLIC_KEY_MODE_PROTECTED + +} + +func privateKeyNameGen(path, deviceID, fingerprint string) string { + sha := sha256.New() + sha.Write([]byte(path)) + sha.Write([]byte(deviceID)) + sha.Write([]byte(fingerprint)) + return hex.EncodeToString(sha.Sum(nil)) +} + +// expandSkipPaths expands the glob patterns in the skipPaths list and returns a set of the +// paths matched by the glob patterns to be skipped. +func expandSkipPaths(skipPaths []string) (map[string]struct{}, error) { + set := make(map[string]struct{}) + for _, glob := range skipPaths { + matches, err := filepath.Glob(glob) + if err != nil { + return nil, trace.Wrap(err, "glob pattern %q is invalid", glob) + } + for _, match := range matches { + set[match] = struct{}{} + } + } + return set, nil +} diff --git a/lib/secretsscanner/scaner/scan_test.go b/lib/secretsscanner/scaner/scan_test.go new file mode 100644 index 0000000000000..df82e08eb0ea7 --- /dev/null +++ b/lib/secretsscanner/scaner/scan_test.go @@ -0,0 +1,237 @@ +/* + * Teleport + * Copyright (C) 2024 Gravitational, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package scanner + +import ( + "context" + "os" + "path/filepath" + "sort" + "testing" + + "github.com/google/go-cmp/cmp" + "github.com/google/uuid" + "github.com/stretchr/testify/require" + "golang.org/x/crypto/ssh" + "google.golang.org/protobuf/testing/protocmp" + + accessgraphsecretsv1pb "github.com/gravitational/teleport/api/gen/proto/go/teleport/accessgraph/v1" + "github.com/gravitational/teleport/api/types/accessgraph" + scantestdata "github.com/gravitational/teleport/lib/secretsscanner/scaner/testdata" +) + +var ( + deviceID = uuid.NewString() +) + +func TestNewScanner(t *testing.T) { + tests := []struct { + name string + keysGen func(t *testing.T, path string) []*accessgraphsecretsv1pb.PrivateKey + skipTestDir bool + assertResult func(t *testing.T, got []*accessgraphsecretsv1pb.PrivateKey) + }{ + { + name: "encrypted keys", + keysGen: writeEncryptedKeys, + }, + { + name: "unencrypted keys", + keysGen: writeUnEncryptedKeys, + }, + { + name: "encryptedKey without public key file", + keysGen: writeEncryptedKeyWithoutPubFile, + }, + { + name: "invalid keys", + keysGen: writeInvalidKeys, + }, + { + name: "skip test dir keys", + keysGen: writeUnEncryptedKeys, + skipTestDir: true, + assertResult: func(t *testing.T, got []*accessgraphsecretsv1pb.PrivateKey) { + require.Empty(t, got, "ScanPrivateKeys with skip test dir should return empty keys") + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + dir := t.TempDir() + + expect := tt.keysGen(t, dir) + + var skipPaths []string + if tt.skipTestDir { + // skip the test directory. + skipPaths = []string{filepath.Join(dir, "*")} + // the expected keys should be nil since the test directory is skipped. + expect = nil + } + + s, err := New(Config{ + Dirs: []string{dir}, + SkipPaths: skipPaths, + }) + require.NoError(t, err) + + keys := s.ScanPrivateKeys(context.Background(), deviceID) + var got []*accessgraphsecretsv1pb.PrivateKey + for _, key := range keys { + got = append(got, key.Key) + } + + // Sort the keys by name for comparison. + sortPrivateKeys(expect) + sortPrivateKeys(got) + + if tt.assertResult != nil { + tt.assertResult(t, got) + } + + diff := cmp.Diff(expect, got, protocmp.Transform()) + require.Empty(t, diff, "ScanPrivateKeys keys mismatch (-got +want)") + }) + } +} + +func sortPrivateKeys(keys []*accessgraphsecretsv1pb.PrivateKey) { + sort.Slice(keys, func(i, j int) bool { + return keys[i].Metadata.Name < keys[j].Metadata.Name + }) +} + +func writeEncryptedKeys(t *testing.T, dir string) []*accessgraphsecretsv1pb.PrivateKey { + t.Helper() + var expectedKeys []*accessgraphsecretsv1pb.PrivateKey + // Write encrypted keys to the directory. + for _, key := range scantestdata.PEMEncryptedKeys { + err := os.Mkdir(filepath.Join(dir, key.Name), 0o777) + require.NoError(t, err) + + filePath := filepath.Join(dir, key.Name, key.Name) + err = os.WriteFile(filePath, key.PEMBytes, 0o666) + require.NoError(t, err) + + s, err := ssh.ParsePrivateKeyWithPassphrase(key.PEMBytes, []byte(key.EncryptionKey)) + require.NoError(t, err) + + if !key.IncludesPublicKey { + pubFilePath := filePath + ".pub" + authorizedKeyBytes := ssh.MarshalAuthorizedKey(s.PublicKey()) + require.NoError(t, os.WriteFile(pubFilePath, authorizedKeyBytes, 0o666)) + } + + fingerprint := ssh.FingerprintSHA256(s.PublicKey()) + + mode := accessgraphsecretsv1pb.PublicKeyMode_PUBLIC_KEY_MODE_DERIVED + if !key.IncludesPublicKey { + mode = accessgraphsecretsv1pb.PublicKeyMode_PUBLIC_KEY_MODE_PUB_FILE + } + + key, err := accessgraph.NewPrivateKeyWithName( + privateKeyNameGen(filePath, deviceID, fingerprint), + &accessgraphsecretsv1pb.PrivateKeySpec{ + PublicKeyFingerprint: fingerprint, + DeviceId: deviceID, + PublicKeyMode: mode, + }, + ) + require.NoError(t, err) + + expectedKeys = append(expectedKeys, key) + } + + return expectedKeys +} + +func writeUnEncryptedKeys(t *testing.T, dir string) []*accessgraphsecretsv1pb.PrivateKey { + t.Helper() + var expectedKeys []*accessgraphsecretsv1pb.PrivateKey + + for name, key := range scantestdata.PEMBytes { + err := os.Mkdir(filepath.Join(dir, name), 0o777) + require.NoError(t, err) + + filePath := filepath.Join(dir, name, name) + err = os.WriteFile(filePath, key, 0o666) + require.NoError(t, err) + + s, err := ssh.ParsePrivateKey(key) + require.NoError(t, err) + + fingerprint := ssh.FingerprintSHA256(s.PublicKey()) + + key, err := accessgraph.NewPrivateKeyWithName( + privateKeyNameGen(filePath, deviceID, fingerprint), + &accessgraphsecretsv1pb.PrivateKeySpec{ + PublicKeyFingerprint: fingerprint, + DeviceId: deviceID, + PublicKeyMode: accessgraphsecretsv1pb.PublicKeyMode_PUBLIC_KEY_MODE_DERIVED, + }, + ) + require.NoError(t, err) + + expectedKeys = append(expectedKeys, key) + } + + return expectedKeys +} + +func writeEncryptedKeyWithoutPubFile(t *testing.T, dir string) []*accessgraphsecretsv1pb.PrivateKey { + t.Helper() + + // Write encrypted keys to the directory. + rawKey := scantestdata.PEMEncryptedKeys[0] + err := os.Mkdir(filepath.Join(dir, rawKey.Name), 0o777) + require.NoError(t, err) + + filePath := filepath.Join(dir, rawKey.Name, rawKey.Name) + err = os.WriteFile(filePath, rawKey.PEMBytes, 0o666) + require.NoError(t, err) + + key, err := accessgraph.NewPrivateKeyWithName( + privateKeyNameGen(filePath, deviceID, ""), + &accessgraphsecretsv1pb.PrivateKeySpec{ + PublicKeyFingerprint: "", + DeviceId: deviceID, + PublicKeyMode: accessgraphsecretsv1pb.PublicKeyMode_PUBLIC_KEY_MODE_PROTECTED, + }, + ) + require.NoError(t, err) + + return []*accessgraphsecretsv1pb.PrivateKey{key} +} + +func writeInvalidKeys(t *testing.T, dir string) []*accessgraphsecretsv1pb.PrivateKey { + t.Helper() + + // Write invalid keys to the directory. + for path, keyBytes := range scantestdata.InvalidKeysBytes { + err := os.Mkdir(filepath.Join(dir, path), 0o777) + require.NoError(t, err) + + filePath := filepath.Join(dir, path, path) + err = os.WriteFile(filePath, keyBytes, 0o666) + require.NoError(t, err) + } + + return nil +} diff --git a/lib/secretsscanner/scaner/testdata/invalid_keys.go b/lib/secretsscanner/scaner/testdata/invalid_keys.go new file mode 100644 index 0000000000000..b2e1b18732770 --- /dev/null +++ b/lib/secretsscanner/scaner/testdata/invalid_keys.go @@ -0,0 +1,50 @@ +/* + * Teleport + * Copyright (C) 2024 Gravitational, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package testdata + +// InvalidKeysBytes is a map of invalid keys to their byte representation. +var InvalidKeysBytes = map[string][]byte{ + "short-file": []byte("short file"), + + "empty-file": []byte(""), + + "invalid-key": []byte(`-----BEGIN PRIVATE +KEY----- +MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDQ7z7z7z7z7z7z +-----END OPENSSH PRIVATE KEY----- +`), + + "invalid-key-valid-headers": []byte( + `-----BEGIN OPENSSH PRIVATE KEY----- +trash +-----END OPENSSH PRIVATE KEY----- +`), + + "invalid-key-invalid-header": []byte( + `abcefg-----BEGIN OPENSSH PRIVATE KEY----- +-----END OPENSSH PRIVATE KEY----- +`), + + "valid-key-not-supported-header": []byte(`-----BEGIN RANDOM PRIVATE KEY----- +MHcCAQEEINGWx0zo6fhJ/0EAfrPzVFyFC9s18lBt3cRoEDhS3ARooAoGCCqGSM49 +AwEHoUQDQgAEi9Hdw6KvZcWxfg2IDhA7UkpDtzzt6ZqJXSsFdLd+Kx4S3Sx4cVO+ +6/ZOXRnPmNAlLUqjShUsUBBngG0u2fqEqA== +-----END EC PRIVATE KEY----- +`), +} diff --git a/lib/secretsscanner/scaner/testdata/ssh_keys.go b/lib/secretsscanner/scaner/testdata/ssh_keys.go new file mode 100644 index 0000000000000..ff35441f77581 --- /dev/null +++ b/lib/secretsscanner/scaner/testdata/ssh_keys.go @@ -0,0 +1,290 @@ +// Copyright 2014 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// forked from golang.org/x/crypto@v0.24.0/ssh/testdata/keys.go + +package testdata + +var PEMBytes = map[string][]byte{ + "dsa": []byte(`-----BEGIN DSA PRIVATE KEY----- +MIIBuwIBAAKBgQD6PDSEyXiI9jfNs97WuM46MSDCYlOqWw80ajN16AohtBncs1YB +lHk//dQOvCYOsYaE+gNix2jtoRjwXhDsc25/IqQbU1ahb7mB8/rsaILRGIbA5WH3 +EgFtJmXFovDz3if6F6TzvhFpHgJRmLYVR8cqsezL3hEZOvvs2iH7MorkxwIVAJHD +nD82+lxh2fb4PMsIiaXudAsBAoGAQRf7Q/iaPRn43ZquUhd6WwvirqUj+tkIu6eV +2nZWYmXLlqFQKEy4Tejl7Wkyzr2OSYvbXLzo7TNxLKoWor6ips0phYPPMyXld14r +juhT24CrhOzuLMhDduMDi032wDIZG4Y+K7ElU8Oufn8Sj5Wge8r6ANmmVgmFfynr +FhdYCngCgYEA3ucGJ93/Mx4q4eKRDxcWD3QzWyqpbRVRRV1Vmih9Ha/qC994nJFz +DQIdjxDIT2Rk2AGzMqFEB68Zc3O+Wcsmz5eWWzEwFxaTwOGWTyDqsDRLm3fD+QYj +nOwuxb0Kce+gWI8voWcqC9cyRm09jGzu2Ab3Bhtpg8JJ8L7gS3MRZK4CFEx4UAfY +Fmsr0W6fHB9nhS4/UXM8 +-----END DSA PRIVATE KEY----- +`), + "ecdsa": []byte(`-----BEGIN EC PRIVATE KEY----- +MHcCAQEEINGWx0zo6fhJ/0EAfrPzVFyFC9s18lBt3cRoEDhS3ARooAoGCCqGSM49 +AwEHoUQDQgAEi9Hdw6KvZcWxfg2IDhA7UkpDtzzt6ZqJXSsFdLd+Kx4S3Sx4cVO+ +6/ZOXRnPmNAlLUqjShUsUBBngG0u2fqEqA== +-----END EC PRIVATE KEY----- +`), + "ecdsap256": []byte(`-----BEGIN EC PRIVATE KEY----- +MHcCAQEEIAPCE25zK0PQSnsgVcEbM1mbKTASH4pqb5QJajplDwDZoAoGCCqGSM49 +AwEHoUQDQgAEWy8TxGcIHRh5XGpO4dFVfDjeNY+VkgubQrf/eyFJZHxAn1SKraXU +qJUjTKj1z622OxYtJ5P7s9CfAEVsTzLCzg== +-----END EC PRIVATE KEY----- +`), + "ecdsap384": []byte(`-----BEGIN EC PRIVATE KEY----- +MIGkAgEBBDBWfSnMuNKq8J9rQLzzEkx3KAoEohSXqhE/4CdjEYtoU2i22HW80DDS +qQhYNHRAduygBwYFK4EEACKhZANiAAQWaDMAd0HUd8ZiXCX7mYDDnC54gwH/nG43 +VhCUEYmF7HMZm/B9Yn3GjFk3qYEDEvuF/52+NvUKBKKaLbh32AWxMv0ibcoba4cz +hL9+hWYhUD9XIUlzMWiZ2y6eBE9PdRI= +-----END EC PRIVATE KEY----- +`), + "ecdsap521": []byte(`-----BEGIN EC PRIVATE KEY----- +MIHcAgEBBEIBrkYpQcy8KTVHNiAkjlFZwee90224Bu6wz94R4OBo+Ts0eoAQG7SF +iaygEDMUbx6kTgXTBcKZ0jrWPKakayNZ/kigBwYFK4EEACOhgYkDgYYABADFuvLV +UoaCDGHcw5uNfdRIsvaLKuWSpLsl48eWGZAwdNG432GDVKduO+pceuE+8XzcyJb+ +uMv+D2b11Q/LQUcHJwE6fqbm8m3EtDKPsoKs0u/XUJb0JsH4J8lkZzbUTjvGYamn +FFlRjzoB3Oxu8UQgb+MWPedtH9XYBbg9biz4jJLkXQ== +-----END EC PRIVATE KEY----- +`), + "rsa": []byte(`-----BEGIN RSA PRIVATE KEY----- +MIIEpQIBAAKCAQEAnuozKMtcQkIImZGSe4IujS4+Lkas9jmlBivziWGU3waivkpU +vYspgJbh7vSvnHOPtKscdIJ+3UUyViDUoM73GumsmHvfeRCoA9YROZK4fQR9G0a1 +wfoRqsrJXGToCzTvr/I2KIwpUG0bRE9rUvsW+JN9xgri+cIJWtu/dGYDkILO4bkF +IxtEvHNVvhGLenyOHFhPw3hAZ7/bKq8kvKzm9D2zOllHe1wWncMkhVmEFF9Houeh +jbddmeIAAxBpRUFfzp1dD7503ADBlJdK306D4CeI4KIFiqE1VrmfcMgP8fti0S0b +4JtmvevYoPd+/wB9ItFqvhc6nyuxF0PfWH+SvwIDAQABAoIBAQCCcpNeSFjKVvRC +Q1nwIrPd1njaec+fK0CIqWl3e2++B+9trwySrvp5gOGjyp2hGsd7Mf7gsQI81oF0 +a+y+uEXlhK3WWdDey0pwI7ft/7+LeDTOQCQRQBpijaXvPzGviVu7nWLRtARx7a41 +S9A4xL5dfI0BFYyuIpaVS8+EV/1TEJIbceZ5q5RBlARA1rc+nBvjygNzYdRq9Rao +yyehvnXZ7pQrATnwofPolbZNseW2Q9sRMmtm1E60XJJ433P7nFbxXtsMAYgxWSQc +V/92iRPYeD7sN/b7qulLEgC6e8el2gLGIB9aQyG7B6KFqloqvx/ymYs07+bWIQCU +6i9y7LABAoGBANKB2Rs0lF5c+gpEE3w0AWoxGyL04TZECtl2hQ/b2jc2n8hLqLhv +zNIKN+xzEP6j0ijXajjEMLiQH10qQ6+Plv8C7o8GJC1V/Oj4u4kbPqfVV1kSxuWm +FBjz6+c8VPbEBgXq5lCMEgC2Ii8XVRoyd3iSSOh+LIMBu/Br3JEsjJq/AoGBAMFC +CvODTiThrZo8v765dRSHrLOvB4jZOPrEKLWECLaQDQpuhgzZhyWm9zFfxGB+LWE9 +R9pU6ZCFPtPfd4cRZ9cezrp+lgdrqjcUX/2ZLLMk21WXFuRaw/4KTlKNsMY6lbAK +qVkUFWIZWaCQ8bdVCP48polipRNmN9mAHsIhIwgBAoGBAM6yn1qeS11I0GAKLlPT +wNvjsfCmIQmm0DxtqwRCbUevxD7pQ5cueCB51iW/ap2OgEqIEo4A3pIrOhDB8kpN +pQdrepFHh3hYqYicy5A6B1DHJAibbl+Krss9n5KjZA4VtpBS8al/kCHQtUomD/M0 +QKlMgnh/g/dzWXYegyqtYraDAoGAGbeBH5B8iJnjcR/eYDHrq5S2XZ7QANzvISeT +RzxPsIOQyK+WdQVJX7BNOqvExRZlUYhHFH2yKwIgLy+Qh0/Aora9ycFok4o3N2cl +suh8M0aXTVdyu2Z8qESU0ZV7TZWkL63rhSgQBGLdM2m2ULAnJzXI74VJ9D/o9K+A +6FJiiAECgYEAujJ/hKxVKEUvxwloGSDhKCUH86+7UOkb/EM2zZFrlPYAz1VcCwr3 +K14r8BtmLFXuLXOlACpoH0Wf4uia+t6n8m9JK3mvpJ7fempAsptP3AdZMQFe7xUm +SXEGQBYxcyS5Q+ncwWZuPgby5wJ9D4Fd6TQH+wwG52sFugt/fGxbPug= +-----END RSA PRIVATE KEY----- +`), + "pkcs8": []byte(`-----BEGIN PRIVATE KEY----- +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCitzS2KiRQTccf +VApb0mbPpo1lt29JjeLBYAehXHWfQ+w8sXpd8e04n/020spx1R94yg+v0NjXyh2R +NFXNBYdhNei33VJxUeKNlExaecvW2yxfuZqka+ZxT1aI8zrAsjh3Rwc6wayAJS4R +wZuzlDv4jZitWqwD+mb/22Zwq/WSs4YX5dUHDklfdWSVnoBfue8K/00n8f5yMTdJ +vFF0qAJwf9spPEHla0lYcozJk64CO5lRkqfLor4UnsXXOiA7aRIoaUSKa+rlhiqt +1EMGYiBjblPt4SwMelGGU2UfywPb4d85gpQ/s8SBARbpPxNVs2IbHDMwj70P3uZc +74M3c4VJAgMBAAECggEAFIzY3mziGzZHgMBncoNXMsCRORh6uKpvygZr0EhSHqRA +cMXlc3n7gNxL6aGjqc7F48Z5RrY0vMQtCcq3T2Z0W6WoV5hfMiqqV0E0h3S8ds1F +hG13h26NMyBXCILXl8Cqev4Afr45IBISCHIQTRTaoiCX+MTr1rDIU2YNQQumvzkz +fMw2XiFTFTgxAtJUAgKoTqLtm7/T+az7TKw+Hesgbx7yaJoMh9DWGBh4Y61DnIDA +fcxJboAfxxnFiXvdBVmzo72pCsRXrWOsjW6WxQmCKuXHvyB1FZTmMaEFNCGSJDa6 +U+OCzA3m65loAZAE7ffFHhYgssz/h9TBaOjKO0BX1QKBgQDZiCBvu+bFh9pEodcS +VxaI+ATlsYcmGdLtnZw5pxuEdr60iNWhpEcV6lGkbdiv5aL43QaGFDLagqeHI77b ++ITFbPPdCiYNaqlk6wyiXv4pdN7V683EDmGWSQlPeC9IhUilt2c+fChK2EB/XlkO +q8c3Vk1MsC6JOxDXNgJxylNpswKBgQC/fYBTb9iD+uM2n3SzJlct/ZlPaONKnNDR +pbTOdxBFHsu2VkfY858tfnEPkmSRX0yKmjHni6e8/qIzfzLwWBY4NmxhNZE5v+qJ +qZF26ULFdrZB4oWXAOliy/1S473OpQnp2MZp2asd0LPcg/BNaMuQrz44hxHb76R7 +qWD0ebIfEwKBgQCRCIiP1pjbVGN7ZOgPS080DSC+wClahtcyI+ZYLglTvRQTLDQ7 +LFtUykCav748MIADKuJBnM/3DiuCF5wV71EejDDfS/fo9BdyuKBY1brhixFTUX+E +Ww5Hc/SoLnpgALVZ/7jvWTpIBHykLxRziqYtR/YLzl+IkX/97P2ePoZ0rwKBgHNC +/7M5Z4JJyepfIMeVFHTCaT27TNTkf20x6Rs937U7TDN8y9JzEiU4LqXI4HAAhPoI +xnExRs4kF04YCnlRDE7Zs3Lv43J3ap1iTATfcymYwyv1RaQXEGQ/lUQHgYCZJtZz +fTrJoo5XyWu6nzJ5Gc8FLNaptr5ECSXGVm3Rsr2xAoGBAJWqEEQS/ejhO05QcPqh +y4cUdLr0269ILVsvic4Ot6zgfPIntXAK6IsHGKcg57kYm6W9k1CmmlA4ENGryJnR +vxyyqA9eyTFc1CQNuc2frKFA9It49JzjXahKc0aDHEHmTR787Tmk1LbuT0/gm9kA +L4INU6g+WqF0fatJxd+IJPrp +-----END PRIVATE KEY----- +`), + "ed25519": []byte(`-----BEGIN OPENSSH PRIVATE KEY----- +b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW +QyNTUxOQAAACA+3f7hS7g5UWwXOGVTrMfhmxyrjqz7Sxxbx7I1j8DvvwAAAJhAFfkOQBX5 +DgAAAAtzc2gtZWQyNTUxOQAAACA+3f7hS7g5UWwXOGVTrMfhmxyrjqz7Sxxbx7I1j8Dvvw +AAAEAaYmXltfW6nhRo3iWGglRB48lYq0z0Q3I3KyrdutEr6j7d/uFLuDlRbBc4ZVOsx+Gb +HKuOrPtLHFvHsjWPwO+/AAAAE2dhcnRvbm1AZ2FydG9ubS14cHMBAg== +-----END OPENSSH PRIVATE KEY----- +`), + "rsa-openssh-format": []byte(`-----BEGIN OPENSSH PRIVATE KEY----- +b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAlwAAAAdzc2gtcn +NhAAAAAwEAAQAAAIEAwa48yfWFi3uIdqzuf9X7C2Zxfea/Iaaw0zIwHudpF8U92WVIiC5l +oEuW1+OaVi3UWfIEjWMV1tHGysrHOwtwc34BPCJqJknUQO/KtDTBTJ4Pryhw1bWPC999Lz +a+yrCTdNQYBzoROXKExZgPFh9pTMi5wqpHDuOQ2qZFIEI3lT0AAAIQWL0H31i9B98AAAAH +c3NoLXJzYQAAAIEAwa48yfWFi3uIdqzuf9X7C2Zxfea/Iaaw0zIwHudpF8U92WVIiC5loE +uW1+OaVi3UWfIEjWMV1tHGysrHOwtwc34BPCJqJknUQO/KtDTBTJ4Pryhw1bWPC999Lza+ +yrCTdNQYBzoROXKExZgPFh9pTMi5wqpHDuOQ2qZFIEI3lT0AAAADAQABAAAAgCThyTGsT4 +IARDxVMhWl6eiB2ZrgFgWSeJm/NOqtppWgOebsIqPMMg4UVuVFsl422/lE3RkPhVkjGXgE +pWvZAdCnmLmApK8wK12vF334lZhZT7t3Z9EzJps88PWEHo7kguf285HcnUM7FlFeissJdk +kXly34y7/3X/a6Tclm+iABAAAAQE0xR/KxZ39slwfMv64Rz7WKk1PPskaryI29aHE3mKHk +pY2QA+P3QlrKxT/VWUMjHUbNNdYfJm48xu0SGNMRdKMAAABBAORh2NP/06JUV3J9W/2Hju +X1ViJuqqcQnJPVzpgSL826EC2xwOECTqoY8uvFpUdD7CtpksIxNVqRIhuNOlz0lqEAAABB +ANkaHTTaPojClO0dKJ/Zjs7pWOCGliebBYprQ/Y4r9QLBkC/XaWMS26gFIrjgC7D2Rv+rZ +wSD0v0RcmkITP1ZR0AAAAYcHF1ZXJuYUBMdWNreUh5ZHJvLmxvY2FsAQID +-----END OPENSSH PRIVATE KEY-----`), + "p256-openssh-format": []byte(`-----BEGIN OPENSSH PRIVATE KEY----- +b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAaAAAABNlY2RzYS +1zaGEyLW5pc3RwMjU2AAAACG5pc3RwMjU2AAAAQQSN5Ld/DFy8LJK0yrWg+Ryhq4/ifHry +QyCQeT4UXSB+UGdRct7kWA0hARbTaSCh+8U/Gs5O+IkDNoTKVsgxKUMQAAAAsO3C7nPtwu +5zAAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBI3kt38MXLwskrTK +taD5HKGrj+J8evJDIJB5PhRdIH5QZ1Fy3uRYDSEBFtNpIKH7xT8azk74iQM2hMpWyDEpQx +AAAAAhAIHB48R+goZaiXndfYTrwk4BT1+MeLPC2/dwe0J5d1QDAAAAE21hcmlhbm9AZW5k +b3IubG9jYWwBAgME +-----END OPENSSH PRIVATE KEY-----`), + "p384-openssh-format": []byte(`-----BEGIN OPENSSH PRIVATE KEY----- +b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAiAAAABNlY2RzYS +1zaGEyLW5pc3RwMzg0AAAACG5pc3RwMzg0AAAAYQTZb2VzEPs2NN/i1qHddKTVfwoIq3Tf +PeQ/kcWBvuCVJfIygvpm9MeusawEPuLSEXwiNDew+YHZ9xHIvFjCmZsLuEOzuh9t9KotwM +57H+7N+RDFzhM2j8hAaOuT5XDLKfUAAADgn/Sny5/0p8sAAAATZWNkc2Etc2hhMi1uaXN0 +cDM4NAAAAAhuaXN0cDM4NAAAAGEE2W9lcxD7NjTf4tah3XSk1X8KCKt03z3kP5HFgb7glS +XyMoL6ZvTHrrGsBD7i0hF8IjQ3sPmB2fcRyLxYwpmbC7hDs7ofbfSqLcDOex/uzfkQxc4T +No/IQGjrk+Vwyyn1AAAAMQDg0hwGKB/9Eq+e2FeTspi8QHW5xTD6prqsHDFx4cKk0ccgFV +61dhFhD/8SEbYlHzEAAAATbWFyaWFub0BlbmRvci5sb2NhbAECAwQ= +-----END OPENSSH PRIVATE KEY-----`), + "p521-openssh-format": []byte(`-----BEGIN OPENSSH PRIVATE KEY----- +b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAArAAAABNlY2RzYS +1zaGEyLW5pc3RwNTIxAAAACG5pc3RwNTIxAAAAhQQBKzI3QSp1a2e1zMulZl1uFF1Y2Dnv +LSIwEu837hOV1epYEgNveAhGNm57TuBqYtnZeVfd2pzaz7CKX6N4B33N1XABQ5Ngji7lF2 +dUbmhNqJoMh43ioIsQNBaBenhmRpYP6f5k8P/7JZMIsLhkJk2hykb8maSZ+B3PYwPMNBdS +vP+0sHQAAAEYIsr2CCLK9ggAAAATZWNkc2Etc2hhMi1uaXN0cDUyMQAAAAhuaXN0cDUyMQ +AAAIUEASsyN0EqdWtntczLpWZdbhRdWNg57y0iMBLvN+4TldXqWBIDb3gIRjZue07gamLZ +2XlX3dqc2s+wil+jeAd9zdVwAUOTYI4u5RdnVG5oTaiaDIeN4qCLEDQWgXp4ZkaWD+n+ZP +D/+yWTCLC4ZCZNocpG/Jmkmfgdz2MDzDQXUrz/tLB0AAAAQgEdeH+im6iRcP/juTAoeSHo +ExLtWhgL4JYqRwcOnzCKuLOPjEY/HSOuc+HRrbN9rbjsq+PcPHYe1NnkzXk0IW8hxQAAAB +NtYXJpYW5vQGVuZG9yLmxvY2FsAQIDBAUGBw== +-----END OPENSSH PRIVATE KEY-----`), + "user": []byte(`-----BEGIN EC PRIVATE KEY----- +MHcCAQEEILYCAeq8f7V4vSSypRw7pxy8yz3V5W4qg8kSC3zJhqpQoAoGCCqGSM49 +AwEHoUQDQgAEYcO2xNKiRUYOLEHM7VYAp57HNyKbOdYtHD83Z4hzNPVC4tM5mdGD +PLL8IEwvYu2wq+lpXfGQnNMbzYf9gspG0w== +-----END EC PRIVATE KEY----- +`), + "ca": []byte(`-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEAvg9dQ9IRG59lYJb+GESfKWTch4yBpr7Ydw1jkK6vvtrx9jLo +5hkA8X6+ElRPRqTAZSlN5cBm6YCAcQIOsmXDUn6Oj1lVPQAoOjTBTvsjM3NjGhvv +52kHTY0nsMsBeY9q5DTtlzmlYkVUq2a6Htgf2mNi01dIw5fJ7uTTo8EbNf7O0i3u +c9a8P19HaZl5NKiWN4EIZkfB2WdXYRJCVBsGgQj3dE/GrEmH9QINq1A+GkNvK96u +vZm8H1jjmuqzHplWa7lFeXcx8FTVTbVb/iJrZ2Lc/JvIPitKZWhqbR59yrGjpwEp +Id7bo4WhO5L3OB0fSIJYvfu+o4WYnt4f3UzecwIDAQABAoIBABRD9yHgKErVuC2Q +bA+SYZY8VvdtF/X7q4EmQFORDNRA7EPgMc03JU6awRGbQ8i4kHs46EFzPoXvWcKz +AXYsO6N0Myc900Tp22A5d9NAHATEbPC/wdje7hRq1KyZONMJY9BphFv3nZbY5apR +Dc90JBFZP5RhXjTc3n9GjvqLAKfFEKVmPRCvqxCOZunw6XR+SgIQLJo36nsIsbhW +QUXIVaCI6cXMN8bRPm8EITdBNZu06Fpu4ZHm6VaxlXN9smERCDkgBSNXNWHKxmmA +c3Glo2DByUr2/JFBOrLEe9fkYgr24KNCQkHVcSaFxEcZvTggr7StjKISVHlCNEaB +7Q+kPoECgYEA3zE9FmvFGoQCU4g4Nl3dpQHs6kaAW8vJlrmq3xsireIuaJoa2HMe +wYdIvgCnK9DIjyxd5OWnE4jXtAEYPsyGD32B5rSLQrRO96lgb3f4bESCLUb3Bsn/ +sdgeE3p1xZMA0B59htqCrvVgN9k8WxyevBxYl3/gSBm/p8OVH1RTW/ECgYEA2f9Z +95OLj0KQHQtxQXf+I3VjhCw3LkLW39QZOXVI0QrCJfqqP7uxsJXH9NYX0l0GFTcR +kRrlyoaSU1EGQosZh+n1MvplGBTkTSV47/bPsTzFpgK2NfEZuFm9RoWgltS+nYeH +Y2k4mnAN3PhReCMwuprmJz8GRLsO3Cs2s2YylKMCgYEA2UX+uO/q7jgqZ5UJW+ue +1H5+W0aMuFA3i7JtZEnvRaUVFqFGlwXin/WJ2+WY1++k/rPrJ+Rk9IBXtBUIvEGw +FC5TIfsKQsJyyWgqx/jbbtJ2g4s8+W/1qfTAuqeRNOg5d2DnRDs90wJuS4//0JaY +9HkHyVwkQyxFxhSA/AHEMJECgYA2MvyFR1O9bIk0D3I7GsA+xKLXa77Ua53MzIjw +9i4CezBGDQpjCiFli/fI8am+jY5DnAtsDknvjoG24UAzLy5L0mk6IXMdB6SzYYut +7ak5oahqW+Y9hxIj+XvLmtGQbphtxhJtLu35x75KoBpxSh6FZpmuTEccs31AVCYn +eFM/DQKBgQDOPUwbLKqVi6ddFGgrV9MrWw+SWsDa43bPuyvYppMM3oqesvyaX1Dt +qDvN7owaNxNM4OnfKcZr91z8YPVCFo4RbBif3DXRzjNNBlxEjHBtuMOikwvsmucN +vIrbeEpjTiUMTEAr6PoTiVHjsfS8WAM6MDlF5M+2PNswDsBpa2yLgA== +-----END RSA PRIVATE KEY----- +`), +} + +var PEMEncryptedKeys = []struct { + Name string + EncryptionKey string + IncludesPublicKey bool + PEMBytes []byte +}{ + 0: { + Name: "rsa-encrypted", + EncryptionKey: "r54-G0pher_t3st$", + PEMBytes: []byte(`-----BEGIN RSA PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: AES-128-CBC,3E1714DE130BC5E81327F36564B05462 + +MqW88sud4fnWk/Jk3fkjh7ydu51ZkHLN5qlQgA4SkAXORPPMj2XvqZOv1v2LOgUV +dUevUn8PZK7a9zbZg4QShUSzwE5k6wdB7XKPyBgI39mJ79GBd2U4W3h6KT6jIdWA +goQpluxkrzr2/X602IaxLEre97FT9mpKC6zxKCLvyFWVIP9n3OSFS47cTTXyFr+l +7PdRhe60nn6jSBgUNk/Q1lAvEQ9fufdPwDYY93F1wyJ6lOr0F1+mzRrMbH67NyKs +rG8J1Fa7cIIre7ueKIAXTIne7OAWqpU9UDgQatDtZTbvA7ciqGsSFgiwwW13N+Rr +hN8MkODKs9cjtONxSKi05s206A3NDU6STtZ3KuPDjFE1gMJODotOuqSM+cxKfyFq +wxpk/CHYCDdMAVBSwxb/vraOHamylL4uCHpJdBHypzf2HABt+lS8Su23uAmL87DR +yvyCS/lmpuNTndef6qHPRkoW2EV3xqD3ovosGf7kgwGJUk2ZpCLVteqmYehKlZDK +r/Jy+J26ooI2jIg9bjvD1PZq+Mv+2dQ1RlDrPG3PB+rEixw6vBaL9x3jatCd4ej7 +XG7lb3qO9xFpLsx89tkEcvpGR+broSpUJ6Mu5LBCVmrvqHjvnDhrZVz1brMiQtU9 +iMZbgXqDLXHd6ERWygk7OTU03u+l1gs+KGMfmS0h0ZYw6KGVLgMnsoxqd6cFSKNB +8Ohk9ZTZGCiovlXBUepyu8wKat1k8YlHSfIHoRUJRhhcd7DrmojC+bcbMIZBU22T +Pl2ftVRGtcQY23lYd0NNKfebF7ncjuLWQGy+vZW+7cgfI6wPIbfYfP6g7QAutk6W +KQx0AoX5woZ6cNxtpIrymaVjSMRRBkKQrJKmRp3pC/lul5E5P2cueMs1fj4OHTbJ +lAUv88ywr+R+mRgYQlFW/XQ653f6DT4t6+njfO9oBcPrQDASZel3LjXLpjjYG/N5 ++BWnVexuJX9ika8HJiFl55oqaKb+WknfNhk5cPY+x7SDV9ywQeMiDZpr0ffeYAEP +LlwwiWRDYpO+uwXHSFF3+JjWwjhs8m8g99iFb7U93yKgBB12dCEPPa2ZeH9wUHMJ +sreYhNuq6f4iWWSXpzN45inQqtTi8jrJhuNLTT543ErW7DtntBO2rWMhff3aiXbn +Uy3qzZM1nPbuCGuBmP9L2dJ3Z5ifDWB4JmOyWY4swTZGt9AVmUxMIKdZpRONx8vz +I9u9nbVPGZBcou50Pa0qTLbkWsSL94MNXrARBxzhHC9Zs6XNEtwN7mOuii7uMkVc +adrxgknBH1J1N+NX/eTKzUwJuPvDtA+Z5ILWNN9wpZT/7ed8zEnKHPNUexyeT5g3 +uw9z9jH7ffGxFYlx87oiVPHGOrCXYZYW5uoZE31SCBkbtNuffNRJRKIFeipmpJ3P +7bpAG+kGHMelQH6b+5K1Qgsv4tpuSyKeTKpPFH9Av5nN4P1ZBm9N80tzbNWqjSJm +S7rYdHnuNEVnUGnRmEUMmVuYZnNBEVN/fP2m2SEwXcP3Uh7TiYlcWw10ygaGmOr7 +MvMLGkYgQ4Utwnd98mtqa0jr0hK2TcOSFir3AqVvXN3XJj4cVULkrXe4Im1laWgp +-----END RSA PRIVATE KEY----- +`), + }, + + 1: { + Name: "dsa-encrypted", + EncryptionKey: "qG0pher-dsa_t3st$", + PEMBytes: []byte(`-----BEGIN DSA PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: AES-128-CBC,7CE7A6E4A647DC01AF860210B15ADE3E + +hvnBpI99Hceq/55pYRdOzBLntIEis02JFNXuLEydWL+RJBFDn7tA+vXec0ERJd6J +G8JXlSOAhmC2H4uK3q2xR8/Y3yL95n6OIcjvCBiLsV+o3jj1MYJmErxP6zRtq4w3 +JjIjGHWmaYFSxPKQ6e8fs74HEqaeMV9ONUoTtB+aISmgaBL15Fcoayg245dkBvVl +h5Kqspe7yvOBmzA3zjRuxmSCqKJmasXM7mqs3vIrMxZE3XPo1/fWKcPuExgpVQoT +HkJZEoIEIIPnPMwT2uYbFJSGgPJVMDT84xz7yvjCdhLmqrsXgs5Qw7Pw0i0c0BUJ +b7fDJ2UhdiwSckWGmIhTLlJZzr8K+JpjCDlP+REYBI5meB7kosBnlvCEHdw2EJkH +0QDc/2F4xlVrHOLbPRFyu1Oi2Gvbeoo9EsM/DThpd1hKAlb0sF5Y0y0d+owv0PnE +R/4X3HWfIdOHsDUvJ8xVWZ4BZk9Zk9qol045DcFCehpr/3hslCrKSZHakLt9GI58 +vVQJ4L0aYp5nloLfzhViZtKJXRLkySMKdzYkIlNmW1oVGl7tce5UCNI8Nok4j6yn +IiHM7GBn+0nJoKTXsOGMIBe3ulKlKVxLjEuk9yivh/8= +-----END DSA PRIVATE KEY----- +`), + }, + + 2: { + Name: "ed25519-encrypted", + EncryptionKey: "password", + IncludesPublicKey: true, + PEMBytes: []byte(`-----BEGIN OPENSSH PRIVATE KEY----- +b3BlbnNzaC1rZXktdjEAAAAACmFlczI1Ni1jdHIAAAAGYmNyeXB0AAAAGAAAABDKj29BlC +ocEWuVhQ94/RjoAAAAEAAAAAEAAAAzAAAAC3NzaC1lZDI1NTE5AAAAIIw1gSurPTDwZidA +2AIjQZgoQi3IFn9jBtFdP10/Jj7DAAAAoFGkQbB2teSU7ikUsnc7ct2aH3pitM359lNVUh +7DQbJWMjbQFbrBYyDJP+ALj1/RZmP2yoIf7/wr99q53/pm28Xp1gGP5V2RGRJYCA6kgFIH +xdB6KEw1Ce7Bz8JaDIeagAGd3xtQTH3cuuleVxCZZnk9NspsPxigADKCls/RUiK7F+z3Qf +Lvs9+PH8nIuhFMYZgo3liqZbVS5z4Fqhyzyq4= +-----END OPENSSH PRIVATE KEY----- +`), + }, + + 3: { + Name: "ed25519-encrypted-cbc", + EncryptionKey: "password", + IncludesPublicKey: true, + PEMBytes: []byte(`-----BEGIN OPENSSH PRIVATE KEY----- +b3BlbnNzaC1rZXktdjEAAAAACmFlczI1Ni1jYmMAAAAGYmNyeXB0AAAAGAAAABDzGKF3uX +G1gXALZKFd6Ir4AAAAEAAAAAEAAAAzAAAAC3NzaC1lZDI1NTE5AAAAIDne4/teO42zTDdj +NwxUMNpbfmp/dxgU4ZNkC3ydgcugAAAAoJ3J/oA7+iqVOz0CIUUk9ufdP1VP4jDf2um+0s +Sgs7x6Gpyjq67Ps7wLRdSmxr/G5b+Z8dRGFYS/wUCQEe3whwuImvLyPwWjXLzkAyMzc01f +ywBGSrHnvP82ppenc2HuTI+E05Xc02i6JVyI1ShiekQL5twoqtR6pEBZnD17UonIx7cRzZ +gbDGyT3bXMQtagvCwoW+/oMTKXiZP5jCJpEO8= +-----END OPENSSH PRIVATE KEY----- +`), + }, +} diff --git a/tool/tsh/common/scan.go b/tool/tsh/common/scan.go new file mode 100644 index 0000000000000..f96eff417b468 --- /dev/null +++ b/tool/tsh/common/scan.go @@ -0,0 +1,170 @@ +/* + * Teleport + * Copyright (C) 2024 Gravitational, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package common + +import ( + "fmt" + "log/slog" + "runtime" + "strings" + + "github.com/alecthomas/kingpin/v2" + "github.com/gravitational/trace" + + "github.com/gravitational/teleport/api/constants" + accessgraphsecretsv1pb "github.com/gravitational/teleport/api/gen/proto/go/teleport/accessgraph/v1" + "github.com/gravitational/teleport/api/types/accessgraph" + "github.com/gravitational/teleport/lib/devicetrust/assert" + dtnative "github.com/gravitational/teleport/lib/devicetrust/native" + secretsscannerclient "github.com/gravitational/teleport/lib/secretsscanner/client" + secretsreporter "github.com/gravitational/teleport/lib/secretsscanner/reporter" + secretsscanner "github.com/gravitational/teleport/lib/secretsscanner/scaner" +) + +type scanCommand struct { + keys *scanKeysCommand +} + +func newScanCommand(app *kingpin.Application) scanCommand { + scan := app.Command("scan", "Scan the local machine for Secrets and report findings to Teleport") + cmd := scanCommand{ + keys: newScanKeysCommand(scan), + } + return cmd +} + +type scanKeysCommand struct { + *kingpin.CmdClause + dirs []string + skipPaths []string +} + +func newScanKeysCommand(parent *kingpin.CmdClause) *scanKeysCommand { + c := &scanKeysCommand{CmdClause: parent.Command("keys", "Scan the local machine for SSH private keys and report findings to Teleport")} + c.Flag("dirs", "Directories to scan.").Default(defaultDirValues()).StringsVar(&c.dirs) + c.Flag("skip-paths", "Paths to directories or files to skip. Supports for matching patterns.").StringsVar(&c.skipPaths) + return c +} + +func defaultDirValues() string { + switch runtime.GOOS { + case constants.LinuxOS: + return "/home/" + case constants.DarwinOS: + return "/Users/" + case constants.WindowsOS: + return "C:\\Users\\" + default: + return "/" + } +} + +func (c *scanKeysCommand) run(cf *CLIConf) error { + if len(c.dirs) == 0 { + return trace.BadParameter("no directories to scan") + } + + if cf.Proxy == "" { + return trace.BadParameter("proxy address is required") + } + + ctx := cf.Context + + deviceCred, err := dtnative.GetDeviceCredential() + if err != nil { + return trace.Wrap(err, "device not enrolled") + } + + fmt.Printf("Device trust credentials found.\nScanning %s.\n", strings.Join(c.dirs, ", ")) + + scanner, err := secretsscanner.New(secretsscanner.Config{ + Dirs: c.dirs, + SkipPaths: c.skipPaths, + Log: slog.Default(), + }) + if err != nil { + return trace.Wrap(err, "failed to create scanner") + } + + privateKeys := scanner.ScanPrivateKeys( + ctx, + deviceCred.Id, + ) + + printPrivateKeys(privateKeys) + + client, err := secretsscannerclient.NewSecretsScannerServiceClient( + ctx, + secretsscannerclient.ClientConfig{ + ProxyServer: cf.Proxy, + Insecure: cf.InsecureSkipVerify, + Log: slog.Default(), + }) + if err != nil { + return trace.Wrap(err, "failed to create client") + } + + reporter, err := secretsreporter.New( + secretsreporter.Config{ + Client: client, + Log: slog.Default(), + AssertCeremonyBuilder: func() (*assert.Ceremony, error) { + return assert.NewCeremony() + }, + }, + ) + if err != nil { + return trace.Wrap(err, "failed to create reporter") + } + + if err := reporter.ReportPrivateKeys(ctx, collectPrivateKeys(privateKeys)); trace.IsNotImplemented(err) { + return handleUnimplementedError(ctx, err, *cf) + } else if err != nil { + return trace.Wrap(err, "failed to report private keys") + } + + fmt.Printf("Reported %d SSH fingerprints to Teleport.\n", len(privateKeys)) + + return nil +} + +func printPrivateKeys(privateKeys []secretsscanner.SSHPrivateKey) { + if len(privateKeys) == 0 { + fmt.Println("No SSH private keys found.") + return + } + + fmt.Println("SSH private keys found:") + for _, pk := range privateKeys { + path, key := pk.Path, pk.Key + fmt.Printf("- SHA256 fingerprint: %q (mode: %s) at %s\n", + key.Spec.PublicKeyFingerprint, + accessgraph.DescribePublicKeyMode(key.Spec.PublicKeyMode), + path, + ) + } +} + +func collectPrivateKeys(privateKeys []secretsscanner.SSHPrivateKey) []*accessgraphsecretsv1pb.PrivateKey { + keys := make([]*accessgraphsecretsv1pb.PrivateKey, 0, len(privateKeys)) + for _, pk := range privateKeys { + keys = append(keys, pk.Key) + } + return keys +} diff --git a/tool/tsh/common/tsh.go b/tool/tsh/common/tsh.go index 0771199a406cc..a7fc58543c477 100644 --- a/tool/tsh/common/tsh.go +++ b/tool/tsh/common/tsh.go @@ -1173,6 +1173,8 @@ func Run(ctx context.Context, args []string, opts ...CliOption) error { kube := newKubeCommand(app) // MFA subcommands. mfa := newMFACommand(app) + // SCAN subcommands. + scan := newScanCommand(app) config := app.Command("config", "Print OpenSSH configuration details.") config.Flag("port", "SSH port on a remote host").Short('p').Int32Var(&cf.NodePort) @@ -1471,7 +1473,8 @@ func Run(ctx context.Context, args []string, opts ...CliOption) error { err = kube.exec.run(&cf) case kube.join.FullCommand(): err = kube.join.run(&cf) - + case scan.keys.FullCommand(): + err = scan.keys.run(&cf) case proxySSH.FullCommand(): err = onProxyCommandSSH(&cf) case proxyDB.FullCommand(): From 22b64898a74dfb0b84f7a3f35db419d8c9e66771 Mon Sep 17 00:00:00 2001 From: Tiago Silva Date: Mon, 29 Jul 2024 18:05:13 +0100 Subject: [PATCH 22/25] [sec_scan][22] add authorized keys reporter (#44523) * [sec_scan][22] add authorized keys reporter This PR introduces a SSH authorized keys reporter that monitors `/etc/passwd` file and all users' authorized_keys files and reports the findings back to teleport. Part of https://github.com/gravitational/access-graph/issues/637 Signed-off-by: Tiago Silva * handle comments * handle comments --------- Signed-off-by: Tiago Silva --- api/types/accessgraph/authorized_key.go | 5 +- .../authorizedkeys/authorized_keys.go | 388 ++++++++++++++++++ .../authorizedkeys/authorized_keys_test.go | 220 ++++++++++ .../authorizedkeys/supervisor.go | 112 +++++ .../authorizedkeys/supervisor_test.go | 135 ++++++ lib/srv/regular/sshserver.go | 33 ++ 6 files changed, 891 insertions(+), 2 deletions(-) create mode 100644 lib/secretsscanner/authorizedkeys/authorized_keys.go create mode 100644 lib/secretsscanner/authorizedkeys/authorized_keys_test.go create mode 100644 lib/secretsscanner/authorizedkeys/supervisor.go create mode 100644 lib/secretsscanner/authorizedkeys/supervisor_test.go diff --git a/api/types/accessgraph/authorized_key.go b/api/types/accessgraph/authorized_key.go index 5532f39bc2775..33de330f9c688 100644 --- a/api/types/accessgraph/authorized_key.go +++ b/api/types/accessgraph/authorized_key.go @@ -28,7 +28,8 @@ import ( ) const ( - authorizedKeyDefaultKeyTTL = 8 * time.Hour + // AuthorizedKeyDefaultKeyTTL is the default TTL for an authorized key. + AuthorizedKeyDefaultKeyTTL = 8 * time.Hour ) // NewAuthorizedKey creates a new SSH authorized key resource. @@ -40,7 +41,7 @@ func NewAuthorizedKey(spec *accessgraphv1pb.AuthorizedKeySpec) (*accessgraphv1pb Metadata: &headerv1.Metadata{ Name: name, Expires: timestamppb.New( - time.Now().Add(authorizedKeyDefaultKeyTTL), + time.Now().Add(AuthorizedKeyDefaultKeyTTL), ), }, Spec: spec, diff --git a/lib/secretsscanner/authorizedkeys/authorized_keys.go b/lib/secretsscanner/authorizedkeys/authorized_keys.go new file mode 100644 index 0000000000000..5e26720fae4c7 --- /dev/null +++ b/lib/secretsscanner/authorizedkeys/authorized_keys.go @@ -0,0 +1,388 @@ +/* + * Teleport + * Copyright (C) 2024 Gravitational, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package authorizedkeys + +import ( + "bufio" + "context" + "errors" + "log/slog" + "os" + "os/user" + "path/filepath" + "runtime" + "strings" + "sync" + "time" + + "github.com/fsnotify/fsnotify" + "github.com/gravitational/trace" + "github.com/jonboulle/clockwork" + "golang.org/x/crypto/ssh" + + "github.com/gravitational/teleport/api/constants" + accessgraphsecretsv1pb "github.com/gravitational/teleport/api/gen/proto/go/teleport/accessgraph/v1" + clusterconfigpb "github.com/gravitational/teleport/api/gen/proto/go/teleport/clusterconfig/v1" + "github.com/gravitational/teleport/api/types/accessgraph" + "github.com/gravitational/teleport/api/utils/retryutils" +) + +var ( + // ErrUnsupportedPlatform is returned when the operating system is not supported. + ErrUnsupportedPlatform = errors.New("unsupported platform") +) + +// Watcher watches for changes to authorized_keys files +// and reports them to the cluster. If the cluster does not have +// scanning enabled, the watcher will hold until the feature is enabled. +type Watcher struct { + // client is the client to use to communicate with the cluster. + client ClusterClient + logger *slog.Logger + clock clockwork.Clock + hostID string + usersAccountFile string +} + +// ClusterClient is the client to use to communicate with the cluster. +type ClusterClient interface { + GetClusterAccessGraphConfig(context.Context) (*clusterconfigpb.AccessGraphConfig, error) + AccessGraphSecretsScannerClient() accessgraphsecretsv1pb.SecretsScannerServiceClient +} + +// WatcherConfig is the configuration for the Watcher. +type WatcherConfig struct { + // Client is the client to use to communicate with the cluster. + Client ClusterClient + // Logger is the logger to use. + Logger *slog.Logger + // Clock is the clock to use. + Clock clockwork.Clock + // HostID is the ID of the host. + HostID string + // getRuntimeOS returns the runtime operating system. + // used for testing purposes. + getRuntimeOS func() string + // etcPasswdFile is the path to the file that contains the users account information on the system. + // This file is used to get the list of users on the system and their home directories. + // Value is set to "/etc/passwd" by default. + etcPasswdFile string +} + +// NewWatcher creates a new Watcher instance. +// Returns [ErrUnsupportedPlatform] if the operating system is not supported. +func NewWatcher(ctx context.Context, config WatcherConfig) (*Watcher, error) { + + if getOS(config) != constants.LinuxOS { + return nil, trace.Wrap(ErrUnsupportedPlatform) + } + + if config.HostID == "" { + return nil, trace.BadParameter("missing host ID") + } + if config.Client == nil { + return nil, trace.BadParameter("missing client") + } + if config.Logger == nil { + config.Logger = slog.Default() + } + if config.Clock == nil { + config.Clock = clockwork.NewRealClock() + } + if config.etcPasswdFile == "" { + // etcPasswordPath is the path to the password file. + // This file is used to get the list of users on the system and their home directories. + const etcPasswordPath = "/etc/passwd" + config.etcPasswdFile = etcPasswordPath + } + + w := &Watcher{ + client: config.Client, + logger: config.Logger, + clock: config.Clock, + hostID: config.HostID, + usersAccountFile: config.etcPasswdFile, + } + + return w, nil +} + +func (w *Watcher) Run(ctx context.Context) error { + return trace.Wrap(w.monitorClusterConfigAndStart(ctx)) +} + +func (w *Watcher) monitorClusterConfigAndStart(ctx context.Context) error { + const tickerInterval = 30 * time.Minute + return trace.Wrap(supervisorRunner(ctx, supervisorRunnerConfig{ + clock: w.clock, + tickerInterval: tickerInterval, + runner: w.start, + checkIfMonitorEnabled: w.isAuthorizedKeysReportEnabled, + logger: w.logger, + })) +} + +// start starts the watcher. +func (w *Watcher) start(ctx context.Context) error { + wg := sync.WaitGroup{} + defer wg.Wait() + + fileWatcher, err := fsnotify.NewWatcher() + if err != nil { + return trace.Wrap(err) + } + defer func() { + if err := fileWatcher.Close(); err != nil { + w.logger.WarnContext(ctx, "Failed to close watcher", "error", err) + } + }() + + ctx, cancel := context.WithCancel(ctx) + defer cancel() + reload := make(chan struct{}) + wg.Add(1) + go func() { + defer wg.Done() + for { + select { + case <-ctx.Done(): + return + case <-fileWatcher.Events: + innerLoop: + for { + select { + case <-ctx.Done(): + return + case <-fileWatcher.Events: + case reload <- struct{}{}: + break innerLoop + } + } + case err := <-fileWatcher.Errors: + w.logger.WarnContext(ctx, "Error watching authorized_keys file", "error", err) + } + } + }() + + if err := fileWatcher.Add(w.usersAccountFile); err != nil { + w.logger.WarnContext(ctx, "Failed to add watcher for file", "error", err) + } + + stream, err := w.client.AccessGraphSecretsScannerClient().ReportAuthorizedKeys(ctx) + if err != nil { + return trace.Wrap(err) + } + + // Wait for the initial delay before sending the first report to spread the load. + // The initial delay is a random value between 0 and maxInitialDelay. + const maxInitialDelay = 5 * time.Minute + select { + case <-ctx.Done(): + return nil + case <-w.clock.After(retryutils.NewFullJitter()(maxInitialDelay)): + } + + jitterFunc := retryutils.NewHalfJitter() + // maxReSendInterval is the maximum interval to re-send the authorized keys report + // to the cluster in case of no changes. + const maxReSendInterval = accessgraph.AuthorizedKeyDefaultKeyTTL - 20*time.Minute + timer := w.clock.NewTimer(jitterFunc(maxReSendInterval)) + defer timer.Stop() + for { + + if err := w.fetchAndReportAuthorizedKeys(ctx, stream, fileWatcher); err != nil { + w.logger.WarnContext(ctx, "Failed to report authorized keys", "error", err) + } + + if !timer.Stop() { + <-timer.Chan() + } + timer.Reset(jitterFunc(maxReSendInterval)) + + select { + case <-ctx.Done(): + return nil + case <-reload: + case <-timer.Chan(): + } + } +} + +// isAuthorizedKeysReportEnabled checks if the cluster has authorized keys report enabled. +func (w *Watcher) isAuthorizedKeysReportEnabled(ctx context.Context) (bool, error) { + accessGraphConfig, err := w.client.GetClusterAccessGraphConfig(ctx) + if err != nil { + return false, trace.Wrap(err) + } + return accessGraphConfig.GetEnabled() && accessGraphConfig.GetSecretsScanConfig().GetSshScanEnabled(), nil +} + +// fetchAndReportAuthorizedKeys fetches the authorized keys from the system and reports them to the cluster. +func (w *Watcher) fetchAndReportAuthorizedKeys( + ctx context.Context, + stream accessgraphsecretsv1pb.SecretsScannerService_ReportAuthorizedKeysClient, + fileWatcher *fsnotify.Watcher, +) error { + users, err := userList(ctx, w.logger, w.usersAccountFile) + if err != nil { + return trace.Wrap(err) + } + var keys []*accessgraphsecretsv1pb.AuthorizedKey + for _, u := range users { + if u.HomeDir == "" { + w.logger.DebugContext(ctx, "Skipping user with empty home directory", "user", u.Name) + continue + } + + for _, file := range []string{"authorized_keys", "authorized_keys2"} { + authorizedKeysPath := filepath.Join(u.HomeDir, ".ssh", file) + if fs, err := os.Stat(authorizedKeysPath); err != nil || fs.IsDir() { + continue + } + + hostKeys, err := w.parseAuthorizedKeysFile(ctx, u, authorizedKeysPath) + if errors.Is(err, os.ErrNotExist) { + continue + } else if err != nil { + w.logger.WarnContext(ctx, "Failed to parse authorized_keys file", "error", err) + continue + } + + // Add the file to the watcher. If file was already added, this is a no-op. + if err := fileWatcher.Add(authorizedKeysPath); err != nil { + w.logger.WarnContext(ctx, "Failed to add watcher for file", "error", err) + } + keys = append(keys, hostKeys...) + } + } + + const maxKeysPerReport = 500 + for i := 0; i < len(keys); i += maxKeysPerReport { + start := i + end := min(i+maxKeysPerReport, len(keys)) + if err := stream.Send( + &accessgraphsecretsv1pb.ReportAuthorizedKeysRequest{ + Keys: keys[start:end], + Operation: accessgraphsecretsv1pb.OperationType_OPERATION_TYPE_ADD, + }, + ); err != nil { + return trace.Wrap(err) + } + } + + if err := stream.Send( + &accessgraphsecretsv1pb.ReportAuthorizedKeysRequest{Operation: accessgraphsecretsv1pb.OperationType_OPERATION_TYPE_SYNC}, + ); err != nil { + return trace.Wrap(err) + } + return nil +} + +// userList retrieves all users on the system +func userList(ctx context.Context, log *slog.Logger, filePath string) ([]user.User, error) { + file, err := os.Open(filePath) + if err != nil { + return nil, err + } + defer func() { + if err := file.Close(); err != nil { + log.DebugContext(ctx, "Failed to close file", "error", err, "file", filePath) + } + }() + + var users []user.User + scanner := bufio.NewScanner(file) + for scanner.Scan() { + line := scanner.Text() + // Skip empty lines and comments + if line == "" || strings.HasPrefix(line, "#") { + continue + } + // username:password:uid:gid:gecos:home:shell + parts := strings.Split(line, ":") + if len(parts) < 7 { + continue + } + users = append(users, user.User{ + Username: parts[0], + Uid: parts[2], + Gid: parts[3], + Name: parts[4], + HomeDir: parts[5], + }) + } + + if err := scanner.Err(); err != nil { + return nil, err + } + + return users, nil +} + +func (w *Watcher) parseAuthorizedKeysFile(ctx context.Context, u user.User, authorizedKeysPath string) ([]*accessgraphsecretsv1pb.AuthorizedKey, error) { + file, err := os.Open(authorizedKeysPath) + if err != nil { + return nil, trace.Wrap(err) + } + defer func() { + if err := file.Close(); err != nil { + w.logger.WarnContext(ctx, "Failed to close file", "error", err, "path", authorizedKeysPath) + } + }() + + var keys []*accessgraphsecretsv1pb.AuthorizedKey + scanner := bufio.NewScanner(file) + scanner.Split(bufio.ScanLines) + for scanner.Scan() { + payload := scanner.Bytes() + if len(payload) == 0 || payload[0] == '#' { + continue + } + parsedKey, _, _, _, err := ssh.ParseAuthorizedKey(payload) + if err != nil { + w.logger.WarnContext(ctx, "Failed to parse authorized key", "error", err) + continue + } else if parsedKey == nil { + continue + } + + authorizedKey, err := accessgraph.NewAuthorizedKey( + &accessgraphsecretsv1pb.AuthorizedKeySpec{ + HostId: w.hostID, + HostUser: u.Username, + KeyFingerprint: ssh.FingerprintSHA256(parsedKey), + }, + ) + if err != nil { + w.logger.WarnContext(ctx, "Failed to create authorized key", "error", err) + continue + } + keys = append(keys, authorizedKey) + } + + return keys, nil +} + +func getOS(config WatcherConfig) string { + goos := runtime.GOOS + if config.getRuntimeOS != nil { + goos = config.getRuntimeOS() + } + return goos +} diff --git a/lib/secretsscanner/authorizedkeys/authorized_keys_test.go b/lib/secretsscanner/authorizedkeys/authorized_keys_test.go new file mode 100644 index 0000000000000..8e54603ad0ec4 --- /dev/null +++ b/lib/secretsscanner/authorizedkeys/authorized_keys_test.go @@ -0,0 +1,220 @@ +/* + * Teleport + * Copyright (C) 2024 Gravitational, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package authorizedkeys + +import ( + "context" + "fmt" + "log/slog" + "os" + "path/filepath" + "slices" + "sync" + "testing" + "time" + + "github.com/google/go-cmp/cmp" + "github.com/gravitational/trace" + "github.com/jonboulle/clockwork" + "github.com/stretchr/testify/require" + "golang.org/x/sync/errgroup" + "google.golang.org/grpc" + "google.golang.org/protobuf/testing/protocmp" + + "github.com/gravitational/teleport/api/constants" + accessgraphsecretsv1pb "github.com/gravitational/teleport/api/gen/proto/go/teleport/accessgraph/v1" + clusterconfigpb "github.com/gravitational/teleport/api/gen/proto/go/teleport/clusterconfig/v1" + headerv1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/header/v1" + "github.com/gravitational/teleport/api/types/accessgraph" +) + +func TestAuthorizedKeys(t *testing.T) { + hostID := "hostID" + + etcPasswdFile := createFSData(t) + clock := clockwork.NewFakeClockAt(time.Date(2024, time.January, 1, 0, 0, 0, 0, time.UTC)) + client := &fakeClient{} + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + watcher, err := NewWatcher(ctx, WatcherConfig{ + Client: client, + etcPasswdFile: etcPasswdFile, + HostID: hostID, + Clock: clock, + Logger: slog.Default(), + getRuntimeOS: func() string { + return constants.LinuxOS + }, + }) + require.NoError(t, err) + + // Start the watcher + group, ctx := errgroup.WithContext(ctx) + group.Go(func() error { + return trace.Wrap(watcher.Run(ctx)) + }) + + // Wait for the watcher to start and to block on the initial spread. + clock.BlockUntil(2) // wait for clock to blocked at supervisor and initial delay routine + // Advance the clock to trigger the first scan + clock.Advance(5 * time.Minute) + + // Wait for the watcher to start + require.Eventually(t, func() bool { + return len(client.getReqReceived()) == 2 + }, 1*time.Second, 10*time.Millisecond, "expected watcher to start, but it did not") + + // Check the requests + got := client.getReqReceived() + require.Len(t, got, 2) + expected := []*accessgraphsecretsv1pb.ReportAuthorizedKeysRequest{ + { + Keys: createKeysForUsers(t, hostID), + Operation: accessgraphsecretsv1pb.OperationType_OPERATION_TYPE_ADD, + }, + { + Operation: accessgraphsecretsv1pb.OperationType_OPERATION_TYPE_SYNC, + }, + } + require.Empty(t, cmp.Diff(got, expected, + protocmp.Transform(), + protocmp.SortRepeated( + func(a, b *accessgraphsecretsv1pb.AuthorizedKey) bool { + return a.Metadata.Name < b.Metadata.Name + }, + ), + protocmp.IgnoreFields(&headerv1.Metadata{}, "expires"), + ), + ) + + // Clear the requests + client.clear() + + // Update the etcPasswdFile + createUsersAndAuthorizedKeys(t, filepath.Dir(etcPasswdFile)) + + cancel() + err = group.Wait() + require.NoError(t, err) + +} + +func createFSData(t *testing.T) string { + dir := t.TempDir() + etcPasswd := exampleEtcPasswdFile(dir) + createFile(t, dir, "passwd", etcPasswd) + + createUsersAndAuthorizedKeys(t, dir) + return filepath.Join(dir, "passwd") +} + +func createFile(t *testing.T, dir, name, content string) { + err := os.MkdirAll(dir, 0755) + require.NoError(t, err) + path := fmt.Sprintf("%s/%s", dir, name) + err = os.WriteFile(path, []byte(content), 0644) + require.NoError(t, err) +} + +func exampleEtcPasswdFile(dir string) string { + return fmt.Sprintf( + `root:x:0:0::%s/root:/usr/bin/bash +bin:x:1:1::/:/usr/bin/nologin +user:x:1000:1000::%s/user:/usr/bin/zsh`, + dir, + dir, + ) +} + +const authorizedFileExample = ` +ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQClwXUKOp/S4XEtFjgr8mfaCy4OyI7N9ZMibdCGxvk2VHP9+Vn8Al1lUSVwuBxHI7EHiq42RCTBetIpTjzn6yiPNAeGNL5cfl9i6r+P5k7og1hz+2oheWveGodx6Dp+Z4o2dw65NGf5EPaotXF8AcHJc3+OiMS5yp/x2A3tu2I1SPQ6dtPa067p8q1L49BKbFwrFRBCVwkr6kpEQAIjnMESMPGD5Buu/AtyAdEZQSLTt8RZajJZDfXFKMEtQm2UF248NFl3hSMAcbbTxITBbZxX7THbwQz22Yuw7422G5CYBPf6WRXBY84Rs6jCS4I4GMxj+3rF4mGtjvuz0wOE32s3w4eMh9h3bPuEynufjE8henmPCIW49+kuZO4LZut7Zg5BfVDQnZYclwokEIMz+gR02YpyflxQOa98t/0mENu+t4f0LNAdkQEBpYtGKKDth5kLphi2Sdi9JpGO2sTivlxMsGyBqdd0wT9VwQpWf4wro6t09HdZJX1SAuEi/0tNI10= friel@test +# comment +ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGtqQKEkGIY5+Bc4EmEv7NeSn6aA7KMl5eiNEAOqwTBl friel@test +invalidLine +# comment +` + +func createUsersAndAuthorizedKeys(t *testing.T, dir string) { + for _, user := range []string{"root", "user"} { + dir := filepath.Join(dir, user, ".ssh") + createFile(t, dir, "authorized_keys", authorizedFileExample) + } +} + +type fakeClient struct { + accessgraphsecretsv1pb.SecretsScannerServiceClient + accessgraphsecretsv1pb.SecretsScannerService_ReportAuthorizedKeysClient + mu sync.Mutex + reqReceived []*accessgraphsecretsv1pb.ReportAuthorizedKeysRequest +} + +func (f *fakeClient) GetClusterAccessGraphConfig(_ context.Context) (*clusterconfigpb.AccessGraphConfig, error) { + return &clusterconfigpb.AccessGraphConfig{ + Enabled: true, + SecretsScanConfig: &clusterconfigpb.AccessGraphSecretsScanConfiguration{ + SshScanEnabled: true, + }, + }, nil +} +func (f *fakeClient) AccessGraphSecretsScannerClient() accessgraphsecretsv1pb.SecretsScannerServiceClient { + return f +} + +func (f *fakeClient) ReportAuthorizedKeys(_ context.Context, _ ...grpc.CallOption) (accessgraphsecretsv1pb.SecretsScannerService_ReportAuthorizedKeysClient, error) { + return f, nil +} + +func (f *fakeClient) Send(req *accessgraphsecretsv1pb.ReportAuthorizedKeysRequest) error { + f.mu.Lock() + defer f.mu.Unlock() + f.reqReceived = append(f.reqReceived, req) + return nil +} + +func (f *fakeClient) clear() { + f.mu.Lock() + defer f.mu.Unlock() + f.reqReceived = nil +} + +func (f *fakeClient) getReqReceived() []*accessgraphsecretsv1pb.ReportAuthorizedKeysRequest { + f.mu.Lock() + defer f.mu.Unlock() + return slices.Clone(f.reqReceived) +} + +func createKeysForUsers(t *testing.T, hostID string) []*accessgraphsecretsv1pb.AuthorizedKey { + var keys []*accessgraphsecretsv1pb.AuthorizedKey + for _, fingerprint := range []string{ + "SHA256:GbJlTLeQgZhvGoklWGXHo0AinGgGEcldllgYExoSy+s", /* ssh-rsa */ + "SHA256:ewwMB/nCAYurNrYFXYZuxLZv7T7vgpPd7QuIo0d5n+U", /* ssh-ed25519 */ + } { + for _, user := range []string{"root", "user"} { + at, err := accessgraph.NewAuthorizedKey(&accessgraphsecretsv1pb.AuthorizedKeySpec{ + HostId: hostID, + HostUser: user, + KeyFingerprint: fingerprint, + }) + require.NoError(t, err) + keys = append(keys, at) + } + } + return keys +} diff --git a/lib/secretsscanner/authorizedkeys/supervisor.go b/lib/secretsscanner/authorizedkeys/supervisor.go new file mode 100644 index 0000000000000..c0048abb07877 --- /dev/null +++ b/lib/secretsscanner/authorizedkeys/supervisor.go @@ -0,0 +1,112 @@ +/* + * Teleport + * Copyright (C) 2024 Gravitational, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package authorizedkeys + +import ( + "context" + "errors" + "log/slog" + "sync" + "time" + + "github.com/jonboulle/clockwork" + + "github.com/gravitational/teleport/api/utils/retryutils" +) + +var errShutdown = errors.New("watcher is shutting down") + +type supervisorRunnerConfig struct { + clock clockwork.Clock + tickerInterval time.Duration + runner func(context.Context) error + checkIfMonitorEnabled func(context.Context) (bool, error) + logger *slog.Logger +} + +// supervisorRunner runs the runner based on the checkIfMonitorEnabled result. +// If the monitor is enabled, the runner is started. If the monitor is disabled, +// the runner is stopped if it is running. +// The checkIfMonitorEnabled is evaluated every tickerInterval duration to determine +// if the monitor should be started or stopped. +// tickerInterval is jittered to prevent all watchers from running at the same time. +// If the watcher is stopped, it will be restarted after the next checkIfMonitorEnabled evaluation. +func supervisorRunner(parentCtx context.Context, cfg supervisorRunnerConfig) error { + var ( + isRunning = false + runCtx context.Context + runCtxCancel context.CancelCauseFunc + wg sync.WaitGroup + mu sync.Mutex + ) + + getIsRunning := func() bool { + mu.Lock() + defer mu.Unlock() + return isRunning + } + + setIsRunning := func(s bool) { + mu.Lock() + defer mu.Unlock() + isRunning = s + } + + runRoutine := func(ctx context.Context, cancel context.CancelCauseFunc) { + defer func() { + wg.Done() + cancel(errShutdown) + setIsRunning(false) + }() + if err := cfg.runner(ctx); err != nil && !errors.Is(err, errShutdown) { + cfg.logger.WarnContext(ctx, "Runner failed", "error", err) + } + } + + jitterFunc := retryutils.NewHalfJitter() + t := cfg.clock.NewTimer(jitterFunc(cfg.tickerInterval)) + for { + switch enabled, err := cfg.checkIfMonitorEnabled(parentCtx); { + case err != nil: + cfg.logger.WarnContext(parentCtx, "Failed to check if authorized keys report is enabled", "error", err) + case enabled && !getIsRunning(): + runCtx, runCtxCancel = context.WithCancelCause(parentCtx) + setIsRunning(true) + wg.Add(1) + go runRoutine(runCtx, runCtxCancel) + case !enabled && getIsRunning(): + runCtxCancel(errShutdown) + // Wait for the runner to stop before checking if the monitor is enabled again. + wg.Wait() + } + + select { + case <-t.Chan(): + if !t.Stop() { + select { + case <-t.Chan(): + default: + } + } + t.Reset(jitterFunc(cfg.tickerInterval)) + case <-parentCtx.Done(): + return nil + } + } +} diff --git a/lib/secretsscanner/authorizedkeys/supervisor_test.go b/lib/secretsscanner/authorizedkeys/supervisor_test.go new file mode 100644 index 0000000000000..93399ec1fdc5b --- /dev/null +++ b/lib/secretsscanner/authorizedkeys/supervisor_test.go @@ -0,0 +1,135 @@ +/* + * Teleport + * Copyright (C) 2024 Gravitational, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package authorizedkeys + +import ( + "context" + "log/slog" + "sync" + "testing" + "time" + + "github.com/jonboulle/clockwork" + "github.com/stretchr/testify/require" + "golang.org/x/sync/errgroup" +) + +func TestSupervisorRunner(t *testing.T) { + // Create a mock clock + clock := clockwork.NewFakeClock() + + t.Run("runner starts and stops based on monitor state", func(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + var mu sync.Mutex + var running bool + + runner := func(ctx context.Context) error { + mu.Lock() + running = true + mu.Unlock() + <-ctx.Done() + mu.Lock() + running = false + mu.Unlock() + return nil + } + + checker, enable, disable := checkIfMonitorEnabled() + enable() + + cfg := supervisorRunnerConfig{ + clock: clock, + tickerInterval: 1 * time.Second, + runner: runner, + checkIfMonitorEnabled: checker, + logger: slog.Default(), + } + + g, ctx := errgroup.WithContext(ctx) + g.Go(func() error { + return supervisorRunner(ctx, cfg) + }) + + require.Eventually(t, func() bool { + mu.Lock() + defer mu.Unlock() + return running + }, 100*time.Millisecond, 10*time.Millisecond, "expected runner to start, but it did not") + + disable() + + clock.BlockUntil(1) + clock.Advance(2 * time.Second) + + require.Eventually(t, func() bool { + mu.Lock() + defer mu.Unlock() + return !running + }, 100*time.Millisecond, 10*time.Millisecond, "expected runner to stop, but it did not") + + enable() + clock.BlockUntil(1) + clock.Advance(2 * time.Second) + + require.Eventually(t, func() bool { + mu.Lock() + defer mu.Unlock() + return running + }, 100*time.Millisecond, 10*time.Millisecond, "expected runner to re-start, but it did not") + + disable() + clock.BlockUntil(1) + clock.Advance(2 * time.Second) + + require.Eventually(t, func() bool { + mu.Lock() + defer mu.Unlock() + return !running + }, 100*time.Millisecond, 10*time.Millisecond, "expected runner to re-stop, but it did not") + + // Cancel the context to stop the supervisor + cancel() + if err := g.Wait(); err != nil { + t.Fatal(err) + } + }) + +} + +func checkIfMonitorEnabled() (checker func(context.Context) (bool, error), enable func(), disable func()) { + var ( + enabled bool + mu sync.Mutex + ) + return func(ctx context.Context) (bool, error) { + mu.Lock() + defer mu.Unlock() + return enabled, nil + }, func() { + mu.Lock() + defer mu.Unlock() + enabled = true + }, func() { + mu.Lock() + defer mu.Unlock() + enabled = false + } +} diff --git a/lib/srv/regular/sshserver.go b/lib/srv/regular/sshserver.go index 301f1c1d6345f..9975612c12c3d 100644 --- a/lib/srv/regular/sshserver.go +++ b/lib/srv/regular/sshserver.go @@ -26,6 +26,7 @@ import ( "errors" "fmt" "io" + "log/slog" "maps" "net" "os" @@ -62,6 +63,7 @@ import ( "github.com/gravitational/teleport/lib/proxy" "github.com/gravitational/teleport/lib/reversetunnel" "github.com/gravitational/teleport/lib/reversetunnelclient" + authorizedkeysreporter "github.com/gravitational/teleport/lib/secretsscanner/authorizedkeys" "github.com/gravitational/teleport/lib/service/servicecfg" "github.com/gravitational/teleport/lib/services" "github.com/gravitational/teleport/lib/services/local" @@ -850,6 +852,12 @@ func New( } s.srv = server + if !s.proxyMode { + if err := s.startAuthorizedKeysManager(ctx, auth); err != nil { + log.WithError(err).Infof("Failed to start authorized keys manager.") + } + } + var heartbeatMode srv.HeartbeatMode if s.proxyMode { heartbeatMode = srv.HeartbeatModeProxy @@ -904,6 +912,31 @@ func (s *Server) tunnelWithAccessChecker(ctx *srv.ServerContext) (reversetunnelc return reversetunnelclient.NewTunnelWithRoles(s.proxyTun, clusterName.GetClusterName(), ctx.Identity.AccessChecker, s.proxyAccessPoint), nil } +// startAuthorizedKeysManager starts the authorized keys manager. +func (s *Server) startAuthorizedKeysManager(ctx context.Context, auth authclient.ClientI) error { + authorizedKeysWatcher, err := authorizedkeysreporter.NewWatcher( + ctx, + authorizedkeysreporter.WatcherConfig{ + Client: auth, + Logger: slog.Default(), + HostID: s.uuid, + Clock: s.clock, + }, + ) + if errors.Is(err, authorizedkeysreporter.ErrUnsupportedPlatform) { + return nil + } else if err != nil { + return trace.Wrap(err) + } + + go func() { + if err := authorizedKeysWatcher.Run(ctx); err != nil { + s.Warningf("Failed to start authorized keys watcher: %v", err) + } + }() + return nil +} + // Context returns server shutdown context func (s *Server) Context() context.Context { return s.ctx From 1028828421b06cfe5da727d194d9458f94aee93d Mon Sep 17 00:00:00 2001 From: Tiago Silva Date: Mon, 29 Jul 2024 20:33:29 +0100 Subject: [PATCH 23/25] [sec_scan][24] extract AuthorizedKey's comment and type (#44643) This PR adds ability to extract the comment and key type from AuthorizedKeys files. Signed-off-by: Tiago Silva --- .../accessgraph/v1/authorized_key.pb.go | 52 ++++++++++++++----- .../access_graph/v1/authorized_key.proto | 6 +++ api/types/accessgraph/authorized_key.go | 4 ++ api/types/accessgraph/authorized_key_test.go | 15 ++++++ .../authorizedkeys/authorized_keys.go | 4 +- .../authorizedkeys/authorized_keys_test.go | 19 +++++-- lib/services/local/access_graph_test.go | 4 ++ 7 files changed, 85 insertions(+), 19 deletions(-) diff --git a/api/gen/proto/go/teleport/accessgraph/v1/authorized_key.pb.go b/api/gen/proto/go/teleport/accessgraph/v1/authorized_key.pb.go index 6ecdbf0e7b9d8..11a3a967d6dbc 100644 --- a/api/gen/proto/go/teleport/accessgraph/v1/authorized_key.pb.go +++ b/api/gen/proto/go/teleport/accessgraph/v1/authorized_key.pb.go @@ -133,6 +133,12 @@ type AuthorizedKeySpec struct { KeyFingerprint string `protobuf:"bytes,2,opt,name=key_fingerprint,json=keyFingerprint,proto3" json:"key_fingerprint,omitempty"` // host_user is the user who can be accessed using the fingerprint above. HostUser string `protobuf:"bytes,3,opt,name=host_user,json=hostUser,proto3" json:"host_user,omitempty"` + // key_comment is the authorized key's comment. + // Authorized keys consist of the following space-separated fields: + // options, keytype, base64-encoded key, comment. The options field is optional. + KeyComment string `protobuf:"bytes,4,opt,name=key_comment,json=keyComment,proto3" json:"key_comment,omitempty"` + // key_type is the ssh's key type. + KeyType string `protobuf:"bytes,5,opt,name=key_type,json=keyType,proto3" json:"key_type,omitempty"` } func (x *AuthorizedKeySpec) Reset() { @@ -188,6 +194,20 @@ func (x *AuthorizedKeySpec) GetHostUser() string { return "" } +func (x *AuthorizedKeySpec) GetKeyComment() string { + if x != nil { + return x.KeyComment + } + return "" +} + +func (x *AuthorizedKeySpec) GetKeyType() string { + if x != nil { + return x.KeyType + } + return "" +} + var File_teleport_access_graph_v1_authorized_key_proto protoreflect.FileDescriptor var file_teleport_access_graph_v1_authorized_key_proto_rawDesc = []byte{ @@ -211,20 +231,24 @@ var file_teleport_access_graph_v1_authorized_key_proto_rawDesc = []byte{ 0x2b, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x67, 0x72, 0x61, 0x70, 0x68, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x4b, 0x65, 0x79, 0x53, 0x70, 0x65, 0x63, 0x52, 0x04, 0x73, 0x70, - 0x65, 0x63, 0x22, 0x72, 0x0a, 0x11, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, - 0x4b, 0x65, 0x79, 0x53, 0x70, 0x65, 0x63, 0x12, 0x17, 0x0a, 0x07, 0x68, 0x6f, 0x73, 0x74, 0x5f, - 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x68, 0x6f, 0x73, 0x74, 0x49, 0x64, - 0x12, 0x27, 0x0a, 0x0f, 0x6b, 0x65, 0x79, 0x5f, 0x66, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, - 0x69, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x6b, 0x65, 0x79, 0x46, 0x69, - 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x68, 0x6f, 0x73, - 0x74, 0x5f, 0x75, 0x73, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x68, 0x6f, - 0x73, 0x74, 0x55, 0x73, 0x65, 0x72, 0x42, 0x5a, 0x5a, 0x58, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, - 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x72, 0x61, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x61, 0x6c, 0x2f, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x61, 0x70, 0x69, 0x2f, - 0x67, 0x65, 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x2f, 0x74, 0x65, 0x6c, - 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x67, 0x72, 0x61, 0x70, - 0x68, 0x2f, 0x76, 0x31, 0x3b, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x67, 0x72, 0x61, 0x70, 0x68, - 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x65, 0x63, 0x22, 0xae, 0x01, 0x0a, 0x11, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, + 0x64, 0x4b, 0x65, 0x79, 0x53, 0x70, 0x65, 0x63, 0x12, 0x17, 0x0a, 0x07, 0x68, 0x6f, 0x73, 0x74, + 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x68, 0x6f, 0x73, 0x74, 0x49, + 0x64, 0x12, 0x27, 0x0a, 0x0f, 0x6b, 0x65, 0x79, 0x5f, 0x66, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, + 0x72, 0x69, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x6b, 0x65, 0x79, 0x46, + 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x68, 0x6f, + 0x73, 0x74, 0x5f, 0x75, 0x73, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x68, + 0x6f, 0x73, 0x74, 0x55, 0x73, 0x65, 0x72, 0x12, 0x1f, 0x0a, 0x0b, 0x6b, 0x65, 0x79, 0x5f, 0x63, + 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6b, 0x65, + 0x79, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x5f, + 0x74, 0x79, 0x70, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6b, 0x65, 0x79, 0x54, + 0x79, 0x70, 0x65, 0x42, 0x5a, 0x5a, 0x58, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, + 0x6d, 0x2f, 0x67, 0x72, 0x61, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x2f, + 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x67, 0x65, 0x6e, + 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x2f, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, + 0x72, 0x74, 0x2f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x67, 0x72, 0x61, 0x70, 0x68, 0x2f, 0x76, + 0x31, 0x3b, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x67, 0x72, 0x61, 0x70, 0x68, 0x76, 0x31, 0x62, + 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/api/proto/teleport/access_graph/v1/authorized_key.proto b/api/proto/teleport/access_graph/v1/authorized_key.proto index 15d95228b4897..1795d7a415a58 100644 --- a/api/proto/teleport/access_graph/v1/authorized_key.proto +++ b/api/proto/teleport/access_graph/v1/authorized_key.proto @@ -43,4 +43,10 @@ message AuthorizedKeySpec { string key_fingerprint = 2; // host_user is the user who can be accessed using the fingerprint above. string host_user = 3; + // key_comment is the authorized key's comment. + // Authorized keys consist of the following space-separated fields: + // options, keytype, base64-encoded key, comment. The options field is optional. + string key_comment = 4; + // key_type is the ssh's key type. + string key_type = 5; } diff --git a/api/types/accessgraph/authorized_key.go b/api/types/accessgraph/authorized_key.go index 33de330f9c688..215583716be49 100644 --- a/api/types/accessgraph/authorized_key.go +++ b/api/types/accessgraph/authorized_key.go @@ -76,6 +76,10 @@ func ValidateAuthorizedKey(k *accessgraphv1pb.AuthorizedKey) error { return trace.BadParameter("KeyFingerprint is unset") } + if k.Spec.KeyType == "" { + return trace.BadParameter("KeyType is unset") + } + if k.Metadata.Name == "" { return trace.BadParameter("Name is unset") } diff --git a/api/types/accessgraph/authorized_key_test.go b/api/types/accessgraph/authorized_key_test.go index d28d72ebd3e7e..46c92cbd15a47 100644 --- a/api/types/accessgraph/authorized_key_test.go +++ b/api/types/accessgraph/authorized_key_test.go @@ -39,6 +39,7 @@ func TestAuthorizedKey(t *testing.T) { HostId: uuid.New().String(), KeyFingerprint: "fingerprint", HostUser: "user", + KeyType: "ssh-rsa", }, errValidation: require.NoError, }, @@ -48,6 +49,7 @@ func TestAuthorizedKey(t *testing.T) { HostId: uuid.New().String(), KeyFingerprint: "", HostUser: "user", + KeyType: "ssh-rsa", }, errValidation: func(t require.TestingT, err error, i ...any) { require.ErrorContains(t, err, "KeyFingerprint is unset") @@ -59,6 +61,7 @@ func TestAuthorizedKey(t *testing.T) { HostId: uuid.New().String(), KeyFingerprint: "fingerprint", HostUser: "", + KeyType: "ssh-rsa", }, errValidation: func(t require.TestingT, err error, i ...any) { require.ErrorContains(t, err, "HostUser is unset") @@ -69,11 +72,23 @@ func TestAuthorizedKey(t *testing.T) { spec: &accessgraphv1pb.AuthorizedKeySpec{ KeyFingerprint: "fingerprint", HostUser: "user", + KeyType: "ssh-rsa", }, errValidation: func(t require.TestingT, err error, i ...any) { require.ErrorContains(t, err, "HostId is unset") }, }, + { + name: "missing HostID", + spec: &accessgraphv1pb.AuthorizedKeySpec{ + KeyFingerprint: "fingerprint", + HostUser: "user", + HostId: uuid.New().String(), + }, + errValidation: func(t require.TestingT, err error, i ...any) { + require.ErrorContains(t, err, "KeyType is unset") + }, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { diff --git a/lib/secretsscanner/authorizedkeys/authorized_keys.go b/lib/secretsscanner/authorizedkeys/authorized_keys.go index 5e26720fae4c7..7919ac6162e6a 100644 --- a/lib/secretsscanner/authorizedkeys/authorized_keys.go +++ b/lib/secretsscanner/authorizedkeys/authorized_keys.go @@ -354,7 +354,7 @@ func (w *Watcher) parseAuthorizedKeysFile(ctx context.Context, u user.User, auth if len(payload) == 0 || payload[0] == '#' { continue } - parsedKey, _, _, _, err := ssh.ParseAuthorizedKey(payload) + parsedKey, comment, _, _, err := ssh.ParseAuthorizedKey(payload) if err != nil { w.logger.WarnContext(ctx, "Failed to parse authorized key", "error", err) continue @@ -367,6 +367,8 @@ func (w *Watcher) parseAuthorizedKeysFile(ctx context.Context, u user.User, auth HostId: w.hostID, HostUser: u.Username, KeyFingerprint: ssh.FingerprintSHA256(parsedKey), + KeyComment: comment, + KeyType: parsedKey.Type(), }, ) if err != nil { diff --git a/lib/secretsscanner/authorizedkeys/authorized_keys_test.go b/lib/secretsscanner/authorizedkeys/authorized_keys_test.go index 8e54603ad0ec4..b6d995dcdcf62 100644 --- a/lib/secretsscanner/authorizedkeys/authorized_keys_test.go +++ b/lib/secretsscanner/authorizedkeys/authorized_keys_test.go @@ -202,15 +202,26 @@ func (f *fakeClient) getReqReceived() []*accessgraphsecretsv1pb.ReportAuthorized func createKeysForUsers(t *testing.T, hostID string) []*accessgraphsecretsv1pb.AuthorizedKey { var keys []*accessgraphsecretsv1pb.AuthorizedKey - for _, fingerprint := range []string{ - "SHA256:GbJlTLeQgZhvGoklWGXHo0AinGgGEcldllgYExoSy+s", /* ssh-rsa */ - "SHA256:ewwMB/nCAYurNrYFXYZuxLZv7T7vgpPd7QuIo0d5n+U", /* ssh-ed25519 */ + for _, k := range []struct { + fingerprint string + keyType string + }{ + { + fingerprint: "SHA256:GbJlTLeQgZhvGoklWGXHo0AinGgGEcldllgYExoSy+s", + keyType: "ssh-ed25519", + }, + { + fingerprint: "SHA256:ewwMB/nCAYurNrYFXYZuxLZv7T7vgpPd7QuIo0d5n+U", + keyType: "ssh-rsa", + }, } { for _, user := range []string{"root", "user"} { at, err := accessgraph.NewAuthorizedKey(&accessgraphsecretsv1pb.AuthorizedKeySpec{ HostId: hostID, HostUser: user, - KeyFingerprint: fingerprint, + KeyFingerprint: k.fingerprint, + KeyComment: "friel@test", + KeyType: k.keyType, }) require.NoError(t, err) keys = append(keys, at) diff --git a/lib/services/local/access_graph_test.go b/lib/services/local/access_graph_test.go index 2eda122f8c045..b2a56819195b1 100644 --- a/lib/services/local/access_graph_test.go +++ b/lib/services/local/access_graph_test.go @@ -55,21 +55,25 @@ func TestAccessGraphAuthorizedKeys(t *testing.T) { HostId: "host1", HostUser: "user1", KeyFingerprint: "AAAAB3NzaC1yc2EAAAADAQABAAABAQC...", + KeyType: "ssh-rsa", }, { HostId: "host1", HostUser: "user2", KeyFingerprint: "AAAAB3NzaC1yc2EAAAADAQABAAABAQC...", + KeyType: "ssh-rsa", }, { HostId: "host2", HostUser: "user1", KeyFingerprint: "AAAAB3NzaC1yc2EAAAADAQABAAABAQC...", + KeyType: "ssh-rsa", }, { HostId: "host2", HostUser: "user2", KeyFingerprint: "AAAAB3NzaC1yc2EAAAADAQABAAABAQC...", + KeyType: "ssh-rsa", }, } var authKeys []*accessgraphsecretspb.AuthorizedKey From 16e8f68a1db7461d9cd3964ec98ce3216c666a1d Mon Sep 17 00:00:00 2001 From: Tiago Silva Date: Tue, 30 Jul 2024 12:07:04 +0100 Subject: [PATCH 24/25] fix api module --- .../teleport/legacy/types/events/events.proto | 3 + api/types/events/events.pb.go | 2229 +++++++++-------- api/types/events/oneof.go | 1 - go.mod | 2 +- integrations/terraform/go.sum | 2 + .../clusterconfig/clusterconfigv1/service.go | 6 +- .../clusterconfigv1/service_test.go | 16 +- 7 files changed, 1257 insertions(+), 1002 deletions(-) diff --git a/api/proto/teleport/legacy/types/events/events.proto b/api/proto/teleport/legacy/types/events/events.proto index ba30cd3128201..5d4d5a6306933 100644 --- a/api/proto/teleport/legacy/types/events/events.proto +++ b/api/proto/teleport/legacy/types/events/events.proto @@ -4442,6 +4442,9 @@ message OneOf { events.DiscoveryConfigDelete DiscoveryConfigDelete = 162; events.DiscoveryConfigDeleteAll DiscoveryConfigDeleteAll = 163; events.AccessGraphSettingsUpdate AccessGraphSettingsUpdate = 164; + events.IntegrationCreate IntegrationCreate = 165; + events.IntegrationUpdate IntegrationUpdate = 166; + events.IntegrationDelete IntegrationDelete = 167; } } diff --git a/api/types/events/events.pb.go b/api/types/events/events.pb.go index fe2856d4f16e3..c27fdfa78a682 100644 --- a/api/types/events/events.pb.go +++ b/api/types/events/events.pb.go @@ -7503,6 +7503,9 @@ type OneOf struct { // *OneOf_DiscoveryConfigDelete // *OneOf_DiscoveryConfigDeleteAll // *OneOf_AccessGraphSettingsUpdate + // *OneOf_IntegrationCreate + // *OneOf_IntegrationUpdate + // *OneOf_IntegrationDelete Event isOneOf_Event `protobuf_oneof:"Event"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` @@ -8037,6 +8040,15 @@ type OneOf_DiscoveryConfigDeleteAll struct { type OneOf_AccessGraphSettingsUpdate struct { AccessGraphSettingsUpdate *AccessGraphSettingsUpdate `protobuf:"bytes,164,opt,name=AccessGraphSettingsUpdate,proto3,oneof" json:"AccessGraphSettingsUpdate,omitempty"` } +type OneOf_IntegrationCreate struct { + IntegrationCreate *IntegrationCreate `protobuf:"bytes,165,opt,name=IntegrationCreate,proto3,oneof" json:"IntegrationCreate,omitempty"` +} +type OneOf_IntegrationUpdate struct { + IntegrationUpdate *IntegrationUpdate `protobuf:"bytes,166,opt,name=IntegrationUpdate,proto3,oneof" json:"IntegrationUpdate,omitempty"` +} +type OneOf_IntegrationDelete struct { + IntegrationDelete *IntegrationDelete `protobuf:"bytes,167,opt,name=IntegrationDelete,proto3,oneof" json:"IntegrationDelete,omitempty"` +} func (*OneOf_UserLogin) isOneOf_Event() {} func (*OneOf_UserCreate) isOneOf_Event() {} @@ -8201,6 +8213,9 @@ func (*OneOf_DiscoveryConfigUpdate) isOneOf_Event() {} func (*OneOf_DiscoveryConfigDelete) isOneOf_Event() {} func (*OneOf_DiscoveryConfigDeleteAll) isOneOf_Event() {} func (*OneOf_AccessGraphSettingsUpdate) isOneOf_Event() {} +func (*OneOf_IntegrationCreate) isOneOf_Event() {} +func (*OneOf_IntegrationUpdate) isOneOf_Event() {} +func (*OneOf_IntegrationDelete) isOneOf_Event() {} func (m *OneOf) GetEvent() isOneOf_Event { if m != nil { @@ -9350,6 +9365,27 @@ func (m *OneOf) GetAccessGraphSettingsUpdate() *AccessGraphSettingsUpdate { return nil } +func (m *OneOf) GetIntegrationCreate() *IntegrationCreate { + if x, ok := m.GetEvent().(*OneOf_IntegrationCreate); ok { + return x.IntegrationCreate + } + return nil +} + +func (m *OneOf) GetIntegrationUpdate() *IntegrationUpdate { + if x, ok := m.GetEvent().(*OneOf_IntegrationUpdate); ok { + return x.IntegrationUpdate + } + return nil +} + +func (m *OneOf) GetIntegrationDelete() *IntegrationDelete { + if x, ok := m.GetEvent().(*OneOf_IntegrationDelete); ok { + return x.IntegrationDelete + } + return nil +} + // XXX_OneofWrappers is for the internal use of the proto package. func (*OneOf) XXX_OneofWrappers() []interface{} { return []interface{}{ @@ -9516,6 +9552,9 @@ func (*OneOf) XXX_OneofWrappers() []interface{} { (*OneOf_DiscoveryConfigDelete)(nil), (*OneOf_DiscoveryConfigDeleteAll)(nil), (*OneOf_AccessGraphSettingsUpdate)(nil), + (*OneOf_IntegrationCreate)(nil), + (*OneOf_IntegrationUpdate)(nil), + (*OneOf_IntegrationDelete)(nil), } } @@ -13575,980 +13614,982 @@ func init() { } var fileDescriptor_007ba1c3d6266d56 = []byte{ - // 15555 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0xbd, 0x6d, 0x70, 0x24, 0xc9, - 0x75, 0x20, 0x86, 0xfe, 0x40, 0x03, 0x78, 0xf8, 0x18, 0x20, 0xe7, 0xab, 0x66, 0x76, 0x66, 0x7a, - 0xb7, 0x96, 0x3b, 0x9c, 0x59, 0xee, 0xce, 0x70, 0x67, 0x67, 0x77, 0xb9, 0x5f, 0xdc, 0x6d, 0xa0, - 0x81, 0x41, 0xef, 0xe0, 0x6b, 0xab, 0x31, 0x33, 0x5c, 0x7e, 0x35, 0x0b, 0x5d, 0x89, 0x46, 0xed, - 0x74, 0x57, 0x35, 0xab, 0xaa, 0x07, 0x83, 0xf5, 0x97, 0x28, 0xeb, 0x83, 0x94, 0x49, 0x8a, 0xa6, - 0x2c, 0x51, 0xb2, 0x64, 0x8b, 0x92, 0xec, 0x08, 0x59, 0x21, 0x4b, 0x96, 0xed, 0x90, 0x44, 0xcb, - 0x0c, 0x4b, 0xa6, 0x3f, 0x56, 0x66, 0xc8, 0x21, 0xc9, 0xb6, 0x42, 0x61, 0xcb, 0xa0, 0x8e, 0x77, - 0xba, 0x1f, 0x88, 0xbb, 0x38, 0xdd, 0x1d, 0xe3, 0xa4, 0xd3, 0xe9, 0x2e, 0x2e, 0xf2, 0x65, 0x56, - 0x55, 0xd6, 0x47, 0x37, 0x80, 0x01, 0x56, 0x58, 0x70, 0xf0, 0x67, 0x06, 0xfd, 0xde, 0xcb, 0x97, - 0x59, 0x2f, 0x5f, 0x66, 0xbe, 0xcc, 0x7c, 0xf9, 0x1e, 0x5c, 0xf6, 0x68, 0x93, 0xb6, 0x6d, 0xc7, - 0xbb, 0xda, 0xa4, 0x0d, 0xbd, 0xbe, 0x71, 0xd5, 0xdb, 0x68, 0x53, 0xf7, 0x2a, 0xbd, 0x47, 0x2d, - 0xcf, 0xff, 0xef, 0x4a, 0xdb, 0xb1, 0x3d, 0x9b, 0x14, 0xf8, 0xaf, 0xb3, 0x27, 0x1a, 0x76, 0xc3, - 0x46, 0xd0, 0x55, 0xf6, 0x17, 0xc7, 0x9e, 0x3d, 0xd7, 0xb0, 0xed, 0x46, 0x93, 0x5e, 0xc5, 0x5f, - 0x2b, 0x9d, 0xd5, 0xab, 0xae, 0xe7, 0x74, 0xea, 0x9e, 0xc0, 0x16, 0xe3, 0x58, 0xcf, 0x6c, 0x51, - 0xd7, 0xd3, 0x5b, 0x6d, 0x41, 0x70, 0x21, 0x4e, 0xb0, 0xee, 0xe8, 0xed, 0x36, 0x75, 0x44, 0xe5, - 0x67, 0x1f, 0x4b, 0x6f, 0x27, 0xfe, 0x2b, 0x48, 0x9e, 0x4e, 0x27, 0xf1, 0x19, 0xc5, 0x38, 0xaa, - 0x5f, 0xcd, 0xc2, 0xe0, 0x3c, 0xf5, 0x74, 0x43, 0xf7, 0x74, 0x72, 0x0e, 0xfa, 0x2b, 0x96, 0x41, - 0xef, 0x2b, 0x99, 0x47, 0x33, 0x97, 0x72, 0x93, 0x85, 0xad, 0xcd, 0x62, 0x96, 0x9a, 0x1a, 0x07, - 0x92, 0xf3, 0x90, 0x5f, 0xde, 0x68, 0x53, 0x25, 0xfb, 0x68, 0xe6, 0xd2, 0xd0, 0xe4, 0xd0, 0xd6, - 0x66, 0xb1, 0x1f, 0x65, 0xa1, 0x21, 0x98, 0x3c, 0x06, 0xd9, 0x4a, 0x59, 0xc9, 0x21, 0x72, 0x62, - 0x6b, 0xb3, 0x38, 0xda, 0x31, 0x8d, 0xa7, 0xec, 0x96, 0xe9, 0xd1, 0x56, 0xdb, 0xdb, 0xd0, 0xb2, - 0x95, 0x32, 0xb9, 0x08, 0xf9, 0x29, 0xdb, 0xa0, 0x4a, 0x1e, 0x89, 0xc8, 0xd6, 0x66, 0x71, 0xac, - 0x6e, 0x1b, 0x54, 0xa2, 0x42, 0x3c, 0x79, 0x1d, 0xf2, 0xcb, 0x66, 0x8b, 0x2a, 0xfd, 0x8f, 0x66, - 0x2e, 0x0d, 0x5f, 0x3b, 0x7b, 0x85, 0x4b, 0xe5, 0x8a, 0x2f, 0x95, 0x2b, 0xcb, 0xbe, 0xd8, 0x26, - 0xc7, 0xdf, 0xdd, 0x2c, 0xf6, 0x6d, 0x6d, 0x16, 0xf3, 0x4c, 0x92, 0x5f, 0xf9, 0x4e, 0x31, 0xa3, - 0x61, 0x49, 0xf2, 0x0a, 0x0c, 0x4f, 0x35, 0x3b, 0xae, 0x47, 0x9d, 0x05, 0xbd, 0x45, 0x95, 0x02, - 0x56, 0x78, 0x76, 0x6b, 0xb3, 0x78, 0xaa, 0xce, 0xc1, 0x35, 0x4b, 0x6f, 0xc9, 0x15, 0xcb, 0xe4, - 0xea, 0x6f, 0x67, 0xe0, 0x58, 0x95, 0xba, 0xae, 0x69, 0x5b, 0x81, 0x6c, 0x9e, 0x80, 0x21, 0x01, - 0xaa, 0x94, 0x51, 0x3e, 0x43, 0x93, 0x03, 0x5b, 0x9b, 0xc5, 0x9c, 0x6b, 0x1a, 0x5a, 0x88, 0x21, - 0x1f, 0x86, 0x81, 0x3b, 0xa6, 0xb7, 0x36, 0x3f, 0x53, 0x12, 0x72, 0x3a, 0xb5, 0xb5, 0x59, 0x24, - 0xeb, 0xa6, 0xb7, 0x56, 0x6b, 0xad, 0xea, 0x52, 0x85, 0x3e, 0x19, 0x99, 0x83, 0xf1, 0x25, 0xc7, - 0xbc, 0xa7, 0x7b, 0xf4, 0x26, 0xdd, 0x58, 0xb2, 0x9b, 0x66, 0x7d, 0x43, 0x48, 0xf1, 0xd1, 0xad, - 0xcd, 0xe2, 0xb9, 0x36, 0xc7, 0xd5, 0xee, 0xd2, 0x8d, 0x5a, 0x1b, 0xb1, 0x12, 0x93, 0x44, 0x49, - 0xf5, 0x5b, 0xfd, 0x30, 0x72, 0xcb, 0xa5, 0x4e, 0xd0, 0xee, 0x8b, 0x90, 0x67, 0xbf, 0x45, 0x93, - 0x51, 0xe6, 0x1d, 0x97, 0x3a, 0xb2, 0xcc, 0x19, 0x9e, 0x5c, 0x86, 0xfe, 0x39, 0xbb, 0x61, 0x5a, - 0xa2, 0xd9, 0xc7, 0xb7, 0x36, 0x8b, 0xc7, 0x9a, 0x0c, 0x20, 0x51, 0x72, 0x0a, 0xf2, 0x51, 0x18, - 0xa9, 0xb4, 0x98, 0x0e, 0xd9, 0x96, 0xee, 0xd9, 0x8e, 0x68, 0x2d, 0x4a, 0xd7, 0x94, 0xe0, 0x52, - 0xc1, 0x08, 0x3d, 0x79, 0x09, 0xa0, 0x74, 0xa7, 0xaa, 0xd9, 0x4d, 0x5a, 0xd2, 0x16, 0x84, 0x32, - 0x60, 0x69, 0x7d, 0xdd, 0xad, 0x39, 0x76, 0x93, 0xd6, 0x74, 0x47, 0xae, 0x56, 0xa2, 0x26, 0xd3, - 0x30, 0x56, 0xaa, 0xd7, 0xa9, 0xeb, 0x6a, 0xf4, 0xb3, 0x1d, 0xea, 0x7a, 0xae, 0xd2, 0xff, 0x68, - 0xee, 0xd2, 0xd0, 0xe4, 0xf9, 0xad, 0xcd, 0xe2, 0x19, 0x1d, 0x31, 0x35, 0x47, 0xa0, 0x24, 0x16, - 0xb1, 0x42, 0x64, 0x12, 0x46, 0x4b, 0xef, 0x74, 0x1c, 0x5a, 0x31, 0xa8, 0xe5, 0x99, 0xde, 0x86, - 0xd0, 0x90, 0x73, 0x5b, 0x9b, 0x45, 0x45, 0x67, 0x88, 0x9a, 0x29, 0x30, 0x12, 0x93, 0x68, 0x11, - 0xb2, 0x08, 0x13, 0x37, 0xa6, 0x96, 0xaa, 0xd4, 0xb9, 0x67, 0xd6, 0x69, 0xa9, 0x5e, 0xb7, 0x3b, - 0x96, 0xa7, 0x0c, 0x20, 0x9f, 0xc7, 0xb6, 0x36, 0x8b, 0xe7, 0x1b, 0xf5, 0x76, 0xcd, 0xe5, 0xd8, - 0x9a, 0xce, 0xd1, 0x12, 0xb3, 0x64, 0x59, 0xf2, 0x71, 0x18, 0x5d, 0x76, 0x98, 0x16, 0x1a, 0x65, - 0xca, 0xe0, 0xca, 0x20, 0xea, 0xff, 0xa9, 0x2b, 0x62, 0x02, 0xe2, 0x50, 0xbf, 0x67, 0x79, 0x63, - 0x3d, 0x5e, 0xa0, 0x66, 0x20, 0x4e, 0x6e, 0x6c, 0x84, 0x15, 0xa1, 0xa0, 0xb0, 0x8f, 0x37, 0x1d, - 0x6a, 0x24, 0xb4, 0x6d, 0x08, 0xdb, 0x7c, 0x79, 0x6b, 0xb3, 0xf8, 0x84, 0x23, 0x68, 0x6a, 0x3d, - 0xd5, 0xae, 0x2b, 0x2b, 0x32, 0x0d, 0x83, 0x4c, 0x9b, 0x6e, 0x9a, 0x96, 0xa1, 0xc0, 0xa3, 0x99, - 0x4b, 0x63, 0xd7, 0xc6, 0xfd, 0xd6, 0xfb, 0xf0, 0xc9, 0xd3, 0x5b, 0x9b, 0xc5, 0xe3, 0x4c, 0x07, - 0x6b, 0x77, 0x4d, 0x4b, 0x9e, 0x22, 0x82, 0xa2, 0xea, 0x5f, 0xe5, 0x61, 0x8c, 0x09, 0x47, 0xd2, - 0xe3, 0x12, 0x1b, 0x92, 0x0c, 0xc2, 0x46, 0xa8, 0xdb, 0xd6, 0xeb, 0x54, 0xa8, 0x34, 0xb2, 0xb3, - 0x7c, 0xa0, 0xc4, 0x2e, 0x4e, 0x4f, 0x2e, 0xc3, 0x20, 0x07, 0x55, 0xca, 0x42, 0xcb, 0x47, 0xb7, - 0x36, 0x8b, 0x43, 0x2e, 0xc2, 0x6a, 0xa6, 0xa1, 0x05, 0x68, 0xa6, 0x66, 0xfc, 0xef, 0x59, 0xdb, - 0xf5, 0x18, 0x73, 0xa1, 0xe4, 0xa8, 0x66, 0xa2, 0xc0, 0x9a, 0x40, 0xc9, 0x6a, 0x16, 0x2d, 0x44, - 0x5e, 0x04, 0xe0, 0x90, 0x92, 0x61, 0x38, 0x42, 0xd3, 0xcf, 0x6c, 0x6d, 0x16, 0x4f, 0x0a, 0x16, - 0xba, 0x61, 0xc8, 0xc3, 0x44, 0x22, 0x26, 0x2d, 0x18, 0xe1, 0xbf, 0xe6, 0xf4, 0x15, 0xda, 0xe4, - 0x6a, 0x3e, 0x7c, 0xed, 0x92, 0x2f, 0xcd, 0xa8, 0x74, 0xae, 0xc8, 0xa4, 0xd3, 0x96, 0xe7, 0x6c, - 0x4c, 0x16, 0xc5, 0xcc, 0x78, 0x5a, 0x54, 0xd5, 0x44, 0x9c, 0x3c, 0x26, 0xe5, 0x32, 0x6c, 0xc2, - 0x9c, 0xb1, 0x9d, 0x75, 0xdd, 0x31, 0xa8, 0x31, 0xb9, 0x21, 0x4f, 0x98, 0xab, 0x3e, 0xb8, 0xb6, - 0x22, 0xeb, 0x80, 0x4c, 0x4e, 0xa6, 0x60, 0x94, 0x73, 0xab, 0x76, 0x56, 0xb0, 0xef, 0x07, 0x12, - 0xd2, 0x72, 0x3b, 0x2b, 0xf1, 0xfe, 0x8e, 0x96, 0x61, 0x63, 0x92, 0x03, 0x6e, 0x53, 0x87, 0xcd, - 0xa6, 0xa8, 0xfe, 0x62, 0x4c, 0x0a, 0x26, 0xf7, 0x38, 0x26, 0xc9, 0x43, 0x14, 0x39, 0xfb, 0x1a, - 0x4c, 0x24, 0x44, 0x41, 0xc6, 0x21, 0x77, 0x97, 0x6e, 0x70, 0x75, 0xd1, 0xd8, 0x9f, 0xe4, 0x04, - 0xf4, 0xdf, 0xd3, 0x9b, 0x1d, 0xb1, 0x96, 0x69, 0xfc, 0xc7, 0x4b, 0xd9, 0x8f, 0x64, 0xd8, 0xd4, - 0x4f, 0xa6, 0x6c, 0xcb, 0xa2, 0x75, 0x4f, 0x9e, 0xfd, 0x9f, 0x87, 0xa1, 0x39, 0xbb, 0xae, 0x37, - 0xb1, 0x1f, 0xb9, 0xde, 0x29, 0x5b, 0x9b, 0xc5, 0x13, 0xac, 0x03, 0xaf, 0x34, 0x19, 0x46, 0x6a, - 0x53, 0x48, 0xca, 0x14, 0x40, 0xa3, 0x2d, 0xdb, 0xa3, 0x58, 0x30, 0x1b, 0x2a, 0x00, 0x16, 0x74, - 0x10, 0x25, 0x2b, 0x40, 0x48, 0x4c, 0xae, 0xc2, 0xe0, 0x12, 0x5b, 0xf0, 0xea, 0x76, 0x53, 0x28, - 0x1f, 0xce, 0xc9, 0xb8, 0x08, 0xca, 0x83, 0xc6, 0x27, 0x52, 0x67, 0x61, 0x6c, 0xaa, 0x69, 0x52, - 0xcb, 0x93, 0x5b, 0xcd, 0x86, 0x54, 0xa9, 0x41, 0x2d, 0x4f, 0x6e, 0x35, 0x0e, 0x3e, 0x9d, 0x41, - 0xe5, 0x56, 0x07, 0xa4, 0xea, 0xff, 0x99, 0x83, 0x33, 0x37, 0x3b, 0x2b, 0xd4, 0xb1, 0xa8, 0x47, - 0x5d, 0xb1, 0x32, 0x06, 0x5c, 0x17, 0x60, 0x22, 0x81, 0x14, 0xdc, 0x71, 0xc5, 0xba, 0x1b, 0x20, - 0x6b, 0x62, 0xb1, 0x95, 0xa7, 0xbd, 0x44, 0x51, 0x32, 0x0b, 0xc7, 0x42, 0x20, 0x6b, 0x84, 0xab, - 0x64, 0x71, 0x4e, 0xbf, 0xb0, 0xb5, 0x59, 0x3c, 0x2b, 0x71, 0x63, 0xcd, 0x96, 0x35, 0x38, 0x5e, - 0x8c, 0xdc, 0x84, 0xf1, 0x10, 0x74, 0xc3, 0xb1, 0x3b, 0x6d, 0x57, 0xc9, 0x21, 0xab, 0xe2, 0xd6, - 0x66, 0xf1, 0x11, 0x89, 0x55, 0x03, 0x91, 0xf2, 0x4a, 0x1a, 0x2f, 0x48, 0x7e, 0x28, 0x23, 0x73, - 0x13, 0xa3, 0x30, 0x8f, 0xa3, 0xf0, 0x05, 0x7f, 0x14, 0x76, 0x15, 0xd2, 0x95, 0x78, 0x49, 0x31, - 0x28, 0x63, 0xcd, 0x48, 0x0c, 0xca, 0x44, 0x8d, 0x67, 0xa7, 0xe0, 0x64, 0x2a, 0xaf, 0x5d, 0x69, - 0xf5, 0x5f, 0xe4, 0x64, 0x2e, 0x4b, 0xb6, 0x11, 0x74, 0xe6, 0xa2, 0xdc, 0x99, 0x4b, 0xb6, 0x81, - 0xe6, 0x52, 0x26, 0x5c, 0xc4, 0xa4, 0xc6, 0xb6, 0x6d, 0x23, 0x6e, 0x35, 0x25, 0xcb, 0x92, 0x4f, - 0xc3, 0xa9, 0x04, 0x90, 0x4f, 0xd7, 0x5c, 0xfb, 0x2f, 0x6e, 0x6d, 0x16, 0xd5, 0x14, 0xae, 0xf1, - 0xd9, 0xbb, 0x0b, 0x17, 0xa2, 0xc3, 0x69, 0x49, 0xea, 0xb6, 0xe5, 0xe9, 0xa6, 0x25, 0xac, 0x3c, - 0x3e, 0x4a, 0x3e, 0xb8, 0xb5, 0x59, 0x7c, 0x5c, 0xd6, 0x41, 0x9f, 0x26, 0xde, 0xf8, 0x6e, 0x7c, - 0x88, 0x01, 0x4a, 0x0a, 0xaa, 0xd2, 0xd2, 0x1b, 0xbe, 0xe9, 0x7a, 0x69, 0x6b, 0xb3, 0xf8, 0x81, - 0xd4, 0x3a, 0x4c, 0x46, 0x25, 0x2f, 0x95, 0xdd, 0x38, 0x11, 0x0d, 0x48, 0x88, 0x5b, 0xb0, 0x0d, - 0x8a, 0xdf, 0xd0, 0x8f, 0xfc, 0xd5, 0xad, 0xcd, 0xe2, 0x05, 0x89, 0xbf, 0x65, 0x1b, 0x34, 0xde, - 0xfc, 0x94, 0xd2, 0xea, 0x6f, 0xe7, 0xe0, 0x42, 0xb5, 0x34, 0x3f, 0x57, 0x31, 0x7c, 0xdb, 0x62, - 0xc9, 0xb1, 0xef, 0x99, 0x86, 0x34, 0x7a, 0x57, 0xe0, 0x74, 0x0c, 0x35, 0x8d, 0xe6, 0x4c, 0x60, - 0xd5, 0xe2, 0xb7, 0xf9, 0x76, 0x4b, 0x5b, 0xd0, 0xd4, 0xb8, 0xcd, 0x53, 0x8b, 0x98, 0xf4, 0xdd, - 0x18, 0xb1, 0x3e, 0x8a, 0xa1, 0xaa, 0x6b, 0xb6, 0xe3, 0xd5, 0x3b, 0x9e, 0x50, 0x02, 0xec, 0xa3, - 0x44, 0x1d, 0xae, 0x20, 0xea, 0x51, 0x85, 0xcf, 0x87, 0x7c, 0x21, 0x03, 0xe3, 0x25, 0xcf, 0x73, - 0xcc, 0x95, 0x8e, 0x47, 0xe7, 0xf5, 0x76, 0xdb, 0xb4, 0x1a, 0x38, 0xd6, 0x87, 0xaf, 0xbd, 0x12, - 0xac, 0x91, 0x3d, 0x25, 0x71, 0x25, 0x5e, 0x5c, 0x1a, 0xa2, 0xba, 0x8f, 0xaa, 0xb5, 0x38, 0x4e, - 0x1e, 0xa2, 0xf1, 0x72, 0x6c, 0x88, 0xa6, 0xf2, 0xda, 0xd5, 0x10, 0xfd, 0x6a, 0x0e, 0xce, 0x2d, - 0xde, 0xf5, 0x74, 0x8d, 0xba, 0x76, 0xc7, 0xa9, 0x53, 0xf7, 0x56, 0xdb, 0xd0, 0x3d, 0x1a, 0x8e, - 0xd4, 0x22, 0xf4, 0x97, 0x0c, 0x83, 0x1a, 0xc8, 0xae, 0x9f, 0xef, 0xbf, 0x74, 0x06, 0xd0, 0x38, - 0x9c, 0x3c, 0x01, 0x03, 0xa2, 0x0c, 0x72, 0xef, 0x9f, 0x1c, 0xde, 0xda, 0x2c, 0x0e, 0x74, 0x38, - 0x48, 0xf3, 0x71, 0x8c, 0xac, 0x4c, 0x9b, 0x94, 0x91, 0xe5, 0x42, 0x32, 0x83, 0x83, 0x34, 0x1f, - 0x47, 0xde, 0x84, 0x31, 0x64, 0x1b, 0xb4, 0x47, 0xcc, 0x7d, 0x27, 0x7c, 0xe9, 0xca, 0x8d, 0xe5, - 0x4b, 0x13, 0xb6, 0xa6, 0xe6, 0xf8, 0x05, 0xb4, 0x18, 0x03, 0x72, 0x07, 0xc6, 0x45, 0x23, 0x42, - 0xa6, 0xfd, 0x3d, 0x98, 0x9e, 0xdc, 0xda, 0x2c, 0x4e, 0x88, 0xf6, 0x4b, 0x6c, 0x13, 0x4c, 0x18, - 0x63, 0xd1, 0xec, 0x90, 0x71, 0x61, 0x3b, 0xc6, 0xe2, 0x8b, 0x65, 0xc6, 0x71, 0x26, 0xea, 0x5b, - 0x30, 0x22, 0x17, 0x24, 0xa7, 0x70, 0x8f, 0xcb, 0xc7, 0x09, 0xee, 0x8e, 0x4d, 0x03, 0x37, 0xb6, - 0xcf, 0xc0, 0x70, 0x99, 0xba, 0x75, 0xc7, 0x6c, 0x33, 0xab, 0x41, 0x28, 0xf9, 0xb1, 0xad, 0xcd, - 0xe2, 0xb0, 0x11, 0x82, 0x35, 0x99, 0x46, 0xfd, 0x17, 0x19, 0x38, 0xc5, 0x78, 0x97, 0x5c, 0xd7, - 0x6c, 0x58, 0x2d, 0x79, 0xd9, 0x7e, 0x0a, 0x0a, 0x55, 0xac, 0x4f, 0xd4, 0x74, 0x62, 0x6b, 0xb3, - 0x38, 0xce, 0x5b, 0x20, 0xe9, 0xa1, 0xa0, 0x09, 0x36, 0x78, 0xd9, 0x6d, 0x36, 0x78, 0xcc, 0xa4, - 0xf5, 0x74, 0xc7, 0x33, 0xad, 0x46, 0xd5, 0xd3, 0xbd, 0x8e, 0x1b, 0x31, 0x69, 0x05, 0xa6, 0xe6, - 0x22, 0x2a, 0x62, 0xd2, 0x46, 0x0a, 0x91, 0xd7, 0x60, 0x64, 0xda, 0x32, 0x42, 0x26, 0x7c, 0x42, - 0x7c, 0x84, 0x59, 0x9a, 0x14, 0xe1, 0x49, 0x16, 0x91, 0x02, 0xea, 0x7f, 0x9d, 0x01, 0x85, 0xef, - 0xc6, 0xe6, 0x4c, 0xd7, 0x9b, 0xa7, 0xad, 0x15, 0x69, 0x76, 0x9a, 0xf1, 0xb7, 0x77, 0x0c, 0x27, - 0xad, 0x45, 0x68, 0x0a, 0x88, 0xed, 0x5d, 0xd3, 0x74, 0xbd, 0xf8, 0x64, 0x18, 0x2b, 0x45, 0x2a, - 0x30, 0xc0, 0x39, 0x73, 0x5b, 0x62, 0xf8, 0x9a, 0xe2, 0x2b, 0x42, 0xbc, 0x6a, 0xae, 0x0c, 0x2d, - 0x4e, 0x2c, 0xef, 0xcf, 0x45, 0x79, 0xf5, 0xbf, 0xc9, 0xc2, 0x78, 0xbc, 0x10, 0xb9, 0x03, 0x83, - 0x6f, 0xd8, 0xa6, 0x45, 0x8d, 0x45, 0x0b, 0x5b, 0xd8, 0xfb, 0x94, 0xc2, 0xb7, 0xc5, 0x8f, 0xbf, - 0x8d, 0x65, 0x6a, 0xb2, 0x05, 0x8b, 0x87, 0x16, 0x01, 0x33, 0xf2, 0x71, 0x18, 0x62, 0x36, 0xe0, - 0x3d, 0xe4, 0x9c, 0xdd, 0x96, 0xf3, 0xa3, 0x82, 0xf3, 0x09, 0x87, 0x17, 0x4a, 0xb2, 0x0e, 0xd9, - 0x31, 0xbd, 0xd2, 0xa8, 0xee, 0xda, 0x96, 0xe8, 0x79, 0xd4, 0x2b, 0x07, 0x21, 0xb2, 0x5e, 0x71, - 0x1a, 0x66, 0xba, 0xf2, 0x8f, 0xc5, 0x6e, 0x90, 0xf6, 0x2e, 0x5c, 0x56, 0xf1, 0x1e, 0x90, 0x88, - 0xd5, 0x1f, 0xc9, 0xc2, 0xd3, 0xa1, 0xc8, 0x34, 0x7a, 0xcf, 0xa4, 0xeb, 0x42, 0x9c, 0x6b, 0x66, - 0x5b, 0x6c, 0x1e, 0x99, 0xca, 0xbb, 0x53, 0x6b, 0xba, 0xd5, 0xa0, 0x06, 0xb9, 0x0c, 0xfd, 0x6c, - 0x87, 0xef, 0x2a, 0x19, 0x34, 0xd7, 0x70, 0x3a, 0x71, 0x18, 0x40, 0x3e, 0x7d, 0x40, 0x0a, 0x62, - 0x43, 0x61, 0xd9, 0xd1, 0x4d, 0xcf, 0xef, 0xd9, 0x52, 0xb2, 0x67, 0x77, 0x50, 0xe3, 0x15, 0xce, - 0x83, 0xcf, 0xf9, 0x28, 0x08, 0x0f, 0x01, 0xb2, 0x20, 0x38, 0xc9, 0xd9, 0x17, 0x61, 0x58, 0x22, - 0xde, 0xd5, 0xa4, 0xfe, 0x8d, 0xbc, 0xac, 0xeb, 0x7e, 0xb3, 0x84, 0xae, 0x5f, 0x65, 0x3a, 0xea, - 0xba, 0xcc, 0xaa, 0xe0, 0x4a, 0x2e, 0x34, 0x11, 0x41, 0x51, 0x4d, 0x44, 0x10, 0x79, 0x16, 0x06, - 0x39, 0x8b, 0x60, 0xff, 0x8a, 0x7b, 0x5f, 0x07, 0x61, 0xd1, 0xa5, 0x39, 0x20, 0x24, 0xbf, 0x92, - 0x81, 0xf3, 0x3d, 0x25, 0x81, 0xca, 0x30, 0x7c, 0xed, 0xb9, 0x07, 0x12, 0xe3, 0xe4, 0xd3, 0x5b, - 0x9b, 0xc5, 0xcb, 0xad, 0x80, 0xa4, 0xe6, 0x48, 0x34, 0xb5, 0x3a, 0x27, 0x92, 0xda, 0xd5, 0xbb, - 0x29, 0xcc, 0x78, 0xe4, 0x95, 0xce, 0xe0, 0x19, 0x8e, 0x55, 0xdf, 0xf0, 0x1b, 0x99, 0x0f, 0x8d, - 0x47, 0xf1, 0xbd, 0xab, 0x3e, 0x49, 0x4a, 0x35, 0x5d, 0xb8, 0x90, 0x3a, 0x9c, 0xe6, 0x98, 0xb2, - 0xbe, 0xb1, 0xb8, 0x3a, 0x6f, 0x5b, 0xde, 0x9a, 0x5f, 0x41, 0xbf, 0x7c, 0x08, 0x82, 0x15, 0x18, - 0xfa, 0x46, 0xcd, 0x5e, 0xad, 0xb5, 0x18, 0x55, 0x4a, 0x1d, 0xdd, 0x38, 0xb1, 0x89, 0x56, 0x8c, - 0x39, 0x7f, 0x0a, 0x2a, 0x84, 0x47, 0x54, 0xfe, 0x38, 0x4d, 0x4e, 0x38, 0xb1, 0x42, 0x6a, 0x05, - 0x46, 0xe6, 0xec, 0xfa, 0xdd, 0x40, 0x5d, 0x5e, 0x84, 0xc2, 0xb2, 0xee, 0x34, 0xa8, 0x87, 0xb2, - 0x18, 0xbe, 0x36, 0x71, 0x85, 0x1f, 0xfb, 0x32, 0x22, 0x8e, 0x98, 0x1c, 0x13, 0xb3, 0x41, 0xc1, - 0xc3, 0xdf, 0x9a, 0x28, 0xa0, 0x7e, 0xa7, 0x1f, 0x46, 0xc4, 0x11, 0x25, 0xce, 0xe6, 0xe4, 0xa5, - 0xf0, 0xd0, 0x57, 0x4c, 0x5f, 0xc1, 0x31, 0x4d, 0x70, 0xbc, 0x34, 0xc2, 0x98, 0xfd, 0xe1, 0x66, - 0x31, 0xb3, 0xb5, 0x59, 0xec, 0xd3, 0x06, 0xa5, 0x4d, 0x65, 0xb8, 0xde, 0x48, 0x0b, 0xac, 0x7c, - 0xe8, 0x18, 0x2b, 0xcb, 0xd7, 0x9f, 0xd7, 0x60, 0x40, 0xb4, 0x41, 0x68, 0xdc, 0xe9, 0xf0, 0x2c, - 0x23, 0x72, 0xd4, 0x1a, 0x2b, 0xed, 0x97, 0x22, 0xaf, 0x40, 0x81, 0xef, 0xed, 0x85, 0x00, 0x4e, - 0xa5, 0x9f, 0x85, 0xc4, 0x8a, 0x8b, 0x32, 0x64, 0x16, 0x20, 0xdc, 0xd7, 0x07, 0x27, 0xcb, 0x82, - 0x43, 0x72, 0xc7, 0x1f, 0xe3, 0x22, 0x95, 0x25, 0xcf, 0xc3, 0xc8, 0x32, 0x75, 0x5a, 0xa6, 0xa5, - 0x37, 0xab, 0xe6, 0x3b, 0xfe, 0xe1, 0x32, 0x2e, 0xbc, 0xae, 0xf9, 0x8e, 0x3c, 0x72, 0x23, 0x74, - 0xe4, 0x53, 0x69, 0xfb, 0xe6, 0x01, 0x6c, 0xc8, 0x63, 0xdb, 0x6e, 0x28, 0x63, 0xed, 0x49, 0xd9, - 0x46, 0xbf, 0x09, 0xa3, 0x91, 0x2d, 0x93, 0x38, 0x3d, 0x3c, 0x9f, 0x64, 0x2d, 0xed, 0xff, 0x62, - 0x6c, 0xa3, 0x1c, 0x98, 0x26, 0x57, 0x2c, 0xd3, 0x33, 0xf5, 0xe6, 0x94, 0xdd, 0x6a, 0xe9, 0x96, - 0xa1, 0x0c, 0x85, 0x9a, 0x6c, 0x72, 0x4c, 0xad, 0xce, 0x51, 0xb2, 0x26, 0x47, 0x0b, 0xb1, 0x6d, - 0xb9, 0xe8, 0x43, 0x8d, 0xd6, 0x6d, 0x87, 0xd9, 0x02, 0x78, 0x38, 0x28, 0xb6, 0xe5, 0x2e, 0xc7, - 0xd5, 0x1c, 0x1f, 0x29, 0x1b, 0xdb, 0xf1, 0x82, 0x6f, 0xe4, 0x07, 0x87, 0xc7, 0x47, 0xe2, 0xe7, - 0xb9, 0xea, 0x7f, 0x95, 0x83, 0x61, 0x41, 0xca, 0x96, 0xd2, 0x23, 0x05, 0xdf, 0x8b, 0x82, 0xa7, - 0x2a, 0x6a, 0x61, 0xbf, 0x14, 0x55, 0xfd, 0x62, 0x36, 0x98, 0x8d, 0x96, 0x1c, 0xd3, 0xda, 0xdb, - 0x6c, 0x74, 0x11, 0x60, 0x6a, 0xad, 0x63, 0xdd, 0xe5, 0xf7, 0x56, 0xd9, 0xf0, 0xde, 0xaa, 0x6e, - 0x6a, 0x12, 0x86, 0x9c, 0x87, 0x7c, 0x99, 0xf1, 0x67, 0x3d, 0x33, 0x32, 0x39, 0xf4, 0x2e, 0xe7, - 0x94, 0x79, 0x5a, 0x43, 0x30, 0xdb, 0x5c, 0x4d, 0x6e, 0x78, 0x94, 0x9b, 0xb3, 0x39, 0xbe, 0xb9, - 0x5a, 0x61, 0x00, 0x8d, 0xc3, 0xc9, 0x75, 0x98, 0x28, 0xd3, 0xa6, 0xbe, 0x31, 0x6f, 0x36, 0x9b, - 0xa6, 0x4b, 0xeb, 0xb6, 0x65, 0xb8, 0x28, 0x64, 0x51, 0x5d, 0xcb, 0xd5, 0x92, 0x04, 0x44, 0x85, - 0xc2, 0xe2, 0xea, 0xaa, 0x4b, 0x3d, 0x14, 0x5f, 0x6e, 0x12, 0xd8, 0xe4, 0x6c, 0x23, 0x44, 0x13, - 0x18, 0xf5, 0xd7, 0x33, 0x6c, 0xf7, 0xe2, 0xde, 0xf5, 0xec, 0x76, 0xa0, 0xe5, 0x7b, 0x12, 0xc9, - 0xe5, 0xd0, 0xae, 0xc8, 0xe2, 0xd7, 0x1e, 0x13, 0x5f, 0x3b, 0x20, 0x6c, 0x8b, 0xd0, 0xa2, 0x48, - 0xfd, 0xaa, 0xdc, 0x36, 0x5f, 0xa5, 0xfe, 0x65, 0x16, 0x4e, 0x8b, 0x16, 0x4f, 0x35, 0xcd, 0xf6, - 0x8a, 0xad, 0x3b, 0x86, 0x46, 0xeb, 0xd4, 0xbc, 0x47, 0x0f, 0xe7, 0xc0, 0x8b, 0x0e, 0x9d, 0xfc, - 0x1e, 0x86, 0xce, 0x35, 0xdc, 0x08, 0x32, 0xc9, 0xe0, 0x81, 0x2f, 0x37, 0x2a, 0xc6, 0xb7, 0x36, - 0x8b, 0x23, 0x06, 0x07, 0xe3, 0x91, 0xbf, 0x26, 0x13, 0x31, 0x25, 0x99, 0xa3, 0x56, 0xc3, 0x5b, - 0x43, 0x25, 0xe9, 0xe7, 0x4a, 0xd2, 0x44, 0x88, 0x26, 0x30, 0xea, 0x3f, 0xce, 0xc2, 0x89, 0xb8, - 0xc8, 0xab, 0xd4, 0x32, 0x8e, 0xe4, 0xfd, 0xde, 0xc8, 0xfb, 0x7b, 0x39, 0x78, 0x44, 0x94, 0xa9, - 0xae, 0xe9, 0x0e, 0x35, 0xca, 0xa6, 0x43, 0xeb, 0x9e, 0xed, 0x6c, 0x1c, 0x62, 0x03, 0x6a, 0xff, - 0xc4, 0x7e, 0x1d, 0x0a, 0x62, 0xfb, 0xcf, 0xd7, 0x99, 0xb1, 0xa0, 0x25, 0x08, 0x4d, 0xac, 0x50, - 0xfc, 0xe8, 0x20, 0xd6, 0x59, 0x85, 0x9d, 0x74, 0xd6, 0x47, 0x60, 0x34, 0x10, 0x3d, 0x6e, 0x44, - 0x07, 0x42, 0x6b, 0xcb, 0xf0, 0x11, 0xb8, 0x17, 0xd5, 0xa2, 0x84, 0x58, 0x9b, 0x0f, 0xa8, 0x94, - 0xd1, 0x1a, 0x1a, 0x15, 0xb5, 0x05, 0xe5, 0x4c, 0x43, 0x93, 0x89, 0xd4, 0xcd, 0x3c, 0x9c, 0x4d, - 0xef, 0x76, 0x8d, 0xea, 0xc6, 0x51, 0xaf, 0x7f, 0x5f, 0xf6, 0x3a, 0x79, 0x0c, 0xf2, 0x4b, 0xba, - 0xb7, 0x26, 0xee, 0xc1, 0xf1, 0x4e, 0x78, 0xd5, 0x6c, 0xd2, 0x5a, 0x5b, 0xf7, 0xd6, 0x34, 0x44, - 0x49, 0x73, 0x06, 0x20, 0xc7, 0x94, 0x39, 0x43, 0x5a, 0xec, 0x87, 0x1f, 0xcd, 0x5c, 0xca, 0xa7, - 0x2e, 0xf6, 0xdf, 0xc9, 0x77, 0x9b, 0x57, 0xee, 0x38, 0xa6, 0x47, 0x8f, 0x34, 0xec, 0x48, 0xc3, - 0xf6, 0xa8, 0x61, 0x7f, 0x9c, 0x85, 0xd1, 0x60, 0xd3, 0xf4, 0x36, 0xad, 0x1f, 0xcc, 0x5a, 0x15, - 0x6e, 0x65, 0x72, 0x7b, 0xde, 0xca, 0xec, 0x45, 0xa1, 0xd4, 0xe0, 0xc8, 0x93, 0x9b, 0x06, 0x28, - 0x31, 0x7e, 0xe4, 0x19, 0x1c, 0x74, 0x3e, 0x06, 0x03, 0xf3, 0xfa, 0x7d, 0xb3, 0xd5, 0x69, 0x09, - 0x2b, 0x1d, 0xfd, 0xba, 0x5a, 0xfa, 0x7d, 0xcd, 0x87, 0xab, 0xff, 0x77, 0x06, 0xc6, 0x84, 0x50, - 0x05, 0xf3, 0x3d, 0x49, 0x35, 0x94, 0x4e, 0x76, 0xcf, 0xd2, 0xc9, 0x3d, 0xb8, 0x74, 0xd4, 0x9f, - 0xcb, 0x81, 0x32, 0x63, 0x36, 0xe9, 0xb2, 0xa3, 0x5b, 0xee, 0x2a, 0x75, 0xc4, 0x76, 0x7a, 0x9a, - 0xb1, 0xda, 0xd3, 0x07, 0x4a, 0x53, 0x4a, 0xf6, 0x81, 0xa6, 0x94, 0x0f, 0xc1, 0x90, 0x68, 0x4c, - 0xe0, 0x53, 0x88, 0xa3, 0xc6, 0xf1, 0x81, 0x5a, 0x88, 0x67, 0xc4, 0xa5, 0x76, 0xdb, 0xb1, 0xef, - 0x51, 0x87, 0xdf, 0x52, 0x09, 0x62, 0xdd, 0x07, 0x6a, 0x21, 0x5e, 0xe2, 0x4c, 0x7d, 0x7b, 0x51, - 0xe6, 0x4c, 0x1d, 0x2d, 0xc4, 0x93, 0x4b, 0x30, 0x38, 0x67, 0xd7, 0x75, 0x14, 0x34, 0x9f, 0x56, - 0x46, 0xb6, 0x36, 0x8b, 0x83, 0x4d, 0x01, 0xd3, 0x02, 0x2c, 0xa3, 0x2c, 0xdb, 0xeb, 0x56, 0xd3, - 0xd6, 0xb9, 0xf3, 0xcb, 0x20, 0xa7, 0x34, 0x04, 0x4c, 0x0b, 0xb0, 0x8c, 0x92, 0xc9, 0x1c, 0x9d, - 0x8a, 0x06, 0x43, 0x9e, 0xab, 0x02, 0xa6, 0x05, 0x58, 0xf5, 0xd7, 0xf3, 0x4c, 0x7b, 0x5d, 0xf3, - 0x9d, 0x87, 0x7e, 0x5d, 0x08, 0x07, 0x4c, 0xff, 0x03, 0x0c, 0x98, 0x87, 0xe6, 0xc0, 0x4e, 0xfd, - 0xab, 0x01, 0x00, 0x21, 0xfd, 0xe9, 0xa3, 0xcd, 0xe1, 0xde, 0xb4, 0xa6, 0x0c, 0x13, 0xd3, 0xd6, - 0x9a, 0x6e, 0xd5, 0xa9, 0x11, 0x1e, 0x5b, 0x16, 0x70, 0x68, 0xa3, 0x4f, 0x2f, 0x15, 0xc8, 0xf0, - 0xdc, 0x52, 0x4b, 0x16, 0x20, 0xcf, 0xc0, 0x70, 0xc5, 0xf2, 0xa8, 0xa3, 0xd7, 0x3d, 0xf3, 0x1e, - 0x15, 0x53, 0x03, 0xde, 0x0c, 0x9b, 0x21, 0x58, 0x93, 0x69, 0xc8, 0x75, 0x18, 0x59, 0xd2, 0x1d, - 0xcf, 0xac, 0x9b, 0x6d, 0xdd, 0xf2, 0x5c, 0x65, 0x10, 0x67, 0x34, 0xb4, 0x30, 0xda, 0x12, 0x5c, - 0x8b, 0x50, 0x91, 0x4f, 0xc1, 0x10, 0x6e, 0x4d, 0xd1, 0x71, 0x7a, 0x68, 0xdb, 0x8b, 0xc3, 0xc7, - 0x43, 0xf7, 0x40, 0x7e, 0xfa, 0x8a, 0x37, 0xc0, 0xf1, 0xbb, 0xc3, 0x80, 0x23, 0xf9, 0x18, 0x0c, - 0x4c, 0x5b, 0x06, 0x32, 0x87, 0x6d, 0x99, 0xab, 0x82, 0xf9, 0xa9, 0x90, 0xb9, 0xdd, 0x8e, 0xf1, - 0xf6, 0xd9, 0xa5, 0x8f, 0xb2, 0xe1, 0xf7, 0x6e, 0x94, 0x8d, 0xbc, 0x07, 0xc7, 0xe2, 0xa3, 0xfb, - 0x75, 0x2c, 0x3e, 0xf6, 0x80, 0xc7, 0xe2, 0xea, 0x3b, 0x30, 0x3c, 0xb9, 0x34, 0x13, 0x8c, 0xde, - 0x33, 0x90, 0x5b, 0x12, 0x9e, 0x0a, 0x79, 0x6e, 0xcf, 0xb4, 0x4d, 0x43, 0x63, 0x30, 0x72, 0x19, - 0x06, 0xa7, 0xd0, 0xfd, 0x4d, 0xdc, 0x22, 0xe6, 0xf9, 0xfa, 0x57, 0x47, 0x18, 0x7a, 0xc1, 0xfa, - 0x68, 0xf2, 0x04, 0x0c, 0x2c, 0x39, 0x76, 0xc3, 0xd1, 0x5b, 0x62, 0x0d, 0x46, 0x57, 0x91, 0x36, - 0x07, 0x69, 0x3e, 0x4e, 0xfd, 0x89, 0x8c, 0x6f, 0xb6, 0xb3, 0x12, 0xd5, 0x0e, 0x1e, 0xcd, 0x63, - 0xdd, 0x83, 0xbc, 0x84, 0xcb, 0x41, 0x9a, 0x8f, 0x23, 0x97, 0xa1, 0x7f, 0xda, 0x71, 0x6c, 0x47, - 0x76, 0x36, 0xa7, 0x0c, 0x20, 0x5f, 0xf7, 0x22, 0x05, 0x79, 0x01, 0x86, 0xf9, 0x9c, 0xc3, 0x4f, - 0x34, 0x73, 0xbd, 0x6e, 0x4a, 0x65, 0x4a, 0xf5, 0x5b, 0x39, 0xc9, 0x66, 0xe3, 0x12, 0x7f, 0x08, - 0x6f, 0x05, 0x9e, 0x85, 0xdc, 0xe4, 0xd2, 0x8c, 0x98, 0x00, 0x8f, 0xfb, 0x45, 0x25, 0x55, 0x89, - 0x95, 0x63, 0xd4, 0xe4, 0x1c, 0xe4, 0x97, 0x98, 0xfa, 0x14, 0x50, 0x3d, 0x06, 0xb7, 0x36, 0x8b, - 0xf9, 0x36, 0xd3, 0x1f, 0x84, 0x22, 0x96, 0x6d, 0x66, 0xf8, 0x8e, 0x89, 0x63, 0xc3, 0x7d, 0xcc, - 0x39, 0xc8, 0x97, 0x9c, 0xc6, 0x3d, 0x31, 0x6b, 0x21, 0x56, 0x77, 0x1a, 0xf7, 0x34, 0x84, 0x92, - 0xab, 0x00, 0x1a, 0xf5, 0x3a, 0x8e, 0x85, 0xef, 0x40, 0x86, 0xf0, 0xfc, 0x0d, 0x67, 0x43, 0x07, - 0xa1, 0xb5, 0xba, 0x6d, 0x50, 0x4d, 0x22, 0x51, 0xff, 0xcb, 0xf0, 0x62, 0xa7, 0x6c, 0xba, 0x77, - 0x8f, 0xba, 0x70, 0x17, 0x5d, 0xa8, 0x8b, 0x23, 0xce, 0x64, 0x27, 0x15, 0xa1, 0x7f, 0xa6, 0xa9, - 0x37, 0x5c, 0xec, 0x43, 0xe1, 0x4b, 0xb6, 0xca, 0x00, 0x1a, 0x87, 0xc7, 0xfa, 0x69, 0x70, 0xfb, - 0x7e, 0xfa, 0x5a, 0x7f, 0x30, 0xda, 0x16, 0xa8, 0xb7, 0x6e, 0x3b, 0x47, 0x5d, 0xb5, 0xd3, 0xae, - 0xba, 0x08, 0x03, 0x55, 0xa7, 0x2e, 0x1d, 0x5d, 0xe0, 0x7e, 0xc0, 0x75, 0xea, 0xfc, 0xd8, 0xc2, - 0x47, 0x32, 0xba, 0xb2, 0xeb, 0x21, 0xdd, 0x40, 0x48, 0x67, 0xb8, 0x9e, 0xa0, 0x13, 0x48, 0x41, - 0xb7, 0x64, 0x3b, 0x9e, 0xe8, 0xb8, 0x80, 0xae, 0x6d, 0x3b, 0x9e, 0xe6, 0x23, 0xc9, 0x87, 0x00, - 0x96, 0xa7, 0x96, 0x7c, 0x67, 0xfb, 0xa1, 0xd0, 0x17, 0x50, 0x78, 0xd9, 0x6b, 0x12, 0x9a, 0x2c, - 0xc3, 0xd0, 0x62, 0x9b, 0x3a, 0x7c, 0x2b, 0xc4, 0x5f, 0x76, 0x7c, 0x30, 0x26, 0x5a, 0xd1, 0xef, - 0x57, 0xc4, 0xff, 0x01, 0x39, 0x5f, 0x5f, 0x6c, 0xff, 0xa7, 0x16, 0x32, 0x22, 0x2f, 0x40, 0xa1, - 0xc4, 0xed, 0xbc, 0x61, 0x64, 0x19, 0x88, 0x0c, 0xb7, 0xa0, 0x1c, 0xc5, 0xf7, 0xec, 0x3a, 0xfe, - 0xad, 0x09, 0x72, 0xf5, 0x32, 0x8c, 0xc7, 0xab, 0x21, 0xc3, 0x30, 0x30, 0xb5, 0xb8, 0xb0, 0x30, - 0x3d, 0xb5, 0x3c, 0xde, 0x47, 0x06, 0x21, 0x5f, 0x9d, 0x5e, 0x28, 0x8f, 0x67, 0xd4, 0x5f, 0x95, - 0x66, 0x10, 0xa6, 0x5a, 0x47, 0x57, 0xc3, 0x7b, 0xba, 0x6f, 0x19, 0xc7, 0xfb, 0x50, 0x3c, 0x31, - 0x68, 0x99, 0x9e, 0x47, 0x0d, 0xb1, 0x4a, 0xe0, 0x7d, 0xa1, 0x77, 0x5f, 0x4b, 0xe0, 0xc9, 0x53, - 0x30, 0x8a, 0x30, 0x71, 0x45, 0xc8, 0xf7, 0xc7, 0xa2, 0x80, 0x73, 0x5f, 0x8b, 0x22, 0xd5, 0x6f, - 0x87, 0xb7, 0xc3, 0x73, 0x54, 0x3f, 0xac, 0x37, 0x8a, 0xef, 0x93, 0xfe, 0x52, 0xff, 0x36, 0xcf, - 0x9f, 0x80, 0xf0, 0x87, 0x7b, 0x07, 0x21, 0xca, 0xf0, 0x48, 0x37, 0xb7, 0x8b, 0x23, 0xdd, 0xa7, - 0xa0, 0x30, 0x4f, 0xbd, 0x35, 0xdb, 0x77, 0xfc, 0x42, 0x0f, 0xbd, 0x16, 0x42, 0x64, 0x0f, 0x3d, - 0x4e, 0x43, 0xee, 0x02, 0xf1, 0x5f, 0xe5, 0x05, 0x8e, 0xd8, 0xfe, 0x11, 0xf2, 0xe9, 0xc4, 0x3e, - 0xa5, 0x8a, 0x4f, 0x72, 0xd1, 0xc7, 0xfe, 0x44, 0xe0, 0xe8, 0x2d, 0x79, 0x62, 0xfd, 0xcd, 0x66, - 0xb1, 0xc0, 0x69, 0xb4, 0x14, 0xb6, 0xe4, 0x4d, 0x18, 0x9a, 0x9f, 0x29, 0x89, 0x17, 0x7a, 0xdc, - 0x2b, 0xe2, 0x4c, 0x20, 0x45, 0x1f, 0x11, 0x88, 0x04, 0xdf, 0xdb, 0xb4, 0x56, 0xf5, 0xe4, 0x03, - 0xbd, 0x90, 0x0b, 0xd3, 0x16, 0xfe, 0x72, 0x47, 0x9c, 0x2e, 0x04, 0xda, 0x12, 0x7d, 0xcf, 0x13, - 0x97, 0x15, 0xc7, 0xc6, 0xb4, 0x65, 0x70, 0x0f, 0xa3, 0x7b, 0x11, 0x26, 0x4a, 0xed, 0x76, 0xd3, - 0xa4, 0x06, 0xea, 0x8b, 0xd6, 0x69, 0x52, 0x57, 0xb8, 0xfc, 0xe0, 0x63, 0x10, 0x9d, 0x23, 0x6b, - 0xf8, 0x2e, 0xb4, 0xe6, 0x74, 0xa2, 0xfe, 0x99, 0xc9, 0xb2, 0xea, 0x4f, 0x65, 0xe1, 0xd4, 0x94, - 0x43, 0x75, 0x8f, 0xce, 0xcf, 0x94, 0x4a, 0x1d, 0xf4, 0x91, 0x6b, 0x36, 0xa9, 0xd5, 0x38, 0x98, - 0x61, 0xfd, 0x32, 0x8c, 0x05, 0x0d, 0xa8, 0xd6, 0xed, 0x36, 0x95, 0x1f, 0x56, 0xd5, 0x7d, 0x4c, - 0xcd, 0x65, 0x28, 0x2d, 0x46, 0x4a, 0x6e, 0xc2, 0xf1, 0x00, 0x52, 0x6a, 0x36, 0xed, 0x75, 0x8d, - 0x76, 0x5c, 0xee, 0x18, 0x3b, 0xc8, 0x1d, 0x63, 0x43, 0x0e, 0x3a, 0xc3, 0xd7, 0x1c, 0x46, 0xa0, - 0xa5, 0x95, 0x52, 0xbf, 0x9e, 0x83, 0xd3, 0xb7, 0xf5, 0xa6, 0x69, 0x84, 0xa2, 0xd1, 0xa8, 0xdb, - 0xb6, 0x2d, 0x97, 0x1e, 0xa2, 0x51, 0x1a, 0x19, 0x0a, 0xf9, 0x7d, 0x19, 0x0a, 0xc9, 0x2e, 0xea, - 0xdf, 0x73, 0x17, 0x15, 0x1e, 0xa8, 0x8b, 0xfe, 0x51, 0x06, 0xc6, 0x7d, 0xc7, 0x7f, 0xf9, 0x35, - 0xb5, 0xe4, 0x95, 0x8e, 0x47, 0x88, 0x31, 0x3f, 0x68, 0xc4, 0x93, 0x2a, 0x0c, 0x4c, 0xdf, 0x6f, - 0x9b, 0x0e, 0x75, 0x77, 0xe0, 0xc4, 0x7d, 0x5e, 0x1c, 0x97, 0x4c, 0x50, 0x5e, 0x24, 0x71, 0x52, - 0xc2, 0xc1, 0xf8, 0x9c, 0x8f, 0x3f, 0x7d, 0x98, 0xf4, 0x9f, 0x88, 0xf3, 0xe7, 0x7c, 0xe2, 0x89, - 0x44, 0xe4, 0x7d, 0x66, 0x48, 0x4a, 0x1e, 0x87, 0xdc, 0xf2, 0xf2, 0x9c, 0x98, 0x49, 0xf1, 0x69, - 0xbe, 0xe7, 0xc9, 0xef, 0x15, 0x19, 0x56, 0xfd, 0xb3, 0x2c, 0x00, 0x53, 0x05, 0x3e, 0x5c, 0x0f, - 0x44, 0x09, 0x27, 0x61, 0xd0, 0x17, 0xb8, 0x50, 0xc3, 0xc0, 0x6b, 0x3f, 0xde, 0x11, 0xf1, 0xba, - 0x83, 0x17, 0x1a, 0x45, 0xdf, 0x91, 0x9c, 0xdf, 0x03, 0xe0, 0xce, 0x06, 0x1d, 0xc9, 0x7d, 0xf7, - 0xf1, 0x0f, 0xc1, 0x90, 0x98, 0xf1, 0xec, 0xc8, 0xf9, 0x7f, 0xdd, 0x07, 0x6a, 0x21, 0x3e, 0x36, - 0xb5, 0x16, 0xf6, 0xb0, 0x10, 0xfb, 0xe2, 0xe5, 0xbd, 0x72, 0x24, 0xde, 0x7d, 0x16, 0xef, 0x97, - 0x85, 0x78, 0xf9, 0x0b, 0x9e, 0x43, 0x2b, 0xde, 0x7d, 0x3b, 0xfb, 0x56, 0xff, 0x38, 0x03, 0x84, - 0x35, 0x6b, 0x49, 0x77, 0xdd, 0x75, 0xdb, 0x31, 0xb8, 0x73, 0xfa, 0x81, 0x08, 0x66, 0xff, 0xee, - 0x2b, 0xbf, 0x35, 0x08, 0xc7, 0x23, 0x8e, 0xbf, 0x87, 0x7c, 0xb2, 0xba, 0x1c, 0x1d, 0x4d, 0xbd, - 0x5e, 0xbd, 0x7c, 0x40, 0xbe, 0x10, 0xed, 0x8f, 0x3c, 0x40, 0x93, 0x6e, 0x42, 0x9f, 0x86, 0x11, - 0xf1, 0x83, 0xad, 0xd0, 0xfe, 0x4d, 0x17, 0x8e, 0x52, 0x97, 0x01, 0xb4, 0x08, 0x9a, 0x3c, 0x07, - 0x43, 0x6c, 0xc0, 0x34, 0x30, 0x8a, 0xc7, 0x40, 0xf8, 0xa2, 0xc4, 0xf0, 0x81, 0xf2, 0x7a, 0x12, - 0x50, 0x4a, 0xef, 0x88, 0x06, 0x77, 0xf0, 0x8e, 0xe8, 0xd3, 0x30, 0x5c, 0xb2, 0x2c, 0xdb, 0xc3, - 0x4d, 0xba, 0x2b, 0xae, 0x26, 0xba, 0x5a, 0xe5, 0x8f, 0xe3, 0xe3, 0xf8, 0x90, 0x3e, 0xd5, 0x2c, - 0x97, 0x19, 0x92, 0x6b, 0xfe, 0xab, 0x18, 0xea, 0x08, 0xaf, 0x72, 0xbc, 0x9e, 0x71, 0x04, 0x2c, - 0xf9, 0x28, 0x06, 0x3b, 0x6f, 0x74, 0xc9, 0xb1, 0xdb, 0xb6, 0x4b, 0x0d, 0x2e, 0xa8, 0xe1, 0x30, - 0xd4, 0x40, 0x5b, 0x20, 0xf0, 0x1d, 0x5b, 0x24, 0xa2, 0x46, 0xa4, 0x08, 0x59, 0x85, 0x13, 0xfe, - 0x45, 0x71, 0xf0, 0x62, 0xb0, 0x52, 0x76, 0x95, 0x11, 0x7c, 0x95, 0x44, 0xe2, 0xca, 0x50, 0x29, - 0x4f, 0x5e, 0xf0, 0xaf, 0x45, 0xfc, 0x27, 0x87, 0x35, 0xd3, 0x90, 0xbb, 0x3a, 0x95, 0x1f, 0xf9, - 0x0c, 0x0c, 0xcf, 0xeb, 0xf7, 0xcb, 0x1d, 0x71, 0xf6, 0x32, 0xba, 0xf3, 0xdb, 0x97, 0x96, 0x7e, - 0xbf, 0x66, 0x88, 0x72, 0x31, 0x9b, 0x42, 0x66, 0x49, 0x6a, 0x70, 0x6a, 0xc9, 0xb1, 0x5b, 0xb6, - 0x47, 0x8d, 0xd8, 0xe3, 0xbb, 0x63, 0xe1, 0x6b, 0xdd, 0xb6, 0xa0, 0xa8, 0xf5, 0x78, 0x85, 0xd7, - 0x85, 0x0d, 0x69, 0xc1, 0xb1, 0x92, 0xeb, 0x76, 0x5a, 0x34, 0xbc, 0xa1, 0x1a, 0xdf, 0xf6, 0x33, - 0x3e, 0x28, 0xbc, 0x96, 0x1f, 0xd1, 0xb1, 0x28, 0xbf, 0xa0, 0xaa, 0x79, 0xa6, 0x5c, 0x23, 0x7e, - 0x4b, 0x9c, 0xf7, 0x1b, 0xf9, 0xc1, 0xb1, 0xf1, 0x63, 0xda, 0xe9, 0x64, 0x63, 0x96, 0x4d, 0xaf, - 0x49, 0xd5, 0x6f, 0x66, 0x00, 0x42, 0x01, 0x93, 0xa7, 0xa3, 0xa1, 0x82, 0x32, 0xe1, 0x45, 0x87, - 0x88, 0x5e, 0x10, 0x89, 0x0d, 0x44, 0xce, 0x41, 0x1e, 0x23, 0x5c, 0x64, 0xc3, 0x83, 0xd5, 0xbb, - 0xa6, 0x65, 0x68, 0x08, 0x65, 0x58, 0xe9, 0x29, 0x3a, 0x62, 0xf1, 0x52, 0x9f, 0x5b, 0x85, 0x65, - 0x38, 0x56, 0xed, 0xac, 0xf8, 0x75, 0x4b, 0xef, 0xea, 0x30, 0xd0, 0x86, 0xdb, 0x59, 0x09, 0x1e, - 0xa3, 0x46, 0xc2, 0x98, 0x44, 0x8b, 0xa8, 0xbf, 0x9e, 0x89, 0xcd, 0x82, 0x07, 0xb8, 0xe8, 0x7d, - 0x20, 0xe9, 0xa7, 0x91, 0x9c, 0x96, 0xd4, 0x9f, 0xcf, 0xc2, 0xf0, 0x92, 0xed, 0x78, 0x22, 0x64, - 0xc8, 0xe1, 0x5e, 0x85, 0xa4, 0xbd, 0x52, 0x7e, 0x17, 0x7b, 0xa5, 0x73, 0x90, 0x97, 0x5c, 0x94, - 0xf9, 0xbd, 0x88, 0x61, 0x38, 0x1a, 0x42, 0xd5, 0x1f, 0xc8, 0x02, 0x7c, 0xec, 0x99, 0x67, 0x1e, - 0x62, 0x01, 0xa9, 0x3f, 0x9b, 0x81, 0x63, 0xe2, 0xa2, 0x4e, 0x0a, 0xba, 0x35, 0xe0, 0x5f, 0xb1, - 0xca, 0xe3, 0x92, 0x83, 0x34, 0x1f, 0xc7, 0x96, 0x80, 0xe9, 0xfb, 0xa6, 0x87, 0x77, 0x15, 0x52, - 0xd4, 0x2d, 0x2a, 0x60, 0xf2, 0x12, 0xe0, 0xd3, 0x91, 0xa7, 0xfd, 0x2b, 0xc8, 0x5c, 0xb8, 0xee, - 0xb1, 0x02, 0xd3, 0xa9, 0xd7, 0x90, 0xea, 0x6f, 0xe6, 0x21, 0x3f, 0x7d, 0x9f, 0xd6, 0x0f, 0x79, - 0xd7, 0x48, 0x07, 0x9b, 0xf9, 0x3d, 0x1e, 0x6c, 0x3e, 0x88, 0x4f, 0xc5, 0x6b, 0x61, 0x7f, 0x16, - 0xa2, 0xd5, 0xc7, 0x7a, 0x3e, 0x5e, 0xbd, 0xdf, 0xd3, 0x87, 0xcf, 0x25, 0xe7, 0x7f, 0xcd, 0x41, - 0xae, 0x3a, 0xb5, 0x74, 0xa4, 0x37, 0x07, 0xaa, 0x37, 0xbd, 0xef, 0xac, 0xd5, 0xe0, 0x1a, 0x6a, - 0x30, 0xf4, 0x12, 0x8d, 0xdd, 0x38, 0x7d, 0x2f, 0x07, 0x63, 0xd5, 0x99, 0xe5, 0x25, 0xe9, 0x24, - 0xf8, 0x26, 0xf7, 0xe4, 0x43, 0x9f, 0x32, 0xde, 0xa5, 0xe7, 0x12, 0xf6, 0xcc, 0xad, 0x8a, 0xe5, - 0x3d, 0x7f, 0xfd, 0xb6, 0xde, 0xec, 0x50, 0x3c, 0x7a, 0xe1, 0x7e, 0xbf, 0xae, 0xf9, 0x0e, 0xfd, - 0x3a, 0x3e, 0xfc, 0xf7, 0x19, 0x90, 0x97, 0x21, 0x77, 0x4b, 0x78, 0x64, 0x74, 0xe3, 0xf3, 0xec, - 0x35, 0xce, 0x87, 0x4d, 0x82, 0xb9, 0x8e, 0x69, 0x20, 0x07, 0x56, 0x8a, 0x15, 0xbe, 0x21, 0x16, - 0xe0, 0x1d, 0x15, 0x6e, 0xf8, 0x85, 0x6f, 0x54, 0xca, 0xa4, 0x0a, 0xc3, 0x4b, 0xd4, 0x69, 0x99, - 0xd8, 0x51, 0xfe, 0x9c, 0xdd, 0x9b, 0x09, 0xdb, 0xa9, 0x0c, 0xb7, 0xc3, 0x42, 0xc8, 0x4c, 0xe6, - 0x42, 0xde, 0x02, 0xe0, 0x36, 0xca, 0x0e, 0x03, 0x39, 0x9e, 0x47, 0xbb, 0x9f, 0x9b, 0x96, 0x29, - 0x36, 0x9e, 0xc4, 0x8c, 0xdc, 0x85, 0xf1, 0x79, 0xdb, 0x30, 0x57, 0x4d, 0xee, 0x7a, 0x89, 0x15, - 0x14, 0xb6, 0x77, 0x78, 0x62, 0xa6, 0x64, 0x4b, 0x2a, 0x97, 0x56, 0x4d, 0x82, 0xb1, 0xfa, 0x3f, - 0xf5, 0x43, 0x9e, 0x75, 0xfb, 0xd1, 0xf8, 0xdd, 0xcb, 0xf8, 0x2d, 0xc1, 0xf8, 0x1d, 0xdb, 0xb9, - 0x6b, 0x5a, 0x8d, 0xc0, 0x2b, 0x5e, 0xec, 0x4d, 0xd1, 0x93, 0x67, 0x9d, 0xe3, 0x6a, 0x81, 0x03, - 0xbd, 0x96, 0x20, 0xdf, 0x66, 0x04, 0xbf, 0x08, 0xc0, 0xdf, 0xba, 0x23, 0xcd, 0x60, 0x18, 0xac, - 0x82, 0xbf, 0x84, 0x47, 0x47, 0x7b, 0x39, 0x58, 0x45, 0x48, 0xcc, 0x36, 0xe1, 0xdc, 0x17, 0x62, - 0x08, 0xfd, 0xee, 0x71, 0x13, 0x8e, 0xbe, 0x10, 0xb2, 0x11, 0xc0, 0xbd, 0x22, 0x96, 0x00, 0xa4, - 0xfb, 0x25, 0x88, 0x09, 0x22, 0x32, 0x39, 0x88, 0xf0, 0x70, 0x29, 0xd7, 0x4b, 0x9a, 0xc4, 0x83, - 0x3c, 0x1f, 0xbb, 0x00, 0x27, 0x11, 0x6e, 0x5d, 0xef, 0xbf, 0x43, 0x07, 0xaa, 0x91, 0xed, 0x1c, - 0xa8, 0xd4, 0x2f, 0x66, 0x61, 0xa8, 0xda, 0x59, 0x71, 0x37, 0x5c, 0x8f, 0xb6, 0x0e, 0xb9, 0x1a, - 0xfb, 0xdb, 0xab, 0x7c, 0xea, 0xf6, 0xea, 0x71, 0x5f, 0x28, 0xd2, 0xb9, 0x63, 0x60, 0xd2, 0xf9, - 0xe2, 0xf8, 0x6f, 0xb3, 0x30, 0xce, 0x2f, 0xce, 0xca, 0xa6, 0x5b, 0xdf, 0x07, 0x67, 0xfe, 0x83, - 0x97, 0xca, 0xde, 0x2e, 0x9b, 0x77, 0xf0, 0x44, 0x42, 0xfd, 0x5c, 0x16, 0x86, 0x4b, 0x1d, 0x6f, - 0xad, 0xe4, 0xa1, 0x6e, 0x3d, 0x94, 0xfb, 0x93, 0xdf, 0xcf, 0xc0, 0x31, 0xd6, 0x90, 0x65, 0xfb, - 0x2e, 0xb5, 0xf6, 0xe1, 0xe0, 0x51, 0x3e, 0x40, 0xcc, 0x3e, 0xe0, 0x01, 0xa2, 0x2f, 0xcb, 0xdc, - 0xee, 0x64, 0x89, 0xc7, 0xe5, 0x9a, 0xdd, 0xa4, 0x87, 0xfb, 0x33, 0xf6, 0xf1, 0xb8, 0xdc, 0x17, - 0xc8, 0x3e, 0x5c, 0xcf, 0x7c, 0x7f, 0x09, 0x64, 0x1f, 0xce, 0x96, 0xbe, 0x3f, 0x04, 0xf2, 0xad, - 0x0c, 0x0c, 0x4d, 0xda, 0xde, 0x21, 0x1f, 0xf8, 0xe2, 0x2b, 0x0e, 0xb7, 0x9a, 0xfb, 0x5f, 0x71, - 0xb8, 0x75, 0x53, 0xfd, 0xe9, 0x2c, 0x9c, 0x10, 0x41, 0xba, 0xc5, 0xf9, 0xc3, 0xd1, 0x74, 0x2c, - 0x06, 0x5b, 0x52, 0x34, 0x47, 0xf3, 0x90, 0x10, 0xcd, 0x2f, 0xe7, 0xe0, 0x04, 0x86, 0x32, 0x65, - 0xdb, 0xb2, 0xef, 0x03, 0x5b, 0x84, 0xd4, 0xa3, 0x97, 0xa0, 0xf3, 0x29, 0x97, 0xa0, 0x7f, 0xb3, - 0x59, 0x7c, 0xbe, 0x61, 0x7a, 0x6b, 0x9d, 0x95, 0x2b, 0x75, 0xbb, 0x75, 0xb5, 0xe1, 0xe8, 0xf7, - 0x4c, 0x7e, 0xfd, 0xa7, 0x37, 0xaf, 0x06, 0xf9, 0x2e, 0xf4, 0xb6, 0x29, 0x32, 0x61, 0x54, 0x71, - 0xaf, 0xc3, 0xb8, 0xfa, 0xd7, 0xa7, 0x2e, 0xc0, 0x1b, 0xb6, 0x69, 0x09, 0x9f, 0x42, 0x6e, 0xe8, - 0x56, 0xd9, 0xfe, 0xf0, 0x6d, 0xdb, 0xb4, 0x6a, 0x71, 0xc7, 0xc2, 0xdd, 0xd6, 0x17, 0xb2, 0xd6, - 0xa4, 0x6a, 0xd4, 0xff, 0x2b, 0x03, 0x67, 0xa2, 0x5a, 0xfc, 0xfd, 0x60, 0x3b, 0xfe, 0x4c, 0x16, - 0x4e, 0xde, 0x40, 0xe1, 0x04, 0x8e, 0x1c, 0x47, 0xf3, 0x96, 0x18, 0x9c, 0x29, 0xb2, 0x39, 0xb2, - 0x28, 0xbb, 0xcb, 0xe6, 0x68, 0x52, 0x17, 0xb2, 0xf9, 0x83, 0x0c, 0x1c, 0x5f, 0xac, 0x94, 0xa7, - 0xbe, 0x4f, 0x46, 0x54, 0xf2, 0x7b, 0x0e, 0xb9, 0xc1, 0x99, 0xf8, 0x9e, 0x43, 0x6e, 0x7a, 0x7e, - 0x35, 0x0b, 0xc7, 0xab, 0xa5, 0xf9, 0xb9, 0xef, 0x97, 0x19, 0x7c, 0x4a, 0xf6, 0x3a, 0xf4, 0x0f, - 0xc1, 0x84, 0x2d, 0x20, 0x7f, 0xe6, 0xed, 0x6b, 0xdd, 0xbd, 0x11, 0x93, 0x42, 0x39, 0xe4, 0x53, - 0xf7, 0xbe, 0x08, 0x85, 0x69, 0x7e, 0x84, 0xfa, 0x90, 0x6b, 0xfe, 0xff, 0x52, 0x80, 0xe1, 0x9b, - 0x9d, 0x15, 0x2a, 0x9c, 0x53, 0x1e, 0xea, 0x93, 0xdf, 0x6b, 0x30, 0x2c, 0xc4, 0x80, 0xb7, 0x26, - 0x52, 0xf0, 0x3c, 0x11, 0x0c, 0x85, 0xc7, 0x27, 0x92, 0x89, 0xc8, 0x39, 0xc8, 0xdf, 0xa6, 0xce, - 0x8a, 0xfc, 0xae, 0xf4, 0x1e, 0x75, 0x56, 0x34, 0x84, 0x92, 0xb9, 0xd0, 0x65, 0xbe, 0xb4, 0x54, - 0xc1, 0x44, 0x2a, 0xe2, 0xc2, 0x06, 0x33, 0xc3, 0x04, 0x7e, 0x6f, 0x7a, 0xdb, 0xe4, 0x29, 0x58, - 0xe4, 0x37, 0xed, 0xf1, 0x92, 0x64, 0x01, 0x26, 0x64, 0xc7, 0x27, 0x9e, 0x45, 0x64, 0x30, 0x85, - 0x5d, 0x5a, 0xfe, 0x90, 0x64, 0x51, 0xf2, 0x1a, 0x8c, 0xf8, 0x40, 0x74, 0xe1, 0x1a, 0x0a, 0x43, - 0xd7, 0x07, 0xac, 0x62, 0x29, 0x8a, 0x22, 0x05, 0x64, 0x06, 0x78, 0x0d, 0x01, 0x29, 0x0c, 0x62, - 0x2e, 0x71, 0x91, 0x02, 0xe4, 0x39, 0x64, 0x80, 0xcf, 0x3c, 0xd0, 0x59, 0x65, 0x18, 0x1f, 0x5d, - 0xa2, 0x4b, 0xbe, 0x23, 0xe0, 0xfc, 0x69, 0x6d, 0x84, 0x8c, 0x2c, 0x02, 0x84, 0x4e, 0x05, 0x22, - 0x80, 0xc1, 0xae, 0xdd, 0x1d, 0x24, 0x16, 0xf2, 0x75, 0xe0, 0xe8, 0x83, 0x5c, 0x07, 0xaa, 0x7f, - 0x94, 0x85, 0xe1, 0x52, 0xbb, 0x1d, 0x0c, 0x85, 0xa7, 0xa1, 0x50, 0x6a, 0xb7, 0x6f, 0x69, 0x15, - 0x39, 0x94, 0xb9, 0xde, 0x6e, 0xd7, 0x3a, 0x8e, 0x29, 0xfb, 0x84, 0x72, 0x22, 0x32, 0x05, 0xa3, - 0xa5, 0x76, 0x7b, 0xa9, 0xb3, 0xd2, 0x34, 0xeb, 0x52, 0x66, 0x24, 0x9e, 0xc4, 0xad, 0xdd, 0xae, - 0xb5, 0x11, 0x13, 0x4f, 0x8f, 0x15, 0x2d, 0x43, 0x3e, 0x8d, 0x61, 0x7f, 0x44, 0x62, 0x1e, 0x9e, - 0xfa, 0x43, 0x0d, 0x82, 0x98, 0x87, 0x6d, 0xbb, 0x12, 0x10, 0xf1, 0x60, 0xef, 0xe7, 0xfc, 0x90, - 0xf9, 0xac, 0xa2, 0x44, 0x02, 0x9e, 0x90, 0x25, 0xf9, 0x30, 0x0c, 0x94, 0xda, 0x6d, 0xe9, 0xbe, - 0x09, 0x9d, 0x8a, 0x58, 0xa9, 0x58, 0x1f, 0xfb, 0x64, 0x67, 0x5f, 0x81, 0xb1, 0x68, 0x65, 0xbb, - 0x0a, 0x16, 0xff, 0xd7, 0x19, 0xfc, 0xa0, 0x43, 0xee, 0xd3, 0xfc, 0x2c, 0xe4, 0x4a, 0xed, 0xb6, - 0x98, 0x8f, 0x8e, 0xa7, 0xf4, 0x47, 0xfc, 0x09, 0x74, 0xa9, 0xdd, 0xf6, 0x3f, 0xfd, 0x90, 0x3f, - 0x8e, 0x78, 0xa0, 0x4f, 0xff, 0x16, 0xff, 0xf4, 0xc3, 0xfd, 0x70, 0x41, 0xfd, 0xcd, 0x1c, 0x1c, - 0x2b, 0xb5, 0xdb, 0x47, 0x41, 0xe6, 0xf7, 0xeb, 0xa1, 0xf5, 0x33, 0x00, 0xd2, 0xf4, 0x38, 0x10, - 0x3c, 0xdd, 0x1a, 0x96, 0xa6, 0x46, 0x25, 0xa3, 0x49, 0x44, 0xbe, 0xfa, 0x0d, 0xee, 0x4a, 0xfd, - 0x3e, 0x97, 0xc3, 0xa9, 0xf8, 0xb0, 0x07, 0x8d, 0x7a, 0xbf, 0x74, 0x9b, 0xe8, 0x83, 0xc2, 0xae, - 0xfa, 0xe0, 0xf7, 0x22, 0x83, 0x07, 0x83, 0x96, 0x1f, 0xf5, 0x42, 0xff, 0x9e, 0xcc, 0xe2, 0x31, - 0x59, 0x98, 0x22, 0x92, 0x8d, 0x9f, 0x48, 0x49, 0xc4, 0x55, 0xaa, 0x33, 0x54, 0xcd, 0x34, 0xb4, - 0x18, 0xad, 0xdf, 0x87, 0x03, 0xbb, 0xea, 0xc3, 0xcd, 0x2c, 0xbe, 0x9d, 0x0e, 0xe2, 0x32, 0xed, - 0x7d, 0x77, 0x71, 0x15, 0x80, 0x7b, 0x1e, 0x04, 0x6e, 0xcd, 0xa3, 0x3c, 0x04, 0x0b, 0xcf, 0xaf, - 0x24, 0x42, 0xb0, 0x84, 0x24, 0x81, 0x87, 0x54, 0x2e, 0xd5, 0x43, 0xea, 0x32, 0x0c, 0x6a, 0xfa, - 0xfa, 0x9b, 0x1d, 0xea, 0x6c, 0x08, 0x73, 0x86, 0x87, 0x3d, 0xd4, 0xd7, 0x6b, 0x9f, 0x65, 0x40, - 0x2d, 0x40, 0x13, 0x35, 0x78, 0x7c, 0x2f, 0x79, 0x84, 0xf0, 0x33, 0xf2, 0xe0, 0xc9, 0xfd, 0x83, - 0x28, 0x3a, 0x79, 0x09, 0x72, 0xa5, 0x3b, 0x55, 0x21, 0xd9, 0xa0, 0x6b, 0x4b, 0x77, 0xaa, 0x42, - 0x5e, 0x5d, 0xcb, 0xde, 0xa9, 0xaa, 0x9f, 0xcb, 0x02, 0x49, 0x52, 0x92, 0xe7, 0x61, 0x08, 0xa1, - 0x0d, 0xa6, 0x33, 0x72, 0x62, 0xce, 0x75, 0xb7, 0xe6, 0x20, 0x34, 0x62, 0xdc, 0xf9, 0xa4, 0xe4, - 0x45, 0xcc, 0x41, 0x2c, 0x52, 0xc3, 0x45, 0x12, 0x73, 0xae, 0xbb, 0x7e, 0xd6, 0xde, 0x58, 0x0a, - 0x62, 0x41, 0x8c, 0x76, 0xe1, 0x9d, 0xea, 0xac, 0xed, 0x7a, 0x42, 0xd4, 0xdc, 0x2e, 0x5c, 0x77, - 0x31, 0x23, 0x6c, 0xc4, 0x2e, 0xe4, 0x64, 0x98, 0xd5, 0xea, 0x4e, 0x95, 0x3f, 0x53, 0x31, 0x34, - 0xbb, 0xe9, 0x1b, 0x94, 0x3c, 0xab, 0xd5, 0xba, 0x5b, 0xe3, 0x4f, 0x5c, 0x0c, 0x4c, 0x7e, 0x1c, - 0xc9, 0x6a, 0x15, 0x29, 0xa5, 0x7e, 0x69, 0x10, 0xc6, 0xcb, 0xba, 0xa7, 0xaf, 0xe8, 0x2e, 0x95, - 0x76, 0xd3, 0xc7, 0x7c, 0x98, 0xff, 0x39, 0x92, 0x1c, 0x8c, 0x95, 0x94, 0xaf, 0x89, 0x17, 0x20, - 0x2f, 0x87, 0x7c, 0x83, 0x9c, 0xa3, 0x72, 0x12, 0xb3, 0x95, 0x5a, 0x5b, 0x80, 0xb5, 0x04, 0x21, - 0x79, 0x0a, 0x86, 0x7d, 0x18, 0xdb, 0x00, 0xe4, 0x42, 0x9d, 0x31, 0x56, 0x98, 0xfd, 0xaf, 0xc9, - 0x68, 0xf2, 0x22, 0x8c, 0xf8, 0x3f, 0x25, 0xd3, 0x9a, 0x67, 0x64, 0x5b, 0x49, 0xec, 0x9e, 0x64, - 0x52, 0xb9, 0x28, 0xce, 0x6f, 0xfd, 0x91, 0xa2, 0xb1, 0xa4, 0x67, 0x11, 0x52, 0xf2, 0x59, 0x18, - 0xf3, 0x7f, 0x8b, 0x0d, 0x03, 0xcf, 0x0f, 0xf7, 0x54, 0x90, 0x5b, 0x39, 0x26, 0xd6, 0x2b, 0x51, - 0x72, 0xbe, 0x75, 0x78, 0xc4, 0xcf, 0xe3, 0x65, 0xac, 0x24, 0x77, 0x0e, 0xb1, 0x0a, 0x48, 0x05, - 0x26, 0x7c, 0x48, 0xa8, 0xa1, 0x03, 0xe1, 0x8e, 0xd1, 0x58, 0xa9, 0xa5, 0x2a, 0x69, 0xb2, 0x14, - 0x69, 0xc2, 0xb9, 0x08, 0xd0, 0x70, 0xd7, 0xcc, 0x55, 0x4f, 0x6c, 0xf7, 0x44, 0x0c, 0x62, 0x91, - 0xb8, 0x31, 0xe0, 0xca, 0x69, 0xfc, 0x0c, 0xac, 0xd1, 0xec, 0x50, 0x3d, 0xb9, 0x91, 0x2a, 0x9c, - 0xf0, 0xf1, 0x37, 0xa6, 0x96, 0x96, 0x1c, 0xfb, 0x6d, 0x5a, 0xf7, 0x2a, 0x65, 0xb1, 0x5d, 0xc6, - 0xd8, 0x74, 0xc6, 0x4a, 0xad, 0x51, 0x6f, 0x33, 0xa5, 0x60, 0xb8, 0x28, 0xf3, 0xd4, 0xc2, 0xe4, - 0x36, 0x9c, 0x94, 0xe0, 0x15, 0xcb, 0xf5, 0x74, 0xab, 0x4e, 0x2b, 0x65, 0xb1, 0x87, 0xc6, 0xfd, - 0xbc, 0xe0, 0x6a, 0x0a, 0x64, 0x94, 0x6d, 0x7a, 0x71, 0xf2, 0x0a, 0x8c, 0xfa, 0x08, 0x7e, 0x8b, - 0x38, 0x8c, 0xb7, 0x88, 0x38, 0x24, 0x8d, 0x95, 0x5a, 0xfc, 0x35, 0x65, 0x94, 0x58, 0xd6, 0x28, - 0x4c, 0x6d, 0x3f, 0x12, 0xd1, 0x28, 0x6f, 0xa3, 0x9d, 0xaa, 0x8c, 0x98, 0xee, 0xfe, 0xb5, 0x50, - 0xa3, 0x16, 0x1d, 0xb3, 0x61, 0xf2, 0x9d, 0xb4, 0xff, 0x80, 0x72, 0xa5, 0x66, 0x23, 0x30, 0x4d, - 0x3f, 0x38, 0xf9, 0xd9, 0x12, 0x1c, 0x4f, 0xd1, 0xb1, 0x5d, 0xed, 0x18, 0xbf, 0x98, 0x0d, 0x1b, - 0x71, 0xc8, 0xb7, 0x8d, 0x93, 0x30, 0xe8, 0x7f, 0x89, 0x30, 0x1e, 0x94, 0x6e, 0x43, 0x33, 0xce, - 0xc3, 0xc7, 0x47, 0xc4, 0x71, 0xc8, 0xb7, 0x92, 0xfb, 0x21, 0x8e, 0x77, 0x33, 0xa1, 0x38, 0x0e, - 0xf9, 0xf6, 0xf2, 0x0f, 0x72, 0xe1, 0x9c, 0x74, 0xb4, 0xc7, 0xdc, 0x2f, 0x33, 0x39, 0xf4, 0x83, - 0x2d, 0xec, 0xe2, 0x21, 0xa3, 0xac, 0x9a, 0x03, 0x0f, 0xa8, 0x9a, 0x7f, 0x92, 0xec, 0x4f, 0x6e, - 0x7a, 0x1e, 0xca, 0xfe, 0xdc, 0x87, 0xc1, 0x4a, 0xae, 0x85, 0xeb, 0x18, 0xb7, 0xd1, 0xfb, 0xa5, - 0x10, 0x7f, 0x2b, 0xc2, 0x44, 0x8f, 0x92, 0x90, 0x4f, 0xc0, 0xe9, 0x08, 0x60, 0x49, 0x77, 0xf4, - 0x16, 0xf5, 0xc2, 0x8c, 0x83, 0x18, 0xb4, 0xc9, 0x2f, 0x5d, 0x6b, 0x07, 0x68, 0x39, 0x8b, 0x61, - 0x17, 0x0e, 0x92, 0x72, 0x0c, 0xec, 0xc2, 0x49, 0xfa, 0x6b, 0xb9, 0xd0, 0x54, 0x89, 0x06, 0x5f, - 0xd5, 0xa8, 0xdb, 0x69, 0x7a, 0x0f, 0x6f, 0x07, 0x3f, 0x58, 0x6a, 0x8b, 0x59, 0x38, 0x56, 0x5a, - 0x5d, 0xa5, 0x75, 0xcf, 0x8f, 0x29, 0xed, 0x8a, 0x70, 0x7b, 0x7c, 0xeb, 0x20, 0x50, 0x22, 0x46, - 0x70, 0x24, 0x37, 0x7e, 0xac, 0x98, 0xfa, 0xa7, 0x79, 0x50, 0x02, 0xd3, 0x3d, 0x78, 0xa8, 0x75, - 0x80, 0xcb, 0xe4, 0xfb, 0xa2, 0x57, 0x4c, 0x98, 0x08, 0x85, 0x51, 0xed, 0xb4, 0x5a, 0x3a, 0x0e, - 0x3d, 0xb6, 0x35, 0x28, 0xc6, 0x99, 0x85, 0x84, 0x7c, 0x37, 0x70, 0x56, 0xec, 0x06, 0x48, 0xf8, - 0x10, 0xae, 0xe6, 0x72, 0x16, 0x5a, 0x92, 0x2b, 0xf9, 0x72, 0x06, 0x4e, 0xf8, 0x9d, 0xb2, 0xb8, - 0xc2, 0xcc, 0xe2, 0x29, 0xbb, 0x63, 0x79, 0xfe, 0x4e, 0xe4, 0xa5, 0xee, 0xd5, 0xf1, 0x4e, 0xba, - 0x92, 0x56, 0x98, 0xb7, 0x24, 0x08, 0x2c, 0x11, 0x28, 0x84, 0x8d, 0x34, 0xb5, 0x3a, 0x12, 0x69, - 0xa9, 0xf5, 0x9e, 0xbd, 0x01, 0x67, 0xba, 0xb2, 0xdc, 0xce, 0x0c, 0xed, 0x97, 0xcd, 0xd0, 0xff, - 0x27, 0x13, 0x4e, 0x44, 0x31, 0x21, 0x91, 0x2b, 0x00, 0x21, 0x48, 0x6c, 0x4c, 0xc7, 0xb6, 0x36, - 0x8b, 0x10, 0x0a, 0x4d, 0x93, 0x28, 0xc8, 0x22, 0x14, 0x84, 0x58, 0x78, 0x76, 0xdf, 0x0f, 0x6d, - 0xd3, 0x0b, 0x57, 0x64, 0x39, 0xe0, 0xa6, 0x53, 0x7c, 0xb3, 0x60, 0x73, 0xf6, 0x45, 0x18, 0x7e, - 0xd0, 0xef, 0xfa, 0x72, 0x0e, 0x88, 0xbc, 0x8b, 0x3c, 0x40, 0x13, 0xfb, 0x10, 0x4f, 0x61, 0x97, - 0x60, 0x90, 0x7d, 0x02, 0xe6, 0xbb, 0x90, 0xe2, 0xdb, 0x76, 0x04, 0x4c, 0x0b, 0xb0, 0x61, 0x70, - 0xa9, 0x81, 0xf4, 0xe0, 0x52, 0xea, 0x4f, 0xe6, 0xe0, 0x94, 0xdc, 0x21, 0x65, 0x8a, 0x21, 0xf3, - 0x8f, 0x3a, 0xe5, 0x3d, 0xec, 0x14, 0x15, 0x0a, 0x7c, 0xf3, 0x20, 0x72, 0x17, 0xf0, 0x83, 0x1d, - 0x84, 0x68, 0x02, 0xa3, 0xfe, 0xfd, 0x2c, 0x8c, 0x2e, 0xd9, 0xae, 0xd7, 0x70, 0xa8, 0xbb, 0xa4, - 0x3b, 0xee, 0x43, 0xdc, 0x1d, 0x1f, 0x81, 0x51, 0x0c, 0x0f, 0xd4, 0xa2, 0x16, 0x0f, 0xa1, 0xd3, - 0x2f, 0x25, 0x1b, 0xf1, 0x11, 0x22, 0xaf, 0x54, 0x84, 0x90, 0x69, 0x3f, 0xb7, 0xfc, 0xa4, 0xa0, - 0x4d, 0xdc, 0xec, 0xe3, 0x70, 0xf5, 0x17, 0x73, 0x30, 0xe2, 0x4b, 0x79, 0xd2, 0x3c, 0xac, 0x37, - 0x35, 0x07, 0x2b, 0xe4, 0xab, 0x00, 0x4b, 0xb6, 0xe3, 0xe9, 0xcd, 0x85, 0x50, 0xf3, 0xf1, 0x88, - 0xb3, 0x8d, 0x50, 0x5e, 0x46, 0x22, 0xc1, 0xf5, 0x2b, 0x34, 0xab, 0xf9, 0xc4, 0xc4, 0xd7, 0xaf, - 0x00, 0xaa, 0x49, 0x14, 0xea, 0xef, 0x64, 0xe1, 0x98, 0xdf, 0x49, 0xd3, 0xf7, 0x69, 0xbd, 0xf3, - 0x30, 0xcf, 0x4d, 0x51, 0x69, 0xf7, 0x6f, 0x2b, 0x6d, 0xf5, 0x9f, 0x4b, 0x13, 0xc9, 0x54, 0xd3, - 0x3e, 0x9a, 0x48, 0xfe, 0x2e, 0x74, 0x5c, 0xfd, 0xa1, 0x1c, 0x9c, 0xf0, 0xa5, 0x3e, 0xd3, 0xb1, - 0xf0, 0x70, 0x60, 0x4a, 0x6f, 0x36, 0x1f, 0xe6, 0xdd, 0xf8, 0xb0, 0x2f, 0x88, 0x45, 0x11, 0x6f, - 0x4f, 0xe4, 0xf8, 0x5b, 0x15, 0xe0, 0x9a, 0x6d, 0x1a, 0x9a, 0x4c, 0x44, 0x5e, 0x83, 0x11, 0xff, - 0x67, 0xc9, 0x69, 0xf8, 0x5b, 0x70, 0x3c, 0xea, 0x0f, 0x0a, 0xe9, 0x4e, 0x24, 0xac, 0x40, 0xa4, - 0x80, 0xfa, 0x0f, 0x0b, 0x70, 0xf6, 0x8e, 0x69, 0x19, 0xf6, 0xba, 0xeb, 0xa7, 0x88, 0x3c, 0xf4, - 0x47, 0x5d, 0x07, 0x9d, 0x1a, 0xf2, 0x4d, 0x38, 0x19, 0x17, 0xa9, 0x13, 0x04, 0xee, 0x16, 0xbd, - 0xb3, 0xce, 0x09, 0x6a, 0x7e, 0xb2, 0x48, 0x71, 0x5f, 0xa6, 0xa5, 0x97, 0x8c, 0x67, 0x9b, 0x1c, - 0xd8, 0x49, 0xb6, 0xc9, 0x27, 0xa1, 0x50, 0xb6, 0x5b, 0xba, 0xe9, 0x07, 0x98, 0xc1, 0x51, 0x1c, - 0xd4, 0x8b, 0x18, 0x4d, 0x50, 0x30, 0xfe, 0xa2, 0x62, 0xec, 0xb2, 0xa1, 0x90, 0xbf, 0x5f, 0x80, - 0x59, 0x69, 0x9a, 0x4c, 0x44, 0x6c, 0x18, 0x15, 0xd5, 0x89, 0xdb, 0x2d, 0xc0, 0xcd, 0xd3, 0x73, - 0xbe, 0x8c, 0xba, 0xab, 0xd5, 0x95, 0x48, 0x39, 0xbe, 0x8d, 0xe2, 0x49, 0x30, 0xc5, 0xc7, 0xf0, - 0x7b, 0x2e, 0x2d, 0xca, 0x5f, 0x12, 0x02, 0x4e, 0x32, 0xc3, 0x49, 0x21, 0xe0, 0x2c, 0x23, 0x13, - 0x91, 0x69, 0x98, 0xc0, 0xf0, 0xca, 0xc1, 0x56, 0x8a, 0xa9, 0xc4, 0x08, 0x1a, 0x95, 0x78, 0x69, - 0xc2, 0x23, 0x32, 0xb3, 0x8f, 0xab, 0xd5, 0x05, 0x5a, 0x4b, 0x96, 0x38, 0xfb, 0x3a, 0x90, 0x64, - 0x9b, 0x77, 0x75, 0x6d, 0xf2, 0xbf, 0x49, 0xfb, 0xba, 0xc3, 0xee, 0xf8, 0xb2, 0x1f, 0xb3, 0x5d, - 0x24, 0x75, 0x58, 0xff, 0x7b, 0x99, 0x3a, 0xac, 0xb0, 0xaf, 0xa9, 0xc3, 0xd4, 0x5f, 0xcb, 0xc0, - 0x44, 0x22, 0xce, 0x38, 0x79, 0x16, 0x80, 0x43, 0xa4, 0x78, 0x8e, 0x18, 0x20, 0x25, 0x8c, 0x3d, - 0x2e, 0xd6, 0xc0, 0x90, 0x8c, 0x5c, 0x85, 0x41, 0xfe, 0x4b, 0xc4, 0x60, 0x4a, 0x16, 0xe9, 0x74, - 0x4c, 0x43, 0x0b, 0x88, 0xc2, 0x5a, 0xf0, 0xe2, 0x30, 0x97, 0x5a, 0xc4, 0xdb, 0x68, 0x07, 0xb5, - 0x30, 0x32, 0xf5, 0x4b, 0x59, 0x18, 0x09, 0x1a, 0x5c, 0x32, 0x0e, 0x4a, 0xe7, 0x0a, 0x22, 0x64, - 0x7b, 0x6e, 0xbb, 0x90, 0xed, 0xb1, 0x49, 0x55, 0xc4, 0x68, 0xdf, 0xbf, 0x77, 0x4f, 0x5f, 0xc9, - 0xc2, 0xb1, 0xa0, 0xd6, 0x03, 0xbc, 0xa3, 0x7a, 0x1f, 0x89, 0xe4, 0xcb, 0x19, 0x50, 0x26, 0xcd, - 0x66, 0xd3, 0xb4, 0x1a, 0x15, 0x6b, 0xd5, 0x76, 0x5a, 0x38, 0xeb, 0x1d, 0xdc, 0x39, 0xad, 0xfa, - 0xa3, 0x19, 0x98, 0x10, 0x0d, 0x9a, 0xd2, 0x1d, 0xe3, 0xe0, 0x0e, 0xc1, 0xe2, 0x2d, 0x39, 0x38, - 0x7d, 0x51, 0xbf, 0x91, 0x05, 0x98, 0xb3, 0xeb, 0x77, 0x0f, 0xf9, 0xb3, 0xa9, 0x97, 0xa1, 0xc0, - 0x03, 0x61, 0x09, 0x8d, 0x9d, 0x10, 0xcf, 0x83, 0xd8, 0xa7, 0x71, 0xc4, 0xe4, 0xb8, 0x98, 0x8f, - 0x0b, 0x3c, 0x90, 0x96, 0x92, 0xd1, 0x44, 0x11, 0x56, 0x29, 0xa3, 0x13, 0x0b, 0x46, 0x50, 0x29, - 0x83, 0x45, 0x2b, 0xdd, 0xda, 0x2c, 0xe6, 0x9b, 0x76, 0xfd, 0xae, 0x86, 0xf4, 0xea, 0xdf, 0x66, - 0xb8, 0xec, 0x0e, 0xf9, 0xe3, 0x4f, 0xff, 0xf3, 0xf3, 0xbb, 0xfc, 0xfc, 0x1f, 0xcb, 0xc0, 0x09, - 0x8d, 0xd6, 0xed, 0x7b, 0xd4, 0xd9, 0x98, 0xb2, 0x0d, 0x7a, 0x83, 0x5a, 0xd4, 0x39, 0xa8, 0x11, - 0xf5, 0x3f, 0x62, 0x8e, 0x8b, 0xb0, 0x31, 0xb7, 0x5c, 0x6a, 0x1c, 0x9e, 0xfc, 0x23, 0xea, 0x7f, - 0x3f, 0x00, 0x4a, 0xaa, 0x69, 0x7b, 0x68, 0xcd, 0xb9, 0xae, 0xfb, 0x95, 0xfc, 0x7e, 0xed, 0x57, - 0xfa, 0x77, 0xb7, 0x5f, 0x29, 0xec, 0x76, 0xbf, 0x32, 0xb0, 0x93, 0xfd, 0x4a, 0x2b, 0xbe, 0x5f, - 0x19, 0xc4, 0xfd, 0xca, 0xb3, 0x3d, 0xf7, 0x2b, 0xd3, 0x96, 0xf1, 0x80, 0xbb, 0x95, 0x43, 0x9b, - 0x1b, 0xf7, 0x41, 0xb6, 0x59, 0x97, 0xd8, 0xa4, 0x58, 0xb7, 0x1d, 0x83, 0x1a, 0x62, 0x77, 0x85, - 0x47, 0xfb, 0x8e, 0x80, 0x69, 0x01, 0x36, 0x91, 0x68, 0x78, 0x74, 0x27, 0x89, 0x86, 0xf7, 0x61, - 0xff, 0xf5, 0xc5, 0x2c, 0x4c, 0x4c, 0x51, 0xc7, 0xe3, 0x91, 0x36, 0xf7, 0xc3, 0x73, 0xad, 0x04, - 0xc7, 0x24, 0x86, 0x68, 0x91, 0x67, 0x43, 0x6f, 0xbc, 0x3a, 0x75, 0xbc, 0xb8, 0x33, 0x5f, 0x9c, - 0x9e, 0x55, 0xef, 0x27, 0xfb, 0x12, 0x63, 0x37, 0xa8, 0xde, 0x87, 0x73, 0x41, 0x9a, 0xe2, 0x97, - 0x16, 0xd0, 0x4b, 0xf9, 0xbb, 0xf2, 0xbb, 0xcf, 0xdf, 0xa5, 0xfe, 0x6a, 0x06, 0x2e, 0x6a, 0xd4, - 0xa2, 0xeb, 0xfa, 0x4a, 0x93, 0x4a, 0xcd, 0x12, 0x2b, 0x03, 0x9b, 0x35, 0x4c, 0xb7, 0xa5, 0x7b, - 0xf5, 0xb5, 0x3d, 0xc9, 0x68, 0x06, 0x46, 0xe4, 0xf9, 0x6b, 0x17, 0x73, 0x5b, 0xa4, 0x9c, 0xfa, - 0x4f, 0x72, 0x30, 0x30, 0x69, 0x7b, 0x6f, 0xd8, 0x7b, 0x4c, 0x28, 0x17, 0x4e, 0xf9, 0xd9, 0x5d, - 0x1c, 0xe8, 0x7c, 0x18, 0x2b, 0x97, 0x62, 0xec, 0xa3, 0xa7, 0xe7, 0x8a, 0x9d, 0xc8, 0x45, 0xe0, - 0x93, 0xed, 0x32, 0x95, 0xdc, 0xf3, 0x30, 0x84, 0x41, 0x5a, 0xa4, 0x23, 0x57, 0xf4, 0xa3, 0xf6, - 0x18, 0x30, 0x5e, 0x47, 0x48, 0x4a, 0x3e, 0x11, 0x09, 0x0d, 0x5a, 0xd8, 0x7b, 0xea, 0x39, 0x39, - 0x4a, 0xe8, 0xb3, 0xfc, 0xb6, 0x0e, 0xdb, 0x24, 0xa5, 0xe9, 0xc0, 0xa3, 0x92, 0x58, 0x93, 0x02, - 0xc2, 0xfd, 0x4b, 0x0b, 0xa7, 0x7e, 0x2f, 0x0f, 0x23, 0xbe, 0xcb, 0xed, 0x01, 0x75, 0xfb, 0xd3, - 0x50, 0x98, 0xb5, 0xa5, 0x24, 0x03, 0xe8, 0xa2, 0xbb, 0x66, 0xbb, 0x31, 0xdf, 0x63, 0x41, 0xc4, - 0x04, 0xb6, 0x60, 0x1b, 0xb2, 0x83, 0x39, 0x0a, 0xcc, 0xb2, 0x8d, 0xc4, 0x03, 0xdd, 0x80, 0x90, - 0x5c, 0x84, 0x3c, 0xfa, 0xe6, 0x4b, 0x07, 0xed, 0x31, 0x7f, 0x7c, 0xc4, 0x4b, 0x0a, 0x55, 0xd8, - 0xad, 0x42, 0x0d, 0x3c, 0xa8, 0x42, 0x0d, 0xee, 0xaf, 0x42, 0xbd, 0x05, 0x23, 0x58, 0x93, 0x9f, - 0xa3, 0x6c, 0xfb, 0x35, 0xf1, 0x8c, 0x58, 0xb6, 0x46, 0x79, 0xbb, 0x45, 0xa6, 0x32, 0x5c, 0xad, - 0x22, 0xac, 0x62, 0x6a, 0x07, 0x7b, 0x50, 0xbb, 0x3f, 0xc9, 0xc0, 0xc0, 0x2d, 0xeb, 0xae, 0x65, - 0xaf, 0xef, 0x4d, 0xe3, 0x9e, 0x85, 0x61, 0xc1, 0x46, 0x5a, 0x18, 0xf0, 0xcd, 0x75, 0x87, 0x83, - 0x6b, 0xc8, 0x49, 0x93, 0xa9, 0xc8, 0x2b, 0x41, 0x21, 0x7c, 0x7e, 0x93, 0x0b, 0xd3, 0x74, 0xf8, - 0x85, 0xea, 0xd1, 0xcc, 0x02, 0x32, 0x39, 0x39, 0x07, 0xf9, 0x32, 0x6b, 0xaa, 0x14, 0xa7, 0x96, - 0x35, 0x45, 0x43, 0xa8, 0xfa, 0xc5, 0x3c, 0x8c, 0xc5, 0xce, 0xac, 0x9e, 0x84, 0x21, 0x71, 0x66, - 0x64, 0xfa, 0xa9, 0x0e, 0xf0, 0x79, 0x4e, 0x00, 0xd4, 0x06, 0xf9, 0x9f, 0x15, 0x83, 0x7c, 0x14, - 0x06, 0x6c, 0x17, 0xd7, 0x33, 0xfc, 0x96, 0xb1, 0x70, 0x08, 0x2d, 0x56, 0x59, 0xdb, 0xf9, 0xe0, - 0x10, 0x24, 0xb2, 0x46, 0xda, 0x2e, 0x7e, 0xda, 0x75, 0x18, 0xd2, 0x5d, 0x97, 0x7a, 0x35, 0x4f, - 0x6f, 0xc8, 0xd9, 0x0f, 0x02, 0xa0, 0x3c, 0x3a, 0x10, 0xb8, 0xac, 0x37, 0xc8, 0xeb, 0x30, 0x5a, - 0x77, 0x28, 0xae, 0x78, 0x7a, 0x93, 0xb5, 0x52, 0xb2, 0x48, 0x23, 0x08, 0xf9, 0x7e, 0x23, 0x44, - 0x54, 0x0c, 0x72, 0x1b, 0x46, 0xc5, 0xe7, 0x70, 0xdf, 0x78, 0x1c, 0x68, 0x63, 0xe1, 0x0a, 0xc4, - 0x45, 0xc2, 0xbd, 0xe3, 0xc5, 0x13, 0x09, 0x99, 0x5c, 0xe6, 0x6b, 0x48, 0xa4, 0x64, 0x11, 0xc8, - 0x3a, 0x5d, 0xa9, 0xe9, 0x1d, 0x6f, 0x8d, 0xd5, 0xc5, 0x83, 0x77, 0x8b, 0xa4, 0x7f, 0xf8, 0xae, - 0x20, 0x89, 0x95, 0x9f, 0x5b, 0xac, 0xd3, 0x95, 0x52, 0x04, 0x49, 0xee, 0xc0, 0xc9, 0x64, 0x11, - 0xf6, 0xc9, 0xfc, 0xf0, 0xfe, 0xf1, 0xad, 0xcd, 0x62, 0x31, 0x95, 0x40, 0x62, 0x7b, 0x3c, 0xc1, - 0xb6, 0x62, 0xbc, 0x91, 0x1f, 0x1c, 0x18, 0x1f, 0xd4, 0xc6, 0x58, 0x59, 0xdf, 0xfa, 0x33, 0x0d, - 0xf5, 0xdb, 0x19, 0x66, 0xe5, 0xb1, 0x0f, 0xc2, 0xac, 0xc7, 0x4c, 0xd7, 0x5b, 0xbb, 0xd4, 0xf5, - 0x56, 0x98, 0x9f, 0xb0, 0xe0, 0xf6, 0x98, 0x5d, 0x35, 0x81, 0x25, 0x57, 0xa0, 0x60, 0xc8, 0x07, - 0x5e, 0xa7, 0xa2, 0x9d, 0xe0, 0xd7, 0xa3, 0x09, 0x2a, 0x72, 0x09, 0xf2, 0x6c, 0xb5, 0x89, 0xef, - 0x76, 0x65, 0xc3, 0x40, 0x43, 0x0a, 0xf5, 0x07, 0xb2, 0x30, 0x22, 0x7d, 0xcd, 0xb5, 0x3d, 0x7d, - 0xce, 0x4b, 0x3b, 0x6b, 0xa6, 0xef, 0x94, 0x82, 0xdb, 0x20, 0xbf, 0xc9, 0xd7, 0x03, 0x51, 0xec, - 0xe8, 0xc2, 0x48, 0x08, 0xe6, 0x79, 0xf1, 0xa1, 0x85, 0x9d, 0xef, 0xfc, 0x18, 0xfd, 0x1b, 0xf9, - 0xc1, 0xec, 0x78, 0xee, 0x8d, 0xfc, 0x60, 0x7e, 0xbc, 0x1f, 0x23, 0x5d, 0x61, 0x70, 0x69, 0xbe, - 0xad, 0xb6, 0x56, 0xcd, 0xc6, 0x21, 0x7f, 0x9d, 0xb1, 0xbf, 0x51, 0xc0, 0x62, 0xb2, 0x39, 0xe4, - 0x4f, 0x35, 0xde, 0x53, 0xd9, 0x1c, 0xe5, 0x33, 0x14, 0xb2, 0xf9, 0xd3, 0x0c, 0x28, 0xa9, 0xb2, - 0x29, 0x1d, 0x90, 0x9f, 0xc2, 0xfe, 0x65, 0x35, 0xfc, 0x6e, 0x16, 0x26, 0x2a, 0x96, 0x47, 0x1b, - 0x7c, 0xb3, 0x77, 0xc8, 0xa7, 0x8a, 0x9b, 0x30, 0x2c, 0x7d, 0x8c, 0xe8, 0xf3, 0x47, 0x82, 0xad, - 0x74, 0x88, 0xea, 0xc2, 0x49, 0x2e, 0xbd, 0x8f, 0x89, 0xd0, 0x63, 0x42, 0x3e, 0xe4, 0x73, 0xce, - 0xe1, 0x10, 0xf2, 0x21, 0x9f, 0xbc, 0xde, 0xa7, 0x42, 0xfe, 0xa7, 0x19, 0x38, 0x9e, 0x52, 0x39, - 0xb9, 0x08, 0x03, 0xd5, 0xce, 0x0a, 0x06, 0xb6, 0xca, 0x84, 0x1e, 0xbd, 0x6e, 0x67, 0x05, 0x63, - 0x5a, 0x69, 0x3e, 0x92, 0x2c, 0xe3, 0xf3, 0xf5, 0xc5, 0x4a, 0x79, 0x4a, 0x48, 0x55, 0x95, 0x1e, - 0xe2, 0x33, 0x70, 0xda, 0x97, 0x05, 0x4f, 0xdc, 0x6d, 0xd3, 0xa8, 0xc7, 0x9e, 0xb8, 0xb3, 0x32, - 0xe4, 0x93, 0x30, 0x54, 0x7a, 0xa7, 0xe3, 0x50, 0xe4, 0xcb, 0x25, 0xfe, 0x81, 0x80, 0xaf, 0x8f, - 0x48, 0xe3, 0xcc, 0x5f, 0xeb, 0x33, 0x8a, 0x38, 0xef, 0x90, 0xa1, 0xfa, 0xa5, 0x0c, 0x9c, 0xed, - 0xde, 0x3a, 0xf2, 0x61, 0x18, 0x60, 0x3b, 0xf3, 0x92, 0xb6, 0x20, 0x3e, 0x9d, 0x67, 0x00, 0xb5, - 0x9b, 0xb4, 0xa6, 0x3b, 0xb2, 0xb1, 0xef, 0x93, 0x91, 0x57, 0x61, 0xb8, 0xe2, 0xba, 0x1d, 0xea, - 0x54, 0x9f, 0xbd, 0xa5, 0x55, 0xc4, 0x9e, 0x10, 0xf7, 0x1c, 0x26, 0x82, 0x6b, 0xee, 0xb3, 0xb1, - 0xd0, 0x55, 0x32, 0xbd, 0xfa, 0xf9, 0x0c, 0x9c, 0xeb, 0xf5, 0x55, 0xe4, 0x59, 0x18, 0x5c, 0xa6, - 0x96, 0x6e, 0x79, 0x95, 0xb2, 0x68, 0x12, 0x6e, 0xb1, 0x3c, 0x84, 0x45, 0x77, 0x0a, 0x01, 0x21, - 0x2b, 0xc4, 0x8f, 0x04, 0x03, 0x1f, 0x04, 0x7e, 0x7c, 0x89, 0xb0, 0x58, 0x21, 0x9f, 0x50, 0xfd, - 0xdd, 0xcf, 0x40, 0xff, 0xa2, 0x45, 0x17, 0x57, 0xc9, 0x33, 0x30, 0xc4, 0x74, 0x1f, 0xd3, 0xef, - 0x8b, 0x81, 0x36, 0x21, 0x0f, 0x18, 0x44, 0xcc, 0xf6, 0x69, 0x21, 0x15, 0xb9, 0x2e, 0xe7, 0xfc, - 0x16, 0xea, 0x40, 0xe4, 0x32, 0x1c, 0x33, 0xdb, 0xa7, 0xc9, 0xb9, 0xc1, 0xaf, 0xcb, 0xb9, 0x96, - 0x45, 0x67, 0x47, 0x4a, 0x71, 0x8c, 0x5f, 0x4a, 0x4c, 0x03, 0x73, 0x69, 0x09, 0x89, 0xe3, 0x36, - 0x41, 0x92, 0x62, 0xb6, 0x4f, 0x4b, 0x4f, 0x64, 0x3c, 0x22, 0xbb, 0x31, 0xc5, 0x6f, 0x21, 0x65, - 0xdc, 0x6c, 0x9f, 0x16, 0xa1, 0x25, 0x2f, 0xc0, 0xb0, 0xf8, 0xfd, 0x86, 0x6d, 0x5a, 0xf1, 0x18, - 0x16, 0x12, 0x6a, 0xb6, 0x4f, 0x93, 0x29, 0xa5, 0x4a, 0x97, 0x1c, 0xd3, 0xf2, 0xc4, 0xcb, 0xb8, - 0x78, 0xa5, 0x88, 0x93, 0x2a, 0xc5, 0xdf, 0xe4, 0x55, 0x18, 0x0d, 0x82, 0x83, 0xbc, 0x4d, 0xeb, - 0x9e, 0x38, 0xd2, 0x39, 0x19, 0x2b, 0xcc, 0x91, 0xb3, 0x7d, 0x5a, 0x94, 0x9a, 0x5c, 0x82, 0x82, - 0x46, 0x5d, 0xf3, 0x1d, 0xff, 0xfe, 0x62, 0x4c, 0x9a, 0xce, 0xcc, 0x77, 0x98, 0x94, 0x04, 0x9e, - 0xf5, 0x4e, 0x78, 0x61, 0x22, 0x0e, 0x60, 0x48, 0xac, 0x96, 0x69, 0xcb, 0x60, 0xbd, 0x23, 0xdd, - 0x96, 0xbd, 0x1e, 0x86, 0x4c, 0x11, 0x89, 0xd6, 0x86, 0xe3, 0x6f, 0x53, 0x65, 0xec, 0x6c, 0x9f, - 0x16, 0xa3, 0x97, 0xa4, 0x5a, 0x36, 0xdd, 0xbb, 0x22, 0x4a, 0x5d, 0x5c, 0xaa, 0x0c, 0x25, 0x49, - 0x95, 0xfd, 0x94, 0xaa, 0x5e, 0xa0, 0xde, 0xba, 0xed, 0xdc, 0x15, 0x31, 0xe9, 0xe2, 0x55, 0x0b, - 0xac, 0x54, 0xb5, 0x80, 0xc8, 0x55, 0xb3, 0x45, 0x66, 0x2c, 0xbd, 0x6a, 0xdd, 0xd3, 0xe5, 0xaa, - 0xf9, 0xfe, 0xd2, 0xef, 0xa4, 0x39, 0xaa, 0xdf, 0xe3, 0xf9, 0x6e, 0x93, 0x1d, 0x8a, 0x38, 0xa9, - 0x43, 0xf1, 0x37, 0xab, 0x54, 0xca, 0x69, 0x2a, 0x12, 0xda, 0x06, 0x95, 0x4a, 0x28, 0x56, 0xa9, - 0x9c, 0xfd, 0xf4, 0xba, 0x9c, 0xea, 0x53, 0x99, 0x88, 0x76, 0x50, 0x88, 0x61, 0x1d, 0x24, 0xa5, - 0x04, 0x2d, 0x62, 0x1a, 0x41, 0x85, 0x20, 0xf9, 0x70, 0xd0, 0xc2, 0xa9, 0xa5, 0xd9, 0x3e, 0x0d, - 0x13, 0x0c, 0xaa, 0x3c, 0x41, 0xa5, 0x72, 0x1c, 0x29, 0x46, 0x7c, 0x0a, 0x06, 0x9b, 0xed, 0xd3, - 0x78, 0xf2, 0xca, 0x67, 0xa4, 0x54, 0x50, 0xca, 0x89, 0xe8, 0x14, 0x11, 0x20, 0xd8, 0x14, 0x11, - 0x26, 0x8c, 0x9a, 0x49, 0xa6, 0x4b, 0x52, 0x4e, 0x46, 0x57, 0xd4, 0x38, 0x7e, 0xb6, 0x4f, 0x4b, - 0xa6, 0x58, 0x7a, 0x21, 0x92, 0x41, 0x48, 0x39, 0x15, 0x0b, 0x1c, 0x13, 0xa2, 0x98, 0xb8, 0xe4, - 0x5c, 0x43, 0x8b, 0xa9, 0x39, 0xbf, 0x95, 0xd3, 0xd1, 0xe5, 0x38, 0x85, 0x64, 0xb6, 0x4f, 0x4b, - 0xcd, 0x16, 0x3e, 0x95, 0xc8, 0xe3, 0xa3, 0x28, 0xd1, 0xcb, 0xda, 0x18, 0x7a, 0xb6, 0x4f, 0x4b, - 0x64, 0xfe, 0xb9, 0x2e, 0x27, 0xd0, 0x51, 0xce, 0x44, 0x3b, 0x31, 0xc4, 0xb0, 0x4e, 0x94, 0x12, - 0xed, 0x5c, 0x97, 0x93, 0xaa, 0x28, 0x67, 0x93, 0xa5, 0xc2, 0x99, 0x53, 0x4a, 0xbe, 0xa2, 0xa5, - 0xe7, 0x89, 0x50, 0x1e, 0x11, 0x99, 0xfa, 0x44, 0xf9, 0x34, 0x9a, 0xd9, 0x3e, 0x2d, 0x3d, 0xc7, - 0x84, 0x96, 0x9e, 0x60, 0x41, 0x39, 0xd7, 0x8b, 0x67, 0xd0, 0xba, 0xf4, 0xe4, 0x0c, 0x7a, 0x8f, - 0x70, 0xf7, 0xca, 0xf9, 0x68, 0xd4, 0xca, 0xae, 0x84, 0xb3, 0x7d, 0x5a, 0x8f, 0xa0, 0xf9, 0xb7, - 0xba, 0xc4, 0x9e, 0x57, 0x2e, 0x44, 0x13, 0x75, 0xa6, 0x12, 0xcd, 0xf6, 0x69, 0x5d, 0x22, 0xd7, - 0xdf, 0xea, 0x12, 0x9a, 0x5c, 0x29, 0xf6, 0x64, 0x1b, 0xc8, 0xa3, 0x4b, 0x60, 0xf3, 0xc5, 0xd4, - 0xa8, 0xde, 0xca, 0xa3, 0x51, 0xd5, 0x4d, 0x21, 0x61, 0xaa, 0x9b, 0x16, 0x0f, 0x7c, 0x31, 0x35, - 0x0c, 0xb5, 0xf2, 0x58, 0x0f, 0x86, 0x41, 0x1b, 0x53, 0x03, 0x58, 0x2f, 0xa6, 0xc6, 0x81, 0x56, - 0xd4, 0x28, 0xc3, 0x14, 0x12, 0xc6, 0x30, 0x2d, 0x82, 0xf4, 0x62, 0x6a, 0xb8, 0x60, 0xe5, 0xf1, - 0x1e, 0x0c, 0xc3, 0x16, 0xa6, 0x05, 0x1a, 0x7e, 0x21, 0x12, 0xaf, 0x57, 0xf9, 0x40, 0x74, 0xde, - 0x90, 0x50, 0x6c, 0xde, 0x90, 0x23, 0xfb, 0x4e, 0x25, 0x22, 0x12, 0x2a, 0x4f, 0x44, 0x87, 0x79, - 0x0c, 0xcd, 0x86, 0x79, 0x3c, 0x86, 0xe1, 0x54, 0x22, 0x32, 0x9b, 0x72, 0xb1, 0x1b, 0x13, 0x44, - 0x47, 0x99, 0xf0, 0x58, 0x6e, 0x95, 0x94, 0xd0, 0x60, 0xca, 0x07, 0xa3, 0x8e, 0x86, 0x09, 0x82, - 0xd9, 0x3e, 0x2d, 0x25, 0xa0, 0x98, 0x96, 0x1e, 0x07, 0x43, 0xb9, 0x14, 0x1d, 0xb6, 0x69, 0x34, - 0x6c, 0xd8, 0xa6, 0xc6, 0xd0, 0x98, 0x4b, 0xf3, 0x86, 0x56, 0x2e, 0x47, 0x0d, 0xb3, 0x24, 0x05, - 0x33, 0xcc, 0x52, 0xbc, 0xa8, 0xb5, 0xf4, 0xc8, 0x0e, 0xca, 0x93, 0x3d, 0x5b, 0x88, 0x34, 0x29, - 0x2d, 0xe4, 0x81, 0x0e, 0x42, 0xdb, 0xe9, 0x56, 0xbb, 0x69, 0xeb, 0x86, 0xf2, 0xa1, 0x54, 0xdb, - 0x89, 0x23, 0x25, 0xdb, 0x89, 0x03, 0xd8, 0x2a, 0x2f, 0x3b, 0xdd, 0x2a, 0x4f, 0x45, 0x57, 0x79, - 0x19, 0xc7, 0x56, 0xf9, 0x88, 0x83, 0xee, 0x54, 0xc2, 0x41, 0x55, 0x79, 0x3a, 0xaa, 0x00, 0x31, - 0x34, 0x53, 0x80, 0xb8, 0x4b, 0xeb, 0xa7, 0xbb, 0xbb, 0x74, 0x2a, 0x57, 0x90, 0xdb, 0xa3, 0x3e, - 0xb7, 0x6e, 0x74, 0xb3, 0x7d, 0x5a, 0x77, 0xb7, 0xd0, 0x4a, 0x8a, 0x87, 0xa6, 0x72, 0x35, 0xaa, - 0x60, 0x09, 0x02, 0xa6, 0x60, 0x49, 0xbf, 0xce, 0x4a, 0x8a, 0x8b, 0xa5, 0xf2, 0xe1, 0xae, 0xac, - 0x82, 0x6f, 0x4e, 0x71, 0xcc, 0xbc, 0x2e, 0xfb, 0x48, 0x2a, 0xcf, 0x44, 0x17, 0xbb, 0x10, 0xc3, - 0x16, 0x3b, 0xc9, 0x97, 0xf2, 0xba, 0xec, 0x1d, 0xa8, 0x5c, 0x4b, 0x96, 0x0a, 0x97, 0x48, 0xc9, - 0x8b, 0x50, 0x4b, 0x77, 0xaa, 0x53, 0x9e, 0x8d, 0x6a, 0x5d, 0x1a, 0x0d, 0xd3, 0xba, 0x54, 0x87, - 0xbc, 0x99, 0xa4, 0x6f, 0x9c, 0x72, 0x3d, 0x7e, 0x96, 0x10, 0xc5, 0x33, 0xcb, 0x27, 0xe1, 0x4f, - 0xf7, 0x7a, 0x3c, 0x48, 0x93, 0xf2, 0x5c, 0xec, 0x32, 0x23, 0x82, 0x65, 0xf6, 0x6d, 0x2c, 0xa8, - 0xd3, 0xeb, 0xf1, 0xb8, 0x46, 0xca, 0xf3, 0xe9, 0x1c, 0x02, 0x5d, 0x89, 0xc7, 0x41, 0x7a, 0x3d, - 0x1e, 0x0a, 0x48, 0x79, 0x21, 0x9d, 0x43, 0x20, 0xdd, 0x78, 0xe8, 0xa0, 0x67, 0xa4, 0xe0, 0xc4, - 0xca, 0x47, 0xa2, 0xa6, 0x63, 0x80, 0x60, 0xa6, 0x63, 0x18, 0xc2, 0xf8, 0x19, 0x29, 0xa8, 0xaf, - 0xf2, 0x62, 0xa2, 0x48, 0xd0, 0x58, 0x29, 0xf4, 0xef, 0x33, 0x52, 0x30, 0x5c, 0xe5, 0xa5, 0x44, - 0x91, 0xa0, 0x75, 0x52, 0xc8, 0x5c, 0xa3, 0xd7, 0xab, 0x29, 0xe5, 0xe5, 0xe8, 0x11, 0x47, 0x77, - 0xca, 0xd9, 0x3e, 0xad, 0xd7, 0xeb, 0xab, 0x4f, 0x77, 0xf7, 0x34, 0x54, 0x5e, 0x89, 0x0e, 0xe1, - 0x6e, 0x74, 0x6c, 0x08, 0x77, 0xf5, 0x56, 0x7c, 0x35, 0xf6, 0x82, 0x5a, 0x79, 0x35, 0x3a, 0xc5, - 0x45, 0x90, 0x6c, 0x8a, 0x8b, 0xbf, 0xb7, 0x8e, 0x3c, 0x0d, 0x56, 0x3e, 0x1a, 0x9d, 0xe2, 0x64, - 0x1c, 0x9b, 0xe2, 0x22, 0xcf, 0x88, 0xa7, 0x12, 0x2f, 0x56, 0x95, 0xd7, 0xa2, 0x53, 0x5c, 0x0c, - 0xcd, 0xa6, 0xb8, 0xf8, 0x1b, 0xd7, 0x57, 0x63, 0x0f, 0x37, 0x95, 0xd7, 0xd3, 0xdb, 0x8f, 0x48, - 0xb9, 0xfd, 0xfc, 0x99, 0xa7, 0x96, 0xfe, 0x02, 0x51, 0x29, 0x45, 0xc7, 0x6f, 0x1a, 0x0d, 0x1b, - 0xbf, 0xa9, 0xaf, 0x17, 0xe3, 0x1b, 0x07, 0xa1, 0x55, 0x93, 0x3d, 0x36, 0x0e, 0xa1, 0x29, 0x92, - 0x02, 0x8e, 0xec, 0x91, 0xf9, 0x46, 0x68, 0xaa, 0xcb, 0x1e, 0xd9, 0xdf, 0x06, 0xc5, 0xe8, 0xd9, - 0xec, 0x9a, 0x70, 0x7c, 0x53, 0xca, 0xd1, 0xd9, 0x35, 0x41, 0xc0, 0x66, 0xd7, 0xa4, 0xbb, 0xdc, - 0x0c, 0x8c, 0x0b, 0x2d, 0xe2, 0xfe, 0x7c, 0xa6, 0xd5, 0x50, 0xa6, 0x63, 0x0f, 0x80, 0x62, 0x78, - 0x36, 0x3b, 0xc5, 0x61, 0xb8, 0x5e, 0x73, 0xd8, 0x54, 0xd3, 0x6c, 0xaf, 0xd8, 0xba, 0x63, 0x54, - 0xa9, 0x65, 0x28, 0x33, 0xb1, 0xf5, 0x3a, 0x85, 0x06, 0xd7, 0xeb, 0x14, 0x38, 0x06, 0x26, 0x8a, - 0xc1, 0x35, 0x5a, 0xa7, 0xe6, 0x3d, 0xaa, 0xdc, 0x40, 0xb6, 0xc5, 0x6e, 0x6c, 0x05, 0xd9, 0x6c, - 0x9f, 0xd6, 0x8d, 0x03, 0xb3, 0xd5, 0xe7, 0x37, 0xaa, 0x6f, 0xce, 0x05, 0x8f, 0x5e, 0x97, 0x1c, - 0xda, 0xd6, 0x1d, 0xaa, 0xcc, 0x46, 0x6d, 0xf5, 0x54, 0x22, 0x66, 0xab, 0xa7, 0x22, 0x92, 0x6c, - 0xfd, 0xb1, 0x50, 0xe9, 0xc5, 0x36, 0x1c, 0x11, 0xe9, 0xa5, 0xd9, 0xec, 0x14, 0x45, 0x30, 0x01, - 0xcd, 0xd9, 0x56, 0x03, 0x4f, 0x2a, 0xde, 0x88, 0xce, 0x4e, 0xdd, 0x29, 0xd9, 0xec, 0xd4, 0x1d, - 0xcb, 0x54, 0x3d, 0x8a, 0xe5, 0x63, 0xf0, 0x66, 0x54, 0xd5, 0x53, 0x48, 0x98, 0xaa, 0xa7, 0x80, - 0x93, 0x0c, 0x35, 0xea, 0x52, 0x4f, 0x99, 0xeb, 0xc5, 0x10, 0x49, 0x92, 0x0c, 0x11, 0x9c, 0x64, - 0x38, 0x43, 0xbd, 0xfa, 0x9a, 0x32, 0xdf, 0x8b, 0x21, 0x92, 0x24, 0x19, 0x22, 0x98, 0x6d, 0x36, - 0xa3, 0xe0, 0xc9, 0x4e, 0xf3, 0xae, 0xdf, 0x67, 0x0b, 0xd1, 0xcd, 0x66, 0x57, 0x42, 0xb6, 0xd9, - 0xec, 0x8a, 0x24, 0x9f, 0xdf, 0xb1, 0x63, 0xa6, 0xb2, 0x88, 0x15, 0x5e, 0x09, 0xed, 0x82, 0x9d, - 0x94, 0x9a, 0xed, 0xd3, 0x76, 0xea, 0xf8, 0xf9, 0xa1, 0xc0, 0x15, 0x4a, 0x59, 0xc2, 0xaa, 0x8e, - 0x05, 0x67, 0x15, 0x1c, 0x3c, 0xdb, 0xa7, 0x05, 0xce, 0x52, 0x2f, 0xc0, 0x30, 0x7e, 0x54, 0xc5, - 0x32, 0xbd, 0xf2, 0xa4, 0xf2, 0x66, 0x74, 0xcb, 0x24, 0xa1, 0xd8, 0x96, 0x49, 0xfa, 0xc9, 0x26, - 0x71, 0xfc, 0xc9, 0xa7, 0x98, 0xf2, 0xa4, 0xa2, 0x45, 0x27, 0xf1, 0x08, 0x92, 0x4d, 0xe2, 0x11, - 0x40, 0x50, 0x6f, 0xd9, 0xb1, 0xdb, 0xe5, 0x49, 0xa5, 0x9a, 0x52, 0x2f, 0x47, 0x05, 0xf5, 0xf2, - 0x9f, 0x41, 0xbd, 0xd5, 0xb5, 0x8e, 0x57, 0x66, 0xdf, 0xb8, 0x9c, 0x52, 0xaf, 0x8f, 0x0c, 0xea, - 0xf5, 0x01, 0x6c, 0x2a, 0x44, 0xc0, 0x92, 0x63, 0xb3, 0x49, 0xfb, 0xa6, 0xd9, 0x6c, 0x2a, 0xb7, - 0xa2, 0x53, 0x61, 0x1c, 0xcf, 0xa6, 0xc2, 0x38, 0x8c, 0x99, 0x9e, 0xbc, 0x55, 0x74, 0xa5, 0xd3, - 0x50, 0x6e, 0x47, 0x4d, 0xcf, 0x10, 0xc3, 0x4c, 0xcf, 0xf0, 0x17, 0xee, 0x2e, 0xd8, 0x2f, 0x8d, - 0xae, 0x3a, 0xd4, 0x5d, 0x53, 0xee, 0xc4, 0x76, 0x17, 0x12, 0x0e, 0x77, 0x17, 0xd2, 0x6f, 0xd2, - 0x80, 0x47, 0x22, 0x0b, 0x8d, 0x7f, 0xf7, 0x54, 0xa5, 0xba, 0x53, 0x5f, 0x53, 0x3e, 0x86, 0xac, - 0x1e, 0x4f, 0x5d, 0xaa, 0xa2, 0xa4, 0xb3, 0x7d, 0x5a, 0x2f, 0x4e, 0xb8, 0x2d, 0x7f, 0x73, 0x8e, - 0x47, 0x10, 0xd4, 0x96, 0xa6, 0xfc, 0x4d, 0xe8, 0x5b, 0xb1, 0x6d, 0x79, 0x92, 0x04, 0xb7, 0xe5, - 0x49, 0x30, 0x69, 0xc3, 0x85, 0xd8, 0x56, 0x6d, 0x5e, 0x6f, 0xb2, 0x7d, 0x09, 0x35, 0x96, 0xf4, - 0xfa, 0x5d, 0xea, 0x29, 0x1f, 0x47, 0xde, 0x17, 0xbb, 0x6c, 0xf8, 0x62, 0xd4, 0xb3, 0x7d, 0xda, - 0x36, 0xfc, 0x88, 0x0a, 0xf9, 0xea, 0xcc, 0xf2, 0x92, 0xf2, 0x89, 0xe8, 0xf9, 0x26, 0x83, 0xcd, - 0xf6, 0x69, 0x88, 0x63, 0x56, 0xda, 0xad, 0x76, 0xc3, 0xd1, 0x0d, 0xca, 0x0d, 0x2d, 0xb4, 0xdd, - 0x84, 0x01, 0xfa, 0xc9, 0xa8, 0x95, 0xd6, 0x8d, 0x8e, 0x59, 0x69, 0xdd, 0x70, 0x4c, 0x51, 0x23, - 0xc1, 0xf2, 0x95, 0x4f, 0x45, 0x15, 0x35, 0x82, 0x64, 0x8a, 0x1a, 0x0d, 0xad, 0xff, 0x31, 0x38, - 0x15, 0xec, 0xe7, 0xc5, 0xfa, 0xcb, 0x3b, 0x4d, 0xf9, 0x34, 0xf2, 0xb9, 0x90, 0xb8, 0x0c, 0x88, - 0x50, 0xcd, 0xf6, 0x69, 0x5d, 0xca, 0xb3, 0x15, 0x37, 0x91, 0x07, 0x46, 0x98, 0x17, 0x9f, 0x89, - 0xae, 0xb8, 0x5d, 0xc8, 0xd8, 0x8a, 0xdb, 0x05, 0x95, 0xca, 0x5c, 0x08, 0x55, 0xdf, 0x86, 0x79, - 0x20, 0xd3, 0x6e, 0x1c, 0x52, 0x99, 0x0b, 0x4b, 0x6d, 0x65, 0x1b, 0xe6, 0x81, 0xb5, 0xd6, 0x8d, - 0x03, 0xb9, 0x04, 0x85, 0x6a, 0x75, 0x5e, 0xeb, 0x58, 0x4a, 0x3d, 0xe6, 0x03, 0x86, 0xd0, 0xd9, - 0x3e, 0x4d, 0xe0, 0x99, 0x19, 0x34, 0xdd, 0xd4, 0x5d, 0xcf, 0xac, 0xbb, 0x38, 0x62, 0xfc, 0x11, - 0x62, 0x44, 0xcd, 0xa0, 0x34, 0x1a, 0x66, 0x06, 0xa5, 0xc1, 0x99, 0xbd, 0x38, 0xa5, 0xbb, 0xae, - 0x6e, 0x19, 0x8e, 0x3e, 0x89, 0xcb, 0x04, 0x8d, 0x3d, 0x0f, 0x88, 0x60, 0x99, 0xbd, 0x18, 0x85, - 0xe0, 0xe1, 0xbb, 0x0f, 0xf1, 0xcd, 0x9c, 0xd5, 0xd8, 0xe1, 0x7b, 0x0c, 0x8f, 0x87, 0xef, 0x31, - 0x18, 0xda, 0x9d, 0x3e, 0x4c, 0xa3, 0x0d, 0x93, 0x89, 0x48, 0x69, 0xc4, 0xec, 0xce, 0x38, 0x01, - 0xda, 0x9d, 0x71, 0x60, 0xa4, 0x49, 0xfe, 0x72, 0xbb, 0xd6, 0xa5, 0x49, 0xe1, 0x2a, 0x9b, 0x28, - 0xc3, 0xd6, 0xef, 0x70, 0x70, 0x94, 0x37, 0x2c, 0xbd, 0x65, 0x97, 0x27, 0x7d, 0xa9, 0x9b, 0xd1, - 0xf5, 0xbb, 0x2b, 0x21, 0x5b, 0xbf, 0xbb, 0x22, 0xd9, 0xec, 0xea, 0x6f, 0xb4, 0xd6, 0x74, 0x87, - 0x1a, 0x65, 0xd3, 0xc1, 0x93, 0xc5, 0x0d, 0xbe, 0x35, 0x7c, 0x3b, 0x3a, 0xbb, 0xf6, 0x20, 0x65, - 0xb3, 0x6b, 0x0f, 0x34, 0x33, 0xf2, 0xd2, 0xd1, 0x1a, 0xd5, 0x0d, 0xe5, 0x6e, 0xd4, 0xc8, 0xeb, - 0x4e, 0xc9, 0x8c, 0xbc, 0xee, 0xd8, 0xee, 0x9f, 0x73, 0xc7, 0x31, 0x3d, 0xaa, 0x34, 0x77, 0xf2, - 0x39, 0x48, 0xda, 0xfd, 0x73, 0x10, 0xcd, 0x36, 0x84, 0xf1, 0x0e, 0x69, 0x45, 0x37, 0x84, 0xc9, - 0x6e, 0x88, 0x97, 0x60, 0x16, 0x8b, 0x78, 0x25, 0xa2, 0x58, 0x51, 0x8b, 0x45, 0x80, 0x99, 0xc5, - 0x12, 0xbe, 0x23, 0x89, 0x3c, 0x30, 0x50, 0xec, 0xe8, 0x1a, 0x2a, 0xe3, 0xd8, 0x1a, 0x1a, 0x79, - 0x8c, 0xf0, 0x42, 0xc4, 0x7b, 0x56, 0x69, 0x47, 0xad, 0x0e, 0x09, 0xc5, 0xac, 0x0e, 0xd9, 0xcf, - 0x76, 0x0a, 0x8e, 0xe1, 0x2d, 0xb8, 0xd6, 0x09, 0xee, 0x71, 0x3e, 0x1b, 0xfd, 0xcc, 0x18, 0x9a, - 0x7d, 0x66, 0x0c, 0x14, 0x61, 0x22, 0xa6, 0x2d, 0xa7, 0x0b, 0x93, 0xf0, 0x7c, 0x30, 0x06, 0x22, - 0x73, 0x40, 0xaa, 0xa5, 0xf9, 0xb9, 0x8a, 0xb1, 0x24, 0x5f, 0x91, 0xb9, 0xd1, 0x13, 0xd8, 0x24, - 0xc5, 0x6c, 0x9f, 0x96, 0x52, 0x8e, 0xbc, 0x0d, 0xe7, 0x04, 0x54, 0x3c, 0x01, 0xc4, 0x74, 0xd1, - 0x46, 0xb0, 0x20, 0x78, 0x51, 0xef, 0x8c, 0x5e, 0xb4, 0xb3, 0x7d, 0x5a, 0x4f, 0x5e, 0xdd, 0xeb, - 0x12, 0xeb, 0x43, 0x67, 0x27, 0x75, 0x05, 0x8b, 0x44, 0x4f, 0x5e, 0xdd, 0xeb, 0x12, 0x72, 0xbf, - 0xb7, 0x93, 0xba, 0x82, 0x4e, 0xe8, 0xc9, 0x8b, 0xb8, 0x50, 0xec, 0x85, 0x2f, 0x35, 0x9b, 0xca, - 0x3a, 0x56, 0xf7, 0xc1, 0x9d, 0x54, 0x57, 0x42, 0x83, 0x73, 0x3b, 0x8e, 0x6c, 0x96, 0x5e, 0x6c, - 0x53, 0xab, 0x1a, 0x59, 0x80, 0xee, 0x47, 0x67, 0xe9, 0x04, 0x01, 0x9b, 0xa5, 0x13, 0x40, 0x36, - 0xa0, 0x64, 0x27, 0x6c, 0x65, 0x23, 0x3a, 0xa0, 0x64, 0x1c, 0x1b, 0x50, 0x11, 0x87, 0xed, 0x45, - 0x38, 0xbe, 0x78, 0xd7, 0xd3, 0x7d, 0x0b, 0xd2, 0x15, 0x5d, 0xf9, 0x4e, 0xec, 0x92, 0x29, 0x49, - 0x82, 0x97, 0x4c, 0x49, 0x30, 0x1b, 0x23, 0x0c, 0x5c, 0xdd, 0xb0, 0xea, 0x33, 0xba, 0xd9, 0xec, - 0x38, 0x54, 0xf9, 0x77, 0xa2, 0x63, 0x24, 0x86, 0x66, 0x63, 0x24, 0x06, 0x62, 0x0b, 0x34, 0x03, - 0x95, 0x5c, 0xd7, 0x6c, 0x58, 0x62, 0x5f, 0xd9, 0x69, 0x7a, 0xca, 0xbf, 0x1b, 0x5d, 0xa0, 0xd3, - 0x68, 0xd8, 0x02, 0x9d, 0x06, 0xc7, 0x53, 0xa7, 0x94, 0x54, 0xea, 0xca, 0xbf, 0x17, 0x3b, 0x75, - 0x4a, 0xa1, 0xc1, 0x53, 0xa7, 0xb4, 0x34, 0xec, 0x33, 0x30, 0xce, 0x6d, 0xb2, 0x39, 0x33, 0xb8, - 0xab, 0xfe, 0xf7, 0xa3, 0xeb, 0x63, 0x1c, 0xcf, 0xd6, 0xc7, 0x38, 0x2c, 0xca, 0x47, 0x74, 0xc1, - 0x7f, 0xd0, 0x8d, 0x4f, 0x20, 0xff, 0x44, 0x19, 0x72, 0x43, 0xe6, 0x23, 0x46, 0xca, 0x0f, 0x64, - 0xba, 0x31, 0x0a, 0x86, 0x47, 0xa2, 0x50, 0x94, 0x91, 0x46, 0xef, 0x99, 0x74, 0x5d, 0xf9, 0x5c, - 0x57, 0x46, 0x9c, 0x20, 0xca, 0x88, 0xc3, 0xc8, 0x5b, 0x70, 0x2a, 0x84, 0xcd, 0xd3, 0xd6, 0x4a, - 0x30, 0x33, 0xfd, 0x60, 0x26, 0x6a, 0x06, 0xa7, 0x93, 0x31, 0x33, 0x38, 0x1d, 0x93, 0xc6, 0x5a, - 0x88, 0xee, 0x3f, 0xdc, 0x86, 0x75, 0x20, 0xc1, 0x2e, 0x0c, 0xd2, 0x58, 0x0b, 0x69, 0xfe, 0xd0, - 0x36, 0xac, 0x03, 0x99, 0x76, 0x61, 0x40, 0xbe, 0x90, 0x81, 0x8b, 0xe9, 0xa8, 0x52, 0xb3, 0x39, - 0x63, 0x3b, 0x21, 0x4e, 0xf9, 0xe1, 0x4c, 0xf4, 0xa0, 0x61, 0x67, 0xc5, 0x66, 0xfb, 0xb4, 0x1d, - 0x56, 0x40, 0x3e, 0x0a, 0xa3, 0xa5, 0x8e, 0x61, 0x7a, 0x78, 0xf1, 0xc6, 0x0c, 0xe7, 0x1f, 0xc9, - 0xc4, 0xb6, 0x38, 0x32, 0x16, 0xb7, 0x38, 0x32, 0x80, 0xbc, 0x01, 0x13, 0x55, 0x5a, 0xef, 0x38, - 0xa6, 0xb7, 0xa1, 0x61, 0x9a, 0x7c, 0xc6, 0xe3, 0x47, 0x33, 0xd1, 0x49, 0x2c, 0x41, 0xc1, 0x26, - 0xb1, 0x04, 0x90, 0xdc, 0xee, 0x92, 0x4c, 0x5d, 0xf9, 0x7c, 0xa6, 0xe7, 0xb5, 0x7c, 0xd0, 0x97, - 0x5d, 0x72, 0xb1, 0x2f, 0xa5, 0x26, 0xa7, 0x56, 0xbe, 0x90, 0xe9, 0x71, 0x8d, 0x2e, 0xcd, 0x70, - 0x29, 0x79, 0xad, 0x97, 0x52, 0x33, 0x07, 0x2b, 0x3f, 0x96, 0xe9, 0x71, 0xed, 0x1d, 0x72, 0x4c, - 0x4b, 0x3a, 0xfc, 0x1c, 0xf7, 0x14, 0x11, 0x8c, 0xfe, 0xa3, 0x4c, 0xd2, 0x55, 0x24, 0x28, 0x2f, - 0x11, 0xb2, 0x62, 0xb7, 0xdc, 0x40, 0xe9, 0xbf, 0x98, 0x49, 0xfa, 0xe6, 0x85, 0xc5, 0xc2, 0x5f, - 0x84, 0xc2, 0xd9, 0xe9, 0xfb, 0x1e, 0x75, 0x2c, 0xbd, 0x89, 0xdd, 0x59, 0xf5, 0x6c, 0x47, 0x6f, - 0xd0, 0x69, 0x4b, 0x5f, 0x69, 0x52, 0xe5, 0x4b, 0x99, 0xa8, 0x05, 0xdb, 0x9d, 0x94, 0x59, 0xb0, - 0xdd, 0xb1, 0x64, 0x0d, 0x1e, 0x49, 0xc3, 0x96, 0x4d, 0x17, 0xeb, 0xf9, 0x72, 0x26, 0x6a, 0xc2, - 0xf6, 0xa0, 0x65, 0x26, 0x6c, 0x0f, 0x34, 0xb9, 0x06, 0x43, 0x93, 0xb6, 0x3f, 0xfd, 0xfe, 0x78, - 0xcc, 0x19, 0x32, 0xc0, 0xcc, 0xf6, 0x69, 0x21, 0x99, 0x28, 0x23, 0x06, 0xf5, 0x57, 0x92, 0x65, - 0xc2, 0xcb, 0xa7, 0xe0, 0x87, 0x28, 0x23, 0xc4, 0xfd, 0x1f, 0x27, 0xcb, 0x84, 0x77, 0x5c, 0xc1, - 0x0f, 0x36, 0x93, 0xf0, 0x1a, 0xe7, 0x67, 0x4a, 0xcc, 0x6e, 0x9b, 0x5a, 0xd3, 0x9b, 0x4d, 0x6a, - 0x35, 0xa8, 0xf2, 0xd5, 0xd8, 0x4c, 0x92, 0x4e, 0xc6, 0x66, 0x92, 0x74, 0x0c, 0xf9, 0x24, 0x9c, - 0xbe, 0xad, 0x37, 0x4d, 0x23, 0xc4, 0xf9, 0x79, 0x64, 0x95, 0x9f, 0xc8, 0x44, 0x77, 0xd3, 0x5d, - 0xe8, 0xd8, 0x6e, 0xba, 0x0b, 0x8a, 0xcc, 0x03, 0xc1, 0x65, 0x34, 0x98, 0x2d, 0xd8, 0xfa, 0xac, - 0xfc, 0x27, 0x99, 0xa8, 0x9d, 0x9a, 0x24, 0x61, 0x76, 0x6a, 0x12, 0x4a, 0x6a, 0xdd, 0x03, 0xd2, - 0x2b, 0x3f, 0x99, 0x89, 0x9e, 0xd6, 0x74, 0x23, 0x9c, 0xed, 0xd3, 0xba, 0x47, 0xb5, 0xbf, 0x01, - 0xe3, 0xd5, 0xa5, 0xca, 0xcc, 0xcc, 0x74, 0xf5, 0x76, 0xa5, 0x8c, 0xee, 0xbb, 0x86, 0xf2, 0x53, - 0xb1, 0x15, 0x2b, 0x4e, 0xc0, 0x56, 0xac, 0x38, 0x8c, 0xbc, 0x0c, 0x23, 0xac, 0xfd, 0x6c, 0xc0, - 0xe0, 0x27, 0x7f, 0x2d, 0x13, 0x35, 0xa7, 0x64, 0x24, 0x33, 0xa7, 0xe4, 0xdf, 0xa4, 0x0a, 0x27, - 0x98, 0x14, 0x97, 0x1c, 0xba, 0x4a, 0x1d, 0x6a, 0xd5, 0xfd, 0x31, 0xfd, 0xd3, 0x99, 0xa8, 0x95, - 0x91, 0x46, 0xc4, 0xac, 0x8c, 0x34, 0x38, 0xb9, 0x0b, 0xe7, 0xe2, 0x27, 0x41, 0xf2, 0x63, 0x2a, - 0xe5, 0x67, 0x32, 0x31, 0x63, 0xb8, 0x07, 0x31, 0x1a, 0xc3, 0x3d, 0xf0, 0xc4, 0x82, 0xf3, 0xe2, - 0x58, 0x45, 0x38, 0x5c, 0xc6, 0x6b, 0xfb, 0x4f, 0x79, 0x6d, 0x4f, 0x84, 0x0e, 0x81, 0x3d, 0xa8, - 0x67, 0xfb, 0xb4, 0xde, 0xec, 0x98, 0x9e, 0x25, 0xc3, 0xae, 0x2b, 0x3f, 0x9b, 0x49, 0xf7, 0x48, - 0x89, 0xb8, 0x29, 0xa7, 0xc5, 0x6b, 0x7f, 0xab, 0x5b, 0xd0, 0x70, 0xe5, 0xe7, 0x62, 0xe3, 0x2d, - 0x9d, 0x8c, 0x8d, 0xb7, 0x2e, 0x51, 0xc7, 0xdf, 0x80, 0x09, 0xae, 0xd4, 0x4b, 0x3a, 0x0e, 0x43, - 0xab, 0x41, 0x0d, 0xe5, 0x3f, 0x8b, 0xad, 0x76, 0x09, 0x0a, 0x74, 0xed, 0x89, 0x03, 0xd9, 0xd4, - 0x5d, 0x6d, 0xeb, 0x96, 0x85, 0xc7, 0xac, 0xca, 0x7f, 0x1e, 0x9b, 0xba, 0x43, 0x14, 0x3a, 0xee, - 0x06, 0xbf, 0x98, 0x26, 0xf4, 0x4a, 0xb8, 0xa1, 0xfc, 0x7c, 0x4c, 0x13, 0x7a, 0x11, 0x33, 0x4d, - 0xe8, 0x99, 0xbd, 0xe3, 0x76, 0x97, 0x87, 0x8d, 0xca, 0xd7, 0x63, 0x2b, 0x72, 0x2a, 0x15, 0x5b, - 0x91, 0xd3, 0xdf, 0x45, 0xde, 0xee, 0xf2, 0x28, 0x50, 0xf9, 0x85, 0xde, 0x7c, 0xc3, 0x95, 0x3e, - 0xfd, 0x4d, 0xe1, 0xed, 0x2e, 0x0f, 0xea, 0x94, 0x5f, 0xec, 0xcd, 0x37, 0x74, 0xec, 0x4b, 0x7f, - 0x8f, 0x57, 0xeb, 0xfe, 0x18, 0x4d, 0xf9, 0xa5, 0xf8, 0xd4, 0xd5, 0x85, 0x10, 0xa7, 0xae, 0x6e, - 0x2f, 0xda, 0x56, 0xe0, 0x0c, 0xd7, 0x90, 0x1b, 0x8e, 0xde, 0x5e, 0xab, 0x52, 0xcf, 0x33, 0xad, - 0x86, 0xbf, 0x13, 0xfb, 0x2f, 0x32, 0xb1, 0xe3, 0xb1, 0x6e, 0x94, 0x78, 0x3c, 0xd6, 0x0d, 0x39, - 0x39, 0x00, 0xfd, 0xb8, 0xe3, 0x53, 0xbf, 0x9e, 0x81, 0x91, 0xaa, 0xe7, 0x50, 0xbd, 0x25, 0xa2, - 0x2d, 0x9c, 0x85, 0x41, 0xee, 0x3a, 0xe5, 0xbf, 0x5e, 0xd0, 0x82, 0xdf, 0xe4, 0x22, 0x8c, 0xcd, - 0xe9, 0xae, 0x87, 0x25, 0x2b, 0x96, 0x41, 0xef, 0xe3, 0xb3, 0x81, 0x9c, 0x16, 0x83, 0x92, 0x39, - 0x4e, 0xc7, 0xcb, 0x61, 0x6c, 0x9c, 0xdc, 0xb6, 0x41, 0x06, 0x06, 0xdf, 0xdd, 0x2c, 0xf6, 0x61, - 0x4c, 0x81, 0x58, 0x59, 0xf5, 0xdb, 0x19, 0x48, 0x38, 0x75, 0x3d, 0xf8, 0xab, 0xa2, 0x45, 0x38, - 0x16, 0x8b, 0xc7, 0x24, 0xde, 0x3e, 0xec, 0x30, 0x5c, 0x53, 0xbc, 0x34, 0xf9, 0x60, 0xe0, 0x73, - 0x7f, 0x4b, 0x9b, 0x13, 0x01, 0x24, 0x06, 0xb6, 0x36, 0x8b, 0xb9, 0x8e, 0xd3, 0xd4, 0x24, 0x94, - 0x78, 0x20, 0xfc, 0xdf, 0x8d, 0x87, 0xc1, 0x66, 0xc8, 0x45, 0xf1, 0xc4, 0x29, 0x13, 0x86, 0x9d, - 0x88, 0xa5, 0x32, 0xe4, 0x4f, 0x9a, 0x3e, 0x0a, 0x23, 0x95, 0x56, 0x9b, 0x3a, 0xae, 0x6d, 0xe9, - 0x9e, 0xed, 0xa7, 0x4c, 0xc7, 0x90, 0x04, 0xa6, 0x04, 0x97, 0x9f, 0xc9, 0xcb, 0xf4, 0xe4, 0xb2, - 0x9f, 0x5d, 0x21, 0x87, 0x61, 0x7e, 0x30, 0x56, 0x65, 0x3c, 0x3d, 0x1e, 0xa7, 0x60, 0xa4, 0xb7, - 0x5c, 0x1d, 0x5f, 0x67, 0x04, 0xa4, 0x1d, 0x06, 0x90, 0x49, 0x91, 0x82, 0x3c, 0x05, 0x05, 0x3c, - 0xcd, 0x72, 0x31, 0x6b, 0x8a, 0x08, 0x86, 0xd1, 0x44, 0x88, 0x1c, 0x7a, 0x80, 0xd3, 0x90, 0x9b, - 0x30, 0x1e, 0x1e, 0xd5, 0x63, 0x92, 0x7f, 0x3f, 0x4e, 0x32, 0xa6, 0x15, 0xbc, 0x1b, 0xe0, 0x6a, - 0x0d, 0x44, 0x4a, 0x2c, 0x12, 0x05, 0xc9, 0x2c, 0x1c, 0x0b, 0x61, 0x4c, 0x44, 0x7e, 0x7c, 0x76, - 0xcc, 0x8d, 0x23, 0xf1, 0x62, 0xe2, 0x8c, 0xe4, 0xc6, 0x89, 0x15, 0x23, 0x15, 0x18, 0xf0, 0x23, - 0x61, 0x0c, 0x6e, 0xab, 0xa4, 0xc7, 0x45, 0x24, 0x8c, 0x01, 0x39, 0x06, 0x86, 0x5f, 0x9e, 0xcc, - 0xc0, 0x98, 0x66, 0x77, 0x3c, 0xba, 0x6c, 0x8b, 0x35, 0x4e, 0x04, 0xf0, 0xc5, 0x36, 0x39, 0x0c, - 0x53, 0xf3, 0x6c, 0x3f, 0x2b, 0xa3, 0x9c, 0x1d, 0x30, 0x5a, 0x8a, 0x2c, 0xc0, 0x44, 0xe2, 0x52, - 0x43, 0xce, 0x95, 0x28, 0x7d, 0x5e, 0x92, 0x59, 0xb2, 0x28, 0xf9, 0x91, 0x0c, 0x14, 0x96, 0x1d, - 0xdd, 0xf4, 0x5c, 0xf1, 0xb0, 0xe3, 0xe4, 0x95, 0x75, 0x47, 0x6f, 0x33, 0xfd, 0xb8, 0x82, 0x71, - 0x9c, 0x6e, 0xeb, 0xcd, 0x0e, 0x75, 0x27, 0xef, 0xb0, 0xaf, 0xfb, 0x7f, 0x37, 0x8b, 0x2f, 0x37, - 0x70, 0xeb, 0x74, 0xa5, 0x6e, 0xb7, 0xae, 0x36, 0x1c, 0xfd, 0x9e, 0xe9, 0xe1, 0x85, 0xb4, 0xde, - 0xbc, 0xea, 0xd1, 0x26, 0xee, 0xd0, 0xae, 0xea, 0x6d, 0xf3, 0x2a, 0xc6, 0x0b, 0xbc, 0x1a, 0x70, - 0xe2, 0x35, 0x30, 0x15, 0xf0, 0xf0, 0x2f, 0x59, 0x05, 0x38, 0x8e, 0x2c, 0xb0, 0x8d, 0x0d, 0x7e, - 0x6a, 0xa9, 0xdd, 0x16, 0xaf, 0x44, 0xa4, 0x7d, 0x8d, 0x8f, 0xe1, 0x8a, 0x1d, 0x08, 0x4c, 0x6f, - 0xb7, 0xe5, 0x6c, 0xac, 0x21, 0x1d, 0xd3, 0x82, 0x65, 0xd1, 0x22, 0x5f, 0x4c, 0xa3, 0xa1, 0xc4, - 0xfd, 0xc6, 0xa6, 0x08, 0x29, 0x5e, 0x8c, 0xac, 0xc0, 0x31, 0xc1, 0x37, 0x88, 0xa8, 0x3b, 0x16, - 0x9d, 0x15, 0x62, 0x68, 0xae, 0xb4, 0x41, 0x1b, 0x0d, 0x01, 0x96, 0xeb, 0x88, 0x95, 0x20, 0x93, - 0x61, 0x9a, 0xaf, 0x05, 0xbd, 0x45, 0x5d, 0xe5, 0x18, 0x6a, 0xec, 0xb9, 0xad, 0xcd, 0xa2, 0xe2, - 0x97, 0xc7, 0xa0, 0x30, 0xa9, 0x49, 0x2b, 0xb1, 0x88, 0xcc, 0x83, 0x6b, 0xfd, 0x78, 0x0a, 0x8f, - 0xb8, 0xce, 0x47, 0x8b, 0x90, 0x29, 0x18, 0x0d, 0x9c, 0x54, 0x6f, 0xdd, 0xaa, 0x94, 0xf1, 0x19, - 0xca, 0xd0, 0xe4, 0xf9, 0xad, 0xcd, 0xe2, 0x99, 0x58, 0xcc, 0x5b, 0x99, 0x49, 0xa4, 0x8c, 0xf4, - 0x5e, 0x8d, 0xbf, 0x4b, 0x89, 0xbd, 0x57, 0x6b, 0xa7, 0xbc, 0x57, 0x5b, 0x22, 0xaf, 0xc2, 0x70, - 0xe9, 0x4e, 0x55, 0xbc, 0xc3, 0x73, 0x95, 0xe3, 0x61, 0x94, 0x74, 0xcc, 0x5b, 0x2a, 0xde, 0xec, - 0xc9, 0x4d, 0x97, 0xe9, 0xc9, 0x34, 0x8c, 0x45, 0xee, 0xb9, 0x5d, 0xe5, 0x04, 0x72, 0xc0, 0x96, - 0xeb, 0x88, 0xa9, 0x39, 0x02, 0x15, 0xc9, 0xa4, 0x1b, 0x29, 0xc4, 0xb4, 0x86, 0x6d, 0x15, 0x9b, - 0x4d, 0x7b, 0x5d, 0xa3, 0xf8, 0xe4, 0x0f, 0x1f, 0xb5, 0x0c, 0x72, 0xad, 0x31, 0x04, 0xaa, 0xe6, - 0x70, 0x5c, 0x24, 0x75, 0x6e, 0xb4, 0x18, 0x79, 0x1b, 0x08, 0xc6, 0xa8, 0xa6, 0x86, 0x7f, 0xec, - 0x59, 0x29, 0xbb, 0xca, 0x29, 0x8c, 0x67, 0x47, 0xe2, 0x6f, 0x4e, 0x2b, 0xe5, 0xc9, 0x8b, 0x62, - 0xfa, 0xb8, 0xa0, 0xf3, 0x52, 0x35, 0x47, 0xe0, 0x6a, 0x66, 0x24, 0x81, 0x57, 0x0a, 0x57, 0xb2, - 0x0e, 0xa7, 0x97, 0x1c, 0x7a, 0xcf, 0xb4, 0x3b, 0xae, 0xbf, 0x7c, 0xf8, 0xf3, 0xd6, 0xe9, 0x6d, - 0xe7, 0xad, 0xc7, 0x44, 0xc5, 0x27, 0xdb, 0x0e, 0xbd, 0x57, 0xf3, 0xa3, 0x98, 0x45, 0x22, 0xf9, - 0x74, 0xe3, 0x8e, 0x69, 0xc8, 0xde, 0xe9, 0x38, 0x54, 0xc0, 0x4d, 0xea, 0x2a, 0x4a, 0x38, 0xd5, - 0xf2, 0xd7, 0x9b, 0x66, 0x80, 0x8b, 0xa4, 0x21, 0x8b, 0x16, 0x23, 0x1a, 0x90, 0x1b, 0x53, 0xfe, - 0x11, 0x78, 0xa9, 0xce, 0x93, 0x35, 0x29, 0x67, 0x90, 0x99, 0xca, 0xc4, 0xd2, 0xa8, 0x07, 0x11, - 0x0d, 0x6b, 0xba, 0xc0, 0xcb, 0x62, 0x49, 0x96, 0x26, 0x73, 0x30, 0xbe, 0xe4, 0xa0, 0x41, 0x7e, - 0x93, 0x6e, 0x2c, 0xd9, 0x4d, 0xb3, 0xbe, 0x81, 0x6f, 0x6b, 0xc4, 0x54, 0xd9, 0xe6, 0xb8, 0xda, - 0x5d, 0xba, 0x51, 0x6b, 0x23, 0x56, 0x5e, 0x56, 0xe2, 0x25, 0xe5, 0x08, 0x63, 0x8f, 0xec, 0x2c, - 0xc2, 0x18, 0x85, 0x71, 0x71, 0x80, 0x7e, 0xdf, 0xa3, 0x16, 0x5b, 0xea, 0x5d, 0xf1, 0x8e, 0x46, - 0x89, 0x1d, 0xb8, 0x07, 0x78, 0x91, 0x46, 0x97, 0x8f, 0x32, 0x1a, 0x80, 0xe5, 0x86, 0xc5, 0x8b, - 0xa8, 0x5f, 0xce, 0xc9, 0x53, 0x27, 0x39, 0x07, 0x79, 0x29, 0xc0, 0x35, 0xc6, 0x18, 0xc2, 0x60, - 0x80, 0x79, 0x11, 0xf5, 0x6c, 0x48, 0x98, 0x1d, 0xc1, 0x63, 0x52, 0x4c, 0x5b, 0x12, 0xc6, 0x9d, - 0xd1, 0x42, 0x02, 0x4c, 0x19, 0xd1, 0x59, 0x69, 0x9a, 0x75, 0x0c, 0x11, 0x99, 0x93, 0x52, 0x46, - 0x20, 0x94, 0x47, 0x88, 0x94, 0x48, 0xc8, 0x35, 0x18, 0xf6, 0xf7, 0x70, 0x61, 0x8c, 0x2d, 0x8c, - 0x1c, 0xe8, 0x27, 0x1c, 0xe6, 0x81, 0x09, 0x25, 0x22, 0xf2, 0x12, 0xa6, 0xdc, 0xf6, 0x1f, 0xea, - 0xf6, 0x87, 0xe6, 0x8b, 0x3c, 0xf0, 0x63, 0x39, 0xb7, 0xfd, 0xf7, 0xba, 0x93, 0x30, 0x2a, 0x6b, - 0x92, 0x9f, 0x24, 0x07, 0xe7, 0xbc, 0x88, 0xfa, 0xc9, 0x7d, 0x1b, 0x2d, 0x42, 0x16, 0x61, 0x22, - 0xa1, 0x3c, 0x22, 0x22, 0x17, 0x26, 0x4a, 0x4c, 0xd1, 0x3c, 0x79, 0x4d, 0x4d, 0x94, 0x55, 0x7f, - 0x30, 0x9b, 0x58, 0x31, 0x98, 0x60, 0x04, 0x95, 0xd4, 0x39, 0x28, 0x18, 0x9f, 0x35, 0x17, 0x8c, - 0x44, 0x44, 0x2e, 0xc1, 0x60, 0x2c, 0xeb, 0x36, 0x3e, 0xdd, 0x0e, 0x52, 0x6e, 0x07, 0x58, 0x72, - 0x4d, 0x4a, 0xdb, 0x24, 0x85, 0xbf, 0xf3, 0xd3, 0x36, 0xc5, 0xe3, 0xc0, 0x61, 0x02, 0xa7, 0x6b, - 0xb1, 0x08, 0xf1, 0x7e, 0x72, 0xe4, 0xe4, 0x6a, 0x15, 0x46, 0x84, 0x0f, 0x6c, 0xc5, 0xfe, 0xed, - 0x6c, 0x45, 0xf5, 0x77, 0x33, 0x49, 0xed, 0x27, 0xd7, 0x93, 0xe1, 0xac, 0x78, 0x5e, 0x64, 0x1f, - 0x28, 0xd7, 0x1a, 0x04, 0xb6, 0x8a, 0x04, 0xa6, 0xca, 0x3e, 0x70, 0x60, 0xaa, 0xdc, 0x2e, 0x03, - 0x53, 0xa9, 0xff, 0x2a, 0xdf, 0xd3, 0x0d, 0xeb, 0x40, 0x02, 0x18, 0xbc, 0xc8, 0xf6, 0x3b, 0xac, - 0xf6, 0x92, 0x9b, 0xb0, 0xda, 0xb9, 0x97, 0x49, 0x4d, 0xe7, 0xa3, 0xc6, 0xd5, 0xa2, 0x94, 0xe4, - 0x35, 0x18, 0xf1, 0x3f, 0x00, 0x03, 0x9e, 0x49, 0x81, 0xba, 0x82, 0xb5, 0x26, 0x9e, 0xda, 0x5a, - 0x2e, 0x40, 0x9e, 0x83, 0x21, 0xb4, 0x34, 0xda, 0x7a, 0xdd, 0x8f, 0x86, 0xc7, 0xc3, 0xe7, 0xf9, - 0x40, 0xf9, 0x91, 0x7e, 0x40, 0x49, 0x3e, 0x05, 0x85, 0x48, 0x6e, 0xf5, 0xab, 0x3b, 0xf0, 0x5b, - 0xbb, 0x22, 0x47, 0x72, 0xe5, 0x7b, 0x87, 0x78, 0x5e, 0x75, 0xc1, 0x94, 0x2c, 0xc3, 0xf1, 0x25, - 0x87, 0x1a, 0xe8, 0x21, 0x39, 0x7d, 0xbf, 0xed, 0x88, 0x38, 0xbb, 0x7c, 0x00, 0xe3, 0xd2, 0xd1, - 0xf6, 0xd1, 0x6c, 0x51, 0x13, 0x78, 0x39, 0x24, 0x57, 0x4a, 0x71, 0x66, 0x4f, 0xf0, 0x96, 0xdc, - 0xa4, 0x1b, 0xeb, 0x98, 0x5f, 0x73, 0x30, 0xb4, 0x27, 0x84, 0xa0, 0xef, 0x0a, 0x94, 0x6c, 0x4f, - 0x44, 0x0b, 0x9d, 0x7d, 0x11, 0x86, 0x1f, 0x34, 0x1a, 0xea, 0x6f, 0x64, 0xbb, 0x38, 0x34, 0x3f, - 0xbc, 0x09, 0x29, 0x82, 0x54, 0x68, 0xfd, 0x5d, 0x52, 0xa1, 0x7d, 0x2f, 0xdb, 0xc5, 0x5b, 0xfb, - 0xa1, 0x4e, 0x59, 0x14, 0x08, 0x23, 0x9a, 0xb2, 0x28, 0xcc, 0x16, 0x65, 0x1a, 0x9a, 0x4c, 0x14, - 0x4b, 0x6e, 0x56, 0xd8, 0x36, 0xb9, 0xd9, 0x2f, 0xe7, 0x7a, 0x79, 0xb3, 0x1f, 0xc9, 0x7e, 0x37, - 0xb2, 0xbf, 0x06, 0xc3, 0x81, 0x64, 0x2b, 0x65, 0xb4, 0x67, 0x46, 0x83, 0xd8, 0xcb, 0x1c, 0x8c, - 0x65, 0x24, 0x22, 0x72, 0x99, 0xb7, 0xb5, 0x6a, 0xbe, 0xc3, 0x43, 0x89, 0x8e, 0x8a, 0x20, 0x91, - 0xba, 0xa7, 0xd7, 0x5c, 0xf3, 0x1d, 0xaa, 0x05, 0x68, 0xf5, 0x7f, 0xce, 0xa6, 0x3e, 0x09, 0x38, - 0xea, 0xa3, 0x5d, 0xf4, 0x51, 0x8a, 0x10, 0xf9, 0x63, 0x86, 0x23, 0x21, 0xee, 0x42, 0x88, 0x7f, - 0x99, 0x4d, 0x7d, 0xfa, 0x71, 0x24, 0xc4, 0xdd, 0xcc, 0x16, 0x4f, 0xc1, 0x90, 0x66, 0xaf, 0xbb, - 0x98, 0xc9, 0x58, 0xcc, 0x15, 0x38, 0x51, 0x3b, 0xf6, 0xba, 0xcb, 0xb3, 0x3c, 0x6b, 0x21, 0x81, - 0xfa, 0xd7, 0xd9, 0x1e, 0x8f, 0x63, 0x8e, 0x04, 0xff, 0x5e, 0x2e, 0x91, 0xbf, 0x95, 0x8d, 0x3c, - 0xbe, 0x79, 0xa8, 0x73, 0x7f, 0x56, 0xeb, 0x6b, 0xb4, 0xa5, 0xc7, 0x73, 0x7f, 0xba, 0x08, 0x15, - 0x19, 0xb8, 0x42, 0x12, 0xf5, 0x1b, 0xd9, 0xd8, 0xeb, 0xa3, 0x23, 0xd9, 0xed, 0x58, 0x76, 0x81, - 0xd6, 0x89, 0x07, 0x55, 0x47, 0x92, 0xdb, 0xa9, 0xe4, 0x3e, 0x9f, 0x8d, 0xbd, 0x3d, 0x7b, 0x68, - 0x65, 0xc7, 0x06, 0x60, 0xf2, 0x4d, 0xdc, 0x43, 0xab, 0x49, 0x4f, 0xc1, 0x90, 0x90, 0x43, 0xb0, - 0x54, 0xf0, 0x79, 0x9f, 0x03, 0xf1, 0x00, 0x35, 0x20, 0x50, 0x7f, 0x38, 0x0b, 0xd1, 0x37, 0x81, - 0x0f, 0xa9, 0x0e, 0xfd, 0x56, 0x36, 0xfa, 0x1a, 0xf2, 0xe1, 0xd5, 0x9f, 0x2b, 0x00, 0xd5, 0xce, - 0x4a, 0x5d, 0x04, 0xd3, 0xeb, 0x97, 0x4e, 0xe0, 0x03, 0xa8, 0x26, 0x51, 0xa8, 0xff, 0x3a, 0x9b, - 0xfa, 0x44, 0xf3, 0xe1, 0x15, 0xe0, 0xb3, 0x78, 0x2a, 0x5e, 0xb7, 0xc2, 0x89, 0x1c, 0x0f, 0x21, - 0xd9, 0xf8, 0x4b, 0xe4, 0xf0, 0xf0, 0x09, 0xc9, 0x47, 0x52, 0xcc, 0x35, 0x8c, 0x30, 0x1a, 0x9a, - 0x6b, 0xf2, 0x0d, 0x83, 0x64, 0xb8, 0xfd, 0x1f, 0xd9, 0xed, 0x5e, 0xb4, 0x3e, 0xcc, 0xab, 0xea, - 0xc0, 0x92, 0xbe, 0x81, 0x91, 0x97, 0x58, 0x4f, 0x8c, 0xf0, 0x0c, 0x13, 0x6d, 0x0e, 0x92, 0x6f, - 0xc4, 0x04, 0x95, 0xfa, 0x17, 0xfd, 0xe9, 0xcf, 0x29, 0x1f, 0x5e, 0x11, 0x9e, 0x83, 0xfc, 0x92, - 0xee, 0xad, 0x09, 0x4d, 0xc6, 0xdb, 0xba, 0xb6, 0xee, 0xad, 0x69, 0x08, 0x25, 0x97, 0x61, 0x50, - 0xd3, 0xd7, 0xf9, 0x99, 0x67, 0x21, 0xcc, 0xfe, 0xe1, 0xe8, 0xeb, 0x35, 0x7e, 0xee, 0x19, 0xa0, - 0x89, 0x1a, 0x64, 0x9f, 0xe1, 0x27, 0xdf, 0x98, 0xfa, 0x80, 0x67, 0x9f, 0x09, 0x72, 0xce, 0x9c, - 0x83, 0xfc, 0xa4, 0x6d, 0x6c, 0xa0, 0x33, 0xcb, 0x08, 0xaf, 0x6c, 0xc5, 0x36, 0x36, 0x34, 0x84, - 0x92, 0x2f, 0x64, 0x60, 0x60, 0x96, 0xea, 0x06, 0x1b, 0x21, 0x43, 0xbd, 0x7c, 0x41, 0x3e, 0xb6, - 0x3f, 0xbe, 0x20, 0x13, 0x6b, 0xbc, 0x32, 0x59, 0x51, 0x44, 0xfd, 0xe4, 0x06, 0x0c, 0x4e, 0xe9, - 0x1e, 0x6d, 0xd8, 0xce, 0x06, 0x7a, 0xb7, 0x8c, 0x85, 0x2e, 0x79, 0x11, 0xfd, 0xf1, 0x89, 0xf8, - 0xcd, 0x58, 0x5d, 0xfc, 0xd2, 0x82, 0xc2, 0x4c, 0x2c, 0x22, 0x95, 0xe5, 0x70, 0x28, 0x16, 0x9e, - 0xb3, 0x32, 0xc8, 0x58, 0x19, 0x1c, 0x2b, 0x8f, 0xa4, 0x1f, 0x2b, 0xa3, 0xf5, 0x88, 0x1e, 0x70, - 0x98, 0xf3, 0x65, 0x14, 0x17, 0x7d, 0x6e, 0x3d, 0x22, 0x14, 0x53, 0xbe, 0x68, 0x12, 0x89, 0xfa, - 0x9d, 0x7e, 0x48, 0x7d, 0x7c, 0x75, 0xa4, 0xe4, 0x47, 0x4a, 0x1e, 0x2a, 0x79, 0x39, 0xa1, 0xe4, - 0x67, 0x93, 0xcf, 0xf9, 0xde, 0xa7, 0x1a, 0xfe, 0xb5, 0x7c, 0xe2, 0x31, 0xf0, 0xc3, 0xbd, 0xbb, - 0x0c, 0xa5, 0xd7, 0xbf, 0xad, 0xf4, 0x82, 0x01, 0x51, 0xd8, 0x76, 0x40, 0x0c, 0xec, 0x74, 0x40, - 0x0c, 0x76, 0x1d, 0x10, 0xa1, 0x82, 0x0c, 0x75, 0x55, 0x90, 0x8a, 0x18, 0x34, 0xd0, 0x3b, 0x9f, - 0xd8, 0xb9, 0xad, 0xcd, 0xe2, 0x18, 0x1b, 0x4d, 0xa9, 0x99, 0xc4, 0x90, 0x85, 0xfa, 0xed, 0x7c, - 0x8f, 0x17, 0xfc, 0x07, 0xa2, 0x23, 0xcf, 0x42, 0xae, 0xd4, 0x6e, 0x0b, 0xfd, 0x38, 0x2e, 0x05, - 0x0f, 0xe8, 0x52, 0x8a, 0x51, 0x93, 0x97, 0x20, 0x57, 0xba, 0x53, 0x8d, 0xc7, 0x21, 0x2f, 0xdd, - 0xa9, 0x8a, 0x2f, 0xe9, 0x5a, 0xf6, 0x4e, 0x95, 0xbc, 0x12, 0x06, 0x04, 0x5b, 0xeb, 0x58, 0x77, - 0xc5, 0x46, 0x51, 0x38, 0xc1, 0xfa, 0x9e, 0x36, 0x75, 0x86, 0x62, 0xdb, 0xc5, 0x18, 0x6d, 0x4c, - 0x9b, 0x0a, 0x3b, 0xd7, 0xa6, 0x81, 0x6d, 0xb5, 0x69, 0x70, 0xa7, 0xda, 0x34, 0xb4, 0x03, 0x6d, - 0x82, 0x6d, 0xb5, 0x69, 0x78, 0xef, 0xda, 0xd4, 0x86, 0xb3, 0xc9, 0xa8, 0x2b, 0x81, 0x46, 0x68, - 0x40, 0x92, 0x58, 0xe1, 0x58, 0x82, 0x57, 0xff, 0x1d, 0x8e, 0xad, 0xf1, 0x94, 0xb3, 0xf1, 0x84, - 0xad, 0x5a, 0x4a, 0x69, 0xf5, 0x37, 0xb2, 0xdd, 0x83, 0xc5, 0x1c, 0xce, 0x29, 0xee, 0x33, 0xa9, - 0x52, 0xca, 0x47, 0x1f, 0xef, 0x75, 0x97, 0x72, 0x8c, 0x6d, 0x9a, 0xcc, 0xbe, 0x95, 0xe9, 0x16, - 0xc1, 0x66, 0x4f, 0x12, 0x7b, 0x22, 0xe9, 0xac, 0x86, 0xde, 0xf3, 0x6e, 0xd4, 0x4b, 0x2d, 0x9e, - 0xc1, 0x34, 0xf7, 0x80, 0x19, 0x4c, 0x7f, 0x37, 0x03, 0xc7, 0x6f, 0x76, 0x56, 0xa8, 0x70, 0x4e, - 0x0b, 0x9a, 0xf1, 0x36, 0x00, 0x03, 0x0b, 0x27, 0x96, 0x0c, 0x3a, 0xb1, 0x7c, 0x48, 0x8e, 0x3e, - 0x13, 0x2b, 0x70, 0x25, 0xa4, 0xe6, 0x0e, 0x2c, 0xe7, 0x7d, 0x17, 0xcb, 0xbb, 0x9d, 0x15, 0x5a, - 0x4b, 0x78, 0xb2, 0x48, 0xdc, 0xcf, 0xbe, 0xca, 0x9d, 0xd7, 0x1f, 0xd4, 0x69, 0xe4, 0xd7, 0xb2, - 0x5d, 0x03, 0xfe, 0x1c, 0xda, 0x7c, 0x2b, 0x9f, 0x48, 0xed, 0x95, 0x78, 0xde, 0x95, 0x14, 0x92, - 0x18, 0xc7, 0x34, 0x2e, 0xe9, 0x02, 0x3b, 0xe4, 0x59, 0x80, 0xde, 0x53, 0x81, 0xfd, 0x51, 0xa6, - 0x6b, 0x60, 0xa6, 0xc3, 0x2a, 0x30, 0xf5, 0x1f, 0xe4, 0xfc, 0x78, 0x50, 0x7b, 0xfa, 0x84, 0xa7, - 0x60, 0x48, 0x3c, 0x8b, 0x8b, 0xfa, 0xd6, 0x8a, 0xa3, 0x3c, 0x3c, 0x1a, 0x0e, 0x08, 0xd8, 0x32, - 0xef, 0xc7, 0xab, 0x09, 0xd2, 0xd7, 0xe2, 0x32, 0x6f, 0x0a, 0x28, 0xa3, 0x97, 0x48, 0xd8, 0x42, - 0x3e, 0x7d, 0xdf, 0xf4, 0xd0, 0x2a, 0x60, 0x7d, 0x99, 0xe3, 0x0b, 0x39, 0xbd, 0x6f, 0x7a, 0xdc, - 0x26, 0x08, 0xd0, 0x6c, 0x91, 0xae, 0x86, 0x39, 0x0e, 0xc5, 0x22, 0xed, 0x8a, 0x54, 0x8f, 0xe2, - 0x31, 0xd7, 0x53, 0x30, 0x24, 0x1c, 0x56, 0x85, 0x9b, 0x89, 0x68, 0xad, 0x70, 0x71, 0xc5, 0xd6, - 0x06, 0x04, 0x8c, 0xa3, 0x46, 0x1b, 0xa1, 0x63, 0x1d, 0x72, 0x74, 0x10, 0xa2, 0x09, 0x0c, 0xb9, - 0x06, 0x63, 0x55, 0x4f, 0xb7, 0x0c, 0xdd, 0x31, 0x16, 0x3b, 0x5e, 0xbb, 0xe3, 0xc9, 0x46, 0xa9, - 0xeb, 0x19, 0x76, 0xc7, 0xd3, 0x62, 0x14, 0xe4, 0xc3, 0x30, 0xea, 0x43, 0xa6, 0x1d, 0xc7, 0x76, - 0x64, 0xcb, 0xc3, 0xf5, 0x0c, 0xea, 0x38, 0x5a, 0x94, 0x80, 0x7c, 0x04, 0x46, 0x2b, 0xd6, 0x3d, - 0x9b, 0x27, 0xcf, 0xbc, 0xa5, 0xcd, 0x09, 0x3b, 0x04, 0x1f, 0x48, 0x99, 0x01, 0xa2, 0xd6, 0x71, - 0x9a, 0x5a, 0x94, 0x50, 0xdd, 0xca, 0x26, 0xc3, 0x66, 0x3d, 0xbc, 0x9b, 0x96, 0xcb, 0x51, 0x67, - 0x3a, 0xf4, 0x20, 0x45, 0x83, 0x50, 0xf6, 0xe5, 0xe5, 0x76, 0xe1, 0x35, 0x18, 0xbc, 0x49, 0x37, - 0xb8, 0xdf, 0x67, 0x21, 0x74, 0x15, 0xbe, 0x2b, 0x60, 0xf2, 0x89, 0xab, 0x4f, 0xa7, 0x7e, 0x33, - 0x9b, 0x0c, 0x08, 0xf6, 0xf0, 0x0a, 0xfb, 0xc3, 0x30, 0x80, 0xa2, 0xac, 0xf8, 0x47, 0xfe, 0x28, - 0x40, 0x14, 0x77, 0xd4, 0x03, 0xd9, 0x27, 0x53, 0x7f, 0xa1, 0x10, 0x8f, 0x12, 0xf7, 0xf0, 0x4a, - 0xef, 0x65, 0x18, 0x9e, 0xb2, 0x2d, 0xd7, 0x74, 0x3d, 0x6a, 0xd5, 0x7d, 0x85, 0x3d, 0xc3, 0x0c, - 0xaa, 0x7a, 0x08, 0x96, 0x5f, 0x06, 0x49, 0xd4, 0x0f, 0xa2, 0xbc, 0xe4, 0x79, 0x18, 0x42, 0x91, - 0xa3, 0x9f, 0xb4, 0x94, 0x9c, 0x7b, 0x85, 0x01, 0xe3, 0x4e, 0xd2, 0x21, 0x29, 0xb9, 0x05, 0x83, - 0x53, 0x6b, 0x66, 0xd3, 0x70, 0xa8, 0x85, 0xfe, 0xc2, 0xd2, 0x63, 0xdc, 0x68, 0x5f, 0x5e, 0xc1, - 0x7f, 0x91, 0x96, 0x37, 0xa7, 0x2e, 0x8a, 0x45, 0xde, 0x46, 0x09, 0xd8, 0xd9, 0x9f, 0xcc, 0x02, - 0x84, 0x05, 0xc8, 0xa3, 0x90, 0x0d, 0xd2, 0x87, 0xa1, 0x9b, 0x4a, 0x44, 0x83, 0xb2, 0xb8, 0x54, - 0x88, 0xb1, 0x9d, 0xdd, 0x76, 0x6c, 0xdf, 0x82, 0x02, 0x3f, 0xf1, 0x42, 0x4f, 0x72, 0x29, 0x70, - 0x55, 0xd7, 0x06, 0x5f, 0x41, 0x7a, 0xbe, 0x99, 0x45, 0xcb, 0x33, 0xe2, 0x95, 0xcd, 0x99, 0x9d, - 0xad, 0x43, 0x3f, 0xfe, 0x45, 0x2e, 0x42, 0x1e, 0xa5, 0x98, 0xc1, 0x7d, 0x2c, 0xce, 0xd2, 0x31, - 0xf9, 0x21, 0x9e, 0x75, 0xd3, 0x94, 0x6d, 0x79, 0xac, 0x6a, 0x6c, 0xf5, 0x88, 0x90, 0x8b, 0x80, - 0x45, 0xe4, 0x22, 0x60, 0xea, 0xff, 0x9e, 0x4d, 0x89, 0x5f, 0xf8, 0xf0, 0x0e, 0x93, 0x17, 0x01, - 0xf0, 0xa1, 0x35, 0x93, 0xa7, 0xff, 0x44, 0x03, 0x47, 0x09, 0x32, 0x42, 0xb5, 0x8d, 0x6c, 0x3b, - 0x42, 0x62, 0xf5, 0xf7, 0x33, 0x89, 0xa0, 0x77, 0x7b, 0x92, 0xa3, 0x6c, 0x95, 0x65, 0x1f, 0xd0, - 0x8c, 0xf5, 0xfb, 0x22, 0xb7, 0xbb, 0xbe, 0x88, 0x7e, 0xcb, 0x3e, 0x58, 0xa6, 0x07, 0xf9, 0x2d, - 0xdf, 0xc9, 0xa6, 0x85, 0x00, 0x3c, 0x9c, 0x2a, 0x7e, 0x3d, 0x30, 0x4a, 0xf3, 0x3b, 0x49, 0xbc, - 0x2d, 0xcc, 0xd4, 0x4f, 0xc3, 0xb1, 0x58, 0x60, 0x3c, 0x91, 0xd3, 0xef, 0x62, 0xef, 0x08, 0x7b, - 0xdd, 0x9f, 0xe8, 0x47, 0xc8, 0xd4, 0x7f, 0x93, 0xe9, 0x1d, 0x16, 0xf1, 0xc0, 0x55, 0x27, 0x45, - 0x00, 0xb9, 0xbf, 0x1b, 0x01, 0xec, 0xc3, 0x36, 0xf8, 0x70, 0x0b, 0xe0, 0x7d, 0x32, 0x79, 0xbc, - 0xd7, 0x02, 0xf8, 0x85, 0xcc, 0xb6, 0x51, 0x2d, 0x0f, 0x5a, 0x06, 0xea, 0xff, 0x9f, 0x49, 0x8d, - 0x3e, 0xb9, 0xa7, 0x76, 0xbd, 0x02, 0x05, 0xee, 0x56, 0x23, 0x5a, 0x25, 0xe5, 0xeb, 0x60, 0xd0, - 0x2e, 0xe5, 0x45, 0x19, 0x32, 0x07, 0x03, 0xbc, 0x0d, 0x46, 0x3c, 0xaf, 0x6d, 0x4a, 0x3b, 0x8d, - 0x6e, 0x93, 0xa3, 0x40, 0xab, 0xbf, 0x97, 0x49, 0x04, 0xc3, 0x3c, 0xc0, 0x6f, 0x0b, 0xa7, 0xea, - 0xdc, 0xce, 0xa7, 0x6a, 0xf5, 0xcf, 0xb3, 0xe9, 0xb1, 0x38, 0x0f, 0xf0, 0x43, 0xf6, 0xe3, 0x38, - 0xed, 0xc1, 0xd6, 0xad, 0x65, 0x18, 0x8b, 0xca, 0x42, 0x2c, 0x5b, 0x17, 0xd2, 0x23, 0x92, 0x76, - 0x69, 0x45, 0x8c, 0x87, 0xfa, 0x6e, 0x26, 0x19, 0x46, 0xf4, 0xc0, 0xe7, 0xa7, 0x07, 0xd3, 0x96, - 0xe8, 0xa7, 0xbc, 0x4f, 0xd6, 0x9a, 0xfd, 0xf8, 0x94, 0xf7, 0xc9, 0xaa, 0xf1, 0x60, 0x9f, 0xf2, - 0x2b, 0xd9, 0x6e, 0x51, 0x58, 0x0f, 0xfc, 0x83, 0x3e, 0x2e, 0x0b, 0x99, 0xb7, 0x4c, 0x7c, 0xda, - 0xa3, 0xdd, 0xc2, 0x9e, 0x76, 0xe1, 0x99, 0xe0, 0xf3, 0x60, 0x63, 0x3c, 0x55, 0x58, 0xef, 0x13, - 0x45, 0x3e, 0x1c, 0xc2, 0x7a, 0x9f, 0x0c, 0x95, 0xf7, 0x9f, 0xb0, 0xfe, 0x87, 0xec, 0x4e, 0x43, - 0xff, 0x1e, 0x09, 0x2f, 0x21, 0xbc, 0xaf, 0x64, 0x93, 0x21, 0xa9, 0x0f, 0x5c, 0x4c, 0x33, 0x50, - 0x10, 0xc1, 0xb1, 0xbb, 0x0a, 0x87, 0xe3, 0xbb, 0x59, 0x34, 0xe2, 0x3b, 0xae, 0x83, 0xb8, 0xc8, - 0xd9, 0x99, 0x48, 0x38, 0xad, 0xfa, 0xd7, 0x99, 0x58, 0xfc, 0xe6, 0x03, 0x39, 0x42, 0x78, 0xa0, - 0x25, 0x89, 0xbc, 0xea, 0x1f, 0x66, 0xe6, 0x63, 0xf1, 0x33, 0x83, 0xef, 0x29, 0x53, 0x4f, 0x37, - 0x9b, 0xf1, 0xf2, 0x22, 0x26, 0xc0, 0x37, 0xb3, 0x30, 0x91, 0x20, 0x25, 0x17, 0x23, 0x51, 0x72, - 0xf0, 0x58, 0x32, 0xe6, 0x3c, 0xce, 0xe3, 0xe5, 0xec, 0xe2, 0x24, 0xf5, 0x22, 0xe4, 0xcb, 0xfa, - 0x06, 0xff, 0xb6, 0x7e, 0xce, 0xd2, 0xd0, 0x37, 0xe4, 0x13, 0x37, 0xc4, 0x93, 0x15, 0x38, 0xc9, - 0xef, 0x43, 0x4c, 0xdb, 0x5a, 0x36, 0x5b, 0xb4, 0x62, 0xcd, 0x9b, 0xcd, 0xa6, 0xe9, 0x8a, 0x4b, - 0xbd, 0xa7, 0xb6, 0x36, 0x8b, 0x97, 0x3c, 0xdb, 0xd3, 0x9b, 0x35, 0xea, 0x93, 0xd5, 0x3c, 0xb3, - 0x45, 0x6b, 0xa6, 0x55, 0x6b, 0x21, 0xa5, 0xc4, 0x32, 0x9d, 0x15, 0xa9, 0xf0, 0x50, 0xa9, 0xd5, - 0xba, 0x6e, 0x59, 0xd4, 0xa8, 0x58, 0x93, 0x1b, 0x1e, 0xe5, 0x97, 0x81, 0x39, 0x7e, 0x24, 0xc8, - 0xdf, 0x86, 0x73, 0x34, 0x63, 0xbc, 0xc2, 0x08, 0xb4, 0x94, 0x42, 0xea, 0xef, 0xe4, 0x53, 0x42, - 0x77, 0x1f, 0x22, 0xf5, 0xf1, 0x7b, 0x3a, 0xbf, 0x4d, 0x4f, 0x5f, 0x85, 0x81, 0xdb, 0xd4, 0xc1, - 0xf3, 0x2d, 0x7e, 0xc1, 0x80, 0xce, 0xec, 0xf7, 0x38, 0x48, 0xbe, 0xa1, 0x11, 0x54, 0xa4, 0x09, - 0x67, 0x97, 0x59, 0x37, 0xa5, 0x77, 0x66, 0xe1, 0x01, 0x3a, 0xb3, 0x07, 0x3f, 0xf2, 0x16, 0x9c, - 0x46, 0x6c, 0x4a, 0xb7, 0x0e, 0x60, 0x55, 0x18, 0x39, 0x8a, 0x57, 0x95, 0xde, 0xb9, 0xdd, 0xca, - 0x93, 0x8f, 0xc3, 0x48, 0x30, 0x40, 0x4c, 0xea, 0x8a, 0x9b, 0x8b, 0x1e, 0xe3, 0x8c, 0x87, 0x65, - 0x63, 0x60, 0x74, 0x21, 0x8b, 0x86, 0xf6, 0x8a, 0xf0, 0x52, 0xff, 0xbf, 0x4c, 0xaf, 0x10, 0xe2, - 0x07, 0x3e, 0x2b, 0xbf, 0x0a, 0x03, 0x06, 0xff, 0x28, 0xa1, 0x53, 0xbd, 0x83, 0x8c, 0x73, 0x52, - 0xcd, 0x2f, 0xa3, 0xfe, 0x59, 0xa6, 0x67, 0xe4, 0xf2, 0xc3, 0xfe, 0x79, 0x5f, 0xc9, 0x75, 0xf9, - 0x3c, 0x31, 0x89, 0x5e, 0x86, 0x71, 0xd3, 0xf2, 0x68, 0x83, 0x27, 0x25, 0xac, 0x85, 0xe1, 0xa7, - 0xb4, 0x63, 0x12, 0x1c, 0x47, 0xd7, 0x75, 0x38, 0xe5, 0x3b, 0x3e, 0x3a, 0xbe, 0x87, 0x98, 0x5b, - 0xeb, 0x38, 0x26, 0x1f, 0x97, 0xda, 0x09, 0x37, 0xe6, 0x3e, 0xe6, 0xde, 0x72, 0x4c, 0x56, 0x81, - 0xee, 0xad, 0x51, 0x4b, 0xaf, 0xad, 0xdb, 0xce, 0x5d, 0x8c, 0xfd, 0xc9, 0x07, 0xa7, 0x76, 0x8c, - 0xc3, 0xef, 0xf8, 0x60, 0xf2, 0x38, 0x8c, 0x36, 0x9a, 0x1d, 0x1a, 0x44, 0x5b, 0xe4, 0x77, 0x7d, - 0xda, 0x08, 0x03, 0x06, 0x37, 0x24, 0xe7, 0x01, 0x90, 0xc8, 0xc3, 0xb8, 0xf2, 0x78, 0xb1, 0xa7, - 0x0d, 0x31, 0xc8, 0xb2, 0xe8, 0xae, 0xb3, 0x5c, 0xab, 0xb9, 0x90, 0x6a, 0x4d, 0xdb, 0x6a, 0xd4, - 0x3c, 0xea, 0xb4, 0xb0, 0xa1, 0xe8, 0xcc, 0xa0, 0x9d, 0x42, 0x0a, 0xbc, 0x3a, 0x71, 0xe7, 0x6c, - 0xab, 0xb1, 0x4c, 0x9d, 0x16, 0x6b, 0xea, 0x53, 0x40, 0x44, 0x53, 0x1d, 0x3c, 0xf4, 0xe0, 0x1f, - 0x87, 0xde, 0x0c, 0x9a, 0xf8, 0x08, 0x7e, 0x1a, 0x82, 0x1f, 0x56, 0x84, 0x61, 0x1e, 0x72, 0x8e, - 0x0b, 0x0d, 0x5d, 0x18, 0x34, 0xe0, 0x20, 0x94, 0xd7, 0x29, 0x10, 0xde, 0x15, 0xdc, 0xab, 0x5b, - 0x13, 0xbf, 0xd4, 0x2f, 0xe6, 0xd2, 0x82, 0xad, 0xef, 0x49, 0xd1, 0xc2, 0x69, 0x35, 0xbb, 0xab, - 0x69, 0xf5, 0x98, 0xd5, 0x69, 0xd5, 0xf4, 0x76, 0xbb, 0xb6, 0x6a, 0x36, 0xf1, 0x59, 0x15, 0x2e, - 0x7c, 0xda, 0xa8, 0xd5, 0x69, 0x95, 0xda, 0xed, 0x19, 0x0e, 0x24, 0x4f, 0xc2, 0x04, 0xa3, 0xc3, - 0x4e, 0x0a, 0x28, 0xf3, 0x48, 0xc9, 0x18, 0x60, 0xcc, 0x56, 0x9f, 0xf6, 0x0c, 0x0c, 0x0a, 0x9e, - 0x7c, 0xad, 0xea, 0xd7, 0x06, 0x38, 0x33, 0x97, 0xf5, 0x5c, 0xc0, 0x86, 0x4f, 0xae, 0xfd, 0xda, - 0x90, 0x5f, 0x1e, 0x23, 0x13, 0x5b, 0x9d, 0x16, 0x8f, 0x88, 0x35, 0x80, 0xc8, 0xe0, 0x37, 0xb9, - 0x08, 0x63, 0x8c, 0x4b, 0x20, 0x30, 0x1e, 0xcc, 0xb5, 0x5f, 0x8b, 0x41, 0xc9, 0x35, 0x38, 0x11, - 0x81, 0x70, 0x1b, 0x94, 0x3f, 0x13, 0xe8, 0xd7, 0x52, 0x71, 0xea, 0x37, 0x72, 0xd1, 0x10, 0xf0, - 0x07, 0xd0, 0x11, 0xa7, 0x61, 0xc0, 0x76, 0x1a, 0xb5, 0x8e, 0xd3, 0x14, 0x63, 0xaf, 0x60, 0x3b, - 0x8d, 0x5b, 0x4e, 0x93, 0x9c, 0x84, 0x02, 0xeb, 0x1d, 0xd3, 0x10, 0x43, 0xac, 0x5f, 0x6f, 0xb7, - 0x2b, 0x06, 0x29, 0xf1, 0x0e, 0xc1, 0x40, 0xa0, 0xb5, 0x3a, 0x6e, 0xed, 0xb9, 0x53, 0x42, 0x3f, - 0x5f, 0xf1, 0x12, 0x48, 0xec, 0x27, 0x0c, 0x0f, 0xca, 0x0f, 0x02, 0x62, 0x2c, 0x0c, 0xdc, 0x96, - 0x18, 0xbc, 0x4f, 0xe2, 0x2c, 0x04, 0x32, 0x64, 0xc1, 0x37, 0x31, 0x06, 0x29, 0x03, 0x09, 0xa9, - 0x5a, 0xb6, 0x61, 0xae, 0x9a, 0x94, 0xbf, 0xea, 0xe8, 0xe7, 0x17, 0xbf, 0x49, 0xac, 0x36, 0xee, - 0x33, 0x99, 0x17, 0x10, 0xf2, 0x32, 0x57, 0x42, 0x4e, 0x87, 0x6b, 0x1f, 0xef, 0x5b, 0x6e, 0xa7, - 0xc5, 0x50, 0xa8, 0x99, 0x58, 0x1e, 0x17, 0x42, 0xf5, 0xdd, 0x5c, 0x32, 0x0f, 0xc0, 0x81, 0xd8, - 0x35, 0xb3, 0x00, 0x22, 0xcd, 0x47, 0x78, 0xb9, 0x16, 0x78, 0x9c, 0x87, 0x98, 0x2e, 0x3c, 0xa4, - 0xb2, 0xe4, 0x32, 0x0c, 0xf2, 0x2f, 0xaa, 0x94, 0x85, 0xbd, 0x83, 0x2e, 0x62, 0x6e, 0xdb, 0x5c, - 0x5d, 0x45, 0x7f, 0xb2, 0x00, 0x4d, 0x2e, 0xc2, 0x40, 0x79, 0xa1, 0x5a, 0x2d, 0x2d, 0xf8, 0x37, - 0xc5, 0xf8, 0xbe, 0xc4, 0xb0, 0xdc, 0x9a, 0xab, 0x5b, 0xae, 0xe6, 0x23, 0xc9, 0xe3, 0x50, 0xa8, - 0x2c, 0x21, 0x19, 0x7f, 0x35, 0x39, 0xbc, 0xb5, 0x59, 0x1c, 0x30, 0xdb, 0x9c, 0x4a, 0xa0, 0xb0, - 0xde, 0xdb, 0x95, 0xb2, 0xe4, 0x2e, 0xc1, 0xeb, 0xbd, 0x67, 0x1a, 0x78, 0xed, 0xac, 0x05, 0x68, - 0xf2, 0x1c, 0x8c, 0x54, 0xa9, 0x63, 0xea, 0xcd, 0x85, 0x0e, 0x6e, 0x15, 0xb9, 0x8b, 0xd8, 0xc4, - 0xd6, 0x66, 0x71, 0xd4, 0x45, 0x78, 0xcd, 0x42, 0x84, 0x16, 0x21, 0x23, 0xe7, 0x20, 0x3f, 0x6b, - 0x5a, 0xfe, 0x13, 0x06, 0xf4, 0x71, 0x5f, 0x33, 0x2d, 0x4f, 0x43, 0xa8, 0xfa, 0xcf, 0xb2, 0xe9, - 0xc9, 0x14, 0x0e, 0x60, 0x38, 0x3e, 0xe0, 0x4d, 0x6f, 0x4c, 0x09, 0xf2, 0x7b, 0x50, 0x82, 0x55, - 0x38, 0x56, 0x32, 0x5a, 0xa6, 0x55, 0xc2, 0x9f, 0xee, 0xfc, 0x4c, 0x09, 0x87, 0xb7, 0xf4, 0x84, - 0x2e, 0x86, 0x16, 0xdf, 0xc3, 0x43, 0xe5, 0x32, 0x54, 0x4d, 0xe7, 0xb8, 0x5a, 0x6b, 0x55, 0xaf, - 0xd5, 0x79, 0x1e, 0x02, 0x2d, 0xce, 0x54, 0xfd, 0x89, 0xec, 0x36, 0xf9, 0x1f, 0x1e, 0x46, 0xe9, - 0xab, 0x5f, 0xcd, 0xf6, 0x4e, 0xc1, 0xf1, 0x50, 0x0a, 0xe5, 0x2f, 0xb3, 0x29, 0x09, 0x31, 0xf6, - 0x24, 0x89, 0xcb, 0x30, 0xc8, 0xd9, 0x04, 0xae, 0xb6, 0x38, 0xe3, 0x70, 0x65, 0xc5, 0x99, 0xce, - 0x47, 0x93, 0x05, 0x38, 0x51, 0x5a, 0x5d, 0xa5, 0x75, 0x2f, 0x0c, 0x9a, 0xbc, 0x10, 0x06, 0x4a, - 0xe5, 0x91, 0x66, 0x05, 0x3e, 0x0c, 0xba, 0x8c, 0x01, 0x41, 0x52, 0xcb, 0x91, 0x65, 0x38, 0x15, - 0x87, 0x57, 0xb9, 0x99, 0x9e, 0x97, 0x82, 0xcf, 0x26, 0x38, 0xf2, 0xff, 0xb4, 0x2e, 0x65, 0xd3, - 0x5a, 0x89, 0xd3, 0x69, 0x7f, 0xaf, 0x56, 0xe2, 0xdc, 0x9a, 0x5a, 0x4e, 0xfd, 0x66, 0x4e, 0xce, - 0x1b, 0xf2, 0xf0, 0x3a, 0x45, 0x5d, 0x8f, 0xb8, 0x42, 0xef, 0x74, 0xc8, 0x3c, 0x27, 0xa2, 0x7c, - 0x18, 0x1d, 0xc7, 0xf7, 0x1a, 0x0c, 0xa2, 0x0c, 0x20, 0x50, 0xf6, 0xff, 0x0b, 0x28, 0x49, 0x05, - 0xf2, 0x25, 0xa7, 0xc1, 0x4d, 0xd0, 0xed, 0x1e, 0x3e, 0xe9, 0x4e, 0xc3, 0x4d, 0x7f, 0xf8, 0xc4, - 0x58, 0xa8, 0x3f, 0x9e, 0xed, 0x91, 0xea, 0xe3, 0x61, 0x9c, 0x44, 0x9e, 0x9c, 0xe7, 0x41, 0x8e, - 0x6f, 0x9a, 0x96, 0x41, 0xce, 0xc0, 0xc9, 0x5b, 0xd5, 0x69, 0xad, 0x76, 0xb3, 0xb2, 0x50, 0xae, - 0xdd, 0x5a, 0xa8, 0x2e, 0x4d, 0x4f, 0x55, 0x66, 0x2a, 0xd3, 0xe5, 0xf1, 0x3e, 0x72, 0x1c, 0x8e, - 0x85, 0xa8, 0xd9, 0x5b, 0xf3, 0xa5, 0x85, 0xf1, 0x0c, 0x99, 0x80, 0xd1, 0x10, 0x38, 0xb9, 0xb8, - 0x3c, 0x9e, 0x7d, 0xf2, 0x83, 0x30, 0x8c, 0xbb, 0x38, 0xbe, 0xa2, 0x91, 0x11, 0x18, 0x5c, 0x9c, - 0xac, 0x4e, 0x6b, 0xb7, 0x91, 0x09, 0x40, 0xa1, 0x3c, 0xbd, 0xc0, 0x18, 0x66, 0x9e, 0xfc, 0x97, - 0x19, 0x80, 0xea, 0xcc, 0xf2, 0x92, 0x20, 0x1c, 0x86, 0x81, 0xca, 0xc2, 0xed, 0xd2, 0x5c, 0x85, - 0xd1, 0x0d, 0x42, 0x7e, 0x71, 0x69, 0x9a, 0xd5, 0x30, 0x04, 0xfd, 0x53, 0x73, 0x8b, 0xd5, 0xe9, - 0xf1, 0x2c, 0x03, 0x6a, 0xd3, 0xa5, 0xf2, 0x78, 0x8e, 0x01, 0xef, 0x68, 0x95, 0xe5, 0xe9, 0xf1, - 0x3c, 0xfb, 0x73, 0xae, 0xba, 0x5c, 0x5a, 0x1e, 0xef, 0x67, 0x7f, 0xce, 0xe0, 0x9f, 0x05, 0xc6, - 0xac, 0x3a, 0xbd, 0x8c, 0x3f, 0x06, 0x58, 0x13, 0x66, 0xfc, 0x5f, 0x83, 0x0c, 0xc5, 0x58, 0x97, - 0x2b, 0xda, 0xf8, 0x10, 0xfb, 0xc1, 0x58, 0xb2, 0x1f, 0xc0, 0x1a, 0xa7, 0x4d, 0xcf, 0x2f, 0xde, - 0x9e, 0x1e, 0x1f, 0x66, 0xbc, 0xe6, 0x6f, 0x32, 0xf0, 0x08, 0xfb, 0x53, 0x9b, 0x67, 0x7f, 0x8e, - 0x32, 0x4e, 0xda, 0x74, 0x69, 0x6e, 0xa9, 0xb4, 0x3c, 0x3b, 0x3e, 0xc6, 0xda, 0x83, 0x3c, 0x8f, - 0xf1, 0x92, 0x0b, 0xa5, 0xf9, 0xe9, 0xf1, 0x71, 0x41, 0x53, 0x9e, 0xab, 0x2c, 0xdc, 0x1c, 0x9f, - 0xc0, 0x86, 0xbc, 0x35, 0x8f, 0x3f, 0x08, 0x2b, 0x80, 0x7f, 0x1d, 0x7f, 0xf2, 0x93, 0x50, 0x58, - 0xac, 0xa2, 0xdd, 0x76, 0x1a, 0x8e, 0x2f, 0x56, 0x6b, 0xcb, 0x6f, 0x2d, 0x4d, 0xc7, 0xe4, 0x3d, - 0x01, 0xa3, 0x3e, 0x62, 0xae, 0xb2, 0x70, 0xeb, 0x63, 0x5c, 0xda, 0x3e, 0x68, 0xbe, 0x34, 0xb5, - 0x58, 0x1d, 0xcf, 0xb2, 0x5e, 0xf1, 0x41, 0x77, 0x2a, 0x0b, 0xe5, 0xc5, 0x3b, 0xd5, 0xf1, 0xdc, - 0x93, 0xf7, 0xfc, 0x6c, 0xa4, 0x8b, 0x8e, 0xd9, 0x30, 0x2d, 0x72, 0x1e, 0xce, 0x94, 0xa7, 0x6f, - 0x57, 0xa6, 0xa6, 0x6b, 0x8b, 0x5a, 0xe5, 0x46, 0x65, 0x21, 0x56, 0xd3, 0x49, 0x98, 0x88, 0xa2, - 0x4b, 0x4b, 0x95, 0xf1, 0x0c, 0x39, 0x05, 0x24, 0x0a, 0x7e, 0xa3, 0x34, 0x3f, 0x33, 0x9e, 0x25, - 0x0a, 0x9c, 0x88, 0xc2, 0x2b, 0x0b, 0xcb, 0xb7, 0x16, 0xa6, 0xc7, 0x73, 0x4f, 0xfe, 0x52, 0x06, - 0x4e, 0xa6, 0x86, 0x11, 0x20, 0x2a, 0x5c, 0x98, 0x9e, 0x2b, 0x55, 0x97, 0x2b, 0x53, 0xd5, 0xe9, - 0x92, 0x36, 0x35, 0x5b, 0x9b, 0x2a, 0x2d, 0x4f, 0xdf, 0x58, 0xd4, 0xde, 0xaa, 0xdd, 0x98, 0x5e, - 0x98, 0xd6, 0x4a, 0x73, 0xe3, 0x7d, 0xe4, 0x71, 0x28, 0x76, 0xa1, 0xa9, 0x4e, 0x4f, 0xdd, 0xd2, - 0x2a, 0xcb, 0x6f, 0x8d, 0x67, 0xc8, 0x63, 0x70, 0xbe, 0x2b, 0x11, 0xfb, 0x3d, 0x9e, 0x25, 0x17, - 0xe0, 0x6c, 0x37, 0x92, 0x37, 0xe7, 0xc6, 0x73, 0x4f, 0xfe, 0x74, 0x06, 0x48, 0xf2, 0x1d, 0x38, - 0x79, 0x14, 0xce, 0x31, 0xbd, 0xa8, 0x75, 0x6f, 0xe0, 0x63, 0x70, 0x3e, 0x95, 0x42, 0x6a, 0x5e, - 0x11, 0x1e, 0xe9, 0x42, 0x22, 0x1a, 0x77, 0x0e, 0x94, 0x74, 0x02, 0x6c, 0xda, 0x6f, 0x66, 0xe0, - 0x64, 0xaa, 0x11, 0x49, 0x2e, 0xc1, 0x07, 0x4a, 0xe5, 0x79, 0xd6, 0x37, 0x53, 0xcb, 0x95, 0xc5, - 0x85, 0x6a, 0x6d, 0x7e, 0xa6, 0x54, 0x63, 0xda, 0x77, 0xab, 0x1a, 0xeb, 0xcd, 0x8b, 0xa0, 0xf6, - 0xa0, 0x9c, 0x9a, 0x2d, 0x2d, 0xdc, 0x60, 0xc3, 0x8f, 0x7c, 0x00, 0x1e, 0xed, 0x4a, 0x37, 0xbd, - 0x50, 0x9a, 0x9c, 0x9b, 0x2e, 0x8f, 0x67, 0xc9, 0x13, 0xf0, 0x58, 0x57, 0xaa, 0x72, 0xa5, 0xca, - 0xc9, 0x72, 0x93, 0xe5, 0x77, 0xff, 0xde, 0x85, 0xbe, 0x77, 0xbf, 0x7b, 0x21, 0xf3, 0x87, 0xdf, - 0xbd, 0x90, 0xf9, 0xf3, 0xef, 0x5e, 0xc8, 0x7c, 0xfc, 0xda, 0x6e, 0xde, 0xf7, 0xf3, 0x69, 0x6b, - 0xa5, 0x80, 0x13, 0xfa, 0xb3, 0xff, 0x36, 0x00, 0x00, 0xff, 0xff, 0xc2, 0xf0, 0xa8, 0xb4, 0x1f, - 0x56, 0x01, 0x00, + // 15593 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0xbd, 0x6b, 0x74, 0x1c, 0xc9, + 0x75, 0x18, 0x8c, 0x79, 0x60, 0x00, 0x5c, 0x3c, 0x08, 0x14, 0x5f, 0x4d, 0x2e, 0xc9, 0xd9, 0xed, + 0xd5, 0x52, 0xe4, 0x6a, 0x97, 0xd4, 0x72, 0xb9, 0xbb, 0xda, 0x97, 0x76, 0x07, 0x18, 0x80, 0x98, + 0x25, 0x5e, 0xdb, 0x03, 0x92, 0x5a, 0xbd, 0xc6, 0x8d, 0xe9, 0x02, 0xd0, 0xcb, 0x99, 0xee, 0x51, + 0x77, 0x0f, 0x41, 0xec, 0xf7, 0xb2, 0xfc, 0xf9, 0x21, 0xf9, 0x93, 0x64, 0x7d, 0x72, 0x6c, 0xd9, + 0xb1, 0x13, 0xcb, 0xaf, 0xc4, 0xf1, 0x71, 0xec, 0x38, 0xc9, 0xb1, 0xad, 0x38, 0x3a, 0xb1, 0xa3, + 0x3c, 0xd6, 0xd1, 0x71, 0x8e, 0xed, 0x24, 0x3e, 0x3e, 0x89, 0x03, 0x39, 0x4a, 0x9c, 0x1f, 0x38, + 0xc9, 0x89, 0x93, 0xe8, 0xc4, 0x8e, 0xe3, 0xe4, 0xe4, 0xd4, 0xad, 0xea, 0xee, 0xea, 0xc7, 0x0c, + 0x9e, 0x6b, 0x2c, 0x44, 0xfc, 0x21, 0x31, 0xf7, 0xde, 0xba, 0x55, 0x7d, 0xeb, 0x56, 0xd5, 0xad, + 0xaa, 0x5b, 0xf7, 0xc2, 0x65, 0x8f, 0x36, 0x68, 0xcb, 0x76, 0xbc, 0xab, 0x0d, 0xba, 0xa2, 0xd7, + 0xd7, 0xaf, 0x7a, 0xeb, 0x2d, 0xea, 0x5e, 0xa5, 0xf7, 0xa8, 0xe5, 0xf9, 0xff, 0x5d, 0x69, 0x39, + 0xb6, 0x67, 0x93, 0x02, 0xff, 0x75, 0xf6, 0xc4, 0x8a, 0xbd, 0x62, 0x23, 0xe8, 0x2a, 0xfb, 0x8b, + 0x63, 0xcf, 0x9e, 0x5b, 0xb1, 0xed, 0x95, 0x06, 0xbd, 0x8a, 0xbf, 0x96, 0xda, 0xcb, 0x57, 0x5d, + 0xcf, 0x69, 0xd7, 0x3d, 0x81, 0x2d, 0xc6, 0xb1, 0x9e, 0xd9, 0xa4, 0xae, 0xa7, 0x37, 0x5b, 0x82, + 0xe0, 0x42, 0x9c, 0x60, 0xcd, 0xd1, 0x5b, 0x2d, 0xea, 0x88, 0xca, 0xcf, 0x3e, 0x92, 0xde, 0x4e, + 0xfc, 0x57, 0x90, 0x3c, 0x99, 0x4e, 0xe2, 0x33, 0x8a, 0x71, 0x54, 0xbf, 0x90, 0x85, 0xfe, 0x59, + 0xea, 0xe9, 0x86, 0xee, 0xe9, 0xe4, 0x1c, 0xf4, 0x56, 0x2c, 0x83, 0xde, 0x57, 0x32, 0x0f, 0x67, + 0x2e, 0xe5, 0xc6, 0x0b, 0x9b, 0x1b, 0xc5, 0x2c, 0x35, 0x35, 0x0e, 0x24, 0xe7, 0x21, 0xbf, 0xb8, + 0xde, 0xa2, 0x4a, 0xf6, 0xe1, 0xcc, 0xa5, 0x81, 0xf1, 0x81, 0xcd, 0x8d, 0x62, 0x2f, 0xca, 0x42, + 0x43, 0x30, 0x79, 0x04, 0xb2, 0x95, 0xb2, 0x92, 0x43, 0xe4, 0xd8, 0xe6, 0x46, 0x71, 0xb8, 0x6d, + 0x1a, 0x4f, 0xd8, 0x4d, 0xd3, 0xa3, 0xcd, 0x96, 0xb7, 0xae, 0x65, 0x2b, 0x65, 0x72, 0x11, 0xf2, + 0x13, 0xb6, 0x41, 0x95, 0x3c, 0x12, 0x91, 0xcd, 0x8d, 0xe2, 0x48, 0xdd, 0x36, 0xa8, 0x44, 0x85, + 0x78, 0xf2, 0x2a, 0xe4, 0x17, 0xcd, 0x26, 0x55, 0x7a, 0x1f, 0xce, 0x5c, 0x1a, 0xbc, 0x76, 0xf6, + 0x0a, 0x97, 0xca, 0x15, 0x5f, 0x2a, 0x57, 0x16, 0x7d, 0xb1, 0x8d, 0x8f, 0xbe, 0xbd, 0x51, 0xec, + 0xd9, 0xdc, 0x28, 0xe6, 0x99, 0x24, 0x3f, 0xff, 0xf5, 0x62, 0x46, 0xc3, 0x92, 0xe4, 0x25, 0x18, + 0x9c, 0x68, 0xb4, 0x5d, 0x8f, 0x3a, 0x73, 0x7a, 0x93, 0x2a, 0x05, 0xac, 0xf0, 0xec, 0xe6, 0x46, + 0xf1, 0x54, 0x9d, 0x83, 0x6b, 0x96, 0xde, 0x94, 0x2b, 0x96, 0xc9, 0xd5, 0x5f, 0xc9, 0xc0, 0xb1, + 0x2a, 0x75, 0x5d, 0xd3, 0xb6, 0x02, 0xd9, 0x3c, 0x06, 0x03, 0x02, 0x54, 0x29, 0xa3, 0x7c, 0x06, + 0xc6, 0xfb, 0x36, 0x37, 0x8a, 0x39, 0xd7, 0x34, 0xb4, 0x10, 0x43, 0xde, 0x0f, 0x7d, 0x77, 0x4c, + 0x6f, 0x75, 0x76, 0xaa, 0x24, 0xe4, 0x74, 0x6a, 0x73, 0xa3, 0x48, 0xd6, 0x4c, 0x6f, 0xb5, 0xd6, + 0x5c, 0xd6, 0xa5, 0x0a, 0x7d, 0x32, 0x32, 0x03, 0xa3, 0x0b, 0x8e, 0x79, 0x4f, 0xf7, 0xe8, 0x4d, + 0xba, 0xbe, 0x60, 0x37, 0xcc, 0xfa, 0xba, 0x90, 0xe2, 0xc3, 0x9b, 0x1b, 0xc5, 0x73, 0x2d, 0x8e, + 0xab, 0xdd, 0xa5, 0xeb, 0xb5, 0x16, 0x62, 0x25, 0x26, 0x89, 0x92, 0xea, 0x57, 0x7b, 0x61, 0xe8, + 0x96, 0x4b, 0x9d, 0xa0, 0xdd, 0x17, 0x21, 0xcf, 0x7e, 0x8b, 0x26, 0xa3, 0xcc, 0xdb, 0x2e, 0x75, + 0x64, 0x99, 0x33, 0x3c, 0xb9, 0x0c, 0xbd, 0x33, 0xf6, 0x8a, 0x69, 0x89, 0x66, 0x1f, 0xdf, 0xdc, + 0x28, 0x1e, 0x6b, 0x30, 0x80, 0x44, 0xc9, 0x29, 0xc8, 0x07, 0x61, 0xa8, 0xd2, 0x64, 0x3a, 0x64, + 0x5b, 0xba, 0x67, 0x3b, 0xa2, 0xb5, 0x28, 0x5d, 0x53, 0x82, 0x4b, 0x05, 0x23, 0xf4, 0xe4, 0x05, + 0x80, 0xd2, 0x9d, 0xaa, 0x66, 0x37, 0x68, 0x49, 0x9b, 0x13, 0xca, 0x80, 0xa5, 0xf5, 0x35, 0xb7, + 0xe6, 0xd8, 0x0d, 0x5a, 0xd3, 0x1d, 0xb9, 0x5a, 0x89, 0x9a, 0x4c, 0xc2, 0x48, 0xa9, 0x5e, 0xa7, + 0xae, 0xab, 0xd1, 0x4f, 0xb4, 0xa9, 0xeb, 0xb9, 0x4a, 0xef, 0xc3, 0xb9, 0x4b, 0x03, 0xe3, 0xe7, + 0x37, 0x37, 0x8a, 0x67, 0x74, 0xc4, 0xd4, 0x1c, 0x81, 0x92, 0x58, 0xc4, 0x0a, 0x91, 0x71, 0x18, + 0x2e, 0xbd, 0xd5, 0x76, 0x68, 0xc5, 0xa0, 0x96, 0x67, 0x7a, 0xeb, 0x42, 0x43, 0xce, 0x6d, 0x6e, + 0x14, 0x15, 0x9d, 0x21, 0x6a, 0xa6, 0xc0, 0x48, 0x4c, 0xa2, 0x45, 0xc8, 0x3c, 0x8c, 0xdd, 0x98, + 0x58, 0xa8, 0x52, 0xe7, 0x9e, 0x59, 0xa7, 0xa5, 0x7a, 0xdd, 0x6e, 0x5b, 0x9e, 0xd2, 0x87, 0x7c, + 0x1e, 0xd9, 0xdc, 0x28, 0x9e, 0x5f, 0xa9, 0xb7, 0x6a, 0x2e, 0xc7, 0xd6, 0x74, 0x8e, 0x96, 0x98, + 0x25, 0xcb, 0x92, 0x0f, 0xc3, 0xf0, 0xa2, 0xc3, 0xb4, 0xd0, 0x28, 0x53, 0x06, 0x57, 0xfa, 0x51, + 0xff, 0x4f, 0x5d, 0x11, 0x13, 0x10, 0x87, 0xfa, 0x3d, 0xcb, 0x1b, 0xeb, 0xf1, 0x02, 0x35, 0x03, + 0x71, 0x72, 0x63, 0x23, 0xac, 0x08, 0x05, 0x85, 0x7d, 0xbc, 0xe9, 0x50, 0x23, 0xa1, 0x6d, 0x03, + 0xd8, 0xe6, 0xcb, 0x9b, 0x1b, 0xc5, 0xc7, 0x1c, 0x41, 0x53, 0xeb, 0xaa, 0x76, 0x1d, 0x59, 0x91, + 0x49, 0xe8, 0x67, 0xda, 0x74, 0xd3, 0xb4, 0x0c, 0x05, 0x1e, 0xce, 0x5c, 0x1a, 0xb9, 0x36, 0xea, + 0xb7, 0xde, 0x87, 0x8f, 0x9f, 0xde, 0xdc, 0x28, 0x1e, 0x67, 0x3a, 0x58, 0xbb, 0x6b, 0x5a, 0xf2, + 0x14, 0x11, 0x14, 0x55, 0xff, 0x38, 0x0f, 0x23, 0x4c, 0x38, 0x92, 0x1e, 0x97, 0xd8, 0x90, 0x64, + 0x10, 0x36, 0x42, 0xdd, 0x96, 0x5e, 0xa7, 0x42, 0xa5, 0x91, 0x9d, 0xe5, 0x03, 0x25, 0x76, 0x71, + 0x7a, 0x72, 0x19, 0xfa, 0x39, 0xa8, 0x52, 0x16, 0x5a, 0x3e, 0xbc, 0xb9, 0x51, 0x1c, 0x70, 0x11, + 0x56, 0x33, 0x0d, 0x2d, 0x40, 0x33, 0x35, 0xe3, 0x7f, 0x4f, 0xdb, 0xae, 0xc7, 0x98, 0x0b, 0x25, + 0x47, 0x35, 0x13, 0x05, 0x56, 0x05, 0x4a, 0x56, 0xb3, 0x68, 0x21, 0xf2, 0x3c, 0x00, 0x87, 0x94, + 0x0c, 0xc3, 0x11, 0x9a, 0x7e, 0x66, 0x73, 0xa3, 0x78, 0x52, 0xb0, 0xd0, 0x0d, 0x43, 0x1e, 0x26, + 0x12, 0x31, 0x69, 0xc2, 0x10, 0xff, 0x35, 0xa3, 0x2f, 0xd1, 0x06, 0x57, 0xf3, 0xc1, 0x6b, 0x97, + 0x7c, 0x69, 0x46, 0xa5, 0x73, 0x45, 0x26, 0x9d, 0xb4, 0x3c, 0x67, 0x7d, 0xbc, 0x28, 0x66, 0xc6, + 0xd3, 0xa2, 0xaa, 0x06, 0xe2, 0xe4, 0x31, 0x29, 0x97, 0x61, 0x13, 0xe6, 0x94, 0xed, 0xac, 0xe9, + 0x8e, 0x41, 0x8d, 0xf1, 0x75, 0x79, 0xc2, 0x5c, 0xf6, 0xc1, 0xb5, 0x25, 0x59, 0x07, 0x64, 0x72, + 0x32, 0x01, 0xc3, 0x9c, 0x5b, 0xb5, 0xbd, 0x84, 0x7d, 0xdf, 0x97, 0x90, 0x96, 0xdb, 0x5e, 0x8a, + 0xf7, 0x77, 0xb4, 0x0c, 0x1b, 0x93, 0x1c, 0x70, 0x9b, 0x3a, 0x6c, 0x36, 0x45, 0xf5, 0x17, 0x63, + 0x52, 0x30, 0xb9, 0xc7, 0x31, 0x49, 0x1e, 0xa2, 0xc8, 0xd9, 0x57, 0x60, 0x2c, 0x21, 0x0a, 0x32, + 0x0a, 0xb9, 0xbb, 0x74, 0x9d, 0xab, 0x8b, 0xc6, 0xfe, 0x24, 0x27, 0xa0, 0xf7, 0x9e, 0xde, 0x68, + 0x8b, 0xb5, 0x4c, 0xe3, 0x3f, 0x5e, 0xc8, 0x7e, 0x20, 0xc3, 0xa6, 0x7e, 0x32, 0x61, 0x5b, 0x16, + 0xad, 0x7b, 0xf2, 0xec, 0xff, 0x2c, 0x0c, 0xcc, 0xd8, 0x75, 0xbd, 0x81, 0xfd, 0xc8, 0xf5, 0x4e, + 0xd9, 0xdc, 0x28, 0x9e, 0x60, 0x1d, 0x78, 0xa5, 0xc1, 0x30, 0x52, 0x9b, 0x42, 0x52, 0xa6, 0x00, + 0x1a, 0x6d, 0xda, 0x1e, 0xc5, 0x82, 0xd9, 0x50, 0x01, 0xb0, 0xa0, 0x83, 0x28, 0x59, 0x01, 0x42, + 0x62, 0x72, 0x15, 0xfa, 0x17, 0xd8, 0x82, 0x57, 0xb7, 0x1b, 0x42, 0xf9, 0x70, 0x4e, 0xc6, 0x45, + 0x50, 0x1e, 0x34, 0x3e, 0x91, 0x3a, 0x0d, 0x23, 0x13, 0x0d, 0x93, 0x5a, 0x9e, 0xdc, 0x6a, 0x36, + 0xa4, 0x4a, 0x2b, 0xd4, 0xf2, 0xe4, 0x56, 0xe3, 0xe0, 0xd3, 0x19, 0x54, 0x6e, 0x75, 0x40, 0xaa, + 0xfe, 0xd3, 0x1c, 0x9c, 0xb9, 0xd9, 0x5e, 0xa2, 0x8e, 0x45, 0x3d, 0xea, 0x8a, 0x95, 0x31, 0xe0, + 0x3a, 0x07, 0x63, 0x09, 0xa4, 0xe0, 0x8e, 0x2b, 0xd6, 0xdd, 0x00, 0x59, 0x13, 0x8b, 0xad, 0x3c, + 0xed, 0x25, 0x8a, 0x92, 0x69, 0x38, 0x16, 0x02, 0x59, 0x23, 0x5c, 0x25, 0x8b, 0x73, 0xfa, 0x85, + 0xcd, 0x8d, 0xe2, 0x59, 0x89, 0x1b, 0x6b, 0xb6, 0xac, 0xc1, 0xf1, 0x62, 0xe4, 0x26, 0x8c, 0x86, + 0xa0, 0x1b, 0x8e, 0xdd, 0x6e, 0xb9, 0x4a, 0x0e, 0x59, 0x15, 0x37, 0x37, 0x8a, 0x0f, 0x49, 0xac, + 0x56, 0x10, 0x29, 0xaf, 0xa4, 0xf1, 0x82, 0xe4, 0x3b, 0x33, 0x32, 0x37, 0x31, 0x0a, 0xf3, 0x38, + 0x0a, 0x9f, 0xf3, 0x47, 0x61, 0x47, 0x21, 0x5d, 0x89, 0x97, 0x14, 0x83, 0x32, 0xd6, 0x8c, 0xc4, + 0xa0, 0x4c, 0xd4, 0x78, 0x76, 0x02, 0x4e, 0xa6, 0xf2, 0xda, 0x91, 0x56, 0xff, 0x61, 0x4e, 0xe6, + 0xb2, 0x60, 0x1b, 0x41, 0x67, 0xce, 0xcb, 0x9d, 0xb9, 0x60, 0x1b, 0x68, 0x2e, 0x65, 0xc2, 0x45, + 0x4c, 0x6a, 0x6c, 0xcb, 0x36, 0xe2, 0x56, 0x53, 0xb2, 0x2c, 0xf9, 0x38, 0x9c, 0x4a, 0x00, 0xf9, + 0x74, 0xcd, 0xb5, 0xff, 0xe2, 0xe6, 0x46, 0x51, 0x4d, 0xe1, 0x1a, 0x9f, 0xbd, 0x3b, 0x70, 0x21, + 0x3a, 0x9c, 0x96, 0xa4, 0x6e, 0x5b, 0x9e, 0x6e, 0x5a, 0xc2, 0xca, 0xe3, 0xa3, 0xe4, 0xbd, 0x9b, + 0x1b, 0xc5, 0x47, 0x65, 0x1d, 0xf4, 0x69, 0xe2, 0x8d, 0xef, 0xc4, 0x87, 0x18, 0xa0, 0xa4, 0xa0, + 0x2a, 0x4d, 0x7d, 0xc5, 0x37, 0x5d, 0x2f, 0x6d, 0x6e, 0x14, 0xdf, 0x93, 0x5a, 0x87, 0xc9, 0xa8, + 0xe4, 0xa5, 0xb2, 0x13, 0x27, 0xa2, 0x01, 0x09, 0x71, 0x73, 0xb6, 0x41, 0xf1, 0x1b, 0x7a, 0x91, + 0xbf, 0xba, 0xb9, 0x51, 0xbc, 0x20, 0xf1, 0xb7, 0x6c, 0x83, 0xc6, 0x9b, 0x9f, 0x52, 0x5a, 0xfd, + 0x95, 0x1c, 0x5c, 0xa8, 0x96, 0x66, 0x67, 0x2a, 0x86, 0x6f, 0x5b, 0x2c, 0x38, 0xf6, 0x3d, 0xd3, + 0x90, 0x46, 0xef, 0x12, 0x9c, 0x8e, 0xa1, 0x26, 0xd1, 0x9c, 0x09, 0xac, 0x5a, 0xfc, 0x36, 0xdf, + 0x6e, 0x69, 0x09, 0x9a, 0x1a, 0xb7, 0x79, 0x6a, 0x11, 0x93, 0xbe, 0x13, 0x23, 0xd6, 0x47, 0x31, + 0x54, 0x75, 0xd5, 0x76, 0xbc, 0x7a, 0xdb, 0x13, 0x4a, 0x80, 0x7d, 0x94, 0xa8, 0xc3, 0x15, 0x44, + 0x5d, 0xaa, 0xf0, 0xf9, 0x90, 0x4f, 0x67, 0x60, 0xb4, 0xe4, 0x79, 0x8e, 0xb9, 0xd4, 0xf6, 0xe8, + 0xac, 0xde, 0x6a, 0x99, 0xd6, 0x0a, 0x8e, 0xf5, 0xc1, 0x6b, 0x2f, 0x05, 0x6b, 0x64, 0x57, 0x49, + 0x5c, 0x89, 0x17, 0x97, 0x86, 0xa8, 0xee, 0xa3, 0x6a, 0x4d, 0x8e, 0x93, 0x87, 0x68, 0xbc, 0x1c, + 0x1b, 0xa2, 0xa9, 0xbc, 0x76, 0x34, 0x44, 0xbf, 0x90, 0x83, 0x73, 0xf3, 0x77, 0x3d, 0x5d, 0xa3, + 0xae, 0xdd, 0x76, 0xea, 0xd4, 0xbd, 0xd5, 0x32, 0x74, 0x8f, 0x86, 0x23, 0xb5, 0x08, 0xbd, 0x25, + 0xc3, 0xa0, 0x06, 0xb2, 0xeb, 0xe5, 0xfb, 0x2f, 0x9d, 0x01, 0x34, 0x0e, 0x27, 0x8f, 0x41, 0x9f, + 0x28, 0x83, 0xdc, 0x7b, 0xc7, 0x07, 0x37, 0x37, 0x8a, 0x7d, 0x6d, 0x0e, 0xd2, 0x7c, 0x1c, 0x23, + 0x2b, 0xd3, 0x06, 0x65, 0x64, 0xb9, 0x90, 0xcc, 0xe0, 0x20, 0xcd, 0xc7, 0x91, 0xd7, 0x61, 0x04, + 0xd9, 0x06, 0xed, 0x11, 0x73, 0xdf, 0x09, 0x5f, 0xba, 0x72, 0x63, 0xf9, 0xd2, 0x84, 0xad, 0xa9, + 0x39, 0x7e, 0x01, 0x2d, 0xc6, 0x80, 0xdc, 0x81, 0x51, 0xd1, 0x88, 0x90, 0x69, 0x6f, 0x17, 0xa6, + 0x27, 0x37, 0x37, 0x8a, 0x63, 0xa2, 0xfd, 0x12, 0xdb, 0x04, 0x13, 0xc6, 0x58, 0x34, 0x3b, 0x64, + 0x5c, 0xd8, 0x8a, 0xb1, 0xf8, 0x62, 0x99, 0x71, 0x9c, 0x89, 0xfa, 0x06, 0x0c, 0xc9, 0x05, 0xc9, + 0x29, 0xdc, 0xe3, 0xf2, 0x71, 0x82, 0xbb, 0x63, 0xd3, 0xc0, 0x8d, 0xed, 0x53, 0x30, 0x58, 0xa6, + 0x6e, 0xdd, 0x31, 0x5b, 0xcc, 0x6a, 0x10, 0x4a, 0x7e, 0x6c, 0x73, 0xa3, 0x38, 0x68, 0x84, 0x60, + 0x4d, 0xa6, 0x51, 0xff, 0x5b, 0x06, 0x4e, 0x31, 0xde, 0x25, 0xd7, 0x35, 0x57, 0xac, 0xa6, 0xbc, + 0x6c, 0x3f, 0x01, 0x85, 0x2a, 0xd6, 0x27, 0x6a, 0x3a, 0xb1, 0xb9, 0x51, 0x1c, 0xe5, 0x2d, 0x90, + 0xf4, 0x50, 0xd0, 0x04, 0x1b, 0xbc, 0xec, 0x16, 0x1b, 0x3c, 0x66, 0xd2, 0x7a, 0xba, 0xe3, 0x99, + 0xd6, 0x4a, 0xd5, 0xd3, 0xbd, 0xb6, 0x1b, 0x31, 0x69, 0x05, 0xa6, 0xe6, 0x22, 0x2a, 0x62, 0xd2, + 0x46, 0x0a, 0x91, 0x57, 0x60, 0x68, 0xd2, 0x32, 0x42, 0x26, 0x7c, 0x42, 0x7c, 0x88, 0x59, 0x9a, + 0x14, 0xe1, 0x49, 0x16, 0x91, 0x02, 0xea, 0x5f, 0xcf, 0x80, 0xc2, 0x77, 0x63, 0x33, 0xa6, 0xeb, + 0xcd, 0xd2, 0xe6, 0x92, 0x34, 0x3b, 0x4d, 0xf9, 0xdb, 0x3b, 0x86, 0x93, 0xd6, 0x22, 0x34, 0x05, + 0xc4, 0xf6, 0xae, 0x61, 0xba, 0x5e, 0x7c, 0x32, 0x8c, 0x95, 0x22, 0x15, 0xe8, 0xe3, 0x9c, 0xb9, + 0x2d, 0x31, 0x78, 0x4d, 0xf1, 0x15, 0x21, 0x5e, 0x35, 0x57, 0x86, 0x26, 0x27, 0x96, 0xf7, 0xe7, + 0xa2, 0xbc, 0xfa, 0x37, 0xb2, 0x30, 0x1a, 0x2f, 0x44, 0xee, 0x40, 0xff, 0x6b, 0xb6, 0x69, 0x51, + 0x63, 0xde, 0xc2, 0x16, 0x76, 0x3f, 0xa5, 0xf0, 0x6d, 0xf1, 0xe3, 0x6f, 0x62, 0x99, 0x9a, 0x6c, + 0xc1, 0xe2, 0xa1, 0x45, 0xc0, 0x8c, 0x7c, 0x18, 0x06, 0x98, 0x0d, 0x78, 0x0f, 0x39, 0x67, 0xb7, + 0xe4, 0xfc, 0xb0, 0xe0, 0x7c, 0xc2, 0xe1, 0x85, 0x92, 0xac, 0x43, 0x76, 0x4c, 0xaf, 0x34, 0xaa, + 0xbb, 0xb6, 0x25, 0x7a, 0x1e, 0xf5, 0xca, 0x41, 0x88, 0xac, 0x57, 0x9c, 0x86, 0x99, 0xae, 0xfc, + 0x63, 0xb1, 0x1b, 0xa4, 0xbd, 0x0b, 0x97, 0x55, 0xbc, 0x07, 0x24, 0x62, 0xf5, 0xbb, 0xb3, 0xf0, + 0x64, 0x28, 0x32, 0x8d, 0xde, 0x33, 0xe9, 0x9a, 0x10, 0xe7, 0xaa, 0xd9, 0x12, 0x9b, 0x47, 0xa6, + 0xf2, 0xee, 0xc4, 0xaa, 0x6e, 0xad, 0x50, 0x83, 0x5c, 0x86, 0x5e, 0xb6, 0xc3, 0x77, 0x95, 0x0c, + 0x9a, 0x6b, 0x38, 0x9d, 0x38, 0x0c, 0x20, 0x9f, 0x3e, 0x20, 0x05, 0xb1, 0xa1, 0xb0, 0xe8, 0xe8, + 0xa6, 0xe7, 0xf7, 0x6c, 0x29, 0xd9, 0xb3, 0xdb, 0xa8, 0xf1, 0x0a, 0xe7, 0xc1, 0xe7, 0x7c, 0x14, + 0x84, 0x87, 0x00, 0x59, 0x10, 0x9c, 0xe4, 0xec, 0xf3, 0x30, 0x28, 0x11, 0xef, 0x68, 0x52, 0xff, + 0x72, 0x5e, 0xd6, 0x75, 0xbf, 0x59, 0x42, 0xd7, 0xaf, 0x32, 0x1d, 0x75, 0x5d, 0x66, 0x55, 0x70, + 0x25, 0x17, 0x9a, 0x88, 0xa0, 0xa8, 0x26, 0x22, 0x88, 0x3c, 0x0d, 0xfd, 0x9c, 0x45, 0xb0, 0x7f, + 0xc5, 0xbd, 0xaf, 0x83, 0xb0, 0xe8, 0xd2, 0x1c, 0x10, 0x92, 0x9f, 0xcd, 0xc0, 0xf9, 0xae, 0x92, + 0x40, 0x65, 0x18, 0xbc, 0xf6, 0xcc, 0xae, 0xc4, 0x38, 0xfe, 0xe4, 0xe6, 0x46, 0xf1, 0x72, 0x33, + 0x20, 0xa9, 0x39, 0x12, 0x4d, 0xad, 0xce, 0x89, 0xa4, 0x76, 0x75, 0x6f, 0x0a, 0x33, 0x1e, 0x79, + 0xa5, 0x53, 0x78, 0x86, 0x63, 0xd5, 0xd7, 0xfd, 0x46, 0xe6, 0x43, 0xe3, 0x51, 0x7c, 0xef, 0xb2, + 0x4f, 0x92, 0x52, 0x4d, 0x07, 0x2e, 0xa4, 0x0e, 0xa7, 0x39, 0xa6, 0xac, 0xaf, 0xcf, 0x2f, 0xcf, + 0xda, 0x96, 0xb7, 0xea, 0x57, 0xd0, 0x2b, 0x1f, 0x82, 0x60, 0x05, 0x86, 0xbe, 0x5e, 0xb3, 0x97, + 0x6b, 0x4d, 0x46, 0x95, 0x52, 0x47, 0x27, 0x4e, 0x6c, 0xa2, 0x15, 0x63, 0xce, 0x9f, 0x82, 0x0a, + 0xe1, 0x11, 0x95, 0x3f, 0x4e, 0x93, 0x13, 0x4e, 0xac, 0x90, 0x5a, 0x81, 0xa1, 0x19, 0xbb, 0x7e, + 0x37, 0x50, 0x97, 0xe7, 0xa1, 0xb0, 0xa8, 0x3b, 0x2b, 0xd4, 0x43, 0x59, 0x0c, 0x5e, 0x1b, 0xbb, + 0xc2, 0x8f, 0x7d, 0x19, 0x11, 0x47, 0x8c, 0x8f, 0x88, 0xd9, 0xa0, 0xe0, 0xe1, 0x6f, 0x4d, 0x14, + 0x50, 0xbf, 0xde, 0x0b, 0x43, 0xe2, 0x88, 0x12, 0x67, 0x73, 0xf2, 0x42, 0x78, 0xe8, 0x2b, 0xa6, + 0xaf, 0xe0, 0x98, 0x26, 0x38, 0x5e, 0x1a, 0x62, 0xcc, 0x7e, 0x6b, 0xa3, 0x98, 0xd9, 0xdc, 0x28, + 0xf6, 0x68, 0xfd, 0xd2, 0xa6, 0x32, 0x5c, 0x6f, 0xa4, 0x05, 0x56, 0x3e, 0x74, 0x8c, 0x95, 0xe5, + 0xeb, 0xcf, 0x2b, 0xd0, 0x27, 0xda, 0x20, 0x34, 0xee, 0x74, 0x78, 0x96, 0x11, 0x39, 0x6a, 0x8d, + 0x95, 0xf6, 0x4b, 0x91, 0x97, 0xa0, 0xc0, 0xf7, 0xf6, 0x42, 0x00, 0xa7, 0xd2, 0xcf, 0x42, 0x62, + 0xc5, 0x45, 0x19, 0x32, 0x0d, 0x10, 0xee, 0xeb, 0x83, 0x93, 0x65, 0xc1, 0x21, 0xb9, 0xe3, 0x8f, + 0x71, 0x91, 0xca, 0x92, 0x67, 0x61, 0x68, 0x91, 0x3a, 0x4d, 0xd3, 0xd2, 0x1b, 0x55, 0xf3, 0x2d, + 0xff, 0x70, 0x19, 0x17, 0x5e, 0xd7, 0x7c, 0x4b, 0x1e, 0xb9, 0x11, 0x3a, 0xf2, 0xb1, 0xb4, 0x7d, + 0x73, 0x1f, 0x36, 0xe4, 0x91, 0x2d, 0x37, 0x94, 0xb1, 0xf6, 0xa4, 0x6c, 0xa3, 0x5f, 0x87, 0xe1, + 0xc8, 0x96, 0x49, 0x9c, 0x1e, 0x9e, 0x4f, 0xb2, 0x96, 0xf6, 0x7f, 0x31, 0xb6, 0x51, 0x0e, 0x4c, + 0x93, 0x2b, 0x96, 0xe9, 0x99, 0x7a, 0x63, 0xc2, 0x6e, 0x36, 0x75, 0xcb, 0x50, 0x06, 0x42, 0x4d, + 0x36, 0x39, 0xa6, 0x56, 0xe7, 0x28, 0x59, 0x93, 0xa3, 0x85, 0xd8, 0xb6, 0x5c, 0xf4, 0xa1, 0x46, + 0xeb, 0xb6, 0xc3, 0x6c, 0x01, 0x3c, 0x1c, 0x14, 0xdb, 0x72, 0x97, 0xe3, 0x6a, 0x8e, 0x8f, 0x94, + 0x8d, 0xed, 0x78, 0xc1, 0xd7, 0xf2, 0xfd, 0x83, 0xa3, 0x43, 0xf1, 0xf3, 0x5c, 0xf5, 0xaf, 0xe5, + 0x60, 0x50, 0x90, 0xb2, 0xa5, 0xf4, 0x48, 0xc1, 0xf7, 0xa2, 0xe0, 0xa9, 0x8a, 0x5a, 0xd8, 0x2f, + 0x45, 0x55, 0x3f, 0x93, 0x0d, 0x66, 0xa3, 0x05, 0xc7, 0xb4, 0xf6, 0x36, 0x1b, 0x5d, 0x04, 0x98, + 0x58, 0x6d, 0x5b, 0x77, 0xf9, 0xbd, 0x55, 0x36, 0xbc, 0xb7, 0xaa, 0x9b, 0x9a, 0x84, 0x21, 0xe7, + 0x21, 0x5f, 0x66, 0xfc, 0x59, 0xcf, 0x0c, 0x8d, 0x0f, 0xbc, 0xcd, 0x39, 0x65, 0x9e, 0xd4, 0x10, + 0xcc, 0x36, 0x57, 0xe3, 0xeb, 0x1e, 0xe5, 0xe6, 0x6c, 0x8e, 0x6f, 0xae, 0x96, 0x18, 0x40, 0xe3, + 0x70, 0x72, 0x1d, 0xc6, 0xca, 0xb4, 0xa1, 0xaf, 0xcf, 0x9a, 0x8d, 0x86, 0xe9, 0xd2, 0xba, 0x6d, + 0x19, 0x2e, 0x0a, 0x59, 0x54, 0xd7, 0x74, 0xb5, 0x24, 0x01, 0x51, 0xa1, 0x30, 0xbf, 0xbc, 0xec, + 0x52, 0x0f, 0xc5, 0x97, 0x1b, 0x07, 0x36, 0x39, 0xdb, 0x08, 0xd1, 0x04, 0x46, 0xfd, 0x85, 0x0c, + 0xdb, 0xbd, 0xb8, 0x77, 0x3d, 0xbb, 0x15, 0x68, 0xf9, 0x9e, 0x44, 0x72, 0x39, 0xb4, 0x2b, 0xb2, + 0xf8, 0xb5, 0xc7, 0xc4, 0xd7, 0xf6, 0x09, 0xdb, 0x22, 0xb4, 0x28, 0x52, 0xbf, 0x2a, 0xb7, 0xc5, + 0x57, 0xa9, 0x7f, 0x94, 0x85, 0xd3, 0xa2, 0xc5, 0x13, 0x0d, 0xb3, 0xb5, 0x64, 0xeb, 0x8e, 0xa1, + 0xd1, 0x3a, 0x35, 0xef, 0xd1, 0xc3, 0x39, 0xf0, 0xa2, 0x43, 0x27, 0xbf, 0x87, 0xa1, 0x73, 0x0d, + 0x37, 0x82, 0x4c, 0x32, 0x78, 0xe0, 0xcb, 0x8d, 0x8a, 0xd1, 0xcd, 0x8d, 0xe2, 0x90, 0xc1, 0xc1, + 0x78, 0xe4, 0xaf, 0xc9, 0x44, 0x4c, 0x49, 0x66, 0xa8, 0xb5, 0xe2, 0xad, 0xa2, 0x92, 0xf4, 0x72, + 0x25, 0x69, 0x20, 0x44, 0x13, 0x18, 0xf5, 0x3f, 0x66, 0xe1, 0x44, 0x5c, 0xe4, 0x55, 0x6a, 0x19, + 0x47, 0xf2, 0x7e, 0x67, 0xe4, 0xfd, 0xcd, 0x1c, 0x3c, 0x24, 0xca, 0x54, 0x57, 0x75, 0x87, 0x1a, + 0x65, 0xd3, 0xa1, 0x75, 0xcf, 0x76, 0xd6, 0x0f, 0xb1, 0x01, 0xb5, 0x7f, 0x62, 0xbf, 0x0e, 0x05, + 0xb1, 0xfd, 0xe7, 0xeb, 0xcc, 0x48, 0xd0, 0x12, 0x84, 0x26, 0x56, 0x28, 0x7e, 0x74, 0x10, 0xeb, + 0xac, 0xc2, 0x76, 0x3a, 0xeb, 0x03, 0x30, 0x1c, 0x88, 0x1e, 0x37, 0xa2, 0x7d, 0xa1, 0xb5, 0x65, + 0xf8, 0x08, 0xdc, 0x8b, 0x6a, 0x51, 0x42, 0xac, 0xcd, 0x07, 0x54, 0xca, 0x68, 0x0d, 0x0d, 0x8b, + 0xda, 0x82, 0x72, 0xa6, 0xa1, 0xc9, 0x44, 0xea, 0x46, 0x1e, 0xce, 0xa6, 0x77, 0xbb, 0x46, 0x75, + 0xe3, 0xa8, 0xd7, 0xbf, 0x25, 0x7b, 0x9d, 0x3c, 0x02, 0xf9, 0x05, 0xdd, 0x5b, 0x15, 0xf7, 0xe0, + 0x78, 0x27, 0xbc, 0x6c, 0x36, 0x68, 0xad, 0xa5, 0x7b, 0xab, 0x1a, 0xa2, 0xa4, 0x39, 0x03, 0x90, + 0x63, 0xca, 0x9c, 0x21, 0x2d, 0xf6, 0x83, 0x0f, 0x67, 0x2e, 0xe5, 0x53, 0x17, 0xfb, 0xaf, 0xe7, + 0x3b, 0xcd, 0x2b, 0x77, 0x1c, 0xd3, 0xa3, 0x47, 0x1a, 0x76, 0xa4, 0x61, 0x7b, 0xd4, 0xb0, 0xdf, + 0xc9, 0xc2, 0x70, 0xb0, 0x69, 0x7a, 0x93, 0xd6, 0x0f, 0x66, 0xad, 0x0a, 0xb7, 0x32, 0xb9, 0x3d, + 0x6f, 0x65, 0xf6, 0xa2, 0x50, 0x6a, 0x70, 0xe4, 0xc9, 0x4d, 0x03, 0x94, 0x18, 0x3f, 0xf2, 0x0c, + 0x0e, 0x3a, 0x1f, 0x81, 0xbe, 0x59, 0xfd, 0xbe, 0xd9, 0x6c, 0x37, 0x85, 0x95, 0x8e, 0x7e, 0x5d, + 0x4d, 0xfd, 0xbe, 0xe6, 0xc3, 0xd5, 0x7f, 0x9e, 0x81, 0x11, 0x21, 0x54, 0xc1, 0x7c, 0x4f, 0x52, + 0x0d, 0xa5, 0x93, 0xdd, 0xb3, 0x74, 0x72, 0xbb, 0x97, 0x8e, 0xfa, 0xa3, 0x39, 0x50, 0xa6, 0xcc, + 0x06, 0x5d, 0x74, 0x74, 0xcb, 0x5d, 0xa6, 0x8e, 0xd8, 0x4e, 0x4f, 0x32, 0x56, 0x7b, 0xfa, 0x40, + 0x69, 0x4a, 0xc9, 0xee, 0x6a, 0x4a, 0x79, 0x1f, 0x0c, 0x88, 0xc6, 0x04, 0x3e, 0x85, 0x38, 0x6a, + 0x1c, 0x1f, 0xa8, 0x85, 0x78, 0x46, 0x5c, 0x6a, 0xb5, 0x1c, 0xfb, 0x1e, 0x75, 0xf8, 0x2d, 0x95, + 0x20, 0xd6, 0x7d, 0xa0, 0x16, 0xe2, 0x25, 0xce, 0xd4, 0xb7, 0x17, 0x65, 0xce, 0xd4, 0xd1, 0x42, + 0x3c, 0xb9, 0x04, 0xfd, 0x33, 0x76, 0x5d, 0x47, 0x41, 0xf3, 0x69, 0x65, 0x68, 0x73, 0xa3, 0xd8, + 0xdf, 0x10, 0x30, 0x2d, 0xc0, 0x32, 0xca, 0xb2, 0xbd, 0x66, 0x35, 0x6c, 0x9d, 0x3b, 0xbf, 0xf4, + 0x73, 0x4a, 0x43, 0xc0, 0xb4, 0x00, 0xcb, 0x28, 0x99, 0xcc, 0xd1, 0xa9, 0xa8, 0x3f, 0xe4, 0xb9, + 0x2c, 0x60, 0x5a, 0x80, 0x55, 0x7f, 0x21, 0xcf, 0xb4, 0xd7, 0x35, 0xdf, 0x7a, 0xe0, 0xd7, 0x85, + 0x70, 0xc0, 0xf4, 0xee, 0x62, 0xc0, 0x3c, 0x30, 0x07, 0x76, 0xea, 0x1f, 0xf7, 0x01, 0x08, 0xe9, + 0x4f, 0x1e, 0x6d, 0x0e, 0xf7, 0xa6, 0x35, 0x65, 0x18, 0x9b, 0xb4, 0x56, 0x75, 0xab, 0x4e, 0x8d, + 0xf0, 0xd8, 0xb2, 0x80, 0x43, 0x1b, 0x7d, 0x7a, 0xa9, 0x40, 0x86, 0xe7, 0x96, 0x5a, 0xb2, 0x00, + 0x79, 0x0a, 0x06, 0x2b, 0x96, 0x47, 0x1d, 0xbd, 0xee, 0x99, 0xf7, 0xa8, 0x98, 0x1a, 0xf0, 0x66, + 0xd8, 0x0c, 0xc1, 0x9a, 0x4c, 0x43, 0xae, 0xc3, 0xd0, 0x82, 0xee, 0x78, 0x66, 0xdd, 0x6c, 0xe9, + 0x96, 0xe7, 0x2a, 0xfd, 0x38, 0xa3, 0xa1, 0x85, 0xd1, 0x92, 0xe0, 0x5a, 0x84, 0x8a, 0x7c, 0x0c, + 0x06, 0x70, 0x6b, 0x8a, 0x8e, 0xd3, 0x03, 0x5b, 0x5e, 0x1c, 0x3e, 0x1a, 0xba, 0x07, 0xf2, 0xd3, + 0x57, 0xbc, 0x01, 0x8e, 0xdf, 0x1d, 0x06, 0x1c, 0xc9, 0x87, 0xa0, 0x6f, 0xd2, 0x32, 0x90, 0x39, + 0x6c, 0xc9, 0x5c, 0x15, 0xcc, 0x4f, 0x85, 0xcc, 0xed, 0x56, 0x8c, 0xb7, 0xcf, 0x2e, 0x7d, 0x94, + 0x0d, 0xbe, 0x73, 0xa3, 0x6c, 0xe8, 0x1d, 0x38, 0x16, 0x1f, 0xde, 0xaf, 0x63, 0xf1, 0x91, 0x5d, + 0x1e, 0x8b, 0xab, 0x6f, 0xc1, 0xe0, 0xf8, 0xc2, 0x54, 0x30, 0x7a, 0xcf, 0x40, 0x6e, 0x41, 0x78, + 0x2a, 0xe4, 0xb9, 0x3d, 0xd3, 0x32, 0x0d, 0x8d, 0xc1, 0xc8, 0x65, 0xe8, 0x9f, 0x40, 0xf7, 0x37, + 0x71, 0x8b, 0x98, 0xe7, 0xeb, 0x5f, 0x1d, 0x61, 0xe8, 0x05, 0xeb, 0xa3, 0xc9, 0x63, 0xd0, 0xb7, + 0xe0, 0xd8, 0x2b, 0x8e, 0xde, 0x14, 0x6b, 0x30, 0xba, 0x8a, 0xb4, 0x38, 0x48, 0xf3, 0x71, 0xea, + 0xf7, 0x67, 0x7c, 0xb3, 0x9d, 0x95, 0xa8, 0xb6, 0xf1, 0x68, 0x1e, 0xeb, 0xee, 0xe7, 0x25, 0x5c, + 0x0e, 0xd2, 0x7c, 0x1c, 0xb9, 0x0c, 0xbd, 0x93, 0x8e, 0x63, 0x3b, 0xb2, 0xb3, 0x39, 0x65, 0x00, + 0xf9, 0xba, 0x17, 0x29, 0xc8, 0x73, 0x30, 0xc8, 0xe7, 0x1c, 0x7e, 0xa2, 0x99, 0xeb, 0x76, 0x53, + 0x2a, 0x53, 0xaa, 0x5f, 0xcd, 0x49, 0x36, 0x1b, 0x97, 0xf8, 0x03, 0x78, 0x2b, 0xf0, 0x34, 0xe4, + 0xc6, 0x17, 0xa6, 0xc4, 0x04, 0x78, 0xdc, 0x2f, 0x2a, 0xa9, 0x4a, 0xac, 0x1c, 0xa3, 0x26, 0xe7, + 0x20, 0xbf, 0xc0, 0xd4, 0xa7, 0x80, 0xea, 0xd1, 0xbf, 0xb9, 0x51, 0xcc, 0xb7, 0x98, 0xfe, 0x20, + 0x14, 0xb1, 0x6c, 0x33, 0xc3, 0x77, 0x4c, 0x1c, 0x1b, 0xee, 0x63, 0xce, 0x41, 0xbe, 0xe4, 0xac, + 0xdc, 0x13, 0xb3, 0x16, 0x62, 0x75, 0x67, 0xe5, 0x9e, 0x86, 0x50, 0x72, 0x15, 0x40, 0xa3, 0x5e, + 0xdb, 0xb1, 0xf0, 0x1d, 0xc8, 0x00, 0x9e, 0xbf, 0xe1, 0x6c, 0xe8, 0x20, 0xb4, 0x56, 0xb7, 0x0d, + 0xaa, 0x49, 0x24, 0xea, 0x4f, 0x87, 0x17, 0x3b, 0x65, 0xd3, 0xbd, 0x7b, 0xd4, 0x85, 0x3b, 0xe8, + 0x42, 0x5d, 0x1c, 0x71, 0x26, 0x3b, 0xa9, 0x08, 0xbd, 0x53, 0x0d, 0x7d, 0xc5, 0xc5, 0x3e, 0x14, + 0xbe, 0x64, 0xcb, 0x0c, 0xa0, 0x71, 0x78, 0xac, 0x9f, 0xfa, 0xb7, 0xee, 0xa7, 0x2f, 0xf6, 0x06, + 0xa3, 0x6d, 0x8e, 0x7a, 0x6b, 0xb6, 0x73, 0xd4, 0x55, 0xdb, 0xed, 0xaa, 0x8b, 0xd0, 0x57, 0x75, + 0xea, 0xd2, 0xd1, 0x05, 0xee, 0x07, 0x5c, 0xa7, 0xce, 0x8f, 0x2d, 0x7c, 0x24, 0xa3, 0x2b, 0xbb, + 0x1e, 0xd2, 0xf5, 0x85, 0x74, 0x86, 0xeb, 0x09, 0x3a, 0x81, 0x14, 0x74, 0x0b, 0xb6, 0xe3, 0x89, + 0x8e, 0x0b, 0xe8, 0x5a, 0xb6, 0xe3, 0x69, 0x3e, 0x92, 0xbc, 0x0f, 0x60, 0x71, 0x62, 0xc1, 0x77, + 0xb6, 0x1f, 0x08, 0x7d, 0x01, 0x85, 0x97, 0xbd, 0x26, 0xa1, 0xc9, 0x22, 0x0c, 0xcc, 0xb7, 0xa8, + 0xc3, 0xb7, 0x42, 0xfc, 0x65, 0xc7, 0x7b, 0x63, 0xa2, 0x15, 0xfd, 0x7e, 0x45, 0xfc, 0x1f, 0x90, + 0xf3, 0xf5, 0xc5, 0xf6, 0x7f, 0x6a, 0x21, 0x23, 0xf2, 0x1c, 0x14, 0x4a, 0xdc, 0xce, 0x1b, 0x44, + 0x96, 0x81, 0xc8, 0x70, 0x0b, 0xca, 0x51, 0x7c, 0xcf, 0xae, 0xe3, 0xdf, 0x9a, 0x20, 0x57, 0x2f, + 0xc3, 0x68, 0xbc, 0x1a, 0x32, 0x08, 0x7d, 0x13, 0xf3, 0x73, 0x73, 0x93, 0x13, 0x8b, 0xa3, 0x3d, + 0xa4, 0x1f, 0xf2, 0xd5, 0xc9, 0xb9, 0xf2, 0x68, 0x46, 0xfd, 0x39, 0x69, 0x06, 0x61, 0xaa, 0x75, + 0x74, 0x35, 0xbc, 0xa7, 0xfb, 0x96, 0x51, 0xbc, 0x0f, 0xc5, 0x13, 0x83, 0xa6, 0xe9, 0x79, 0xd4, + 0x10, 0xab, 0x04, 0xde, 0x17, 0x7a, 0xf7, 0xb5, 0x04, 0x9e, 0x3c, 0x01, 0xc3, 0x08, 0x13, 0x57, + 0x84, 0x7c, 0x7f, 0x2c, 0x0a, 0x38, 0xf7, 0xb5, 0x28, 0x52, 0xfd, 0x5a, 0x78, 0x3b, 0x3c, 0x43, + 0xf5, 0xc3, 0x7a, 0xa3, 0xf8, 0x2e, 0xe9, 0x2f, 0xf5, 0xcf, 0xf2, 0xfc, 0x09, 0x08, 0x7f, 0xb8, + 0x77, 0x10, 0xa2, 0x0c, 0x8f, 0x74, 0x73, 0x3b, 0x38, 0xd2, 0x7d, 0x02, 0x0a, 0xb3, 0xd4, 0x5b, + 0xb5, 0x7d, 0xc7, 0x2f, 0xf4, 0xd0, 0x6b, 0x22, 0x44, 0xf6, 0xd0, 0xe3, 0x34, 0xe4, 0x2e, 0x10, + 0xff, 0x55, 0x5e, 0xe0, 0x88, 0xed, 0x1f, 0x21, 0x9f, 0x4e, 0xec, 0x53, 0xaa, 0xf8, 0x24, 0x17, + 0x7d, 0xec, 0x4f, 0x04, 0x8e, 0xde, 0x92, 0x27, 0xd6, 0x9f, 0x6e, 0x14, 0x0b, 0x9c, 0x46, 0x4b, + 0x61, 0x4b, 0x5e, 0x87, 0x81, 0xd9, 0xa9, 0x92, 0x78, 0xa1, 0xc7, 0xbd, 0x22, 0xce, 0x04, 0x52, + 0xf4, 0x11, 0x81, 0x48, 0xf0, 0xbd, 0x4d, 0x73, 0x59, 0x4f, 0x3e, 0xd0, 0x0b, 0xb9, 0x30, 0x6d, + 0xe1, 0x2f, 0x77, 0xc4, 0xe9, 0x42, 0xa0, 0x2d, 0xd1, 0xf7, 0x3c, 0x71, 0x59, 0x71, 0x6c, 0x4c, + 0x5b, 0xfa, 0xf7, 0x30, 0xba, 0xe7, 0x61, 0xac, 0xd4, 0x6a, 0x35, 0x4c, 0x6a, 0xa0, 0xbe, 0x68, + 0xed, 0x06, 0x75, 0x85, 0xcb, 0x0f, 0x3e, 0x06, 0xd1, 0x39, 0xb2, 0x86, 0xef, 0x42, 0x6b, 0x4e, + 0x3b, 0xea, 0x9f, 0x99, 0x2c, 0xab, 0xfe, 0x60, 0x16, 0x4e, 0x4d, 0x38, 0x54, 0xf7, 0xe8, 0xec, + 0x54, 0xa9, 0xd4, 0x46, 0x1f, 0xb9, 0x46, 0x83, 0x5a, 0x2b, 0x07, 0x33, 0xac, 0x5f, 0x84, 0x91, + 0xa0, 0x01, 0xd5, 0xba, 0xdd, 0xa2, 0xf2, 0xc3, 0xaa, 0xba, 0x8f, 0xa9, 0xb9, 0x0c, 0xa5, 0xc5, + 0x48, 0xc9, 0x4d, 0x38, 0x1e, 0x40, 0x4a, 0x8d, 0x86, 0xbd, 0xa6, 0xd1, 0xb6, 0xcb, 0x1d, 0x63, + 0xfb, 0xb9, 0x63, 0x6c, 0xc8, 0x41, 0x67, 0xf8, 0x9a, 0xc3, 0x08, 0xb4, 0xb4, 0x52, 0xea, 0x97, + 0x72, 0x70, 0xfa, 0xb6, 0xde, 0x30, 0x8d, 0x50, 0x34, 0x1a, 0x75, 0x5b, 0xb6, 0xe5, 0xd2, 0x43, + 0x34, 0x4a, 0x23, 0x43, 0x21, 0xbf, 0x2f, 0x43, 0x21, 0xd9, 0x45, 0xbd, 0x7b, 0xee, 0xa2, 0xc2, + 0xae, 0xba, 0xe8, 0x3f, 0x64, 0x60, 0xd4, 0x77, 0xfc, 0x97, 0x5f, 0x53, 0x4b, 0x5e, 0xe9, 0x78, + 0x84, 0x18, 0xf3, 0x83, 0x46, 0x3c, 0xa9, 0x42, 0xdf, 0xe4, 0xfd, 0x96, 0xe9, 0x50, 0x77, 0x1b, + 0x4e, 0xdc, 0xe7, 0xc5, 0x71, 0xc9, 0x18, 0xe5, 0x45, 0x12, 0x27, 0x25, 0x1c, 0x8c, 0xcf, 0xf9, + 0xf8, 0xd3, 0x87, 0x71, 0xff, 0x89, 0x38, 0x7f, 0xce, 0x27, 0x9e, 0x48, 0x44, 0xde, 0x67, 0x86, + 0xa4, 0xe4, 0x51, 0xc8, 0x2d, 0x2e, 0xce, 0x88, 0x99, 0x14, 0x9f, 0xe6, 0x7b, 0x9e, 0xfc, 0x5e, + 0x91, 0x61, 0xd5, 0xdf, 0xcf, 0x02, 0x30, 0x55, 0xe0, 0xc3, 0xf5, 0x40, 0x94, 0x70, 0x1c, 0xfa, + 0x7d, 0x81, 0x0b, 0x35, 0x0c, 0xbc, 0xf6, 0xe3, 0x1d, 0x11, 0xaf, 0x3b, 0x78, 0xa1, 0x51, 0xf4, + 0x1d, 0xc9, 0xf9, 0x3d, 0x00, 0xee, 0x6c, 0xd0, 0x91, 0xdc, 0x77, 0x1f, 0x7f, 0x1f, 0x0c, 0x88, + 0x19, 0xcf, 0x8e, 0x9c, 0xff, 0xd7, 0x7d, 0xa0, 0x16, 0xe2, 0x63, 0x53, 0x6b, 0x61, 0x0f, 0x0b, + 0xb1, 0x2f, 0x5e, 0xde, 0x2b, 0x47, 0xe2, 0xdd, 0x67, 0xf1, 0x7e, 0x4e, 0x88, 0x97, 0xbf, 0xe0, + 0x39, 0xb4, 0xe2, 0xdd, 0xb7, 0xb3, 0x6f, 0xf5, 0x77, 0x32, 0x40, 0x58, 0xb3, 0x16, 0x74, 0xd7, + 0x5d, 0xb3, 0x1d, 0x83, 0x3b, 0xa7, 0x1f, 0x88, 0x60, 0xf6, 0xef, 0xbe, 0xf2, 0xab, 0xfd, 0x70, + 0x3c, 0xe2, 0xf8, 0x7b, 0xc8, 0x27, 0xab, 0xcb, 0xd1, 0xd1, 0xd4, 0xed, 0xd5, 0xcb, 0x7b, 0xe4, + 0x0b, 0xd1, 0xde, 0xc8, 0x03, 0x34, 0xe9, 0x26, 0xf4, 0x49, 0x18, 0x12, 0x3f, 0xd8, 0x0a, 0xed, + 0xdf, 0x74, 0xe1, 0x28, 0x75, 0x19, 0x40, 0x8b, 0xa0, 0xc9, 0x33, 0x30, 0xc0, 0x06, 0xcc, 0x0a, + 0x46, 0xf1, 0xe8, 0x0b, 0x5f, 0x94, 0x18, 0x3e, 0x50, 0x5e, 0x4f, 0x02, 0x4a, 0xe9, 0x1d, 0x51, + 0xff, 0x36, 0xde, 0x11, 0x7d, 0x1c, 0x06, 0x4b, 0x96, 0x65, 0x7b, 0xb8, 0x49, 0x77, 0xc5, 0xd5, + 0x44, 0x47, 0xab, 0xfc, 0x51, 0x7c, 0x1c, 0x1f, 0xd2, 0xa7, 0x9a, 0xe5, 0x32, 0x43, 0x72, 0xcd, + 0x7f, 0x15, 0x43, 0x1d, 0xe1, 0x55, 0x8e, 0xd7, 0x33, 0x8e, 0x80, 0x25, 0x1f, 0xc5, 0x60, 0xe7, + 0x0d, 0x2f, 0x38, 0x76, 0xcb, 0x76, 0xa9, 0xc1, 0x05, 0x35, 0x18, 0x86, 0x1a, 0x68, 0x09, 0x04, + 0xbe, 0x63, 0x8b, 0x44, 0xd4, 0x88, 0x14, 0x21, 0xcb, 0x70, 0xc2, 0xbf, 0x28, 0x0e, 0x5e, 0x0c, + 0x56, 0xca, 0xae, 0x32, 0x84, 0xaf, 0x92, 0x48, 0x5c, 0x19, 0x2a, 0xe5, 0xf1, 0x0b, 0xfe, 0xb5, + 0x88, 0xff, 0xe4, 0xb0, 0x66, 0x1a, 0x72, 0x57, 0xa7, 0xf2, 0x23, 0xdf, 0x06, 0x83, 0xb3, 0xfa, + 0xfd, 0x72, 0x5b, 0x9c, 0xbd, 0x0c, 0x6f, 0xff, 0xf6, 0xa5, 0xa9, 0xdf, 0xaf, 0x19, 0xa2, 0x5c, + 0xcc, 0xa6, 0x90, 0x59, 0x92, 0x1a, 0x9c, 0x5a, 0x70, 0xec, 0xa6, 0xed, 0x51, 0x23, 0xf6, 0xf8, + 0xee, 0x58, 0xf8, 0x5a, 0xb7, 0x25, 0x28, 0x6a, 0x5d, 0x5e, 0xe1, 0x75, 0x60, 0x43, 0x9a, 0x70, + 0xac, 0xe4, 0xba, 0xed, 0x26, 0x0d, 0x6f, 0xa8, 0x46, 0xb7, 0xfc, 0x8c, 0xf7, 0x0a, 0xaf, 0xe5, + 0x87, 0x74, 0x2c, 0xca, 0x2f, 0xa8, 0x6a, 0x9e, 0x29, 0xd7, 0x88, 0xdf, 0x12, 0xe7, 0xfd, 0x5a, + 0xbe, 0x7f, 0x64, 0xf4, 0x98, 0x76, 0x3a, 0xd9, 0x98, 0x45, 0xd3, 0x6b, 0x50, 0xf5, 0x2b, 0x19, + 0x80, 0x50, 0xc0, 0xe4, 0xc9, 0x68, 0xa8, 0xa0, 0x4c, 0x78, 0xd1, 0x21, 0xa2, 0x17, 0x44, 0x62, + 0x03, 0x91, 0x73, 0x90, 0xc7, 0x08, 0x17, 0xd9, 0xf0, 0x60, 0xf5, 0xae, 0x69, 0x19, 0x1a, 0x42, + 0x19, 0x56, 0x7a, 0x8a, 0x8e, 0x58, 0xbc, 0xd4, 0xe7, 0x56, 0x61, 0x19, 0x8e, 0x55, 0xdb, 0x4b, + 0x7e, 0xdd, 0xd2, 0xbb, 0x3a, 0x0c, 0xb4, 0xe1, 0xb6, 0x97, 0x82, 0xc7, 0xa8, 0x91, 0x30, 0x26, + 0xd1, 0x22, 0xea, 0x2f, 0x64, 0x62, 0xb3, 0xe0, 0x01, 0x2e, 0x7a, 0xef, 0x49, 0xfa, 0x69, 0x24, + 0xa7, 0x25, 0xf5, 0xc7, 0xb2, 0x30, 0xb8, 0x60, 0x3b, 0x9e, 0x08, 0x19, 0x72, 0xb8, 0x57, 0x21, + 0x69, 0xaf, 0x94, 0xdf, 0xc1, 0x5e, 0xe9, 0x1c, 0xe4, 0x25, 0x17, 0x65, 0x7e, 0x2f, 0x62, 0x18, + 0x8e, 0x86, 0x50, 0xf5, 0xdb, 0xb3, 0x00, 0x1f, 0x7a, 0xea, 0xa9, 0x07, 0x58, 0x40, 0xea, 0x8f, + 0x64, 0xe0, 0x98, 0xb8, 0xa8, 0x93, 0x82, 0x6e, 0xf5, 0xf9, 0x57, 0xac, 0xf2, 0xb8, 0xe4, 0x20, + 0xcd, 0xc7, 0xb1, 0x25, 0x60, 0xf2, 0xbe, 0xe9, 0xe1, 0x5d, 0x85, 0x14, 0x75, 0x8b, 0x0a, 0x98, + 0xbc, 0x04, 0xf8, 0x74, 0xe4, 0x49, 0xff, 0x0a, 0x32, 0x17, 0xae, 0x7b, 0xac, 0xc0, 0x64, 0xea, + 0x35, 0xa4, 0xfa, 0x4b, 0x79, 0xc8, 0x4f, 0xde, 0xa7, 0xf5, 0x43, 0xde, 0x35, 0xd2, 0xc1, 0x66, + 0x7e, 0x8f, 0x07, 0x9b, 0xbb, 0xf1, 0xa9, 0x78, 0x25, 0xec, 0xcf, 0x42, 0xb4, 0xfa, 0x58, 0xcf, + 0xc7, 0xab, 0xf7, 0x7b, 0xfa, 0xf0, 0xb9, 0xe4, 0xfc, 0xc3, 0x1c, 0xe4, 0xaa, 0x13, 0x0b, 0x47, + 0x7a, 0x73, 0xa0, 0x7a, 0xd3, 0xfd, 0xce, 0x5a, 0x0d, 0xae, 0xa1, 0xfa, 0x43, 0x2f, 0xd1, 0xd8, + 0x8d, 0xd3, 0x37, 0x73, 0x30, 0x52, 0x9d, 0x5a, 0x5c, 0x90, 0x4e, 0x82, 0x6f, 0x72, 0x4f, 0x3e, + 0xf4, 0x29, 0xe3, 0x5d, 0x7a, 0x2e, 0x61, 0xcf, 0xdc, 0xaa, 0x58, 0xde, 0xb3, 0xd7, 0x6f, 0xeb, + 0x8d, 0x36, 0xc5, 0xa3, 0x17, 0xee, 0xf7, 0xeb, 0x9a, 0x6f, 0xd1, 0x2f, 0xe1, 0xc3, 0x7f, 0x9f, + 0x01, 0x79, 0x11, 0x72, 0xb7, 0x84, 0x47, 0x46, 0x27, 0x3e, 0x4f, 0x5f, 0xe3, 0x7c, 0xd8, 0x24, + 0x98, 0x6b, 0x9b, 0x06, 0x72, 0x60, 0xa5, 0x58, 0xe1, 0x1b, 0x62, 0x01, 0xde, 0x56, 0xe1, 0x15, + 0xbf, 0xf0, 0x8d, 0x4a, 0x99, 0x54, 0x61, 0x70, 0x81, 0x3a, 0x4d, 0x13, 0x3b, 0xca, 0x9f, 0xb3, + 0xbb, 0x33, 0x61, 0x3b, 0x95, 0xc1, 0x56, 0x58, 0x08, 0x99, 0xc9, 0x5c, 0xc8, 0x1b, 0x00, 0xdc, + 0x46, 0xd9, 0x66, 0x20, 0xc7, 0xf3, 0x68, 0xf7, 0x73, 0xd3, 0x32, 0xc5, 0xc6, 0x93, 0x98, 0x91, + 0xbb, 0x30, 0x3a, 0x6b, 0x1b, 0xe6, 0xb2, 0xc9, 0x5d, 0x2f, 0xb1, 0x82, 0xc2, 0xd6, 0x0e, 0x4f, + 0xcc, 0x94, 0x6c, 0x4a, 0xe5, 0xd2, 0xaa, 0x49, 0x30, 0x56, 0xff, 0x5e, 0x2f, 0xe4, 0x59, 0xb7, + 0x1f, 0x8d, 0xdf, 0xbd, 0x8c, 0xdf, 0x12, 0x8c, 0xde, 0xb1, 0x9d, 0xbb, 0xa6, 0xb5, 0x12, 0x78, + 0xc5, 0x8b, 0xbd, 0x29, 0x7a, 0xf2, 0xac, 0x71, 0x5c, 0x2d, 0x70, 0xa0, 0xd7, 0x12, 0xe4, 0x5b, + 0x8c, 0xe0, 0xe7, 0x01, 0xf8, 0x5b, 0x77, 0xa4, 0xe9, 0x0f, 0x83, 0x55, 0xf0, 0x97, 0xf0, 0xe8, + 0x68, 0x2f, 0x07, 0xab, 0x08, 0x89, 0xd9, 0x26, 0x9c, 0xfb, 0x42, 0x0c, 0xa0, 0xdf, 0x3d, 0x6e, + 0xc2, 0xd1, 0x17, 0x42, 0x36, 0x02, 0xb8, 0x57, 0xc4, 0x02, 0x80, 0x74, 0xbf, 0x04, 0x31, 0x41, + 0x44, 0x26, 0x07, 0x11, 0x1e, 0x2e, 0xe5, 0x7a, 0x49, 0x93, 0x78, 0x90, 0x67, 0x63, 0x17, 0xe0, + 0x24, 0xc2, 0xad, 0xe3, 0xfd, 0x77, 0xe8, 0x40, 0x35, 0xb4, 0x95, 0x03, 0x95, 0xfa, 0x99, 0x2c, + 0x0c, 0x54, 0xdb, 0x4b, 0xee, 0xba, 0xeb, 0xd1, 0xe6, 0x21, 0x57, 0x63, 0x7f, 0x7b, 0x95, 0x4f, + 0xdd, 0x5e, 0x3d, 0xea, 0x0b, 0x45, 0x3a, 0x77, 0x0c, 0x4c, 0x3a, 0x5f, 0x1c, 0x7f, 0x33, 0x0b, + 0xa3, 0xfc, 0xe2, 0xac, 0x6c, 0xba, 0xf5, 0x7d, 0x70, 0xe6, 0x3f, 0x78, 0xa9, 0xec, 0xed, 0xb2, + 0x79, 0x1b, 0x4f, 0x24, 0xd4, 0x4f, 0x66, 0x61, 0xb0, 0xd4, 0xf6, 0x56, 0x4b, 0x1e, 0xea, 0xd6, + 0x03, 0xb9, 0x3f, 0xf9, 0x8d, 0x0c, 0x1c, 0x63, 0x0d, 0x59, 0xb4, 0xef, 0x52, 0x6b, 0x1f, 0x0e, + 0x1e, 0xe5, 0x03, 0xc4, 0xec, 0x2e, 0x0f, 0x10, 0x7d, 0x59, 0xe6, 0x76, 0x26, 0x4b, 0x3c, 0x2e, + 0xd7, 0xec, 0x06, 0x3d, 0xdc, 0x9f, 0xb1, 0x8f, 0xc7, 0xe5, 0xbe, 0x40, 0xf6, 0xe1, 0x7a, 0xe6, + 0x5b, 0x4b, 0x20, 0xfb, 0x70, 0xb6, 0xf4, 0xad, 0x21, 0x90, 0xaf, 0x66, 0x60, 0x60, 0xdc, 0xf6, + 0x0e, 0xf9, 0xc0, 0x17, 0x5f, 0x71, 0xb8, 0xd5, 0xdc, 0xff, 0x8a, 0xc3, 0xad, 0x9b, 0xea, 0x0f, + 0x65, 0xe1, 0x84, 0x08, 0xd2, 0x2d, 0xce, 0x1f, 0x8e, 0xa6, 0x63, 0x31, 0xd8, 0x92, 0xa2, 0x39, + 0x9a, 0x87, 0x84, 0x68, 0x7e, 0x26, 0x07, 0x27, 0x30, 0x94, 0x29, 0xdb, 0x96, 0x7d, 0x0b, 0xd8, + 0x22, 0xa4, 0x1e, 0xbd, 0x04, 0x9d, 0x4d, 0xb9, 0x04, 0xfd, 0xd3, 0x8d, 0xe2, 0xb3, 0x2b, 0xa6, + 0xb7, 0xda, 0x5e, 0xba, 0x52, 0xb7, 0x9b, 0x57, 0x57, 0x1c, 0xfd, 0x9e, 0xc9, 0xaf, 0xff, 0xf4, + 0xc6, 0xd5, 0x20, 0xdf, 0x85, 0xde, 0x32, 0x45, 0x26, 0x8c, 0x2a, 0xee, 0x75, 0x18, 0x57, 0xff, + 0xfa, 0xd4, 0x05, 0x78, 0xcd, 0x36, 0x2d, 0xe1, 0x53, 0xc8, 0x0d, 0xdd, 0x2a, 0xdb, 0x1f, 0xbe, + 0x69, 0x9b, 0x56, 0x2d, 0xee, 0x58, 0xb8, 0xd3, 0xfa, 0x42, 0xd6, 0x9a, 0x54, 0x8d, 0xfa, 0xcf, + 0x32, 0x70, 0x26, 0xaa, 0xc5, 0xdf, 0x0a, 0xb6, 0xe3, 0x0f, 0x67, 0xe1, 0xe4, 0x0d, 0x14, 0x4e, + 0xe0, 0xc8, 0x71, 0x34, 0x6f, 0x89, 0xc1, 0x99, 0x22, 0x9b, 0x23, 0x8b, 0xb2, 0xb3, 0x6c, 0x8e, + 0x26, 0x75, 0x21, 0x9b, 0xdf, 0xcc, 0xc0, 0xf1, 0xf9, 0x4a, 0x79, 0xe2, 0x5b, 0x64, 0x44, 0x25, + 0xbf, 0xe7, 0x90, 0x1b, 0x9c, 0x89, 0xef, 0x39, 0xe4, 0xa6, 0xe7, 0x17, 0xb2, 0x70, 0xbc, 0x5a, + 0x9a, 0x9d, 0xf9, 0x56, 0x99, 0xc1, 0x27, 0x64, 0xaf, 0x43, 0xff, 0x10, 0x4c, 0xd8, 0x02, 0xf2, + 0x67, 0xde, 0xbe, 0xd6, 0xd9, 0x1b, 0x31, 0x29, 0x94, 0x43, 0x3e, 0x75, 0xef, 0x8b, 0x50, 0x98, + 0xe6, 0x47, 0xa8, 0x0f, 0xb9, 0xe6, 0xff, 0x83, 0x02, 0x0c, 0xde, 0x6c, 0x2f, 0x51, 0xe1, 0x9c, + 0xf2, 0x40, 0x9f, 0xfc, 0x5e, 0x83, 0x41, 0x21, 0x06, 0xbc, 0x35, 0x91, 0x82, 0xe7, 0x89, 0x60, + 0x28, 0x3c, 0x3e, 0x91, 0x4c, 0x44, 0xce, 0x41, 0xfe, 0x36, 0x75, 0x96, 0xe4, 0x77, 0xa5, 0xf7, + 0xa8, 0xb3, 0xa4, 0x21, 0x94, 0xcc, 0x84, 0x2e, 0xf3, 0xa5, 0x85, 0x0a, 0x26, 0x52, 0x11, 0x17, + 0x36, 0x98, 0x19, 0x26, 0xf0, 0x7b, 0xd3, 0x5b, 0x26, 0x4f, 0xc1, 0x22, 0xbf, 0x69, 0x8f, 0x97, + 0x24, 0x73, 0x30, 0x26, 0x3b, 0x3e, 0xf1, 0x2c, 0x22, 0xfd, 0x29, 0xec, 0xd2, 0xf2, 0x87, 0x24, + 0x8b, 0x92, 0x57, 0x60, 0xc8, 0x07, 0xa2, 0x0b, 0xd7, 0x40, 0x18, 0xba, 0x3e, 0x60, 0x15, 0x4b, + 0x51, 0x14, 0x29, 0x20, 0x33, 0xc0, 0x6b, 0x08, 0x48, 0x61, 0x10, 0x73, 0x89, 0x8b, 0x14, 0x20, + 0xcf, 0x20, 0x03, 0x7c, 0xe6, 0x81, 0xce, 0x2a, 0x83, 0xf8, 0xe8, 0x12, 0x5d, 0xf2, 0x1d, 0x01, + 0xe7, 0x4f, 0x6b, 0x23, 0x64, 0x64, 0x1e, 0x20, 0x74, 0x2a, 0x10, 0x01, 0x0c, 0x76, 0xec, 0xee, + 0x20, 0xb1, 0x90, 0xaf, 0x03, 0x87, 0x77, 0x73, 0x1d, 0xa8, 0xfe, 0x76, 0x16, 0x06, 0x4b, 0xad, + 0x56, 0x30, 0x14, 0x9e, 0x84, 0x42, 0xa9, 0xd5, 0xba, 0xa5, 0x55, 0xe4, 0x50, 0xe6, 0x7a, 0xab, + 0x55, 0x6b, 0x3b, 0xa6, 0xec, 0x13, 0xca, 0x89, 0xc8, 0x04, 0x0c, 0x97, 0x5a, 0xad, 0x85, 0xf6, + 0x52, 0xc3, 0xac, 0x4b, 0x99, 0x91, 0x78, 0x12, 0xb7, 0x56, 0xab, 0xd6, 0x42, 0x4c, 0x3c, 0x3d, + 0x56, 0xb4, 0x0c, 0xf9, 0x38, 0x86, 0xfd, 0x11, 0x89, 0x79, 0x78, 0xea, 0x0f, 0x35, 0x08, 0x62, + 0x1e, 0xb6, 0xed, 0x4a, 0x40, 0xc4, 0x83, 0xbd, 0x9f, 0xf3, 0x43, 0xe6, 0xb3, 0x8a, 0x12, 0x09, + 0x78, 0x42, 0x96, 0xe4, 0xfd, 0xd0, 0x57, 0x6a, 0xb5, 0xa4, 0xfb, 0x26, 0x74, 0x2a, 0x62, 0xa5, + 0x62, 0x7d, 0xec, 0x93, 0x9d, 0x7d, 0x09, 0x46, 0xa2, 0x95, 0xed, 0x28, 0x58, 0xfc, 0x9f, 0x64, + 0xf0, 0x83, 0x0e, 0xb9, 0x4f, 0xf3, 0xd3, 0x90, 0x2b, 0xb5, 0x5a, 0x62, 0x3e, 0x3a, 0x9e, 0xd2, + 0x1f, 0xf1, 0x27, 0xd0, 0xa5, 0x56, 0xcb, 0xff, 0xf4, 0x43, 0xfe, 0x38, 0x62, 0x57, 0x9f, 0xfe, + 0x55, 0xfe, 0xe9, 0x87, 0xfb, 0xe1, 0x82, 0xfa, 0x4b, 0x39, 0x38, 0x56, 0x6a, 0xb5, 0x8e, 0x82, + 0xcc, 0xef, 0xd7, 0x43, 0xeb, 0xa7, 0x00, 0xa4, 0xe9, 0xb1, 0x2f, 0x78, 0xba, 0x35, 0x28, 0x4d, + 0x8d, 0x4a, 0x46, 0x93, 0x88, 0x7c, 0xf5, 0xeb, 0xdf, 0x91, 0xfa, 0x7d, 0x32, 0x87, 0x53, 0xf1, + 0x61, 0x0f, 0x1a, 0xf5, 0x6e, 0xe9, 0x36, 0xd1, 0x07, 0x85, 0x1d, 0xf5, 0xc1, 0xaf, 0x47, 0x06, + 0x0f, 0x06, 0x2d, 0x3f, 0xea, 0x85, 0xde, 0x3d, 0x99, 0xc5, 0x23, 0xb2, 0x30, 0x45, 0x24, 0x1b, + 0x3f, 0x91, 0x92, 0x88, 0xab, 0x54, 0x67, 0xa8, 0x9a, 0x69, 0x68, 0x31, 0x5a, 0xbf, 0x0f, 0xfb, + 0x76, 0xd4, 0x87, 0x1b, 0x59, 0x7c, 0x3b, 0x1d, 0xc4, 0x65, 0xda, 0xfb, 0xee, 0xe2, 0x2a, 0x00, + 0xf7, 0x3c, 0x08, 0xdc, 0x9a, 0x87, 0x79, 0x08, 0x16, 0x9e, 0x5f, 0x49, 0x84, 0x60, 0x09, 0x49, + 0x02, 0x0f, 0xa9, 0x5c, 0xaa, 0x87, 0xd4, 0x65, 0xe8, 0xd7, 0xf4, 0xb5, 0xd7, 0xdb, 0xd4, 0x59, + 0x17, 0xe6, 0x0c, 0x0f, 0x7b, 0xa8, 0xaf, 0xd5, 0x3e, 0xc1, 0x80, 0x5a, 0x80, 0x26, 0x6a, 0xf0, + 0xf8, 0x5e, 0xf2, 0x08, 0xe1, 0x67, 0xe4, 0xc1, 0x93, 0xfb, 0xdd, 0x28, 0x3a, 0x79, 0x01, 0x72, + 0xa5, 0x3b, 0x55, 0x21, 0xd9, 0xa0, 0x6b, 0x4b, 0x77, 0xaa, 0x42, 0x5e, 0x1d, 0xcb, 0xde, 0xa9, + 0xaa, 0x9f, 0xcc, 0x02, 0x49, 0x52, 0x92, 0x67, 0x61, 0x00, 0xa1, 0x2b, 0x4c, 0x67, 0xe4, 0xc4, + 0x9c, 0x6b, 0x6e, 0xcd, 0x41, 0x68, 0xc4, 0xb8, 0xf3, 0x49, 0xc9, 0xf3, 0x98, 0x83, 0x58, 0xa4, + 0x86, 0x8b, 0x24, 0xe6, 0x5c, 0x73, 0xfd, 0xac, 0xbd, 0xb1, 0x14, 0xc4, 0x82, 0x18, 0xed, 0xc2, + 0x3b, 0xd5, 0x69, 0xdb, 0xf5, 0x84, 0xa8, 0xb9, 0x5d, 0xb8, 0xe6, 0x62, 0x46, 0xd8, 0x88, 0x5d, + 0xc8, 0xc9, 0x30, 0xab, 0xd5, 0x9d, 0x2a, 0x7f, 0xa6, 0x62, 0x68, 0x76, 0xc3, 0x37, 0x28, 0x79, + 0x56, 0xab, 0x35, 0xb7, 0xc6, 0x9f, 0xb8, 0x18, 0x98, 0xfc, 0x38, 0x92, 0xd5, 0x2a, 0x52, 0x4a, + 0xfd, 0x6c, 0x3f, 0x8c, 0x96, 0x75, 0x4f, 0x5f, 0xd2, 0x5d, 0x2a, 0xed, 0xa6, 0x8f, 0xf9, 0x30, + 0xff, 0x73, 0x24, 0x39, 0x18, 0x4b, 0x29, 0x5f, 0x13, 0x2f, 0x40, 0x5e, 0x0c, 0xf9, 0x06, 0x39, + 0x47, 0xe5, 0x24, 0x66, 0x4b, 0xb5, 0x96, 0x00, 0x6b, 0x09, 0x42, 0xf2, 0x04, 0x0c, 0xfa, 0x30, + 0xb6, 0x01, 0xc8, 0x85, 0x3a, 0x63, 0x2c, 0x31, 0xfb, 0x5f, 0x93, 0xd1, 0xe4, 0x79, 0x18, 0xf2, + 0x7f, 0x4a, 0xa6, 0x35, 0xcf, 0xc8, 0xb6, 0x94, 0xd8, 0x3d, 0xc9, 0xa4, 0x72, 0x51, 0x9c, 0xdf, + 0x7a, 0x23, 0x45, 0x63, 0x49, 0xcf, 0x22, 0xa4, 0xe4, 0x13, 0x30, 0xe2, 0xff, 0x16, 0x1b, 0x06, + 0x9e, 0x1f, 0xee, 0x89, 0x20, 0xb7, 0x72, 0x4c, 0xac, 0x57, 0xa2, 0xe4, 0x7c, 0xeb, 0xf0, 0x90, + 0x9f, 0xc7, 0xcb, 0x58, 0x4a, 0xee, 0x1c, 0x62, 0x15, 0x90, 0x0a, 0x8c, 0xf9, 0x90, 0x50, 0x43, + 0xfb, 0xc2, 0x1d, 0xa3, 0xb1, 0x54, 0x4b, 0x55, 0xd2, 0x64, 0x29, 0xd2, 0x80, 0x73, 0x11, 0xa0, + 0xe1, 0xae, 0x9a, 0xcb, 0x9e, 0xd8, 0xee, 0x89, 0x18, 0xc4, 0x22, 0x71, 0x63, 0xc0, 0x95, 0xd3, + 0xf8, 0x19, 0x58, 0xa3, 0xd9, 0xa1, 0xba, 0x72, 0x23, 0x55, 0x38, 0xe1, 0xe3, 0x6f, 0x4c, 0x2c, + 0x2c, 0x38, 0xf6, 0x9b, 0xb4, 0xee, 0x55, 0xca, 0x62, 0xbb, 0x8c, 0xb1, 0xe9, 0x8c, 0xa5, 0xda, + 0x4a, 0xbd, 0xc5, 0x94, 0x82, 0xe1, 0xa2, 0xcc, 0x53, 0x0b, 0x93, 0xdb, 0x70, 0x52, 0x82, 0x57, + 0x2c, 0xd7, 0xd3, 0xad, 0x3a, 0xad, 0x94, 0xc5, 0x1e, 0x1a, 0xf7, 0xf3, 0x82, 0xab, 0x29, 0x90, + 0x51, 0xb6, 0xe9, 0xc5, 0xc9, 0x4b, 0x30, 0xec, 0x23, 0xf8, 0x2d, 0xe2, 0x20, 0xde, 0x22, 0xe2, + 0x90, 0x34, 0x96, 0x6a, 0xf1, 0xd7, 0x94, 0x51, 0x62, 0x59, 0xa3, 0x30, 0xb5, 0xfd, 0x50, 0x44, + 0xa3, 0xbc, 0xf5, 0x56, 0xaa, 0x32, 0x62, 0xba, 0xfb, 0x57, 0x42, 0x8d, 0x9a, 0x77, 0xcc, 0x15, + 0x93, 0xef, 0xa4, 0xfd, 0x07, 0x94, 0x4b, 0x35, 0x1b, 0x81, 0x69, 0xfa, 0xc1, 0xc9, 0xcf, 0x96, + 0xe0, 0x78, 0x8a, 0x8e, 0xed, 0x68, 0xc7, 0xf8, 0x99, 0x6c, 0xd8, 0x88, 0x43, 0xbe, 0x6d, 0x1c, + 0x87, 0x7e, 0xff, 0x4b, 0x84, 0xf1, 0xa0, 0x74, 0x1a, 0x9a, 0x71, 0x1e, 0x3e, 0x3e, 0x22, 0x8e, + 0x43, 0xbe, 0x95, 0xdc, 0x0f, 0x71, 0xbc, 0x9d, 0x09, 0xc5, 0x71, 0xc8, 0xb7, 0x97, 0xbf, 0x99, + 0x0b, 0xe7, 0xa4, 0xa3, 0x3d, 0xe6, 0x7e, 0x99, 0xc9, 0xa1, 0x1f, 0x6c, 0x61, 0x07, 0x0f, 0x19, + 0x65, 0xd5, 0xec, 0xdb, 0xa5, 0x6a, 0xfe, 0x6e, 0xb2, 0x3f, 0xb9, 0xe9, 0x79, 0x28, 0xfb, 0x73, + 0x1f, 0x06, 0x2b, 0xb9, 0x16, 0xae, 0x63, 0xdc, 0x46, 0xef, 0x95, 0x42, 0xfc, 0x2d, 0x09, 0x13, + 0x3d, 0x4a, 0x42, 0x3e, 0x02, 0xa7, 0x23, 0x80, 0x05, 0xdd, 0xd1, 0x9b, 0xd4, 0x0b, 0x33, 0x0e, + 0x62, 0xd0, 0x26, 0xbf, 0x74, 0xad, 0x15, 0xa0, 0xe5, 0x2c, 0x86, 0x1d, 0x38, 0x48, 0xca, 0xd1, + 0xb7, 0x03, 0x27, 0xe9, 0x2f, 0xe6, 0x42, 0x53, 0x25, 0x1a, 0x7c, 0x55, 0xa3, 0x6e, 0xbb, 0xe1, + 0x3d, 0xb8, 0x1d, 0xbc, 0xbb, 0xd4, 0x16, 0xd3, 0x70, 0xac, 0xb4, 0xbc, 0x4c, 0xeb, 0x9e, 0x1f, + 0x53, 0xda, 0x15, 0xe1, 0xf6, 0xf8, 0xd6, 0x41, 0xa0, 0x44, 0x8c, 0xe0, 0x48, 0x6e, 0xfc, 0x58, + 0x31, 0xf5, 0xf7, 0xf2, 0xa0, 0x04, 0xa6, 0x7b, 0xf0, 0x50, 0xeb, 0x00, 0x97, 0xc9, 0x77, 0x45, + 0xaf, 0x98, 0x30, 0x16, 0x0a, 0xa3, 0xda, 0x6e, 0x36, 0x75, 0x1c, 0x7a, 0x6c, 0x6b, 0x50, 0x8c, + 0x33, 0x0b, 0x09, 0xf9, 0x6e, 0xe0, 0xac, 0xd8, 0x0d, 0x90, 0xf0, 0x21, 0x5c, 0xcd, 0xe5, 0x2c, + 0xb4, 0x24, 0x57, 0xf2, 0xb9, 0x0c, 0x9c, 0xf0, 0x3b, 0x65, 0x7e, 0x89, 0x99, 0xc5, 0x13, 0x76, + 0xdb, 0xf2, 0xfc, 0x9d, 0xc8, 0x0b, 0x9d, 0xab, 0xe3, 0x9d, 0x74, 0x25, 0xad, 0x30, 0x6f, 0x49, + 0x10, 0x58, 0x22, 0x50, 0x08, 0x1b, 0x69, 0x6a, 0x75, 0x24, 0xd2, 0x52, 0xeb, 0x3d, 0x7b, 0x03, + 0xce, 0x74, 0x64, 0xb9, 0x95, 0x19, 0xda, 0x2b, 0x9b, 0xa1, 0xff, 0x22, 0x13, 0x4e, 0x44, 0x31, + 0x21, 0x91, 0x2b, 0x00, 0x21, 0x48, 0x6c, 0x4c, 0x47, 0x36, 0x37, 0x8a, 0x10, 0x0a, 0x4d, 0x93, + 0x28, 0xc8, 0x3c, 0x14, 0x84, 0x58, 0x78, 0x76, 0xdf, 0xf7, 0x6d, 0xd1, 0x0b, 0x57, 0x64, 0x39, + 0xe0, 0xa6, 0x53, 0x7c, 0xb3, 0x60, 0x73, 0xf6, 0x79, 0x18, 0xdc, 0xed, 0x77, 0x7d, 0x2e, 0x07, + 0x44, 0xde, 0x45, 0x1e, 0xa0, 0x89, 0x7d, 0x88, 0xa7, 0xb0, 0x4b, 0xd0, 0xcf, 0x3e, 0x01, 0xf3, + 0x5d, 0x48, 0xf1, 0x6d, 0xdb, 0x02, 0xa6, 0x05, 0xd8, 0x30, 0xb8, 0x54, 0x5f, 0x7a, 0x70, 0x29, + 0xf5, 0x07, 0x72, 0x70, 0x4a, 0xee, 0x90, 0x32, 0xc5, 0x90, 0xf9, 0x47, 0x9d, 0xf2, 0x0e, 0x76, + 0x8a, 0x0a, 0x05, 0xbe, 0x79, 0x10, 0xb9, 0x0b, 0xf8, 0xc1, 0x0e, 0x42, 0x34, 0x81, 0x51, 0xff, + 0x6d, 0x16, 0x86, 0x17, 0x6c, 0xd7, 0x5b, 0x71, 0xa8, 0xbb, 0xa0, 0x3b, 0xee, 0x03, 0xdc, 0x1d, + 0x1f, 0x80, 0x61, 0x0c, 0x0f, 0xd4, 0xa4, 0x16, 0x0f, 0xa1, 0xd3, 0x2b, 0x25, 0x1b, 0xf1, 0x11, + 0x22, 0xaf, 0x54, 0x84, 0x90, 0x69, 0x3f, 0xb7, 0xfc, 0xa4, 0xa0, 0x4d, 0xdc, 0xec, 0xe3, 0x70, + 0xf5, 0x27, 0x72, 0x30, 0xe4, 0x4b, 0x79, 0xdc, 0x3c, 0xac, 0x37, 0x35, 0x07, 0x2b, 0xe4, 0xab, + 0x00, 0x0b, 0xb6, 0xe3, 0xe9, 0x8d, 0xb9, 0x50, 0xf3, 0xf1, 0x88, 0xb3, 0x85, 0x50, 0x5e, 0x46, + 0x22, 0xc1, 0xf5, 0x2b, 0x34, 0xab, 0xf9, 0xc4, 0xc4, 0xd7, 0xaf, 0x00, 0xaa, 0x49, 0x14, 0xea, + 0xaf, 0x66, 0xe1, 0x98, 0xdf, 0x49, 0x93, 0xf7, 0x69, 0xbd, 0xfd, 0x20, 0xcf, 0x4d, 0x51, 0x69, + 0xf7, 0x6e, 0x29, 0x6d, 0xf5, 0xbf, 0x4a, 0x13, 0xc9, 0x44, 0xc3, 0x3e, 0x9a, 0x48, 0xfe, 0x3c, + 0x74, 0x5c, 0xfd, 0xce, 0x1c, 0x9c, 0xf0, 0xa5, 0x3e, 0xd5, 0xb6, 0xf0, 0x70, 0x60, 0x42, 0x6f, + 0x34, 0x1e, 0xe4, 0xdd, 0xf8, 0xa0, 0x2f, 0x88, 0x79, 0x11, 0x6f, 0x4f, 0xe4, 0xf8, 0x5b, 0x16, + 0xe0, 0x9a, 0x6d, 0x1a, 0x9a, 0x4c, 0x44, 0x5e, 0x81, 0x21, 0xff, 0x67, 0xc9, 0x59, 0xf1, 0xb7, + 0xe0, 0x78, 0xd4, 0x1f, 0x14, 0xd2, 0x9d, 0x48, 0x58, 0x81, 0x48, 0x01, 0xf5, 0xdf, 0x17, 0xe0, + 0xec, 0x1d, 0xd3, 0x32, 0xec, 0x35, 0xd7, 0x4f, 0x11, 0x79, 0xe8, 0x8f, 0xba, 0x0e, 0x3a, 0x35, + 0xe4, 0xeb, 0x70, 0x32, 0x2e, 0x52, 0x27, 0x08, 0xdc, 0x2d, 0x7a, 0x67, 0x8d, 0x13, 0xd4, 0xfc, + 0x64, 0x91, 0xe2, 0xbe, 0x4c, 0x4b, 0x2f, 0x19, 0xcf, 0x36, 0xd9, 0xb7, 0x9d, 0x6c, 0x93, 0x8f, + 0x43, 0xa1, 0x6c, 0x37, 0x75, 0xd3, 0x0f, 0x30, 0x83, 0xa3, 0x38, 0xa8, 0x17, 0x31, 0x9a, 0xa0, + 0x60, 0xfc, 0x45, 0xc5, 0xd8, 0x65, 0x03, 0x21, 0x7f, 0xbf, 0x00, 0xb3, 0xd2, 0x34, 0x99, 0x88, + 0xd8, 0x30, 0x2c, 0xaa, 0x13, 0xb7, 0x5b, 0x80, 0x9b, 0xa7, 0x67, 0x7c, 0x19, 0x75, 0x56, 0xab, + 0x2b, 0x91, 0x72, 0x7c, 0x1b, 0xc5, 0x93, 0x60, 0x8a, 0x8f, 0xe1, 0xf7, 0x5c, 0x5a, 0x94, 0xbf, + 0x24, 0x04, 0x9c, 0x64, 0x06, 0x93, 0x42, 0xc0, 0x59, 0x46, 0x26, 0x22, 0x93, 0x30, 0x86, 0xe1, + 0x95, 0x83, 0xad, 0x14, 0x53, 0x89, 0x21, 0x34, 0x2a, 0xf1, 0xd2, 0x84, 0x47, 0x64, 0x66, 0x1f, + 0x57, 0xab, 0x0b, 0xb4, 0x96, 0x2c, 0x71, 0xf6, 0x55, 0x20, 0xc9, 0x36, 0xef, 0xe8, 0xda, 0xe4, + 0x1f, 0x49, 0xfb, 0xba, 0xc3, 0xee, 0xf8, 0xb2, 0x1f, 0xb3, 0x5d, 0x24, 0x75, 0x58, 0xef, 0x3b, + 0x99, 0x3a, 0xac, 0xb0, 0xaf, 0xa9, 0xc3, 0xd4, 0x9f, 0xcf, 0xc0, 0x58, 0x22, 0xce, 0x38, 0x79, + 0x1a, 0x80, 0x43, 0xa4, 0x78, 0x8e, 0x18, 0x20, 0x25, 0x8c, 0x3d, 0x2e, 0xd6, 0xc0, 0x90, 0x8c, + 0x5c, 0x85, 0x7e, 0xfe, 0x4b, 0xc4, 0x60, 0x4a, 0x16, 0x69, 0xb7, 0x4d, 0x43, 0x0b, 0x88, 0xc2, + 0x5a, 0xf0, 0xe2, 0x30, 0x97, 0x5a, 0xc4, 0x5b, 0x6f, 0x05, 0xb5, 0x30, 0x32, 0xf5, 0xb3, 0x59, + 0x18, 0x0a, 0x1a, 0x5c, 0x32, 0x0e, 0x4a, 0xe7, 0x0a, 0x22, 0x64, 0x7b, 0x6e, 0xab, 0x90, 0xed, + 0xb1, 0x49, 0x55, 0xc4, 0x68, 0xdf, 0xbf, 0x77, 0x4f, 0x9f, 0xcf, 0xc2, 0xb1, 0xa0, 0xd6, 0x03, + 0xbc, 0xa3, 0x7a, 0x17, 0x89, 0xe4, 0x73, 0x19, 0x50, 0xc6, 0xcd, 0x46, 0xc3, 0xb4, 0x56, 0x2a, + 0xd6, 0xb2, 0xed, 0x34, 0x71, 0xd6, 0x3b, 0xb8, 0x73, 0x5a, 0xf5, 0x7b, 0x32, 0x30, 0x26, 0x1a, + 0x34, 0xa1, 0x3b, 0xc6, 0xc1, 0x1d, 0x82, 0xc5, 0x5b, 0x72, 0x70, 0xfa, 0xa2, 0x7e, 0x39, 0x0b, + 0x30, 0x63, 0xd7, 0xef, 0x1e, 0xf2, 0x67, 0x53, 0x2f, 0x42, 0x81, 0x07, 0xc2, 0x12, 0x1a, 0x3b, + 0x26, 0x9e, 0x07, 0xb1, 0x4f, 0xe3, 0x88, 0xf1, 0x51, 0x31, 0x1f, 0x17, 0x78, 0x20, 0x2d, 0x25, + 0xa3, 0x89, 0x22, 0xac, 0x52, 0x46, 0x27, 0x16, 0x8c, 0xa0, 0x52, 0x06, 0x8b, 0x56, 0xba, 0xb9, + 0x51, 0xcc, 0x37, 0xec, 0xfa, 0x5d, 0x0d, 0xe9, 0xd5, 0x3f, 0xcb, 0x70, 0xd9, 0x1d, 0xf2, 0xc7, + 0x9f, 0xfe, 0xe7, 0xe7, 0x77, 0xf8, 0xf9, 0xdf, 0x9b, 0x81, 0x13, 0x1a, 0xad, 0xdb, 0xf7, 0xa8, + 0xb3, 0x3e, 0x61, 0x1b, 0xf4, 0x06, 0xb5, 0xa8, 0x73, 0x50, 0x23, 0xea, 0xef, 0x62, 0x8e, 0x8b, + 0xb0, 0x31, 0xb7, 0x5c, 0x6a, 0x1c, 0x9e, 0xfc, 0x23, 0xea, 0xdf, 0xee, 0x03, 0x25, 0xd5, 0xb4, + 0x3d, 0xb4, 0xe6, 0x5c, 0xc7, 0xfd, 0x4a, 0x7e, 0xbf, 0xf6, 0x2b, 0xbd, 0x3b, 0xdb, 0xaf, 0x14, + 0x76, 0xba, 0x5f, 0xe9, 0xdb, 0xce, 0x7e, 0xa5, 0x19, 0xdf, 0xaf, 0xf4, 0xe3, 0x7e, 0xe5, 0xe9, + 0xae, 0xfb, 0x95, 0x49, 0xcb, 0xd8, 0xe5, 0x6e, 0xe5, 0xd0, 0xe6, 0xc6, 0xdd, 0xcd, 0x36, 0xeb, + 0x12, 0x9b, 0x14, 0xeb, 0xb6, 0x63, 0x50, 0x43, 0xec, 0xae, 0xf0, 0x68, 0xdf, 0x11, 0x30, 0x2d, + 0xc0, 0x26, 0x12, 0x0d, 0x0f, 0x6f, 0x27, 0xd1, 0xf0, 0x3e, 0xec, 0xbf, 0x3e, 0x93, 0x85, 0xb1, + 0x09, 0xea, 0x78, 0x3c, 0xd2, 0xe6, 0x7e, 0x78, 0xae, 0x95, 0xe0, 0x98, 0xc4, 0x10, 0x2d, 0xf2, + 0x6c, 0xe8, 0x8d, 0x57, 0xa7, 0x8e, 0x17, 0x77, 0xe6, 0x8b, 0xd3, 0xb3, 0xea, 0xfd, 0x64, 0x5f, + 0x62, 0xec, 0x06, 0xd5, 0xfb, 0x70, 0x2e, 0x48, 0x53, 0xfc, 0xd2, 0x02, 0x7a, 0x29, 0x7f, 0x57, + 0x7e, 0xe7, 0xf9, 0xbb, 0xd4, 0x9f, 0xcb, 0xc0, 0x45, 0x8d, 0x5a, 0x74, 0x4d, 0x5f, 0x6a, 0x50, + 0xa9, 0x59, 0x62, 0x65, 0x60, 0xb3, 0x86, 0xe9, 0x36, 0x75, 0xaf, 0xbe, 0xba, 0x27, 0x19, 0x4d, + 0xc1, 0x90, 0x3c, 0x7f, 0xed, 0x60, 0x6e, 0x8b, 0x94, 0x53, 0xff, 0x53, 0x0e, 0xfa, 0xc6, 0x6d, + 0xef, 0x35, 0x7b, 0x8f, 0x09, 0xe5, 0xc2, 0x29, 0x3f, 0xbb, 0x83, 0x03, 0x9d, 0xf7, 0x63, 0xe5, + 0x52, 0x8c, 0x7d, 0xf4, 0xf4, 0x5c, 0xb2, 0x13, 0xb9, 0x08, 0x7c, 0xb2, 0x1d, 0xa6, 0x92, 0x7b, + 0x16, 0x06, 0x30, 0x48, 0x8b, 0x74, 0xe4, 0x8a, 0x7e, 0xd4, 0x1e, 0x03, 0xc6, 0xeb, 0x08, 0x49, + 0xc9, 0x47, 0x22, 0xa1, 0x41, 0x0b, 0x7b, 0x4f, 0x3d, 0x27, 0x47, 0x09, 0x7d, 0x9a, 0xdf, 0xd6, + 0x61, 0x9b, 0xa4, 0x34, 0x1d, 0x78, 0x54, 0x12, 0x6b, 0x52, 0x40, 0xb8, 0x7f, 0x69, 0xe1, 0xd4, + 0x6f, 0xe6, 0x61, 0xc8, 0x77, 0xb9, 0x3d, 0xa0, 0x6e, 0x7f, 0x12, 0x0a, 0xd3, 0xb6, 0x94, 0x64, + 0x00, 0x5d, 0x74, 0x57, 0x6d, 0x37, 0xe6, 0x7b, 0x2c, 0x88, 0x98, 0xc0, 0xe6, 0x6c, 0x43, 0x76, + 0x30, 0x47, 0x81, 0x59, 0xb6, 0x91, 0x78, 0xa0, 0x1b, 0x10, 0x92, 0x8b, 0x90, 0x47, 0xdf, 0x7c, + 0xe9, 0xa0, 0x3d, 0xe6, 0x8f, 0x8f, 0x78, 0x49, 0xa1, 0x0a, 0x3b, 0x55, 0xa8, 0xbe, 0xdd, 0x2a, + 0x54, 0xff, 0xfe, 0x2a, 0xd4, 0x1b, 0x30, 0x84, 0x35, 0xf9, 0x39, 0xca, 0xb6, 0x5e, 0x13, 0xcf, + 0x88, 0x65, 0x6b, 0x98, 0xb7, 0x5b, 0x64, 0x2a, 0xc3, 0xd5, 0x2a, 0xc2, 0x2a, 0xa6, 0x76, 0xb0, + 0x07, 0xb5, 0xfb, 0xdd, 0x0c, 0xf4, 0xdd, 0xb2, 0xee, 0x5a, 0xf6, 0xda, 0xde, 0x34, 0xee, 0x69, + 0x18, 0x14, 0x6c, 0xa4, 0x85, 0x01, 0xdf, 0x5c, 0xb7, 0x39, 0xb8, 0x86, 0x9c, 0x34, 0x99, 0x8a, + 0xbc, 0x14, 0x14, 0xc2, 0xe7, 0x37, 0xb9, 0x30, 0x4d, 0x87, 0x5f, 0xa8, 0x1e, 0xcd, 0x2c, 0x20, + 0x93, 0x93, 0x73, 0x90, 0x2f, 0xb3, 0xa6, 0x4a, 0x71, 0x6a, 0x59, 0x53, 0x34, 0x84, 0xaa, 0x9f, + 0xc9, 0xc3, 0x48, 0xec, 0xcc, 0xea, 0x71, 0x18, 0x10, 0x67, 0x46, 0xa6, 0x9f, 0xea, 0x00, 0x9f, + 0xe7, 0x04, 0x40, 0xad, 0x9f, 0xff, 0x59, 0x31, 0xc8, 0x07, 0xa1, 0xcf, 0x76, 0x71, 0x3d, 0xc3, + 0x6f, 0x19, 0x09, 0x87, 0xd0, 0x7c, 0x95, 0xb5, 0x9d, 0x0f, 0x0e, 0x41, 0x22, 0x6b, 0xa4, 0xed, + 0xe2, 0xa7, 0x5d, 0x87, 0x01, 0xdd, 0x75, 0xa9, 0x57, 0xf3, 0xf4, 0x15, 0x39, 0xfb, 0x41, 0x00, + 0x94, 0x47, 0x07, 0x02, 0x17, 0xf5, 0x15, 0xf2, 0x2a, 0x0c, 0xd7, 0x1d, 0x8a, 0x2b, 0x9e, 0xde, + 0x60, 0xad, 0x94, 0x2c, 0xd2, 0x08, 0x42, 0xbe, 0xdf, 0x08, 0x11, 0x15, 0x83, 0xdc, 0x86, 0x61, + 0xf1, 0x39, 0xdc, 0x37, 0x1e, 0x07, 0xda, 0x48, 0xb8, 0x02, 0x71, 0x91, 0x70, 0xef, 0x78, 0xf1, + 0x44, 0x42, 0x26, 0x97, 0xf9, 0x1a, 0x12, 0x29, 0x99, 0x07, 0xb2, 0x46, 0x97, 0x6a, 0x7a, 0xdb, + 0x5b, 0x65, 0x75, 0xf1, 0xe0, 0xdd, 0x22, 0xe9, 0x1f, 0xbe, 0x2b, 0x48, 0x62, 0xe5, 0xe7, 0x16, + 0x6b, 0x74, 0xa9, 0x14, 0x41, 0x92, 0x3b, 0x70, 0x32, 0x59, 0x84, 0x7d, 0x32, 0x3f, 0xbc, 0x7f, + 0x74, 0x73, 0xa3, 0x58, 0x4c, 0x25, 0x90, 0xd8, 0x1e, 0x4f, 0xb0, 0xad, 0x18, 0xaf, 0xe5, 0xfb, + 0xfb, 0x46, 0xfb, 0xb5, 0x11, 0x56, 0xd6, 0xb7, 0xfe, 0x4c, 0x43, 0xfd, 0x5a, 0x86, 0x59, 0x79, + 0xec, 0x83, 0x30, 0xeb, 0x31, 0xd3, 0xf5, 0xe6, 0x0e, 0x75, 0xbd, 0x19, 0xe6, 0x27, 0x2c, 0xb8, + 0x5d, 0x66, 0x57, 0x4d, 0x60, 0xc9, 0x15, 0x28, 0x18, 0xf2, 0x81, 0xd7, 0xa9, 0x68, 0x27, 0xf8, + 0xf5, 0x68, 0x82, 0x8a, 0x5c, 0x82, 0x3c, 0x5b, 0x6d, 0xe2, 0xbb, 0x5d, 0xd9, 0x30, 0xd0, 0x90, + 0x42, 0xfd, 0xf6, 0x2c, 0x0c, 0x49, 0x5f, 0x73, 0x6d, 0x4f, 0x9f, 0xf3, 0xc2, 0xf6, 0x9a, 0xe9, + 0x3b, 0xa5, 0xe0, 0x36, 0xc8, 0x6f, 0xf2, 0xf5, 0x40, 0x14, 0xdb, 0xba, 0x30, 0x12, 0x82, 0x79, + 0x56, 0x7c, 0x68, 0x61, 0xfb, 0x3b, 0x3f, 0x46, 0xff, 0x5a, 0xbe, 0x3f, 0x3b, 0x9a, 0x7b, 0x2d, + 0xdf, 0x9f, 0x1f, 0xed, 0xc5, 0x48, 0x57, 0x18, 0x5c, 0x9a, 0x6f, 0xab, 0xad, 0x65, 0x73, 0xe5, + 0x90, 0xbf, 0xce, 0xd8, 0xdf, 0x28, 0x60, 0x31, 0xd9, 0x1c, 0xf2, 0xa7, 0x1a, 0xef, 0xa8, 0x6c, + 0x8e, 0xf2, 0x19, 0x0a, 0xd9, 0xfc, 0x5e, 0x06, 0x94, 0x54, 0xd9, 0x94, 0x0e, 0xc8, 0x4f, 0x61, + 0xff, 0xb2, 0x1a, 0x7e, 0x23, 0x0b, 0x63, 0x15, 0xcb, 0xa3, 0x2b, 0x7c, 0xb3, 0x77, 0xc8, 0xa7, + 0x8a, 0x9b, 0x30, 0x28, 0x7d, 0x8c, 0xe8, 0xf3, 0x87, 0x82, 0xad, 0x74, 0x88, 0xea, 0xc0, 0x49, + 0x2e, 0xbd, 0x8f, 0x89, 0xd0, 0x63, 0x42, 0x3e, 0xe4, 0x73, 0xce, 0xe1, 0x10, 0xf2, 0x21, 0x9f, + 0xbc, 0xde, 0xa5, 0x42, 0xfe, 0xcf, 0x19, 0x38, 0x9e, 0x52, 0x39, 0xb9, 0x08, 0x7d, 0xd5, 0xf6, + 0x12, 0x06, 0xb6, 0xca, 0x84, 0x1e, 0xbd, 0x6e, 0x7b, 0x09, 0x63, 0x5a, 0x69, 0x3e, 0x92, 0x2c, + 0xe2, 0xf3, 0xf5, 0xf9, 0x4a, 0x79, 0x42, 0x48, 0x55, 0x95, 0x1e, 0xe2, 0x33, 0x70, 0xda, 0x97, + 0x05, 0x4f, 0xdc, 0x6d, 0xd3, 0xa8, 0xc7, 0x9e, 0xb8, 0xb3, 0x32, 0xe4, 0xa3, 0x30, 0x50, 0x7a, + 0xab, 0xed, 0x50, 0xe4, 0xcb, 0x25, 0xfe, 0x9e, 0x80, 0xaf, 0x8f, 0x48, 0xe3, 0xcc, 0x5f, 0xeb, + 0x33, 0x8a, 0x38, 0xef, 0x90, 0xa1, 0xfa, 0xd9, 0x0c, 0x9c, 0xed, 0xdc, 0x3a, 0xf2, 0x7e, 0xe8, + 0x63, 0x3b, 0xf3, 0x92, 0x36, 0x27, 0x3e, 0x9d, 0x67, 0x00, 0xb5, 0x1b, 0xb4, 0xa6, 0x3b, 0xb2, + 0xb1, 0xef, 0x93, 0x91, 0x97, 0x61, 0xb0, 0xe2, 0xba, 0x6d, 0xea, 0x54, 0x9f, 0xbe, 0xa5, 0x55, + 0xc4, 0x9e, 0x10, 0xf7, 0x1c, 0x26, 0x82, 0x6b, 0xee, 0xd3, 0xb1, 0xd0, 0x55, 0x32, 0xbd, 0xfa, + 0xa9, 0x0c, 0x9c, 0xeb, 0xf6, 0x55, 0xe4, 0x69, 0xe8, 0x5f, 0xa4, 0x96, 0x6e, 0x79, 0x95, 0xb2, + 0x68, 0x12, 0x6e, 0xb1, 0x3c, 0x84, 0x45, 0x77, 0x0a, 0x01, 0x21, 0x2b, 0xc4, 0x8f, 0x04, 0x03, + 0x1f, 0x04, 0x7e, 0x7c, 0x89, 0xb0, 0x58, 0x21, 0x9f, 0x50, 0xfd, 0xa9, 0x25, 0xe8, 0x9d, 0xb7, + 0xe8, 0xfc, 0x32, 0x79, 0x0a, 0x06, 0x98, 0xee, 0x63, 0xfa, 0x7d, 0x31, 0xd0, 0xc6, 0xe4, 0x01, + 0x83, 0x88, 0xe9, 0x1e, 0x2d, 0xa4, 0x22, 0xd7, 0xe5, 0x9c, 0xdf, 0x42, 0x1d, 0x88, 0x5c, 0x86, + 0x63, 0xa6, 0x7b, 0x34, 0x39, 0x37, 0xf8, 0x75, 0x39, 0xd7, 0xb2, 0xe8, 0xec, 0x48, 0x29, 0x8e, + 0xf1, 0x4b, 0x89, 0x69, 0x60, 0x26, 0x2d, 0x21, 0x71, 0xdc, 0x26, 0x48, 0x52, 0x4c, 0xf7, 0x68, + 0xe9, 0x89, 0x8c, 0x87, 0x64, 0x37, 0xa6, 0xf8, 0x2d, 0xa4, 0x8c, 0x9b, 0xee, 0xd1, 0x22, 0xb4, + 0xe4, 0x39, 0x18, 0x14, 0xbf, 0x5f, 0xb3, 0x4d, 0x2b, 0x1e, 0xc3, 0x42, 0x42, 0x4d, 0xf7, 0x68, + 0x32, 0xa5, 0x54, 0xe9, 0x82, 0x63, 0x5a, 0x9e, 0x78, 0x19, 0x17, 0xaf, 0x14, 0x71, 0x52, 0xa5, + 0xf8, 0x9b, 0xbc, 0x0c, 0xc3, 0x41, 0x70, 0x90, 0x37, 0x69, 0xdd, 0x13, 0x47, 0x3a, 0x27, 0x63, + 0x85, 0x39, 0x72, 0xba, 0x47, 0x8b, 0x52, 0x93, 0x4b, 0x50, 0xd0, 0xa8, 0x6b, 0xbe, 0xe5, 0xdf, + 0x5f, 0x8c, 0x48, 0xd3, 0x99, 0xf9, 0x16, 0x93, 0x92, 0xc0, 0xb3, 0xde, 0x09, 0x2f, 0x4c, 0xc4, + 0x01, 0x0c, 0x89, 0xd5, 0x32, 0x69, 0x19, 0xac, 0x77, 0xa4, 0xdb, 0xb2, 0x57, 0xc3, 0x90, 0x29, + 0x22, 0xd1, 0xda, 0x60, 0xfc, 0x6d, 0xaa, 0x8c, 0x9d, 0xee, 0xd1, 0x62, 0xf4, 0x92, 0x54, 0xcb, + 0xa6, 0x7b, 0x57, 0x44, 0xa9, 0x8b, 0x4b, 0x95, 0xa1, 0x24, 0xa9, 0xb2, 0x9f, 0x52, 0xd5, 0x73, + 0xd4, 0x5b, 0xb3, 0x9d, 0xbb, 0x22, 0x26, 0x5d, 0xbc, 0x6a, 0x81, 0x95, 0xaa, 0x16, 0x10, 0xb9, + 0x6a, 0xb6, 0xc8, 0x8c, 0xa4, 0x57, 0xad, 0x7b, 0xba, 0x5c, 0x35, 0xdf, 0x5f, 0xfa, 0x9d, 0x34, + 0x43, 0xf5, 0x7b, 0x3c, 0xdf, 0x6d, 0xb2, 0x43, 0x11, 0x27, 0x75, 0x28, 0xfe, 0x66, 0x95, 0x4a, + 0x39, 0x4d, 0x45, 0x42, 0xdb, 0xa0, 0x52, 0x09, 0xc5, 0x2a, 0x95, 0xb3, 0x9f, 0x5e, 0x97, 0x53, + 0x7d, 0x2a, 0x63, 0xd1, 0x0e, 0x0a, 0x31, 0xac, 0x83, 0xa4, 0x94, 0xa0, 0x45, 0x4c, 0x23, 0xa8, + 0x10, 0x24, 0x1f, 0x0c, 0x5a, 0x38, 0xb1, 0x30, 0xdd, 0xa3, 0x61, 0x82, 0x41, 0x95, 0x27, 0xa8, + 0x54, 0x8e, 0x23, 0xc5, 0x90, 0x4f, 0xc1, 0x60, 0xd3, 0x3d, 0x1a, 0x4f, 0x5e, 0xf9, 0x94, 0x94, + 0x0a, 0x4a, 0x39, 0x11, 0x9d, 0x22, 0x02, 0x04, 0x9b, 0x22, 0xc2, 0x84, 0x51, 0x53, 0xc9, 0x74, + 0x49, 0xca, 0xc9, 0xe8, 0x8a, 0x1a, 0xc7, 0x4f, 0xf7, 0x68, 0xc9, 0x14, 0x4b, 0xcf, 0x45, 0x32, + 0x08, 0x29, 0xa7, 0x62, 0x81, 0x63, 0x42, 0x14, 0x13, 0x97, 0x9c, 0x6b, 0x68, 0x3e, 0x35, 0xe7, + 0xb7, 0x72, 0x3a, 0xba, 0x1c, 0xa7, 0x90, 0x4c, 0xf7, 0x68, 0xa9, 0xd9, 0xc2, 0x27, 0x12, 0x79, + 0x7c, 0x14, 0x25, 0x7a, 0x59, 0x1b, 0x43, 0x4f, 0xf7, 0x68, 0x89, 0xcc, 0x3f, 0xd7, 0xe5, 0x04, + 0x3a, 0xca, 0x99, 0x68, 0x27, 0x86, 0x18, 0xd6, 0x89, 0x52, 0xa2, 0x9d, 0xeb, 0x72, 0x52, 0x15, + 0xe5, 0x6c, 0xb2, 0x54, 0x38, 0x73, 0x4a, 0xc9, 0x57, 0xb4, 0xf4, 0x3c, 0x11, 0xca, 0x43, 0x22, + 0x53, 0x9f, 0x28, 0x9f, 0x46, 0x33, 0xdd, 0xa3, 0xa5, 0xe7, 0x98, 0xd0, 0xd2, 0x13, 0x2c, 0x28, + 0xe7, 0xba, 0xf1, 0x0c, 0x5a, 0x97, 0x9e, 0x9c, 0x41, 0xef, 0x12, 0xee, 0x5e, 0x39, 0x1f, 0x8d, + 0x5a, 0xd9, 0x91, 0x70, 0xba, 0x47, 0xeb, 0x12, 0x34, 0xff, 0x56, 0x87, 0xd8, 0xf3, 0xca, 0x85, + 0x68, 0xa2, 0xce, 0x54, 0xa2, 0xe9, 0x1e, 0xad, 0x43, 0xe4, 0xfa, 0x5b, 0x1d, 0x42, 0x93, 0x2b, + 0xc5, 0xae, 0x6c, 0x03, 0x79, 0x74, 0x08, 0x6c, 0x3e, 0x9f, 0x1a, 0xd5, 0x5b, 0x79, 0x38, 0xaa, + 0xba, 0x29, 0x24, 0x4c, 0x75, 0xd3, 0xe2, 0x81, 0xcf, 0xa7, 0x86, 0xa1, 0x56, 0x1e, 0xe9, 0xc2, + 0x30, 0x68, 0x63, 0x6a, 0x00, 0xeb, 0xf9, 0xd4, 0x38, 0xd0, 0x8a, 0x1a, 0x65, 0x98, 0x42, 0xc2, + 0x18, 0xa6, 0x45, 0x90, 0x9e, 0x4f, 0x0d, 0x17, 0xac, 0x3c, 0xda, 0x85, 0x61, 0xd8, 0xc2, 0xb4, + 0x40, 0xc3, 0xcf, 0x45, 0xe2, 0xf5, 0x2a, 0xef, 0x89, 0xce, 0x1b, 0x12, 0x8a, 0xcd, 0x1b, 0x72, + 0x64, 0xdf, 0x89, 0x44, 0x44, 0x42, 0xe5, 0xb1, 0xe8, 0x30, 0x8f, 0xa1, 0xd9, 0x30, 0x8f, 0xc7, + 0x30, 0x9c, 0x48, 0x44, 0x66, 0x53, 0x2e, 0x76, 0x62, 0x82, 0xe8, 0x28, 0x13, 0x1e, 0xcb, 0xad, + 0x92, 0x12, 0x1a, 0x4c, 0x79, 0x6f, 0xd4, 0xd1, 0x30, 0x41, 0x30, 0xdd, 0xa3, 0xa5, 0x04, 0x14, + 0xd3, 0xd2, 0xe3, 0x60, 0x28, 0x97, 0xa2, 0xc3, 0x36, 0x8d, 0x86, 0x0d, 0xdb, 0xd4, 0x18, 0x1a, + 0x33, 0x69, 0xde, 0xd0, 0xca, 0xe5, 0xa8, 0x61, 0x96, 0xa4, 0x60, 0x86, 0x59, 0x8a, 0x17, 0xb5, + 0x96, 0x1e, 0xd9, 0x41, 0x79, 0xbc, 0x6b, 0x0b, 0x91, 0x26, 0xa5, 0x85, 0x3c, 0xd0, 0x41, 0x68, + 0x3b, 0xdd, 0x6a, 0x35, 0x6c, 0xdd, 0x50, 0xde, 0x97, 0x6a, 0x3b, 0x71, 0xa4, 0x64, 0x3b, 0x71, + 0x00, 0x5b, 0xe5, 0x65, 0xa7, 0x5b, 0xe5, 0x89, 0xe8, 0x2a, 0x2f, 0xe3, 0xd8, 0x2a, 0x1f, 0x71, + 0xd0, 0x9d, 0x48, 0x38, 0xa8, 0x2a, 0x4f, 0x46, 0x15, 0x20, 0x86, 0x66, 0x0a, 0x10, 0x77, 0x69, + 0xfd, 0x78, 0x67, 0x97, 0x4e, 0xe5, 0x0a, 0x72, 0x7b, 0xd8, 0xe7, 0xd6, 0x89, 0x6e, 0xba, 0x47, + 0xeb, 0xec, 0x16, 0x5a, 0x49, 0xf1, 0xd0, 0x54, 0xae, 0x46, 0x15, 0x2c, 0x41, 0xc0, 0x14, 0x2c, + 0xe9, 0xd7, 0x59, 0x49, 0x71, 0xb1, 0x54, 0xde, 0xdf, 0x91, 0x55, 0xf0, 0xcd, 0x29, 0x8e, 0x99, + 0xd7, 0x65, 0x1f, 0x49, 0xe5, 0xa9, 0xe8, 0x62, 0x17, 0x62, 0xd8, 0x62, 0x27, 0xf9, 0x52, 0x5e, + 0x97, 0xbd, 0x03, 0x95, 0x6b, 0xc9, 0x52, 0xe1, 0x12, 0x29, 0x79, 0x11, 0x6a, 0xe9, 0x4e, 0x75, + 0xca, 0xd3, 0x51, 0xad, 0x4b, 0xa3, 0x61, 0x5a, 0x97, 0xea, 0x90, 0x37, 0x95, 0xf4, 0x8d, 0x53, + 0xae, 0xc7, 0xcf, 0x12, 0xa2, 0x78, 0x66, 0xf9, 0x24, 0xfc, 0xe9, 0x5e, 0x8d, 0x07, 0x69, 0x52, + 0x9e, 0x89, 0x5d, 0x66, 0x44, 0xb0, 0xcc, 0xbe, 0x8d, 0x05, 0x75, 0x7a, 0x35, 0x1e, 0xd7, 0x48, + 0x79, 0x36, 0x9d, 0x43, 0xa0, 0x2b, 0xf1, 0x38, 0x48, 0xaf, 0xc6, 0x43, 0x01, 0x29, 0xcf, 0xa5, + 0x73, 0x08, 0xa4, 0x1b, 0x0f, 0x1d, 0xf4, 0x94, 0x14, 0x9c, 0x58, 0xf9, 0x40, 0xd4, 0x74, 0x0c, + 0x10, 0xcc, 0x74, 0x0c, 0x43, 0x18, 0x3f, 0x25, 0x05, 0xf5, 0x55, 0x9e, 0x4f, 0x14, 0x09, 0x1a, + 0x2b, 0x85, 0xfe, 0x7d, 0x4a, 0x0a, 0x86, 0xab, 0xbc, 0x90, 0x28, 0x12, 0xb4, 0x4e, 0x0a, 0x99, + 0x6b, 0x74, 0x7b, 0x35, 0xa5, 0xbc, 0x18, 0x3d, 0xe2, 0xe8, 0x4c, 0x39, 0xdd, 0xa3, 0x75, 0x7b, + 0x7d, 0xf5, 0xf1, 0xce, 0x9e, 0x86, 0xca, 0x4b, 0xd1, 0x21, 0xdc, 0x89, 0x8e, 0x0d, 0xe1, 0x8e, + 0xde, 0x8a, 0x2f, 0xc7, 0x5e, 0x50, 0x2b, 0x2f, 0x47, 0xa7, 0xb8, 0x08, 0x92, 0x4d, 0x71, 0xf1, + 0xf7, 0xd6, 0x91, 0xa7, 0xc1, 0xca, 0x07, 0xa3, 0x53, 0x9c, 0x8c, 0x63, 0x53, 0x5c, 0xe4, 0x19, + 0xf1, 0x44, 0xe2, 0xc5, 0xaa, 0xf2, 0x4a, 0x74, 0x8a, 0x8b, 0xa1, 0xd9, 0x14, 0x17, 0x7f, 0xe3, + 0xfa, 0x72, 0xec, 0xe1, 0xa6, 0xf2, 0x6a, 0x7a, 0xfb, 0x11, 0x29, 0xb7, 0x9f, 0x3f, 0xf3, 0xd4, + 0xd2, 0x5f, 0x20, 0x2a, 0xa5, 0xe8, 0xf8, 0x4d, 0xa3, 0x61, 0xe3, 0x37, 0xf5, 0xf5, 0x62, 0x7c, + 0xe3, 0x20, 0xb4, 0x6a, 0xbc, 0xcb, 0xc6, 0x21, 0x34, 0x45, 0x52, 0xc0, 0x91, 0x3d, 0x32, 0xdf, + 0x08, 0x4d, 0x74, 0xd8, 0x23, 0xfb, 0xdb, 0xa0, 0x18, 0x3d, 0x9b, 0x5d, 0x13, 0x8e, 0x6f, 0x4a, + 0x39, 0x3a, 0xbb, 0x26, 0x08, 0xd8, 0xec, 0x9a, 0x74, 0x97, 0x9b, 0x82, 0x51, 0xa1, 0x45, 0xdc, + 0x9f, 0xcf, 0xb4, 0x56, 0x94, 0xc9, 0xd8, 0x03, 0xa0, 0x18, 0x9e, 0xcd, 0x4e, 0x71, 0x18, 0xae, + 0xd7, 0x1c, 0x36, 0xd1, 0x30, 0x5b, 0x4b, 0xb6, 0xee, 0x18, 0x55, 0x6a, 0x19, 0xca, 0x54, 0x6c, + 0xbd, 0x4e, 0xa1, 0xc1, 0xf5, 0x3a, 0x05, 0x8e, 0x81, 0x89, 0x62, 0x70, 0x8d, 0xd6, 0xa9, 0x79, + 0x8f, 0x2a, 0x37, 0x90, 0x6d, 0xb1, 0x13, 0x5b, 0x41, 0x36, 0xdd, 0xa3, 0x75, 0xe2, 0xc0, 0x6c, + 0xf5, 0xd9, 0xf5, 0xea, 0xeb, 0x33, 0xc1, 0xa3, 0xd7, 0x05, 0x87, 0xb6, 0x74, 0x87, 0x2a, 0xd3, + 0x51, 0x5b, 0x3d, 0x95, 0x88, 0xd9, 0xea, 0xa9, 0x88, 0x24, 0x5b, 0x7f, 0x2c, 0x54, 0xba, 0xb1, + 0x0d, 0x47, 0x44, 0x7a, 0x69, 0x36, 0x3b, 0x45, 0x11, 0x4c, 0x40, 0x33, 0xb6, 0xb5, 0x82, 0x27, + 0x15, 0xaf, 0x45, 0x67, 0xa7, 0xce, 0x94, 0x6c, 0x76, 0xea, 0x8c, 0x65, 0xaa, 0x1e, 0xc5, 0xf2, + 0x31, 0x78, 0x33, 0xaa, 0xea, 0x29, 0x24, 0x4c, 0xd5, 0x53, 0xc0, 0x49, 0x86, 0x1a, 0x75, 0xa9, + 0xa7, 0xcc, 0x74, 0x63, 0x88, 0x24, 0x49, 0x86, 0x08, 0x4e, 0x32, 0x9c, 0xa2, 0x5e, 0x7d, 0x55, + 0x99, 0xed, 0xc6, 0x10, 0x49, 0x92, 0x0c, 0x11, 0xcc, 0x36, 0x9b, 0x51, 0xf0, 0x78, 0xbb, 0x71, + 0xd7, 0xef, 0xb3, 0xb9, 0xe8, 0x66, 0xb3, 0x23, 0x21, 0xdb, 0x6c, 0x76, 0x44, 0x92, 0x4f, 0x6d, + 0xdb, 0x31, 0x53, 0x99, 0xc7, 0x0a, 0xaf, 0x84, 0x76, 0xc1, 0x76, 0x4a, 0x4d, 0xf7, 0x68, 0xdb, + 0x75, 0xfc, 0x7c, 0x5f, 0xe0, 0x0a, 0xa5, 0x2c, 0x60, 0x55, 0xc7, 0x82, 0xb3, 0x0a, 0x0e, 0x9e, + 0xee, 0xd1, 0x02, 0x67, 0xa9, 0xe7, 0x60, 0x10, 0x3f, 0xaa, 0x62, 0x99, 0x5e, 0x79, 0x5c, 0x79, + 0x3d, 0xba, 0x65, 0x92, 0x50, 0x6c, 0xcb, 0x24, 0xfd, 0x64, 0x93, 0x38, 0xfe, 0xe4, 0x53, 0x4c, + 0x79, 0x5c, 0xd1, 0xa2, 0x93, 0x78, 0x04, 0xc9, 0x26, 0xf1, 0x08, 0x20, 0xa8, 0xb7, 0xec, 0xd8, + 0xad, 0xf2, 0xb8, 0x52, 0x4d, 0xa9, 0x97, 0xa3, 0x82, 0x7a, 0xf9, 0xcf, 0xa0, 0xde, 0xea, 0x6a, + 0xdb, 0x2b, 0xb3, 0x6f, 0x5c, 0x4c, 0xa9, 0xd7, 0x47, 0x06, 0xf5, 0xfa, 0x00, 0x36, 0x15, 0x22, + 0x60, 0xc1, 0xb1, 0xd9, 0xa4, 0x7d, 0xd3, 0x6c, 0x34, 0x94, 0x5b, 0xd1, 0xa9, 0x30, 0x8e, 0x67, + 0x53, 0x61, 0x1c, 0xc6, 0x4c, 0x4f, 0xde, 0x2a, 0xba, 0xd4, 0x5e, 0x51, 0x6e, 0x47, 0x4d, 0xcf, + 0x10, 0xc3, 0x4c, 0xcf, 0xf0, 0x17, 0xee, 0x2e, 0xd8, 0x2f, 0x8d, 0x2e, 0x3b, 0xd4, 0x5d, 0x55, + 0xee, 0xc4, 0x76, 0x17, 0x12, 0x0e, 0x77, 0x17, 0xd2, 0x6f, 0xb2, 0x02, 0x0f, 0x45, 0x16, 0x1a, + 0xff, 0xee, 0xa9, 0x4a, 0x75, 0xa7, 0xbe, 0xaa, 0x7c, 0x08, 0x59, 0x3d, 0x9a, 0xba, 0x54, 0x45, + 0x49, 0xa7, 0x7b, 0xb4, 0x6e, 0x9c, 0x70, 0x5b, 0xfe, 0xfa, 0x0c, 0x8f, 0x20, 0xa8, 0x2d, 0x4c, + 0xf8, 0x9b, 0xd0, 0x37, 0x62, 0xdb, 0xf2, 0x24, 0x09, 0x6e, 0xcb, 0x93, 0x60, 0xd2, 0x82, 0x0b, + 0xb1, 0xad, 0xda, 0xac, 0xde, 0x60, 0xfb, 0x12, 0x6a, 0x2c, 0xe8, 0xf5, 0xbb, 0xd4, 0x53, 0x3e, + 0x8c, 0xbc, 0x2f, 0x76, 0xd8, 0xf0, 0xc5, 0xa8, 0xa7, 0x7b, 0xb4, 0x2d, 0xf8, 0x11, 0x15, 0xf2, + 0xd5, 0xa9, 0xc5, 0x05, 0xe5, 0x23, 0xd1, 0xf3, 0x4d, 0x06, 0x9b, 0xee, 0xd1, 0x10, 0xc7, 0xac, + 0xb4, 0x5b, 0xad, 0x15, 0x47, 0x37, 0x28, 0x37, 0xb4, 0xd0, 0x76, 0x13, 0x06, 0xe8, 0x47, 0xa3, + 0x56, 0x5a, 0x27, 0x3a, 0x66, 0xa5, 0x75, 0xc2, 0x31, 0x45, 0x8d, 0x04, 0xcb, 0x57, 0x3e, 0x16, + 0x55, 0xd4, 0x08, 0x92, 0x29, 0x6a, 0x34, 0xb4, 0xfe, 0x87, 0xe0, 0x54, 0xb0, 0x9f, 0x17, 0xeb, + 0x2f, 0xef, 0x34, 0xe5, 0xe3, 0xc8, 0xe7, 0x42, 0xe2, 0x32, 0x20, 0x42, 0x35, 0xdd, 0xa3, 0x75, + 0x28, 0xcf, 0x56, 0xdc, 0x44, 0x1e, 0x18, 0x61, 0x5e, 0x7c, 0x5b, 0x74, 0xc5, 0xed, 0x40, 0xc6, + 0x56, 0xdc, 0x0e, 0xa8, 0x54, 0xe6, 0x42, 0xa8, 0xfa, 0x16, 0xcc, 0x03, 0x99, 0x76, 0xe2, 0x90, + 0xca, 0x5c, 0x58, 0x6a, 0x4b, 0x5b, 0x30, 0x0f, 0xac, 0xb5, 0x4e, 0x1c, 0xc8, 0x25, 0x28, 0x54, + 0xab, 0xb3, 0x5a, 0xdb, 0x52, 0xea, 0x31, 0x1f, 0x30, 0x84, 0x4e, 0xf7, 0x68, 0x02, 0xcf, 0xcc, + 0xa0, 0xc9, 0x86, 0xee, 0x7a, 0x66, 0xdd, 0xc5, 0x11, 0xe3, 0x8f, 0x10, 0x23, 0x6a, 0x06, 0xa5, + 0xd1, 0x30, 0x33, 0x28, 0x0d, 0xce, 0xec, 0xc5, 0x09, 0xdd, 0x75, 0x75, 0xcb, 0x70, 0xf4, 0x71, + 0x5c, 0x26, 0x68, 0xec, 0x79, 0x40, 0x04, 0xcb, 0xec, 0xc5, 0x28, 0x04, 0x0f, 0xdf, 0x7d, 0x88, + 0x6f, 0xe6, 0x2c, 0xc7, 0x0e, 0xdf, 0x63, 0x78, 0x3c, 0x7c, 0x8f, 0xc1, 0xd0, 0xee, 0xf4, 0x61, + 0x1a, 0x5d, 0x31, 0x99, 0x88, 0x94, 0x95, 0x98, 0xdd, 0x19, 0x27, 0x40, 0xbb, 0x33, 0x0e, 0x8c, + 0x34, 0xc9, 0x5f, 0x6e, 0x57, 0x3b, 0x34, 0x29, 0x5c, 0x65, 0x13, 0x65, 0xd8, 0xfa, 0x1d, 0x0e, + 0x8e, 0xf2, 0xba, 0xa5, 0x37, 0xed, 0xf2, 0xb8, 0x2f, 0x75, 0x33, 0xba, 0x7e, 0x77, 0x24, 0x64, + 0xeb, 0x77, 0x47, 0x24, 0x9b, 0x5d, 0xfd, 0x8d, 0xd6, 0xaa, 0xee, 0x50, 0xa3, 0x6c, 0x3a, 0x78, + 0xb2, 0xb8, 0xce, 0xb7, 0x86, 0x6f, 0x46, 0x67, 0xd7, 0x2e, 0xa4, 0x6c, 0x76, 0xed, 0x82, 0x66, + 0x46, 0x5e, 0x3a, 0x5a, 0xa3, 0xba, 0xa1, 0xdc, 0x8d, 0x1a, 0x79, 0x9d, 0x29, 0x99, 0x91, 0xd7, + 0x19, 0xdb, 0xf9, 0x73, 0xee, 0x38, 0xa6, 0x47, 0x95, 0xc6, 0x76, 0x3e, 0x07, 0x49, 0x3b, 0x7f, + 0x0e, 0xa2, 0xd9, 0x86, 0x30, 0xde, 0x21, 0xcd, 0xe8, 0x86, 0x30, 0xd9, 0x0d, 0xf1, 0x12, 0xcc, + 0x62, 0x11, 0xaf, 0x44, 0x14, 0x2b, 0x6a, 0xb1, 0x08, 0x30, 0xb3, 0x58, 0xc2, 0x77, 0x24, 0x91, + 0x07, 0x06, 0x8a, 0x1d, 0x5d, 0x43, 0x65, 0x1c, 0x5b, 0x43, 0x23, 0x8f, 0x11, 0x9e, 0x8b, 0x78, + 0xcf, 0x2a, 0xad, 0xa8, 0xd5, 0x21, 0xa1, 0x98, 0xd5, 0x21, 0xfb, 0xd9, 0x4e, 0xc0, 0x31, 0xbc, + 0x05, 0xd7, 0xda, 0xc1, 0x3d, 0xce, 0x27, 0xa2, 0x9f, 0x19, 0x43, 0xb3, 0xcf, 0x8c, 0x81, 0x22, + 0x4c, 0xc4, 0xb4, 0xe5, 0x74, 0x60, 0x12, 0x9e, 0x0f, 0xc6, 0x40, 0x64, 0x06, 0x48, 0xb5, 0x34, + 0x3b, 0x53, 0x31, 0x16, 0xe4, 0x2b, 0x32, 0x37, 0x7a, 0x02, 0x9b, 0xa4, 0x98, 0xee, 0xd1, 0x52, + 0xca, 0x91, 0x37, 0xe1, 0x9c, 0x80, 0x8a, 0x27, 0x80, 0x98, 0x2e, 0xda, 0x08, 0x16, 0x04, 0x2f, + 0xea, 0x9d, 0xd1, 0x8d, 0x76, 0xba, 0x47, 0xeb, 0xca, 0xab, 0x73, 0x5d, 0x62, 0x7d, 0x68, 0x6f, + 0xa7, 0xae, 0x60, 0x91, 0xe8, 0xca, 0xab, 0x73, 0x5d, 0x42, 0xee, 0xf7, 0xb6, 0x53, 0x57, 0xd0, + 0x09, 0x5d, 0x79, 0x11, 0x17, 0x8a, 0xdd, 0xf0, 0xa5, 0x46, 0x43, 0x59, 0xc3, 0xea, 0xde, 0xbb, + 0x9d, 0xea, 0x4a, 0x68, 0x70, 0x6e, 0xc5, 0x91, 0xcd, 0xd2, 0xf3, 0x2d, 0x6a, 0x55, 0x23, 0x0b, + 0xd0, 0xfd, 0xe8, 0x2c, 0x9d, 0x20, 0x60, 0xb3, 0x74, 0x02, 0xc8, 0x06, 0x94, 0xec, 0x84, 0xad, + 0xac, 0x47, 0x07, 0x94, 0x8c, 0x63, 0x03, 0x2a, 0xe2, 0xb0, 0x3d, 0x0f, 0xc7, 0xe7, 0xef, 0x7a, + 0xba, 0x6f, 0x41, 0xba, 0xa2, 0x2b, 0xdf, 0x8a, 0x5d, 0x32, 0x25, 0x49, 0xf0, 0x92, 0x29, 0x09, + 0x66, 0x63, 0x84, 0x81, 0xab, 0xeb, 0x56, 0x7d, 0x4a, 0x37, 0x1b, 0x6d, 0x87, 0x2a, 0xff, 0x47, + 0x74, 0x8c, 0xc4, 0xd0, 0x6c, 0x8c, 0xc4, 0x40, 0x6c, 0x81, 0x66, 0xa0, 0x92, 0xeb, 0x9a, 0x2b, + 0x96, 0xd8, 0x57, 0xb6, 0x1b, 0x9e, 0xf2, 0x7f, 0x46, 0x17, 0xe8, 0x34, 0x1a, 0xb6, 0x40, 0xa7, + 0xc1, 0xf1, 0xd4, 0x29, 0x25, 0x95, 0xba, 0xf2, 0x7f, 0xc5, 0x4e, 0x9d, 0x52, 0x68, 0xf0, 0xd4, + 0x29, 0x2d, 0x0d, 0xfb, 0x14, 0x8c, 0x72, 0x9b, 0x6c, 0xc6, 0x0c, 0xee, 0xaa, 0xff, 0xef, 0xe8, + 0xfa, 0x18, 0xc7, 0xb3, 0xf5, 0x31, 0x0e, 0x8b, 0xf2, 0x11, 0x5d, 0xf0, 0xff, 0x74, 0xe2, 0x13, + 0xc8, 0x3f, 0x51, 0x86, 0xdc, 0x90, 0xf9, 0x88, 0x91, 0xf2, 0xed, 0x99, 0x4e, 0x8c, 0x82, 0xe1, + 0x91, 0x28, 0x14, 0x65, 0xa4, 0xd1, 0x7b, 0x26, 0x5d, 0x53, 0x3e, 0xd9, 0x91, 0x11, 0x27, 0x88, + 0x32, 0xe2, 0x30, 0xf2, 0x06, 0x9c, 0x0a, 0x61, 0xb3, 0xb4, 0xb9, 0x14, 0xcc, 0x4c, 0xdf, 0x91, + 0x89, 0x9a, 0xc1, 0xe9, 0x64, 0xcc, 0x0c, 0x4e, 0xc7, 0xa4, 0xb1, 0x16, 0xa2, 0xfb, 0x7f, 0xb7, + 0x60, 0x1d, 0x48, 0xb0, 0x03, 0x83, 0x34, 0xd6, 0x42, 0x9a, 0xdf, 0xb9, 0x05, 0xeb, 0x40, 0xa6, + 0x1d, 0x18, 0x90, 0x4f, 0x67, 0xe0, 0x62, 0x3a, 0xaa, 0xd4, 0x68, 0x4c, 0xd9, 0x4e, 0x88, 0x53, + 0xbe, 0x2b, 0x13, 0x3d, 0x68, 0xd8, 0x5e, 0xb1, 0xe9, 0x1e, 0x6d, 0x9b, 0x15, 0x90, 0x0f, 0xc2, + 0x70, 0xa9, 0x6d, 0x98, 0x1e, 0x5e, 0xbc, 0x31, 0xc3, 0xf9, 0xbb, 0x33, 0xb1, 0x2d, 0x8e, 0x8c, + 0xc5, 0x2d, 0x8e, 0x0c, 0x20, 0xaf, 0xc1, 0x58, 0x95, 0xd6, 0xdb, 0x8e, 0xe9, 0xad, 0x6b, 0x98, + 0x26, 0x9f, 0xf1, 0xf8, 0x9e, 0x4c, 0x74, 0x12, 0x4b, 0x50, 0xb0, 0x49, 0x2c, 0x01, 0x24, 0xb7, + 0x3b, 0x24, 0x53, 0x57, 0x3e, 0x95, 0xe9, 0x7a, 0x2d, 0x1f, 0xf4, 0x65, 0x87, 0x5c, 0xec, 0x0b, + 0xa9, 0xc9, 0xa9, 0x95, 0x4f, 0x67, 0xba, 0x5c, 0xa3, 0x4b, 0x33, 0x5c, 0x4a, 0x5e, 0xeb, 0x85, + 0xd4, 0xcc, 0xc1, 0xca, 0xf7, 0x66, 0xba, 0x5c, 0x7b, 0x87, 0x1c, 0xd3, 0x92, 0x0e, 0x3f, 0xc3, + 0x3d, 0x45, 0x04, 0xa3, 0xff, 0x2f, 0x93, 0x74, 0x15, 0x09, 0xca, 0x4b, 0x84, 0xac, 0xd8, 0x2d, + 0x37, 0x50, 0xfa, 0xcf, 0x64, 0x92, 0xbe, 0x79, 0x61, 0xb1, 0xf0, 0x17, 0xa1, 0x70, 0x76, 0xf2, + 0xbe, 0x47, 0x1d, 0x4b, 0x6f, 0x60, 0x77, 0x56, 0x3d, 0xdb, 0xd1, 0x57, 0xe8, 0xa4, 0xa5, 0x2f, + 0x35, 0xa8, 0xf2, 0xd9, 0x4c, 0xd4, 0x82, 0xed, 0x4c, 0xca, 0x2c, 0xd8, 0xce, 0x58, 0xb2, 0x0a, + 0x0f, 0xa5, 0x61, 0xcb, 0xa6, 0x8b, 0xf5, 0x7c, 0x2e, 0x13, 0x35, 0x61, 0xbb, 0xd0, 0x32, 0x13, + 0xb6, 0x0b, 0x9a, 0x5c, 0x83, 0x81, 0x71, 0xdb, 0x9f, 0x7e, 0xbf, 0x2f, 0xe6, 0x0c, 0x19, 0x60, + 0xa6, 0x7b, 0xb4, 0x90, 0x4c, 0x94, 0x11, 0x83, 0xfa, 0xf3, 0xc9, 0x32, 0xe1, 0xe5, 0x53, 0xf0, + 0x43, 0x94, 0x11, 0xe2, 0xfe, 0xff, 0x93, 0x65, 0xc2, 0x3b, 0xae, 0xe0, 0x07, 0x9b, 0x49, 0x78, + 0x8d, 0xb3, 0x53, 0x25, 0x66, 0xb7, 0x4d, 0xac, 0xea, 0x8d, 0x06, 0xb5, 0x56, 0xa8, 0xf2, 0x85, + 0xd8, 0x4c, 0x92, 0x4e, 0xc6, 0x66, 0x92, 0x74, 0x0c, 0xf9, 0x28, 0x9c, 0xbe, 0xad, 0x37, 0x4c, + 0x23, 0xc4, 0xf9, 0x79, 0x64, 0x95, 0xef, 0xcf, 0x44, 0x77, 0xd3, 0x1d, 0xe8, 0xd8, 0x6e, 0xba, + 0x03, 0x8a, 0xcc, 0x02, 0xc1, 0x65, 0x34, 0x98, 0x2d, 0xd8, 0xfa, 0xac, 0xfc, 0x85, 0x4c, 0xd4, + 0x4e, 0x4d, 0x92, 0x30, 0x3b, 0x35, 0x09, 0x25, 0xb5, 0xce, 0x01, 0xe9, 0x95, 0x1f, 0xc8, 0x44, + 0x4f, 0x6b, 0x3a, 0x11, 0x4e, 0xf7, 0x68, 0x9d, 0xa3, 0xda, 0xdf, 0x80, 0xd1, 0xea, 0x42, 0x65, + 0x6a, 0x6a, 0xb2, 0x7a, 0xbb, 0x52, 0x46, 0xf7, 0x5d, 0x43, 0xf9, 0xc1, 0xd8, 0x8a, 0x15, 0x27, + 0x60, 0x2b, 0x56, 0x1c, 0x46, 0x5e, 0x84, 0x21, 0xd6, 0x7e, 0x36, 0x60, 0xf0, 0x93, 0xbf, 0x98, + 0x89, 0x9a, 0x53, 0x32, 0x92, 0x99, 0x53, 0xf2, 0x6f, 0x52, 0x85, 0x13, 0x4c, 0x8a, 0x0b, 0x0e, + 0x5d, 0xa6, 0x0e, 0xb5, 0xea, 0xfe, 0x98, 0xfe, 0xa1, 0x4c, 0xd4, 0xca, 0x48, 0x23, 0x62, 0x56, + 0x46, 0x1a, 0x9c, 0xdc, 0x85, 0x73, 0xf1, 0x93, 0x20, 0xf9, 0x31, 0x95, 0xf2, 0xc3, 0x99, 0x98, + 0x31, 0xdc, 0x85, 0x18, 0x8d, 0xe1, 0x2e, 0x78, 0x62, 0xc1, 0x79, 0x71, 0xac, 0x22, 0x1c, 0x2e, + 0xe3, 0xb5, 0xfd, 0x45, 0x5e, 0xdb, 0x63, 0xa1, 0x43, 0x60, 0x17, 0xea, 0xe9, 0x1e, 0xad, 0x3b, + 0x3b, 0xa6, 0x67, 0xc9, 0xb0, 0xeb, 0xca, 0x8f, 0x64, 0xd2, 0x3d, 0x52, 0x22, 0x6e, 0xca, 0x69, + 0xf1, 0xda, 0xdf, 0xe8, 0x14, 0x34, 0x5c, 0xf9, 0xd1, 0xd8, 0x78, 0x4b, 0x27, 0x63, 0xe3, 0xad, + 0x43, 0xd4, 0xf1, 0xd7, 0x60, 0x8c, 0x2b, 0xf5, 0x82, 0x8e, 0xc3, 0xd0, 0x5a, 0xa1, 0x86, 0xf2, + 0x97, 0x62, 0xab, 0x5d, 0x82, 0x02, 0x5d, 0x7b, 0xe2, 0x40, 0x36, 0x75, 0x57, 0x5b, 0xba, 0x65, + 0xe1, 0x31, 0xab, 0xf2, 0x97, 0x63, 0x53, 0x77, 0x88, 0x42, 0xc7, 0xdd, 0xe0, 0x17, 0xd3, 0x84, + 0x6e, 0x09, 0x37, 0x94, 0x1f, 0x8b, 0x69, 0x42, 0x37, 0x62, 0xa6, 0x09, 0x5d, 0xb3, 0x77, 0xdc, + 0xee, 0xf0, 0xb0, 0x51, 0xf9, 0x52, 0x6c, 0x45, 0x4e, 0xa5, 0x62, 0x2b, 0x72, 0xfa, 0xbb, 0xc8, + 0xdb, 0x1d, 0x1e, 0x05, 0x2a, 0x3f, 0xde, 0x9d, 0x6f, 0xb8, 0xd2, 0xa7, 0xbf, 0x29, 0xbc, 0xdd, + 0xe1, 0x41, 0x9d, 0xf2, 0x13, 0xdd, 0xf9, 0x86, 0x8e, 0x7d, 0xe9, 0xef, 0xf1, 0x6a, 0x9d, 0x1f, + 0xa3, 0x29, 0x3f, 0x19, 0x9f, 0xba, 0x3a, 0x10, 0xe2, 0xd4, 0xd5, 0xe9, 0x45, 0xdb, 0x12, 0x9c, + 0xe1, 0x1a, 0x72, 0xc3, 0xd1, 0x5b, 0xab, 0x55, 0xea, 0x79, 0xa6, 0xb5, 0xe2, 0xef, 0xc4, 0x7e, + 0x2a, 0x13, 0x3b, 0x1e, 0xeb, 0x44, 0x89, 0xc7, 0x63, 0x9d, 0x90, 0x4c, 0x79, 0x13, 0xcf, 0xce, + 0x94, 0x9f, 0x8e, 0x29, 0x6f, 0x82, 0x82, 0x29, 0x6f, 0xf2, 0xb5, 0xda, 0x6b, 0x29, 0xaf, 0xab, + 0x94, 0xbf, 0xd2, 0x99, 0x57, 0xd0, 0xbe, 0x94, 0x47, 0x59, 0xaf, 0xa5, 0x3c, 0x22, 0x52, 0xfe, + 0x6a, 0x67, 0x5e, 0xa1, 0x0f, 0x52, 0x02, 0x38, 0xde, 0x07, 0xbd, 0xb8, 0xab, 0x55, 0xbf, 0x94, + 0x81, 0xa1, 0xaa, 0xe7, 0x50, 0xbd, 0x29, 0x22, 0x4a, 0x9c, 0x85, 0x7e, 0xee, 0x1e, 0xe6, 0xbf, + 0xd0, 0xd0, 0x82, 0xdf, 0xe4, 0x22, 0x8c, 0xcc, 0xe8, 0xae, 0x87, 0x25, 0x2b, 0x96, 0x41, 0xef, + 0xe3, 0xd3, 0x88, 0x9c, 0x16, 0x83, 0x92, 0x19, 0x4e, 0xc7, 0xcb, 0x61, 0xfc, 0x9f, 0xdc, 0x96, + 0x81, 0x14, 0xfa, 0xdf, 0xde, 0x28, 0xf6, 0x60, 0xdc, 0x84, 0x58, 0x59, 0xf5, 0x6b, 0x19, 0x48, + 0x38, 0xae, 0xed, 0xfe, 0xe5, 0xd4, 0x3c, 0x1c, 0x8b, 0xc5, 0x9c, 0x12, 0xef, 0x3b, 0xb6, 0x19, + 0x92, 0x2a, 0x5e, 0x9a, 0xbc, 0x37, 0x78, 0x57, 0x70, 0x4b, 0x9b, 0x11, 0x41, 0x32, 0xfa, 0x36, + 0x37, 0x8a, 0xb9, 0xb6, 0xd3, 0xd0, 0x24, 0x94, 0x78, 0x04, 0xfd, 0xb7, 0x46, 0xc3, 0x80, 0x3a, + 0xe4, 0xa2, 0x78, 0xc6, 0x95, 0x09, 0x43, 0x6b, 0xc4, 0xd2, 0x35, 0xf2, 0x67, 0x5b, 0x1f, 0x84, + 0xa1, 0x4a, 0xb3, 0x45, 0x1d, 0xd7, 0xb6, 0x74, 0xcf, 0xf6, 0xd3, 0xc2, 0x63, 0xd8, 0x05, 0x53, + 0x82, 0xcb, 0xa1, 0x00, 0x64, 0x7a, 0x72, 0xd9, 0xcf, 0x20, 0x91, 0xc3, 0x50, 0x46, 0x18, 0x8f, + 0x33, 0x9e, 0x02, 0x90, 0x53, 0x30, 0xd2, 0x5b, 0xae, 0x8e, 0x2f, 0x50, 0x02, 0xd2, 0x36, 0x03, + 0xc8, 0xa4, 0x48, 0x41, 0x9e, 0x80, 0x02, 0x9e, 0xd8, 0xb9, 0x98, 0x19, 0x46, 0x04, 0xfc, 0x68, + 0x20, 0x44, 0x0e, 0xaf, 0xc0, 0x69, 0xc8, 0x4d, 0x18, 0x0d, 0xaf, 0x23, 0x6e, 0x38, 0x76, 0xbb, + 0xe5, 0xc7, 0x82, 0xc6, 0xd4, 0x89, 0x77, 0x03, 0x5c, 0x6d, 0x05, 0x91, 0x12, 0x8b, 0x44, 0x41, + 0x32, 0x0d, 0xc7, 0x42, 0x18, 0x13, 0x91, 0x1f, 0x83, 0x1e, 0xf3, 0xff, 0x48, 0xbc, 0x98, 0x38, + 0x23, 0xf9, 0x7f, 0x62, 0xc5, 0x48, 0x05, 0xfa, 0xfc, 0x68, 0x1f, 0xfd, 0x5b, 0x2a, 0xe9, 0x71, + 0x11, 0xed, 0xa3, 0x4f, 0x8e, 0xf3, 0xe1, 0x97, 0x27, 0x53, 0x30, 0xa2, 0xd9, 0x6d, 0x8f, 0x2e, + 0xda, 0x62, 0x1d, 0x17, 0x41, 0x8a, 0xb1, 0x4d, 0x0e, 0xc3, 0xd4, 0x3c, 0xdb, 0xcf, 0x3c, 0x29, + 0x67, 0x40, 0x8c, 0x96, 0x22, 0x73, 0x30, 0x96, 0xb8, 0xb8, 0x91, 0xf3, 0x41, 0x4a, 0x9f, 0x97, + 0x64, 0x96, 0x2c, 0x4a, 0xbe, 0x3b, 0x03, 0x85, 0x45, 0x47, 0x37, 0x3d, 0x57, 0x3c, 0x5e, 0x39, + 0x79, 0x65, 0xcd, 0xd1, 0x5b, 0x4c, 0x3f, 0xae, 0x60, 0xac, 0xaa, 0xdb, 0x7a, 0xa3, 0x4d, 0xdd, + 0xf1, 0x3b, 0xec, 0xeb, 0xfe, 0xe5, 0x46, 0xf1, 0xc5, 0x15, 0xdc, 0x1e, 0x5e, 0xa9, 0xdb, 0xcd, + 0xab, 0x2b, 0x8e, 0x7e, 0xcf, 0xf4, 0x70, 0xea, 0xd0, 0x1b, 0x57, 0x3d, 0xda, 0xc0, 0x5d, 0xe8, + 0x55, 0xbd, 0x65, 0x5e, 0xc5, 0x98, 0x88, 0x57, 0x03, 0x4e, 0xbc, 0x06, 0xa6, 0x02, 0x1e, 0xfe, + 0x25, 0xab, 0x00, 0xc7, 0x91, 0x39, 0xb6, 0x79, 0xc3, 0x4f, 0x2d, 0xb5, 0x5a, 0xe2, 0x25, 0x8c, + 0xb4, 0x77, 0xf3, 0x31, 0x5c, 0xb1, 0x03, 0x81, 0xe9, 0xad, 0x96, 0x9c, 0x71, 0x36, 0xa4, 0x63, + 0x5a, 0xb0, 0x28, 0x5a, 0xe4, 0x8b, 0x69, 0x38, 0x94, 0xb8, 0xdf, 0xd8, 0x14, 0x21, 0xc5, 0x8b, + 0x91, 0x25, 0x38, 0x26, 0xf8, 0x06, 0x51, 0x83, 0x47, 0xa2, 0xb3, 0x42, 0x0c, 0xcd, 0x95, 0x36, + 0x68, 0xa3, 0x21, 0xc0, 0x72, 0x1d, 0xb1, 0x12, 0x64, 0x3c, 0x4c, 0x65, 0x36, 0xa7, 0x37, 0xa9, + 0xab, 0x1c, 0x43, 0x8d, 0x3d, 0xb7, 0xb9, 0x51, 0x54, 0xfc, 0xf2, 0x18, 0xf8, 0x26, 0x35, 0x31, + 0x27, 0x16, 0x91, 0x79, 0x70, 0xad, 0x1f, 0x4d, 0xe1, 0x11, 0xd7, 0xf9, 0x68, 0x11, 0x32, 0x01, + 0xc3, 0x81, 0x23, 0xee, 0xad, 0x5b, 0x95, 0x32, 0x3e, 0xb5, 0x19, 0x18, 0x3f, 0xbf, 0xb9, 0x51, + 0x3c, 0x13, 0x8b, 0xeb, 0x2b, 0x33, 0x89, 0x94, 0x91, 0xde, 0xe4, 0xf1, 0xb7, 0x37, 0xb1, 0x37, + 0x79, 0xad, 0x94, 0x37, 0x79, 0x0b, 0xe4, 0x65, 0x18, 0x2c, 0xdd, 0xa9, 0x8a, 0xb7, 0x86, 0xae, + 0x72, 0x3c, 0x8c, 0x04, 0x8f, 0xb9, 0x59, 0xc5, 0xbb, 0x44, 0xb9, 0xe9, 0x32, 0x3d, 0x99, 0x84, + 0x91, 0xc8, 0x5d, 0xbe, 0xab, 0x9c, 0x40, 0x0e, 0xd8, 0x72, 0x1d, 0x31, 0x35, 0x47, 0xa0, 0x22, + 0xd9, 0x82, 0x23, 0x85, 0x98, 0xd6, 0xb0, 0xed, 0x70, 0xa3, 0x61, 0xaf, 0x69, 0x14, 0x9f, 0x35, + 0xe2, 0xc3, 0x9d, 0x7e, 0xae, 0x35, 0x86, 0x40, 0xd5, 0x1c, 0x8e, 0x8b, 0xa4, 0x07, 0x8e, 0x16, + 0x23, 0x6f, 0x02, 0xc1, 0x38, 0xdc, 0xd4, 0xf0, 0x8f, 0x76, 0x2b, 0x65, 0x57, 0x39, 0x85, 0x31, + 0xfb, 0x48, 0xfc, 0x5d, 0x6d, 0xa5, 0x3c, 0x7e, 0x51, 0x4c, 0x1f, 0x17, 0x74, 0x5e, 0xaa, 0xe6, + 0x08, 0x5c, 0xcd, 0x8c, 0x24, 0x29, 0x4b, 0xe1, 0x4a, 0xd6, 0xe0, 0xf4, 0x82, 0x43, 0xef, 0x99, + 0x76, 0xdb, 0xf5, 0x97, 0x0f, 0x7f, 0xde, 0x3a, 0xbd, 0xe5, 0xbc, 0xf5, 0x88, 0xa8, 0xf8, 0x64, + 0xcb, 0xa1, 0xf7, 0x6a, 0x7e, 0xa4, 0xb6, 0x48, 0xb4, 0xa2, 0x4e, 0xdc, 0x31, 0xd5, 0xda, 0x5b, + 0x6d, 0x87, 0x0a, 0xb8, 0x49, 0x5d, 0x45, 0x09, 0xa7, 0x5a, 0xfe, 0x42, 0xd5, 0x0c, 0x70, 0x91, + 0x54, 0x6b, 0xd1, 0x62, 0x44, 0x03, 0x72, 0x63, 0xc2, 0x3f, 0xe6, 0x2f, 0xd5, 0x79, 0x42, 0x2a, + 0xe5, 0x0c, 0x32, 0x53, 0x99, 0x58, 0x56, 0xea, 0x41, 0xd4, 0xc6, 0x9a, 0x2e, 0xf0, 0xb2, 0x58, + 0x92, 0xa5, 0xc9, 0x0c, 0x8c, 0x2e, 0x38, 0xb8, 0xe9, 0xb8, 0x49, 0xd7, 0x17, 0xec, 0x86, 0x59, + 0x5f, 0xc7, 0xf7, 0x43, 0x62, 0xaa, 0x6c, 0x71, 0x5c, 0xed, 0x2e, 0x5d, 0xaf, 0xb5, 0x10, 0x2b, + 0x2f, 0x2b, 0xf1, 0x92, 0x72, 0x14, 0xb5, 0x87, 0xb6, 0x17, 0x45, 0x8d, 0xc2, 0xa8, 0xb8, 0x24, + 0xb8, 0xef, 0x51, 0x8b, 0x2d, 0xf5, 0xae, 0x78, 0x2b, 0xa4, 0xc4, 0x2e, 0x15, 0x02, 0xbc, 0x48, + 0x15, 0xcc, 0x47, 0x19, 0x0d, 0xc0, 0x72, 0xc3, 0xe2, 0x45, 0xd4, 0xcf, 0xe5, 0xe4, 0xa9, 0x93, + 0x9c, 0x83, 0xbc, 0x14, 0xc4, 0x1b, 0xe3, 0x28, 0x61, 0xc0, 0xc3, 0xbc, 0x88, 0xec, 0x36, 0x20, + 0xcc, 0x8e, 0xe0, 0xc1, 0x2c, 0xa6, 0x66, 0x09, 0x63, 0xeb, 0x68, 0x21, 0x01, 0xa6, 0xc5, 0x68, + 0x2f, 0x35, 0xcc, 0x3a, 0x86, 0xc1, 0xcc, 0x49, 0x69, 0x31, 0x10, 0xca, 0xa3, 0x60, 0x4a, 0x24, + 0xe4, 0x1a, 0x0c, 0xfa, 0xfb, 0xd4, 0x30, 0x8e, 0x18, 0x46, 0x47, 0xf4, 0x93, 0x2a, 0xf3, 0xe0, + 0x8b, 0x12, 0x11, 0x79, 0x01, 0xd3, 0x8a, 0xfb, 0x8f, 0x91, 0x7b, 0x43, 0xf3, 0x45, 0x1e, 0xf8, + 0xb1, 0xbc, 0xe2, 0xfe, 0x9b, 0xe4, 0x71, 0x18, 0x96, 0x35, 0xc9, 0x4f, 0x04, 0x84, 0x73, 0x5e, + 0x44, 0xfd, 0xe4, 0xbe, 0x8d, 0x16, 0x21, 0xf3, 0x30, 0x96, 0x50, 0x1e, 0x11, 0x75, 0x0c, 0x93, + 0x41, 0xa6, 0x68, 0x9e, 0xbc, 0xa6, 0x26, 0xca, 0xaa, 0xdf, 0x91, 0x4d, 0xac, 0x18, 0x4c, 0x30, + 0x82, 0x4a, 0xea, 0x1c, 0x14, 0x8c, 0xcf, 0x9a, 0x0b, 0x46, 0x22, 0x22, 0x97, 0xa0, 0x3f, 0x96, + 0x59, 0x1c, 0x9f, 0xa7, 0x07, 0x69, 0xc5, 0x03, 0x2c, 0xb9, 0x26, 0xa5, 0xa6, 0x92, 0x42, 0xfc, + 0xf9, 0xa9, 0xa9, 0xe2, 0xb1, 0xee, 0x30, 0x49, 0xd5, 0xb5, 0x58, 0x14, 0x7c, 0x3f, 0x01, 0x74, + 0x72, 0xb5, 0x0a, 0xa3, 0xde, 0x07, 0xb6, 0x62, 0xef, 0x56, 0xb6, 0xa2, 0xfa, 0x6b, 0x99, 0xa4, + 0xf6, 0x93, 0xeb, 0xc9, 0x90, 0x5d, 0x3c, 0xf7, 0xb3, 0x0f, 0x94, 0x6b, 0x0d, 0x82, 0x77, 0x45, + 0x82, 0x6f, 0x65, 0x77, 0x1d, 0x7c, 0x2b, 0xb7, 0xc3, 0xe0, 0x5b, 0xea, 0xff, 0xc8, 0x77, 0x75, + 0x35, 0x3b, 0x90, 0x20, 0x0d, 0xcf, 0xb3, 0xfd, 0x0e, 0xab, 0xbd, 0xe4, 0x26, 0xac, 0x76, 0xee, + 0x49, 0x53, 0xd3, 0xf9, 0xa8, 0x71, 0xb5, 0x28, 0x25, 0x79, 0x05, 0x86, 0xfc, 0x0f, 0xc0, 0xa0, + 0x6e, 0x52, 0x30, 0xb2, 0x60, 0xad, 0x89, 0xa7, 0xef, 0x96, 0x0b, 0x90, 0x67, 0x60, 0x00, 0x2d, + 0x8d, 0x96, 0x5e, 0xf7, 0x23, 0xfe, 0xf1, 0x10, 0x81, 0x3e, 0x50, 0x0e, 0x44, 0x10, 0x50, 0x92, + 0x8f, 0x41, 0x21, 0x92, 0x3f, 0xfe, 0xea, 0x36, 0x7c, 0xf3, 0xae, 0xc8, 0xd1, 0x6a, 0xf9, 0xde, + 0x21, 0x9e, 0x3b, 0x5e, 0x30, 0x25, 0x8b, 0x70, 0x7c, 0xc1, 0xa1, 0x06, 0x7a, 0x81, 0x4e, 0xde, + 0x6f, 0x39, 0x22, 0x96, 0x30, 0x1f, 0xc0, 0xb8, 0x74, 0xb4, 0x7c, 0x34, 0x5b, 0xd4, 0x04, 0x5e, + 0x0e, 0x3b, 0x96, 0x52, 0x9c, 0xd9, 0x13, 0xbc, 0x25, 0x37, 0xe9, 0xfa, 0x1a, 0xe6, 0x10, 0xed, + 0x0f, 0xed, 0x09, 0x21, 0xe8, 0xbb, 0x02, 0x25, 0xdb, 0x13, 0xd1, 0x42, 0x67, 0x9f, 0x87, 0xc1, + 0xdd, 0x46, 0x7c, 0xfd, 0xc5, 0x6c, 0x07, 0xa7, 0xed, 0x07, 0x37, 0xe9, 0x46, 0x90, 0xee, 0xad, + 0xb7, 0x43, 0xba, 0xb7, 0x6f, 0x66, 0x3b, 0x78, 0xa4, 0x3f, 0xd0, 0x69, 0x99, 0x02, 0x61, 0x44, + 0xd3, 0x32, 0x85, 0x19, 0xb1, 0x4c, 0x43, 0x93, 0x89, 0x62, 0x09, 0xdc, 0x0a, 0x5b, 0x26, 0x70, + 0xfb, 0x99, 0x5c, 0x37, 0x8f, 0xfd, 0x23, 0xd9, 0xef, 0x44, 0xf6, 0xd7, 0x60, 0x30, 0x90, 0x6c, + 0xa5, 0x8c, 0xf6, 0xcc, 0x70, 0x10, 0x5f, 0x9a, 0x83, 0xb1, 0x8c, 0x44, 0x44, 0x2e, 0xf3, 0xb6, + 0x56, 0xcd, 0xb7, 0x78, 0xb8, 0xd4, 0x61, 0x11, 0x08, 0x53, 0xf7, 0xf4, 0x9a, 0x6b, 0xbe, 0x45, + 0xb5, 0x00, 0xad, 0xfe, 0xfd, 0x6c, 0xea, 0xb3, 0x87, 0xa3, 0x3e, 0xda, 0x41, 0x1f, 0xa5, 0x08, + 0x91, 0x3f, 0xd8, 0x38, 0x12, 0xe2, 0x0e, 0x84, 0xf8, 0x47, 0xd9, 0xd4, 0xe7, 0x2d, 0x47, 0x42, + 0xdc, 0xc9, 0x6c, 0xf1, 0x04, 0x0c, 0x68, 0xf6, 0x9a, 0x8b, 0xd9, 0x9a, 0xc5, 0x5c, 0x81, 0x13, + 0xb5, 0x63, 0xaf, 0xb9, 0x3c, 0x93, 0xb5, 0x16, 0x12, 0xa8, 0x7f, 0x92, 0xed, 0xf2, 0x00, 0xe8, + 0x48, 0xf0, 0xef, 0xe4, 0x12, 0xf9, 0xcb, 0xd9, 0xc8, 0x03, 0xa3, 0x07, 0x3a, 0xbf, 0x69, 0xb5, + 0xbe, 0x4a, 0x9b, 0x7a, 0x3c, 0xbf, 0xa9, 0x8b, 0x50, 0x91, 0x65, 0x2c, 0x24, 0x51, 0xbf, 0x9c, + 0x8d, 0xbd, 0xb0, 0x3a, 0x92, 0xdd, 0xb6, 0x65, 0x17, 0x68, 0x9d, 0x78, 0x34, 0x76, 0x24, 0xb9, + 0xed, 0x4a, 0xee, 0x53, 0xd9, 0xd8, 0xfb, 0xba, 0x07, 0x56, 0x76, 0x6c, 0x00, 0x26, 0xdf, 0xfd, + 0x3d, 0xb0, 0x9a, 0xf4, 0x04, 0x0c, 0x08, 0x39, 0x04, 0x4b, 0x05, 0x9f, 0xf7, 0x39, 0x10, 0x0f, + 0x50, 0x03, 0x02, 0xf5, 0xbb, 0xb2, 0x10, 0x7d, 0xf7, 0xf8, 0x80, 0xea, 0xd0, 0x2f, 0x67, 0xa3, + 0x2f, 0x3e, 0x1f, 0x5c, 0xfd, 0xb9, 0x02, 0x50, 0x6d, 0x2f, 0xd5, 0x45, 0xc0, 0xc0, 0x5e, 0xe9, + 0x04, 0x3e, 0x80, 0x6a, 0x12, 0x85, 0xfa, 0x3f, 0xb3, 0xa9, 0xcf, 0x50, 0x1f, 0x5c, 0x01, 0x3e, + 0x8d, 0xa7, 0xe2, 0x75, 0x2b, 0x9c, 0xc8, 0xf1, 0x10, 0x92, 0x8d, 0xbf, 0x44, 0x9e, 0x12, 0x9f, + 0x90, 0x7c, 0x20, 0xc5, 0x5c, 0xc3, 0x28, 0xaa, 0xa1, 0xb9, 0x26, 0xdf, 0x30, 0x48, 0x86, 0xdb, + 0x3f, 0xc9, 0x6e, 0xf5, 0x6a, 0xf7, 0x41, 0x5e, 0x55, 0xfb, 0x16, 0xf4, 0x75, 0x8c, 0x2e, 0xc5, + 0x7a, 0x62, 0x88, 0x67, 0xd1, 0x68, 0x71, 0x90, 0x7c, 0x23, 0x26, 0xa8, 0xd4, 0x3f, 0xec, 0x4d, + 0x7f, 0x32, 0xfa, 0xe0, 0x8a, 0xf0, 0x1c, 0xe4, 0x17, 0x74, 0x6f, 0x55, 0x68, 0x32, 0xde, 0xd6, + 0xb5, 0x74, 0x6f, 0x55, 0x43, 0x28, 0xb9, 0x0c, 0xfd, 0x9a, 0xbe, 0xc6, 0xcf, 0x3c, 0x0b, 0x61, + 0x86, 0x13, 0x47, 0x5f, 0xab, 0xf1, 0x73, 0xcf, 0x00, 0x4d, 0xd4, 0x20, 0xc3, 0x0e, 0x3f, 0xf9, + 0xc6, 0xf4, 0x0e, 0x3c, 0xc3, 0x4e, 0x90, 0x57, 0xe7, 0x1c, 0xe4, 0xc7, 0x6d, 0x63, 0x1d, 0x9d, + 0x59, 0x86, 0x78, 0x65, 0x4b, 0xb6, 0xb1, 0xae, 0x21, 0x94, 0x7c, 0x3a, 0x03, 0x7d, 0xd3, 0x54, + 0x37, 0xd8, 0x08, 0x19, 0xe8, 0xe6, 0x0b, 0xf2, 0xa1, 0xfd, 0xf1, 0x05, 0x19, 0x5b, 0xe5, 0x95, + 0xc9, 0x8a, 0x22, 0xea, 0x27, 0x37, 0xa0, 0x7f, 0x42, 0xf7, 0xe8, 0x8a, 0xed, 0xac, 0xa3, 0x77, + 0xcb, 0x48, 0xe8, 0x76, 0x18, 0xd1, 0x1f, 0x9f, 0x88, 0xdf, 0x8c, 0xd5, 0xc5, 0x2f, 0x2d, 0x28, + 0xcc, 0xc4, 0x22, 0xd2, 0x75, 0x0e, 0x86, 0x62, 0xe1, 0x79, 0x39, 0x83, 0xac, 0x9c, 0xc1, 0xb1, + 0xf2, 0x50, 0xfa, 0xb1, 0x32, 0x5a, 0x8f, 0xe8, 0x01, 0x87, 0x79, 0x6d, 0x86, 0x71, 0xd1, 0xe7, + 0xd6, 0x23, 0x42, 0x31, 0xad, 0x8d, 0x26, 0x91, 0xa8, 0x5f, 0xef, 0x85, 0xd4, 0x07, 0x66, 0x47, + 0x4a, 0x7e, 0xa4, 0xe4, 0xa1, 0x92, 0x97, 0x13, 0x4a, 0x7e, 0x36, 0xf9, 0x64, 0xf1, 0x5d, 0xaa, + 0xe1, 0x5f, 0xcc, 0x27, 0x1e, 0x3c, 0x3f, 0xd8, 0xbb, 0xcb, 0x50, 0x7a, 0xbd, 0x5b, 0x4a, 0x2f, + 0x18, 0x10, 0x85, 0x2d, 0x07, 0x44, 0xdf, 0x76, 0x07, 0x44, 0x7f, 0xc7, 0x01, 0x11, 0x2a, 0xc8, + 0x40, 0x47, 0x05, 0xa9, 0x88, 0x41, 0x03, 0xdd, 0x73, 0xa6, 0x9d, 0xdb, 0xdc, 0x28, 0x8e, 0xb0, + 0xd1, 0x94, 0x9a, 0x2d, 0x0d, 0x59, 0xa8, 0x5f, 0xcb, 0x77, 0x89, 0x52, 0x70, 0x20, 0x3a, 0xf2, + 0x34, 0xe4, 0x4a, 0xad, 0x96, 0xd0, 0x8f, 0xe3, 0x52, 0x80, 0x84, 0x0e, 0xa5, 0x18, 0x35, 0x79, + 0x01, 0x72, 0xa5, 0x3b, 0xd5, 0x78, 0xac, 0xf5, 0xd2, 0x9d, 0xaa, 0xf8, 0x92, 0x8e, 0x65, 0xef, + 0x54, 0xc9, 0x4b, 0x61, 0xd0, 0xb3, 0xd5, 0xb6, 0x75, 0x57, 0x6c, 0x14, 0x85, 0x13, 0xac, 0xef, + 0x69, 0x53, 0x67, 0x28, 0xb6, 0x5d, 0x8c, 0xd1, 0xc6, 0xb4, 0xa9, 0xb0, 0x7d, 0x6d, 0xea, 0xdb, + 0x52, 0x9b, 0xfa, 0xb7, 0xab, 0x4d, 0x03, 0xdb, 0xd0, 0x26, 0xd8, 0x52, 0x9b, 0x06, 0xf7, 0xae, + 0x4d, 0x2d, 0x38, 0x9b, 0x8c, 0x2c, 0x13, 0x68, 0x84, 0x06, 0x24, 0x89, 0x15, 0x8e, 0x25, 0x78, + 0xf5, 0xdf, 0xe6, 0xd8, 0x1a, 0x4f, 0xab, 0x1b, 0x4f, 0x4a, 0xab, 0xa5, 0x94, 0x56, 0x7f, 0x31, + 0xdb, 0x39, 0x20, 0xce, 0xe1, 0x9c, 0xe2, 0xbe, 0x2d, 0x55, 0x4a, 0xf9, 0xe8, 0x03, 0xc5, 0xce, + 0x52, 0x8e, 0xb1, 0x4d, 0x93, 0xd9, 0x57, 0x33, 0x9d, 0xa2, 0xf4, 0xec, 0x49, 0x62, 0x8f, 0x25, + 0x9d, 0xd5, 0xd0, 0x7b, 0xde, 0x8d, 0x7a, 0xa9, 0xc5, 0xb3, 0xb4, 0xe6, 0x76, 0x99, 0xa5, 0xf5, + 0xd7, 0x32, 0x70, 0xfc, 0x66, 0x7b, 0x89, 0x0a, 0xe7, 0xb4, 0xa0, 0x19, 0x6f, 0x02, 0x30, 0xb0, + 0x70, 0x62, 0xc9, 0xa0, 0x13, 0xcb, 0xfb, 0xe4, 0x08, 0x3b, 0xb1, 0x02, 0x57, 0x42, 0x6a, 0xee, + 0xc0, 0x72, 0xde, 0x77, 0xb1, 0xbc, 0xdb, 0x5e, 0xa2, 0xb5, 0x84, 0x27, 0x8b, 0xc4, 0xfd, 0xec, + 0xcb, 0xdc, 0x79, 0x7d, 0xb7, 0x4e, 0x23, 0x3f, 0x9f, 0xed, 0x18, 0xd4, 0xe8, 0xd0, 0xe6, 0x94, + 0xf9, 0x48, 0x6a, 0xaf, 0xc4, 0x73, 0xcb, 0xa4, 0x90, 0xc4, 0x38, 0xa6, 0x71, 0x49, 0x17, 0xd8, + 0x21, 0xcf, 0x74, 0xf4, 0x8e, 0x0a, 0xec, 0xb7, 0x33, 0x1d, 0x83, 0x4f, 0x1d, 0x56, 0x81, 0xa9, + 0xff, 0x2e, 0xe7, 0xc7, 0xbc, 0xda, 0xd3, 0x27, 0x3c, 0x01, 0x03, 0xe2, 0xe9, 0x5f, 0xd4, 0xb7, + 0x56, 0x1c, 0xe5, 0xe1, 0xd1, 0x70, 0x40, 0xc0, 0x96, 0x79, 0x3f, 0x26, 0x4f, 0x90, 0xa2, 0x17, + 0x97, 0x79, 0x53, 0x40, 0x19, 0xbd, 0x44, 0xc2, 0x16, 0xf2, 0xc9, 0xfb, 0xa6, 0x87, 0x56, 0x01, + 0xeb, 0xcb, 0x1c, 0x5f, 0xc8, 0xe9, 0x7d, 0xd3, 0xe3, 0x36, 0x41, 0x80, 0x66, 0x8b, 0x74, 0x35, + 0xcc, 0xe3, 0x28, 0x16, 0x69, 0x57, 0xa4, 0xb3, 0x14, 0x8f, 0xb9, 0x9e, 0x80, 0x01, 0xe1, 0xb0, + 0x2a, 0xdc, 0x4c, 0x44, 0x6b, 0x85, 0x8b, 0x2b, 0xb6, 0x36, 0x20, 0x60, 0x1c, 0x35, 0xba, 0x12, + 0x3a, 0xd6, 0x21, 0x47, 0x07, 0x21, 0x9a, 0xc0, 0x90, 0x6b, 0x30, 0x52, 0xf5, 0x74, 0xcb, 0xd0, + 0x1d, 0x63, 0xbe, 0xed, 0xb5, 0xda, 0x9e, 0x6c, 0x94, 0xba, 0x9e, 0x61, 0xb7, 0x3d, 0x2d, 0x46, + 0x41, 0xde, 0x0f, 0xc3, 0x3e, 0x64, 0xd2, 0x71, 0x6c, 0x47, 0xb6, 0x3c, 0x5c, 0xcf, 0xa0, 0x8e, + 0xa3, 0x45, 0x09, 0xc8, 0x07, 0x60, 0xb8, 0x62, 0xdd, 0xb3, 0x79, 0x82, 0xd0, 0x5b, 0xda, 0x8c, + 0xb0, 0x43, 0xf0, 0x81, 0x94, 0x19, 0x20, 0x6a, 0x6d, 0xa7, 0xa1, 0x45, 0x09, 0xd5, 0xcd, 0x6c, + 0x32, 0x34, 0xd8, 0x83, 0xbb, 0x69, 0xb9, 0x1c, 0x75, 0xa6, 0x43, 0x0f, 0x52, 0x34, 0x08, 0x65, + 0x5f, 0x5e, 0x6e, 0x17, 0x5e, 0x83, 0xfe, 0x9b, 0x74, 0x9d, 0xfb, 0x7d, 0x16, 0x42, 0x57, 0xe1, + 0xbb, 0x02, 0x26, 0x9f, 0xb8, 0xfa, 0x74, 0xea, 0x57, 0xb2, 0xc9, 0xa0, 0x67, 0x0f, 0xae, 0xb0, + 0xdf, 0x0f, 0x7d, 0x28, 0xca, 0x8a, 0x7f, 0xe4, 0x8f, 0x02, 0x44, 0x71, 0x47, 0x3d, 0x90, 0x7d, + 0x32, 0xf5, 0xc7, 0x0b, 0xf1, 0x48, 0x78, 0x0f, 0xae, 0xf4, 0x5e, 0x84, 0xc1, 0x09, 0xdb, 0x72, + 0x4d, 0xd7, 0xa3, 0x56, 0xdd, 0x57, 0xd8, 0x33, 0xcc, 0xa0, 0xaa, 0x87, 0x60, 0xf9, 0x65, 0x90, + 0x44, 0xbd, 0x1b, 0xe5, 0x25, 0xcf, 0xc2, 0x00, 0x8a, 0x1c, 0xfd, 0xa4, 0xa5, 0x04, 0xe4, 0x4b, + 0x0c, 0x18, 0x77, 0x92, 0x0e, 0x49, 0xc9, 0x2d, 0xe8, 0x9f, 0x58, 0x35, 0x1b, 0x86, 0x43, 0x2d, + 0xf4, 0x17, 0x96, 0x1e, 0x1c, 0x47, 0xfb, 0xf2, 0x0a, 0xfe, 0x8b, 0xb4, 0xbc, 0x39, 0x75, 0x51, + 0x2c, 0xf2, 0x36, 0x4a, 0xc0, 0xce, 0xfe, 0x40, 0x16, 0x20, 0x2c, 0x40, 0x1e, 0x86, 0x6c, 0x90, + 0x22, 0x0d, 0xdd, 0x54, 0x22, 0x1a, 0x94, 0xc5, 0xa5, 0x42, 0x8c, 0xed, 0xec, 0x96, 0x63, 0xfb, + 0x16, 0x14, 0xf8, 0x89, 0x17, 0x7a, 0x92, 0x4b, 0xc1, 0xb9, 0x3a, 0x36, 0xf8, 0x0a, 0xd2, 0xf3, + 0xcd, 0x2c, 0x5a, 0x9e, 0x11, 0xaf, 0x6c, 0xce, 0xec, 0x6c, 0x1d, 0x7a, 0xf1, 0x2f, 0x72, 0x11, + 0xf2, 0x28, 0xc5, 0x0c, 0xee, 0x63, 0x71, 0x96, 0x8e, 0xc9, 0x0f, 0xf1, 0xac, 0x9b, 0x26, 0x6c, + 0xcb, 0x63, 0x55, 0x63, 0xab, 0x87, 0x84, 0x5c, 0x04, 0x2c, 0x22, 0x17, 0x01, 0x53, 0xff, 0x71, + 0x36, 0x25, 0x46, 0xe3, 0x83, 0x3b, 0x4c, 0x9e, 0x07, 0xc0, 0x87, 0xd6, 0x4c, 0x9e, 0xfe, 0x13, + 0x0d, 0x1c, 0x25, 0xc8, 0x08, 0xd5, 0x36, 0xb2, 0xed, 0x08, 0x89, 0xd5, 0xdf, 0xc8, 0x24, 0x02, + 0xfb, 0xed, 0x49, 0x8e, 0xb2, 0x55, 0x96, 0xdd, 0xa5, 0x19, 0xeb, 0xf7, 0x45, 0x6e, 0x67, 0x7d, + 0x11, 0xfd, 0x96, 0x7d, 0xb0, 0x4c, 0x0f, 0xf2, 0x5b, 0xbe, 0x9e, 0x4d, 0x0b, 0x73, 0x78, 0x38, + 0x55, 0xfc, 0x7a, 0x60, 0x94, 0xe6, 0xb7, 0x93, 0x5c, 0x5c, 0x98, 0xa9, 0x1f, 0x87, 0x63, 0xb1, + 0xe0, 0x7f, 0x22, 0x6f, 0xe1, 0xc5, 0xee, 0x51, 0x04, 0x3b, 0x3f, 0xd1, 0x8f, 0x90, 0xa9, 0xff, + 0x2b, 0xd3, 0x3d, 0xf4, 0xe3, 0x81, 0xab, 0x4e, 0x8a, 0x00, 0x72, 0x7f, 0x3e, 0x02, 0xd8, 0x87, + 0x6d, 0xf0, 0xe1, 0x16, 0xc0, 0xbb, 0x64, 0xf2, 0x78, 0xa7, 0x05, 0xf0, 0xe3, 0x99, 0x2d, 0x23, + 0x77, 0x1e, 0xb4, 0x0c, 0xd4, 0x7f, 0x9d, 0x49, 0x8d, 0xb0, 0xb9, 0xa7, 0x76, 0xbd, 0x04, 0x05, + 0xee, 0x56, 0x23, 0x5a, 0x25, 0xe5, 0x24, 0x61, 0xd0, 0x0e, 0xe5, 0x45, 0x19, 0x32, 0x03, 0x7d, + 0xbc, 0x0d, 0x46, 0x3c, 0x77, 0x6f, 0x4a, 0x3b, 0x8d, 0x4e, 0x93, 0xa3, 0x40, 0xab, 0xbf, 0x9e, + 0x49, 0x04, 0xfc, 0x3c, 0xc0, 0x6f, 0x0b, 0xa7, 0xea, 0xdc, 0xf6, 0xa7, 0x6a, 0xf5, 0x0f, 0xb2, + 0xe9, 0xf1, 0x46, 0x0f, 0xf0, 0x43, 0xf6, 0xe3, 0x38, 0x6d, 0x77, 0xeb, 0xd6, 0x22, 0x8c, 0x44, + 0x65, 0x21, 0x96, 0xad, 0x0b, 0xe9, 0x51, 0x57, 0x3b, 0xb4, 0x22, 0xc6, 0x43, 0x7d, 0x3b, 0x93, + 0x0c, 0x95, 0x7a, 0xe0, 0xf3, 0xd3, 0xee, 0xb4, 0x25, 0xfa, 0x29, 0xef, 0x92, 0xb5, 0x66, 0x3f, + 0x3e, 0xe5, 0x5d, 0xb2, 0x6a, 0xec, 0xee, 0x53, 0x7e, 0x36, 0xdb, 0x29, 0xd2, 0xec, 0x81, 0x7f, + 0xd0, 0x87, 0x65, 0x21, 0xf3, 0x96, 0x89, 0x4f, 0x7b, 0xb8, 0x53, 0x68, 0xd7, 0x0e, 0x3c, 0x13, + 0x7c, 0x76, 0x37, 0xc6, 0x53, 0x85, 0xf5, 0x2e, 0x51, 0xe4, 0xc3, 0x21, 0xac, 0x77, 0xc9, 0x50, + 0x79, 0xf7, 0x09, 0xeb, 0xef, 0x64, 0xb7, 0x1b, 0xde, 0xf8, 0x48, 0x78, 0x09, 0xe1, 0x7d, 0x3e, + 0x9b, 0x0c, 0xbb, 0x7d, 0xe0, 0x62, 0x9a, 0x82, 0x82, 0x08, 0x00, 0xde, 0x51, 0x38, 0x1c, 0xdf, + 0xc9, 0xa2, 0x11, 0xdf, 0x71, 0x1d, 0xc4, 0x45, 0xce, 0xf6, 0x44, 0xc2, 0x69, 0xd5, 0x3f, 0xc9, + 0xc4, 0x62, 0x54, 0x1f, 0xc8, 0x11, 0xc2, 0xae, 0x96, 0x24, 0xf2, 0xb2, 0x7f, 0x98, 0x99, 0x8f, + 0xc5, 0x08, 0x0d, 0xbe, 0xa7, 0x4c, 0x3d, 0xdd, 0x6c, 0xc4, 0xcb, 0x8b, 0x98, 0x00, 0x5f, 0xc9, + 0xc2, 0x58, 0x82, 0x94, 0x5c, 0x8c, 0x44, 0xc9, 0xc1, 0x63, 0xc9, 0x98, 0xf3, 0x38, 0x8f, 0x97, + 0xb3, 0x83, 0x93, 0xd4, 0x8b, 0x90, 0x2f, 0xeb, 0xeb, 0xfc, 0xdb, 0x7a, 0x39, 0x4b, 0x43, 0x5f, + 0x97, 0x4f, 0xdc, 0x10, 0x4f, 0x96, 0xe0, 0x24, 0xbf, 0x0f, 0x31, 0x6d, 0x6b, 0xd1, 0x6c, 0xd2, + 0x8a, 0x35, 0x6b, 0x36, 0x1a, 0xa6, 0x2b, 0x2e, 0xf5, 0x9e, 0xd8, 0xdc, 0x28, 0x5e, 0xf2, 0x6c, + 0x4f, 0x6f, 0xd4, 0xa8, 0x4f, 0x56, 0xf3, 0xcc, 0x26, 0xad, 0x99, 0x56, 0xad, 0x89, 0x94, 0x12, + 0xcb, 0x74, 0x56, 0xa4, 0xc2, 0xc3, 0xc1, 0x56, 0xeb, 0xba, 0x65, 0x51, 0xa3, 0x62, 0x8d, 0xaf, + 0x7b, 0x94, 0x5f, 0x06, 0xe6, 0xf8, 0x91, 0x20, 0x7f, 0x1b, 0xce, 0xd1, 0x8c, 0xf1, 0x12, 0x23, + 0xd0, 0x52, 0x0a, 0xa9, 0xbf, 0x9a, 0x4f, 0x09, 0x4f, 0x7e, 0x88, 0xd4, 0xc7, 0xef, 0xe9, 0xfc, + 0x16, 0x3d, 0x7d, 0x15, 0xfa, 0x6e, 0x53, 0x07, 0xcf, 0xb7, 0xf8, 0x05, 0x03, 0x3a, 0xb3, 0xdf, + 0xe3, 0x20, 0xf9, 0x86, 0x46, 0x50, 0x91, 0x06, 0x9c, 0x5d, 0x64, 0xdd, 0x94, 0xde, 0x99, 0x85, + 0x5d, 0x74, 0x66, 0x17, 0x7e, 0xe4, 0x0d, 0x38, 0x8d, 0xd8, 0x94, 0x6e, 0xed, 0xc3, 0xaa, 0x30, + 0x72, 0x14, 0xaf, 0x2a, 0xbd, 0x73, 0x3b, 0x95, 0x27, 0x1f, 0x86, 0xa1, 0x60, 0x80, 0x98, 0xd4, + 0x15, 0x37, 0x17, 0x5d, 0xc6, 0x19, 0x0f, 0xcb, 0xc6, 0xc0, 0xe8, 0x42, 0x16, 0x0d, 0xed, 0x15, + 0xe1, 0xa5, 0xfe, 0xab, 0x4c, 0xb7, 0x30, 0xe9, 0x07, 0x3e, 0x2b, 0xbf, 0x0c, 0x7d, 0x06, 0xff, + 0x28, 0xa1, 0x53, 0xdd, 0x03, 0xa9, 0x73, 0x52, 0xcd, 0x2f, 0xa3, 0xfe, 0x7e, 0xa6, 0x6b, 0x74, + 0xf6, 0xc3, 0xfe, 0x79, 0x9f, 0xcf, 0x75, 0xf8, 0x3c, 0x31, 0x89, 0x5e, 0x86, 0x51, 0x33, 0x0c, + 0x1f, 0x5b, 0x0b, 0xc3, 0x4f, 0x69, 0xc7, 0x24, 0x38, 0x8e, 0xae, 0xeb, 0x70, 0xca, 0x77, 0x7c, + 0x74, 0x7c, 0x0f, 0x31, 0xb7, 0xd6, 0x76, 0x4c, 0x3e, 0x2e, 0xb5, 0x13, 0x6e, 0xcc, 0x7d, 0xcc, + 0xbd, 0xe5, 0x98, 0xac, 0x02, 0xdd, 0x5b, 0xa5, 0x96, 0x5e, 0x5b, 0xb3, 0x9d, 0xbb, 0x18, 0xfb, + 0x93, 0x0f, 0x4e, 0xed, 0x18, 0x87, 0xdf, 0xf1, 0xc1, 0xe4, 0x51, 0x18, 0x5e, 0x69, 0xb4, 0x69, + 0x10, 0x6d, 0x91, 0xdf, 0xf5, 0x69, 0x43, 0x0c, 0x18, 0xdc, 0x90, 0x9c, 0x07, 0x40, 0x22, 0x0f, + 0x63, 0xe7, 0xe3, 0xc5, 0x9e, 0x36, 0xc0, 0x20, 0x8b, 0xa2, 0xbb, 0xce, 0x72, 0xad, 0xe6, 0x42, + 0xaa, 0x35, 0x6c, 0x6b, 0xa5, 0xe6, 0x51, 0xa7, 0x89, 0x0d, 0x45, 0x67, 0x06, 0xed, 0x14, 0x52, + 0xe0, 0xd5, 0x89, 0x3b, 0x63, 0x5b, 0x2b, 0x8b, 0xd4, 0x69, 0xb2, 0xa6, 0x3e, 0x01, 0x44, 0x34, + 0xd5, 0xc1, 0x43, 0x0f, 0xfe, 0x71, 0xe8, 0xcd, 0xa0, 0x89, 0x8f, 0xe0, 0xa7, 0x21, 0xf8, 0x61, + 0x45, 0x18, 0xe4, 0x21, 0xe7, 0xb8, 0xd0, 0xd0, 0x85, 0x41, 0x03, 0x0e, 0x42, 0x79, 0x9d, 0x02, + 0xe1, 0x5d, 0xc1, 0xbd, 0xba, 0x35, 0xf1, 0x4b, 0xfd, 0x4c, 0x2e, 0x2d, 0xa0, 0xfc, 0x9e, 0x14, + 0x2d, 0x9c, 0x56, 0xb3, 0x3b, 0x9a, 0x56, 0x8f, 0x59, 0xed, 0x66, 0x4d, 0x6f, 0xb5, 0x6a, 0xcb, + 0x66, 0x03, 0x9f, 0x55, 0xe1, 0xc2, 0xa7, 0x0d, 0x5b, 0xed, 0x66, 0xa9, 0xd5, 0x9a, 0xe2, 0x40, + 0xf2, 0x38, 0x8c, 0x31, 0x3a, 0xec, 0xa4, 0x80, 0x32, 0x8f, 0x94, 0x8c, 0x01, 0xc6, 0x6c, 0xf5, + 0x69, 0xcf, 0x40, 0xbf, 0xe0, 0xc9, 0xd7, 0xaa, 0x5e, 0xad, 0x8f, 0x33, 0x73, 0x59, 0xcf, 0x05, + 0x6c, 0xf8, 0xe4, 0xda, 0xab, 0x0d, 0xf8, 0xe5, 0x31, 0x32, 0xb1, 0xd5, 0x6e, 0xf2, 0x88, 0x58, + 0x7d, 0x88, 0x0c, 0x7e, 0x93, 0x8b, 0x30, 0xc2, 0xb8, 0x04, 0x02, 0xe3, 0xc1, 0x5c, 0x7b, 0xb5, + 0x18, 0x94, 0x5c, 0x83, 0x13, 0x11, 0x08, 0xb7, 0x41, 0xf9, 0x33, 0x81, 0x5e, 0x2d, 0x15, 0xa7, + 0x7e, 0x39, 0x17, 0x0d, 0x73, 0x7f, 0x00, 0x1d, 0x71, 0x1a, 0xfa, 0x6c, 0x67, 0xa5, 0xd6, 0x76, + 0x1a, 0x62, 0xec, 0x15, 0x6c, 0x67, 0xe5, 0x96, 0xd3, 0x20, 0x27, 0xa1, 0xc0, 0x7a, 0xc7, 0x34, + 0xc4, 0x10, 0xeb, 0xd5, 0x5b, 0xad, 0x8a, 0x41, 0x4a, 0xbc, 0x43, 0x30, 0x10, 0x68, 0xad, 0x8e, + 0x5b, 0x7b, 0xee, 0x94, 0xd0, 0xcb, 0x57, 0xbc, 0x04, 0x12, 0xfb, 0x09, 0xc3, 0x83, 0xf2, 0x83, + 0x80, 0x18, 0x0b, 0x03, 0xb7, 0x25, 0x06, 0xef, 0x93, 0x38, 0x0b, 0x81, 0x0c, 0x59, 0xf0, 0x4d, + 0x8c, 0x41, 0xca, 0x40, 0x42, 0xaa, 0xa6, 0x6d, 0x98, 0xcb, 0x26, 0xe5, 0xaf, 0x3a, 0x7a, 0xf9, + 0xc5, 0x6f, 0x12, 0xab, 0x8d, 0xfa, 0x4c, 0x66, 0x05, 0x84, 0xbc, 0xc8, 0x95, 0x90, 0xd3, 0xe1, + 0xda, 0xc7, 0xfb, 0x96, 0xdb, 0x69, 0x31, 0x14, 0x6a, 0x26, 0x96, 0xc7, 0x85, 0x50, 0x7d, 0x3b, + 0x97, 0xcc, 0x75, 0x70, 0x20, 0x76, 0xcd, 0x34, 0x80, 0x48, 0x65, 0x12, 0x5e, 0xae, 0x05, 0x1e, + 0xe7, 0x21, 0xa6, 0x03, 0x0f, 0xa9, 0x2c, 0xb9, 0x0c, 0xfd, 0xfc, 0x8b, 0x2a, 0x65, 0x61, 0xef, + 0xa0, 0x8b, 0x98, 0xdb, 0x32, 0x97, 0x97, 0xd1, 0x9f, 0x2c, 0x40, 0x93, 0x8b, 0xd0, 0x57, 0x9e, + 0xab, 0x56, 0x4b, 0x73, 0xfe, 0x4d, 0x31, 0xbe, 0x2f, 0x31, 0x2c, 0xb7, 0xe6, 0xea, 0x96, 0xab, + 0xf9, 0x48, 0xf2, 0x28, 0x14, 0x2a, 0x0b, 0x48, 0xc6, 0x5f, 0x4d, 0x0e, 0x6e, 0x6e, 0x14, 0xfb, + 0xcc, 0x16, 0xa7, 0x12, 0x28, 0xac, 0xf7, 0x76, 0xa5, 0x2c, 0xb9, 0x4b, 0xf0, 0x7a, 0xef, 0x99, + 0x06, 0x5e, 0x3b, 0x6b, 0x01, 0x9a, 0x3c, 0x03, 0x43, 0x55, 0xea, 0x98, 0x7a, 0x63, 0xae, 0x8d, + 0x5b, 0x45, 0xee, 0x22, 0x36, 0xb6, 0xb9, 0x51, 0x1c, 0x76, 0x11, 0x5e, 0xb3, 0x10, 0xa1, 0x45, + 0xc8, 0xc8, 0x39, 0xc8, 0x4f, 0x9b, 0x96, 0xff, 0x84, 0x01, 0x7d, 0xdc, 0x57, 0x4d, 0xcb, 0xd3, + 0x10, 0xaa, 0xfe, 0x97, 0x6c, 0x7a, 0xc2, 0x88, 0x03, 0x18, 0x8e, 0xbb, 0xbc, 0xe9, 0x8d, 0x29, + 0x41, 0x7e, 0x0f, 0x4a, 0xb0, 0x0c, 0xc7, 0x4a, 0x46, 0xd3, 0xb4, 0x4a, 0xf8, 0xd3, 0x9d, 0x9d, + 0x2a, 0xe1, 0xf0, 0x96, 0x9e, 0xd0, 0xc5, 0xd0, 0xe2, 0x7b, 0x78, 0xa8, 0x5c, 0x86, 0xaa, 0xe9, + 0x1c, 0x57, 0x6b, 0x2e, 0xeb, 0xb5, 0x3a, 0xcf, 0xb5, 0xa0, 0xc5, 0x99, 0xaa, 0xdf, 0x9f, 0xdd, + 0x22, 0xc7, 0xc5, 0x83, 0x28, 0x7d, 0xf5, 0x0b, 0xd9, 0xee, 0x69, 0x46, 0x1e, 0x48, 0xa1, 0xfc, + 0x51, 0x36, 0x25, 0xe9, 0xc7, 0x9e, 0x24, 0x71, 0x19, 0xfa, 0x39, 0x9b, 0xc0, 0xd5, 0x16, 0x67, + 0x1c, 0xae, 0xac, 0x38, 0xd3, 0xf9, 0x68, 0x32, 0x07, 0x27, 0x4a, 0xcb, 0xcb, 0xb4, 0xee, 0x85, + 0x41, 0x93, 0xe7, 0xc2, 0x40, 0xa9, 0x3c, 0xd2, 0xac, 0xc0, 0x87, 0x41, 0x97, 0x31, 0x20, 0x48, + 0x6a, 0x39, 0xb2, 0x08, 0xa7, 0xe2, 0xf0, 0x2a, 0x37, 0xd3, 0xf3, 0x52, 0xf0, 0xd9, 0x04, 0x47, + 0xfe, 0x9f, 0xd6, 0xa1, 0x6c, 0x5a, 0x2b, 0x71, 0x3a, 0xed, 0xed, 0xd6, 0x4a, 0x9c, 0x5b, 0x53, + 0xcb, 0xa9, 0x5f, 0xc9, 0xc9, 0xb9, 0x51, 0x1e, 0x5c, 0xa7, 0xa8, 0xeb, 0x11, 0x57, 0xe8, 0xed, + 0x0e, 0x99, 0x67, 0x44, 0x94, 0x0f, 0xa3, 0xed, 0xf8, 0x5e, 0x83, 0x41, 0x94, 0x01, 0x04, 0xca, + 0xfe, 0x7f, 0x01, 0x25, 0xa9, 0x40, 0xbe, 0xe4, 0xac, 0x70, 0x13, 0x74, 0xab, 0x87, 0x4f, 0xba, + 0xb3, 0xe2, 0xa6, 0x3f, 0x7c, 0x62, 0x2c, 0xd4, 0xef, 0xcb, 0x76, 0x49, 0x67, 0xf2, 0x20, 0x4e, + 0x22, 0x8f, 0xcf, 0xf2, 0x20, 0xc7, 0x37, 0x4d, 0xcb, 0x20, 0x67, 0xe0, 0xe4, 0xad, 0xea, 0xa4, + 0x56, 0xbb, 0x59, 0x99, 0x2b, 0xd7, 0x6e, 0xcd, 0x55, 0x17, 0x26, 0x27, 0x2a, 0x53, 0x95, 0xc9, + 0xf2, 0x68, 0x0f, 0x39, 0x0e, 0xc7, 0x42, 0xd4, 0xf4, 0xad, 0xd9, 0xd2, 0xdc, 0x68, 0x86, 0x8c, + 0xc1, 0x70, 0x08, 0x1c, 0x9f, 0x5f, 0x1c, 0xcd, 0x3e, 0xfe, 0x5e, 0x18, 0xc4, 0x5d, 0x1c, 0x5f, + 0xd1, 0xc8, 0x10, 0xf4, 0xcf, 0x8f, 0x57, 0x27, 0xb5, 0xdb, 0xc8, 0x04, 0xa0, 0x50, 0x9e, 0x9c, + 0x63, 0x0c, 0x33, 0x8f, 0xff, 0xf7, 0x0c, 0x40, 0x75, 0x6a, 0x71, 0x41, 0x10, 0x0e, 0x42, 0x5f, + 0x65, 0xee, 0x76, 0x69, 0xa6, 0xc2, 0xe8, 0xfa, 0x21, 0x3f, 0xbf, 0x30, 0xc9, 0x6a, 0x18, 0x80, + 0xde, 0x89, 0x99, 0xf9, 0xea, 0xe4, 0x68, 0x96, 0x01, 0xb5, 0xc9, 0x52, 0x79, 0x34, 0xc7, 0x80, + 0x77, 0xb4, 0xca, 0xe2, 0xe4, 0x68, 0x9e, 0xfd, 0x39, 0x53, 0x5d, 0x2c, 0x2d, 0x8e, 0xf6, 0xb2, + 0x3f, 0xa7, 0xf0, 0xcf, 0x02, 0x63, 0x56, 0x9d, 0x5c, 0xc4, 0x1f, 0x7d, 0xac, 0x09, 0x53, 0xfe, + 0xaf, 0x7e, 0x86, 0x62, 0xac, 0xcb, 0x15, 0x6d, 0x74, 0x80, 0xfd, 0x60, 0x2c, 0xd9, 0x0f, 0x60, + 0x8d, 0xd3, 0x26, 0x67, 0xe7, 0x6f, 0x4f, 0x8e, 0x0e, 0x32, 0x5e, 0xb3, 0x37, 0x19, 0x78, 0x88, + 0xfd, 0xa9, 0xcd, 0xb2, 0x3f, 0x87, 0x19, 0x27, 0x6d, 0xb2, 0x34, 0xb3, 0x50, 0x5a, 0x9c, 0x1e, + 0x1d, 0x61, 0xed, 0x41, 0x9e, 0xc7, 0x78, 0xc9, 0xb9, 0xd2, 0xec, 0xe4, 0xe8, 0xa8, 0xa0, 0x29, + 0xcf, 0x54, 0xe6, 0x6e, 0x8e, 0x8e, 0x61, 0x43, 0xde, 0x98, 0xc5, 0x1f, 0x84, 0x15, 0xc0, 0xbf, + 0x8e, 0x3f, 0xfe, 0x51, 0x28, 0xcc, 0x57, 0xd1, 0x6e, 0x3b, 0x0d, 0xc7, 0xe7, 0xab, 0xb5, 0xc5, + 0x37, 0x16, 0x26, 0x63, 0xf2, 0x1e, 0x83, 0x61, 0x1f, 0x31, 0x53, 0x99, 0xbb, 0xf5, 0x21, 0x2e, + 0x6d, 0x1f, 0x34, 0x5b, 0x9a, 0x98, 0xaf, 0x8e, 0x66, 0x59, 0xaf, 0xf8, 0xa0, 0x3b, 0x95, 0xb9, + 0xf2, 0xfc, 0x9d, 0xea, 0x68, 0xee, 0xf1, 0x7b, 0x7e, 0xc6, 0xd5, 0x79, 0xc7, 0x5c, 0x31, 0x2d, + 0x72, 0x1e, 0xce, 0x94, 0x27, 0x6f, 0x57, 0x26, 0x26, 0x6b, 0xf3, 0x5a, 0xe5, 0x46, 0x65, 0x2e, + 0x56, 0xd3, 0x49, 0x18, 0x8b, 0xa2, 0x4b, 0x0b, 0x95, 0xd1, 0x0c, 0x39, 0x05, 0x24, 0x0a, 0x7e, + 0xad, 0x34, 0x3b, 0x35, 0x9a, 0x25, 0x0a, 0x9c, 0x88, 0xc2, 0x2b, 0x73, 0x8b, 0xb7, 0xe6, 0x26, + 0x47, 0x73, 0x8f, 0xff, 0x64, 0x06, 0x4e, 0xa6, 0x86, 0x11, 0x20, 0x2a, 0x5c, 0x98, 0x9c, 0x29, + 0x55, 0x17, 0x2b, 0x13, 0xd5, 0xc9, 0x92, 0x36, 0x31, 0x5d, 0x9b, 0x28, 0x2d, 0x4e, 0xde, 0x98, + 0xd7, 0xde, 0xa8, 0xdd, 0x98, 0x9c, 0x9b, 0xd4, 0x4a, 0x33, 0xa3, 0x3d, 0xe4, 0x51, 0x28, 0x76, + 0xa0, 0xa9, 0x4e, 0x4e, 0xdc, 0xd2, 0x2a, 0x8b, 0x6f, 0x8c, 0x66, 0xc8, 0x23, 0x70, 0xbe, 0x23, + 0x11, 0xfb, 0x3d, 0x9a, 0x25, 0x17, 0xe0, 0x6c, 0x27, 0x92, 0xd7, 0x67, 0x46, 0x73, 0x8f, 0xff, + 0x50, 0x06, 0x48, 0xf2, 0x1d, 0x38, 0x79, 0x18, 0xce, 0x31, 0xbd, 0xa8, 0x75, 0x6e, 0xe0, 0x23, + 0x70, 0x3e, 0x95, 0x42, 0x6a, 0x5e, 0x11, 0x1e, 0xea, 0x40, 0x22, 0x1a, 0x77, 0x0e, 0x94, 0x74, + 0x02, 0x6c, 0xda, 0x2f, 0x65, 0xe0, 0x64, 0xaa, 0x11, 0x49, 0x2e, 0xc1, 0x7b, 0x4a, 0xe5, 0x59, + 0xd6, 0x37, 0x13, 0x8b, 0x95, 0xf9, 0xb9, 0x6a, 0x6d, 0x76, 0xaa, 0x54, 0x63, 0xda, 0x77, 0xab, + 0x1a, 0xeb, 0xcd, 0x8b, 0xa0, 0x76, 0xa1, 0x9c, 0x98, 0x2e, 0xcd, 0xdd, 0x60, 0xc3, 0x8f, 0xbc, + 0x07, 0x1e, 0xee, 0x48, 0x37, 0x39, 0x57, 0x1a, 0x9f, 0x99, 0x2c, 0x8f, 0x66, 0xc9, 0x63, 0xf0, + 0x48, 0x47, 0xaa, 0x72, 0xa5, 0xca, 0xc9, 0x72, 0xe3, 0xe5, 0xb7, 0xff, 0xcd, 0x85, 0x9e, 0xb7, + 0xbf, 0x71, 0x21, 0xf3, 0x5b, 0xdf, 0xb8, 0x90, 0xf9, 0x83, 0x6f, 0x5c, 0xc8, 0x7c, 0xf8, 0xda, + 0x4e, 0xde, 0xf7, 0xf3, 0x69, 0x6b, 0xa9, 0x80, 0x13, 0xfa, 0xd3, 0xff, 0x3b, 0x00, 0x00, 0xff, + 0xff, 0x09, 0x71, 0x1b, 0xb1, 0x03, 0x57, 0x01, 0x00, } func (m *Metadata) Marshal() (dAtA []byte, err error) { @@ -28482,6 +28523,75 @@ func (m *OneOf_AccessGraphSettingsUpdate) MarshalToSizedBuffer(dAtA []byte) (int } return len(dAtA) - i, nil } +func (m *OneOf_IntegrationCreate) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *OneOf_IntegrationCreate) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + if m.IntegrationCreate != nil { + { + size, err := m.IntegrationCreate.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintEvents(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + i-- + dAtA[i] = 0xaa + } + return len(dAtA) - i, nil +} +func (m *OneOf_IntegrationUpdate) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *OneOf_IntegrationUpdate) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + if m.IntegrationUpdate != nil { + { + size, err := m.IntegrationUpdate.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintEvents(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + i-- + dAtA[i] = 0xb2 + } + return len(dAtA) - i, nil +} +func (m *OneOf_IntegrationDelete) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *OneOf_IntegrationDelete) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + if m.IntegrationDelete != nil { + { + size, err := m.IntegrationDelete.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintEvents(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + i-- + dAtA[i] = 0xba + } + return len(dAtA) - i, nil +} func (m *StreamStatus) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -28506,12 +28616,12 @@ func (m *StreamStatus) MarshalToSizedBuffer(dAtA []byte) (int, error) { i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } - n609, err609 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.LastUploadTime, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.LastUploadTime):]) - if err609 != nil { - return 0, err609 + n612, err612 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.LastUploadTime, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.LastUploadTime):]) + if err612 != nil { + return 0, err612 } - i -= n609 - i = encodeVarintEvents(dAtA, i, uint64(n609)) + i -= n612 + i = encodeVarintEvents(dAtA, i, uint64(n612)) i-- dAtA[i] = 0x1a if m.LastEventIndex != 0 { @@ -28661,12 +28771,12 @@ func (m *Identity) MarshalToSizedBuffer(dAtA []byte) (int, error) { dAtA[i] = 0xc2 } } - n613, err613 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.PreviousIdentityExpires, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.PreviousIdentityExpires):]) - if err613 != nil { - return 0, err613 + n616, err616 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.PreviousIdentityExpires, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.PreviousIdentityExpires):]) + if err616 != nil { + return 0, err616 } - i -= n613 - i = encodeVarintEvents(dAtA, i, uint64(n613)) + i -= n616 + i = encodeVarintEvents(dAtA, i, uint64(n616)) i-- dAtA[i] = 0x1 i-- @@ -28814,12 +28924,12 @@ func (m *Identity) MarshalToSizedBuffer(dAtA []byte) (int, error) { i-- dAtA[i] = 0x4a } - n617, err617 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Expires, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Expires):]) - if err617 != nil { - return 0, err617 + n620, err620 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Expires, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Expires):]) + if err620 != nil { + return 0, err620 } - i -= n617 - i = encodeVarintEvents(dAtA, i, uint64(n617)) + i -= n620 + i = encodeVarintEvents(dAtA, i, uint64(n620)) i-- dAtA[i] = 0x42 if len(m.KubernetesUsers) > 0 { @@ -39691,6 +39801,42 @@ func (m *OneOf_AccessGraphSettingsUpdate) Size() (n int) { } return n } +func (m *OneOf_IntegrationCreate) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.IntegrationCreate != nil { + l = m.IntegrationCreate.Size() + n += 2 + l + sovEvents(uint64(l)) + } + return n +} +func (m *OneOf_IntegrationUpdate) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.IntegrationUpdate != nil { + l = m.IntegrationUpdate.Size() + n += 2 + l + sovEvents(uint64(l)) + } + return n +} +func (m *OneOf_IntegrationDelete) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.IntegrationDelete != nil { + l = m.IntegrationDelete.Size() + n += 2 + l + sovEvents(uint64(l)) + } + return n +} func (m *StreamStatus) Size() (n int) { if m == nil { return 0 @@ -78104,6 +78250,111 @@ func (m *OneOf) Unmarshal(dAtA []byte) error { } m.Event = &OneOf_AccessGraphSettingsUpdate{v} iNdEx = postIndex + case 165: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field IntegrationCreate", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthEvents + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + v := &IntegrationCreate{} + if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + m.Event = &OneOf_IntegrationCreate{v} + iNdEx = postIndex + case 166: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field IntegrationUpdate", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthEvents + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + v := &IntegrationUpdate{} + if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + m.Event = &OneOf_IntegrationUpdate{v} + iNdEx = postIndex + case 167: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field IntegrationDelete", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthEvents + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + v := &IntegrationDelete{} + if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + m.Event = &OneOf_IntegrationDelete{v} + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipEvents(dAtA[iNdEx:]) diff --git a/api/types/events/oneof.go b/api/types/events/oneof.go index 76c0f408c3437..5ea72a16c63e1 100644 --- a/api/types/events/oneof.go +++ b/api/types/events/oneof.go @@ -704,7 +704,6 @@ func ToOneOf(in AuditEvent) (*OneOf, error) { out.Event = &OneOf_IntegrationDelete{ IntegrationDelete: e, } - default: slog.ErrorContext(context.Background(), "Attempted to convert dynamic event of unknown type into protobuf event.", "event_type", in.GetType()) unknown := &Unknown{} diff --git a/go.mod b/go.mod index e865a43bdeae8..35aab3a2177db 100644 --- a/go.mod +++ b/go.mod @@ -317,7 +317,7 @@ require ( github.com/fatih/color v1.16.0 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect github.com/form3tech-oss/jwt-go v3.2.5+incompatible // indirect - github.com/fsnotify/fsnotify v1.7.0 // indirect + github.com/fsnotify/fsnotify v1.7.0 github.com/fvbommel/sortorder v1.1.0 // indirect github.com/gabriel-vasile/mimetype v1.4.3 // indirect github.com/go-asn1-ber/asn1-ber v1.5.5 // indirect diff --git a/integrations/terraform/go.sum b/integrations/terraform/go.sum index 02ed32106d312..d16c6ac592237 100644 --- a/integrations/terraform/go.sum +++ b/integrations/terraform/go.sum @@ -1024,6 +1024,8 @@ github.com/foxcpp/go-mockdns v1.0.0 h1:7jBqxd3WDWwi/6WhDvacvH1XsN3rOLXyHM1uhvIx6 github.com/foxcpp/go-mockdns v1.0.0/go.mod h1:lgRN6+KxQBawyIghpnl5CezHFGS9VLzvtVlwxvzXTQ4= github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= +github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= +github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= github.com/fxamacker/cbor/v2 v2.6.0 h1:sU6J2usfADwWlYDAFhZBQ6TnLFBHxgesMrQfQgk1tWA= github.com/fxamacker/cbor/v2 v2.6.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ= github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= diff --git a/lib/auth/clusterconfig/clusterconfigv1/service.go b/lib/auth/clusterconfig/clusterconfigv1/service.go index 8a98b855996cd..8edecb8757bea 100644 --- a/lib/auth/clusterconfig/clusterconfigv1/service.go +++ b/lib/auth/clusterconfig/clusterconfigv1/service.go @@ -1030,7 +1030,7 @@ func (s *Service) UpdateAccessGraphSettings(ctx context.Context, req *clustercon return nil, trace.Wrap(err) } - if !modules.GetModules().Features().GetEntitlement(entitlements.Policy).Enabled && !modules.GetModules().Features().AccessGraph { + if !modules.GetModules().Features().Policy.Enabled && !modules.GetModules().Features().AccessGraph { return nil, trace.AccessDenied("access graph is feature isn't enabled") } @@ -1074,7 +1074,7 @@ func (s *Service) UpsertAccessGraphSettings(ctx context.Context, req *clustercon return nil, trace.Wrap(err) } - if !modules.GetModules().Features().GetEntitlement(entitlements.Policy).Enabled && !modules.GetModules().Features().AccessGraph { + if !modules.GetModules().Features().Policy.Enabled && !modules.GetModules().Features().AccessGraph { return nil, trace.AccessDenied("access graph is feature isn't enabled") } @@ -1118,7 +1118,7 @@ func (s *Service) ResetAccessGraphSettings(ctx context.Context, _ *clusterconfig return nil, trace.Wrap(err) } - if !modules.GetModules().Features().GetEntitlement(entitlements.Policy).Enabled && !modules.GetModules().Features().AccessGraph { + if !modules.GetModules().Features().Policy.Enabled && !modules.GetModules().Features().AccessGraph { return nil, trace.AccessDenied("access graph is feature isn't enabled") } diff --git a/lib/auth/clusterconfig/clusterconfigv1/service_test.go b/lib/auth/clusterconfig/clusterconfigv1/service_test.go index 714567f3fb505..b3ac67e1cc342 100644 --- a/lib/auth/clusterconfig/clusterconfigv1/service_test.go +++ b/lib/auth/clusterconfig/clusterconfigv1/service_test.go @@ -1902,8 +1902,8 @@ func TestGetAccessGraphConfig(t *testing.T) { testSetup: func(t *testing.T) { m := modules.TestModules{ TestFeatures: modules.Features{ - Entitlements: map[entitlements.EntitlementKind]modules.EntitlementInfo{ - entitlements.Policy: {Enabled: true}, + Policy: modules.PolicyFeature{ + Enabled: true, }, }, } @@ -2060,8 +2060,8 @@ func TestUpdateAccessGraphSettings(t *testing.T) { testSetup: func(t *testing.T) { m := modules.TestModules{ TestFeatures: modules.Features{ - Entitlements: map[entitlements.EntitlementKind]modules.EntitlementInfo{ - entitlements.Policy: {Enabled: true}, + Policy: modules.PolicyFeature{ + Enabled: true, }, }, } @@ -2185,8 +2185,8 @@ func TestUpsertAccessGraphSettings(t *testing.T) { testSetup: func(t *testing.T) { m := modules.TestModules{ TestFeatures: modules.Features{ - Entitlements: map[entitlements.EntitlementKind]modules.EntitlementInfo{ - entitlements.Policy: {Enabled: true}, + Policy: modules.PolicyFeature{ + Enabled: true, }, }, } @@ -2279,8 +2279,8 @@ func TestResetAccessGraphSettings(t *testing.T) { testSetup: func(t *testing.T) { m := modules.TestModules{ TestFeatures: modules.Features{ - Entitlements: map[entitlements.EntitlementKind]modules.EntitlementInfo{ - entitlements.Policy: {Enabled: true}, + Policy: modules.PolicyFeature{ + Enabled: true, }, }, } From 1ef60c9eed5401f6d35e7d8c40ea671c7f51b967 Mon Sep 17 00:00:00 2001 From: Tiago Silva Date: Wed, 7 Aug 2024 13:38:29 +0100 Subject: [PATCH 25/25] [sec_scan][27] add support for LDAP users and macOS (#45109) * [sec_scan][27] add support for LDAP users and macOS This PR extends support for authorized keys report for users managed by LDAP system and macOS targets. It leverages `getpwent` to read the system database files and retrieve the user properties. It doesn't use the `getpwent_r` because it's not available in macOS and because it's not (yet) standerdized > PLEASE NOTE: the `getpwent_r' function is not (yet) standardized. > The interface may change in later versions of this library. But > the interface is designed following the principals used for the > other reentrant functions so the chances are good this is what the > POSIX people would choose. Part of https://github.com/gravitational/access-graph/issues/637 * handle comments * handle comments 2 * add comment --- .../authorizedkeys/authorized_keys.go | 86 +++++-------------- .../authorizedkeys/authorized_keys_test.go | 55 +++++++----- .../authorizedkeys/users_list.go | 43 ++++++++++ .../authorizedkeys/users_list_darwin.go | 47 ++++++++++ .../authorizedkeys/users_list_unix.go | 67 +++++++++++++++ 5 files changed, 214 insertions(+), 84 deletions(-) create mode 100644 lib/secretsscanner/authorizedkeys/users_list.go create mode 100644 lib/secretsscanner/authorizedkeys/users_list_darwin.go create mode 100644 lib/secretsscanner/authorizedkeys/users_list_unix.go diff --git a/lib/secretsscanner/authorizedkeys/authorized_keys.go b/lib/secretsscanner/authorizedkeys/authorized_keys.go index 7919ac6162e6a..ae6e2adb1b8c8 100644 --- a/lib/secretsscanner/authorizedkeys/authorized_keys.go +++ b/lib/secretsscanner/authorizedkeys/authorized_keys.go @@ -27,7 +27,6 @@ import ( "os/user" "path/filepath" "runtime" - "strings" "sync" "time" @@ -53,11 +52,11 @@ var ( // scanning enabled, the watcher will hold until the feature is enabled. type Watcher struct { // client is the client to use to communicate with the cluster. - client ClusterClient - logger *slog.Logger - clock clockwork.Clock - hostID string - usersAccountFile string + client ClusterClient + logger *slog.Logger + clock clockwork.Clock + hostID string + getHostUsers func() ([]user.User, error) } // ClusterClient is the client to use to communicate with the cluster. @@ -79,17 +78,19 @@ type WatcherConfig struct { // getRuntimeOS returns the runtime operating system. // used for testing purposes. getRuntimeOS func() string - // etcPasswdFile is the path to the file that contains the users account information on the system. - // This file is used to get the list of users on the system and their home directories. - // Value is set to "/etc/passwd" by default. - etcPasswdFile string + // getHostUsers is a function that returns the list of users on the system. + // used for testing purposes. When nil, it uses the default implementation + // that leverages getpwent. + getHostUsers func() ([]user.User, error) } // NewWatcher creates a new Watcher instance. // Returns [ErrUnsupportedPlatform] if the operating system is not supported. func NewWatcher(ctx context.Context, config WatcherConfig) (*Watcher, error) { - if getOS(config) != constants.LinuxOS { + switch platform := getOS(config); platform { + case constants.LinuxOS, constants.DarwinOS: + default: return nil, trace.Wrap(ErrUnsupportedPlatform) } @@ -105,19 +106,16 @@ func NewWatcher(ctx context.Context, config WatcherConfig) (*Watcher, error) { if config.Clock == nil { config.Clock = clockwork.NewRealClock() } - if config.etcPasswdFile == "" { - // etcPasswordPath is the path to the password file. - // This file is used to get the list of users on the system and their home directories. - const etcPasswordPath = "/etc/passwd" - config.etcPasswdFile = etcPasswordPath + if config.getHostUsers == nil { + config.getHostUsers = getHostUsers } w := &Watcher{ - client: config.Client, - logger: config.Logger, - clock: config.Clock, - hostID: config.HostID, - usersAccountFile: config.etcPasswdFile, + client: config.Client, + logger: config.Logger, + clock: config.Clock, + hostID: config.HostID, + getHostUsers: config.getHostUsers, } return w, nil @@ -180,7 +178,8 @@ func (w *Watcher) start(ctx context.Context) error { } }() - if err := fileWatcher.Add(w.usersAccountFile); err != nil { + const etcPasswd = "/etc/passwd" + if err := fileWatcher.Add(etcPasswd); err != nil { w.logger.WarnContext(ctx, "Failed to add watcher for file", "error", err) } @@ -239,7 +238,7 @@ func (w *Watcher) fetchAndReportAuthorizedKeys( stream accessgraphsecretsv1pb.SecretsScannerService_ReportAuthorizedKeysClient, fileWatcher *fsnotify.Watcher, ) error { - users, err := userList(ctx, w.logger, w.usersAccountFile) + users, err := w.getHostUsers() if err != nil { return trace.Wrap(err) } @@ -294,47 +293,6 @@ func (w *Watcher) fetchAndReportAuthorizedKeys( return nil } -// userList retrieves all users on the system -func userList(ctx context.Context, log *slog.Logger, filePath string) ([]user.User, error) { - file, err := os.Open(filePath) - if err != nil { - return nil, err - } - defer func() { - if err := file.Close(); err != nil { - log.DebugContext(ctx, "Failed to close file", "error", err, "file", filePath) - } - }() - - var users []user.User - scanner := bufio.NewScanner(file) - for scanner.Scan() { - line := scanner.Text() - // Skip empty lines and comments - if line == "" || strings.HasPrefix(line, "#") { - continue - } - // username:password:uid:gid:gecos:home:shell - parts := strings.Split(line, ":") - if len(parts) < 7 { - continue - } - users = append(users, user.User{ - Username: parts[0], - Uid: parts[2], - Gid: parts[3], - Name: parts[4], - HomeDir: parts[5], - }) - } - - if err := scanner.Err(); err != nil { - return nil, err - } - - return users, nil -} - func (w *Watcher) parseAuthorizedKeysFile(ctx context.Context, u user.User, authorizedKeysPath string) ([]*accessgraphsecretsv1pb.AuthorizedKey, error) { file, err := os.Open(authorizedKeysPath) if err != nil { diff --git a/lib/secretsscanner/authorizedkeys/authorized_keys_test.go b/lib/secretsscanner/authorizedkeys/authorized_keys_test.go index b6d995dcdcf62..1a512221041c8 100644 --- a/lib/secretsscanner/authorizedkeys/authorized_keys_test.go +++ b/lib/secretsscanner/authorizedkeys/authorized_keys_test.go @@ -23,6 +23,7 @@ import ( "fmt" "log/slog" "os" + "os/user" "path/filepath" "slices" "sync" @@ -47,18 +48,20 @@ import ( func TestAuthorizedKeys(t *testing.T) { hostID := "hostID" - etcPasswdFile := createFSData(t) + dir := createFSData(t) clock := clockwork.NewFakeClockAt(time.Date(2024, time.January, 1, 0, 0, 0, 0, time.UTC)) client := &fakeClient{} ctx, cancel := context.WithCancel(context.Background()) defer cancel() watcher, err := NewWatcher(ctx, WatcherConfig{ - Client: client, - etcPasswdFile: etcPasswdFile, - HostID: hostID, - Clock: clock, - Logger: slog.Default(), + Client: client, + getHostUsers: func() ([]user.User, error) { + return exampleUsers(dir) + }, + HostID: hostID, + Clock: clock, + Logger: slog.Default(), getRuntimeOS: func() string { return constants.LinuxOS }, @@ -107,9 +110,6 @@ func TestAuthorizedKeys(t *testing.T) { // Clear the requests client.clear() - // Update the etcPasswdFile - createUsersAndAuthorizedKeys(t, filepath.Dir(etcPasswdFile)) - cancel() err = group.Wait() require.NoError(t, err) @@ -118,11 +118,9 @@ func TestAuthorizedKeys(t *testing.T) { func createFSData(t *testing.T) string { dir := t.TempDir() - etcPasswd := exampleEtcPasswdFile(dir) - createFile(t, dir, "passwd", etcPasswd) createUsersAndAuthorizedKeys(t, dir) - return filepath.Join(dir, "passwd") + return dir } func createFile(t *testing.T, dir, name, content string) { @@ -133,14 +131,31 @@ func createFile(t *testing.T, dir, name, content string) { require.NoError(t, err) } -func exampleEtcPasswdFile(dir string) string { - return fmt.Sprintf( - `root:x:0:0::%s/root:/usr/bin/bash -bin:x:1:1::/:/usr/bin/nologin -user:x:1000:1000::%s/user:/usr/bin/zsh`, - dir, - dir, - ) +func exampleUsers(dir string) ([]user.User, error) { + return []user.User{ + { + Name: "root", + Username: "root", + Uid: "0", + Gid: "0", + HomeDir: fmt.Sprintf("%s/root", dir), + }, + { + Name: "bin", + Username: "bin", + Uid: "1", + Gid: "1", + HomeDir: "/", + }, + { + Name: "user", + Username: "user", + Uid: "1000", + Gid: "1000", + HomeDir: fmt.Sprintf("%s/user", dir), + }, + }, nil + } const authorizedFileExample = ` diff --git a/lib/secretsscanner/authorizedkeys/users_list.go b/lib/secretsscanner/authorizedkeys/users_list.go new file mode 100644 index 0000000000000..70f3bc2bbdff1 --- /dev/null +++ b/lib/secretsscanner/authorizedkeys/users_list.go @@ -0,0 +1,43 @@ +//go:build !windows + +/* + * Teleport + * Copyright (C) 2024 Gravitational, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package authorizedkeys + +/* +#cgo CFLAGS: -D_POSIX_PTHREAD_SEMANTICS +#include +*/ +import "C" + +import ( + "os/user" + "strconv" +) + +// passwdC2Go converts `passwd` struct from C to golang native struct +func passwdC2Go(passwdC *C.struct_passwd) user.User { + return user.User{ + Name: C.GoString(passwdC.pw_name), + Username: C.GoString(passwdC.pw_name), + Uid: strconv.FormatUint(uint64(passwdC.pw_uid), 10), + Gid: strconv.FormatUint(uint64(passwdC.pw_gid), 10), + HomeDir: C.GoString(passwdC.pw_dir), + } +} diff --git a/lib/secretsscanner/authorizedkeys/users_list_darwin.go b/lib/secretsscanner/authorizedkeys/users_list_darwin.go new file mode 100644 index 0000000000000..9155cf4392e68 --- /dev/null +++ b/lib/secretsscanner/authorizedkeys/users_list_darwin.go @@ -0,0 +1,47 @@ +/* + * Teleport + * Copyright (C) 2024 Gravitational, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package authorizedkeys + +/* +#cgo CFLAGS: -D_POSIX_PTHREAD_SEMANTICS +#include +*/ +import "C" + +import ( + "os/user" +) + +// getHostUsers returns a list of all users on the host +// from local /etc/passwd file, LDAP, or other user databases. +func getHostUsers() (results []user.User, _ error) { + C.setpwent() + var result *C.struct_passwd + for { + result = C.getpwent() /* on darwin, getpwent() is reentrant */ + if result == nil { + break + } + results = append(results, passwdC2Go(result)) + } + + C.endpwent() + + return results, nil +} diff --git a/lib/secretsscanner/authorizedkeys/users_list_unix.go b/lib/secretsscanner/authorizedkeys/users_list_unix.go new file mode 100644 index 0000000000000..b8c2dc45ffa9c --- /dev/null +++ b/lib/secretsscanner/authorizedkeys/users_list_unix.go @@ -0,0 +1,67 @@ +//go:build !darwin + +/* + * Teleport + * Copyright (C) 2024 Gravitational, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package authorizedkeys + +/* +#cgo CFLAGS: -D_POSIX_PTHREAD_SEMANTICS -D__USE_MISC +#include +#include +#include +#include +*/ +import "C" + +import ( + "os/user" + + "github.com/gravitational/trace" +) + +// getHostUsers returns a list of all users on the host +// from local /etc/passwd file, LDAP, or other user databases. +func getHostUsers() (results []user.User, _ error) { + + bufSize := C.sysconf(C._SC_GETPW_R_SIZE_MAX) + if bufSize == -1 { + bufSize = 16384 + } + if bufSize <= 0 || bufSize > 1<<20 { + return nil, trace.BadParameter("unreasonable _SC_GETPW_R_SIZE_MAX of %d", bufSize) + } + buf := C.malloc(C.size_t(bufSize)) + defer C.free(buf) + + C.setpwent() + + var pwdBuf C.struct_passwd + for { + var result *C.struct_passwd + rv := C.getpwent_r(&pwdBuf, (*C.char)(buf), C.size_t(bufSize), &result) + if rv != 0 || result == nil { + break + } + results = append(results, passwdC2Go(&pwdBuf)) + } + + C.endpwent() + + return results, nil +}