diff --git a/adapter/openconnect.go b/adapter/openconnect.go index a0e012c69..e2bf3218f 100644 --- a/adapter/openconnect.go +++ b/adapter/openconnect.go @@ -16,15 +16,15 @@ type OpenConnectEndpoint interface { Endpoint OpenConnectStatus() OpenConnectStatus StatusUpdated() <-chan struct{} - CompleteAuthForm(formID string, values map[string]string) error - CancelAuthForm(formID string) error + CompleteAuthChallenge(challengeID string, response OpenConnectAuthResponse) error + CancelAuthChallenge(challengeID string) error } type OpenConnectStatus struct { - State string - AuthForm *OpenConnectAuthForm - Error string - TunnelInfo *OpenConnectTunnelInfo + State string + AuthChallenge *OpenConnectAuthChallenge + Error string + TunnelInfo *OpenConnectTunnelInfo } type OpenConnectTunnelInfo struct { @@ -38,13 +38,49 @@ type OpenConnectTunnelInfo struct { ConnectedSince time.Time } -type OpenConnectAuthForm struct { +type OpenConnectAuthChallenge struct { ID string Banner string Message string Error string - URL string - Fields []OpenConnectAuthFormField + Form *OpenConnectAuthForm + Browser *OpenConnectBrowserRequest +} + +type OpenConnectAuthForm struct { + Fields []OpenConnectAuthFormField +} + +type OpenConnectBrowserRequest struct { + URL string + FinalURL string + CookieNames []string + HeaderNames []string +} + +type OpenConnectBrowserCookie struct { + Name string + Value string +} + +type OpenConnectBrowserHeader struct { + Name string + Values []string +} + +type OpenConnectAuthResponse struct { + Form *OpenConnectAuthFormResponse + Browser *OpenConnectBrowserResult +} + +type OpenConnectAuthFormResponse struct { + Values map[string]string +} + +type OpenConnectBrowserResult struct { + FinalURL string + Cookies []OpenConnectBrowserCookie + Headers []OpenConnectBrowserHeader } type OpenConnectAuthFormField struct { diff --git a/daemon/started_service.go b/daemon/started_service.go index 9e9f43f89..693521a7a 100644 --- a/daemon/started_service.go +++ b/daemon/started_service.go @@ -1620,35 +1620,46 @@ func openConnectEndpointStatusToProto(tag string, endpointStatus adapter.OpenCon Error: endpointStatus.Error, TunnelInfo: openConnectTunnelInfoToProto(endpointStatus.TunnelInfo), } - if endpointStatus.AuthForm != nil { - fields := common.Map(endpointStatus.AuthForm.Fields, func(field adapter.OpenConnectAuthFormField) *OpenConnectAuthFormField { - return &OpenConnectAuthFormField{ - SubmissionKey: field.SubmissionKey, - Name: field.Name, - Label: field.Label, - Kind: field.Kind, - Value: field.Value, - Options: common.Map(field.Options, func(option adapter.OpenConnectAuthFormChoice) *OpenConnectAuthFormChoice { - return &OpenConnectAuthFormChoice{ - Value: option.Value, - Label: option.Label, + if endpointStatus.AuthChallenge != nil { + challenge := &OpenConnectAuthChallenge{ + Id: endpointStatus.AuthChallenge.ID, + Banner: endpointStatus.AuthChallenge.Banner, + Message: endpointStatus.AuthChallenge.Message, + Error: endpointStatus.AuthChallenge.Error, + } + if endpointStatus.AuthChallenge.Form != nil { + challenge.Challenge = &OpenConnectAuthChallenge_Form{Form: &OpenConnectAuthForm{ + Fields: common.Map(endpointStatus.AuthChallenge.Form.Fields, func(field adapter.OpenConnectAuthFormField) *OpenConnectAuthFormField { + return &OpenConnectAuthFormField{ + SubmissionKey: field.SubmissionKey, + Name: field.Name, + Label: field.Label, + Kind: field.Kind, + Value: field.Value, + Options: common.Map(field.Options, func(option adapter.OpenConnectAuthFormChoice) *OpenConnectAuthFormChoice { + return &OpenConnectAuthFormChoice{ + Value: option.Value, + Label: option.Label, + } + }), } }), - } - }) - result.AuthForm = &OpenConnectAuthForm{ - Id: endpointStatus.AuthForm.ID, - Banner: endpointStatus.AuthForm.Banner, - Message: endpointStatus.AuthForm.Message, - Error: endpointStatus.AuthForm.Error, - Url: endpointStatus.AuthForm.URL, - Fields: fields, + }} } + if endpointStatus.AuthChallenge.Browser != nil { + challenge.Challenge = &OpenConnectAuthChallenge_Browser{Browser: &OpenConnectBrowserRequest{ + Url: endpointStatus.AuthChallenge.Browser.URL, + FinalURL: endpointStatus.AuthChallenge.Browser.FinalURL, + CookieNames: endpointStatus.AuthChallenge.Browser.CookieNames, + HeaderNames: endpointStatus.AuthChallenge.Browser.HeaderNames, + }} + } + result.AuthChallenge = challenge } return result } -func (s *StartedService) SubmitOpenConnectAuthForm(ctx context.Context, request *OpenConnectAuthFormSubmission) (*emptypb.Empty, error) { +func (s *StartedService) SubmitOpenConnectAuthResponse(ctx context.Context, request *OpenConnectAuthResponseSubmission) (*emptypb.Empty, error) { err := s.waitForStarted(ctx) if err != nil { return nil, err @@ -1661,14 +1672,31 @@ func (s *StartedService) SubmitOpenConnectAuthForm(ctx context.Context, request if err != nil { return nil, err } - err = endpoint.CompleteAuthForm(request.FormID, request.Values) + var authResponse adapter.OpenConnectAuthResponse + form := request.GetForm() + if form != nil { + authResponse.Form = &adapter.OpenConnectAuthFormResponse{Values: form.Values} + } + browser := request.GetBrowser() + if browser != nil { + authResponse.Browser = &adapter.OpenConnectBrowserResult{ + FinalURL: browser.FinalURL, + Cookies: common.Map(browser.Cookies, func(cookie *OpenConnectBrowserCookie) adapter.OpenConnectBrowserCookie { + return adapter.OpenConnectBrowserCookie{Name: cookie.Name, Value: cookie.Value} + }), + Headers: common.Map(browser.Headers, func(header *OpenConnectBrowserHeader) adapter.OpenConnectBrowserHeader { + return adapter.OpenConnectBrowserHeader{Name: header.Name, Values: header.Values} + }), + } + } + err = endpoint.CompleteAuthChallenge(request.ChallengeID, authResponse) if err != nil { return nil, err } return &emptypb.Empty{}, nil } -func (s *StartedService) CancelOpenConnectAuthForm(ctx context.Context, request *OpenConnectAuthFormCancel) (*emptypb.Empty, error) { +func (s *StartedService) CancelOpenConnectAuthChallenge(ctx context.Context, request *OpenConnectAuthChallengeCancel) (*emptypb.Empty, error) { err := s.waitForStarted(ctx) if err != nil { return nil, err @@ -1681,7 +1709,7 @@ func (s *StartedService) CancelOpenConnectAuthForm(ctx context.Context, request if err != nil { return nil, err } - err = endpoint.CancelAuthForm(request.FormID) + err = endpoint.CancelAuthChallenge(request.ChallengeID) if err != nil { return nil, err } diff --git a/daemon/started_service.pb.go b/daemon/started_service.pb.go index 039db91fb..c019f557c 100644 --- a/daemon/started_service.pb.go +++ b/daemon/started_service.pb.go @@ -4671,13 +4671,13 @@ func (x *OpenConnectStatusUpdate) GetEndpoints() []*OpenConnectEndpointStatus { } type OpenConnectEndpointStatus struct { - state protoimpl.MessageState `protogen:"open.v1"` - EndpointTag string `protobuf:"bytes,1,opt,name=endpointTag,proto3" json:"endpointTag,omitempty"` - State string `protobuf:"bytes,2,opt,name=state,proto3" json:"state,omitempty"` - StateText string `protobuf:"bytes,3,opt,name=stateText,proto3" json:"stateText,omitempty"` - AuthForm *OpenConnectAuthForm `protobuf:"bytes,4,opt,name=authForm,proto3" json:"authForm,omitempty"` - Error string `protobuf:"bytes,5,opt,name=error,proto3" json:"error,omitempty"` - TunnelInfo *OpenConnectTunnelInfo `protobuf:"bytes,6,opt,name=tunnelInfo,proto3" json:"tunnelInfo,omitempty"` + state protoimpl.MessageState `protogen:"open.v1"` + EndpointTag string `protobuf:"bytes,1,opt,name=endpointTag,proto3" json:"endpointTag,omitempty"` + State string `protobuf:"bytes,2,opt,name=state,proto3" json:"state,omitempty"` + StateText string `protobuf:"bytes,3,opt,name=stateText,proto3" json:"stateText,omitempty"` + AuthChallenge *OpenConnectAuthChallenge `protobuf:"bytes,4,opt,name=authChallenge,proto3" json:"authChallenge,omitempty"` + Error string `protobuf:"bytes,5,opt,name=error,proto3" json:"error,omitempty"` + TunnelInfo *OpenConnectTunnelInfo `protobuf:"bytes,6,opt,name=tunnelInfo,proto3" json:"tunnelInfo,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } @@ -4733,9 +4733,9 @@ func (x *OpenConnectEndpointStatus) GetStateText() string { return "" } -func (x *OpenConnectEndpointStatus) GetAuthForm() *OpenConnectAuthForm { +func (x *OpenConnectEndpointStatus) GetAuthChallenge() *OpenConnectAuthChallenge { if x != nil { - return x.AuthForm + return x.AuthChallenge } return nil } @@ -4854,21 +4854,130 @@ func (x *OpenConnectTunnelInfo) GetConnectedSince() int64 { return 0 } +type OpenConnectAuthChallenge struct { + state protoimpl.MessageState `protogen:"open.v1"` + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Banner string `protobuf:"bytes,2,opt,name=banner,proto3" json:"banner,omitempty"` + Message string `protobuf:"bytes,3,opt,name=message,proto3" json:"message,omitempty"` + Error string `protobuf:"bytes,4,opt,name=error,proto3" json:"error,omitempty"` + // Types that are valid to be assigned to Challenge: + // + // *OpenConnectAuthChallenge_Form + // *OpenConnectAuthChallenge_Browser + Challenge isOpenConnectAuthChallenge_Challenge `protobuf_oneof:"challenge"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *OpenConnectAuthChallenge) Reset() { + *x = OpenConnectAuthChallenge{} + mi := &file_daemon_started_service_proto_msgTypes[64] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *OpenConnectAuthChallenge) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*OpenConnectAuthChallenge) ProtoMessage() {} + +func (x *OpenConnectAuthChallenge) ProtoReflect() protoreflect.Message { + mi := &file_daemon_started_service_proto_msgTypes[64] + 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 OpenConnectAuthChallenge.ProtoReflect.Descriptor instead. +func (*OpenConnectAuthChallenge) Descriptor() ([]byte, []int) { + return file_daemon_started_service_proto_rawDescGZIP(), []int{64} +} + +func (x *OpenConnectAuthChallenge) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *OpenConnectAuthChallenge) GetBanner() string { + if x != nil { + return x.Banner + } + return "" +} + +func (x *OpenConnectAuthChallenge) GetMessage() string { + if x != nil { + return x.Message + } + return "" +} + +func (x *OpenConnectAuthChallenge) GetError() string { + if x != nil { + return x.Error + } + return "" +} + +func (x *OpenConnectAuthChallenge) GetChallenge() isOpenConnectAuthChallenge_Challenge { + if x != nil { + return x.Challenge + } + return nil +} + +func (x *OpenConnectAuthChallenge) GetForm() *OpenConnectAuthForm { + if x != nil { + if x, ok := x.Challenge.(*OpenConnectAuthChallenge_Form); ok { + return x.Form + } + } + return nil +} + +func (x *OpenConnectAuthChallenge) GetBrowser() *OpenConnectBrowserRequest { + if x != nil { + if x, ok := x.Challenge.(*OpenConnectAuthChallenge_Browser); ok { + return x.Browser + } + } + return nil +} + +type isOpenConnectAuthChallenge_Challenge interface { + isOpenConnectAuthChallenge_Challenge() +} + +type OpenConnectAuthChallenge_Form struct { + Form *OpenConnectAuthForm `protobuf:"bytes,5,opt,name=form,proto3,oneof"` +} + +type OpenConnectAuthChallenge_Browser struct { + Browser *OpenConnectBrowserRequest `protobuf:"bytes,6,opt,name=browser,proto3,oneof"` +} + +func (*OpenConnectAuthChallenge_Form) isOpenConnectAuthChallenge_Challenge() {} + +func (*OpenConnectAuthChallenge_Browser) isOpenConnectAuthChallenge_Challenge() {} + type OpenConnectAuthForm struct { state protoimpl.MessageState `protogen:"open.v1"` - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` - Banner string `protobuf:"bytes,2,opt,name=banner,proto3" json:"banner,omitempty"` - Message string `protobuf:"bytes,3,opt,name=message,proto3" json:"message,omitempty"` - Error string `protobuf:"bytes,4,opt,name=error,proto3" json:"error,omitempty"` - Url string `protobuf:"bytes,5,opt,name=url,proto3" json:"url,omitempty"` - Fields []*OpenConnectAuthFormField `protobuf:"bytes,6,rep,name=fields,proto3" json:"fields,omitempty"` + Fields []*OpenConnectAuthFormField `protobuf:"bytes,1,rep,name=fields,proto3" json:"fields,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } func (x *OpenConnectAuthForm) Reset() { *x = OpenConnectAuthForm{} - mi := &file_daemon_started_service_proto_msgTypes[64] + mi := &file_daemon_started_service_proto_msgTypes[65] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4880,7 +4989,7 @@ func (x *OpenConnectAuthForm) String() string { func (*OpenConnectAuthForm) ProtoMessage() {} func (x *OpenConnectAuthForm) ProtoReflect() protoreflect.Message { - mi := &file_daemon_started_service_proto_msgTypes[64] + mi := &file_daemon_started_service_proto_msgTypes[65] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4893,42 +5002,7 @@ func (x *OpenConnectAuthForm) ProtoReflect() protoreflect.Message { // Deprecated: Use OpenConnectAuthForm.ProtoReflect.Descriptor instead. func (*OpenConnectAuthForm) Descriptor() ([]byte, []int) { - return file_daemon_started_service_proto_rawDescGZIP(), []int{64} -} - -func (x *OpenConnectAuthForm) GetId() string { - if x != nil { - return x.Id - } - return "" -} - -func (x *OpenConnectAuthForm) GetBanner() string { - if x != nil { - return x.Banner - } - return "" -} - -func (x *OpenConnectAuthForm) GetMessage() string { - if x != nil { - return x.Message - } - return "" -} - -func (x *OpenConnectAuthForm) GetError() string { - if x != nil { - return x.Error - } - return "" -} - -func (x *OpenConnectAuthForm) GetUrl() string { - if x != nil { - return x.Url - } - return "" + return file_daemon_started_service_proto_rawDescGZIP(), []int{65} } func (x *OpenConnectAuthForm) GetFields() []*OpenConnectAuthFormField { @@ -4952,7 +5026,7 @@ type OpenConnectAuthFormField struct { func (x *OpenConnectAuthFormField) Reset() { *x = OpenConnectAuthFormField{} - mi := &file_daemon_started_service_proto_msgTypes[65] + mi := &file_daemon_started_service_proto_msgTypes[66] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4964,7 +5038,7 @@ func (x *OpenConnectAuthFormField) String() string { func (*OpenConnectAuthFormField) ProtoMessage() {} func (x *OpenConnectAuthFormField) ProtoReflect() protoreflect.Message { - mi := &file_daemon_started_service_proto_msgTypes[65] + mi := &file_daemon_started_service_proto_msgTypes[66] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4977,7 +5051,7 @@ func (x *OpenConnectAuthFormField) ProtoReflect() protoreflect.Message { // Deprecated: Use OpenConnectAuthFormField.ProtoReflect.Descriptor instead. func (*OpenConnectAuthFormField) Descriptor() ([]byte, []int) { - return file_daemon_started_service_proto_rawDescGZIP(), []int{65} + return file_daemon_started_service_proto_rawDescGZIP(), []int{66} } func (x *OpenConnectAuthFormField) GetSubmissionKey() string { @@ -5032,7 +5106,7 @@ type OpenConnectAuthFormChoice struct { func (x *OpenConnectAuthFormChoice) Reset() { *x = OpenConnectAuthFormChoice{} - mi := &file_daemon_started_service_proto_msgTypes[66] + mi := &file_daemon_started_service_proto_msgTypes[67] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5044,7 +5118,7 @@ func (x *OpenConnectAuthFormChoice) String() string { func (*OpenConnectAuthFormChoice) ProtoMessage() {} func (x *OpenConnectAuthFormChoice) ProtoReflect() protoreflect.Message { - mi := &file_daemon_started_service_proto_msgTypes[66] + mi := &file_daemon_started_service_proto_msgTypes[67] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5057,7 +5131,7 @@ func (x *OpenConnectAuthFormChoice) ProtoReflect() protoreflect.Message { // Deprecated: Use OpenConnectAuthFormChoice.ProtoReflect.Descriptor instead. func (*OpenConnectAuthFormChoice) Descriptor() ([]byte, []int) { - return file_daemon_started_service_proto_rawDescGZIP(), []int{66} + return file_daemon_started_service_proto_rawDescGZIP(), []int{67} } func (x *OpenConnectAuthFormChoice) GetValue() string { @@ -5074,30 +5148,31 @@ func (x *OpenConnectAuthFormChoice) GetLabel() string { return "" } -type OpenConnectAuthFormSubmission struct { +type OpenConnectBrowserRequest struct { state protoimpl.MessageState `protogen:"open.v1"` - EndpointTag string `protobuf:"bytes,1,opt,name=endpointTag,proto3" json:"endpointTag,omitempty"` - FormID string `protobuf:"bytes,2,opt,name=formID,proto3" json:"formID,omitempty"` - Values map[string]string `protobuf:"bytes,3,rep,name=values,proto3" json:"values,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` + Url string `protobuf:"bytes,1,opt,name=url,proto3" json:"url,omitempty"` + FinalURL string `protobuf:"bytes,2,opt,name=finalURL,proto3" json:"finalURL,omitempty"` + CookieNames []string `protobuf:"bytes,3,rep,name=cookieNames,proto3" json:"cookieNames,omitempty"` + HeaderNames []string `protobuf:"bytes,4,rep,name=headerNames,proto3" json:"headerNames,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } -func (x *OpenConnectAuthFormSubmission) Reset() { - *x = OpenConnectAuthFormSubmission{} - mi := &file_daemon_started_service_proto_msgTypes[67] +func (x *OpenConnectBrowserRequest) Reset() { + *x = OpenConnectBrowserRequest{} + mi := &file_daemon_started_service_proto_msgTypes[68] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *OpenConnectAuthFormSubmission) String() string { +func (x *OpenConnectBrowserRequest) String() string { return protoimpl.X.MessageStringOf(x) } -func (*OpenConnectAuthFormSubmission) ProtoMessage() {} +func (*OpenConnectBrowserRequest) ProtoMessage() {} -func (x *OpenConnectAuthFormSubmission) ProtoReflect() protoreflect.Message { - mi := &file_daemon_started_service_proto_msgTypes[67] +func (x *OpenConnectBrowserRequest) ProtoReflect() protoreflect.Message { + mi := &file_daemon_started_service_proto_msgTypes[68] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5108,55 +5183,165 @@ func (x *OpenConnectAuthFormSubmission) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use OpenConnectAuthFormSubmission.ProtoReflect.Descriptor instead. -func (*OpenConnectAuthFormSubmission) Descriptor() ([]byte, []int) { - return file_daemon_started_service_proto_rawDescGZIP(), []int{67} +// Deprecated: Use OpenConnectBrowserRequest.ProtoReflect.Descriptor instead. +func (*OpenConnectBrowserRequest) Descriptor() ([]byte, []int) { + return file_daemon_started_service_proto_rawDescGZIP(), []int{68} } -func (x *OpenConnectAuthFormSubmission) GetEndpointTag() string { +func (x *OpenConnectBrowserRequest) GetUrl() string { if x != nil { - return x.EndpointTag + return x.Url } return "" } -func (x *OpenConnectAuthFormSubmission) GetFormID() string { +func (x *OpenConnectBrowserRequest) GetFinalURL() string { if x != nil { - return x.FormID + return x.FinalURL } return "" } -func (x *OpenConnectAuthFormSubmission) GetValues() map[string]string { +func (x *OpenConnectBrowserRequest) GetCookieNames() []string { + if x != nil { + return x.CookieNames + } + return nil +} + +func (x *OpenConnectBrowserRequest) GetHeaderNames() []string { + if x != nil { + return x.HeaderNames + } + return nil +} + +type OpenConnectBrowserCookie struct { + state protoimpl.MessageState `protogen:"open.v1"` + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Value string `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *OpenConnectBrowserCookie) Reset() { + *x = OpenConnectBrowserCookie{} + mi := &file_daemon_started_service_proto_msgTypes[69] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *OpenConnectBrowserCookie) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*OpenConnectBrowserCookie) ProtoMessage() {} + +func (x *OpenConnectBrowserCookie) ProtoReflect() protoreflect.Message { + mi := &file_daemon_started_service_proto_msgTypes[69] + 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 OpenConnectBrowserCookie.ProtoReflect.Descriptor instead. +func (*OpenConnectBrowserCookie) Descriptor() ([]byte, []int) { + return file_daemon_started_service_proto_rawDescGZIP(), []int{69} +} + +func (x *OpenConnectBrowserCookie) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *OpenConnectBrowserCookie) GetValue() string { + if x != nil { + return x.Value + } + return "" +} + +type OpenConnectBrowserHeader struct { + state protoimpl.MessageState `protogen:"open.v1"` + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Values []string `protobuf:"bytes,2,rep,name=values,proto3" json:"values,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *OpenConnectBrowserHeader) Reset() { + *x = OpenConnectBrowserHeader{} + mi := &file_daemon_started_service_proto_msgTypes[70] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *OpenConnectBrowserHeader) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*OpenConnectBrowserHeader) ProtoMessage() {} + +func (x *OpenConnectBrowserHeader) ProtoReflect() protoreflect.Message { + mi := &file_daemon_started_service_proto_msgTypes[70] + 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 OpenConnectBrowserHeader.ProtoReflect.Descriptor instead. +func (*OpenConnectBrowserHeader) Descriptor() ([]byte, []int) { + return file_daemon_started_service_proto_rawDescGZIP(), []int{70} +} + +func (x *OpenConnectBrowserHeader) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *OpenConnectBrowserHeader) GetValues() []string { if x != nil { return x.Values } return nil } -type OpenConnectAuthFormCancel struct { +type OpenConnectAuthFormResponse struct { state protoimpl.MessageState `protogen:"open.v1"` - EndpointTag string `protobuf:"bytes,1,opt,name=endpointTag,proto3" json:"endpointTag,omitempty"` - FormID string `protobuf:"bytes,2,opt,name=formID,proto3" json:"formID,omitempty"` + Values map[string]string `protobuf:"bytes,1,rep,name=values,proto3" json:"values,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } -func (x *OpenConnectAuthFormCancel) Reset() { - *x = OpenConnectAuthFormCancel{} - mi := &file_daemon_started_service_proto_msgTypes[68] +func (x *OpenConnectAuthFormResponse) Reset() { + *x = OpenConnectAuthFormResponse{} + mi := &file_daemon_started_service_proto_msgTypes[71] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *OpenConnectAuthFormCancel) String() string { +func (x *OpenConnectAuthFormResponse) String() string { return protoimpl.X.MessageStringOf(x) } -func (*OpenConnectAuthFormCancel) ProtoMessage() {} +func (*OpenConnectAuthFormResponse) ProtoMessage() {} -func (x *OpenConnectAuthFormCancel) ProtoReflect() protoreflect.Message { - mi := &file_daemon_started_service_proto_msgTypes[68] +func (x *OpenConnectAuthFormResponse) ProtoReflect() protoreflect.Message { + mi := &file_daemon_started_service_proto_msgTypes[71] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5167,21 +5352,224 @@ func (x *OpenConnectAuthFormCancel) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use OpenConnectAuthFormCancel.ProtoReflect.Descriptor instead. -func (*OpenConnectAuthFormCancel) Descriptor() ([]byte, []int) { - return file_daemon_started_service_proto_rawDescGZIP(), []int{68} +// Deprecated: Use OpenConnectAuthFormResponse.ProtoReflect.Descriptor instead. +func (*OpenConnectAuthFormResponse) Descriptor() ([]byte, []int) { + return file_daemon_started_service_proto_rawDescGZIP(), []int{71} } -func (x *OpenConnectAuthFormCancel) GetEndpointTag() string { +func (x *OpenConnectAuthFormResponse) GetValues() map[string]string { + if x != nil { + return x.Values + } + return nil +} + +type OpenConnectBrowserResult struct { + state protoimpl.MessageState `protogen:"open.v1"` + FinalURL string `protobuf:"bytes,1,opt,name=finalURL,proto3" json:"finalURL,omitempty"` + Cookies []*OpenConnectBrowserCookie `protobuf:"bytes,2,rep,name=cookies,proto3" json:"cookies,omitempty"` + Headers []*OpenConnectBrowserHeader `protobuf:"bytes,3,rep,name=headers,proto3" json:"headers,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *OpenConnectBrowserResult) Reset() { + *x = OpenConnectBrowserResult{} + mi := &file_daemon_started_service_proto_msgTypes[72] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *OpenConnectBrowserResult) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*OpenConnectBrowserResult) ProtoMessage() {} + +func (x *OpenConnectBrowserResult) ProtoReflect() protoreflect.Message { + mi := &file_daemon_started_service_proto_msgTypes[72] + 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 OpenConnectBrowserResult.ProtoReflect.Descriptor instead. +func (*OpenConnectBrowserResult) Descriptor() ([]byte, []int) { + return file_daemon_started_service_proto_rawDescGZIP(), []int{72} +} + +func (x *OpenConnectBrowserResult) GetFinalURL() string { + if x != nil { + return x.FinalURL + } + return "" +} + +func (x *OpenConnectBrowserResult) GetCookies() []*OpenConnectBrowserCookie { + if x != nil { + return x.Cookies + } + return nil +} + +func (x *OpenConnectBrowserResult) GetHeaders() []*OpenConnectBrowserHeader { + if x != nil { + return x.Headers + } + return nil +} + +type OpenConnectAuthResponseSubmission struct { + state protoimpl.MessageState `protogen:"open.v1"` + EndpointTag string `protobuf:"bytes,1,opt,name=endpointTag,proto3" json:"endpointTag,omitempty"` + ChallengeID string `protobuf:"bytes,2,opt,name=challengeID,proto3" json:"challengeID,omitempty"` + // Types that are valid to be assigned to Response: + // + // *OpenConnectAuthResponseSubmission_Form + // *OpenConnectAuthResponseSubmission_Browser + Response isOpenConnectAuthResponseSubmission_Response `protobuf_oneof:"response"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *OpenConnectAuthResponseSubmission) Reset() { + *x = OpenConnectAuthResponseSubmission{} + mi := &file_daemon_started_service_proto_msgTypes[73] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *OpenConnectAuthResponseSubmission) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*OpenConnectAuthResponseSubmission) ProtoMessage() {} + +func (x *OpenConnectAuthResponseSubmission) ProtoReflect() protoreflect.Message { + mi := &file_daemon_started_service_proto_msgTypes[73] + 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 OpenConnectAuthResponseSubmission.ProtoReflect.Descriptor instead. +func (*OpenConnectAuthResponseSubmission) Descriptor() ([]byte, []int) { + return file_daemon_started_service_proto_rawDescGZIP(), []int{73} +} + +func (x *OpenConnectAuthResponseSubmission) GetEndpointTag() string { if x != nil { return x.EndpointTag } return "" } -func (x *OpenConnectAuthFormCancel) GetFormID() string { +func (x *OpenConnectAuthResponseSubmission) GetChallengeID() string { if x != nil { - return x.FormID + return x.ChallengeID + } + return "" +} + +func (x *OpenConnectAuthResponseSubmission) GetResponse() isOpenConnectAuthResponseSubmission_Response { + if x != nil { + return x.Response + } + return nil +} + +func (x *OpenConnectAuthResponseSubmission) GetForm() *OpenConnectAuthFormResponse { + if x != nil { + if x, ok := x.Response.(*OpenConnectAuthResponseSubmission_Form); ok { + return x.Form + } + } + return nil +} + +func (x *OpenConnectAuthResponseSubmission) GetBrowser() *OpenConnectBrowserResult { + if x != nil { + if x, ok := x.Response.(*OpenConnectAuthResponseSubmission_Browser); ok { + return x.Browser + } + } + return nil +} + +type isOpenConnectAuthResponseSubmission_Response interface { + isOpenConnectAuthResponseSubmission_Response() +} + +type OpenConnectAuthResponseSubmission_Form struct { + Form *OpenConnectAuthFormResponse `protobuf:"bytes,3,opt,name=form,proto3,oneof"` +} + +type OpenConnectAuthResponseSubmission_Browser struct { + Browser *OpenConnectBrowserResult `protobuf:"bytes,4,opt,name=browser,proto3,oneof"` +} + +func (*OpenConnectAuthResponseSubmission_Form) isOpenConnectAuthResponseSubmission_Response() {} + +func (*OpenConnectAuthResponseSubmission_Browser) isOpenConnectAuthResponseSubmission_Response() {} + +type OpenConnectAuthChallengeCancel struct { + state protoimpl.MessageState `protogen:"open.v1"` + EndpointTag string `protobuf:"bytes,1,opt,name=endpointTag,proto3" json:"endpointTag,omitempty"` + ChallengeID string `protobuf:"bytes,2,opt,name=challengeID,proto3" json:"challengeID,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *OpenConnectAuthChallengeCancel) Reset() { + *x = OpenConnectAuthChallengeCancel{} + mi := &file_daemon_started_service_proto_msgTypes[74] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *OpenConnectAuthChallengeCancel) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*OpenConnectAuthChallengeCancel) ProtoMessage() {} + +func (x *OpenConnectAuthChallengeCancel) ProtoReflect() protoreflect.Message { + mi := &file_daemon_started_service_proto_msgTypes[74] + 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 OpenConnectAuthChallengeCancel.ProtoReflect.Descriptor instead. +func (*OpenConnectAuthChallengeCancel) Descriptor() ([]byte, []int) { + return file_daemon_started_service_proto_rawDescGZIP(), []int{74} +} + +func (x *OpenConnectAuthChallengeCancel) GetEndpointTag() string { + if x != nil { + return x.EndpointTag + } + return "" +} + +func (x *OpenConnectAuthChallengeCancel) GetChallengeID() string { + if x != nil { + return x.ChallengeID } return "" } @@ -5195,7 +5583,7 @@ type OpenVPNStatusUpdate struct { func (x *OpenVPNStatusUpdate) Reset() { *x = OpenVPNStatusUpdate{} - mi := &file_daemon_started_service_proto_msgTypes[69] + mi := &file_daemon_started_service_proto_msgTypes[75] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5207,7 +5595,7 @@ func (x *OpenVPNStatusUpdate) String() string { func (*OpenVPNStatusUpdate) ProtoMessage() {} func (x *OpenVPNStatusUpdate) ProtoReflect() protoreflect.Message { - mi := &file_daemon_started_service_proto_msgTypes[69] + mi := &file_daemon_started_service_proto_msgTypes[75] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5220,7 +5608,7 @@ func (x *OpenVPNStatusUpdate) ProtoReflect() protoreflect.Message { // Deprecated: Use OpenVPNStatusUpdate.ProtoReflect.Descriptor instead. func (*OpenVPNStatusUpdate) Descriptor() ([]byte, []int) { - return file_daemon_started_service_proto_rawDescGZIP(), []int{69} + return file_daemon_started_service_proto_rawDescGZIP(), []int{75} } func (x *OpenVPNStatusUpdate) GetEndpoints() []*OpenVPNEndpointStatus { @@ -5244,7 +5632,7 @@ type OpenVPNEndpointStatus struct { func (x *OpenVPNEndpointStatus) Reset() { *x = OpenVPNEndpointStatus{} - mi := &file_daemon_started_service_proto_msgTypes[70] + mi := &file_daemon_started_service_proto_msgTypes[76] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5256,7 +5644,7 @@ func (x *OpenVPNEndpointStatus) String() string { func (*OpenVPNEndpointStatus) ProtoMessage() {} func (x *OpenVPNEndpointStatus) ProtoReflect() protoreflect.Message { - mi := &file_daemon_started_service_proto_msgTypes[70] + mi := &file_daemon_started_service_proto_msgTypes[76] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5269,7 +5657,7 @@ func (x *OpenVPNEndpointStatus) ProtoReflect() protoreflect.Message { // Deprecated: Use OpenVPNEndpointStatus.ProtoReflect.Descriptor instead. func (*OpenVPNEndpointStatus) Descriptor() ([]byte, []int) { - return file_daemon_started_service_proto_rawDescGZIP(), []int{70} + return file_daemon_started_service_proto_rawDescGZIP(), []int{76} } func (x *OpenVPNEndpointStatus) GetEndpointTag() string { @@ -5330,7 +5718,7 @@ type OpenVPNTunnelInfo struct { func (x *OpenVPNTunnelInfo) Reset() { *x = OpenVPNTunnelInfo{} - mi := &file_daemon_started_service_proto_msgTypes[71] + mi := &file_daemon_started_service_proto_msgTypes[77] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5342,7 +5730,7 @@ func (x *OpenVPNTunnelInfo) String() string { func (*OpenVPNTunnelInfo) ProtoMessage() {} func (x *OpenVPNTunnelInfo) ProtoReflect() protoreflect.Message { - mi := &file_daemon_started_service_proto_msgTypes[71] + mi := &file_daemon_started_service_proto_msgTypes[77] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5355,7 +5743,7 @@ func (x *OpenVPNTunnelInfo) ProtoReflect() protoreflect.Message { // Deprecated: Use OpenVPNTunnelInfo.ProtoReflect.Descriptor instead. func (*OpenVPNTunnelInfo) Descriptor() ([]byte, []int) { - return file_daemon_started_service_proto_rawDescGZIP(), []int{71} + return file_daemon_started_service_proto_rawDescGZIP(), []int{77} } func (x *OpenVPNTunnelInfo) GetServer() string { @@ -5431,7 +5819,7 @@ type OpenVPNChallenge struct { func (x *OpenVPNChallenge) Reset() { *x = OpenVPNChallenge{} - mi := &file_daemon_started_service_proto_msgTypes[72] + mi := &file_daemon_started_service_proto_msgTypes[78] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5443,7 +5831,7 @@ func (x *OpenVPNChallenge) String() string { func (*OpenVPNChallenge) ProtoMessage() {} func (x *OpenVPNChallenge) ProtoReflect() protoreflect.Message { - mi := &file_daemon_started_service_proto_msgTypes[72] + mi := &file_daemon_started_service_proto_msgTypes[78] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5456,7 +5844,7 @@ func (x *OpenVPNChallenge) ProtoReflect() protoreflect.Message { // Deprecated: Use OpenVPNChallenge.ProtoReflect.Descriptor instead. func (*OpenVPNChallenge) Descriptor() ([]byte, []int) { - return file_daemon_started_service_proto_rawDescGZIP(), []int{72} + return file_daemon_started_service_proto_rawDescGZIP(), []int{78} } func (x *OpenVPNChallenge) GetId() string { @@ -5535,7 +5923,7 @@ type OpenVPNChallengeSubmission struct { func (x *OpenVPNChallengeSubmission) Reset() { *x = OpenVPNChallengeSubmission{} - mi := &file_daemon_started_service_proto_msgTypes[73] + mi := &file_daemon_started_service_proto_msgTypes[79] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5547,7 +5935,7 @@ func (x *OpenVPNChallengeSubmission) String() string { func (*OpenVPNChallengeSubmission) ProtoMessage() {} func (x *OpenVPNChallengeSubmission) ProtoReflect() protoreflect.Message { - mi := &file_daemon_started_service_proto_msgTypes[73] + mi := &file_daemon_started_service_proto_msgTypes[79] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5560,7 +5948,7 @@ func (x *OpenVPNChallengeSubmission) ProtoReflect() protoreflect.Message { // Deprecated: Use OpenVPNChallengeSubmission.ProtoReflect.Descriptor instead. func (*OpenVPNChallengeSubmission) Descriptor() ([]byte, []int) { - return file_daemon_started_service_proto_rawDescGZIP(), []int{73} + return file_daemon_started_service_proto_rawDescGZIP(), []int{79} } func (x *OpenVPNChallengeSubmission) GetEndpointTag() string { @@ -5608,7 +5996,7 @@ type OpenVPNChallengeCancel struct { func (x *OpenVPNChallengeCancel) Reset() { *x = OpenVPNChallengeCancel{} - mi := &file_daemon_started_service_proto_msgTypes[74] + mi := &file_daemon_started_service_proto_msgTypes[80] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5620,7 +6008,7 @@ func (x *OpenVPNChallengeCancel) String() string { func (*OpenVPNChallengeCancel) ProtoMessage() {} func (x *OpenVPNChallengeCancel) ProtoReflect() protoreflect.Message { - mi := &file_daemon_started_service_proto_msgTypes[74] + mi := &file_daemon_started_service_proto_msgTypes[80] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5633,7 +6021,7 @@ func (x *OpenVPNChallengeCancel) ProtoReflect() protoreflect.Message { // Deprecated: Use OpenVPNChallengeCancel.ProtoReflect.Descriptor instead. func (*OpenVPNChallengeCancel) Descriptor() ([]byte, []int) { - return file_daemon_started_service_proto_rawDescGZIP(), []int{74} + return file_daemon_started_service_proto_rawDescGZIP(), []int{80} } func (x *OpenVPNChallengeCancel) GetEndpointTag() string { @@ -5660,7 +6048,7 @@ type Log_Message struct { func (x *Log_Message) Reset() { *x = Log_Message{} - mi := &file_daemon_started_service_proto_msgTypes[75] + mi := &file_daemon_started_service_proto_msgTypes[81] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5672,7 +6060,7 @@ func (x *Log_Message) String() string { func (*Log_Message) ProtoMessage() {} func (x *Log_Message) ProtoReflect() protoreflect.Message { - mi := &file_daemon_started_service_proto_msgTypes[75] + mi := &file_daemon_started_service_proto_msgTypes[81] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6066,12 +6454,12 @@ const file_daemon_started_service_proto_rawDesc = "" + "\abackend\x18\x04 \x01(\x0e2\x12.daemon.USBBackendR\abackend\x12,\n" + "\x05state\x18\x05 \x01(\x0e2\x16.daemon.USBDeviceStateR\x05state\"Z\n" + "\x17OpenConnectStatusUpdate\x12?\n" + - "\tendpoints\x18\x01 \x03(\v2!.daemon.OpenConnectEndpointStatusR\tendpoints\"\xff\x01\n" + + "\tendpoints\x18\x01 \x03(\v2!.daemon.OpenConnectEndpointStatusR\tendpoints\"\x8e\x02\n" + "\x19OpenConnectEndpointStatus\x12 \n" + "\vendpointTag\x18\x01 \x01(\tR\vendpointTag\x12\x14\n" + "\x05state\x18\x02 \x01(\tR\x05state\x12\x1c\n" + - "\tstateText\x18\x03 \x01(\tR\tstateText\x127\n" + - "\bauthForm\x18\x04 \x01(\v2\x1b.daemon.OpenConnectAuthFormR\bauthForm\x12\x14\n" + + "\tstateText\x18\x03 \x01(\tR\tstateText\x12F\n" + + "\rauthChallenge\x18\x04 \x01(\v2 .daemon.OpenConnectAuthChallengeR\rauthChallenge\x12\x14\n" + "\x05error\x18\x05 \x01(\tR\x05error\x12=\n" + "\n" + "tunnelInfo\x18\x06 \x01(\v2\x1d.daemon.OpenConnectTunnelInfoR\n" + @@ -6084,14 +6472,17 @@ const file_daemon_started_service_proto_rawDesc = "" + "\x04ipv6\x18\x05 \x03(\tR\x04ipv6\x12\x10\n" + "\x03dns\x18\x06 \x03(\tR\x03dns\x12\x10\n" + "\x03mtu\x18\a \x01(\rR\x03mtu\x12&\n" + - "\x0econnectedSince\x18\b \x01(\x03R\x0econnectedSince\"\xb9\x01\n" + - "\x13OpenConnectAuthForm\x12\x0e\n" + + "\x0econnectedSince\x18\b \x01(\x03R\x0econnectedSince\"\xf1\x01\n" + + "\x18OpenConnectAuthChallenge\x12\x0e\n" + "\x02id\x18\x01 \x01(\tR\x02id\x12\x16\n" + "\x06banner\x18\x02 \x01(\tR\x06banner\x12\x18\n" + "\amessage\x18\x03 \x01(\tR\amessage\x12\x14\n" + - "\x05error\x18\x04 \x01(\tR\x05error\x12\x10\n" + - "\x03url\x18\x05 \x01(\tR\x03url\x128\n" + - "\x06fields\x18\x06 \x03(\v2 .daemon.OpenConnectAuthFormFieldR\x06fields\"\xd1\x01\n" + + "\x05error\x18\x04 \x01(\tR\x05error\x121\n" + + "\x04form\x18\x05 \x01(\v2\x1b.daemon.OpenConnectAuthFormH\x00R\x04form\x12=\n" + + "\abrowser\x18\x06 \x01(\v2!.daemon.OpenConnectBrowserRequestH\x00R\abrowserB\v\n" + + "\tchallenge\"O\n" + + "\x13OpenConnectAuthForm\x128\n" + + "\x06fields\x18\x01 \x03(\v2 .daemon.OpenConnectAuthFormFieldR\x06fields\"\xd1\x01\n" + "\x18OpenConnectAuthFormField\x12$\n" + "\rsubmissionKey\x18\x01 \x01(\tR\rsubmissionKey\x12\x12\n" + "\x04name\x18\x02 \x01(\tR\x04name\x12\x14\n" + @@ -6101,17 +6492,37 @@ const file_daemon_started_service_proto_rawDesc = "" + "\aoptions\x18\x06 \x03(\v2!.daemon.OpenConnectAuthFormChoiceR\aoptions\"G\n" + "\x19OpenConnectAuthFormChoice\x12\x14\n" + "\x05value\x18\x01 \x01(\tR\x05value\x12\x14\n" + - "\x05label\x18\x02 \x01(\tR\x05label\"\xdf\x01\n" + - "\x1dOpenConnectAuthFormSubmission\x12 \n" + - "\vendpointTag\x18\x01 \x01(\tR\vendpointTag\x12\x16\n" + - "\x06formID\x18\x02 \x01(\tR\x06formID\x12I\n" + - "\x06values\x18\x03 \x03(\v21.daemon.OpenConnectAuthFormSubmission.ValuesEntryR\x06values\x1a9\n" + + "\x05label\x18\x02 \x01(\tR\x05label\"\x8d\x01\n" + + "\x19OpenConnectBrowserRequest\x12\x10\n" + + "\x03url\x18\x01 \x01(\tR\x03url\x12\x1a\n" + + "\bfinalURL\x18\x02 \x01(\tR\bfinalURL\x12 \n" + + "\vcookieNames\x18\x03 \x03(\tR\vcookieNames\x12 \n" + + "\vheaderNames\x18\x04 \x03(\tR\vheaderNames\"D\n" + + "\x18OpenConnectBrowserCookie\x12\x12\n" + + "\x04name\x18\x01 \x01(\tR\x04name\x12\x14\n" + + "\x05value\x18\x02 \x01(\tR\x05value\"F\n" + + "\x18OpenConnectBrowserHeader\x12\x12\n" + + "\x04name\x18\x01 \x01(\tR\x04name\x12\x16\n" + + "\x06values\x18\x02 \x03(\tR\x06values\"\xa1\x01\n" + + "\x1bOpenConnectAuthFormResponse\x12G\n" + + "\x06values\x18\x01 \x03(\v2/.daemon.OpenConnectAuthFormResponse.ValuesEntryR\x06values\x1a9\n" + "\vValuesEntry\x12\x10\n" + "\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n" + - "\x05value\x18\x02 \x01(\tR\x05value:\x028\x01\"U\n" + - "\x19OpenConnectAuthFormCancel\x12 \n" + - "\vendpointTag\x18\x01 \x01(\tR\vendpointTag\x12\x16\n" + - "\x06formID\x18\x02 \x01(\tR\x06formID\"R\n" + + "\x05value\x18\x02 \x01(\tR\x05value:\x028\x01\"\xae\x01\n" + + "\x18OpenConnectBrowserResult\x12\x1a\n" + + "\bfinalURL\x18\x01 \x01(\tR\bfinalURL\x12:\n" + + "\acookies\x18\x02 \x03(\v2 .daemon.OpenConnectBrowserCookieR\acookies\x12:\n" + + "\aheaders\x18\x03 \x03(\v2 .daemon.OpenConnectBrowserHeaderR\aheaders\"\xec\x01\n" + + "!OpenConnectAuthResponseSubmission\x12 \n" + + "\vendpointTag\x18\x01 \x01(\tR\vendpointTag\x12 \n" + + "\vchallengeID\x18\x02 \x01(\tR\vchallengeID\x129\n" + + "\x04form\x18\x03 \x01(\v2#.daemon.OpenConnectAuthFormResponseH\x00R\x04form\x12<\n" + + "\abrowser\x18\x04 \x01(\v2 .daemon.OpenConnectBrowserResultH\x00R\abrowserB\n" + + "\n" + + "\bresponse\"d\n" + + "\x1eOpenConnectAuthChallengeCancel\x12 \n" + + "\vendpointTag\x18\x01 \x01(\tR\vendpointTag\x12 \n" + + "\vchallengeID\x18\x02 \x01(\tR\vchallengeID\"R\n" + "\x13OpenVPNStatusUpdate\x12;\n" + "\tendpoints\x18\x01 \x03(\v2\x1d.daemon.OpenVPNEndpointStatusR\tendpoints\"\xf6\x01\n" + "\x15OpenVPNEndpointStatus\x12 \n" + @@ -6173,7 +6584,7 @@ const file_daemon_started_service_proto_rawDesc = "" + "\x17USB_BACKEND_LINUX_SYSFS\x10\x01\x12\x17\n" + "\x13USB_BACKEND_DYNAMIC\x10\x02\x12\x1c\n" + "\x18USB_BACKEND_DARWIN_IOKIT\x10\x03\x12\x1f\n" + - "\x1bUSB_BACKEND_WINDOWS_VBOXUSB\x10\x042\xee\x14\n" + + "\x1bUSB_BACKEND_WINDOWS_VBOXUSB\x10\x042\x80\x15\n" + "\x0eStartedService\x127\n" + "\n" + "GetVersion\x12\x16.google.protobuf.Empty\x1a\x0f.daemon.Version\"\x00\x12K\n" + @@ -6204,9 +6615,9 @@ const file_daemon_started_service_proto_rawDesc = "" + "\x18StartTailscaleSSHSession\x12!.daemon.TailscaleSSHClientMessage\x1a!.daemon.TailscaleSSHServerMessage\"\x00(\x010\x01\x12O\n" + "\x11ProvideUSBDevices\x12\x1a.daemon.USBProviderMessage\x1a\x18.daemon.USBServerMessage\"\x00(\x010\x01\x12Y\n" + "\x1aSubscribeUSBIPServerStatus\x12\x16.google.protobuf.Empty\x1a\x1f.daemon.USBIPServerStatusUpdate\"\x000\x01\x12Y\n" + - "\x1aSubscribeOpenConnectStatus\x12\x16.google.protobuf.Empty\x1a\x1f.daemon.OpenConnectStatusUpdate\"\x000\x01\x12\\\n" + - "\x19SubmitOpenConnectAuthForm\x12%.daemon.OpenConnectAuthFormSubmission\x1a\x16.google.protobuf.Empty\"\x00\x12X\n" + - "\x19CancelOpenConnectAuthForm\x12!.daemon.OpenConnectAuthFormCancel\x1a\x16.google.protobuf.Empty\"\x00\x12Q\n" + + "\x1aSubscribeOpenConnectStatus\x12\x16.google.protobuf.Empty\x1a\x1f.daemon.OpenConnectStatusUpdate\"\x000\x01\x12d\n" + + "\x1dSubmitOpenConnectAuthResponse\x12).daemon.OpenConnectAuthResponseSubmission\x1a\x16.google.protobuf.Empty\"\x00\x12b\n" + + "\x1eCancelOpenConnectAuthChallenge\x12&.daemon.OpenConnectAuthChallengeCancel\x1a\x16.google.protobuf.Empty\"\x00\x12Q\n" + "\x16SubscribeOpenVPNStatus\x12\x16.google.protobuf.Empty\x1a\x1b.daemon.OpenVPNStatusUpdate\"\x000\x01\x12^\n" + "\x1eSubmitOpenVPNChallengeResponse\x12\".daemon.OpenVPNChallengeSubmission\x1a\x16.google.protobuf.Empty\"\x00\x12R\n" + "\x16CancelOpenVPNChallenge\x12\x1e.daemon.OpenVPNChallengeCancel\x1a\x16.google.protobuf.Empty\"\x00B%Z#github.com/sagernet/sing-box/daemonb\x06proto3" @@ -6225,97 +6636,103 @@ func file_daemon_started_service_proto_rawDescGZIP() []byte { var ( file_daemon_started_service_proto_enumTypes = make([]protoimpl.EnumInfo, 5) - file_daemon_started_service_proto_msgTypes = make([]protoimpl.MessageInfo, 77) + file_daemon_started_service_proto_msgTypes = make([]protoimpl.MessageInfo, 83) file_daemon_started_service_proto_goTypes = []any{ - (LogLevel)(0), // 0: daemon.LogLevel - (ConnectionEventType)(0), // 1: daemon.ConnectionEventType - (USBDeviceState)(0), // 2: daemon.USBDeviceState - (USBBackend)(0), // 3: daemon.USBBackend - (ServiceStatus_Type)(0), // 4: daemon.ServiceStatus.Type - (*Version)(nil), // 5: daemon.Version - (*ServiceStatus)(nil), // 6: daemon.ServiceStatus - (*SubscribeStatusRequest)(nil), // 7: daemon.SubscribeStatusRequest - (*Log)(nil), // 8: daemon.Log - (*DefaultLogLevel)(nil), // 9: daemon.DefaultLogLevel - (*Status)(nil), // 10: daemon.Status - (*Groups)(nil), // 11: daemon.Groups - (*Group)(nil), // 12: daemon.Group - (*GroupItem)(nil), // 13: daemon.GroupItem - (*URLTestRequest)(nil), // 14: daemon.URLTestRequest - (*SelectOutboundRequest)(nil), // 15: daemon.SelectOutboundRequest - (*SetGroupExpandRequest)(nil), // 16: daemon.SetGroupExpandRequest - (*ClashMode)(nil), // 17: daemon.ClashMode - (*ClashModeStatus)(nil), // 18: daemon.ClashModeStatus - (*SubscribeConnectionsRequest)(nil), // 19: daemon.SubscribeConnectionsRequest - (*ConnectionEvent)(nil), // 20: daemon.ConnectionEvent - (*ConnectionEvents)(nil), // 21: daemon.ConnectionEvents - (*Connection)(nil), // 22: daemon.Connection - (*ProcessInfo)(nil), // 23: daemon.ProcessInfo - (*CloseConnectionRequest)(nil), // 24: daemon.CloseConnectionRequest - (*DeprecatedWarnings)(nil), // 25: daemon.DeprecatedWarnings - (*DeprecatedWarning)(nil), // 26: daemon.DeprecatedWarning - (*StartedAt)(nil), // 27: daemon.StartedAt - (*OutboundList)(nil), // 28: daemon.OutboundList - (*NetworkQualityTestRequest)(nil), // 29: daemon.NetworkQualityTestRequest - (*NetworkQualityTestProgress)(nil), // 30: daemon.NetworkQualityTestProgress - (*STUNTestRequest)(nil), // 31: daemon.STUNTestRequest - (*STUNTestProgress)(nil), // 32: daemon.STUNTestProgress - (*TailscaleStatusUpdate)(nil), // 33: daemon.TailscaleStatusUpdate - (*TailscaleEndpointStatus)(nil), // 34: daemon.TailscaleEndpointStatus - (*TailscaleUserGroup)(nil), // 35: daemon.TailscaleUserGroup - (*TailscalePeer)(nil), // 36: daemon.TailscalePeer - (*TailscalePingRequest)(nil), // 37: daemon.TailscalePingRequest - (*TailscalePingResponse)(nil), // 38: daemon.TailscalePingResponse - (*SetTailscaleExitNodeRequest)(nil), // 39: daemon.SetTailscaleExitNodeRequest - (*TailscaleLogoutRequest)(nil), // 40: daemon.TailscaleLogoutRequest - (*TailscaleSSHClientMessage)(nil), // 41: daemon.TailscaleSSHClientMessage - (*TailscaleSSHStart)(nil), // 42: daemon.TailscaleSSHStart - (*TailscaleSSHInput)(nil), // 43: daemon.TailscaleSSHInput - (*TailscaleSSHResize)(nil), // 44: daemon.TailscaleSSHResize - (*TailscaleSSHServerMessage)(nil), // 45: daemon.TailscaleSSHServerMessage - (*TailscaleSSHAuthBanner)(nil), // 46: daemon.TailscaleSSHAuthBanner - (*TailscaleSSHReady)(nil), // 47: daemon.TailscaleSSHReady - (*TailscaleSSHOutput)(nil), // 48: daemon.TailscaleSSHOutput - (*TailscaleSSHExit)(nil), // 49: daemon.TailscaleSSHExit - (*TailscaleSSHError)(nil), // 50: daemon.TailscaleSSHError - (*USBProviderMessage)(nil), // 51: daemon.USBProviderMessage - (*USBServerMessage)(nil), // 52: daemon.USBServerMessage - (*USBDeviceDescriptor)(nil), // 53: daemon.USBDeviceDescriptor - (*USBDeviceAttach)(nil), // 54: daemon.USBDeviceAttach - (*USBInterface)(nil), // 55: daemon.USBInterface - (*USBDeviceDetach)(nil), // 56: daemon.USBDeviceDetach - (*USBDeviceReady)(nil), // 57: daemon.USBDeviceReady - (*USBURBRequest)(nil), // 58: daemon.USBURBRequest - (*USBURBResponse)(nil), // 59: daemon.USBURBResponse - (*USBIsoPacket)(nil), // 60: daemon.USBIsoPacket - (*USBEndpointAbort)(nil), // 61: daemon.USBEndpointAbort - (*USBError)(nil), // 62: daemon.USBError - (*USBIPServerStatusUpdate)(nil), // 63: daemon.USBIPServerStatusUpdate - (*USBIPServerStatus)(nil), // 64: daemon.USBIPServerStatus - (*USBSharedDevice)(nil), // 65: daemon.USBSharedDevice - (*OpenConnectStatusUpdate)(nil), // 66: daemon.OpenConnectStatusUpdate - (*OpenConnectEndpointStatus)(nil), // 67: daemon.OpenConnectEndpointStatus - (*OpenConnectTunnelInfo)(nil), // 68: daemon.OpenConnectTunnelInfo - (*OpenConnectAuthForm)(nil), // 69: daemon.OpenConnectAuthForm - (*OpenConnectAuthFormField)(nil), // 70: daemon.OpenConnectAuthFormField - (*OpenConnectAuthFormChoice)(nil), // 71: daemon.OpenConnectAuthFormChoice - (*OpenConnectAuthFormSubmission)(nil), // 72: daemon.OpenConnectAuthFormSubmission - (*OpenConnectAuthFormCancel)(nil), // 73: daemon.OpenConnectAuthFormCancel - (*OpenVPNStatusUpdate)(nil), // 74: daemon.OpenVPNStatusUpdate - (*OpenVPNEndpointStatus)(nil), // 75: daemon.OpenVPNEndpointStatus - (*OpenVPNTunnelInfo)(nil), // 76: daemon.OpenVPNTunnelInfo - (*OpenVPNChallenge)(nil), // 77: daemon.OpenVPNChallenge - (*OpenVPNChallengeSubmission)(nil), // 78: daemon.OpenVPNChallengeSubmission - (*OpenVPNChallengeCancel)(nil), // 79: daemon.OpenVPNChallengeCancel - (*Log_Message)(nil), // 80: daemon.Log.Message - nil, // 81: daemon.OpenConnectAuthFormSubmission.ValuesEntry - (*emptypb.Empty)(nil), // 82: google.protobuf.Empty + (LogLevel)(0), // 0: daemon.LogLevel + (ConnectionEventType)(0), // 1: daemon.ConnectionEventType + (USBDeviceState)(0), // 2: daemon.USBDeviceState + (USBBackend)(0), // 3: daemon.USBBackend + (ServiceStatus_Type)(0), // 4: daemon.ServiceStatus.Type + (*Version)(nil), // 5: daemon.Version + (*ServiceStatus)(nil), // 6: daemon.ServiceStatus + (*SubscribeStatusRequest)(nil), // 7: daemon.SubscribeStatusRequest + (*Log)(nil), // 8: daemon.Log + (*DefaultLogLevel)(nil), // 9: daemon.DefaultLogLevel + (*Status)(nil), // 10: daemon.Status + (*Groups)(nil), // 11: daemon.Groups + (*Group)(nil), // 12: daemon.Group + (*GroupItem)(nil), // 13: daemon.GroupItem + (*URLTestRequest)(nil), // 14: daemon.URLTestRequest + (*SelectOutboundRequest)(nil), // 15: daemon.SelectOutboundRequest + (*SetGroupExpandRequest)(nil), // 16: daemon.SetGroupExpandRequest + (*ClashMode)(nil), // 17: daemon.ClashMode + (*ClashModeStatus)(nil), // 18: daemon.ClashModeStatus + (*SubscribeConnectionsRequest)(nil), // 19: daemon.SubscribeConnectionsRequest + (*ConnectionEvent)(nil), // 20: daemon.ConnectionEvent + (*ConnectionEvents)(nil), // 21: daemon.ConnectionEvents + (*Connection)(nil), // 22: daemon.Connection + (*ProcessInfo)(nil), // 23: daemon.ProcessInfo + (*CloseConnectionRequest)(nil), // 24: daemon.CloseConnectionRequest + (*DeprecatedWarnings)(nil), // 25: daemon.DeprecatedWarnings + (*DeprecatedWarning)(nil), // 26: daemon.DeprecatedWarning + (*StartedAt)(nil), // 27: daemon.StartedAt + (*OutboundList)(nil), // 28: daemon.OutboundList + (*NetworkQualityTestRequest)(nil), // 29: daemon.NetworkQualityTestRequest + (*NetworkQualityTestProgress)(nil), // 30: daemon.NetworkQualityTestProgress + (*STUNTestRequest)(nil), // 31: daemon.STUNTestRequest + (*STUNTestProgress)(nil), // 32: daemon.STUNTestProgress + (*TailscaleStatusUpdate)(nil), // 33: daemon.TailscaleStatusUpdate + (*TailscaleEndpointStatus)(nil), // 34: daemon.TailscaleEndpointStatus + (*TailscaleUserGroup)(nil), // 35: daemon.TailscaleUserGroup + (*TailscalePeer)(nil), // 36: daemon.TailscalePeer + (*TailscalePingRequest)(nil), // 37: daemon.TailscalePingRequest + (*TailscalePingResponse)(nil), // 38: daemon.TailscalePingResponse + (*SetTailscaleExitNodeRequest)(nil), // 39: daemon.SetTailscaleExitNodeRequest + (*TailscaleLogoutRequest)(nil), // 40: daemon.TailscaleLogoutRequest + (*TailscaleSSHClientMessage)(nil), // 41: daemon.TailscaleSSHClientMessage + (*TailscaleSSHStart)(nil), // 42: daemon.TailscaleSSHStart + (*TailscaleSSHInput)(nil), // 43: daemon.TailscaleSSHInput + (*TailscaleSSHResize)(nil), // 44: daemon.TailscaleSSHResize + (*TailscaleSSHServerMessage)(nil), // 45: daemon.TailscaleSSHServerMessage + (*TailscaleSSHAuthBanner)(nil), // 46: daemon.TailscaleSSHAuthBanner + (*TailscaleSSHReady)(nil), // 47: daemon.TailscaleSSHReady + (*TailscaleSSHOutput)(nil), // 48: daemon.TailscaleSSHOutput + (*TailscaleSSHExit)(nil), // 49: daemon.TailscaleSSHExit + (*TailscaleSSHError)(nil), // 50: daemon.TailscaleSSHError + (*USBProviderMessage)(nil), // 51: daemon.USBProviderMessage + (*USBServerMessage)(nil), // 52: daemon.USBServerMessage + (*USBDeviceDescriptor)(nil), // 53: daemon.USBDeviceDescriptor + (*USBDeviceAttach)(nil), // 54: daemon.USBDeviceAttach + (*USBInterface)(nil), // 55: daemon.USBInterface + (*USBDeviceDetach)(nil), // 56: daemon.USBDeviceDetach + (*USBDeviceReady)(nil), // 57: daemon.USBDeviceReady + (*USBURBRequest)(nil), // 58: daemon.USBURBRequest + (*USBURBResponse)(nil), // 59: daemon.USBURBResponse + (*USBIsoPacket)(nil), // 60: daemon.USBIsoPacket + (*USBEndpointAbort)(nil), // 61: daemon.USBEndpointAbort + (*USBError)(nil), // 62: daemon.USBError + (*USBIPServerStatusUpdate)(nil), // 63: daemon.USBIPServerStatusUpdate + (*USBIPServerStatus)(nil), // 64: daemon.USBIPServerStatus + (*USBSharedDevice)(nil), // 65: daemon.USBSharedDevice + (*OpenConnectStatusUpdate)(nil), // 66: daemon.OpenConnectStatusUpdate + (*OpenConnectEndpointStatus)(nil), // 67: daemon.OpenConnectEndpointStatus + (*OpenConnectTunnelInfo)(nil), // 68: daemon.OpenConnectTunnelInfo + (*OpenConnectAuthChallenge)(nil), // 69: daemon.OpenConnectAuthChallenge + (*OpenConnectAuthForm)(nil), // 70: daemon.OpenConnectAuthForm + (*OpenConnectAuthFormField)(nil), // 71: daemon.OpenConnectAuthFormField + (*OpenConnectAuthFormChoice)(nil), // 72: daemon.OpenConnectAuthFormChoice + (*OpenConnectBrowserRequest)(nil), // 73: daemon.OpenConnectBrowserRequest + (*OpenConnectBrowserCookie)(nil), // 74: daemon.OpenConnectBrowserCookie + (*OpenConnectBrowserHeader)(nil), // 75: daemon.OpenConnectBrowserHeader + (*OpenConnectAuthFormResponse)(nil), // 76: daemon.OpenConnectAuthFormResponse + (*OpenConnectBrowserResult)(nil), // 77: daemon.OpenConnectBrowserResult + (*OpenConnectAuthResponseSubmission)(nil), // 78: daemon.OpenConnectAuthResponseSubmission + (*OpenConnectAuthChallengeCancel)(nil), // 79: daemon.OpenConnectAuthChallengeCancel + (*OpenVPNStatusUpdate)(nil), // 80: daemon.OpenVPNStatusUpdate + (*OpenVPNEndpointStatus)(nil), // 81: daemon.OpenVPNEndpointStatus + (*OpenVPNTunnelInfo)(nil), // 82: daemon.OpenVPNTunnelInfo + (*OpenVPNChallenge)(nil), // 83: daemon.OpenVPNChallenge + (*OpenVPNChallengeSubmission)(nil), // 84: daemon.OpenVPNChallengeSubmission + (*OpenVPNChallengeCancel)(nil), // 85: daemon.OpenVPNChallengeCancel + (*Log_Message)(nil), // 86: daemon.Log.Message + nil, // 87: daemon.OpenConnectAuthFormResponse.ValuesEntry + (*emptypb.Empty)(nil), // 88: google.protobuf.Empty } ) var file_daemon_started_service_proto_depIdxs = []int32{ 4, // 0: daemon.ServiceStatus.status:type_name -> daemon.ServiceStatus.Type - 80, // 1: daemon.Log.messages:type_name -> daemon.Log.Message + 86, // 1: daemon.Log.messages:type_name -> daemon.Log.Message 0, // 2: daemon.DefaultLogLevel.level:type_name -> daemon.LogLevel 12, // 3: daemon.Groups.group:type_name -> daemon.Group 13, // 4: daemon.Group.items:type_name -> daemon.GroupItem @@ -6355,88 +6772,94 @@ var file_daemon_started_service_proto_depIdxs = []int32{ 3, // 38: daemon.USBSharedDevice.backend:type_name -> daemon.USBBackend 2, // 39: daemon.USBSharedDevice.state:type_name -> daemon.USBDeviceState 67, // 40: daemon.OpenConnectStatusUpdate.endpoints:type_name -> daemon.OpenConnectEndpointStatus - 69, // 41: daemon.OpenConnectEndpointStatus.authForm:type_name -> daemon.OpenConnectAuthForm + 69, // 41: daemon.OpenConnectEndpointStatus.authChallenge:type_name -> daemon.OpenConnectAuthChallenge 68, // 42: daemon.OpenConnectEndpointStatus.tunnelInfo:type_name -> daemon.OpenConnectTunnelInfo - 70, // 43: daemon.OpenConnectAuthForm.fields:type_name -> daemon.OpenConnectAuthFormField - 71, // 44: daemon.OpenConnectAuthFormField.options:type_name -> daemon.OpenConnectAuthFormChoice - 81, // 45: daemon.OpenConnectAuthFormSubmission.values:type_name -> daemon.OpenConnectAuthFormSubmission.ValuesEntry - 75, // 46: daemon.OpenVPNStatusUpdate.endpoints:type_name -> daemon.OpenVPNEndpointStatus - 77, // 47: daemon.OpenVPNEndpointStatus.challenge:type_name -> daemon.OpenVPNChallenge - 76, // 48: daemon.OpenVPNEndpointStatus.tunnelInfo:type_name -> daemon.OpenVPNTunnelInfo - 0, // 49: daemon.Log.Message.level:type_name -> daemon.LogLevel - 82, // 50: daemon.StartedService.GetVersion:input_type -> google.protobuf.Empty - 82, // 51: daemon.StartedService.SubscribeServiceStatus:input_type -> google.protobuf.Empty - 82, // 52: daemon.StartedService.SubscribeLog:input_type -> google.protobuf.Empty - 82, // 53: daemon.StartedService.GetDefaultLogLevel:input_type -> google.protobuf.Empty - 82, // 54: daemon.StartedService.ClearLogs:input_type -> google.protobuf.Empty - 7, // 55: daemon.StartedService.SubscribeStatus:input_type -> daemon.SubscribeStatusRequest - 82, // 56: daemon.StartedService.SubscribeGroups:input_type -> google.protobuf.Empty - 82, // 57: daemon.StartedService.GetClashModeStatus:input_type -> google.protobuf.Empty - 82, // 58: daemon.StartedService.SubscribeClashMode:input_type -> google.protobuf.Empty - 17, // 59: daemon.StartedService.SetClashMode:input_type -> daemon.ClashMode - 14, // 60: daemon.StartedService.URLTest:input_type -> daemon.URLTestRequest - 15, // 61: daemon.StartedService.SelectOutbound:input_type -> daemon.SelectOutboundRequest - 16, // 62: daemon.StartedService.SetGroupExpand:input_type -> daemon.SetGroupExpandRequest - 19, // 63: daemon.StartedService.SubscribeConnections:input_type -> daemon.SubscribeConnectionsRequest - 24, // 64: daemon.StartedService.CloseConnection:input_type -> daemon.CloseConnectionRequest - 82, // 65: daemon.StartedService.CloseAllConnections:input_type -> google.protobuf.Empty - 82, // 66: daemon.StartedService.GetDeprecatedWarnings:input_type -> google.protobuf.Empty - 82, // 67: daemon.StartedService.GetStartedAt:input_type -> google.protobuf.Empty - 82, // 68: daemon.StartedService.SubscribeOutbounds:input_type -> google.protobuf.Empty - 29, // 69: daemon.StartedService.StartNetworkQualityTest:input_type -> daemon.NetworkQualityTestRequest - 31, // 70: daemon.StartedService.StartSTUNTest:input_type -> daemon.STUNTestRequest - 82, // 71: daemon.StartedService.SubscribeTailscaleStatus:input_type -> google.protobuf.Empty - 37, // 72: daemon.StartedService.StartTailscalePing:input_type -> daemon.TailscalePingRequest - 39, // 73: daemon.StartedService.SetTailscaleExitNode:input_type -> daemon.SetTailscaleExitNodeRequest - 40, // 74: daemon.StartedService.TailscaleLogout:input_type -> daemon.TailscaleLogoutRequest - 41, // 75: daemon.StartedService.StartTailscaleSSHSession:input_type -> daemon.TailscaleSSHClientMessage - 51, // 76: daemon.StartedService.ProvideUSBDevices:input_type -> daemon.USBProviderMessage - 82, // 77: daemon.StartedService.SubscribeUSBIPServerStatus:input_type -> google.protobuf.Empty - 82, // 78: daemon.StartedService.SubscribeOpenConnectStatus:input_type -> google.protobuf.Empty - 72, // 79: daemon.StartedService.SubmitOpenConnectAuthForm:input_type -> daemon.OpenConnectAuthFormSubmission - 73, // 80: daemon.StartedService.CancelOpenConnectAuthForm:input_type -> daemon.OpenConnectAuthFormCancel - 82, // 81: daemon.StartedService.SubscribeOpenVPNStatus:input_type -> google.protobuf.Empty - 78, // 82: daemon.StartedService.SubmitOpenVPNChallengeResponse:input_type -> daemon.OpenVPNChallengeSubmission - 79, // 83: daemon.StartedService.CancelOpenVPNChallenge:input_type -> daemon.OpenVPNChallengeCancel - 5, // 84: daemon.StartedService.GetVersion:output_type -> daemon.Version - 6, // 85: daemon.StartedService.SubscribeServiceStatus:output_type -> daemon.ServiceStatus - 8, // 86: daemon.StartedService.SubscribeLog:output_type -> daemon.Log - 9, // 87: daemon.StartedService.GetDefaultLogLevel:output_type -> daemon.DefaultLogLevel - 82, // 88: daemon.StartedService.ClearLogs:output_type -> google.protobuf.Empty - 10, // 89: daemon.StartedService.SubscribeStatus:output_type -> daemon.Status - 11, // 90: daemon.StartedService.SubscribeGroups:output_type -> daemon.Groups - 18, // 91: daemon.StartedService.GetClashModeStatus:output_type -> daemon.ClashModeStatus - 17, // 92: daemon.StartedService.SubscribeClashMode:output_type -> daemon.ClashMode - 82, // 93: daemon.StartedService.SetClashMode:output_type -> google.protobuf.Empty - 82, // 94: daemon.StartedService.URLTest:output_type -> google.protobuf.Empty - 82, // 95: daemon.StartedService.SelectOutbound:output_type -> google.protobuf.Empty - 82, // 96: daemon.StartedService.SetGroupExpand:output_type -> google.protobuf.Empty - 21, // 97: daemon.StartedService.SubscribeConnections:output_type -> daemon.ConnectionEvents - 82, // 98: daemon.StartedService.CloseConnection:output_type -> google.protobuf.Empty - 82, // 99: daemon.StartedService.CloseAllConnections:output_type -> google.protobuf.Empty - 25, // 100: daemon.StartedService.GetDeprecatedWarnings:output_type -> daemon.DeprecatedWarnings - 27, // 101: daemon.StartedService.GetStartedAt:output_type -> daemon.StartedAt - 28, // 102: daemon.StartedService.SubscribeOutbounds:output_type -> daemon.OutboundList - 30, // 103: daemon.StartedService.StartNetworkQualityTest:output_type -> daemon.NetworkQualityTestProgress - 32, // 104: daemon.StartedService.StartSTUNTest:output_type -> daemon.STUNTestProgress - 33, // 105: daemon.StartedService.SubscribeTailscaleStatus:output_type -> daemon.TailscaleStatusUpdate - 38, // 106: daemon.StartedService.StartTailscalePing:output_type -> daemon.TailscalePingResponse - 82, // 107: daemon.StartedService.SetTailscaleExitNode:output_type -> google.protobuf.Empty - 82, // 108: daemon.StartedService.TailscaleLogout:output_type -> google.protobuf.Empty - 45, // 109: daemon.StartedService.StartTailscaleSSHSession:output_type -> daemon.TailscaleSSHServerMessage - 52, // 110: daemon.StartedService.ProvideUSBDevices:output_type -> daemon.USBServerMessage - 63, // 111: daemon.StartedService.SubscribeUSBIPServerStatus:output_type -> daemon.USBIPServerStatusUpdate - 66, // 112: daemon.StartedService.SubscribeOpenConnectStatus:output_type -> daemon.OpenConnectStatusUpdate - 82, // 113: daemon.StartedService.SubmitOpenConnectAuthForm:output_type -> google.protobuf.Empty - 82, // 114: daemon.StartedService.CancelOpenConnectAuthForm:output_type -> google.protobuf.Empty - 74, // 115: daemon.StartedService.SubscribeOpenVPNStatus:output_type -> daemon.OpenVPNStatusUpdate - 82, // 116: daemon.StartedService.SubmitOpenVPNChallengeResponse:output_type -> google.protobuf.Empty - 82, // 117: daemon.StartedService.CancelOpenVPNChallenge:output_type -> google.protobuf.Empty - 84, // [84:118] is the sub-list for method output_type - 50, // [50:84] is the sub-list for method input_type - 50, // [50:50] is the sub-list for extension type_name - 50, // [50:50] is the sub-list for extension extendee - 0, // [0:50] is the sub-list for field type_name + 70, // 43: daemon.OpenConnectAuthChallenge.form:type_name -> daemon.OpenConnectAuthForm + 73, // 44: daemon.OpenConnectAuthChallenge.browser:type_name -> daemon.OpenConnectBrowserRequest + 71, // 45: daemon.OpenConnectAuthForm.fields:type_name -> daemon.OpenConnectAuthFormField + 72, // 46: daemon.OpenConnectAuthFormField.options:type_name -> daemon.OpenConnectAuthFormChoice + 87, // 47: daemon.OpenConnectAuthFormResponse.values:type_name -> daemon.OpenConnectAuthFormResponse.ValuesEntry + 74, // 48: daemon.OpenConnectBrowserResult.cookies:type_name -> daemon.OpenConnectBrowserCookie + 75, // 49: daemon.OpenConnectBrowserResult.headers:type_name -> daemon.OpenConnectBrowserHeader + 76, // 50: daemon.OpenConnectAuthResponseSubmission.form:type_name -> daemon.OpenConnectAuthFormResponse + 77, // 51: daemon.OpenConnectAuthResponseSubmission.browser:type_name -> daemon.OpenConnectBrowserResult + 81, // 52: daemon.OpenVPNStatusUpdate.endpoints:type_name -> daemon.OpenVPNEndpointStatus + 83, // 53: daemon.OpenVPNEndpointStatus.challenge:type_name -> daemon.OpenVPNChallenge + 82, // 54: daemon.OpenVPNEndpointStatus.tunnelInfo:type_name -> daemon.OpenVPNTunnelInfo + 0, // 55: daemon.Log.Message.level:type_name -> daemon.LogLevel + 88, // 56: daemon.StartedService.GetVersion:input_type -> google.protobuf.Empty + 88, // 57: daemon.StartedService.SubscribeServiceStatus:input_type -> google.protobuf.Empty + 88, // 58: daemon.StartedService.SubscribeLog:input_type -> google.protobuf.Empty + 88, // 59: daemon.StartedService.GetDefaultLogLevel:input_type -> google.protobuf.Empty + 88, // 60: daemon.StartedService.ClearLogs:input_type -> google.protobuf.Empty + 7, // 61: daemon.StartedService.SubscribeStatus:input_type -> daemon.SubscribeStatusRequest + 88, // 62: daemon.StartedService.SubscribeGroups:input_type -> google.protobuf.Empty + 88, // 63: daemon.StartedService.GetClashModeStatus:input_type -> google.protobuf.Empty + 88, // 64: daemon.StartedService.SubscribeClashMode:input_type -> google.protobuf.Empty + 17, // 65: daemon.StartedService.SetClashMode:input_type -> daemon.ClashMode + 14, // 66: daemon.StartedService.URLTest:input_type -> daemon.URLTestRequest + 15, // 67: daemon.StartedService.SelectOutbound:input_type -> daemon.SelectOutboundRequest + 16, // 68: daemon.StartedService.SetGroupExpand:input_type -> daemon.SetGroupExpandRequest + 19, // 69: daemon.StartedService.SubscribeConnections:input_type -> daemon.SubscribeConnectionsRequest + 24, // 70: daemon.StartedService.CloseConnection:input_type -> daemon.CloseConnectionRequest + 88, // 71: daemon.StartedService.CloseAllConnections:input_type -> google.protobuf.Empty + 88, // 72: daemon.StartedService.GetDeprecatedWarnings:input_type -> google.protobuf.Empty + 88, // 73: daemon.StartedService.GetStartedAt:input_type -> google.protobuf.Empty + 88, // 74: daemon.StartedService.SubscribeOutbounds:input_type -> google.protobuf.Empty + 29, // 75: daemon.StartedService.StartNetworkQualityTest:input_type -> daemon.NetworkQualityTestRequest + 31, // 76: daemon.StartedService.StartSTUNTest:input_type -> daemon.STUNTestRequest + 88, // 77: daemon.StartedService.SubscribeTailscaleStatus:input_type -> google.protobuf.Empty + 37, // 78: daemon.StartedService.StartTailscalePing:input_type -> daemon.TailscalePingRequest + 39, // 79: daemon.StartedService.SetTailscaleExitNode:input_type -> daemon.SetTailscaleExitNodeRequest + 40, // 80: daemon.StartedService.TailscaleLogout:input_type -> daemon.TailscaleLogoutRequest + 41, // 81: daemon.StartedService.StartTailscaleSSHSession:input_type -> daemon.TailscaleSSHClientMessage + 51, // 82: daemon.StartedService.ProvideUSBDevices:input_type -> daemon.USBProviderMessage + 88, // 83: daemon.StartedService.SubscribeUSBIPServerStatus:input_type -> google.protobuf.Empty + 88, // 84: daemon.StartedService.SubscribeOpenConnectStatus:input_type -> google.protobuf.Empty + 78, // 85: daemon.StartedService.SubmitOpenConnectAuthResponse:input_type -> daemon.OpenConnectAuthResponseSubmission + 79, // 86: daemon.StartedService.CancelOpenConnectAuthChallenge:input_type -> daemon.OpenConnectAuthChallengeCancel + 88, // 87: daemon.StartedService.SubscribeOpenVPNStatus:input_type -> google.protobuf.Empty + 84, // 88: daemon.StartedService.SubmitOpenVPNChallengeResponse:input_type -> daemon.OpenVPNChallengeSubmission + 85, // 89: daemon.StartedService.CancelOpenVPNChallenge:input_type -> daemon.OpenVPNChallengeCancel + 5, // 90: daemon.StartedService.GetVersion:output_type -> daemon.Version + 6, // 91: daemon.StartedService.SubscribeServiceStatus:output_type -> daemon.ServiceStatus + 8, // 92: daemon.StartedService.SubscribeLog:output_type -> daemon.Log + 9, // 93: daemon.StartedService.GetDefaultLogLevel:output_type -> daemon.DefaultLogLevel + 88, // 94: daemon.StartedService.ClearLogs:output_type -> google.protobuf.Empty + 10, // 95: daemon.StartedService.SubscribeStatus:output_type -> daemon.Status + 11, // 96: daemon.StartedService.SubscribeGroups:output_type -> daemon.Groups + 18, // 97: daemon.StartedService.GetClashModeStatus:output_type -> daemon.ClashModeStatus + 17, // 98: daemon.StartedService.SubscribeClashMode:output_type -> daemon.ClashMode + 88, // 99: daemon.StartedService.SetClashMode:output_type -> google.protobuf.Empty + 88, // 100: daemon.StartedService.URLTest:output_type -> google.protobuf.Empty + 88, // 101: daemon.StartedService.SelectOutbound:output_type -> google.protobuf.Empty + 88, // 102: daemon.StartedService.SetGroupExpand:output_type -> google.protobuf.Empty + 21, // 103: daemon.StartedService.SubscribeConnections:output_type -> daemon.ConnectionEvents + 88, // 104: daemon.StartedService.CloseConnection:output_type -> google.protobuf.Empty + 88, // 105: daemon.StartedService.CloseAllConnections:output_type -> google.protobuf.Empty + 25, // 106: daemon.StartedService.GetDeprecatedWarnings:output_type -> daemon.DeprecatedWarnings + 27, // 107: daemon.StartedService.GetStartedAt:output_type -> daemon.StartedAt + 28, // 108: daemon.StartedService.SubscribeOutbounds:output_type -> daemon.OutboundList + 30, // 109: daemon.StartedService.StartNetworkQualityTest:output_type -> daemon.NetworkQualityTestProgress + 32, // 110: daemon.StartedService.StartSTUNTest:output_type -> daemon.STUNTestProgress + 33, // 111: daemon.StartedService.SubscribeTailscaleStatus:output_type -> daemon.TailscaleStatusUpdate + 38, // 112: daemon.StartedService.StartTailscalePing:output_type -> daemon.TailscalePingResponse + 88, // 113: daemon.StartedService.SetTailscaleExitNode:output_type -> google.protobuf.Empty + 88, // 114: daemon.StartedService.TailscaleLogout:output_type -> google.protobuf.Empty + 45, // 115: daemon.StartedService.StartTailscaleSSHSession:output_type -> daemon.TailscaleSSHServerMessage + 52, // 116: daemon.StartedService.ProvideUSBDevices:output_type -> daemon.USBServerMessage + 63, // 117: daemon.StartedService.SubscribeUSBIPServerStatus:output_type -> daemon.USBIPServerStatusUpdate + 66, // 118: daemon.StartedService.SubscribeOpenConnectStatus:output_type -> daemon.OpenConnectStatusUpdate + 88, // 119: daemon.StartedService.SubmitOpenConnectAuthResponse:output_type -> google.protobuf.Empty + 88, // 120: daemon.StartedService.CancelOpenConnectAuthChallenge:output_type -> google.protobuf.Empty + 80, // 121: daemon.StartedService.SubscribeOpenVPNStatus:output_type -> daemon.OpenVPNStatusUpdate + 88, // 122: daemon.StartedService.SubmitOpenVPNChallengeResponse:output_type -> google.protobuf.Empty + 88, // 123: daemon.StartedService.CancelOpenVPNChallenge:output_type -> google.protobuf.Empty + 90, // [90:124] is the sub-list for method output_type + 56, // [56:90] is the sub-list for method input_type + 56, // [56:56] is the sub-list for extension type_name + 56, // [56:56] is the sub-list for extension extendee + 0, // [0:56] is the sub-list for field type_name } func init() { file_daemon_started_service_proto_init() } @@ -6467,13 +6890,21 @@ func file_daemon_started_service_proto_init() { (*USBServerMessage_Abort)(nil), (*USBServerMessage_Error)(nil), } + file_daemon_started_service_proto_msgTypes[64].OneofWrappers = []any{ + (*OpenConnectAuthChallenge_Form)(nil), + (*OpenConnectAuthChallenge_Browser)(nil), + } + file_daemon_started_service_proto_msgTypes[73].OneofWrappers = []any{ + (*OpenConnectAuthResponseSubmission_Form)(nil), + (*OpenConnectAuthResponseSubmission_Browser)(nil), + } type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: unsafe.Slice(unsafe.StringData(file_daemon_started_service_proto_rawDesc), len(file_daemon_started_service_proto_rawDesc)), NumEnums: 5, - NumMessages: 77, + NumMessages: 83, NumExtensions: 0, NumServices: 1, }, diff --git a/daemon/started_service.proto b/daemon/started_service.proto index dd524275b..650f4122d 100644 --- a/daemon/started_service.proto +++ b/daemon/started_service.proto @@ -39,8 +39,8 @@ service StartedService { rpc ProvideUSBDevices(stream USBProviderMessage) returns (stream USBServerMessage) {} rpc SubscribeUSBIPServerStatus(google.protobuf.Empty) returns (stream USBIPServerStatusUpdate) {} rpc SubscribeOpenConnectStatus(google.protobuf.Empty) returns (stream OpenConnectStatusUpdate) {} - rpc SubmitOpenConnectAuthForm(OpenConnectAuthFormSubmission) returns (google.protobuf.Empty) {} - rpc CancelOpenConnectAuthForm(OpenConnectAuthFormCancel) returns (google.protobuf.Empty) {} + rpc SubmitOpenConnectAuthResponse(OpenConnectAuthResponseSubmission) returns (google.protobuf.Empty) {} + rpc CancelOpenConnectAuthChallenge(OpenConnectAuthChallengeCancel) returns (google.protobuf.Empty) {} rpc SubscribeOpenVPNStatus(google.protobuf.Empty) returns (stream OpenVPNStatusUpdate) {} rpc SubmitOpenVPNChallengeResponse(OpenVPNChallengeSubmission) returns (google.protobuf.Empty) {} rpc CancelOpenVPNChallenge(OpenVPNChallengeCancel) returns (google.protobuf.Empty) {} @@ -532,7 +532,7 @@ message OpenConnectEndpointStatus { string endpointTag = 1; string state = 2; string stateText = 3; - OpenConnectAuthForm authForm = 4; + OpenConnectAuthChallenge authChallenge = 4; string error = 5; OpenConnectTunnelInfo tunnelInfo = 6; } @@ -548,13 +548,19 @@ message OpenConnectTunnelInfo { int64 connectedSince = 8; } -message OpenConnectAuthForm { +message OpenConnectAuthChallenge { string id = 1; string banner = 2; string message = 3; string error = 4; - string url = 5; - repeated OpenConnectAuthFormField fields = 6; + oneof challenge { + OpenConnectAuthForm form = 5; + OpenConnectBrowserRequest browser = 6; + } +} + +message OpenConnectAuthForm { + repeated OpenConnectAuthFormField fields = 1; } message OpenConnectAuthFormField { @@ -571,15 +577,45 @@ message OpenConnectAuthFormChoice { string label = 2; } -message OpenConnectAuthFormSubmission { - string endpointTag = 1; - string formID = 2; - map values = 3; +message OpenConnectBrowserRequest { + string url = 1; + string finalURL = 2; + repeated string cookieNames = 3; + repeated string headerNames = 4; } -message OpenConnectAuthFormCancel { +message OpenConnectBrowserCookie { + string name = 1; + string value = 2; +} + +message OpenConnectBrowserHeader { + string name = 1; + repeated string values = 2; +} + +message OpenConnectAuthFormResponse { + map values = 1; +} + +message OpenConnectBrowserResult { + string finalURL = 1; + repeated OpenConnectBrowserCookie cookies = 2; + repeated OpenConnectBrowserHeader headers = 3; +} + +message OpenConnectAuthResponseSubmission { string endpointTag = 1; - string formID = 2; + string challengeID = 2; + oneof response { + OpenConnectAuthFormResponse form = 3; + OpenConnectBrowserResult browser = 4; + } +} + +message OpenConnectAuthChallengeCancel { + string endpointTag = 1; + string challengeID = 2; } message OpenVPNStatusUpdate { diff --git a/daemon/started_service_grpc.pb.go b/daemon/started_service_grpc.pb.go index bbd3ac04f..405c8368c 100644 --- a/daemon/started_service_grpc.pb.go +++ b/daemon/started_service_grpc.pb.go @@ -44,8 +44,8 @@ const ( StartedService_ProvideUSBDevices_FullMethodName = "/daemon.StartedService/ProvideUSBDevices" StartedService_SubscribeUSBIPServerStatus_FullMethodName = "/daemon.StartedService/SubscribeUSBIPServerStatus" StartedService_SubscribeOpenConnectStatus_FullMethodName = "/daemon.StartedService/SubscribeOpenConnectStatus" - StartedService_SubmitOpenConnectAuthForm_FullMethodName = "/daemon.StartedService/SubmitOpenConnectAuthForm" - StartedService_CancelOpenConnectAuthForm_FullMethodName = "/daemon.StartedService/CancelOpenConnectAuthForm" + StartedService_SubmitOpenConnectAuthResponse_FullMethodName = "/daemon.StartedService/SubmitOpenConnectAuthResponse" + StartedService_CancelOpenConnectAuthChallenge_FullMethodName = "/daemon.StartedService/CancelOpenConnectAuthChallenge" StartedService_SubscribeOpenVPNStatus_FullMethodName = "/daemon.StartedService/SubscribeOpenVPNStatus" StartedService_SubmitOpenVPNChallengeResponse_FullMethodName = "/daemon.StartedService/SubmitOpenVPNChallengeResponse" StartedService_CancelOpenVPNChallenge_FullMethodName = "/daemon.StartedService/CancelOpenVPNChallenge" @@ -84,8 +84,8 @@ type StartedServiceClient interface { ProvideUSBDevices(ctx context.Context, opts ...grpc.CallOption) (grpc.BidiStreamingClient[USBProviderMessage, USBServerMessage], error) SubscribeUSBIPServerStatus(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (grpc.ServerStreamingClient[USBIPServerStatusUpdate], error) SubscribeOpenConnectStatus(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (grpc.ServerStreamingClient[OpenConnectStatusUpdate], error) - SubmitOpenConnectAuthForm(ctx context.Context, in *OpenConnectAuthFormSubmission, opts ...grpc.CallOption) (*emptypb.Empty, error) - CancelOpenConnectAuthForm(ctx context.Context, in *OpenConnectAuthFormCancel, opts ...grpc.CallOption) (*emptypb.Empty, error) + SubmitOpenConnectAuthResponse(ctx context.Context, in *OpenConnectAuthResponseSubmission, opts ...grpc.CallOption) (*emptypb.Empty, error) + CancelOpenConnectAuthChallenge(ctx context.Context, in *OpenConnectAuthChallengeCancel, opts ...grpc.CallOption) (*emptypb.Empty, error) SubscribeOpenVPNStatus(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (grpc.ServerStreamingClient[OpenVPNStatusUpdate], error) SubmitOpenVPNChallengeResponse(ctx context.Context, in *OpenVPNChallengeSubmission, opts ...grpc.CallOption) (*emptypb.Empty, error) CancelOpenVPNChallenge(ctx context.Context, in *OpenVPNChallengeCancel, opts ...grpc.CallOption) (*emptypb.Empty, error) @@ -512,20 +512,20 @@ func (c *startedServiceClient) SubscribeOpenConnectStatus(ctx context.Context, i // This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name. type StartedService_SubscribeOpenConnectStatusClient = grpc.ServerStreamingClient[OpenConnectStatusUpdate] -func (c *startedServiceClient) SubmitOpenConnectAuthForm(ctx context.Context, in *OpenConnectAuthFormSubmission, opts ...grpc.CallOption) (*emptypb.Empty, error) { +func (c *startedServiceClient) SubmitOpenConnectAuthResponse(ctx context.Context, in *OpenConnectAuthResponseSubmission, opts ...grpc.CallOption) (*emptypb.Empty, error) { cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) out := new(emptypb.Empty) - err := c.cc.Invoke(ctx, StartedService_SubmitOpenConnectAuthForm_FullMethodName, in, out, cOpts...) + err := c.cc.Invoke(ctx, StartedService_SubmitOpenConnectAuthResponse_FullMethodName, in, out, cOpts...) if err != nil { return nil, err } return out, nil } -func (c *startedServiceClient) CancelOpenConnectAuthForm(ctx context.Context, in *OpenConnectAuthFormCancel, opts ...grpc.CallOption) (*emptypb.Empty, error) { +func (c *startedServiceClient) CancelOpenConnectAuthChallenge(ctx context.Context, in *OpenConnectAuthChallengeCancel, opts ...grpc.CallOption) (*emptypb.Empty, error) { cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) out := new(emptypb.Empty) - err := c.cc.Invoke(ctx, StartedService_CancelOpenConnectAuthForm_FullMethodName, in, out, cOpts...) + err := c.cc.Invoke(ctx, StartedService_CancelOpenConnectAuthChallenge_FullMethodName, in, out, cOpts...) if err != nil { return nil, err } @@ -604,8 +604,8 @@ type StartedServiceServer interface { ProvideUSBDevices(grpc.BidiStreamingServer[USBProviderMessage, USBServerMessage]) error SubscribeUSBIPServerStatus(*emptypb.Empty, grpc.ServerStreamingServer[USBIPServerStatusUpdate]) error SubscribeOpenConnectStatus(*emptypb.Empty, grpc.ServerStreamingServer[OpenConnectStatusUpdate]) error - SubmitOpenConnectAuthForm(context.Context, *OpenConnectAuthFormSubmission) (*emptypb.Empty, error) - CancelOpenConnectAuthForm(context.Context, *OpenConnectAuthFormCancel) (*emptypb.Empty, error) + SubmitOpenConnectAuthResponse(context.Context, *OpenConnectAuthResponseSubmission) (*emptypb.Empty, error) + CancelOpenConnectAuthChallenge(context.Context, *OpenConnectAuthChallengeCancel) (*emptypb.Empty, error) SubscribeOpenVPNStatus(*emptypb.Empty, grpc.ServerStreamingServer[OpenVPNStatusUpdate]) error SubmitOpenVPNChallengeResponse(context.Context, *OpenVPNChallengeSubmission) (*emptypb.Empty, error) CancelOpenVPNChallenge(context.Context, *OpenVPNChallengeCancel) (*emptypb.Empty, error) @@ -735,12 +735,12 @@ func (UnimplementedStartedServiceServer) SubscribeOpenConnectStatus(*emptypb.Emp return status.Error(codes.Unimplemented, "method SubscribeOpenConnectStatus not implemented") } -func (UnimplementedStartedServiceServer) SubmitOpenConnectAuthForm(context.Context, *OpenConnectAuthFormSubmission) (*emptypb.Empty, error) { - return nil, status.Error(codes.Unimplemented, "method SubmitOpenConnectAuthForm not implemented") +func (UnimplementedStartedServiceServer) SubmitOpenConnectAuthResponse(context.Context, *OpenConnectAuthResponseSubmission) (*emptypb.Empty, error) { + return nil, status.Error(codes.Unimplemented, "method SubmitOpenConnectAuthResponse not implemented") } -func (UnimplementedStartedServiceServer) CancelOpenConnectAuthForm(context.Context, *OpenConnectAuthFormCancel) (*emptypb.Empty, error) { - return nil, status.Error(codes.Unimplemented, "method CancelOpenConnectAuthForm not implemented") +func (UnimplementedStartedServiceServer) CancelOpenConnectAuthChallenge(context.Context, *OpenConnectAuthChallengeCancel) (*emptypb.Empty, error) { + return nil, status.Error(codes.Unimplemented, "method CancelOpenConnectAuthChallenge not implemented") } func (UnimplementedStartedServiceServer) SubscribeOpenVPNStatus(*emptypb.Empty, grpc.ServerStreamingServer[OpenVPNStatusUpdate]) error { @@ -1184,38 +1184,38 @@ func _StartedService_SubscribeOpenConnectStatus_Handler(srv interface{}, stream // This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name. type StartedService_SubscribeOpenConnectStatusServer = grpc.ServerStreamingServer[OpenConnectStatusUpdate] -func _StartedService_SubmitOpenConnectAuthForm_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(OpenConnectAuthFormSubmission) +func _StartedService_SubmitOpenConnectAuthResponse_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(OpenConnectAuthResponseSubmission) if err := dec(in); err != nil { return nil, err } if interceptor == nil { - return srv.(StartedServiceServer).SubmitOpenConnectAuthForm(ctx, in) + return srv.(StartedServiceServer).SubmitOpenConnectAuthResponse(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: StartedService_SubmitOpenConnectAuthForm_FullMethodName, + FullMethod: StartedService_SubmitOpenConnectAuthResponse_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(StartedServiceServer).SubmitOpenConnectAuthForm(ctx, req.(*OpenConnectAuthFormSubmission)) + return srv.(StartedServiceServer).SubmitOpenConnectAuthResponse(ctx, req.(*OpenConnectAuthResponseSubmission)) } return interceptor(ctx, in, info, handler) } -func _StartedService_CancelOpenConnectAuthForm_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(OpenConnectAuthFormCancel) +func _StartedService_CancelOpenConnectAuthChallenge_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(OpenConnectAuthChallengeCancel) if err := dec(in); err != nil { return nil, err } if interceptor == nil { - return srv.(StartedServiceServer).CancelOpenConnectAuthForm(ctx, in) + return srv.(StartedServiceServer).CancelOpenConnectAuthChallenge(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: StartedService_CancelOpenConnectAuthForm_FullMethodName, + FullMethod: StartedService_CancelOpenConnectAuthChallenge_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(StartedServiceServer).CancelOpenConnectAuthForm(ctx, req.(*OpenConnectAuthFormCancel)) + return srv.(StartedServiceServer).CancelOpenConnectAuthChallenge(ctx, req.(*OpenConnectAuthChallengeCancel)) } return interceptor(ctx, in, info, handler) } @@ -1331,12 +1331,12 @@ var StartedService_ServiceDesc = grpc.ServiceDesc{ Handler: _StartedService_TailscaleLogout_Handler, }, { - MethodName: "SubmitOpenConnectAuthForm", - Handler: _StartedService_SubmitOpenConnectAuthForm_Handler, + MethodName: "SubmitOpenConnectAuthResponse", + Handler: _StartedService_SubmitOpenConnectAuthResponse_Handler, }, { - MethodName: "CancelOpenConnectAuthForm", - Handler: _StartedService_CancelOpenConnectAuthForm_Handler, + MethodName: "CancelOpenConnectAuthChallenge", + Handler: _StartedService_CancelOpenConnectAuthChallenge_Handler, }, { MethodName: "SubmitOpenVPNChallengeResponse", diff --git a/experimental/libbox/command_client.go b/experimental/libbox/command_client.go index 4d7b54d4d..df466c870 100644 --- a/experimental/libbox/command_client.go +++ b/experimental/libbox/command_client.go @@ -966,29 +966,45 @@ func (c *CommandClient) SubscribeOpenConnectStatus(handler OpenConnectStatusHand return session, nil } -func (c *CommandClient) SubmitOpenConnectAuthForm(endpointTag string, formID string, values *OpenConnectFormValues) error { +func (c *CommandClient) SubmitOpenConnectAuthResponse(endpointTag string, challengeID string, response *OpenConnectAuthResponse) error { + submission := &daemon.OpenConnectAuthResponseSubmission{ + EndpointTag: endpointTag, + ChallengeID: challengeID, + } + if response.formValues != nil { + submission.Response = &daemon.OpenConnectAuthResponseSubmission_Form{Form: &daemon.OpenConnectAuthFormResponse{ + Values: response.formValues.values, + }} + } + if response.browserResult != nil { + submission.Response = &daemon.OpenConnectAuthResponseSubmission_Browser{Browser: &daemon.OpenConnectBrowserResult{ + FinalURL: response.browserResult.FinalURL, + Cookies: common.Map(response.browserResult.cookies, func(cookie openConnectBrowserCookie) *daemon.OpenConnectBrowserCookie { + return &daemon.OpenConnectBrowserCookie{Name: cookie.Name, Value: cookie.Value} + }), + Headers: common.Map(response.browserResult.headers, func(header openConnectBrowserHeader) *daemon.OpenConnectBrowserHeader { + return &daemon.OpenConnectBrowserHeader{Name: header.Name, Values: header.Values} + }), + }} + } _, err := callWithResult(c, func(ctx context.Context, client daemon.StartedServiceClient) (*emptypb.Empty, error) { - return client.SubmitOpenConnectAuthForm(ctx, &daemon.OpenConnectAuthFormSubmission{ - EndpointTag: endpointTag, - FormID: formID, - Values: values.values, - }) + return client.SubmitOpenConnectAuthResponse(ctx, submission) }) if err != nil { - return E.Cause(err, "submit openconnect authentication form") + return E.Cause(err, "submit openconnect authentication response") } return nil } -func (c *CommandClient) CancelOpenConnectAuthForm(endpointTag string, formID string) error { +func (c *CommandClient) CancelOpenConnectAuthChallenge(endpointTag string, challengeID string) error { _, err := callWithResult(c, func(ctx context.Context, client daemon.StartedServiceClient) (*emptypb.Empty, error) { - return client.CancelOpenConnectAuthForm(ctx, &daemon.OpenConnectAuthFormCancel{ + return client.CancelOpenConnectAuthChallenge(ctx, &daemon.OpenConnectAuthChallengeCancel{ EndpointTag: endpointTag, - FormID: formID, + ChallengeID: challengeID, }) }) if err != nil { - return E.Cause(err, "cancel openconnect authentication form") + return E.Cause(err, "cancel openconnect authentication challenge") } return nil } diff --git a/experimental/libbox/command_types_openconnect.go b/experimental/libbox/command_types_openconnect.go index 1f6658798..e384e04eb 100644 --- a/experimental/libbox/command_types_openconnect.go +++ b/experimental/libbox/command_types_openconnect.go @@ -19,12 +19,12 @@ type OpenConnectEndpointStatusIterator interface { } type OpenConnectEndpointStatus struct { - EndpointTag string - State string - StateText string - AuthForm *OpenConnectAuthForm - Error string - TunnelInfo *OpenConnectTunnelInfo + EndpointTag string + State string + StateText string + AuthChallenge *OpenConnectAuthChallenge + Error string + TunnelInfo *OpenConnectTunnelInfo } type OpenConnectTunnelInfo struct { @@ -50,19 +50,38 @@ func (i *OpenConnectTunnelInfo) DNS() StringIterator { return newIterator(i.dns) } -type OpenConnectAuthForm struct { +type OpenConnectAuthChallenge struct { ID string Banner string Message string Error string - URL string - fields []*OpenConnectAuthFormField + Form *OpenConnectAuthForm + Browser *OpenConnectBrowserRequest +} + +type OpenConnectAuthForm struct { + fields []*OpenConnectAuthFormField } func (f *OpenConnectAuthForm) Fields() OpenConnectAuthFormFieldIterator { return newIterator(f.fields) } +type OpenConnectBrowserRequest struct { + URL string + FinalURL string + cookieNames []string + headerNames []string +} + +func (r *OpenConnectBrowserRequest) CookieNames() StringIterator { + return newIterator(r.cookieNames) +} + +func (r *OpenConnectBrowserRequest) HeaderNames() StringIterator { + return newIterator(r.headerNames) +} + type OpenConnectAuthFormFieldIterator interface { Next() *OpenConnectAuthFormField HasNext() bool @@ -103,6 +122,53 @@ func (v *OpenConnectFormValues) Add(key string, value string) { v.values[key] = value } +type OpenConnectBrowserResult struct { + FinalURL string + cookies []openConnectBrowserCookie + headers []openConnectBrowserHeader +} + +func NewOpenConnectBrowserResult(finalURL string) *OpenConnectBrowserResult { + return &OpenConnectBrowserResult{FinalURL: finalURL} +} + +func (r *OpenConnectBrowserResult) AddCookie(name string, value string) { + r.cookies = append(r.cookies, openConnectBrowserCookie{Name: name, Value: value}) +} + +func (r *OpenConnectBrowserResult) AddHeader(name string, value string) { + for _, header := range r.headers { + if header.Name == name { + header.Values = append(header.Values, value) + return + } + } + r.headers = append(r.headers, openConnectBrowserHeader{Name: name, Values: []string{value}}) +} + +type openConnectBrowserCookie struct { + Name string + Value string +} + +type openConnectBrowserHeader struct { + Name string + Values []string +} + +type OpenConnectAuthResponse struct { + formValues *OpenConnectFormValues + browserResult *OpenConnectBrowserResult +} + +func NewOpenConnectAuthFormResponse(values *OpenConnectFormValues) *OpenConnectAuthResponse { + return &OpenConnectAuthResponse{formValues: values} +} + +func NewOpenConnectBrowserAuthResponse(result *OpenConnectBrowserResult) *OpenConnectAuthResponse { + return &OpenConnectAuthResponse{browserResult: result} +} + type OpenConnectStatusHandler interface { OnStatusUpdate(status *OpenConnectStatusUpdate) OnError(message string) @@ -125,30 +191,43 @@ func openConnectEndpointStatusFromGRPC(status *daemon.OpenConnectEndpointStatus) StateText: status.StateText, Error: status.Error, } - if status.AuthForm != nil { - fields := common.Map(status.AuthForm.Fields, func(field *daemon.OpenConnectAuthFormField) *OpenConnectAuthFormField { - return &OpenConnectAuthFormField{ - SubmissionKey: field.SubmissionKey, - Name: field.Name, - Label: field.Label, - Kind: field.Kind, - Value: field.Value, - options: common.Map(field.Options, func(option *daemon.OpenConnectAuthFormChoice) *OpenConnectAuthFormChoice { - return &OpenConnectAuthFormChoice{ - Value: option.Value, - Label: option.Label, + if status.AuthChallenge != nil { + challenge := &OpenConnectAuthChallenge{ + ID: status.AuthChallenge.Id, + Banner: status.AuthChallenge.Banner, + Message: status.AuthChallenge.Message, + Error: status.AuthChallenge.Error, + } + form := status.AuthChallenge.GetForm() + if form != nil { + challenge.Form = &OpenConnectAuthForm{ + fields: common.Map(form.Fields, func(field *daemon.OpenConnectAuthFormField) *OpenConnectAuthFormField { + return &OpenConnectAuthFormField{ + SubmissionKey: field.SubmissionKey, + Name: field.Name, + Label: field.Label, + Kind: field.Kind, + Value: field.Value, + options: common.Map(field.Options, func(option *daemon.OpenConnectAuthFormChoice) *OpenConnectAuthFormChoice { + return &OpenConnectAuthFormChoice{ + Value: option.Value, + Label: option.Label, + } + }), } }), } - }) - result.AuthForm = &OpenConnectAuthForm{ - ID: status.AuthForm.Id, - Banner: status.AuthForm.Banner, - Message: status.AuthForm.Message, - Error: status.AuthForm.Error, - URL: status.AuthForm.Url, - fields: fields, } + browser := status.AuthChallenge.GetBrowser() + if browser != nil { + challenge.Browser = &OpenConnectBrowserRequest{ + URL: browser.Url, + FinalURL: browser.FinalURL, + cookieNames: browser.CookieNames, + headerNames: browser.HeaderNames, + } + } + result.AuthChallenge = challenge } if status.TunnelInfo != nil { result.TunnelInfo = &OpenConnectTunnelInfo{ diff --git a/go.mod b/go.mod index 0bc3be05a..5004a6de4 100644 --- a/go.mod +++ b/go.mod @@ -46,8 +46,8 @@ require ( github.com/sagernet/sing v0.8.12-0.20260717153536-4f1ed45a99a5 github.com/sagernet/sing-cloudflared v0.1.3-0.20260706062323-d9787e794aa3 github.com/sagernet/sing-mux v0.3.5 - github.com/sagernet/sing-openconnect v0.0.0-20260717081856-cf2c71a71aba - github.com/sagernet/sing-openvpn v0.0.0-20260718013246-3cd8a7b83247 + github.com/sagernet/sing-openconnect v0.0.0-20260718163953-a1c7815e4f04 + github.com/sagernet/sing-openvpn v0.0.0-20260718163953-26ecbeb6352c github.com/sagernet/sing-quic v0.6.4-0.20260709034545-e23afe1172dc github.com/sagernet/sing-shadowsocks v0.2.8 github.com/sagernet/sing-shadowsocks2 v0.2.1 diff --git a/go.sum b/go.sum index e0bc38e90..30e2cf36e 100644 --- a/go.sum +++ b/go.sum @@ -285,10 +285,10 @@ github.com/sagernet/sing-cloudflared v0.1.3-0.20260706062323-d9787e794aa3 h1:3y6 github.com/sagernet/sing-cloudflared v0.1.3-0.20260706062323-d9787e794aa3/go.mod h1:XEqEDYRCAYLaoPjZ1ifVWJg5iWAJHL2gOAXe/PM28Cg= github.com/sagernet/sing-mux v0.3.5 h1:RHnhVEc+SFqkrK4xMygYjDwwLhzp2Bj3lztSukONfhI= github.com/sagernet/sing-mux v0.3.5/go.mod h1:QvlKMyNBNrQoyX4x+gq028uPbLM2XeRpWtDsWBJbFSk= -github.com/sagernet/sing-openconnect v0.0.0-20260717081856-cf2c71a71aba h1:S87Ej/jFssn0qhPF1ExF0YIV0USfGZF2If6kSjGLPt8= -github.com/sagernet/sing-openconnect v0.0.0-20260717081856-cf2c71a71aba/go.mod h1:EIzh5HtImfQJxPKXFwS9lyMnmMy4aCQCx7ntQ4u41Gs= -github.com/sagernet/sing-openvpn v0.0.0-20260718013246-3cd8a7b83247 h1:IfZqHohaWz13eqc6SAUHkmP9xhMpMBDIShl7OtgRd5Y= -github.com/sagernet/sing-openvpn v0.0.0-20260718013246-3cd8a7b83247/go.mod h1:CmTGnS5ijVSqFQV1dTq4WvFLUoz7bk9xasBPsX8NcYo= +github.com/sagernet/sing-openconnect v0.0.0-20260718163953-a1c7815e4f04 h1:HIb3Tu19qqH5fD5xnyyHb6zJaETIsnXamb/hWTtxil8= +github.com/sagernet/sing-openconnect v0.0.0-20260718163953-a1c7815e4f04/go.mod h1:EIzh5HtImfQJxPKXFwS9lyMnmMy4aCQCx7ntQ4u41Gs= +github.com/sagernet/sing-openvpn v0.0.0-20260718163953-26ecbeb6352c h1:EhwLZF3IUyDj4uZ7vkUZAI7GymXCeOCwiseuOTsFjp8= +github.com/sagernet/sing-openvpn v0.0.0-20260718163953-26ecbeb6352c/go.mod h1:CmTGnS5ijVSqFQV1dTq4WvFLUoz7bk9xasBPsX8NcYo= github.com/sagernet/sing-quic v0.6.4-0.20260709034545-e23afe1172dc h1:zdc0fj4JdAdgAmQIoh7ZF+B/wPTEF2X75lYDqTmvlaw= github.com/sagernet/sing-quic v0.6.4-0.20260709034545-e23afe1172dc/go.mod h1:9k+dzGsWMttUGldBzq3dU792YHXzW6NgfbOGltnXq+0= github.com/sagernet/sing-shadowsocks v0.2.8 h1:PURj5PRoAkqeHh2ZW205RWzN9E9RtKCVCzByXruQWfE= diff --git a/protocol/openconnect/client.go b/protocol/openconnect/client.go index 84f8820a0..553fb9a6b 100644 --- a/protocol/openconnect/client.go +++ b/protocol/openconnect/client.go @@ -364,7 +364,10 @@ func (e *Endpoint) readLoop() { err = e.device.WriteInboundBuffers(packetBuffers) buf.ReleaseMulti(packetBuffers) if err != nil { - e.logger.Error(E.Cause(err, "write OpenConnect packet to device")) + err = E.Cause(err, "write packet to device") + e.logger.Error(err) + e.setTerminalError(err) + return } } } diff --git a/protocol/openconnect/status.go b/protocol/openconnect/status.go index 13eff5059..ea0cd8fbe 100644 --- a/protocol/openconnect/status.go +++ b/protocol/openconnect/status.go @@ -1,6 +1,7 @@ package openconnect import ( + "net/http" "slices" "github.com/sagernet/sing-box/adapter" @@ -13,37 +14,48 @@ var _ adapter.OpenConnectEndpoint = (*Endpoint)(nil) func (e *Endpoint) OpenConnectStatus() adapter.OpenConnectStatus { var status adapter.OpenConnectStatus clientState := e.state.Load() - authForm := e.client.PendingAuthForm() + authChallenge := e.client.PendingAuthChallenge() e.statusAccess.Lock() status.Error = e.terminalError e.statusAccess.Unlock() - if authForm != nil { - fields := common.Map(authForm.Fields, func(field openconnect.AuthFormField) adapter.OpenConnectAuthFormField { - return adapter.OpenConnectAuthFormField{ - SubmissionKey: field.SubmissionKey, - Name: field.Name, - Label: field.Label, - Kind: field.Kind, - Value: field.Value, - Options: common.Map(field.Options, func(choice openconnect.AuthFormChoice) adapter.OpenConnectAuthFormChoice { - return adapter.OpenConnectAuthFormChoice{ - Value: choice.Value, - Label: choice.Label, + if authChallenge != nil { + challenge := &adapter.OpenConnectAuthChallenge{ + ID: authChallenge.ID, + Banner: authChallenge.Banner, + Message: authChallenge.Message, + Error: authChallenge.Error, + } + if authChallenge.Form != nil { + challenge.Form = &adapter.OpenConnectAuthForm{ + Fields: common.Map(authChallenge.Form.Fields, func(field openconnect.AuthFormField) adapter.OpenConnectAuthFormField { + return adapter.OpenConnectAuthFormField{ + SubmissionKey: field.SubmissionKey, + Name: field.Name, + Label: field.Label, + Kind: field.Kind, + Value: field.Value, + Options: common.Map(field.Options, func(choice openconnect.AuthFormChoice) adapter.OpenConnectAuthFormChoice { + return adapter.OpenConnectAuthFormChoice{ + Value: choice.Value, + Label: choice.Label, + } + }), } }), } - }) - status.AuthForm = &adapter.OpenConnectAuthForm{ - ID: authForm.ID, - Banner: authForm.Banner, - Message: authForm.Message, - Error: authForm.Error, - URL: authForm.URL, - Fields: fields, } + if authChallenge.Browser != nil { + challenge.Browser = &adapter.OpenConnectBrowserRequest{ + URL: authChallenge.Browser.URL, + FinalURL: authChallenge.Browser.FinalURL, + CookieNames: slices.Clone(authChallenge.Browser.CookieNames), + HeaderNames: slices.Clone(authChallenge.Browser.HeaderNames), + } + } + status.AuthChallenge = challenge } switch { - case status.AuthForm != nil: + case status.AuthChallenge != nil: status.State = adapter.OpenConnectStateAuthPending case status.Error != "": status.State = adapter.OpenConnectStateError @@ -66,12 +78,31 @@ func (e *Endpoint) StatusUpdated() <-chan struct{} { return e.statusUpdated } -func (e *Endpoint) CompleteAuthForm(formID string, values map[string]string) error { - return e.client.CompleteAuthForm(formID, values) +func (e *Endpoint) CompleteAuthChallenge(challengeID string, response adapter.OpenConnectAuthResponse) error { + var authResponse openconnect.AuthResponse + if response.Form != nil { + authResponse.Form = &openconnect.AuthFormResponse{Values: response.Form.Values} + } + if response.Browser != nil { + browserResult := &openconnect.BrowserResult{ + FinalURL: response.Browser.FinalURL, + Cookies: common.Map(response.Browser.Cookies, func(cookie adapter.OpenConnectBrowserCookie) openconnect.BrowserCookie { + return openconnect.BrowserCookie{Name: cookie.Name, Value: cookie.Value} + }), + Header: make(http.Header), + } + for _, header := range response.Browser.Headers { + for _, value := range header.Values { + browserResult.Header.Add(header.Name, value) + } + } + authResponse.Browser = browserResult + } + return e.client.CompleteAuthChallenge(challengeID, authResponse) } -func (e *Endpoint) CancelAuthForm(formID string) error { - return e.client.CancelAuthForm(formID) +func (e *Endpoint) CancelAuthChallenge(challengeID string) error { + return e.client.CancelAuthChallenge(challengeID) } func (e *Endpoint) notifyStatusUpdated() { @@ -94,14 +125,14 @@ func (e *Endpoint) setTerminalError(err error) { func (e *Endpoint) watchAuthForms() { defer close(e.authFormLoopDone) - var loggedAuthFormID string + var loggedAuthChallengeID string for { - authFormUpdated := e.client.AuthFormUpdated() - authForm := e.client.PendingAuthForm() - if authForm != nil && authForm.ID != loggedAuthFormID { - loggedAuthFormID = authForm.ID - if authForm.URL != "" { - e.logger.Info("waiting for authentication: ", authForm.URL) + authChallengeUpdated := e.client.AuthChallengeUpdated() + authChallenge := e.client.PendingAuthChallenge() + if authChallenge != nil && authChallenge.ID != loggedAuthChallengeID { + loggedAuthChallengeID = authChallenge.ID + if authChallenge.Browser != nil { + e.logger.Info("waiting for browser authentication") } else { e.logger.Info("waiting for authentication") } @@ -110,7 +141,7 @@ func (e *Endpoint) watchAuthForms() { select { case <-e.loopContext.Done(): return - case <-authFormUpdated: + case <-authChallengeUpdated: } } } diff --git a/protocol/openvpn/client.go b/protocol/openvpn/client.go index d3b4323d7..2677d6500 100644 --- a/protocol/openvpn/client.go +++ b/protocol/openvpn/client.go @@ -425,7 +425,10 @@ func (c *ClientEndpoint) readLoop() { err = c.device.WriteInboundBuffers(packetBuffers) buf.ReleaseMulti(packetBuffers) if err != nil { - c.logger.Error(E.Cause(err, "write OpenVPN packet to device")) + err = E.Cause(err, "write packet to device") + c.logger.Error(err) + c.setTerminalError(err) + return } } } diff --git a/protocol/openvpn/server.go b/protocol/openvpn/server.go index 0001f1831..8c5dc0439 100644 --- a/protocol/openvpn/server.go +++ b/protocol/openvpn/server.go @@ -433,7 +433,8 @@ func (s *ServerEndpoint) readLoop() { err = s.device.WriteInboundBuffers(packetBuffers) buf.ReleaseMulti(packetBuffers) if err != nil { - s.logger.Error(E.Cause(err, "write OpenVPN packet to device")) + s.logger.Error(E.Cause(err, "write packet to device")) + return } } } diff --git a/test/go.mod b/test/go.mod index 5bb65a5eb..b42fbe5c5 100644 --- a/test/go.mod +++ b/test/go.mod @@ -153,8 +153,8 @@ require ( github.com/sagernet/nftables v0.3.0-mod.4 // indirect github.com/sagernet/sing-cloudflared v0.1.3-0.20260706062323-d9787e794aa3 // indirect github.com/sagernet/sing-mux v0.3.5 // indirect - github.com/sagernet/sing-openconnect v0.0.0-20260717081856-cf2c71a71aba // indirect - github.com/sagernet/sing-openvpn v0.0.0-20260718013246-3cd8a7b83247 // indirect + github.com/sagernet/sing-openconnect v0.0.0-20260718163953-a1c7815e4f04 // indirect + github.com/sagernet/sing-openvpn v0.0.0-20260718163953-26ecbeb6352c // indirect github.com/sagernet/sing-shadowtls v0.2.1 // indirect github.com/sagernet/sing-snell v0.0.0-20260710094516-a4e97ee24beb // indirect github.com/sagernet/sing-usbip v0.0.0-20260616101517-efb91521eddb // indirect diff --git a/test/go.sum b/test/go.sum index 80e57b66f..6712ad5f1 100644 --- a/test/go.sum +++ b/test/go.sum @@ -304,10 +304,10 @@ github.com/sagernet/sing-cloudflared v0.1.3-0.20260706062323-d9787e794aa3 h1:3y6 github.com/sagernet/sing-cloudflared v0.1.3-0.20260706062323-d9787e794aa3/go.mod h1:XEqEDYRCAYLaoPjZ1ifVWJg5iWAJHL2gOAXe/PM28Cg= github.com/sagernet/sing-mux v0.3.5 h1:RHnhVEc+SFqkrK4xMygYjDwwLhzp2Bj3lztSukONfhI= github.com/sagernet/sing-mux v0.3.5/go.mod h1:QvlKMyNBNrQoyX4x+gq028uPbLM2XeRpWtDsWBJbFSk= -github.com/sagernet/sing-openconnect v0.0.0-20260717081856-cf2c71a71aba h1:S87Ej/jFssn0qhPF1ExF0YIV0USfGZF2If6kSjGLPt8= -github.com/sagernet/sing-openconnect v0.0.0-20260717081856-cf2c71a71aba/go.mod h1:EIzh5HtImfQJxPKXFwS9lyMnmMy4aCQCx7ntQ4u41Gs= -github.com/sagernet/sing-openvpn v0.0.0-20260718013246-3cd8a7b83247 h1:IfZqHohaWz13eqc6SAUHkmP9xhMpMBDIShl7OtgRd5Y= -github.com/sagernet/sing-openvpn v0.0.0-20260718013246-3cd8a7b83247/go.mod h1:CmTGnS5ijVSqFQV1dTq4WvFLUoz7bk9xasBPsX8NcYo= +github.com/sagernet/sing-openconnect v0.0.0-20260718163953-a1c7815e4f04 h1:HIb3Tu19qqH5fD5xnyyHb6zJaETIsnXamb/hWTtxil8= +github.com/sagernet/sing-openconnect v0.0.0-20260718163953-a1c7815e4f04/go.mod h1:EIzh5HtImfQJxPKXFwS9lyMnmMy4aCQCx7ntQ4u41Gs= +github.com/sagernet/sing-openvpn v0.0.0-20260718163953-26ecbeb6352c h1:EhwLZF3IUyDj4uZ7vkUZAI7GymXCeOCwiseuOTsFjp8= +github.com/sagernet/sing-openvpn v0.0.0-20260718163953-26ecbeb6352c/go.mod h1:CmTGnS5ijVSqFQV1dTq4WvFLUoz7bk9xasBPsX8NcYo= github.com/sagernet/sing-quic v0.6.4-0.20260709034545-e23afe1172dc h1:zdc0fj4JdAdgAmQIoh7ZF+B/wPTEF2X75lYDqTmvlaw= github.com/sagernet/sing-quic v0.6.4-0.20260709034545-e23afe1172dc/go.mod h1:9k+dzGsWMttUGldBzq3dU792YHXzW6NgfbOGltnXq+0= github.com/sagernet/sing-shadowsocks v0.2.8 h1:PURj5PRoAkqeHh2ZW205RWzN9E9RtKCVCzByXruQWfE= diff --git a/test/openconnect_test.go b/test/openconnect_test.go index 6b494478a..5ec905b3e 100644 --- a/test/openconnect_test.go +++ b/test/openconnect_test.go @@ -123,7 +123,7 @@ func TestOpenConnectDockerInterop(t *testing.T) { )) endpoint := requireOpenConnectEndpoint(subtest, instance) status := waitForOpenConnectState(subtest, endpoint, adapter.OpenConnectStateConnected, 45*time.Second) - require.Nil(subtest, status.AuthForm) + require.Nil(subtest, status.AuthChallenge) err := exchangeOpenConnectTCPEcho(endpoint, 256*1024, 30*time.Second) require.NoError(subtest, err) err = exchangeOpenConnectUDPEcho(endpoint, 1400, 30*time.Second) @@ -167,7 +167,7 @@ func TestOpenConnectDockerInterop(t *testing.T) { status := endpoint.OpenConnectStatus() require.Equal(subtest, adapter.OpenConnectStateConnected, status.State, status.Error) - require.Nil(subtest, status.AuthForm) + require.Nil(subtest, status.AuthChallenge) logs, err := openConnectDockerOutput(ctx, "logs", container.name) require.NoError(subtest, err) require.GreaterOrEqual(subtest, strings.Count(logs, "HTTP CONNECT /CSCOSSLC/tunnel"), 2, logs) @@ -254,13 +254,15 @@ func driveOpenConnectInteractiveAuthentication(t *testing.T, endpoint adapter.Op case adapter.OpenConnectStateError: t.Fatal(status.Error) case adapter.OpenConnectStateAuthPending: - form := status.AuthForm - require.NotNil(t, form) - require.NotEmpty(t, form.ID) - _, completed := completedForms[form.ID] + challenge := status.AuthChallenge + require.NotNil(t, challenge) + require.NotNil(t, challenge.Form) + require.Nil(t, challenge.Browser) + require.NotEmpty(t, challenge.ID) + _, completed := completedForms[challenge.ID] if !completed { - values := make(map[string]string, len(form.Fields)) - for _, field := range form.Fields { + values := make(map[string]string, len(challenge.Form.Fields)) + for _, field := range challenge.Form.Fields { require.NotEmpty(t, field.SubmissionKey) switch field.Name { case "username": @@ -274,9 +276,11 @@ func driveOpenConnectInteractiveAuthentication(t *testing.T, endpoint adapter.Op } } require.NotEmpty(t, values) - err := endpoint.CompleteAuthForm(form.ID, values) + err := endpoint.CompleteAuthChallenge(challenge.ID, adapter.OpenConnectAuthResponse{ + Form: &adapter.OpenConnectAuthFormResponse{Values: values}, + }) require.NoError(t, err) - completedForms[form.ID] = struct{}{} + completedForms[challenge.ID] = struct{}{} continue } } diff --git a/transport/openconnect/device_system.go b/transport/openconnect/device_system.go index ab6d01b7c..2b73b773c 100644 --- a/transport/openconnect/device_system.go +++ b/transport/openconnect/device_system.go @@ -150,7 +150,7 @@ func (d *systemDevice) readLoop(tunInterface tun.Tun, mtu int) { return } d.options.Logger.Error(E.Cause(err, "read packet")) - continue + return } if readN <= tun.PacketOffset { continue @@ -162,6 +162,7 @@ func (d *systemDevice) readLoop(tunInterface tun.Tun, mtu int) { packetBuffer.DecRef() if err != nil { d.options.Logger.Error(E.Cause(err, "write packet")) + return } } } @@ -192,6 +193,7 @@ func (d *systemDevice) readLoopLinux(tunInterface tun.LinuxTUN, batchSize int, m } if writeErr != nil { d.options.Logger.Error(E.Cause(writeErr, "write packet batch")) + return } } if readErr != nil { @@ -199,6 +201,7 @@ func (d *systemDevice) readLoopLinux(tunInterface tun.LinuxTUN, batchSize int, m return } d.options.Logger.Error(E.Cause(readErr, "batch read packet")) + return } } } @@ -218,6 +221,7 @@ func (d *systemDevice) readLoopDarwin(tunInterface tun.DarwinTUN) { writeErr := d.writeOutbound(outboundBuffers) if writeErr != nil { d.options.Logger.Error(E.Cause(writeErr, "write packet batch")) + return } } if readErr != nil { @@ -225,6 +229,7 @@ func (d *systemDevice) readLoopDarwin(tunInterface tun.DarwinTUN) { return } d.options.Logger.Error(E.Cause(readErr, "batch read packet")) + return } } } diff --git a/transport/openvpn/device_stack.go b/transport/openvpn/device_stack.go index c13c994af..6dc8eab4d 100644 --- a/transport/openvpn/device_stack.go +++ b/transport/openvpn/device_stack.go @@ -103,6 +103,7 @@ func (d *stackDevice) UpdateConfiguration(configuration Configuration) error { defer d.stateAccess.Unlock() if d.logRouteOptions && hasRouteOptions(configuration.Routes) { d.options.Logger.Debug("OpenVPN route gateway and metric options are not representable by the gVisor stack device; routes are installed by prefix") + d.logRouteOptions = false } if configuration.MTU != 0 { d.options.MTU = configuration.MTU diff --git a/transport/openvpn/device_system.go b/transport/openvpn/device_system.go index bea50ab2c..85c257cf4 100644 --- a/transport/openvpn/device_system.go +++ b/transport/openvpn/device_system.go @@ -30,13 +30,14 @@ const ( type systemDevice struct { baseDevice - stateAccess sync.RWMutex - options DeviceOptions - dialer N.Dialer - device tun.Tun - inet4Address netip.Addr - inet6Address netip.Addr - closed bool + stateAccess sync.RWMutex + options DeviceOptions + dialer N.Dialer + device tun.Tun + inet4Address netip.Addr + inet6Address netip.Addr + logRouteOptions bool + closed bool } func newSystemDevice(options DeviceOptions) (*systemDevice, error) { @@ -54,10 +55,11 @@ func newSystemDevice(options DeviceOptions) (*systemDevice, error) { } inet4Address, inet6Address := firstAddresses(options.Configuration.Address) return &systemDevice{ - options: options, - dialer: interfaceDialer, - inet4Address: inet4Address, - inet6Address: inet6Address, + options: options, + dialer: interfaceDialer, + inet4Address: inet4Address, + inet6Address: inet6Address, + logRouteOptions: true, }, nil } @@ -191,7 +193,7 @@ func (d *systemDevice) readLoop(tunInterface tun.Tun, mtu int) { return } d.options.Logger.Error(E.Cause(err, "read packet")) - continue + return } if readN <= tun.PacketOffset { continue @@ -206,6 +208,7 @@ func (d *systemDevice) readLoop(tunInterface tun.Tun, mtu int) { packetBuffer.DecRef() if err != nil { d.options.Logger.Error(E.Cause(err, "write packet")) + return } } } @@ -243,6 +246,7 @@ func (d *systemDevice) readLoopLinux(tunInterface tun.LinuxTUN, batchSize int, m } if writeErr != nil { d.options.Logger.Error(E.Cause(writeErr, "write packet batch")) + return } } if readErr != nil { @@ -250,6 +254,7 @@ func (d *systemDevice) readLoopLinux(tunInterface tun.LinuxTUN, batchSize int, m return } d.options.Logger.Error(E.Cause(readErr, "batch read packet")) + return } } } @@ -274,6 +279,7 @@ func (d *systemDevice) readLoopDarwin(tunInterface tun.DarwinTUN) { writeErr := d.writeOutbound(outboundBuffers) if writeErr != nil { d.options.Logger.Error(E.Cause(writeErr, "write packet batch")) + return } } if readErr != nil { @@ -281,6 +287,7 @@ func (d *systemDevice) readLoopDarwin(tunInterface tun.DarwinTUN) { return } d.options.Logger.Error(E.Cause(readErr, "batch read packet")) + return } } } @@ -291,8 +298,9 @@ func (d *systemDevice) UpdateConfiguration(configuration Configuration) error { routes := routesWithBlockIPv6(configuration) _, hasUnrepresentableInet4RouteOptions := systemRouteGateway(routes, true) _, hasUnrepresentableInet6RouteOptions := systemRouteGateway(routes, false) - if hasUnrepresentableInet4RouteOptions || hasUnrepresentableInet6RouteOptions { + if d.logRouteOptions && (hasUnrepresentableInet4RouteOptions || hasUnrepresentableInet6RouteOptions) { d.options.Logger.Debug("some OpenVPN route gateway or metric options are not representable by the system device; routes are installed by prefix") + d.logRouteOptions = false } previousConfiguration := d.options.Configuration previousMTU := d.options.MTU