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