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,10 +221,6 @@ func Load(configFile string) Configuration {
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() {
log.Fatalf("ntlm and kerberos authentication are not stackable")
}

View file

@ -236,8 +236,9 @@ func main() {
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", "Negotiate").HandlerFunc(ntlm.NTLMAuth(gw.HandleGatewayProtocol))
auth.Register(`NTLM`)
auth.Register(`Negotiate`)
auth.Register([]string{`NTLM`, `Negotiate`}, func(r *http.Request) bool {
return r.Header.Get("Sec-WebSocket-Protocol") != "binary" // rdp client for ios is incompatible with this NTLM method.
})
}
// basic auth
@ -245,7 +246,7 @@ func main() {
log.Printf("enabling basic authentication")
q := web.BasicAuthHandler{SocketAddress: conf.Server.AuthSocket, Timeout: conf.Server.BasicAuthTimeout}
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
@ -263,7 +264,7 @@ func main() {
// kdcproxy
k := kdcproxy.InitKdcProxy(conf.Kerberos.Krb5Conf)
r.HandleFunc(kdcProxyEndPoint, k.Handler).Methods("POST")
auth.Register("Negotiate")
auth.Register([]string{"Negotiate"}, nil)
}
// setup server

View file

@ -5,21 +5,32 @@ import (
"net/http"
)
type AuthMux struct {
type authInfo struct {
headers []string
verifier AuthAvailableVerifier
}
type AuthMux struct {
headers []authInfo
}
type AuthAvailableVerifier func(r *http.Request) bool
func NewAuthMux() *AuthMux {
return &AuthMux{}
}
func (a *AuthMux) Register(s string) {
a.headers = append(a.headers, s)
func (a *AuthMux) Register(s []string, verifier AuthAvailableVerifier) {
a.headers = append(a.headers, authInfo{s, verifier})
}
func (a *AuthMux) SetAuthenticate(w http.ResponseWriter, r *http.Request) {
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)
}