diff --git a/internal/gen/controller/servers/services/credential.pb.go b/internal/gen/controller/servers/services/credential.pb.go new file mode 100644 index 0000000000..b8a3746e39 --- /dev/null +++ b/internal/gen/controller/servers/services/credential.pb.go @@ -0,0 +1,253 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.27.1 +// protoc v3.17.3 +// source: controller/servers/services/v1/credential.proto + +package services + +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) +) + +type Credential struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Types that are assignable to Credential: + // *Credential_UserPassword + Credential isCredential_Credential `protobuf_oneof:"credential"` +} + +func (x *Credential) Reset() { + *x = Credential{} + if protoimpl.UnsafeEnabled { + mi := &file_controller_servers_services_v1_credential_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Credential) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Credential) ProtoMessage() {} + +func (x *Credential) ProtoReflect() protoreflect.Message { + mi := &file_controller_servers_services_v1_credential_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 Credential.ProtoReflect.Descriptor instead. +func (*Credential) Descriptor() ([]byte, []int) { + return file_controller_servers_services_v1_credential_proto_rawDescGZIP(), []int{0} +} + +func (m *Credential) GetCredential() isCredential_Credential { + if m != nil { + return m.Credential + } + return nil +} + +func (x *Credential) GetUserPassword() *UserPassword { + if x, ok := x.GetCredential().(*Credential_UserPassword); ok { + return x.UserPassword + } + return nil +} + +type isCredential_Credential interface { + isCredential_Credential() +} + +type Credential_UserPassword struct { + UserPassword *UserPassword `protobuf:"bytes,1,opt,name=user_password,json=userPassword,proto3,oneof"` +} + +func (*Credential_UserPassword) isCredential_Credential() {} + +// UserPassword is a credential containing a username and a password. +type UserPassword struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The username of the credential + Username string `protobuf:"bytes,10,opt,name=username,proto3" json:"username,omitempty"` // @gotags: `class:"public"` + // The password of the credential + Password string `protobuf:"bytes,20,opt,name=password,proto3" json:"password,omitempty"` // @gotags: `class:"secret"` +} + +func (x *UserPassword) Reset() { + *x = UserPassword{} + if protoimpl.UnsafeEnabled { + mi := &file_controller_servers_services_v1_credential_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UserPassword) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UserPassword) ProtoMessage() {} + +func (x *UserPassword) ProtoReflect() protoreflect.Message { + mi := &file_controller_servers_services_v1_credential_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 UserPassword.ProtoReflect.Descriptor instead. +func (*UserPassword) Descriptor() ([]byte, []int) { + return file_controller_servers_services_v1_credential_proto_rawDescGZIP(), []int{1} +} + +func (x *UserPassword) GetUsername() string { + if x != nil { + return x.Username + } + return "" +} + +func (x *UserPassword) GetPassword() string { + if x != nil { + return x.Password + } + return "" +} + +var File_controller_servers_services_v1_credential_proto protoreflect.FileDescriptor + +var file_controller_servers_services_v1_credential_proto_rawDesc = []byte{ + 0x0a, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2f, 0x73, 0x65, 0x72, + 0x76, 0x65, 0x72, 0x73, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2f, 0x76, 0x31, + 0x2f, 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x12, 0x1e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x73, 0x65, + 0x72, 0x76, 0x65, 0x72, 0x73, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x76, + 0x31, 0x22, 0x6f, 0x0a, 0x0a, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x12, + 0x53, 0x0a, 0x0d, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, + 0x6c, 0x65, 0x72, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x2e, 0x73, 0x65, 0x72, 0x76, + 0x69, 0x63, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x50, 0x61, 0x73, 0x73, + 0x77, 0x6f, 0x72, 0x64, 0x48, 0x00, 0x52, 0x0c, 0x75, 0x73, 0x65, 0x72, 0x50, 0x61, 0x73, 0x73, + 0x77, 0x6f, 0x72, 0x64, 0x42, 0x0c, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, + 0x61, 0x6c, 0x22, 0x46, 0x0a, 0x0c, 0x55, 0x73, 0x65, 0x72, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, + 0x72, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x0a, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1a, + 0x0a, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x14, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x42, 0x51, 0x5a, 0x4f, 0x67, 0x69, + 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, + 0x72, 0x70, 0x2f, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x61, 0x72, 0x79, 0x2f, 0x69, 0x6e, 0x74, 0x65, + 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, + 0x6c, 0x65, 0x72, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x2f, 0x73, 0x65, 0x72, 0x76, + 0x69, 0x63, 0x65, 0x73, 0x3b, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x62, 0x06, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_controller_servers_services_v1_credential_proto_rawDescOnce sync.Once + file_controller_servers_services_v1_credential_proto_rawDescData = file_controller_servers_services_v1_credential_proto_rawDesc +) + +func file_controller_servers_services_v1_credential_proto_rawDescGZIP() []byte { + file_controller_servers_services_v1_credential_proto_rawDescOnce.Do(func() { + file_controller_servers_services_v1_credential_proto_rawDescData = protoimpl.X.CompressGZIP(file_controller_servers_services_v1_credential_proto_rawDescData) + }) + return file_controller_servers_services_v1_credential_proto_rawDescData +} + +var file_controller_servers_services_v1_credential_proto_msgTypes = make([]protoimpl.MessageInfo, 2) +var file_controller_servers_services_v1_credential_proto_goTypes = []interface{}{ + (*Credential)(nil), // 0: controller.servers.services.v1.Credential + (*UserPassword)(nil), // 1: controller.servers.services.v1.UserPassword +} +var file_controller_servers_services_v1_credential_proto_depIdxs = []int32{ + 1, // 0: controller.servers.services.v1.Credential.user_password:type_name -> controller.servers.services.v1.UserPassword + 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_controller_servers_services_v1_credential_proto_init() } +func file_controller_servers_services_v1_credential_proto_init() { + if File_controller_servers_services_v1_credential_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_controller_servers_services_v1_credential_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Credential); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_controller_servers_services_v1_credential_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UserPassword); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + file_controller_servers_services_v1_credential_proto_msgTypes[0].OneofWrappers = []interface{}{ + (*Credential_UserPassword)(nil), + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_controller_servers_services_v1_credential_proto_rawDesc, + NumEnums: 0, + NumMessages: 2, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_controller_servers_services_v1_credential_proto_goTypes, + DependencyIndexes: file_controller_servers_services_v1_credential_proto_depIdxs, + MessageInfos: file_controller_servers_services_v1_credential_proto_msgTypes, + }.Build() + File_controller_servers_services_v1_credential_proto = out.File + file_controller_servers_services_v1_credential_proto_rawDesc = nil + file_controller_servers_services_v1_credential_proto_goTypes = nil + file_controller_servers_services_v1_credential_proto_depIdxs = nil +} diff --git a/internal/gen/controller/servers/services/session_service.pb.go b/internal/gen/controller/servers/services/session_service.pb.go index af8715dd79..49fbae4588 100644 --- a/internal/gen/controller/servers/services/session_service.pb.go +++ b/internal/gen/controller/servers/services/session_service.pb.go @@ -99,6 +99,7 @@ type LookupSessionResponse struct { HostSetId string `protobuf:"bytes,100,opt,name=host_set_id,json=hostSetId,proto3" json:"host_set_id,omitempty" class:"public"` // @gotags: `class:"public"` TargetId string `protobuf:"bytes,110,opt,name=target_id,json=targetId,proto3" json:"target_id,omitempty" class:"public"` // @gotags: `class:"public"` UserId string `protobuf:"bytes,120,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty" class:"public"` // @gotags: `class:"public"` + Credentials []*Credential `protobuf:"bytes,130,rep,name=credentials,proto3" json:"credentials,omitempty" class:"secret"` // @gotags: `class:"secret"` } func (x *LookupSessionResponse) Reset() { @@ -217,6 +218,13 @@ func (x *LookupSessionResponse) GetUserId() string { return "" } +func (x *LookupSessionResponse) GetCredentials() []*Credential { + if x != nil { + return x.Credentials + } + return nil +} + type ActivateSessionRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -566,8 +574,8 @@ type ConnectConnectionRequest struct { EndpointTcpAddress string `protobuf:"bytes,40,opt,name=endpoint_tcp_address,json=endpointTcpAddress,proto3" json:"endpoint_tcp_address,omitempty" class:"public"` // @gotags: `class:"public"` EndpointTcpPort uint32 `protobuf:"varint,50,opt,name=endpoint_tcp_port,json=endpointTcpPort,proto3" json:"endpoint_tcp_port,omitempty" class:"public"` // @gotags: `class:"public"` Type string `protobuf:"bytes,60,opt,name=type,proto3" json:"type,omitempty" class:"public"` // @gotags: `class:"public"` - // user_client_ip is the user's client ip for the connection as determined - // the inbound http request + // user_client_ip is the user's client ip for the connection as determined by + // the inbound http request handler UserClientIp string `protobuf:"bytes,70,opt,name=user_client_ip,json=userClientIp,proto3" json:"user_client_ip,omitempty" class:"public"` // @gotags: `class:"public" } @@ -932,50 +940,58 @@ var file_controller_servers_services_v1_session_service_proto_rawDesc = []byte{ 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x30, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x2f, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x73, 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x61, 0x72, - 0x67, 0x65, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x40, 0x63, 0x6f, 0x6e, 0x74, 0x72, + 0x67, 0x65, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x2f, 0x73, 0x65, - 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, - 0x5f, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x73, 0x65, - 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x52, 0x0a, 0x14, 0x4c, - 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x69, - 0x64, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, - 0x49, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, - 0x14, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x49, 0x64, 0x22, - 0x99, 0x04, 0x0a, 0x15, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, - 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x63, 0x0a, 0x0d, 0x61, 0x75, 0x74, - 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x3d, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, - 0x69, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x2e, 0x74, 0x61, 0x72, 0x67, - 0x65, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x41, 0x75, - 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x61, 0x74, 0x61, 0x52, - 0x0d, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1d, - 0x0a, 0x0a, 0x74, 0x6f, 0x66, 0x75, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x14, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x09, 0x74, 0x6f, 0x66, 0x75, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x18, 0x0a, - 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x1e, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, - 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1a, 0x0a, 0x08, 0x65, 0x6e, 0x64, 0x70, 0x6f, - 0x69, 0x6e, 0x74, 0x18, 0x28, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x65, 0x6e, 0x64, 0x70, 0x6f, - 0x69, 0x6e, 0x74, 0x12, 0x3a, 0x0a, 0x0a, 0x65, 0x78, 0x70, 0x69, 0x72, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x18, 0x32, 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, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, - 0x45, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x3c, 0x20, 0x01, 0x28, 0x0e, 0x32, - 0x2d, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x73, 0x65, 0x72, - 0x76, 0x65, 0x72, 0x73, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x76, 0x31, - 0x2e, 0x53, 0x45, 0x53, 0x53, 0x49, 0x4f, 0x4e, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x52, 0x06, - 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x29, 0x0a, 0x10, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, - 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x46, 0x20, 0x01, 0x28, 0x05, - 0x52, 0x0f, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4c, 0x69, 0x6d, 0x69, - 0x74, 0x12, 0x29, 0x0a, 0x10, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, - 0x5f, 0x6c, 0x65, 0x66, 0x74, 0x18, 0x50, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0f, 0x63, 0x6f, 0x6e, - 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x4c, 0x65, 0x66, 0x74, 0x12, 0x17, 0x0a, 0x07, - 0x68, 0x6f, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x5a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x68, - 0x6f, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1e, 0x0a, 0x0b, 0x68, 0x6f, 0x73, 0x74, 0x5f, 0x73, 0x65, - 0x74, 0x5f, 0x69, 0x64, 0x18, 0x64, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x68, 0x6f, 0x73, 0x74, - 0x53, 0x65, 0x74, 0x49, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, - 0x69, 0x64, 0x18, 0x6e, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, - 0x49, 0x64, 0x12, 0x17, 0x0a, 0x07, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x78, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x22, 0xd4, 0x01, 0x0a, 0x16, + 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2f, 0x76, 0x31, 0x2f, 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, + 0x74, 0x69, 0x61, 0x6c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x40, 0x63, 0x6f, 0x6e, 0x74, + 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x2f, 0x73, + 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x65, + 0x72, 0x5f, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x73, + 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x52, 0x0a, 0x14, + 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, + 0x69, 0x64, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, + 0x6e, 0x49, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x69, 0x64, + 0x18, 0x14, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x49, 0x64, + 0x22, 0xe8, 0x04, 0x0a, 0x15, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x53, 0x65, 0x73, 0x73, 0x69, + 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x63, 0x0a, 0x0d, 0x61, 0x75, + 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x0a, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x3d, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, + 0x70, 0x69, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x2e, 0x74, 0x61, 0x72, + 0x67, 0x65, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x41, + 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x61, 0x74, 0x61, + 0x52, 0x0d, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, + 0x1d, 0x0a, 0x0a, 0x74, 0x6f, 0x66, 0x75, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x14, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x09, 0x74, 0x6f, 0x66, 0x75, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x18, + 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x1e, 0x20, 0x01, 0x28, 0x0d, 0x52, + 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1a, 0x0a, 0x08, 0x65, 0x6e, 0x64, 0x70, + 0x6f, 0x69, 0x6e, 0x74, 0x18, 0x28, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x65, 0x6e, 0x64, 0x70, + 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x3a, 0x0a, 0x0a, 0x65, 0x78, 0x70, 0x69, 0x72, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x18, 0x32, 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, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x12, 0x45, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x3c, 0x20, 0x01, 0x28, 0x0e, + 0x32, 0x2d, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x73, 0x65, + 0x72, 0x76, 0x65, 0x72, 0x73, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x76, + 0x31, 0x2e, 0x53, 0x45, 0x53, 0x53, 0x49, 0x4f, 0x4e, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x52, + 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x29, 0x0a, 0x10, 0x63, 0x6f, 0x6e, 0x6e, 0x65, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x46, 0x20, 0x01, 0x28, + 0x05, 0x52, 0x0f, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4c, 0x69, 0x6d, + 0x69, 0x74, 0x12, 0x29, 0x0a, 0x10, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x5f, 0x6c, 0x65, 0x66, 0x74, 0x18, 0x50, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0f, 0x63, 0x6f, + 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x4c, 0x65, 0x66, 0x74, 0x12, 0x17, 0x0a, + 0x07, 0x68, 0x6f, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x5a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, + 0x68, 0x6f, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1e, 0x0a, 0x0b, 0x68, 0x6f, 0x73, 0x74, 0x5f, 0x73, + 0x65, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x64, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x68, 0x6f, 0x73, + 0x74, 0x53, 0x65, 0x74, 0x49, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, + 0x5f, 0x69, 0x64, 0x18, 0x6e, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x74, 0x61, 0x72, 0x67, 0x65, + 0x74, 0x49, 0x64, 0x12, 0x17, 0x0a, 0x07, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x78, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x12, 0x4d, 0x0a, 0x0b, + 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x18, 0x82, 0x01, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, + 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, + 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x52, 0x0b, + 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x22, 0xd4, 0x01, 0x0a, 0x16, 0x41, 0x63, 0x74, 0x69, 0x76, 0x61, 0x74, 0x65, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x65, 0x73, 0x73, @@ -1174,37 +1190,39 @@ var file_controller_servers_services_v1_session_service_proto_goTypes = []interf (*targets.SessionAuthorizationData)(nil), // 14: controller.api.resources.targets.v1.SessionAuthorizationData (*timestamppb.Timestamp)(nil), // 15: google.protobuf.Timestamp (SESSIONSTATUS)(0), // 16: controller.servers.services.v1.SESSIONSTATUS - (CONNECTIONSTATUS)(0), // 17: controller.servers.services.v1.CONNECTIONSTATUS + (*Credential)(nil), // 17: controller.servers.services.v1.Credential + (CONNECTIONSTATUS)(0), // 18: controller.servers.services.v1.CONNECTIONSTATUS } var file_controller_servers_services_v1_session_service_proto_depIdxs = []int32{ 14, // 0: controller.servers.services.v1.LookupSessionResponse.authorization:type_name -> controller.api.resources.targets.v1.SessionAuthorizationData 15, // 1: controller.servers.services.v1.LookupSessionResponse.expiration:type_name -> google.protobuf.Timestamp 16, // 2: controller.servers.services.v1.LookupSessionResponse.status:type_name -> controller.servers.services.v1.SESSIONSTATUS - 16, // 3: controller.servers.services.v1.ActivateSessionRequest.status:type_name -> controller.servers.services.v1.SESSIONSTATUS - 16, // 4: controller.servers.services.v1.ActivateSessionResponse.status:type_name -> controller.servers.services.v1.SESSIONSTATUS - 16, // 5: controller.servers.services.v1.CancelSessionResponse.status:type_name -> controller.servers.services.v1.SESSIONSTATUS - 17, // 6: controller.servers.services.v1.AuthorizeConnectionResponse.status:type_name -> controller.servers.services.v1.CONNECTIONSTATUS - 17, // 7: controller.servers.services.v1.ConnectConnectionResponse.status:type_name -> controller.servers.services.v1.CONNECTIONSTATUS - 10, // 8: controller.servers.services.v1.CloseConnectionRequest.close_request_data:type_name -> controller.servers.services.v1.CloseConnectionRequestData - 17, // 9: controller.servers.services.v1.CloseConnectionResponseData.status:type_name -> controller.servers.services.v1.CONNECTIONSTATUS - 12, // 10: controller.servers.services.v1.CloseConnectionResponse.close_response_data:type_name -> controller.servers.services.v1.CloseConnectionResponseData - 0, // 11: controller.servers.services.v1.SessionService.LookupSession:input_type -> controller.servers.services.v1.LookupSessionRequest - 2, // 12: controller.servers.services.v1.SessionService.ActivateSession:input_type -> controller.servers.services.v1.ActivateSessionRequest - 4, // 13: controller.servers.services.v1.SessionService.CancelSession:input_type -> controller.servers.services.v1.CancelSessionRequest - 6, // 14: controller.servers.services.v1.SessionService.AuthorizeConnection:input_type -> controller.servers.services.v1.AuthorizeConnectionRequest - 8, // 15: controller.servers.services.v1.SessionService.ConnectConnection:input_type -> controller.servers.services.v1.ConnectConnectionRequest - 11, // 16: controller.servers.services.v1.SessionService.CloseConnection:input_type -> controller.servers.services.v1.CloseConnectionRequest - 1, // 17: controller.servers.services.v1.SessionService.LookupSession:output_type -> controller.servers.services.v1.LookupSessionResponse - 3, // 18: controller.servers.services.v1.SessionService.ActivateSession:output_type -> controller.servers.services.v1.ActivateSessionResponse - 5, // 19: controller.servers.services.v1.SessionService.CancelSession:output_type -> controller.servers.services.v1.CancelSessionResponse - 7, // 20: controller.servers.services.v1.SessionService.AuthorizeConnection:output_type -> controller.servers.services.v1.AuthorizeConnectionResponse - 9, // 21: controller.servers.services.v1.SessionService.ConnectConnection:output_type -> controller.servers.services.v1.ConnectConnectionResponse - 13, // 22: controller.servers.services.v1.SessionService.CloseConnection:output_type -> controller.servers.services.v1.CloseConnectionResponse - 17, // [17:23] is the sub-list for method output_type - 11, // [11:17] is the sub-list for method input_type - 11, // [11:11] is the sub-list for extension type_name - 11, // [11:11] is the sub-list for extension extendee - 0, // [0:11] is the sub-list for field type_name + 17, // 3: controller.servers.services.v1.LookupSessionResponse.credentials:type_name -> controller.servers.services.v1.Credential + 16, // 4: controller.servers.services.v1.ActivateSessionRequest.status:type_name -> controller.servers.services.v1.SESSIONSTATUS + 16, // 5: controller.servers.services.v1.ActivateSessionResponse.status:type_name -> controller.servers.services.v1.SESSIONSTATUS + 16, // 6: controller.servers.services.v1.CancelSessionResponse.status:type_name -> controller.servers.services.v1.SESSIONSTATUS + 18, // 7: controller.servers.services.v1.AuthorizeConnectionResponse.status:type_name -> controller.servers.services.v1.CONNECTIONSTATUS + 18, // 8: controller.servers.services.v1.ConnectConnectionResponse.status:type_name -> controller.servers.services.v1.CONNECTIONSTATUS + 10, // 9: controller.servers.services.v1.CloseConnectionRequest.close_request_data:type_name -> controller.servers.services.v1.CloseConnectionRequestData + 18, // 10: controller.servers.services.v1.CloseConnectionResponseData.status:type_name -> controller.servers.services.v1.CONNECTIONSTATUS + 12, // 11: controller.servers.services.v1.CloseConnectionResponse.close_response_data:type_name -> controller.servers.services.v1.CloseConnectionResponseData + 0, // 12: controller.servers.services.v1.SessionService.LookupSession:input_type -> controller.servers.services.v1.LookupSessionRequest + 2, // 13: controller.servers.services.v1.SessionService.ActivateSession:input_type -> controller.servers.services.v1.ActivateSessionRequest + 4, // 14: controller.servers.services.v1.SessionService.CancelSession:input_type -> controller.servers.services.v1.CancelSessionRequest + 6, // 15: controller.servers.services.v1.SessionService.AuthorizeConnection:input_type -> controller.servers.services.v1.AuthorizeConnectionRequest + 8, // 16: controller.servers.services.v1.SessionService.ConnectConnection:input_type -> controller.servers.services.v1.ConnectConnectionRequest + 11, // 17: controller.servers.services.v1.SessionService.CloseConnection:input_type -> controller.servers.services.v1.CloseConnectionRequest + 1, // 18: controller.servers.services.v1.SessionService.LookupSession:output_type -> controller.servers.services.v1.LookupSessionResponse + 3, // 19: controller.servers.services.v1.SessionService.ActivateSession:output_type -> controller.servers.services.v1.ActivateSessionResponse + 5, // 20: controller.servers.services.v1.SessionService.CancelSession:output_type -> controller.servers.services.v1.CancelSessionResponse + 7, // 21: controller.servers.services.v1.SessionService.AuthorizeConnection:output_type -> controller.servers.services.v1.AuthorizeConnectionResponse + 9, // 22: controller.servers.services.v1.SessionService.ConnectConnection:output_type -> controller.servers.services.v1.ConnectConnectionResponse + 13, // 23: controller.servers.services.v1.SessionService.CloseConnection:output_type -> controller.servers.services.v1.CloseConnectionResponse + 18, // [18:24] is the sub-list for method output_type + 12, // [12:18] is the sub-list for method input_type + 12, // [12:12] is the sub-list for extension type_name + 12, // [12:12] is the sub-list for extension extendee + 0, // [0:12] is the sub-list for field type_name } func init() { file_controller_servers_services_v1_session_service_proto_init() } @@ -1212,6 +1230,7 @@ func file_controller_servers_services_v1_session_service_proto_init() { if File_controller_servers_services_v1_session_service_proto != nil { return } + file_controller_servers_services_v1_credential_proto_init() file_controller_servers_services_v1_server_coordination_service_proto_init() if !protoimpl.UnsafeEnabled { file_controller_servers_services_v1_session_service_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { diff --git a/internal/gen/controller/servers/services/session_service_grpc.pb.go b/internal/gen/controller/servers/services/session_service_grpc.pb.go index ab0a6d5deb..f089a26fde 100644 --- a/internal/gen/controller/servers/services/session_service_grpc.pb.go +++ b/internal/gen/controller/servers/services/session_service_grpc.pb.go @@ -18,7 +18,7 @@ const _ = grpc.SupportPackageIsVersion7 // // 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. type SessionServiceClient interface { - // GetSession allows a worker to retrieve session information from the + // LookupSession allows a worker to retrieve session information from the // controller. LookupSession(ctx context.Context, in *LookupSessionRequest, opts ...grpc.CallOption) (*LookupSessionResponse, error) // ActivateSession allows a worker to activate a session on a controller. @@ -99,7 +99,7 @@ func (c *sessionServiceClient) CloseConnection(ctx context.Context, in *CloseCon // All implementations must embed UnimplementedSessionServiceServer // for forward compatibility type SessionServiceServer interface { - // GetSession allows a worker to retrieve session information from the + // LookupSession allows a worker to retrieve session information from the // controller. LookupSession(context.Context, *LookupSessionRequest) (*LookupSessionResponse, error) // ActivateSession allows a worker to activate a session on a controller. diff --git a/internal/proto/local/controller/servers/services/v1/credential.proto b/internal/proto/local/controller/servers/services/v1/credential.proto new file mode 100644 index 0000000000..74fb6d5a09 --- /dev/null +++ b/internal/proto/local/controller/servers/services/v1/credential.proto @@ -0,0 +1,20 @@ +syntax = "proto3"; + +package controller.servers.services.v1; + +option go_package = "github.com/hashicorp/boundary/internal/gen/controller/servers/services;services"; + +message Credential { + oneof credential { + UserPassword user_password = 1; + } +} + +// UserPassword is a credential containing a username and a password. +message UserPassword { + // The username of the credential + string username = 10; // @gotags: `class:"public"` + + // The password of the credential + string password = 20; // @gotags: `class:"secret"` +} diff --git a/internal/proto/local/controller/servers/services/v1/session_service.proto b/internal/proto/local/controller/servers/services/v1/session_service.proto index ab1cafbdc1..248456207f 100644 --- a/internal/proto/local/controller/servers/services/v1/session_service.proto +++ b/internal/proto/local/controller/servers/services/v1/session_service.proto @@ -6,10 +6,11 @@ option go_package = "github.com/hashicorp/boundary/internal/gen/controller/serve import "google/protobuf/timestamp.proto"; import "controller/api/resources/targets/v1/target.proto"; +import "controller/servers/services/v1/credential.proto"; import "controller/servers/services/v1/server_coordination_service.proto"; service SessionService { - // GetSession allows a worker to retrieve session information from the + // LookupSession allows a worker to retrieve session information from the // controller. rpc LookupSession(LookupSessionRequest) returns (LookupSessionResponse) {} @@ -52,6 +53,7 @@ message LookupSessionResponse { string host_set_id = 100; // @gotags: `class:"public"` string target_id = 110; // @gotags: `class:"public"` string user_id = 120; // @gotags: `class:"public"` + repeated Credential credentials = 130; // @gotags: `class:"secret"` } message ActivateSessionRequest { diff --git a/internal/servers/controller/handlers/targets/target_service.go b/internal/servers/controller/handlers/targets/target_service.go index 7b91c6f221..bfcd70b431 100644 --- a/internal/servers/controller/handlers/targets/target_service.go +++ b/internal/servers/controller/handlers/targets/target_service.go @@ -16,6 +16,7 @@ import ( "github.com/hashicorp/boundary/internal/db/timestamp" "github.com/hashicorp/boundary/internal/errors" pbs "github.com/hashicorp/boundary/internal/gen/controller/api/services" + serverpb "github.com/hashicorp/boundary/internal/gen/controller/servers/services" "github.com/hashicorp/boundary/internal/host" "github.com/hashicorp/boundary/internal/host/plugin" "github.com/hashicorp/boundary/internal/host/static" @@ -1063,52 +1064,78 @@ func (s Service) AuthorizeSession(ctx context.Context, req *pbs.AuthorizeSession } var creds []*pb.SessionCredential + var workerCreds []session.Credential for _, c := range cs { - l := c.Library() - secret := c.Secret() - // TODO: Access the json directly from the vault response instead of re-marshalling it. - jSecret, err := json.Marshal(secret) - if err != nil { - return nil, errors.Wrap(ctx, err, op, errors.WithMsg("marshalling secret to json")) - } - var sSecret *structpb.Struct - switch secret.(type) { - case map[string]interface{}: - // In this case we actually have to re-decode it. The proto wrappers - // choke on json.Number and at the time I'm writing this I don't - // have time to write a walk function to dig through with reflect - // and find all json.Numbers and replace them. So we eat the - // inefficiency. So note that we are specifically _not_ using a - // decoder with UseNumber here. - var dSecret map[string]interface{} - if err := json.Unmarshal(jSecret, &dSecret); err != nil { - return nil, errors.Wrap(ctx, err, op, errors.WithMsg("decoding json for proto marshaling")) + switch c.Purpose() { + case credential.EgressPurpose: + m, err := credentialToProto(ctx, c) + if err != nil { + return nil, errors.Wrap(ctx, err, op) } - sSecret, err = structpb.NewStruct(dSecret) + data, err := proto.Marshal(m) if err != nil { - return nil, errors.Wrap(ctx, err, op, errors.WithMsg("creating proto struct for secret")) + return nil, errors.Wrap(ctx, err, op, errors.WithMsg("marshalling secret to proto")) } + workerCreds = append(workerCreds, data) + + case credential.ApplicationPurpose: + l := c.Library() + secret := c.Secret() + // TODO: Access the json directly from the vault response instead of re-marshalling it. + jSecret, err := json.Marshal(secret) + if err != nil { + return nil, errors.Wrap(ctx, err, op, errors.WithMsg("marshalling secret to json")) + } + var sSecret *structpb.Struct + switch secret.(type) { + case map[string]interface{}: + // In this case we actually have to re-decode it. The proto wrappers + // choke on json.Number and at the time I'm writing this I don't + // have time to write a walk function to dig through with reflect + // and find all json.Numbers and replace them. So we eat the + // inefficiency. So note that we are specifically _not_ using a + // decoder with UseNumber here. + var dSecret map[string]interface{} + if err := json.Unmarshal(jSecret, &dSecret); err != nil { + return nil, errors.Wrap(ctx, err, op, errors.WithMsg("decoding json for proto marshaling")) + } + sSecret, err = structpb.NewStruct(dSecret) + if err != nil { + return nil, errors.Wrap(ctx, err, op, errors.WithMsg("creating proto struct for secret")) + } + } + creds = append(creds, &pb.SessionCredential{ + CredentialLibrary: &pb.CredentialLibrary{ + Id: l.GetPublicId(), + Name: l.GetName(), + Description: l.GetDescription(), + CredentialStoreId: l.GetStoreId(), + Type: credential.SubtypeFromId(l.GetPublicId()).String(), + }, + CredentialSource: &pb.CredentialSource{ + Id: l.GetPublicId(), + Name: l.GetName(), + Description: l.GetDescription(), + CredentialStoreId: l.GetStoreId(), + Type: credential.SubtypeFromId(l.GetPublicId()).String(), + }, + Secret: &pb.SessionSecret{ + Raw: base64.StdEncoding.EncodeToString(jSecret), + Decoded: sSecret, + }, + }) + + default: + return nil, errors.New(ctx, errors.Unknown, op, fmt.Sprintf("unsupported credential purpose %s", c.Purpose())) + } + } + + if len(workerCreds) > 0 { + // store credentials in repo, worker will request creds when a connection is established + err = sessionRepo.AddSessionCredentials(ctx, sess.ScopeId, sess.PublicId, workerCreds) + if err != nil { + return nil, errors.Wrap(ctx, err, op) } - creds = append(creds, &pb.SessionCredential{ - CredentialLibrary: &pb.CredentialLibrary{ - Id: l.GetPublicId(), - Name: l.GetName(), - Description: l.GetDescription(), - CredentialStoreId: l.GetStoreId(), - Type: credential.SubtypeFromId(l.GetPublicId()).String(), - }, - CredentialSource: &pb.CredentialSource{ - Id: l.GetPublicId(), - Name: l.GetName(), - Description: l.GetDescription(), - CredentialStoreId: l.GetStoreId(), - Type: credential.SubtypeFromId(l.GetPublicId()).String(), - }, - Secret: &pb.SessionSecret{ - Raw: base64.StdEncoding.EncodeToString(jSecret), - Decoded: sSecret, - }, - }) } sad := &pb.SessionAuthorizationData{ @@ -2079,3 +2106,22 @@ func createCredLibs(targetId string, applicationIds, ingressIds, egressIds []str } return credLibs, nil } + +// credentialToProto converts the strongly typed credential.Credential into a known proto.Message. +func credentialToProto(ctx context.Context, cred credential.Credential) (*serverpb.Credential, error) { + const op = "targets.credentialToProto" + switch c := cred.(type) { + case credential.UserPassword: + return &serverpb.Credential{ + Credential: &serverpb.Credential_UserPassword{ + UserPassword: &serverpb.UserPassword{ + Username: c.Username(), + Password: string(c.Password()), + }, + }, + }, nil + + default: + return nil, errors.New(ctx, errors.InvalidParameter, op, fmt.Sprintf("unsupported credential %T", c)) + } +} diff --git a/internal/servers/controller/handlers/workers/worker_service.go b/internal/servers/controller/handlers/workers/worker_service.go index 834d8a78ae..29e250c459 100644 --- a/internal/servers/controller/handlers/workers/worker_service.go +++ b/internal/servers/controller/handlers/workers/worker_service.go @@ -19,6 +19,7 @@ import ( "github.com/hashicorp/go-bexpr" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" + "google.golang.org/protobuf/proto" ) type workerServiceServer struct { @@ -277,6 +278,22 @@ func (ws *workerServiceServer) LookupSession(ctx context.Context, req *pbs.Looku } } + creds, err := sessRepo.ListSessionCredentials(ctx, sessionInfo.ScopeId, sessionInfo.PublicId) + if err != nil { + return &pbs.LookupSessionResponse{}, status.Errorf(codes.Internal, + fmt.Sprintf("Error retrieving session credentials: %s", err)) + } + var workerCreds []*pbs.Credential + for _, c := range creds { + m := &pbs.Credential{} + err = proto.Unmarshal(c, m) + if err != nil { + return &pbs.LookupSessionResponse{}, status.Errorf(codes.Internal, + fmt.Sprintf("Error unmarshaling credentials: %s", err)) + } + workerCreds = append(workerCreds, m) + } + resp := &pbs.LookupSessionResponse{ Authorization: &targets.SessionAuthorizationData{ SessionId: sessionInfo.GetPublicId(), @@ -293,6 +310,7 @@ func (ws *workerServiceServer) LookupSession(ctx context.Context, req *pbs.Looku HostSetId: sessionInfo.HostSetId, TargetId: sessionInfo.TargetId, UserId: sessionInfo.UserId, + Credentials: workerCreds, } if resp.ConnectionsLeft != -1 { resp.ConnectionsLeft -= int32(authzSummary.CurrentConnectionCount) diff --git a/internal/servers/controller/handlers/workers/worker_service_test.go b/internal/servers/controller/handlers/workers/worker_service_test.go new file mode 100644 index 0000000000..50cd2e1a52 --- /dev/null +++ b/internal/servers/controller/handlers/workers/worker_service_test.go @@ -0,0 +1,173 @@ +package workers_test + +import ( + "context" + "sync" + "testing" + + "github.com/google/go-cmp/cmp" + "github.com/google/go-cmp/cmp/cmpopts" + "github.com/hashicorp/boundary/internal/authtoken" + "github.com/hashicorp/boundary/internal/db" + pbs "github.com/hashicorp/boundary/internal/gen/controller/servers/services" + "github.com/hashicorp/boundary/internal/host/static" + "github.com/hashicorp/boundary/internal/iam" + "github.com/hashicorp/boundary/internal/kms" + "github.com/hashicorp/boundary/internal/servers" + "github.com/hashicorp/boundary/internal/servers/controller/handlers/workers" + "github.com/hashicorp/boundary/internal/session" + "github.com/hashicorp/boundary/internal/target" + "github.com/hashicorp/boundary/internal/target/tcp" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "google.golang.org/protobuf/proto" +) + +func TestLookupSession(t *testing.T) { + ctx := context.Background() + conn, _ := db.TestSetup(t, "postgres") + rw := db.New(conn) + wrapper := db.TestWrapper(t) + kms := kms.TestKms(t, conn, wrapper) + org, prj := iam.TestScopes(t, iam.TestRepo(t, conn, wrapper)) + + serversRepoFn := func() (*servers.Repository, error) { + return servers.NewRepository(rw, rw, kms) + } + sessionRepoFn := func() (*session.Repository, error) { + return session.NewRepository(rw, rw, kms) + } + + at := authtoken.TestAuthToken(t, conn, kms, org.GetPublicId()) + uId := at.GetIamUserId() + hc := static.TestCatalogs(t, conn, prj.GetPublicId(), 1)[0] + hs := static.TestSets(t, conn, hc.GetPublicId(), 1)[0] + h := static.TestHosts(t, conn, hc.GetPublicId(), 1)[0] + static.TestSetMembers(t, conn, hs.GetPublicId(), []*static.Host{h}) + tar := tcp.TestTarget(ctx, t, conn, prj.GetPublicId(), "test", target.WithHostSources([]string{hs.GetPublicId()})) + + sess := session.TestSession(t, conn, wrapper, session.ComposedOf{ + UserId: uId, + HostId: h.GetPublicId(), + TargetId: tar.GetPublicId(), + HostSetId: hs.GetPublicId(), + AuthTokenId: at.GetPublicId(), + ScopeId: prj.GetPublicId(), + Endpoint: "tcp://127.0.0.1:22", + }) + + egressSess := session.TestSession(t, conn, wrapper, session.ComposedOf{ + UserId: uId, + HostId: h.GetPublicId(), + TargetId: tar.GetPublicId(), + HostSetId: hs.GetPublicId(), + AuthTokenId: at.GetPublicId(), + ScopeId: prj.GetPublicId(), + Endpoint: "tcp://127.0.0.1:22", + }) + + repo, err := sessionRepoFn() + require.NoError(t, err) + + creds := []*pbs.Credential{ + { + Credential: &pbs.Credential_UserPassword{ + UserPassword: &pbs.UserPassword{ + Username: "username", + Password: "password", + }, + }, + }, + { + Credential: &pbs.Credential_UserPassword{ + UserPassword: &pbs.UserPassword{ + Username: "another-username", + Password: "a different password", + }, + }, + }, + } + + workerCreds := make([]session.Credential, 0, len(creds)) + for _, c := range creds { + data, err := proto.Marshal(c) + require.NoError(t, err) + workerCreds = append(workerCreds, data) + } + err = repo.AddSessionCredentials(ctx, egressSess.ScopeId, egressSess.GetPublicId(), workerCreds) + require.NoError(t, err) + + s := workers.NewWorkerServiceServer(serversRepoFn, sessionRepoFn, new(sync.Map), kms) + require.NotNil(t, s) + + cases := []struct { + name string + wantErr bool + wantErrMsg string + want *pbs.LookupSessionResponse + sessionId string + }{ + { + name: "Invalid session id", + sessionId: "s_fakesession", + wantErr: true, + wantErrMsg: "rpc error: code = PermissionDenied desc = Unknown session ID.", + }, + { + name: "Valid", + sessionId: sess.PublicId, + want: &pbs.LookupSessionResponse{ + ConnectionLimit: 1, + ConnectionsLeft: 1, + Version: 1, + Endpoint: sess.Endpoint, + HostId: sess.HostId, + HostSetId: sess.HostSetId, + TargetId: sess.TargetId, + UserId: sess.UserId, + Status: pbs.SESSIONSTATUS_SESSIONSTATUS_PENDING, + }, + }, + { + name: "Valid-with-egress-creds", + sessionId: egressSess.PublicId, + want: &pbs.LookupSessionResponse{ + ConnectionLimit: 1, + ConnectionsLeft: 1, + Version: 1, + Endpoint: egressSess.Endpoint, + HostId: egressSess.HostId, + HostSetId: egressSess.HostSetId, + TargetId: egressSess.TargetId, + UserId: egressSess.UserId, + Status: pbs.SESSIONSTATUS_SESSIONSTATUS_PENDING, + Credentials: creds, + }, + }, + } + + for _, tc := range cases { + t.Run(tc.name, func(t *testing.T) { + assert, require := assert.New(t), require.New(t) + req := &pbs.LookupSessionRequest{ + SessionId: tc.sessionId, + } + + got, err := s.LookupSession(ctx, req) + if tc.wantErr { + require.Error(err) + assert.Nil(got) + assert.Equal(tc.wantErrMsg, err.Error()) + return + } + assert.Empty( + cmp.Diff( + tc.want, + got, + cmpopts.IgnoreUnexported(pbs.LookupSessionResponse{}, pbs.Credential{}, pbs.UserPassword{}), + cmpopts.IgnoreFields(pbs.LookupSessionResponse{}, "Expiration", "Authorization"), + ), + ) + }) + } +} diff --git a/internal/servers/worker/handler.go b/internal/servers/worker/handler.go index 9809252382..0cdd55629f 100644 --- a/internal/servers/worker/handler.go +++ b/internal/servers/worker/handler.go @@ -93,6 +93,7 @@ func (w *Worker) handleProxy(listenerCfg *listenerutil.ListenerConfig) (http.Han tofuToken := si.LookupSessionResponse.GetTofuToken() version := si.LookupSessionResponse.GetVersion() endpoint := si.LookupSessionResponse.GetEndpoint() + credentials := si.LookupSessionResponse.GetCredentials() sessStatus := si.Status si.RUnlock() @@ -249,7 +250,12 @@ func (w *Worker) handleProxy(listenerCfg *listenerutil.ListenerConfig) (http.Han return } - if err = handleProxyFn(connCtx, conf); err != nil { + var proxyOpts []proxyHandlers.Option + if len(credentials) > 0 { + proxyOpts = append(proxyOpts, proxyHandlers.WithEgressCredentials(credentials)) + } + + if err = handleProxyFn(connCtx, conf, proxyOpts...); err != nil { event.WriteError(ctx, op, err, event.WithInfoMsg("error handling proxy", "session_id", sessionId, "endpoint", endpoint)) if err = conn.Close(websocket.StatusInternalError, "unable to establish proxy"); err != nil { event.WriteError(ctx, op, err, event.WithInfoMsg("error closing client connection")) diff --git a/internal/servers/worker/proxy/options.go b/internal/servers/worker/proxy/options.go index be2d905959..70b21c1fe9 100644 --- a/internal/servers/worker/proxy/options.go +++ b/internal/servers/worker/proxy/options.go @@ -1,7 +1,7 @@ package proxy import ( - "github.com/hashicorp/boundary/internal/credential" + serverpb "github.com/hashicorp/boundary/internal/gen/controller/servers/services" ) // Option - how Options are passed as arguments. @@ -18,7 +18,7 @@ func GetOpts(opt ...Option) Options { // Options = how options are represented type Options struct { - WithEgressCredentials []credential.Credential + WithEgressCredentials []*serverpb.Credential } func getDefaultOptions() Options { @@ -28,7 +28,7 @@ func getDefaultOptions() Options { } // WithEgressCredentials provides an optional egress credentials to use when establishing a proxy -func WithEgressCredentials(creds []credential.Credential) Option { +func WithEgressCredentials(creds []*serverpb.Credential) Option { return func(o *Options) { o.WithEgressCredentials = creds } diff --git a/internal/servers/worker/proxy/options_test.go b/internal/servers/worker/proxy/options_test.go index e5efae64a4..b2fdcf4640 100644 --- a/internal/servers/worker/proxy/options_test.go +++ b/internal/servers/worker/proxy/options_test.go @@ -3,28 +3,27 @@ package proxy import ( "testing" - "github.com/hashicorp/boundary/internal/credential" + serverpb "github.com/hashicorp/boundary/internal/gen/controller/servers/services" "github.com/stretchr/testify/assert" ) -type cred struct { - id string - secret string -} - -func (c cred) GetPublicId() string { return c.id } -func (c cred) Secret() credential.SecretData { return c.secret } - func Test_GetOpts(t *testing.T) { t.Parallel() t.Run("WithEgressCredentials", func(t *testing.T) { assert := assert.New(t) - c := cred{id: "test", secret: "hello"} - opts := GetOpts(WithEgressCredentials([]credential.Credential{c})) + c := &serverpb.Credential{ + Credential: &serverpb.Credential_UserPassword{ + UserPassword: &serverpb.UserPassword{ + Username: "user", + Password: "pass", + }, + }, + } + opts := GetOpts(WithEgressCredentials([]*serverpb.Credential{c})) testOpts := getDefaultOptions() assert.NotEqual(opts, testOpts) - testOpts.WithEgressCredentials = []credential.Credential{c} + testOpts.WithEgressCredentials = []*serverpb.Credential{c} assert.Equal(opts, testOpts) }) }