1 /* Test getaddrinfo and getnameinfo without usable libidn2.
2 Copyright (C) 2018-2022 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 #define TEST_USE_UTF8 1
20 #include "tst-resolv-ai_idn-common.c"
21
22 #include <locale.h>
23 #include <support/xdlfcn.h>
24
25 /* Tests for getaddrinfo. */
26 static void
gai_tests(void)27 gai_tests (void)
28 {
29 /* No CNAME. */
30 check_ai ("non-idn.example", 0,
31 "address: STREAM/TCP 192.0.2.110 80\n");
32 check_ai ("non-idn.example", AI_IDN,
33 "flags: AI_IDN\n"
34 "address: STREAM/TCP 192.0.2.110 80\n");
35 check_ai ("non-idn.example", AI_IDN | AI_CANONNAME | AI_CANONIDN,
36 "flags: AI_CANONNAME AI_IDN AI_CANONIDN\n"
37 "canonname: non-idn.example\n"
38 "address: STREAM/TCP 192.0.2.110 80\n");
39
40 /* This gets passed over the network to the server, so it will
41 result in an NXDOMAIN error. */
42 check_ai (NAEMCHEN ".example", 0,
43 "error: Name or service not known\n");
44 /* Due to missing libidn2, this fails inside getaddrinfo. */
45 check_ai (NAEMCHEN ".example", AI_IDN,
46 "error: Parameter string not correctly encoded\n");
47 check_ai (NAEMCHEN ".example", AI_IDN | AI_CANONNAME | AI_CANONIDN,
48 "error: Parameter string not correctly encoded\n");
49
50 /* Non-IDN CNAME. */
51 check_ai ("with.cname.example", 0,
52 "address: STREAM/TCP 192.0.2.119 80\n");
53 check_ai ("with.cname.example", AI_IDN,
54 "flags: AI_IDN\n"
55 "address: STREAM/TCP 192.0.2.119 80\n");
56 check_ai ("with.cname.example", AI_IDN | AI_CANONNAME | AI_CANONIDN,
57 "flags: AI_CANONNAME AI_IDN AI_CANONIDN\n"
58 "canonname: non-idn-cname.example\n"
59 "address: STREAM/TCP 192.0.2.119 80\n");
60
61 /* IDN CNAME. */
62 check_ai ("With.idn-cname.example", 0,
63 "address: STREAM/TCP 192.0.2.87 80\n");
64 check_ai ("With.idn-cname.example", AI_IDN,
65 "flags: AI_IDN\n"
66 "address: STREAM/TCP 192.0.2.87 80\n");
67 check_ai ("With.idn-cname.example", AI_IDN | AI_CANONNAME,
68 "flags: AI_CANONNAME AI_IDN\n"
69 "canonname: " ANDERES_NAEMCHEN_IDNA ".example\n"
70 "address: STREAM/TCP 192.0.2.87 80\n");
71 check_ai ("With.idn-cname.example",
72 AI_IDN | AI_CANONNAME | AI_CANONIDN,
73 "flags: AI_CANONNAME AI_IDN AI_CANONIDN\n"
74 "canonname: " ANDERES_NAEMCHEN_IDNA ".example\n"
75 "address: STREAM/TCP 192.0.2.87 80\n");
76
77 /* Non-IDN to IDN CNAME chain. */
78 check_ai ("both.cname.idn-cname.example", 0,
79 "address: STREAM/TCP 192.0.2.98 80\n");
80 check_ai ("both.cname.idn-cname.example", AI_IDN,
81 "flags: AI_IDN\n"
82 "address: STREAM/TCP 192.0.2.98 80\n");
83 check_ai ("both.cname.idn-cname.example", AI_IDN | AI_CANONNAME,
84 "flags: AI_CANONNAME AI_IDN\n"
85 "canonname: " ANDERES_NAEMCHEN_IDNA ".example\n"
86 "address: STREAM/TCP 192.0.2.98 80\n");
87 check_ai ("both.cname.idn-cname.example",
88 AI_IDN | AI_CANONNAME | AI_CANONIDN,
89 "flags: AI_CANONNAME AI_IDN AI_CANONIDN\n"
90 "canonname: " ANDERES_NAEMCHEN_IDNA ".example\n"
91 "address: STREAM/TCP 192.0.2.98 80\n");
92 }
93
94 /* Tests for getnameinfo. */
95 static void
gni_tests(void)96 gni_tests (void)
97 {
98 /* All non-IDN an IDN results are the same due to lack of libidn2
99 support. */
100 for (int do_ni_idn = 0; do_ni_idn < 2; ++do_ni_idn)
101 {
102 int flags = 0;
103 if (do_ni_idn)
104 flags |= NI_IDN;
105
106 gni_test (gni_non_idn_name, flags, "non-idn.example");
107 gni_test (gni_non_idn_name, flags | NI_NUMERICHOST, "192.0.2.0");
108 gni_test (gni_non_idn_cname_to_non_idn_name, flags,
109 "non-idn-name.example");
110 gni_test (gni_non_idn_cname_to_idn_name, flags,
111 NAEMCHEN_IDNA ".example");
112 gni_test (gni_idn_name, flags, NAEMCHEN_IDNA ".example");
113 gni_test (gni_idn_cname_to_non_idn_name, flags, "non-idn-name.example");
114 gni_test (gni_idn_cname_to_idn_name, flags,
115 ANDERES_NAEMCHEN_IDNA ".example");
116
117 /* Test encoding errors. */
118 gni_test (gni_invalid_idn_1, flags, "xn---.example");
119 gni_test (gni_invalid_idn_2, flags, "xn--x.example");
120 }
121 }
122
123 static int
do_test(void)124 do_test (void)
125 {
126 void *handle = xdlopen ("tst-no-libidn2.so", RTLD_LAZY);
127 {
128 /* Verify that this replaced libidn2. */
129 void *handle2 = xdlopen (LIBIDN2_SONAME, RTLD_LAZY | RTLD_NOLOAD);
130 TEST_VERIFY (handle2 == handle);
131 xdlclose (handle2);
132 }
133
134 if (setlocale (LC_CTYPE, "en_US.UTF-8") == NULL)
135 FAIL_EXIT1 ("setlocale: %m");
136
137 struct resolv_test *aux = resolv_test_start
138 ((struct resolv_redirect_config)
139 {
140 .response_callback = response,
141 });
142
143 gai_tests ();
144 gni_tests ();
145
146 resolv_test_end (aux);
147 xdlclose (handle);
148 return 0;
149 }
150
151 #include <support/test-driver.c>
152