Branch data Line data Source code
1 : : /* SPDX-License-Identifier: LGPL-2.1+ */
2 : : #pragma once
3 : :
4 : : #include <netinet/in.h>
5 : :
6 : : #include "bitmap.h"
7 : : #include "dns-type.h"
8 : : #include "hashmap.h"
9 : : #include "in-addr-util.h"
10 : : #include "list.h"
11 : : #include "string-util.h"
12 : : #include "time-util.h"
13 : :
14 : : typedef struct DnsResourceKey DnsResourceKey;
15 : : typedef struct DnsResourceRecord DnsResourceRecord;
16 : : typedef struct DnsTxtItem DnsTxtItem;
17 : :
18 : : /* DNSKEY RR flags */
19 : : #define DNSKEY_FLAG_SEP (UINT16_C(1) << 0)
20 : : #define DNSKEY_FLAG_REVOKE (UINT16_C(1) << 7)
21 : : #define DNSKEY_FLAG_ZONE_KEY (UINT16_C(1) << 8)
22 : :
23 : : /* mDNS RR flags */
24 : : #define MDNS_RR_CACHE_FLUSH (UINT16_C(1) << 15)
25 : :
26 : : /* DNSSEC algorithm identifiers, see
27 : : * http://tools.ietf.org/html/rfc4034#appendix-A.1 and
28 : : * https://www.iana.org/assignments/dns-sec-alg-numbers/dns-sec-alg-numbers.xhtml */
29 : : enum {
30 : : DNSSEC_ALGORITHM_RSAMD5 = 1,
31 : : DNSSEC_ALGORITHM_DH,
32 : : DNSSEC_ALGORITHM_DSA,
33 : : DNSSEC_ALGORITHM_ECC,
34 : : DNSSEC_ALGORITHM_RSASHA1,
35 : : DNSSEC_ALGORITHM_DSA_NSEC3_SHA1,
36 : : DNSSEC_ALGORITHM_RSASHA1_NSEC3_SHA1,
37 : : DNSSEC_ALGORITHM_RSASHA256 = 8, /* RFC 5702 */
38 : : DNSSEC_ALGORITHM_RSASHA512 = 10, /* RFC 5702 */
39 : : DNSSEC_ALGORITHM_ECC_GOST = 12, /* RFC 5933 */
40 : : DNSSEC_ALGORITHM_ECDSAP256SHA256 = 13, /* RFC 6605 */
41 : : DNSSEC_ALGORITHM_ECDSAP384SHA384 = 14, /* RFC 6605 */
42 : : DNSSEC_ALGORITHM_ED25519 = 15, /* RFC 8080 */
43 : : DNSSEC_ALGORITHM_ED448 = 16, /* RFC 8080 */
44 : : DNSSEC_ALGORITHM_INDIRECT = 252,
45 : : DNSSEC_ALGORITHM_PRIVATEDNS,
46 : : DNSSEC_ALGORITHM_PRIVATEOID,
47 : : _DNSSEC_ALGORITHM_MAX_DEFINED
48 : : };
49 : :
50 : : /* DNSSEC digest identifiers, see
51 : : * https://www.iana.org/assignments/ds-rr-types/ds-rr-types.xhtml */
52 : : enum {
53 : : DNSSEC_DIGEST_SHA1 = 1,
54 : : DNSSEC_DIGEST_SHA256 = 2, /* RFC 4509 */
55 : : DNSSEC_DIGEST_GOST_R_34_11_94 = 3, /* RFC 5933 */
56 : : DNSSEC_DIGEST_SHA384 = 4, /* RFC 6605 */
57 : : _DNSSEC_DIGEST_MAX_DEFINED
58 : : };
59 : :
60 : : /* DNSSEC NSEC3 hash algorithms, see
61 : : * https://www.iana.org/assignments/dnssec-nsec3-parameters/dnssec-nsec3-parameters.xhtml */
62 : : enum {
63 : : NSEC3_ALGORITHM_SHA1 = 1,
64 : : _NSEC3_ALGORITHM_MAX_DEFINED
65 : : };
66 : :
67 : : struct DnsResourceKey {
68 : : unsigned n_ref; /* (unsigned -1) for const keys, see below */
69 : : uint16_t class, type;
70 : : char *_name; /* don't access directly, use dns_resource_key_name()! */
71 : : };
72 : :
73 : : /* Creates a temporary resource key. This is only useful to quickly
74 : : * look up something, without allocating a full DnsResourceKey object
75 : : * for it. Note that it is not OK to take references to this kind of
76 : : * resource key object. */
77 : : #define DNS_RESOURCE_KEY_CONST(c, t, n) \
78 : : ((DnsResourceKey) { \
79 : : .n_ref = (unsigned) -1, \
80 : : .class = c, \
81 : : .type = t, \
82 : : ._name = (char*) n, \
83 : : })
84 : :
85 : : struct DnsTxtItem {
86 : : size_t length;
87 : : LIST_FIELDS(DnsTxtItem, items);
88 : : uint8_t data[];
89 : : };
90 : :
91 : : struct DnsResourceRecord {
92 : : unsigned n_ref;
93 : : DnsResourceKey *key;
94 : :
95 : : char *to_string;
96 : :
97 : : uint32_t ttl;
98 : : usec_t expiry; /* RRSIG signature expiry */
99 : :
100 : : /* How many labels to strip to determine "signer" of the RRSIG (aka, the zone). -1 if not signed. */
101 : : unsigned n_skip_labels_signer;
102 : : /* How many labels to strip to determine "synthesizing source" of this RR, i.e. the wildcard's immediate parent. -1 if not signed. */
103 : : unsigned n_skip_labels_source;
104 : :
105 : : bool unparseable:1;
106 : :
107 : : bool wire_format_canonical:1;
108 : : void *wire_format;
109 : : size_t wire_format_size;
110 : : size_t wire_format_rdata_offset;
111 : :
112 : : union {
113 : : struct {
114 : : void *data;
115 : : size_t data_size;
116 : : } generic, opt;
117 : :
118 : : struct {
119 : : uint16_t priority;
120 : : uint16_t weight;
121 : : uint16_t port;
122 : : char *name;
123 : : } srv;
124 : :
125 : : struct {
126 : : char *name;
127 : : } ptr, ns, cname, dname;
128 : :
129 : : struct {
130 : : char *cpu;
131 : : char *os;
132 : : } hinfo;
133 : :
134 : : struct {
135 : : DnsTxtItem *items;
136 : : } txt, spf;
137 : :
138 : : struct {
139 : : struct in_addr in_addr;
140 : : } a;
141 : :
142 : : struct {
143 : : struct in6_addr in6_addr;
144 : : } aaaa;
145 : :
146 : : struct {
147 : : char *mname;
148 : : char *rname;
149 : : uint32_t serial;
150 : : uint32_t refresh;
151 : : uint32_t retry;
152 : : uint32_t expire;
153 : : uint32_t minimum;
154 : : } soa;
155 : :
156 : : struct {
157 : : uint16_t priority;
158 : : char *exchange;
159 : : } mx;
160 : :
161 : : /* https://tools.ietf.org/html/rfc1876 */
162 : : struct {
163 : : uint8_t version;
164 : : uint8_t size;
165 : : uint8_t horiz_pre;
166 : : uint8_t vert_pre;
167 : : uint32_t latitude;
168 : : uint32_t longitude;
169 : : uint32_t altitude;
170 : : } loc;
171 : :
172 : : /* https://tools.ietf.org/html/rfc4255#section-3.1 */
173 : : struct {
174 : : uint8_t algorithm;
175 : : uint8_t fptype;
176 : : void *fingerprint;
177 : : size_t fingerprint_size;
178 : : } sshfp;
179 : :
180 : : /* http://tools.ietf.org/html/rfc4034#section-2.1 */
181 : : struct {
182 : : uint16_t flags;
183 : : uint8_t protocol;
184 : : uint8_t algorithm;
185 : : void* key;
186 : : size_t key_size;
187 : : } dnskey;
188 : :
189 : : /* http://tools.ietf.org/html/rfc4034#section-3.1 */
190 : : struct {
191 : : uint16_t type_covered;
192 : : uint8_t algorithm;
193 : : uint8_t labels;
194 : : uint32_t original_ttl;
195 : : uint32_t expiration;
196 : : uint32_t inception;
197 : : uint16_t key_tag;
198 : : char *signer;
199 : : void *signature;
200 : : size_t signature_size;
201 : : } rrsig;
202 : :
203 : : /* https://tools.ietf.org/html/rfc4034#section-4.1 */
204 : : struct {
205 : : char *next_domain_name;
206 : : Bitmap *types;
207 : : } nsec;
208 : :
209 : : /* https://tools.ietf.org/html/rfc4034#section-5.1 */
210 : : struct {
211 : : uint16_t key_tag;
212 : : uint8_t algorithm;
213 : : uint8_t digest_type;
214 : : void *digest;
215 : : size_t digest_size;
216 : : } ds;
217 : :
218 : : struct {
219 : : uint8_t algorithm;
220 : : uint8_t flags;
221 : : uint16_t iterations;
222 : : void *salt;
223 : : size_t salt_size;
224 : : void *next_hashed_name;
225 : : size_t next_hashed_name_size;
226 : : Bitmap *types;
227 : : } nsec3;
228 : :
229 : : /* https://tools.ietf.org/html/draft-ietf-dane-protocol-23 */
230 : : struct {
231 : : uint8_t cert_usage;
232 : : uint8_t selector;
233 : : uint8_t matching_type;
234 : : void *data;
235 : : size_t data_size;
236 : : } tlsa;
237 : :
238 : : /* https://tools.ietf.org/html/rfc6844 */
239 : : struct {
240 : : uint8_t flags;
241 : : char *tag;
242 : : void *value;
243 : : size_t value_size;
244 : : } caa;
245 : : };
246 : : };
247 : :
248 : 16 : static inline const void* DNS_RESOURCE_RECORD_RDATA(const DnsResourceRecord *rr) {
249 [ - + ]: 16 : if (!rr)
250 : 0 : return NULL;
251 : :
252 [ - + ]: 16 : if (!rr->wire_format)
253 : 0 : return NULL;
254 : :
255 [ - + ]: 16 : assert(rr->wire_format_rdata_offset <= rr->wire_format_size);
256 : 16 : return (uint8_t*) rr->wire_format + rr->wire_format_rdata_offset;
257 : : }
258 : :
259 : 16 : static inline size_t DNS_RESOURCE_RECORD_RDATA_SIZE(const DnsResourceRecord *rr) {
260 [ - + ]: 16 : if (!rr)
261 : 0 : return 0;
262 [ - + ]: 16 : if (!rr->wire_format)
263 : 0 : return 0;
264 : :
265 [ - + ]: 16 : assert(rr->wire_format_rdata_offset <= rr->wire_format_size);
266 : 16 : return rr->wire_format_size - rr->wire_format_rdata_offset;
267 : : }
268 : :
269 : 0 : static inline uint8_t DNS_RESOURCE_RECORD_OPT_VERSION_SUPPORTED(const DnsResourceRecord *rr) {
270 [ # # ]: 0 : assert(rr);
271 [ # # ]: 0 : assert(rr->key->type == DNS_TYPE_OPT);
272 : :
273 : 0 : return ((rr->ttl >> 16) & 0xFF) == 0;
274 : : }
275 : :
276 : : DnsResourceKey* dns_resource_key_new(uint16_t class, uint16_t type, const char *name);
277 : : DnsResourceKey* dns_resource_key_new_redirect(const DnsResourceKey *key, const DnsResourceRecord *cname);
278 : : int dns_resource_key_new_append_suffix(DnsResourceKey **ret, DnsResourceKey *key, char *name);
279 : : DnsResourceKey* dns_resource_key_new_consume(uint16_t class, uint16_t type, char *name);
280 : : DnsResourceKey* dns_resource_key_ref(DnsResourceKey *key);
281 : : DnsResourceKey* dns_resource_key_unref(DnsResourceKey *key);
282 : : const char* dns_resource_key_name(const DnsResourceKey *key);
283 : : bool dns_resource_key_is_address(const DnsResourceKey *key);
284 : : bool dns_resource_key_is_dnssd_ptr(const DnsResourceKey *key);
285 : : int dns_resource_key_equal(const DnsResourceKey *a, const DnsResourceKey *b);
286 : : int dns_resource_key_match_rr(const DnsResourceKey *key, DnsResourceRecord *rr, const char *search_domain);
287 : : int dns_resource_key_match_cname_or_dname(const DnsResourceKey *key, const DnsResourceKey *cname, const char *search_domain);
288 : : int dns_resource_key_match_soa(const DnsResourceKey *key, const DnsResourceKey *soa);
289 : :
290 : : /* _DNS_{CLASS,TYPE}_STRING_MAX include one byte for NUL, which we use for space instead below.
291 : : * DNS_HOSTNAME_MAX does not include the NUL byte, so we need to add 1. */
292 : : #define DNS_RESOURCE_KEY_STRING_MAX (_DNS_CLASS_STRING_MAX + _DNS_TYPE_STRING_MAX + DNS_HOSTNAME_MAX + 1)
293 : :
294 : : char* dns_resource_key_to_string(const DnsResourceKey *key, char *buf, size_t buf_size);
295 : : ssize_t dns_resource_record_payload(DnsResourceRecord *rr, void **out);
296 : :
297 [ + - ]: 1976 : DEFINE_TRIVIAL_CLEANUP_FUNC(DnsResourceKey*, dns_resource_key_unref);
298 : :
299 : 0 : static inline bool dns_key_is_shared(const DnsResourceKey *key) {
300 [ # # ]: 0 : return IN_SET(key->type, DNS_TYPE_PTR);
301 : : }
302 : :
303 : : bool dns_resource_key_reduce(DnsResourceKey **a, DnsResourceKey **b);
304 : :
305 : : DnsResourceRecord* dns_resource_record_new(DnsResourceKey *key);
306 : : DnsResourceRecord* dns_resource_record_new_full(uint16_t class, uint16_t type, const char *name);
307 : : DnsResourceRecord* dns_resource_record_ref(DnsResourceRecord *rr);
308 : : DnsResourceRecord* dns_resource_record_unref(DnsResourceRecord *rr);
309 : : int dns_resource_record_new_reverse(DnsResourceRecord **ret, int family, const union in_addr_union *address, const char *name);
310 : : int dns_resource_record_new_address(DnsResourceRecord **ret, int family, const union in_addr_union *address, const char *name);
311 : : int dns_resource_record_equal(const DnsResourceRecord *a, const DnsResourceRecord *b);
312 : : int dns_resource_record_payload_equal(const DnsResourceRecord *a, const DnsResourceRecord *b);
313 : :
314 : : const char* dns_resource_record_to_string(DnsResourceRecord *rr);
315 : : DnsResourceRecord *dns_resource_record_copy(DnsResourceRecord *rr);
316 [ + + ]: 7688 : DEFINE_TRIVIAL_CLEANUP_FUNC(DnsResourceRecord*, dns_resource_record_unref);
317 : :
318 : : int dns_resource_record_to_wire_format(DnsResourceRecord *rr, bool canonical);
319 : :
320 : : int dns_resource_record_signer(DnsResourceRecord *rr, const char **ret);
321 : : int dns_resource_record_source(DnsResourceRecord *rr, const char **ret);
322 : : int dns_resource_record_is_signer(DnsResourceRecord *rr, const char *zone);
323 : : int dns_resource_record_is_synthetic(DnsResourceRecord *rr);
324 : :
325 : : int dns_resource_record_clamp_ttl(DnsResourceRecord **rr, uint32_t max_ttl);
326 : :
327 : : DnsTxtItem *dns_txt_item_free_all(DnsTxtItem *i);
328 : : bool dns_txt_item_equal(DnsTxtItem *a, DnsTxtItem *b);
329 : : DnsTxtItem *dns_txt_item_copy(DnsTxtItem *i);
330 : : int dns_txt_item_new_empty(DnsTxtItem **ret);
331 : :
332 : : void dns_resource_record_hash_func(const DnsResourceRecord *i, struct siphash *state);
333 : :
334 : : extern const struct hash_ops dns_resource_key_hash_ops;
335 : : extern const struct hash_ops dns_resource_record_hash_ops;
336 : :
337 : : int dnssec_algorithm_to_string_alloc(int i, char **ret);
338 : : int dnssec_algorithm_from_string(const char *s) _pure_;
339 : :
340 : : int dnssec_digest_to_string_alloc(int i, char **ret);
341 : : int dnssec_digest_from_string(const char *s) _pure_;
|