Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: replace GetRecord by GetChallengeInfo #1863

Merged
merged 4 commits into from
Mar 7, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 31 additions & 7 deletions challenge/dns01/dns_challenge.go
Original file line number Diff line number Diff line change
@@ -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) {
@@ -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)
}
@@ -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
}

12 changes: 6 additions & 6 deletions challenge/dns01/dns_challenge_manual.go
Original file line number Diff line number Diff line change
@@ -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')
@@ -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
}
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
@@ -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.
19 changes: 5 additions & 14 deletions providers/dns/acmedns/acmedns.go
Original file line number Diff line number Diff line change
@@ -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
@@ -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
@@ -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
}
@@ -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)
}
12 changes: 6 additions & 6 deletions providers/dns/allinkl/allinkl.go
Original file line number Diff line number Diff line change
@@ -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)
}
@@ -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)
}
@@ -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)
@@ -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 {
@@ -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)
16 changes: 8 additions & 8 deletions providers/dns/arvancloud/arvancloud.go
Original file line number Diff line number Diff line change
@@ -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{
@@ -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()
@@ -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
}
@@ -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 {
14 changes: 7 additions & 7 deletions providers/dns/auroradns/auroradns.go
Original file line number Diff line number Diff line change
@@ -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)
}
@@ -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)

@@ -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,
}

@@ -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)
}
12 changes: 6 additions & 6 deletions providers/dns/autodns/autodns.go
Original file line number Diff line number Diff line change
@@ -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.
@@ -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.
Loading