mirror of
				https://github.com/caddyserver/caddy.git
				synced 2025-10-31 10:37:24 -04:00 
			
		
		
		
	General cleanup and more godocs
This commit is contained in:
		
							parent
							
								
									2d056fbe66
								
							
						
					
					
						commit
						43961b542b
					
				
							
								
								
									
										39
									
								
								modules.go
									
									
									
									
									
								
							
							
						
						
									
										39
									
								
								modules.go
									
									
									
									
									
								
							| @ -11,15 +11,44 @@ import ( | ||||
| 
 | ||||
| // Module represents a Caddy module. | ||||
| type Module struct { | ||||
| 	Name     string | ||||
| 	New      func() (interface{}, error) | ||||
| 	OnLoad   func(instances []interface{}, priorState interface{}) (newState interface{}, err error) | ||||
| 	// Name is the full name of the module. It | ||||
| 	// must be unique and properly namespaced. | ||||
| 	Name string | ||||
| 
 | ||||
| 	// New returns a new, empty instance of | ||||
| 	// the module's type. The host module | ||||
| 	// which loads this module will likely | ||||
| 	// invoke methods on the returned value. | ||||
| 	// It must return a pointer; if not, it | ||||
| 	// is converted into one. | ||||
| 	New func() (interface{}, error) | ||||
| 
 | ||||
| 	// OnLoad is invoked after all module | ||||
| 	// instances ave been loaded. It receives | ||||
| 	// pointers to each instance of this | ||||
| 	// module, and any state from a previous | ||||
| 	// running configuration, which may be | ||||
| 	// nil. | ||||
| 	// | ||||
| 	// If this module is to carry "global" | ||||
| 	// state between all instances through | ||||
| 	// reloads, you might find it helpful | ||||
| 	// to return it. | ||||
| 	// TODO: Is this really better/safer than a global variable? | ||||
| 	OnLoad func(instances []interface{}, priorState interface{}) (newState interface{}, err error) | ||||
| 
 | ||||
| 	// OnUnload is called after all module | ||||
| 	// instances have been stopped, possibly | ||||
| 	// in favor of a new configuration. It | ||||
| 	// receives the state given by OnLoad (if | ||||
| 	// any). | ||||
| 	OnUnload func(state interface{}) error | ||||
| } | ||||
| 
 | ||||
| func (m Module) String() string { return m.Name } | ||||
| 
 | ||||
| // RegisterModule registers a module. | ||||
| // RegisterModule registers a module. Modules must call | ||||
| // this function in the init phase of runtime. | ||||
| func RegisterModule(mod Module) error { | ||||
| 	if mod.Name == "caddy" { | ||||
| 		return fmt.Errorf("modules cannot be named 'caddy'") | ||||
| @ -35,7 +64,7 @@ func RegisterModule(mod Module) error { | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| // GetModule returns a module by name. | ||||
| // GetModule returns a module by its full name. | ||||
| func GetModule(name string) (Module, error) { | ||||
| 	modulesMu.Lock() | ||||
| 	defer modulesMu.Unlock() | ||||
|  | ||||
| @ -3,6 +3,7 @@ package caddytls | ||||
| import ( | ||||
| 	"encoding/json" | ||||
| 	"fmt" | ||||
| 	"time" | ||||
| 
 | ||||
| 	"github.com/go-acme/lego/certcrypto" | ||||
| 
 | ||||
| @ -18,11 +19,6 @@ func init() { | ||||
| 	}) | ||||
| } | ||||
| 
 | ||||
| // ManagerMaker TODO: WIP... | ||||
| type ManagerMaker interface { | ||||
| 	newManager(interactive bool) (certmagic.Manager, error) | ||||
| } | ||||
| 
 | ||||
| // acmeManagerMaker makes an ACME manager | ||||
| // for managinig certificates using ACME. | ||||
| type acmeManagerMaker struct { | ||||
| @ -40,9 +36,11 @@ type acmeManagerMaker struct { | ||||
| 	keyType certcrypto.KeyType | ||||
| } | ||||
| 
 | ||||
| func (m *acmeManagerMaker) Provision() error { | ||||
| 	m.setDefaults() | ||||
| func (m *acmeManagerMaker) newManager(interactive bool) (certmagic.Manager, error) { | ||||
| 	return nil, nil | ||||
| } | ||||
| 
 | ||||
| func (m *acmeManagerMaker) Provision() error { | ||||
| 	// DNS providers | ||||
| 	if m.Challenges.DNS != nil { | ||||
| 		val, err := caddy2.LoadModuleInline("provider", "tls.dns", m.Challenges.DNS) | ||||
| @ -67,18 +65,71 @@ func (m *acmeManagerMaker) Provision() error { | ||||
| 		m.Storage = nil // allow GC to deallocate - TODO: Does this help? | ||||
| 	} | ||||
| 
 | ||||
| 	m.setDefaults() | ||||
| 
 | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| // setDefaults indiscriminately sets all the default values in m. | ||||
| // setDefaults sets necessary values that are | ||||
| // currently empty to their default values. | ||||
| func (m *acmeManagerMaker) setDefaults() { | ||||
| 	m.CA = certmagic.LetsEncryptStagingCA // certmagic.Default.CA // TODO: When not testing, switch to production CA | ||||
| 	m.Email = certmagic.Default.Email | ||||
| 	m.RenewAhead = caddy2.Duration(certmagic.Default.RenewDurationBefore) | ||||
| 	m.keyType = certmagic.Default.KeyType | ||||
| 	m.storage = certmagic.Default.Storage | ||||
| 	if m.CA == "" { | ||||
| 		m.CA = certmagic.LetsEncryptStagingCA // certmagic.Default.CA // TODO: When not testing, switch to production CA | ||||
| 	} | ||||
| 	if m.Email == "" { | ||||
| 		m.Email = certmagic.Default.Email | ||||
| 	} | ||||
| 	if m.RenewAhead == 0 { | ||||
| 		m.RenewAhead = caddy2.Duration(certmagic.Default.RenewDurationBefore) | ||||
| 	} | ||||
| 	if m.keyType == "" { | ||||
| 		m.keyType = certmagic.Default.KeyType | ||||
| 	} | ||||
| 	if m.storage == nil { | ||||
| 		m.storage = certmagic.Default.Storage | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func (m *acmeManagerMaker) newManager(interactive bool) (certmagic.Manager, error) { | ||||
| 	return nil, nil | ||||
| // makeCertMagicConfig converts m into a certmagic.Config, because | ||||
| // this is a special case where the default manager is the certmagic | ||||
| // Config and not a separate manager. | ||||
| func (m *acmeManagerMaker) makeCertMagicConfig() certmagic.Config { | ||||
| 	storage := m.storage | ||||
| 	if storage == nil { | ||||
| 		storage = caddy2.GetStorage() | ||||
| 	} | ||||
| 
 | ||||
| 	var ond *certmagic.OnDemandConfig | ||||
| 	if m.OnDemand != nil { | ||||
| 		ond = &certmagic.OnDemandConfig{ | ||||
| 			// TODO: fill this out | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	return certmagic.Config{ | ||||
| 		CA:                      certmagic.LetsEncryptStagingCA, //ap.CA, // TODO: Restore true value | ||||
| 		Email:                   m.Email, | ||||
| 		Agreed:                  true, | ||||
| 		DisableHTTPChallenge:    m.Challenges.HTTP.Disabled, | ||||
| 		DisableTLSALPNChallenge: m.Challenges.TLSALPN.Disabled, | ||||
| 		RenewDurationBefore:     time.Duration(m.RenewAhead), | ||||
| 		AltHTTPPort:             m.Challenges.HTTP.AlternatePort, | ||||
| 		AltTLSALPNPort:          m.Challenges.TLSALPN.AlternatePort, | ||||
| 		DNSProvider:             m.Challenges.dns, | ||||
| 		KeyType:                 supportedCertKeyTypes[m.KeyType], | ||||
| 		CertObtainTimeout:       time.Duration(m.ACMETimeout), | ||||
| 		OnDemand:                ond, | ||||
| 		MustStaple:              m.MustStaple, | ||||
| 		Storage:                 storage, | ||||
| 		// TODO: listenHost | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // supportedCertKeyTypes is all the key types that are supported | ||||
| // for certificates that are obtained through ACME. | ||||
| var supportedCertKeyTypes = map[string]certcrypto.KeyType{ | ||||
| 	"RSA2048": certcrypto.RSA2048, | ||||
| 	"RSA4096": certcrypto.RSA4096, | ||||
| 	"P256":    certcrypto.EC256, | ||||
| 	"P384":    certcrypto.EC384, | ||||
| } | ||||
|  | ||||
| @ -7,13 +7,22 @@ import ( | ||||
| ) | ||||
| 
 | ||||
| type ( | ||||
| 	// MatchServerName matches based on SNI. | ||||
| 	MatchServerName []string | ||||
| 
 | ||||
| 	// TODO: these others should be enterprise-only, probably | ||||
| 	MatchProtocol   []string // TODO: version or protocol? | ||||
| 
 | ||||
| 	// MatchProtocol matches based on protocol. | ||||
| 	MatchProtocol []string // TODO: Protocol or version? | ||||
| 
 | ||||
| 	// MatchClientCert matches based on client certificate / client auth? | ||||
| 	MatchClientCert struct{} // TODO: client certificate options | ||||
| 	MatchRemote     []string | ||||
| 	MatchStarlark   string | ||||
| 
 | ||||
| 	// MatchRemote matches based on the remote address of the connection. | ||||
| 	MatchRemote []string | ||||
| 
 | ||||
| 	// MatchStarlark matches based on a Starlark script. | ||||
| 	MatchStarlark string | ||||
| ) | ||||
| 
 | ||||
| func init() { | ||||
| @ -39,6 +48,7 @@ func init() { | ||||
| 	}) | ||||
| } | ||||
| 
 | ||||
| // Match matches hello based on SNI. | ||||
| func (m MatchServerName) Match(hello *tls.ClientHelloInfo) bool { | ||||
| 	for _, name := range m { | ||||
| 		// TODO: support wildcards (and regex?) | ||||
| @ -49,21 +59,25 @@ func (m MatchServerName) Match(hello *tls.ClientHelloInfo) bool { | ||||
| 	return false | ||||
| } | ||||
| 
 | ||||
| // Match matches hello based on protocol version. | ||||
| func (m MatchProtocol) Match(hello *tls.ClientHelloInfo) bool { | ||||
| 	// TODO: not implemented | ||||
| 	return false | ||||
| } | ||||
| 
 | ||||
| // Match matches hello based on client certificate. | ||||
| func (m MatchClientCert) Match(hello *tls.ClientHelloInfo) bool { | ||||
| 	// TODO: not implemented | ||||
| 	return false | ||||
| } | ||||
| 
 | ||||
| // Match matches hello based on remote address. | ||||
| func (m MatchRemote) Match(hello *tls.ClientHelloInfo) bool { | ||||
| 	// TODO: not implemented | ||||
| 	return false | ||||
| } | ||||
| 
 | ||||
| // Match matches hello based on a Starlark script. | ||||
| func (m MatchStarlark) Match(hello *tls.ClientHelloInfo) bool { | ||||
| 	// TODO: not implemented | ||||
| 	return false | ||||
|  | ||||
| @ -5,10 +5,8 @@ import ( | ||||
| 	"encoding/json" | ||||
| 	"fmt" | ||||
| 	"net/http" | ||||
| 	"time" | ||||
| 
 | ||||
| 	"bitbucket.org/lightcodelabs/caddy2" | ||||
| 	"github.com/go-acme/lego/certcrypto" | ||||
| 	"github.com/go-acme/lego/challenge" | ||||
| 	"github.com/klauspost/cpuid" | ||||
| 	"github.com/mholt/certmagic" | ||||
| @ -30,8 +28,7 @@ type TLS struct { | ||||
| 	certCache          *certmagic.Cache | ||||
| } | ||||
| 
 | ||||
| // TODO: Finish stubbing out this two-phase setup process: prepare, then start... | ||||
| 
 | ||||
| // Provision sets up the configuration for the TLS app. | ||||
| func (t *TLS) Provision() error { | ||||
| 	// set up the certificate cache | ||||
| 	// TODO: this makes a new cache every time; better to only make a new | ||||
| @ -97,15 +94,6 @@ func (t *TLS) Start(handle caddy2.Handle) error { | ||||
| 		if err != nil { | ||||
| 			return fmt.Errorf("automate: managing %v: %v", names, err) | ||||
| 		} | ||||
| 		// for _, name := range names { | ||||
| 		// 	t.Manage([]string{name) | ||||
| 		// 	ap := t.getAutomationPolicyForName(name) | ||||
| 		// 	magic := certmagic.New(t.certCache, ap.makeCertMagicConfig()) | ||||
| 		// 	err := magic.Manage([]string{name}) | ||||
| 		// 	if err != nil { | ||||
| 		// 		return fmt.Errorf("automate: manage %s: %v", name, err) | ||||
| 		// 	} | ||||
| 		// } | ||||
| 	} | ||||
| 	t.Certificates = nil // allow GC to deallocate - TODO: Does this help? | ||||
| 
 | ||||
| @ -191,38 +179,11 @@ type AutomationPolicy struct { | ||||
| } | ||||
| 
 | ||||
| func (ap AutomationPolicy) makeCertMagicConfig() certmagic.Config { | ||||
| 	// default manager (ACME) is a special case because of how CertMagic is designed | ||||
| 	// TODO: refactor certmagic so that ACME manager is not a special case by extracting | ||||
| 	// its config fields out of the certmagic.Config struct, or something... | ||||
| 	if acmeMgmt, ok := ap.management.(*acmeManagerMaker); ok { | ||||
| 		// default, which is management via ACME | ||||
| 
 | ||||
| 		storage := acmeMgmt.storage | ||||
| 		if storage == nil { | ||||
| 			storage = caddy2.GetStorage() | ||||
| 		} | ||||
| 
 | ||||
| 		var ond *certmagic.OnDemandConfig | ||||
| 		if acmeMgmt.OnDemand != nil { | ||||
| 			ond = &certmagic.OnDemandConfig{ | ||||
| 				// TODO: fill this out | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		return certmagic.Config{ | ||||
| 			CA:                      certmagic.LetsEncryptStagingCA, //ap.CA, // TODO: Restore true value | ||||
| 			Email:                   acmeMgmt.Email, | ||||
| 			Agreed:                  true, | ||||
| 			DisableHTTPChallenge:    acmeMgmt.Challenges.HTTP.Disabled, | ||||
| 			DisableTLSALPNChallenge: acmeMgmt.Challenges.TLSALPN.Disabled, | ||||
| 			RenewDurationBefore:     time.Duration(acmeMgmt.RenewAhead), | ||||
| 			AltHTTPPort:             acmeMgmt.Challenges.HTTP.AlternatePort, | ||||
| 			AltTLSALPNPort:          acmeMgmt.Challenges.TLSALPN.AlternatePort, | ||||
| 			DNSProvider:             acmeMgmt.Challenges.dns, | ||||
| 			KeyType:                 supportedCertKeyTypes[acmeMgmt.KeyType], | ||||
| 			CertObtainTimeout:       time.Duration(acmeMgmt.ACMETimeout), | ||||
| 			OnDemand:                ond, | ||||
| 			MustStaple:              acmeMgmt.MustStaple, | ||||
| 			Storage:                 storage, | ||||
| 			// TODO: listenHost | ||||
| 		} | ||||
| 		return acmeMgmt.makeCertMagicConfig() | ||||
| 	} | ||||
| 
 | ||||
| 	return certmagic.Config{ | ||||
| @ -260,13 +221,9 @@ type OnDemandConfig struct { | ||||
| 	AskStarlark string `json:"ask_starlark,omitempty"` | ||||
| } | ||||
| 
 | ||||
| // supportedCertKeyTypes is all the key types that are supported | ||||
| // for certificates that are obtained through ACME. | ||||
| var supportedCertKeyTypes = map[string]certcrypto.KeyType{ | ||||
| 	"RSA2048": certcrypto.RSA2048, | ||||
| 	"RSA4096": certcrypto.RSA4096, | ||||
| 	"P256":    certcrypto.EC256, | ||||
| 	"P384":    certcrypto.EC384, | ||||
| // ManagerMaker makes a certificate manager. | ||||
| type ManagerMaker interface { | ||||
| 	newManager(interactive bool) (certmagic.Manager, error) | ||||
| } | ||||
| 
 | ||||
| // supportedCipherSuites is the unordered map of cipher suite | ||||
|  | ||||
							
								
								
									
										16
									
								
								storage.go
									
									
									
									
									
								
							
							
						
						
									
										16
									
								
								storage.go
									
									
									
									
									
								
							| @ -16,22 +16,14 @@ func init() { | ||||
| } | ||||
| 
 | ||||
| // StorageConverter is a type that can convert itself | ||||
| // to a valid, usable certmagic.Storage value. The | ||||
| // value might be short-lived. | ||||
| // to a valid, usable certmagic.Storage value. (The | ||||
| // value might be short-lived.) This interface allows | ||||
| // us to adapt any CertMagic storage implementation | ||||
| // into a consistent API for Caddy configuration. | ||||
| type StorageConverter interface { | ||||
| 	CertMagicStorage() (certmagic.Storage, error) | ||||
| } | ||||
| 
 | ||||
| // TODO: Wrappers other than file_system should be enterprise-only. | ||||
| 
 | ||||
| // It may seem trivial to wrap these, but the benefits are: | ||||
| // 1. We don't need to change the actual CertMagic storage implementions | ||||
| // to a structure that is operable with Caddy's config (including JSON | ||||
| // tags), and | ||||
| // 2. We don't need to rely on rely on maintainers of third-party | ||||
| // certmagic.Storage implementations. We can make any certmagic.Storage | ||||
| // work with Caddy this way. | ||||
| 
 | ||||
| // fileStorage is a certmagic.Storage wrapper for certmagic.FileStorage. | ||||
| type fileStorage struct { | ||||
| 	Root string `json:"root"` | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user