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