Branch data Line data Source code
1 : : /* SPDX-License-Identifier: LGPL-2.1+ */
2 : :
3 : : #include <sys/socket.h>
4 : : #include <errno.h>
5 : :
6 : : #include "dns-type.h"
7 : : #include "parse-util.h"
8 : : #include "string-util.h"
9 : :
10 : : typedef const struct {
11 : : uint16_t type;
12 : : const char *name;
13 : : } dns_type;
14 : :
15 : : static const struct dns_type_name *
16 : : lookup_dns_type (register const char *str, register GPERF_LEN_TYPE len);
17 : :
18 : : #include "dns_type-from-name.h"
19 : : #include "dns_type-to-name.h"
20 : :
21 : 131088 : int dns_type_from_string(const char *s) {
22 : : const struct dns_type_name *sc;
23 : :
24 [ - + ]: 131088 : assert(s);
25 : :
26 : 131088 : sc = lookup_dns_type(s, strlen(s));
27 [ + + ]: 131088 : if (sc)
28 : 308 : return sc->id;
29 : :
30 : 130780 : s = startswith_no_case(s, "TYPE");
31 [ - + ]: 130780 : if (s) {
32 : : unsigned x;
33 : :
34 [ # # ]: 0 : if (safe_atou(s, &x) >= 0 &&
35 [ # # ]: 0 : x <= UINT16_MAX)
36 : 0 : return (int) x;
37 : : }
38 : :
39 : 130780 : return _DNS_TYPE_INVALID;
40 : : }
41 : :
42 : 1484 : bool dns_type_is_pseudo(uint16_t type) {
43 : :
44 : : /* Checks whether the specified type is a "pseudo-type". What
45 : : * a "pseudo-type" precisely is, is defined only very weakly,
46 : : * but apparently entails all RR types that are not actually
47 : : * stored as RRs on the server and should hence also not be
48 : : * cached. We use this list primarily to validate NSEC type
49 : : * bitfields, and to verify what to cache. */
50 : :
51 [ + + ]: 1484 : return IN_SET(type,
52 : : 0, /* A Pseudo RR type, according to RFC 2931 */
53 : : DNS_TYPE_ANY,
54 : : DNS_TYPE_AXFR,
55 : : DNS_TYPE_IXFR,
56 : : DNS_TYPE_OPT,
57 : : DNS_TYPE_TSIG,
58 : : DNS_TYPE_TKEY
59 : : );
60 : : }
61 : :
62 : 8 : bool dns_class_is_pseudo(uint16_t class) {
63 : 8 : return class == DNS_TYPE_ANY;
64 : : }
65 : :
66 : 308 : bool dns_type_is_valid_query(uint16_t type) {
67 : :
68 : : /* The types valid as questions in packets */
69 : :
70 [ + + ]: 308 : return !IN_SET(type,
71 : : 0,
72 : : DNS_TYPE_OPT,
73 : : DNS_TYPE_TSIG,
74 : : DNS_TYPE_TKEY,
75 : :
76 : : /* RRSIG are technically valid as questions, but we refuse doing explicit queries for them, as
77 : : * they aren't really payload, but signatures for payload, and cannot be validated on their
78 : : * own. After all they are the signatures, and have no signatures of their own validating
79 : : * them. */
80 : : DNS_TYPE_RRSIG);
81 : : }
82 : :
83 : 0 : bool dns_type_is_zone_transer(uint16_t type) {
84 : :
85 : : /* Zone transfers, either normal or incremental */
86 : :
87 [ # # ]: 0 : return IN_SET(type,
88 : : DNS_TYPE_AXFR,
89 : : DNS_TYPE_IXFR);
90 : : }
91 : :
92 : 2212 : bool dns_type_is_valid_rr(uint16_t type) {
93 : :
94 : : /* The types valid as RR in packets (but not necessarily
95 : : * stored on servers). */
96 : :
97 [ + + ]: 2212 : return !IN_SET(type,
98 : : DNS_TYPE_ANY,
99 : : DNS_TYPE_AXFR,
100 : : DNS_TYPE_IXFR);
101 : : }
102 : :
103 : 1912 : bool dns_class_is_valid_rr(uint16_t class) {
104 : 1912 : return class != DNS_CLASS_ANY;
105 : : }
106 : :
107 : 308 : bool dns_type_may_redirect(uint16_t type) {
108 : : /* The following record types should never be redirected using
109 : : * CNAME/DNAME RRs. See
110 : : * <https://tools.ietf.org/html/rfc4035#section-2.5>. */
111 : :
112 [ + + ]: 308 : if (dns_type_is_pseudo(type))
113 : 24 : return false;
114 : :
115 [ + + ]: 284 : return !IN_SET(type,
116 : : DNS_TYPE_CNAME,
117 : : DNS_TYPE_DNAME,
118 : : DNS_TYPE_NSEC3,
119 : : DNS_TYPE_NSEC,
120 : : DNS_TYPE_RRSIG,
121 : : DNS_TYPE_NXT,
122 : : DNS_TYPE_SIG,
123 : : DNS_TYPE_KEY);
124 : : }
125 : :
126 : 308 : bool dns_type_may_wildcard(uint16_t type) {
127 : :
128 : : /* The following records may not be expanded from wildcard RRsets */
129 : :
130 [ + + ]: 308 : if (dns_type_is_pseudo(type))
131 : 24 : return false;
132 : :
133 [ + + ]: 284 : return !IN_SET(type,
134 : : DNS_TYPE_NSEC3,
135 : : DNS_TYPE_SOA,
136 : :
137 : : /* Prohibited by https://tools.ietf.org/html/rfc4592#section-4.4 */
138 : : DNS_TYPE_DNAME);
139 : : }
140 : :
141 : 324 : bool dns_type_apex_only(uint16_t type) {
142 : :
143 : : /* Returns true for all RR types that may only appear signed in a zone apex */
144 : :
145 [ + + ]: 324 : return IN_SET(type,
146 : : DNS_TYPE_SOA,
147 : : DNS_TYPE_NS, /* this one can appear elsewhere, too, but not signed */
148 : : DNS_TYPE_DNSKEY,
149 : : DNS_TYPE_NSEC3PARAM);
150 : : }
151 : :
152 : 308 : bool dns_type_is_dnssec(uint16_t type) {
153 [ + + ]: 308 : return IN_SET(type,
154 : : DNS_TYPE_DS,
155 : : DNS_TYPE_DNSKEY,
156 : : DNS_TYPE_RRSIG,
157 : : DNS_TYPE_NSEC,
158 : : DNS_TYPE_NSEC3,
159 : : DNS_TYPE_NSEC3PARAM);
160 : : }
161 : :
162 : 308 : bool dns_type_is_obsolete(uint16_t type) {
163 [ + + ]: 308 : return IN_SET(type,
164 : : /* Obsoleted by RFC 973 */
165 : : DNS_TYPE_MD,
166 : : DNS_TYPE_MF,
167 : : DNS_TYPE_MAILA,
168 : :
169 : : /* Kinda obsoleted by RFC 2505 */
170 : : DNS_TYPE_MB,
171 : : DNS_TYPE_MG,
172 : : DNS_TYPE_MR,
173 : : DNS_TYPE_MINFO,
174 : : DNS_TYPE_MAILB,
175 : :
176 : : /* RFC1127 kinda obsoleted this by recommending against its use */
177 : : DNS_TYPE_WKS,
178 : :
179 : : /* Declared historical by RFC 6563 */
180 : : DNS_TYPE_A6,
181 : :
182 : : /* Obsoleted by DNSSEC-bis */
183 : : DNS_TYPE_NXT,
184 : :
185 : : /* RFC 1035 removed support for concepts that needed this from RFC 883 */
186 : : DNS_TYPE_NULL);
187 : : }
188 : :
189 : 308 : bool dns_type_needs_authentication(uint16_t type) {
190 : :
191 : : /* Returns true for all (non-obsolete) RR types where records are not useful if they aren't
192 : : * authenticated. I.e. everything that contains crypto keys. */
193 : :
194 [ + + ]: 308 : return IN_SET(type,
195 : : DNS_TYPE_CERT,
196 : : DNS_TYPE_SSHFP,
197 : : DNS_TYPE_IPSECKEY,
198 : : DNS_TYPE_DS,
199 : : DNS_TYPE_DNSKEY,
200 : : DNS_TYPE_TLSA,
201 : : DNS_TYPE_CDNSKEY,
202 : : DNS_TYPE_OPENPGPKEY,
203 : : DNS_TYPE_CAA);
204 : : }
205 : :
206 : 0 : int dns_type_to_af(uint16_t t) {
207 [ # # # # ]: 0 : switch (t) {
208 : :
209 : 0 : case DNS_TYPE_A:
210 : 0 : return AF_INET;
211 : :
212 : 0 : case DNS_TYPE_AAAA:
213 : 0 : return AF_INET6;
214 : :
215 : 0 : case DNS_TYPE_ANY:
216 : 0 : return AF_UNSPEC;
217 : :
218 : 0 : default:
219 : 0 : return -EINVAL;
220 : : }
221 : : }
222 : :
223 : 3952 : const char *dns_class_to_string(uint16_t class) {
224 : :
225 [ + + + ]: 3952 : switch (class) {
226 : :
227 : 2932 : case DNS_CLASS_IN:
228 : 2932 : return "IN";
229 : :
230 : 4 : case DNS_CLASS_ANY:
231 : 4 : return "ANY";
232 : : }
233 : :
234 : 1016 : return NULL;
235 : : }
236 : :
237 : 0 : int dns_class_from_string(const char *s) {
238 : :
239 [ # # ]: 0 : if (!s)
240 : 0 : return _DNS_CLASS_INVALID;
241 : :
242 [ # # ]: 0 : if (strcaseeq(s, "IN"))
243 : 0 : return DNS_CLASS_IN;
244 [ # # ]: 0 : else if (strcaseeq(s, "ANY"))
245 : 0 : return DNS_CLASS_ANY;
246 : :
247 : 0 : return _DNS_CLASS_INVALID;
248 : : }
249 : :
250 : 24 : const char* tlsa_cert_usage_to_string(uint8_t cert_usage) {
251 : :
252 [ + - - - : 24 : switch (cert_usage) {
- - ]
253 : :
254 : 24 : case 0:
255 : 24 : return "CA constraint";
256 : :
257 : 0 : case 1:
258 : 0 : return "Service certificate constraint";
259 : :
260 : 0 : case 2:
261 : 0 : return "Trust anchor assertion";
262 : :
263 : 0 : case 3:
264 : 0 : return "Domain-issued certificate";
265 : :
266 : 0 : case 4 ... 254:
267 : 0 : return "Unassigned";
268 : :
269 : 0 : case 255:
270 : 0 : return "Private use";
271 : : }
272 : :
273 : : return NULL; /* clang cannot count that we covered everything */
274 : : }
275 : :
276 : 24 : const char* tlsa_selector_to_string(uint8_t selector) {
277 [ + - - - ]: 24 : switch (selector) {
278 : :
279 : 24 : case 0:
280 : 24 : return "Full Certificate";
281 : :
282 : 0 : case 1:
283 : 0 : return "SubjectPublicKeyInfo";
284 : :
285 : 0 : case 2 ... 254:
286 : 0 : return "Unassigned";
287 : :
288 : 0 : case 255:
289 : 0 : return "Private use";
290 : : }
291 : :
292 : : return NULL;
293 : : }
294 : :
295 : 24 : const char* tlsa_matching_type_to_string(uint8_t selector) {
296 : :
297 [ - + - - : 24 : switch (selector) {
- ]
298 : :
299 : 0 : case 0:
300 : 0 : return "No hash used";
301 : :
302 : 24 : case 1:
303 : 24 : return "SHA-256";
304 : :
305 : 0 : case 2:
306 : 0 : return "SHA-512";
307 : :
308 : 0 : case 3 ... 254:
309 : 0 : return "Unassigned";
310 : :
311 : 0 : case 255:
312 : 0 : return "Private use";
313 : : }
314 : :
315 : : return NULL;
316 : : }
|