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
Show file tree
Hide file tree
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
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.
dmke marked this conversation as resolved.
Show resolved Hide resolved

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