Fix Fortinet SSO again
This commit is contained in:
@@ -32,6 +32,8 @@ type V2RayServer interface {
|
||||
type CacheFile interface {
|
||||
LifecycleService
|
||||
|
||||
CacheID() string
|
||||
|
||||
StoreFakeIP() bool
|
||||
FakeIPStorage
|
||||
|
||||
|
||||
@@ -52,10 +52,13 @@ type OpenConnectAuthForm struct {
|
||||
}
|
||||
|
||||
type OpenConnectBrowserRequest struct {
|
||||
URL string
|
||||
FinalURL string
|
||||
CookieNames []string
|
||||
HeaderNames []string
|
||||
URL string
|
||||
FinalURL string
|
||||
CookieNames []string
|
||||
EarlyCookieNames []string
|
||||
HeaderNames []string
|
||||
CallbackURLPrefixes []string
|
||||
CacheID string
|
||||
}
|
||||
|
||||
type OpenConnectBrowserCookie struct {
|
||||
|
||||
@@ -163,14 +163,14 @@ func buildAndroid() {
|
||||
|
||||
bindTarget := getAndroidBindTarget()
|
||||
|
||||
// Build main variant (SDK 23)
|
||||
// Build main variant (SDK 24)
|
||||
mainTags := append([]string{}, sharedTags...)
|
||||
// mainTags = append(mainTags, memcTags...)
|
||||
if debugEnabled {
|
||||
mainTags = append(mainTags, debugTags...)
|
||||
}
|
||||
buildAndroidVariant(AndroidBuildConfig{
|
||||
AndroidAPI: 23,
|
||||
AndroidAPI: 24,
|
||||
OutputName: "libbox.aar",
|
||||
Tags: mainTags,
|
||||
}, bindTarget)
|
||||
|
||||
@@ -1649,10 +1649,13 @@ func openConnectEndpointStatusToProto(tag string, endpointStatus adapter.OpenCon
|
||||
}
|
||||
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,
|
||||
Url: endpointStatus.AuthChallenge.Browser.URL,
|
||||
FinalURL: endpointStatus.AuthChallenge.Browser.FinalURL,
|
||||
CookieNames: endpointStatus.AuthChallenge.Browser.CookieNames,
|
||||
EarlyCookieNames: endpointStatus.AuthChallenge.Browser.EarlyCookieNames,
|
||||
HeaderNames: endpointStatus.AuthChallenge.Browser.HeaderNames,
|
||||
CallbackURLPrefixes: endpointStatus.AuthChallenge.Browser.CallbackURLPrefixes,
|
||||
CacheID: endpointStatus.AuthChallenge.Browser.CacheID,
|
||||
}}
|
||||
}
|
||||
result.AuthChallenge = challenge
|
||||
|
||||
@@ -5149,13 +5149,16 @@ func (x *OpenConnectAuthFormChoice) GetLabel() string {
|
||||
}
|
||||
|
||||
type OpenConnectBrowserRequest struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
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
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
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"`
|
||||
CallbackURLPrefixes []string `protobuf:"bytes,5,rep,name=callbackURLPrefixes,proto3" json:"callbackURLPrefixes,omitempty"`
|
||||
EarlyCookieNames []string `protobuf:"bytes,6,rep,name=earlyCookieNames,proto3" json:"earlyCookieNames,omitempty"`
|
||||
CacheID string `protobuf:"bytes,7,opt,name=cacheID,proto3" json:"cacheID,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *OpenConnectBrowserRequest) Reset() {
|
||||
@@ -5216,6 +5219,27 @@ func (x *OpenConnectBrowserRequest) GetHeaderNames() []string {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *OpenConnectBrowserRequest) GetCallbackURLPrefixes() []string {
|
||||
if x != nil {
|
||||
return x.CallbackURLPrefixes
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *OpenConnectBrowserRequest) GetEarlyCookieNames() []string {
|
||||
if x != nil {
|
||||
return x.EarlyCookieNames
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *OpenConnectBrowserRequest) GetCacheID() string {
|
||||
if x != nil {
|
||||
return x.CacheID
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type OpenConnectBrowserCookie struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
|
||||
@@ -6492,12 +6516,15 @@ 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\"\x8d\x01\n" +
|
||||
"\x05label\x18\x02 \x01(\tR\x05label\"\x85\x02\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" +
|
||||
"\vheaderNames\x18\x04 \x03(\tR\vheaderNames\x120\n" +
|
||||
"\x13callbackURLPrefixes\x18\x05 \x03(\tR\x13callbackURLPrefixes\x12*\n" +
|
||||
"\x10earlyCookieNames\x18\x06 \x03(\tR\x10earlyCookieNames\x12\x18\n" +
|
||||
"\acacheID\x18\a \x01(\tR\acacheID\"D\n" +
|
||||
"\x18OpenConnectBrowserCookie\x12\x12\n" +
|
||||
"\x04name\x18\x01 \x01(\tR\x04name\x12\x14\n" +
|
||||
"\x05value\x18\x02 \x01(\tR\x05value\"F\n" +
|
||||
|
||||
@@ -582,6 +582,9 @@ message OpenConnectBrowserRequest {
|
||||
string finalURL = 2;
|
||||
repeated string cookieNames = 3;
|
||||
repeated string headerNames = 4;
|
||||
repeated string callbackURLPrefixes = 5;
|
||||
repeated string earlyCookieNames = 6;
|
||||
string cacheID = 7;
|
||||
}
|
||||
|
||||
message OpenConnectBrowserCookie {
|
||||
|
||||
@@ -415,9 +415,9 @@ Disable AnyConnect XML POST authentication and start authentication with the leg
|
||||
|
||||
### external_auth_disabled
|
||||
|
||||
Disable external browser authentication such as SSO and SAML for AnyConnect and GlobalProtect.
|
||||
Disable external browser authentication such as SSO and SAML for AnyConnect, GlobalProtect, and Fortinet.
|
||||
|
||||
When enabled, external authentication is not advertised to the server and an unexpected external authentication request is rejected.
|
||||
When enabled, external authentication is not advertised for AnyConnect or GlobalProtect, and any unexpected external authentication request, including Fortinet SAML, is rejected.
|
||||
|
||||
### password_authentication_disabled
|
||||
|
||||
|
||||
@@ -415,9 +415,9 @@ AnyConnect 压缩模式,可选值为:
|
||||
|
||||
### external_auth_disabled
|
||||
|
||||
禁用 AnyConnect 和 GlobalProtect 的 SSO、SAML 等外部浏览器认证。
|
||||
禁用 AnyConnect、GlobalProtect 和 Fortinet 的 SSO、SAML 等外部浏览器认证。
|
||||
|
||||
启用时不会向服务器声明外部认证支持,并会拒绝意外收到的外部认证请求。
|
||||
启用时不会为 AnyConnect 或 GlobalProtect 向服务器声明外部认证支持,并会拒绝任何意外收到的外部认证请求,包括 Fortinet SAML。
|
||||
|
||||
### password_authentication_disabled
|
||||
|
||||
|
||||
@@ -45,6 +45,7 @@ type CacheFile struct {
|
||||
logger logger.Logger
|
||||
path string
|
||||
cacheID []byte
|
||||
cacheIDText string
|
||||
storeFakeIP bool
|
||||
storeRDRC bool
|
||||
storeDNS bool
|
||||
@@ -104,6 +105,7 @@ func New(ctx context.Context, logger logger.Logger, options option.CacheFileOpti
|
||||
logger: logger,
|
||||
path: filemanager.BasePath(ctx, path),
|
||||
cacheID: cacheIDBytes,
|
||||
cacheIDText: options.CacheID,
|
||||
storeFakeIP: options.StoreFakeIP,
|
||||
storeRDRC: options.StoreRDRC,
|
||||
storeDNS: options.StoreDNS,
|
||||
@@ -124,6 +126,10 @@ func (c *CacheFile) Dependencies() []string {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *CacheFile) CacheID() string {
|
||||
return c.cacheIDText
|
||||
}
|
||||
|
||||
func (c *CacheFile) SetOptimisticTimeout(timeout time.Duration) {
|
||||
c.optimisticTimeout = timeout
|
||||
}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package libbox
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/sagernet/sing-box/daemon"
|
||||
"github.com/sagernet/sing/common"
|
||||
)
|
||||
@@ -68,20 +70,31 @@ func (f *OpenConnectAuthForm) Fields() OpenConnectAuthFormFieldIterator {
|
||||
}
|
||||
|
||||
type OpenConnectBrowserRequest struct {
|
||||
URL string
|
||||
FinalURL string
|
||||
cookieNames []string
|
||||
headerNames []string
|
||||
URL string
|
||||
FinalURL string
|
||||
CacheID string
|
||||
cookieNames []string
|
||||
earlyCookieNames []string
|
||||
headerNames []string
|
||||
callbackURLPrefixes []string
|
||||
}
|
||||
|
||||
func (r *OpenConnectBrowserRequest) CookieNames() StringIterator {
|
||||
return newIterator(r.cookieNames)
|
||||
}
|
||||
|
||||
func (r *OpenConnectBrowserRequest) EarlyCookieNames() StringIterator {
|
||||
return newIterator(r.earlyCookieNames)
|
||||
}
|
||||
|
||||
func (r *OpenConnectBrowserRequest) HeaderNames() StringIterator {
|
||||
return newIterator(r.headerNames)
|
||||
}
|
||||
|
||||
func (r *OpenConnectBrowserRequest) CallbackURLPrefixes() StringIterator {
|
||||
return newIterator(r.callbackURLPrefixes)
|
||||
}
|
||||
|
||||
type OpenConnectAuthFormFieldIterator interface {
|
||||
Next() *OpenConnectAuthFormField
|
||||
HasNext() bool
|
||||
@@ -137,9 +150,9 @@ func (r *OpenConnectBrowserResult) AddCookie(name string, value string) {
|
||||
}
|
||||
|
||||
func (r *OpenConnectBrowserResult) AddHeader(name string, value string) {
|
||||
for _, header := range r.headers {
|
||||
if header.Name == name {
|
||||
header.Values = append(header.Values, value)
|
||||
for i := range r.headers {
|
||||
if strings.EqualFold(r.headers[i].Name, name) {
|
||||
r.headers[i].Values = append(r.headers[i].Values, value)
|
||||
return
|
||||
}
|
||||
}
|
||||
@@ -221,10 +234,13 @@ func openConnectEndpointStatusFromGRPC(status *daemon.OpenConnectEndpointStatus)
|
||||
browser := status.AuthChallenge.GetBrowser()
|
||||
if browser != nil {
|
||||
challenge.Browser = &OpenConnectBrowserRequest{
|
||||
URL: browser.Url,
|
||||
FinalURL: browser.FinalURL,
|
||||
cookieNames: browser.CookieNames,
|
||||
headerNames: browser.HeaderNames,
|
||||
URL: browser.Url,
|
||||
FinalURL: browser.FinalURL,
|
||||
CacheID: browser.CacheID,
|
||||
cookieNames: browser.CookieNames,
|
||||
earlyCookieNames: browser.EarlyCookieNames,
|
||||
headerNames: browser.HeaderNames,
|
||||
callbackURLPrefixes: browser.CallbackURLPrefixes,
|
||||
}
|
||||
}
|
||||
result.AuthChallenge = challenge
|
||||
|
||||
@@ -46,7 +46,7 @@ require (
|
||||
github.com/sagernet/sing v0.8.12-0.20260721063414-596db5dd6ef4
|
||||
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-20260721123934-0d945d43288f
|
||||
github.com/sagernet/sing-openconnect v0.0.0-20260722140139-e0c977659ca2
|
||||
github.com/sagernet/sing-openvpn v0.0.0-20260721005523-64b754d1c277
|
||||
github.com/sagernet/sing-quic v0.6.4-0.20260720125339-63fa6a7ebc31
|
||||
github.com/sagernet/sing-shadowsocks v0.2.8
|
||||
|
||||
@@ -317,8 +317,8 @@ 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-20260721123934-0d945d43288f h1:FKT5eCVyNiRNpa5jov6Fl9aQpAgKuCmkuhqVXvBK8b4=
|
||||
github.com/sagernet/sing-openconnect v0.0.0-20260721123934-0d945d43288f/go.mod h1:4AKZLVcvY3r54UaK2Gbnm7aN8pOwdLz+y4EP0QFZ5Eg=
|
||||
github.com/sagernet/sing-openconnect v0.0.0-20260722140139-e0c977659ca2 h1:IOzb7F/NRhAKx49+8HEsJmKrZT73EPseFouxQ6MvAOo=
|
||||
github.com/sagernet/sing-openconnect v0.0.0-20260722140139-e0c977659ca2/go.mod h1:4AKZLVcvY3r54UaK2Gbnm7aN8pOwdLz+y4EP0QFZ5Eg=
|
||||
github.com/sagernet/sing-openvpn v0.0.0-20260721005523-64b754d1c277 h1:4H38L3OxOx1fGEuH4n9lh/5O7XtZTgQ/1V/gdQ+b+Es=
|
||||
github.com/sagernet/sing-openvpn v0.0.0-20260721005523-64b754d1c277/go.mod h1:PWX7WygD8jpwfqfaGNySXpJYTn0SOwjBI1BKHHC2+Bw=
|
||||
github.com/sagernet/sing-quic v0.6.4-0.20260720125339-63fa6a7ebc31 h1:FuiTs45PaA1/f2Kj6E2QlctFBrJUUFB8QAHnV5im9c8=
|
||||
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
"github.com/sagernet/sing-box/adapter"
|
||||
"github.com/sagernet/sing-openconnect"
|
||||
"github.com/sagernet/sing/common"
|
||||
"github.com/sagernet/sing/service"
|
||||
)
|
||||
|
||||
var _ adapter.OpenConnectEndpoint = (*Endpoint)(nil)
|
||||
@@ -45,11 +46,19 @@ func (e *Endpoint) OpenConnectStatus() adapter.OpenConnectStatus {
|
||||
}
|
||||
}
|
||||
if authChallenge.Browser != nil {
|
||||
var cacheID string
|
||||
cacheFile := service.FromContext[adapter.CacheFile](e.loopContext)
|
||||
if cacheFile != nil {
|
||||
cacheID = cacheFile.CacheID()
|
||||
}
|
||||
challenge.Browser = &adapter.OpenConnectBrowserRequest{
|
||||
URL: authChallenge.Browser.URL,
|
||||
FinalURL: authChallenge.Browser.FinalURL,
|
||||
CookieNames: slices.Clone(authChallenge.Browser.CookieNames),
|
||||
HeaderNames: slices.Clone(authChallenge.Browser.HeaderNames),
|
||||
URL: authChallenge.Browser.URL,
|
||||
FinalURL: authChallenge.Browser.FinalURL,
|
||||
CookieNames: slices.Clone(authChallenge.Browser.CookieNames),
|
||||
EarlyCookieNames: slices.Clone(authChallenge.Browser.EarlyCookieNames),
|
||||
HeaderNames: slices.Clone(authChallenge.Browser.HeaderNames),
|
||||
CallbackURLPrefixes: slices.Clone(authChallenge.Browser.CallbackURLPrefixes),
|
||||
CacheID: cacheID,
|
||||
}
|
||||
}
|
||||
status.AuthChallenge = challenge
|
||||
|
||||
Reference in New Issue
Block a user