(root)/
glibc-2.38/
resolv/
res-name-checking.c
       1  /* Syntax checking for DNS domain names.
       2     Copyright (C) 1995-2023 Free Software Foundation, Inc.
       3     This file is part of the GNU C Library.
       4  
       5     The GNU C Library is free software; you can redistribute it and/or
       6     modify it under the terms of the GNU Lesser General Public
       7     License as published by the Free Software Foundation; either
       8     version 2.1 of the License, or (at your option) any later version.
       9  
      10     The GNU C Library is distributed in the hope that it will be useful,
      11     but WITHOUT ANY WARRANTY; without even the implied warranty of
      12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      13     Lesser General Public License for more details.
      14  
      15     You should have received a copy of the GNU Lesser General Public
      16     License along with the GNU C Library; if not, see
      17     <https://www.gnu.org/licenses/>.  */
      18  
      19  /*
      20   * Copyright (c) 1985, 1993
      21   *    The Regents of the University of California.  All rights reserved.
      22   *
      23   * Redistribution and use in source and binary forms, with or without
      24   * modification, are permitted provided that the following conditions
      25   * are met:
      26   * 1. Redistributions of source code must retain the above copyright
      27   *    notice, this list of conditions and the following disclaimer.
      28   * 2. Redistributions in binary form must reproduce the above copyright
      29   *    notice, this list of conditions and the following disclaimer in the
      30   *    documentation and/or other materials provided with the distribution.
      31   * 4. Neither the name of the University nor the names of its contributors
      32   *    may be used to endorse or promote products derived from this software
      33   *    without specific prior written permission.
      34   *
      35   * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
      36   * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
      37   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
      38   * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
      39   * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
      40   * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
      41   * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
      42   * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
      43   * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
      44   * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
      45   * SUCH DAMAGE.
      46   */
      47  
      48  /*
      49   * Portions Copyright (c) 1993 by Digital Equipment Corporation.
      50   *
      51   * Permission to use, copy, modify, and distribute this software for any
      52   * purpose with or without fee is hereby granted, provided that the above
      53   * copyright notice and this permission notice appear in all copies, and that
      54   * the name of Digital Equipment Corporation not be used in advertising or
      55   * publicity pertaining to distribution of the document or software without
      56   * specific, written prior permission.
      57   *
      58   * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
      59   * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
      60   * OF MERCHANTABILITY AND FITNESS.   IN NO EVENT SHALL DIGITAL EQUIPMENT
      61   * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
      62   * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
      63   * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
      64   * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
      65   * SOFTWARE.
      66   */
      67  
      68  /*
      69   * Portions Copyright (c) 1996-1999 by Internet Software Consortium.
      70   *
      71   * Permission to use, copy, modify, and distribute this software for any
      72   * purpose with or without fee is hereby granted, provided that the above
      73   * copyright notice and this permission notice appear in all copies.
      74   *
      75   * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
      76   * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
      77   * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
      78   * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
      79   * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
      80   * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
      81   * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
      82   * SOFTWARE.
      83   */
      84  
      85  #include <arpa/nameser.h>
      86  #include <resolv.h>
      87  #include <shlib-compat.h>
      88  
      89  /* Return true if the string consists of printable ASCII characters
      90     only.  */
      91  static bool
      92  printable_string (const char *dn)
      93  {
      94    while (true)
      95      {
      96        char ch = *dn;
      97        if (ch == '\0')
      98  	return true;
      99        if (ch <= ' ' || ch > '~')
     100  	return false;
     101        ++dn;
     102      }
     103  }
     104  
     105  /* Return true if DN points to a name consisting only of [0-9a-zA-Z_-]
     106     characters.  DN must be in DNS wire format, without
     107     compression.  */
     108  static bool
     109  binary_hnok (const unsigned char *dn)
     110  {
     111    while (true)
     112      {
     113        size_t label_length = *dn;
     114        if (label_length == 0)
     115  	break;
     116        ++dn;
     117        const unsigned char *label_end = dn + label_length;
     118        do
     119  	{
     120  	  unsigned char ch = *dn;
     121  	  if (!(('0' <= ch && ch <= '9')
     122  		|| ('A' <= ch && ch <= 'Z')
     123  		|| ('a' <= ch && ch <= 'z')
     124  		|| ch == '-' || ch == '_'))
     125  	    return false;
     126  	  ++dn;
     127  	}
     128        while (dn < label_end);
     129      }
     130    return true;
     131  }
     132  
     133  /* Return true if the binary domain name has a first labels which
     134     starts with '-'.  */
     135  static inline bool
     136  binary_leading_dash (const unsigned char *dn)
     137  {
     138    return dn[0] > 0 && dn[1] == '-';
     139  }
     140  
     141  bool
     142  __res_binary_hnok (const unsigned char *dn)
     143  {
     144    return !binary_leading_dash (dn) && binary_hnok (dn);
     145  }
     146  
     147  /* Return 1 if res_hnok is a valid host name.  Labels must only
     148     contain [0-9a-zA-Z_-] characters, and the name must not start with
     149     a '-'.  The latter is to avoid confusion with program options.  */
     150  int
     151  ___res_hnok (const char *dn)
     152  {
     153    unsigned char buf[NS_MAXCDNAME];
     154    return (printable_string (dn)
     155  	  && __ns_name_pton (dn, buf, sizeof (buf)) >= 0
     156  	  && __res_binary_hnok (buf));
     157  }
     158  versioned_symbol (libc, ___res_hnok, res_hnok, GLIBC_2_34);
     159  versioned_symbol (libc, ___res_hnok, __libc_res_hnok, GLIBC_PRIVATE);
     160  libc_hidden_ver (___res_hnok, __libc_res_hnok)
     161  #if OTHER_SHLIB_COMPAT (libresolv, GLIBC_2_0, GLIBC_2_34)
     162  compat_symbol (libresolv, ___res_hnok, __res_hnok, GLIBC_2_0);
     163  #endif
     164  
     165  /* Hostname-like (A, MX, WKS) owners can have "*" as their first label
     166     but must otherwise be as a host name.  */
     167  int
     168  ___res_ownok (const char *dn)
     169  {
     170    unsigned char buf[NS_MAXCDNAME];
     171    if (!printable_string (dn)
     172        || __ns_name_pton (dn, buf, sizeof (buf)) < 0
     173        || binary_leading_dash (buf))
     174      return 0;
     175    if (buf[0] == 1 && buf [1] == '*')
     176      /* Skip over the leading "*." part.  */
     177      return binary_hnok (buf + 2);
     178    else
     179      return binary_hnok (buf);
     180  }
     181  versioned_symbol (libc, ___res_ownok, res_ownok, GLIBC_2_34);
     182  #if OTHER_SHLIB_COMPAT (libresolv, GLIBC_2_0, GLIBC_2_34)
     183  compat_symbol (libresolv, ___res_ownok, __res_ownok, GLIBC_2_0);
     184  #endif
     185  
     186  /* SOA RNAMEs and RP RNAMEs can have any byte in their first label,
     187     but the rest of the name has to look like a host name.  */
     188  int
     189  ___res_mailok (const char *dn)
     190  {
     191    unsigned char buf[NS_MAXCDNAME];
     192    if (!printable_string (dn)
     193        || __ns_name_pton (dn, buf, sizeof (buf)) < 0)
     194      return 0;
     195    unsigned char label_length = buf[0];
     196    /* "." is a valid missing representation */
     197    if (label_length == 0)
     198      return 1;
     199    /* Skip over the first label.  */
     200    unsigned char *tail = buf + 1 + label_length;
     201    if (*tail == 0)
     202      /* More than one label is required (except for ".").  */
     203      return 0;
     204    return binary_hnok (tail);
     205  }
     206  versioned_symbol (libc, ___res_mailok, res_mailok, GLIBC_2_34);
     207  #if OTHER_SHLIB_COMPAT (libresolv, GLIBC_2_0, GLIBC_2_34)
     208  compat_symbol (libresolv, ___res_mailok, __res_mailok, GLIBC_2_0);
     209  #endif
     210  
     211  /* Return 1 if DN is a syntactically valid domain name.  Empty names
     212     are accepted.  */
     213  int
     214  ___res_dnok (const char *dn)
     215  {
     216    unsigned char buf[NS_MAXCDNAME];
     217    return printable_string (dn) && __ns_name_pton (dn, buf, sizeof (buf)) >= 0;
     218  }
     219  versioned_symbol (libc, ___res_dnok, res_dnok, GLIBC_2_34);
     220  versioned_symbol (libc, ___res_dnok, __libc_res_dnok, GLIBC_PRIVATE);
     221  libc_hidden_ver (___res_dnok, __libc_res_dnok)
     222  #if OTHER_SHLIB_COMPAT (libresolv, GLIBC_2_0, GLIBC_2_34)
     223  compat_symbol (libresolv, ___res_dnok, __res_dnok, GLIBC_2_0);
     224  #endif