mirror of
https://github.com/caddyserver/caddy.git
synced 2025-02-24 23:57:05 -05:00
vendor: Update certmagic
This commit is contained in:
parent
393bc2992e
commit
598de9e6d9
10 changed files with 111 additions and 76 deletions
12
vendor/github.com/mholt/certmagic/certmagic.go
generated
vendored
12
vendor/github.com/mholt/certmagic/certmagic.go
generated
vendored
|
@ -16,12 +16,12 @@
|
||||||
// including TLS & HTTPS best practices such as robust OCSP stapling, caching,
|
// including TLS & HTTPS best practices such as robust OCSP stapling, caching,
|
||||||
// HTTP->HTTPS redirects, and more.
|
// HTTP->HTTPS redirects, and more.
|
||||||
//
|
//
|
||||||
// Its high-level API serves your HTTP handlers over HTTPS by simply giving
|
// Its high-level API serves your HTTP handlers over HTTPS if you simply give
|
||||||
// the domain name(s) and the http.Handler; CertMagic will create and run
|
// the domain name(s) and the http.Handler; CertMagic will create and run
|
||||||
// the HTTPS server for you, fully managing certificates during the lifetime
|
// the HTTPS server for you, fully managing certificates during the lifetime
|
||||||
// of the server. Similarly, it can be used to start TLS listeners or return
|
// of the server. Similarly, it can be used to start TLS listeners or return
|
||||||
// a ready-to-use tls.Config -- whatever layer you need TLS for, CertMagic
|
// a ready-to-use tls.Config -- whatever layer you need TLS for, CertMagic
|
||||||
// makes it easy.
|
// makes it easy. See the HTTPS, Listen, and TLS functions for that.
|
||||||
//
|
//
|
||||||
// If you need more control, create a Config using New() and then call
|
// If you need more control, create a Config using New() and then call
|
||||||
// Manage() on the config; but you'll have to be sure to solve the HTTP
|
// Manage() on the config; but you'll have to be sure to solve the HTTP
|
||||||
|
@ -475,10 +475,14 @@ const (
|
||||||
// forward packets from the defaults to whatever these
|
// forward packets from the defaults to whatever these
|
||||||
// are set to; otherwise ACME challenges will fail.
|
// are set to; otherwise ACME challenges will fail.
|
||||||
var (
|
var (
|
||||||
// HTTPPort is the port on which to serve HTTP.
|
// HTTPPort is the port on which to serve HTTP
|
||||||
|
// and, by extension, the HTTP challenge (unless
|
||||||
|
// AltHTTPPort is set).
|
||||||
HTTPPort = 80
|
HTTPPort = 80
|
||||||
|
|
||||||
// HTTPSPort is the port on which to serve HTTPS.
|
// HTTPSPort is the port on which to serve HTTPS
|
||||||
|
// and, by extension, the TLS-ALPN challenge
|
||||||
|
// (unless AltTLSALPNPort is set).
|
||||||
HTTPSPort = 443
|
HTTPSPort = 443
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
14
vendor/github.com/mholt/certmagic/client.go
generated
vendored
14
vendor/github.com/mholt/certmagic/client.go
generated
vendored
|
@ -142,6 +142,12 @@ func (cfg *Config) newACMEClient(interactive bool) (*acmeClient, error) {
|
||||||
// figure out which ports we'll be serving the challenges on
|
// figure out which ports we'll be serving the challenges on
|
||||||
useHTTPPort := HTTPChallengePort
|
useHTTPPort := HTTPChallengePort
|
||||||
useTLSALPNPort := TLSALPNChallengePort
|
useTLSALPNPort := TLSALPNChallengePort
|
||||||
|
if HTTPPort > 0 && HTTPPort != HTTPChallengePort {
|
||||||
|
useHTTPPort = HTTPPort
|
||||||
|
}
|
||||||
|
if HTTPSPort > 0 && HTTPSPort != TLSALPNChallengePort {
|
||||||
|
useTLSALPNPort = HTTPSPort
|
||||||
|
}
|
||||||
if cfg.AltHTTPPort > 0 {
|
if cfg.AltHTTPPort > 0 {
|
||||||
useHTTPPort = cfg.AltHTTPPort
|
useHTTPPort = cfg.AltHTTPPort
|
||||||
}
|
}
|
||||||
|
@ -333,7 +339,7 @@ func (c *acmeClient) Renew(name string) error {
|
||||||
// Revoke revokes the certificate for name and deletes
|
// Revoke revokes the certificate for name and deletes
|
||||||
// it from storage.
|
// it from storage.
|
||||||
func (c *acmeClient) Revoke(name string) error {
|
func (c *acmeClient) Revoke(name string) error {
|
||||||
if !c.config.certCache.storage.Exists(prefixSiteKey(c.config.CA, name)) {
|
if !c.config.certCache.storage.Exists(StorageKeys.SitePrivateKey(c.config.CA, name)) {
|
||||||
return fmt.Errorf("private key not found for %s", name)
|
return fmt.Errorf("private key not found for %s", name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -351,15 +357,15 @@ func (c *acmeClient) Revoke(name string) error {
|
||||||
c.config.OnEvent("acme_cert_revoked", name)
|
c.config.OnEvent("acme_cert_revoked", name)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = c.config.certCache.storage.Delete(prefixSiteCert(c.config.CA, name))
|
err = c.config.certCache.storage.Delete(StorageKeys.SiteCert(c.config.CA, name))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("certificate revoked, but unable to delete certificate file: %v", err)
|
return fmt.Errorf("certificate revoked, but unable to delete certificate file: %v", err)
|
||||||
}
|
}
|
||||||
err = c.config.certCache.storage.Delete(prefixSiteKey(c.config.CA, name))
|
err = c.config.certCache.storage.Delete(StorageKeys.SitePrivateKey(c.config.CA, name))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("certificate revoked, but unable to delete private key: %v", err)
|
return fmt.Errorf("certificate revoked, but unable to delete private key: %v", err)
|
||||||
}
|
}
|
||||||
err = c.config.certCache.storage.Delete(prefixSiteMeta(c.config.CA, name))
|
err = c.config.certCache.storage.Delete(StorageKeys.SiteMeta(c.config.CA, name))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("certificate revoked, but unable to delete certificate metadata: %v", err)
|
return fmt.Errorf("certificate revoked, but unable to delete certificate metadata: %v", err)
|
||||||
}
|
}
|
||||||
|
|
2
vendor/github.com/mholt/certmagic/config.go
generated
vendored
2
vendor/github.com/mholt/certmagic/config.go
generated
vendored
|
@ -266,7 +266,7 @@ func (cfg *Config) ObtainCert(name string, interactive bool) error {
|
||||||
|
|
||||||
// we expect this to be a new site; if the
|
// we expect this to be a new site; if the
|
||||||
// cert already exists, then no-op
|
// cert already exists, then no-op
|
||||||
if cfg.certCache.storage.Exists(prefixSiteCert(cfg.CA, name)) {
|
if cfg.certCache.storage.Exists(StorageKeys.SiteCert(cfg.CA, name)) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
12
vendor/github.com/mholt/certmagic/crypto.go
generated
vendored
12
vendor/github.com/mholt/certmagic/crypto.go
generated
vendored
|
@ -104,15 +104,15 @@ func (cfg *Config) saveCertResource(cert *certificate.Resource) error {
|
||||||
|
|
||||||
all := []keyValue{
|
all := []keyValue{
|
||||||
{
|
{
|
||||||
key: prefixSiteCert(cfg.CA, cert.Domain),
|
key: StorageKeys.SiteCert(cfg.CA, cert.Domain),
|
||||||
value: cert.Certificate,
|
value: cert.Certificate,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: prefixSiteKey(cfg.CA, cert.Domain),
|
key: StorageKeys.SitePrivateKey(cfg.CA, cert.Domain),
|
||||||
value: cert.PrivateKey,
|
value: cert.PrivateKey,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: prefixSiteMeta(cfg.CA, cert.Domain),
|
key: StorageKeys.SiteMeta(cfg.CA, cert.Domain),
|
||||||
value: metaBytes,
|
value: metaBytes,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -122,15 +122,15 @@ func (cfg *Config) saveCertResource(cert *certificate.Resource) error {
|
||||||
|
|
||||||
func (cfg *Config) loadCertResource(domain string) (certificate.Resource, error) {
|
func (cfg *Config) loadCertResource(domain string) (certificate.Resource, error) {
|
||||||
var certRes certificate.Resource
|
var certRes certificate.Resource
|
||||||
certBytes, err := cfg.certCache.storage.Load(prefixSiteCert(cfg.CA, domain))
|
certBytes, err := cfg.certCache.storage.Load(StorageKeys.SiteCert(cfg.CA, domain))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return certRes, err
|
return certRes, err
|
||||||
}
|
}
|
||||||
keyBytes, err := cfg.certCache.storage.Load(prefixSiteKey(cfg.CA, domain))
|
keyBytes, err := cfg.certCache.storage.Load(StorageKeys.SitePrivateKey(cfg.CA, domain))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return certRes, err
|
return certRes, err
|
||||||
}
|
}
|
||||||
metaBytes, err := cfg.certCache.storage.Load(prefixSiteMeta(cfg.CA, domain))
|
metaBytes, err := cfg.certCache.storage.Load(StorageKeys.SiteMeta(cfg.CA, domain))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return certRes, err
|
return certRes, err
|
||||||
}
|
}
|
||||||
|
|
18
vendor/github.com/mholt/certmagic/filestorage.go
generated
vendored
18
vendor/github.com/mholt/certmagic/filestorage.go
generated
vendored
|
@ -33,13 +33,13 @@ type FileStorage struct {
|
||||||
|
|
||||||
// Exists returns true if key exists in fs.
|
// Exists returns true if key exists in fs.
|
||||||
func (fs FileStorage) Exists(key string) bool {
|
func (fs FileStorage) Exists(key string) bool {
|
||||||
_, err := os.Stat(fs.filename(key))
|
_, err := os.Stat(fs.Filename(key))
|
||||||
return !os.IsNotExist(err)
|
return !os.IsNotExist(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Store saves value at key.
|
// Store saves value at key.
|
||||||
func (fs FileStorage) Store(key string, value []byte) error {
|
func (fs FileStorage) Store(key string, value []byte) error {
|
||||||
filename := fs.filename(key)
|
filename := fs.Filename(key)
|
||||||
err := os.MkdirAll(filepath.Dir(filename), 0700)
|
err := os.MkdirAll(filepath.Dir(filename), 0700)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -49,7 +49,7 @@ func (fs FileStorage) Store(key string, value []byte) error {
|
||||||
|
|
||||||
// Load retrieves the value at key.
|
// Load retrieves the value at key.
|
||||||
func (fs FileStorage) Load(key string) ([]byte, error) {
|
func (fs FileStorage) Load(key string) ([]byte, error) {
|
||||||
contents, err := ioutil.ReadFile(fs.filename(key))
|
contents, err := ioutil.ReadFile(fs.Filename(key))
|
||||||
if os.IsNotExist(err) {
|
if os.IsNotExist(err) {
|
||||||
return nil, ErrNotExist(err)
|
return nil, ErrNotExist(err)
|
||||||
}
|
}
|
||||||
|
@ -59,7 +59,7 @@ func (fs FileStorage) Load(key string) ([]byte, error) {
|
||||||
// Delete deletes the value at key.
|
// Delete deletes the value at key.
|
||||||
// TODO: Delete any empty folders caused by this operation
|
// TODO: Delete any empty folders caused by this operation
|
||||||
func (fs FileStorage) Delete(key string) error {
|
func (fs FileStorage) Delete(key string) error {
|
||||||
err := os.Remove(fs.filename(key))
|
err := os.Remove(fs.Filename(key))
|
||||||
if os.IsNotExist(err) {
|
if os.IsNotExist(err) {
|
||||||
return ErrNotExist(err)
|
return ErrNotExist(err)
|
||||||
}
|
}
|
||||||
|
@ -68,7 +68,7 @@ func (fs FileStorage) Delete(key string) error {
|
||||||
|
|
||||||
// List returns all keys that match prefix.
|
// List returns all keys that match prefix.
|
||||||
func (fs FileStorage) List(prefix string) ([]string, error) {
|
func (fs FileStorage) List(prefix string) ([]string, error) {
|
||||||
d, err := os.Open(fs.filename(prefix))
|
d, err := os.Open(fs.Filename(prefix))
|
||||||
if os.IsNotExist(err) {
|
if os.IsNotExist(err) {
|
||||||
return nil, ErrNotExist(err)
|
return nil, ErrNotExist(err)
|
||||||
}
|
}
|
||||||
|
@ -81,7 +81,7 @@ func (fs FileStorage) List(prefix string) ([]string, error) {
|
||||||
|
|
||||||
// Stat returns information about key.
|
// Stat returns information about key.
|
||||||
func (fs FileStorage) Stat(key string) (KeyInfo, error) {
|
func (fs FileStorage) Stat(key string) (KeyInfo, error) {
|
||||||
fi, err := os.Stat(fs.filename(key))
|
fi, err := os.Stat(fs.Filename(key))
|
||||||
if os.IsNotExist(err) {
|
if os.IsNotExist(err) {
|
||||||
return KeyInfo{}, ErrNotExist(err)
|
return KeyInfo{}, ErrNotExist(err)
|
||||||
}
|
}
|
||||||
|
@ -95,7 +95,9 @@ func (fs FileStorage) Stat(key string) (KeyInfo, error) {
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (fs FileStorage) filename(key string) string {
|
// Filename returns the key as a path on the file
|
||||||
|
// system prefixed by fs.Path.
|
||||||
|
func (fs FileStorage) Filename(key string) string {
|
||||||
return filepath.Join(fs.Path, filepath.FromSlash(key))
|
return filepath.Join(fs.Path, filepath.FromSlash(key))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -149,7 +151,7 @@ func (fs FileStorage) TryLock(key string) (Waiter, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
fw = &fileStorageWaiter{
|
fw = &fileStorageWaiter{
|
||||||
filename: filepath.Join(lockDir, safeKey(key)+".lock"),
|
filename: filepath.Join(lockDir, StorageKeys.safe(key)+".lock"),
|
||||||
wg: new(sync.WaitGroup),
|
wg: new(sync.WaitGroup),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
2
vendor/github.com/mholt/certmagic/ocsp.go
generated
vendored
2
vendor/github.com/mholt/certmagic/ocsp.go
generated
vendored
|
@ -52,7 +52,7 @@ func (certCache *Cache) stapleOCSP(cert *Certificate, pemBundle []byte) error {
|
||||||
|
|
||||||
// First try to load OCSP staple from storage and see if
|
// First try to load OCSP staple from storage and see if
|
||||||
// we can still use it.
|
// we can still use it.
|
||||||
ocspStapleKey := prefixOCSPStaple(cert, pemBundle)
|
ocspStapleKey := StorageKeys.OCSPStaple(cert, pemBundle)
|
||||||
cachedOCSP, err := certCache.storage.Load(ocspStapleKey)
|
cachedOCSP, err := certCache.storage.Load(ocspStapleKey)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
resp, err := ocsp.ParseResponse(cachedOCSP, nil)
|
resp, err := ocsp.ParseResponse(cachedOCSP, nil)
|
||||||
|
|
4
vendor/github.com/mholt/certmagic/solvers.go
generated
vendored
4
vendor/github.com/mholt/certmagic/solvers.go
generated
vendored
|
@ -134,13 +134,13 @@ func (dhs distributedSolver) CleanUp(domain, token, keyAuth string) error {
|
||||||
|
|
||||||
// challengeTokensPrefix returns the key prefix for challenge info.
|
// challengeTokensPrefix returns the key prefix for challenge info.
|
||||||
func (dhs distributedSolver) challengeTokensPrefix() string {
|
func (dhs distributedSolver) challengeTokensPrefix() string {
|
||||||
return filepath.Join(prefixCA(dhs.config.CA), "challenge_tokens")
|
return filepath.Join(StorageKeys.CAPrefix(dhs.config.CA), "challenge_tokens")
|
||||||
}
|
}
|
||||||
|
|
||||||
// challengeTokensKey returns the key to use to store and access
|
// challengeTokensKey returns the key to use to store and access
|
||||||
// challenge info for domain.
|
// challenge info for domain.
|
||||||
func (dhs distributedSolver) challengeTokensKey(domain string) string {
|
func (dhs distributedSolver) challengeTokensKey(domain string) string {
|
||||||
return filepath.Join(dhs.challengeTokensPrefix(), safeKey(domain)+".json")
|
return filepath.Join(dhs.challengeTokensPrefix(), StorageKeys.safe(domain)+".json")
|
||||||
}
|
}
|
||||||
|
|
||||||
type challengeInfo struct {
|
type challengeInfo struct {
|
||||||
|
|
107
vendor/github.com/mholt/certmagic/storage.go
generated
vendored
107
vendor/github.com/mholt/certmagic/storage.go
generated
vendored
|
@ -117,91 +117,100 @@ type keyValue struct {
|
||||||
value []byte
|
value []byte
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
// KeyBuilder provides a namespace for methods that
|
||||||
prefixACME = "acme"
|
// build keys and key prefixes, for addressing items
|
||||||
prefixOCSP = "ocsp"
|
// in a Storage implementation.
|
||||||
)
|
type KeyBuilder struct{}
|
||||||
|
|
||||||
func prefixCA(ca string) string {
|
// CAPrefix returns the storage key prefix for
|
||||||
|
// the given certificate authority URL.
|
||||||
|
func (keys KeyBuilder) CAPrefix(ca string) string {
|
||||||
caURL, err := url.Parse(ca)
|
caURL, err := url.Parse(ca)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
caURL = &url.URL{Host: ca}
|
caURL = &url.URL{Host: ca}
|
||||||
}
|
}
|
||||||
return path.Join(prefixACME, safeKey(caURL.Host))
|
return path.Join(prefixACME, keys.safe(caURL.Host))
|
||||||
}
|
}
|
||||||
|
|
||||||
func prefixSite(ca, domain string) string {
|
// SitePrefix returns a key prefix for items associated with
|
||||||
return path.Join(prefixCA(ca), "sites", safeKey(domain))
|
// the site using the given CA URL.
|
||||||
|
func (keys KeyBuilder) SitePrefix(ca, domain string) string {
|
||||||
|
return path.Join(keys.CAPrefix(ca), "sites", keys.safe(domain))
|
||||||
}
|
}
|
||||||
|
|
||||||
// prefixSiteCert returns the path to the certificate file for domain.
|
// SiteCert returns the path to the certificate file for domain.
|
||||||
func prefixSiteCert(ca, domain string) string {
|
func (keys KeyBuilder) SiteCert(ca, domain string) string {
|
||||||
return path.Join(prefixSite(ca, domain), safeKey(domain)+".crt")
|
return path.Join(keys.SitePrefix(ca, domain), keys.safe(domain)+".crt")
|
||||||
}
|
}
|
||||||
|
|
||||||
// prefixSiteKey returns the path to domain's private key file.
|
// SitePrivateKey returns the path to domain's private key file.
|
||||||
func prefixSiteKey(ca, domain string) string {
|
func (keys KeyBuilder) SitePrivateKey(ca, domain string) string {
|
||||||
return path.Join(prefixSite(ca, domain), safeKey(domain)+".key")
|
return path.Join(keys.SitePrefix(ca, domain), keys.safe(domain)+".key")
|
||||||
}
|
}
|
||||||
|
|
||||||
// prefixSiteMeta returns the path to the domain's asset metadata file.
|
// SiteMeta returns the path to the domain's asset metadata file.
|
||||||
func prefixSiteMeta(ca, domain string) string {
|
func (keys KeyBuilder) SiteMeta(ca, domain string) string {
|
||||||
return path.Join(prefixSite(ca, domain), safeKey(domain)+".json")
|
return path.Join(keys.SitePrefix(ca, domain), keys.safe(domain)+".json")
|
||||||
}
|
}
|
||||||
|
|
||||||
func prefixUsers(ca string) string {
|
// UsersPrefix returns a key prefix for items related to
|
||||||
return path.Join(prefixCA(ca), "users")
|
// users associated with the given CA URL.
|
||||||
|
func (keys KeyBuilder) UsersPrefix(ca string) string {
|
||||||
|
return path.Join(keys.CAPrefix(ca), "users")
|
||||||
}
|
}
|
||||||
|
|
||||||
// prefixUser gets the account folder for the user with email
|
// UserPrefix returns a key prefix for items related to
|
||||||
func prefixUser(ca, email string) string {
|
// the user with the given email for the given CA URL.
|
||||||
|
func (keys KeyBuilder) UserPrefix(ca, email string) string {
|
||||||
if email == "" {
|
if email == "" {
|
||||||
email = emptyEmail
|
email = emptyEmail
|
||||||
}
|
}
|
||||||
return path.Join(prefixUsers(ca), safeKey(email))
|
return path.Join(keys.UsersPrefix(ca), keys.safe(email))
|
||||||
}
|
}
|
||||||
|
|
||||||
// prefixUserReg gets the path to the registration file for the user with the
|
// UserReg gets the path to the registration file for the user
|
||||||
// given email address.
|
// with the given email address for the given CA URL.
|
||||||
func prefixUserReg(ca, email string) string {
|
func (keys KeyBuilder) UserReg(ca, email string) string {
|
||||||
return safeUserKey(ca, email, "registration", ".json")
|
return keys.safeUserKey(ca, email, "registration", ".json")
|
||||||
}
|
}
|
||||||
|
|
||||||
// prefixUserKey gets the path to the private key file for the user with the
|
// UserPrivateKey gets the path to the private key file for the
|
||||||
// given email address.
|
// user with the given email address on the given CA URL.
|
||||||
func prefixUserKey(ca, email string) string {
|
func (keys KeyBuilder) UserPrivateKey(ca, email string) string {
|
||||||
return safeUserKey(ca, email, "private", ".key")
|
return keys.safeUserKey(ca, email, "private", ".key")
|
||||||
}
|
}
|
||||||
|
|
||||||
func prefixOCSPStaple(cert *Certificate, pemBundle []byte) string {
|
// OCSPStaple returns a key for the OCSP staple associated
|
||||||
|
// with the given certificate. If you have the PEM bundle
|
||||||
|
// handy, pass that in to save an extra encoding step.
|
||||||
|
func (keys KeyBuilder) OCSPStaple(cert *Certificate, pemBundle []byte) string {
|
||||||
var ocspFileName string
|
var ocspFileName string
|
||||||
if len(cert.Names) > 0 {
|
if len(cert.Names) > 0 {
|
||||||
firstName := safeKey(cert.Names[0])
|
firstName := keys.safe(cert.Names[0])
|
||||||
ocspFileName = firstName + "-"
|
ocspFileName = firstName + "-"
|
||||||
}
|
}
|
||||||
ocspFileName += fastHash(pemBundle)
|
ocspFileName += fastHash(pemBundle)
|
||||||
return path.Join(prefixOCSP, ocspFileName)
|
return path.Join(prefixOCSP, ocspFileName)
|
||||||
}
|
}
|
||||||
|
|
||||||
// safeUserKey returns a key for the given email,
|
// safeUserKey returns a key for the given email, with the default
|
||||||
// with the default filename, and the filename
|
// filename, and the filename ending in the given extension.
|
||||||
// ending in the given extension.
|
func (keys KeyBuilder) safeUserKey(ca, email, defaultFilename, extension string) string {
|
||||||
func safeUserKey(ca, email, defaultFilename, extension string) string {
|
|
||||||
if email == "" {
|
if email == "" {
|
||||||
email = emptyEmail
|
email = emptyEmail
|
||||||
}
|
}
|
||||||
email = strings.ToLower(email)
|
email = strings.ToLower(email)
|
||||||
filename := emailUsername(email)
|
filename := keys.emailUsername(email)
|
||||||
if filename == "" {
|
if filename == "" {
|
||||||
filename = defaultFilename
|
filename = defaultFilename
|
||||||
}
|
}
|
||||||
filename = safeKey(filename)
|
filename = keys.safe(filename)
|
||||||
return path.Join(prefixUser(ca, email), filename+extension)
|
return path.Join(keys.UserPrefix(ca, email), filename+extension)
|
||||||
}
|
}
|
||||||
|
|
||||||
// emailUsername returns the username portion of an email address (part before
|
// emailUsername returns the username portion of an email address (part before
|
||||||
// '@') or the original input if it can't find the "@" symbol.
|
// '@') or the original input if it can't find the "@" symbol.
|
||||||
func emailUsername(email string) string {
|
func (keys KeyBuilder) emailUsername(email string) string {
|
||||||
at := strings.Index(email, "@")
|
at := strings.Index(email, "@")
|
||||||
if at == -1 {
|
if at == -1 {
|
||||||
return email
|
return email
|
||||||
|
@ -211,8 +220,9 @@ func emailUsername(email string) string {
|
||||||
return email[:at]
|
return email[:at]
|
||||||
}
|
}
|
||||||
|
|
||||||
// safeKey standardizes and sanitizes str for use in a file path.
|
// safe standardizes and sanitizes str for use as
|
||||||
func safeKey(str string) string {
|
// a storage key. This method is idempotent.
|
||||||
|
func (keys KeyBuilder) safe(str string) string {
|
||||||
str = strings.ToLower(str)
|
str = strings.ToLower(str)
|
||||||
str = strings.TrimSpace(str)
|
str = strings.TrimSpace(str)
|
||||||
|
|
||||||
|
@ -229,6 +239,19 @@ func safeKey(str string) string {
|
||||||
return safeKeyRE.ReplaceAllLiteralString(str, "")
|
return safeKeyRE.ReplaceAllLiteralString(str, "")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// StorageKeys provides methods for accessing
|
||||||
|
// keys and key prefixes for items in a Storage.
|
||||||
|
// Typically, you will not need to use this
|
||||||
|
// because accessing storage is abstracted away
|
||||||
|
// for most cases. Only use this if you need to
|
||||||
|
// directly access TLS assets in your application.
|
||||||
|
var StorageKeys KeyBuilder
|
||||||
|
|
||||||
|
const (
|
||||||
|
prefixACME = "acme"
|
||||||
|
prefixOCSP = "ocsp"
|
||||||
|
)
|
||||||
|
|
||||||
// safeKeyRE matches any undesirable characters in storage keys.
|
// safeKeyRE matches any undesirable characters in storage keys.
|
||||||
// Note that this allows dots, so you'll have to strip ".." manually.
|
// Note that this allows dots, so you'll have to strip ".." manually.
|
||||||
var safeKeyRE = regexp.MustCompile(`[^\w@.-]`)
|
var safeKeyRE = regexp.MustCompile(`[^\w@.-]`)
|
||||||
|
|
14
vendor/github.com/mholt/certmagic/user.go
generated
vendored
14
vendor/github.com/mholt/certmagic/user.go
generated
vendored
|
@ -155,7 +155,7 @@ func (cfg *Config) getEmail(userPresent bool) (string, error) {
|
||||||
func (cfg *Config) getUser(email string) (user, error) {
|
func (cfg *Config) getUser(email string) (user, error) {
|
||||||
var user user
|
var user user
|
||||||
|
|
||||||
regBytes, err := cfg.certCache.storage.Load(prefixUserReg(cfg.CA, email))
|
regBytes, err := cfg.certCache.storage.Load(StorageKeys.UserReg(cfg.CA, email))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if _, ok := err.(ErrNotExist); ok {
|
if _, ok := err.(ErrNotExist); ok {
|
||||||
// create a new user
|
// create a new user
|
||||||
|
@ -163,7 +163,7 @@ func (cfg *Config) getUser(email string) (user, error) {
|
||||||
}
|
}
|
||||||
return user, err
|
return user, err
|
||||||
}
|
}
|
||||||
keyBytes, err := cfg.certCache.storage.Load(prefixUserKey(cfg.CA, email))
|
keyBytes, err := cfg.certCache.storage.Load(StorageKeys.UserPrivateKey(cfg.CA, email))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if _, ok := err.(ErrNotExist); ok {
|
if _, ok := err.(ErrNotExist); ok {
|
||||||
// create a new user
|
// create a new user
|
||||||
|
@ -197,11 +197,11 @@ func (cfg *Config) saveUser(user user) error {
|
||||||
|
|
||||||
all := []keyValue{
|
all := []keyValue{
|
||||||
{
|
{
|
||||||
key: prefixUserReg(cfg.CA, user.Email),
|
key: StorageKeys.UserReg(cfg.CA, user.Email),
|
||||||
value: regBytes,
|
value: regBytes,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: prefixUserKey(cfg.CA, user.Email),
|
key: StorageKeys.UserPrivateKey(cfg.CA, user.Email),
|
||||||
value: keyBytes,
|
value: keyBytes,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -240,13 +240,13 @@ func (cfg *Config) askUserAgreement(agreementURL string) bool {
|
||||||
// account, errors here are discarded to simplify code flow in
|
// account, errors here are discarded to simplify code flow in
|
||||||
// the caller, and errors are not important here anyway.
|
// the caller, and errors are not important here anyway.
|
||||||
func (cfg *Config) mostRecentUserEmail() string {
|
func (cfg *Config) mostRecentUserEmail() string {
|
||||||
userList, err := cfg.certCache.storage.List(prefixUsers(cfg.CA))
|
userList, err := cfg.certCache.storage.List(StorageKeys.UsersPrefix(cfg.CA))
|
||||||
if err != nil || len(userList) == 0 {
|
if err != nil || len(userList) == 0 {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
sort.Slice(userList, func(i, j int) bool {
|
sort.Slice(userList, func(i, j int) bool {
|
||||||
iInfo, _ := cfg.certCache.storage.Stat(prefixUser(cfg.CA, userList[i]))
|
iInfo, _ := cfg.certCache.storage.Stat(StorageKeys.UserPrefix(cfg.CA, userList[i]))
|
||||||
jInfo, _ := cfg.certCache.storage.Stat(prefixUser(cfg.CA, userList[j]))
|
jInfo, _ := cfg.certCache.storage.Stat(StorageKeys.UserPrefix(cfg.CA, userList[j]))
|
||||||
return jInfo.Modified.Before(iInfo.Modified)
|
return jInfo.Modified.Before(iInfo.Modified)
|
||||||
})
|
})
|
||||||
user, err := cfg.getUser(userList[0])
|
user, err := cfg.getUser(userList[0])
|
||||||
|
|
2
vendor/manifest
vendored
2
vendor/manifest
vendored
|
@ -138,7 +138,7 @@
|
||||||
"importpath": "github.com/mholt/certmagic",
|
"importpath": "github.com/mholt/certmagic",
|
||||||
"repository": "https://github.com/mholt/certmagic",
|
"repository": "https://github.com/mholt/certmagic",
|
||||||
"vcs": "git",
|
"vcs": "git",
|
||||||
"revision": "8b6ddf223c912a863aaadd388bfdd29be295fb5d",
|
"revision": "5b3085c491553887f36460365533eb5955fdeef0",
|
||||||
"branch": "master",
|
"branch": "master",
|
||||||
"notests": true
|
"notests": true
|
||||||
},
|
},
|
||||||
|
|
Loading…
Add table
Reference in a new issue