Merge pull request #2316 from poettering/dnssec14

Fourteenth DNSSEC PR
This commit is contained in:
Tom Gundersen
2016-01-14 17:02:57 +01:00
15 changed files with 430 additions and 119 deletions
+81 -82
View File
@@ -263,7 +263,6 @@ int dns_label_escape(const char *p, size_t l, char *dest, size_t sz) {
*(q++) = '0' + (char) ((uint8_t) *p % 10);
sz -= 4;
}
p++;
@@ -522,7 +521,7 @@ int dns_name_compare_func(const void *a, const void *b) {
y = (const char *) b + strlen(b);
for (;;) {
char la[DNS_LABEL_MAX+1], lb[DNS_LABEL_MAX+1];
char la[DNS_LABEL_MAX], lb[DNS_LABEL_MAX];
if (x == NULL && y == NULL)
return 0;
@@ -532,8 +531,15 @@ int dns_name_compare_func(const void *a, const void *b) {
if (r < 0 || q < 0)
return r - q;
k = dns_label_undo_idna(la, r, la, sizeof(la));
w = dns_label_undo_idna(lb, q, lb, sizeof(lb));
if (r > 0)
k = dns_label_undo_idna(la, r, la, sizeof(la));
else
k = 0;
if (q > 0)
w = dns_label_undo_idna(lb, q, lb, sizeof(lb));
else
w = 0;
if (k < 0 || w < 0)
return k - w;
if (k > 0)
@@ -541,8 +547,7 @@ int dns_name_compare_func(const void *a, const void *b) {
if (w > 0)
q = w;
la[r] = lb[q] = 0;
r = strcasecmp(la, lb);
r = ascii_strcasecmp_nn(la, r, lb, q);
if (r != 0)
return r;
}
@@ -553,54 +558,54 @@ const struct hash_ops dns_name_hash_ops = {
.compare = dns_name_compare_func
};
static int dns_label_unescape_undo_idna(const char **name, char *dest, size_t sz) {
int r, k;
/* Clobbers all arguments on failure... */
r = dns_label_unescape(name, dest, sz);
if (r <= 0)
return r;
k = dns_label_undo_idna(dest, r, dest, sz);
if (k < 0)
return k;
if (k == 0) /* not an IDNA name */
return r;
return k;
}
int dns_name_equal(const char *x, const char *y) {
int r, q, k, w;
int r, q;
assert(x);
assert(y);
for (;;) {
char la[DNS_LABEL_MAX+1], lb[DNS_LABEL_MAX+1];
char la[DNS_LABEL_MAX], lb[DNS_LABEL_MAX];
if (*x == 0 && *y == 0)
return true;
r = dns_label_unescape(&x, la, sizeof(la));
r = dns_label_unescape_undo_idna(&x, la, sizeof(la));
if (r < 0)
return r;
if (r > 0) {
k = dns_label_undo_idna(la, r, la, sizeof(la));
if (k < 0)
return k;
if (k > 0)
r = k;
}
q = dns_label_unescape(&y, lb, sizeof(lb));
q = dns_label_unescape_undo_idna(&y, lb, sizeof(lb));
if (q < 0)
return q;
if (q > 0) {
w = dns_label_undo_idna(lb, q, lb, sizeof(lb));
if (w < 0)
return w;
if (w > 0)
q = w;
}
/* If one name had fewer labels than the other, this
* will show up as empty label here, which the
* strcasecmp() below will properly consider different
* from a non-empty label. */
if (r != q)
return false;
if (r == 0)
return true;
la[r] = lb[q] = 0;
if (strcasecmp(la, lb) != 0)
if (ascii_strcasecmp_n(la, lb, r) != 0)
return false;
}
}
int dns_name_endswith(const char *name, const char *suffix) {
const char *n, *s, *saved_n = NULL;
int r, q, k, w;
int r, q;
assert(name);
assert(suffix);
@@ -609,41 +614,25 @@ int dns_name_endswith(const char *name, const char *suffix) {
s = suffix;
for (;;) {
char ln[DNS_LABEL_MAX+1], ls[DNS_LABEL_MAX+1];
char ln[DNS_LABEL_MAX], ls[DNS_LABEL_MAX];
r = dns_label_unescape(&n, ln, sizeof(ln));
r = dns_label_unescape_undo_idna(&n, ln, sizeof(ln));
if (r < 0)
return r;
if (r > 0) {
k = dns_label_undo_idna(ln, r, ln, sizeof(ln));
if (k < 0)
return k;
if (k > 0)
r = k;
}
if (!saved_n)
saved_n = n;
q = dns_label_unescape(&s, ls, sizeof(ls));
q = dns_label_unescape_undo_idna(&s, ls, sizeof(ls));
if (q < 0)
return q;
if (q > 0) {
w = dns_label_undo_idna(ls, q, ls, sizeof(ls));
if (w < 0)
return w;
if (w > 0)
q = w;
}
if (r == 0 && q == 0)
return true;
if (r == 0 && saved_n == n)
return false;
ln[r] = ls[q] = 0;
if (r != q || strcasecmp(ln, ls)) {
if (r != q || ascii_strcasecmp_n(ln, ls, r) != 0) {
/* Not the same, let's jump back, and try with the next label again */
s = suffix;
@@ -653,9 +642,39 @@ int dns_name_endswith(const char *name, const char *suffix) {
}
}
int dns_name_startswith(const char *name, const char *prefix) {
const char *n, *p;
int r, q;
assert(name);
assert(prefix);
n = name;
p = prefix;
for (;;) {
char ln[DNS_LABEL_MAX], lp[DNS_LABEL_MAX];
r = dns_label_unescape_undo_idna(&p, lp, sizeof(lp));
if (r < 0)
return r;
if (r == 0)
return true;
q = dns_label_unescape_undo_idna(&n, ln, sizeof(ln));
if (q < 0)
return q;
if (r != q)
return false;
if (ascii_strcasecmp_n(ln, lp, r) != 0)
return false;
}
}
int dns_name_change_suffix(const char *name, const char *old_suffix, const char *new_suffix, char **ret) {
const char *n, *s, *saved_before = NULL, *saved_after = NULL, *prefix;
int r, q, k, w;
int r, q;
assert(name);
assert(old_suffix);
@@ -666,35 +685,21 @@ int dns_name_change_suffix(const char *name, const char *old_suffix, const char
s = old_suffix;
for (;;) {
char ln[DNS_LABEL_MAX+1], ls[DNS_LABEL_MAX+1];
char ln[DNS_LABEL_MAX], ls[DNS_LABEL_MAX];
if (!saved_before)
saved_before = n;
r = dns_label_unescape(&n, ln, sizeof(ln));
r = dns_label_unescape_undo_idna(&n, ln, sizeof(ln));
if (r < 0)
return r;
if (r > 0) {
k = dns_label_undo_idna(ln, r, ln, sizeof(ln));
if (k < 0)
return k;
if (k > 0)
r = k;
}
if (!saved_after)
saved_after = n;
q = dns_label_unescape(&s, ls, sizeof(ls));
q = dns_label_unescape_undo_idna(&s, ls, sizeof(ls));
if (q < 0)
return q;
if (q > 0) {
w = dns_label_undo_idna(ls, q, ls, sizeof(ls));
if (w < 0)
return w;
if (w > 0)
q = w;
}
if (r == 0 && q == 0)
break;
@@ -703,9 +708,7 @@ int dns_name_change_suffix(const char *name, const char *old_suffix, const char
return 0;
}
ln[r] = ls[q] = 0;
if (r != q || strcasecmp(ln, ls)) {
if (r != q || ascii_strcasecmp_n(ln, ls, r) != 0) {
/* Not the same, let's jump back, and try with the next label again */
s = old_suffix;
@@ -873,12 +876,11 @@ bool dns_name_is_root(const char *name) {
}
bool dns_name_is_single_label(const char *name) {
char label[DNS_LABEL_MAX+1];
int r;
assert(name);
r = dns_label_unescape(&name, label, sizeof(label));
r = dns_name_parent(&name);
if (r <= 0)
return false;
@@ -1099,17 +1101,15 @@ int dns_service_split(const char *joined, char **_name, char **_type, char **_do
if (x >= 3 && srv_type_label_is_valid(c, cn)) {
if (dns_service_name_label_is_valid(a, an)) {
/* OK, got <name> . <type> . <type2> . <domain> */
name = strndup(a, an);
if (!name)
return -ENOMEM;
type = new(char, bn+1+cn+1);
type = strjoin(b, ".", c, NULL);
if (!type)
return -ENOMEM;
strcpy(stpcpy(stpcpy(type, b), "."), c);
d = p;
goto finish;
@@ -1121,10 +1121,9 @@ int dns_service_split(const char *joined, char **_name, char **_type, char **_do
name = NULL;
type = new(char, an+1+bn+1);
type = strjoin(a, ".", b, NULL);
if (!type)
return -ENOMEM;
strcpy(stpcpy(stpcpy(type, a), "."), b);
d = q;
goto finish;
+1
View File
@@ -83,6 +83,7 @@ extern const struct hash_ops dns_name_hash_ops;
int dns_name_between(const char *a, const char *b, const char *c);
int dns_name_equal(const char *x, const char *y);
int dns_name_endswith(const char *name, const char *suffix);
int dns_name_startswith(const char *name, const char *prefix);
int dns_name_change_suffix(const char *name, const char *old_suffix, const char *new_suffix, char **ret);