diff options
Diffstat (limited to 'meta/packages/tcp-wrappers/tcp-wrappers-7.6/10_usagi-ipv6.patch')
-rw-r--r-- | meta/packages/tcp-wrappers/tcp-wrappers-7.6/10_usagi-ipv6.patch | 1253 |
1 files changed, 1253 insertions, 0 deletions
diff --git a/meta/packages/tcp-wrappers/tcp-wrappers-7.6/10_usagi-ipv6.patch b/meta/packages/tcp-wrappers/tcp-wrappers-7.6/10_usagi-ipv6.patch new file mode 100644 index 0000000000..5c8be5c27c --- /dev/null +++ b/meta/packages/tcp-wrappers/tcp-wrappers-7.6/10_usagi-ipv6.patch | |||
@@ -0,0 +1,1253 @@ | |||
1 | diff -ruN tcp_wrappers_7.6.orig/fix_options.c tcp_wrappers_7.6/fix_options.c | ||
2 | --- tcp_wrappers_7.6.orig/fix_options.c 1997-04-08 02:29:19.000000000 +0200 | ||
3 | +++ tcp_wrappers_7.6/fix_options.c 2004-04-10 19:07:43.000000000 +0200 | ||
4 | @@ -11,6 +11,9 @@ | ||
5 | |||
6 | #include <sys/types.h> | ||
7 | #include <sys/param.h> | ||
8 | +#ifdef INET6 | ||
9 | +#include <sys/socket.h> | ||
10 | +#endif | ||
11 | #include <netinet/in.h> | ||
12 | #include <netinet/in_systm.h> | ||
13 | #include <netinet/ip.h> | ||
14 | @@ -41,6 +44,22 @@ | ||
15 | unsigned int opt; | ||
16 | int optlen; | ||
17 | struct in_addr dummy; | ||
18 | +#ifdef INET6 | ||
19 | + struct sockaddr_storage ss; | ||
20 | + int sslen; | ||
21 | + | ||
22 | + /* | ||
23 | + * check if this is AF_INET socket | ||
24 | + * XXX IPv6 support? | ||
25 | + */ | ||
26 | + sslen = sizeof(ss); | ||
27 | + if (getsockname(fd, (struct sockaddr *)&ss, &sslen) < 0) { | ||
28 | + syslog(LOG_ERR, "getpeername: %m"); | ||
29 | + clean_exit(request); | ||
30 | + } | ||
31 | + if (ss.ss_family != AF_INET) | ||
32 | + return; | ||
33 | +#endif | ||
34 | |||
35 | if ((ip = getprotobyname("ip")) != 0) | ||
36 | ipproto = ip->p_proto; | ||
37 | diff -ruN tcp_wrappers_7.6.orig/hosts_access.5 tcp_wrappers_7.6/hosts_access.5 | ||
38 | --- tcp_wrappers_7.6.orig/hosts_access.5 2004-04-10 19:22:58.000000000 +0200 | ||
39 | +++ tcp_wrappers_7.6/hosts_access.5 2004-04-10 19:07:43.000000000 +0200 | ||
40 | @@ -85,11 +85,18 @@ | ||
41 | for daemon process names or for client user names. | ||
42 | .IP \(bu | ||
43 | An expression of the form `n.n.n.n/m.m.m.m\' is interpreted as a | ||
44 | -`net/mask\' pair. A host address is matched if `net\' is equal to the | ||
45 | +`net/mask\' pair. An IPv4 host address is matched if `net\' is equal to the | ||
46 | bitwise AND of the address and the `mask\'. For example, the net/mask | ||
47 | pattern `131.155.72.0/255.255.254.0\' matches every address in the | ||
48 | range `131.155.72.0\' through `131.155.73.255\'. | ||
49 | .IP \(bu | ||
50 | +An expression of the form `[n:n:n:n:n:n:n:n]/m\' is interpreted as a | ||
51 | +`[net]/prefixlen\' pair. An IPv6 host address is matched if | ||
52 | +`prefixlen\' bits of `net\' is equal to the `prefixlen\' bits of the | ||
53 | +address. For example, the [net]/prefixlen pattern | ||
54 | +`[3ffe:505:2:1::]/64\' matches every address in the range | ||
55 | +`3ffe:505:2:1::\' through `3ffe:505:2:1:ffff:ffff:ffff:ffff\'. | ||
56 | +.IP \(bu | ||
57 | Wildcards `*\' and `?\' can be used to match hostnames or IP addresses. This | ||
58 | method of matching cannot be used in conjunction with `net/mask\' matching, | ||
59 | hostname matching beginning with `.\' or IP address matching ending with `.\'. | ||
60 | diff -ruN tcp_wrappers_7.6.orig/hosts_access.c tcp_wrappers_7.6/hosts_access.c | ||
61 | --- tcp_wrappers_7.6.orig/hosts_access.c 2004-04-10 19:22:58.000000000 +0200 | ||
62 | +++ tcp_wrappers_7.6/hosts_access.c 2004-04-10 19:07:43.000000000 +0200 | ||
63 | @@ -24,7 +24,13 @@ | ||
64 | /* System libraries. */ | ||
65 | |||
66 | #include <sys/types.h> | ||
67 | +#ifdef INT32_T | ||
68 | + typedef uint32_t u_int32_t; | ||
69 | +#endif | ||
70 | #include <sys/param.h> | ||
71 | +#ifdef INET6 | ||
72 | +#include <sys/socket.h> | ||
73 | +#endif | ||
74 | #include <netinet/in.h> | ||
75 | #include <arpa/inet.h> | ||
76 | #include <stdio.h> | ||
77 | @@ -33,6 +39,9 @@ | ||
78 | #include <errno.h> | ||
79 | #include <setjmp.h> | ||
80 | #include <string.h> | ||
81 | +#ifdef INET6 | ||
82 | +#include <netdb.h> | ||
83 | +#endif | ||
84 | |||
85 | extern char *fgets(); | ||
86 | extern int errno; | ||
87 | @@ -82,6 +91,10 @@ | ||
88 | static int host_match(); | ||
89 | static int string_match(); | ||
90 | static int masked_match(); | ||
91 | +#ifdef INET6 | ||
92 | +static int masked_match4(); | ||
93 | +static int masked_match6(); | ||
94 | +#endif | ||
95 | |||
96 | /* Size of logical line buffer. */ | ||
97 | |||
98 | @@ -289,6 +302,13 @@ | ||
99 | { | ||
100 | int n; | ||
101 | |||
102 | +#ifdef INET6 | ||
103 | + /* convert IPv4 mapped IPv6 address to IPv4 address */ | ||
104 | + if (STRN_EQ(string, "::ffff:", 7) | ||
105 | + && dot_quad_addr(string + 7) != INADDR_NONE) { | ||
106 | + string += 7; | ||
107 | + } | ||
108 | +#endif | ||
109 | #ifndef DISABLE_WILDCARD_MATCHING | ||
110 | if (strchr(tok, '*') || strchr(tok,'?')) { /* contains '*' or '?' */ | ||
111 | return (match_pattern_ylo(string,tok)); | ||
112 | @@ -304,20 +324,72 @@ | ||
113 | } else if (tok[(n = strlen(tok)) - 1] == '.') { /* prefix */ | ||
114 | return (STRN_EQ(tok, string, n)); | ||
115 | } else { /* exact match */ | ||
116 | +#ifdef INET6 | ||
117 | + struct addrinfo hints, *res; | ||
118 | + struct sockaddr_in6 pat, addr; | ||
119 | + int len, ret; | ||
120 | + char ch; | ||
121 | + | ||
122 | + len = strlen(tok); | ||
123 | + if (*tok == '[' && tok[len - 1] == ']') { | ||
124 | + ch = tok[len - 1]; | ||
125 | + tok[len - 1] = '\0'; | ||
126 | + memset(&hints, 0, sizeof(hints)); | ||
127 | + hints.ai_family = AF_INET6; | ||
128 | + hints.ai_socktype = SOCK_STREAM; | ||
129 | + hints.ai_flags = AI_PASSIVE | AI_NUMERICHOST; | ||
130 | + if ((ret = getaddrinfo(tok + 1, NULL, &hints, &res)) == 0) { | ||
131 | + memcpy(&pat, res->ai_addr, sizeof(pat)); | ||
132 | + freeaddrinfo(res); | ||
133 | + } | ||
134 | + tok[len - 1] = ch; | ||
135 | + if (ret != 0 || getaddrinfo(string, NULL, &hints, &res) != 0) | ||
136 | + return NO; | ||
137 | + memcpy(&addr, res->ai_addr, sizeof(addr)); | ||
138 | + freeaddrinfo(res); | ||
139 | +#ifdef NI_WITHSCOPEID | ||
140 | + if (pat.sin6_scope_id != 0 && | ||
141 | + addr.sin6_scope_id != pat.sin6_scope_id) | ||
142 | + return NO; | ||
143 | +#endif | ||
144 | + return (!memcmp(&pat.sin6_addr, &addr.sin6_addr, | ||
145 | + sizeof(struct in6_addr))); | ||
146 | + return (ret); | ||
147 | + } | ||
148 | +#endif | ||
149 | return (STR_EQ(tok, string)); | ||
150 | } | ||
151 | } | ||
152 | |||
153 | /* masked_match - match address against netnumber/netmask */ | ||
154 | |||
155 | +#ifdef INET6 | ||
156 | static int masked_match(net_tok, mask_tok, string) | ||
157 | char *net_tok; | ||
158 | char *mask_tok; | ||
159 | char *string; | ||
160 | { | ||
161 | + return (masked_match4(net_tok, mask_tok, string) || | ||
162 | + masked_match6(net_tok, mask_tok, string)); | ||
163 | +} | ||
164 | + | ||
165 | +static int masked_match4(net_tok, mask_tok, string) | ||
166 | +#else | ||
167 | +static int masked_match(net_tok, mask_tok, string) | ||
168 | +#endif | ||
169 | +char *net_tok; | ||
170 | +char *mask_tok; | ||
171 | +char *string; | ||
172 | +{ | ||
173 | +#ifdef INET6 | ||
174 | + u_int32_t net; | ||
175 | + u_int32_t mask; | ||
176 | + u_int32_t addr; | ||
177 | +#else | ||
178 | unsigned long net; | ||
179 | unsigned long mask; | ||
180 | unsigned long addr; | ||
181 | +#endif | ||
182 | |||
183 | /* | ||
184 | * Disallow forms other than dotted quad: the treatment that inet_addr() | ||
185 | @@ -329,12 +401,78 @@ | ||
186 | return (NO); | ||
187 | if ((net = dot_quad_addr(net_tok)) == INADDR_NONE | ||
188 | || (mask = dot_quad_addr(mask_tok)) == INADDR_NONE) { | ||
189 | +#ifndef INET6 | ||
190 | tcpd_warn("bad net/mask expression: %s/%s", net_tok, mask_tok); | ||
191 | +#endif | ||
192 | return (NO); /* not tcpd_jump() */ | ||
193 | } | ||
194 | return ((addr & mask) == net); | ||
195 | } | ||
196 | |||
197 | +#ifdef INET6 | ||
198 | +static int masked_match6(net_tok, mask_tok, string) | ||
199 | +char *net_tok; | ||
200 | +char *mask_tok; | ||
201 | +char *string; | ||
202 | +{ | ||
203 | + struct addrinfo hints, *res; | ||
204 | + struct sockaddr_in6 net, addr; | ||
205 | + u_int32_t mask; | ||
206 | + int len, mask_len, i = 0; | ||
207 | + char ch; | ||
208 | + | ||
209 | + memset(&hints, 0, sizeof(hints)); | ||
210 | + hints.ai_family = AF_INET6; | ||
211 | + hints.ai_socktype = SOCK_STREAM; | ||
212 | + hints.ai_flags = AI_PASSIVE | AI_NUMERICHOST; | ||
213 | + if (getaddrinfo(string, NULL, &hints, &res) != 0) | ||
214 | + return NO; | ||
215 | + memcpy(&addr, res->ai_addr, sizeof(addr)); | ||
216 | + freeaddrinfo(res); | ||
217 | + | ||
218 | + if (IN6_IS_ADDR_V4MAPPED(&addr.sin6_addr)) { | ||
219 | + if ((*(u_int32_t *)&net.sin6_addr.s6_addr[12] = dot_quad_addr(net_tok)) == INADDR_NONE | ||
220 | + || (mask = dot_quad_addr(mask_tok)) == INADDR_NONE) | ||
221 | + return (NO); | ||
222 | + return ((*(u_int32_t *)&addr.sin6_addr.s6_addr[12] & mask) == *(u_int32_t *)&net.sin6_addr.s6_addr[12]); | ||
223 | + } | ||
224 | + | ||
225 | + /* match IPv6 address against netnumber/prefixlen */ | ||
226 | + len = strlen(net_tok); | ||
227 | + if (*net_tok != '[' || net_tok[len - 1] != ']') | ||
228 | + return NO; | ||
229 | + ch = net_tok[len - 1]; | ||
230 | + net_tok[len - 1] = '\0'; | ||
231 | + if (getaddrinfo(net_tok + 1, NULL, &hints, &res) != 0) { | ||
232 | + net_tok[len - 1] = ch; | ||
233 | + return NO; | ||
234 | + } | ||
235 | + memcpy(&net, res->ai_addr, sizeof(net)); | ||
236 | + freeaddrinfo(res); | ||
237 | + net_tok[len - 1] = ch; | ||
238 | + if ((mask_len = atoi(mask_tok)) < 0 || mask_len > 128) | ||
239 | + return NO; | ||
240 | + | ||
241 | +#ifdef NI_WITHSCOPEID | ||
242 | + if (net.sin6_scope_id != 0 && addr.sin6_scope_id != net.sin6_scope_id) | ||
243 | + return NO; | ||
244 | +#endif | ||
245 | + while (mask_len > 0) { | ||
246 | + if (mask_len < 32) { | ||
247 | + mask = htonl(~(0xffffffff >> mask_len)); | ||
248 | + if ((*(u_int32_t *)&addr.sin6_addr.s6_addr[i] & mask) != (*(u_int32_t *)&net.sin6_addr.s6_addr[i] & mask)) | ||
249 | + return NO; | ||
250 | + break; | ||
251 | + } | ||
252 | + if (*(u_int32_t *)&addr.sin6_addr.s6_addr[i] != *(u_int32_t *)&net.sin6_addr.s6_addr[i]) | ||
253 | + return NO; | ||
254 | + i += 4; | ||
255 | + mask_len -= 32; | ||
256 | + } | ||
257 | + return YES; | ||
258 | +} | ||
259 | +#endif /* INET6 */ | ||
260 | + | ||
261 | #ifndef DISABLE_WILDCARD_MATCHING | ||
262 | /* Note: this feature has been adapted in a pretty straightforward way | ||
263 | from Tatu Ylonen's last SSH version under free license by | ||
264 | diff -ruN tcp_wrappers_7.6.orig/Makefile tcp_wrappers_7.6/Makefile | ||
265 | --- tcp_wrappers_7.6.orig/Makefile 1997-03-21 19:27:21.000000000 +0100 | ||
266 | +++ tcp_wrappers_7.6/Makefile 2004-04-10 19:22:44.000000000 +0200 | ||
267 | @@ -21,7 +21,7 @@ | ||
268 | @echo " dynix epix esix freebsd hpux irix4 irix5 irix6 isc iunix" | ||
269 | @echo " linux machten mips(untested) ncrsvr4 netbsd next osf power_unix_211" | ||
270 | @echo " ptx-2.x ptx-generic pyramid sco sco-nis sco-od2 sco-os5 sinix sunos4" | ||
271 | - @echo " sunos40 sunos5 sysv4 tandem ultrix unicos7 unicos8 unixware1 unixware2" | ||
272 | + @echo " sunos40 sunos5 solaris8 sysv4 tandem ultrix unicos7 unicos8 unixware1 unixware2" | ||
273 | @echo " uts215 uxp" | ||
274 | @echo | ||
275 | @echo "If none of these match your environment, edit the system" | ||
276 | @@ -131,20 +131,34 @@ | ||
277 | NETGROUP=-DNETGROUP TLI= SYSTYPE="-systype bsd43" all | ||
278 | |||
279 | # Freebsd and linux by default have no NIS. | ||
280 | -386bsd netbsd bsdos: | ||
281 | +386bsd bsdos: | ||
282 | @make REAL_DAEMON_DIR=$(REAL_DAEMON_DIR) STYLE=$(STYLE) \ | ||
283 | LIBS= RANLIB=ranlib ARFLAGS=rv AUX_OBJ= NETGROUP= TLI= \ | ||
284 | EXTRA_CFLAGS=-DSYS_ERRLIST_DEFINED VSYSLOG= all | ||
285 | |||
286 | freebsd: | ||
287 | @make REAL_DAEMON_DIR=$(REAL_DAEMON_DIR) STYLE=$(STYLE) \ | ||
288 | + LIBS="-L/usr/local/v6/lib -linet6" \ | ||
289 | LIBS= RANLIB=ranlib ARFLAGS=rv AUX_OBJ= NETGROUP= TLI= \ | ||
290 | - EXTRA_CFLAGS=-DSYS_ERRLIST_DEFINED VSYSLOG= all | ||
291 | + EXTRA_CFLAGS="-DSYS_ERRLIST_DEFINED -DINET6 -Dss_family=__ss_family -Dss_len=__ss_len" \ | ||
292 | + VSYSLOG= all | ||
293 | + | ||
294 | +netbsd: | ||
295 | + @make REAL_DAEMON_DIR=$(REAL_DAEMON_DIR) STYLE=$(STYLE) \ | ||
296 | + LIBS= RANLIB=ranlib ARFLAGS=rv AUX_OBJ= NETGROUP= TLI= \ | ||
297 | + EXTRA_CFLAGS="-DSYS_ERRLIST_DEFINED -DINET6 -Dss_family=__ss_family -Dss_len=__ss_len" VSYSLOG= all | ||
298 | |||
299 | linux: | ||
300 | @make REAL_DAEMON_DIR=$(REAL_DAEMON_DIR) STYLE=$(STYLE) \ | ||
301 | - LIBS= RANLIB=ranlib ARFLAGS=rv AUX_OBJ=setenv.o \ | ||
302 | - NETGROUP= TLI= EXTRA_CFLAGS="-DBROKEN_SO_LINGER" all | ||
303 | + LIBS=-lnsl RANLIB=ranlib ARFLAGS=rv AUX_OBJ= \ | ||
304 | + NETGROUP="-DNETGROUP" TLI= VSYSLOG= BUGS= \ | ||
305 | + EXTRA_CFLAGS="-DSYS_ERRLIST_DEFINED -DHAVE_STRERROR -DINET6=1 -Dss_family=__ss_family -Dss_len=__ss_len" all | ||
306 | + | ||
307 | +gnu: | ||
308 | + @make REAL_DAEMON_DIR=$(REAL_DAEMON_DIR) STYLE=$(STYLE) \ | ||
309 | + LIBS=-lnsl RANLIB=ranlib ARFLAGS=rv AUX_OBJ= \ | ||
310 | + NETGROUP=-DNETGROUP TLI= VSYSLOG= BUGS= \ | ||
311 | + EXTRA_CFLAGS="-DSYS_ERRLIST_DEFINED -DHAVE_STRERROR" all | ||
312 | |||
313 | # This is good for many SYSV+BSD hybrids with NIS, probably also for HP-UX 7.x. | ||
314 | hpux hpux8 hpux9 hpux10: | ||
315 | @@ -196,6 +210,13 @@ | ||
316 | NETGROUP=-DNETGROUP AUX_OBJ=setenv.o TLI=-DTLI \ | ||
317 | BUGS="$(BUGS) -DSOLARIS_24_GETHOSTBYNAME_BUG" all | ||
318 | |||
319 | +# SunOS 5.8 is another SYSV4 variant, but has IPv6 support | ||
320 | +solaris8: | ||
321 | + @make REAL_DAEMON_DIR=$(REAL_DAEMON_DIR) STYLE=$(STYLE) \ | ||
322 | + LIBS="-lsocket -lnsl" RANLIB=echo ARFLAGS=rv VSYSLOG= \ | ||
323 | + NETGROUP=-DNETGROUP AUX_OBJ=setenv.o TLI=-DTLI \ | ||
324 | + EXTRA_CFLAGS="-DINET6 -DNO_CLONE_DEVICE -DINT32_T" all | ||
325 | + | ||
326 | # Generic SYSV40 | ||
327 | esix sysv4: | ||
328 | @make REAL_DAEMON_DIR=$(REAL_DAEMON_DIR) STYLE=$(STYLE) \ | ||
329 | diff -ruN tcp_wrappers_7.6.orig/misc.c tcp_wrappers_7.6/misc.c | ||
330 | --- tcp_wrappers_7.6.orig/misc.c 1996-02-11 17:01:30.000000000 +0100 | ||
331 | +++ tcp_wrappers_7.6/misc.c 2004-04-10 19:07:43.000000000 +0200 | ||
332 | @@ -58,9 +58,31 @@ | ||
333 | { | ||
334 | char *cp; | ||
335 | |||
336 | +#ifdef INET6 | ||
337 | + int bracket = 0; | ||
338 | + | ||
339 | + for (cp = string; cp && *cp; cp++) { | ||
340 | + switch (*cp) { | ||
341 | + case '[': | ||
342 | + bracket++; | ||
343 | + break; | ||
344 | + case ']': | ||
345 | + bracket--; | ||
346 | + break; | ||
347 | + default: | ||
348 | + if (bracket == 0 && *cp == delimiter) { | ||
349 | + *cp++ = 0; | ||
350 | + return cp; | ||
351 | + } | ||
352 | + break; | ||
353 | + } | ||
354 | + } | ||
355 | + return (NULL); | ||
356 | +#else | ||
357 | if ((cp = strchr(string, delimiter)) != 0) | ||
358 | *cp++ = 0; | ||
359 | return (cp); | ||
360 | +#endif | ||
361 | } | ||
362 | |||
363 | /* dot_quad_addr - convert dotted quad to internal form */ | ||
364 | diff -ruN tcp_wrappers_7.6.orig/refuse.c tcp_wrappers_7.6/refuse.c | ||
365 | --- tcp_wrappers_7.6.orig/refuse.c 1994-12-28 17:42:40.000000000 +0100 | ||
366 | +++ tcp_wrappers_7.6/refuse.c 2004-04-10 19:07:43.000000000 +0200 | ||
367 | @@ -25,7 +25,12 @@ | ||
368 | void refuse(request) | ||
369 | struct request_info *request; | ||
370 | { | ||
371 | +#ifdef INET6 | ||
372 | + syslog(deny_severity, "refused connect from %s (%s)", | ||
373 | + eval_client(request), eval_hostaddr(request->client)); | ||
374 | +#else | ||
375 | syslog(deny_severity, "refused connect from %s", eval_client(request)); | ||
376 | +#endif | ||
377 | clean_exit(request); | ||
378 | /* NOTREACHED */ | ||
379 | } | ||
380 | diff -ruN tcp_wrappers_7.6.orig/rfc931.c tcp_wrappers_7.6/rfc931.c | ||
381 | --- tcp_wrappers_7.6.orig/rfc931.c 1995-01-02 16:11:34.000000000 +0100 | ||
382 | +++ tcp_wrappers_7.6/rfc931.c 2004-04-10 19:07:43.000000000 +0200 | ||
383 | @@ -68,20 +68,50 @@ | ||
384 | /* rfc931 - return remote user name, given socket structures */ | ||
385 | |||
386 | void rfc931(rmt_sin, our_sin, dest) | ||
387 | +#ifdef INET6 | ||
388 | +struct sockaddr *rmt_sin; | ||
389 | +struct sockaddr *our_sin; | ||
390 | +#else | ||
391 | struct sockaddr_in *rmt_sin; | ||
392 | struct sockaddr_in *our_sin; | ||
393 | +#endif | ||
394 | char *dest; | ||
395 | { | ||
396 | unsigned rmt_port; | ||
397 | unsigned our_port; | ||
398 | +#ifdef INET6 | ||
399 | + struct sockaddr_storage rmt_query_sin; | ||
400 | + struct sockaddr_storage our_query_sin; | ||
401 | + int alen; | ||
402 | +#else | ||
403 | struct sockaddr_in rmt_query_sin; | ||
404 | struct sockaddr_in our_query_sin; | ||
405 | +#endif | ||
406 | char user[256]; /* XXX */ | ||
407 | char buffer[512]; /* XXX */ | ||
408 | char *cp; | ||
409 | char *result = unknown; | ||
410 | FILE *fp; | ||
411 | |||
412 | +#ifdef INET6 | ||
413 | + /* address family must be the same */ | ||
414 | + if (rmt_sin->sa_family != our_sin->sa_family) { | ||
415 | + STRN_CPY(dest, result, STRING_LENGTH); | ||
416 | + return; | ||
417 | + } | ||
418 | + switch (our_sin->sa_family) { | ||
419 | + case AF_INET: | ||
420 | + alen = sizeof(struct sockaddr_in); | ||
421 | + break; | ||
422 | + case AF_INET6: | ||
423 | + alen = sizeof(struct sockaddr_in6); | ||
424 | + break; | ||
425 | + default: | ||
426 | + STRN_CPY(dest, result, STRING_LENGTH); | ||
427 | + return; | ||
428 | + } | ||
429 | +#endif | ||
430 | + | ||
431 | /* | ||
432 | * Use one unbuffered stdio stream for writing to and for reading from | ||
433 | * the RFC931 etc. server. This is done because of a bug in the SunOS | ||
434 | @@ -92,7 +122,11 @@ | ||
435 | * sockets. | ||
436 | */ | ||
437 | |||
438 | +#ifdef INET6 | ||
439 | + if ((fp = fsocket(our_sin->sa_family, SOCK_STREAM, 0)) != 0) { | ||
440 | +#else | ||
441 | if ((fp = fsocket(AF_INET, SOCK_STREAM, 0)) != 0) { | ||
442 | +#endif | ||
443 | setbuf(fp, (char *) 0); | ||
444 | |||
445 | /* | ||
446 | @@ -112,6 +146,25 @@ | ||
447 | * addresses from the query socket. | ||
448 | */ | ||
449 | |||
450 | +#ifdef INET6 | ||
451 | + memcpy(&our_query_sin, our_sin, alen); | ||
452 | + memcpy(&rmt_query_sin, rmt_sin, alen); | ||
453 | + switch (our_sin->sa_family) { | ||
454 | + case AF_INET: | ||
455 | + ((struct sockaddr_in *)&our_query_sin)->sin_port = htons(ANY_PORT); | ||
456 | + ((struct sockaddr_in *)&rmt_query_sin)->sin_port = htons(RFC931_PORT); | ||
457 | + break; | ||
458 | + case AF_INET6: | ||
459 | + ((struct sockaddr_in6 *)&our_query_sin)->sin6_port = htons(ANY_PORT); | ||
460 | + ((struct sockaddr_in6 *)&rmt_query_sin)->sin6_port = htons(RFC931_PORT); | ||
461 | + break; | ||
462 | + } | ||
463 | + | ||
464 | + if (bind(fileno(fp), (struct sockaddr *) & our_query_sin, | ||
465 | + alen) >= 0 && | ||
466 | + connect(fileno(fp), (struct sockaddr *) & rmt_query_sin, | ||
467 | + alen) >= 0) { | ||
468 | +#else | ||
469 | our_query_sin = *our_sin; | ||
470 | our_query_sin.sin_port = htons(ANY_PORT); | ||
471 | rmt_query_sin = *rmt_sin; | ||
472 | @@ -121,6 +174,7 @@ | ||
473 | sizeof(our_query_sin)) >= 0 && | ||
474 | connect(fileno(fp), (struct sockaddr *) & rmt_query_sin, | ||
475 | sizeof(rmt_query_sin)) >= 0) { | ||
476 | +#endif | ||
477 | |||
478 | /* | ||
479 | * Send query to server. Neglect the risk that a 13-byte | ||
480 | @@ -129,8 +183,13 @@ | ||
481 | */ | ||
482 | |||
483 | fprintf(fp, "%u,%u\r\n", | ||
484 | +#ifdef INET6 | ||
485 | + ntohs(((struct sockaddr_in *)rmt_sin)->sin_port), | ||
486 | + ntohs(((struct sockaddr_in *)our_sin)->sin_port)); | ||
487 | +#else | ||
488 | ntohs(rmt_sin->sin_port), | ||
489 | ntohs(our_sin->sin_port)); | ||
490 | +#endif | ||
491 | fflush(fp); | ||
492 | |||
493 | /* | ||
494 | @@ -144,8 +203,13 @@ | ||
495 | && ferror(fp) == 0 && feof(fp) == 0 | ||
496 | && sscanf(buffer, "%u , %u : USERID :%*[^:]:%255s", | ||
497 | &rmt_port, &our_port, user) == 3 | ||
498 | +#ifdef INET6 | ||
499 | + && ntohs(((struct sockaddr_in *)rmt_sin)->sin_port) == rmt_port | ||
500 | + && ntohs(((struct sockaddr_in *)our_sin)->sin_port) == our_port) { | ||
501 | +#else | ||
502 | && ntohs(rmt_sin->sin_port) == rmt_port | ||
503 | && ntohs(our_sin->sin_port) == our_port) { | ||
504 | +#endif | ||
505 | |||
506 | /* | ||
507 | * Strip trailing carriage return. It is part of the | ||
508 | diff -ruN tcp_wrappers_7.6.orig/scaffold.c tcp_wrappers_7.6/scaffold.c | ||
509 | --- tcp_wrappers_7.6.orig/scaffold.c 1997-03-21 19:27:24.000000000 +0100 | ||
510 | +++ tcp_wrappers_7.6/scaffold.c 2004-04-10 19:07:43.000000000 +0200 | ||
511 | @@ -25,7 +25,9 @@ | ||
512 | #define INADDR_NONE (-1) /* XXX should be 0xffffffff */ | ||
513 | #endif | ||
514 | |||
515 | +#ifndef INET6 | ||
516 | extern char *malloc(); | ||
517 | +#endif | ||
518 | |||
519 | /* Application-specific. */ | ||
520 | |||
521 | @@ -39,6 +41,7 @@ | ||
522 | int deny_severity = LOG_WARNING; | ||
523 | int rfc931_timeout = RFC931_TIMEOUT; | ||
524 | |||
525 | +#ifndef INET6 | ||
526 | /* dup_hostent - create hostent in one memory block */ | ||
527 | |||
528 | static struct hostent *dup_hostent(hp) | ||
529 | @@ -73,9 +76,46 @@ | ||
530 | } | ||
531 | return (&hb->host); | ||
532 | } | ||
533 | +#endif | ||
534 | |||
535 | /* find_inet_addr - find all addresses for this host, result to free() */ | ||
536 | |||
537 | +#ifdef INET6 | ||
538 | +struct addrinfo *find_inet_addr(host) | ||
539 | +char *host; | ||
540 | +{ | ||
541 | + struct addrinfo hints, *res; | ||
542 | + | ||
543 | + memset(&hints, 0, sizeof(hints)); | ||
544 | + hints.ai_family = PF_UNSPEC; | ||
545 | + hints.ai_socktype = SOCK_STREAM; | ||
546 | + hints.ai_flags = AI_PASSIVE | AI_NUMERICHOST; | ||
547 | + if (getaddrinfo(host, NULL, &hints, &res) == 0) | ||
548 | + return (res); | ||
549 | + | ||
550 | + memset(&hints, 0, sizeof(hints)); | ||
551 | + hints.ai_family = PF_UNSPEC; | ||
552 | + hints.ai_socktype = SOCK_STREAM; | ||
553 | + hints.ai_flags = AI_PASSIVE | AI_CANONNAME; | ||
554 | + if (getaddrinfo(host, NULL, &hints, &res) != 0) { | ||
555 | + tcpd_warn("%s: host not found", host); | ||
556 | + return (0); | ||
557 | + } | ||
558 | + if (res->ai_family != AF_INET6 && res->ai_family != AF_INET) { | ||
559 | + tcpd_warn("%d: not an internet host", res->ai_family); | ||
560 | + freeaddrinfo(res); | ||
561 | + return (0); | ||
562 | + } | ||
563 | + if (!res->ai_canonname) { | ||
564 | + tcpd_warn("%s: hostname alias", host); | ||
565 | + tcpd_warn("(cannot obtain official name)", res->ai_canonname); | ||
566 | + } else if (STR_NE(host, res->ai_canonname)) { | ||
567 | + tcpd_warn("%s: hostname alias", host); | ||
568 | + tcpd_warn("(official name: %.*s)", STRING_LENGTH, res->ai_canonname); | ||
569 | + } | ||
570 | + return (res); | ||
571 | +} | ||
572 | +#else | ||
573 | struct hostent *find_inet_addr(host) | ||
574 | char *host; | ||
575 | { | ||
576 | @@ -118,6 +158,7 @@ | ||
577 | } | ||
578 | return (dup_hostent(hp)); | ||
579 | } | ||
580 | +#endif | ||
581 | |||
582 | /* check_dns - give each address thorough workout, return address count */ | ||
583 | |||
584 | @@ -125,8 +166,13 @@ | ||
585 | char *host; | ||
586 | { | ||
587 | struct request_info request; | ||
588 | +#ifdef INET6 | ||
589 | + struct sockaddr_storage sin; | ||
590 | + struct addrinfo *hp, *res; | ||
591 | +#else | ||
592 | struct sockaddr_in sin; | ||
593 | struct hostent *hp; | ||
594 | +#endif | ||
595 | int count; | ||
596 | char *addr; | ||
597 | |||
598 | @@ -134,11 +180,18 @@ | ||
599 | return (0); | ||
600 | request_init(&request, RQ_CLIENT_SIN, &sin, 0); | ||
601 | sock_methods(&request); | ||
602 | +#ifndef INET6 | ||
603 | memset((char *) &sin, 0, sizeof(sin)); | ||
604 | sin.sin_family = AF_INET; | ||
605 | +#endif | ||
606 | |||
607 | +#ifdef INET6 | ||
608 | + for (res = hp, count = 0; res; res = res->ai_next, count++) { | ||
609 | + memcpy(&sin, res->ai_addr, res->ai_addrlen); | ||
610 | +#else | ||
611 | for (count = 0; (addr = hp->h_addr_list[count]) != 0; count++) { | ||
612 | memcpy((char *) &sin.sin_addr, addr, sizeof(sin.sin_addr)); | ||
613 | +#endif | ||
614 | |||
615 | /* | ||
616 | * Force host name and address conversions. Use the request structure | ||
617 | @@ -151,7 +204,11 @@ | ||
618 | tcpd_warn("host address %s->name lookup failed", | ||
619 | eval_hostaddr(request.client)); | ||
620 | } | ||
621 | +#ifdef INET6 | ||
622 | + freeaddrinfo(hp); | ||
623 | +#else | ||
624 | free((char *) hp); | ||
625 | +#endif | ||
626 | return (count); | ||
627 | } | ||
628 | |||
629 | diff -ruN tcp_wrappers_7.6.orig/scaffold.h tcp_wrappers_7.6/scaffold.h | ||
630 | --- tcp_wrappers_7.6.orig/scaffold.h 1994-12-31 18:19:20.000000000 +0100 | ||
631 | +++ tcp_wrappers_7.6/scaffold.h 2004-04-10 19:07:43.000000000 +0200 | ||
632 | @@ -4,6 +4,10 @@ | ||
633 | * Author: Wietse Venema, Eindhoven University of Technology, The Netherlands. | ||
634 | */ | ||
635 | |||
636 | +#ifdef INET6 | ||
637 | +extern struct addrinfo *find_inet_addr(); | ||
638 | +#else | ||
639 | extern struct hostent *find_inet_addr(); | ||
640 | +#endif | ||
641 | extern int check_dns(); | ||
642 | extern int check_path(); | ||
643 | diff -ruN tcp_wrappers_7.6.orig/socket.c tcp_wrappers_7.6/socket.c | ||
644 | --- tcp_wrappers_7.6.orig/socket.c 2004-04-10 19:22:58.000000000 +0200 | ||
645 | +++ tcp_wrappers_7.6/socket.c 2004-04-10 19:07:43.000000000 +0200 | ||
646 | @@ -24,13 +24,22 @@ | ||
647 | #include <sys/types.h> | ||
648 | #include <sys/param.h> | ||
649 | #include <sys/socket.h> | ||
650 | +#ifdef INT32_T | ||
651 | +typedef uint32_t u_int32_t; | ||
652 | +#endif | ||
653 | #include <netinet/in.h> | ||
654 | #include <netdb.h> | ||
655 | #include <stdio.h> | ||
656 | #include <syslog.h> | ||
657 | #include <string.h> | ||
658 | |||
659 | +#ifdef INET6 | ||
660 | +#ifndef NI_WITHSCOPEID | ||
661 | +#define NI_WITHSCOPEID 0 | ||
662 | +#endif | ||
663 | +#else | ||
664 | extern char *inet_ntoa(); | ||
665 | +#endif | ||
666 | |||
667 | /* Local stuff. */ | ||
668 | |||
669 | @@ -79,8 +88,13 @@ | ||
670 | void sock_host(request) | ||
671 | struct request_info *request; | ||
672 | { | ||
673 | +#ifdef INET6 | ||
674 | + static struct sockaddr_storage client; | ||
675 | + static struct sockaddr_storage server; | ||
676 | +#else | ||
677 | static struct sockaddr_in client; | ||
678 | static struct sockaddr_in server; | ||
679 | +#endif | ||
680 | int len; | ||
681 | char buf[BUFSIZ]; | ||
682 | int fd = request->fd; | ||
683 | @@ -109,7 +123,11 @@ | ||
684 | memset(buf, 0 sizeof(buf)); | ||
685 | #endif | ||
686 | } | ||
687 | +#ifdef INET6 | ||
688 | + request->client->sin = (struct sockaddr *)&client; | ||
689 | +#else | ||
690 | request->client->sin = &client; | ||
691 | +#endif | ||
692 | |||
693 | /* | ||
694 | * Determine the server binding. This is used for client username | ||
695 | @@ -122,7 +140,11 @@ | ||
696 | tcpd_warn("getsockname: %m"); | ||
697 | return; | ||
698 | } | ||
699 | +#ifdef INET6 | ||
700 | + request->server->sin = (struct sockaddr *)&server; | ||
701 | +#else | ||
702 | request->server->sin = &server; | ||
703 | +#endif | ||
704 | } | ||
705 | |||
706 | /* sock_hostaddr - map endpoint address to printable form */ | ||
707 | @@ -130,10 +152,26 @@ | ||
708 | void sock_hostaddr(host) | ||
709 | struct host_info *host; | ||
710 | { | ||
711 | +#ifdef INET6 | ||
712 | + struct sockaddr *sin = host->sin; | ||
713 | + int salen; | ||
714 | + | ||
715 | + if (!sin) | ||
716 | + return; | ||
717 | +#ifdef SIN6_LEN | ||
718 | + salen = sin->sa_len; | ||
719 | +#else | ||
720 | + salen = (sin->sa_family == AF_INET) ? sizeof(struct sockaddr_in) | ||
721 | + : sizeof(struct sockaddr_in6); | ||
722 | +#endif | ||
723 | + getnameinfo(sin, salen, host->addr, sizeof(host->addr), | ||
724 | + NULL, 0, NI_NUMERICHOST | NI_WITHSCOPEID); | ||
725 | +#else | ||
726 | struct sockaddr_in *sin = host->sin; | ||
727 | |||
728 | if (sin != 0) | ||
729 | STRN_CPY(host->addr, inet_ntoa(sin->sin_addr), sizeof(host->addr)); | ||
730 | +#endif | ||
731 | } | ||
732 | |||
733 | /* sock_hostname - map endpoint address to host name */ | ||
734 | @@ -141,6 +179,160 @@ | ||
735 | void sock_hostname(host) | ||
736 | struct host_info *host; | ||
737 | { | ||
738 | +#ifdef INET6 | ||
739 | + struct sockaddr *sin = host->sin; | ||
740 | + struct sockaddr_in sin4; | ||
741 | + struct addrinfo hints, *res, *res0 = NULL; | ||
742 | + int salen, alen, err = 1; | ||
743 | + char *ap = NULL, *rap, hname[NI_MAXHOST]; | ||
744 | + | ||
745 | + if (sin != NULL) { | ||
746 | + if (sin->sa_family == AF_INET6) { | ||
747 | + struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sin; | ||
748 | + | ||
749 | + if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) { | ||
750 | + memset(&sin4, 0, sizeof(sin4)); | ||
751 | +#ifdef SIN6_LEN | ||
752 | + sin4.sin_len = sizeof(sin4); | ||
753 | +#endif | ||
754 | + sin4.sin_family = AF_INET; | ||
755 | + sin4.sin_port = sin6->sin6_port; | ||
756 | + sin4.sin_addr.s_addr = *(u_int32_t *)&sin6->sin6_addr.s6_addr[12]; | ||
757 | + sin = (struct sockaddr *)&sin4; | ||
758 | + } | ||
759 | + } | ||
760 | + switch (sin->sa_family) { | ||
761 | + case AF_INET: | ||
762 | + ap = (char *)&((struct sockaddr_in *)sin)->sin_addr; | ||
763 | + alen = sizeof(struct in_addr); | ||
764 | + salen = sizeof(struct sockaddr_in); | ||
765 | + break; | ||
766 | + case AF_INET6: | ||
767 | + ap = (char *)&((struct sockaddr_in6 *)sin)->sin6_addr; | ||
768 | + alen = sizeof(struct in6_addr); | ||
769 | + salen = sizeof(struct sockaddr_in6); | ||
770 | + break; | ||
771 | + default: | ||
772 | + break; | ||
773 | + } | ||
774 | + if (ap) | ||
775 | + err = getnameinfo(sin, salen, hname, sizeof(hname), | ||
776 | + NULL, 0, NI_WITHSCOPEID | NI_NAMEREQD); | ||
777 | + } | ||
778 | + if (!err) { | ||
779 | + | ||
780 | + STRN_CPY(host->name, hname, sizeof(host->name)); | ||
781 | + | ||
782 | + /* reject numeric addresses */ | ||
783 | + memset(&hints, 0, sizeof(hints)); | ||
784 | + hints.ai_family = sin->sa_family; | ||
785 | + hints.ai_socktype = SOCK_STREAM; | ||
786 | + hints.ai_flags = AI_PASSIVE | AI_CANONNAME | AI_NUMERICHOST; | ||
787 | + if ((err = getaddrinfo(host->name, NULL, &hints, &res0) == 0)) { | ||
788 | + freeaddrinfo(res0); | ||
789 | + res0 = NULL; | ||
790 | + tcpd_warn("host name/name mismatch: " | ||
791 | + "reverse lookup results in non-FQDN %s", | ||
792 | + host->name); | ||
793 | + strcpy(host->name, paranoid); /* name is bad, clobber it */ | ||
794 | + } | ||
795 | + err = !err; | ||
796 | + } | ||
797 | + if (!err) { | ||
798 | + /* we are now sure that this is non-numeric */ | ||
799 | + | ||
800 | + /* | ||
801 | + * Verify that the address is a member of the address list returned | ||
802 | + * by gethostbyname(hostname). | ||
803 | + * | ||
804 | + * Verify also that gethostbyaddr() and gethostbyname() return the same | ||
805 | + * hostname, or rshd and rlogind may still end up being spoofed. | ||
806 | + * | ||
807 | + * On some sites, gethostbyname("localhost") returns "localhost.domain". | ||
808 | + * This is a DNS artefact. We treat it as a special case. When we | ||
809 | + * can't believe the address list from gethostbyname("localhost") | ||
810 | + * we're in big trouble anyway. | ||
811 | + */ | ||
812 | + | ||
813 | + memset(&hints, 0, sizeof(hints)); | ||
814 | + hints.ai_family = sin->sa_family; | ||
815 | + hints.ai_socktype = SOCK_STREAM; | ||
816 | + hints.ai_flags = AI_PASSIVE | AI_CANONNAME; | ||
817 | + if (getaddrinfo(host->name, NULL, &hints, &res0) != 0) { | ||
818 | + | ||
819 | + /* | ||
820 | + * Unable to verify that the host name matches the address. This | ||
821 | + * may be a transient problem or a botched name server setup. | ||
822 | + */ | ||
823 | + | ||
824 | + tcpd_warn("can't verify hostname: getaddrinfo(%s, %s) failed", | ||
825 | + host->name, | ||
826 | + (sin->sa_family == AF_INET) ? "AF_INET" : "AF_INET6"); | ||
827 | + | ||
828 | + } else if ((res0->ai_canonname == NULL | ||
829 | + || STR_NE(host->name, res0->ai_canonname)) | ||
830 | + && STR_NE(host->name, "localhost")) { | ||
831 | + | ||
832 | + /* | ||
833 | + * The gethostbyaddr() and gethostbyname() calls did not return | ||
834 | + * the same hostname. This could be a nameserver configuration | ||
835 | + * problem. It could also be that someone is trying to spoof us. | ||
836 | + */ | ||
837 | + | ||
838 | + tcpd_warn("host name/name mismatch: %s != %.*s", | ||
839 | + host->name, STRING_LENGTH, | ||
840 | + (res0->ai_canonname == NULL) ? "" : res0->ai_canonname); | ||
841 | + | ||
842 | + } else { | ||
843 | + | ||
844 | + /* | ||
845 | + * The address should be a member of the address list returned by | ||
846 | + * gethostbyname(). We should first verify that the h_addrtype | ||
847 | + * field is AF_INET, but this program has already caused too much | ||
848 | + * grief on systems with broken library code. | ||
849 | + */ | ||
850 | + | ||
851 | + for (res = res0; res; res = res->ai_next) { | ||
852 | + if (res->ai_family != sin->sa_family) | ||
853 | + continue; | ||
854 | + switch (res->ai_family) { | ||
855 | + case AF_INET: | ||
856 | + rap = (char *)&((struct sockaddr_in *)res->ai_addr)->sin_addr; | ||
857 | + break; | ||
858 | + case AF_INET6: | ||
859 | + /* need to check scope_id */ | ||
860 | + if (((struct sockaddr_in6 *)sin)->sin6_scope_id != | ||
861 | + ((struct sockaddr_in6 *)res->ai_addr)->sin6_scope_id) { | ||
862 | + continue; | ||
863 | + } | ||
864 | + rap = (char *)&((struct sockaddr_in6 *)res->ai_addr)->sin6_addr; | ||
865 | + break; | ||
866 | + default: | ||
867 | + continue; | ||
868 | + } | ||
869 | + if (memcmp(rap, ap, alen) == 0) { | ||
870 | + freeaddrinfo(res0); | ||
871 | + return; /* name is good, keep it */ | ||
872 | + } | ||
873 | + } | ||
874 | + | ||
875 | + /* | ||
876 | + * The host name does not map to the initial address. Perhaps | ||
877 | + * someone has messed up. Perhaps someone compromised a name | ||
878 | + * server. | ||
879 | + */ | ||
880 | + | ||
881 | + getnameinfo(sin, salen, hname, sizeof(hname), | ||
882 | + NULL, 0, NI_NUMERICHOST | NI_WITHSCOPEID); | ||
883 | + tcpd_warn("host name/address mismatch: %s != %.*s", | ||
884 | + hname, STRING_LENGTH, | ||
885 | + (res0->ai_canonname == NULL) ? "" : res0->ai_canonname); | ||
886 | + } | ||
887 | + strcpy(host->name, paranoid); /* name is bad, clobber it */ | ||
888 | + if (res0) | ||
889 | + freeaddrinfo(res0); | ||
890 | + } | ||
891 | +#else /* INET6 */ | ||
892 | struct sockaddr_in *sin = host->sin; | ||
893 | struct hostent *hp; | ||
894 | int i; | ||
895 | @@ -220,6 +412,7 @@ | ||
896 | } | ||
897 | strcpy(host->name, paranoid); /* name is bad, clobber it */ | ||
898 | } | ||
899 | +#endif /* INET6 */ | ||
900 | } | ||
901 | |||
902 | /* sock_sink - absorb unreceived IP datagram */ | ||
903 | @@ -228,7 +421,11 @@ | ||
904 | int fd; | ||
905 | { | ||
906 | char buf[BUFSIZ]; | ||
907 | +#ifdef INET6 | ||
908 | + struct sockaddr_storage sin; | ||
909 | +#else | ||
910 | struct sockaddr_in sin; | ||
911 | +#endif | ||
912 | int size = sizeof(sin); | ||
913 | |||
914 | /* | ||
915 | diff -ruN tcp_wrappers_7.6.orig/tcpd.c tcp_wrappers_7.6/tcpd.c | ||
916 | --- tcp_wrappers_7.6.orig/tcpd.c 1996-02-11 17:01:33.000000000 +0100 | ||
917 | +++ tcp_wrappers_7.6/tcpd.c 2004-04-10 19:07:43.000000000 +0200 | ||
918 | @@ -120,7 +120,12 @@ | ||
919 | |||
920 | /* Report request and invoke the real daemon program. */ | ||
921 | |||
922 | +#ifdef INET6 | ||
923 | + syslog(allow_severity, "connect from %s (%s)", | ||
924 | + eval_client(&request), eval_hostaddr(request.client)); | ||
925 | +#else | ||
926 | syslog(allow_severity, "connect from %s", eval_client(&request)); | ||
927 | +#endif | ||
928 | closelog(); | ||
929 | (void) execv(path, argv); | ||
930 | syslog(LOG_ERR, "error: cannot execute %s: %m", path); | ||
931 | diff -ruN tcp_wrappers_7.6.orig/tcpdchk.c tcp_wrappers_7.6/tcpdchk.c | ||
932 | --- tcp_wrappers_7.6.orig/tcpdchk.c 1997-02-12 02:13:25.000000000 +0100 | ||
933 | +++ tcp_wrappers_7.6/tcpdchk.c 2004-04-10 19:07:43.000000000 +0200 | ||
934 | @@ -22,6 +22,9 @@ | ||
935 | |||
936 | #include <sys/types.h> | ||
937 | #include <sys/stat.h> | ||
938 | +#ifdef INET6 | ||
939 | +#include <sys/socket.h> | ||
940 | +#endif | ||
941 | #include <netinet/in.h> | ||
942 | #include <arpa/inet.h> | ||
943 | #include <stdio.h> | ||
944 | @@ -397,6 +400,31 @@ | ||
945 | } | ||
946 | } | ||
947 | |||
948 | +#ifdef INET6 | ||
949 | +static int is_inet6_addr(pat) | ||
950 | + char *pat; | ||
951 | +{ | ||
952 | + struct addrinfo hints, *res; | ||
953 | + int len, ret; | ||
954 | + char ch; | ||
955 | + | ||
956 | + if (*pat != '[') | ||
957 | + return (0); | ||
958 | + len = strlen(pat); | ||
959 | + if ((ch = pat[len - 1]) != ']') | ||
960 | + return (0); | ||
961 | + pat[len - 1] = '\0'; | ||
962 | + memset(&hints, 0, sizeof(hints)); | ||
963 | + hints.ai_family = AF_INET6; | ||
964 | + hints.ai_socktype = SOCK_STREAM; | ||
965 | + hints.ai_flags = AI_PASSIVE | AI_NUMERICHOST; | ||
966 | + if ((ret = getaddrinfo(pat + 1, NULL, &hints, &res)) == 0) | ||
967 | + freeaddrinfo(res); | ||
968 | + pat[len - 1] = ch; | ||
969 | + return (ret == 0); | ||
970 | +} | ||
971 | +#endif | ||
972 | + | ||
973 | /* check_host - criticize host pattern */ | ||
974 | |||
975 | static int check_host(pat) | ||
976 | @@ -423,14 +451,27 @@ | ||
977 | #endif | ||
978 | #endif | ||
979 | } else if (mask = split_at(pat, '/')) { /* network/netmask */ | ||
980 | +#ifdef INET6 | ||
981 | + int mask_len; | ||
982 | + | ||
983 | + if ((dot_quad_addr(pat) == INADDR_NONE | ||
984 | + || dot_quad_addr(mask) == INADDR_NONE) | ||
985 | + && (!is_inet6_addr(pat) | ||
986 | + || ((mask_len = atoi(mask)) < 0 || mask_len > 128))) | ||
987 | +#else | ||
988 | if (dot_quad_addr(pat) == INADDR_NONE | ||
989 | || dot_quad_addr(mask) == INADDR_NONE) | ||
990 | +#endif | ||
991 | tcpd_warn("%s/%s: bad net/mask pattern", pat, mask); | ||
992 | } else if (STR_EQ(pat, "FAIL")) { /* obsolete */ | ||
993 | tcpd_warn("FAIL is no longer recognized"); | ||
994 | tcpd_warn("(use EXCEPT or DENY instead)"); | ||
995 | } else if (reserved_name(pat)) { /* other reserved */ | ||
996 | /* void */ ; | ||
997 | +#ifdef INET6 | ||
998 | + } else if (is_inet6_addr(pat)) { /* IPv6 address */ | ||
999 | + addr_count = 1; | ||
1000 | +#endif | ||
1001 | } else if (NOT_INADDR(pat)) { /* internet name */ | ||
1002 | if (pat[strlen(pat) - 1] == '.') { | ||
1003 | tcpd_warn("%s: domain or host name ends in dot", pat); | ||
1004 | diff -ruN tcp_wrappers_7.6.orig/tcpd.h tcp_wrappers_7.6/tcpd.h | ||
1005 | --- tcp_wrappers_7.6.orig/tcpd.h 1996-03-19 16:22:25.000000000 +0100 | ||
1006 | +++ tcp_wrappers_7.6/tcpd.h 2004-04-10 19:07:43.000000000 +0200 | ||
1007 | @@ -11,7 +11,11 @@ | ||
1008 | struct host_info { | ||
1009 | char name[STRING_LENGTH]; /* access via eval_hostname(host) */ | ||
1010 | char addr[STRING_LENGTH]; /* access via eval_hostaddr(host) */ | ||
1011 | +#ifdef INET6 | ||
1012 | + struct sockaddr *sin; /* socket address or 0 */ | ||
1013 | +#else | ||
1014 | struct sockaddr_in *sin; /* socket address or 0 */ | ||
1015 | +#endif | ||
1016 | struct t_unitdata *unit; /* TLI transport address or 0 */ | ||
1017 | struct request_info *request; /* for shared information */ | ||
1018 | }; | ||
1019 | diff -ruN tcp_wrappers_7.6.orig/tcpdmatch.c tcp_wrappers_7.6/tcpdmatch.c | ||
1020 | --- tcp_wrappers_7.6.orig/tcpdmatch.c 1996-02-11 17:01:36.000000000 +0100 | ||
1021 | +++ tcp_wrappers_7.6/tcpdmatch.c 2004-04-10 19:07:43.000000000 +0200 | ||
1022 | @@ -57,7 +57,11 @@ | ||
1023 | int argc; | ||
1024 | char **argv; | ||
1025 | { | ||
1026 | +#ifdef INET6 | ||
1027 | + struct addrinfo hints, *hp, *res; | ||
1028 | +#else | ||
1029 | struct hostent *hp; | ||
1030 | +#endif | ||
1031 | char *myname = argv[0]; | ||
1032 | char *client; | ||
1033 | char *server; | ||
1034 | @@ -68,8 +72,13 @@ | ||
1035 | int ch; | ||
1036 | char *inetcf = 0; | ||
1037 | int count; | ||
1038 | +#ifdef INET6 | ||
1039 | + struct sockaddr_storage server_sin; | ||
1040 | + struct sockaddr_storage client_sin; | ||
1041 | +#else | ||
1042 | struct sockaddr_in server_sin; | ||
1043 | struct sockaddr_in client_sin; | ||
1044 | +#endif | ||
1045 | struct stat st; | ||
1046 | |||
1047 | /* | ||
1048 | @@ -172,13 +181,20 @@ | ||
1049 | if (NOT_INADDR(server) == 0 || HOSTNAME_KNOWN(server)) { | ||
1050 | if ((hp = find_inet_addr(server)) == 0) | ||
1051 | exit(1); | ||
1052 | +#ifndef INET6 | ||
1053 | memset((char *) &server_sin, 0, sizeof(server_sin)); | ||
1054 | server_sin.sin_family = AF_INET; | ||
1055 | +#endif | ||
1056 | request_set(&request, RQ_SERVER_SIN, &server_sin, 0); | ||
1057 | |||
1058 | +#ifdef INET6 | ||
1059 | + for (res = hp, count = 0; res; res = res->ai_next, count++) { | ||
1060 | + memcpy(&server_sin, res->ai_addr, res->ai_addrlen); | ||
1061 | +#else | ||
1062 | for (count = 0; (addr = hp->h_addr_list[count]) != 0; count++) { | ||
1063 | memcpy((char *) &server_sin.sin_addr, addr, | ||
1064 | sizeof(server_sin.sin_addr)); | ||
1065 | +#endif | ||
1066 | |||
1067 | /* | ||
1068 | * Force evaluation of server host name and address. Host name | ||
1069 | @@ -194,7 +210,11 @@ | ||
1070 | fprintf(stderr, "Please specify an address instead\n"); | ||
1071 | exit(1); | ||
1072 | } | ||
1073 | +#ifdef INET6 | ||
1074 | + freeaddrinfo(hp); | ||
1075 | +#else | ||
1076 | free((char *) hp); | ||
1077 | +#endif | ||
1078 | } else { | ||
1079 | request_set(&request, RQ_SERVER_NAME, server, 0); | ||
1080 | } | ||
1081 | @@ -208,6 +228,18 @@ | ||
1082 | tcpdmatch(&request); | ||
1083 | exit(0); | ||
1084 | } | ||
1085 | +#ifdef INET6 | ||
1086 | + memset(&hints, 0, sizeof(hints)); | ||
1087 | + hints.ai_family = AF_INET6; | ||
1088 | + hints.ai_socktype = SOCK_STREAM; | ||
1089 | + hints.ai_flags = AI_PASSIVE | AI_NUMERICHOST; | ||
1090 | + if (getaddrinfo(client, NULL, &hints, &res) == 0) { | ||
1091 | + freeaddrinfo(res); | ||
1092 | + request_set(&request, RQ_CLIENT_ADDR, client, 0); | ||
1093 | + tcpdmatch(&request); | ||
1094 | + exit(0); | ||
1095 | + } | ||
1096 | +#endif | ||
1097 | |||
1098 | /* | ||
1099 | * Perhaps they are testing special client hostname patterns that aren't | ||
1100 | @@ -229,6 +261,34 @@ | ||
1101 | */ | ||
1102 | if ((hp = find_inet_addr(client)) == 0) | ||
1103 | exit(1); | ||
1104 | +#ifdef INET6 | ||
1105 | + request_set(&request, RQ_CLIENT_SIN, &client_sin, 0); | ||
1106 | + | ||
1107 | + for (res = hp, count = 0; res; res = res->ai_next, count++) { | ||
1108 | + memcpy(&client_sin, res->ai_addr, res->ai_addrlen); | ||
1109 | + | ||
1110 | + /* | ||
1111 | + * getnameinfo() doesn't do reverse lookup against link-local | ||
1112 | + * address. So, we pass through host name evaluation against | ||
1113 | + * such addresses. | ||
1114 | + */ | ||
1115 | + if (res->ai_family != AF_INET6 || | ||
1116 | + !IN6_IS_ADDR_LINKLOCAL(&((struct sockaddr_in6 *)res->ai_addr)->sin6_addr)) { | ||
1117 | + /* | ||
1118 | + * Force evaluation of client host name and address. Host name | ||
1119 | + * conflicts will be reported while eval_hostname() does its job. | ||
1120 | + */ | ||
1121 | + request_set(&request, RQ_CLIENT_NAME, "", RQ_CLIENT_ADDR, "", 0); | ||
1122 | + if (STR_EQ(eval_hostname(request.client), unknown)) | ||
1123 | + tcpd_warn("host address %s->name lookup failed", | ||
1124 | + eval_hostaddr(request.client)); | ||
1125 | + } | ||
1126 | + tcpdmatch(&request); | ||
1127 | + if (res->ai_next) | ||
1128 | + printf("\n"); | ||
1129 | + } | ||
1130 | + freeaddrinfo(hp); | ||
1131 | +#else | ||
1132 | memset((char *) &client_sin, 0, sizeof(client_sin)); | ||
1133 | client_sin.sin_family = AF_INET; | ||
1134 | request_set(&request, RQ_CLIENT_SIN, &client_sin, 0); | ||
1135 | @@ -250,6 +310,7 @@ | ||
1136 | printf("\n"); | ||
1137 | } | ||
1138 | free((char *) hp); | ||
1139 | +#endif | ||
1140 | exit(0); | ||
1141 | } | ||
1142 | |||
1143 | diff -ruN tcp_wrappers_7.6.orig/tli.c tcp_wrappers_7.6/tli.c | ||
1144 | --- tcp_wrappers_7.6.orig/tli.c 1997-03-21 19:27:26.000000000 +0100 | ||
1145 | +++ tcp_wrappers_7.6/tli.c 2004-04-10 19:07:43.000000000 +0200 | ||
1146 | @@ -65,8 +65,13 @@ | ||
1147 | void tli_host(request) | ||
1148 | struct request_info *request; | ||
1149 | { | ||
1150 | +#ifdef INET6 | ||
1151 | + static struct sockaddr_storage client; | ||
1152 | + static struct sockaddr_storage server; | ||
1153 | +#else | ||
1154 | static struct sockaddr_in client; | ||
1155 | static struct sockaddr_in server; | ||
1156 | +#endif | ||
1157 | |||
1158 | /* | ||
1159 | * If we discover that we are using an IP transport, pretend we never | ||
1160 | @@ -76,14 +81,29 @@ | ||
1161 | |||
1162 | tli_endpoints(request); | ||
1163 | if ((request->config = tli_transport(request->fd)) != 0 | ||
1164 | +#ifdef INET6 | ||
1165 | + && (STR_EQ(request->config->nc_protofmly, "inet") || | ||
1166 | + STR_EQ(request->config->nc_protofmly, "inet6"))) { | ||
1167 | +#else | ||
1168 | && STR_EQ(request->config->nc_protofmly, "inet")) { | ||
1169 | +#endif | ||
1170 | if (request->client->unit != 0) { | ||
1171 | +#ifdef INET6 | ||
1172 | + client = *(struct sockaddr_storage *) request->client->unit->addr.buf; | ||
1173 | + request->client->sin = (struct sockaddr *) &client; | ||
1174 | +#else | ||
1175 | client = *(struct sockaddr_in *) request->client->unit->addr.buf; | ||
1176 | request->client->sin = &client; | ||
1177 | +#endif | ||
1178 | } | ||
1179 | if (request->server->unit != 0) { | ||
1180 | +#ifdef INET6 | ||
1181 | + server = *(struct sockaddr_storage *) request->server->unit->addr.buf; | ||
1182 | + request->server->sin = (struct sockaddr *) &server; | ||
1183 | +#else | ||
1184 | server = *(struct sockaddr_in *) request->server->unit->addr.buf; | ||
1185 | request->server->sin = &server; | ||
1186 | +#endif | ||
1187 | } | ||
1188 | tli_cleanup(request); | ||
1189 | sock_methods(request); | ||
1190 | @@ -187,7 +207,15 @@ | ||
1191 | } | ||
1192 | while (config = getnetconfig(handlep)) { | ||
1193 | if (stat(config->nc_device, &from_config) == 0) { | ||
1194 | +#ifdef NO_CLONE_DEVICE | ||
1195 | + /* | ||
1196 | + * If the network devices are not cloned (as is the case for | ||
1197 | + * Solaris 8 Beta), we must compare the major device numbers. | ||
1198 | + */ | ||
1199 | + if (major(from_config.st_rdev) == major(from_client.st_rdev)) | ||
1200 | +#else | ||
1201 | if (minor(from_config.st_rdev) == major(from_client.st_rdev)) | ||
1202 | +#endif | ||
1203 | break; | ||
1204 | } | ||
1205 | } | ||
1206 | diff -ruN tcp_wrappers_7.6.orig/update.c tcp_wrappers_7.6/update.c | ||
1207 | --- tcp_wrappers_7.6.orig/update.c 1994-12-28 17:42:56.000000000 +0100 | ||
1208 | +++ tcp_wrappers_7.6/update.c 2004-04-10 19:07:43.000000000 +0200 | ||
1209 | @@ -46,10 +46,18 @@ | ||
1210 | request->fd = va_arg(ap, int); | ||
1211 | continue; | ||
1212 | case RQ_CLIENT_SIN: | ||
1213 | +#ifdef INET6 | ||
1214 | + request->client->sin = va_arg(ap, struct sockaddr *); | ||
1215 | +#else | ||
1216 | request->client->sin = va_arg(ap, struct sockaddr_in *); | ||
1217 | +#endif | ||
1218 | continue; | ||
1219 | case RQ_SERVER_SIN: | ||
1220 | +#ifdef INET6 | ||
1221 | + request->server->sin = va_arg(ap, struct sockaddr *); | ||
1222 | +#else | ||
1223 | request->server->sin = va_arg(ap, struct sockaddr_in *); | ||
1224 | +#endif | ||
1225 | continue; | ||
1226 | |||
1227 | /* | ||
1228 | diff -ruN tcp_wrappers_7.6.orig/workarounds.c tcp_wrappers_7.6/workarounds.c | ||
1229 | --- tcp_wrappers_7.6.orig/workarounds.c 1996-03-19 16:22:26.000000000 +0100 | ||
1230 | +++ tcp_wrappers_7.6/workarounds.c 2004-04-10 19:07:43.000000000 +0200 | ||
1231 | @@ -166,11 +166,22 @@ | ||
1232 | int *len; | ||
1233 | { | ||
1234 | int ret; | ||
1235 | +#ifdef INET6 | ||
1236 | + struct sockaddr *sin = sa; | ||
1237 | +#else | ||
1238 | struct sockaddr_in *sin = (struct sockaddr_in *) sa; | ||
1239 | +#endif | ||
1240 | |||
1241 | if ((ret = getpeername(sock, sa, len)) >= 0 | ||
1242 | +#ifdef INET6 | ||
1243 | + && ((sin->su_si.si_family == AF_INET6 | ||
1244 | + && IN6_IS_ADDR_UNSPECIFIED(&sin->su_sin6.sin6_addr)) | ||
1245 | + || (sin->su_si.si_family == AF_INET | ||
1246 | + && sin->su_sin.sin_addr.s_addr == 0))) { | ||
1247 | +#else | ||
1248 | && sa->sa_family == AF_INET | ||
1249 | && sin->sin_addr.s_addr == 0) { | ||
1250 | +#endif | ||
1251 | errno = ENOTCONN; | ||
1252 | return (-1); | ||
1253 | } else { | ||