Skip to content

Commit

Permalink
chore: replace GetRecord by GetChallengeInfo (#1863)
Browse files Browse the repository at this point in the history
  • Loading branch information
ldez authored Mar 7, 2023
1 parent 2c9f6b1 commit e638d79
Show file tree
Hide file tree
Showing 122 changed files with 927 additions and 901 deletions.
38 changes: 31 additions & 7 deletions challenge/dns01/dns_challenge.go
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ func (c *Challenge) Solve(authz acme.Authorization) error {
return err
}

fqdn, value := GetRecord(authz.Identifier.Value, keyAuth)
info := GetChallengeInfo(authz.Identifier.Value, keyAuth)

var timeout, interval time.Duration
switch provider := c.provider.(type) {
Expand All @@ -129,7 +129,7 @@ func (c *Challenge) Solve(authz acme.Authorization) error {
time.Sleep(interval)

err = wait.For("propagation", timeout, interval, func() (bool, error) {
stop, errP := c.preCheck.call(domain, fqdn, value)
stop, errP := c.preCheck.call(domain, info.EffectiveFQDN, info.Value)
if !stop || errP != nil {
log.Infof("[%s] acme: Waiting for DNS record propagation.", domain)
}
Expand Down Expand Up @@ -172,20 +172,44 @@ type sequential interface {
}

// GetRecord returns a DNS record which will fulfill the `dns-01` challenge.
// Deprecated: use GetChallengeInfo instead.
func GetRecord(domain, keyAuth string) (fqdn, value string) {
info := GetChallengeInfo(domain, keyAuth)

return info.EffectiveFQDN, info.Value
}

// ChallengeInfo contains the information use to create the TXT record.
type ChallengeInfo struct {
// FQDN is the full-qualified challenge domain (i.e. `_acme-challenge.[domain].`)
FQDN string

// EffectiveFQDN contains the resulting FQDN after the CNAMEs resolutions.
EffectiveFQDN string

// Value contains the value for the TXT record.
Value string
}

// GetChallengeInfo returns information used to create a DNS record which will fulfill the `dns-01` challenge.
func GetChallengeInfo(domain, keyAuth string) ChallengeInfo {
keyAuthShaBytes := sha256.Sum256([]byte(keyAuth))
// base64URL encoding without padding
value = base64.RawURLEncoding.EncodeToString(keyAuthShaBytes[:sha256.Size])
value := base64.RawURLEncoding.EncodeToString(keyAuthShaBytes[:sha256.Size])

fqdn = getChallengeFqdn(domain)
ok, _ := strconv.ParseBool(os.Getenv("LEGO_DISABLE_CNAME_SUPPORT"))

return
return ChallengeInfo{
Value: value,
FQDN: getChallengeFQDN(domain, false),
EffectiveFQDN: getChallengeFQDN(domain, !ok),
}
}

func getChallengeFqdn(domain string) string {
func getChallengeFQDN(domain string, followCNAME bool) string {
fqdn := fmt.Sprintf("_acme-challenge.%s.", domain)

if ok, _ := strconv.ParseBool(os.Getenv("LEGO_DISABLE_CNAME_SUPPORT")); ok {
if !followCNAME {
return fqdn
}

Expand Down
12 changes: 6 additions & 6 deletions challenge/dns01/dns_challenge_manual.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,15 @@ func NewDNSProviderManual() (*DNSProviderManual, error) {

// Present prints instructions for manually creating the TXT record.
func (*DNSProviderManual) Present(domain, token, keyAuth string) error {
fqdn, value := GetRecord(domain, keyAuth)
info := GetChallengeInfo(domain, keyAuth)

authZone, err := FindZoneByFqdn(fqdn)
authZone, err := FindZoneByFqdn(info.EffectiveFQDN)
if err != nil {
return err
}

fmt.Printf("lego: Please create the following TXT record in your %s zone:\n", authZone)
fmt.Printf(dnsTemplate+"\n", fqdn, DefaultTTL, value)
fmt.Printf(dnsTemplate+"\n", info.EffectiveFQDN, DefaultTTL, info.Value)
fmt.Printf("lego: Press 'Enter' when you are done\n")

_, err = bufio.NewReader(os.Stdin).ReadBytes('\n')
Expand All @@ -39,15 +39,15 @@ func (*DNSProviderManual) Present(domain, token, keyAuth string) error {

// CleanUp prints instructions for manually removing the TXT record.
func (*DNSProviderManual) CleanUp(domain, token, keyAuth string) error {
fqdn, _ := GetRecord(domain, keyAuth)
info := GetChallengeInfo(domain, keyAuth)

authZone, err := FindZoneByFqdn(fqdn)
authZone, err := FindZoneByFqdn(info.EffectiveFQDN)
if err != nil {
return err
}

fmt.Printf("lego: You can now remove this TXT record from your %s zone:\n", authZone)
fmt.Printf(dnsTemplate+"\n", fqdn, DefaultTTL, "...")
fmt.Printf(dnsTemplate+"\n", info.EffectiveFQDN, DefaultTTL, "...")

return nil
}
Expand Down
9 changes: 5 additions & 4 deletions docs/content/usage/library/Writing-a-Challenge-Solver.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,15 +59,16 @@ For DNS-01, we'll just use `domain` and `keyAuth`.

```go
func (d *DNSProviderBestDNS) Present(domain, token, keyAuth string) error {
fqdn, value := dns01.GetRecord(domain, keyAuth)
info := dns01.GetChallengeInfo(domain, keyAuth)
// make API request to set a TXT record on fqdn with value and TTL
return nil
}
```

After calling `dns01.GetRecord(domain, keyAuth)`, we now have the information we need to make our API request and set the TXT record:
- `fqdn` is the fully qualified domain name on which to set the TXT record.
- `value` is the record's value to set on the record.
After calling `dns01.GetChallengeInfo(domain, keyAuth)`, we now have the information we need to make our API request and set the TXT record:
- `FQDN` is the fully qualified domain name on which to set the TXT record.
- `EffectiveFQDN` is the fully qualified domain name after the CNAMEs resolutions on which to set the TXT record.
- `Value` is the record's value to set on the record.

So then you make an API request to the DNS service according to their docs.
Once the TXT record is set on the domain, you may return and the challenge will proceed.
Expand Down
19 changes: 5 additions & 14 deletions providers/dns/acmedns/acmedns.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,28 +103,23 @@ func (e ErrCNAMERequired) Error() string {
// This will halt issuance and indicate to the user that a one-time manual setup is required for the domain.
func (d *DNSProvider) Present(domain, _, keyAuth string) error {
// Compute the challenge response FQDN and TXT value for the domain based on the keyAuth.
fqdn, value := dns01.GetRecord(domain, keyAuth)

effectiveDomain := domain
if isCNAME(domain, fqdn) {
effectiveDomain = fqdn
}
info := dns01.GetChallengeInfo(domain, keyAuth)

// Check if credentials were previously saved for this domain.
account, err := d.storage.Fetch(effectiveDomain)
account, err := d.storage.Fetch(domain)
if err != nil {
if errors.Is(err, goacmedns.ErrDomainNotFound) {
// The account did not exist.
// Create a new one and return an error indicating the required one-time manual CNAME setup.
return d.register(effectiveDomain, fqdn)
return d.register(domain, info.FQDN)
}

// Errors other than goacmeDNS.ErrDomainNotFound are unexpected.
// Errors other than goacmedns.ErrDomainNotFound are unexpected.
return err
}

// Update the acme-dns TXT record.
return d.client.UpdateTXTRecord(account, value)
return d.client.UpdateTXTRecord(account, info.Value)
}

// CleanUp removes the record matching the specified parameters. It is not
Expand Down Expand Up @@ -165,7 +160,3 @@ func (d *DNSProvider) register(domain, fqdn string) error {
Target: newAcct.FullDomain,
}
}

func isCNAME(domain, fqdn string) bool {
return fmt.Sprintf("_acme-challenge.%s.", domain) != fqdn
}
12 changes: 6 additions & 6 deletions providers/dns/alidns/alidns.go
Original file line number Diff line number Diff line change
Expand Up @@ -129,14 +129,14 @@ func (d *DNSProvider) Timeout() (timeout, interval time.Duration) {

// Present creates a TXT record to fulfill the dns-01 challenge.
func (d *DNSProvider) Present(domain, token, keyAuth string) error {
fqdn, value := dns01.GetRecord(domain, keyAuth)
info := dns01.GetChallengeInfo(domain, keyAuth)

zoneName, err := d.getHostedZone(fqdn)
zoneName, err := d.getHostedZone(info.EffectiveFQDN)
if err != nil {
return fmt.Errorf("alicloud: %w", err)
}

recordAttributes, err := d.newTxtRecord(zoneName, fqdn, value)
recordAttributes, err := d.newTxtRecord(zoneName, info.EffectiveFQDN, info.Value)
if err != nil {
return err
}
Expand All @@ -150,14 +150,14 @@ func (d *DNSProvider) Present(domain, token, keyAuth string) error {

// CleanUp removes the TXT record matching the specified parameters.
func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error {
fqdn, _ := dns01.GetRecord(domain, keyAuth)
info := dns01.GetChallengeInfo(domain, keyAuth)

records, err := d.findTxtRecords(fqdn)
records, err := d.findTxtRecords(info.EffectiveFQDN)
if err != nil {
return fmt.Errorf("alicloud: %w", err)
}

_, err = d.getHostedZone(fqdn)
_, err = d.getHostedZone(info.EffectiveFQDN)
if err != nil {
return fmt.Errorf("alicloud: %w", err)
}
Expand Down
12 changes: 6 additions & 6 deletions providers/dns/allinkl/allinkl.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,9 +101,9 @@ func (d *DNSProvider) Timeout() (timeout, interval time.Duration) {

// Present creates a TXT record using the specified parameters.
func (d *DNSProvider) Present(domain, token, keyAuth string) error {
fqdn, value := dns01.GetRecord(domain, keyAuth)
info := dns01.GetChallengeInfo(domain, keyAuth)

authZone, err := dns01.FindZoneByFqdn(fqdn)
authZone, err := dns01.FindZoneByFqdn(info.EffectiveFQDN)
if err != nil {
return fmt.Errorf("allinkl: could not determine zone for domain %q: %w", domain, err)
}
Expand All @@ -113,7 +113,7 @@ func (d *DNSProvider) Present(domain, token, keyAuth string) error {
return fmt.Errorf("allinkl: %w", err)
}

subDomain, err := dns01.ExtractSubDomain(fqdn, authZone)
subDomain, err := dns01.ExtractSubDomain(info.EffectiveFQDN, authZone)
if err != nil {
return fmt.Errorf("allinkl: %w", err)
}
Expand All @@ -122,7 +122,7 @@ func (d *DNSProvider) Present(domain, token, keyAuth string) error {
ZoneHost: authZone,
RecordType: "TXT",
RecordName: subDomain,
RecordData: value,
RecordData: info.Value,
}

recordID, err := d.client.AddDNSSettings(credential, record)
Expand All @@ -139,7 +139,7 @@ func (d *DNSProvider) Present(domain, token, keyAuth string) error {

// CleanUp removes the TXT record matching the specified parameters.
func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error {
fqdn, _ := dns01.GetRecord(domain, keyAuth)
info := dns01.GetChallengeInfo(domain, keyAuth)

credential, err := d.client.Authentication(60, true)
if err != nil {
Expand All @@ -151,7 +151,7 @@ func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error {
recordID, ok := d.recordIDs[token]
d.recordIDsMu.Unlock()
if !ok {
return fmt.Errorf("allinkl: unknown record ID for '%s' '%s'", fqdn, token)
return fmt.Errorf("allinkl: unknown record ID for '%s' '%s'", info.EffectiveFQDN, token)
}

_, err = d.client.DeleteDNSSettings(credential, recordID)
Expand Down
16 changes: 8 additions & 8 deletions providers/dns/arvancloud/arvancloud.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,22 +106,22 @@ func (d *DNSProvider) Timeout() (timeout, interval time.Duration) {

// Present creates a TXT record to fulfill the dns-01 challenge.
func (d *DNSProvider) Present(domain, token, keyAuth string) error {
fqdn, value := dns01.GetRecord(domain, keyAuth)
info := dns01.GetChallengeInfo(domain, keyAuth)

authZone, err := getZone(fqdn)
authZone, err := getZone(info.EffectiveFQDN)
if err != nil {
return err
}

subDomain, err := dns01.ExtractSubDomain(fqdn, authZone)
subDomain, err := dns01.ExtractSubDomain(info.EffectiveFQDN, authZone)
if err != nil {
return fmt.Errorf("arvancloud: %w", err)
}

record := internal.DNSRecord{
Type: "txt",
Name: subDomain,
Value: internal.TXTRecordValue{Text: value},
Value: internal.TXTRecordValue{Text: info.Value},
TTL: d.config.TTL,
UpstreamHTTPS: "default",
IPFilterMode: &internal.IPFilterMode{
Expand All @@ -133,7 +133,7 @@ func (d *DNSProvider) Present(domain, token, keyAuth string) error {

newRecord, err := d.client.CreateRecord(authZone, record)
if err != nil {
return fmt.Errorf("arvancloud: failed to add TXT record: fqdn=%s: %w", fqdn, err)
return fmt.Errorf("arvancloud: failed to add TXT record: fqdn=%s: %w", info.EffectiveFQDN, err)
}

d.recordIDsMu.Lock()
Expand All @@ -145,9 +145,9 @@ func (d *DNSProvider) Present(domain, token, keyAuth string) error {

// CleanUp removes the TXT record matching the specified parameters.
func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error {
fqdn, _ := dns01.GetRecord(domain, keyAuth)
info := dns01.GetChallengeInfo(domain, keyAuth)

authZone, err := getZone(fqdn)
authZone, err := getZone(info.EffectiveFQDN)
if err != nil {
return err
}
Expand All @@ -157,7 +157,7 @@ func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error {
recordID, ok := d.recordIDs[token]
d.recordIDsMu.Unlock()
if !ok {
return fmt.Errorf("arvancloud: unknown record ID for '%s' '%s'", fqdn, token)
return fmt.Errorf("arvancloud: unknown record ID for '%s' '%s'", info.EffectiveFQDN, token)
}

if err := d.client.DeleteRecord(authZone, recordID); err != nil {
Expand Down
14 changes: 7 additions & 7 deletions providers/dns/auroradns/auroradns.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,9 +104,9 @@ func NewDNSProviderConfig(config *Config) (*DNSProvider, error) {

// Present creates a TXT record using the specified parameters.
func (d *DNSProvider) Present(domain, token, keyAuth string) error {
fqdn, value := dns01.GetRecord(domain, keyAuth)
info := dns01.GetChallengeInfo(domain, keyAuth)

authZone, err := dns01.FindZoneByFqdn(fqdn)
authZone, err := dns01.FindZoneByFqdn(info.EffectiveFQDN)
if err != nil {
return fmt.Errorf("aurora: could not determine zone for domain %q: %w", domain, err)
}
Expand All @@ -118,7 +118,7 @@ func (d *DNSProvider) Present(domain, token, keyAuth string) error {
// the subdomain, resulting in _acme-challenge..<domain> rather
// than _acme-challenge.<domain>

subdomain := fqdn[0 : len(fqdn)-len(authZone)-1]
subdomain := info.EffectiveFQDN[0 : len(info.EffectiveFQDN)-len(authZone)-1]

authZone = dns01.UnFqdn(authZone)

Expand All @@ -130,7 +130,7 @@ func (d *DNSProvider) Present(domain, token, keyAuth string) error {
record := auroradns.Record{
RecordType: "TXT",
Name: subdomain,
Content: value,
Content: info.Value,
TTL: d.config.TTL,
}

Expand All @@ -148,17 +148,17 @@ func (d *DNSProvider) Present(domain, token, keyAuth string) error {

// CleanUp removes a given record that was generated by Present.
func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error {
fqdn, _ := dns01.GetRecord(domain, keyAuth)
info := dns01.GetChallengeInfo(domain, keyAuth)

d.recordIDsMu.Lock()
recordID, ok := d.recordIDs[token]
d.recordIDsMu.Unlock()

if !ok {
return fmt.Errorf("unknown recordID for %q", fqdn)
return fmt.Errorf("unknown recordID for %q", info.EffectiveFQDN)
}

authZone, err := dns01.FindZoneByFqdn(dns01.ToFqdn(fqdn))
authZone, err := dns01.FindZoneByFqdn(dns01.ToFqdn(info.EffectiveFQDN))
if err != nil {
return fmt.Errorf("could not determine zone for domain %q: %w", domain, err)
}
Expand Down
12 changes: 6 additions & 6 deletions providers/dns/autodns/autodns.go
Original file line number Diff line number Diff line change
Expand Up @@ -105,13 +105,13 @@ func (d *DNSProvider) Timeout() (timeout, interval time.Duration) {

// Present creates a TXT record to fulfill the dns-01 challenge.
func (d *DNSProvider) Present(domain, token, keyAuth string) error {
fqdn, value := dns01.GetRecord(domain, keyAuth)
info := dns01.GetChallengeInfo(domain, keyAuth)

records := []*ResourceRecord{{
Name: fqdn,
Name: info.EffectiveFQDN,
TTL: int64(d.config.TTL),
Type: "TXT",
Value: value,
Value: info.Value,
}}

// TODO(ldez) replace domain by FQDN to follow CNAME.
Expand All @@ -125,13 +125,13 @@ func (d *DNSProvider) Present(domain, token, keyAuth string) error {

// CleanUp removes the TXT record previously created.
func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error {
fqdn, value := dns01.GetRecord(domain, keyAuth)
info := dns01.GetChallengeInfo(domain, keyAuth)

records := []*ResourceRecord{{
Name: fqdn,
Name: info.EffectiveFQDN,
TTL: int64(d.config.TTL),
Type: "TXT",
Value: value,
Value: info.Value,
}}

// TODO(ldez) replace domain by FQDN to follow CNAME.
Expand Down
Loading

0 comments on commit e638d79

Please sign in to comment.