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