Commit 8a511989 authored by Matthew Holt's avatar Matthew Holt

vendor: Update CertMagic; fix bug related to accounts with empty emails

parent 44e3a97a
...@@ -240,6 +240,10 @@ func NewWithCache(certCache *Cache, cfg Config) *Config { ...@@ -240,6 +240,10 @@ func NewWithCache(certCache *Cache, cfg Config) *Config {
// prepared to serve them up during TLS handshakes. // prepared to serve them up during TLS handshakes.
func (cfg *Config) Manage(domainNames []string) error { func (cfg *Config) Manage(domainNames []string) error {
for _, domainName := range domainNames { for _, domainName := range domainNames {
if !HostQualifies(domainName) {
return fmt.Errorf("name does not qualify for automatic certificate management: %s", domainName)
}
// if on-demand is configured, simply whitelist this name // if on-demand is configured, simply whitelist this name
if cfg.OnDemand != nil { if cfg.OnDemand != nil {
if !cfg.OnDemand.whitelistContains(domainName) { if !cfg.OnDemand.whitelistContains(domainName) {
...@@ -289,6 +293,9 @@ func (cfg *Config) Manage(domainNames []string) error { ...@@ -289,6 +293,9 @@ func (cfg *Config) Manage(domainNames []string) error {
// it does not load them into memory. If interactive is true, // it does not load them into memory. If interactive is true,
// the user may be shown a prompt. // the user may be shown a prompt.
func (cfg *Config) ObtainCert(name string, interactive bool) error { func (cfg *Config) ObtainCert(name string, interactive bool) error {
if cfg.storageHasCertResources(name) {
return nil
}
skip, err := cfg.preObtainOrRenewChecks(name, interactive) skip, err := cfg.preObtainOrRenewChecks(name, interactive)
if err != nil { if err != nil {
return err return err
...@@ -296,16 +303,10 @@ func (cfg *Config) ObtainCert(name string, interactive bool) error { ...@@ -296,16 +303,10 @@ func (cfg *Config) ObtainCert(name string, interactive bool) error {
if skip { if skip {
return nil return nil
} }
if cfg.storageHasCertResources(name) {
return nil
}
client, err := cfg.newACMEClient(interactive) client, err := cfg.newACMEClient(interactive)
if err != nil { if err != nil {
return err return err
} }
return client.Obtain(name) return client.Obtain(name)
} }
......
...@@ -84,10 +84,11 @@ func (cfg *Config) getEmail(allowPrompts bool) error { ...@@ -84,10 +84,11 @@ func (cfg *Config) getEmail(allowPrompts bool) error {
leEmail = Email leEmail = Email
} }
// Then try to get most recent user email from storage // Then try to get most recent user email from storage
var gotRecentEmail bool
if leEmail == "" { if leEmail == "" {
leEmail = cfg.mostRecentUserEmail() leEmail, gotRecentEmail = cfg.mostRecentUserEmail()
} }
if leEmail == "" && allowPrompts { if !gotRecentEmail && leEmail == "" && allowPrompts {
// Looks like there is no email address readily available, // Looks like there is no email address readily available,
// so we will have to ask the user if we can. // so we will have to ask the user if we can.
var err error var err error
...@@ -95,10 +96,14 @@ func (cfg *Config) getEmail(allowPrompts bool) error { ...@@ -95,10 +96,14 @@ func (cfg *Config) getEmail(allowPrompts bool) error {
if err != nil { if err != nil {
return err return err
} }
cfg.Agreed = true
} }
// lower-casing the email is important for consistency
cfg.Email = strings.ToLower(leEmail) // save the email for later and ensure it is consistent
// for repeated use; then update cfg with our new defaults
Email = strings.TrimSpace(strings.ToLower(leEmail))
cfg.Email = Email
cfg.Agreed = Agreed
return nil return nil
} }
...@@ -123,6 +128,11 @@ func (cfg *Config) getAgreementURL() (string, error) { ...@@ -123,6 +128,11 @@ func (cfg *Config) getAgreementURL() (string, error) {
return dir.Meta.TermsOfService, nil return dir.Meta.TermsOfService, nil
} }
// promptUserForEmail prompts the user for an email address
// and returns the email address they entered (which could
// be the empty string). If no error is returned, then Agreed
// will also be set to true, since continuing through the
// prompt signifies agreement.
func (cfg *Config) promptUserForEmail() (string, error) { func (cfg *Config) promptUserForEmail() (string, error) {
agreementURL, err := cfg.getAgreementURL() agreementURL, err := cfg.getAgreementURL()
if err != nil { if err != nil {
...@@ -139,6 +149,7 @@ func (cfg *Config) promptUserForEmail() (string, error) { ...@@ -139,6 +149,7 @@ func (cfg *Config) promptUserForEmail() (string, error) {
return "", fmt.Errorf("reading email address: %v", err) return "", fmt.Errorf("reading email address: %v", err)
} }
leEmail = strings.TrimSpace(leEmail) leEmail = strings.TrimSpace(leEmail)
Agreed = true
return leEmail, nil return leEmail, nil
} }
...@@ -234,10 +245,10 @@ func (cfg *Config) askUserAgreement(agreementURL string) bool { ...@@ -234,10 +245,10 @@ func (cfg *Config) askUserAgreement(agreementURL string) bool {
// in s. Since this is part of a complex sequence to get a user // in s. Since this is part of a complex sequence to get a user
// 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, bool) {
userList, err := cfg.certCache.storage.List(StorageKeys.UsersPrefix(cfg.CA), false) userList, err := cfg.certCache.storage.List(StorageKeys.UsersPrefix(cfg.CA), false)
if err != nil || len(userList) == 0 { if err != nil || len(userList) == 0 {
return "" return "", false
} }
sort.Slice(userList, func(i, j int) bool { sort.Slice(userList, func(i, j int) bool {
iInfo, _ := cfg.certCache.storage.Stat(userList[i]) iInfo, _ := cfg.certCache.storage.Stat(userList[i])
...@@ -246,9 +257,9 @@ func (cfg *Config) mostRecentUserEmail() string { ...@@ -246,9 +257,9 @@ func (cfg *Config) mostRecentUserEmail() string {
}) })
user, err := cfg.getUser(path.Base(userList[0])) user, err := cfg.getUser(path.Base(userList[0]))
if err != nil { if err != nil {
return "" return "", false
} }
return user.Email return user.Email, true
} }
// agreementTestURL is set during tests to skip requiring // agreementTestURL is set during tests to skip requiring
......
...@@ -138,7 +138,7 @@ ...@@ -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": "a7f18a937c080b88693cd4e14d48e42cc067b268", "revision": "e3e89d1096d76d61680f8eeb8f67649baa6c54b8",
"branch": "master", "branch": "master",
"notests": true "notests": true
}, },
......
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