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