From 083fa1803a99197cfd9b6d656ad606e73b9eedbf Mon Sep 17 00:00:00 2001 From: Kebin Liu Date: Wed, 5 Jan 2022 22:17:13 +0800 Subject: [PATCH] cmd/stdiscosrv: Support deploying behind Caddyserver (#8092) --- cmd/stdiscosrv/apisrv.go | 31 +++++++++++++++++++++---------- 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/cmd/stdiscosrv/apisrv.go b/cmd/stdiscosrv/apisrv.go index 3c9b5b3ab..ad2b1f478 100644 --- a/cmd/stdiscosrv/apisrv.go +++ b/cmd/stdiscosrv/apisrv.go @@ -10,8 +10,10 @@ import ( "bytes" "context" "crypto/tls" + "encoding/base64" "encoding/json" "encoding/pem" + "errors" "fmt" "log" "math/rand" @@ -229,10 +231,10 @@ func (s *apiSrv) handleGET(ctx context.Context, w http.ResponseWriter, req *http func (s *apiSrv) handlePOST(ctx context.Context, remoteAddr *net.TCPAddr, w http.ResponseWriter, req *http.Request) { reqID := ctx.Value(idKey).(requestID) - rawCert := certificateBytes(req) - if rawCert == nil { + rawCert, err := certificateBytes(req) + if err != nil { if debug { - log.Println(reqID, "no certificates") + log.Println(reqID, "no certificates:", err) } announceRequestsTotal.WithLabelValues("no_certificate").Inc() w.Header().Set("Retry-After", errorRetryAfterString()) @@ -304,9 +306,9 @@ func handlePing(w http.ResponseWriter, r *http.Request) { w.WriteHeader(204) } -func certificateBytes(req *http.Request) []byte { +func certificateBytes(req *http.Request) ([]byte, error) { if req.TLS != nil && len(req.TLS.PeerCertificates) > 0 { - return req.TLS.PeerCertificates[0].Raw + return req.TLS.PeerCertificates[0].Raw, nil } var bs []byte @@ -319,7 +321,7 @@ func certificateBytes(req *http.Request) []byte { hdr, err := url.QueryUnescape(hdr) if err != nil { // Decoding failed - return nil + return nil, err } bs = []byte(hdr) @@ -338,6 +340,15 @@ func certificateBytes(req *http.Request) []byte { } } } + } else if hdr := req.Header.Get("X-Tls-Client-Cert-Der-Base64"); hdr != "" { + // Caddy {tls_client_certificate_der_base64} + hdr, err := base64.StdEncoding.DecodeString(hdr) + if err != nil { + // Decoding failed + return nil, err + } + + bs = pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: hdr}) } else if hdr := req.Header.Get("X-Forwarded-Tls-Client-Cert"); hdr != "" { // Traefik 2 passtlsclientcert // The certificate is in PEM format with url encoding but without newlines @@ -346,7 +357,7 @@ func certificateBytes(req *http.Request) []byte { hdr, err := url.QueryUnescape(hdr) if err != nil { // Decoding failed - return nil + return nil, err } for i := 64; i < len(hdr); i += 65 { @@ -359,16 +370,16 @@ func certificateBytes(req *http.Request) []byte { } if bs == nil { - return nil + return nil, errors.New("empty certificate header") } block, _ := pem.Decode(bs) if block == nil { // Decoding failed - return nil + return nil, errors.New("certificate decode result is empty") } - return block.Bytes + return block.Bytes, nil } // fixupAddresses checks the list of addresses, removing invalid ones and