This is an automated email from the ASF dual-hosted git repository.

zrhoffman pushed a commit to branch 6.0.x
in repository https://gitbox.apache.org/repos/asf/trafficcontrol.git

commit 675de0795e06af90d9dacf3de6561d1a232fb1d4
Author: mattjackson220 <[email protected]>
AuthorDate: Mon Sep 20 16:11:38 2021 -0600

    Le regex fix (#6184)
    
    * Lets Encrypt updated for domains that don't contain the xmlid
    
    * updated changelog
    
    (cherry picked from commit 14d8d8ecc1660c183afc36678cc55d73dc9a9aa6)
---
 CHANGELOG.md                                       |  1 +
 ...21090914220900_le_dns_challenge_xml_id.down.sql | 18 +++++++++
 ...2021090914220900_le_dns_challenge_xml_id.up.sql | 18 +++++++++
 .../traffic_ops_golang/deliveryservice/acme.go     | 12 +++---
 .../deliveryservice/acme_renew.go                  |  2 +-
 .../deliveryservice/letsencrypt_dns_challenge.go   |  5 ++-
 .../core/ds/LetsEncryptDnsChallenge.java           | 16 +++++++-
 .../core/ds/LetsEncryptDnsChallengeWatcher.java    | 45 +++++++++++-----------
 8 files changed, 84 insertions(+), 33 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 0e01602..1fd6704 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -106,6 +106,7 @@ The format is based on [Keep a 
Changelog](http://keepachangelog.com/en/1.0.0/).
 - Fixed Federations IMS so TR federations watcher will get updates.
 - [#5129](https://github.com/apache/trafficcontrol/issues/5129) - Updated TM 
so that it returns a 404 if the endpoint is not supported.
 - Fixed Traffic Router crs/stats to prevent overflow and to correctly record 
the time used in averages.
+- [#6093](https://github.com/apache/trafficcontrol/issues/6093) - Fixed Let's 
Encrypt to work for delivery services where the domain does not contain the 
XMLID.
 
 ### Changed
 - Migrated completely off of bower in favor of npm
diff --git 
a/traffic_ops/app/db/migrations/2021090914220900_le_dns_challenge_xml_id.down.sql
 
b/traffic_ops/app/db/migrations/2021090914220900_le_dns_challenge_xml_id.down.sql
new file mode 100644
index 0000000..d2e7e61
--- /dev/null
+++ 
b/traffic_ops/app/db/migrations/2021090914220900_le_dns_challenge_xml_id.down.sql
@@ -0,0 +1,18 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with this
+ * work for additional information regarding copyright ownership.  The ASF
+ * licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations 
under
+ * the License.
+ */
+
+ALTER TABLE dnschallenges DROP COLUMN IF EXISTS xml_id;
diff --git 
a/traffic_ops/app/db/migrations/2021090914220900_le_dns_challenge_xml_id.up.sql 
b/traffic_ops/app/db/migrations/2021090914220900_le_dns_challenge_xml_id.up.sql
new file mode 100644
index 0000000..64df6a0
--- /dev/null
+++ 
b/traffic_ops/app/db/migrations/2021090914220900_le_dns_challenge_xml_id.up.sql
@@ -0,0 +1,18 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with this
+ * work for additional information regarding copyright ownership.  The ASF
+ * licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations 
under
+ * the License.
+ */
+
+ALTER TABLE dnschallenges ADD COLUMN xml_id text NOT NULL;
diff --git a/traffic_ops/traffic_ops_golang/deliveryservice/acme.go 
b/traffic_ops/traffic_ops_golang/deliveryservice/acme.go
index 044a466..e89b8e6 100644
--- a/traffic_ops/traffic_ops_golang/deliveryservice/acme.go
+++ b/traffic_ops/traffic_ops_golang/deliveryservice/acme.go
@@ -82,7 +82,8 @@ func (u *MyUser) GetPrivateKey() crypto.PrivateKey {
 
 // DNSProviderTrafficRouter is used in the lego library and contains a 
database in order to store the DNS challenges for ACME protocol.
 type DNSProviderTrafficRouter struct {
-       db *sqlx.DB
+       db    *sqlx.DB
+       xmlId *string
 }
 
 // NewDNSProviderTrafficRouter returns a new DNSProviderTrafficRouter object.
@@ -100,8 +101,8 @@ func (d *DNSProviderTrafficRouter) Present(domain, token, 
keyAuth string) error
        tx, err := d.db.Begin()
        fqdn, value := dns01.GetRecord(domain, keyAuth)
 
-       q := `INSERT INTO dnschallenges (fqdn, record) VALUES ($1, $2)`
-       response, err := tx.Exec(q, fqdn, value)
+       q := `INSERT INTO dnschallenges (fqdn, record, xml_id) VALUES ($1, $2, 
$3)`
+       response, err := tx.Exec(q, fqdn, value, *d.xmlId)
        tx.Commit()
        if err != nil {
                log.Errorf("Inserting dns txt record for fqdn '" + fqdn + "' 
record '" + value + "': " + err.Error())
@@ -439,7 +440,7 @@ func GetAcmeCertificates(cfg *config.Config, req 
tc.DeliveryServiceAcmeSSLKeysRe
                account = acmeAccount
        }
 
-       client, err := GetAcmeClient(account, userTx, db)
+       client, err := GetAcmeClient(account, userTx, db, req.Key)
        if err != nil {
                log.Errorf("acme: getting acme client for provider %s: %v", 
provider, err)
                api.CreateChangeLogRawTx(api.ApiChange, "DS: 
"+*req.DeliveryService+", ID: "+strconv.Itoa(dsID)+", ACTION: FAILED to add SSL 
keys with "+provider, currentUser, logTx)
@@ -560,7 +561,7 @@ func GetAcmeAccountConfig(cfg *config.Config, acmeProvider 
string) *config.Confi
 }
 
 // GetAcmeClient uses the ACME account information in either cdn.conf or the 
database to create and register an ACME client.
-func GetAcmeClient(acmeAccount *config.ConfigAcmeAccount, userTx *sql.Tx, db 
*sqlx.DB) (*lego.Client, error) {
+func GetAcmeClient(acmeAccount *config.ConfigAcmeAccount, userTx *sql.Tx, db 
*sqlx.DB, xmlId *string) (*lego.Client, error) {
        if acmeAccount.UserEmail == "" {
                log.Errorf("An email address must be provided to use ACME with 
%v", acmeAccount.AcmeProvider)
                return nil, errors.New("An email address must be provided to 
use ACME with " + acmeAccount.AcmeProvider)
@@ -610,6 +611,7 @@ func GetAcmeClient(acmeAccount *config.ConfigAcmeAccount, 
userTx *sql.Tx, db *sq
                client.Challenge.Remove(challenge.TLSALPN01)
                trafficRouterDns := NewDNSProviderTrafficRouter()
                trafficRouterDns.db = db
+               trafficRouterDns.xmlId = xmlId
                if err != nil {
                        log.Errorf("Error creating Traffic Router DNS provider: 
%s", err.Error())
                        return nil, err
diff --git a/traffic_ops/traffic_ops_golang/deliveryservice/acme_renew.go 
b/traffic_ops/traffic_ops_golang/deliveryservice/acme_renew.go
index 7b92526..eb7c78a 100644
--- a/traffic_ops/traffic_ops_golang/deliveryservice/acme_renew.go
+++ b/traffic_ops/traffic_ops_golang/deliveryservice/acme_renew.go
@@ -145,7 +145,7 @@ func renewAcmeCerts(cfg *config.Config, dsName string, ctx 
context.Context, http
                return nil, errors.New("No acme account information in cdn.conf 
for " + keyObj.AuthType), http.StatusInternalServerError
        }
 
-       client, err := GetAcmeClient(acmeAccount, userTx, db)
+       client, err := GetAcmeClient(acmeAccount, userTx, db, &dsName)
        if err != nil {
                api.CreateChangeLogRawTx(api.ApiChange, "DS: "+dsName+", ID: 
"+strconv.Itoa(*dsID)+", ACTION: FAILED to add SSL keys with 
"+acmeAccount.AcmeProvider, currentUser, logTx)
                return nil, errors.New("getting acme client: " + err.Error()), 
http.StatusInternalServerError
diff --git 
a/traffic_ops/traffic_ops_golang/deliveryservice/letsencrypt_dns_challenge.go 
b/traffic_ops/traffic_ops_golang/deliveryservice/letsencrypt_dns_challenge.go
index 45fb560..a9af8cd 100644
--- 
a/traffic_ops/traffic_ops_golang/deliveryservice/letsencrypt_dns_challenge.go
+++ 
b/traffic_ops/traffic_ops_golang/deliveryservice/letsencrypt_dns_challenge.go
@@ -33,6 +33,7 @@ import (
 type DnsRecord struct {
        Fqdn   *string `json:"fqdn" db:"fqdn"`
        Record *string `json:"record" db:"record"`
+       XmlId  *string `json:"xmlId" db:"xml_id"`
 }
 
 func GetDnsChallengeRecords(w http.ResponseWriter, r *http.Request) {
@@ -43,7 +44,7 @@ func GetDnsChallengeRecords(w http.ResponseWriter, r 
*http.Request) {
        }
        defer inf.Close()
 
-       getQuery := `SELECT fqdn, record FROM dnschallenges`
+       getQuery := `SELECT fqdn, record, xml_id FROM dnschallenges`
 
        queryParamsToQueryCols := map[string]dbhelpers.WhereColumnInfo{
                "fqdn": dbhelpers.WhereColumnInfo{Column: "fqdn"},
@@ -73,7 +74,7 @@ func getDnsRecords(tx *sqlx.Tx, getQuery string, queryValues 
map[string]interfac
        defer rows.Close()
        for rows.Next() {
                record := DnsRecord{}
-               if err := rows.Scan(&record.Fqdn, &record.Record); err != nil {
+               if err := rows.Scan(&record.Fqdn, &record.Record, 
&record.XmlId); err != nil {
                        return nil, errors.New("scanning dns challenge records: 
" + err.Error())
                }
                records = append(records, record)
diff --git 
a/traffic_router/core/src/main/java/org/apache/traffic_control/traffic_router/core/ds/LetsEncryptDnsChallenge.java
 
b/traffic_router/core/src/main/java/org/apache/traffic_control/traffic_router/core/ds/LetsEncryptDnsChallenge.java
index 8261ba0..2260825 100644
--- 
a/traffic_router/core/src/main/java/org/apache/traffic_control/traffic_router/core/ds/LetsEncryptDnsChallenge.java
+++ 
b/traffic_router/core/src/main/java/org/apache/traffic_control/traffic_router/core/ds/LetsEncryptDnsChallenge.java
@@ -26,6 +26,9 @@ public class LetsEncryptDnsChallenge {
     @JsonProperty
     private String record;
 
+    @JsonProperty
+    private String xmlId;
+
     public String getFqdn() {
         return fqdn;
     }
@@ -42,6 +45,14 @@ public class LetsEncryptDnsChallenge {
         this.record = record;
     }
 
+    public String getXmlId() {
+        return xmlId;
+    }
+
+    public void setXmlId(final String xmlId) {
+        this.xmlId = xmlId;
+    }
+
     @Override
     public boolean equals(final Object o) {
         if (this == o) {
@@ -52,11 +63,12 @@ public class LetsEncryptDnsChallenge {
         }
         final LetsEncryptDnsChallenge that = (LetsEncryptDnsChallenge) o;
         return fqdn.equals(that.fqdn) &&
-                record.equals(that.record);
+                record.equals(that.record) &&
+                xmlId.equals(that.xmlId);
     }
 
     @Override
     public int hashCode() {
-        return Objects.hash(fqdn, record);
+        return Objects.hash(fqdn, record, xmlId);
     }
 }
diff --git 
a/traffic_router/core/src/main/java/org/apache/traffic_control/traffic_router/core/ds/LetsEncryptDnsChallengeWatcher.java
 
b/traffic_router/core/src/main/java/org/apache/traffic_control/traffic_router/core/ds/LetsEncryptDnsChallengeWatcher.java
index 957bf06..5ebc89c 100644
--- 
a/traffic_router/core/src/main/java/org/apache/traffic_control/traffic_router/core/ds/LetsEncryptDnsChallengeWatcher.java
+++ 
b/traffic_router/core/src/main/java/org/apache/traffic_control/traffic_router/core/ds/LetsEncryptDnsChallengeWatcher.java
@@ -31,6 +31,7 @@ import org.apache.log4j.Logger;
 import java.io.*;
 import java.time.Instant;
 import java.util.HashMap;
+import java.util.Iterator;
 import java.util.List;
 
 public class LetsEncryptDnsChallengeWatcher extends AbstractResourceWatcher {
@@ -57,35 +58,33 @@ public class LetsEncryptDnsChallengeWatcher extends 
AbstractResourceWatcher {
 
 
             challengeList.forEach(challenge -> {
-                final StringBuilder sb = new StringBuilder();
-                sb.append(challenge.getFqdn());
-                if (!challenge.getFqdn().endsWith(".")) {
-                    sb.append('.');
+                final ObjectNode deliveryServiceConfig = (ObjectNode) 
deliveryServicesNode.get(challenge.getXmlId());
+                if (deliveryServiceConfig == null) {
+                    LOGGER.error("finding deliveryservice in cr-config for " + 
challenge.getXmlId());
+                    return;
                 }
-                final String challengeDomain = sb.toString();
-                final String fqdn = challengeDomain.substring(0, 
challengeDomain.length() - 1).replace("_acme-challenge.", "");
-
-                ObjectNode deliveryServiceConfig = null;
-                String dsLabel = "";
-                final StringBuilder nameSb = new StringBuilder();
-                nameSb.append("_acme-challenge");
-                for (final String label : fqdn.split("\\.")) {
-                    deliveryServiceConfig = (ObjectNode) 
deliveryServicesNode.get(label);
-                    if (deliveryServiceConfig != null) {
-                        dsLabel = label;
-                        break;
-                    } else {
-                        nameSb.append('.');
-                        nameSb.append(label);
-                    }
+
+                String staticEntryString = challenge.getFqdn();
+                final ArrayNode domains = (ArrayNode) 
deliveryServiceConfig.get("domains");
+                if (domains == null || domains.size() == 0) {
+                    LOGGER.error("no domains found in cr-config for 
deliveryservice " + challenge.getXmlId());
+                    return;
+                }
+
+                final Iterator<JsonNode> domainIter = domains.iterator();
+                while(domainIter.hasNext()) {
+                    final JsonNode domainNode = domainIter.next();
+                    staticEntryString = 
staticEntryString.replace(domainNode.asText() + ".", "");
                 }
 
-                final String name = nameSb.toString();
+                if (staticEntryString.endsWith(".")) {
+                    staticEntryString = staticEntryString.substring(0, 
staticEntryString.length() - 1);
+                }
 
-                final ArrayNode staticDnsEntriesNode = 
updateStaticEntries(challenge, name, mapper, deliveryServiceConfig);
+                final ArrayNode staticDnsEntriesNode = 
updateStaticEntries(challenge, staticEntryString, mapper, 
deliveryServiceConfig);
 
                 deliveryServiceConfig.set("staticDnsEntries", 
staticDnsEntriesNode);
-                deliveryServicesNode.set(dsLabel, deliveryServiceConfig);
+                deliveryServicesNode.set(challenge.getXmlId(), 
deliveryServiceConfig);
 
             });
 

Reply via email to