]>
Commit | Line | Data |
---|---|---|
1ce4542c TO |
1 | Note: |
2 | IPv6 support depends on v6-capable getifaddrs() function | |
3 | (i.e. from USAGI libinet6, not glibc) | |
4 | ||
5 | non-getifaddrs v6 support is not complete - network masks | |
6 | are not read, which could cause postfix to act as open-relay | |
7 | (when using mynetworks_style!=host and permit_mynetworks), | |
8 | so I decided to add #errors if getifaddrs is not supported. | |
9 | ||
10 | If you write (correctly working) missing code, please send | |
11 | it to me and I'll add it to patch. | |
12 | ||
13 | Jakub Bogusz <qboosh@pld.org.pl> | |
14 | ||
15 | diff -Nur postfix-2.0.9.orig/makedefs postfix-2.0.9/makedefs | |
16 | --- postfix-2.0.9.orig/makedefs Thu Jan 23 14:45:02 2003 | |
17 | +++ postfix-2.0.9/makedefs Fri Apr 18 20:55:35 2003 | |
23bbf6c1 JB |
18 | @@ -52,6 +52,21 @@ |
19 | SYSTEM=`(uname -s) 2>/dev/null` | |
20 | RELEASE=`(uname -r) 2>/dev/null` | |
21 | VERSION=`(uname -v) 2>/dev/null` | |
22 | +if test -f /usr/include/netinet6/in6.h; then | |
23 | + grep __KAME__ /usr/include/netinet6/in6.h 2>&1 >/dev/null | |
24 | + if [ $? = 1 ]; then | |
25 | + INET6= | |
26 | + else | |
27 | + if [ -f /usr/local/v6/lib/libinet6.a ]; then | |
28 | + INET6=kame | |
29 | + else | |
30 | + INET6=kame-merged | |
31 | + fi | |
32 | + fi | |
33 | +fi | |
34 | +if [ -z "$INET6" -a -f /usr/include/netinet/ip6.h -a -f /usr/include/linux/icmpv6.h ]; then | |
35 | + INET6=linux | |
36 | +fi | |
37 | ||
38 | case "$VERSION" in | |
39 | dcosx*) SYSTEM=$VERSION;; | |
1ce4542c | 40 | @@ -318,6 +333,26 @@ |
23bbf6c1 JB |
41 | |
42 | : ${CC='gcc $(WARN)'} ${OPT='-O'} ${DEBUG='-g'} ${AWK=awk} | |
830ba608 | 43 | |
23bbf6c1 JB |
44 | +case "$INET6" in |
45 | +kame) | |
46 | + CCARGS="$CCARGS -DINET6 -D__ss_family=ss_family -D__ss_len=ss_len" | |
47 | + if test -f /usr/local/v6/lib/libinet6.a; then | |
48 | + SYSLIBS="$SYSLIBS -L/usr/local/v6/lib -linet6" | |
49 | + fi | |
50 | + ;; | |
51 | +kame-merged) | |
52 | + CCARGS="$CCARGS -DINET6 -D__ss_family=ss_family -D__ss_len=ss_len" | |
53 | + ;; | |
54 | +linux) | |
55 | + CCARGS="$CCARGS -DINET6 -D__ss_family=ss_family" | |
56 | + if test -f /usr/include/libinet6/netinet/ip6.h -a \ | |
57 | + -f /usr/lib/libinet6.a; then | |
58 | + CCARGS="$CCARGS -I/usr/include/libinet6 -DUSAGI_LIBINET6" | |
59 | + SYSLIBS="$SYSLIBS -linet6" | |
60 | + fi | |
61 | + ;; | |
62 | +esac | |
830ba608 | 63 | + |
23bbf6c1 JB |
64 | export SYSTYPE AR ARFL RANLIB SYSLIBS CC OPT DEBUG AWK OPTS |
65 | ||
830ba608 | 66 | sed 's/ / /g' <<EOF |
1ce4542c TO |
67 | diff -Nur postfix-2.0.9.orig/src/global/Makefile.in postfix-2.0.9/src/global/Makefile.in |
68 | --- postfix-2.0.9.orig/src/global/Makefile.in Fri Apr 18 20:55:10 2003 | |
69 | +++ postfix-2.0.9/src/global/Makefile.in Fri Apr 18 20:55:35 2003 | |
23bbf6c1 JB |
70 | @@ -19,7 +19,7 @@ |
71 | timed_ipc.c tok822_find.c tok822_node.c tok822_parse.c \ | |
72 | tok822_resolve.c tok822_rewrite.c tok822_tree.c xtext.c bounce_log.c \ | |
73 | flush_clnt.c mail_conf_time.c mbox_conf.c mbox_open.c abounce.c \ | |
7e195e4d TO |
74 | - verp_sender.c match_parent_style.c mime_state.c header_token.c \ |
75 | + verp_sender.c match_parent_style.c mime_state.c header_token.c wildcard_inet_addr.c\ | |
76 | strip_addr.c virtual8_maps.c hold_message.c dict_proxy.c mail_dict.c \ | |
77 | pfixtls.c | |
23bbf6c1 | 78 | OBJS = been_here.o bounce.o canon_addr.o cleanup_strerror.o clnt_stream.o \ |
7e195e4d | 79 | @@ -42,7 +42,7 @@ |
23bbf6c1 JB |
80 | timed_ipc.o tok822_find.o tok822_node.o tok822_parse.o \ |
81 | tok822_resolve.o tok822_rewrite.o tok822_tree.o xtext.o bounce_log.o \ | |
82 | flush_clnt.o mail_conf_time.o mbox_conf.o mbox_open.o abounce.o \ | |
7e195e4d TO |
83 | - verp_sender.o match_parent_style.o mime_state.o header_token.o \ |
84 | + verp_sender.o match_parent_style.o mime_state.o header_token.o wildcard_inet_addr.o\ | |
85 | strip_addr.o virtual8_maps.o hold_message.o dict_proxy.o mail_dict.o \ | |
86 | pfixtls.o | |
23bbf6c1 | 87 | HDRS = been_here.h bounce.h canon_addr.h cleanup_user.h clnt_stream.h \ |
7e195e4d | 88 | @@ -61,7 +61,7 @@ |
23bbf6c1 JB |
89 | rewrite_clnt.h sent.h smtp_stream.h split_addr.h string_list.h \ |
90 | sys_exits.h timed_ipc.h tok822.h xtext.h bounce_log.h flush_clnt.h \ | |
447bfc58 | 91 | mbox_conf.h mbox_open.h abounce.h qmqp_proto.h verp_sender.h \ |
7e195e4d TO |
92 | - match_parent_style.h quote_flags.h mime_state.h header_token.h \ |
93 | + match_parent_style.h quote_flags.h mime_state.h header_token.h wildcard_inet_addr.h\ | |
94 | lex_822.h strip_addr.h virtual8_maps.h hold_message.h dict_proxy.h \ | |
95 | mail_dict.h pfixtls.h | |
23bbf6c1 | 96 | TESTSRC = rec2stream.c stream2rec.c recdump.c |
1ce4542c TO |
97 | diff -Nur postfix-2.0.9.orig/src/global/mynetworks.c postfix-2.0.9/src/global/mynetworks.c |
98 | --- postfix-2.0.9.orig/src/global/mynetworks.c Sun Feb 25 02:46:07 2001 | |
99 | +++ postfix-2.0.9/src/global/mynetworks.c Fri Apr 18 20:55:35 2003 | |
23bbf6c1 JB |
100 | @@ -50,6 +50,11 @@ |
101 | #include <vstring.h> | |
102 | #include <inet_addr_list.h> | |
103 | #include <name_mask.h> | |
104 | +#ifdef INET6 | |
105 | +#include <sys/socket.h> | |
106 | +#include <netinet/in.h> | |
107 | +#include <netdb.h> | |
108 | +#endif | |
109 | ||
110 | /* Global library. */ | |
111 | ||
112 | @@ -75,6 +80,9 @@ | |
113 | const char *mynetworks(void) | |
114 | { | |
115 | static VSTRING *result; | |
116 | +#ifdef INET6 | |
117 | + char hbuf[NI_MAXHOST]; | |
118 | +#endif | |
119 | ||
120 | if (result == 0) { | |
121 | char *myname = "mynetworks"; | |
1ce4542c | 122 | @@ -87,6 +95,13 @@ |
23bbf6c1 JB |
123 | int junk; |
124 | int i; | |
125 | int mask_style; | |
126 | +#ifdef INET6 | |
127 | + struct sockaddr *sa; | |
1ce4542c TO |
128 | + struct sockaddr_in6 *addr6; |
129 | + struct sockaddr_in6 *mask6; | |
130 | + struct in6_addr net6; | |
131 | + int j; | |
23bbf6c1 JB |
132 | +#endif |
133 | ||
134 | mask_style = name_mask("mynetworks mask style", mask_styles, | |
135 | var_mynetworks_style); | |
1ce4542c | 136 | @@ -96,8 +111,45 @@ |
23bbf6c1 JB |
137 | my_mask_list = own_inet_mask_list(); |
138 | ||
139 | for (i = 0; i < my_addr_list->used; i++) { | |
140 | +#ifdef INET6 | |
141 | + sa = (struct sockaddr *)&my_addr_list->addrs[i]; | |
1ce4542c TO |
142 | + if (sa->sa_family == AF_INET6) { |
143 | + addr6 = (struct sockaddr_in6 *)sa; | |
144 | + mask6 = (struct sockaddr_in6 *)&my_mask_list->addrs[i]; | |
145 | + | |
146 | + switch (mask_style) { | |
147 | + case MASK_STYLE_CLASS: | |
148 | + /* treat as subnet for IPv6 */ | |
149 | + case MASK_STYLE_SUBNET: | |
150 | + for (j=0; j<16; j++) | |
151 | + net6.s6_addr[j] = addr6->sin6_addr.s6_addr[j] & mask6->sin6_addr.s6_addr[j]; | |
152 | + for(shift=128; shift>0; shift--) | |
153 | + if ((mask6->sin6_addr.s6_addr[(shift-1) / 8]) & (0x80 >> ((shift-1) % 8))) | |
154 | + break; | |
155 | + break; | |
156 | + case MASK_STYLE_HOST: | |
157 | + memcpy (&net6, &(addr6->sin6_addr), sizeof(net6)); | |
158 | + shift=128; | |
159 | + break; | |
160 | + default: | |
161 | + msg_panic("unknown mynetworks mask style: %s", | |
162 | + var_mynetworks_style); | |
163 | + } | |
164 | + inet_ntop(AF_INET6, &net6, hbuf, sizeof(hbuf)); | |
165 | + if (!shift) | |
166 | + msg_warn("%s: skipped network with zero mask: [%s/0]", myname, hbuf); | |
167 | + else | |
168 | + vstring_sprintf_append(result, "[%s/%d] ", hbuf, shift); | |
169 | + continue; | |
170 | + } else if (sa->sa_family != AF_INET) { | |
23bbf6c1 JB |
171 | + continue; |
172 | + } | |
173 | + addr = ntohl(((struct sockaddr_in *)sa)->sin_addr.s_addr); | |
174 | + mask = ntohl(((struct sockaddr_in *)&my_mask_list->addrs[i])->sin_addr.s_addr); | |
175 | +#else | |
176 | addr = ntohl(my_addr_list->addrs[i].s_addr); | |
177 | mask = ntohl(my_mask_list->addrs[i].s_addr); | |
178 | +#endif | |
179 | ||
180 | switch (mask_style) { | |
181 | ||
1ce4542c | 182 | @@ -119,8 +171,15 @@ |
23bbf6c1 JB |
183 | mask = IN_CLASSD_NET; |
184 | shift = IN_CLASSD_NSHIFT; | |
185 | } else { | |
186 | +#ifdef INET6 | |
187 | + if (getnameinfo(sa, SA_LEN(sa), hbuf, sizeof(hbuf), NULL, 0, | |
188 | + NI_NUMERICHOST)) | |
189 | + strncpy(hbuf, "???", sizeof(hbuf)); | |
190 | + msg_fatal("%s: bad address class: %s", myname, hbuf); | |
191 | +#else | |
192 | msg_fatal("%s: bad address class: %s", | |
193 | myname, inet_ntoa(my_addr_list->addrs[i])); | |
194 | +#endif | |
195 | } | |
196 | break; | |
197 | ||
1ce4542c TO |
198 | @@ -146,6 +205,18 @@ |
199 | var_mynetworks_style); | |
200 | } | |
201 | net.s_addr = htonl(addr & mask); | |
202 | + if (shift == BITS_PER_ADDR) { | |
203 | +#ifdef INET6 | |
204 | + if (getnameinfo(sa, SA_LEN(sa), hbuf, sizeof(hbuf), NULL, 0, | |
205 | + NI_NUMERICHOST)) | |
206 | + strncpy(hbuf, "???", sizeof(hbuf)); | |
207 | + msg_warn("%s: skipped network with zero mask: %s/0", myname, hbuf); | |
208 | +#else | |
209 | + msg_warn("%s: skipped network with zero mask: %s/0", | |
210 | + myname, inet_ntoa(my_addr_list->addrs[i])); | |
211 | +#endif | |
212 | + continue; | |
213 | + } | |
214 | vstring_sprintf_append(result, "%s/%d ", | |
215 | inet_ntoa(net), BITS_PER_ADDR - shift); | |
216 | } | |
217 | diff -Nur postfix-2.0.9.orig/src/global/own_inet_addr.c postfix-2.0.9/src/global/own_inet_addr.c | |
218 | --- postfix-2.0.9.orig/src/global/own_inet_addr.c Fri Oct 25 01:19:19 2002 | |
219 | +++ postfix-2.0.9/src/global/own_inet_addr.c Fri Apr 18 20:55:35 2003 | |
220 | @@ -50,6 +50,10 @@ | |
23bbf6c1 JB |
221 | #include <netinet/in.h> |
222 | #include <arpa/inet.h> | |
223 | #include <string.h> | |
224 | +#ifdef INET6 | |
225 | +#include <sys/socket.h> | |
226 | +#include <netdb.h> | |
227 | +#endif | |
228 | ||
229 | #ifdef STRCASECMP_IN_STRINGS_H | |
230 | #include <strings.h> | |
1ce4542c | 231 | @@ -113,10 +117,11 @@ |
23bbf6c1 JB |
232 | */ |
233 | else { | |
234 | bufp = hosts = mystrdup(var_inet_interfaces); | |
235 | - while ((host = mystrtok(&bufp, sep)) != 0) | |
236 | + while ((host = mystrtok(&bufp, sep)) != 0) { | |
237 | if (inet_addr_host(addr_list, host) == 0) | |
238 | msg_fatal("config variable %s: host not found: %s", | |
239 | VAR_INET_INTERFACES, host); | |
240 | + } | |
241 | myfree(hosts); | |
242 | ||
35140025 | 243 | /* |
1ce4542c | 244 | @@ -133,15 +138,39 @@ |
23bbf6c1 JB |
245 | msg_fatal("could not find any active network interfaces"); |
246 | for (nvirtual = 0; nvirtual < addr_list->used; nvirtual++) { | |
247 | for (nlocal = 0; /* see below */ ; nlocal++) { | |
248 | - if (nlocal >= local_addrs.used) | |
249 | + if (nlocal >= local_addrs.used) { | |
250 | +#ifdef INET6 | |
251 | + char hbuf[NI_MAXHOST]; | |
252 | + if (getnameinfo((struct sockaddr *)&addr_list->addrs[nvirtual], | |
253 | + SS_LEN(addr_list->addrs[nvirtual]), hbuf, | |
254 | + sizeof(hbuf), NULL, 0, NI_NUMERICHOST) != 0) | |
255 | + strncpy(hbuf, "???", sizeof(hbuf)); | |
256 | + msg_fatal("parameter %s: no local interface found for %s", | |
257 | + VAR_INET_INTERFACES, hbuf); | |
258 | +#else | |
259 | msg_fatal("parameter %s: no local interface found for %s", | |
260 | VAR_INET_INTERFACES, | |
261 | inet_ntoa(addr_list->addrs[nvirtual])); | |
262 | +#endif | |
263 | + } | |
264 | +#ifdef INET6 | |
265 | + if (addr_list->addrs[nvirtual].ss_family == | |
266 | + local_addrs.addrs[nlocal].ss_family && | |
267 | + SS_LEN(addr_list->addrs[nvirtual]) == | |
268 | + SS_LEN(local_addrs.addrs[nlocal]) && | |
269 | + memcmp(&addr_list->addrs[nvirtual], | |
270 | + &local_addrs.addrs[nlocal], | |
271 | + SS_LEN(local_addrs.addrs[nlocal])) == 0) { | |
272 | + inet_addr_list_append(mask_list, (struct sockaddr *)&local_masks.addrs[nlocal]); | |
273 | + break; | |
274 | + } | |
275 | +#else | |
276 | if (addr_list->addrs[nvirtual].s_addr | |
277 | == local_addrs.addrs[nlocal].s_addr) { | |
278 | inet_addr_list_append(mask_list, &local_masks.addrs[nlocal]); | |
279 | break; | |
280 | } | |
281 | +#endif | |
282 | } | |
283 | } | |
284 | inet_addr_list_free(&local_addrs); | |
1ce4542c | 285 | @@ -151,6 +180,42 @@ |
23bbf6c1 JB |
286 | |
287 | /* own_inet_addr - is this my own internet address */ | |
288 | ||
289 | +#ifdef INET6 | |
290 | +int own_inet_addr(struct sockaddr * addr) | |
291 | +{ | |
292 | + int i; | |
293 | + char *p, *q; | |
294 | + int l; | |
295 | + struct sockaddr *sa; | |
296 | + | |
297 | + if (addr_list.used == 0) | |
298 | + own_inet_addr_init(&addr_list, &mask_list); | |
299 | + | |
300 | + for (i = 0; i < addr_list.used; i++) { | |
301 | + sa = (struct sockaddr *)&addr_list.addrs[i]; | |
302 | + if (addr->sa_family != sa->sa_family) | |
303 | + continue; | |
304 | + switch (addr->sa_family) { | |
305 | + case AF_INET: | |
306 | + p = (char *)&((struct sockaddr_in *)addr)->sin_addr; | |
307 | + q = (char *)&((struct sockaddr_in *)&addr_list.addrs[i])->sin_addr; | |
308 | + l = sizeof(struct in_addr); | |
309 | + break; | |
310 | + case AF_INET6: | |
311 | + /* XXX scope */ | |
312 | + p = (char *)&((struct sockaddr_in6 *)addr)->sin6_addr; | |
313 | + q = (char *)&((struct sockaddr_in6 *)&addr_list.addrs[i])->sin6_addr; | |
314 | + l = sizeof(struct in6_addr); | |
315 | + break; | |
316 | + default: | |
317 | + continue; | |
318 | + } | |
319 | + if (memcmp(p, q, l) == 0) | |
320 | + return (1); | |
321 | + } | |
322 | + return (0); | |
323 | +} | |
324 | +#else | |
325 | int own_inet_addr(struct in_addr * addr) | |
326 | { | |
327 | int i; | |
1ce4542c | 328 | @@ -161,8 +226,8 @@ |
23bbf6c1 JB |
329 | for (i = 0; i < addr_list.used; i++) |
330 | if (addr->s_addr == addr_list.addrs[i].s_addr) | |
331 | return (1); | |
332 | - return (0); | |
333 | } | |
334 | +#endif | |
335 | ||
336 | /* own_inet_addr_list - return list of addresses */ | |
337 | ||
9d0b6835 TO |
338 | @@ -213,6 +278,45 @@ |
339 | ||
340 | /* proxy_inet_addr - is this my proxy internet address */ | |
341 | ||
342 | +#ifdef INET6 | |
343 | +int proxy_inet_addr(struct sockaddr * addr) | |
344 | +{ | |
345 | + int i; | |
346 | + char *p, *q; | |
347 | + int l; | |
348 | + struct sockaddr *sa; | |
349 | + | |
350 | + if (*var_proxy_interfaces == 0) | |
351 | + return (0); | |
352 | + | |
353 | + if (proxy_list.used == 0) | |
354 | + proxy_inet_addr_init(&proxy_list); | |
355 | + | |
356 | + for (i = 0; i < proxy_list.used; i++) { | |
357 | + sa = (struct sockaddr *)&proxy_list.addrs[i]; | |
358 | + if (addr->sa_family != sa->sa_family) | |
359 | + continue; | |
360 | + switch (addr->sa_family) { | |
361 | + case AF_INET: | |
362 | + p = (char *)&((struct sockaddr_in *)addr)->sin_addr; | |
363 | + q = (char *)&((struct sockaddr_in *)&addr_list.addrs[i])->sin_addr; | |
364 | + l = sizeof(struct in_addr); | |
365 | + break; | |
366 | + case AF_INET6: | |
367 | + /* XXX scope */ | |
368 | + p = (char *)&((struct sockaddr_in6 *)addr)->sin6_addr; | |
369 | + q = (char *)&((struct sockaddr_in6 *)&addr_list.addrs[i])->sin6_addr; | |
370 | + l = sizeof(struct in6_addr); | |
371 | + break; | |
372 | + default: | |
373 | + continue; | |
374 | + } | |
375 | + if (memcmp(p, q, l) == 0) | |
376 | + return (1); | |
377 | + } | |
378 | + return (0); | |
379 | +} | |
380 | +#else | |
381 | int proxy_inet_addr(struct in_addr * addr) | |
382 | { | |
383 | int i; | |
384 | @@ -228,6 +332,7 @@ | |
385 | return (1); | |
386 | return (0); | |
387 | } | |
388 | +#endif | |
389 | ||
390 | /* proxy_inet_addr_list - return list of addresses */ | |
391 | ||
1ce4542c TO |
392 | diff -Nur postfix-2.0.9.orig/src/global/own_inet_addr.h postfix-2.0.9/src/global/own_inet_addr.h |
393 | --- postfix-2.0.9.orig/src/global/own_inet_addr.h Fri Oct 25 01:07:05 2002 | |
394 | +++ postfix-2.0.9/src/global/own_inet_addr.h Fri Apr 18 20:55:35 2003 | |
cc66c172 | 395 | @@ -15,14 +15,25 @@ |
23bbf6c1 JB |
396 | * System library. |
397 | */ | |
398 | #include <netinet/in.h> | |
399 | +#ifdef INET6 | |
400 | +#include <sys/socket.h> | |
401 | +#endif | |
402 | ||
403 | /* | |
404 | * External interface. | |
405 | */ | |
406 | +#ifdef INET6 | |
407 | +extern int own_inet_addr(struct sockaddr *); | |
408 | +#else | |
409 | extern int own_inet_addr(struct in_addr *); | |
410 | +#endif | |
411 | extern struct INET_ADDR_LIST *own_inet_addr_list(void); | |
412 | extern struct INET_ADDR_LIST *own_inet_mask_list(void); | |
cc66c172 TO |
413 | +#ifdef INET6 |
414 | +extern int proxy_inet_addr(struct sockaddr *); | |
415 | +#else | |
416 | extern int proxy_inet_addr(struct in_addr *); | |
417 | +#endif | |
418 | extern struct INET_ADDR_LIST *proxy_inet_addr_list(void); | |
23bbf6c1 | 419 | |
cc66c172 | 420 | /* LICENSE |
1ce4542c TO |
421 | diff -Nur postfix-2.0.9.orig/src/global/peer_name.c postfix-2.0.9/src/global/peer_name.c |
422 | --- postfix-2.0.9.orig/src/global/peer_name.c Sun Jan 28 16:23:02 2001 | |
423 | +++ postfix-2.0.9/src/global/peer_name.c Fri Apr 18 20:55:35 2003 | |
23bbf6c1 JB |
424 | @@ -69,12 +69,32 @@ |
425 | PEER_NAME *peer_name(int sock) | |
426 | { | |
427 | static PEER_NAME peer; | |
428 | - struct sockaddr_in sin; | |
429 | - SOCKADDR_SIZE len = sizeof(sin); | |
430 | + union sockunion { | |
431 | + struct { | |
432 | + u_char si_len; | |
433 | + u_char si_family; | |
434 | + u_short si_port; | |
435 | + } su_si; | |
436 | + struct sockaddr peer_un; | |
437 | + struct sockaddr_in peer_un4; | |
438 | +#ifdef INET6 | |
439 | + struct sockaddr_in6 peer_un6; | |
440 | +#endif | |
441 | + } p_un; | |
442 | +#define sun p_un.peer_un | |
443 | +#define sin p_un.peer_un4 | |
444 | +#ifdef INET6 | |
445 | +#define sin6 p_un.peer_un6 | |
446 | + static char hbuf[NI_MAXHOST]; | |
447 | + static char abuf[NI_MAXHOST]; | |
448 | +#else | |
449 | struct hostent *hp; | |
450 | +#endif | |
451 | + SOCKADDR_SIZE len = sizeof(p_un); | |
452 | ||
453 | - if (getpeername(sock, (struct sockaddr *) & sin, &len) == 0) { | |
454 | - switch (sin.sin_family) { | |
455 | + if (getpeername(sock, (struct sockaddr *)&p_un, &len) == 0) { | |
456 | + switch (p_un.peer_un.sa_family) { | |
457 | +#ifndef INET6 | |
458 | case AF_INET: | |
459 | peer.type = PEER_TYPE_INET; | |
460 | hp = gethostbyaddr((char *) &(sin.sin_addr), | |
461 | @@ -83,6 +103,24 @@ | |
462 | hp->h_name : "unknown"); | |
463 | peer.addr = inet_ntoa(sin.sin_addr); | |
464 | return (&peer); | |
465 | +#else | |
466 | + case AF_INET: | |
467 | + peer.type = PEER_TYPE_INET; | |
468 | + if (getnameinfo(&sun, len, hbuf, sizeof(hbuf), NULL, 0, NI_NAMEREQD) != 0) | |
469 | + peer.name = "unknown"; | |
470 | + else | |
471 | + peer.name = hbuf; | |
472 | + peer.addr = abuf; | |
473 | + return (&peer); | |
474 | + case AF_INET6: | |
475 | + peer.type = PEER_TYPE_INET6; | |
476 | + if (getnameinfo(&sun, len, hbuf, sizeof(hbuf), NULL, 0, NI_NAMEREQD) != 0) | |
477 | + peer.name = "unknown"; | |
478 | + else | |
479 | + peer.name = hbuf; | |
480 | + peer.addr = abuf; | |
481 | + return (&peer); | |
482 | +#endif | |
483 | case AF_UNSPEC: | |
484 | case AF_UNIX: | |
485 | peer.type = PEER_TYPE_LOCAL; | |
1ce4542c TO |
486 | diff -Nur postfix-2.0.9.orig/src/global/peer_name.h postfix-2.0.9/src/global/peer_name.h |
487 | --- postfix-2.0.9.orig/src/global/peer_name.h Fri Dec 11 19:55:32 1998 | |
488 | +++ postfix-2.0.9/src/global/peer_name.h Fri Apr 18 20:55:35 2003 | |
23bbf6c1 JB |
489 | @@ -22,6 +22,9 @@ |
490 | #define PEER_TYPE_UNKNOWN 0 | |
491 | #define PEER_TYPE_INET 1 | |
492 | #define PEER_TYPE_LOCAL 2 | |
493 | +#ifdef INET6 | |
494 | +#define PEER_TYPE_INET6 3 | |
495 | +#endif | |
496 | ||
497 | extern PEER_NAME *peer_name(int); | |
498 | ||
1ce4542c TO |
499 | diff -Nur postfix-2.0.9.orig/src/global/resolve_local.c postfix-2.0.9/src/global/resolve_local.c |
500 | --- postfix-2.0.9.orig/src/global/resolve_local.c Fri Oct 25 01:21:20 2002 | |
501 | +++ postfix-2.0.9/src/global/resolve_local.c Fri Apr 18 20:55:35 2003 | |
502 | @@ -43,6 +43,7 @@ | |
23bbf6c1 JB |
503 | #include <netinet/in.h> |
504 | #include <arpa/inet.h> | |
505 | #include <string.h> | |
506 | +#include <netdb.h> | |
507 | ||
508 | #ifndef INADDR_NONE | |
509 | #define INADDR_NONE 0xffffffff | |
1ce4542c | 510 | @@ -80,7 +81,12 @@ |
23bbf6c1 JB |
511 | { |
512 | char *saved_addr = mystrdup(addr); | |
513 | char *dest; | |
514 | +#ifdef INET6 | |
515 | + struct addrinfo hints, *res, *res0; | |
516 | + int error; | |
517 | +#else | |
518 | struct in_addr ipaddr; | |
519 | +#endif | |
520 | int len; | |
521 | ||
522 | #define RETURN(x) { myfree(saved_addr); return(x); } | |
7e195e4d | 523 | @@ -118,9 +124,25 @@ |
23bbf6c1 JB |
524 | if (*dest == '[' && dest[len - 1] == ']') { |
525 | dest++; | |
526 | dest[len -= 2] = 0; | |
527 | +#ifdef INET6 | |
528 | + memset(&hints, 0, sizeof(hints)); | |
529 | + hints.ai_family = PF_UNSPEC; | |
530 | + hints.ai_socktype = SOCK_DGRAM; | |
531 | + error = getaddrinfo(dest, NULL, &hints, &res0); | |
532 | + if (!error) { | |
533 | + for (res = res0; res; res = res->ai_next) { | |
534 | + if (own_inet_addr(res->ai_addr)) { | |
535 | + freeaddrinfo(res0); | |
536 | + RETURN(1); | |
537 | + } | |
538 | + } | |
539 | + freeaddrinfo(res0); | |
540 | + } | |
541 | +#else | |
542 | if ((ipaddr.s_addr = inet_addr(dest)) != INADDR_NONE | |
7e195e4d | 543 | && (own_inet_addr(&ipaddr) || proxy_inet_addr(&ipaddr))) |
23bbf6c1 JB |
544 | RETURN(1); |
545 | +#endif | |
546 | } | |
547 | ||
548 | /* | |
1ce4542c TO |
549 | diff -Nur postfix-2.0.9.orig/src/global/wildcard_inet_addr.c postfix-2.0.9/src/global/wildcard_inet_addr.c |
550 | --- postfix-2.0.9.orig/src/global/wildcard_inet_addr.c Thu Jan 1 01:00:00 1970 | |
551 | +++ postfix-2.0.9/src/global/wildcard_inet_addr.c Fri Apr 18 20:55:35 2003 | |
23bbf6c1 JB |
552 | @@ -0,0 +1,82 @@ |
553 | +/* System library. */ | |
554 | + | |
555 | +#include <sys_defs.h> | |
556 | +#include <netinet/in.h> | |
557 | +#include <arpa/inet.h> | |
558 | +#include <string.h> | |
559 | +#ifdef INET6 | |
560 | +#include <sys/socket.h> | |
561 | +#endif | |
562 | +#include <netdb.h> | |
563 | + | |
564 | +#ifdef STRCASECMP_IN_STRINGS_H | |
565 | +#include <strings.h> | |
566 | +#endif | |
567 | + | |
568 | +/* Utility library. */ | |
569 | + | |
570 | +#include <msg.h> | |
571 | +#include <mymalloc.h> | |
572 | +#include <inet_addr_list.h> | |
573 | +#include <inet_addr_local.h> | |
574 | +#include <inet_addr_host.h> | |
575 | +#include <stringops.h> | |
576 | + | |
577 | +/* Global library. */ | |
578 | + | |
579 | +#include <mail_params.h> | |
580 | +#include <wildcard_inet_addr.h> | |
581 | + | |
582 | +/* Application-specific. */ | |
583 | +static INET_ADDR_LIST addr_list; | |
584 | + | |
585 | +/* wildcard_inet_addr_init - initialize my own address list */ | |
586 | + | |
587 | +static void wildcard_inet_addr_init(INET_ADDR_LIST *addr_list) | |
588 | +{ | |
589 | +#ifdef INET6 | |
590 | + struct addrinfo hints, *res, *res0; | |
591 | + char hbuf[NI_MAXHOST]; | |
592 | + int error; | |
593 | +#ifdef NI_WITHSCOPEID | |
594 | + const int niflags = NI_NUMERICHOST | NI_WITHSCOPEID; | |
595 | +#else | |
596 | + const int niflags = NI_NUMERICHOST; | |
597 | +#endif | |
598 | + | |
599 | + inet_addr_list_init(addr_list); | |
600 | + | |
601 | + memset(&hints, 0, sizeof(hints)); | |
602 | + hints.ai_family = PF_UNSPEC; | |
603 | + hints.ai_socktype = SOCK_STREAM; | |
604 | + hints.ai_flags = AI_PASSIVE; | |
605 | + error = getaddrinfo(NULL, "0", &hints, &res0); | |
606 | + if (error) | |
607 | + msg_fatal("could not get list of wildcard addresses"); | |
608 | + for (res = res0; res; res = res->ai_next) { | |
609 | + if (res->ai_family != AF_INET && res->ai_family != AF_INET6) | |
610 | + continue; | |
611 | + if (getnameinfo(res->ai_addr, res->ai_addrlen, hbuf, sizeof(hbuf), | |
612 | + NULL, 0, niflags) != 0) | |
613 | + continue; | |
614 | + if (inet_addr_host(addr_list, hbuf) == 0) | |
615 | + continue; /* msg_fatal("config variable %s: host not found: %s", | |
616 | + VAR_INET_INTERFACES, hbuf); */ | |
617 | + } | |
618 | + freeaddrinfo(res0); | |
619 | +#else | |
620 | + if (inet_addr_host(addr_list, "0.0.0.0") == 0) | |
621 | + msg_fatal("config variable %s: host not found: %s", | |
622 | + VAR_INET_INTERFACES, "0.0.0.0"); | |
623 | +#endif | |
624 | +} | |
625 | + | |
626 | +/* wildcard_inet_addr_list - return list of addresses */ | |
627 | + | |
628 | +INET_ADDR_LIST *wildcard_inet_addr_list(void) | |
629 | +{ | |
630 | + if (addr_list.used == 0) | |
631 | + wildcard_inet_addr_init(&addr_list); | |
632 | + | |
633 | + return (&addr_list); | |
634 | +} | |
1ce4542c TO |
635 | diff -Nur postfix-2.0.9.orig/src/global/wildcard_inet_addr.h postfix-2.0.9/src/global/wildcard_inet_addr.h |
636 | --- postfix-2.0.9.orig/src/global/wildcard_inet_addr.h Thu Jan 1 01:00:00 1970 | |
637 | +++ postfix-2.0.9/src/global/wildcard_inet_addr.h Fri Apr 18 20:55:35 2003 | |
23bbf6c1 JB |
638 | @@ -0,0 +1,36 @@ |
639 | +#ifndef _WILDCARD_INET_ADDR_H_INCLUDED_ | |
640 | +#define _WILDCARD_INET_ADDR_H_INCLUDED_ | |
641 | + | |
642 | +/*++ | |
643 | +/* NAME | |
644 | +/* wildcard_inet_addr_list 3h | |
645 | +/* SUMMARY | |
646 | +/* grab the list of wildcard IP addresses. | |
647 | +/* SYNOPSIS | |
648 | +/* #include <own_inet_addr.h> | |
649 | +/* DESCRIPTION | |
650 | +/* .nf | |
651 | +/*--*/ | |
652 | + | |
653 | + /* | |
654 | + * System library. | |
655 | + */ | |
656 | +#include <netinet/in.h> | |
657 | +#ifdef INET6 | |
658 | +#include <sys/socket.h> | |
659 | +#endif | |
660 | + | |
661 | + /* | |
662 | + * External interface. | |
663 | + */ | |
664 | +extern struct INET_ADDR_LIST *wildcard_inet_addr_list(void); | |
665 | + | |
666 | +/* LICENSE | |
667 | +/* .ad | |
668 | +/* .fi | |
669 | +/* foo | |
670 | +/* AUTHOR(S) | |
671 | +/* Jun-ichiro itojun Hagino | |
672 | +/*--*/ | |
673 | + | |
674 | +#endif | |
1ce4542c TO |
675 | diff -Nur postfix-2.0.9.orig/src/master/master_ent.c postfix-2.0.9/src/master/master_ent.c |
676 | --- postfix-2.0.9.orig/src/master/master_ent.c Mon Jan 13 01:25:39 2003 | |
677 | +++ postfix-2.0.9/src/master/master_ent.c Fri Apr 18 20:55:35 2003 | |
678 | @@ -285,8 +285,13 @@ | |
679 | inet_addr_list_uniq(MASTER_INET_ADDRLIST(serv)); | |
23bbf6c1 JB |
680 | serv->listen_fd_count = MASTER_INET_ADDRLIST(serv)->used; |
681 | } else if (strcasecmp(var_inet_interfaces, DEF_INET_INTERFACES) == 0) { | |
682 | +#ifdef INET6 | |
683 | + MASTER_INET_ADDRLIST(serv) = wildcard_inet_addr_list(); | |
684 | + serv->listen_fd_count = MASTER_INET_ADDRLIST(serv)->used; | |
685 | +#else | |
686 | MASTER_INET_ADDRLIST(serv) = 0; /* wild-card */ | |
687 | serv->listen_fd_count = 1; | |
688 | +#endif | |
689 | } else { | |
690 | MASTER_INET_ADDRLIST(serv) = own_inet_addr_list(); /* virtual */ | |
1ce4542c TO |
691 | inet_addr_list_uniq(MASTER_INET_ADDRLIST(serv)); |
692 | diff -Nur postfix-2.0.9.orig/src/master/master_listen.c postfix-2.0.9/src/master/master_listen.c | |
693 | --- postfix-2.0.9.orig/src/master/master_listen.c Tue May 1 00:47:57 2001 | |
694 | +++ postfix-2.0.9/src/master/master_listen.c Fri Apr 18 20:55:35 2003 | |
e38d57a7 | 695 | @@ -64,13 +64,22 @@ |
23bbf6c1 JB |
696 | |
697 | #include "master.h" | |
698 | ||
699 | +#ifdef INET6 | |
700 | +#include <netdb.h> | |
701 | +#include <stdio.h> | |
702 | +#endif | |
703 | + | |
704 | /* master_listen_init - enable connection requests */ | |
705 | ||
706 | void master_listen_init(MASTER_SERV *serv) | |
e38d57a7 | 707 | { |
23bbf6c1 JB |
708 | char *myname = "master_listen_init"; |
709 | char *end_point; | |
e38d57a7 JB |
710 | - int n; |
711 | + int n,m,tmpfd; | |
23bbf6c1 JB |
712 | +#ifdef INET6 |
713 | + char hbuf[NI_MAXHOST]; | |
714 | + SOCKADDR_SIZE salen; | |
715 | +#endif | |
716 | ||
717 | /* | |
718 | * Find out what transport we should use, then create one or more | |
e38d57a7 JB |
719 | @@ -111,18 +120,31 @@ |
720 | serv->listen_fd[0] = | |
721 | inet_listen(MASTER_INET_PORT(serv), | |
722 | serv->max_proc > var_proc_limit ? | |
723 | - serv->max_proc : var_proc_limit, NON_BLOCKING); | |
724 | + serv->max_proc : var_proc_limit, NON_BLOCKING, 1); | |
23bbf6c1 JB |
725 | close_on_exec(serv->listen_fd[0], CLOSE_ON_EXEC); |
726 | } else { /* virtual or host:port */ | |
e38d57a7 JB |
727 | - for (n = 0; n < serv->listen_fd_count; n++) { |
728 | + for (m = n = 0; n < serv->listen_fd_count; n++) { | |
23bbf6c1 JB |
729 | +#ifdef INET6 |
730 | + if (getnameinfo((struct sockaddr *)&MASTER_INET_ADDRLIST(serv)->addrs[n], | |
731 | + SA_LEN((struct sockaddr *)&MASTER_INET_ADDRLIST(serv)->addrs[n]), | |
732 | + hbuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST)) { | |
733 | + strncpy(hbuf, "?????", sizeof(hbuf)); | |
734 | + } | |
735 | + end_point = concatenate(hbuf, ":", MASTER_INET_PORT(serv), (char *) 0); | |
736 | +#else | |
737 | end_point = concatenate(inet_ntoa(MASTER_INET_ADDRLIST(serv)->addrs[n]), | |
738 | ":", MASTER_INET_PORT(serv), (char *) 0); | |
e38d57a7 | 739 | - serv->listen_fd[n] |
23bbf6c1 | 740 | +#endif |
e38d57a7 | 741 | + tmpfd |
23bbf6c1 | 742 | = inet_listen(end_point, serv->max_proc > var_proc_limit ? |
e38d57a7 JB |
743 | - serv->max_proc : var_proc_limit, NON_BLOCKING); |
744 | - close_on_exec(serv->listen_fd[n], CLOSE_ON_EXEC); | |
745 | + serv->max_proc : var_proc_limit, NON_BLOCKING, 0); | |
746 | + if (tmpfd >= 0) { | |
747 | + serv->listen_fd[m] = tmpfd; | |
748 | + close_on_exec(serv->listen_fd[m++], CLOSE_ON_EXEC); | |
749 | + } | |
750 | myfree(end_point); | |
751 | } | |
752 | + serv->listen_fd_count=m; | |
753 | } | |
754 | break; | |
755 | default: | |
1ce4542c TO |
756 | diff -Nur postfix-2.0.9.orig/src/smtp/Makefile.in postfix-2.0.9/src/smtp/Makefile.in |
757 | --- postfix-2.0.9.orig/src/smtp/Makefile.in Fri Apr 18 20:55:10 2003 | |
758 | +++ postfix-2.0.9/src/smtp/Makefile.in Fri Apr 18 20:55:35 2003 | |
759 | @@ -143,6 +143,7 @@ | |
23bbf6c1 JB |
760 | smtp_connect.o: ../../include/mail_params.h |
761 | smtp_connect.o: ../../include/own_inet_addr.h | |
762 | smtp_connect.o: ../../include/dns.h | |
763 | +smtp_connect.o: ../../include/get_port.h | |
764 | smtp_connect.o: smtp.h | |
765 | smtp_connect.o: ../../include/argv.h | |
766 | smtp_connect.o: ../../include/deliver_request.h | |
1ce4542c TO |
767 | diff -Nur postfix-2.0.9.orig/src/smtp/smtp_addr.c postfix-2.0.9/src/smtp/smtp_addr.c |
768 | --- postfix-2.0.9.orig/src/smtp/smtp_addr.c Fri Oct 25 01:03:11 2002 | |
769 | +++ postfix-2.0.9/src/smtp/smtp_addr.c Fri Apr 18 20:55:35 2003 | |
35140025 | 770 | @@ -134,18 +134,68 @@ |
23bbf6c1 JB |
771 | static void smtp_print_addr(char *what, DNS_RR *addr_list) |
772 | { | |
773 | DNS_RR *addr; | |
774 | - struct in_addr in_addr; | |
775 | +#ifdef INET6 | |
776 | + struct sockaddr_storage ss; | |
777 | +#else | |
778 | + struct sockaddr ss; | |
779 | +#endif | |
780 | + struct sockaddr_in *sin; | |
781 | +#ifdef INET6 | |
782 | + struct sockaddr_in6 *sin6; | |
783 | + char hbuf[NI_MAXHOST]; | |
784 | +#else | |
785 | + char hbuf[sizeof("255.255.255.255") + 1]; | |
786 | +#endif | |
787 | ||
788 | msg_info("begin %s address list", what); | |
789 | for (addr = addr_list; addr; addr = addr->next) { | |
790 | - if (addr->data_len > sizeof(addr)) { | |
791 | - msg_warn("skipping address length %d", addr->data_len); | |
792 | - } else { | |
793 | - memcpy((char *) &in_addr, addr->data, sizeof(in_addr)); | |
794 | - msg_info("pref %4d host %s/%s", | |
795 | - addr->pref, addr->name, | |
796 | - inet_ntoa(in_addr)); | |
797 | + if (addr->class != C_IN) { | |
798 | + msg_warn("skipping unsupported address (class=%u)", addr->class); | |
799 | + continue; | |
800 | } | |
801 | + switch (addr->type) { | |
802 | + case T_A: | |
803 | + if (addr->data_len != sizeof(sin->sin_addr)) { | |
804 | + msg_warn("skipping invalid address (AAAA, len=%u)", | |
805 | + addr->data_len); | |
806 | + continue; | |
807 | + } | |
808 | + sin = (struct sockaddr_in *)&ss; | |
809 | + memset(sin, 0, sizeof(*sin)); | |
810 | + sin->sin_family = AF_INET; | |
811 | +#ifdef HAS_SA_LEN | |
812 | + sin->sin_len = sizeof(*sin); | |
813 | +#endif | |
814 | + memcpy(&sin->sin_addr, addr->data, sizeof(sin->sin_addr)); | |
815 | + break; | |
816 | +#ifdef INET6 | |
817 | + case T_AAAA: | |
818 | + if (addr->data_len != sizeof(sin6->sin6_addr)) { | |
819 | + msg_warn("skipping invalid address (AAAA, len=%u)", | |
820 | + addr->data_len); | |
821 | + continue; | |
822 | + } | |
823 | + sin6 = (struct sockaddr_in6 *)&ss; | |
824 | + memset(sin6, 0, sizeof(*sin6)); | |
825 | + sin6->sin6_family = AF_INET6; | |
826 | +#ifdef HAS_SA_LEN | |
827 | + sin6->sin6_len = sizeof(*sin6); | |
828 | +#endif | |
829 | + memcpy(&sin6->sin6_addr, addr->data, sizeof(sin6->sin6_addr)); | |
830 | + break; | |
831 | +#endif | |
832 | + default: | |
833 | + msg_warn("skipping unsupported address (type=%u)", addr->type); | |
834 | + continue; | |
835 | + } | |
836 | + | |
837 | +#ifdef INET6 | |
838 | + (void)getnameinfo((struct sockaddr *)&ss, SS_LEN(ss), | |
839 | + hbuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST); | |
840 | +#else | |
841 | + (void)inet_ntop(AF_INET, &sin->sin_addr, hbuf, sizeof(hbuf)); | |
842 | +#endif | |
843 | + msg_info("pref %4d host %s/%s", addr->pref, addr->name, hbuf); | |
844 | } | |
845 | msg_info("end %s address list", what); | |
846 | } | |
35140025 | 847 | @@ -155,15 +205,23 @@ |
23bbf6c1 JB |
848 | static DNS_RR *smtp_addr_one(DNS_RR *addr_list, char *host, unsigned pref, VSTRING *why) |
849 | { | |
850 | char *myname = "smtp_addr_one"; | |
851 | +#ifndef INET6 | |
852 | struct in_addr inaddr; | |
853 | - DNS_FIXED fixed; | |
854 | DNS_RR *addr = 0; | |
855 | DNS_RR *rr; | |
856 | struct hostent *hp; | |
857 | +#else | |
858 | + struct addrinfo hints, *res0, *res; | |
859 | + int error = -1; | |
860 | + char *addr; | |
861 | + size_t addrlen; | |
862 | +#endif | |
863 | + DNS_FIXED fixed; | |
864 | ||
865 | if (msg_verbose) | |
866 | msg_info("%s: host %s", myname, host); | |
867 | ||
868 | +#ifndef INET6 | |
869 | /* | |
870 | * Interpret a numerical name as an address. | |
871 | */ | |
35140025 | 872 | @@ -216,6 +274,48 @@ |
23bbf6c1 JB |
873 | smtp_errno = SMTP_FAIL; |
874 | break; | |
875 | } | |
876 | +#else | |
877 | + memset(&hints, 0, sizeof(hints)); | |
878 | + hints.ai_family = PF_UNSPEC; | |
879 | + hints.ai_socktype = SOCK_STREAM; | |
880 | + error = getaddrinfo(host, NULL, &hints, &res0); | |
881 | + if (error) { | |
882 | + switch (error) { | |
883 | + case EAI_AGAIN: | |
884 | + smtp_errno = SMTP_RETRY; | |
885 | + break; | |
886 | + default: | |
887 | + vstring_sprintf(why, "[%s]: %s",host,gai_strerror(error)); | |
888 | + smtp_errno = SMTP_FAIL; | |
889 | + break; | |
890 | + } | |
891 | + return (addr_list); | |
892 | + } | |
893 | + for (res = res0; res; res = res->ai_next) { | |
894 | + memset((char *) &fixed, 0, sizeof(fixed)); | |
895 | + switch(res->ai_family) { | |
896 | + case AF_INET6: | |
897 | + /* XXX not scope friendly */ | |
898 | + fixed.type = T_AAAA; | |
899 | + addr = (char *)&((struct sockaddr_in6 *)res->ai_addr)->sin6_addr; | |
900 | + addrlen = sizeof(struct in6_addr); | |
901 | + break; | |
902 | + case AF_INET: | |
903 | + fixed.type = T_A; | |
904 | + addr = (char *)&((struct sockaddr_in *)res->ai_addr)->sin_addr; | |
905 | + addrlen = sizeof(struct in_addr); | |
906 | + break; | |
907 | + default: | |
908 | + msg_warn("%s: unknown address family %d for %s", | |
909 | + myname, res->ai_family, host); | |
910 | + continue; | |
911 | + } | |
912 | + addr_list = dns_rr_append(addr_list, | |
913 | + dns_rr_create(host, &fixed, pref, addr, addrlen)); | |
914 | + } | |
915 | + if (res0) | |
916 | + freeaddrinfo(res0); | |
917 | +#endif | |
918 | return (addr_list); | |
919 | } | |
920 | ||
35140025 | 921 | @@ -251,6 +351,9 @@ |
23bbf6c1 JB |
922 | INET_ADDR_LIST *self; |
923 | DNS_RR *addr; | |
924 | int i; | |
925 | +#ifdef INET6 | |
926 | + struct sockaddr *sa; | |
927 | +#endif | |
928 | ||
929 | /* | |
930 | * Find the first address that lists any address that this mail system is | |
35140025 | 931 | @@ -260,12 +363,36 @@ |
23bbf6c1 JB |
932 | |
933 | self = own_inet_addr_list(); | |
934 | for (addr = addr_list; addr; addr = addr->next) { | |
935 | - for (i = 0; i < self->used; i++) | |
936 | + for (i = 0; i < self->used; i++) { | |
937 | +#ifdef INET6 | |
938 | + sa = (struct sockaddr *)&self->addrs[i]; | |
939 | + switch(addr->type) { | |
940 | + case T_AAAA: | |
941 | + /* XXX scope */ | |
942 | + if (sa->sa_family != AF_INET6) | |
943 | + break; | |
944 | + if (memcmp(&((struct sockaddr_in6 *)sa)->sin6_addr, | |
945 | + addr->data, sizeof(struct in6_addr)) == 0) { | |
946 | + return(addr); | |
947 | + } | |
948 | + break; | |
949 | + case T_A: | |
950 | + if (sa->sa_family != AF_INET) | |
951 | + break; | |
952 | + if (memcmp(&((struct sockaddr_in *)sa)->sin_addr, | |
953 | + addr->data, sizeof(struct in_addr)) == 0) { | |
954 | + return(addr); | |
955 | + } | |
956 | + break; | |
957 | + } | |
958 | +#else | |
959 | if (INADDRP(addr->data)->s_addr == self->addrs[i].s_addr) { | |
960 | if (msg_verbose) | |
961 | msg_info("%s: found at pref %d", myname, addr->pref); | |
962 | return (addr); | |
963 | } | |
964 | +#endif | |
965 | + } | |
966 | } | |
967 | ||
368b25b6 | 968 | /* |
1ce4542c | 969 | @@ -273,12 +400,36 @@ |
368b25b6 TO |
970 | */ |
971 | self = proxy_inet_addr_list(); | |
972 | for (addr = addr_list; addr; addr = addr->next) { | |
973 | - for (i = 0; i < self->used; i++) | |
974 | + for (i = 0; i < self->used; i++) { | |
975 | +#ifdef INET6 | |
976 | + sa = (struct sockaddr *)&self->addrs[i]; | |
977 | + switch(addr->type) { | |
978 | + case T_AAAA: | |
979 | + /* XXX scope */ | |
980 | + if (sa->sa_family != AF_INET6) | |
981 | + break; | |
982 | + if (memcmp(&((struct sockaddr_in6 *)sa)->sin6_addr, | |
983 | + addr->data, sizeof(struct in6_addr)) == 0) { | |
984 | + return(addr); | |
985 | + } | |
986 | + break; | |
987 | + case T_A: | |
988 | + if (sa->sa_family != AF_INET) | |
989 | + break; | |
990 | + if (memcmp(&((struct sockaddr_in *)sa)->sin_addr, | |
991 | + addr->data, sizeof(struct in_addr)) == 0) { | |
992 | + return(addr); | |
993 | + } | |
994 | + break; | |
995 | + } | |
996 | +#else | |
997 | if (INADDRP(addr->data)->s_addr == self->addrs[i].s_addr) { | |
998 | if (msg_verbose) | |
999 | msg_info("%s: found at pref %d", myname, addr->pref); | |
1000 | return (addr); | |
1001 | } | |
1002 | +#endif | |
1003 | + } | |
1004 | } | |
1005 | ||
23bbf6c1 | 1006 | /* |
1ce4542c TO |
1007 | diff -Nur postfix-2.0.9.orig/src/smtp/smtp_connect.c postfix-2.0.9/src/smtp/smtp_connect.c |
1008 | --- postfix-2.0.9.orig/src/smtp/smtp_connect.c Fri Apr 18 20:55:10 2003 | |
1009 | +++ postfix-2.0.9/src/smtp/smtp_connect.c Fri Apr 18 20:55:35 2003 | |
23bbf6c1 JB |
1010 | @@ -81,6 +81,7 @@ |
1011 | /* System library. */ | |
1012 | ||
1013 | #include <sys_defs.h> | |
1014 | +#include <stdlib.h> | |
1015 | #include <sys/socket.h> | |
1016 | #include <netinet/in.h> | |
1017 | #include <arpa/inet.h> | |
1018 | @@ -110,6 +111,7 @@ | |
1019 | #include <inet_addr_list.h> | |
1020 | #include <iostuff.h> | |
1021 | #include <timed_connect.h> | |
1022 | +#include <get_port.h> | |
1023 | #include <stringops.h> | |
7e195e4d | 1024 | #include <host_port.h> |
23bbf6c1 | 1025 | |
7e195e4d | 1026 | @@ -134,19 +136,45 @@ |
23bbf6c1 JB |
1027 | VSTRING *why) |
1028 | { | |
1029 | char *myname = "smtp_connect_addr"; | |
1030 | - struct sockaddr_in sin; | |
1031 | - int sock; | |
1032 | +#ifdef INET6 | |
1033 | + struct sockaddr_storage ss; | |
1034 | +#else | |
1035 | + struct sockaddr ss; | |
1036 | +#endif | |
1037 | + struct sockaddr *sa; | |
1038 | + struct sockaddr_in *sin; | |
1039 | +#ifdef INET6 | |
1040 | + struct sockaddr_in6 *sin6; | |
1041 | +#endif | |
1042 | + SOCKADDR_SIZE salen; | |
1043 | +#ifdef INET6 | |
1044 | + char hbuf[NI_MAXHOST]; | |
1045 | +#else | |
1046 | + char hbuf[sizeof("255.255.255.255") + 1]; | |
1047 | +#endif | |
1048 | + int sock = -1; | |
1049 | INET_ADDR_LIST *addr_list; | |
1050 | int conn_stat; | |
1051 | int saved_errno; | |
1052 | VSTREAM *stream; | |
1053 | int ch; | |
1054 | - unsigned long inaddr; | |
1055 | + | |
1056 | + sa = (struct sockaddr *)&ss; | |
1057 | + sin = (struct sockaddr_in *)&ss; | |
1058 | +#ifdef INET6 | |
1059 | + sin6 = (struct sockaddr_in6 *)&ss; | |
1060 | +#endif | |
1061 | ||
1062 | /* | |
1063 | * Sanity checks. | |
1064 | */ | |
1065 | - if (addr->data_len > sizeof(sin.sin_addr)) { | |
1066 | +#ifdef INET6 | |
1067 | + if (((addr->type==T_A) && (addr->data_len > sizeof(sin->sin_addr))) || | |
1068 | + ((addr->type==T_AAAA) && (addr->data_len > sizeof(sin6->sin6_addr)))) | |
1069 | +#else | |
1070 | + if (addr->data_len > sizeof(sin->sin_addr)) | |
1071 | +#endif | |
1072 | + { | |
1073 | msg_warn("%s: skip address with length %d", myname, addr->data_len); | |
1074 | smtp_errno = SMTP_RETRY; | |
1075 | return (0); | |
7e195e4d | 1076 | @@ -155,17 +183,39 @@ |
23bbf6c1 JB |
1077 | /* |
1078 | * Initialize. | |
1079 | */ | |
1080 | - memset((char *) &sin, 0, sizeof(sin)); | |
1081 | - sin.sin_family = AF_INET; | |
1082 | - | |
1083 | - if ((sock = socket(sin.sin_family, SOCK_STREAM, 0)) < 0) | |
1084 | - msg_fatal("%s: socket: %m", myname); | |
1085 | - | |
1086 | + switch (addr->type) { | |
1087 | +#ifdef INET6 | |
1088 | + case T_AAAA: | |
1089 | + memset(sin6, 0, sizeof(*sin6)); | |
1090 | + sin6->sin6_family = AF_INET6; | |
1091 | + salen = sizeof(*sin6); | |
1092 | + break; | |
1093 | +#endif | |
1094 | + default: /* T_A: */ | |
1095 | + memset(sin, 0, sizeof(*sin)); | |
1096 | + sin->sin_family = AF_INET; | |
1097 | + salen = sizeof(*sin); | |
1098 | + break; | |
1099 | + } | |
1100 | +#ifdef HAS_SA_LEN | |
1101 | + sa->sa_len = salen; | |
1102 | +#endif | |
1103 | + if ((sock = socket(sa->sa_family, SOCK_STREAM, 0)) < 0) | |
1104 | + msg_warn("%s: socket: %m", myname); | |
1105 | + | |
1106 | /* | |
1107 | * Allow the sysadmin to specify the source address, for example, as "-o | |
1108 | * smtp_bind_address=x.x.x.x" in the master.cf file. | |
1109 | */ | |
1110 | if (*var_smtp_bind_addr) { | |
1111 | +#ifndef INET6 | |
1112 | + struct sockaddr_in sin; | |
1113 | + | |
1114 | + memset(&sin, 0, sizeof(sin)); | |
1115 | + sin.sin_family = AF_INET; | |
1116 | +#ifdef HAS_SA_LEN | |
1117 | + sin.sin_len = sizeof(sin); | |
1118 | +#endif | |
1119 | sin.sin_addr.s_addr = inet_addr(var_smtp_bind_addr); | |
1120 | if (sin.sin_addr.s_addr == INADDR_NONE) | |
1121 | msg_fatal("%s: bad %s parameter: %s", | |
7e195e4d | 1122 | @@ -174,6 +224,25 @@ |
23bbf6c1 JB |
1123 | msg_warn("%s: bind %s: %m", myname, inet_ntoa(sin.sin_addr)); |
1124 | if (msg_verbose) | |
1125 | msg_info("%s: bind %s", myname, inet_ntoa(sin.sin_addr)); | |
1126 | +#else | |
1127 | + char hbufl[NI_MAXHOST]; | |
1128 | + struct addrinfo hints, *res; | |
1129 | + | |
1130 | + memset(&hints, 0, sizeof(hints)); | |
1131 | + hints.ai_family = sa->sa_family; | |
1132 | + hints.ai_socktype = SOCK_STREAM; | |
1133 | + hints.ai_flags = AI_PASSIVE|AI_NUMERICHOST; | |
1134 | + snprintf(hbufl, sizeof(hbufl)-1, "%s", var_smtp_bind_addr); | |
1135 | + if (getaddrinfo(hbufl, NULL, &hints, &res) == 0) { | |
1136 | + (void)getnameinfo(res->ai_addr, res->ai_addrlen, hbufl, | |
1137 | + sizeof(hbufl), NULL, 0, NI_NUMERICHOST); | |
1138 | + if (bind(sock, res->ai_addr, res->ai_addrlen) < 0) | |
1139 | + msg_warn("%s: bind %s: %m", myname, hbufl); | |
1140 | + freeaddrinfo(res); | |
1141 | + if (msg_verbose) | |
1142 | + msg_info("%s: bind %s", myname, hbufl); | |
1143 | + } | |
1144 | +#endif | |
1145 | } | |
1146 | ||
1147 | /* | |
7e195e4d | 1148 | @@ -181,8 +250,17 @@ |
23bbf6c1 JB |
1149 | * the mail appears to come from the "right" machine address. |
1150 | */ | |
1151 | else if ((addr_list = own_inet_addr_list())->used == 1) { | |
1152 | +#ifndef INET6 | |
1153 | + struct sockaddr_in sin; | |
1154 | + unsigned long inaddr; /*XXX BAD!*/ | |
1155 | + | |
1156 | + memset(&sin, 0, sizeof(sin)); | |
1157 | + sin.sin_family = AF_INET; | |
1158 | +#ifdef HAS_SA_LEN | |
1159 | + sin.sin_len = sizeof(sin); | |
1160 | +#endif | |
1161 | memcpy((char *) &sin.sin_addr, addr_list->addrs, sizeof(sin.sin_addr)); | |
1162 | - inaddr = ntohl(sin.sin_addr.s_addr); | |
1163 | + inaddr = (unsigned long)ntohl(sin.sin_addr.s_addr); | |
1164 | if (!IN_CLASSA(inaddr) | |
1165 | || !(((inaddr & IN_CLASSA_NET) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET)) { | |
1166 | if (bind(sock, (struct sockaddr *) & sin, sizeof(sin)) < 0) | |
7e195e4d | 1167 | @@ -190,30 +268,85 @@ |
23bbf6c1 JB |
1168 | if (msg_verbose) |
1169 | msg_info("%s: bind %s", myname, inet_ntoa(sin.sin_addr)); | |
1170 | } | |
1171 | +#else | |
1172 | + char hbufl[NI_MAXHOST]; | |
1173 | + struct addrinfo hints, *res = NULL, *loopback = NULL; | |
1174 | + | |
1175 | + memset(&hints, 0, sizeof(hints)); | |
1176 | + hints.ai_family = sa->sa_family; | |
1177 | + hints.ai_socktype = SOCK_STREAM; | |
1178 | + if (getaddrinfo(NULL, "0", &hints, &loopback) != 0) | |
1179 | + loopback = NULL; | |
1180 | + | |
1181 | + /* | |
1182 | + * getnameinfo -> getaddrinfo loop is here so that we can | |
1183 | + * get rid of port. | |
1184 | + */ | |
1185 | + (void)getnameinfo((struct sockaddr *)addr_list->addrs, SA_LEN((struct sockaddr *)addr_list->addrs), | |
1186 | + hbufl, sizeof(hbufl), NULL, 0, NI_NUMERICHOST); | |
1187 | + hbufl[sizeof(hbufl)-1] = 0; | |
1188 | + memset(&hints, 0, sizeof(hints)); | |
1189 | + hints.ai_family = sa->sa_family; | |
1190 | + hints.ai_socktype = SOCK_STREAM; | |
1191 | + hints.ai_flags = AI_PASSIVE|AI_NUMERICHOST; | |
1192 | + if (getaddrinfo(hbufl, NULL, &hints, &res) == 0 && | |
1193 | + !(res->ai_addrlen == loopback->ai_addrlen && | |
1194 | + memcmp(res->ai_addr, loopback->ai_addr, res->ai_addrlen) == 0)) { | |
1195 | + if (bind(sock, res->ai_addr, res->ai_addrlen) < 0) | |
1196 | + msg_warn("%s: bind %s: %m", myname, hbufl); | |
1197 | + if (msg_verbose) | |
1198 | + msg_info("%s: bind %s", myname, hbufl); | |
1199 | + } | |
1200 | + if (res) | |
1201 | + freeaddrinfo(res); | |
1202 | + if (loopback) | |
1203 | + freeaddrinfo(loopback); | |
1204 | +#endif | |
1205 | } | |
1206 | ||
1207 | /* | |
1208 | * Connect to the SMTP server. | |
1209 | */ | |
1210 | - sin.sin_port = port; | |
1211 | - memcpy((char *) &sin.sin_addr, addr->data, sizeof(sin.sin_addr)); | |
1212 | + switch (addr->type) { | |
1213 | +#ifdef INET6 | |
1214 | + case T_AAAA: | |
1215 | + /* XXX scope unfriendly */ | |
1216 | + memset(sin6, 0, sizeof(*sin6)); | |
1217 | + sin6->sin6_port = port; | |
1218 | + sin6->sin6_family = AF_INET6; | |
1219 | + salen = sizeof(*sin6); | |
1220 | + memcpy(&sin6->sin6_addr, addr->data, sizeof(sin6->sin6_addr)); | |
1221 | + inet_ntop(AF_INET6, &sin6->sin6_addr, hbuf, sizeof(hbuf)); | |
1222 | + break; | |
1223 | +#endif | |
1224 | + default: /* T_A */ | |
1225 | + memset(sin, 0, sizeof(*sin)); | |
1226 | + sin->sin_port = port; | |
1227 | + sin->sin_family = AF_INET; | |
1228 | + salen = sizeof(*sin); | |
1229 | + memcpy(&sin->sin_addr, addr->data, sizeof(sin->sin_addr)); | |
1230 | + inet_ntop(AF_INET, &sin->sin_addr, hbuf, sizeof(hbuf)); | |
1231 | + break; | |
1232 | + } | |
1233 | +#ifdef HAS_SA_LEN | |
1234 | + sa->sa_len = salen; | |
1235 | +#endif | |
1236 | ||
1237 | if (msg_verbose) | |
1238 | msg_info("%s: trying: %s[%s] port %d...", | |
1239 | - myname, addr->name, inet_ntoa(sin.sin_addr), ntohs(port)); | |
1240 | + myname, addr->name, hbuf, ntohs(port)); | |
1241 | if (var_smtp_conn_tmout > 0) { | |
1242 | non_blocking(sock, NON_BLOCKING); | |
1243 | - conn_stat = timed_connect(sock, (struct sockaddr *) & sin, | |
1244 | - sizeof(sin), var_smtp_conn_tmout); | |
1245 | + conn_stat = timed_connect(sock, sa, salen, var_smtp_conn_tmout); | |
1246 | saved_errno = errno; | |
1247 | non_blocking(sock, BLOCKING); | |
1248 | errno = saved_errno; | |
1249 | } else { | |
1250 | - conn_stat = connect(sock, (struct sockaddr *) & sin, sizeof(sin)); | |
1251 | + conn_stat = connect(sock, sa, salen); | |
1252 | } | |
1253 | if (conn_stat < 0) { | |
1254 | vstring_sprintf(why, "connect to %s[%s]: %m", | |
1255 | - addr->name, inet_ntoa(sin.sin_addr)); | |
1256 | + addr->name, hbuf); | |
1257 | smtp_errno = SMTP_RETRY; | |
1258 | close(sock); | |
1259 | return (0); | |
7e195e4d | 1260 | @@ -223,8 +356,8 @@ |
23bbf6c1 JB |
1261 | * Skip this host if it takes no action within some time limit. |
1262 | */ | |
1263 | if (read_wait(sock, var_smtp_helo_tmout) < 0) { | |
1264 | - vstring_sprintf(why, "connect to %s[%s]: read timeout", | |
1265 | - addr->name, inet_ntoa(sin.sin_addr)); | |
1266 | + vstring_sprintf(why, "connect to %s [%s]: read timeout", | |
1267 | + addr->name, hbuf); | |
1268 | smtp_errno = SMTP_RETRY; | |
1269 | close(sock); | |
1270 | return (0); | |
1ce4542c | 1271 | @@ -236,7 +369,7 @@ |
368b25b6 TO |
1272 | stream = vstream_fdopen(sock, O_RDWR); |
1273 | if ((ch = VSTREAM_GETC(stream)) == VSTREAM_EOF) { | |
1274 | vstring_sprintf(why, "connect to %s[%s]: server dropped connection without sending the initial greeting", | |
1275 | - addr->name, inet_ntoa(sin.sin_addr)); | |
1276 | + addr->name, hbuf); | |
1277 | smtp_errno = SMTP_RETRY; | |
1278 | vstream_fclose(stream); | |
1279 | return (0); | |
1ce4542c | 1280 | @@ -248,7 +381,7 @@ |
368b25b6 TO |
1281 | */ |
1282 | if (ch == '4' && var_smtp_skip_4xx_greeting) { | |
1283 | vstring_sprintf(why, "connect to %s[%s]: server refused mail service", | |
1284 | - addr->name, inet_ntoa(sin.sin_addr)); | |
1285 | + addr->name, hbuf); | |
1286 | smtp_errno = SMTP_RETRY; | |
1287 | vstream_fclose(stream); | |
1288 | return (0); | |
1ce4542c | 1289 | @@ -259,12 +392,12 @@ |
368b25b6 TO |
1290 | */ |
1291 | if (ch == '5' && var_smtp_skip_5xx_greeting) { | |
1292 | vstring_sprintf(why, "connect to %s[%s]: server refused mail service", | |
1293 | - addr->name, inet_ntoa(sin.sin_addr)); | |
1294 | + addr->name, hbuf); | |
1295 | smtp_errno = SMTP_RETRY; | |
1296 | vstream_fclose(stream); | |
1297 | return (0); | |
1298 | } | |
1299 | - return (smtp_session_alloc(dest, stream, addr->name, inet_ntoa(sin.sin_addr))); | |
1300 | + return (smtp_session_alloc(dest, stream, addr->name, hbuf)); | |
1301 | } | |
1302 | ||
1303 | /* smtp_connect_host - direct connection to host */ | |
1ce4542c TO |
1304 | diff -Nur postfix-2.0.9.orig/src/smtp/smtp_unalias.c postfix-2.0.9/src/smtp/smtp_unalias.c |
1305 | --- postfix-2.0.9.orig/src/smtp/smtp_unalias.c Thu Sep 28 19:06:09 2000 | |
1306 | +++ postfix-2.0.9/src/smtp/smtp_unalias.c Fri Apr 18 20:55:35 2003 | |
23bbf6c1 JB |
1307 | @@ -86,7 +86,11 @@ |
1308 | if ((result = htable_find(cache, name)) == 0) { | |
1309 | fqdn = vstring_alloc(10); | |
1310 | if (dns_lookup_types(name, smtp_unalias_flags, (DNS_RR **) 0, | |
1311 | - fqdn, (VSTRING *) 0, T_MX, T_A, 0) != DNS_OK) | |
1312 | + fqdn, (VSTRING *) 0, T_MX, T_A, | |
1313 | +#ifdef INET6 | |
1314 | + T_AAAA, | |
1315 | +#endif | |
1316 | + 0) != DNS_OK) | |
1317 | vstring_strcpy(fqdn, name); | |
1318 | htable_enter(cache, name, result = vstring_export(fqdn)); | |
1319 | } | |
1ce4542c TO |
1320 | diff -Nur postfix-2.0.9.orig/src/smtpd/smtpd_check.c postfix-2.0.9/src/smtpd/smtpd_check.c |
1321 | --- postfix-2.0.9.orig/src/smtpd/smtpd_check.c Fri Apr 18 20:55:10 2003 | |
1322 | +++ postfix-2.0.9/src/smtpd/smtpd_check.c Fri Apr 18 20:55:35 2003 | |
1323 | @@ -1362,6 +1362,49 @@ | |
1324 | static int has_my_addr(SMTPD_STATE *state, const char *host, | |
1325 | const char *reply_name, const char *reply_class) | |
23bbf6c1 JB |
1326 | { |
1327 | +#ifdef INET6 | |
1328 | + char *myname = "has_my_addr"; | |
1329 | + struct addrinfo hints, *res, *res0; | |
1330 | + int error; | |
1331 | + char hbuf[NI_MAXHOST]; | |
1332 | + | |
1333 | + if (msg_verbose) | |
1334 | + msg_info("%s: host %s", myname, host); | |
1335 | + | |
1336 | + /* | |
1337 | + * If we can't lookup the host, play safe and assume it is OK. | |
1338 | + */ | |
1339 | +#define YUP 1 | |
1340 | +#define NOPE 0 | |
1341 | + | |
1342 | + memset(&hints, 0, sizeof(hints)); | |
1343 | + hints.ai_family = PF_UNSPEC; | |
1344 | + hints.ai_socktype = SOCK_DGRAM; | |
1345 | + error = getaddrinfo(host, NULL, &hints, &res0); | |
1346 | + if (error) { | |
1347 | + if (msg_verbose) | |
1348 | + msg_info("%s: host %s: %s", myname, host, gai_strerror(error)); | |
1349 | + return (YUP); | |
1350 | + } | |
1351 | + for (res = res0; res; res = res->ai_next) { | |
1352 | + if (msg_verbose) { | |
1353 | + if (getnameinfo(res->ai_addr, res->ai_addrlen, hbuf, sizeof(hbuf), | |
1354 | + NULL, 0, NI_NUMERICHOST)) { | |
1355 | + strncpy(hbuf, "???", sizeof(hbuf)); | |
1356 | + } | |
1357 | + msg_info("%s: addr %s", myname, hbuf); | |
1358 | + } | |
1359 | + if (own_inet_addr(res->ai_addr)) { | |
1360 | + freeaddrinfo(res0); | |
1361 | + return (YUP); | |
1362 | + } | |
1363 | + } | |
1364 | + freeaddrinfo(res0); | |
1365 | + if (msg_verbose) | |
1366 | + msg_info("%s: host %s: no match", myname, host); | |
1367 | + | |
1368 | + return (NOPE); | |
1369 | +#else | |
1370 | char *myname = "has_my_addr"; | |
1371 | struct in_addr addr; | |
1372 | char **cpp; | |
1ce4542c | 1373 | @@ -1400,6 +1443,7 @@ |
23bbf6c1 JB |
1374 | msg_info("%s: host %s: no match", myname, host); |
1375 | ||
1376 | return (NOPE); | |
1377 | +#endif | |
1378 | } | |
1379 | ||
35140025 | 1380 | /* i_am_mx - is this machine listed as MX relay */ |
1ce4542c | 1381 | @@ -1984,11 +2028,28 @@ |
a4192b77 JB |
1382 | #define CHK_ADDR_RETURN(x,y) { *found = y; return(x); } |
1383 | ||
1384 | addr = STR(vstring_strcpy(error_text, address)); | |
1385 | - | |
1386 | +#ifdef INET6 | |
1387 | + if (strncmp(addr, "::ffff:", 7) == 0 && msg_verbose) | |
1388 | + msg_info("%s: %s v6 addr in v4 compat-mode, " | |
1389 | + "converted to v4 for map checking compatibility (%s)", \ | |
1390 | + myname, addr, addr+7); | |
1391 | +#endif | |
1392 | + | |
1393 | if ((dict = dict_handle(table)) == 0) | |
1394 | msg_panic("%s: dictionary not found: %s", myname, table); | |
1395 | do { | |
1396 | if (flags == 0 || (flags & dict->flags) != 0) { | |
1397 | +#ifdef INET6 | |
1398 | + if (strncmp(addr, "::ffff:", 7) == 0) { | |
1399 | + /* try if ::ffff: formati is present in map, if not, try | |
1400 | + traditional IPv4 format striping :ffff: part */ | |
1401 | + if ((value = dict_get(dict, addr)) != 0 || \ | |
1402 | + (value = dict_get(dict, addr+7)) != 0) | |
1403 | + CHK_ADDR_RETURN(check_table_result(state, table, value, address, | |
1404 | + reply_name, reply_class, | |
1405 | + def_acl), FOUND); | |
1406 | + } else | |
1407 | +#endif | |
1408 | if ((value = dict_get(dict, addr)) != 0) | |
1409 | CHK_ADDR_RETURN(check_table_result(state, table, value, address, | |
1410 | reply_name, reply_class, | |
1ce4542c | 1411 | @@ -2431,16 +2492,32 @@ |
c6bc5048 TO |
1412 | VSTRING *query; |
1413 | int i; | |
1414 | SMTPD_RBL_STATE *rbl; | |
1415 | +#ifdef INET6 | |
1416 | + struct in_addr a; | |
1417 | +#else | |
1418 | + struct in6_addr a; | |
1419 | +#endif | |
1420 | ||
23bbf6c1 | 1421 | if (msg_verbose) |
7e195e4d | 1422 | msg_info("%s: %s %s", myname, reply_class, addr); |
e38d57a7 | 1423 | |
da71bd09 JB |
1424 | - /* |
1425 | - * IPv4 only for now | |
1426 | - */ | |
1427 | -#ifdef INET6 | |
1428 | +#ifndef INET6 | |
23bbf6c1 | 1429 | + /* IPv4 only for now */ |
7e195e4d | 1430 | if (inet_pton(AF_INET, addr, &a) != 1) |
da71bd09 JB |
1431 | return SMTPD_CHECK_DUNNO; |
1432 | + octets = argv_split(state->addr, "."); | |
1433 | +#else | |
1434 | + /* IPv4 and IPv6-mapped IPv4 only for now */ | |
1435 | + if (inet_pton(AF_INET, state->addr, &a) == 1) | |
7e195e4d | 1436 | + octets = argv_split(state->addr, "."); |
da71bd09 | 1437 | + else { |
7e195e4d TO |
1438 | + struct in6_addr a6; |
1439 | + if (inet_pton(AF_INET6, state->addr, &a6) != 1) | |
da71bd09 | 1440 | + return SMTPD_CHECK_DUNNO; |
7e195e4d | 1441 | + if (!IN6_IS_ADDR_V4MAPPED(&a6) || (strrchr(state->addr,':') == NULL)) |
da71bd09 | 1442 | + return SMTPD_CHECK_DUNNO; |
7e195e4d | 1443 | + octets = argv_split(strrchr(state->addr,':')+1, "."); |
da71bd09 JB |
1444 | + } |
1445 | #endif | |
1446 | ||
23bbf6c1 | 1447 | /* |
1ce4542c TO |
1448 | diff -Nur postfix-2.0.9.orig/src/smtpd/smtpd_peer.c postfix-2.0.9/src/smtpd/smtpd_peer.c |
1449 | --- postfix-2.0.9.orig/src/smtpd/smtpd_peer.c Thu Aug 22 19:50:51 2002 | |
1450 | +++ postfix-2.0.9/src/smtpd/smtpd_peer.c Fri Apr 18 20:55:35 2003 | |
23bbf6c1 JB |
1451 | @@ -63,6 +63,15 @@ |
1452 | #include <netdb.h> | |
1453 | #include <string.h> | |
1454 | ||
1455 | +/* Utility library. */ | |
1456 | + | |
1457 | +#include <msg.h> | |
1458 | +#include <mymalloc.h> | |
1459 | +#include <valid_hostname.h> | |
1460 | +#include <stringops.h> | |
1461 | + | |
1462 | +/* Global library. */ | |
1463 | + | |
1464 | /* | |
1465 | * Older systems don't have h_errno. Even modern systems don't have | |
1466 | * hstrerror(). | |
1467 | @@ -84,16 +93,11 @@ | |
1468 | ) | |
1469 | #endif | |
1470 | ||
1471 | -/* Utility library. */ | |
1472 | - | |
1473 | -#include <msg.h> | |
1474 | -#include <mymalloc.h> | |
1475 | -#include <valid_hostname.h> | |
1476 | -#include <stringops.h> | |
1477 | - | |
1478 | -/* Global library. */ | |
1479 | - | |
1480 | - | |
1481 | +#ifdef INET6 | |
1482 | +#define GAI_STRERROR(error) \ | |
1483 | + ((error = EAI_SYSTEM) ? gai_strerror(error) : strerror(errno)) | |
1484 | +#endif | |
1485 | + | |
1486 | /* Application-specific. */ | |
1487 | ||
1488 | #include "smtpd.h" | |
c6bc5048 | 1489 | @@ -102,21 +106,28 @@ |
23bbf6c1 JB |
1490 | |
1491 | void smtpd_peer_init(SMTPD_STATE *state) | |
1492 | { | |
1493 | - struct sockaddr_in sin; | |
1494 | - SOCKADDR_SIZE len = sizeof(sin); | |
1495 | +#ifdef INET6 | |
1496 | + struct sockaddr_storage ss; | |
1497 | +#else | |
1498 | + struct sockaddr ss; | |
1499 | + struct in_addr *in; | |
1500 | struct hostent *hp; | |
1501 | - int i; | |
1502 | +#endif | |
1503 | + struct sockaddr *sa; | |
1504 | + SOCKADDR_SIZE len; | |
1505 | + | |
1506 | + sa = (struct sockaddr *)&ss; | |
1507 | + len = sizeof(ss); | |
1508 | ||
7e195e4d TO |
1509 | /* |
1510 | * Avoid suprious complaints from Purify on Solaris. | |
c6bc5048 TO |
1511 | */ |
1512 | - memset((char *) &sin, 0, len); | |
b733fb75 | 1513 | + memset((char *) sa, 0, len); |
c6bc5048 | 1514 | |
23bbf6c1 JB |
1515 | /* |
1516 | * Look up the peer address information. | |
1517 | */ | |
1518 | - if (getpeername(vstream_fileno(state->client), | |
1519 | - (struct sockaddr *) & sin, &len) >= 0) { | |
1520 | + if (getpeername(vstream_fileno(state->client), sa, &len) >= 0) { | |
1521 | errno = 0; | |
1522 | } | |
1523 | ||
7e195e4d | 1524 | @@ -132,23 +143,56 @@ |
23bbf6c1 JB |
1525 | /* |
1526 | * Look up and "verify" the client hostname. | |
1527 | */ | |
1528 | - else if (errno == 0 && sin.sin_family == AF_INET) { | |
1529 | - state->addr = mystrdup(inet_ntoa(sin.sin_addr)); | |
1530 | - hp = gethostbyaddr((char *) &(sin.sin_addr), | |
1531 | - sizeof(sin.sin_addr), AF_INET); | |
1532 | - if (hp == 0) { | |
1533 | + else if (errno == 0 && (sa->sa_family == AF_INET | |
1534 | +#ifdef INET6 | |
1535 | + || sa->sa_family == AF_INET6 | |
1536 | +#endif | |
1537 | + )) { | |
1538 | +#ifdef INET6 | |
1539 | + char hbuf[NI_MAXHOST]; | |
1540 | + char abuf[NI_MAXHOST]; | |
1541 | + struct addrinfo hints, *rnull = NULL; | |
1542 | +#else | |
1543 | + char abuf[sizeof("255.255.255.255") + 1]; | |
1544 | + char *hbuf; | |
1545 | +#endif | |
1546 | + int error = -1; | |
1547 | + | |
1548 | +#ifdef INET6 | |
1549 | + (void)getnameinfo(sa, len, abuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST); | |
1550 | +#else | |
1551 | + in = &((struct sockaddr_in *)sa)->sin_addr; | |
1552 | + inet_ntop(AF_INET, in, abuf, sizeof(hbuf)); | |
1553 | +#endif | |
1554 | + state->addr = mystrdup(abuf); | |
1555 | +#ifdef INET6 | |
1556 | + error = getnameinfo(sa, len, hbuf, sizeof(hbuf), NULL, 0, NI_NAMEREQD); | |
1557 | +#else | |
1558 | + hbuf = NULL; | |
1559 | + hp = gethostbyaddr((char *)in, sizeof(*in), AF_INET); | |
1560 | + if (hp) { | |
1561 | + error = 0; | |
1562 | + hbuf = mystrdup(hp->h_name); | |
1563 | + } else | |
1564 | + error = 1; | |
1565 | +#endif | |
1566 | + if (error) { | |
1567 | state->name = mystrdup("unknown"); | |
1568 | +#ifdef INET6 | |
1569 | + state->peer_code = (error == EAI_AGAIN ? 4 : 5); | |
1570 | +#else | |
1571 | state->peer_code = (h_errno == TRY_AGAIN ? 4 : 5); | |
7e195e4d | 1572 | - } else if (valid_hostaddr(hp->h_name, DONT_GRIPE)) { |
23bbf6c1 | 1573 | +#endif |
7e195e4d TO |
1574 | + } else if (valid_hostaddr(hbuf, DONT_GRIPE)) { |
1575 | msg_warn("numeric result %s in address->name lookup for %s", | |
1576 | - hp->h_name, state->addr); | |
c6bc5048 | 1577 | + hbuf, state->addr); |
7e195e4d TO |
1578 | state->name = mystrdup("unknown"); |
1579 | state->peer_code = 5; | |
1580 | - } else if (!valid_hostname(hp->h_name, DONT_GRIPE)) { | |
23bbf6c1 JB |
1581 | + } else if (!valid_hostname(hbuf, DONT_GRIPE)) { |
1582 | state->name = mystrdup("unknown"); | |
1583 | state->peer_code = 5; | |
1584 | } else { | |
1585 | - state->name = mystrdup(hp->h_name); /* hp->name is clobbered!! */ | |
c6bc5048 | 1586 | + state->name = mystrdup(hbuf); /* hp->name is clobbered!! */ |
23bbf6c1 JB |
1587 | state->peer_code = 2; |
1588 | ||
1589 | /* | |
1ce4542c | 1590 | @@ -160,16 +204,31 @@ |
23bbf6c1 JB |
1591 | state->peer_code = code; \ |
1592 | } | |
1593 | ||
1594 | +#ifdef INET6 | |
1595 | + memset(&hints, 0, sizeof(hints)); | |
1596 | + hints.ai_family = AF_UNSPEC; | |
1597 | + hints.ai_socktype = SOCK_STREAM; | |
1598 | + error = getaddrinfo(state->name, NULL, &hints, &rnull); | |
1599 | + if (error) { | |
1600 | + msg_warn("%s: hostname %s verification failed: %s", | |
1601 | + state->addr, state->name, GAI_STRERROR(error)); | |
1602 | + REJECT_PEER_NAME(state, (error == EAI_AGAIN ? 4 : 5)); | |
1603 | + } | |
1604 | + /* memcmp() isn't needed if we use getaddrinfo */ | |
1605 | + if (rnull) | |
1606 | + freeaddrinfo(rnull); | |
1607 | +#else | |
1608 | hp = gethostbyname(state->name); /* clobbers hp->name!! */ | |
1609 | if (hp == 0) { | |
1610 | msg_warn("%s: hostname %s verification failed: %s", | |
1611 | state->addr, state->name, HSTRERROR(h_errno)); | |
1612 | REJECT_PEER_NAME(state, (h_errno == TRY_AGAIN ? 4 : 5)); | |
1613 | - } else if (hp->h_length != sizeof(sin.sin_addr)) { | |
1614 | + } else if (hp->h_length != sizeof(*in)) { | |
1615 | msg_warn("%s: hostname %s verification failed: bad address size %d", | |
1616 | state->addr, state->name, hp->h_length); | |
1617 | REJECT_PEER_NAME(state, 5); | |
1618 | } else { | |
1619 | + int i; | |
1620 | for (i = 0; /* void */ ; i++) { | |
1621 | if (hp->h_addr_list[i] == 0) { | |
1622 | msg_warn("%s: address not listed for hostname %s", | |
1ce4542c | 1623 | @@ -177,12 +236,11 @@ |
23bbf6c1 JB |
1624 | REJECT_PEER_NAME(state, 5); |
1625 | break; | |
1626 | } | |
1627 | - if (memcmp(hp->h_addr_list[i], | |
1628 | - (char *) &sin.sin_addr, | |
1629 | - sizeof(sin.sin_addr)) == 0) | |
1630 | + if (memcmp(hp->h_addr_list[i], (char *)in, sizeof(*in)) == 0) | |
1631 | break; /* keep peer name */ | |
1632 | } | |
1633 | } | |
1634 | +#endif | |
1635 | } | |
1636 | } | |
1637 | ||
1ce4542c TO |
1638 | diff -Nur postfix-2.0.9.orig/src/smtpstone/smtp-sink.c postfix-2.0.9/src/smtpstone/smtp-sink.c |
1639 | --- postfix-2.0.9.orig/src/smtpstone/smtp-sink.c Fri Aug 16 17:05:25 2002 | |
1640 | +++ postfix-2.0.9/src/smtpstone/smtp-sink.c Fri Apr 18 20:55:35 2003 | |
1641 | @@ -606,7 +606,7 @@ | |
e38d57a7 JB |
1642 | } else { |
1643 | if (strncmp(argv[optind], "inet:", 5) == 0) | |
1644 | argv[optind] += 5; | |
1645 | - sock = inet_listen(argv[optind], backlog, BLOCKING); | |
1646 | + sock = inet_listen(argv[optind], backlog, BLOCKING, 1); | |
1647 | } | |
1648 | ||
23bbf6c1 | 1649 | /* |
1ce4542c TO |
1650 | diff -Nur postfix-2.0.9.orig/src/util/Makefile.in postfix-2.0.9/src/util/Makefile.in |
1651 | --- postfix-2.0.9.orig/src/util/Makefile.in Fri Apr 18 20:55:10 2003 | |
1652 | +++ postfix-2.0.9/src/util/Makefile.in Fri Apr 18 20:55:35 2003 | |
830ba608 | 1653 | @@ -8,7 +8,7 @@ |
1654 | dict_tcp.c dict_unix.c dir_forest.c doze.c duplex_pipe.c \ | |
1655 | environ.c events.c exec_command.c fifo_listen.c fifo_trigger.c \ | |
1656 | file_limit.c find_inet.c fsspace.c fullname.c get_domainname.c \ | |
1657 | - get_hostname.c hex_quote.c htable.c inet_addr_host.c \ | |
1658 | + get_hostname.c get_port.c hex_quote.c htable.c inet_addr_host.c \ | |
1659 | inet_addr_list.c inet_addr_local.c inet_connect.c inet_listen.c \ | |
1660 | inet_trigger.c inet_util.c intv.c line_wrap.c lowercase.c \ | |
1661 | lstat_as.c mac_expand.c mac_parse.c make_dirs.c match_list.c \ | |
1662 | @@ -36,7 +36,7 @@ | |
1663 | dict_tcp.o dict_unix.o dir_forest.o doze.o duplex_pipe.o \ | |
1664 | environ.o events.o exec_command.o fifo_listen.o fifo_trigger.o \ | |
1665 | file_limit.o find_inet.o fsspace.o fullname.o get_domainname.o \ | |
1666 | - get_hostname.o hex_quote.o htable.o inet_addr_host.o \ | |
1667 | + get_hostname.o get_port.o hex_quote.o htable.o inet_addr_host.o \ | |
1668 | inet_addr_list.o inet_addr_local.o inet_connect.o inet_listen.o \ | |
1669 | inet_trigger.o inet_util.o intv.o line_wrap.o lowercase.o \ | |
1670 | lstat_as.o mac_expand.o mac_parse.o make_dirs.o match_list.o \ | |
1671 | @@ -60,7 +60,7 @@ | |
1672 | dict_ht.h dict_ldap.h dict_mysql.h dict_ni.h dict_nis.h \ | |
1ce4542c | 1673 | dict_nisplus.h dict_pcre.h dict_pgsql.h dict_regexp.h dict_static.h dict_tcp.h \ |
830ba608 | 1674 | dict_unix.h dir_forest.h events.h exec_command.h find_inet.h \ |
1675 | - fsspace.h fullname.h get_domainname.h get_hostname.h hex_quote.h \ | |
1676 | + fsspace.h fullname.h get_domainname.h get_hostname.h get_port.h hex_quote.h \ | |
1677 | htable.h inet_addr_host.h inet_addr_list.h inet_addr_local.h \ | |
1678 | inet_util.h intv.h iostuff.h line_wrap.h listen.h lstat_as.h \ | |
1679 | mac_expand.h mac_parse.h make_dirs.h match_list.h match_ops.h \ | |
1ce4542c | 1680 | @@ -780,6 +780,7 @@ |
23bbf6c1 JB |
1681 | get_domainname.o: mymalloc.h |
1682 | get_domainname.o: get_hostname.h | |
1683 | get_domainname.o: get_domainname.h | |
1684 | +get_port.o: sys_defs.h | |
1685 | get_hostname.o: get_hostname.c | |
1686 | get_hostname.o: sys_defs.h | |
1687 | get_hostname.o: mymalloc.h | |
1ce4542c | 1688 | @@ -905,6 +906,7 @@ |
23bbf6c1 JB |
1689 | match_list.o: stringops.h |
1690 | match_list.o: argv.h | |
1691 | match_list.o: dict.h | |
1692 | +match_list.o: inet_util.h | |
447bfc58 | 1693 | match_list.o: match_ops.h |
23bbf6c1 JB |
1694 | match_list.o: match_list.h |
1695 | match_ops.o: match_ops.c | |
1ce4542c TO |
1696 | diff -Nur postfix-2.0.9.orig/src/util/get_port.c postfix-2.0.9/src/util/get_port.c |
1697 | --- postfix-2.0.9.orig/src/util/get_port.c Thu Jan 1 01:00:00 1970 | |
1698 | +++ postfix-2.0.9/src/util/get_port.c Fri Apr 18 20:55:35 2003 | |
23bbf6c1 JB |
1699 | @@ -0,0 +1,65 @@ |
1700 | +/*++ | |
1701 | +/* NAME | |
1702 | +/* get_port 3 | |
1703 | +/* SUMMARY | |
1704 | +/* trivial host and port extracter | |
1705 | +/* SYNOPSIS | |
1706 | +/* #include <get_port.h> | |
1707 | +/* | |
1708 | +/* char *get_port(data) | |
1709 | +/* char *data; | |
1710 | +/* | |
1711 | +/* DESCRIPTION | |
1712 | +/* get_port() extract host name or ip address from | |
1713 | +/* strings such as [3ffe:902:12::10]:25, [::1] | |
1714 | +/* or 192.168.0.1:25, and null-terminates the | |
1715 | +/* \fIdata\fR at the first occurrence of port separator. | |
1716 | +/* DIAGNOSTICS | |
1717 | +/* If port not found return null pointer. | |
1718 | +/* LICENSE | |
1719 | +/* .ad | |
1720 | +/* .fi | |
1721 | +/* BSD Style (or BSD like) license. | |
1722 | +/* AUTHOR(S) | |
1723 |