From 62b4553f7d14912d6bcec53068f0e176ea9065e4 Mon Sep 17 00:00:00 2001
From: Matthew Holt <mholt@users.noreply.github.com>
Date: Wed, 19 Jun 2019 16:57:32 -0600
Subject: [PATCH] tls: Disable on-demand TLS when random config is chosen

A random config is intended to be used only for solving TLS-ALPN
challenges; so we have to be sure to disable on-demand TLS so that
arbitrary names can't request certificates with another name's
on-demand config.
---
 caddytls/handshake.go | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/caddytls/handshake.go b/caddytls/handshake.go
index 0cd8a15ad..5bed3adea 100644
--- a/caddytls/handshake.go
+++ b/caddytls/handshake.go
@@ -88,6 +88,30 @@ func (cg configGroup) getConfig(hello *tls.ClientHelloInfo) *Config {
 	// TLS configuration for; any config will do for
 	// this purpose
 	for _, config := range cg {
+		// important! disable on-demand TLS so we don't
+		// try to get certificates for unrecognized names;
+		// this requires a careful pointer dance... first
+		// make shallow copies of the structs
+		if config.Manager != nil && config.Manager.OnDemand != nil {
+			cfgCopy := *config
+			mgrCopy := *config.Manager
+			tlsCfgCopy := config.tlsConfig.Clone()
+
+			// then turn off on-demand TLS
+			mgrCopy.OnDemand = nil
+
+			// then change the copies; make sure the
+			// GetCertificate callback is updated so
+			// it points to our modified config
+			cfgCopy.Manager = &mgrCopy
+			tlsCfgCopy.GetCertificate = mgrCopy.GetCertificate
+			cfgCopy.tlsConfig = tlsCfgCopy
+
+			// finally, return the reconstructed config
+			return &cfgCopy
+		}
+		// if on-demand TLS was not enabled, we should
+		// be able to use this config directly
 		return config
 	}