Fix acme account deletion without provider change

This commit is contained in:
Lukas Prettenthaler 2018-07-31 11:50:03 +02:00 committed by Traefiker Bot
parent 91cafd1752
commit 838dd8c19f
3 changed files with 109 additions and 2 deletions

View file

@ -9,6 +9,7 @@ import (
fmtlog "log"
"net"
"net/http"
"net/url"
"reflect"
"strings"
"time"
@ -183,7 +184,8 @@ func (a *ACME) leadershipListener(elected bool) error {
account := object.(*Account)
account.Init()
// Reset Account values if caServer changed, thus registration URI can be updated
if account != nil && account.Registration != nil && !strings.HasPrefix(account.Registration.URI, a.CAServer) {
if account != nil && account.Registration != nil && !isAccountMatchingCaServer(account.Registration.URI, a.CAServer) {
log.Info("Account URI does not match the current CAServer. The account will be reset")
account.reset()
}
@ -230,6 +232,20 @@ func (a *ACME) leadershipListener(elected bool) error {
return nil
}
func isAccountMatchingCaServer(accountURI string, serverURI string) bool {
aru, err := url.Parse(accountURI)
if err != nil {
log.Infof("Unable to parse account.Registration URL : %v", err)
return false
}
cau, err := url.Parse(serverURI)
if err != nil {
log.Infof("Unable to parse CAServer URL : %v", err)
return false
}
return cau.Hostname() == aru.Hostname()
}
func (a *ACME) getCertificate(clientHello *tls.ClientHelloInfo) (*tls.Certificate, error) {
domain := types.CanonicalDomain(clientHello.ServerName)
account := a.store.Get().(*Account)

View file

@ -6,6 +6,7 @@ import (
"fmt"
"io/ioutil"
fmtlog "log"
"net/url"
"reflect"
"strings"
"sync"
@ -130,7 +131,8 @@ func (p *Provider) Init(_ types.Constraints) error {
}
// Reset Account if caServer changed, thus registration URI can be updated
if p.account != nil && p.account.Registration != nil && !strings.HasPrefix(p.account.Registration.URI, p.CAServer) {
if p.account != nil && p.account.Registration != nil && !isAccountMatchingCaServer(p.account.Registration.URI, p.CAServer) {
log.Info("Account URI does not match the current CAServer. The account will be reset")
p.account = nil
}
@ -142,6 +144,20 @@ func (p *Provider) Init(_ types.Constraints) error {
return nil
}
func isAccountMatchingCaServer(accountURI string, serverURI string) bool {
aru, err := url.Parse(accountURI)
if err != nil {
log.Infof("Unable to parse account.Registration URL : %v", err)
return false
}
cau, err := url.Parse(serverURI)
if err != nil {
log.Infof("Unable to parse CAServer URL : %v", err)
return false
}
return cau.Hostname() == aru.Hostname()
}
// Provide allows the file provider to provide configurations to traefik
// using the given Configuration channel.
func (p *Provider) Provide(configurationChan chan<- types.ConfigMessage, pool *safe.Pool) error {

View file

@ -429,3 +429,78 @@ func TestDeleteUnnecessaryDomains(t *testing.T) {
})
}
}
func TestIsAccountMatchingCaServer(t *testing.T) {
testCases := []struct {
desc string
accountURI string
serverURI string
expected bool
}{
{
desc: "acme staging with matching account",
accountURI: "https://acme-staging-v02.api.letsencrypt.org/acme/acct/1234567",
serverURI: "https://acme-staging-v02.api.letsencrypt.org/acme/directory",
expected: true,
},
{
desc: "acme production with matching account",
accountURI: "https://acme-v02.api.letsencrypt.org/acme/acct/1234567",
serverURI: "https://acme-v02.api.letsencrypt.org/acme/directory",
expected: true,
},
{
desc: "http only acme with matching account",
accountURI: "http://acme.api.letsencrypt.org/acme/acct/1234567",
serverURI: "http://acme.api.letsencrypt.org/acme/directory",
expected: true,
},
{
desc: "different subdomains for account and server",
accountURI: "https://test1.example.org/acme/acct/1234567",
serverURI: "https://test2.example.org/acme/directory",
expected: false,
},
{
desc: "different domains for account and server",
accountURI: "https://test.example1.org/acme/acct/1234567",
serverURI: "https://test.example2.org/acme/directory",
expected: false,
},
{
desc: "different tld for account and server",
accountURI: "https://test.example.com/acme/acct/1234567",
serverURI: "https://test.example.org/acme/directory",
expected: false,
},
{
desc: "malformed account url",
accountURI: "//|\\/test.example.com/acme/acct/1234567",
serverURI: "https://test.example.com/acme/directory",
expected: false,
},
{
desc: "malformed server url",
accountURI: "https://test.example.com/acme/acct/1234567",
serverURI: "//|\\/test.example.com/acme/directory",
expected: false,
},
{
desc: "malformed server and account url",
accountURI: "//|\\/test.example.com/acme/acct/1234567",
serverURI: "//|\\/test.example.com/acme/directory",
expected: false,
},
}
for _, test := range testCases {
test := test
t.Run(test.desc, func(t *testing.T) {
t.Parallel()
result := isAccountMatchingCaServer(test.accountURI, test.serverURI)
assert.Equal(t, test.expected, result)
})
}
}