LCOV - code coverage report
Current view: top level - resolve - dns-type.c (source / functions) Hit Total Coverage
Test: main_coverage.info Lines: 53 100 53.0 %
Date: 2019-08-22 15:41:25 Functions: 16 19 84.2 %

          Line data    Source code
       1             : /* SPDX-License-Identifier: LGPL-2.1+ */
       2             : 
       3             : #include <sys/socket.h>
       4             : #include <errno.h>
       5             : 
       6             : #include "dns-type.h"
       7             : #include "parse-util.h"
       8             : #include "string-util.h"
       9             : 
      10             : typedef const struct {
      11             :         uint16_t type;
      12             :         const char *name;
      13             : } dns_type;
      14             : 
      15             : static const struct dns_type_name *
      16             : lookup_dns_type (register const char *str, register GPERF_LEN_TYPE len);
      17             : 
      18             : #include "dns_type-from-name.h"
      19             : #include "dns_type-to-name.h"
      20             : 
      21       32772 : int dns_type_from_string(const char *s) {
      22             :         const struct dns_type_name *sc;
      23             : 
      24       32772 :         assert(s);
      25             : 
      26       32772 :         sc = lookup_dns_type(s, strlen(s));
      27       32772 :         if (sc)
      28          77 :                 return sc->id;
      29             : 
      30       32695 :         s = startswith_no_case(s, "TYPE");
      31       32695 :         if (s) {
      32             :                 unsigned x;
      33             : 
      34           0 :                 if (safe_atou(s, &x) >= 0 &&
      35           0 :                     x <= UINT16_MAX)
      36           0 :                         return (int) x;
      37             :         }
      38             : 
      39       32695 :         return _DNS_TYPE_INVALID;
      40             : }
      41             : 
      42         371 : bool dns_type_is_pseudo(uint16_t type) {
      43             : 
      44             :         /* Checks whether the specified type is a "pseudo-type". What
      45             :          * a "pseudo-type" precisely is, is defined only very weakly,
      46             :          * but apparently entails all RR types that are not actually
      47             :          * stored as RRs on the server and should hence also not be
      48             :          * cached. We use this list primarily to validate NSEC type
      49             :          * bitfields, and to verify what to cache. */
      50             : 
      51         371 :         return IN_SET(type,
      52             :                       0, /* A Pseudo RR type, according to RFC 2931 */
      53             :                       DNS_TYPE_ANY,
      54             :                       DNS_TYPE_AXFR,
      55             :                       DNS_TYPE_IXFR,
      56             :                       DNS_TYPE_OPT,
      57             :                       DNS_TYPE_TSIG,
      58             :                       DNS_TYPE_TKEY
      59             :         );
      60             : }
      61             : 
      62           2 : bool dns_class_is_pseudo(uint16_t class) {
      63           2 :         return class == DNS_TYPE_ANY;
      64             : }
      65             : 
      66          77 : bool dns_type_is_valid_query(uint16_t type) {
      67             : 
      68             :         /* The types valid as questions in packets */
      69             : 
      70          77 :         return !IN_SET(type,
      71             :                        0,
      72             :                        DNS_TYPE_OPT,
      73             :                        DNS_TYPE_TSIG,
      74             :                        DNS_TYPE_TKEY,
      75             : 
      76             :                        /* RRSIG are technically valid as questions, but we refuse doing explicit queries for them, as
      77             :                         * they aren't really payload, but signatures for payload, and cannot be validated on their
      78             :                         * own. After all they are the signatures, and have no signatures of their own validating
      79             :                         * them. */
      80             :                        DNS_TYPE_RRSIG);
      81             : }
      82             : 
      83           0 : bool dns_type_is_zone_transer(uint16_t type) {
      84             : 
      85             :         /* Zone transfers, either normal or incremental */
      86             : 
      87           0 :         return IN_SET(type,
      88             :                       DNS_TYPE_AXFR,
      89             :                       DNS_TYPE_IXFR);
      90             : }
      91             : 
      92         553 : bool dns_type_is_valid_rr(uint16_t type) {
      93             : 
      94             :         /* The types valid as RR in packets (but not necessarily
      95             :          * stored on servers). */
      96             : 
      97         553 :         return !IN_SET(type,
      98             :                        DNS_TYPE_ANY,
      99             :                        DNS_TYPE_AXFR,
     100             :                        DNS_TYPE_IXFR);
     101             : }
     102             : 
     103         478 : bool dns_class_is_valid_rr(uint16_t class) {
     104         478 :         return class != DNS_CLASS_ANY;
     105             : }
     106             : 
     107          77 : bool dns_type_may_redirect(uint16_t type) {
     108             :         /* The following record types should never be redirected using
     109             :          * CNAME/DNAME RRs. See
     110             :          * <https://tools.ietf.org/html/rfc4035#section-2.5>. */
     111             : 
     112          77 :         if (dns_type_is_pseudo(type))
     113           6 :                 return false;
     114             : 
     115          71 :         return !IN_SET(type,
     116             :                        DNS_TYPE_CNAME,
     117             :                        DNS_TYPE_DNAME,
     118             :                        DNS_TYPE_NSEC3,
     119             :                        DNS_TYPE_NSEC,
     120             :                        DNS_TYPE_RRSIG,
     121             :                        DNS_TYPE_NXT,
     122             :                        DNS_TYPE_SIG,
     123             :                        DNS_TYPE_KEY);
     124             : }
     125             : 
     126          77 : bool dns_type_may_wildcard(uint16_t type) {
     127             : 
     128             :         /* The following records may not be expanded from wildcard RRsets */
     129             : 
     130          77 :         if (dns_type_is_pseudo(type))
     131           6 :                 return false;
     132             : 
     133          71 :         return !IN_SET(type,
     134             :                        DNS_TYPE_NSEC3,
     135             :                        DNS_TYPE_SOA,
     136             : 
     137             :                        /* Prohibited by https://tools.ietf.org/html/rfc4592#section-4.4 */
     138             :                        DNS_TYPE_DNAME);
     139             : }
     140             : 
     141          81 : bool dns_type_apex_only(uint16_t type) {
     142             : 
     143             :         /* Returns true for all RR types that may only appear signed in a zone apex */
     144             : 
     145          81 :         return IN_SET(type,
     146             :                       DNS_TYPE_SOA,
     147             :                       DNS_TYPE_NS,            /* this one can appear elsewhere, too, but not signed */
     148             :                       DNS_TYPE_DNSKEY,
     149             :                       DNS_TYPE_NSEC3PARAM);
     150             : }
     151             : 
     152          77 : bool dns_type_is_dnssec(uint16_t type) {
     153          77 :         return IN_SET(type,
     154             :                       DNS_TYPE_DS,
     155             :                       DNS_TYPE_DNSKEY,
     156             :                       DNS_TYPE_RRSIG,
     157             :                       DNS_TYPE_NSEC,
     158             :                       DNS_TYPE_NSEC3,
     159             :                       DNS_TYPE_NSEC3PARAM);
     160             : }
     161             : 
     162          77 : bool dns_type_is_obsolete(uint16_t type) {
     163          77 :         return IN_SET(type,
     164             :                       /* Obsoleted by RFC 973 */
     165             :                       DNS_TYPE_MD,
     166             :                       DNS_TYPE_MF,
     167             :                       DNS_TYPE_MAILA,
     168             : 
     169             :                       /* Kinda obsoleted by RFC 2505 */
     170             :                       DNS_TYPE_MB,
     171             :                       DNS_TYPE_MG,
     172             :                       DNS_TYPE_MR,
     173             :                       DNS_TYPE_MINFO,
     174             :                       DNS_TYPE_MAILB,
     175             : 
     176             :                       /* RFC1127 kinda obsoleted this by recommending against its use */
     177             :                       DNS_TYPE_WKS,
     178             : 
     179             :                       /* Declared historical by RFC 6563 */
     180             :                       DNS_TYPE_A6,
     181             : 
     182             :                       /* Obsoleted by DNSSEC-bis */
     183             :                       DNS_TYPE_NXT,
     184             : 
     185             :                       /* RFC 1035 removed support for concepts that needed this from RFC 883 */
     186             :                       DNS_TYPE_NULL);
     187             : }
     188             : 
     189          77 : bool dns_type_needs_authentication(uint16_t type) {
     190             : 
     191             :         /* Returns true for all (non-obsolete) RR types where records are not useful if they aren't
     192             :          * authenticated. I.e. everything that contains crypto keys. */
     193             : 
     194          77 :         return IN_SET(type,
     195             :                       DNS_TYPE_CERT,
     196             :                       DNS_TYPE_SSHFP,
     197             :                       DNS_TYPE_IPSECKEY,
     198             :                       DNS_TYPE_DS,
     199             :                       DNS_TYPE_DNSKEY,
     200             :                       DNS_TYPE_TLSA,
     201             :                       DNS_TYPE_CDNSKEY,
     202             :                       DNS_TYPE_OPENPGPKEY,
     203             :                       DNS_TYPE_CAA);
     204             : }
     205             : 
     206           0 : int dns_type_to_af(uint16_t t) {
     207           0 :         switch (t) {
     208             : 
     209           0 :         case DNS_TYPE_A:
     210           0 :                 return AF_INET;
     211             : 
     212           0 :         case DNS_TYPE_AAAA:
     213           0 :                 return AF_INET6;
     214             : 
     215           0 :         case DNS_TYPE_ANY:
     216           0 :                 return AF_UNSPEC;
     217             : 
     218           0 :         default:
     219           0 :                 return -EINVAL;
     220             :         }
     221             : }
     222             : 
     223         988 : const char *dns_class_to_string(uint16_t class) {
     224             : 
     225         988 :         switch (class) {
     226             : 
     227         733 :         case DNS_CLASS_IN:
     228         733 :                 return "IN";
     229             : 
     230           1 :         case DNS_CLASS_ANY:
     231           1 :                 return "ANY";
     232             :         }
     233             : 
     234         254 :         return NULL;
     235             : }
     236             : 
     237           0 : int dns_class_from_string(const char *s) {
     238             : 
     239           0 :         if (!s)
     240           0 :                 return _DNS_CLASS_INVALID;
     241             : 
     242           0 :         if (strcaseeq(s, "IN"))
     243           0 :                 return DNS_CLASS_IN;
     244           0 :         else if (strcaseeq(s, "ANY"))
     245           0 :                 return DNS_CLASS_ANY;
     246             : 
     247           0 :         return _DNS_CLASS_INVALID;
     248             : }
     249             : 
     250           6 : const char* tlsa_cert_usage_to_string(uint8_t cert_usage) {
     251             : 
     252           6 :         switch (cert_usage) {
     253             : 
     254           6 :         case 0:
     255           6 :                 return "CA constraint";
     256             : 
     257           0 :         case 1:
     258           0 :                 return "Service certificate constraint";
     259             : 
     260           0 :         case 2:
     261           0 :                 return "Trust anchor assertion";
     262             : 
     263           0 :         case 3:
     264           0 :                 return "Domain-issued certificate";
     265             : 
     266           0 :         case 4 ... 254:
     267           0 :                 return "Unassigned";
     268             : 
     269           0 :         case 255:
     270           0 :                 return "Private use";
     271             :         }
     272             : 
     273             :         return NULL;  /* clang cannot count that we covered everything */
     274             : }
     275             : 
     276           6 : const char* tlsa_selector_to_string(uint8_t selector) {
     277           6 :         switch (selector) {
     278             : 
     279           6 :         case 0:
     280           6 :                 return "Full Certificate";
     281             : 
     282           0 :         case 1:
     283           0 :                 return "SubjectPublicKeyInfo";
     284             : 
     285           0 :         case 2 ... 254:
     286           0 :                 return "Unassigned";
     287             : 
     288           0 :         case 255:
     289           0 :                 return "Private use";
     290             :         }
     291             : 
     292             :         return NULL;
     293             : }
     294             : 
     295           6 : const char* tlsa_matching_type_to_string(uint8_t selector) {
     296             : 
     297           6 :         switch (selector) {
     298             : 
     299           0 :         case 0:
     300           0 :                 return "No hash used";
     301             : 
     302           6 :         case 1:
     303           6 :                 return "SHA-256";
     304             : 
     305           0 :         case 2:
     306           0 :                 return "SHA-512";
     307             : 
     308           0 :         case 3 ... 254:
     309           0 :                 return "Unassigned";
     310             : 
     311           0 :         case 255:
     312           0 :                 return "Private use";
     313             :         }
     314             : 
     315             :         return NULL;
     316             : }

Generated by: LCOV version 1.14