~ubuntu-branches/debian/sid/postfix/sid

« back to all changes in this revision

Viewing changes to src/posttls-finger/posttls-finger.c

  • Committer: Package Import Robot
  • Author(s): LaMont Jones, LaMont Jones, localization folks
  • Date: 2014-02-11 07:44:30 UTC
  • mfrom: (1.1.41)
  • Revision ID: package-import@ubuntu.com-20140211074430-91tdwgjriazawdz4
Tags: 2.11.0-1
[LaMont Jones]

* New upstream release: 2.11.0

[localization folks]

* l10n: Updated German translations.  Closes: #734893 (Helge Kreutzmann)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
 
 
361
static int conn_tmout = 30;
 
362
static 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
 
 
370
static const NAME_MASK lookup_masks[] = {
 
371
    "dns", HOST_FLAG_DNS,
 
372
    "native", HOST_FLAG_NATIVE,
 
373
    0,
 
374
};
 
375
 
 
376
static 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
 
 
383
typedef 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
  */
 
400
typedef 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
 
 
440
static 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
  */
 
447
typedef 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
 
 
456
static 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
 
 
485
static 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
 
 
537
static 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
 
 
551
static 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
 
 
584
static 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
 
 
617
static 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
 
 
641
static 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
 
 
738
static 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
 
 
801
static 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
 
 
854
static 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
 
 
904
static 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
 
 
957
static 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
 
 
1070
static 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
 
 
1088
static 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
 
 
1139
static 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
 
 
1163
static 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
 
 
1225
static 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
 
 
1265
static 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
 
 
1312
static 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
 
 
1336
static 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
 
 
1381
static 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
 
 
1431
static 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
 
 
1449
static 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
 
 
1467
static 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
 
 
1504
static 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
 
 
1522
static 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
 
 
1550
static 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
 
 
1564
static 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
 
 
1732
static 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
 
 
1767
static 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
 
 
1793
int     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
}