quickjs-tart

quickjs-based runtime for wallet-core logic
Log | Files | Refs | README | LICENSE

unit1650.c (9787B)


      1 /***************************************************************************
      2  *                                  _   _ ____  _
      3  *  Project                     ___| | | |  _ \| |
      4  *                             / __| | | | |_) | |
      5  *                            | (__| |_| |  _ <| |___
      6  *                             \___|\___/|_| \_\_____|
      7  *
      8  * Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
      9  *
     10  * This software is licensed as described in the file COPYING, which
     11  * you should have received as part of this distribution. The terms
     12  * are also available at https://curl.se/docs/copyright.html.
     13  *
     14  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
     15  * copies of the Software, and permit persons to whom the Software is
     16  * furnished to do so, under the terms of the COPYING file.
     17  *
     18  * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
     19  * KIND, either express or implied.
     20  *
     21  * SPDX-License-Identifier: curl
     22  *
     23  ***************************************************************************/
     24 #include "unitcheck.h"
     25 
     26 #include "doh.h"
     27 
     28 static CURLcode test_unit1650(char *arg)
     29 {
     30   UNITTEST_BEGIN_SIMPLE
     31 
     32 #ifndef CURL_DISABLE_DOH
     33 
     34 #define DNS_PREAMBLE "\x00\x00\x01\x00\x00\x01\x00\x00\x00\x00\x00\x00"
     35 #define LABEL_TEST "\x04\x74\x65\x73\x74"
     36 #define LABEL_HOST "\x04\x68\x6f\x73\x74"
     37 #define LABEL_NAME "\x04\x6e\x61\x6d\x65"
     38 #define DNSA_TYPE "\x01"
     39 #define DNSAAAA_TYPE "\x1c"
     40 #define DNSA_EPILOGUE "\x00\x00" DNSA_TYPE "\x00\x01"
     41 #define DNSAAAA_EPILOGUE "\x00\x00" DNSAAAA_TYPE "\x00\x01"
     42 
     43 #define DNS_Q1 DNS_PREAMBLE LABEL_TEST LABEL_HOST LABEL_NAME DNSA_EPILOGUE
     44 #define DNS_Q2 DNS_PREAMBLE LABEL_TEST LABEL_HOST LABEL_NAME DNSAAAA_EPILOGUE
     45 
     46   struct dohrequest {
     47     /* input */
     48     const char *name;
     49     DNStype type;
     50 
     51     /* output */
     52     const char *packet;
     53     size_t size;
     54     DOHcode rc;
     55   };
     56 
     57   static const struct dohrequest req[] = {
     58     {"test.host.name", DNS_TYPE_A, DNS_Q1, sizeof(DNS_Q1)-1, DOH_OK },
     59     {"test.host.name", DNS_TYPE_AAAA, DNS_Q2, sizeof(DNS_Q2)-1, DOH_OK },
     60     {"zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz"
     61      ".host.name",
     62      DNS_TYPE_AAAA, NULL, 0, DOH_DNS_BAD_LABEL }
     63   };
     64 
     65   struct dohresp {
     66     /* input */
     67     const char *packet;
     68     size_t size;
     69     DNStype type;
     70 
     71     /* output */
     72     DOHcode rc;
     73     const char *out;
     74   };
     75 
     76 #define DNS_FOO_EXAMPLE_COM                                          \
     77   "\x00\x00\x01\x00\x00\x01\x00\x01\x00\x00\x00\x00\x03\x66\x6f\x6f" \
     78   "\x07\x65\x78\x61\x6d\x70\x6c\x65\x03\x63\x6f\x6d\x00\x00\x01\x00" \
     79   "\x01\xc0\x0c\x00\x01\x00\x01\x00\x00\x00\x37\x00\x04\x7f\x00\x00" \
     80   "\x01"
     81 
     82   static const char full49[] = DNS_FOO_EXAMPLE_COM;
     83 
     84   static const struct dohresp resp[] = {
     85   {"\x00\x00", 2, DNS_TYPE_A, DOH_TOO_SMALL_BUFFER, NULL },
     86   {"\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01", 12,
     87    DNS_TYPE_A, DOH_DNS_BAD_ID, NULL },
     88   {"\x00\x00\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01", 12,
     89    DNS_TYPE_A, DOH_DNS_BAD_RCODE, NULL },
     90   {"\x00\x00\x01\x00\x00\x01\x00\x01\x00\x00\x00\x00\x03\x66\x6f\x6f", 16,
     91    DNS_TYPE_A, DOH_DNS_OUT_OF_RANGE, NULL },
     92   {"\x00\x00\x01\x00\x00\x01\x00\x01\x00\x00\x00\x00\x03\x66\x6f\x6f\x00", 17,
     93    DNS_TYPE_A, DOH_DNS_OUT_OF_RANGE, NULL },
     94   {"\x00\x00\x01\x00\x00\x01\x00\x01\x00\x00\x00\x00\x03\x66\x6f\x6f\x00"
     95    "\x00\x01\x00\x01", 21,
     96    DNS_TYPE_A, DOH_DNS_OUT_OF_RANGE, NULL },
     97   {"\x00\x00\x01\x00\x00\x01\x00\x01\x00\x00\x00\x00\x03\x66\x6f\x6f\x00"
     98    "\x00\x01\x00\x01"
     99    "\x04", 18,
    100    DNS_TYPE_A, DOH_DNS_OUT_OF_RANGE, NULL },
    101 
    102   {"\x00\x00\x01\x00\x00\x01\x00\x01\x00\x00\x00\x00\x04\x63\x75\x72"
    103    "\x6c\x04\x63\x75\x72\x6c\x00\x00\x05\x00\x01\xc0\x0c\x00\x05\x00"
    104    "\x01\x00\x00\x00\x37\x00\x11\x08\x61\x6e\x79\x77\x68\x65\x72\x65"
    105    "\x06\x72\x65\x61\x6c\x6c\x79\x00", 56,
    106    DNS_TYPE_A, DOH_OK, "anywhere.really "},
    107 
    108   {DNS_FOO_EXAMPLE_COM, 49, DNS_TYPE_A, DOH_OK, "127.0.0.1 "},
    109 
    110   {"\x00\x00\x01\x00\x00\x01\x00\x01\x00\x00\x00\x00\x04\x61\x61\x61"
    111    "\x61\x07\x65\x78\x61\x6d\x70\x6c\x65\x03\x63\x6f\x6d\x00\x00\x1c"
    112    "\x00\x01\xc0\x0c\x00\x1c\x00\x01\x00\x00\x00\x37\x00\x10\x20\x20"
    113    "\x20\x20\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x20\x20", 62,
    114    DNS_TYPE_AAAA, DOH_OK,
    115    "2020:2020:0000:0000:0000:0000:0000:2020 " },
    116 
    117   {"\x00\x00\x01\x00\x00\x01\x00\x01\x00\x00\x00\x00\x04\x63\x75\x72"
    118    "\x6c\x04\x63\x75\x72\x6c\x00\x00\x05\x00\x01\xc0\x0c\x00\x05\x00"
    119    "\x01\x00\x00\x00\x37\x00"
    120    "\x07\x03\x61\x6e\x79\xc0\x27\x00", 46,
    121    DNS_TYPE_A, DOH_DNS_LABEL_LOOP, NULL},
    122 
    123   /* packet with NSCOUNT == 1 */
    124   {"\x00\x00\x01\x00\x00\x01\x00\x01\x00\x01\x00\x00\x04\x61\x61\x61"
    125    "\x61\x07\x65\x78\x61\x6d\x70\x6c\x65\x03\x63\x6f\x6d\x00\x00\x1c"
    126    "\x00\x01\xc0\x0c\x00\x1c\x00\x01\x00\x00\x00\x37\x00\x10\x20\x20"
    127    "\x20\x20\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x20\x20"
    128    LABEL_TEST LABEL_HOST LABEL_NAME DNSAAAA_EPILOGUE "\x00\x00\x00\x01"
    129    "\00\x04\x01\x01\x01\x01", /* RDDATA */
    130 
    131    62 + 30,
    132    DNS_TYPE_AAAA, DOH_OK,
    133    "2020:2020:0000:0000:0000:0000:0000:2020 " },
    134 
    135   /* packet with ARCOUNT == 1 */
    136   {"\x00\x00\x01\x00\x00\x01\x00\x01\x00\x00\x00\x01\x04\x61\x61\x61"
    137    "\x61\x07\x65\x78\x61\x6d\x70\x6c\x65\x03\x63\x6f\x6d\x00\x00\x1c"
    138    "\x00\x01\xc0\x0c\x00\x1c\x00\x01\x00\x00\x00\x37\x00\x10\x20\x20"
    139    "\x20\x20\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x20\x20"
    140    LABEL_TEST LABEL_HOST LABEL_NAME DNSAAAA_EPILOGUE "\x00\x00\x00\x01"
    141    "\00\x04\x01\x01\x01\x01", /* RDDATA */
    142 
    143    62 + 30,
    144    DNS_TYPE_AAAA, DOH_OK,
    145    "2020:2020:0000:0000:0000:0000:0000:2020 " },
    146 
    147   };
    148 
    149   size_t size = 0;
    150   unsigned char buffer[256];
    151   size_t i;
    152   unsigned char *p;
    153 
    154   for(i = 0; i < CURL_ARRAYSIZE(req); i++) {
    155     DOHcode rc = doh_req_encode(req[i].name, req[i].type,
    156                                 buffer, sizeof(buffer), &size);
    157     if(rc != req[i].rc) {
    158       curl_mfprintf(stderr, "req %zu: Expected return code %d got %d\n", i,
    159                     req[i].rc, rc);
    160       abort_if(rc != req[i].rc, "return code");
    161     }
    162     if(size != req[i].size) {
    163       curl_mfprintf(stderr, "req %zu: Expected size %zu got %zu\n", i,
    164                     req[i].size, size);
    165       curl_mfprintf(stderr, "DNS encode made: %s\n", hexdump(buffer, size));
    166       abort_if(size != req[i].size, "size");
    167     }
    168     if(req[i].packet && memcmp(req[i].packet, buffer, size)) {
    169       curl_mfprintf(stderr, "DNS encode made: %s\n", hexdump(buffer, size));
    170       curl_mfprintf(stderr, "... instead of: %s\n",
    171                     hexdump((const unsigned char *)req[i].packet, size));
    172       abort_if(req[i].packet && memcmp(req[i].packet, buffer, size),
    173                "contents");
    174     }
    175   }
    176 
    177   for(i = 0; i < CURL_ARRAYSIZE(resp); i++) {
    178     struct dohentry d;
    179     DOHcode rc;
    180     char *ptr;
    181     size_t len;
    182     int u;
    183     de_init(&d);
    184     rc = doh_resp_decode((const unsigned char *)resp[i].packet, resp[i].size,
    185                          resp[i].type, &d);
    186     if(rc != resp[i].rc) {
    187       curl_mfprintf(stderr, "resp %zu: Expected return code %d got %d\n", i,
    188                     resp[i].rc, rc);
    189       abort_if(rc != resp[i].rc, "return code");
    190     }
    191     len = sizeof(buffer);
    192     ptr = (char *)buffer;
    193     for(u = 0; u < d.numaddr; u++) {
    194       size_t o;
    195       struct dohaddr *a;
    196       a = &d.addr[u];
    197       if(resp[i].type == DNS_TYPE_A) {
    198         p = &a->ip.v4[0];
    199         curl_msnprintf(ptr, len, "%u.%u.%u.%u ", p[0], p[1], p[2], p[3]);
    200         o = strlen(ptr);
    201         len -= o;
    202         ptr += o;
    203       }
    204       else {
    205         int j;
    206         for(j = 0; j < 16; j += 2) {
    207           size_t l;
    208           curl_msnprintf(ptr, len, "%s%02x%02x", j?":":"", a->ip.v6[j],
    209                          a->ip.v6[j + 1]);
    210           l = strlen(ptr);
    211           len -= l;
    212           ptr += l;
    213         }
    214         curl_msnprintf(ptr, len, " ");
    215         len--;
    216         ptr++;
    217       }
    218     }
    219     for(u = 0; u < d.numcname; u++) {
    220       size_t o;
    221       curl_msnprintf(ptr, len, "%s ", curlx_dyn_ptr(&d.cname[u]));
    222       o = strlen(ptr);
    223       len -= o;
    224       ptr += o;
    225     }
    226     de_cleanup(&d);
    227     if(resp[i].out && strcmp((char *)buffer, resp[i].out)) {
    228       curl_mfprintf(stderr, "resp %zu: Expected %s got %s\n", i,
    229                     resp[i].out, buffer);
    230       abort_if(resp[i].out && strcmp((char *)buffer, resp[i].out), "content");
    231     }
    232   }
    233 
    234   /* pass all sizes into the decoder until full */
    235   for(i = 0; i < sizeof(full49)-1; i++) {
    236     struct dohentry d;
    237     DOHcode rc;
    238     memset(&d, 0, sizeof(d));
    239     rc = doh_resp_decode((const unsigned char *)full49, i, DNS_TYPE_A, &d);
    240     if(!rc) {
    241       /* none of them should work */
    242       curl_mfprintf(stderr, "%zu: %d\n", i, rc);
    243       abort_if(!rc, "error rc");
    244     }
    245   }
    246 
    247   /* and try all pieces from the other end of the packet */
    248   for(i = 1; i < sizeof(full49); i++) {
    249     struct dohentry d;
    250     DOHcode rc;
    251     memset(&d, 0, sizeof(d));
    252     rc = doh_resp_decode((const unsigned char *)&full49[i], sizeof(full49)-i-1,
    253                          DNS_TYPE_A, &d);
    254     if(!rc) {
    255       /* none of them should work */
    256       curl_mfprintf(stderr, "2 %zu: %d\n", i, rc);
    257       abort_if(!rc, "error rc");
    258     }
    259   }
    260 
    261   {
    262     DOHcode rc;
    263     struct dohentry d;
    264     struct dohaddr *a;
    265     memset(&d, 0, sizeof(d));
    266     rc = doh_resp_decode((const unsigned char *)full49, sizeof(full49)-1,
    267                          DNS_TYPE_A, &d);
    268     fail_if(d.numaddr != 1, "missing address");
    269     a = &d.addr[0];
    270     p = &a->ip.v4[0];
    271     curl_msnprintf((char *)buffer, sizeof(buffer),
    272                    "%u.%u.%u.%u", p[0], p[1], p[2], p[3]);
    273     if(rc || strcmp((char *)buffer, "127.0.0.1")) {
    274       curl_mfprintf(stderr, "bad address decoded: %s, rc == %d\n", buffer, rc);
    275       abort_if(rc || strcmp((char *)buffer, "127.0.0.1"), "bad address");
    276     }
    277     fail_if(d.numcname, "bad cname counter");
    278   }
    279 #endif
    280 
    281   UNITTEST_END_SIMPLE
    282 }