1/*++
2/* NAME
3/*	posttls-finger 1
4/* SUMMARY
5/*	Probe the TLS properties of an ESMTP or LMTP server.
6/* SYNOPSIS
7/*	\fBposttls-finger\fR [\fIoptions\fR] [\fBinet:\fR]\fIdomain\fR[:\fIport\fR] [\fImatch ...\fR]
8/* .br
9/*	\fBposttls-finger\fR -S [\fIoptions\fR] \fBunix:\fIpathname\fR [\fImatch ...\fR]
10/* DESCRIPTION
11/*	\fBposttls-finger\fR(1) connects to the specified destination
12/*	and reports TLS-related information about the server. With SMTP, the
13/*	destination is a domainname; with LMTP it is either a domainname
14/*	prefixed with \fBinet:\fR or a pathname prefixed with \fBunix:\fR.  If
15/*	Postfix is built without TLS support, the resulting posttls-finger
16/*	program has very limited functionality, and only the \fB-a\fR, \fB-c\fR,
17/*	\fB-h\fR, \fB-o\fR, \fB-S\fR, \fB-t\fR, \fB-T\fR and \fB-v\fR options
18/*	are available.
19/*
20/*	Note: this is an unsupported test program. No attempt is made
21/*	to maintain compatibility between successive versions.
22/*
23/*	For SMTP servers that don't support ESMTP, only the greeting banner
24/*	and the negative EHLO response are reported. Otherwise, the reported
25/*	EHLO response details further server capabilities.
26/*
27/*	If TLS support is enabled when \fBposttls-finger\fR(1) is compiled, and
28/*	the server supports \fBSTARTTLS\fR, a TLS handshake is attempted.
29/*
30/*	If DNSSEC support is available, the connection TLS security level
31/*	(\fB-l\fR option) defaults to \fBdane\fR; see TLS_README for
32/*	details. Otherwise, it defaults to \fBsecure\fR.  This setting
33/*	determines the certificate matching policy.
34/*
35/*	If TLS negotiation succeeds, the TLS protocol and cipher details are
36/*	reported. The server certificate is then verified in accordance with
37/*	the policy at the chosen (or default) security level.  With public
38/*	CA-based trust, when the \fB-L\fR option includes \fBcertmatch\fR,
39/*	(true by default) name matching is performed even if the certificate
40/*	chain is not trusted.  This logs the names found in the remote SMTP
41/*	server certificate and which if any would match, were the certificate
42/*	chain trusted.
43/*
44/*	Note: \fBposttls-finger\fR(1) does not perform any table lookups, so
45/*	the TLS policy table and obsolete per-site tables are not consulted.
46/*	It does not communicate with the \fBtlsmgr\fR(8) daemon (or any other
47/*	Postfix daemons); its TLS session cache is held in private memory, and
48/*	disappears when the process exits.
49/*
50/*	With the \fB-r \fIdelay\fR option, if the server assigns a TLS
51/*	session id, the TLS session is cached. The connection is then closed
52/*	and re-opened after the specified delay, and \fBposttls-finger\fR(1)
53/*	then reports whether the cached TLS session was re-used.
54/*
55/*	When the destination is a load-balancer, it may be distributing
56/*	load between multiple server caches. Typically, each server returns
57/*	its unique name in its EHLO response. If, upon reconnecting with
58/*	\fB-r\fR, a new server name is detected, another session is cached
59/*	for the new server, and the reconnect is repeated up to a maximum
60/*	number of times (default 5) that can be specified via the \fB-m\fR
61/*	option.
62/*
63/*	The choice of SMTP or LMTP (\fB-S\fR option) determines the syntax of
64/*	the destination argument. With SMTP, one can specify a service on a
65/*	non-default port as \fIhost\fR:\fIservice\fR, and disable MX (mail
66/*	exchanger) DNS lookups with [\fIhost\fR] or [\fIhost\fR]:\fIport\fR.
67/*	The [] form is required when you specify an IP address instead of a
68/*	hostname.  An IPv6 address takes the form [\fBipv6:\fIaddress\fR].
69/*	The default port for SMTP is taken from the \fBsmtp/tcp\fR entry in
70/*	/etc/services, defaulting to 25 if the entry is not found.
71/*
72/*	With LMTP, specify \fBunix:\fIpathname\fR to connect to a local server
73/*	listening on a unix-domain socket bound to the specified pathname;
74/*	otherwise, specify an optional \fBinet:\fR prefix followed by a
75/*	\fIdomain\fR and an optional port, with the same syntax as for
76/*	SMTP. The default TCP port for LMTP is 24.
77/*
78/*	Arguments:
79/* .IP "\fB-a\fR \fIfamily\fR (default: \fBany\fR)"
80/*	Address family preference: \fBipv4\fR, \fBipv6\fR or \fBany\fR.  When
81/*	using \fBany\fR, posttls-finger will randomly select one of the two as
82/*	the more preferred, and exhaust all MX preferences for the first
83/*	address family before trying any addresses for the other.
84/* .IP "\fB-A\fR \fItrust-anchor.pem\fR (default: none)"
85/*	A list of PEM trust-anchor files that overrides CAfile and CApath
86/*	trust chain verification.  Specify the option multiple times to
87/*	specify multiple files.  See the main.cf documentation for
88/*	smtp_tls_trust_anchor_file for details.
89/* .IP "\fB-c\fR"
90/*	Disable SMTP chat logging; only TLS-related information is logged.
91/* .IP "\fB-C\fR"
92/*	Print the remote SMTP server certificate trust chain in PEM format.
93/*	The issuer DN, subject DN, certificate and public key fingerprints
94/*	(see \fB-d \fImdalg\fR option below) are printed above each PEM
95/*	certificate block.  If you specify \fB-F \fICAfile\fR or
96/*	\fB-P \fICApath\fR, the OpenSSL library may augment the chain with
97/*	missing issuer certificates.  To see the actual chain sent by the
98/*	remote SMTP server leave \fICAfile\fR and \fICApath\fR unset.
99/* .IP "\fB-d \fImdalg\fR (default: \fBsha1\fR)"
100/*	The message digest algorithm to use for reporting remote SMTP server
101/*	fingerprints and matching against user provided certificate
102/*	fingerprints (with DANE TLSA records the algorithm is specified
103/*	in the DNS).
104/* .IP "\fB-f\fR"
105/*	Lookup the associated DANE TLSA RRset even when a hostname is not an
106/*	alias and its address records lie in an unsigned zone.  See
107/*	smtp_tls_force_insecure_host_tlsa_lookup for details.
108/* .IP "\fB-F \fICAfile.pem\fR (default: none)"
109/*	The PEM formatted CAfile for remote SMTP server certificate
110/*	verification.  By default no CAfile is used and no public CAs
111/*	are trusted.
112/* .IP "\fB-g \fIgrade\fR (default: medium)"
113/*	The minimum TLS cipher grade used by posttls-finger.  See
114/*	smtp_tls_mandatory_ciphers for details.
115/* .IP "\fB-h \fIhost_lookup\fR (default: \fBdns\fR)"
116/*	The hostname lookup methods used for the connection.  See the
117/*	documentation of smtp_host_lookup for syntax and semantics.
118/* .IP "\fB-l \fIlevel\fR (default: \fBdane\fR or \fBsecure\fR)"
119/*	The security level for the connection, default \fBdane\fR or
120/*	\fBsecure\fR depending on whether DNSSEC is available.  For syntax
121/*	and semantics, see the documentation of smtp_tls_security_level.
122/*	When \fBdane\fR or \fBdane-only\fR is supported and selected, if no
123/*	TLSA records are found, or all the records found are unusable, the
124/*	\fIsecure\fR level will be used instead.  The \fBfingerprint\fR
125/*	security level allows you to test certificate or public-key
126/*	fingerprint matches before you deploy them in the policy table.
127/* .IP
128/*	Note, since \fBposttls-finger\fR does not actually deliver any email,
129/*	the \fBnone\fR, \fBmay\fR and \fBencrypt\fR security levels are not
130/*	very useful.  Since \fBmay\fR and \fBencrypt\fR don't require peer
131/*	certificates, they will often negotiate anonymous TLS ciphersuites,
132/*	so you won't learn much about the remote SMTP server's certificates
133/*	at these levels if it also supports anonymous TLS (though you may
134/*	learn that the server supports anonymous TLS).
135/* .IP "\fB-L \fIlogopts\fR (default: \fBroutine,certmatch\fR)"
136/*	Fine-grained TLS logging options. To tune the TLS features logged
137/*	during the TLS handshake, specify one or more of:
138/* .RS
139/* .IP "\fB0, none\fR"
140/*	These yield no TLS logging; you'll generally want more, but this
141/*	is handy if you just want the trust chain:
142/* .RS
143/* .ad
144/* .nf
145/*	$ posttls-finger -cC -L none destination
146/* .fi
147/* .RE
148/* .IP "\fB1, routine, summary\fR"
149/*	These synonymous values yield a normal one-line summary of the TLS
150/*	connection.
151/* .IP "\fB2, debug\fR"
152/*	These synonymous values combine routine, ssl-debug, cache and verbose.
153/* .IP "\fB3, ssl-expert\fR"
154/*	These synonymous values combine debug with ssl-handshake-packet-dump.
155/*	For experts only.
156/* .IP "\fB4, ssl-developer\fR"
157/*	These synonymous values combine ssl-expert with ssl-session-packet-dump.
158/*	For experts only, and in most cases, use wireshark instead.
159/* .IP "\fBssl-debug\fR"
160/*	Turn on OpenSSL logging of the progress of the SSL handshake.
161/* .IP "\fBssl-handshake-packet-dump\fR"
162/*	Log hexadecimal packet dumps of the SSL handshake; for experts only.
163/* .IP "\fBssl-session-packet-dump\fR"
164/*	Log hexadecimal packet dumps of the entire SSL session; only useful
165/*	to those who can debug SSL protocol problems from hex dumps.
166/* .IP "\fBuntrusted\fR"
167/*	Logs trust chain verification problems.  This is turned on
168/*	automatically at security levels that use peer names signed
169/*	by certificate authorities to validate certificates.  So while
170/*	this setting is recognized, you should never need to set it
171/*	explicitly.
172/* .IP "\fBpeercert\fR"
173/*	This logs a one line summary of the remote SMTP server certificate
174/*	subject, issuer, and fingerprints.
175/* .IP "\fBcertmatch\fR"
176/*	This logs remote SMTP server certificate matching, showing the CN
177/*	and each subjectAltName and which name matched.  With DANE, logs
178/*	matching of TLSA record trust-anchor and end-entity certificates.
179/* .IP "\fBcache\fR"
180/*	This logs session cache operations, showing whether session caching
181/*	is effective with the remote SMTP server.  Automatically used when
182/*	reconnecting with the \fB-r\fR option; rarely needs to be set
183/*	explicitly.
184/* .IP "\fBverbose\fR"
185/*	Enables verbose logging in the Postfix TLS driver; includes all of
186/*	peercert..cache and more.
187/* .RE
188/* .IP
189/*	The default is \fBroutine,certmatch\fR. After a reconnect,
190/*	\fBpeercert\fR, \fBcertmatch\fR and \fBverbose\fR are automatically
191/*	disabled while \fBcache\fR and \fBsummary\fR are enabled.
192/* .IP "\fB-m \fIcount\fR (default: \fB5\fR)"
193/*	When the \fB-r \fIdelay\fR option is specified, the \fB-m\fR option
194/*	determines the maximum number of reconnect attempts to use with
195/*	a server behind a load-balacer, to see whether connection caching
196/*	is likely to be effective for this destination.  Some MTAs
197/*	don't expose the underlying server identity in their EHLO
198/*	response; with these servers there will never be more than
199/*	1 reconnection attempt.
200/* .IP "\fB-o \fIname=value\fR"
201/*	Specify zero or more times to override the value of the main.cf
202/*	parameter \fIname\fR with \fIvalue\fR.  Possible use-cases include
203/*	overriding the values of TLS library parameters, or "myhostname" to
204/*	configure the SMTP EHLO name sent to the remote server.
205/* .IP "\fB-p \fIprotocols\fR (default: !SSLv2)"
206/*	List of TLS protocols that posttls-finger will exclude or include.  See
207/*	smtp_tls_mandatory_protocols for details.
208/* .IP "\fB-P \fICApath/\fR (default: none)"
209/*	The OpenSSL CApath/ directory (indexed via c_rehash(1)) for remote
210/*	SMTP server certificate verification.  By default no CApath is used
211/*	and no public CAs are trusted.
212/* .IP "\fB-r \fIdelay\fR"
213/*	With a cachable TLS session, disconnect and reconnect after \fIdelay\fR
214/*	seconds. Report whether the session is re-used. Retry if a new server
215/*	is encountered, up to 5 times or as specified with the \fB-m\fR option.
216/*	By default reconnection is disabled, specify a positive delay to
217/*	enable this behavior.
218/* .IP "\fB-S\fR"
219/*	Disable SMTP; that is, connect to an LMTP server. The default port for
220/*	LMTP over TCP is 24.  Alternative ports can specified by appending
221/*	"\fI:servicename\fR" or ":\fIportnumber\fR" to the destination
222/*	argument.
223/* .IP "\fB-t \fItimeout\fR (default: \fB30\fR)"
224/*	The TCP connection timeout to use.  This is also the timeout for
225/*	reading the remote server's 220 banner.
226/* .IP "\fB-T \fItimeout\fR (default: \fB30\fR)"
227/*	The SMTP/LMTP command timeout for EHLO/LHLO, STARTTLS and QUIT.
228/* .IP "\fB-v\fR"
229/*	Enable verose Postfix logging.  Specify more than once to increase
230/*	the level of verbose logging.
231/* .IP "[\fBinet:\fR]\fIdomain\fR[:\fIport\fR]"
232/*	Connect via TCP to domain \fIdomain\fR, port \fIport\fR. The default
233/*	port is \fBsmtp\fR (or 24 with LMTP).  With SMTP an MX lookup is
234/*	performed to resolve the domain to a host, unless the domain is
235/*	enclosed in \fB[]\fR.  If you want to connect to a specific MX host,
236/*	for instance \fImx1.example.com\fR, specify [\fImx1.example.com\fR]
237/*	as the destination and \fIexample.com\fR as a \fBmatch\fR argument.
238/*	When using DNS, the destination domain is assumed fully qualified
239/*	and no default domain or search suffixes are applied; you must use
240/*	fully-qualified names or also enable \fBnative\fR host lookups
241/*	(these don't support \fBdane\fR or \fBdane-only\fR as no DNSSEC
242/*	validation information is available via \fBnative\fR lookups).
243/* .IP "\fBunix:\fIpathname\fR"
244/*	Connect to the UNIX-domain socket at \fIpathname\fR. LMTP only.
245/* .IP "\fBmatch ...\fR"
246/*	With no match arguments specified, certificate peername matching uses
247/*	the compiled-in default strategies for each security level.  If you
248/*	specify one or more arguments, these will be used as the list of
249/*	certificate or public-key digests to match for the \fBfingerprint\fR
250/*	level, or as the list of DNS names to match in the certificate at the
251/*	\fBverify\fR and \fBsecure\fR levels.  If the security level is
252/*	\fBdane\fR, or \fBdane-only\fR the match names are ignored, and
253/*	\fBhostname, nexthop\fR strategies are used.
254/* .ad
255/* .fi
256/* ENVIRONMENT
257/* .ad
258/* .fi
259/* .IP \fBMAIL_CONFIG\fR
260/*	Read configuration parameters from a non-default location.
261/* .IP \fBMAIL_VERBOSE\fR
262/*	Same as \fB-v\fR option.
263/* SEE ALSO
264/*	smtp-source(1), SMTP/LMTP message source
265/*	smtp-sink(1), SMTP/LMTP message dump
266/*
267/* README FILES
268/* .ad
269/* .fi
270/*	Use "\fBpostconf readme_directory\fR" or "\fBpostconf
271/*	html_directory\fR" to locate this information.
272/* .na
273/* .nf
274/*	TLS_README, Postfix STARTTLS howto
275/* LICENSE
276/* .ad
277/* .fi
278/*	The Secure Mailer license must be distributed with this software.
279/* AUTHOR(S)
280/*	Wietse Venema
281/*	IBM T.J. Watson Research
282/*	P.O. Box 704
283/*	Yorktown Heights, NY 10598, USA
284/*
285/*	Viktor Dukhovni
286/*--*/
287
288 /*
289  * System library.
290  */
291#include <sys_defs.h>
292#include <stdarg.h>
293#include <string.h>
294#include <ctype.h>
295#include <stdlib.h>
296#include <unistd.h>
297#include <signal.h>
298#include <fcntl.h>
299#include <errno.h>
300#include <sys/socket.h>
301#include <sys/un.h>
302#include <netinet/in.h>
303#include <arpa/inet.h>
304
305 /*
306  * Utility library.
307  */
308#include <msg.h>
309#include <msg_vstream.h>
310#include <vstring.h>
311#include <vstream.h>
312#include <vstring_vstream.h>
313#include <mymalloc.h>
314#include <stringops.h>
315#include <argv.h>
316#include <name_mask.h>
317#include <name_code.h>
318#include <chroot_uid.h>
319#include <host_port.h>
320#include <inet_proto.h>
321#include <iostuff.h>
322#include <timed_connect.h>
323#include <sane_connect.h>
324#include <myaddrinfo.h>
325#include <sock_addr.h>
326
327#define STR(x)		vstring_str(x)
328
329 /*
330  * Global library.
331  */
332#include <mail_params.h>
333#include <mail_conf.h>
334#include <smtp_stream.h>
335#include <dsn_buf.h>
336
337/* DNS library. */
338
339#include <dns.h>
340
341 /*
342  * master library
343  */
344#include <mail_server.h>
345
346 /*
347  * TLS Library
348  */
349#define TLS_INTERNAL
350#include <tls.h>
351
352#ifdef USE_TLS
353#include <openssl/engine.h>
354#endif
355
356 /*
357  * Application specific
358  */
359#include "tlsmgrmem.h"
360
361static int conn_tmout = 30;
362static int smtp_tmout = 30;
363
364#define HOST_FLAG_DNS		(1<<0)
365#define HOST_FLAG_NATIVE	(1<<1)
366
367#define MISC_FLAG_PREF_IPV6	(1<<0)
368#define MISC_FLAG_PREF_IPV4	(1<<1)
369
370static const NAME_MASK lookup_masks[] = {
371    "dns", HOST_FLAG_DNS,
372    "native", HOST_FLAG_NATIVE,
373    0,
374};
375
376static const NAME_CODE addr_pref_map[] = {
377    INET_PROTO_NAME_IPV6, MISC_FLAG_PREF_IPV6,
378    INET_PROTO_NAME_IPV4, MISC_FLAG_PREF_IPV4,
379    INET_PROTO_NAME_ANY, 0,
380    0, -1,
381};
382
383typedef struct OPTIONS {
384    char   *logopts;
385    char   *level;
386    ARGV   *tas;
387    char   *host_lookup;
388    char   *addr_pref;
389} OPTIONS;
390
391 /*
392  * Per-session data structure with state.
393  *
394  * This software can maintain multiple parallel connections to the same SMTP
395  * server. However, it makes no more than one connection request at a time
396  * to avoid overwhelming the server with SYN packets and having to back off.
397  * Back-off would screw up the benchmark. Pending connection requests are
398  * kept in a linear list.
399  */
400typedef struct STATE {
401    int     smtp;			/* SMTP or LMTP? */
402    int     host_lookup;		/* dns|native|dns,native */
403    int     addr_pref;			/* v4, v6, both */
404    int     log_mask;			/* via tls_log_mask() */
405    int     reconnect;			/* -r option */
406    int     max_reconnect;		/* -m option */
407    int     force_tlsa;			/* -f option */
408    unsigned port;			/* TCP port */
409    char   *dest;			/* Full destination spec */
410    char   *addrport;			/* [addr]:port */
411    char   *namaddrport;		/* name[addr]:port */
412    char   *nexthop;			/* Nexthop domain for verification */
413    char   *hostname;			/* Hostname for verification */
414    DNS_RR *addr;			/* IPv[46] Address to (re)connect to */
415    DNS_RR *mx;				/* MX RRset qname, rname, valid */
416    int     pass;			/* Pass number, 2 for reconnect */
417    int     nochat;			/* disable chat logging */
418    char   *helo;			/* Server name from EHLO reply */
419    DSN_BUF *why;			/* SMTP-style error message */
420    VSTRING *buffer;			/* Response buffer */
421    VSTREAM *stream;			/* Open connection */
422    int     level;			/* TLS security level */
423#ifdef USE_TLS
424    char   *mdalg;			/* fingerprint digest algorithm */
425    char   *CAfile;			/* Trusted public CAs */
426    char   *CApath;			/* Trusted public CAs */
427    ARGV   *match;			/* match arguments */
428    int     print_trust;		/* -C option */
429    BIO    *tls_bio;			/* BIO wrapper for stdout */
430    TLS_APPL_STATE *tls_ctx;		/* Application TLS context */
431    TLS_SESS_STATE *tls_context;	/* Session TLS context */
432    TLS_DANE *dane;			/* DANE TLSA validation structure */
433    TLS_DANE *ddane;			/* DANE TLSA from DNS */
434    char   *grade;			/* Minimum cipher grade */
435    char   *protocols;			/* Protocol inclusion/exclusion */
436#endif
437    OPTIONS options;			/* JCL */
438} STATE;
439
440static DNS_RR *host_addr(STATE *, const char *);
441
442#define HNAME(addr) (addr->qname)
443
444 /*
445  * Structure with broken-up SMTP server response.
446  */
447typedef struct {			/* server response */
448    int     code;			/* status */
449    char   *str;			/* text */
450    VSTRING *buf;			/* origin of text */
451} RESPONSE;
452
453
454/* command - send an SMTP command */
455
456static void command(STATE *state, int verbose, char *fmt,...)
457{
458    VSTREAM *stream = state->stream;
459    VSTRING *buf;
460    va_list ap;
461    char   *line;
462
463    buf = vstring_alloc(100);
464    va_start(ap, fmt);
465    vstring_vsprintf(buf, fmt, ap);
466    va_end(ap);
467    line = vstring_str(buf);
468
469    while (line && *line) {
470	char   *nextline = strchr(line, '\n');
471
472	if (nextline)
473	    *nextline++ = '\0';
474	if (verbose && !state->nochat)
475	    msg_info("> %s", line);
476	smtp_printf(stream, "%s", line);
477	line = nextline;
478    }
479
480    vstring_free(buf);
481}
482
483/* response - read and process SMTP server response */
484
485static RESPONSE *response(STATE *state, int verbose)
486{
487    VSTREAM *stream = state->stream;
488    VSTRING *buf = state->buffer;
489    static RESPONSE rdata;
490    int     more;
491    char   *cp;
492
493    /*
494     * Initialize the response data buffer. Defend against a denial of
495     * service attack by limiting the amount of multi-line text that we are
496     * willing to store.
497     */
498    if (rdata.buf == 0) {
499	rdata.buf = vstring_alloc(100);
500	vstring_ctl(rdata.buf, VSTRING_CTL_MAXLEN, (ssize_t) var_line_limit, 0);
501    }
502
503    /*
504     * Censor out non-printable characters in server responses. Concatenate
505     * multi-line server responses. Separate the status code from the text.
506     * Leave further parsing up to the application.
507     */
508#define BUF ((char *) vstring_str(buf))
509    VSTRING_RESET(rdata.buf);
510    for (;;) {
511	smtp_get(buf, stream, var_line_limit, SMTP_GET_FLAG_SKIP);
512	for (cp = BUF; *cp != 0; cp++)
513	    if (!ISPRINT(*cp) && !ISSPACE(*cp))
514		*cp = '?';
515	cp = BUF;
516	if (verbose && !state->nochat)
517	    msg_info("< %s", cp);
518	while (ISDIGIT(*cp))
519	    cp++;
520	rdata.code = (cp - BUF == 3 ? atoi(BUF) : 0);
521	if ((more = (*cp == '-')) != 0)
522	    cp++;
523	while (ISSPACE(*cp))
524	    cp++;
525	vstring_strcat(rdata.buf, cp);
526	if (more == 0)
527	    break;
528	VSTRING_ADDCH(rdata.buf, '\n');
529    }
530    VSTRING_TERMINATE(rdata.buf);
531    rdata.str = vstring_str(rdata.buf);
532    return (&rdata);
533}
534
535/* exception_text - translate exceptions from the smtp_stream module */
536
537static char *exception_text(int except)
538{
539    switch (except) {
540	case SMTP_ERR_EOF:
541	return ("lost connection");
542    case SMTP_ERR_TIME:
543	return ("timeout");
544    default:
545	msg_panic("exception_text: unknown exception %d", except);
546    }
547}
548
549/* ehlo - send EHLO/LHLO */
550
551static RESPONSE *ehlo(STATE *state)
552{
553    int     except;
554    int     verbose;
555    volatile char *ehlo = state->smtp ? "EHLO" : "LHLO";
556    VSTREAM *stream = state->stream;
557    RESPONSE *resp;
558
559#ifdef USE_TLS
560    verbose = (state->pass == 1 && state->nochat == 0);
561#else
562    verbose = 1;
563#endif
564
565    /*
566     * Send the standard greeting with our hostname
567     */
568    if ((except = vstream_setjmp(stream)) != 0) {
569	msg_info("%s while sending %s", exception_text(except), ehlo);
570	return (0);
571    }
572    command(state, verbose, "%s %s", ehlo, var_myhostname);
573
574    resp = response(state, verbose);
575    if (resp->code / 100 != 2) {
576	msg_info("%s rejected: %d %s", ehlo, resp->code, resp->str);
577	return (0);
578    }
579    return resp;
580}
581
582#ifdef USE_TLS
583
584static void print_stack(STATE *state, x509_stack_t *sk, int trustout)
585{
586    int     i;
587
588    for (i = 0; i < sk_X509_num(sk); i++) {
589	X509   *cert = sk_X509_value(sk, i);
590	char    buf[CCERT_BUFSIZ];
591	X509_NAME *xn;
592	char   *digest;
593
594	if ((xn = X509_get_subject_name(cert)) != 0) {
595	    X509_NAME_oneline(xn, buf, sizeof buf);
596	    BIO_printf(state->tls_bio, "%2d subject: %s\n", i, buf);
597	}
598	if ((xn = X509_get_issuer_name(cert)) != 0) {
599	    X509_NAME_oneline(xn, buf, sizeof buf);
600	    BIO_printf(state->tls_bio, "    issuer: %s\n", buf);
601	}
602	digest = tls_cert_fprint(cert, state->mdalg);
603	BIO_printf(state->tls_bio, "   cert digest=%s\n", digest);
604	myfree(digest);
605
606	digest = tls_pkey_fprint(cert, state->mdalg);
607	BIO_printf(state->tls_bio, "   pkey digest=%s\n", digest);
608	myfree(digest);
609
610	if (trustout)
611	    PEM_write_bio_X509_AUX(state->tls_bio, cert);
612	else
613	    PEM_write_bio_X509(state->tls_bio, cert);
614    }
615}
616
617static void print_trust_info(STATE *state)
618{
619    x509_stack_t *sk = SSL_get_peer_cert_chain(state->tls_context->con);
620
621    if (sk != 0) {
622	BIO_printf(state->tls_bio, "\n---\nCertificate chain\n");
623	print_stack(state, sk, 0);
624    }
625#ifdef dane_verify_debug
626    /* print internally constructed untrusted chain */
627    if ((sk = state->tls_context->untrusted) != 0) {
628	BIO_printf(state->tls_bio, "\n---\nUntrusted chain\n");
629	print_stack(state, sk, 0);
630    }
631    /* print associated root CA */
632    if ((sk = state->tls_context->trusted) != 0) {
633	BIO_printf(state->tls_bio, "\n---\nTrusted chain\n");
634	print_stack(state, sk, 1);
635    }
636#endif
637}
638
639/* starttls - SMTP STARTTLS handshake */
640
641static int starttls(STATE *state)
642{
643    VSTRING *cipher_exclusions;
644    int     except;
645    RESPONSE *resp;
646    VSTREAM *stream = state->stream;
647    TLS_CLIENT_START_PROPS tls_props;
648
649    /* SMTP stream with deadline timeouts */
650    smtp_stream_setup(stream, smtp_tmout, 1);
651    if ((except = vstream_setjmp(stream)) != 0) {
652	msg_fatal("%s while sending STARTTLS", exception_text(except));
653	return (1);
654    }
655    command(state, state->pass == 1, "STARTTLS");
656
657    resp = response(state, state->pass == 1);
658    if (resp->code / 100 != 2) {
659	msg_info("STARTTLS rejected: %d %s", resp->code, resp->str);
660	return (1);
661    }
662
663    /*
664     * Discard any plain-text data that may be piggybacked after the server's
665     * 220 STARTTLS reply. Should we abort the session instead?
666     */
667    vstream_fpurge(stream, VSTREAM_PURGE_READ);
668
669#define ADD_EXCLUDE(vstr, str) \
670    do { \
671	if (*(str)) \
672	    vstring_sprintf_append((vstr), "%s%s", \
673				   VSTRING_LEN(vstr) ? " " : "", (str)); \
674    } while (0)
675
676    cipher_exclusions = vstring_alloc(10);
677    ADD_EXCLUDE(cipher_exclusions, DEF_SMTP_TLS_EXCL_CIPH);
678    if (TLS_REQUIRED(state->level))
679	ADD_EXCLUDE(cipher_exclusions, DEF_SMTP_TLS_MAND_EXCL);
680
681    /*
682     * If we're authenticating suppress anonymous ciphersuites, otherwise at
683     * least encrypt, not much point in doing neither.
684     */
685    if (TLS_MUST_MATCH(state->level))
686	ADD_EXCLUDE(cipher_exclusions, "aNULL");
687    else
688	ADD_EXCLUDE(cipher_exclusions, "eNULL");
689
690    state->tls_context =
691	TLS_CLIENT_START(&tls_props,
692			 ctx = state->tls_ctx,
693			 stream = stream,
694			 timeout = smtp_tmout,
695			 tls_level = state->level,
696			 nexthop = state->nexthop,
697			 host = state->hostname,
698			 namaddr = state->namaddrport,
699			 serverid = state->addrport,
700			 helo = state->helo ? state->helo : "",
701			 protocols = state->protocols,
702			 cipher_grade = state->grade,
703			 cipher_exclusions
704			 = vstring_str(cipher_exclusions),
705			 matchargv = state->match,
706			 mdalg = state->mdalg,
707			 dane = state->ddane ? state->ddane : state->dane);
708    vstring_free(cipher_exclusions);
709    if (state->helo) {
710	myfree(state->helo);
711	state->helo = 0;
712    }
713    if (state->tls_context == 0) {
714	/* We must avoid further I/O, the peer is in an undefined state. */
715	(void) vstream_fpurge(stream, VSTREAM_PURGE_BOTH);
716	(void) vstream_fclose(stream);
717	state->stream = 0;
718	return (1);
719    }
720    if (state->pass == 1) {
721	ehlo(state);
722	if (!TLS_CERT_IS_PRESENT(state->tls_context))
723	    msg_info("Server is anonymous");
724	else if (state->print_trust)
725	    print_trust_info(state);
726	state->log_mask &= ~(TLS_LOG_CERTMATCH | TLS_LOG_PEERCERT |
727			     TLS_LOG_VERBOSE | TLS_LOG_UNTRUSTED);
728	state->log_mask |= TLS_LOG_CACHE | TLS_LOG_SUMMARY;
729	tls_update_app_logmask(state->tls_ctx, state->log_mask);
730    }
731    return (0);
732}
733
734#endif
735
736/* doproto - do SMTP handshake */
737
738static int doproto(STATE *state)
739{
740    VSTREAM *stream = state->stream;
741    RESPONSE *resp;
742    int     except;
743    int     n;
744    char   *lines;
745    char   *words;
746    char   *word;
747
748    /*
749     * Prepare for disaster.
750     */
751    smtp_stream_setup(stream, conn_tmout, 1);
752    if ((except = vstream_setjmp(stream)) != 0)
753	msg_fatal("%s while reading server greeting", exception_text(except));
754
755    /*
756     * Read and parse the server's SMTP greeting banner.
757     */
758    if (((resp = response(state, 1))->code / 100) != 2) {
759	msg_info("SMTP service not available: %d %s", resp->code, resp->str);
760	return (1);
761    }
762
763    /*
764     * Send the standard greeting with our hostname
765     */
766    if ((resp = ehlo(state)) == 0)
767	return (1);
768
769    lines = resp->str;
770    for (n = 0; (words = mystrtok(&lines, "\n")) != 0; ++n) {
771	if ((word = mystrtok(&words, " \t=")) != 0) {
772	    if (n == 0)
773		state->helo = mystrdup(word);
774	    if (strcasecmp(word, "STARTTLS") == 0)
775		break;
776	}
777    }
778
779#ifdef USE_TLS
780    if (words && state->tls_ctx)
781	if (starttls(state))
782	    return (1);
783#endif
784
785    /*
786     * Prepare for disaster.
787     */
788    smtp_stream_setup(stream, smtp_tmout, 1);
789    if ((except = vstream_setjmp(stream)) != 0) {
790	msg_warn("%s while sending QUIT command", exception_text(except));
791	return (0);
792    }
793    command(state, 1, "QUIT");
794    (void) response(state, 1);
795
796    return (0);
797}
798
799/* connect_sock - connect a socket over some transport */
800
801static VSTREAM *connect_sock(int sock, struct sockaddr *sa, int salen,
802		           const char *name, const char *addr, STATE *state)
803{
804    DSN_BUF *why = state->why;
805    int     conn_stat;
806    int     saved_errno;
807    VSTREAM *stream;
808
809    if (conn_tmout > 0) {
810	non_blocking(sock, NON_BLOCKING);
811	conn_stat = timed_connect(sock, sa, salen, conn_tmout);
812	saved_errno = errno;
813	non_blocking(sock, BLOCKING);
814	errno = saved_errno;
815    } else {
816	conn_stat = sane_connect(sock, sa, salen);
817    }
818    if (conn_stat < 0) {
819	if (state->port)
820	    dsb_simple(why, "4.4.1", "connect to %s[%s]:%d: %m",
821		       name, addr, ntohs(state->port));
822	else
823	    dsb_simple(why, "4.4.1", "connect to %s[%s]: %m", name, addr);
824	close(sock);
825	return (0);
826    }
827    stream = vstream_fdopen(sock, O_RDWR);
828    state->namaddrport =
829	vstring_export(state->port == 0 ?
830		  vstring_sprintf(vstring_alloc(10), "%s[%s]", name, addr) :
831		       vstring_sprintf(vstring_alloc(10), "%s[%s]:%u",
832				       name, addr, ntohs(state->port)));
833    state->addrport =
834	vstring_export(state->port == 0 ?
835		       vstring_sprintf(vstring_alloc(10), "%s", addr) :
836		       vstring_sprintf(vstring_alloc(10), "[%s]:%u",
837				       addr, ntohs(state->port)));
838
839    /*
840     * Avoid poor performance when TCP MSS > VSTREAM_BUFSIZE.
841     */
842    if (sa->sa_family == AF_INET
843#ifdef AF_INET6
844	|| sa->sa_family == AF_INET6
845#endif
846	)
847	vstream_tweak_tcp(stream);
848
849    return (stream);
850}
851
852/* connect_unix - connect to a unix-domain socket */
853
854static VSTREAM *connect_unix(STATE *state, const char *path)
855{
856    static const char *myname = "connect_unix";
857    DSN_BUF *why = state->why;
858    struct sockaddr_un sock_un;
859    int     len = strlen(path);
860    int     sock;
861
862    if (!state->nexthop)
863	state->nexthop = mystrdup(var_myhostname);
864    state->hostname = mystrdup(var_myhostname);
865
866    dsb_reset(why);				/* Paranoia */
867
868    /*
869     * Sanity checks.
870     */
871    if (len >= (int) sizeof(sock_un.sun_path)) {
872	dsb_simple(why, "4.3.5", "unix-domain name too long: %s", path);
873	return (0);
874    }
875
876    /*
877     * Initialize.
878     */
879    memset((char *) &sock_un, 0, sizeof(sock_un));
880    sock_un.sun_family = AF_UNIX;
881#ifdef HAS_SUN_LEN
882    sock_un.sun_len = len + 1;
883#endif
884    memcpy(sock_un.sun_path, path, len + 1);
885
886    /*
887     * Create a client socket.
888     */
889    if ((sock = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
890	msg_fatal("%s: socket: %m", myname);
891
892    /*
893     * Connect to the server.
894     */
895    if (msg_verbose)
896	msg_info("%s: trying: %s...", myname, path);
897
898    return (connect_sock(sock, (struct sockaddr *) &sock_un, sizeof(sock_un),
899			 var_myhostname, path, state));
900}
901
902/* connect_addr - connect to explicit address */
903
904static VSTREAM *connect_addr(STATE *state, DNS_RR *addr)
905{
906    static const char *myname = "connect_addr";
907    DSN_BUF *why = state->why;
908    struct sockaddr_storage ss;		/* remote */
909    struct sockaddr *sa = (struct sockaddr *) &ss;
910    SOCKADDR_SIZE salen = sizeof(ss);
911    MAI_HOSTADDR_STR hostaddr;
912    int     sock;
913
914    dsb_reset(why);				/* Paranoia */
915
916    /*
917     * Sanity checks.
918     */
919    if (dns_rr_to_sa(addr, state->port, sa, &salen) != 0) {
920	msg_warn("%s: skip address type %s: %m",
921		 myname, dns_strtype(addr->type));
922	dsb_simple(why, "4.4.0", "network address conversion failed: %m");
923	return (0);
924    }
925
926    /*
927     * Initialize.
928     */
929    if ((sock = socket(sa->sa_family, SOCK_STREAM, 0)) < 0)
930	msg_fatal("%s: socket: %m", myname);
931
932    if (inet_windowsize > 0)
933	set_inet_windowsize(sock, inet_windowsize);
934
935    /*
936     * Connect to the server.
937     */
938    SOCKADDR_TO_HOSTADDR(sa, salen, &hostaddr, (MAI_SERVPORT_STR *) 0, 0);
939    if (msg_verbose)
940	msg_info("%s: trying: %s[%s] port %d...",
941		 myname, HNAME(addr), hostaddr.buf, ntohs(state->port));
942
943    return (connect_sock(sock, sa, salen, HNAME(addr), hostaddr.buf, state));
944}
945
946#define HAS_DSN(why)		(STR((why)->status)[0] != 0)
947#define HAS_SOFT_DSN(why)	(STR((why)->status)[0] == '4')
948#define HAS_HARD_DSN(why)	(STR((why)->status)[0] == '5')
949#define HAS_LOOP_DSN(why) \
950    (HAS_DSN(why) && strcmp(STR((why)->status) + 1, ".4.6") == 0)
951
952#define SET_SOFT_DSN(why)	(STR((why)->status)[0] = '4')
953#define SET_HARD_DSN(why)	(STR((why)->status)[0] = '5')
954
955/* addr_one - address lookup for one host name */
956
957static DNS_RR *addr_one(STATE *state, DNS_RR *addr_list, const char *host,
958			        int res_opt, unsigned pref)
959{
960    static const char *myname = "addr_one";
961    DSN_BUF *why = state->why;
962    DNS_RR *addr = 0;
963    DNS_RR *rr;
964    int     aierr;
965    struct addrinfo *res0;
966    struct addrinfo *res;
967    INET_PROTO_INFO *proto_info = inet_proto_info();
968    int     found;
969
970    if (msg_verbose)
971	msg_info("%s: host %s", myname, host);
972
973    /*
974     * Interpret a numerical name as an address.
975     */
976    if (hostaddr_to_sockaddr(host, (char *) 0, 0, &res0) == 0
977     && strchr((char *) proto_info->sa_family_list, res0->ai_family) != 0) {
978	if ((addr = dns_sa_to_rr(host, pref, res0->ai_addr)) == 0)
979	    msg_fatal("host %s: conversion error for address family %d: %m",
980		    host, ((struct sockaddr *) (res0->ai_addr))->sa_family);
981	addr_list = dns_rr_append(addr_list, addr);
982	freeaddrinfo(res0);
983	return (addr_list);
984    }
985
986    /*
987     * Use DNS lookup, but keep the option open to use native name service.
988     *
989     * XXX A soft error dominates past and future hard errors. Therefore we
990     * should not clobber a soft error text and status code.
991     */
992    if (state->host_lookup & HOST_FLAG_DNS) {
993	switch (dns_lookup_v(host, res_opt, &addr, (VSTRING *) 0,
994			     why->reason, DNS_REQ_FLAG_NONE,
995			     proto_info->dns_atype_list)) {
996	case DNS_OK:
997	    for (rr = addr; rr; rr = rr->next)
998		rr->pref = pref;
999	    addr_list = dns_rr_append(addr_list, addr);
1000	    return (addr_list);
1001	default:
1002	    dsb_status(why, "4.4.3");
1003	    return (addr_list);
1004	case DNS_FAIL:
1005	    dsb_status(why, HAS_SOFT_DSN(why) ? "4.4.3" : "5.4.3");
1006	    return (addr_list);
1007	case DNS_INVAL:
1008	    dsb_status(why, HAS_SOFT_DSN(why) ? "4.4.4" : "5.4.4");
1009	    return (addr_list);
1010	case DNS_NOTFOUND:
1011	    dsb_status(why, HAS_SOFT_DSN(why) ? "4.4.4" : "5.4.4");
1012	    /* maybe native naming service will succeed */
1013	    break;
1014	}
1015    }
1016
1017    /*
1018     * Use the native name service which also looks in /etc/hosts.
1019     *
1020     * XXX A soft error dominates past and future hard errors. Therefore we
1021     * should not clobber a soft error text and status code.
1022     */
1023#define RETRY_AI_ERROR(e) \
1024        ((e) == EAI_AGAIN || (e) == EAI_MEMORY || (e) == EAI_SYSTEM)
1025#ifdef EAI_NODATA
1026#define DSN_NOHOST(e) \
1027	((e) == EAI_AGAIN || (e) == EAI_NODATA || (e) == EAI_NONAME)
1028#else
1029#define DSN_NOHOST(e) \
1030	((e) == EAI_AGAIN || (e) == EAI_NONAME)
1031#endif
1032
1033    if (state->host_lookup & HOST_FLAG_NATIVE) {
1034	if ((aierr = hostname_to_sockaddr(host, (char *) 0, 0, &res0)) != 0) {
1035	    dsb_simple(why, (HAS_SOFT_DSN(why) || RETRY_AI_ERROR(aierr)) ?
1036		       (DSN_NOHOST(aierr) ? "4.4.4" : "4.3.0") :
1037		       (DSN_NOHOST(aierr) ? "5.4.4" : "5.3.0"),
1038		       "unable to look up host %s: %s",
1039		       host, MAI_STRERROR(aierr));
1040	} else {
1041	    for (found = 0, res = res0; res != 0; res = res->ai_next) {
1042		if (strchr((char *) proto_info->sa_family_list, res->ai_family) == 0) {
1043		    msg_info("skipping address family %d for host %s",
1044			     res->ai_family, host);
1045		    continue;
1046		}
1047		found++;
1048		if ((addr = dns_sa_to_rr(host, pref, res->ai_addr)) == 0)
1049		    msg_fatal("host %s: conversion error for address family %d: %m",
1050		    host, ((struct sockaddr *) (res0->ai_addr))->sa_family);
1051		addr_list = dns_rr_append(addr_list, addr);
1052	    }
1053	    freeaddrinfo(res0);
1054	    if (found == 0) {
1055		dsb_simple(why, HAS_SOFT_DSN(why) ? "4.4.4" : "5.4.4",
1056			   "%s: host not found", host);
1057	    }
1058	    return (addr_list);
1059	}
1060    }
1061
1062    /*
1063     * No further alternatives for host lookup.
1064     */
1065    return (addr_list);
1066}
1067
1068/* mx_addr_list - address lookup for a list of mail exchangers */
1069
1070static DNS_RR *mx_addr_list(STATE *state, DNS_RR *mx_names)
1071{
1072    static const char *myname = "mx_addr_list";
1073    DNS_RR *addr_list = 0;
1074    DNS_RR *rr;
1075    int     res_opt = mx_names->dnssec_valid ? RES_USE_DNSSEC : 0;
1076
1077    for (rr = mx_names; rr; rr = rr->next) {
1078	if (rr->type != T_MX)
1079	    msg_panic("%s: bad resource type: %d", myname, rr->type);
1080	addr_list = addr_one(state, addr_list, (char *) rr->data, res_opt,
1081			     rr->pref);
1082    }
1083    return (addr_list);
1084}
1085
1086/* smtp_domain_addr - mail exchanger address lookup */
1087
1088static DNS_RR *domain_addr(STATE *state, char *domain)
1089{
1090    DNS_RR *mx_names;
1091    DNS_RR *addr_list = 0;
1092    int     r = 0;			/* Resolver flags */
1093
1094    dsb_reset(state->why);
1095
1096#if (RES_USE_DNSSEC != 0) && (RES_USE_EDNS0 != 0)
1097    r |= RES_USE_DNSSEC;
1098#endif
1099
1100    switch (dns_lookup(domain, T_MX, r, &mx_names, (VSTRING *) 0,
1101		       state->why->reason)) {
1102    default:
1103	dsb_status(state->why, "4.4.3");
1104	break;
1105    case DNS_INVAL:
1106	dsb_status(state->why, "5.4.4");
1107	break;
1108    case DNS_FAIL:
1109	dsb_status(state->why, "5.4.3");
1110	break;
1111    case DNS_OK:
1112	mx_names = dns_rr_sort(mx_names, dns_rr_compare_pref_any);
1113	addr_list = mx_addr_list(state, mx_names);
1114	state->mx = dns_rr_copy(mx_names);
1115	dns_rr_free(mx_names);
1116	if (addr_list == 0) {
1117	    msg_warn("no MX host for %s has a valid address record", domain);
1118	    break;
1119	}
1120#define COMPARE_ADDR(flags) \
1121	((flags & MISC_FLAG_PREF_IPV6) ? dns_rr_compare_pref_ipv6 : \
1122	 (flags & MISC_FLAG_PREF_IPV4) ? dns_rr_compare_pref_ipv4 : \
1123	 dns_rr_compare_pref_any)
1124	if (addr_list && addr_list->next) {
1125	    addr_list = dns_rr_shuffle(addr_list);
1126	    addr_list = dns_rr_sort(addr_list, COMPARE_ADDR(state->addr_pref));
1127	}
1128	break;
1129    case DNS_NOTFOUND:
1130	addr_list = host_addr(state, domain);
1131	break;
1132    }
1133
1134    return (addr_list);
1135}
1136
1137/* host_addr - direct host lookup */
1138
1139static DNS_RR *host_addr(STATE *state, const char *host)
1140{
1141    DSN_BUF *why = state->why;
1142    DNS_RR *addr_list;
1143    int     res_opt = 0;
1144
1145    dsb_reset(why);				/* Paranoia */
1146
1147#if (RES_USE_DNSSEC != 0) && (RES_USE_EDNS0 != 0)
1148    res_opt |= RES_USE_DNSSEC;
1149#endif
1150
1151#define PREF0	0
1152    addr_list = addr_one(state, (DNS_RR *) 0, host, res_opt, PREF0);
1153    if (addr_list && addr_list->next) {
1154	addr_list = dns_rr_shuffle(addr_list);
1155	if (inet_proto_info()->ai_family_list[1] != 0)
1156	    addr_list = dns_rr_sort(addr_list, COMPARE_ADDR(state->addr_pref));
1157    }
1158    return (addr_list);
1159}
1160
1161/* dane_host_level - canidate host "dane" or degraded security level */
1162
1163static int dane_host_level(STATE *state, DNS_RR *addr)
1164{
1165    int     level = state->level;
1166
1167#ifdef USE_TLS
1168    if (level == TLS_LEV_DANE) {
1169	if (state->mx == 0 || state->mx->dnssec_valid) {
1170	    if (state->log_mask & (TLS_LOG_CERTMATCH | TLS_LOG_VERBOSE))
1171		tls_dane_verbose(1);
1172	    else
1173		tls_dane_verbose(0);
1174
1175	    /* See addr loop in connect_remote() */
1176	    if (state->ddane)
1177		tls_dane_free(state->ddane);
1178
1179	    /*
1180	     * When TLSA lookups fail, next host.  If unusable or not found,
1181	     * fallback to "secure"
1182	     */
1183	    state->ddane = tls_dane_resolve(state->port, "tcp", addr,
1184					    state->force_tlsa);
1185	    if (!state->ddane) {
1186		dsb_simple(state->why, "4.7.5",
1187			   "TLSA lookup error for %s:%u",
1188			   HNAME(addr), ntohs(state->port));
1189		level = TLS_LEV_INVALID;
1190	    } else if (tls_dane_notfound(state->ddane)
1191		       || tls_dane_unusable(state->ddane)) {
1192		if (msg_verbose)
1193		    msg_info("no %sTLSA records found, "
1194			     "resorting to \"secure\"",
1195			     tls_dane_unusable(state->ddane) ?
1196			     "usable " : "");
1197		level = TLS_LEV_SECURE;
1198	    } else if (!TLS_DANE_HASTA(state->ddane)
1199		       && !TLS_DANE_HASEE(state->ddane)) {
1200		msg_panic("empty DANE match list");
1201	    } else {
1202		if (state->match)
1203		    argv_free(state->match);
1204		argv_add(state->match = argv_alloc(2),
1205			 state->ddane->base_domain, ARGV_END);
1206		if (state->mx) {
1207		    if (strcmp(state->mx->qname, state->mx->rname) == 0)
1208			argv_add(state->match, state->mx->qname, ARGV_END);
1209		    else
1210			argv_add(state->match, state->mx->rname,
1211				 state->mx->qname, ARGV_END);
1212		}
1213	    }
1214	} else {
1215	    level = TLS_LEV_SECURE;
1216	}
1217    }
1218#endif
1219
1220    return (level);
1221}
1222
1223/* parse_destination - parse host/port destination */
1224
1225static char *parse_destination(char *destination, char *def_service,
1226			               char **hostp, unsigned *portp)
1227{
1228    char   *buf = mystrdup(destination);
1229    char   *service;
1230    struct servent *sp;
1231    char   *protocol = "tcp";
1232    unsigned port;
1233    const char *err;
1234
1235    if (msg_verbose)
1236	msg_info("parse_destination: %s %s", destination, def_service);
1237
1238    /*
1239     * Parse the host/port information. We're working with a copy of the
1240     * destination argument so the parsing can be destructive.
1241     */
1242    if ((err = host_port(buf, hostp, (char *) 0, &service, def_service)) != 0)
1243	msg_fatal("%s in server description: %s", err, destination);
1244
1245    /*
1246     * Convert service to port number, network byte order.
1247     */
1248    if (alldig(service)) {
1249	if ((port = atoi(service)) >= 65536 || port == 0)
1250	    msg_fatal("bad network port in destination: %s", destination);
1251	*portp = htons(port);
1252    } else {
1253	if ((sp = getservbyname(service, protocol)) != 0)
1254	    *portp = sp->s_port;
1255	else if (strcmp(service, "smtp") == 0)
1256	    *portp = htons(25);
1257	else
1258	    msg_fatal("unknown service: %s/%s", service, protocol);
1259    }
1260    return (buf);
1261}
1262
1263/* connect_remote - connect to TCP destination or log an error */
1264
1265static void connect_remote(STATE *state, char *dest)
1266{
1267    DNS_RR *addr;
1268    char   *buf;
1269    char   *domain;
1270
1271    /* When reconnecting use IP address of previous session */
1272    if (state->addr == 0) {
1273	buf = parse_destination(dest, state->smtp ? "smtp" : "24",
1274				&domain, &state->port);
1275	if (!state->nexthop)
1276	    state->nexthop = mystrdup(domain);
1277	if (state->smtp == 0 || *dest == '[')
1278	    state->addr = host_addr(state, domain);
1279	else
1280	    state->addr = domain_addr(state, domain);
1281	myfree(buf);
1282
1283	if (state->addr == 0) {
1284	    msg_info("Destination address lookup failed: %s",
1285		     vstring_str(state->why->reason));
1286	    return;
1287	}
1288    }
1289    for (addr = state->addr; addr; addr = addr->next) {
1290	int     level = dane_host_level(state, addr);
1291
1292	if (level == TLS_LEV_INVALID
1293	    || (state->stream = connect_addr(state, addr)) == 0) {
1294	    msg_info("Failed to establish session to %s via %s: %s",
1295		     dest, HNAME(addr), vstring_str(state->why->reason));
1296	    continue;
1297	}
1298	/* We have a connection */
1299	state->level = level;
1300	state->hostname = mystrdup(HNAME(addr));
1301
1302	/* We use the same address when reconnecting, so flush the rest. */
1303	addr = dns_rr_copy(addr);
1304	dns_rr_free(state->addr);
1305	state->addr = addr;
1306	break;
1307    }
1308}
1309
1310/* connect_dest - connect to given inet: or unix: destination */
1311
1312static int connect_dest(STATE *state)
1313{
1314    char   *dest = state->dest;
1315
1316    /*
1317     * With LMTP we have direct-to-host delivery only. The destination may
1318     * have multiple IP addresses.
1319     */
1320    if (state->smtp == 0) {
1321	if (strncmp(dest, "unix:", 5) == 0) {
1322	    connect_unix(state, dest + 5);
1323	    if (!state->stream)
1324		msg_info("Failed to establish session to %s: %s",
1325			 dest, vstring_str(state->why->reason));
1326	    return (1);
1327	}
1328	if (strncmp(dest, "inet:", 5) == 0)
1329	    dest += 5;
1330    }
1331    connect_remote(state, dest);
1332
1333    return (state->stream == 0);
1334}
1335
1336static void disconnect_dest(STATE *state)
1337{
1338#ifdef USE_TLS
1339    if (state->tls_context)
1340	tls_client_stop(state->tls_ctx, state->stream,
1341			smtp_tmout, 0, state->tls_context);
1342    state->tls_context = 0;
1343    if (state->ddane)
1344	tls_dane_free(state->ddane);
1345    state->ddane = 0;
1346#endif
1347
1348    if (state->stream)
1349	vstream_fclose(state->stream);
1350    state->stream = 0;
1351
1352    if (state->namaddrport)
1353	myfree(state->namaddrport);
1354    state->namaddrport = 0;
1355
1356    if (state->addrport)
1357	myfree(state->addrport);
1358    state->addrport = 0;
1359
1360    /* Reused on reconnect */
1361    if (state->reconnect <= 0) {
1362	if (state->addr)
1363	    dns_rr_free(state->addr);
1364	state->addr = 0;
1365	if (state->mx)
1366	    dns_rr_free(state->mx);
1367	state->mx = 0;
1368
1369	if (state->nexthop)
1370	    myfree(state->nexthop);
1371	state->nexthop = 0;
1372    }
1373    if (state->hostname)
1374	myfree(state->hostname);
1375    state->hostname = 0;
1376
1377    dsb_free(state->why);
1378    vstring_free(state->buffer);
1379}
1380
1381static int finger(STATE *state)
1382{
1383    int     err;
1384
1385    /*
1386     * Make sure the SMTP server cannot run us out of memory by sending
1387     * never-ending lines of text.
1388     */
1389    state->buffer = vstring_alloc(100);
1390    vstring_ctl(state->buffer, VSTRING_CTL_MAXLEN,
1391		(ssize_t) var_line_limit, 0);
1392    state->why = dsb_create();
1393
1394    if (!(err = connect_dest(state))) {
1395	if (state->pass == 1 && !state->nochat)
1396	    msg_info("Connected to %s", state->namaddrport);
1397	err = doproto(state);
1398    }
1399    disconnect_dest(state);
1400
1401    if (err != 0)
1402	return (1);
1403
1404#ifdef USE_TLS
1405    if (state->reconnect > 0) {
1406	int     cache_enabled;
1407	int     cache_count;
1408	int     cache_hits;
1409
1410	tlsmgrmem_status(&cache_enabled, &cache_count, &cache_hits);
1411	if (cache_enabled && cache_count == 0) {
1412	    msg_info("Server declined session caching. Done reconnecting.");
1413	    state->reconnect = 0;
1414	} else if (cache_hits > 0 && (state->log_mask & TLS_LOG_SESSTKT) != 0) {
1415	    msg_info("Found a previously used server.  Done reconnecting.");
1416	    state->reconnect = 0;
1417	} else if (state->max_reconnect-- <= 0) {
1418	    msg_info("Maximum reconnect count reached.");
1419	    state->reconnect = 0;
1420	}
1421    }
1422#endif
1423
1424    return (0);
1425}
1426
1427#ifdef USE_TLS
1428
1429/* ssl_cleanup - free memory allocated in the OpenSSL library */
1430
1431static void ssl_cleanup(void)
1432{
1433#if OPENSSL_VERSION_NUMBER >= 0x10000000L
1434    ERR_remove_thread_state(0);		/* Thread-id is now a pointer */
1435#else
1436    ERR_remove_state(0);		/* Deprecated with OpenSSL 1.0.0 */
1437#endif
1438    ENGINE_cleanup();
1439    CONF_modules_unload(1);
1440    ERR_free_strings();
1441    EVP_cleanup();
1442    CRYPTO_cleanup_all_ex_data();
1443}
1444
1445#endif
1446
1447/* run - do what we were asked to do. */
1448
1449static int run(STATE *state)
1450{
1451
1452    while (1) {
1453	if (finger(state) != 0)
1454	    break;
1455	if (state->reconnect <= 0)
1456	    break;
1457	msg_info("Reconnecting after %d seconds", state->reconnect);
1458	++state->pass;
1459	sleep(state->reconnect);
1460    }
1461
1462    return (0);
1463}
1464
1465/* cleanup - free memory allocated in main */
1466
1467static void cleanup(STATE *state)
1468{
1469#ifdef USE_TLS
1470    if (state->tls_ctx != 0)
1471	tls_free_app_context(state->tls_ctx);
1472    if (state->tls_bio)
1473	(void) BIO_free(state->tls_bio);
1474    state->tls_bio = 0;
1475
1476    myfree(state->mdalg);
1477    myfree(state->CApath);
1478    myfree(state->CAfile);
1479    if (state->options.level)
1480	myfree(state->options.level);
1481    myfree(state->options.logopts);
1482    if (state->match)
1483	argv_free(state->match);
1484    if (state->options.tas)
1485	argv_free(state->options.tas);
1486    if (state->dane)
1487	tls_dane_free(state->dane);
1488
1489    /* Flush and free DANE TLSA cache */
1490    tls_dane_flush();
1491    /* Flush and free memory tlsmgr cache */
1492    tlsmgrmem_flush();
1493    myfree(state->grade);
1494    myfree(state->protocols);
1495#endif
1496    myfree(state->options.host_lookup);
1497    myfree(state->dest);
1498
1499    mail_conf_flush();
1500}
1501
1502/* usage - explain */
1503
1504static void usage(void)
1505{
1506#ifdef USE_TLS
1507    fprintf(stderr, "usage: %s %s \\\n\t%s \\\n\t%s \\\n\t%s"
1508	    " destination [match ...]\n", var_procname,
1509	    "[-acCfSv] [-t conn_tmout] [-T cmd_tmout] [-L logopts]",
1510	 "[-h host_lookup] [-l level] [-d mdalg] [-g grade] [-p protocols]",
1511	    "[-A tafile] [-F CAfile.pem] [-P CApath/] [-m count] [-r delay]",
1512	    "[-o name=value]");
1513#else
1514    fprintf(stderr, "usage: %s [-acStTv] [-h host_lookup] [-o name=value] destination\n",
1515	    var_procname);
1516#endif
1517    exit(1);
1518}
1519
1520/* tls_init - initialize application TLS library context */
1521
1522static void tls_init(STATE *state)
1523{
1524#ifdef USE_TLS
1525    TLS_CLIENT_INIT_PROPS props;
1526
1527    if (state->level <= TLS_LEV_NONE)
1528	return;
1529
1530    state->tls_ctx =
1531	TLS_CLIENT_INIT(&props,
1532			log_param = "-L option",
1533			log_level = state->options.logopts,
1534			verifydepth = DEF_SMTP_TLS_SCERT_VD,
1535			cache_type = "memory",
1536			cert_file = "",
1537			key_file = "",
1538			dcert_file = "",
1539			dkey_file = "",
1540			eccert_file = "",
1541			eckey_file = "",
1542			CAfile = state->CAfile,
1543			CApath = state->CApath,
1544			mdalg = state->mdalg);
1545#endif
1546}
1547
1548/* override - update main.cf parameter */
1549
1550static void override(const char *nameval)
1551{
1552    char   *param_name;
1553    char   *param_value;
1554    char   *save = mystrdup(nameval);
1555
1556    if (split_nameval(save, &param_name, &param_value) != 0)
1557	usage();
1558    mail_conf_update(param_name, param_value);
1559    myfree(save);
1560}
1561
1562/* parse_options - (argc, argv) -> state */
1563
1564static void parse_options(STATE *state, int argc, char *argv[])
1565{
1566    int     c;
1567
1568    state->smtp = 1;
1569    state->pass = 1;
1570    state->reconnect = -1;
1571    state->max_reconnect = 5;
1572#ifdef USE_TLS
1573    state->protocols = mystrdup("!SSLv2");
1574    state->grade = mystrdup("medium");
1575#endif
1576    memset((char *) &state->options, 0, sizeof(state->options));
1577    state->options.host_lookup = mystrdup("dns");
1578
1579#define OPTS "a:ch:o:St:T:v"
1580#ifdef USE_TLS
1581#define TLSOPTS "A:Cd:fF:g:l:L:m:p:P:r:"
1582
1583    state->mdalg = mystrdup("sha1");
1584    state->CApath = mystrdup("");
1585    state->CAfile = mystrdup("");
1586    state->options.tas = argv_alloc(1);
1587    state->options.logopts = 0;
1588    state->level = TLS_LEV_DANE;
1589#else
1590#define TLSOPTS ""
1591    state->level = TLS_LEV_NONE;
1592#endif
1593
1594    while ((c = GETOPT(argc, argv, OPTS TLSOPTS)) > 0) {
1595	switch (c) {
1596	default:
1597	    usage();
1598	    break;
1599	case 'a':
1600	    state->options.addr_pref = mystrdup(optarg);
1601	    break;
1602	case 'c':
1603	    state->nochat = 1;
1604	    break;
1605	case 'h':
1606	    myfree(state->options.host_lookup);
1607	    state->options.host_lookup = mystrdup(optarg);
1608	    break;
1609	case 'o':
1610	    override(optarg);
1611	    break;
1612	case 'S':
1613	    state->smtp = 0;
1614	    break;
1615	case 't':
1616	    conn_tmout = atoi(optarg);
1617	    break;
1618	case 'T':
1619	    smtp_tmout = atoi(optarg);
1620	    break;
1621	case 'v':
1622	    msg_verbose++;
1623	    break;
1624#ifdef USE_TLS
1625	case 'A':
1626	    argv_add(state->options.tas, optarg, ARGV_END);
1627	    break;
1628	case 'C':
1629	    state->print_trust = 1;
1630	    break;
1631	case 'd':
1632	    myfree(state->mdalg);
1633	    state->mdalg = mystrdup(optarg);
1634	    break;
1635	case 'f':
1636	    state->force_tlsa = 1;
1637	    break;
1638	case 'F':
1639	    myfree(state->CAfile);
1640	    state->CAfile = mystrdup(optarg);
1641	    break;
1642	case 'g':
1643	    myfree(state->grade);
1644	    state->grade = mystrdup(optarg);
1645	    break;
1646	case 'l':
1647	    if (state->options.level)
1648		myfree(state->options.level);
1649	    state->options.level = mystrdup(optarg);
1650	    break;
1651	case 'L':
1652	    if (state->options.logopts)
1653		myfree(state->options.logopts);
1654	    state->options.logopts = mystrdup(optarg);
1655	    break;
1656	case 'm':
1657	    state->max_reconnect = atoi(optarg);
1658	    break;
1659	case 'p':
1660	    myfree(state->protocols);
1661	    state->protocols = mystrdup(optarg);
1662	    break;
1663	case 'P':
1664	    myfree(state->CApath);
1665	    state->CApath = mystrdup(optarg);
1666	    break;
1667	case 'r':
1668	    state->reconnect = atoi(optarg);
1669	    break;
1670#endif
1671	}
1672    }
1673
1674    /*
1675     * Address family preference.
1676     */
1677    state->addr_pref =
1678	name_code(addr_pref_map, NAME_CODE_FLAG_NONE, state->options.addr_pref ?
1679		  state->options.addr_pref : "any");
1680    if (state->addr_pref < 0)
1681	msg_fatal("bad '-a' option value: %s", state->options.addr_pref);
1682
1683    /*
1684     * Select hostname lookup mechanisms.
1685     */
1686    state->host_lookup =
1687	name_mask("-h option", lookup_masks, state->options.host_lookup ?
1688		  state->options.host_lookup : "dns");
1689
1690#ifdef USE_TLS
1691
1692    if (state->reconnect < 0)
1693	tlsmgrmem_disable();
1694
1695    if (state->options.logopts == 0)
1696	state->options.logopts = mystrdup("routine,certmatch");
1697    state->log_mask = tls_log_mask("-L option", state->options.logopts);
1698
1699    if (state->options.level) {
1700	state->level = tls_level_lookup(state->options.level);
1701
1702	switch (state->level) {
1703	case TLS_LEV_DANE_ONLY:
1704	    state->level = TLS_LEV_DANE;
1705	    break;
1706	case TLS_LEV_NONE:
1707	    return;
1708	case TLS_LEV_INVALID:
1709	    msg_fatal("Invalid TLS level \"%s\"", state->options.level);
1710	}
1711    }
1712
1713    /*
1714     * We first call tls_init(), which ultimately calls SSL_library_init(),
1715     * since otherwise we can't tell whether we have the message digests
1716     * required for DANE support.
1717     */
1718    tls_init(state);
1719    if (state->level == TLS_LEV_DANE && !tls_dane_avail()) {
1720	msg_warn("The \"dane\" TLS security level is not available");
1721	state->level = TLS_LEV_SECURE;
1722    }
1723    state->tls_bio = 0;
1724    if (state->print_trust)
1725	state->tls_bio = BIO_new_fp(stdout, BIO_NOCLOSE);
1726
1727#endif
1728}
1729
1730/* parse_match - process match arguments */
1731
1732static void parse_match(STATE *state, int argc, char *argv[])
1733{
1734#ifdef USE_TLS
1735
1736    switch (state->level) {
1737	case TLS_LEV_SECURE:
1738	state->match = argv_alloc(2);
1739	while (*argv)
1740	    argv_split_append(state->match, *argv++, "");
1741	if (state->match->argc == 0)
1742	    argv_add(state->match, "nexthop", "dot-nexthop", ARGV_END);
1743	break;
1744    case TLS_LEV_VERIFY:
1745	state->match = argv_alloc(1);
1746	while (*argv)
1747	    argv_split_append(state->match, *argv++, "");
1748	if (state->match->argc == 0)
1749	    argv_add(state->match, "hostname", ARGV_END);
1750	break;
1751    case TLS_LEV_FPRINT:
1752	state->dane = tls_dane_alloc();
1753	while (*argv)
1754	    tls_dane_add_ee_digests((TLS_DANE *) state->dane,
1755				    state->mdalg, *argv++, "");
1756	break;
1757    case TLS_LEV_DANE:
1758	state->match = argv_alloc(2);
1759	argv_add(state->match, "nexthop", "hostname", ARGV_END);
1760	break;
1761    }
1762#endif
1763}
1764
1765/* parse_tas - process '-A' trust anchor file option */
1766
1767static void parse_tas(STATE *state)
1768{
1769#ifdef USE_TLS
1770    char  **file;
1771
1772    if (!state->options.tas->argc)
1773	return;
1774
1775    switch (state->level) {
1776    default:
1777	return;
1778    case TLS_LEV_SECURE:
1779    case TLS_LEV_VERIFY:
1780	state->dane = tls_dane_alloc();
1781	for (file = state->options.tas->argv; *file; ++file) {
1782	    if (!tls_dane_load_trustfile((TLS_DANE *) state->dane, *file))
1783		break;
1784	}
1785	if (*file)
1786	    msg_fatal("Failed to load trust anchor file: %s", *file);
1787	break;
1788    }
1789#endif
1790}
1791
1792
1793int     main(int argc, char *argv[])
1794{
1795    static STATE state;
1796    char   *loopenv = getenv("VALGRINDLOOP");
1797    int     loop = loopenv ? atoi(loopenv) : 1;
1798
1799    /* Don't die when a peer goes away unexpectedly. */
1800    signal(SIGPIPE, SIG_IGN);
1801
1802    /* We're a diagnostic utility, so diagnostic messages go to stdout. */
1803    var_procname = mystrdup(basename(argv[0]));
1804    set_mail_conf_str(VAR_PROCNAME, var_procname);
1805    msg_vstream_init(var_procname, VSTREAM_OUT);
1806
1807    /*
1808     * Load main.cf, parse command-line options, then process main.cf
1809     * settings plus any command-line "-o" overrides.
1810     */
1811    mail_conf_suck();
1812    parse_options(&state, argc, argv);
1813    mail_params_init();
1814    parse_tas(&state);
1815
1816    argc -= optind;
1817    argv += optind;
1818
1819    /* The first non-option argument is the destination. */
1820    if (!argc)
1821	usage();
1822
1823    state.dest = mystrdup(argv[0]);
1824    parse_match(&state, --argc, ++argv);
1825
1826    /* Don't talk to remote systems as root */
1827    if (!geteuid())
1828	chroot_uid(0, var_mail_owner);
1829
1830    while (loop-- > 0)
1831	run(&state);
1832
1833    /* Be valgrind friendly and clean-up */
1834    cleanup(&state);
1835#ifdef USE_TLS
1836    ssl_cleanup();
1837#endif
1838
1839    return (0);
1840}
1841