diff --git a/provider/acme/challenge_http.go b/provider/acme/challenge_http.go index e620dbc4e..de9cd2407 100644 --- a/provider/acme/challenge_http.go +++ b/provider/acme/challenge_http.go @@ -1,7 +1,6 @@ package acme import ( - "fmt" "net" "net/http" "time" @@ -21,43 +20,12 @@ type challengeHTTP struct { // Present presents a challenge to obtain new ACME certificate func (c *challengeHTTP) Present(domain, token, keyAuth string) error { - httpChallenges, err := c.Store.GetHTTPChallenges() - if err != nil { - return fmt.Errorf("unable to get HTTPChallenges : %s", err) - } - - if httpChallenges == nil { - httpChallenges = map[string]map[string][]byte{} - } - - if _, ok := httpChallenges[token]; !ok { - httpChallenges[token] = map[string][]byte{} - } - - httpChallenges[token][domain] = []byte(keyAuth) - - return c.Store.SaveHTTPChallenges(httpChallenges) + return c.Store.SetHTTPChallengeToken(token, domain, []byte(keyAuth)) } // CleanUp cleans the challenges when certificate is obtained func (c *challengeHTTP) CleanUp(domain, token, keyAuth string) error { - httpChallenges, err := c.Store.GetHTTPChallenges() - if err != nil { - return fmt.Errorf("unable to get HTTPChallenges : %s", err) - } - - log.Debugf("Challenge CleanUp for domain %s", domain) - - if _, ok := httpChallenges[token]; ok { - if _, domainOk := httpChallenges[token][domain]; domainOk { - delete(httpChallenges[token], domain) - } - if len(httpChallenges[token]) == 0 { - delete(httpChallenges, token) - } - return c.Store.SaveHTTPChallenges(httpChallenges) - } - return nil + return c.Store.RemoveHTTPChallengeToken(token, domain) } // Timeout calculates the maximum of time allowed to resolved an ACME challenge @@ -70,16 +38,9 @@ func getTokenValue(token, domain string, store Store) []byte { var result []byte operation := func() error { - httpChallenges, err := store.GetHTTPChallenges() - if err != nil { - return fmt.Errorf("HTTPChallenges not available : %s", err) - } - - var ok bool - if result, ok = httpChallenges[token][domain]; !ok { - return fmt.Errorf("cannot find challenge for token %v", token) - } - return nil + var err error + result, err = store.GetHTTPChallengeToken(token, domain) + return err } notify := func(err error, time time.Duration) { diff --git a/provider/acme/local_store.go b/provider/acme/local_store.go index c27ae1c60..2407fbc83 100644 --- a/provider/acme/local_store.go +++ b/provider/acme/local_store.go @@ -2,6 +2,7 @@ package acme import ( "encoding/json" + "fmt" "io/ioutil" "os" "regexp" @@ -154,14 +155,60 @@ func (s *LocalStore) SaveCertificates(certificates []*Certificate) error { return nil } -// GetHTTPChallenges returns ACME HTTP Challenges list -func (s *LocalStore) GetHTTPChallenges() (map[string]map[string][]byte, error) { - return s.storedData.HTTPChallenges, nil +// GetHTTPChallengeToken Get the http challenge token from the store +func (s *LocalStore) GetHTTPChallengeToken(token, domain string) ([]byte, error) { + s.lock.RLock() + defer s.lock.RUnlock() + + if s.storedData.HTTPChallenges == nil { + s.storedData.HTTPChallenges = map[string]map[string][]byte{} + } + + if _, ok := s.storedData.HTTPChallenges[token]; !ok { + return nil, fmt.Errorf("cannot find challenge for token %v", token) + } + + result, ok := s.storedData.HTTPChallenges[token][domain] + if !ok { + return nil, fmt.Errorf("cannot find challenge for token %v", token) + } + return result, nil } -// SaveHTTPChallenges stores ACME HTTP Challenges list -func (s *LocalStore) SaveHTTPChallenges(httpChallenges map[string]map[string][]byte) error { - s.storedData.HTTPChallenges = httpChallenges +// SetHTTPChallengeToken Set the http challenge token in the store +func (s *LocalStore) SetHTTPChallengeToken(token, domain string, keyAuth []byte) error { + s.lock.Lock() + defer s.lock.Unlock() + + if s.storedData.HTTPChallenges == nil { + s.storedData.HTTPChallenges = map[string]map[string][]byte{} + } + + if _, ok := s.storedData.HTTPChallenges[token]; !ok { + s.storedData.HTTPChallenges[token] = map[string][]byte{} + } + + s.storedData.HTTPChallenges[token][domain] = []byte(keyAuth) + return nil +} + +// RemoveHTTPChallengeToken Remove the http challenge token in the store +func (s *LocalStore) RemoveHTTPChallengeToken(token, domain string) error { + s.lock.Lock() + defer s.lock.Unlock() + + if s.storedData.HTTPChallenges == nil { + return nil + } + + if _, ok := s.storedData.HTTPChallenges[token]; ok { + if _, domainOk := s.storedData.HTTPChallenges[token][domain]; domainOk { + delete(s.storedData.HTTPChallenges[token], domain) + } + if len(s.storedData.HTTPChallenges[token]) == 0 { + delete(s.storedData.HTTPChallenges, token) + } + } return nil } diff --git a/provider/acme/store.go b/provider/acme/store.go index efd97852b..7573d1635 100644 --- a/provider/acme/store.go +++ b/provider/acme/store.go @@ -15,8 +15,9 @@ type Store interface { GetCertificates() ([]*Certificate, error) SaveCertificates([]*Certificate) error - GetHTTPChallenges() (map[string]map[string][]byte, error) - SaveHTTPChallenges(map[string]map[string][]byte) error + GetHTTPChallengeToken(token, domain string) ([]byte, error) + SetHTTPChallengeToken(token, domain string, keyAuth []byte) error + RemoveHTTPChallengeToken(token, domain string) error AddTLSChallenge(domain string, cert *Certificate) error GetTLSChallenge(domain string) (*Certificate, error)