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