fix application bug
This commit is contained in:
210
vendor/github.com/mholt/certmagic/config.go
generated
vendored
210
vendor/github.com/mholt/certmagic/config.go
generated
vendored
@@ -20,11 +20,11 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/xenolf/lego/certcrypto"
|
||||
"github.com/xenolf/lego/certificate"
|
||||
"github.com/xenolf/lego/challenge"
|
||||
"github.com/xenolf/lego/challenge/tlsalpn01"
|
||||
"github.com/xenolf/lego/lego"
|
||||
"github.com/go-acme/lego/certcrypto"
|
||||
"github.com/go-acme/lego/certificate"
|
||||
"github.com/go-acme/lego/challenge"
|
||||
"github.com/go-acme/lego/challenge/tlsalpn01"
|
||||
"github.com/go-acme/lego/lego"
|
||||
)
|
||||
|
||||
// Config configures a certificate manager instance.
|
||||
@@ -74,7 +74,7 @@ type Config struct {
|
||||
ListenHost string
|
||||
|
||||
// The alternate port to use for the ACME HTTP
|
||||
// challenge; if non-empty, this port will be
|
||||
// challenge; if non-empty, this port will be
|
||||
// used instead of HTTPChallengePort to spin up
|
||||
// a listener for the HTTP challenge
|
||||
AltHTTPPort int
|
||||
@@ -113,117 +113,167 @@ type Config struct {
|
||||
// CSR generated by lego/acme
|
||||
MustStaple bool
|
||||
|
||||
// Map of hostname to certificate hash; used
|
||||
// to complete handshakes and serve the right
|
||||
// certificate given SNI
|
||||
certificates map[string]string
|
||||
// The storage to access when storing or
|
||||
// loading TLS assets
|
||||
Storage Storage
|
||||
|
||||
// Pointer to the certificate store to use
|
||||
// NewManager returns a new Manager. If nil,
|
||||
// an ACME client will be created and used.
|
||||
NewManager func(interactive bool) (Manager, error)
|
||||
|
||||
// Pointer to the in-memory certificate cache
|
||||
certCache *Cache
|
||||
|
||||
// Map of client config key to ACME clients
|
||||
// so they can be reused
|
||||
// TODO: It might be better if these were globally cached, rather than per-config, which are ephemeral... but maybe evict them after a certain time, like 1 day or something
|
||||
acmeClients map[string]*lego.Client
|
||||
acmeClientsMu *sync.Mutex
|
||||
}
|
||||
|
||||
// NewDefault returns a new, valid, default config.
|
||||
// NewDefault makes a valid config based on the package
|
||||
// Default config. Most users will call this function
|
||||
// instead of New() since most use cases require only a
|
||||
// single config for any and all certificates.
|
||||
//
|
||||
// Calling this function signifies your acceptance to
|
||||
// the CA's Subscriber Agreement and/or Terms of Service.
|
||||
// If your requirements are more advanced (for example,
|
||||
// multiple configs depending on the certificate), then use
|
||||
// New() instead. (You will need to make your own Cache
|
||||
// first.) If you only need a single Config to manage your
|
||||
// certs (even if that config changes, as long as it is the
|
||||
// only one), customize the Default package variable before
|
||||
// calling NewDefault().
|
||||
//
|
||||
// All calls to NewDefault() will return configs that use the
|
||||
// same, default certificate cache. All configs returned
|
||||
// by NewDefault() are based on the values of the fields of
|
||||
// Default at the time it is called.
|
||||
func NewDefault() *Config {
|
||||
return New(Config{Agreed: true})
|
||||
}
|
||||
|
||||
// New makes a valid config based on cfg and uses
|
||||
// a default certificate cache. All calls to
|
||||
// New() will use the same certificate cache.
|
||||
func New(cfg Config) *Config {
|
||||
return NewWithCache(nil, cfg)
|
||||
}
|
||||
|
||||
// NewWithCache makes a valid new config based on cfg
|
||||
// and uses the provided certificate cache. If certCache
|
||||
// is nil, a new, default one will be created using
|
||||
// DefaultStorage; or, if a default cache has already
|
||||
// been created, it will be reused.
|
||||
func NewWithCache(certCache *Cache, cfg Config) *Config {
|
||||
// avoid nil pointers with sensible defaults,
|
||||
// careful to initialize a default cache (which
|
||||
// begins its maintenance goroutine) only if
|
||||
// needed - and only once (we don't initialize
|
||||
// it at package init to give importers a chance
|
||||
// to set DefaultStorage if they so desire)
|
||||
if certCache == nil {
|
||||
defaultCacheMu.Lock()
|
||||
if defaultCache == nil {
|
||||
defaultCache = NewCache(DefaultStorage)
|
||||
}
|
||||
certCache = defaultCache
|
||||
defaultCacheMu.Unlock()
|
||||
defaultCacheMu.Lock()
|
||||
if defaultCache == nil {
|
||||
defaultCache = NewCache(CacheOptions{
|
||||
// the cache will likely need to renew certificates,
|
||||
// so it will need to know how to do that, which
|
||||
// depends on the certificate being managed and which
|
||||
// can change during the lifetime of the cache; this
|
||||
// callback makes it possible to get the latest and
|
||||
// correct config with which to manage the cert,
|
||||
// but if the user does not provide one, we can only
|
||||
// assume that we are to use the default config
|
||||
GetConfigForCert: func(Certificate) (Config, error) {
|
||||
return Default, nil
|
||||
},
|
||||
})
|
||||
}
|
||||
if certCache.storage == nil {
|
||||
certCache.storage = DefaultStorage
|
||||
certCache := defaultCache
|
||||
defaultCacheMu.Unlock()
|
||||
|
||||
return newWithCache(certCache, Default)
|
||||
}
|
||||
|
||||
// New makes a new, valid config based on cfg and
|
||||
// uses the provided certificate cache. certCache
|
||||
// MUST NOT be nil or this function will panic.
|
||||
//
|
||||
// Use this method when you have an advanced use case
|
||||
// that requires a custom certificate cache and config
|
||||
// that may differ from the Default. For example, if
|
||||
// not all certificates are managed/renewed the same
|
||||
// way, you need to make your own Cache value with a
|
||||
// GetConfigForCert callback that returns the correct
|
||||
// configuration for each certificate. However, for
|
||||
// the vast majority of cases, there will be only a
|
||||
// single Config, thus the default cache (which always
|
||||
// uses the default Config) and default config will
|
||||
// suffice, and you should use New() instead.
|
||||
func New(certCache *Cache, cfg Config) *Config {
|
||||
if certCache == nil {
|
||||
panic("a certificate cache is required")
|
||||
}
|
||||
if certCache.options.GetConfigForCert == nil {
|
||||
panic("cache must have GetConfigForCert set in its options")
|
||||
}
|
||||
return newWithCache(certCache, cfg)
|
||||
}
|
||||
|
||||
// newWithCache ensures that cfg is a valid config by populating
|
||||
// zero-value fields from the Default Config. If certCache is
|
||||
// nil, this function panics.
|
||||
func newWithCache(certCache *Cache, cfg Config) *Config {
|
||||
if certCache == nil {
|
||||
panic("cannot make a valid config without a pointer to a certificate cache")
|
||||
}
|
||||
|
||||
// fill in default values
|
||||
if cfg.CA == "" {
|
||||
cfg.CA = CA
|
||||
cfg.CA = Default.CA
|
||||
}
|
||||
if cfg.Email == "" {
|
||||
cfg.Email = Email
|
||||
cfg.Email = Default.Email
|
||||
}
|
||||
if cfg.OnDemand == nil {
|
||||
cfg.OnDemand = OnDemand
|
||||
cfg.OnDemand = Default.OnDemand
|
||||
}
|
||||
if !cfg.Agreed {
|
||||
cfg.Agreed = Agreed
|
||||
cfg.Agreed = Default.Agreed
|
||||
}
|
||||
if !cfg.DisableHTTPChallenge {
|
||||
cfg.DisableHTTPChallenge = DisableHTTPChallenge
|
||||
cfg.DisableHTTPChallenge = Default.DisableHTTPChallenge
|
||||
}
|
||||
if !cfg.DisableTLSALPNChallenge {
|
||||
cfg.DisableTLSALPNChallenge = DisableTLSALPNChallenge
|
||||
cfg.DisableTLSALPNChallenge = Default.DisableTLSALPNChallenge
|
||||
}
|
||||
if cfg.RenewDurationBefore == 0 {
|
||||
cfg.RenewDurationBefore = RenewDurationBefore
|
||||
cfg.RenewDurationBefore = Default.RenewDurationBefore
|
||||
}
|
||||
if cfg.RenewDurationBeforeAtStartup == 0 {
|
||||
cfg.RenewDurationBeforeAtStartup = RenewDurationBeforeAtStartup
|
||||
cfg.RenewDurationBeforeAtStartup = Default.RenewDurationBeforeAtStartup
|
||||
}
|
||||
if cfg.OnEvent == nil {
|
||||
cfg.OnEvent = OnEvent
|
||||
cfg.OnEvent = Default.OnEvent
|
||||
}
|
||||
if cfg.ListenHost == "" {
|
||||
cfg.ListenHost = ListenHost
|
||||
cfg.ListenHost = Default.ListenHost
|
||||
}
|
||||
if cfg.AltHTTPPort == 0 {
|
||||
cfg.AltHTTPPort = AltHTTPPort
|
||||
cfg.AltHTTPPort = Default.AltHTTPPort
|
||||
}
|
||||
if cfg.AltTLSALPNPort == 0 {
|
||||
cfg.AltTLSALPNPort = AltTLSALPNPort
|
||||
cfg.AltTLSALPNPort = Default.AltTLSALPNPort
|
||||
}
|
||||
if cfg.DNSProvider == nil {
|
||||
cfg.DNSProvider = DNSProvider
|
||||
cfg.DNSProvider = Default.DNSProvider
|
||||
}
|
||||
if cfg.KeyType == "" {
|
||||
cfg.KeyType = KeyType
|
||||
cfg.KeyType = Default.KeyType
|
||||
}
|
||||
if cfg.CertObtainTimeout == 0 {
|
||||
cfg.CertObtainTimeout = CertObtainTimeout
|
||||
cfg.CertObtainTimeout = Default.CertObtainTimeout
|
||||
}
|
||||
if cfg.DefaultServerName == "" {
|
||||
cfg.DefaultServerName = DefaultServerName
|
||||
cfg.DefaultServerName = Default.DefaultServerName
|
||||
}
|
||||
if cfg.OnDemand == nil {
|
||||
cfg.OnDemand = OnDemand
|
||||
cfg.OnDemand = Default.OnDemand
|
||||
}
|
||||
if !cfg.MustStaple {
|
||||
cfg.MustStaple = MustStaple
|
||||
cfg.MustStaple = Default.MustStaple
|
||||
}
|
||||
if cfg.Storage == nil {
|
||||
cfg.Storage = Default.Storage
|
||||
}
|
||||
if cfg.NewManager == nil {
|
||||
cfg.NewManager = Default.NewManager
|
||||
}
|
||||
|
||||
// absolutely don't allow a nil storage,
|
||||
// because that would make almost anything
|
||||
// a config can do pointless
|
||||
if cfg.Storage == nil {
|
||||
cfg.Storage = defaultFileStorage
|
||||
}
|
||||
|
||||
// ensure the unexported fields are valid
|
||||
cfg.certificates = make(map[string]string)
|
||||
cfg.certCache = certCache
|
||||
cfg.acmeClients = make(map[string]*lego.Client)
|
||||
cfg.acmeClientsMu = new(sync.Mutex)
|
||||
@@ -272,7 +322,7 @@ func (cfg *Config) Manage(domainNames []string) error {
|
||||
}
|
||||
|
||||
// for existing certificates, make sure it is renewed
|
||||
if cert.NeedsRenewal() {
|
||||
if cert.NeedsRenewal(cfg) {
|
||||
err := cfg.RenewCert(domainName, false)
|
||||
if err != nil {
|
||||
return fmt.Errorf("%s: renewing certificate: %v", domainName, err)
|
||||
@@ -303,11 +353,11 @@ func (cfg *Config) ObtainCert(name string, interactive bool) error {
|
||||
if skip {
|
||||
return nil
|
||||
}
|
||||
client, err := cfg.newACMEClient(interactive)
|
||||
manager, err := cfg.newManager(interactive)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return client.Obtain(name)
|
||||
return manager.Obtain(name)
|
||||
}
|
||||
|
||||
// RenewCert renews the certificate for name using cfg. It stows the
|
||||
@@ -320,20 +370,20 @@ func (cfg *Config) RenewCert(name string, interactive bool) error {
|
||||
if skip {
|
||||
return nil
|
||||
}
|
||||
client, err := cfg.newACMEClient(interactive)
|
||||
manager, err := cfg.newManager(interactive)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return client.Renew(name)
|
||||
return manager.Renew(name)
|
||||
}
|
||||
|
||||
// RevokeCert revokes the certificate for domain via ACME protocol.
|
||||
func (cfg *Config) RevokeCert(domain string, interactive bool) error {
|
||||
client, err := cfg.newACMEClient(interactive)
|
||||
manager, err := cfg.newManager(interactive)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return client.Revoke(domain)
|
||||
return manager.Revoke(domain)
|
||||
}
|
||||
|
||||
// TLSConfig is an opinionated method that returns a
|
||||
@@ -394,18 +444,26 @@ func (cfg *Config) storageHasCertResources(domain string) bool {
|
||||
certKey := StorageKeys.SiteCert(cfg.CA, domain)
|
||||
keyKey := StorageKeys.SitePrivateKey(cfg.CA, domain)
|
||||
metaKey := StorageKeys.SiteMeta(cfg.CA, domain)
|
||||
return cfg.certCache.storage.Exists(certKey) &&
|
||||
cfg.certCache.storage.Exists(keyKey) &&
|
||||
cfg.certCache.storage.Exists(metaKey)
|
||||
return cfg.Storage.Exists(certKey) &&
|
||||
cfg.Storage.Exists(keyKey) &&
|
||||
cfg.Storage.Exists(metaKey)
|
||||
}
|
||||
|
||||
// managedCertNeedsRenewal returns true if certRes is
|
||||
// expiring soon or already expired, or if the process
|
||||
// of checking the expiration returned an error.
|
||||
func (cfg *Config) managedCertNeedsRenewal(certRes certificate.Resource) bool {
|
||||
cert, err := cfg.makeCertificate(certRes.Certificate, certRes.PrivateKey)
|
||||
cert, err := makeCertificate(certRes.Certificate, certRes.PrivateKey)
|
||||
if err != nil {
|
||||
return true
|
||||
}
|
||||
return cert.NeedsRenewal()
|
||||
return cert.NeedsRenewal(cfg)
|
||||
}
|
||||
|
||||
// Manager is a type that can manage a certificate.
|
||||
// They are usually very short-lived.
|
||||
type Manager interface {
|
||||
Obtain(name string) error
|
||||
Renew(name string) error
|
||||
Revoke(name string) error
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user