update dynamic LoginName
This commit is contained in:
@@ -7,7 +7,16 @@ RUN xcaddy build ${CADDY_VERSION} \
|
|||||||
--with github.com/caddy-dns/cloudflare \
|
--with github.com/caddy-dns/cloudflare \
|
||||||
--with github.com/caddyserver/replace-response
|
--with github.com/caddyserver/replace-response
|
||||||
|
|
||||||
|
# Autodiscover Handler in Go bauen (Go ist im Builder-Image bereits verfügbar)
|
||||||
|
COPY autodiscover-handler.go /src/autodiscover-handler.go
|
||||||
|
WORKDIR /src
|
||||||
|
RUN CGO_ENABLED=0 go build -ldflags="-s -w" -o /usr/bin/autodiscover-handler autodiscover-handler.go
|
||||||
|
|
||||||
FROM caddy:${CADDY_VERSION}
|
FROM caddy:${CADDY_VERSION}
|
||||||
COPY --from=builder /usr/bin/caddy /usr/bin/caddy
|
COPY --from=builder /usr/bin/caddy /usr/bin/caddy
|
||||||
RUN mkdir -p /var/log/caddy
|
COPY --from=builder /usr/bin/autodiscover-handler /usr/local/bin/autodiscover-handler
|
||||||
|
COPY start.sh /usr/local/bin/start.sh
|
||||||
|
RUN chmod +x /usr/local/bin/start.sh /usr/local/bin/autodiscover-handler \
|
||||||
|
&& mkdir -p /var/log/caddy
|
||||||
|
|
||||||
|
CMD ["/usr/local/bin/start.sh"]
|
||||||
109
caddy/autodiscover-handler.go
Normal file
109
caddy/autodiscover-handler.go
Normal file
@@ -0,0 +1,109 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"log"
|
||||||
|
"net/http"
|
||||||
|
"regexp"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
const port = "8280"
|
||||||
|
|
||||||
|
var emailRegex = regexp.MustCompile(`(?i)<EMailAddress>([^<]+)</EMailAddress>`)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
http.HandleFunc("/health", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
w.WriteHeader(http.StatusOK)
|
||||||
|
fmt.Fprint(w, "OK")
|
||||||
|
})
|
||||||
|
|
||||||
|
http.HandleFunc("/autodiscover/autodiscover.xml", handleAutodiscover)
|
||||||
|
// Outlook sendet manchmal mit Großbuchstaben
|
||||||
|
http.HandleFunc("/Autodiscover/Autodiscover.xml", handleAutodiscover)
|
||||||
|
http.HandleFunc("/AutoDiscover/AutoDiscover.xml", handleAutodiscover)
|
||||||
|
|
||||||
|
log.Printf("[autodiscover] Listening on port %s", port)
|
||||||
|
if err := http.ListenAndServe(":"+port, nil); err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func handleAutodiscover(w http.ResponseWriter, r *http.Request) {
|
||||||
|
var email string
|
||||||
|
|
||||||
|
if r.Method == http.MethodPost {
|
||||||
|
body, err := io.ReadAll(r.Body)
|
||||||
|
if err == nil {
|
||||||
|
if match := emailRegex.FindStringSubmatch(string(body)); len(match) > 1 {
|
||||||
|
email = strings.TrimSpace(match[1])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
r.Body.Close()
|
||||||
|
}
|
||||||
|
|
||||||
|
var domain string
|
||||||
|
if email != "" {
|
||||||
|
parts := strings.SplitN(email, "@", 2)
|
||||||
|
if len(parts) == 2 {
|
||||||
|
domain = parts[1]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if domain == "" {
|
||||||
|
domain = extractDomainFromHost(r.Host)
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Printf("[autodiscover] %s from %s - email=%q domain=%s", r.Method, r.RemoteAddr, email, domain)
|
||||||
|
|
||||||
|
w.Header().Set("Content-Type", "application/xml")
|
||||||
|
w.WriteHeader(http.StatusOK)
|
||||||
|
fmt.Fprint(w, buildResponse(domain, email))
|
||||||
|
}
|
||||||
|
|
||||||
|
func extractDomainFromHost(host string) string {
|
||||||
|
// Strip port
|
||||||
|
if idx := strings.Index(host, ":"); idx >= 0 {
|
||||||
|
host = host[:idx]
|
||||||
|
}
|
||||||
|
parts := strings.Split(host, ".")
|
||||||
|
if len(parts) >= 3 && strings.EqualFold(parts[0], "autodiscover") {
|
||||||
|
return strings.Join(parts[1:], ".")
|
||||||
|
}
|
||||||
|
if len(parts) >= 2 {
|
||||||
|
return strings.Join(parts[len(parts)-2:], ".")
|
||||||
|
}
|
||||||
|
return host
|
||||||
|
}
|
||||||
|
|
||||||
|
func buildResponse(domain, loginName string) string {
|
||||||
|
return fmt.Sprintf(`<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Autodiscover xmlns="http://schemas.microsoft.com/exchange/autodiscover/responseschema/2006">
|
||||||
|
<Response xmlns="http://schemas.microsoft.com/exchange/autodiscover/outlook/responseschema/2006a">
|
||||||
|
<Account>
|
||||||
|
<AccountType>email</AccountType>
|
||||||
|
<Action>settings</Action>
|
||||||
|
<Protocol>
|
||||||
|
<Type>IMAP</Type>
|
||||||
|
<Server>imap.%s</Server>
|
||||||
|
<Port>993</Port>
|
||||||
|
<DomainRequired>off</DomainRequired>
|
||||||
|
<LoginName>%s</LoginName>
|
||||||
|
<SPA>off</SPA>
|
||||||
|
<SSL>on</SSL>
|
||||||
|
<AuthRequired>on</AuthRequired>
|
||||||
|
</Protocol>
|
||||||
|
<Protocol>
|
||||||
|
<Type>SMTP</Type>
|
||||||
|
<Server>smtp.%s</Server>
|
||||||
|
<Port>465</Port>
|
||||||
|
<DomainRequired>off</DomainRequired>
|
||||||
|
<LoginName>%s</LoginName>
|
||||||
|
<SPA>off</SPA>
|
||||||
|
<SSL>on</SSL>
|
||||||
|
<AuthRequired>on</AuthRequired>
|
||||||
|
</Protocol>
|
||||||
|
</Account>
|
||||||
|
</Response>
|
||||||
|
</Autodiscover>`, domain, loginName, domain, loginName)
|
||||||
|
}
|
||||||
8
caddy/start.sh
Normal file
8
caddy/start.sh
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# Autodiscover handler im Hintergrund starten
|
||||||
|
/usr/local/bin/autodiscover-handler &
|
||||||
|
|
||||||
|
# Caddy im Vordergrund
|
||||||
|
exec caddy run --config /etc/caddy/Caddyfile --adapter caddyfile
|
||||||
@@ -78,36 +78,7 @@ OUTPUT="${OUTPUT}(email_settings) {\n"
|
|||||||
# --- 1. Outlook Classic Autodiscover (POST + GET XML) ---
|
# --- 1. Outlook Classic Autodiscover (POST + GET XML) ---
|
||||||
OUTPUT="${OUTPUT} # Outlook Autodiscover (XML) - POST und GET\n"
|
OUTPUT="${OUTPUT} # Outlook Autodiscover (XML) - POST und GET\n"
|
||||||
OUTPUT="${OUTPUT} route /autodiscover/autodiscover.xml {\n"
|
OUTPUT="${OUTPUT} route /autodiscover/autodiscover.xml {\n"
|
||||||
OUTPUT="${OUTPUT} header Content-Type \"application/xml\"\n"
|
OUTPUT="${OUTPUT} reverse_proxy localhost:8280\n"
|
||||||
OUTPUT="${OUTPUT} respond \`<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
|
|
||||||
OUTPUT="${OUTPUT}<Autodiscover xmlns=\"http://schemas.microsoft.com/exchange/autodiscover/responseschema/2006\">\n"
|
|
||||||
OUTPUT="${OUTPUT} <Response xmlns=\"http://schemas.microsoft.com/exchange/autodiscover/outlook/responseschema/2006a\">\n"
|
|
||||||
OUTPUT="${OUTPUT} <Account>\n"
|
|
||||||
OUTPUT="${OUTPUT} <AccountType>email</AccountType>\n"
|
|
||||||
OUTPUT="${OUTPUT} <Action>settings</Action>\n"
|
|
||||||
OUTPUT="${OUTPUT} <Protocol>\n"
|
|
||||||
OUTPUT="${OUTPUT} <Type>IMAP</Type>\n"
|
|
||||||
OUTPUT="${OUTPUT} <Server>imap.{labels.1}.{labels.0}</Server>\n"
|
|
||||||
OUTPUT="${OUTPUT} <Port>993</Port>\n"
|
|
||||||
OUTPUT="${OUTPUT} <DomainRequired>off</DomainRequired>\n"
|
|
||||||
OUTPUT="${OUTPUT} <LoginName></LoginName>\n"
|
|
||||||
OUTPUT="${OUTPUT} <SPA>off</SPA>\n"
|
|
||||||
OUTPUT="${OUTPUT} <SSL>on</SSL>\n"
|
|
||||||
OUTPUT="${OUTPUT} <AuthRequired>on</AuthRequired>\n"
|
|
||||||
OUTPUT="${OUTPUT} </Protocol>\n"
|
|
||||||
OUTPUT="${OUTPUT} <Protocol>\n"
|
|
||||||
OUTPUT="${OUTPUT} <Type>SMTP</Type>\n"
|
|
||||||
OUTPUT="${OUTPUT} <Server>smtp.{labels.1}.{labels.0}</Server>\n"
|
|
||||||
OUTPUT="${OUTPUT} <Port>465</Port>\n"
|
|
||||||
OUTPUT="${OUTPUT} <DomainRequired>off</DomainRequired>\n"
|
|
||||||
OUTPUT="${OUTPUT} <LoginName></LoginName>\n"
|
|
||||||
OUTPUT="${OUTPUT} <SPA>off</SPA>\n"
|
|
||||||
OUTPUT="${OUTPUT} <SSL>on</SSL>\n"
|
|
||||||
OUTPUT="${OUTPUT} <AuthRequired>on</AuthRequired>\n"
|
|
||||||
OUTPUT="${OUTPUT} </Protocol>\n"
|
|
||||||
OUTPUT="${OUTPUT} </Account>\n"
|
|
||||||
OUTPUT="${OUTPUT} </Response>\n"
|
|
||||||
OUTPUT="${OUTPUT}</Autodiscover>\` 200\n"
|
|
||||||
OUTPUT="${OUTPUT} }\n"
|
OUTPUT="${OUTPUT} }\n"
|
||||||
OUTPUT="${OUTPUT}\n"
|
OUTPUT="${OUTPUT}\n"
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user