krb5: DNS TXT records test for invalid gTLD

As per
https://www.icann.org/en/system/files/files/name-collision-mitigation-01aug14-en.pdf
prior to a new top-level domain being put into service there is a
controlled interuption service which will return explicit responses to DNS
A, MX, SRV, and TXT queries that can be used to detect private namespace collisions.

Modify the signature of copy_txt_to_realm() to accept a krb5_context so
that meaningful errors can be recorded.

Write a warning to the log (if any).

Change-Id: I51ff8feed4f9d2af8b956bd4ba26e1c4644247c2
This commit is contained in:
Jeffrey Altman
2015-12-26 10:29:39 -05:00
parent c80816f9c3
commit b0e7dc5106

View File

@@ -49,8 +49,10 @@
*/ */
static int static int
copy_txt_to_realms (struct rk_resource_record *head, copy_txt_to_realms(krb5_context context,
krb5_realm **realms) const char *domain,
struct rk_resource_record *head,
krb5_realm **realms)
{ {
struct rk_resource_record *rr; struct rk_resource_record *rr;
unsigned int n, i; unsigned int n, i;
@@ -64,21 +66,36 @@ copy_txt_to_realms (struct rk_resource_record *head,
*realms = malloc ((n + 1) * sizeof(krb5_realm)); *realms = malloc ((n + 1) * sizeof(krb5_realm));
if (*realms == NULL) if (*realms == NULL)
return -1; return krb5_enomem(context);;
for (i = 0; i < n + 1; ++i) for (i = 0; i < n + 1; ++i)
(*realms)[i] = NULL; (*realms)[i] = NULL;
for (i = 0, rr = head; rr; rr = rr->next) { for (i = 0, rr = head; rr; rr = rr->next) {
if (rr->type == rk_ns_t_txt) { if (rr->type == rk_ns_t_txt) {
char *tmp; char *tmp = NULL;
int invalid_tld = 1;
tmp = strdup(rr->u.txt); /* Check for a gTLD controlled interruption */
if (strcmp("Your DNS configuration needs immediate "
"attention see https://icann.org/namecollision",
rr->u.txt) != 0) {
invalid_tld = 0;
tmp = strdup(rr->u.txt);
}
if (tmp == NULL) { if (tmp == NULL) {
for (i = 0; i < n; ++i) for (i = 0; i < n; ++i)
free ((*realms)[i]); free ((*realms)[i]);
free (*realms); free (*realms);
return -1; if (invalid_tld) {
krb5_warnx(context,
"Realm lookup failed: "
"Domain '%s' needs immediate attention "
"see https://icann.org/namecollision",
domain);
return KRB5_KDC_UNREACH;
}
return krb5_enomem(context);;
} }
(*realms)[i] = tmp; (*realms)[i] = tmp;
++i; ++i;
@@ -97,7 +114,7 @@ dns_find_realm(krb5_context context,
struct rk_dns_reply *r; struct rk_dns_reply *r;
const char **labels; const char **labels;
char **config_labels; char **config_labels;
int i, ret; int i, ret = 0;
config_labels = krb5_config_get_strings(context, NULL, "libdefaults", config_labels = krb5_config_get_strings(context, NULL, "libdefaults",
"dns_lookup_realm_labels", NULL); "dns_lookup_realm_labels", NULL);
@@ -110,24 +127,26 @@ dns_find_realm(krb5_context context,
for (i = 0; labels[i] != NULL; i++) { for (i = 0; labels[i] != NULL; i++) {
ret = snprintf(dom, sizeof(dom), "%s.%s.", labels[i], domain); ret = snprintf(dom, sizeof(dom), "%s.%s.", labels[i], domain);
if(ret < 0 || (size_t)ret >= sizeof(dom)) { if(ret < 0 || (size_t)ret >= sizeof(dom)) {
if (config_labels) ret = krb5_enomem(context);
krb5_config_free_strings(config_labels); goto out;
return -1;
} }
r = rk_dns_lookup(dom, "TXT"); r = rk_dns_lookup(dom, "TXT");
if(r != NULL) { if(r != NULL) {
ret = copy_txt_to_realms (r->head, realms); ret = copy_txt_to_realms(context, domain, r->head, realms);
rk_dns_free_data(r); rk_dns_free_data(r);
if(ret == 0) { if(ret == 0)
if (config_labels) goto out;
krb5_config_free_strings(config_labels);
return 0;
}
} }
} }
krb5_set_error_message(context, KRB5_KDC_UNREACH,
"Realm lookup failed: "
"No DNS TXT record for %s",
domain);
ret = KRB5_KDC_UNREACH;
out:
if (config_labels) if (config_labels)
krb5_config_free_strings(config_labels); krb5_config_free_strings(config_labels);
return -1; return ret;
} }
/* /*