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