cmd/derper: fix data race & server panic in manual cert mode

(Thanks for debugging, Roland!)

Fixes #4082

Change-Id: I400a64001c3c58899bb570b759b08e745abc0be1
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
pull/5338/head
Brad Fitzpatrick 2 years ago committed by Brad Fitzpatrick
parent 9996d94b3c
commit 090033ede5

@ -20,6 +20,11 @@ var unsafeHostnameCharacters = regexp.MustCompile(`[^a-zA-Z0-9-\.]`)
type certProvider interface { type certProvider interface {
// TLSConfig creates a new TLS config suitable for net/http.Server servers. // TLSConfig creates a new TLS config suitable for net/http.Server servers.
//
// The returned Config must have a GetCertificate function set and that
// function must return a unique *tls.Certificate for each call. The
// returned *tls.Certificate will be mutated by the caller to append to the
// (*tls.Certificate).Certificate field.
TLSConfig() *tls.Config TLSConfig() *tls.Config
// HTTPHandler handle ACME related request, if any. // HTTPHandler handle ACME related request, if any.
HTTPHandler(fallback http.Handler) http.Handler HTTPHandler(fallback http.Handler) http.Handler
@ -87,7 +92,13 @@ func (m *manualCertManager) getCertificate(hi *tls.ClientHelloInfo) (*tls.Certif
if hi.ServerName != m.hostname { if hi.ServerName != m.hostname {
return nil, fmt.Errorf("cert mismatch with hostname: %q", hi.ServerName) return nil, fmt.Errorf("cert mismatch with hostname: %q", hi.ServerName)
} }
return m.cert, nil
// Return a shallow copy of the cert so the caller can append to its
// Certificate field.
certCopy := new(tls.Certificate)
*certCopy = *m.cert
certCopy.Certificate = certCopy.Certificate[:len(certCopy.Certificate):len(certCopy.Certificate)]
return certCopy, nil
} }
func (m *manualCertManager) HTTPHandler(fallback http.Handler) http.Handler { func (m *manualCertManager) HTTPHandler(fallback http.Handler) http.Handler {

Loading…
Cancel
Save