cmd/stdiscosrv: Add support for Traefik 2 as a reverse proxy (#6065)

This commit is contained in:
Cyprien Devillez 2019-10-07 13:55:27 +02:00 committed by Audrius Butkevicius
parent 67b8ef1f3e
commit 6408a116f9

View File

@ -295,28 +295,66 @@ func certificateBytes(req *http.Request) []byte {
return req.TLS.PeerCertificates[0].Raw return req.TLS.PeerCertificates[0].Raw
} }
var bs []byte
if hdr := req.Header.Get("X-SSL-Cert"); hdr != "" { if hdr := req.Header.Get("X-SSL-Cert"); hdr != "" {
bs := []byte(hdr) if strings.Contains(hdr, "%") {
// The certificate is in PEM format but with spaces for newlines. We // Nginx using $ssl_client_escaped_cert
// need to reinstate the newlines for the PEM decoder. But we need to // The certificate is in PEM format with url encoding.
// leave the spaces in the BEGIN and END lines - the first and last // We need to decode for the PEM decoder
// space - alone. hdr, err := url.QueryUnescape(hdr)
firstSpace := bytes.Index(bs, []byte(" ")) if err != nil {
lastSpace := bytes.LastIndex(bs, []byte(" ")) // Decoding failed
for i := firstSpace + 1; i < lastSpace; i++ { return nil
if bs[i] == ' ' { }
bs[i] = '\n'
bs = []byte(hdr)
} else {
// Nginx using $ssl_client_cert
// The certificate is in PEM format but with spaces for newlines. We
// need to reinstate the newlines for the PEM decoder. But we need to
// leave the spaces in the BEGIN and END lines - the first and last
// space - alone.
bs = []byte(hdr)
firstSpace := bytes.Index(bs, []byte(" "))
lastSpace := bytes.LastIndex(bs, []byte(" "))
for i := firstSpace + 1; i < lastSpace; i++ {
if bs[i] == ' ' {
bs[i] = '\n'
}
} }
} }
block, _ := pem.Decode(bs) } else if hdr := req.Header.Get("X-Forwarded-Tls-Client-Cert"); hdr != "" {
if block == nil { // Traefik 2 passtlsclientcert
// The certificate is in PEM format with url encoding but without newlines
// and start/end statements. We need to decode, reinstate the newlines every 64
// character and add statements for the PEM decoder
hdr, err := url.QueryUnescape(hdr)
if err != nil {
// Decoding failed // Decoding failed
return nil return nil
} }
return block.Bytes
for i := 64; i < len(hdr); i += 65 {
hdr = hdr[:i] + "\n" + hdr[i:]
}
hdr = "-----BEGIN CERTIFICATE-----\n" + hdr
hdr = hdr + "\n-----END CERTIFICATE-----\n"
bs = []byte(hdr)
} }
return nil if bs == nil {
return nil
}
block, _ := pem.Decode(bs)
if block == nil {
// Decoding failed
return nil
}
return block.Bytes
} }
// fixupAddresses checks the list of addresses, removing invalid ones and // fixupAddresses checks the list of addresses, removing invalid ones and