@@ -32,7 +32,7 @@ type Controller interface {
3232 // UpdateDDNSAddress changes DDNS A/AAAA records
3333 UpdateDDNSAddress (ctx context.Context , domain string , addrs []netip.Addr ) error
3434 // UpdateACMEChallenge changes ACME TXT record for DNS-01 challenge
35- UpdateACMEChallenge (ctx context.Context , domain string , token string ) error
35+ UpdateACMEChallenge (ctx context.Context , domain string , newToken , oldToken string ) error
3636}
3737
3838type File struct {
@@ -91,7 +91,7 @@ func (s *DomainCtrl) UpdateDDNSAddress(ctx context.Context, domain string, addrs
9191 }
9292}
9393
94- func (s * DomainCtrl ) UpdateACMEChallenge (ctx context.Context , domain string , token string ) error {
94+ func (s * DomainCtrl ) UpdateACMEChallenge (ctx context.Context , domain string , newToken , oldToken string ) error {
9595
9696 lg := slog .Default ().With ("domain" , domain )
9797
@@ -108,7 +108,7 @@ func (s *DomainCtrl) UpdateACMEChallenge(ctx context.Context, domain string, tok
108108 lg .DebugContext (ctx , "Check file" , "file_origin" , fl .origin )
109109 if strings .HasSuffix (domainDot , fl .origin ) {
110110 lg .InfoContext (ctx , "Zone file found" , "zonefile" , path .Base (fl .path ))
111- return fl .UpdateACMEChallenge (ctx , domainDot , token )
111+ return fl .UpdateACMEChallenge (ctx , domainDot , newToken , oldToken )
112112 }
113113 }
114114
@@ -314,7 +314,7 @@ func (s *File) UpdateDDNSAddress(ctx context.Context, domain string, addrs []net
314314 return nil
315315}
316316
317- func (s * File ) UpdateACMEChallenge (ctx context.Context , domain string , token string ) error {
317+ func (s * File ) UpdateACMEChallenge (ctx context.Context , domain string , newToken , oldToken string ) error {
318318 s .mu .Lock ()
319319 defer s .mu .Unlock ()
320320
@@ -323,9 +323,10 @@ func (s *File) UpdateACMEChallenge(ctx context.Context, domain string, token str
323323 return err
324324 }
325325
326- if token == "" {
327- s .lg .Warn ("Use placeholder for empty TXT record" , "domain" , domain )
328- token = EmptyPlaceholder
326+ lg := s .lg .With ("domain" , domain )
327+ if newToken == "" {
328+ lg .Warn ("Use placeholder for empty TXT record" )
329+ newToken = EmptyPlaceholder
329330 }
330331
331332 shortDomain := []byte (StripOrigin (domain , s .origin ))
@@ -340,12 +341,25 @@ func (s *File) UpdateACMEChallenge(ctx context.Context, domain string, token str
340341 }
341342
342343 if ent .RRType () == dns .TypeTXT {
343- entTXT = append (entTXT , & ent )
344+ if oldToken == "" {
345+ // ACMEDNS mode - replace all TXTs
346+ entTXT = append (entTXT , & ent )
347+ } else {
348+ // HTTP-REQ mode - replace only matching TXTs
349+ vals := ent .Values ()
350+ if len (vals ) == 1 && bytes .Equal (vals [0 ], []byte (oldToken )) {
351+ entTXT = append (entTXT , & ent )
352+ if oldToken == EmptyPlaceholder {
353+ // leave other placeholders for next requests
354+ break
355+ }
356+ }
357+ }
344358 }
345359 }
346360
347361 if len (entTXT ) < 1 {
348- newent = fmt .Appendf (newent , "\n %s IN TXT %v\n " , shortDomain , quoteTXT (token ))
362+ newent = fmt .Appendf (newent , "\n %s IN TXT %v\n " , shortDomain , quoteTXT (newToken ))
349363 }
350364
351365 if len (newent ) > 0 {
@@ -365,12 +379,12 @@ func (s *File) UpdateACMEChallenge(ctx context.Context, domain string, token str
365379 for _ , ent := range entTXT {
366380 vals := ent .Values ()
367381 if len (vals ) == 1 {
368- s . lg .Info ("Replace value" , "old_value" , string (vals [0 ]), "new_value" , token )
382+ lg .Info ("Replace value" , "old_value" , string (vals [0 ]), "new_value" , newToken )
369383 } else if len (vals ) > 1 {
370- s . lg .Warn ("Possibly bad record matched" , "vals" , vals )
384+ lg .Warn ("Possibly bad record matched" , "vals" , vals )
371385 }
372386
373- err := ent .SetValue (0 , []byte (token ))
387+ err := ent .SetValue (0 , []byte (newToken ))
374388 if err != nil {
375389 return err
376390 }
@@ -389,7 +403,7 @@ func (s *File) UpdateACMEChallenge(ctx context.Context, domain string, token str
389403
390404 err = os .WriteFile (s .path , ret .Bytes (), 0644 )
391405 if err != nil {
392- s . lg .ErrorContext (ctx , "Failed to save file" , "error" , err )
406+ lg .ErrorContext (ctx , "Failed to save file" , "error" , err )
393407 return err
394408 }
395409
0 commit comments