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