/src/dovecot/src/lib-dns/dns-util.c
Line | Count | Source |
1 | | /* Copyright (c) 2010-2018 Dovecot authors, see the included COPYING file */ |
2 | | #include "lib.h" |
3 | | #include "dns-util.h" |
4 | | |
5 | | /** |
6 | | return first position from b->a of c or a if not found |
7 | | */ |
8 | | static inline |
9 | | const char *strchr_ba(const char *a, const char *b, char c) |
10 | 0 | { |
11 | 0 | for(;b>a && *b != c; b--); |
12 | 0 | return b; |
13 | 0 | } |
14 | | |
15 | | int dns_ncompare(const char *a, const char *b, size_t n) |
16 | 0 | { |
17 | 0 | if (a == NULL && b == NULL) return 0; |
18 | 0 | if (a == NULL && b != NULL) return 1; |
19 | 0 | if (a != NULL && b == NULL) return -1; |
20 | | |
21 | 0 | for(size_t i = 0; i < n && |
22 | 0 | *a != '\0' && |
23 | 0 | *b != '\0' && |
24 | 0 | dns_tolower(*a) == dns_tolower(*b); |
25 | 0 | i++, a++, b++); |
26 | |
|
27 | 0 | return dns_tolower(*a) - dns_tolower(*b); |
28 | 0 | } |
29 | | |
30 | | int dns_compare(const char *a, const char *b) |
31 | 0 | { |
32 | 0 | return dns_ncompare(a, b, SIZE_MAX); |
33 | 0 | } |
34 | | |
35 | | int dns_compare_labels(const char *a, const char *b) |
36 | 0 | { |
37 | 0 | if (a == NULL && b == NULL) return 0; |
38 | 0 | if (a == NULL && b != NULL) return 1; |
39 | 0 | if (a != NULL && b == NULL) return -1; |
40 | | |
41 | 0 | const char *ptr_a = a + strlen(a); |
42 | 0 | const char *ptr_b = b + strlen(b); |
43 | 0 | const char *label_a = ptr_a, *label_b = ptr_b; |
44 | 0 | int comp = 0; |
45 | |
|
46 | 0 | while(comp == 0 && ptr_a > a && ptr_b > b) { |
47 | | /* look for start of label, including dot */ |
48 | 0 | label_a = strchr_ba(a, ptr_a, '.'); |
49 | 0 | label_b = strchr_ba(b, ptr_b, '.'); |
50 | 0 | if (ptr_a - label_a != ptr_b - label_b) |
51 | | /* compare labels up to minimum length |
52 | | but include \0 to make sure that we |
53 | | don't consider alpha and alphabet |
54 | | equal */ |
55 | 0 | return dns_ncompare(label_a, label_b, |
56 | 0 | I_MIN(ptr_a - label_a, |
57 | 0 | ptr_b - label_b)+1); |
58 | 0 | comp = dns_ncompare(label_a, label_b, ptr_a -label_a); |
59 | 0 | ptr_a = label_a - 1; |
60 | 0 | ptr_b = label_b - 1; |
61 | 0 | } |
62 | | |
63 | 0 | return dns_tolower(*label_a) - dns_tolower(*label_b); |
64 | 0 | } |
65 | | |
66 | | int dns_match_wildcard(const char *name, const char *mask) |
67 | 0 | { |
68 | 0 | i_assert(name != NULL && mask != NULL); |
69 | | |
70 | 0 | for(;*name != '\0' && *mask != '\0'; name++, mask++) { |
71 | 0 | switch(*mask) { |
72 | 0 | case '*': |
73 | 0 | name = strchr(name, '.'); |
74 | 0 | if (name == NULL || mask[1] != '.') return -1; |
75 | 0 | mask++; |
76 | 0 | break; |
77 | 0 | case '?': |
78 | 0 | break; |
79 | 0 | default: |
80 | 0 | if (dns_tolower(*name) != dns_tolower(*mask)) return -1; |
81 | 0 | } |
82 | 0 | } |
83 | 0 | if (*mask == '*') mask++; |
84 | 0 | return dns_tolower(*name) == dns_tolower(*mask) ? 0 : -1; |
85 | 0 | } |