local auth works with tls disabled.

verify if the auth method is supported before adding it to the response.
This commit is contained in:
snowie2000 2025-02-21 15:19:07 +08:00
parent c6b36ab627
commit a0732f42d0
3 changed files with 25 additions and 17 deletions

View file

@ -221,13 +221,9 @@ func Load(configFile string) Configuration {
log.Fatalf("host selection is set to `signed` but `querytokensigningkey` is not set") log.Fatalf("host selection is set to `signed` but `querytokensigningkey` is not set")
} }
if Conf.Server.BasicAuthEnabled() && Conf.Server.Tls == "disable" {
log.Fatalf("basicauth=local and tls=disable are mutually exclusive")
}
if Conf.Server.NtlmEnabled() && Conf.Server.KerberosEnabled() { if Conf.Server.NtlmEnabled() && Conf.Server.KerberosEnabled() {
log.Fatalf("ntlm and kerberos authentication are not stackable") log.Fatalf("ntlm and kerberos authentication are not stackable")
} }
if !Conf.Caps.TokenAuth && Conf.Server.OpenIDEnabled() { if !Conf.Caps.TokenAuth && Conf.Server.OpenIDEnabled() {
log.Fatalf("openid is configured but tokenauth disabled") log.Fatalf("openid is configured but tokenauth disabled")

View file

@ -110,7 +110,7 @@ func main() {
RdpOpts: web.RdpOpts{ RdpOpts: web.RdpOpts{
UsernameTemplate: conf.Client.UsernameTemplate, UsernameTemplate: conf.Client.UsernameTemplate,
SplitUserDomain: conf.Client.SplitUserDomain, SplitUserDomain: conf.Client.SplitUserDomain,
NoUsername: conf.Client.NoUsername, NoUsername: conf.Client.NoUsername,
}, },
GatewayAddress: url, GatewayAddress: url,
TemplateFile: conf.Client.Defaults, TemplateFile: conf.Client.Defaults,
@ -229,23 +229,24 @@ func main() {
// for stacking of authentication // for stacking of authentication
auth := web.NewAuthMux() auth := web.NewAuthMux()
rdp.MatcherFunc(web.NoAuthz).HandlerFunc(auth.SetAuthenticate) rdp.MatcherFunc(web.NoAuthz).HandlerFunc(auth.SetAuthenticate)
// ntlm // ntlm
if conf.Server.NtlmEnabled() { if conf.Server.NtlmEnabled() {
log.Printf("enabling NTLM authentication") log.Printf("enabling NTLM authentication")
ntlm := web.NTLMAuthHandler{SocketAddress: conf.Server.AuthSocket, Timeout: conf.Server.BasicAuthTimeout} ntlm := web.NTLMAuthHandler{SocketAddress: conf.Server.AuthSocket, Timeout: conf.Server.BasicAuthTimeout}
rdp.NewRoute().HeadersRegexp("Authorization", "NTLM").HandlerFunc(ntlm.NTLMAuth(gw.HandleGatewayProtocol)) rdp.NewRoute().HeadersRegexp("Authorization", "NTLM").HandlerFunc(ntlm.NTLMAuth(gw.HandleGatewayProtocol))
rdp.NewRoute().HeadersRegexp("Authorization", "Negotiate").HandlerFunc(ntlm.NTLMAuth(gw.HandleGatewayProtocol)) rdp.NewRoute().HeadersRegexp("Authorization", "Negotiate").HandlerFunc(ntlm.NTLMAuth(gw.HandleGatewayProtocol))
auth.Register(`NTLM`) auth.Register([]string{`NTLM`, `Negotiate`}, func(r *http.Request) bool {
auth.Register(`Negotiate`) return r.Header.Get("Sec-WebSocket-Protocol") != "binary" // rdp client for ios is incompatible with this NTLM method.
} })
}
// basic auth // basic auth
if conf.Server.BasicAuthEnabled() { if conf.Server.BasicAuthEnabled() {
log.Printf("enabling basic authentication") log.Printf("enabling basic authentication")
q := web.BasicAuthHandler{SocketAddress: conf.Server.AuthSocket, Timeout: conf.Server.BasicAuthTimeout} q := web.BasicAuthHandler{SocketAddress: conf.Server.AuthSocket, Timeout: conf.Server.BasicAuthTimeout}
rdp.NewRoute().HeadersRegexp("Authorization", "Basic").HandlerFunc(q.BasicAuth(gw.HandleGatewayProtocol)) rdp.NewRoute().HeadersRegexp("Authorization", "Basic").HandlerFunc(q.BasicAuth(gw.HandleGatewayProtocol))
auth.Register(`Basic realm="restricted", charset="UTF-8"`) auth.Register([]string{`Basic realm="restricted", charset="UTF-8"`}, nil)
} }
// spnego / kerberos // spnego / kerberos
@ -263,7 +264,7 @@ func main() {
// kdcproxy // kdcproxy
k := kdcproxy.InitKdcProxy(conf.Kerberos.Krb5Conf) k := kdcproxy.InitKdcProxy(conf.Kerberos.Krb5Conf)
r.HandleFunc(kdcProxyEndPoint, k.Handler).Methods("POST") r.HandleFunc(kdcProxyEndPoint, k.Handler).Methods("POST")
auth.Register("Negotiate") auth.Register([]string{"Negotiate"}, nil)
} }
// setup server // setup server

View file

@ -5,21 +5,32 @@ import (
"net/http" "net/http"
) )
type AuthMux struct { type authInfo struct {
headers []string headers []string
verifier AuthAvailableVerifier
} }
type AuthMux struct {
headers []authInfo
}
type AuthAvailableVerifier func(r *http.Request) bool
func NewAuthMux() *AuthMux { func NewAuthMux() *AuthMux {
return &AuthMux{} return &AuthMux{}
} }
func (a *AuthMux) Register(s string) { func (a *AuthMux) Register(s []string, verifier AuthAvailableVerifier) {
a.headers = append(a.headers, s) a.headers = append(a.headers, authInfo{s, verifier})
} }
func (a *AuthMux) SetAuthenticate(w http.ResponseWriter, r *http.Request) { func (a *AuthMux) SetAuthenticate(w http.ResponseWriter, r *http.Request) {
for _, s := range a.headers { for _, s := range a.headers {
w.Header().Add("WWW-Authenticate", s) if s.verifier == nil || s.verifier(r) { // verify if the auth method works for the target client
for _, h := range s.headers {
w.Header().Add("WWW-Authenticate", h)
}
}
} }
http.Error(w, "Unauthorized", http.StatusUnauthorized) http.Error(w, "Unauthorized", http.StatusUnauthorized)
} }