1 /* $NetBSD: smtp_connect.c,v 1.4 2022/10/08 16:12:49 christos Exp $ */
2
3 /*++
4 /* NAME
5 /* smtp_connect 3
6 /* SUMMARY
7 /* connect to SMTP/LMTP server and deliver
8 /* SYNOPSIS
9 /* #include "smtp.h"
10 /*
11 /* int smtp_connect(state)
12 /* SMTP_STATE *state;
13 /* DESCRIPTION
14 /* This module implements SMTP/LMTP connection management and controls
15 /* mail delivery.
16 /*
17 /* smtp_connect() attempts to establish an SMTP/LMTP session with a host
18 /* that represents the destination domain, or with an optional fallback
19 /* relay when {the destination cannot be found, or when all the
20 /* destination servers are unavailable}. It skips over IP addresses
21 /* that fail to complete the SMTP/LMTP handshake and tries to find
22 /* an alternate server when an SMTP/LMTP session fails to deliver.
23 /*
24 /* This layer also controls what connections are retrieved from
25 /* the connection cache, and what connections are saved to the cache.
26 /*
27 /* The destination is either a host (or domain) name or a numeric
28 /* address. Symbolic or numeric service port information may be
29 /* appended, separated by a colon (":"). In the case of LMTP,
30 /* destinations may be specified as "unix:pathname", "inet:host"
31 /* or "inet:host:port".
32 /*
33 /* With SMTP, the Internet domain name service is queried for mail
34 /* exchanger hosts. Quote the domain name with `[' and `]' to
35 /* suppress mail exchanger lookups.
36 /*
37 /* Numerical address information should always be quoted with `[]'.
38 /* DIAGNOSTICS
39 /* The delivery status is the result value.
40 /* SEE ALSO
41 /* smtp_proto(3) SMTP client protocol
42 /* LICENSE
43 /* .ad
44 /* .fi
45 /* The Secure Mailer license must be distributed with this software.
46 /* AUTHOR(S)
47 /* Wietse Venema
48 /* IBM T.J. Watson Research
49 /* P.O. Box 704
50 /* Yorktown Heights, NY 10598, USA
51 /*
52 /* Wietse Venema
53 /* Google, Inc.
54 /* 111 8th Avenue
55 /* New York, NY 10011, USA
56 /*
57 /* Connection caching in cooperation with:
58 /* Victor Duchovni
59 /* Morgan Stanley
60 /*--*/
61
62 /* System library. */
63
64 #include <sys_defs.h>
65 #include <stdlib.h>
66 #include <sys/socket.h>
67 #include <sys/un.h>
68 #include <netinet/in.h>
69 #include <arpa/inet.h>
70 #include <errno.h>
71 #include <netdb.h>
72 #include <stdlib.h>
73 #include <string.h>
74 #include <unistd.h>
75 #include <fcntl.h>
76 #include <ctype.h>
77
78 #ifndef IPPORT_SMTP
79 #define IPPORT_SMTP 25
80 #endif
81
82 /* Utility library. */
83
84 #include <msg.h>
85 #include <vstream.h>
86 #include <vstring.h>
87 #include <split_at.h>
88 #include <mymalloc.h>
89 #include <inet_addr_list.h>
90 #include <iostuff.h>
91 #include <timed_connect.h>
92 #include <stringops.h>
93 #include <host_port.h>
94 #include <sane_connect.h>
95 #include <myaddrinfo.h>
96 #include <sock_addr.h>
97 #include <inet_proto.h>
98 #include <known_tcp_ports.h>
99
100 /* Global library. */
101
102 #include <mail_params.h>
103 #include <own_inet_addr.h>
104 #include <deliver_pass.h>
105 #include <mail_error.h>
106 #include <dsn_buf.h>
107 #include <mail_addr.h>
108
109 /* DNS library. */
110
111 #include <dns.h>
112
113 /* Application-specific. */
114
115 #include <smtp.h>
116 #include <smtp_addr.h>
117 #include <smtp_reuse.h>
118
119 /*
120 * Forward declaration.
121 */
122 static SMTP_SESSION *smtp_connect_sock(int, struct sockaddr *, int,
123 SMTP_ITERATOR *, DSN_BUF *,
124 int);
125
126 /* smtp_connect_unix - connect to UNIX-domain address */
127
smtp_connect_unix(SMTP_ITERATOR * iter,DSN_BUF * why,int sess_flags)128 static SMTP_SESSION *smtp_connect_unix(SMTP_ITERATOR *iter, DSN_BUF *why,
129 int sess_flags)
130 {
131 const char *myname = "smtp_connect_unix";
132 struct sockaddr_un sock_un;
133 const char *addr = STR(iter->addr);
134 int len = strlen(addr);
135 int sock;
136
137 dsb_reset(why); /* Paranoia */
138
139 /*
140 * Sanity checks.
141 */
142 if (len >= (int) sizeof(sock_un.sun_path)) {
143 msg_warn("unix-domain name too long: %s", addr);
144 dsb_simple(why, "4.3.5", "Server configuration error");
145 return (0);
146 }
147
148 /*
149 * Initialize.
150 */
151 memset((void *) &sock_un, 0, sizeof(sock_un));
152 sock_un.sun_family = AF_UNIX;
153 #ifdef HAS_SUN_LEN
154 sock_un.sun_len = len + 1;
155 #endif
156 memcpy(sock_un.sun_path, addr, len + 1);
157
158 /*
159 * Create a client socket.
160 */
161 if ((sock = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
162 msg_fatal("%s: socket: %m", myname);
163
164 /*
165 * Connect to the server.
166 */
167 if (msg_verbose)
168 msg_info("%s: trying: %s...", myname, addr);
169
170 return (smtp_connect_sock(sock, (struct sockaddr *) &sock_un,
171 sizeof(sock_un), iter, why, sess_flags));
172 }
173
174 /* smtp_connect_addr - connect to explicit address */
175
smtp_connect_addr(SMTP_ITERATOR * iter,DSN_BUF * why,int sess_flags)176 static SMTP_SESSION *smtp_connect_addr(SMTP_ITERATOR *iter, DSN_BUF *why,
177 int sess_flags)
178 {
179 const char *myname = "smtp_connect_addr";
180 struct sockaddr_storage ss; /* remote */
181 struct sockaddr *sa = (struct sockaddr *) &ss;
182 SOCKADDR_SIZE salen = sizeof(ss);
183 MAI_HOSTADDR_STR hostaddr;
184 DNS_RR *addr = iter->rr;
185 unsigned port = iter->port;
186 int sock;
187 char *bind_addr;
188 char *bind_var;
189 char *saved_bind_addr = 0;
190 char *tail;
191
192 dsb_reset(why); /* Paranoia */
193
194 /*
195 * Sanity checks.
196 */
197 if (dns_rr_to_sa(addr, port, sa, &salen) != 0) {
198 msg_warn("%s: skip address type %s: %m",
199 myname, dns_strtype(addr->type));
200 dsb_simple(why, "4.4.0", "network address conversion failed: %m");
201 return (0);
202 }
203
204 /*
205 * Initialize.
206 */
207 if ((sock = socket(sa->sa_family, SOCK_STREAM, 0)) < 0)
208 msg_fatal("%s: socket: %m", myname);
209
210 #define RETURN_EARLY() do { \
211 if (saved_bind_addr) \
212 myfree(saved_bind_addr); \
213 (void) close(sock); \
214 return (0); \
215 } while (0)
216
217 if (inet_windowsize > 0)
218 set_inet_windowsize(sock, inet_windowsize);
219
220 /*
221 * Allow the sysadmin to specify the source address, for example, as "-o
222 * smtp_bind_address=x.x.x.x" in the master.cf file.
223 */
224 #ifdef HAS_IPV6
225 if (sa->sa_family == AF_INET6) {
226 bind_addr = var_smtp_bind_addr6;
227 bind_var = VAR_LMTP_SMTP(BIND_ADDR6);
228 } else
229 #endif
230 if (sa->sa_family == AF_INET) {
231 bind_addr = var_smtp_bind_addr;
232 bind_var = VAR_LMTP_SMTP(BIND_ADDR);
233 } else
234 bind_var = bind_addr = "";
235 if (*bind_addr) {
236 int aierr;
237 struct addrinfo *res0;
238
239 if (*bind_addr == '[') {
240 saved_bind_addr = mystrdup(bind_addr + 1);
241 if ((tail = split_at(saved_bind_addr, ']')) == 0 || *tail)
242 msg_fatal("%s: malformed %s parameter: %s",
243 myname, bind_var, bind_addr);
244 bind_addr = saved_bind_addr;
245 }
246 if ((aierr = hostaddr_to_sockaddr(bind_addr, (char *) 0, 0, &res0)) != 0)
247 msg_fatal("%s: bad %s parameter: %s: %s",
248 myname, bind_var, bind_addr, MAI_STRERROR(aierr));
249 if (bind(sock, res0->ai_addr, res0->ai_addrlen) < 0) {
250 msg_warn("%s: bind %s: %m", myname, bind_addr);
251 if (var_smtp_bind_addr_enforce) {
252 freeaddrinfo(res0);
253 dsb_simple(why, "4.4.0", "server configuration error");
254 RETURN_EARLY();
255 }
256 } else if (msg_verbose)
257 msg_info("%s: bind %s", myname, bind_addr);
258 if (saved_bind_addr)
259 myfree(saved_bind_addr);
260 freeaddrinfo(res0);
261 }
262
263 /*
264 * When running as a virtual host, bind to the virtual interface so that
265 * the mail appears to come from the "right" machine address.
266 *
267 * XXX The IPv6 patch expands the null host (as client endpoint) and uses
268 * the result as the loopback address list.
269 */
270 else {
271 int count = 0;
272 struct sockaddr *own_addr = 0;
273 INET_ADDR_LIST *addr_list = own_inet_addr_list();
274 struct sockaddr_storage *s;
275
276 for (s = addr_list->addrs; s < addr_list->addrs + addr_list->used; s++) {
277 if (SOCK_ADDR_FAMILY(s) == sa->sa_family) {
278 if (count++ > 0)
279 break;
280 own_addr = SOCK_ADDR_PTR(s);
281 }
282 }
283 if (count == 1 && !sock_addr_in_loopback(own_addr)) {
284 if (bind(sock, own_addr, SOCK_ADDR_LEN(own_addr)) < 0) {
285 SOCKADDR_TO_HOSTADDR(own_addr, SOCK_ADDR_LEN(own_addr),
286 &hostaddr, (MAI_SERVPORT_STR *) 0, 0);
287 msg_warn("%s: bind %s: %m", myname, hostaddr.buf);
288 } else if (msg_verbose) {
289 SOCKADDR_TO_HOSTADDR(own_addr, SOCK_ADDR_LEN(own_addr),
290 &hostaddr, (MAI_SERVPORT_STR *) 0, 0);
291 msg_info("%s: bind %s", myname, hostaddr.buf);
292 }
293 }
294 }
295
296 /*
297 * Connect to the server.
298 */
299 if (msg_verbose)
300 msg_info("%s: trying: %s[%s] port %d...",
301 myname, STR(iter->host), STR(iter->addr), ntohs(port));
302
303 return (smtp_connect_sock(sock, sa, salen, iter, why, sess_flags));
304 }
305
306 /* smtp_connect_sock - connect a socket over some transport */
307
smtp_connect_sock(int sock,struct sockaddr * sa,int salen,SMTP_ITERATOR * iter,DSN_BUF * why,int sess_flags)308 static SMTP_SESSION *smtp_connect_sock(int sock, struct sockaddr *sa,
309 int salen,
310 SMTP_ITERATOR *iter,
311 DSN_BUF *why,
312 int sess_flags)
313 {
314 int conn_stat;
315 int saved_errno;
316 VSTREAM *stream;
317 time_t start_time;
318 const char *name = STR(iter->host);
319 const char *addr = STR(iter->addr);
320 unsigned port = iter->port;
321
322 start_time = time((time_t *) 0);
323 if (var_smtp_conn_tmout > 0) {
324 non_blocking(sock, NON_BLOCKING);
325 conn_stat = timed_connect(sock, sa, salen, var_smtp_conn_tmout);
326 saved_errno = errno;
327 non_blocking(sock, BLOCKING);
328 errno = saved_errno;
329 } else {
330 conn_stat = sane_connect(sock, sa, salen);
331 }
332 if (conn_stat < 0) {
333 if (port)
334 dsb_simple(why, "4.4.1", "connect to %s[%s]:%d: %m",
335 name, addr, ntohs(port));
336 else
337 dsb_simple(why, "4.4.1", "connect to %s[%s]: %m", name, addr);
338 close(sock);
339 return (0);
340 }
341 stream = vstream_fdopen(sock, O_RDWR);
342
343 /*
344 * Avoid poor performance when TCP MSS > VSTREAM_BUFSIZE.
345 */
346 if (sa->sa_family == AF_INET
347 #ifdef AF_INET6
348 || sa->sa_family == AF_INET6
349 #endif
350 )
351 vstream_tweak_tcp(stream);
352
353 /*
354 * Bundle up what we have into a nice SMTP_SESSION object.
355 */
356 return (smtp_session_alloc(stream, iter, start_time, sess_flags));
357 }
358
359 /* smtp_parse_destination - parse host/port destination */
360
smtp_parse_destination(char * destination,char * def_service,char ** hostp,unsigned * portp)361 static char *smtp_parse_destination(char *destination, char *def_service,
362 char **hostp, unsigned *portp)
363 {
364 char *buf = mystrdup(destination);
365 char *service;
366 struct servent *sp;
367 char *protocol = "tcp"; /* XXX configurable? */
368 unsigned port;
369 const char *err;
370
371 if (msg_verbose)
372 msg_info("smtp_parse_destination: %s %s", destination, def_service);
373
374 /*
375 * Parse the host/port information. We're working with a copy of the
376 * destination argument so the parsing can be destructive.
377 */
378 if ((err = host_port(buf, hostp, (char *) 0, &service, def_service)) != 0)
379 msg_fatal("%s in server description: %s", err, destination);
380
381 /*
382 * Convert service to port number, network byte order.
383 */
384 service = (char *) filter_known_tcp_port(service);
385 if (alldig(service)) {
386 if ((port = atoi(service)) >= 65536 || port == 0)
387 msg_fatal("bad network port: %s for destination: %s",
388 service, destination);
389 *portp = htons(port);
390 } else {
391 if ((sp = getservbyname(service, protocol)) == 0)
392 msg_fatal("unknown service: %s/%s", service, protocol);
393 *portp = sp->s_port;
394 }
395 return (buf);
396 }
397
398 /* smtp_cleanup_session - clean up after using a session */
399
smtp_cleanup_session(SMTP_STATE * state)400 static void smtp_cleanup_session(SMTP_STATE *state)
401 {
402 DELIVER_REQUEST *request = state->request;
403 SMTP_SESSION *session = state->session;
404 int throttled;
405
406 /*
407 * Inform the postmaster of trouble.
408 *
409 * XXX Don't send notifications about errors while sending notifications.
410 */
411 #define POSSIBLE_NOTIFICATION(sender) \
412 (*sender == 0 || strcmp(sender, mail_addr_double_bounce()) == 0)
413
414 if (session->history != 0
415 && (session->error_mask & name_mask(VAR_NOTIFY_CLASSES,
416 mail_error_masks,
417 var_notify_classes)) != 0
418 && POSSIBLE_NOTIFICATION(request->sender) == 0)
419 smtp_chat_notify(session);
420
421 /*
422 * When session caching is enabled, cache the first good session for this
423 * delivery request under the next-hop destination, and cache all good
424 * sessions under their server network address (destroying the session in
425 * the process).
426 *
427 * Caching under the next-hop destination name (rather than the fall-back
428 * destination) allows us to skip over non-responding primary or backup
429 * hosts. In fact, this is the only benefit of caching logical to
430 * physical bindings; caching a session under its own hostname provides
431 * no performance benefit, given the way smtp_connect() works.
432 */
433 throttled = THIS_SESSION_IS_THROTTLED; /* smtp_quit() may fail */
434 if (THIS_SESSION_IS_EXPIRED)
435 smtp_quit(state); /* also disables caching */
436 if (THIS_SESSION_IS_CACHED
437 /* Redundant tests for safety... */
438 && vstream_ferror(session->stream) == 0
439 && vstream_feof(session->stream) == 0) {
440 smtp_save_session(state, SMTP_KEY_MASK_SCACHE_DEST_LABEL,
441 SMTP_KEY_MASK_SCACHE_ENDP_LABEL);
442 } else {
443 smtp_session_free(session);
444 }
445 state->session = 0;
446
447 /*
448 * If this session was good, reset the scache next-hop destination, so
449 * that we won't cache connections to less-preferred servers under the
450 * same next-hop destination. Otherwise we could end up skipping over the
451 * available and more-preferred servers.
452 */
453 if (HAVE_SCACHE_REQUEST_NEXTHOP(state) && !throttled)
454 CLEAR_SCACHE_REQUEST_NEXTHOP(state);
455
456 /*
457 * Clean up the lists with todo and dropped recipients.
458 */
459 smtp_rcpt_cleanup(state);
460
461 /*
462 * Reset profiling info.
463 *
464 * XXX When one delivery request results in multiple sessions, the set-up
465 * and transmission latencies of the earlier sessions will count as
466 * connection set-up time for the later sessions.
467 *
468 * XXX On the other hand, when we first try to connect to one or more dead
469 * hosts before we reach a good host, then all that time must be counted
470 * as connection set-up time for the session with the good host.
471 *
472 * XXX So this set-up attribution problem exists only when we actually
473 * engage in a session, spend a lot of time delivering a message, find
474 * that it fails, and then connect to an alternate host.
475 */
476 memset((void *) &request->msg_stats.conn_setup_done, 0,
477 sizeof(request->msg_stats.conn_setup_done));
478 memset((void *) &request->msg_stats.deliver_done, 0,
479 sizeof(request->msg_stats.deliver_done));
480 request->msg_stats.reuse_count = 0;
481 }
482
smtp_cache_policy(SMTP_STATE * state,const char * dest)483 static void smtp_cache_policy(SMTP_STATE *state, const char *dest)
484 {
485 DELIVER_REQUEST *request = state->request;
486
487 state->misc_flags &= ~SMTP_MISC_FLAG_CONN_CACHE_MASK;
488
489 if (smtp_cache_dest && string_list_match(smtp_cache_dest, dest)) {
490 state->misc_flags |= SMTP_MISC_FLAG_CONN_CACHE_MASK;
491 } else if (var_smtp_cache_demand) {
492 if (request->flags & DEL_REQ_FLAG_CONN_LOAD)
493 state->misc_flags |= SMTP_MISC_FLAG_CONN_LOAD;
494 if (request->flags & DEL_REQ_FLAG_CONN_STORE)
495 state->misc_flags |= SMTP_MISC_FLAG_CONN_STORE;
496 }
497 }
498
499 /* smtp_connect_local - connect to local server */
500
smtp_connect_local(SMTP_STATE * state,const char * path)501 static void smtp_connect_local(SMTP_STATE *state, const char *path)
502 {
503 const char *myname = "smtp_connect_local";
504 SMTP_ITERATOR *iter = state->iterator;
505 SMTP_SESSION *session;
506 DSN_BUF *why = state->why;
507
508 /*
509 * Do not silently ignore an unused setting.
510 */
511 if (*var_fallback_relay)
512 msg_warn("ignoring \"%s = %s\" setting for non-TCP connections",
513 VAR_LMTP_FALLBACK, var_fallback_relay);
514
515 /*
516 * It's too painful to weave this code into the SMTP connection
517 * management routine.
518 *
519 * Connection cache management is based on the UNIX-domain pathname, without
520 * the "unix:" prefix.
521 */
522 smtp_cache_policy(state, path);
523 if (state->misc_flags & SMTP_MISC_FLAG_CONN_CACHE_MASK)
524 SET_SCACHE_REQUEST_NEXTHOP(state, path);
525
526 /*
527 * Here we ensure that the iter->addr member refers to a copy of the
528 * UNIX-domain pathname, so that smtp_save_session() will cache the
529 * connection using the pathname as the physical endpoint name.
530 *
531 * We set dest=path for backwards compatibility.
532 */
533 #define NO_PORT 0
534
535 SMTP_ITER_INIT(iter, path, var_myhostname, path, NO_PORT, state);
536
537 /*
538 * Opportunistic TLS for unix domain sockets does not make much sense,
539 * since the channel is private, mere encryption without authentication
540 * is just wasted cycles and opportunity for breakage. Since we are not
541 * willing to retry after TLS handshake failures here, we downgrade "may"
542 * no "none". Nothing is lost, and much waste is avoided.
543 *
544 * We don't know who is authenticating whom, so if a client cert is
545 * available, "encrypt" may be a sensible policy. Otherwise, we also
546 * downgrade "encrypt" to "none", this time just to avoid waste.
547 *
548 * We use smtp_reuse_nexthop() instead of smtp_reuse_addr(), so that we can
549 * reuse a SASL-authenticated connection (however unlikely this scenario
550 * may be). The smtp_reuse_addr() interface currently supports only reuse
551 * of SASL-unauthenticated connections.
552 */
553 #ifdef USE_TLS
554 if (!smtp_tls_policy_cache_query(why, state->tls, iter)) {
555 msg_warn("TLS policy lookup error for %s/%s: %s",
556 STR(iter->host), STR(iter->addr), STR(why->reason));
557 return;
558 }
559 #endif
560 if ((state->misc_flags & SMTP_MISC_FLAG_CONN_LOAD) == 0
561 || (session = smtp_reuse_nexthop(state,
562 SMTP_KEY_MASK_SCACHE_DEST_LABEL)) == 0)
563 session = smtp_connect_unix(iter, why, state->misc_flags);
564 if ((state->session = session) != 0) {
565 session->state = state;
566 #ifdef USE_TLS
567 session->tls_nexthop = var_myhostname; /* for TLS_LEV_SECURE */
568 if (state->tls->level == TLS_LEV_MAY) {
569 msg_warn("%s: opportunistic TLS encryption is not appropriate "
570 "for unix-domain destinations.", myname);
571 state->tls->level = TLS_LEV_NONE;
572 }
573 #endif
574 /* All delivery errors bounce or defer. */
575 state->misc_flags |= SMTP_MISC_FLAG_FINAL_SERVER;
576
577 /*
578 * When a TLS handshake fails, the stream is marked "dead" to avoid
579 * further I/O over a broken channel.
580 */
581 if ((session->features & SMTP_FEATURE_FROM_CACHE) == 0
582 && smtp_helo(state) != 0) {
583 if (!THIS_SESSION_IS_FORBIDDEN
584 && vstream_ferror(session->stream) == 0
585 && vstream_feof(session->stream) == 0)
586 smtp_quit(state);
587 } else {
588 smtp_xfer(state);
589 }
590
591 /*
592 * With opportunistic TLS disabled we don't expect to be asked to
593 * retry connections without TLS, and so we expect the final server
594 * flag to stay on.
595 */
596 if ((state->misc_flags & SMTP_MISC_FLAG_FINAL_SERVER) == 0)
597 msg_panic("%s: unix-domain destination not final!", myname);
598 smtp_cleanup_session(state);
599 }
600
601 /*
602 * Cleanup.
603 */
604 if (HAVE_SCACHE_REQUEST_NEXTHOP(state))
605 CLEAR_SCACHE_REQUEST_NEXTHOP(state);
606 }
607
608 /* smtp_scrub_address_list - delete all cached addresses from list */
609
smtp_scrub_addr_list(HTABLE * cached_addr,DNS_RR ** addr_list)610 static void smtp_scrub_addr_list(HTABLE *cached_addr, DNS_RR **addr_list)
611 {
612 MAI_HOSTADDR_STR hostaddr;
613 DNS_RR *addr;
614 DNS_RR *next;
615
616 /*
617 * XXX Extend the DNS_RR structure with fields for the printable address
618 * and/or binary sockaddr representations, so that we can avoid repeated
619 * binary->string transformations for the same address.
620 */
621 for (addr = *addr_list; addr; addr = next) {
622 next = addr->next;
623 if (dns_rr_to_pa(addr, &hostaddr) == 0) {
624 msg_warn("cannot convert type %s record to printable address",
625 dns_strtype(addr->type));
626 continue;
627 }
628 if (htable_locate(cached_addr, hostaddr.buf))
629 *addr_list = dns_rr_remove(*addr_list, addr);
630 }
631 }
632
633 /* smtp_update_addr_list - common address list update */
634
smtp_update_addr_list(DNS_RR ** addr_list,const char * server_addr,int session_count)635 static void smtp_update_addr_list(DNS_RR **addr_list, const char *server_addr,
636 int session_count)
637 {
638 DNS_RR *addr;
639 DNS_RR *next;
640 int aierr;
641 struct addrinfo *res0;
642
643 if (*addr_list == 0)
644 return;
645
646 /*
647 * Truncate the address list if we are not going to use it anyway.
648 */
649 if (session_count == var_smtp_mxsess_limit
650 || session_count == var_smtp_mxaddr_limit) {
651 dns_rr_free(*addr_list);
652 *addr_list = 0;
653 return;
654 }
655
656 /*
657 * Convert server address to internal form, and look it up in the address
658 * list.
659 *
660 * XXX smtp_reuse_session() breaks if we remove two or more adjacent list
661 * elements but do not truncate the list to zero length.
662 *
663 * XXX Extend the SMTP_SESSION structure with sockaddr information so that
664 * we can avoid repeated string->binary transformations for the same
665 * address.
666 */
667 if ((aierr = hostaddr_to_sockaddr(server_addr, (char *) 0, 0, &res0)) != 0) {
668 msg_warn("hostaddr_to_sockaddr %s: %s",
669 server_addr, MAI_STRERROR(aierr));
670 } else {
671 for (addr = *addr_list; addr; addr = next) {
672 next = addr->next;
673 if (DNS_RR_EQ_SA(addr, (struct sockaddr *) res0->ai_addr)) {
674 *addr_list = dns_rr_remove(*addr_list, addr);
675 break;
676 }
677 }
678 freeaddrinfo(res0);
679 }
680 }
681
682 /* smtp_reuse_session - try to use existing connection, return session count */
683
smtp_reuse_session(SMTP_STATE * state,DNS_RR ** addr_list,int domain_best_pref)684 static int smtp_reuse_session(SMTP_STATE *state, DNS_RR **addr_list,
685 int domain_best_pref)
686 {
687 int session_count = 0;
688 DNS_RR *addr;
689 DNS_RR *next;
690 MAI_HOSTADDR_STR hostaddr;
691 SMTP_SESSION *session;
692 SMTP_ITERATOR *iter = state->iterator;
693 DSN_BUF *why = state->why;
694
695 /*
696 * First, search the cache by delivery request nexthop. We truncate the
697 * server address list when all the sessions for this destination are
698 * used up, to reduce the number of variables that need to be checked
699 * later.
700 *
701 * Note: connection reuse by delivery request nexthop restores the "best MX"
702 * bit.
703 *
704 * smtp_reuse_nexthop() clobbers the iterators's "dest" attribute. We save
705 * and restore it here, so that subsequent connections will use the
706 * proper nexthop information.
707 *
708 * We don't use TLS level info for nexthop-based connection cache storage
709 * keys. The combination of (service, nexthop, etc.) should be stable
710 * over the time range of interest, and the policy is still enforced on
711 * an individual connection to an MX host, before that connection is
712 * stored under a nexthop- or host-based storage key.
713 */
714 #ifdef USE_TLS
715 smtp_tls_policy_dummy(state->tls);
716 #endif
717 SMTP_ITER_SAVE_DEST(state->iterator);
718 if (*addr_list && SMTP_RCPT_LEFT(state) > 0
719 && HAVE_SCACHE_REQUEST_NEXTHOP(state)
720 && (session = smtp_reuse_nexthop(state, SMTP_KEY_MASK_SCACHE_DEST_LABEL)) != 0) {
721 session_count = 1;
722 smtp_update_addr_list(addr_list, STR(iter->addr), session_count);
723 if ((state->misc_flags & SMTP_MISC_FLAG_FINAL_NEXTHOP)
724 && *addr_list == 0)
725 state->misc_flags |= SMTP_MISC_FLAG_FINAL_SERVER;
726 smtp_xfer(state);
727 smtp_cleanup_session(state);
728 }
729 SMTP_ITER_RESTORE_DEST(state->iterator);
730
731 /*
732 * Second, search the cache by primary MX address. Again, we use address
733 * list truncation so that we have to check fewer variables later.
734 *
735 * XXX This loop is safe because smtp_update_addr_list() either truncates
736 * the list to zero length, or removes at most one list element.
737 *
738 * Currently, we use smtp_reuse_addr() only for SASL-unauthenticated
739 * connections. Furthermore, we rely on smtp_reuse_addr() to look up an
740 * existing SASL-unauthenticated connection only when a new connection
741 * would be guaranteed not to require SASL authentication.
742 *
743 * In addition, we rely on smtp_reuse_addr() to look up an existing
744 * plaintext connection only when a new connection would be guaranteed
745 * not to use TLS.
746 *
747 * For more precise control over reuse, the iterator should look up SASL and
748 * TLS policy as it evaluates mail exchangers in order, instead of
749 * relying on duplicate lookup request code in smtp_reuse(3) and
750 * smtp_session(3).
751 */
752 for (addr = *addr_list; SMTP_RCPT_LEFT(state) > 0 && addr; addr = next) {
753 if (addr->pref != domain_best_pref)
754 break;
755 next = addr->next;
756 if (dns_rr_to_pa(addr, &hostaddr) == 0) {
757 msg_warn("cannot convert type %s record to printable address",
758 dns_strtype(addr->type));
759 /* XXX Assume there is no code at the end of this loop. */
760 continue;
761 }
762 vstring_strcpy(iter->addr, hostaddr.buf);
763 vstring_strcpy(iter->host, SMTP_HNAME(addr));
764 iter->rr = addr;
765 #ifdef USE_TLS
766 if (!smtp_tls_policy_cache_query(why, state->tls, iter)) {
767 msg_warn("TLS policy lookup error for %s/%s: %s",
768 STR(iter->dest), STR(iter->host), STR(why->reason));
769 continue;
770 /* XXX Assume there is no code at the end of this loop. */
771 }
772 #endif
773 if ((session = smtp_reuse_addr(state,
774 SMTP_KEY_MASK_SCACHE_ENDP_LABEL)) != 0) {
775 session->features |= SMTP_FEATURE_BEST_MX;
776 session_count += 1;
777 smtp_update_addr_list(addr_list, STR(iter->addr), session_count);
778 if (*addr_list == 0)
779 next = 0;
780 if ((state->misc_flags & SMTP_MISC_FLAG_FINAL_NEXTHOP)
781 && next == 0)
782 state->misc_flags |= SMTP_MISC_FLAG_FINAL_SERVER;
783 smtp_xfer(state);
784 smtp_cleanup_session(state);
785 }
786 }
787 return (session_count);
788 }
789
790 /* smtp_connect_inet - establish network connection */
791
smtp_connect_inet(SMTP_STATE * state,const char * nexthop,char * def_service)792 static void smtp_connect_inet(SMTP_STATE *state, const char *nexthop,
793 char *def_service)
794 {
795 DELIVER_REQUEST *request = state->request;
796 SMTP_ITERATOR *iter = state->iterator;
797 ARGV *sites;
798 char *dest;
799 char **cpp;
800 int non_fallback_sites;
801 int retry_plain = 0;
802 DSN_BUF *why = state->why;
803
804 /*
805 * For sanity, require that at least one of INET or INET6 is enabled.
806 * Otherwise, we can't look up interface information, and we can't
807 * convert names or addresses.
808 */
809 if (inet_proto_info()->ai_family_list[0] == 0) {
810 dsb_simple(why, "4.4.4", "all network protocols are disabled");
811 return;
812 }
813
814 /*
815 * Do a null destination sanity check in case the primary destination is
816 * a list that consists of only separators.
817 */
818 sites = argv_split(nexthop, CHARS_COMMA_SP);
819 if (sites->argc == 0)
820 msg_panic("null destination: \"%s\"", nexthop);
821 non_fallback_sites = sites->argc;
822 argv_split_append(sites, var_fallback_relay, CHARS_COMMA_SP);
823
824 /*
825 * Don't give up after a hard host lookup error until we have tried the
826 * fallback relay servers.
827 *
828 * Don't bounce mail after a host lookup problem with a relayhost or with a
829 * fallback relay.
830 *
831 * Don't give up after a qualifying soft error until we have tried all
832 * qualifying backup mail servers.
833 *
834 * All this means that error handling and error reporting depends on whether
835 * the error qualifies for trying to deliver to a backup mail server, or
836 * whether we're looking up a relayhost or fallback relay. The challenge
837 * then is to build this into the pre-existing SMTP client without
838 * getting lost in the complexity.
839 */
840 #define IS_FALLBACK_RELAY(cpp, sites, non_fallback_sites) \
841 (*(cpp) && (cpp) >= (sites)->argv + (non_fallback_sites))
842
843 for (cpp = sites->argv, (state->misc_flags |= SMTP_MISC_FLAG_FIRST_NEXTHOP);
844 SMTP_RCPT_LEFT(state) > 0 && (dest = *cpp) != 0;
845 cpp++, (state->misc_flags &= ~SMTP_MISC_FLAG_FIRST_NEXTHOP)) {
846 char *dest_buf;
847 char *domain;
848 unsigned port;
849 DNS_RR *addr_list;
850 DNS_RR *addr;
851 DNS_RR *next;
852 int addr_count;
853 int sess_count;
854 SMTP_SESSION *session;
855 int lookup_mx;
856 unsigned domain_best_pref;
857 MAI_HOSTADDR_STR hostaddr;
858
859 if (cpp[1] == 0)
860 state->misc_flags |= SMTP_MISC_FLAG_FINAL_NEXTHOP;
861
862 /*
863 * Parse the destination. If no TCP port is specified, use the port
864 * that is reserved for the protocol (SMTP or LMTP).
865 */
866 dest_buf = smtp_parse_destination(dest, def_service, &domain, &port);
867 if (var_helpful_warnings && var_smtp_tls_wrappermode == 0
868 && ntohs(port) == 465) {
869 msg_info("SMTPS wrappermode (TCP port 465) requires setting "
870 "\"%s = yes\", and \"%s = encrypt\" (or stronger)",
871 VAR_LMTP_SMTP(TLS_WRAPPER), VAR_LMTP_SMTP(TLS_LEVEL));
872 }
873 #define NO_HOST "" /* safety */
874 #define NO_ADDR "" /* safety */
875
876 SMTP_ITER_INIT(iter, dest, NO_HOST, NO_ADDR, port, state);
877
878 /*
879 * Resolve an SMTP or LMTP server. In the case of SMTP, skip mail
880 * exchanger lookups when a quoted host is specified or when DNS
881 * lookups are disabled.
882 */
883 if (msg_verbose)
884 msg_info("connecting to %s port %d", domain, ntohs(port));
885 if (smtp_mode) {
886 if (ntohs(port) == IPPORT_SMTP)
887 state->misc_flags |= SMTP_MISC_FLAG_LOOP_DETECT;
888 else
889 state->misc_flags &= ~SMTP_MISC_FLAG_LOOP_DETECT;
890 lookup_mx = (smtp_dns_support != SMTP_DNS_DISABLED && *dest != '[');
891 } else
892 lookup_mx = 0;
893 if (!lookup_mx) {
894 addr_list = smtp_host_addr(domain, state->misc_flags, why);
895 /* XXX We could be an MX host for this destination... */
896 } else {
897 int i_am_mx = 0;
898
899 addr_list = smtp_domain_addr(domain, &iter->mx, state->misc_flags,
900 why, &i_am_mx);
901 /* If we're MX host, don't connect to non-MX backups. */
902 if (i_am_mx)
903 state->misc_flags |= SMTP_MISC_FLAG_FINAL_NEXTHOP;
904 }
905
906 /*
907 * Don't try fall-back hosts if mail loops to myself. That would just
908 * make the problem worse.
909 */
910 if (addr_list == 0 && SMTP_HAS_LOOP_DSN(why))
911 state->misc_flags |= SMTP_MISC_FLAG_FINAL_NEXTHOP;
912
913 /*
914 * No early loop exit or we have a memory leak with dest_buf.
915 */
916 if (addr_list)
917 domain_best_pref = addr_list->pref;
918
919 /*
920 * When connection caching is enabled, store the first good
921 * connection for this delivery request under the delivery request
922 * next-hop name. Good connections will also be stored under their
923 * specific server IP address.
924 *
925 * XXX smtp_session_cache_destinations specifies domain names without
926 * :port, because : is already used for maptype:mapname. Because of
927 * this limitation we use the bare domain without the optional [] or
928 * non-default TCP port.
929 *
930 * Opportunistic (a.k.a. on-demand) session caching on request by the
931 * queue manager. This is turned temporarily when a destination has a
932 * high volume of mail in the active queue. When the surge reaches
933 * its end, the queue manager requests that connections be retrieved
934 * but not stored.
935 */
936 if (addr_list && (state->misc_flags & SMTP_MISC_FLAG_FIRST_NEXTHOP)) {
937 smtp_cache_policy(state, domain);
938 if (state->misc_flags & SMTP_MISC_FLAG_CONN_CACHE_MASK)
939 SET_SCACHE_REQUEST_NEXTHOP(state, dest);
940 }
941
942 /*
943 * Delete visited cached hosts from the address list.
944 *
945 * Optionally search the connection cache by domain name or by primary
946 * MX address before we try to create new connections.
947 *
948 * Enforce the MX session and MX address counts per next-hop or
949 * fall-back destination. smtp_reuse_session() will truncate the
950 * address list when either limit is reached.
951 */
952 if (addr_list && (state->misc_flags & SMTP_MISC_FLAG_CONN_LOAD)) {
953 if (state->cache_used->used > 0)
954 smtp_scrub_addr_list(state->cache_used, &addr_list);
955 sess_count = addr_count =
956 smtp_reuse_session(state, &addr_list, domain_best_pref);
957 } else
958 sess_count = addr_count = 0;
959
960 /*
961 * Connect to an SMTP server: create primary MX connections, and
962 * reuse or create backup MX connections.
963 *
964 * At the start of an SMTP session, all recipients are unmarked. In the
965 * course of an SMTP session, recipients are marked as KEEP (deliver
966 * to alternate mail server) or DROP (remove from recipient list). At
967 * the end of an SMTP session, weed out the recipient list. Unmark
968 * any left-over recipients and try to deliver them to a backup mail
969 * server.
970 *
971 * Cache the first good session under the next-hop destination name.
972 * Cache all good sessions under their physical endpoint.
973 *
974 * Don't query the session cache for primary MX hosts. We already did
975 * that in smtp_reuse_session(), and if any were found in the cache,
976 * they were already deleted from the address list.
977 *
978 * Currently, we use smtp_reuse_addr() only for SASL-unauthenticated
979 * connections. Furthermore, we rely on smtp_reuse_addr() to look up
980 * an existing SASL-unauthenticated connection only when a new
981 * connection would be guaranteed not to require SASL authentication.
982 *
983 * In addition, we rely on smtp_reuse_addr() to look up an existing
984 * plaintext connection only when a new connection would be
985 * guaranteed not to use TLS.
986 */
987 for (addr = addr_list; SMTP_RCPT_LEFT(state) > 0 && addr; addr = next) {
988 next = addr->next;
989 if (++addr_count == var_smtp_mxaddr_limit)
990 next = 0;
991 if (dns_rr_to_pa(addr, &hostaddr) == 0) {
992 msg_warn("cannot convert type %s record to printable address",
993 dns_strtype(addr->type));
994 /* XXX Assume there is no code at the end of this loop. */
995 continue;
996 }
997 vstring_strcpy(iter->addr, hostaddr.buf);
998 vstring_strcpy(iter->host, SMTP_HNAME(addr));
999 iter->rr = addr;
1000 #ifdef USE_TLS
1001 if (!smtp_tls_policy_cache_query(why, state->tls, iter)) {
1002 msg_warn("TLS policy lookup for %s/%s: %s",
1003 STR(iter->dest), STR(iter->host), STR(why->reason));
1004 continue;
1005 /* XXX Assume there is no code at the end of this loop. */
1006 }
1007 if (var_smtp_tls_wrappermode
1008 && state->tls->level < TLS_LEV_ENCRYPT) {
1009 msg_warn("%s requires \"%s = encrypt\" (or stronger)",
1010 VAR_LMTP_SMTP(TLS_WRAPPER), VAR_LMTP_SMTP(TLS_LEVEL));
1011 continue;
1012 /* XXX Assume there is no code at the end of this loop. */
1013 }
1014 /* Disable TLS when retrying after a handshake failure */
1015 if (retry_plain) {
1016 state->tls->level = TLS_LEV_NONE;
1017 retry_plain = 0;
1018 }
1019 #endif
1020 if ((state->misc_flags & SMTP_MISC_FLAG_CONN_LOAD) == 0
1021 || addr->pref == domain_best_pref
1022 || !(session = smtp_reuse_addr(state,
1023 SMTP_KEY_MASK_SCACHE_ENDP_LABEL)))
1024 session = smtp_connect_addr(iter, why, state->misc_flags);
1025 if ((state->session = session) != 0) {
1026 session->state = state;
1027 #ifdef USE_TLS
1028 session->tls_nexthop = domain;
1029 #endif
1030 if (addr->pref == domain_best_pref)
1031 session->features |= SMTP_FEATURE_BEST_MX;
1032 /* Don't count handshake errors towards the session limit. */
1033 if ((state->misc_flags & SMTP_MISC_FLAG_FINAL_NEXTHOP)
1034 && next == 0)
1035 state->misc_flags |= SMTP_MISC_FLAG_FINAL_SERVER;
1036 if ((session->features & SMTP_FEATURE_FROM_CACHE) == 0
1037 && smtp_helo(state) != 0) {
1038 #ifdef USE_TLS
1039
1040 /*
1041 * When an opportunistic TLS handshake fails, try the
1042 * same address again, with TLS disabled. See also the
1043 * RETRY_AS_PLAINTEXT macro.
1044 */
1045 if ((retry_plain = session->tls_retry_plain) != 0) {
1046 --addr_count;
1047 next = addr;
1048 }
1049 #endif
1050
1051 /*
1052 * When a TLS handshake fails, the stream is marked
1053 * "dead" to avoid further I/O over a broken channel.
1054 */
1055 if (!THIS_SESSION_IS_FORBIDDEN
1056 && vstream_ferror(session->stream) == 0
1057 && vstream_feof(session->stream) == 0)
1058 smtp_quit(state);
1059 } else {
1060 /* Do count delivery errors towards the session limit. */
1061 if (++sess_count == var_smtp_mxsess_limit)
1062 next = 0;
1063 if ((state->misc_flags & SMTP_MISC_FLAG_FINAL_NEXTHOP)
1064 && next == 0)
1065 state->misc_flags |= SMTP_MISC_FLAG_FINAL_SERVER;
1066 smtp_xfer(state);
1067 #ifdef USE_TLS
1068
1069 /*
1070 * When opportunistic TLS fails after the STARTTLS
1071 * handshake, try the same address again, with TLS
1072 * disabled. See also the RETRY_AS_PLAINTEXT macro.
1073 */
1074 if ((retry_plain = session->tls_retry_plain) != 0) {
1075 --sess_count;
1076 --addr_count;
1077 next = addr;
1078 }
1079 #endif
1080 }
1081 smtp_cleanup_session(state);
1082 } else {
1083 /* The reason already includes the IP address and TCP port. */
1084 msg_info("%s", STR(why->reason));
1085 }
1086 /* XXX Code above assumes there is no code at this loop ending. */
1087 }
1088 dns_rr_free(addr_list);
1089 if (iter->mx) {
1090 dns_rr_free(iter->mx);
1091 iter->mx = 0; /* Just in case */
1092 }
1093 myfree(dest_buf);
1094 if (state->misc_flags & SMTP_MISC_FLAG_FINAL_NEXTHOP)
1095 break;
1096 }
1097
1098 /*
1099 * We still need to deliver, bounce or defer some left-over recipients:
1100 * either mail loops or some backup mail server was unavailable.
1101 */
1102 if (SMTP_RCPT_LEFT(state) > 0) {
1103
1104 /*
1105 * In case of a "no error" indication we make up an excuse: we did
1106 * find the host address, but we did not attempt to connect to it.
1107 * This can happen when the fall-back relay was already tried via a
1108 * cached connection, so that the address list scrubber left behind
1109 * an empty list.
1110 */
1111 if (!SMTP_HAS_DSN(why)) {
1112 dsb_simple(why, "4.3.0",
1113 "server unavailable or unable to receive mail");
1114 }
1115
1116 /*
1117 * Pay attention to what could be configuration problems, and pretend
1118 * that these are recoverable rather than bouncing the mail.
1119 */
1120 else if (!SMTP_HAS_SOFT_DSN(why)) {
1121
1122 /*
1123 * The fall-back destination did not resolve as expected, or it
1124 * is refusing to talk to us, or mail for it loops back to us.
1125 */
1126 if (IS_FALLBACK_RELAY(cpp, sites, non_fallback_sites)) {
1127 msg_warn("%s configuration problem", VAR_SMTP_FALLBACK);
1128 vstring_strcpy(why->status, "4.3.5");
1129 /* XXX Keep the diagnostic code and MTA. */
1130 }
1131
1132 /*
1133 * The next-hop relayhost did not resolve as expected, or it is
1134 * refusing to talk to us, or mail for it loops back to us.
1135 *
1136 * XXX There is no equivalent safety net for mis-configured
1137 * sender-dependent relay hosts. The trivial-rewrite resolver
1138 * would have to flag the result, and the queue manager would
1139 * have to provide that information to delivery agents.
1140 */
1141 else if (smtp_mode && strcmp(sites->argv[0], var_relayhost) == 0) {
1142 msg_warn("%s configuration problem", VAR_RELAYHOST);
1143 vstring_strcpy(why->status, "4.3.5");
1144 /* XXX Keep the diagnostic code and MTA. */
1145 }
1146
1147 /*
1148 * Mail for the next-hop destination loops back to myself. Pass
1149 * the mail to the best_mx_transport or bounce it.
1150 */
1151 else if (smtp_mode && SMTP_HAS_LOOP_DSN(why) && *var_bestmx_transp) {
1152 dsb_reset(why); /* XXX */
1153 state->status = deliver_pass_all(MAIL_CLASS_PRIVATE,
1154 var_bestmx_transp,
1155 request);
1156 SMTP_RCPT_LEFT(state) = 0; /* XXX */
1157 }
1158 }
1159 }
1160
1161 /*
1162 * Cleanup.
1163 */
1164 if (HAVE_SCACHE_REQUEST_NEXTHOP(state))
1165 CLEAR_SCACHE_REQUEST_NEXTHOP(state);
1166 argv_free(sites);
1167 }
1168
1169 /* smtp_connect - establish SMTP connection */
1170
smtp_connect(SMTP_STATE * state)1171 int smtp_connect(SMTP_STATE *state)
1172 {
1173 DELIVER_REQUEST *request = state->request;
1174 char *destination = request->nexthop;
1175
1176 /*
1177 * All deliveries proceed along the same lines, whether they are over TCP
1178 * or UNIX-domain sockets, and whether they use SMTP or LMTP: get a
1179 * connection from the cache or create a new connection; deliver mail;
1180 * update the connection cache or disconnect.
1181 *
1182 * The major differences appear at a higher level: the expansion from
1183 * destination to address list, and whether to stop before we reach the
1184 * end of that list.
1185 */
1186
1187 /*
1188 * With LMTP we have direct-to-host delivery only. The destination may
1189 * have multiple IP addresses.
1190 */
1191 if (!smtp_mode) {
1192 if (strncmp(destination, "unix:", 5) == 0) {
1193 smtp_connect_local(state, destination + 5);
1194 } else {
1195 if (strncmp(destination, "inet:", 5) == 0)
1196 destination += 5;
1197 smtp_connect_inet(state, destination, var_smtp_tcp_port);
1198 }
1199 }
1200
1201 /*
1202 * XXX We don't add support for "unix:" or "inet:" prefixes in SMTP
1203 * destinations, because that would break compatibility with existing
1204 * Postfix configurations that have a host with such a name.
1205 */
1206 else {
1207 smtp_connect_inet(state, destination, var_smtp_tcp_port);
1208 }
1209
1210 /*
1211 * We still need to bounce or defer some left-over recipients: either
1212 * (SMTP) mail loops or some server was unavailable.
1213 *
1214 * We could avoid this (and the "final server" complexity) by keeping one
1215 * DSN structure per recipient in memory, by updating those in-memory
1216 * structures with each delivery attempt, and by always flushing all
1217 * deferred recipients at the end. We'd probably still want to bounce
1218 * recipients immediately, so we'd end up with another chunk of code for
1219 * defer logging only.
1220 */
1221 if (SMTP_RCPT_LEFT(state) > 0) {
1222 state->misc_flags |= SMTP_MISC_FLAG_FINAL_SERVER; /* XXX */
1223 smtp_sess_fail(state);
1224
1225 /*
1226 * Sanity check. Don't silently lose recipients.
1227 */
1228 smtp_rcpt_cleanup(state);
1229 if (SMTP_RCPT_LEFT(state) > 0)
1230 msg_panic("smtp_connect: left-over recipients");
1231 }
1232 return (state->status);
1233 }
1234