Add a mutex on local store for HTTPChallenges
This commit is contained in:
parent
bacd58ed7b
commit
f173ff02e3
4 changed files with 66 additions and 53 deletions
|
@ -175,7 +175,7 @@ func runCmd(globalConfiguration *configuration.GlobalConfiguration, configFile s
|
||||||
log.Debugf("Global configuration loaded %s", string(jsonConf))
|
log.Debugf("Global configuration loaded %s", string(jsonConf))
|
||||||
if acme.IsEnabled() {
|
if acme.IsEnabled() {
|
||||||
store := acme.NewLocalStore(acme.Get().Storage)
|
store := acme.NewLocalStore(acme.Get().Storage)
|
||||||
acme.Get().Store = &store
|
acme.Get().Store = store
|
||||||
}
|
}
|
||||||
svr := server.NewServer(*globalConfiguration, configuration.NewProviderAggregator(globalConfiguration))
|
svr := server.NewServer(*globalConfiguration, configuration.NewProviderAggregator(globalConfiguration))
|
||||||
if acme.IsEnabled() && acme.Get().OnHostRule {
|
if acme.IsEnabled() && acme.Get().OnHostRule {
|
||||||
|
|
|
@ -34,15 +34,9 @@ func getTokenValue(token, domain string, store Store) []byte {
|
||||||
var result []byte
|
var result []byte
|
||||||
|
|
||||||
operation := func() error {
|
operation := func() error {
|
||||||
var ok bool
|
var err error
|
||||||
httpChallenges, err := store.GetHTTPChallenges()
|
result, err = store.GetHTTPChallengeToken(token, domain)
|
||||||
if err != nil {
|
return err
|
||||||
return fmt.Errorf("HTTPChallenges not available : %s", err)
|
|
||||||
}
|
|
||||||
if result, ok = httpChallenges[token][domain]; !ok {
|
|
||||||
return fmt.Errorf("cannot find challenge for token %v", token)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
notify := func(err error, time time.Duration) {
|
notify := func(err error, time time.Duration) {
|
||||||
|
@ -60,40 +54,9 @@ func getTokenValue(token, domain string, store Store) []byte {
|
||||||
}
|
}
|
||||||
|
|
||||||
func presentHTTPChallenge(domain, token, keyAuth string, store Store) error {
|
func presentHTTPChallenge(domain, token, keyAuth string, store Store) error {
|
||||||
httpChallenges, err := store.GetHTTPChallenges()
|
return store.SetHTTPChallengeToken(token, domain, []byte(keyAuth))
|
||||||
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 store.SaveHTTPChallenges(httpChallenges)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func cleanUpHTTPChallenge(domain, token string, store Store) error {
|
func cleanUpHTTPChallenge(domain, token string, store Store) error {
|
||||||
httpChallenges, err := store.GetHTTPChallenges()
|
return store.RemoveHTTPChallengeToken(token, domain)
|
||||||
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 store.SaveHTTPChallenges(httpChallenges)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,9 +2,11 @@ package acme
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"regexp"
|
"regexp"
|
||||||
|
"sync"
|
||||||
|
|
||||||
"github.com/containous/traefik/log"
|
"github.com/containous/traefik/log"
|
||||||
"github.com/containous/traefik/safe"
|
"github.com/containous/traefik/safe"
|
||||||
|
@ -17,11 +19,12 @@ type LocalStore struct {
|
||||||
filename string
|
filename string
|
||||||
storedData *StoredData
|
storedData *StoredData
|
||||||
SaveDataChan chan *StoredData `json:"-"`
|
SaveDataChan chan *StoredData `json:"-"`
|
||||||
|
lock sync.RWMutex
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewLocalStore initializes a new LocalStore with a file name
|
// NewLocalStore initializes a new LocalStore with a file name
|
||||||
func NewLocalStore(filename string) LocalStore {
|
func NewLocalStore(filename string) *LocalStore {
|
||||||
store := LocalStore{filename: filename, SaveDataChan: make(chan *StoredData)}
|
store := &LocalStore{filename: filename, SaveDataChan: make(chan *StoredData)}
|
||||||
store.listenSaveAction()
|
store.listenSaveAction()
|
||||||
return store
|
return store
|
||||||
}
|
}
|
||||||
|
@ -149,13 +152,59 @@ func (s *LocalStore) SaveCertificates(certificates []*Certificate) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetHTTPChallenges returns ACME HTTP Challenges list
|
// GetHTTPChallengeToken Get the http challenge token from the store
|
||||||
func (s *LocalStore) GetHTTPChallenges() (map[string]map[string][]byte, error) {
|
func (s *LocalStore) GetHTTPChallengeToken(token, domain string) ([]byte, error) {
|
||||||
return s.storedData.HTTPChallenges, nil
|
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
|
// SetHTTPChallengeToken Set the http challenge token in the store
|
||||||
func (s *LocalStore) SaveHTTPChallenges(httpChallenges map[string]map[string][]byte) error {
|
func (s *LocalStore) SetHTTPChallengeToken(token, domain string, keyAuth []byte) error {
|
||||||
s.storedData.HTTPChallenges = httpChallenges
|
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
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,7 @@ type Store interface {
|
||||||
SaveAccount(*Account) error
|
SaveAccount(*Account) error
|
||||||
GetCertificates() ([]*Certificate, error)
|
GetCertificates() ([]*Certificate, error)
|
||||||
SaveCertificates([]*Certificate) error
|
SaveCertificates([]*Certificate) error
|
||||||
GetHTTPChallenges() (map[string]map[string][]byte, error)
|
GetHTTPChallengeToken(token, domain string) ([]byte, error)
|
||||||
SaveHTTPChallenges(map[string]map[string][]byte) error
|
SetHTTPChallengeToken(token, domain string, keyAuth []byte) error
|
||||||
|
RemoveHTTPChallengeToken(token, domain string) error
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue