Commit 0a95b5d3 authored by Matthew Holt's avatar Matthew Holt

caddytls: Move config of certmagic storage to NewConfig (fixes #2465)

Breaking API change for server type plugins that use caddytls package.
Now an error value is returned from NewConfig as well. Sorry about that.
parent 22db8bcf
......@@ -190,7 +190,10 @@ func (h *httpContext) InspectServerBlocks(sourceFile string, serverBlocks []cadd
// Make our caddytls.Config, which has a pointer to the
// instance's certificate cache and enough information
// to use automatic HTTPS when the time comes
caddytlsConfig := caddytls.NewConfig(h.instance)
caddytlsConfig, err := caddytls.NewConfig(h.instance)
if err != nil {
return nil, fmt.Errorf("creating new caddytls configuration: %v", err)
}
caddytlsConfig.Hostname = addr.Host
caddytlsConfig.Manager.AltHTTPPort = altHTTPPort
caddytlsConfig.Manager.AltTLSALPNPort = altTLSALPNPort
......
......@@ -19,6 +19,8 @@ import (
"crypto/x509"
"fmt"
"io/ioutil"
"os"
"sync/atomic"
"github.com/xenolf/lego/challenge/tlsalpn01"
......@@ -95,11 +97,31 @@ type Config struct {
// NewConfig returns a new Config with a pointer to the instance's
// certificate cache. You will usually need to set other fields on
// the returned Config for successful practical use.
func NewConfig(inst *caddy.Instance) *Config {
func NewConfig(inst *caddy.Instance) (*Config, error) {
inst.StorageMu.RLock()
certCache, ok := inst.Storage[CertCacheInstStorageKey].(*certmagic.Cache)
inst.StorageMu.RUnlock()
if !ok || certCache == nil {
// set up the clustering plugin, if there is one (and there should always
// be one since this tls plugin requires it) -- this should be done exactly
// once, but we can't do it during init while plugins are still registering,
// so do it as soon as we run a setup)
if atomic.CompareAndSwapInt32(&clusterPluginSetup, 0, 1) {
clusterPluginName := os.Getenv("CADDY_CLUSTERING")
if clusterPluginName == "" {
clusterPluginName = "file" // name of default storage plugin
}
clusterFn, ok := clusterProviders[clusterPluginName]
if ok {
storage, err := clusterFn()
if err != nil {
return nil, fmt.Errorf("constructing cluster plugin %s: %v", clusterPluginName, err)
}
certmagic.DefaultStorage = storage
} else {
return nil, fmt.Errorf("unrecognized cluster plugin (was it included in the Caddy build?): %s", clusterPluginName)
}
}
certCache = certmagic.NewCache(certmagic.DefaultStorage)
inst.OnShutdown = append(inst.OnShutdown, func() error {
certCache.Stop()
......@@ -111,7 +133,7 @@ func NewConfig(inst *caddy.Instance) *Config {
}
return &Config{
Manager: certmagic.NewWithCache(certCache, certmagic.Config{}),
}
}, nil
}
// buildStandardTLSConfig converts cfg (*caddytls.Config) to a *tls.Config
......@@ -519,6 +541,8 @@ var defaultCurves = []tls.CurveID{
tls.CurveP256,
}
var clusterPluginSetup int32 // access atomically
// CertCacheInstStorageKey is the name of the key for
// accessing the certificate storage on the *caddy.Instance.
const CertCacheInstStorageKey = "tls_cert_cache"
......@@ -26,7 +26,6 @@ import (
"path/filepath"
"strconv"
"strings"
"sync/atomic"
"github.com/mholt/caddy"
"github.com/mholt/caddy/telemetry"
......@@ -44,27 +43,6 @@ func init() {
// are specified by the user in the config file. All the automatic HTTPS
// stuff comes later outside of this function.
func setupTLS(c *caddy.Controller) error {
// set up the clustering plugin, if there is one (and there should always
// be one since this tls plugin requires it) -- this should be done exactly
// once, but we can't do it during init while plugins are still registering,
// so do it as soon as we run a setup)
if atomic.CompareAndSwapInt32(&clusterPluginSetup, 0, 1) {
clusterPluginName := os.Getenv("CADDY_CLUSTERING")
if clusterPluginName == "" {
clusterPluginName = "file" // name of default storage plugin
}
clusterFn, ok := clusterProviders[clusterPluginName]
if ok {
storage, err := clusterFn()
if err != nil {
return fmt.Errorf("constructing cluster plugin %s: %v", clusterPluginName, err)
}
certmagic.DefaultStorage = storage
} else {
return fmt.Errorf("unrecognized cluster plugin (was it included in the Caddy build?): %s", clusterPluginName)
}
}
configGetter, ok := configGetters[c.ServerType()]
if !ok {
return fmt.Errorf("no caddytls.ConfigGetter for %s server type; must call RegisterConfigGetter", c.ServerType())
......@@ -445,5 +423,3 @@ func loadCertsInDir(cfg *Config, c *caddy.Controller, dir string) error {
func constructDefaultClusterPlugin() (certmagic.Storage, error) {
return &certmagic.FileStorage{Path: caddy.AssetsPath()}, nil
}
var clusterPluginSetup int32 // access atomically
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment