]>
Commit | Line | Data |
---|---|---|
1fc9ac36 SS |
1 | From 19809fe6154ea0471a2c4fa3bd66787facf7704a Mon Sep 17 00:00:00 2001 |
2 | From: Tomas Hozza <thozza@redhat.com> | |
3 | Date: Mon, 26 May 2014 15:25:34 +0200 | |
4 | Subject: [PATCH] Use libidn instead of bundled idnkit | |
5 | ||
6 | Signed-off-by: Tomas Hozza <thozza@redhat.com> | |
7 | --- | |
8 | bin/dig/Makefile.in | 6 +- | |
9 | bin/dig/dig.docbook | 4 +- | |
10 | bin/dig/dighost.c | 168 ++++++++++++++++++++++++++++++++++++++++++++++++---- | |
11 | 3 files changed, 162 insertions(+), 16 deletions(-) | |
12 | ||
13 | diff --git a/bin/dig/Makefile.in b/bin/dig/Makefile.in | |
14 | index 5bc4db0..3864e06 100644 | |
15 | --- a/bin/dig/Makefile.in | |
16 | +++ b/bin/dig/Makefile.in | |
17 | @@ -48,10 +48,10 @@ DEPLIBS = ${DNSDEPLIBS} ${BIND9DEPLIBS} ${ISCDEPLIBS} ${ISCCFGDEPLIBS} \ | |
18 | ${LWRESDEPLIBS} | |
19 | ||
20 | LIBS = ${LWRESLIBS} ${DNSLIBS} ${BIND9LIBS} ${ISCCFGLIBS} \ | |
21 | - ${ISCLIBS} @IDNLIBS@ @LIBS@ | |
22 | + ${ISCLIBS} @IDNLIBS@ @LIBS@ -lidn | |
23 | ||
24 | NOSYMLIBS = ${LWRESLIBS} ${DNSLIBS} ${BIND9LIBS} ${ISCCFGLIBS} \ | |
25 | - ${ISCNOSYMLIBS} @IDNLIBS@ @LIBS@ | |
26 | + ${ISCNOSYMLIBS} @IDNLIBS@ @LIBS@ -lidn | |
27 | ||
28 | SUBDIRS = | |
29 | ||
30 | @@ -69,6 +69,8 @@ HTMLPAGES = dig.html host.html nslookup.html | |
31 | ||
32 | MANOBJS = ${MANPAGES} ${HTMLPAGES} | |
33 | ||
34 | +EXT_CFLAGS = -DWITH_LIBIDN | |
35 | + | |
36 | @BIND9_MAKE_RULES@ | |
37 | ||
38 | dig@EXEEXT@: dig.@O@ dighost.@O@ ${UOBJS} ${DEPLIBS} | |
39 | diff --git a/bin/dig/dig.docbook b/bin/dig/dig.docbook | |
40 | index 7a01ec0..c3a7976 100644 | |
41 | --- a/bin/dig/dig.docbook | |
42 | +++ b/bin/dig/dig.docbook | |
43 | @@ -970,8 +970,8 @@ dig +qr www.isc.org any -x 127.0.0.1 isc.org ns +noqr | |
44 | <command>dig</command> appropriately converts character encoding of | |
45 | domain name before sending a request to DNS server or displaying a | |
46 | reply from the server. | |
47 | - If you'd like to turn off the IDN support for some reason, defines | |
48 | - the <envar>IDN_DISABLE</envar> environment variable. | |
49 | + If you'd like to turn off the IDN support for some reason, define | |
50 | + the <envar>CHARSET=ASCII</envar> environment variable. | |
51 | The IDN support is disabled if the variable is set when | |
52 | <command>dig</command> runs. | |
53 | </para> | |
54 | diff --git a/bin/dig/dighost.c b/bin/dig/dighost.c | |
55 | index 56d763c..5a40051 100644 | |
56 | --- a/bin/dig/dighost.c | |
57 | +++ b/bin/dig/dighost.c | |
58 | @@ -44,6 +44,11 @@ | |
59 | #include <idn/api.h> | |
60 | #endif | |
61 | ||
62 | +#ifdef WITH_LIBIDN | |
63 | +#include <stringprep.h> | |
64 | +#include <idna.h> | |
65 | +#endif | |
66 | + | |
67 | #include <dns/byaddr.h> | |
68 | #ifdef DIG_SIGCHASE | |
69 | #include <dns/callbacks.h> | |
70 | @@ -158,6 +163,14 @@ static void idn_check_result(idn_result_t r, const char *msg); | |
71 | int idnoptions = 0; | |
72 | #endif | |
73 | ||
74 | +#ifdef WITH_LIBIDN | |
75 | +static isc_result_t libidn_locale_to_utf8 (const char* from, char *to); | |
76 | +static isc_result_t libidn_utf8_to_ascii (const char* from, char *to); | |
77 | +static isc_result_t output_filter (isc_buffer_t *buffer, | |
78 | + unsigned int used_org, | |
79 | + isc_boolean_t absolute); | |
80 | +#endif | |
81 | + | |
82 | isc_socket_t *keep = NULL; | |
83 | isc_sockaddr_t keepaddr; | |
84 | ||
85 | @@ -1210,6 +1223,9 @@ setup_system(void) { | |
86 | dig_searchlist_t *domain = NULL; | |
87 | lwres_result_t lwresult; | |
88 | unsigned int lwresflags; | |
89 | +#ifdef WITH_LIBIDN | |
90 | + isc_result_t result; | |
91 | +#endif | |
92 | ||
93 | debug("setup_system()"); | |
94 | ||
95 | @@ -1268,8 +1284,15 @@ setup_system(void) { | |
96 | ||
97 | #ifdef WITH_IDN | |
98 | initialize_idn(); | |
99 | + | |
100 | +#endif | |
101 | +#ifdef WITH_LIBIDN | |
102 | + result = dns_name_settotextfilter(output_filter); | |
103 | + check_result(result, "dns_name_settotextfilter"); | |
104 | +#ifdef HAVE_SETLOCALE | |
105 | + setlocale (LC_ALL, ""); | |
106 | +#endif | |
107 | #endif | |
108 | - | |
109 | if (keyfile[0] != 0) | |
110 | setup_file_key(); | |
111 | else if (keysecret[0] != 0) | |
112 | @@ -2028,12 +2051,14 @@ setup_lookup(dig_lookup_t *lookup) { | |
113 | idn_result_t mr; | |
114 | char utf8_textname[MXNAME], utf8_origin[MXNAME], idn_textname[MXNAME]; | |
115 | #endif | |
116 | +#ifdef WITH_LIBIDN | |
117 | + char utf8_str[MXNAME], utf8_name[MXNAME], ascii_name[MXNAME]; | |
118 | +#endif | |
119 | ||
120 | -#ifdef WITH_IDN | |
121 | +#if defined (WITH_IDN) || defined (WITH_LIBIDN) | |
122 | result = dns_name_settotextfilter(output_filter); | |
123 | check_result(result, "dns_name_settotextfilter"); | |
124 | #endif | |
125 | - | |
126 | REQUIRE(lookup != NULL); | |
127 | INSIST(!free_now); | |
128 | ||
129 | @@ -2070,6 +2095,14 @@ setup_lookup(dig_lookup_t *lookup) { | |
130 | mr = idn_encodename(IDN_LOCALCONV | IDN_DELIMMAP, lookup->textname, | |
131 | utf8_textname, sizeof(utf8_textname)); | |
132 | idn_check_result(mr, "convert textname to UTF-8"); | |
133 | +#elif defined (WITH_LIBIDN) | |
134 | + result = libidn_locale_to_utf8 (lookup->textname, utf8_str); | |
135 | + check_result (result, "convert textname to UTF-8"); | |
136 | + len = strlen (utf8_str); | |
137 | + if (len < MXNAME) | |
138 | + (void) strcpy (utf8_name, utf8_str); | |
139 | + else | |
140 | + fatal ("Too long name"); | |
141 | #endif | |
142 | ||
143 | /* | |
144 | @@ -2082,15 +2115,11 @@ setup_lookup(dig_lookup_t *lookup) { | |
145 | if (lookup->new_search) { | |
146 | #ifdef WITH_IDN | |
147 | if ((count_dots(utf8_textname) >= ndots) || !usesearch) { | |
148 | - lookup->origin = NULL; /* Force abs lookup */ | |
149 | - lookup->done_as_is = ISC_TRUE; | |
150 | - lookup->need_search = usesearch; | |
151 | - } else if (lookup->origin == NULL && usesearch) { | |
152 | - lookup->origin = ISC_LIST_HEAD(search_list); | |
153 | - lookup->need_search = ISC_FALSE; | |
154 | - } | |
155 | +#elif defined (WITH_LIBIDN) | |
156 | + if ((count_dots(utf8_name) >= ndots) || !usesearch) { | |
157 | #else | |
158 | if ((count_dots(lookup->textname) >= ndots) || !usesearch) { | |
159 | +#endif | |
160 | lookup->origin = NULL; /* Force abs lookup */ | |
161 | lookup->done_as_is = ISC_TRUE; | |
162 | lookup->need_search = usesearch; | |
163 | @@ -2098,7 +2127,6 @@ setup_lookup(dig_lookup_t *lookup) { | |
164 | lookup->origin = ISC_LIST_HEAD(search_list); | |
165 | lookup->need_search = ISC_FALSE; | |
166 | } | |
167 | -#endif | |
168 | } | |
169 | ||
170 | #ifdef WITH_IDN | |
171 | @@ -2115,6 +2143,20 @@ setup_lookup(dig_lookup_t *lookup) { | |
172 | IDN_IDNCONV | IDN_LENCHECK, utf8_textname, | |
173 | idn_textname, sizeof(idn_textname)); | |
174 | idn_check_result(mr, "convert UTF-8 textname to IDN encoding"); | |
175 | +#elif defined (WITH_LIBIDN) | |
176 | + if (lookup->origin != NULL) { | |
177 | + result = libidn_locale_to_utf8 (lookup->origin->origin, utf8_str); | |
178 | + check_result (result, "convert origin to UTF-8"); | |
179 | + if (len > 0 && utf8_name[len - 1] != '.') { | |
180 | + utf8_name[len++] = '.'; | |
181 | + if (len + strlen (utf8_str) < MXNAME) | |
182 | + (void) strcpy (utf8_name + len, utf8_str); | |
183 | + else | |
184 | + fatal ("Too long name + origin"); | |
185 | + } | |
186 | + } | |
187 | + | |
188 | + result = libidn_utf8_to_ascii (utf8_name, ascii_name); | |
189 | #else | |
190 | if (lookup->origin != NULL) { | |
191 | debug("trying origin %s", lookup->origin->origin); | |
192 | @@ -2170,6 +2212,13 @@ setup_lookup(dig_lookup_t *lookup) { | |
193 | result = dns_name_fromtext(lookup->name, &b, | |
194 | dns_rootname, 0, | |
195 | &lookup->namebuf); | |
196 | +#elif defined (WITH_LIBIDN) | |
197 | + len = strlen (ascii_name); | |
198 | + isc_buffer_init(&b, ascii_name, len); | |
199 | + isc_buffer_add(&b, len); | |
200 | + result = dns_name_fromtext(lookup->name, &b, | |
201 | + dns_rootname, 0, | |
202 | + &lookup->namebuf); | |
203 | #else | |
204 | len = strlen(lookup->textname); | |
205 | isc_buffer_init(&b, lookup->textname, len); | |
206 | @@ -3788,7 +3837,7 @@ destroy_libs(void) { | |
207 | void * ptr; | |
208 | dig_message_t *chase_msg; | |
209 | #endif | |
210 | -#ifdef WITH_IDN | |
211 | +#if defined (WITH_IDN) || defined (WITH_LIBIDN) | |
212 | isc_result_t result; | |
213 | #endif | |
214 | ||
215 | @@ -3829,6 +3878,10 @@ destroy_libs(void) { | |
216 | result = dns_name_settotextfilter(NULL); | |
217 | check_result(result, "dns_name_settotextfilter"); | |
218 | #endif | |
219 | +#ifdef WITH_LIBIDN | |
220 | + result = dns_name_settotextfilter (NULL); | |
221 | + check_result(result, "clearing dns_name_settotextfilter"); | |
222 | +#endif | |
223 | dns_name_destroy(); | |
224 | ||
225 | if (commctx != NULL) { | |
226 | @@ -4008,6 +4061,97 @@ idn_check_result(idn_result_t r, const char *msg) { | |
227 | } | |
228 | } | |
229 | #endif /* WITH_IDN */ | |
230 | +#ifdef WITH_LIBIDN | |
231 | +static isc_result_t | |
232 | +libidn_locale_to_utf8 (const char *from, char *to) { | |
233 | + char *utf8_str; | |
234 | + | |
235 | + debug ("libidn_locale_to_utf8"); | |
236 | + utf8_str = stringprep_locale_to_utf8 (from); | |
237 | + if (utf8_str != NULL) { | |
238 | + (void) strcpy (to, utf8_str); | |
239 | + free (utf8_str); | |
240 | + return ISC_R_SUCCESS; | |
241 | + } | |
242 | + | |
243 | + debug ("libidn_locale_to_utf8: failure"); | |
244 | + return ISC_R_FAILURE; | |
245 | +} | |
246 | +static isc_result_t | |
247 | +libidn_utf8_to_ascii (const char *from, char *to) { | |
248 | + char *ascii; | |
249 | + int iresult; | |
250 | + | |
251 | + debug ("libidn_utf8_to_ascii"); | |
252 | + iresult = idna_to_ascii_8z (from, &ascii, 0); | |
253 | + if (iresult != IDNA_SUCCESS) { | |
254 | + debug ("idna_to_ascii_8z: %s", idna_strerror (iresult)); | |
255 | + return ISC_R_FAILURE; | |
256 | + } | |
257 | + | |
258 | + (void) strcpy (to, ascii); | |
259 | + free (ascii); | |
260 | + return ISC_R_SUCCESS; | |
261 | +} | |
262 | + | |
263 | +static isc_result_t | |
264 | +output_filter (isc_buffer_t *buffer, unsigned int used_org, | |
265 | + isc_boolean_t absolute) { | |
266 | + | |
267 | + char tmp1[MXNAME], *tmp2; | |
268 | + size_t fromlen, tolen; | |
269 | + isc_boolean_t end_with_dot; | |
270 | + int iresult; | |
271 | + | |
272 | + debug ("output_filter"); | |
273 | + | |
274 | + fromlen = isc_buffer_usedlength (buffer) - used_org; | |
275 | + if (fromlen >= MXNAME) | |
276 | + return ISC_R_SUCCESS; | |
277 | + memcpy (tmp1, (char *) isc_buffer_base (buffer) + used_org, fromlen); | |
278 | + end_with_dot = (tmp1[fromlen - 1] == '.') ? ISC_TRUE : ISC_FALSE; | |
279 | + if (absolute && !end_with_dot) { | |
280 | + fromlen++; | |
281 | + if (fromlen >= MXNAME) | |
282 | + return ISC_R_SUCCESS; | |
283 | + tmp1[fromlen - 1] = '.'; | |
284 | + } | |
285 | + tmp1[fromlen] = '\0'; | |
286 | + | |
287 | + iresult = idna_to_unicode_8z8z (tmp1, &tmp2, 0); | |
288 | + if (iresult != IDNA_SUCCESS) { | |
289 | + debug ("output_filter: %s", idna_strerror (iresult)); | |
290 | + return ISC_R_SUCCESS; | |
291 | + } | |
292 | + | |
293 | + (void) strcpy (tmp1, tmp2); | |
294 | + free (tmp2); | |
295 | + | |
296 | + tmp2 = stringprep_utf8_to_locale (tmp1); | |
297 | + if (tmp2 == NULL) { | |
298 | + debug ("output_filter: stringprep_utf8_to_locale failed"); | |
299 | + return ISC_R_SUCCESS; | |
300 | + } | |
301 | + | |
302 | + (void) strcpy (tmp1, tmp2); | |
303 | + free (tmp2); | |
304 | + | |
305 | + tolen = strlen (tmp1); | |
306 | + if (absolute && !end_with_dot && tmp1[tolen - 1] == '.') | |
307 | + tolen--; | |
308 | + | |
309 | + if (isc_buffer_length (buffer) < used_org + tolen) | |
310 | + return ISC_R_NOSPACE; | |
311 | + | |
312 | + debug ("%s", tmp1); | |
313 | + | |
314 | + isc_buffer_subtract (buffer, isc_buffer_usedlength (buffer) - used_org); | |
315 | + memcpy (isc_buffer_used (buffer), tmp1, tolen); | |
316 | + isc_buffer_add (buffer, tolen); | |
317 | + | |
318 | + return ISC_R_SUCCESS; | |
319 | +} | |
320 | +#endif /* WITH_LIBIDN*/ | |
321 | ||
322 | #ifdef DIG_SIGCHASE | |
323 | void | |
324 | -- | |
325 | 1.9.0 | |
326 |