]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/resolve/resolved-dns-packet.c
Merge pull request #585 from teg/resolved-harden-2
[thirdparty/systemd.git] / src / resolve / resolved-dns-packet.c
1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3 /***
4 This file is part of systemd.
5
6 Copyright 2014 Lennart Poettering
7
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
12
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
17
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
20 ***/
21
22 #include "utf8.h"
23 #include "util.h"
24 #include "strv.h"
25 #include "unaligned.h"
26 #include "dns-domain.h"
27 #include "resolved-dns-packet.h"
28
29 int dns_packet_new(DnsPacket **ret, DnsProtocol protocol, size_t mtu) {
30 DnsPacket *p;
31 size_t a;
32
33 assert(ret);
34
35 if (mtu <= UDP_PACKET_HEADER_SIZE)
36 a = DNS_PACKET_SIZE_START;
37 else
38 a = mtu - UDP_PACKET_HEADER_SIZE;
39
40 if (a < DNS_PACKET_HEADER_SIZE)
41 a = DNS_PACKET_HEADER_SIZE;
42
43 /* round up to next page size */
44 a = PAGE_ALIGN(ALIGN(sizeof(DnsPacket)) + a) - ALIGN(sizeof(DnsPacket));
45
46 /* make sure we never allocate more than useful */
47 if (a > DNS_PACKET_SIZE_MAX)
48 a = DNS_PACKET_SIZE_MAX;
49
50 p = malloc0(ALIGN(sizeof(DnsPacket)) + a);
51 if (!p)
52 return -ENOMEM;
53
54 p->size = p->rindex = DNS_PACKET_HEADER_SIZE;
55 p->allocated = a;
56 p->protocol = protocol;
57 p->n_ref = 1;
58
59 *ret = p;
60
61 return 0;
62 }
63
64 int dns_packet_new_query(DnsPacket **ret, DnsProtocol protocol, size_t mtu) {
65 DnsPacket *p;
66 DnsPacketHeader *h;
67 int r;
68
69 assert(ret);
70
71 r = dns_packet_new(&p, protocol, mtu);
72 if (r < 0)
73 return r;
74
75 h = DNS_PACKET_HEADER(p);
76
77 if (protocol == DNS_PROTOCOL_LLMNR)
78 h->flags = htobe16(DNS_PACKET_MAKE_FLAGS(0 /* qr */,
79 0 /* opcode */,
80 0 /* c */,
81 0 /* tc */,
82 0 /* t */,
83 0 /* ra */,
84 0 /* ad */,
85 0 /* cd */,
86 0 /* rcode */));
87 else
88 h->flags = htobe16(DNS_PACKET_MAKE_FLAGS(0 /* qr */,
89 0 /* opcode */,
90 0 /* aa */,
91 0 /* tc */,
92 1 /* rd (ask for recursion) */,
93 0 /* ra */,
94 0 /* ad */,
95 0 /* cd */,
96 0 /* rcode */));
97
98 *ret = p;
99 return 0;
100 }
101
102 DnsPacket *dns_packet_ref(DnsPacket *p) {
103
104 if (!p)
105 return NULL;
106
107 assert(p->n_ref > 0);
108 p->n_ref++;
109 return p;
110 }
111
112 static void dns_packet_free(DnsPacket *p) {
113 char *s;
114
115 assert(p);
116
117 dns_question_unref(p->question);
118 dns_answer_unref(p->answer);
119
120 while ((s = hashmap_steal_first_key(p->names)))
121 free(s);
122 hashmap_free(p->names);
123
124 free(p->_data);
125 free(p);
126 }
127
128 DnsPacket *dns_packet_unref(DnsPacket *p) {
129 if (!p)
130 return NULL;
131
132 assert(p->n_ref > 0);
133
134 if (p->n_ref == 1)
135 dns_packet_free(p);
136 else
137 p->n_ref--;
138
139 return NULL;
140 }
141
142 int dns_packet_validate(DnsPacket *p) {
143 assert(p);
144
145 if (p->size < DNS_PACKET_HEADER_SIZE)
146 return -EBADMSG;
147
148 if (p->size > DNS_PACKET_SIZE_MAX)
149 return -EBADMSG;
150
151 return 1;
152 }
153
154 int dns_packet_validate_reply(DnsPacket *p) {
155 int r;
156
157 assert(p);
158
159 r = dns_packet_validate(p);
160 if (r < 0)
161 return r;
162
163 if (DNS_PACKET_QR(p) != 1)
164 return 0;
165
166 if (DNS_PACKET_OPCODE(p) != 0)
167 return -EBADMSG;
168
169 switch (p->protocol) {
170 case DNS_PROTOCOL_LLMNR:
171 /* RFC 4795, Section 2.1.1. says to discard all replies with QDCOUNT != 1 */
172 if (DNS_PACKET_QDCOUNT(p) != 1)
173 return -EBADMSG;
174
175 break;
176
177 default:
178 break;
179 }
180
181 return 1;
182 }
183
184 int dns_packet_validate_query(DnsPacket *p) {
185 int r;
186
187 assert(p);
188
189 r = dns_packet_validate(p);
190 if (r < 0)
191 return r;
192
193 if (DNS_PACKET_QR(p) != 0)
194 return 0;
195
196 if (DNS_PACKET_OPCODE(p) != 0)
197 return -EBADMSG;
198
199 if (DNS_PACKET_TC(p))
200 return -EBADMSG;
201
202 switch (p->protocol) {
203 case DNS_PROTOCOL_LLMNR:
204 /* RFC 4795, Section 2.1.1. says to discard all queries with QDCOUNT != 1 */
205 if (DNS_PACKET_QDCOUNT(p) != 1)
206 return -EBADMSG;
207
208 /* RFC 4795, Section 2.1.1. says to discard all queries with ANCOUNT != 0 */
209 if (DNS_PACKET_ANCOUNT(p) > 0)
210 return -EBADMSG;
211
212 /* RFC 4795, Section 2.1.1. says to discard all queries with NSCOUNT != 0 */
213 if (DNS_PACKET_NSCOUNT(p) > 0)
214 return -EBADMSG;
215
216 break;
217
218 default:
219 break;
220 }
221
222 return 1;
223 }
224
225 static int dns_packet_extend(DnsPacket *p, size_t add, void **ret, size_t *start) {
226 assert(p);
227
228 if (p->size + add > p->allocated) {
229 size_t a;
230
231 a = PAGE_ALIGN((p->size + add) * 2);
232 if (a > DNS_PACKET_SIZE_MAX)
233 a = DNS_PACKET_SIZE_MAX;
234
235 if (p->size + add > a)
236 return -EMSGSIZE;
237
238 if (p->_data) {
239 void *d;
240
241 d = realloc(p->_data, a);
242 if (!d)
243 return -ENOMEM;
244
245 p->_data = d;
246 } else {
247 p->_data = malloc(a);
248 if (!p->_data)
249 return -ENOMEM;
250
251 memcpy(p->_data, (uint8_t*) p + ALIGN(sizeof(DnsPacket)), p->size);
252 memzero((uint8_t*) p->_data + p->size, a - p->size);
253 }
254
255 p->allocated = a;
256 }
257
258 if (start)
259 *start = p->size;
260
261 if (ret)
262 *ret = (uint8_t*) DNS_PACKET_DATA(p) + p->size;
263
264 p->size += add;
265 return 0;
266 }
267
268 static void dns_packet_truncate(DnsPacket *p, size_t sz) {
269 Iterator i;
270 char *s;
271 void *n;
272
273 assert(p);
274
275 if (p->size <= sz)
276 return;
277
278 HASHMAP_FOREACH_KEY(s, n, p->names, i) {
279
280 if (PTR_TO_SIZE(n) < sz)
281 continue;
282
283 hashmap_remove(p->names, s);
284 free(s);
285 }
286
287 p->size = sz;
288 }
289
290 int dns_packet_append_blob(DnsPacket *p, const void *d, size_t l, size_t *start) {
291 void *q;
292 int r;
293
294 assert(p);
295
296 r = dns_packet_extend(p, l, &q, start);
297 if (r < 0)
298 return r;
299
300 memcpy(q, d, l);
301 return 0;
302 }
303
304 int dns_packet_append_uint8(DnsPacket *p, uint8_t v, size_t *start) {
305 void *d;
306 int r;
307
308 assert(p);
309
310 r = dns_packet_extend(p, sizeof(uint8_t), &d, start);
311 if (r < 0)
312 return r;
313
314 ((uint8_t*) d)[0] = v;
315
316 return 0;
317 }
318
319 int dns_packet_append_uint16(DnsPacket *p, uint16_t v, size_t *start) {
320 void *d;
321 int r;
322
323 assert(p);
324
325 r = dns_packet_extend(p, sizeof(uint16_t), &d, start);
326 if (r < 0)
327 return r;
328
329 unaligned_write_be16(d, v);
330
331 return 0;
332 }
333
334 int dns_packet_append_uint32(DnsPacket *p, uint32_t v, size_t *start) {
335 void *d;
336 int r;
337
338 assert(p);
339
340 r = dns_packet_extend(p, sizeof(uint32_t), &d, start);
341 if (r < 0)
342 return r;
343
344 unaligned_write_be32(d, v);
345
346 return 0;
347 }
348
349 int dns_packet_append_string(DnsPacket *p, const char *s, size_t *start) {
350 void *d;
351 size_t l;
352 int r;
353
354 assert(p);
355 assert(s);
356
357 l = strlen(s);
358 if (l > 255)
359 return -E2BIG;
360
361 r = dns_packet_extend(p, 1 + l, &d, start);
362 if (r < 0)
363 return r;
364
365 ((uint8_t*) d)[0] = (uint8_t) l;
366 memcpy(((uint8_t*) d) + 1, s, l);
367
368 return 0;
369 }
370
371 int dns_packet_append_label(DnsPacket *p, const char *d, size_t l, size_t *start) {
372 void *w;
373 int r;
374
375 assert(p);
376 assert(d);
377
378 if (l > DNS_LABEL_MAX)
379 return -E2BIG;
380
381 r = dns_packet_extend(p, 1 + l, &w, start);
382 if (r < 0)
383 return r;
384
385 ((uint8_t*) w)[0] = (uint8_t) l;
386 memcpy(((uint8_t*) w) + 1, d, l);
387
388 return 0;
389 }
390
391 int dns_packet_append_name(DnsPacket *p, const char *name,
392 bool allow_compression, size_t *start) {
393 size_t saved_size;
394 int r;
395
396 assert(p);
397 assert(name);
398
399 saved_size = p->size;
400
401 while (*name) {
402 _cleanup_free_ char *s = NULL;
403 char label[DNS_LABEL_MAX];
404 size_t n = 0;
405 int k;
406
407 if (allow_compression)
408 n = PTR_TO_SIZE(hashmap_get(p->names, name));
409 if (n > 0) {
410 assert(n < p->size);
411
412 if (n < 0x4000) {
413 r = dns_packet_append_uint16(p, 0xC000 | n, NULL);
414 if (r < 0)
415 goto fail;
416
417 goto done;
418 }
419 }
420
421 s = strdup(name);
422 if (!s) {
423 r = -ENOMEM;
424 goto fail;
425 }
426
427 r = dns_label_unescape(&name, label, sizeof(label));
428 if (r < 0)
429 goto fail;
430
431 if (p->protocol == DNS_PROTOCOL_DNS)
432 k = dns_label_apply_idna(label, r, label, sizeof(label));
433 else
434 k = dns_label_undo_idna(label, r, label, sizeof(label));
435 if (k < 0) {
436 r = k;
437 goto fail;
438 }
439 if (k > 0)
440 r = k;
441
442 r = dns_packet_append_label(p, label, r, &n);
443 if (r < 0)
444 goto fail;
445
446 if (allow_compression) {
447 r = hashmap_ensure_allocated(&p->names, &dns_name_hash_ops);
448 if (r < 0)
449 goto fail;
450
451 r = hashmap_put(p->names, s, SIZE_TO_PTR(n));
452 if (r < 0)
453 goto fail;
454
455 s = NULL;
456 }
457 }
458
459 r = dns_packet_append_uint8(p, 0, NULL);
460 if (r < 0)
461 return r;
462
463 done:
464 if (start)
465 *start = saved_size;
466
467 return 0;
468
469 fail:
470 dns_packet_truncate(p, saved_size);
471 return r;
472 }
473
474 int dns_packet_append_key(DnsPacket *p, const DnsResourceKey *k, size_t *start) {
475 size_t saved_size;
476 int r;
477
478 assert(p);
479 assert(k);
480
481 saved_size = p->size;
482
483 r = dns_packet_append_name(p, DNS_RESOURCE_KEY_NAME(k), true, NULL);
484 if (r < 0)
485 goto fail;
486
487 r = dns_packet_append_uint16(p, k->type, NULL);
488 if (r < 0)
489 goto fail;
490
491 r = dns_packet_append_uint16(p, k->class, NULL);
492 if (r < 0)
493 goto fail;
494
495 if (start)
496 *start = saved_size;
497
498 return 0;
499
500 fail:
501 dns_packet_truncate(p, saved_size);
502 return r;
503 }
504
505 int dns_packet_append_rr(DnsPacket *p, const DnsResourceRecord *rr, size_t *start) {
506 size_t saved_size, rdlength_offset, end, rdlength;
507 int r;
508
509 assert(p);
510 assert(rr);
511
512 saved_size = p->size;
513
514 r = dns_packet_append_key(p, rr->key, NULL);
515 if (r < 0)
516 goto fail;
517
518 r = dns_packet_append_uint32(p, rr->ttl, NULL);
519 if (r < 0)
520 goto fail;
521
522 /* Initially we write 0 here */
523 r = dns_packet_append_uint16(p, 0, &rdlength_offset);
524 if (r < 0)
525 goto fail;
526
527 switch (rr->unparseable ? _DNS_TYPE_INVALID : rr->key->type) {
528
529 case DNS_TYPE_SRV:
530 r = dns_packet_append_uint16(p, rr->srv.priority, NULL);
531 if (r < 0)
532 goto fail;
533
534 r = dns_packet_append_uint16(p, rr->srv.weight, NULL);
535 if (r < 0)
536 goto fail;
537
538 r = dns_packet_append_uint16(p, rr->srv.port, NULL);
539 if (r < 0)
540 goto fail;
541
542 r = dns_packet_append_name(p, rr->srv.name, true, NULL);
543 break;
544
545 case DNS_TYPE_PTR:
546 case DNS_TYPE_NS:
547 case DNS_TYPE_CNAME:
548 case DNS_TYPE_DNAME:
549 r = dns_packet_append_name(p, rr->ptr.name, true, NULL);
550 break;
551
552 case DNS_TYPE_HINFO:
553 r = dns_packet_append_string(p, rr->hinfo.cpu, NULL);
554 if (r < 0)
555 goto fail;
556
557 r = dns_packet_append_string(p, rr->hinfo.os, NULL);
558 break;
559
560 case DNS_TYPE_SPF: /* exactly the same as TXT */
561 case DNS_TYPE_TXT: {
562 char **s;
563
564 if (strv_isempty(rr->txt.strings)) {
565 /* RFC 6763, section 6.1 suggests to generate
566 * single empty string for an empty array. */
567
568 r = dns_packet_append_string(p, "", NULL);
569 if (r < 0)
570 goto fail;
571 } else {
572 STRV_FOREACH(s, rr->txt.strings) {
573 r = dns_packet_append_string(p, *s, NULL);
574 if (r < 0)
575 goto fail;
576 }
577 }
578
579 r = 0;
580 break;
581 }
582
583 case DNS_TYPE_A:
584 r = dns_packet_append_blob(p, &rr->a.in_addr, sizeof(struct in_addr), NULL);
585 break;
586
587 case DNS_TYPE_AAAA:
588 r = dns_packet_append_blob(p, &rr->aaaa.in6_addr, sizeof(struct in6_addr), NULL);
589 break;
590
591 case DNS_TYPE_SOA:
592 r = dns_packet_append_name(p, rr->soa.mname, true, NULL);
593 if (r < 0)
594 goto fail;
595
596 r = dns_packet_append_name(p, rr->soa.rname, true, NULL);
597 if (r < 0)
598 goto fail;
599
600 r = dns_packet_append_uint32(p, rr->soa.serial, NULL);
601 if (r < 0)
602 goto fail;
603
604 r = dns_packet_append_uint32(p, rr->soa.refresh, NULL);
605 if (r < 0)
606 goto fail;
607
608 r = dns_packet_append_uint32(p, rr->soa.retry, NULL);
609 if (r < 0)
610 goto fail;
611
612 r = dns_packet_append_uint32(p, rr->soa.expire, NULL);
613 if (r < 0)
614 goto fail;
615
616 r = dns_packet_append_uint32(p, rr->soa.minimum, NULL);
617 break;
618
619 case DNS_TYPE_MX:
620 r = dns_packet_append_uint16(p, rr->mx.priority, NULL);
621 if (r < 0)
622 goto fail;
623
624 r = dns_packet_append_name(p, rr->mx.exchange, true, NULL);
625 break;
626
627 case DNS_TYPE_LOC:
628 r = dns_packet_append_uint8(p, rr->loc.version, NULL);
629 if (r < 0)
630 goto fail;
631
632 r = dns_packet_append_uint8(p, rr->loc.size, NULL);
633 if (r < 0)
634 goto fail;
635
636 r = dns_packet_append_uint8(p, rr->loc.horiz_pre, NULL);
637 if (r < 0)
638 goto fail;
639
640 r = dns_packet_append_uint8(p, rr->loc.vert_pre, NULL);
641 if (r < 0)
642 goto fail;
643
644 r = dns_packet_append_uint32(p, rr->loc.latitude, NULL);
645 if (r < 0)
646 goto fail;
647
648 r = dns_packet_append_uint32(p, rr->loc.longitude, NULL);
649 if (r < 0)
650 goto fail;
651
652 r = dns_packet_append_uint32(p, rr->loc.altitude, NULL);
653 break;
654
655 case DNS_TYPE_SSHFP:
656 r = dns_packet_append_uint8(p, rr->sshfp.algorithm, NULL);
657 if (r < 0)
658 goto fail;
659
660 r = dns_packet_append_uint8(p, rr->sshfp.fptype, NULL);
661 if (r < 0)
662 goto fail;
663
664 r = dns_packet_append_blob(p, rr->sshfp.key, rr->sshfp.key_size, NULL);
665 break;
666
667 case DNS_TYPE_DNSKEY:
668 r = dns_packet_append_uint16(p, dnskey_to_flags(rr), NULL);
669 if (r < 0)
670 goto fail;
671
672 r = dns_packet_append_uint8(p, 3u, NULL);
673 if (r < 0)
674 goto fail;
675
676 r = dns_packet_append_uint8(p, rr->dnskey.algorithm, NULL);
677 if (r < 0)
678 goto fail;
679
680 r = dns_packet_append_blob(p, rr->dnskey.key, rr->dnskey.key_size, NULL);
681 break;
682
683 case DNS_TYPE_RRSIG:
684 r = dns_packet_append_uint16(p, rr->rrsig.type_covered, NULL);
685 if (r < 0)
686 goto fail;
687
688 r = dns_packet_append_uint8(p, rr->rrsig.algorithm, NULL);
689 if (r < 0)
690 goto fail;
691
692 r = dns_packet_append_uint8(p, rr->rrsig.labels, NULL);
693 if (r < 0)
694 goto fail;
695
696 r = dns_packet_append_uint32(p, rr->rrsig.original_ttl, NULL);
697 if (r < 0)
698 goto fail;
699
700 r = dns_packet_append_uint32(p, rr->rrsig.expiration, NULL);
701 if (r < 0)
702 goto fail;
703
704 r = dns_packet_append_uint32(p, rr->rrsig.inception, NULL);
705 if (r < 0)
706 goto fail;
707
708 r = dns_packet_append_uint16(p, rr->rrsig.key_tag, NULL);
709 if (r < 0)
710 goto fail;
711
712 r = dns_packet_append_name(p, rr->rrsig.signer, false, NULL);
713 if (r < 0)
714 goto fail;
715
716 r = dns_packet_append_blob(p, rr->rrsig.signature, rr->rrsig.signature_size, NULL);
717 break;
718
719 case _DNS_TYPE_INVALID: /* unparseable */
720 default:
721
722 r = dns_packet_append_blob(p, rr->generic.data, rr->generic.size, NULL);
723 break;
724 }
725 if (r < 0)
726 goto fail;
727
728 /* Let's calculate the actual data size and update the field */
729 rdlength = p->size - rdlength_offset - sizeof(uint16_t);
730 if (rdlength > 0xFFFF) {
731 r = ENOSPC;
732 goto fail;
733 }
734
735 end = p->size;
736 p->size = rdlength_offset;
737 r = dns_packet_append_uint16(p, rdlength, NULL);
738 if (r < 0)
739 goto fail;
740 p->size = end;
741
742 if (start)
743 *start = saved_size;
744
745 return 0;
746
747 fail:
748 dns_packet_truncate(p, saved_size);
749 return r;
750 }
751
752
753 int dns_packet_read(DnsPacket *p, size_t sz, const void **ret, size_t *start) {
754 assert(p);
755
756 if (p->rindex + sz > p->size)
757 return -EMSGSIZE;
758
759 if (ret)
760 *ret = (uint8_t*) DNS_PACKET_DATA(p) + p->rindex;
761
762 if (start)
763 *start = p->rindex;
764
765 p->rindex += sz;
766 return 0;
767 }
768
769 void dns_packet_rewind(DnsPacket *p, size_t idx) {
770 assert(p);
771 assert(idx <= p->size);
772 assert(idx >= DNS_PACKET_HEADER_SIZE);
773
774 p->rindex = idx;
775 }
776
777 int dns_packet_read_blob(DnsPacket *p, void *d, size_t sz, size_t *start) {
778 const void *q;
779 int r;
780
781 assert(p);
782 assert(d);
783
784 r = dns_packet_read(p, sz, &q, start);
785 if (r < 0)
786 return r;
787
788 memcpy(d, q, sz);
789 return 0;
790 }
791
792 int dns_packet_read_uint8(DnsPacket *p, uint8_t *ret, size_t *start) {
793 const void *d;
794 int r;
795
796 assert(p);
797
798 r = dns_packet_read(p, sizeof(uint8_t), &d, start);
799 if (r < 0)
800 return r;
801
802 *ret = ((uint8_t*) d)[0];
803 return 0;
804 }
805
806 int dns_packet_read_uint16(DnsPacket *p, uint16_t *ret, size_t *start) {
807 const void *d;
808 int r;
809
810 assert(p);
811
812 r = dns_packet_read(p, sizeof(uint16_t), &d, start);
813 if (r < 0)
814 return r;
815
816 *ret = unaligned_read_be16(d);
817
818 return 0;
819 }
820
821 int dns_packet_read_uint32(DnsPacket *p, uint32_t *ret, size_t *start) {
822 const void *d;
823 int r;
824
825 assert(p);
826
827 r = dns_packet_read(p, sizeof(uint32_t), &d, start);
828 if (r < 0)
829 return r;
830
831 *ret = unaligned_read_be32(d);
832
833 return 0;
834 }
835
836 int dns_packet_read_string(DnsPacket *p, char **ret, size_t *start) {
837 size_t saved_rindex;
838 const void *d;
839 char *t;
840 uint8_t c;
841 int r;
842
843 assert(p);
844
845 saved_rindex = p->rindex;
846
847 r = dns_packet_read_uint8(p, &c, NULL);
848 if (r < 0)
849 goto fail;
850
851 r = dns_packet_read(p, c, &d, NULL);
852 if (r < 0)
853 goto fail;
854
855 if (memchr(d, 0, c)) {
856 r = -EBADMSG;
857 goto fail;
858 }
859
860 t = strndup(d, c);
861 if (!t) {
862 r = -ENOMEM;
863 goto fail;
864 }
865
866 if (!utf8_is_valid(t)) {
867 free(t);
868 r = -EBADMSG;
869 goto fail;
870 }
871
872 *ret = t;
873
874 if (start)
875 *start = saved_rindex;
876
877 return 0;
878
879 fail:
880 dns_packet_rewind(p, saved_rindex);
881 return r;
882 }
883
884 int dns_packet_read_name(DnsPacket *p, char **_ret,
885 bool allow_compression, size_t *start) {
886 size_t saved_rindex, after_rindex = 0, jump_barrier;
887 _cleanup_free_ char *ret = NULL;
888 size_t n = 0, allocated = 0;
889 bool first = true;
890 int r;
891
892 assert(p);
893 assert(_ret);
894
895 saved_rindex = p->rindex;
896 jump_barrier = p->rindex;
897
898 for (;;) {
899 uint8_t c, d;
900
901 r = dns_packet_read_uint8(p, &c, NULL);
902 if (r < 0)
903 goto fail;
904
905 if (c == 0)
906 /* End of name */
907 break;
908 else if (c <= 63) {
909 _cleanup_free_ char *t = NULL;
910 const char *label;
911
912 /* Literal label */
913 r = dns_packet_read(p, c, (const void**) &label, NULL);
914 if (r < 0)
915 goto fail;
916
917 r = dns_label_escape(label, c, &t);
918 if (r < 0)
919 goto fail;
920
921 if (!GREEDY_REALLOC(ret, allocated, n + !first + strlen(t) + 1)) {
922 r = -ENOMEM;
923 goto fail;
924 }
925
926 if (!first)
927 ret[n++] = '.';
928 else
929 first = false;
930
931 memcpy(ret + n, t, r);
932 n += r;
933 continue;
934 } else if (allow_compression && (c & 0xc0) == 0xc0) {
935 uint16_t ptr;
936
937 /* Pointer */
938 r = dns_packet_read_uint8(p, &d, NULL);
939 if (r < 0)
940 goto fail;
941
942 ptr = (uint16_t) (c & ~0xc0) << 8 | (uint16_t) d;
943 if (ptr < DNS_PACKET_HEADER_SIZE || ptr >= jump_barrier) {
944 r = -EBADMSG;
945 goto fail;
946 }
947
948 if (after_rindex == 0)
949 after_rindex = p->rindex;
950
951 /* Jumps are limited to a "prior occurrence" (RFC-1035 4.1.4) */
952 jump_barrier = ptr;
953 p->rindex = ptr;
954 } else {
955 r = -EBADMSG;
956 goto fail;
957 }
958 }
959
960 if (!GREEDY_REALLOC(ret, allocated, n + 1)) {
961 r = -ENOMEM;
962 goto fail;
963 }
964
965 ret[n] = 0;
966
967 if (after_rindex != 0)
968 p->rindex= after_rindex;
969
970 *_ret = ret;
971 ret = NULL;
972
973 if (start)
974 *start = saved_rindex;
975
976 return 0;
977
978 fail:
979 dns_packet_rewind(p, saved_rindex);
980 return r;
981 }
982
983 int dns_packet_read_key(DnsPacket *p, DnsResourceKey **ret, size_t *start) {
984 _cleanup_free_ char *name = NULL;
985 uint16_t class, type;
986 DnsResourceKey *key;
987 size_t saved_rindex;
988 int r;
989
990 assert(p);
991 assert(ret);
992
993 saved_rindex = p->rindex;
994
995 r = dns_packet_read_name(p, &name, true, NULL);
996 if (r < 0)
997 goto fail;
998
999 r = dns_packet_read_uint16(p, &type, NULL);
1000 if (r < 0)
1001 goto fail;
1002
1003 r = dns_packet_read_uint16(p, &class, NULL);
1004 if (r < 0)
1005 goto fail;
1006
1007 key = dns_resource_key_new_consume(class, type, name);
1008 if (!key) {
1009 r = -ENOMEM;
1010 goto fail;
1011 }
1012
1013 name = NULL;
1014 *ret = key;
1015
1016 if (start)
1017 *start = saved_rindex;
1018
1019 return 0;
1020 fail:
1021 dns_packet_rewind(p, saved_rindex);
1022 return r;
1023 }
1024
1025 static int dns_packet_read_public_key(DnsPacket *p, size_t length,
1026 void **dp, size_t *lengthp,
1027 size_t *start) {
1028 int r;
1029 const void *d;
1030 void *d2;
1031
1032 r = dns_packet_read(p, length, &d, NULL);
1033 if (r < 0)
1034 return r;
1035
1036 d2 = memdup(d, length);
1037 if (!d2)
1038 return -ENOMEM;
1039
1040 *dp = d2;
1041 *lengthp = length;
1042 return 0;
1043 }
1044
1045 static bool loc_size_ok(uint8_t size) {
1046 uint8_t m = size >> 4, e = size & 0xF;
1047
1048 return m <= 9 && e <= 9 && (m > 0 || e == 0);
1049 }
1050
1051 static int dnskey_parse_flags(DnsResourceRecord *rr, uint16_t flags) {
1052 assert(rr);
1053
1054 if (flags & ~(DNSKEY_FLAG_SEP | DNSKEY_FLAG_ZONE_KEY))
1055 return -EBADMSG;
1056
1057 rr->dnskey.zone_key_flag = flags & DNSKEY_FLAG_ZONE_KEY;
1058 rr->dnskey.sep_flag = flags & DNSKEY_FLAG_SEP;
1059 return 0;
1060 }
1061
1062 int dns_packet_read_rr(DnsPacket *p, DnsResourceRecord **ret, size_t *start) {
1063 _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *rr = NULL;
1064 _cleanup_(dns_resource_key_unrefp) DnsResourceKey *key = NULL;
1065 size_t saved_rindex, offset;
1066 uint16_t rdlength;
1067 const void *d;
1068 int r;
1069
1070 assert(p);
1071 assert(ret);
1072
1073 saved_rindex = p->rindex;
1074
1075 r = dns_packet_read_key(p, &key, NULL);
1076 if (r < 0)
1077 goto fail;
1078
1079 if (key->class == DNS_CLASS_ANY ||
1080 key->type == DNS_TYPE_ANY) {
1081 r = -EBADMSG;
1082 goto fail;
1083 }
1084
1085 rr = dns_resource_record_new(key);
1086 if (!rr) {
1087 r = -ENOMEM;
1088 goto fail;
1089 }
1090
1091 r = dns_packet_read_uint32(p, &rr->ttl, NULL);
1092 if (r < 0)
1093 goto fail;
1094
1095 r = dns_packet_read_uint16(p, &rdlength, NULL);
1096 if (r < 0)
1097 goto fail;
1098
1099 if (p->rindex + rdlength > p->size) {
1100 r = -EBADMSG;
1101 goto fail;
1102 }
1103
1104 offset = p->rindex;
1105
1106 switch (rr->key->type) {
1107
1108 case DNS_TYPE_SRV:
1109 r = dns_packet_read_uint16(p, &rr->srv.priority, NULL);
1110 if (r < 0)
1111 goto fail;
1112 r = dns_packet_read_uint16(p, &rr->srv.weight, NULL);
1113 if (r < 0)
1114 goto fail;
1115 r = dns_packet_read_uint16(p, &rr->srv.port, NULL);
1116 if (r < 0)
1117 goto fail;
1118 r = dns_packet_read_name(p, &rr->srv.name, true, NULL);
1119 break;
1120
1121 case DNS_TYPE_PTR:
1122 case DNS_TYPE_NS:
1123 case DNS_TYPE_CNAME:
1124 case DNS_TYPE_DNAME:
1125 r = dns_packet_read_name(p, &rr->ptr.name, true, NULL);
1126 break;
1127
1128 case DNS_TYPE_HINFO:
1129 r = dns_packet_read_string(p, &rr->hinfo.cpu, NULL);
1130 if (r < 0)
1131 goto fail;
1132
1133 r = dns_packet_read_string(p, &rr->hinfo.os, NULL);
1134 break;
1135
1136 case DNS_TYPE_SPF: /* exactly the same as TXT */
1137 case DNS_TYPE_TXT:
1138 if (rdlength <= 0) {
1139 /* RFC 6763, section 6.1 suggests to treat
1140 * empty TXT RRs as equivalent to a TXT record
1141 * with a single empty string. */
1142
1143 r = strv_extend(&rr->txt.strings, "");
1144 if (r < 0)
1145 goto fail;
1146 } else {
1147 while (p->rindex < offset + rdlength) {
1148 char *s;
1149
1150 r = dns_packet_read_string(p, &s, NULL);
1151 if (r < 0)
1152 goto fail;
1153
1154 r = strv_consume(&rr->txt.strings, s);
1155 if (r < 0)
1156 goto fail;
1157 }
1158 }
1159
1160 r = 0;
1161 break;
1162
1163 case DNS_TYPE_A:
1164 r = dns_packet_read_blob(p, &rr->a.in_addr, sizeof(struct in_addr), NULL);
1165 break;
1166
1167 case DNS_TYPE_AAAA:
1168 r = dns_packet_read_blob(p, &rr->aaaa.in6_addr, sizeof(struct in6_addr), NULL);
1169 break;
1170
1171 case DNS_TYPE_SOA:
1172 r = dns_packet_read_name(p, &rr->soa.mname, true, NULL);
1173 if (r < 0)
1174 goto fail;
1175
1176 r = dns_packet_read_name(p, &rr->soa.rname, true, NULL);
1177 if (r < 0)
1178 goto fail;
1179
1180 r = dns_packet_read_uint32(p, &rr->soa.serial, NULL);
1181 if (r < 0)
1182 goto fail;
1183
1184 r = dns_packet_read_uint32(p, &rr->soa.refresh, NULL);
1185 if (r < 0)
1186 goto fail;
1187
1188 r = dns_packet_read_uint32(p, &rr->soa.retry, NULL);
1189 if (r < 0)
1190 goto fail;
1191
1192 r = dns_packet_read_uint32(p, &rr->soa.expire, NULL);
1193 if (r < 0)
1194 goto fail;
1195
1196 r = dns_packet_read_uint32(p, &rr->soa.minimum, NULL);
1197 break;
1198
1199 case DNS_TYPE_MX:
1200 r = dns_packet_read_uint16(p, &rr->mx.priority, NULL);
1201 if (r < 0)
1202 goto fail;
1203
1204 r = dns_packet_read_name(p, &rr->mx.exchange, true, NULL);
1205 break;
1206
1207 case DNS_TYPE_LOC: {
1208 uint8_t t;
1209 size_t pos;
1210
1211 r = dns_packet_read_uint8(p, &t, &pos);
1212 if (r < 0)
1213 goto fail;
1214
1215 if (t == 0) {
1216 rr->loc.version = t;
1217
1218 r = dns_packet_read_uint8(p, &rr->loc.size, NULL);
1219 if (r < 0)
1220 goto fail;
1221
1222 if (!loc_size_ok(rr->loc.size)) {
1223 r = -EBADMSG;
1224 goto fail;
1225 }
1226
1227 r = dns_packet_read_uint8(p, &rr->loc.horiz_pre, NULL);
1228 if (r < 0)
1229 goto fail;
1230
1231 if (!loc_size_ok(rr->loc.horiz_pre)) {
1232 r = -EBADMSG;
1233 goto fail;
1234 }
1235
1236 r = dns_packet_read_uint8(p, &rr->loc.vert_pre, NULL);
1237 if (r < 0)
1238 goto fail;
1239
1240 if (!loc_size_ok(rr->loc.vert_pre)) {
1241 r = -EBADMSG;
1242 goto fail;
1243 }
1244
1245 r = dns_packet_read_uint32(p, &rr->loc.latitude, NULL);
1246 if (r < 0)
1247 goto fail;
1248
1249 r = dns_packet_read_uint32(p, &rr->loc.longitude, NULL);
1250 if (r < 0)
1251 goto fail;
1252
1253 r = dns_packet_read_uint32(p, &rr->loc.altitude, NULL);
1254 if (r < 0)
1255 goto fail;
1256
1257 break;
1258 } else {
1259 dns_packet_rewind(p, pos);
1260 rr->unparseable = true;
1261 goto unparseable;
1262 }
1263 }
1264
1265 case DNS_TYPE_SSHFP:
1266 r = dns_packet_read_uint8(p, &rr->sshfp.algorithm, NULL);
1267 if (r < 0)
1268 goto fail;
1269
1270 r = dns_packet_read_uint8(p, &rr->sshfp.fptype, NULL);
1271 if (r < 0)
1272 goto fail;
1273
1274 r = dns_packet_read_public_key(p, rdlength - 2,
1275 &rr->sshfp.key, &rr->sshfp.key_size,
1276 NULL);
1277 break;
1278
1279 case DNS_TYPE_DNSKEY: {
1280 uint16_t flags;
1281 uint8_t proto;
1282
1283 r = dns_packet_read_uint16(p, &flags, NULL);
1284 if (r < 0)
1285 goto fail;
1286
1287 r = dnskey_parse_flags(rr, flags);
1288 if (r < 0)
1289 goto fail;
1290
1291 r = dns_packet_read_uint8(p, &proto, NULL);
1292 if (r < 0)
1293 goto fail;
1294
1295 /* protocol is required to be always 3 */
1296 if (proto != 3) {
1297 r = -EBADMSG;
1298 goto fail;
1299 }
1300
1301 r = dns_packet_read_uint8(p, &rr->dnskey.algorithm, NULL);
1302 if (r < 0)
1303 goto fail;
1304
1305 r = dns_packet_read_public_key(p, rdlength - 4,
1306 &rr->dnskey.key, &rr->dnskey.key_size,
1307 NULL);
1308 break;
1309 }
1310
1311 case DNS_TYPE_RRSIG:
1312 r = dns_packet_read_uint16(p, &rr->rrsig.type_covered, NULL);
1313 if (r < 0)
1314 goto fail;
1315
1316 r = dns_packet_read_uint8(p, &rr->rrsig.algorithm, NULL);
1317 if (r < 0)
1318 goto fail;
1319
1320 r = dns_packet_read_uint8(p, &rr->rrsig.labels, NULL);
1321 if (r < 0)
1322 goto fail;
1323
1324 r = dns_packet_read_uint32(p, &rr->rrsig.original_ttl, NULL);
1325 if (r < 0)
1326 goto fail;
1327
1328 r = dns_packet_read_uint32(p, &rr->rrsig.expiration, NULL);
1329 if (r < 0)
1330 goto fail;
1331
1332 r = dns_packet_read_uint32(p, &rr->rrsig.inception, NULL);
1333 if (r < 0)
1334 goto fail;
1335
1336 r = dns_packet_read_uint16(p, &rr->rrsig.key_tag, NULL);
1337 if (r < 0)
1338 goto fail;
1339
1340 r = dns_packet_read_name(p, &rr->rrsig.signer, false, NULL);
1341 if (r < 0)
1342 goto fail;
1343
1344 r = dns_packet_read_public_key(p, offset + rdlength - p->rindex,
1345 &rr->rrsig.signature, &rr->rrsig.signature_size,
1346 NULL);
1347 break;
1348
1349 default:
1350 unparseable:
1351 r = dns_packet_read(p, rdlength, &d, NULL);
1352 if (r < 0)
1353 goto fail;
1354
1355 rr->generic.data = memdup(d, rdlength);
1356 if (!rr->generic.data) {
1357 r = -ENOMEM;
1358 goto fail;
1359 }
1360
1361 rr->generic.size = rdlength;
1362 break;
1363 }
1364 if (r < 0)
1365 goto fail;
1366 if (p->rindex != offset + rdlength) {
1367 r = -EBADMSG;
1368 goto fail;
1369 }
1370
1371 *ret = rr;
1372 rr = NULL;
1373
1374 if (start)
1375 *start = saved_rindex;
1376
1377 return 0;
1378 fail:
1379 dns_packet_rewind(p, saved_rindex);
1380 return r;
1381 }
1382
1383 int dns_packet_extract(DnsPacket *p) {
1384 _cleanup_(dns_question_unrefp) DnsQuestion *question = NULL;
1385 _cleanup_(dns_answer_unrefp) DnsAnswer *answer = NULL;
1386 size_t saved_rindex;
1387 unsigned n, i;
1388 int r;
1389
1390 if (p->extracted)
1391 return 0;
1392
1393 saved_rindex = p->rindex;
1394 dns_packet_rewind(p, DNS_PACKET_HEADER_SIZE);
1395
1396 n = DNS_PACKET_QDCOUNT(p);
1397 if (n > 0) {
1398 question = dns_question_new(n);
1399 if (!question) {
1400 r = -ENOMEM;
1401 goto finish;
1402 }
1403
1404 for (i = 0; i < n; i++) {
1405 _cleanup_(dns_resource_key_unrefp) DnsResourceKey *key = NULL;
1406
1407 r = dns_packet_read_key(p, &key, NULL);
1408 if (r < 0)
1409 goto finish;
1410
1411 r = dns_question_add(question, key);
1412 if (r < 0)
1413 goto finish;
1414 }
1415 }
1416
1417 n = DNS_PACKET_RRCOUNT(p);
1418 if (n > 0) {
1419 answer = dns_answer_new(n);
1420 if (!answer) {
1421 r = -ENOMEM;
1422 goto finish;
1423 }
1424
1425 for (i = 0; i < n; i++) {
1426 _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *rr = NULL;
1427
1428 r = dns_packet_read_rr(p, &rr, NULL);
1429 if (r < 0)
1430 goto finish;
1431
1432 r = dns_answer_add(answer, rr);
1433 if (r < 0)
1434 goto finish;
1435 }
1436 }
1437
1438 p->question = question;
1439 question = NULL;
1440
1441 p->answer = answer;
1442 answer = NULL;
1443
1444 p->extracted = true;
1445
1446 r = 0;
1447
1448 finish:
1449 p->rindex = saved_rindex;
1450 return r;
1451 }
1452
1453 static const char* const dns_rcode_table[_DNS_RCODE_MAX_DEFINED] = {
1454 [DNS_RCODE_SUCCESS] = "SUCCESS",
1455 [DNS_RCODE_FORMERR] = "FORMERR",
1456 [DNS_RCODE_SERVFAIL] = "SERVFAIL",
1457 [DNS_RCODE_NXDOMAIN] = "NXDOMAIN",
1458 [DNS_RCODE_NOTIMP] = "NOTIMP",
1459 [DNS_RCODE_REFUSED] = "REFUSED",
1460 [DNS_RCODE_YXDOMAIN] = "YXDOMAIN",
1461 [DNS_RCODE_YXRRSET] = "YRRSET",
1462 [DNS_RCODE_NXRRSET] = "NXRRSET",
1463 [DNS_RCODE_NOTAUTH] = "NOTAUTH",
1464 [DNS_RCODE_NOTZONE] = "NOTZONE",
1465 [DNS_RCODE_BADVERS] = "BADVERS",
1466 [DNS_RCODE_BADKEY] = "BADKEY",
1467 [DNS_RCODE_BADTIME] = "BADTIME",
1468 [DNS_RCODE_BADMODE] = "BADMODE",
1469 [DNS_RCODE_BADNAME] = "BADNAME",
1470 [DNS_RCODE_BADALG] = "BADALG",
1471 [DNS_RCODE_BADTRUNC] = "BADTRUNC",
1472 };
1473 DEFINE_STRING_TABLE_LOOKUP(dns_rcode, int);
1474
1475 static const char* const dns_protocol_table[_DNS_PROTOCOL_MAX] = {
1476 [DNS_PROTOCOL_DNS] = "dns",
1477 [DNS_PROTOCOL_MDNS] = "mdns",
1478 [DNS_PROTOCOL_LLMNR] = "llmnr",
1479 };
1480 DEFINE_STRING_TABLE_LOOKUP(dns_protocol, DnsProtocol);
1481
1482 static const char* const dnssec_algorithm_table[_DNSSEC_ALGORITHM_MAX_DEFINED] = {
1483 [DNSSEC_ALGORITHM_RSAMD5] = "RSAMD5",
1484 [DNSSEC_ALGORITHM_DH] = "DH",
1485 [DNSSEC_ALGORITHM_DSA] = "DSA",
1486 [DNSSEC_ALGORITHM_ECC] = "ECC",
1487 [DNSSEC_ALGORITHM_RSASHA1] = "RSASHA1",
1488 [DNSSEC_ALGORITHM_INDIRECT] = "INDIRECT",
1489 [DNSSEC_ALGORITHM_PRIVATEDNS] = "PRIVATEDNS",
1490 [DNSSEC_ALGORITHM_PRIVATEOID] = "PRIVATEOID",
1491 };
1492 DEFINE_STRING_TABLE_LOOKUP(dnssec_algorithm, int);