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