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