From c2307ccd04cb47d63cfbeacc415614fa95fb16a1 Mon Sep 17 00:00:00 2001 From: "STeve (Xin) Huang" Date: Wed, 27 May 2026 10:44:32 -0400 Subject: [PATCH] Merge branch 'master' of github.com:gravitational/teleport into STeve/vnet_process_app_https_tunnel (#66451) --- .../vnet/v1/client_application_service.pb.go | 518 ++++++++++-------- lib/tbot/services/beams/vnet_service.go | 71 +-- lib/tbot/services/beams/vnet_service_test.go | 8 +- lib/vnet/app_handler.go | 34 +- lib/vnet/app_handler_test.go | 65 +++ lib/vnet/fqdn_resolver.go | 58 +- lib/vnet/tcp_handler_resolver.go | 34 +- lib/vnet/user_process.go | 11 + lib/vnet/vnet_test.go | 157 +++++- .../vnet/v1/client_application_service.proto | 16 +- 10 files changed, 643 insertions(+), 329 deletions(-) create mode 100644 lib/vnet/app_handler_test.go diff --git a/gen/proto/go/teleport/lib/vnet/v1/client_application_service.pb.go b/gen/proto/go/teleport/lib/vnet/v1/client_application_service.pb.go index 888b7760dcd..e1e36648a43 100644 --- a/gen/proto/go/teleport/lib/vnet/v1/client_application_service.pb.go +++ b/gen/proto/go/teleport/lib/vnet/v1/client_application_service.pb.go @@ -520,6 +520,7 @@ type ResolveFQDNResponse struct { // *ResolveFQDNResponse_MatchedWebApp // *ResolveFQDNResponse_MatchedCluster // *ResolveFQDNResponse_MatchedDatabase + // *ResolveFQDNResponse_MatchedHttpsTunnelApp Match isResolveFQDNResponse_Match `protobuf_oneof:"match"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache @@ -598,6 +599,15 @@ func (x *ResolveFQDNResponse) GetMatchedDatabase() *MatchedDatabase { return nil } +func (x *ResolveFQDNResponse) GetMatchedHttpsTunnelApp() *MatchedHTTPSTunnelApp { + if x != nil { + if x, ok := x.Match.(*ResolveFQDNResponse_MatchedHttpsTunnelApp); ok { + return x.MatchedHttpsTunnelApp + } + } + return nil +} + type isResolveFQDNResponse_Match interface { isResolveFQDNResponse_Match() } @@ -608,7 +618,11 @@ type ResolveFQDNResponse_MatchedTcpApp struct { } type ResolveFQDNResponse_MatchedWebApp struct { - // MatchedWebApp will be set when the query matched a web app. + // MatchedWebApp will be set when the query matched a web app and when app + // HTTPS tunnel is not used. MatchedWebApp signifies that the query matched + // a web app that VNet should not handle. DNS will be forwarded upstream so + // the browser resolves to the proxy's real address and goes through the + // normal web app login flow. MatchedWebApp *MatchedWebApp `protobuf:"bytes,2,opt,name=matched_web_app,json=matchedWebApp,proto3,oneof"` } @@ -624,6 +638,12 @@ type ResolveFQDNResponse_MatchedDatabase struct { MatchedDatabase *MatchedDatabase `protobuf:"bytes,4,opt,name=matched_database,json=matchedDatabase,proto3,oneof"` } +type ResolveFQDNResponse_MatchedHttpsTunnelApp struct { + // MatchedHTTPSTunnelApp will be set when the query matched an app that + // should be tunneled via the HTTPS-in-mTLS ALPN protocol. + MatchedHttpsTunnelApp *MatchedHTTPSTunnelApp `protobuf:"bytes,5,opt,name=matched_https_tunnel_app,json=matchedHttpsTunnelApp,proto3,oneof"` +} + func (*ResolveFQDNResponse_MatchedTcpApp) isResolveFQDNResponse_Match() {} func (*ResolveFQDNResponse_MatchedWebApp) isResolveFQDNResponse_Match() {} @@ -632,6 +652,8 @@ func (*ResolveFQDNResponse_MatchedCluster) isResolveFQDNResponse_Match() {} func (*ResolveFQDNResponse_MatchedDatabase) isResolveFQDNResponse_Match() {} +func (*ResolveFQDNResponse_MatchedHttpsTunnelApp) isResolveFQDNResponse_Match() {} + // MatchedTCPApp holds info about a TCP app that matched a query. type MatchedTCPApp struct { state protoimpl.MessageState `protogen:"open.v1"` @@ -715,6 +737,53 @@ func (*MatchedWebApp) Descriptor() ([]byte, []int) { return file_teleport_lib_vnet_v1_client_application_service_proto_rawDescGZIP(), []int{10} } +// MatchedHTTPSTunnelApp holds info about an app that should be proxied through +// the HTTPS-in-mTLS tunnel. +type MatchedHTTPSTunnelApp struct { + state protoimpl.MessageState `protogen:"open.v1"` + // AppInfo holds all necessary info for making connections to the resolved app. + AppInfo *AppInfo `protobuf:"bytes,1,opt,name=app_info,json=appInfo,proto3" json:"app_info,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *MatchedHTTPSTunnelApp) Reset() { + *x = MatchedHTTPSTunnelApp{} + mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[11] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *MatchedHTTPSTunnelApp) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MatchedHTTPSTunnelApp) ProtoMessage() {} + +func (x *MatchedHTTPSTunnelApp) ProtoReflect() protoreflect.Message { + mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[11] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use MatchedHTTPSTunnelApp.ProtoReflect.Descriptor instead. +func (*MatchedHTTPSTunnelApp) Descriptor() ([]byte, []int) { + return file_teleport_lib_vnet_v1_client_application_service_proto_rawDescGZIP(), []int{11} +} + +func (x *MatchedHTTPSTunnelApp) GetAppInfo() *AppInfo { + if x != nil { + return x.AppInfo + } + return nil +} + // MatchedCluster holds info about a cluster that a query matched. type MatchedCluster struct { state protoimpl.MessageState `protogen:"open.v1"` @@ -738,7 +807,7 @@ type MatchedCluster struct { func (x *MatchedCluster) Reset() { *x = MatchedCluster{} - mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[11] + mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[12] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -750,7 +819,7 @@ func (x *MatchedCluster) String() string { func (*MatchedCluster) ProtoMessage() {} func (x *MatchedCluster) ProtoReflect() protoreflect.Message { - mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[11] + mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[12] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -763,7 +832,7 @@ func (x *MatchedCluster) ProtoReflect() protoreflect.Message { // Deprecated: Use MatchedCluster.ProtoReflect.Descriptor instead. func (*MatchedCluster) Descriptor() ([]byte, []int) { - return file_teleport_lib_vnet_v1_client_application_service_proto_rawDescGZIP(), []int{11} + return file_teleport_lib_vnet_v1_client_application_service_proto_rawDescGZIP(), []int{12} } func (x *MatchedCluster) GetIpv4CidrRange() string { @@ -824,7 +893,7 @@ type AppInfo struct { func (x *AppInfo) Reset() { *x = AppInfo{} - mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[12] + mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[13] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -836,7 +905,7 @@ func (x *AppInfo) String() string { func (*AppInfo) ProtoMessage() {} func (x *AppInfo) ProtoReflect() protoreflect.Message { - mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[12] + mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[13] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -849,7 +918,7 @@ func (x *AppInfo) ProtoReflect() protoreflect.Message { // Deprecated: Use AppInfo.ProtoReflect.Descriptor instead. func (*AppInfo) Descriptor() ([]byte, []int) { - return file_teleport_lib_vnet_v1_client_application_service_proto_rawDescGZIP(), []int{12} + return file_teleport_lib_vnet_v1_client_application_service_proto_rawDescGZIP(), []int{13} } func (x *AppInfo) GetAppKey() *AppKey { @@ -903,7 +972,7 @@ type AppKey struct { func (x *AppKey) Reset() { *x = AppKey{} - mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[13] + mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[14] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -915,7 +984,7 @@ func (x *AppKey) String() string { func (*AppKey) ProtoMessage() {} func (x *AppKey) ProtoReflect() protoreflect.Message { - mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[13] + mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[14] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -928,7 +997,7 @@ func (x *AppKey) ProtoReflect() protoreflect.Message { // Deprecated: Use AppKey.ProtoReflect.Descriptor instead. func (*AppKey) Descriptor() ([]byte, []int) { - return file_teleport_lib_vnet_v1_client_application_service_proto_rawDescGZIP(), []int{13} + return file_teleport_lib_vnet_v1_client_application_service_proto_rawDescGZIP(), []int{14} } func (x *AppKey) GetProfile() string { @@ -974,7 +1043,7 @@ type DialOptions struct { func (x *DialOptions) Reset() { *x = DialOptions{} - mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[14] + mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[15] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -986,7 +1055,7 @@ func (x *DialOptions) String() string { func (*DialOptions) ProtoMessage() {} func (x *DialOptions) ProtoReflect() protoreflect.Message { - mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[14] + mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[15] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -999,7 +1068,7 @@ func (x *DialOptions) ProtoReflect() protoreflect.Message { // Deprecated: Use DialOptions.ProtoReflect.Descriptor instead. func (*DialOptions) Descriptor() ([]byte, []int) { - return file_teleport_lib_vnet_v1_client_application_service_proto_rawDescGZIP(), []int{14} + return file_teleport_lib_vnet_v1_client_application_service_proto_rawDescGZIP(), []int{15} } func (x *DialOptions) GetWebProxyAddr() string { @@ -1051,7 +1120,7 @@ type ReissueAppCertRequest struct { func (x *ReissueAppCertRequest) Reset() { *x = ReissueAppCertRequest{} - mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[15] + mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[16] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1063,7 +1132,7 @@ func (x *ReissueAppCertRequest) String() string { func (*ReissueAppCertRequest) ProtoMessage() {} func (x *ReissueAppCertRequest) ProtoReflect() protoreflect.Message { - mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[15] + mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[16] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1076,7 +1145,7 @@ func (x *ReissueAppCertRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ReissueAppCertRequest.ProtoReflect.Descriptor instead. func (*ReissueAppCertRequest) Descriptor() ([]byte, []int) { - return file_teleport_lib_vnet_v1_client_application_service_proto_rawDescGZIP(), []int{15} + return file_teleport_lib_vnet_v1_client_application_service_proto_rawDescGZIP(), []int{16} } func (x *ReissueAppCertRequest) GetAppInfo() *AppInfo { @@ -1104,7 +1173,7 @@ type ReissueAppCertResponse struct { func (x *ReissueAppCertResponse) Reset() { *x = ReissueAppCertResponse{} - mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[16] + mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[17] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1116,7 +1185,7 @@ func (x *ReissueAppCertResponse) String() string { func (*ReissueAppCertResponse) ProtoMessage() {} func (x *ReissueAppCertResponse) ProtoReflect() protoreflect.Message { - mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[16] + mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[17] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1129,7 +1198,7 @@ func (x *ReissueAppCertResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ReissueAppCertResponse.ProtoReflect.Descriptor instead. func (*ReissueAppCertResponse) Descriptor() ([]byte, []int) { - return file_teleport_lib_vnet_v1_client_application_service_proto_rawDescGZIP(), []int{16} + return file_teleport_lib_vnet_v1_client_application_service_proto_rawDescGZIP(), []int{17} } func (x *ReissueAppCertResponse) GetCert() []byte { @@ -1161,7 +1230,7 @@ type SignForAppRequest struct { func (x *SignForAppRequest) Reset() { *x = SignForAppRequest{} - mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[17] + mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[18] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1173,7 +1242,7 @@ func (x *SignForAppRequest) String() string { func (*SignForAppRequest) ProtoMessage() {} func (x *SignForAppRequest) ProtoReflect() protoreflect.Message { - mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[17] + mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[18] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1186,7 +1255,7 @@ func (x *SignForAppRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use SignForAppRequest.ProtoReflect.Descriptor instead. func (*SignForAppRequest) Descriptor() ([]byte, []int) { - return file_teleport_lib_vnet_v1_client_application_service_proto_rawDescGZIP(), []int{17} + return file_teleport_lib_vnet_v1_client_application_service_proto_rawDescGZIP(), []int{18} } func (x *SignForAppRequest) GetAppKey() *AppKey { @@ -1226,7 +1295,7 @@ type SignRequest struct { func (x *SignRequest) Reset() { *x = SignRequest{} - mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[18] + mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[19] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1238,7 +1307,7 @@ func (x *SignRequest) String() string { func (*SignRequest) ProtoMessage() {} func (x *SignRequest) ProtoReflect() protoreflect.Message { - mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[18] + mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[19] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1251,7 +1320,7 @@ func (x *SignRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use SignRequest.ProtoReflect.Descriptor instead. func (*SignRequest) Descriptor() ([]byte, []int) { - return file_teleport_lib_vnet_v1_client_application_service_proto_rawDescGZIP(), []int{18} + return file_teleport_lib_vnet_v1_client_application_service_proto_rawDescGZIP(), []int{19} } func (x *SignRequest) GetDigest() []byte { @@ -1286,7 +1355,7 @@ type SignForAppResponse struct { func (x *SignForAppResponse) Reset() { *x = SignForAppResponse{} - mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[19] + mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[20] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1298,7 +1367,7 @@ func (x *SignForAppResponse) String() string { func (*SignForAppResponse) ProtoMessage() {} func (x *SignForAppResponse) ProtoReflect() protoreflect.Message { - mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[19] + mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[20] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1311,7 +1380,7 @@ func (x *SignForAppResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use SignForAppResponse.ProtoReflect.Descriptor instead. func (*SignForAppResponse) Descriptor() ([]byte, []int) { - return file_teleport_lib_vnet_v1_client_application_service_proto_rawDescGZIP(), []int{19} + return file_teleport_lib_vnet_v1_client_application_service_proto_rawDescGZIP(), []int{20} } func (x *SignForAppResponse) GetSignature() []byte { @@ -1332,7 +1401,7 @@ type OnNewAppConnectionRequest struct { func (x *OnNewAppConnectionRequest) Reset() { *x = OnNewAppConnectionRequest{} - mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[20] + mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[21] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1344,7 +1413,7 @@ func (x *OnNewAppConnectionRequest) String() string { func (*OnNewAppConnectionRequest) ProtoMessage() {} func (x *OnNewAppConnectionRequest) ProtoReflect() protoreflect.Message { - mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[20] + mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[21] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1357,7 +1426,7 @@ func (x *OnNewAppConnectionRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use OnNewAppConnectionRequest.ProtoReflect.Descriptor instead. func (*OnNewAppConnectionRequest) Descriptor() ([]byte, []int) { - return file_teleport_lib_vnet_v1_client_application_service_proto_rawDescGZIP(), []int{20} + return file_teleport_lib_vnet_v1_client_application_service_proto_rawDescGZIP(), []int{21} } func (x *OnNewAppConnectionRequest) GetAppKey() *AppKey { @@ -1376,7 +1445,7 @@ type OnNewAppConnectionResponse struct { func (x *OnNewAppConnectionResponse) Reset() { *x = OnNewAppConnectionResponse{} - mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[21] + mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[22] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1388,7 +1457,7 @@ func (x *OnNewAppConnectionResponse) String() string { func (*OnNewAppConnectionResponse) ProtoMessage() {} func (x *OnNewAppConnectionResponse) ProtoReflect() protoreflect.Message { - mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[21] + mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[22] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1401,7 +1470,7 @@ func (x *OnNewAppConnectionResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use OnNewAppConnectionResponse.ProtoReflect.Descriptor instead. func (*OnNewAppConnectionResponse) Descriptor() ([]byte, []int) { - return file_teleport_lib_vnet_v1_client_application_service_proto_rawDescGZIP(), []int{21} + return file_teleport_lib_vnet_v1_client_application_service_proto_rawDescGZIP(), []int{22} } // OnInvalidLocalPortRequest is a request for OnInvalidLocalPort. @@ -1420,7 +1489,7 @@ type OnInvalidLocalPortRequest struct { func (x *OnInvalidLocalPortRequest) Reset() { *x = OnInvalidLocalPortRequest{} - mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[22] + mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[23] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1432,7 +1501,7 @@ func (x *OnInvalidLocalPortRequest) String() string { func (*OnInvalidLocalPortRequest) ProtoMessage() {} func (x *OnInvalidLocalPortRequest) ProtoReflect() protoreflect.Message { - mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[22] + mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[23] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1445,7 +1514,7 @@ func (x *OnInvalidLocalPortRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use OnInvalidLocalPortRequest.ProtoReflect.Descriptor instead. func (*OnInvalidLocalPortRequest) Descriptor() ([]byte, []int) { - return file_teleport_lib_vnet_v1_client_application_service_proto_rawDescGZIP(), []int{22} + return file_teleport_lib_vnet_v1_client_application_service_proto_rawDescGZIP(), []int{23} } func (x *OnInvalidLocalPortRequest) GetAppInfo() *AppInfo { @@ -1471,7 +1540,7 @@ type OnInvalidLocalPortResponse struct { func (x *OnInvalidLocalPortResponse) Reset() { *x = OnInvalidLocalPortResponse{} - mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[23] + mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[24] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1483,7 +1552,7 @@ func (x *OnInvalidLocalPortResponse) String() string { func (*OnInvalidLocalPortResponse) ProtoMessage() {} func (x *OnInvalidLocalPortResponse) ProtoReflect() protoreflect.Message { - mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[23] + mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[24] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1496,7 +1565,7 @@ func (x *OnInvalidLocalPortResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use OnInvalidLocalPortResponse.ProtoReflect.Descriptor instead. func (*OnInvalidLocalPortResponse) Descriptor() ([]byte, []int) { - return file_teleport_lib_vnet_v1_client_application_service_proto_rawDescGZIP(), []int{23} + return file_teleport_lib_vnet_v1_client_application_service_proto_rawDescGZIP(), []int{24} } // GetTargetOSConfigurationRequest is a request for the target host OS configuration. @@ -1508,7 +1577,7 @@ type GetTargetOSConfigurationRequest struct { func (x *GetTargetOSConfigurationRequest) Reset() { *x = GetTargetOSConfigurationRequest{} - mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[24] + mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[25] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1520,7 +1589,7 @@ func (x *GetTargetOSConfigurationRequest) String() string { func (*GetTargetOSConfigurationRequest) ProtoMessage() {} func (x *GetTargetOSConfigurationRequest) ProtoReflect() protoreflect.Message { - mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[24] + mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[25] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1533,7 +1602,7 @@ func (x *GetTargetOSConfigurationRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetTargetOSConfigurationRequest.ProtoReflect.Descriptor instead. func (*GetTargetOSConfigurationRequest) Descriptor() ([]byte, []int) { - return file_teleport_lib_vnet_v1_client_application_service_proto_rawDescGZIP(), []int{24} + return file_teleport_lib_vnet_v1_client_application_service_proto_rawDescGZIP(), []int{25} } // GetTargetOSConfigurationResponse is a response including the target host OS configuration. @@ -1547,7 +1616,7 @@ type GetTargetOSConfigurationResponse struct { func (x *GetTargetOSConfigurationResponse) Reset() { *x = GetTargetOSConfigurationResponse{} - mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[25] + mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[26] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1559,7 +1628,7 @@ func (x *GetTargetOSConfigurationResponse) String() string { func (*GetTargetOSConfigurationResponse) ProtoMessage() {} func (x *GetTargetOSConfigurationResponse) ProtoReflect() protoreflect.Message { - mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[25] + mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[26] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1572,7 +1641,7 @@ func (x *GetTargetOSConfigurationResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetTargetOSConfigurationResponse.ProtoReflect.Descriptor instead. func (*GetTargetOSConfigurationResponse) Descriptor() ([]byte, []int) { - return file_teleport_lib_vnet_v1_client_application_service_proto_rawDescGZIP(), []int{25} + return file_teleport_lib_vnet_v1_client_application_service_proto_rawDescGZIP(), []int{26} } func (x *GetTargetOSConfigurationResponse) GetTargetOsConfiguration() *TargetOSConfiguration { @@ -1602,7 +1671,7 @@ type TargetOSConfiguration struct { func (x *TargetOSConfiguration) Reset() { *x = TargetOSConfiguration{} - mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[26] + mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[27] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1614,7 +1683,7 @@ func (x *TargetOSConfiguration) String() string { func (*TargetOSConfiguration) ProtoMessage() {} func (x *TargetOSConfiguration) ProtoReflect() protoreflect.Message { - mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[26] + mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[27] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1627,7 +1696,7 @@ func (x *TargetOSConfiguration) ProtoReflect() protoreflect.Message { // Deprecated: Use TargetOSConfiguration.ProtoReflect.Descriptor instead. func (*TargetOSConfiguration) Descriptor() ([]byte, []int) { - return file_teleport_lib_vnet_v1_client_application_service_proto_rawDescGZIP(), []int{26} + return file_teleport_lib_vnet_v1_client_application_service_proto_rawDescGZIP(), []int{27} } func (x *TargetOSConfiguration) GetDnsZones() []string { @@ -1655,7 +1724,7 @@ type UserTLSCertRequest struct { func (x *UserTLSCertRequest) Reset() { *x = UserTLSCertRequest{} - mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[27] + mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[28] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1667,7 +1736,7 @@ func (x *UserTLSCertRequest) String() string { func (*UserTLSCertRequest) ProtoMessage() {} func (x *UserTLSCertRequest) ProtoReflect() protoreflect.Message { - mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[27] + mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[28] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1680,7 +1749,7 @@ func (x *UserTLSCertRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use UserTLSCertRequest.ProtoReflect.Descriptor instead. func (*UserTLSCertRequest) Descriptor() ([]byte, []int) { - return file_teleport_lib_vnet_v1_client_application_service_proto_rawDescGZIP(), []int{27} + return file_teleport_lib_vnet_v1_client_application_service_proto_rawDescGZIP(), []int{28} } func (x *UserTLSCertRequest) GetProfile() string { @@ -1704,7 +1773,7 @@ type UserTLSCertResponse struct { func (x *UserTLSCertResponse) Reset() { *x = UserTLSCertResponse{} - mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[28] + mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[29] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1716,7 +1785,7 @@ func (x *UserTLSCertResponse) String() string { func (*UserTLSCertResponse) ProtoMessage() {} func (x *UserTLSCertResponse) ProtoReflect() protoreflect.Message { - mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[28] + mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[29] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1729,7 +1798,7 @@ func (x *UserTLSCertResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use UserTLSCertResponse.ProtoReflect.Descriptor instead. func (*UserTLSCertResponse) Descriptor() ([]byte, []int) { - return file_teleport_lib_vnet_v1_client_application_service_proto_rawDescGZIP(), []int{28} + return file_teleport_lib_vnet_v1_client_application_service_proto_rawDescGZIP(), []int{29} } func (x *UserTLSCertResponse) GetCert() []byte { @@ -1759,7 +1828,7 @@ type SignForUserTLSRequest struct { func (x *SignForUserTLSRequest) Reset() { *x = SignForUserTLSRequest{} - mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[29] + mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[30] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1771,7 +1840,7 @@ func (x *SignForUserTLSRequest) String() string { func (*SignForUserTLSRequest) ProtoMessage() {} func (x *SignForUserTLSRequest) ProtoReflect() protoreflect.Message { - mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[29] + mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[30] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1784,7 +1853,7 @@ func (x *SignForUserTLSRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use SignForUserTLSRequest.ProtoReflect.Descriptor instead. func (*SignForUserTLSRequest) Descriptor() ([]byte, []int) { - return file_teleport_lib_vnet_v1_client_application_service_proto_rawDescGZIP(), []int{29} + return file_teleport_lib_vnet_v1_client_application_service_proto_rawDescGZIP(), []int{30} } func (x *SignForUserTLSRequest) GetProfile() string { @@ -1812,7 +1881,7 @@ type SignForUserTLSResponse struct { func (x *SignForUserTLSResponse) Reset() { *x = SignForUserTLSResponse{} - mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[30] + mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[31] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1824,7 +1893,7 @@ func (x *SignForUserTLSResponse) String() string { func (*SignForUserTLSResponse) ProtoMessage() {} func (x *SignForUserTLSResponse) ProtoReflect() protoreflect.Message { - mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[30] + mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[31] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1837,7 +1906,7 @@ func (x *SignForUserTLSResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use SignForUserTLSResponse.ProtoReflect.Descriptor instead. func (*SignForUserTLSResponse) Descriptor() ([]byte, []int) { - return file_teleport_lib_vnet_v1_client_application_service_proto_rawDescGZIP(), []int{30} + return file_teleport_lib_vnet_v1_client_application_service_proto_rawDescGZIP(), []int{31} } func (x *SignForUserTLSResponse) GetSignature() []byte { @@ -1869,7 +1938,7 @@ type SessionSSHConfigRequest struct { func (x *SessionSSHConfigRequest) Reset() { *x = SessionSSHConfigRequest{} - mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[31] + mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[32] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1881,7 +1950,7 @@ func (x *SessionSSHConfigRequest) String() string { func (*SessionSSHConfigRequest) ProtoMessage() {} func (x *SessionSSHConfigRequest) ProtoReflect() protoreflect.Message { - mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[31] + mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[32] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1894,7 +1963,7 @@ func (x *SessionSSHConfigRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use SessionSSHConfigRequest.ProtoReflect.Descriptor instead. func (*SessionSSHConfigRequest) Descriptor() ([]byte, []int) { - return file_teleport_lib_vnet_v1_client_application_service_proto_rawDescGZIP(), []int{31} + return file_teleport_lib_vnet_v1_client_application_service_proto_rawDescGZIP(), []int{32} } func (x *SessionSSHConfigRequest) GetProfile() string { @@ -1957,7 +2026,7 @@ type SessionSSHConfigResponse struct { func (x *SessionSSHConfigResponse) Reset() { *x = SessionSSHConfigResponse{} - mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[32] + mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[33] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1969,7 +2038,7 @@ func (x *SessionSSHConfigResponse) String() string { func (*SessionSSHConfigResponse) ProtoMessage() {} func (x *SessionSSHConfigResponse) ProtoReflect() protoreflect.Message { - mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[32] + mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[33] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1982,7 +2051,7 @@ func (x *SessionSSHConfigResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use SessionSSHConfigResponse.ProtoReflect.Descriptor instead. func (*SessionSSHConfigResponse) Descriptor() ([]byte, []int) { - return file_teleport_lib_vnet_v1_client_application_service_proto_rawDescGZIP(), []int{32} + return file_teleport_lib_vnet_v1_client_application_service_proto_rawDescGZIP(), []int{33} } func (x *SessionSSHConfigResponse) GetSessionId() string { @@ -2020,7 +2089,7 @@ type SignForSSHSessionRequest struct { func (x *SignForSSHSessionRequest) Reset() { *x = SignForSSHSessionRequest{} - mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[33] + mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[34] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2032,7 +2101,7 @@ func (x *SignForSSHSessionRequest) String() string { func (*SignForSSHSessionRequest) ProtoMessage() {} func (x *SignForSSHSessionRequest) ProtoReflect() protoreflect.Message { - mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[33] + mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[34] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2045,7 +2114,7 @@ func (x *SignForSSHSessionRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use SignForSSHSessionRequest.ProtoReflect.Descriptor instead. func (*SignForSSHSessionRequest) Descriptor() ([]byte, []int) { - return file_teleport_lib_vnet_v1_client_application_service_proto_rawDescGZIP(), []int{33} + return file_teleport_lib_vnet_v1_client_application_service_proto_rawDescGZIP(), []int{34} } func (x *SignForSSHSessionRequest) GetSessionId() string { @@ -2073,7 +2142,7 @@ type SignForSSHSessionResponse struct { func (x *SignForSSHSessionResponse) Reset() { *x = SignForSSHSessionResponse{} - mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[34] + mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[35] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2085,7 +2154,7 @@ func (x *SignForSSHSessionResponse) String() string { func (*SignForSSHSessionResponse) ProtoMessage() {} func (x *SignForSSHSessionResponse) ProtoReflect() protoreflect.Message { - mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[34] + mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[35] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2098,7 +2167,7 @@ func (x *SignForSSHSessionResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use SignForSSHSessionResponse.ProtoReflect.Descriptor instead. func (*SignForSSHSessionResponse) Descriptor() ([]byte, []int) { - return file_teleport_lib_vnet_v1_client_application_service_proto_rawDescGZIP(), []int{34} + return file_teleport_lib_vnet_v1_client_application_service_proto_rawDescGZIP(), []int{35} } func (x *SignForSSHSessionResponse) GetSignature() []byte { @@ -2120,7 +2189,7 @@ type ExchangeSSHKeysRequest struct { func (x *ExchangeSSHKeysRequest) Reset() { *x = ExchangeSSHKeysRequest{} - mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[35] + mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[36] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2132,7 +2201,7 @@ func (x *ExchangeSSHKeysRequest) String() string { func (*ExchangeSSHKeysRequest) ProtoMessage() {} func (x *ExchangeSSHKeysRequest) ProtoReflect() protoreflect.Message { - mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[35] + mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[36] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2145,7 +2214,7 @@ func (x *ExchangeSSHKeysRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ExchangeSSHKeysRequest.ProtoReflect.Descriptor instead. func (*ExchangeSSHKeysRequest) Descriptor() ([]byte, []int) { - return file_teleport_lib_vnet_v1_client_application_service_proto_rawDescGZIP(), []int{35} + return file_teleport_lib_vnet_v1_client_application_service_proto_rawDescGZIP(), []int{36} } func (x *ExchangeSSHKeysRequest) GetHostPublicKey() []byte { @@ -2167,7 +2236,7 @@ type ExchangeSSHKeysResponse struct { func (x *ExchangeSSHKeysResponse) Reset() { *x = ExchangeSSHKeysResponse{} - mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[36] + mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[37] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2179,7 +2248,7 @@ func (x *ExchangeSSHKeysResponse) String() string { func (*ExchangeSSHKeysResponse) ProtoMessage() {} func (x *ExchangeSSHKeysResponse) ProtoReflect() protoreflect.Message { - mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[36] + mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[37] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2192,7 +2261,7 @@ func (x *ExchangeSSHKeysResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ExchangeSSHKeysResponse.ProtoReflect.Descriptor instead. func (*ExchangeSSHKeysResponse) Descriptor() ([]byte, []int) { - return file_teleport_lib_vnet_v1_client_application_service_proto_rawDescGZIP(), []int{36} + return file_teleport_lib_vnet_v1_client_application_service_proto_rawDescGZIP(), []int{37} } func (x *ExchangeSSHKeysResponse) GetUserPublicKey() []byte { @@ -2217,7 +2286,7 @@ type PerformSessionMFACeremonyRequest struct { func (x *PerformSessionMFACeremonyRequest) Reset() { *x = PerformSessionMFACeremonyRequest{} - mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[37] + mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[38] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2229,7 +2298,7 @@ func (x *PerformSessionMFACeremonyRequest) String() string { func (*PerformSessionMFACeremonyRequest) ProtoMessage() {} func (x *PerformSessionMFACeremonyRequest) ProtoReflect() protoreflect.Message { - mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[37] + mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[38] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2242,7 +2311,7 @@ func (x *PerformSessionMFACeremonyRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use PerformSessionMFACeremonyRequest.ProtoReflect.Descriptor instead. func (*PerformSessionMFACeremonyRequest) Descriptor() ([]byte, []int) { - return file_teleport_lib_vnet_v1_client_application_service_proto_rawDescGZIP(), []int{37} + return file_teleport_lib_vnet_v1_client_application_service_proto_rawDescGZIP(), []int{38} } func (x *PerformSessionMFACeremonyRequest) GetProfile() string { @@ -2277,7 +2346,7 @@ type PerformSessionMFACeremonyResponse struct { func (x *PerformSessionMFACeremonyResponse) Reset() { *x = PerformSessionMFACeremonyResponse{} - mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[38] + mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[39] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2289,7 +2358,7 @@ func (x *PerformSessionMFACeremonyResponse) String() string { func (*PerformSessionMFACeremonyResponse) ProtoMessage() {} func (x *PerformSessionMFACeremonyResponse) ProtoReflect() protoreflect.Message { - mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[38] + mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[39] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2302,7 +2371,7 @@ func (x *PerformSessionMFACeremonyResponse) ProtoReflect() protoreflect.Message // Deprecated: Use PerformSessionMFACeremonyResponse.ProtoReflect.Descriptor instead. func (*PerformSessionMFACeremonyResponse) Descriptor() ([]byte, []int) { - return file_teleport_lib_vnet_v1_client_application_service_proto_rawDescGZIP(), []int{38} + return file_teleport_lib_vnet_v1_client_application_service_proto_rawDescGZIP(), []int{39} } func (x *PerformSessionMFACeremonyResponse) GetChallengeName() string { @@ -2323,7 +2392,7 @@ type MatchedDatabase struct { func (x *MatchedDatabase) Reset() { *x = MatchedDatabase{} - mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[39] + mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[40] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2335,7 +2404,7 @@ func (x *MatchedDatabase) String() string { func (*MatchedDatabase) ProtoMessage() {} func (x *MatchedDatabase) ProtoReflect() protoreflect.Message { - mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[39] + mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[40] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2348,7 +2417,7 @@ func (x *MatchedDatabase) ProtoReflect() protoreflect.Message { // Deprecated: Use MatchedDatabase.ProtoReflect.Descriptor instead. func (*MatchedDatabase) Descriptor() ([]byte, []int) { - return file_teleport_lib_vnet_v1_client_application_service_proto_rawDescGZIP(), []int{39} + return file_teleport_lib_vnet_v1_client_application_service_proto_rawDescGZIP(), []int{40} } func (x *MatchedDatabase) GetDatabaseInfo() *DatabaseInfo { @@ -2380,7 +2449,7 @@ type DatabaseInfo struct { func (x *DatabaseInfo) Reset() { *x = DatabaseInfo{} - mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[40] + mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[41] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2392,7 +2461,7 @@ func (x *DatabaseInfo) String() string { func (*DatabaseInfo) ProtoMessage() {} func (x *DatabaseInfo) ProtoReflect() protoreflect.Message { - mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[40] + mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[41] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2405,7 +2474,7 @@ func (x *DatabaseInfo) ProtoReflect() protoreflect.Message { // Deprecated: Use DatabaseInfo.ProtoReflect.Descriptor instead. func (*DatabaseInfo) Descriptor() ([]byte, []int) { - return file_teleport_lib_vnet_v1_client_application_service_proto_rawDescGZIP(), []int{40} + return file_teleport_lib_vnet_v1_client_application_service_proto_rawDescGZIP(), []int{41} } func (x *DatabaseInfo) GetDatabaseKey() *DatabaseKey { @@ -2459,7 +2528,7 @@ type DatabaseKey struct { func (x *DatabaseKey) Reset() { *x = DatabaseKey{} - mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[41] + mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[42] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2471,7 +2540,7 @@ func (x *DatabaseKey) String() string { func (*DatabaseKey) ProtoMessage() {} func (x *DatabaseKey) ProtoReflect() protoreflect.Message { - mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[41] + mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[42] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2484,7 +2553,7 @@ func (x *DatabaseKey) ProtoReflect() protoreflect.Message { // Deprecated: Use DatabaseKey.ProtoReflect.Descriptor instead. func (*DatabaseKey) Descriptor() ([]byte, []int) { - return file_teleport_lib_vnet_v1_client_application_service_proto_rawDescGZIP(), []int{41} + return file_teleport_lib_vnet_v1_client_application_service_proto_rawDescGZIP(), []int{42} } func (x *DatabaseKey) GetProfile() string { @@ -2520,7 +2589,7 @@ type ReissueDBCertRequest struct { func (x *ReissueDBCertRequest) Reset() { *x = ReissueDBCertRequest{} - mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[42] + mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[43] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2532,7 +2601,7 @@ func (x *ReissueDBCertRequest) String() string { func (*ReissueDBCertRequest) ProtoMessage() {} func (x *ReissueDBCertRequest) ProtoReflect() protoreflect.Message { - mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[42] + mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[43] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2545,7 +2614,7 @@ func (x *ReissueDBCertRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ReissueDBCertRequest.ProtoReflect.Descriptor instead. func (*ReissueDBCertRequest) Descriptor() ([]byte, []int) { - return file_teleport_lib_vnet_v1_client_application_service_proto_rawDescGZIP(), []int{42} + return file_teleport_lib_vnet_v1_client_application_service_proto_rawDescGZIP(), []int{43} } func (x *ReissueDBCertRequest) GetDatabaseInfo() *DatabaseInfo { @@ -2566,7 +2635,7 @@ type ReissueDBCertResponse struct { func (x *ReissueDBCertResponse) Reset() { *x = ReissueDBCertResponse{} - mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[43] + mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[44] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2578,7 +2647,7 @@ func (x *ReissueDBCertResponse) String() string { func (*ReissueDBCertResponse) ProtoMessage() {} func (x *ReissueDBCertResponse) ProtoReflect() protoreflect.Message { - mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[43] + mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[44] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2591,7 +2660,7 @@ func (x *ReissueDBCertResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ReissueDBCertResponse.ProtoReflect.Descriptor instead. func (*ReissueDBCertResponse) Descriptor() ([]byte, []int) { - return file_teleport_lib_vnet_v1_client_application_service_proto_rawDescGZIP(), []int{43} + return file_teleport_lib_vnet_v1_client_application_service_proto_rawDescGZIP(), []int{44} } func (x *ReissueDBCertResponse) GetCert() []byte { @@ -2618,7 +2687,7 @@ type SignForDBRequest struct { func (x *SignForDBRequest) Reset() { *x = SignForDBRequest{} - mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[44] + mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[45] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2630,7 +2699,7 @@ func (x *SignForDBRequest) String() string { func (*SignForDBRequest) ProtoMessage() {} func (x *SignForDBRequest) ProtoReflect() protoreflect.Message { - mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[44] + mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[45] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2643,7 +2712,7 @@ func (x *SignForDBRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use SignForDBRequest.ProtoReflect.Descriptor instead. func (*SignForDBRequest) Descriptor() ([]byte, []int) { - return file_teleport_lib_vnet_v1_client_application_service_proto_rawDescGZIP(), []int{44} + return file_teleport_lib_vnet_v1_client_application_service_proto_rawDescGZIP(), []int{45} } func (x *SignForDBRequest) GetDatabaseKey() *DatabaseKey { @@ -2671,7 +2740,7 @@ type SignForDBResponse struct { func (x *SignForDBResponse) Reset() { *x = SignForDBResponse{} - mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[45] + mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[46] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2683,7 +2752,7 @@ func (x *SignForDBResponse) String() string { func (*SignForDBResponse) ProtoMessage() {} func (x *SignForDBResponse) ProtoReflect() protoreflect.Message { - mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[45] + mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[46] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2696,7 +2765,7 @@ func (x *SignForDBResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use SignForDBResponse.ProtoReflect.Descriptor instead. func (*SignForDBResponse) Descriptor() ([]byte, []int) { - return file_teleport_lib_vnet_v1_client_application_service_proto_rawDescGZIP(), []int{45} + return file_teleport_lib_vnet_v1_client_application_service_proto_rawDescGZIP(), []int{46} } func (x *SignForDBResponse) GetSignature() []byte { @@ -2717,7 +2786,7 @@ type OnNewDBConnectionRequest struct { func (x *OnNewDBConnectionRequest) Reset() { *x = OnNewDBConnectionRequest{} - mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[46] + mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[47] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2729,7 +2798,7 @@ func (x *OnNewDBConnectionRequest) String() string { func (*OnNewDBConnectionRequest) ProtoMessage() {} func (x *OnNewDBConnectionRequest) ProtoReflect() protoreflect.Message { - mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[46] + mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[47] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2742,7 +2811,7 @@ func (x *OnNewDBConnectionRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use OnNewDBConnectionRequest.ProtoReflect.Descriptor instead. func (*OnNewDBConnectionRequest) Descriptor() ([]byte, []int) { - return file_teleport_lib_vnet_v1_client_application_service_proto_rawDescGZIP(), []int{46} + return file_teleport_lib_vnet_v1_client_application_service_proto_rawDescGZIP(), []int{47} } func (x *OnNewDBConnectionRequest) GetDatabaseKey() *DatabaseKey { @@ -2761,7 +2830,7 @@ type OnNewDBConnectionResponse struct { func (x *OnNewDBConnectionResponse) Reset() { *x = OnNewDBConnectionResponse{} - mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[47] + mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[48] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2773,7 +2842,7 @@ func (x *OnNewDBConnectionResponse) String() string { func (*OnNewDBConnectionResponse) ProtoMessage() {} func (x *OnNewDBConnectionResponse) ProtoReflect() protoreflect.Message { - mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[47] + mi := &file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[48] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2786,7 +2855,7 @@ func (x *OnNewDBConnectionResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use OnNewDBConnectionResponse.ProtoReflect.Descriptor instead. func (*OnNewDBConnectionResponse) Descriptor() ([]byte, []int) { - return file_teleport_lib_vnet_v1_client_application_service_proto_rawDescGZIP(), []int{47} + return file_teleport_lib_vnet_v1_client_application_service_proto_rawDescGZIP(), []int{48} } var File_teleport_lib_vnet_v1_client_application_service_proto protoreflect.FileDescriptor @@ -2809,16 +2878,19 @@ const file_teleport_lib_vnet_v1_client_application_service_proto_rawDesc = "" + "\vPingRequest\"\x0e\n" + "\fPingResponse\"(\n" + "\x12ResolveFQDNRequest\x12\x12\n" + - "\x04fqdn\x18\x01 \x01(\tR\x04fqdn\"\xe1\x02\n" + + "\x04fqdn\x18\x01 \x01(\tR\x04fqdn\"\xc9\x03\n" + "\x13ResolveFQDNResponse\x12M\n" + "\x0fmatched_tcp_app\x18\x01 \x01(\v2#.teleport.lib.vnet.v1.MatchedTCPAppH\x00R\rmatchedTcpApp\x12M\n" + "\x0fmatched_web_app\x18\x02 \x01(\v2#.teleport.lib.vnet.v1.MatchedWebAppH\x00R\rmatchedWebApp\x12O\n" + "\x0fmatched_cluster\x18\x03 \x01(\v2$.teleport.lib.vnet.v1.MatchedClusterH\x00R\x0ematchedCluster\x12R\n" + - "\x10matched_database\x18\x04 \x01(\v2%.teleport.lib.vnet.v1.MatchedDatabaseH\x00R\x0fmatchedDatabaseB\a\n" + + "\x10matched_database\x18\x04 \x01(\v2%.teleport.lib.vnet.v1.MatchedDatabaseH\x00R\x0fmatchedDatabase\x12f\n" + + "\x18matched_https_tunnel_app\x18\x05 \x01(\v2+.teleport.lib.vnet.v1.MatchedHTTPSTunnelAppH\x00R\x15matchedHttpsTunnelAppB\a\n" + "\x05match\"I\n" + "\rMatchedTCPApp\x128\n" + "\bapp_info\x18\x01 \x01(\v2\x1d.teleport.lib.vnet.v1.AppInfoR\aappInfo\"\x0f\n" + - "\rMatchedWebApp\"\xbe\x01\n" + + "\rMatchedWebApp\"Q\n" + + "\x15MatchedHTTPSTunnelApp\x128\n" + + "\bapp_info\x18\x01 \x01(\v2\x1d.teleport.lib.vnet.v1.AppInfoR\aappInfo\"\xbe\x01\n" + "\x0eMatchedCluster\x12&\n" + "\x0fipv4_cidr_range\x18\x01 \x01(\tR\ripv4CidrRange\x12$\n" + "\x0eweb_proxy_addr\x18\x02 \x01(\tR\fwebProxyAddr\x12\x18\n" + @@ -2978,7 +3050,7 @@ func file_teleport_lib_vnet_v1_client_application_service_proto_rawDescGZIP() [] } var file_teleport_lib_vnet_v1_client_application_service_proto_enumTypes = make([]protoimpl.EnumInfo, 2) -var file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes = make([]protoimpl.MessageInfo, 48) +var file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes = make([]protoimpl.MessageInfo, 49) var file_teleport_lib_vnet_v1_client_application_service_proto_goTypes = []any{ (Hash)(0), // 0: teleport.lib.vnet.v1.Hash (SessionSSHConfigCredentialMode)(0), // 1: teleport.lib.vnet.v1.SessionSSHConfigCredentialMode @@ -2993,114 +3065,117 @@ var file_teleport_lib_vnet_v1_client_application_service_proto_goTypes = []any{ (*ResolveFQDNResponse)(nil), // 10: teleport.lib.vnet.v1.ResolveFQDNResponse (*MatchedTCPApp)(nil), // 11: teleport.lib.vnet.v1.MatchedTCPApp (*MatchedWebApp)(nil), // 12: teleport.lib.vnet.v1.MatchedWebApp - (*MatchedCluster)(nil), // 13: teleport.lib.vnet.v1.MatchedCluster - (*AppInfo)(nil), // 14: teleport.lib.vnet.v1.AppInfo - (*AppKey)(nil), // 15: teleport.lib.vnet.v1.AppKey - (*DialOptions)(nil), // 16: teleport.lib.vnet.v1.DialOptions - (*ReissueAppCertRequest)(nil), // 17: teleport.lib.vnet.v1.ReissueAppCertRequest - (*ReissueAppCertResponse)(nil), // 18: teleport.lib.vnet.v1.ReissueAppCertResponse - (*SignForAppRequest)(nil), // 19: teleport.lib.vnet.v1.SignForAppRequest - (*SignRequest)(nil), // 20: teleport.lib.vnet.v1.SignRequest - (*SignForAppResponse)(nil), // 21: teleport.lib.vnet.v1.SignForAppResponse - (*OnNewAppConnectionRequest)(nil), // 22: teleport.lib.vnet.v1.OnNewAppConnectionRequest - (*OnNewAppConnectionResponse)(nil), // 23: teleport.lib.vnet.v1.OnNewAppConnectionResponse - (*OnInvalidLocalPortRequest)(nil), // 24: teleport.lib.vnet.v1.OnInvalidLocalPortRequest - (*OnInvalidLocalPortResponse)(nil), // 25: teleport.lib.vnet.v1.OnInvalidLocalPortResponse - (*GetTargetOSConfigurationRequest)(nil), // 26: teleport.lib.vnet.v1.GetTargetOSConfigurationRequest - (*GetTargetOSConfigurationResponse)(nil), // 27: teleport.lib.vnet.v1.GetTargetOSConfigurationResponse - (*TargetOSConfiguration)(nil), // 28: teleport.lib.vnet.v1.TargetOSConfiguration - (*UserTLSCertRequest)(nil), // 29: teleport.lib.vnet.v1.UserTLSCertRequest - (*UserTLSCertResponse)(nil), // 30: teleport.lib.vnet.v1.UserTLSCertResponse - (*SignForUserTLSRequest)(nil), // 31: teleport.lib.vnet.v1.SignForUserTLSRequest - (*SignForUserTLSResponse)(nil), // 32: teleport.lib.vnet.v1.SignForUserTLSResponse - (*SessionSSHConfigRequest)(nil), // 33: teleport.lib.vnet.v1.SessionSSHConfigRequest - (*SessionSSHConfigResponse)(nil), // 34: teleport.lib.vnet.v1.SessionSSHConfigResponse - (*SignForSSHSessionRequest)(nil), // 35: teleport.lib.vnet.v1.SignForSSHSessionRequest - (*SignForSSHSessionResponse)(nil), // 36: teleport.lib.vnet.v1.SignForSSHSessionResponse - (*ExchangeSSHKeysRequest)(nil), // 37: teleport.lib.vnet.v1.ExchangeSSHKeysRequest - (*ExchangeSSHKeysResponse)(nil), // 38: teleport.lib.vnet.v1.ExchangeSSHKeysResponse - (*PerformSessionMFACeremonyRequest)(nil), // 39: teleport.lib.vnet.v1.PerformSessionMFACeremonyRequest - (*PerformSessionMFACeremonyResponse)(nil), // 40: teleport.lib.vnet.v1.PerformSessionMFACeremonyResponse - (*MatchedDatabase)(nil), // 41: teleport.lib.vnet.v1.MatchedDatabase - (*DatabaseInfo)(nil), // 42: teleport.lib.vnet.v1.DatabaseInfo - (*DatabaseKey)(nil), // 43: teleport.lib.vnet.v1.DatabaseKey - (*ReissueDBCertRequest)(nil), // 44: teleport.lib.vnet.v1.ReissueDBCertRequest - (*ReissueDBCertResponse)(nil), // 45: teleport.lib.vnet.v1.ReissueDBCertResponse - (*SignForDBRequest)(nil), // 46: teleport.lib.vnet.v1.SignForDBRequest - (*SignForDBResponse)(nil), // 47: teleport.lib.vnet.v1.SignForDBResponse - (*OnNewDBConnectionRequest)(nil), // 48: teleport.lib.vnet.v1.OnNewDBConnectionRequest - (*OnNewDBConnectionResponse)(nil), // 49: teleport.lib.vnet.v1.OnNewDBConnectionResponse - (*types.AppV3)(nil), // 50: types.AppV3 + (*MatchedHTTPSTunnelApp)(nil), // 13: teleport.lib.vnet.v1.MatchedHTTPSTunnelApp + (*MatchedCluster)(nil), // 14: teleport.lib.vnet.v1.MatchedCluster + (*AppInfo)(nil), // 15: teleport.lib.vnet.v1.AppInfo + (*AppKey)(nil), // 16: teleport.lib.vnet.v1.AppKey + (*DialOptions)(nil), // 17: teleport.lib.vnet.v1.DialOptions + (*ReissueAppCertRequest)(nil), // 18: teleport.lib.vnet.v1.ReissueAppCertRequest + (*ReissueAppCertResponse)(nil), // 19: teleport.lib.vnet.v1.ReissueAppCertResponse + (*SignForAppRequest)(nil), // 20: teleport.lib.vnet.v1.SignForAppRequest + (*SignRequest)(nil), // 21: teleport.lib.vnet.v1.SignRequest + (*SignForAppResponse)(nil), // 22: teleport.lib.vnet.v1.SignForAppResponse + (*OnNewAppConnectionRequest)(nil), // 23: teleport.lib.vnet.v1.OnNewAppConnectionRequest + (*OnNewAppConnectionResponse)(nil), // 24: teleport.lib.vnet.v1.OnNewAppConnectionResponse + (*OnInvalidLocalPortRequest)(nil), // 25: teleport.lib.vnet.v1.OnInvalidLocalPortRequest + (*OnInvalidLocalPortResponse)(nil), // 26: teleport.lib.vnet.v1.OnInvalidLocalPortResponse + (*GetTargetOSConfigurationRequest)(nil), // 27: teleport.lib.vnet.v1.GetTargetOSConfigurationRequest + (*GetTargetOSConfigurationResponse)(nil), // 28: teleport.lib.vnet.v1.GetTargetOSConfigurationResponse + (*TargetOSConfiguration)(nil), // 29: teleport.lib.vnet.v1.TargetOSConfiguration + (*UserTLSCertRequest)(nil), // 30: teleport.lib.vnet.v1.UserTLSCertRequest + (*UserTLSCertResponse)(nil), // 31: teleport.lib.vnet.v1.UserTLSCertResponse + (*SignForUserTLSRequest)(nil), // 32: teleport.lib.vnet.v1.SignForUserTLSRequest + (*SignForUserTLSResponse)(nil), // 33: teleport.lib.vnet.v1.SignForUserTLSResponse + (*SessionSSHConfigRequest)(nil), // 34: teleport.lib.vnet.v1.SessionSSHConfigRequest + (*SessionSSHConfigResponse)(nil), // 35: teleport.lib.vnet.v1.SessionSSHConfigResponse + (*SignForSSHSessionRequest)(nil), // 36: teleport.lib.vnet.v1.SignForSSHSessionRequest + (*SignForSSHSessionResponse)(nil), // 37: teleport.lib.vnet.v1.SignForSSHSessionResponse + (*ExchangeSSHKeysRequest)(nil), // 38: teleport.lib.vnet.v1.ExchangeSSHKeysRequest + (*ExchangeSSHKeysResponse)(nil), // 39: teleport.lib.vnet.v1.ExchangeSSHKeysResponse + (*PerformSessionMFACeremonyRequest)(nil), // 40: teleport.lib.vnet.v1.PerformSessionMFACeremonyRequest + (*PerformSessionMFACeremonyResponse)(nil), // 41: teleport.lib.vnet.v1.PerformSessionMFACeremonyResponse + (*MatchedDatabase)(nil), // 42: teleport.lib.vnet.v1.MatchedDatabase + (*DatabaseInfo)(nil), // 43: teleport.lib.vnet.v1.DatabaseInfo + (*DatabaseKey)(nil), // 44: teleport.lib.vnet.v1.DatabaseKey + (*ReissueDBCertRequest)(nil), // 45: teleport.lib.vnet.v1.ReissueDBCertRequest + (*ReissueDBCertResponse)(nil), // 46: teleport.lib.vnet.v1.ReissueDBCertResponse + (*SignForDBRequest)(nil), // 47: teleport.lib.vnet.v1.SignForDBRequest + (*SignForDBResponse)(nil), // 48: teleport.lib.vnet.v1.SignForDBResponse + (*OnNewDBConnectionRequest)(nil), // 49: teleport.lib.vnet.v1.OnNewDBConnectionRequest + (*OnNewDBConnectionResponse)(nil), // 50: teleport.lib.vnet.v1.OnNewDBConnectionResponse + (*types.AppV3)(nil), // 51: types.AppV3 } var file_teleport_lib_vnet_v1_client_application_service_proto_depIdxs = []int32{ 5, // 0: teleport.lib.vnet.v1.ReportNetworkStackInfoRequest.network_stack_info:type_name -> teleport.lib.vnet.v1.NetworkStackInfo 11, // 1: teleport.lib.vnet.v1.ResolveFQDNResponse.matched_tcp_app:type_name -> teleport.lib.vnet.v1.MatchedTCPApp 12, // 2: teleport.lib.vnet.v1.ResolveFQDNResponse.matched_web_app:type_name -> teleport.lib.vnet.v1.MatchedWebApp - 13, // 3: teleport.lib.vnet.v1.ResolveFQDNResponse.matched_cluster:type_name -> teleport.lib.vnet.v1.MatchedCluster - 41, // 4: teleport.lib.vnet.v1.ResolveFQDNResponse.matched_database:type_name -> teleport.lib.vnet.v1.MatchedDatabase - 14, // 5: teleport.lib.vnet.v1.MatchedTCPApp.app_info:type_name -> teleport.lib.vnet.v1.AppInfo - 15, // 6: teleport.lib.vnet.v1.AppInfo.app_key:type_name -> teleport.lib.vnet.v1.AppKey - 50, // 7: teleport.lib.vnet.v1.AppInfo.app:type_name -> types.AppV3 - 16, // 8: teleport.lib.vnet.v1.AppInfo.dial_options:type_name -> teleport.lib.vnet.v1.DialOptions - 14, // 9: teleport.lib.vnet.v1.ReissueAppCertRequest.app_info:type_name -> teleport.lib.vnet.v1.AppInfo - 15, // 10: teleport.lib.vnet.v1.SignForAppRequest.app_key:type_name -> teleport.lib.vnet.v1.AppKey - 20, // 11: teleport.lib.vnet.v1.SignForAppRequest.sign:type_name -> teleport.lib.vnet.v1.SignRequest - 0, // 12: teleport.lib.vnet.v1.SignRequest.hash:type_name -> teleport.lib.vnet.v1.Hash - 15, // 13: teleport.lib.vnet.v1.OnNewAppConnectionRequest.app_key:type_name -> teleport.lib.vnet.v1.AppKey - 14, // 14: teleport.lib.vnet.v1.OnInvalidLocalPortRequest.app_info:type_name -> teleport.lib.vnet.v1.AppInfo - 28, // 15: teleport.lib.vnet.v1.GetTargetOSConfigurationResponse.target_os_configuration:type_name -> teleport.lib.vnet.v1.TargetOSConfiguration - 16, // 16: teleport.lib.vnet.v1.UserTLSCertResponse.dial_options:type_name -> teleport.lib.vnet.v1.DialOptions - 20, // 17: teleport.lib.vnet.v1.SignForUserTLSRequest.sign:type_name -> teleport.lib.vnet.v1.SignRequest - 1, // 18: teleport.lib.vnet.v1.SessionSSHConfigRequest.credential_mode:type_name -> teleport.lib.vnet.v1.SessionSSHConfigCredentialMode - 20, // 19: teleport.lib.vnet.v1.SignForSSHSessionRequest.sign:type_name -> teleport.lib.vnet.v1.SignRequest - 42, // 20: teleport.lib.vnet.v1.MatchedDatabase.database_info:type_name -> teleport.lib.vnet.v1.DatabaseInfo - 43, // 21: teleport.lib.vnet.v1.DatabaseInfo.database_key:type_name -> teleport.lib.vnet.v1.DatabaseKey - 16, // 22: teleport.lib.vnet.v1.DatabaseInfo.dial_options:type_name -> teleport.lib.vnet.v1.DialOptions - 42, // 23: teleport.lib.vnet.v1.ReissueDBCertRequest.database_info:type_name -> teleport.lib.vnet.v1.DatabaseInfo - 43, // 24: teleport.lib.vnet.v1.SignForDBRequest.database_key:type_name -> teleport.lib.vnet.v1.DatabaseKey - 20, // 25: teleport.lib.vnet.v1.SignForDBRequest.sign:type_name -> teleport.lib.vnet.v1.SignRequest - 43, // 26: teleport.lib.vnet.v1.OnNewDBConnectionRequest.database_key:type_name -> teleport.lib.vnet.v1.DatabaseKey - 2, // 27: teleport.lib.vnet.v1.ClientApplicationService.AuthenticateProcess:input_type -> teleport.lib.vnet.v1.AuthenticateProcessRequest - 4, // 28: teleport.lib.vnet.v1.ClientApplicationService.ReportNetworkStackInfo:input_type -> teleport.lib.vnet.v1.ReportNetworkStackInfoRequest - 7, // 29: teleport.lib.vnet.v1.ClientApplicationService.Ping:input_type -> teleport.lib.vnet.v1.PingRequest - 9, // 30: teleport.lib.vnet.v1.ClientApplicationService.ResolveFQDN:input_type -> teleport.lib.vnet.v1.ResolveFQDNRequest - 17, // 31: teleport.lib.vnet.v1.ClientApplicationService.ReissueAppCert:input_type -> teleport.lib.vnet.v1.ReissueAppCertRequest - 19, // 32: teleport.lib.vnet.v1.ClientApplicationService.SignForApp:input_type -> teleport.lib.vnet.v1.SignForAppRequest - 22, // 33: teleport.lib.vnet.v1.ClientApplicationService.OnNewAppConnection:input_type -> teleport.lib.vnet.v1.OnNewAppConnectionRequest - 24, // 34: teleport.lib.vnet.v1.ClientApplicationService.OnInvalidLocalPort:input_type -> teleport.lib.vnet.v1.OnInvalidLocalPortRequest - 26, // 35: teleport.lib.vnet.v1.ClientApplicationService.GetTargetOSConfiguration:input_type -> teleport.lib.vnet.v1.GetTargetOSConfigurationRequest - 29, // 36: teleport.lib.vnet.v1.ClientApplicationService.UserTLSCert:input_type -> teleport.lib.vnet.v1.UserTLSCertRequest - 31, // 37: teleport.lib.vnet.v1.ClientApplicationService.SignForUserTLS:input_type -> teleport.lib.vnet.v1.SignForUserTLSRequest - 33, // 38: teleport.lib.vnet.v1.ClientApplicationService.SessionSSHConfig:input_type -> teleport.lib.vnet.v1.SessionSSHConfigRequest - 35, // 39: teleport.lib.vnet.v1.ClientApplicationService.SignForSSHSession:input_type -> teleport.lib.vnet.v1.SignForSSHSessionRequest - 37, // 40: teleport.lib.vnet.v1.ClientApplicationService.ExchangeSSHKeys:input_type -> teleport.lib.vnet.v1.ExchangeSSHKeysRequest - 39, // 41: teleport.lib.vnet.v1.ClientApplicationService.PerformSessionMFACeremony:input_type -> teleport.lib.vnet.v1.PerformSessionMFACeremonyRequest - 44, // 42: teleport.lib.vnet.v1.ClientApplicationService.ReissueDBCert:input_type -> teleport.lib.vnet.v1.ReissueDBCertRequest - 46, // 43: teleport.lib.vnet.v1.ClientApplicationService.SignForDB:input_type -> teleport.lib.vnet.v1.SignForDBRequest - 48, // 44: teleport.lib.vnet.v1.ClientApplicationService.OnNewDBConnection:input_type -> teleport.lib.vnet.v1.OnNewDBConnectionRequest - 3, // 45: teleport.lib.vnet.v1.ClientApplicationService.AuthenticateProcess:output_type -> teleport.lib.vnet.v1.AuthenticateProcessResponse - 6, // 46: teleport.lib.vnet.v1.ClientApplicationService.ReportNetworkStackInfo:output_type -> teleport.lib.vnet.v1.ReportNetworkStackInfoResponse - 8, // 47: teleport.lib.vnet.v1.ClientApplicationService.Ping:output_type -> teleport.lib.vnet.v1.PingResponse - 10, // 48: teleport.lib.vnet.v1.ClientApplicationService.ResolveFQDN:output_type -> teleport.lib.vnet.v1.ResolveFQDNResponse - 18, // 49: teleport.lib.vnet.v1.ClientApplicationService.ReissueAppCert:output_type -> teleport.lib.vnet.v1.ReissueAppCertResponse - 21, // 50: teleport.lib.vnet.v1.ClientApplicationService.SignForApp:output_type -> teleport.lib.vnet.v1.SignForAppResponse - 23, // 51: teleport.lib.vnet.v1.ClientApplicationService.OnNewAppConnection:output_type -> teleport.lib.vnet.v1.OnNewAppConnectionResponse - 25, // 52: teleport.lib.vnet.v1.ClientApplicationService.OnInvalidLocalPort:output_type -> teleport.lib.vnet.v1.OnInvalidLocalPortResponse - 27, // 53: teleport.lib.vnet.v1.ClientApplicationService.GetTargetOSConfiguration:output_type -> teleport.lib.vnet.v1.GetTargetOSConfigurationResponse - 30, // 54: teleport.lib.vnet.v1.ClientApplicationService.UserTLSCert:output_type -> teleport.lib.vnet.v1.UserTLSCertResponse - 32, // 55: teleport.lib.vnet.v1.ClientApplicationService.SignForUserTLS:output_type -> teleport.lib.vnet.v1.SignForUserTLSResponse - 34, // 56: teleport.lib.vnet.v1.ClientApplicationService.SessionSSHConfig:output_type -> teleport.lib.vnet.v1.SessionSSHConfigResponse - 36, // 57: teleport.lib.vnet.v1.ClientApplicationService.SignForSSHSession:output_type -> teleport.lib.vnet.v1.SignForSSHSessionResponse - 38, // 58: teleport.lib.vnet.v1.ClientApplicationService.ExchangeSSHKeys:output_type -> teleport.lib.vnet.v1.ExchangeSSHKeysResponse - 40, // 59: teleport.lib.vnet.v1.ClientApplicationService.PerformSessionMFACeremony:output_type -> teleport.lib.vnet.v1.PerformSessionMFACeremonyResponse - 45, // 60: teleport.lib.vnet.v1.ClientApplicationService.ReissueDBCert:output_type -> teleport.lib.vnet.v1.ReissueDBCertResponse - 47, // 61: teleport.lib.vnet.v1.ClientApplicationService.SignForDB:output_type -> teleport.lib.vnet.v1.SignForDBResponse - 49, // 62: teleport.lib.vnet.v1.ClientApplicationService.OnNewDBConnection:output_type -> teleport.lib.vnet.v1.OnNewDBConnectionResponse - 45, // [45:63] is the sub-list for method output_type - 27, // [27:45] is the sub-list for method input_type - 27, // [27:27] is the sub-list for extension type_name - 27, // [27:27] is the sub-list for extension extendee - 0, // [0:27] is the sub-list for field type_name + 14, // 3: teleport.lib.vnet.v1.ResolveFQDNResponse.matched_cluster:type_name -> teleport.lib.vnet.v1.MatchedCluster + 42, // 4: teleport.lib.vnet.v1.ResolveFQDNResponse.matched_database:type_name -> teleport.lib.vnet.v1.MatchedDatabase + 13, // 5: teleport.lib.vnet.v1.ResolveFQDNResponse.matched_https_tunnel_app:type_name -> teleport.lib.vnet.v1.MatchedHTTPSTunnelApp + 15, // 6: teleport.lib.vnet.v1.MatchedTCPApp.app_info:type_name -> teleport.lib.vnet.v1.AppInfo + 15, // 7: teleport.lib.vnet.v1.MatchedHTTPSTunnelApp.app_info:type_name -> teleport.lib.vnet.v1.AppInfo + 16, // 8: teleport.lib.vnet.v1.AppInfo.app_key:type_name -> teleport.lib.vnet.v1.AppKey + 51, // 9: teleport.lib.vnet.v1.AppInfo.app:type_name -> types.AppV3 + 17, // 10: teleport.lib.vnet.v1.AppInfo.dial_options:type_name -> teleport.lib.vnet.v1.DialOptions + 15, // 11: teleport.lib.vnet.v1.ReissueAppCertRequest.app_info:type_name -> teleport.lib.vnet.v1.AppInfo + 16, // 12: teleport.lib.vnet.v1.SignForAppRequest.app_key:type_name -> teleport.lib.vnet.v1.AppKey + 21, // 13: teleport.lib.vnet.v1.SignForAppRequest.sign:type_name -> teleport.lib.vnet.v1.SignRequest + 0, // 14: teleport.lib.vnet.v1.SignRequest.hash:type_name -> teleport.lib.vnet.v1.Hash + 16, // 15: teleport.lib.vnet.v1.OnNewAppConnectionRequest.app_key:type_name -> teleport.lib.vnet.v1.AppKey + 15, // 16: teleport.lib.vnet.v1.OnInvalidLocalPortRequest.app_info:type_name -> teleport.lib.vnet.v1.AppInfo + 29, // 17: teleport.lib.vnet.v1.GetTargetOSConfigurationResponse.target_os_configuration:type_name -> teleport.lib.vnet.v1.TargetOSConfiguration + 17, // 18: teleport.lib.vnet.v1.UserTLSCertResponse.dial_options:type_name -> teleport.lib.vnet.v1.DialOptions + 21, // 19: teleport.lib.vnet.v1.SignForUserTLSRequest.sign:type_name -> teleport.lib.vnet.v1.SignRequest + 1, // 20: teleport.lib.vnet.v1.SessionSSHConfigRequest.credential_mode:type_name -> teleport.lib.vnet.v1.SessionSSHConfigCredentialMode + 21, // 21: teleport.lib.vnet.v1.SignForSSHSessionRequest.sign:type_name -> teleport.lib.vnet.v1.SignRequest + 43, // 22: teleport.lib.vnet.v1.MatchedDatabase.database_info:type_name -> teleport.lib.vnet.v1.DatabaseInfo + 44, // 23: teleport.lib.vnet.v1.DatabaseInfo.database_key:type_name -> teleport.lib.vnet.v1.DatabaseKey + 17, // 24: teleport.lib.vnet.v1.DatabaseInfo.dial_options:type_name -> teleport.lib.vnet.v1.DialOptions + 43, // 25: teleport.lib.vnet.v1.ReissueDBCertRequest.database_info:type_name -> teleport.lib.vnet.v1.DatabaseInfo + 44, // 26: teleport.lib.vnet.v1.SignForDBRequest.database_key:type_name -> teleport.lib.vnet.v1.DatabaseKey + 21, // 27: teleport.lib.vnet.v1.SignForDBRequest.sign:type_name -> teleport.lib.vnet.v1.SignRequest + 44, // 28: teleport.lib.vnet.v1.OnNewDBConnectionRequest.database_key:type_name -> teleport.lib.vnet.v1.DatabaseKey + 2, // 29: teleport.lib.vnet.v1.ClientApplicationService.AuthenticateProcess:input_type -> teleport.lib.vnet.v1.AuthenticateProcessRequest + 4, // 30: teleport.lib.vnet.v1.ClientApplicationService.ReportNetworkStackInfo:input_type -> teleport.lib.vnet.v1.ReportNetworkStackInfoRequest + 7, // 31: teleport.lib.vnet.v1.ClientApplicationService.Ping:input_type -> teleport.lib.vnet.v1.PingRequest + 9, // 32: teleport.lib.vnet.v1.ClientApplicationService.ResolveFQDN:input_type -> teleport.lib.vnet.v1.ResolveFQDNRequest + 18, // 33: teleport.lib.vnet.v1.ClientApplicationService.ReissueAppCert:input_type -> teleport.lib.vnet.v1.ReissueAppCertRequest + 20, // 34: teleport.lib.vnet.v1.ClientApplicationService.SignForApp:input_type -> teleport.lib.vnet.v1.SignForAppRequest + 23, // 35: teleport.lib.vnet.v1.ClientApplicationService.OnNewAppConnection:input_type -> teleport.lib.vnet.v1.OnNewAppConnectionRequest + 25, // 36: teleport.lib.vnet.v1.ClientApplicationService.OnInvalidLocalPort:input_type -> teleport.lib.vnet.v1.OnInvalidLocalPortRequest + 27, // 37: teleport.lib.vnet.v1.ClientApplicationService.GetTargetOSConfiguration:input_type -> teleport.lib.vnet.v1.GetTargetOSConfigurationRequest + 30, // 38: teleport.lib.vnet.v1.ClientApplicationService.UserTLSCert:input_type -> teleport.lib.vnet.v1.UserTLSCertRequest + 32, // 39: teleport.lib.vnet.v1.ClientApplicationService.SignForUserTLS:input_type -> teleport.lib.vnet.v1.SignForUserTLSRequest + 34, // 40: teleport.lib.vnet.v1.ClientApplicationService.SessionSSHConfig:input_type -> teleport.lib.vnet.v1.SessionSSHConfigRequest + 36, // 41: teleport.lib.vnet.v1.ClientApplicationService.SignForSSHSession:input_type -> teleport.lib.vnet.v1.SignForSSHSessionRequest + 38, // 42: teleport.lib.vnet.v1.ClientApplicationService.ExchangeSSHKeys:input_type -> teleport.lib.vnet.v1.ExchangeSSHKeysRequest + 40, // 43: teleport.lib.vnet.v1.ClientApplicationService.PerformSessionMFACeremony:input_type -> teleport.lib.vnet.v1.PerformSessionMFACeremonyRequest + 45, // 44: teleport.lib.vnet.v1.ClientApplicationService.ReissueDBCert:input_type -> teleport.lib.vnet.v1.ReissueDBCertRequest + 47, // 45: teleport.lib.vnet.v1.ClientApplicationService.SignForDB:input_type -> teleport.lib.vnet.v1.SignForDBRequest + 49, // 46: teleport.lib.vnet.v1.ClientApplicationService.OnNewDBConnection:input_type -> teleport.lib.vnet.v1.OnNewDBConnectionRequest + 3, // 47: teleport.lib.vnet.v1.ClientApplicationService.AuthenticateProcess:output_type -> teleport.lib.vnet.v1.AuthenticateProcessResponse + 6, // 48: teleport.lib.vnet.v1.ClientApplicationService.ReportNetworkStackInfo:output_type -> teleport.lib.vnet.v1.ReportNetworkStackInfoResponse + 8, // 49: teleport.lib.vnet.v1.ClientApplicationService.Ping:output_type -> teleport.lib.vnet.v1.PingResponse + 10, // 50: teleport.lib.vnet.v1.ClientApplicationService.ResolveFQDN:output_type -> teleport.lib.vnet.v1.ResolveFQDNResponse + 19, // 51: teleport.lib.vnet.v1.ClientApplicationService.ReissueAppCert:output_type -> teleport.lib.vnet.v1.ReissueAppCertResponse + 22, // 52: teleport.lib.vnet.v1.ClientApplicationService.SignForApp:output_type -> teleport.lib.vnet.v1.SignForAppResponse + 24, // 53: teleport.lib.vnet.v1.ClientApplicationService.OnNewAppConnection:output_type -> teleport.lib.vnet.v1.OnNewAppConnectionResponse + 26, // 54: teleport.lib.vnet.v1.ClientApplicationService.OnInvalidLocalPort:output_type -> teleport.lib.vnet.v1.OnInvalidLocalPortResponse + 28, // 55: teleport.lib.vnet.v1.ClientApplicationService.GetTargetOSConfiguration:output_type -> teleport.lib.vnet.v1.GetTargetOSConfigurationResponse + 31, // 56: teleport.lib.vnet.v1.ClientApplicationService.UserTLSCert:output_type -> teleport.lib.vnet.v1.UserTLSCertResponse + 33, // 57: teleport.lib.vnet.v1.ClientApplicationService.SignForUserTLS:output_type -> teleport.lib.vnet.v1.SignForUserTLSResponse + 35, // 58: teleport.lib.vnet.v1.ClientApplicationService.SessionSSHConfig:output_type -> teleport.lib.vnet.v1.SessionSSHConfigResponse + 37, // 59: teleport.lib.vnet.v1.ClientApplicationService.SignForSSHSession:output_type -> teleport.lib.vnet.v1.SignForSSHSessionResponse + 39, // 60: teleport.lib.vnet.v1.ClientApplicationService.ExchangeSSHKeys:output_type -> teleport.lib.vnet.v1.ExchangeSSHKeysResponse + 41, // 61: teleport.lib.vnet.v1.ClientApplicationService.PerformSessionMFACeremony:output_type -> teleport.lib.vnet.v1.PerformSessionMFACeremonyResponse + 46, // 62: teleport.lib.vnet.v1.ClientApplicationService.ReissueDBCert:output_type -> teleport.lib.vnet.v1.ReissueDBCertResponse + 48, // 63: teleport.lib.vnet.v1.ClientApplicationService.SignForDB:output_type -> teleport.lib.vnet.v1.SignForDBResponse + 50, // 64: teleport.lib.vnet.v1.ClientApplicationService.OnNewDBConnection:output_type -> teleport.lib.vnet.v1.OnNewDBConnectionResponse + 47, // [47:65] is the sub-list for method output_type + 29, // [29:47] is the sub-list for method input_type + 29, // [29:29] is the sub-list for extension type_name + 29, // [29:29] is the sub-list for extension extendee + 0, // [0:29] is the sub-list for field type_name } func init() { file_teleport_lib_vnet_v1_client_application_service_proto_init() } @@ -3113,15 +3188,16 @@ func file_teleport_lib_vnet_v1_client_application_service_proto_init() { (*ResolveFQDNResponse_MatchedWebApp)(nil), (*ResolveFQDNResponse_MatchedCluster)(nil), (*ResolveFQDNResponse_MatchedDatabase)(nil), + (*ResolveFQDNResponse_MatchedHttpsTunnelApp)(nil), } - file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[18].OneofWrappers = []any{} + file_teleport_lib_vnet_v1_client_application_service_proto_msgTypes[19].OneofWrappers = []any{} type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: unsafe.Slice(unsafe.StringData(file_teleport_lib_vnet_v1_client_application_service_proto_rawDesc), len(file_teleport_lib_vnet_v1_client_application_service_proto_rawDesc)), NumEnums: 2, - NumMessages: 48, + NumMessages: 49, NumExtensions: 0, NumServices: 1, }, diff --git a/lib/tbot/services/beams/vnet_service.go b/lib/tbot/services/beams/vnet_service.go index a084ae1428a..9bc3c8316ef 100644 --- a/lib/tbot/services/beams/vnet_service.go +++ b/lib/tbot/services/beams/vnet_service.go @@ -383,44 +383,7 @@ func (v *vnetApplicationService) ResolveFQDN(ctx context.Context, fqdn string) ( if !ok { return nil, trace.BadParameter("expected *types.AppV3, got %T", rsp.Resources[0].GetApp()) } - if !vnet.IsVNetApp(app) { - v.logger.DebugContext(ctx, "Application protocol not supported by VNet", - "fqdn", fqdn, - "app_name", app.GetName(), - "app_uri", app.GetURI(), - "app_protocol", app.GetProtocol(), - ) - return &vnetv1.ResolveFQDNResponse{}, nil - } - // VNet intentionally doesn't support HTTP apps for a number of reasons. - // - // One such reason is the security risk of untrusted code (e.g. JavaScript - // in a web browser) being able to access arbitrary local services. Browsers - // help to some extent here via the same-origin policy, but cannot reliably - // prevent DNS rebinding attacks for plain HTTP apps. - // - // While the underlying issue remains in the beam sandbox, the risk is more - // acceptable because (1) you can restrict the beam's access to a subset of - // your application via Delegation Sessions, and (2) allowing untrusted code - // and agents to access your Teleport-protected resources is the entire point - // of Beams! by using them you're already accepting a larger security trade- - // off than the browser sandbox normally would. - // - // We make it work by pretending they're actually plain TCP apps: - // - // - The local ALPN proxy will advertise support for the "teleport-tcp" - // protocol in the TLS handshake. - // - // - On the Teleport proxy-side, this protocol is routed to the web server's - // HandleConnection method. - // - // - From there, the connection is handed off to the app handler, which - // determines the protocol from the application *resource* not the ALPN - // protocol. - // - // TODO(boxofrad): Replace this with HTTPS-in-mTLS once RFD 0035e is approved - // and implemented. ca, err := v.clusterAccess(osConfig) if err != nil { return nil, trace.Wrap(err) @@ -436,13 +399,35 @@ func (v *vnetApplicationService) ResolveFQDN(ctx context.Context, fqdn string) ( DialOptions: ca.dialOptions, } - return &vnetv1.ResolveFQDNResponse{ - Match: &vnetv1.ResolveFQDNResponse_MatchedTcpApp{ - MatchedTcpApp: &vnetv1.MatchedTCPApp{ - AppInfo: appInfo, + switch { + case app.IsTCP(): + return &vnetv1.ResolveFQDNResponse{ + Match: &vnetv1.ResolveFQDNResponse_MatchedTcpApp{ + MatchedTcpApp: &vnetv1.MatchedTCPApp{ + AppInfo: appInfo, + }, }, - }, - }, nil + }, nil + case vnet.IsHTTPSTunnelApp(app): + // HTTP and LLM apps are tunneled via the HTTPS-in-mTLS ALPN protocol. + // Browser access via this tunnel is currently disabled on the web app + // handler, which should be fine for common use cases inside beams. + return &vnetv1.ResolveFQDNResponse{ + Match: &vnetv1.ResolveFQDNResponse_MatchedHttpsTunnelApp{ + MatchedHttpsTunnelApp: &vnetv1.MatchedHTTPSTunnelApp{ + AppInfo: appInfo, + }, + }, + }, nil + default: + v.logger.DebugContext(ctx, "Application protocol not supported by VNet", + "fqdn", fqdn, + "app_name", app.GetName(), + "app_uri", app.GetURI(), + "app_protocol", app.GetProtocol(), + ) + return &vnetv1.ResolveFQDNResponse{}, nil + } } // GetAppCert issues a TLS certificate for the given application. diff --git a/lib/tbot/services/beams/vnet_service_test.go b/lib/tbot/services/beams/vnet_service_test.go index 7ab3f5b9b02..bb4cde08871 100644 --- a/lib/tbot/services/beams/vnet_service_test.go +++ b/lib/tbot/services/beams/vnet_service_test.go @@ -246,9 +246,11 @@ func TestVNetService(t *testing.T) { t.Fatal("timeout waiting for host network to be configured") } - // Call the HTTP app over VNet. - client := &http.Client{Transport: hostNetwork.HTTPTransport()} - rsp, err := client.Get("http://intranet.dunder-mifflin.com") + // Call the HTTP app over VNet via the HTTPS tunnel. + transport := hostNetwork.HTTPTransport() + transport.TLSClientConfig = &tls.Config{InsecureSkipVerify: true} + client := &http.Client{Transport: transport} + rsp, err := client.Get("https://intranet.dunder-mifflin.com") require.NoError(t, err) defer rsp.Body.Close() diff --git a/lib/vnet/app_handler.go b/lib/vnet/app_handler.go index 1dd4e1f5816..09ec2c7644d 100644 --- a/lib/vnet/app_handler.go +++ b/lib/vnet/app_handler.go @@ -37,8 +37,8 @@ import ( alpncommon "github.com/gravitational/teleport/lib/srv/alpnproxy/common" ) -type tcpAppHandler struct { - cfg *tcpAppHandlerConfig +type appHandler struct { + cfg *appHandlerConfig log *slog.Logger // mu guards access to portToLocalProxy. @@ -46,8 +46,10 @@ type tcpAppHandler struct { portToLocalProxy map[uint16]*alpnproxy.LocalProxy } -type tcpAppHandlerConfig struct { - appInfo *vnetv1.AppInfo +type appHandlerConfig struct { + appInfo *vnetv1.AppInfo + protocol alpncommon.Protocol + appProvider *appProvider clock clockwork.Clock // alwaysTrustRootClusterCA can be set in tests so that TLS dials to the @@ -56,11 +58,11 @@ type tcpAppHandlerConfig struct { alwaysTrustRootClusterCA bool } -func newTCPAppHandler(cfg *tcpAppHandlerConfig) *tcpAppHandler { - return &tcpAppHandler{ +func newAppHandler(cfg *appHandlerConfig) *appHandler { + return &appHandler{ cfg: cfg, log: log.With( - teleport.ComponentKey, teleport.Component("vnet", "tcp-app-handler"), + teleport.ComponentKey, teleport.Component("vnet", "app-handler"), "profile", cfg.appInfo.GetAppKey().GetProfile(), "leaf_cluster", cfg.appInfo.GetAppKey().GetLeafCluster(), "fqdn", cfg.appInfo.GetApp().GetPublicAddr()), @@ -70,7 +72,7 @@ func newTCPAppHandler(cfg *tcpAppHandlerConfig) *tcpAppHandler { // getOrInitializeLocalProxy returns a separate local proxy for each port for multi-port apps. For // single-port apps, it returns the same local proxy no matter the port. -func (h *tcpAppHandler) getOrInitializeLocalProxy(ctx context.Context, localPort uint16) (*alpnproxy.LocalProxy, error) { +func (h *appHandler) getOrInitializeLocalProxy(ctx context.Context, localPort uint16) (*alpnproxy.LocalProxy, error) { h.mu.Lock() defer h.mu.Unlock() // Connections to single-port apps need to go through a local proxy that has a cert with TargetPort @@ -97,10 +99,10 @@ func (h *tcpAppHandler) getOrInitializeLocalProxy(ctx context.Context, localPort return h.cfg.appProvider.OnNewAppConnection(ctx, h.cfg.appInfo.GetAppKey()) }, } - h.log.DebugContext(ctx, "Creating local proxy", "target_port", localPort) + h.log.DebugContext(ctx, "Creating local proxy", "target_port", localPort, "protocol", h.cfg.protocol) newLP, err := newLocalProxy(localProxyConfig{ dialOptions: h.cfg.appInfo.GetDialOptions(), - protocols: []alpncommon.Protocol{alpncommon.ProtocolTCP}, + protocols: []alpncommon.Protocol{h.cfg.protocol}, parentContext: ctx, middleware: middleware, clock: h.cfg.clock, @@ -115,7 +117,7 @@ func (h *tcpAppHandler) getOrInitializeLocalProxy(ctx context.Context, localPort // handleTCPConnector handles an incoming TCP connection from VNet by passing it to the local alpn proxy, // which is set up with middleware to automatically handle certificate renewal and re-logins. -func (h *tcpAppHandler) handleTCPConnector(ctx context.Context, localPort uint16, connector func() (net.Conn, error)) error { +func (h *appHandler) handleTCPConnector(ctx context.Context, localPort uint16, connector func() (net.Conn, error)) error { app := h.cfg.appInfo.GetApp() if len(app.GetTCPPorts()) > 0 { if !app.GetTCPPorts().Contains(int(localPort)) { @@ -151,12 +153,10 @@ func (i *appCertIssuer) IssueCert(ctx context.Context) (tls.Certificate, error) return cert.(tls.Certificate), trace.Wrap(err) } -// IsVNetApp returns true if the app type is supported by VNet. -func IsVNetApp(app types.Application) bool { - return app.IsTCP() || - app.GetProtocol() == "HTTP" || - app.IsLLM() || - types.GetMCPServerTransportType(app.GetURI()) == types.MCPTransportHTTP +// IsHTTPSTunnelApp returns true if the app should be proxied through the +// HTTPS-in-mTLS tunnel. Currently this includes HTTP and LLM apps. +func IsHTTPSTunnelApp(app types.Application) bool { + return app.IsLLM() || app.GetProtocol() == types.ApplicationProtocolHTTP } // RouteToApp returns a *proto.RouteToApp populated from appInfo and targetPort. diff --git a/lib/vnet/app_handler_test.go b/lib/vnet/app_handler_test.go new file mode 100644 index 00000000000..b06af27bcf2 --- /dev/null +++ b/lib/vnet/app_handler_test.go @@ -0,0 +1,65 @@ +// Teleport +// Copyright (C) 2026 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 vnet + +import ( + "testing" + + "github.com/stretchr/testify/require" + + "github.com/gravitational/teleport/api/types" +) + +func TestIsHTTPSTunnelApp(t *testing.T) { + tests := []struct { + name string + uri string + expect require.BoolAssertionFunc + }{ + { + name: "TCP app", + uri: "tcp://localhost:5432", + expect: require.False, + }, + { + name: "HTTP app", + uri: "http://localhost:8080", + expect: require.True, + }, + { + name: "HTTPS app", + uri: "https://localhost:8443", + expect: require.True, + }, + { + name: "LLM app", + uri: "llm://", + expect: require.True, + }, + { + name: "MCP app", + uri: "mcp+http://localhost:8080", + expect: require.False, + }, + } + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + app := &types.AppV3{Spec: types.AppSpecV3{URI: tc.uri}} + tc.expect(t, IsHTTPSTunnelApp(app)) + }) + } +} diff --git a/lib/vnet/fqdn_resolver.go b/lib/vnet/fqdn_resolver.go index 6c6fc0f237a..fcb5b00a92d 100644 --- a/lib/vnet/fqdn_resolver.go +++ b/lib/vnet/fqdn_resolver.go @@ -47,6 +47,7 @@ type fqdnResolverConfig struct { leafClusterCache *leafClusterCache // allowDatabaseAccess gates VNet database FQDN resolution for tsh/Connect. allowDatabaseAccess bool + allowAppHTTPSTunnel bool } func newFQDNResolver(cfg *fqdnResolverConfig) *fqdnResolver { @@ -305,13 +306,13 @@ func (r *fqdnResolver) resolveAppInfoForCluster( "name", app.GetName(), "public_addr", app.GetPublicAddr()) continue } - if app.IsTCP() { + if app.IsTCP() || r.shouldUseAppHTTPSTunnel(app) { if matchedByPublicAddr { - // Greedily prefer to match an arbitrary TCP app by public addr. + // Greedily prefer to match a VNet-handled app by public addr. return app, nil } - // Skip TCP apps that only matched by name, VNet only handles - // TCP apps that match a public addr. + // Skip apps that only matched by name, VNet only handles + // apps that match a public addr. } else { matchedWebApp = app } @@ -331,15 +332,46 @@ func (r *fqdnResolver) resolveAppInfoForCluster( // At this point we have found a matching app in the cluster, any error is // unexpected and is preventing access to the app and should be returned to // the user. - if !app.IsTCP() { + switch { + case app.IsTCP(): + log.InfoContext(ctx, "Query matched a TCP app") + appInfo, err := r.makeAppInfo(ctx, candidate, app) + if err != nil { + return nil, trace.Wrap(err) + } + return &vnetv1.ResolveFQDNResponse{ + Match: &vnetv1.ResolveFQDNResponse_MatchedTcpApp{ + MatchedTcpApp: &vnetv1.MatchedTCPApp{ + AppInfo: appInfo, + }, + }, + }, nil + + case r.shouldUseAppHTTPSTunnel(app): + log.InfoContext(ctx, "Query matched an HTTPS tunnel app", "protocol", app.GetProtocol()) + appInfo, err := r.makeAppInfo(ctx, candidate, app) + if err != nil { + return nil, trace.Wrap(err) + } + return &vnetv1.ResolveFQDNResponse{ + Match: &vnetv1.ResolveFQDNResponse_MatchedHttpsTunnelApp{ + MatchedHttpsTunnelApp: &vnetv1.MatchedHTTPSTunnelApp{ + AppInfo: appInfo, + }, + }, + }, nil + + default: log.InfoContext(ctx, "Query matched a web app") - // If not a TCP app this must be a web app and we can return early. return &vnetv1.ResolveFQDNResponse{ Match: &vnetv1.ResolveFQDNResponse_MatchedWebApp{ MatchedWebApp: &vnetv1.MatchedWebApp{}, }, }, nil } +} + +func (r *fqdnResolver) makeAppInfo(ctx context.Context, candidate clusterResolutionCandidate, app *types.AppV3) (*vnetv1.AppInfo, error) { clusterConfig, err := r.cfg.clusterConfigCache.GetClusterConfig(ctx, candidate.client) if err != nil { log.ErrorContext(ctx, "Failed to get cluster VNet config for matching app", "error", err) @@ -350,8 +382,7 @@ func (r *fqdnResolver) resolveAppInfoForCluster( log.ErrorContext(ctx, "Failed to get cluster dial options", "error", err) return nil, trace.Wrap(err, "getting dial options for matching app") } - log.InfoContext(ctx, "Query matched a TCP app") - appInfo := &vnetv1.AppInfo{ + return &vnetv1.AppInfo{ AppKey: &vnetv1.AppKey{ Profile: candidate.profileName, LeafCluster: candidate.leafClusterName, @@ -361,13 +392,6 @@ func (r *fqdnResolver) resolveAppInfoForCluster( App: app, Ipv4CidrRange: clusterConfig.IPv4CIDRRange, DialOptions: dialOpts, - } - return &vnetv1.ResolveFQDNResponse{ - Match: &vnetv1.ResolveFQDNResponse_MatchedTcpApp{ - MatchedTcpApp: &vnetv1.MatchedTCPApp{ - AppInfo: appInfo, - }, - }, }, nil } @@ -496,3 +520,7 @@ func isDirectSubdomain(fqdn, zone string) bool { } return !strings.ContainsRune(trimmed, '.') } + +func (r *fqdnResolver) shouldUseAppHTTPSTunnel(app types.Application) bool { + return r.cfg.allowAppHTTPSTunnel && IsHTTPSTunnelApp(app) +} diff --git a/lib/vnet/tcp_handler_resolver.go b/lib/vnet/tcp_handler_resolver.go index 53405105c50..c917573804f 100644 --- a/lib/vnet/tcp_handler_resolver.go +++ b/lib/vnet/tcp_handler_resolver.go @@ -27,6 +27,7 @@ import ( "github.com/jonboulle/clockwork" "github.com/gravitational/teleport/api/defaults" + alpncommon "github.com/gravitational/teleport/lib/srv/alpnproxy/common" "github.com/gravitational/teleport/lib/utils" ) @@ -71,7 +72,21 @@ func (r *tcpHandlerResolver) resolveTCPHandler(ctx context.Context, fqdn string) appInfo := matchedTCPApp.GetAppInfo() return &tcpHandlerSpec{ ipv4CIDRRange: appInfo.GetIpv4CidrRange(), - tcpHandler: newTCPAppHandler(&tcpAppHandlerConfig{ + tcpHandler: newAppHandler(&appHandlerConfig{ + protocol: alpncommon.ProtocolTCP, + appInfo: appInfo, + appProvider: r.cfg.appProvider, + clock: r.cfg.clock, + alwaysTrustRootClusterCA: r.cfg.alwaysTrustRootClusterCA, + }), + }, nil + } + if matchedHTTPSTunnelApp := resp.GetMatchedHttpsTunnelApp(); matchedHTTPSTunnelApp != nil { + appInfo := matchedHTTPSTunnelApp.GetAppInfo() + return &tcpHandlerSpec{ + ipv4CIDRRange: appInfo.GetIpv4CidrRange(), + tcpHandler: newAppHandler(&appHandlerConfig{ + protocol: alpncommon.ProtocolAppHTTPS, appInfo: appInfo, appProvider: r.cfg.appProvider, clock: r.cfg.clock, @@ -222,10 +237,11 @@ func (h *undecidedHandler) handleTCPConnector(ctx context.Context, localPort uin } log := log.With("fqdn", h.cfg.fqdn, "local_port", localPort) if matchedTCPApp := resp.GetMatchedTcpApp(); matchedTCPApp != nil { - // If matched a TCP app, build a tcpAppHandler that will be used for this + // If matched a TCP app, build an appHandler that will be used for this // and all subsequent connections to this address. log.DebugContext(ctx, "Resolved FQDN to a matched TCP app") - tcpAppHandler := newTCPAppHandler(&tcpAppHandlerConfig{ + tcpAppHandler := newAppHandler(&appHandlerConfig{ + protocol: alpncommon.ProtocolTCP, appInfo: matchedTCPApp.GetAppInfo(), appProvider: h.cfg.appProvider, clock: h.cfg.clock, @@ -234,6 +250,18 @@ func (h *undecidedHandler) handleTCPConnector(ctx context.Context, localPort uin h.setDecidedHandler(tcpAppHandler) return tcpAppHandler.handleTCPConnector(ctx, localPort, connector) } + if matchedHTTPSTunnelApp := resp.GetMatchedHttpsTunnelApp(); matchedHTTPSTunnelApp != nil { + log.DebugContext(ctx, "Resolved FQDN to a matched HTTPS tunnel app") + handler := newAppHandler(&appHandlerConfig{ + protocol: alpncommon.ProtocolAppHTTPS, + appInfo: matchedHTTPSTunnelApp.GetAppInfo(), + appProvider: h.cfg.appProvider, + clock: h.cfg.clock, + alwaysTrustRootClusterCA: h.cfg.alwaysTrustRootClusterCA, + }) + h.setDecidedHandler(handler) + return handler.handleTCPConnector(ctx, localPort, connector) + } if matchedDB := resp.GetMatchedDatabase(); matchedDB != nil { // If matched a database, build a dbHandler that will be used for this // and all subsequent connections to this address. diff --git a/lib/vnet/user_process.go b/lib/vnet/user_process.go index 15b0779e08c..42cc146918d 100644 --- a/lib/vnet/user_process.go +++ b/lib/vnet/user_process.go @@ -19,10 +19,12 @@ package vnet import ( "context" "crypto/tls" + "os" "github.com/gravitational/trace" "github.com/jonboulle/clockwork" + apiutils "github.com/gravitational/teleport/api/utils" vnetv1 "github.com/gravitational/teleport/gen/proto/go/teleport/lib/vnet/v1" "github.com/gravitational/teleport/lib/auth/authclient" "github.com/gravitational/teleport/lib/client" @@ -108,6 +110,14 @@ func RunUserProcess(ctx context.Context, clientApplication ClientApplication) (* if err != nil { return nil, trace.Wrap(err) } + + // TODO(greedy52) VNet config may have a flag like `allow_app_https_tunnel` + // to opt-in this feature once browser support is added for app HTTPS + // tunnel. Using an unstable env var for testing purpose for now. + allowAppHTTPSTunnel, _ := apiutils.ParseBool(os.Getenv("TELEPORT_UNSTABLE_VNET_APP_HTTPS_TUNNEL")) + if allowAppHTTPSTunnel { + log.InfoContext(ctx, "App HTTPS tunnel is enabled") + } fqdnResolver := newFQDNResolver(&fqdnResolverConfig{ clientApplication: clientApplication, clusterConfigCache: clusterConfigCache, @@ -116,6 +126,7 @@ func RunUserProcess(ctx context.Context, clientApplication ClientApplication) (* // disabled for tsh/Connect by default. flip to true to enable DB access via VNet // for tsh/Connect to validate locally. allowDatabaseAccess: false, + allowAppHTTPSTunnel: allowAppHTTPSTunnel, }) unifiedClusterConfigProvider := NewUnifiedClusterConfigProvider(&UnifiedClusterConfigProviderConfig{ clientApplication: clientApplication, diff --git a/lib/vnet/vnet_test.go b/lib/vnet/vnet_test.go index 0c53a5e8425..35ab9549164 100644 --- a/lib/vnet/vnet_test.go +++ b/lib/vnet/vnet_test.go @@ -83,9 +83,10 @@ type testPack struct { } type testPackConfig struct { - clock clockwork.Clock - fakeClientApp *fakeClientApp - homePath string + clock clockwork.Clock + fakeClientApp *fakeClientApp + homePath string + allowAppHTTPSTunnel bool } func newTestPack(t *testing.T, ctx context.Context, cfg testPackConfig) *testPack { @@ -166,6 +167,14 @@ func (p *testPack) lookupHost(ctx context.Context, host string) ([]string, error return p.hostNetwork.DNSResolver().LookupHost(ctx, host) } +func (p *testPack) lookupHostShouldFail(t *testing.T, host string) { + t.Helper() + ctx, cancel := context.WithTimeout(t.Context(), 100*time.Millisecond) + defer cancel() + _, err := p.lookupHost(ctx, host) + require.Error(t, err) +} + func (p *testPack) dialHost(ctx context.Context, host string, port int) (net.Conn, error) { addr := net.JoinHostPort(host, strconv.Itoa(port)) if net.ParseIP(host) != nil { @@ -200,6 +209,7 @@ func runTestClientApplicationService(t *testing.T, ctx context.Context, cfg test clusterConfigCache: clusterConfigCache, leafClusterCache: leafClusterCache, allowDatabaseAccess: true, + allowAppHTTPSTunnel: cfg.allowAppHTTPSTunnel, }) clientApplicationService, err := newClientApplicationService(&clientApplicationServiceConfig{ clientApplication: cfg.fakeClientApp, @@ -258,6 +268,7 @@ type appSpec struct { name string publicAddr string isWebApp bool + isLLMApp bool tcpPorts []*types.PortRange } @@ -266,10 +277,14 @@ func (s *appSpec) getName() string { } func (s *appSpec) getURI() string { - if s.isWebApp { + switch { + case s.isLLMApp: + return types.SchemeLLMEndpoint + "://" + case s.isWebApp: return "http://" + s.publicAddr + default: + return "tcp://" + s.publicAddr } - return "tcp://" + s.publicAddr } type dbSpec struct { @@ -1028,14 +1043,6 @@ func TestDialFakeApp(t *testing.T) { } }) - lookupShouldFailFast := func(t *testing.T, host string) { - t.Helper() - lookupCtx, cancel := context.WithTimeout(ctx, 100*time.Millisecond) - defer cancel() - _, err := p.lookupHost(lookupCtx, host) - require.Error(t, err) - } - t.Run("invalid FQDN", func(t *testing.T) { t.Parallel() invalidTestCases := []string{ @@ -1045,7 +1052,7 @@ func TestDialFakeApp(t *testing.T) { for _, fqdn := range invalidTestCases { t.Run(fqdn, func(t *testing.T) { t.Parallel() - lookupShouldFailFast(t, fqdn) + p.lookupHostShouldFail(t, fqdn) }) } }) @@ -1083,9 +1090,107 @@ func TestDialFakeApp(t *testing.T) { // For the test we've configured VNet with no upstream // nameservers, so we expect the DNS lookup to fail. - // net.Resolver.LookupHost takes a while to fail unless we - // provide a short context. - lookupShouldFailFast(t, addr) + p.lookupHostShouldFail(t, addr) + }) + } + }) +} + +func TestDialHTTPSTunnelApp(t *testing.T) { + t.Parallel() + clock := clockwork.NewFakeClockAt(time.Now()) + + clusterSpec := map[string]testClusterSpec{ + "root.example.com": { + apps: []appSpec{ + {publicAddr: "tcp-app.root.example.com"}, + {publicAddr: "http-app.root.example.com", isWebApp: true}, + {publicAddr: "llm-app.root.example.com", isLLMApp: true}, + }, + }, + } + + t.Run("enabled", func(t *testing.T) { + t.Parallel() + ctx := t.Context() + + clientApp := newFakeClientApp(ctx, t, &fakeClientAppConfig{ + clusters: clusterSpec, + clock: clock, + signatureAlgorithmSuite: types.SignatureAlgorithmSuite_SIGNATURE_ALGORITHM_SUITE_BALANCED_V1, + }) + p := newTestPack(t, ctx, testPackConfig{ + fakeClientApp: clientApp, + clock: clock, + allowAppHTTPSTunnel: true, + }) + + for _, tc := range []struct { + name string + app string + }{ + { + name: "TCP app", + app: "tcp-app.root.example.com", + }, + { + name: "HTTP app", + app: "http-app.root.example.com", + }, + { + name: "LLM app", + app: "llm-app.root.example.com", + }, + } { + t.Run(tc.name, func(t *testing.T) { + t.Parallel() + conn, err := p.dialHost(ctx, tc.app, 443) + require.NoError(t, err) + testEchoConnection(t, conn) + require.NoError(t, conn.Close()) + }) + } + }) + + t.Run("disabled", func(t *testing.T) { + t.Parallel() + ctx := t.Context() + + clientApp := newFakeClientApp(ctx, t, &fakeClientAppConfig{ + clusters: clusterSpec, + clock: clock, + signatureAlgorithmSuite: types.SignatureAlgorithmSuite_SIGNATURE_ALGORITHM_SUITE_BALANCED_V1, + }) + p := newTestPack(t, ctx, testPackConfig{ + fakeClientApp: clientApp, + clock: clock, + allowAppHTTPSTunnel: false, + }) + + t.Run("TCP app still works", func(t *testing.T) { + t.Parallel() + conn, err := p.dialHost(ctx, "tcp-app.root.example.com", 443) + require.NoError(t, err) + testEchoConnection(t, conn) + require.NoError(t, conn.Close()) + }) + + for _, tc := range []struct { + name string + app string + }{ + { + name: "HTTP app not resolved", + app: "http-app.root.example.com", + }, + { + name: "LLM app not resolved", + app: "llm-app.root.example.com", + }, + } { + t.Run(tc.name, func(t *testing.T) { + t.Parallel() + p.lookupHostShouldFail(t, tc.app) }) } }) @@ -1817,14 +1922,6 @@ func TestPriority(t *testing.T) { webProxyPort, err := strconv.Atoi(webProxyPortString) require.NoError(t, err) - lookupShouldFailFast := func(t *testing.T, host string) { - t.Helper() - lookupCtx, cancel := context.WithTimeout(ctx, 100*time.Millisecond) - defer cancel() - _, err := p.lookupHost(lookupCtx, host) - require.Error(t, err) - } - knownHosts, err := os.ReadFile(keypaths.VNetKnownHostsPath(homePath)) require.NoError(t, err) marker, hosts, hostCAPubKey, _, _, err := ssh.ParseKnownHosts(knownHosts) @@ -1859,7 +1956,7 @@ func TestPriority(t *testing.T) { t.Run("web app beats SSH cluster match", func(t *testing.T) { t.Parallel() - lookupShouldFailFast(t, "webwins.leaf.example.com") + p.lookupHostShouldFail(t, "webwins.leaf.example.com") assert.Empty(t, clientApp.RequestedRouteToApps("webwins.leaf.example.com")) }) @@ -2106,9 +2203,16 @@ func mustStartFakeWebProxy( return trace.Wrap(runTestSSHServerInstance(conn, serverConfig)) } + httpsTunnelAppHandler := func(conn net.Conn) error { + // HTTPS tunnel apps use the same echo handler as TCP apps for testing. + _, err := io.Copy(conn, conn) + return trace.Wrap(err, "io.Copy error in HTTPS tunnel echo server") + } + // Run a simplified TLS router for the test. protocolHandlers := map[alpncommon.Protocol]func(net.Conn) error{ alpncommon.ProtocolTCP: tcpAppHandler, + alpncommon.ProtocolAppHTTPS: httpsTunnelAppHandler, alpncommon.ProtocolProxySSH: sshHandler, } for _, dbProto := range alpncommon.DatabaseProtocols { @@ -2193,6 +2297,7 @@ func fakeWebProxyALPNProtocols() []string { protos := []string{ string(alpncommon.ProtocolProxySSH), string(alpncommon.ProtocolTCP), + string(alpncommon.ProtocolAppHTTPS), } for _, dbProto := range alpncommon.DatabaseProtocols { protos = append(protos, string(dbProto)) diff --git a/proto/teleport/lib/vnet/v1/client_application_service.proto b/proto/teleport/lib/vnet/v1/client_application_service.proto index ce338cadadf..2a2c2277419 100644 --- a/proto/teleport/lib/vnet/v1/client_application_service.proto +++ b/proto/teleport/lib/vnet/v1/client_application_service.proto @@ -127,7 +127,11 @@ message ResolveFQDNResponse { oneof match { // MatchedTcpApp will be set when the query matched a TCP app. MatchedTCPApp matched_tcp_app = 1; - // MatchedWebApp will be set when the query matched a web app. + // MatchedWebApp will be set when the query matched a web app and when app + // HTTPS tunnel is not used. MatchedWebApp signifies that the query matched + // a web app that VNet should not handle. DNS will be forwarded upstream so + // the browser resolves to the proxy's real address and goes through the + // normal web app login flow. MatchedWebApp matched_web_app = 2; // MatchedCluster will be set when the query did not match any app, but did // match a subdomain of a proxy address. VNet will resolve the DNS query to @@ -135,6 +139,9 @@ message ResolveFQDNResponse { MatchedCluster matched_cluster = 3; // MatchedDatabase will be set when the query matched a database resource. MatchedDatabase matched_database = 4; + // MatchedHTTPSTunnelApp will be set when the query matched an app that + // should be tunneled via the HTTPS-in-mTLS ALPN protocol. + MatchedHTTPSTunnelApp matched_https_tunnel_app = 5; } } @@ -147,6 +154,13 @@ message MatchedTCPApp { // MatchedTCPApp is a placeholder to signify that the query matched a web app. message MatchedWebApp {} +// MatchedHTTPSTunnelApp holds info about an app that should be proxied through +// the HTTPS-in-mTLS tunnel. +message MatchedHTTPSTunnelApp { + // AppInfo holds all necessary info for making connections to the resolved app. + AppInfo app_info = 1; +} + // MatchedCluster holds info about a cluster that a query matched. message MatchedCluster { // Ipv4CidrRange is the CIDR range from which an IPv4 address should be assigned