1 /*------------------------------------------------------------------------------
2 *
3 * Copyright (c) 2011-2021, EURid vzw. All rights reserved.
4 * The YADIFA TM software product is provided under the BSD 3-clause license:
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * * Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * * Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * * Neither the name of EURid nor the names of its contributors may be
16 * used to endorse or promote products derived from this software
17 * without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
23 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 *
31 *------------------------------------------------------------------------------
32 *
33 */
34
35 /** @defgroup dnspacket DNS Messages
36 * @ingroup dnscore
37 * @brief
38 *
39 *
40 *
41 * @{
42 *
43 *----------------------------------------------------------------------------*/
44 #include "dnscore/dnscore-config.h"
45 #include <stdio.h>
46 #include <stdlib.h>
47 #include <arpa/inet.h>
48 #include <ctype.h>
49
50 #include "dnscore/dnscore-config.h"
51 #include "dnscore/packet_reader.h"
52 //#include "dnscore/rfc.h"
53 #include "dnscore/tsig.h"
54
55 #if HAS_CTRL
56 #include "dnscore/ctrl-rfc.h"
57 #endif
58
59 #define TMP00003_TAG 0x3330303030504d54
60
61 ya_result
packet_reader_read_fqdn(packet_unpack_reader_data * reader,u8 * output_buffer,u32 len_)62 packet_reader_read_fqdn(packet_unpack_reader_data* reader, u8 *output_buffer, u32 len_)
63 {
64 const u8 *p_limit = &reader->packet[reader->packet_size];
65
66 u8 *buffer = output_buffer;
67 u8 *buffer_limit = &buffer[len_];
68 const u8 *p = &reader->packet[reader->offset];
69
70 /* ------------------------------------------------------------ */
71
72 if(p >= p_limit)
73 {
74 reader->offset = reader->packet_size;
75 return UNEXPECTED_EOF; /* EOF */
76 }
77
78 for(;;)
79 {
80 u8 len = *p++;
81
82 if((len & 0xc0) == 0xc0)
83 {
84 if(p >= p_limit)
85 {
86 reader->offset = reader->packet_size;
87 return UNEXPECTED_EOF; /* EOF */
88 }
89
90 reader->offset = p - reader->packet;
91
92 /* reposition the pointer */
93 u32 new_offset = len & 0x3f;
94 new_offset <<= 8;
95 new_offset |= *p;
96
97 const u8* q = &reader->packet[new_offset];
98
99 if(q >= p)
100 {
101 return RCODE_ERROR_CODE(RCODE_FORMERR);
102 }
103
104 p = q;
105
106 reader->offset++;
107
108 break;
109 }
110
111 *buffer++ = len;
112
113 if(len == 0)
114 {
115 reader->offset = p - reader->packet;
116 return buffer - output_buffer;
117 }
118
119 if(p + len >= p_limit)
120 {
121 reader->offset = reader->packet_size;
122 return UNEXPECTED_EOF;
123 }
124
125 if(buffer + len >= buffer_limit)
126 {
127 return BUFFER_WOULD_OVERFLOW;
128 }
129 /*
130 MEMCOPY(buffer, p, len);
131 buffer += len;
132 p += len;
133 */
134 u8* buffer_limit = &buffer[len];
135 do
136 {
137 *buffer++ = tolower(*p++);
138 }
139 while(buffer < buffer_limit);
140 }
141
142 for(;;)
143 {
144 u8 len = *p;
145
146 if((len & 0xc0) == 0xc0) /* EDF: better yet: cmp len, 192; jge */
147 {
148 /* reposition the pointer */
149 u32 new_offset = len & 0x3f;
150 new_offset <<= 8;
151 new_offset |= p[1];
152
153 const u8* q = &reader->packet[new_offset];
154
155 if(q < p)
156 {
157 p = q;
158 continue;
159 }
160
161 return RCODE_ERROR_CODE(RCODE_FORMERR);
162 }
163
164 *buffer++ = len;
165
166 if(len == 0)
167 {
168 return buffer - output_buffer;
169 }
170
171 ++p;
172
173 if(p + len >= p_limit)
174 {
175 reader->offset = reader->packet_size;
176 return UNEXPECTED_EOF;
177 }
178
179 if(buffer + len >= buffer_limit)
180 {
181 return BUFFER_WOULD_OVERFLOW;
182 }
183
184 u8* buffer_limit = &buffer[len];
185
186 do
187 {
188 *buffer++ = tolower(*p++);
189 }
190 while(buffer < buffer_limit);
191 }
192
193 // never reached
194 }
195
196 ya_result
packet_reader_read(packet_unpack_reader_data * reader,void * output_buffer,u32 len)197 packet_reader_read(packet_unpack_reader_data* reader, void *output_buffer, u32 len)
198 {
199 u32 remaining = reader->packet_size - reader->offset;
200
201 if(remaining >= len)
202 {
203 MEMCOPY(output_buffer, &reader->packet[reader->offset], len);
204 reader->offset += len;
205
206 return len;
207 }
208 else
209 {
210 reader->offset = reader->packet_size;
211 return UNEXPECTED_EOF;
212 }
213 }
214
215 ya_result
packet_reader_read_u16(packet_unpack_reader_data * reader,u16 * val)216 packet_reader_read_u16(packet_unpack_reader_data* reader, u16 *val)
217 {
218 yassert(val != NULL);
219
220 u32 remaining = reader->packet_size - reader->offset;
221
222 if(remaining >= 2)
223 {
224 *val = GET_U16_AT(reader->packet[reader->offset]);
225 reader->offset += 2;
226 return 2;
227 }
228 else
229 {
230 reader->offset = reader->packet_size;
231 return UNEXPECTED_EOF;
232 }
233 }
234
235 ya_result
packet_reader_skip_bytes(packet_unpack_reader_data * reader,u16 count)236 packet_reader_skip_bytes(packet_unpack_reader_data* reader, u16 count)
237 {
238 u32 remaining = reader->packet_size - reader->offset;
239
240 if(remaining >= count)
241 {
242 reader->offset += count;
243 return count;
244 }
245 else
246 {
247 reader->offset = reader->packet_size;
248 return UNEXPECTED_EOF;
249 }
250 }
251
252 ya_result
packet_reader_read_dnstype(packet_unpack_reader_data * reader)253 packet_reader_read_dnstype(packet_unpack_reader_data* reader)
254 {
255 u32 remaining = reader->packet_size - reader->offset;
256
257 if(remaining >= 2)
258 {
259 u16 dnstype = GET_U16_AT(reader->packet[reader->offset]);
260 reader->offset += 2;
261 return dnstype;
262 }
263 else
264 {
265 reader->offset = reader->packet_size;
266 return UNEXPECTED_EOF;
267 }
268 }
269
270 ya_result
packet_reader_read_dnsclass(packet_unpack_reader_data * reader)271 packet_reader_read_dnsclass(packet_unpack_reader_data* reader)
272 {
273 u32 remaining = reader->packet_size - reader->offset;
274
275 if(remaining >= 2)
276 {
277 u16 dnsclass = GET_U16_AT(reader->packet[reader->offset]);
278 reader->offset += 2;
279 return dnsclass;
280 }
281 else
282 {
283 reader->offset = reader->packet_size;
284 return UNEXPECTED_EOF;
285 }
286 }
287
288 ya_result
packet_reader_skip_query(packet_unpack_reader_data * reader,const u8 * domain,u16 dnstype,u16 dnsclass)289 packet_reader_skip_query(packet_unpack_reader_data* reader, const u8 *domain, u16 dnstype, u16 dnsclass)
290 {
291 ya_result ret;
292 u8 fqdn[MAX_DOMAIN_LENGTH];
293 if(ISOK(ret = packet_reader_read_fqdn(reader, fqdn, sizeof(fqdn))))
294 {
295 if(dnsname_equals_ignorecase(domain, fqdn))
296 {
297 if(FAIL(ret = packet_reader_read_dnstype(reader)))
298 {
299 return ret;
300 }
301
302 if(ret != dnstype)
303 {
304 return MESSAGE_UNEXPECTED_ANSWER_TYPE_CLASS;
305 }
306
307 if(FAIL(ret = packet_reader_read_dnsclass(reader)))
308 {
309 return ret;
310 }
311
312 if(ret != dnsclass)
313 {
314 return MESSAGE_UNEXPECTED_ANSWER_TYPE_CLASS;
315 }
316 }
317 else
318 {
319 return MESSAGE_UNEXPECTED_ANSWER_DOMAIN;
320 }
321 }
322
323 return ret;
324 }
325
326 ya_result
packet_reader_read_u32(packet_unpack_reader_data * reader,u32 * val)327 packet_reader_read_u32(packet_unpack_reader_data* reader, u32 *val)
328 {
329 yassert(val != NULL);
330
331 u32 remaining = reader->packet_size - reader->offset;
332
333 if(remaining >= 4)
334 {
335 *val = GET_U32_AT(reader->packet[reader->offset]);
336 reader->offset += 4;
337 return 4;
338 }
339 else
340 {
341 reader->offset = reader->packet_size;
342 return UNEXPECTED_EOF;
343 }
344 }
345
346 ya_result
packet_reader_read_zone_record(packet_unpack_reader_data * reader,u8 * output_buffer,u32 buffer_size)347 packet_reader_read_zone_record(packet_unpack_reader_data* reader, u8* output_buffer, u32 buffer_size)
348 {
349 ya_result ret;
350
351 u8* buffer = output_buffer;
352
353 /* Read the name */
354
355 if(FAIL(ret = packet_reader_read_fqdn(reader, buffer, buffer_size)))
356 {
357 return ret;
358 }
359
360 buffer += ret;
361 buffer_size -= ret;
362
363 if(buffer_size >= 4)
364 {
365 /* read the TYPE CLASS (4 bytes) */
366
367 if(FAIL(ret = packet_reader_read(reader, buffer, 4))) // exact
368 {
369 return ret;
370 }
371
372 yassert(ret == 4);
373
374 buffer += 4;
375
376 return buffer - output_buffer;
377 }
378 else
379 {
380 reader->offset = reader->packet_size;
381 return UNEXPECTED_EOF;
382 }
383 }
384
385 ya_result
packet_reader_skip_zone_record(packet_unpack_reader_data * reader)386 packet_reader_skip_zone_record(packet_unpack_reader_data* reader)
387 {
388 u32 from = reader->offset;
389 ya_result ret;
390
391 /* Read the name */
392
393 if(FAIL(ret = packet_reader_skip_fqdn(reader)))
394 {
395 return ret;
396 }
397
398 /* read the TYPE CLASS TTL RDATASIZE (4 bytes) */
399
400 if(FAIL(ret = packet_reader_skip(reader, 4)))
401 {
402 return ret;
403 }
404
405 return reader->offset - from;
406 }
407
408 ya_result
packet_reader_skip_query_section(packet_unpack_reader_data * reader)409 packet_reader_skip_query_section(packet_unpack_reader_data* reader)
410 {
411 u32 from = reader->offset;
412 u16 records = ntohs(MESSAGE_SECTION_COUNT(reader->packet, 0));
413
414 while(records > 0)
415 {
416 ya_result ret = packet_reader_skip_zone_record(reader);
417 if(FAIL(ret))
418 {
419 return ret;
420 }
421
422 --records;
423 }
424
425 return reader->offset - from;
426 }
427
428 ya_result
packet_reader_skip_section(packet_unpack_reader_data * reader,int section)429 packet_reader_skip_section(packet_unpack_reader_data* reader, int section)
430 {
431 switch(section)
432 {
433 case 0:
434 {
435 ya_result ret = packet_reader_skip_query_section(reader);
436 return ret;
437 }
438 case 1:
439 case 2:
440 case 3:
441 {
442 s32 from = reader->offset;
443 u16 records = MESSAGE_SECTION_COUNT(reader->packet, section);
444
445 while(records > 0)
446 {
447 ya_result ret = packet_reader_skip_record(reader);
448 if(FAIL(ret))
449 {
450 return ret;
451 }
452
453 --records;
454 }
455
456 return reader->offset - from;
457 }
458 default:
459 return INVALID_ARGUMENT_ERROR;
460 }
461 }
462
463
464 ya_result
packet_reader_read_rdata(packet_unpack_reader_data * reader,u16 type,s32 rdata_size,u8 * buffer,s32 buffer_size)465 packet_reader_read_rdata(packet_unpack_reader_data* reader, u16 type, s32 rdata_size, u8 *buffer, s32 buffer_size)
466 {
467 u8* rdata_start = buffer;
468 const u32 rdata_limit = reader->offset + rdata_size; // without compression, this is where the rdata ends + 1 byte
469 ya_result ret;
470
471 if(packet_reader_available(reader) < rdata_size)
472 {
473 reader->offset = reader->packet_size;
474 return UNEXPECTED_EOF;
475 }
476
477 switch(type)
478 {
479 /******************************************************************************
480 * The types that requires special handling (dname compression)
481 ******************************************************************************/
482
483 case TYPE_MX:
484 case TYPE_AFSDB:
485 {
486 u8 *p = buffer;
487 buffer += 2;
488 buffer_size -= 2;
489 rdata_size -= 2;
490
491 if(buffer_size == 0 || rdata_size > MAX_DOMAIN_LENGTH)
492 {
493 return INVALID_RECORD; /* wrong size */
494 }
495
496 packet_reader_read_unchecked(reader, p, 2); // exact
497
498 if(FAIL(ret = packet_reader_read_fqdn(reader, buffer, buffer_size))) /* err = error code or bytes filled, not bytes read (compression) */
499 {
500 return ret;
501 }
502
503 buffer += ret;
504
505 break;
506 }
507 case TYPE_NS:
508 case TYPE_CNAME:
509 case TYPE_DNAME:
510 case TYPE_PTR:
511 case TYPE_MB:
512 case TYPE_MD:
513 case TYPE_MF:
514 case TYPE_MG:
515 case TYPE_MR:
516 {
517 /* ONE NAME record */
518
519 if(rdata_size == 0 || rdata_size > MAX_DOMAIN_LENGTH)
520 {
521 return INVALID_RECORD; /* wrong size */
522 }
523
524 if(FAIL(ret = packet_reader_read_fqdn(reader, buffer, buffer_size)))
525 {
526 return ret;
527 }
528
529 buffer += ret;
530
531 break;
532 }
533 case TYPE_SOA:
534 {
535 /* NOTE: NO NEED TO SORT (There is only one) */
536 if(FAIL(ret = packet_reader_read_fqdn(reader, buffer, buffer_size)))
537 {
538 return ret;
539 }
540
541 buffer += ret;
542 buffer_size -= ret;
543
544 if(FAIL(ret = packet_reader_read_fqdn(reader, buffer, buffer_size)))
545 {
546 return ret;
547 }
548
549 if(rdata_limit - reader->offset != 20)
550 {
551 return INVALID_RECORD;
552 }
553
554 buffer_size -= ret;
555 if(buffer_size < 20)
556 {
557 return BUFFER_WOULD_OVERFLOW;
558 }
559
560 buffer += ret;
561 //len -= err;
562
563 packet_reader_read_unchecked(reader, buffer, 20); // exact
564
565 buffer += 20;
566
567 break;
568 }
569 case TYPE_RRSIG: /* not supposed to be compressed */
570 {
571 if(rdata_size > 2+1+1+4+4+4+2+256+1024+4)
572 {
573 return UNSUPPORTED_RECORD; /* too big */
574 }
575
576 if(rdata_size < RRSIG_RDATA_HEADER_LEN)
577 {
578 return INVALID_RECORD;
579 }
580
581 packet_reader_read_unchecked(reader, buffer, RRSIG_RDATA_HEADER_LEN); // exact
582
583 buffer += RRSIG_RDATA_HEADER_LEN;
584 buffer_size -= RRSIG_RDATA_HEADER_LEN;
585
586 if(FAIL(ret = packet_reader_read_fqdn(reader, buffer, buffer_size)))
587 {
588 return ret;
589 }
590
591 buffer += ret;
592
593 if(FAIL(ret = packet_reader_read(reader, buffer, rdata_limit - reader->offset))) // exact
594 {
595 return ret;
596 }
597
598 buffer += ret;
599
600 break;
601 }
602 case TYPE_NSEC: /* not supposed to be compressed */
603 {
604 if(FAIL(ret = packet_reader_read_fqdn(reader, buffer, buffer_size)))
605 {
606 return ret;
607 }
608
609 buffer += ret;
610 //len -= err;
611
612 if(rdata_limit - reader->offset == 0)
613 {
614 return INVALID_RECORD; // record is broken
615 }
616
617 if(FAIL(ret = packet_reader_read(reader, buffer, rdata_limit - reader->offset))) // exact
618 {
619 return ret;
620 }
621
622 buffer += ret;
623
624 break;
625 }
626
627 /******************************************************************************
628 * The types we reject
629 ******************************************************************************/
630
631 case TYPE_SIG:
632 {
633 if(rdata_size > 1024)
634 {
635 return UNSUPPORTED_RECORD; /* key is too big */
636 }
637
638 packet_reader_skip_unchecked(reader, rdata_size); // checked
639
640 return UNSUPPORTED_TYPE;
641 }
642 case TYPE_A6:
643 {
644 if(rdata_size > 1+16+256)
645 {
646 return UNSUPPORTED_RECORD; /* key is too big */
647 }
648
649 packet_reader_skip_unchecked(reader, rdata_size); // checked
650
651 return UNSUPPORTED_TYPE;
652 }
653
654 /******************************************************************************
655 * The other types
656 ******************************************************************************/
657
658 case TYPE_A:
659 {
660 if(rdata_size != 4)
661 {
662 return INCORRECT_IPADDRESS;
663 }
664
665 packet_reader_read_unchecked(reader, buffer, 4); // exact
666
667 buffer += 4;
668 break;
669 }
670 case TYPE_AAAA:
671 {
672 if(rdata_size != 16)
673 {
674 return INCORRECT_IPADDRESS;
675 }
676
677 packet_reader_read_unchecked(reader, buffer, 16); // exact
678
679 buffer += 16;
680 break;
681 }
682 /*
683 case TYPE_HINFO:
684 case TYPE_MINFO:
685 case TYPE_DS:
686 case TYPE_TXT:
687 case TYPE_WKS:
688 case TYPE_DNSKEY:
689 case TYPE_NSEC3:
690 case TYPE_NSEC3PARAM:
691 case TYPE_LOC:
692 */
693 default:
694 {
695 packet_reader_read_unchecked(reader, buffer, rdata_size); // exact // rdata_size has been checked for overflow already
696 buffer += rdata_size;
697 break;
698 }
699 }
700
701 if(rdata_limit != reader->offset)
702 {
703 reader->offset = reader->packet_size;
704 return UNEXPECTED_EOF;
705 }
706
707 return buffer - rdata_start;
708 }
709
710 /**
711 * @note DOES NOT AND SHOULD NOT WORK FOR CTRL TYPES !
712 */
713
714 ya_result
packet_reader_read_record(packet_unpack_reader_data * reader,u8 * output_buffer,u32 len)715 packet_reader_read_record(packet_unpack_reader_data* reader, u8* output_buffer, u32 len)
716 {
717 ya_result ret;
718
719 u8* buffer = output_buffer;
720
721 /* Read the name */
722
723 if(FAIL(ret = packet_reader_read_fqdn(reader, buffer, len)))
724 {
725 return ret;
726 }
727
728 buffer += ret;
729 len -= ret;
730
731 if(len < 10)
732 {
733 return BUFFER_WOULD_OVERFLOW;
734 }
735
736 /* read the TYPE CLASS TTL RDATASIZE (10 bytes) */
737
738 ret = packet_reader_read(reader, buffer, 10); // exact
739
740 if(FAIL(ret))
741 {
742 return ret;
743 }
744 /*
745 * ret always return either what was asked, either unexpected eof
746 * if(ret != 10)
747 * {
748 * reader->offset = reader->packet_size;
749 * return UNEXPECTED_EOF;
750 * }
751 */
752 u16 rdata_size = ntohs(GET_U16_AT(buffer[8]));
753
754 if(rdata_size == 0) /* Can occur for dynupdate record set delete */
755 {
756 return (buffer - output_buffer) + 10;
757 }
758
759 if(len < rdata_size)
760 {
761 return BUFFER_WOULD_OVERFLOW;
762 }
763
764 if(packet_reader_available(reader) < rdata_size)
765 {
766 reader->offset = reader->packet_size;
767 return UNEXPECTED_EOF;
768 }
769
770 u16 rtype = (GET_U16_AT(buffer[0])); /** @note : NATIVETYPE */
771
772 buffer += 10;
773
774 /*
775 * EDF: No need to cut the len short, especially since what is returned
776 * by the fqdn readers is the output side, not the input one (unpack)
777 */
778
779 u8* rdata_start = buffer;
780 u32 rdata_limit = reader->offset + rdata_size;
781
782 switch(rtype)
783 {
784 /******************************************************************************
785 * The types that requires special handling (dname compression)
786 ******************************************************************************/
787
788 case TYPE_MX:
789 case TYPE_AFSDB:
790 {
791 u8 *p = buffer;
792
793 buffer += 2;
794 len -= 2;
795 rdata_size -= 2;
796
797 if(len == 0 || rdata_size > MAX_DOMAIN_LENGTH)
798 {
799 return INVALID_RECORD; /* wrong rdata_size */
800 }
801
802 packet_reader_read_unchecked(reader, p, 2); // exact
803
804 if(FAIL(ret = packet_reader_read_fqdn(reader, buffer, len))) /* err = error code or bytes filled, not bytes read (compression) */
805 {
806 return ret;
807 }
808
809 buffer += ret;
810
811 break;
812 }
813 case TYPE_NS:
814 case TYPE_CNAME:
815 case TYPE_DNAME:
816 case TYPE_PTR:
817 case TYPE_MB:
818 case TYPE_MD:
819 case TYPE_MF:
820 case TYPE_MG:
821 case TYPE_MR:
822 {
823 /* ONE NAME record */
824
825 if((rdata_size == 0) || (rdata_size > MAX_DOMAIN_LENGTH))
826 {
827 return INVALID_RECORD; /* wrong rdata_size */
828 }
829
830 if(FAIL(ret = packet_reader_read_fqdn(reader, buffer, len)))
831 {
832 return ret;
833 }
834
835 buffer += ret;
836
837 break;
838 }
839 case TYPE_SOA:
840 {
841 /* NOTE: NO NEED TO SORT (There is only one) */
842 if(FAIL(ret = packet_reader_read_fqdn(reader, buffer, len)))
843 {
844 return ret;
845 }
846
847 buffer += ret;
848 len -= ret;
849
850 if(FAIL(ret = packet_reader_read_fqdn(reader, buffer, len)))
851 {
852 return ret;
853 }
854
855 if(rdata_limit - reader->offset != 20)
856 {
857 return INVALID_RECORD;
858 }
859
860 len -= ret;
861 if(len < 20)
862 {
863 return BUFFER_WOULD_OVERFLOW;
864 }
865
866 buffer += ret;
867 //len -= err;
868
869 packet_reader_read_unchecked(reader, buffer, 20); // exact
870
871 buffer += 20;
872
873 break;
874 }
875 case TYPE_RRSIG: /* not supposed to be compressed */
876 {
877 if(rdata_size > 2+1+1+4+4+4+2+256+1024+4)
878 {
879 return UNSUPPORTED_RECORD; /* too big */
880 }
881
882 if(rdata_size < RRSIG_RDATA_HEADER_LEN)
883 {
884 reader->offset = reader->packet_size;
885 return UNEXPECTED_EOF;
886 }
887
888 packet_reader_read_unchecked(reader, buffer, RRSIG_RDATA_HEADER_LEN); // exact
889
890 buffer += RRSIG_RDATA_HEADER_LEN;
891 len -= RRSIG_RDATA_HEADER_LEN;
892
893 if(FAIL(ret = packet_reader_read_fqdn(reader, buffer, len)))
894 {
895 return ret;
896 }
897
898 buffer += ret;
899
900 if(FAIL(ret = packet_reader_read(reader, buffer, rdata_limit - reader->offset))) // exact
901 {
902 return ret;
903 }
904
905 buffer += ret;
906
907 break;
908 }
909 case TYPE_NSEC: /* not supposed to be compressed */
910 {
911 if(FAIL(ret = packet_reader_read_fqdn(reader, buffer, len)))
912 {
913 return ret;
914 }
915
916 buffer += ret;
917 //len -= err;
918
919 if(rdata_limit - reader->offset == 0)
920 {
921 return INVALID_RECORD; // record is broken
922 }
923
924 if(FAIL(ret = packet_reader_read(reader, buffer, rdata_limit - reader->offset))) // exact
925 {
926 return ret;
927 }
928
929 buffer += ret;
930
931 break;
932 }
933
934 /******************************************************************************
935 * The types we reject
936 ******************************************************************************/
937
938 case TYPE_SIG:
939 {
940 if(rdata_size > 1024)
941 {
942 return UNSUPPORTED_RECORD; /* key is too big */
943 }
944
945 packet_reader_skip_unchecked(reader, rdata_size); // checked
946
947 //buffer += err;
948
949 return UNSUPPORTED_TYPE;
950 }
951 case TYPE_A6:
952 {
953 if(rdata_size > 1+16+256)
954 {
955 return UNSUPPORTED_RECORD; /* key is too big */
956 }
957
958 packet_reader_skip_unchecked(reader, rdata_size); // checked
959
960 return UNSUPPORTED_TYPE;
961 }
962
963 /******************************************************************************
964 * The other types
965 ******************************************************************************/
966
967 case TYPE_A:
968 {
969 if(rdata_size != 4)
970 {
971 return INCORRECT_IPADDRESS;
972 }
973
974 packet_reader_read_unchecked(reader, buffer, 4); // exact
975 buffer += 4;
976
977 break;
978 }
979 case TYPE_AAAA:
980 {
981 if(rdata_size != 16)
982 {
983 return INCORRECT_IPADDRESS;
984 }
985
986 packet_reader_read_unchecked(reader, buffer, 16); // exact
987
988 buffer += 16;
989 break;
990 }
991 /*
992 case TYPE_HINFO:
993 case TYPE_MINFO:
994 case TYPE_DS:
995 case TYPE_TXT:
996 case TYPE_WKS:
997 case TYPE_DNSKEY:
998 case TYPE_NSEC3:
999 case TYPE_NSEC3PARAM:
1000 case TYPE_LOC:
1001 */
1002 default:
1003 {
1004 packet_reader_read_unchecked(reader, buffer, rdata_size); // exact
1005 buffer += rdata_size;
1006 break;
1007 }
1008 }
1009
1010 if(rdata_limit != reader->offset)
1011 {
1012 reader->offset = reader->packet_size;
1013 return UNEXPECTED_EOF;
1014 }
1015
1016 SET_U16_AT(rdata_start[-2], htons(buffer - rdata_start)); /* rdata rdata_size */
1017
1018 /*
1019 * This len was the rdata_size but this was the packed rdata_size.
1020 * So I cannot compare without a relatively expensive test
1021 * yassert(len == 0);
1022 *
1023 */
1024
1025 return buffer - output_buffer;
1026 }
1027
1028 ya_result
packet_reader_read_dns_resource_record(packet_unpack_reader_data * reader,dns_resource_record * rr)1029 packet_reader_read_dns_resource_record(packet_unpack_reader_data* reader, dns_resource_record *rr)
1030 {
1031
1032 ya_result ret;
1033
1034 if(ISOK(ret = packet_reader_read_fqdn(reader, rr->name, sizeof(rr->name))))
1035 {
1036 rr->name_len = ret;
1037 if(ISOK(ret = packet_reader_read(reader, &rr->tctr, 10)))
1038 {
1039 u16 rdata_size = ntohs(rr->tctr.rdlen);
1040 dns_resource_record_ensure_size(rr, rdata_size);
1041 rr->rdata_size = rdata_size;
1042 u32 offset = reader->offset;
1043 while((ret = packet_reader_read_rdata(reader, rr->tctr.qtype, rdata_size, rr->rdata, rr->rdata_buffer_size)) == BUFFER_WOULD_OVERFLOW)
1044 {
1045 dns_resource_record_ensure_size(rr, MIN((MAX_DOMAIN_LENGTH + 7) & ~7, MAX(rr->rdata_buffer_size * 2, 65535)));
1046 reader->offset = offset;
1047 }
1048 }
1049 }
1050
1051 return ret;
1052 }
1053
1054 void
packet_reader_rewind(packet_unpack_reader_data * reader)1055 packet_reader_rewind(packet_unpack_reader_data* reader)
1056 {
1057 reader->offset = 0;
1058 }
1059
1060 /*
1061 * Skip a compressed fqdn
1062 */
1063
1064 ya_result
packet_reader_skip_fqdn(packet_unpack_reader_data * reader)1065 packet_reader_skip_fqdn(packet_unpack_reader_data* reader)
1066 {
1067 /* Testing for a minimum len size is pointless */
1068
1069 u32 from = reader->offset;
1070 const u8* p_limit = &reader->packet[reader->packet_size];
1071 const u8* p = &reader->packet[reader->offset];
1072
1073 if(p >= p_limit)
1074 {
1075 reader->offset = reader->packet_size;
1076 return UNEXPECTED_EOF; /* EOF */
1077 }
1078
1079 for(;;)
1080 {
1081 u8 len = *p++;
1082
1083 if((len & 0xc0) == 0xc0)
1084 {
1085 p++;
1086 reader->offset = p - reader->packet;
1087 return reader->offset - from;
1088 }
1089
1090 if(len == 0)
1091 {
1092 reader->offset = p - reader->packet;
1093 return reader->offset - from;
1094 }
1095
1096 if(p + len >= p_limit)
1097 {
1098 reader->offset = reader->packet_size;
1099 return UNEXPECTED_EOF;
1100 }
1101
1102 p += len;
1103 }
1104 }
1105
1106 /*
1107 * Skip a record
1108 */
1109
1110 ya_result
packet_reader_skip_record(packet_unpack_reader_data * reader)1111 packet_reader_skip_record(packet_unpack_reader_data* reader)
1112 {
1113 ya_result err;
1114 ya_result from = reader->offset;
1115
1116 /* Read the name */
1117
1118 if(FAIL(err = packet_reader_skip_fqdn(reader)))
1119 {
1120 return err;
1121 }
1122
1123 /* read the TYPE CLASS TTL RDATASIZE (10 bytes) */
1124
1125 u16 size = ntohs(GET_U16_AT(reader->packet[reader->offset + 8]));
1126 u32 next_offset = reader->offset + 10 + size;
1127
1128 if(next_offset > reader->packet_size)
1129 {
1130 reader->offset = reader->packet_size;
1131 return UNEXPECTED_EOF;
1132 }
1133
1134 reader->offset = next_offset;
1135
1136 /*
1137 * This len was the rdata_size but this was the packed size.
1138 * So I cannot compare without a relatively expensive test
1139 * yassert(len == 0);
1140 *
1141 */
1142
1143 return reader->offset - from;
1144 }
1145
1146 #if HAS_CTRL
1147
1148 /**
1149 *
1150 * Returns true iff the string txt is utf-8
1151 * The current implementation checks it's ASCII7 (which is a valid subset of utf-8)
1152 *
1153 * @param txt
1154 * @param len
1155 * @return
1156 */
1157
1158 static bool
is_utf8(const char * txt,u16 len)1159 is_utf8(const char *txt, u16 len)
1160 {
1161 for(u16 i = 0; i < len; i++)
1162 {
1163 if((txt[i] & 0x80) != 0)
1164 {
1165 return FALSE;
1166 }
1167 }
1168
1169 return TRUE;
1170 }
1171
1172 /**
1173 *
1174 * @note Yes, this COULD go in the message.* files, once they are finalised
1175 *
1176 * @param reader
1177 * @param rdatasize
1178 * @param rclass
1179 * @param txt
1180 * @param dryrun
1181 * @return
1182 */
1183
1184 ya_result
packet_reader_read_utf8(packet_unpack_reader_data * reader,u16 rdatasize,u16 rclass,char ** txt,bool dryrun)1185 packet_reader_read_utf8(packet_unpack_reader_data *reader, u16 rdatasize, u16 rclass, char **txt, bool dryrun)
1186 {
1187 char *tmp = NULL;
1188 ya_result return_value;
1189
1190 if(rclass == CLASS_ANY)
1191 {
1192 if(rdatasize != 0)
1193 {
1194 return RCODE_ERROR_CODE(RCODE_FORMERR); /* formerr */
1195 }
1196
1197 if(!dryrun)
1198 {
1199 free(*txt);
1200 *txt = NULL;
1201 }
1202
1203 return_value = SUCCESS;
1204 }
1205 else
1206 {
1207 MALLOC_OR_DIE(char *, tmp, rdatasize + 1, TMP00003_TAG);
1208 if(ISOK(packet_reader_read(reader, (u8*)tmp, rdatasize)))
1209 {
1210 tmp[rdatasize] = '\0';
1211
1212 if(is_utf8(tmp, rdatasize))
1213 {
1214 return_value = SUCCESS;
1215
1216 if(!dryrun)
1217 {
1218 if(rclass != CLASS_NONE)
1219 {
1220 if(*txt != NULL)
1221 {
1222 free(*txt);
1223 }
1224
1225 *txt = tmp;
1226 tmp = NULL;
1227 }
1228 else
1229 {
1230 if(*txt != NULL)
1231 {
1232 if(strcmp(*txt, tmp) == 0)
1233 {
1234 free(*txt);
1235 *txt = NULL;
1236 }
1237 }
1238 }
1239 }
1240 }
1241 else
1242 {
1243 return_value = MAKE_DNSMSG_ERROR(RCODE_FORMERR);
1244 }
1245 }
1246 else
1247 {
1248 return_value = MAKE_DNSMSG_ERROR(RCODE_FORMERR);
1249 }
1250
1251 if(tmp != NULL)
1252 {
1253 free(tmp);
1254 }
1255 }
1256
1257 return return_value;
1258 }
1259
1260 /**
1261 *
1262 * @note Yes, this COULD go in the message.* files, once they are finalised
1263 *
1264 * @param reader
1265 * @param rdatasize
1266 * @param rclass
1267 * @param ha
1268 * @param dryrun
1269 * @return
1270 */
1271
1272 ya_result
packet_reader_read_remote_server(packet_unpack_reader_data * reader,u16 rdatasize,u16 rclass,host_address ** ha,bool dryrun)1273 packet_reader_read_remote_server(packet_unpack_reader_data *reader, u16 rdatasize, u16 rclass, host_address **ha, bool dryrun)
1274 {
1275 u16 ip_port = 0;
1276 u8 ipver;
1277 u8 flags;
1278
1279 u8 ip_buffer[16];
1280 u8 tsig_name[MAX_DOMAIN_LENGTH];
1281
1282 if(rclass == CLASS_ANY)
1283 {
1284 if(rdatasize != 0)
1285 {
1286 return RCODE_ERROR_CODE(RCODE_FORMERR); /* formerr */
1287 }
1288
1289 if(!dryrun)
1290 {
1291 if(*ha != NULL)
1292 {
1293 host_address_delete_list(*ha);
1294 *ha = NULL;
1295 }
1296 }
1297
1298 return SUCCESS;
1299 }
1300
1301 ya_result return_value;
1302
1303 if(ISOK(return_value = packet_reader_read(reader, &flags, 1)))
1304 {
1305 return_value = INVALID_STATE_ERROR;
1306
1307 ipver = flags & REMOTE_SERVER_FLAGS_IP_MASK;
1308
1309 if((ipver == HOST_ADDRESS_IPV4) || (ipver == HOST_ADDRESS_IPV6))
1310 {
1311 tsig_item *tsig = NULL;
1312
1313 if(ipver == HOST_ADDRESS_IPV4)
1314 {
1315 return_value = packet_reader_read(reader, ip_buffer, 4);
1316 }
1317 else
1318 {
1319 return_value = packet_reader_read(reader, ip_buffer, 16);
1320 }
1321
1322 if(FAIL(return_value))
1323 {
1324 return return_value;
1325 }
1326
1327 if((flags & REMOTE_SERVER_FLAGS_PORT_MASK) != 0)
1328 {
1329 if(FAIL(return_value = packet_reader_read_u16(reader, &ip_port)))
1330 {
1331 return return_value;
1332 }
1333 }
1334
1335 if((flags & REMOTE_SERVER_FLAGS_KEY_MASK) != 0)
1336 {
1337 if(FAIL(return_value = packet_reader_read_fqdn(reader, tsig_name, sizeof(tsig_name))))
1338 {
1339 return return_value;
1340 }
1341
1342 if((tsig = tsig_get(tsig_name)) == NULL)
1343 {
1344 return RCODE_ERROR_CODE(RCODE_BADKEY);
1345 }
1346 }
1347
1348 if(!dryrun)
1349 {
1350 host_address *address;
1351
1352 MALLOC_OBJECT_OR_DIE(address, host_address, HOSTADDR_TAG);
1353
1354 address->next = NULL;
1355 address->tsig = tsig;
1356
1357 if(ipver == HOST_ADDRESS_IPV4)
1358 {
1359 memcpy(address->ip.v4.bytes, ip_buffer, 4);
1360 address->port = ip_port;
1361 address->version = HOST_ADDRESS_IPV4;
1362 }
1363 else // HOST_ADDRESS_IPV6:
1364 {
1365 memcpy(address->ip.v6.bytes, ip_buffer, 16);
1366 address->port = ip_port;
1367 address->version = HOST_ADDRESS_IPV6;
1368 }
1369
1370 /*
1371 * Here the rclass changes the behaviour
1372 */
1373
1374 if(rclass != CLASS_NONE)
1375 {
1376 if(*ha == NULL)
1377 {
1378 *ha = address;
1379 }
1380 else
1381 {
1382 host_address_append_host_address(*ha, address); // copy made, or may fail is address is not supported
1383 free(address);
1384 }
1385 }
1386 else
1387 {
1388 host_address_remove_host_address(ha, address); /* not freed */
1389 free(address);
1390 }
1391
1392 return_value = SUCCESS;
1393 }
1394 }
1395 }
1396
1397 return return_value;
1398 }
1399
1400 #endif
1401
1402 /** @} */
1403