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